1use std::borrow::Cow;
14use std::sync::Arc;
15
16use crate::error::Result;
17use crate::expressions::*;
18use crate::DialectType;
19
20pub struct Generator {
45 config: Arc<GeneratorConfig>,
46 output: String,
47 unsupported_messages: Vec<String>,
48 indent_level: usize,
49 athena_hive_context: bool,
52 sqlite_inline_pk_columns: std::collections::HashSet<String>,
54 merge_strip_qualifiers: Vec<String>,
56 clickhouse_nullable_depth: i32,
61}
62
63#[derive(Debug, Clone, Copy, PartialEq, Default)]
69pub enum NormalizeFunctions {
70 #[default]
72 Upper,
73 Lower,
75 None,
77}
78
79#[derive(Debug, Clone, Copy, PartialEq, Default)]
81pub enum LimitFetchStyle {
82 #[default]
84 Limit,
85 Top,
87 FetchFirst,
89}
90
91#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
93pub enum NotInStyle {
94 #[default]
96 Prefix,
97 Infix,
99}
100
101#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
103pub enum UnsupportedLevel {
104 Ignore,
106 #[default]
108 Warn,
109 Raise,
111 Immediate,
113}
114
115#[derive(Debug, Clone, Copy, PartialEq, Eq)]
116enum ConnectorOperator {
117 And,
118 Or,
119}
120
121impl ConnectorOperator {
122 fn keyword(self) -> &'static str {
123 match self {
124 Self::And => "AND",
125 Self::Or => "OR",
126 }
127 }
128}
129
130#[derive(Debug, Clone, Copy, PartialEq)]
132pub struct IdentifierQuoteStyle {
133 pub start: char,
135 pub end: char,
137}
138
139impl Default for IdentifierQuoteStyle {
140 fn default() -> Self {
141 Self {
142 start: '"',
143 end: '"',
144 }
145 }
146}
147
148impl IdentifierQuoteStyle {
149 pub const DOUBLE_QUOTE: Self = Self {
151 start: '"',
152 end: '"',
153 };
154 pub const BACKTICK: Self = Self {
156 start: '`',
157 end: '`',
158 };
159 pub const BRACKET: Self = Self {
161 start: '[',
162 end: ']',
163 };
164}
165
166#[derive(Debug, Clone)]
188pub struct GeneratorConfig {
189 pub pretty: bool,
192 pub indent: &'static str,
194 pub max_text_width: usize,
196 pub identifier_quote: char,
198 pub identifier_quote_style: IdentifierQuoteStyle,
200 pub uppercase_keywords: bool,
202 pub normalize_identifiers: bool,
204 pub dialect: Option<crate::dialects::DialectType>,
206 pub source_dialect: Option<crate::dialects::DialectType>,
208 pub unsupported_level: UnsupportedLevel,
210 pub max_unsupported: usize,
212 pub normalize_functions: NormalizeFunctions,
214 pub string_escape: char,
216 pub case_sensitive_identifiers: bool,
218 pub identifiers_can_start_with_digit: bool,
220 pub always_quote_identifiers: bool,
223 pub not_in_style: NotInStyle,
225
226 pub null_ordering_supported: bool,
230 pub ignore_nulls_in_func: bool,
233 pub nvl2_supported: bool,
235
236 pub limit_fetch_style: LimitFetchStyle,
239 pub limit_is_top: bool,
241 pub limit_only_literals: bool,
243
244 pub single_string_interval: bool,
247 pub interval_allows_plural_form: bool,
249
250 pub cte_recursive_keyword_required: bool,
253
254 pub values_as_table: bool,
257 pub wrap_derived_values: bool,
259
260 pub tablesample_seed_keyword: &'static str,
263 pub tablesample_requires_parens: bool,
265 pub tablesample_size_is_rows: bool,
267 pub tablesample_keywords: &'static str,
269 pub tablesample_with_method: bool,
271 pub alias_post_tablesample: bool,
273
274 pub aggregate_filter_supported: bool,
277 pub multi_arg_distinct: bool,
279 pub quantified_no_paren_space: bool,
281 pub supports_median: bool,
283
284 pub supports_select_into: bool,
287 pub locking_reads_supported: bool,
289
290 pub rename_table_with_db: bool,
293 pub semi_anti_join_with_side: bool,
295 pub supports_table_alias_columns: bool,
297 pub join_hints: bool,
299 pub table_hints: bool,
301 pub query_hints: bool,
303 pub query_hint_sep: &'static str,
305 pub supports_column_join_marks: bool,
307
308 pub index_using_no_space: bool,
312 pub supports_unlogged_tables: bool,
314 pub supports_create_table_like: bool,
316 pub like_property_inside_schema: bool,
318 pub alter_table_include_column_keyword: bool,
320 pub supports_table_copy: bool,
322 pub alter_set_type: &'static str,
324 pub alter_set_wrapped: bool,
326
327 pub tz_to_with_time_zone: bool,
330 pub supports_convert_timezone: bool,
332
333 pub json_type_required_for_extraction: bool,
336 pub json_path_bracketed_key_supported: bool,
338 pub json_path_single_quote_escape: bool,
340 pub quote_json_path: bool,
342 pub json_key_value_pair_sep: &'static str,
344
345 pub copy_params_are_wrapped: bool,
348 pub copy_params_eq_required: bool,
350 pub copy_has_into_keyword: bool,
352
353 pub supports_window_exclude: bool,
356 pub unnest_with_ordinality: bool,
358 pub lowercase_window_frame_keywords: bool,
361 pub normalize_window_frame_between: bool,
364
365 pub array_concat_is_var_len: bool,
368 pub array_size_dim_required: Option<bool>,
371 pub can_implement_array_any: bool,
373 pub array_size_name: &'static str,
375
376 pub supports_between_flags: bool,
379
380 pub is_bool_allowed: bool,
383 pub ensure_bools: bool,
385
386 pub extract_allows_quotes: bool,
389 pub normalize_extract_date_parts: bool,
391
392 pub try_supported: bool,
395 pub supports_uescape: bool,
397 pub supports_to_number: bool,
399 pub supports_single_arg_concat: bool,
401 pub last_day_supports_date_part: bool,
403 pub supports_exploding_projections: bool,
405 pub supports_unix_seconds: bool,
407 pub supports_like_quantifiers: bool,
409 pub supports_decode_case: bool,
411 pub set_op_modifiers: bool,
413 pub update_statement_supports_from: bool,
415
416 pub collate_is_func: bool,
419
420 pub duplicate_key_update_with_set: bool,
423 pub insert_overwrite: &'static str,
425
426 pub returning_end: bool,
429
430 pub matched_by_source: bool,
433
434 pub create_function_return_as: bool,
437 pub parameter_default_equals: bool,
439
440 pub computed_column_with_type: bool,
443
444 pub unpivot_aliases_are_identifiers: bool,
447
448 pub star_except: &'static str,
451
452 pub hex_func: &'static str,
455
456 pub with_properties_prefix: &'static str,
459
460 pub pad_fill_pattern_is_required: bool,
463
464 pub index_on: &'static str,
467
468 pub groupings_sep: &'static str,
471
472 pub struct_delimiter: (&'static str, &'static str),
475 pub struct_curly_brace_notation: bool,
477 pub array_bracket_only: bool,
479 pub struct_field_sep: &'static str,
481
482 pub except_intersect_support_all_clause: bool,
485
486 pub parameter_token: &'static str,
489 pub named_placeholder_token: &'static str,
491
492 pub data_type_specifiers_allowed: bool,
495
496 pub schema_comment_with_eq: bool,
500}
501
502impl Default for GeneratorConfig {
503 fn default() -> Self {
504 Self {
505 pretty: false,
507 indent: " ",
508 max_text_width: 80,
509 identifier_quote: '"',
510 identifier_quote_style: IdentifierQuoteStyle::DOUBLE_QUOTE,
511 uppercase_keywords: true,
512 normalize_identifiers: false,
513 dialect: None,
514 source_dialect: None,
515 unsupported_level: UnsupportedLevel::Warn,
516 max_unsupported: 3,
517 normalize_functions: NormalizeFunctions::Upper,
518 string_escape: '\'',
519 case_sensitive_identifiers: false,
520 identifiers_can_start_with_digit: false,
521 always_quote_identifiers: false,
522 not_in_style: NotInStyle::Prefix,
523
524 null_ordering_supported: true,
526 ignore_nulls_in_func: false,
527 nvl2_supported: true,
528
529 limit_fetch_style: LimitFetchStyle::Limit,
531 limit_is_top: false,
532 limit_only_literals: false,
533
534 single_string_interval: false,
536 interval_allows_plural_form: true,
537
538 cte_recursive_keyword_required: true,
540
541 values_as_table: true,
543 wrap_derived_values: true,
544
545 tablesample_seed_keyword: "SEED",
547 tablesample_requires_parens: true,
548 tablesample_size_is_rows: true,
549 tablesample_keywords: "TABLESAMPLE",
550 tablesample_with_method: true,
551 alias_post_tablesample: false,
552
553 aggregate_filter_supported: true,
555 multi_arg_distinct: true,
556 quantified_no_paren_space: false,
557 supports_median: true,
558
559 supports_select_into: false,
561 locking_reads_supported: true,
562
563 rename_table_with_db: true,
565 semi_anti_join_with_side: true,
566 supports_table_alias_columns: true,
567 join_hints: true,
568 table_hints: true,
569 query_hints: true,
570 query_hint_sep: ", ",
571 supports_column_join_marks: false,
572
573 index_using_no_space: false,
575 supports_unlogged_tables: false,
576 supports_create_table_like: true,
577 like_property_inside_schema: false,
578 alter_table_include_column_keyword: true,
579 supports_table_copy: true,
580 alter_set_type: "SET DATA TYPE",
581 alter_set_wrapped: false,
582
583 tz_to_with_time_zone: false,
585 supports_convert_timezone: false,
586
587 json_type_required_for_extraction: false,
589 json_path_bracketed_key_supported: true,
590 json_path_single_quote_escape: false,
591 quote_json_path: true,
592 json_key_value_pair_sep: ":",
593
594 copy_params_are_wrapped: true,
596 copy_params_eq_required: false,
597 copy_has_into_keyword: true,
598
599 supports_window_exclude: false,
601 unnest_with_ordinality: true,
602 lowercase_window_frame_keywords: false,
603 normalize_window_frame_between: false,
604
605 array_concat_is_var_len: true,
607 array_size_dim_required: None,
608 can_implement_array_any: false,
609 array_size_name: "ARRAY_LENGTH",
610
611 supports_between_flags: false,
613
614 is_bool_allowed: true,
616 ensure_bools: false,
617
618 extract_allows_quotes: true,
620 normalize_extract_date_parts: false,
621
622 try_supported: true,
624 supports_uescape: true,
625 supports_to_number: true,
626 supports_single_arg_concat: true,
627 last_day_supports_date_part: true,
628 supports_exploding_projections: true,
629 supports_unix_seconds: false,
630 supports_like_quantifiers: true,
631 supports_decode_case: true,
632 set_op_modifiers: true,
633 update_statement_supports_from: true,
634
635 collate_is_func: false,
637
638 duplicate_key_update_with_set: true,
640 insert_overwrite: " OVERWRITE TABLE",
641
642 returning_end: true,
644
645 matched_by_source: true,
647
648 create_function_return_as: true,
650 parameter_default_equals: false,
651
652 computed_column_with_type: true,
654
655 unpivot_aliases_are_identifiers: true,
657
658 star_except: "EXCEPT",
660
661 hex_func: "HEX",
663
664 with_properties_prefix: "WITH",
666
667 pad_fill_pattern_is_required: false,
669
670 index_on: "ON",
672
673 groupings_sep: ",",
675
676 struct_delimiter: ("<", ">"),
678 struct_curly_brace_notation: false,
679 array_bracket_only: false,
680 struct_field_sep: " ",
681
682 except_intersect_support_all_clause: true,
684
685 parameter_token: "@",
687 named_placeholder_token: ":",
688
689 data_type_specifiers_allowed: false,
691
692 schema_comment_with_eq: true,
694 }
695 }
696}
697
698mod reserved_keywords {
701 use std::collections::HashSet;
702 use std::sync::LazyLock;
703
704 pub static SQL_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
706 [
707 "all",
708 "alter",
709 "and",
710 "any",
711 "array",
712 "as",
713 "asc",
714 "at",
715 "authorization",
716 "begin",
717 "between",
718 "both",
719 "by",
720 "case",
721 "cast",
722 "check",
723 "collate",
724 "column",
725 "commit",
726 "constraint",
727 "create",
728 "cross",
729 "cube",
730 "current",
731 "current_date",
732 "current_time",
733 "current_timestamp",
734 "current_user",
735 "default",
736 "delete",
737 "desc",
738 "distinct",
739 "drop",
740 "else",
741 "end",
742 "escape",
743 "except",
744 "execute",
745 "exists",
746 "external",
747 "false",
748 "fetch",
749 "filter",
750 "for",
751 "foreign",
752 "from",
753 "full",
754 "function",
755 "grant",
756 "group",
757 "grouping",
758 "having",
759 "if",
760 "in",
761 "index",
762 "inner",
763 "insert",
764 "intersect",
765 "interval",
766 "into",
767 "is",
768 "join",
769 "key",
770 "leading",
771 "left",
772 "like",
773 "limit",
774 "local",
775 "localtime",
776 "localtimestamp",
777 "match",
778 "merge",
779 "natural",
780 "no",
781 "not",
782 "null",
783 "of",
784 "offset",
785 "on",
786 "only",
787 "or",
788 "order",
789 "outer",
790 "over",
791 "partition",
792 "primary",
793 "procedure",
794 "range",
795 "references",
796 "right",
797 "rollback",
798 "rollup",
799 "row",
800 "rows",
801 "select",
802 "session_user",
803 "set",
804 "some",
805 "table",
806 "tablesample",
807 "then",
808 "to",
809 "trailing",
810 "true",
811 "truncate",
812 "union",
813 "unique",
814 "unknown",
815 "update",
816 "user",
817 "using",
818 "values",
819 "view",
820 "when",
821 "where",
822 "window",
823 "with",
824 ]
825 .into_iter()
826 .collect()
827 });
828
829 pub static BIGQUERY_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
832 let mut set = SQL_RESERVED.clone();
833 set.extend([
834 "assert_rows_modified",
835 "at",
836 "contains",
837 "cube",
838 "current",
839 "define",
840 "enum",
841 "escape",
842 "exclude",
843 "following",
844 "for",
845 "groups",
846 "hash",
847 "ignore",
848 "lateral",
849 "lookup",
850 "new",
851 "no",
852 "nulls",
853 "of",
854 "over",
855 "preceding",
856 "proto",
857 "qualify",
858 "recursive",
859 "respect",
860 "struct",
861 "tablesample",
862 "treat",
863 "unbounded",
864 "unnest",
865 "window",
866 "within",
867 ]);
868 set.remove("grant");
870 set.remove("key");
871 set.remove("index");
872 set.remove("offset");
873 set.remove("values");
874 set.remove("table");
875 set
876 });
877
878 pub static MYSQL_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
880 let mut set = SQL_RESERVED.clone();
881 set.extend([
882 "accessible",
883 "add",
884 "analyze",
885 "asensitive",
886 "before",
887 "bigint",
888 "binary",
889 "blob",
890 "call",
891 "cascade",
892 "change",
893 "char",
894 "character",
895 "condition",
896 "continue",
897 "convert",
898 "current_date",
899 "current_time",
900 "current_timestamp",
901 "current_user",
902 "cursor",
903 "database",
904 "databases",
905 "day_hour",
906 "day_microsecond",
907 "day_minute",
908 "day_second",
909 "dec",
910 "decimal",
911 "declare",
912 "delayed",
913 "describe",
914 "deterministic",
915 "distinctrow",
916 "div",
917 "double",
918 "dual",
919 "each",
920 "elseif",
921 "enclosed",
922 "escaped",
923 "exit",
924 "explain",
925 "float",
926 "float4",
927 "float8",
928 "force",
929 "get",
930 "high_priority",
931 "hour_microsecond",
932 "hour_minute",
933 "hour_second",
934 "ignore",
935 "infile",
936 "inout",
937 "insensitive",
938 "int",
939 "int1",
940 "int2",
941 "int3",
942 "int4",
943 "int8",
944 "integer",
945 "iterate",
946 "keys",
947 "kill",
948 "leave",
949 "linear",
950 "lines",
951 "load",
952 "lock",
953 "long",
954 "longblob",
955 "longtext",
956 "loop",
957 "low_priority",
958 "master_ssl_verify_server_cert",
959 "maxvalue",
960 "mediumblob",
961 "mediumint",
962 "mediumtext",
963 "middleint",
964 "minute_microsecond",
965 "minute_second",
966 "mod",
967 "modifies",
968 "no_write_to_binlog",
969 "numeric",
970 "optimize",
971 "option",
972 "optionally",
973 "out",
974 "outfile",
975 "precision",
976 "purge",
977 "read",
978 "reads",
979 "real",
980 "regexp",
981 "release",
982 "rename",
983 "repeat",
984 "replace",
985 "require",
986 "resignal",
987 "restrict",
988 "return",
989 "revoke",
990 "rlike",
991 "schema",
992 "schemas",
993 "second_microsecond",
994 "sensitive",
995 "separator",
996 "show",
997 "signal",
998 "smallint",
999 "spatial",
1000 "specific",
1001 "sql",
1002 "sql_big_result",
1003 "sql_calc_found_rows",
1004 "sql_small_result",
1005 "sqlexception",
1006 "sqlstate",
1007 "sqlwarning",
1008 "ssl",
1009 "starting",
1010 "straight_join",
1011 "terminated",
1012 "text",
1013 "tinyblob",
1014 "tinyint",
1015 "tinytext",
1016 "trigger",
1017 "undo",
1018 "unlock",
1019 "unsigned",
1020 "usage",
1021 "utc_date",
1022 "utc_time",
1023 "utc_timestamp",
1024 "varbinary",
1025 "varchar",
1026 "varcharacter",
1027 "varying",
1028 "while",
1029 "write",
1030 "xor",
1031 "year_month",
1032 "zerofill",
1033 ]);
1034 set.remove("table");
1035 set
1036 });
1037
1038 pub static DORIS_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1041 let mut set = MYSQL_RESERVED.clone();
1042 set.extend([
1043 "aggregate",
1044 "anti",
1045 "array",
1046 "backend",
1047 "backup",
1048 "begin",
1049 "bitmap",
1050 "boolean",
1051 "broker",
1052 "buckets",
1053 "cached",
1054 "cancel",
1055 "cast",
1056 "catalog",
1057 "charset",
1058 "cluster",
1059 "collation",
1060 "columns",
1061 "comment",
1062 "commit",
1063 "config",
1064 "connection",
1065 "count",
1066 "current",
1067 "data",
1068 "date",
1069 "datetime",
1070 "day",
1071 "deferred",
1072 "distributed",
1073 "dynamic",
1074 "enable",
1075 "end",
1076 "events",
1077 "export",
1078 "external",
1079 "fields",
1080 "first",
1081 "follower",
1082 "format",
1083 "free",
1084 "frontend",
1085 "full",
1086 "functions",
1087 "global",
1088 "grants",
1089 "hash",
1090 "help",
1091 "hour",
1092 "install",
1093 "intermediate",
1094 "json",
1095 "label",
1096 "last",
1097 "less",
1098 "level",
1099 "link",
1100 "local",
1101 "location",
1102 "max",
1103 "merge",
1104 "min",
1105 "minute",
1106 "modify",
1107 "month",
1108 "name",
1109 "names",
1110 "negative",
1111 "nulls",
1112 "observer",
1113 "offset",
1114 "only",
1115 "open",
1116 "overwrite",
1117 "password",
1118 "path",
1119 "plan",
1120 "plugin",
1121 "plugins",
1122 "policy",
1123 "process",
1124 "properties",
1125 "property",
1126 "query",
1127 "quota",
1128 "recover",
1129 "refresh",
1130 "repair",
1131 "replica",
1132 "repository",
1133 "resource",
1134 "restore",
1135 "resume",
1136 "role",
1137 "roles",
1138 "rollback",
1139 "rollup",
1140 "routine",
1141 "sample",
1142 "second",
1143 "semi",
1144 "session",
1145 "signed",
1146 "snapshot",
1147 "start",
1148 "stats",
1149 "status",
1150 "stop",
1151 "stream",
1152 "string",
1153 "sum",
1154 "tables",
1155 "tablet",
1156 "temporary",
1157 "text",
1158 "timestamp",
1159 "transaction",
1160 "trash",
1161 "trim",
1162 "truncate",
1163 "type",
1164 "user",
1165 "value",
1166 "variables",
1167 "verbose",
1168 "version",
1169 "view",
1170 "warnings",
1171 "week",
1172 "work",
1173 "year",
1174 ]);
1175 set
1176 });
1177
1178 pub static POSTGRES_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1180 let mut set = SQL_RESERVED.clone();
1181 set.extend([
1182 "analyse",
1183 "analyze",
1184 "asymmetric",
1185 "binary",
1186 "collation",
1187 "concurrently",
1188 "current_catalog",
1189 "current_role",
1190 "current_schema",
1191 "deferrable",
1192 "do",
1193 "freeze",
1194 "ilike",
1195 "initially",
1196 "isnull",
1197 "lateral",
1198 "notnull",
1199 "placing",
1200 "returning",
1201 "similar",
1202 "symmetric",
1203 "variadic",
1204 "verbose",
1205 ]);
1206 set.remove("default");
1208 set.remove("interval");
1209 set.remove("match");
1210 set.remove("offset");
1211 set.remove("table");
1212 set
1213 });
1214
1215 pub static REDSHIFT_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1219 [
1220 "aes128",
1221 "aes256",
1222 "all",
1223 "allowoverwrite",
1224 "analyse",
1225 "analyze",
1226 "and",
1227 "any",
1228 "array",
1229 "as",
1230 "asc",
1231 "authorization",
1232 "az64",
1233 "backup",
1234 "between",
1235 "binary",
1236 "blanksasnull",
1237 "both",
1238 "bytedict",
1239 "bzip2",
1240 "case",
1241 "cast",
1242 "check",
1243 "collate",
1244 "column",
1245 "constraint",
1246 "create",
1247 "credentials",
1248 "cross",
1249 "current_date",
1250 "current_time",
1251 "current_timestamp",
1252 "current_user",
1253 "current_user_id",
1254 "default",
1255 "deferrable",
1256 "deflate",
1257 "defrag",
1258 "delta",
1259 "delta32k",
1260 "desc",
1261 "disable",
1262 "distinct",
1263 "do",
1264 "else",
1265 "emptyasnull",
1266 "enable",
1267 "encode",
1268 "encrypt",
1269 "encryption",
1270 "end",
1271 "except",
1272 "explicit",
1273 "false",
1274 "for",
1275 "foreign",
1276 "freeze",
1277 "from",
1278 "full",
1279 "globaldict256",
1280 "globaldict64k",
1281 "grant",
1282 "group",
1283 "gzip",
1284 "having",
1285 "identity",
1286 "ignore",
1287 "ilike",
1288 "in",
1289 "initially",
1290 "inner",
1291 "intersect",
1292 "interval",
1293 "into",
1294 "is",
1295 "isnull",
1296 "join",
1297 "leading",
1298 "left",
1299 "like",
1300 "limit",
1301 "localtime",
1302 "localtimestamp",
1303 "lun",
1304 "luns",
1305 "lzo",
1306 "lzop",
1307 "minus",
1308 "mostly16",
1309 "mostly32",
1310 "mostly8",
1311 "natural",
1312 "new",
1313 "not",
1314 "notnull",
1315 "null",
1316 "nulls",
1317 "off",
1318 "offline",
1319 "offset",
1320 "oid",
1321 "old",
1322 "on",
1323 "only",
1324 "open",
1325 "or",
1326 "order",
1327 "outer",
1328 "overlaps",
1329 "parallel",
1330 "partition",
1331 "percent",
1332 "permissions",
1333 "pivot",
1334 "placing",
1335 "primary",
1336 "raw",
1337 "readratio",
1338 "recover",
1339 "references",
1340 "rejectlog",
1341 "resort",
1342 "respect",
1343 "restore",
1344 "right",
1345 "select",
1346 "session_user",
1347 "similar",
1348 "snapshot",
1349 "some",
1350 "sysdate",
1351 "system",
1352 "table",
1353 "tag",
1354 "tdes",
1355 "text255",
1356 "text32k",
1357 "then",
1358 "timestamp",
1359 "to",
1360 "top",
1361 "trailing",
1362 "true",
1363 "truncatecolumns",
1364 "type",
1365 "union",
1366 "unique",
1367 "unnest",
1368 "unpivot",
1369 "user",
1370 "using",
1371 "verbose",
1372 "wallet",
1373 "when",
1374 "where",
1375 "with",
1376 "without",
1377 ]
1378 .into_iter()
1379 .collect()
1380 });
1381
1382 pub static DUCKDB_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1384 let mut set = POSTGRES_RESERVED.clone();
1385 set.extend([
1386 "anti",
1387 "asof",
1388 "columns",
1389 "describe",
1390 "groups",
1391 "macro",
1392 "pivot",
1393 "pivot_longer",
1394 "pivot_wider",
1395 "qualify",
1396 "replace",
1397 "respect",
1398 "semi",
1399 "show",
1400 "table",
1401 "unpivot",
1402 ]);
1403 set.remove("at");
1404 set.remove("key");
1405 set.remove("range");
1406 set.remove("row");
1407 set.remove("values");
1408 set
1409 });
1410
1411 pub static PRESTO_TRINO_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1413 let mut set = SQL_RESERVED.clone();
1414 set.extend([
1415 "alter",
1416 "and",
1417 "as",
1418 "between",
1419 "by",
1420 "case",
1421 "cast",
1422 "constraint",
1423 "create",
1424 "cross",
1425 "cube",
1426 "current_catalog",
1427 "current_date",
1428 "current_path",
1429 "current_role",
1430 "current_schema",
1431 "current_time",
1432 "current_timestamp",
1433 "current_user",
1434 "deallocate",
1435 "delete",
1436 "describe",
1437 "distinct",
1438 "drop",
1439 "else",
1440 "end",
1441 "escape",
1442 "except",
1443 "execute",
1444 "exists",
1445 "extract",
1446 "false",
1447 "for",
1448 "from",
1449 "full",
1450 "group",
1451 "grouping",
1452 "having",
1453 "in",
1454 "inner",
1455 "insert",
1456 "intersect",
1457 "into",
1458 "is",
1459 "join",
1460 "json_array",
1461 "json_exists",
1462 "json_object",
1463 "json_query",
1464 "json_table",
1465 "json_value",
1466 "left",
1467 "like",
1468 "listagg",
1469 "localtime",
1470 "localtimestamp",
1471 "natural",
1472 "normalize",
1473 "not",
1474 "null",
1475 "on",
1476 "or",
1477 "order",
1478 "outer",
1479 "prepare",
1480 "recursive",
1481 "right",
1482 "rollup",
1483 "select",
1484 "skip",
1485 "table",
1486 "then",
1487 "trim",
1488 "true",
1489 "uescape",
1490 "union",
1491 "unnest",
1492 "using",
1493 "values",
1494 "when",
1495 "where",
1496 "with",
1497 ]);
1498 set.remove("key");
1500 set
1501 });
1502
1503 pub static STARROCKS_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1506 [
1507 "add",
1508 "all",
1509 "alter",
1510 "analyze",
1511 "and",
1512 "array",
1513 "as",
1514 "asc",
1515 "between",
1516 "bigint",
1517 "bitmap",
1518 "both",
1519 "by",
1520 "case",
1521 "char",
1522 "character",
1523 "check",
1524 "collate",
1525 "column",
1526 "compaction",
1527 "convert",
1528 "create",
1529 "cross",
1530 "cube",
1531 "current_date",
1532 "current_role",
1533 "current_time",
1534 "current_timestamp",
1535 "current_user",
1536 "database",
1537 "databases",
1538 "decimal",
1539 "decimalv2",
1540 "decimal32",
1541 "decimal64",
1542 "decimal128",
1543 "default",
1544 "deferred",
1545 "delete",
1546 "dense_rank",
1547 "desc",
1548 "describe",
1549 "distinct",
1550 "double",
1551 "drop",
1552 "dual",
1553 "else",
1554 "except",
1555 "exists",
1556 "explain",
1557 "false",
1558 "first_value",
1559 "float",
1560 "for",
1561 "force",
1562 "from",
1563 "full",
1564 "function",
1565 "grant",
1566 "group",
1567 "grouping",
1568 "grouping_id",
1569 "groups",
1570 "having",
1571 "hll",
1572 "host",
1573 "if",
1574 "ignore",
1575 "immediate",
1576 "in",
1577 "index",
1578 "infile",
1579 "inner",
1580 "insert",
1581 "int",
1582 "integer",
1583 "intersect",
1584 "into",
1585 "is",
1586 "join",
1587 "json",
1588 "key",
1589 "keys",
1590 "kill",
1591 "lag",
1592 "largeint",
1593 "last_value",
1594 "lateral",
1595 "lead",
1596 "left",
1597 "like",
1598 "limit",
1599 "load",
1600 "localtime",
1601 "localtimestamp",
1602 "maxvalue",
1603 "minus",
1604 "mod",
1605 "not",
1606 "ntile",
1607 "null",
1608 "on",
1609 "or",
1610 "order",
1611 "outer",
1612 "outfile",
1613 "over",
1614 "partition",
1615 "percentile",
1616 "primary",
1617 "procedure",
1618 "qualify",
1619 "range",
1620 "rank",
1621 "read",
1622 "regexp",
1623 "release",
1624 "rename",
1625 "replace",
1626 "revoke",
1627 "right",
1628 "rlike",
1629 "row",
1630 "row_number",
1631 "rows",
1632 "schema",
1633 "schemas",
1634 "select",
1635 "set",
1636 "set_var",
1637 "show",
1638 "smallint",
1639 "system",
1640 "table",
1641 "terminated",
1642 "text",
1643 "then",
1644 "tinyint",
1645 "to",
1646 "true",
1647 "union",
1648 "unique",
1649 "unsigned",
1650 "update",
1651 "use",
1652 "using",
1653 "values",
1654 "varchar",
1655 "when",
1656 "where",
1657 "with",
1658 ]
1659 .into_iter()
1660 .collect()
1661 });
1662
1663 pub static SINGLESTORE_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1666 let mut set = MYSQL_RESERVED.clone();
1667 set.extend([
1668 "abs",
1671 "account",
1672 "acos",
1673 "adddate",
1674 "addtime",
1675 "admin",
1676 "aes_decrypt",
1677 "aes_encrypt",
1678 "aggregate",
1679 "aggregates",
1680 "aggregator",
1681 "anti_join",
1682 "any_value",
1683 "approx_count_distinct",
1684 "approx_percentile",
1685 "arrange",
1686 "arrangement",
1687 "asin",
1688 "atan",
1689 "atan2",
1690 "attach",
1691 "autostats",
1692 "avro",
1693 "background",
1694 "backup",
1695 "batch",
1696 "batches",
1697 "boot_strapping",
1698 "ceil",
1699 "ceiling",
1700 "coercibility",
1701 "columnar",
1702 "columnstore",
1703 "compile",
1704 "concurrent",
1705 "connection_id",
1706 "cos",
1707 "cot",
1708 "current_security_groups",
1709 "current_security_roles",
1710 "dayname",
1711 "dayofmonth",
1712 "dayofweek",
1713 "dayofyear",
1714 "degrees",
1715 "dot_product",
1716 "dump",
1717 "durability",
1718 "earliest",
1719 "echo",
1720 "election",
1721 "euclidean_distance",
1722 "exp",
1723 "extractor",
1724 "extractors",
1725 "floor",
1726 "foreground",
1727 "found_rows",
1728 "from_base64",
1729 "from_days",
1730 "from_unixtime",
1731 "fs",
1732 "fulltext",
1733 "gc",
1734 "gcs",
1735 "geography",
1736 "geography_area",
1737 "geography_contains",
1738 "geography_distance",
1739 "geography_intersects",
1740 "geography_latitude",
1741 "geography_length",
1742 "geography_longitude",
1743 "geographypoint",
1744 "geography_point",
1745 "geography_within_distance",
1746 "geometry",
1747 "geometry_area",
1748 "geometry_contains",
1749 "geometry_distance",
1750 "geometry_filter",
1751 "geometry_intersects",
1752 "geometry_length",
1753 "geometrypoint",
1754 "geometry_point",
1755 "geometry_within_distance",
1756 "geometry_x",
1757 "geometry_y",
1758 "greatest",
1759 "groups",
1760 "group_concat",
1761 "gzip",
1762 "hdfs",
1763 "hex",
1764 "highlight",
1765 "ifnull",
1766 "ilike",
1767 "inet_aton",
1768 "inet_ntoa",
1769 "inet6_aton",
1770 "inet6_ntoa",
1771 "initcap",
1772 "instr",
1773 "interpreter_mode",
1774 "isnull",
1775 "json",
1776 "json_agg",
1777 "json_array_contains_double",
1778 "json_array_contains_json",
1779 "json_array_contains_string",
1780 "json_delete_key",
1781 "json_extract_double",
1782 "json_extract_json",
1783 "json_extract_string",
1784 "json_extract_bigint",
1785 "json_get_type",
1786 "json_length",
1787 "json_set_double",
1788 "json_set_json",
1789 "json_set_string",
1790 "kafka",
1791 "lag",
1792 "last_day",
1793 "last_insert_id",
1794 "latest",
1795 "lcase",
1796 "lead",
1797 "leaf",
1798 "least",
1799 "leaves",
1800 "length",
1801 "license",
1802 "links",
1803 "llvm",
1804 "ln",
1805 "load",
1806 "locate",
1807 "log",
1808 "log10",
1809 "log2",
1810 "lpad",
1811 "lz4",
1812 "management",
1813 "match",
1814 "mbc",
1815 "md5",
1816 "median",
1817 "memsql",
1818 "memsql_deserialize",
1819 "memsql_serialize",
1820 "metadata",
1821 "microsecond",
1822 "minute",
1823 "model",
1824 "monthname",
1825 "months_between",
1826 "mpl",
1827 "namespace",
1828 "node",
1829 "noparam",
1830 "now",
1831 "nth_value",
1832 "ntile",
1833 "nullcols",
1834 "nullif",
1835 "object",
1836 "octet_length",
1837 "offsets",
1838 "online",
1839 "optimizer",
1840 "orphan",
1841 "parquet",
1842 "partitions",
1843 "pause",
1844 "percentile_cont",
1845 "percentile_disc",
1846 "periodic",
1847 "persisted",
1848 "pi",
1849 "pipeline",
1850 "pipelines",
1851 "plancache",
1852 "plugins",
1853 "pool",
1854 "pools",
1855 "pow",
1856 "power",
1857 "process",
1858 "processlist",
1859 "profile",
1860 "profiles",
1861 "quarter",
1862 "queries",
1863 "query",
1864 "radians",
1865 "rand",
1866 "record",
1867 "reduce",
1868 "redundancy",
1869 "regexp_match",
1870 "regexp_substr",
1871 "remote",
1872 "replication",
1873 "resource",
1874 "resource_pool",
1875 "restore",
1876 "retry",
1877 "role",
1878 "roles",
1879 "round",
1880 "rpad",
1881 "rtrim",
1882 "running",
1883 "s3",
1884 "scalar",
1885 "sec_to_time",
1886 "second",
1887 "security_lists_intersect",
1888 "semi_join",
1889 "sha",
1890 "sha1",
1891 "sha2",
1892 "shard",
1893 "sharded",
1894 "sharded_id",
1895 "sigmoid",
1896 "sign",
1897 "sin",
1898 "skip",
1899 "sleep",
1900 "snapshot",
1901 "soname",
1902 "sparse",
1903 "spatial_check_index",
1904 "split",
1905 "sqrt",
1906 "standalone",
1907 "std",
1908 "stddev",
1909 "stddev_pop",
1910 "stddev_samp",
1911 "stop",
1912 "str_to_date",
1913 "subdate",
1914 "substr",
1915 "substring_index",
1916 "success",
1917 "synchronize",
1918 "table_checksum",
1919 "tan",
1920 "task",
1921 "timediff",
1922 "time_bucket",
1923 "time_format",
1924 "time_to_sec",
1925 "timestampadd",
1926 "timestampdiff",
1927 "to_base64",
1928 "to_char",
1929 "to_date",
1930 "to_days",
1931 "to_json",
1932 "to_number",
1933 "to_seconds",
1934 "to_timestamp",
1935 "tracelogs",
1936 "transform",
1937 "trim",
1938 "trunc",
1939 "truncate",
1940 "ucase",
1941 "unhex",
1942 "unix_timestamp",
1943 "utc_date",
1944 "utc_time",
1945 "utc_timestamp",
1946 "vacuum",
1947 "variance",
1948 "var_pop",
1949 "var_samp",
1950 "vector_sub",
1951 "voting",
1952 "week",
1953 "weekday",
1954 "weekofyear",
1955 "workload",
1956 "year",
1957 ]);
1958 set.remove("all");
1960 set
1961 });
1962
1963 pub static SQLITE_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1967 [
1969 "abort",
1970 "action",
1971 "add",
1972 "after",
1973 "all",
1974 "alter",
1975 "always",
1976 "analyze",
1977 "and",
1978 "as",
1979 "asc",
1980 "attach",
1981 "autoincrement",
1982 "before",
1983 "begin",
1984 "between",
1985 "by",
1986 "cascade",
1987 "case",
1988 "cast",
1989 "check",
1990 "collate",
1991 "column",
1992 "commit",
1993 "conflict",
1994 "constraint",
1995 "create",
1996 "cross",
1997 "current",
1998 "current_date",
1999 "current_time",
2000 "current_timestamp",
2001 "database",
2002 "default",
2003 "deferrable",
2004 "deferred",
2005 "delete",
2006 "desc",
2007 "detach",
2008 "distinct",
2009 "do",
2010 "drop",
2011 "each",
2012 "else",
2013 "end",
2014 "escape",
2015 "except",
2016 "exclude",
2017 "exclusive",
2018 "exists",
2019 "explain",
2020 "fail",
2021 "filter",
2022 "first",
2023 "following",
2024 "for",
2025 "foreign",
2026 "from",
2027 "full",
2028 "generated",
2029 "glob",
2030 "group",
2031 "groups",
2032 "having",
2033 "if",
2034 "ignore",
2035 "immediate",
2036 "in",
2037 "index",
2038 "indexed",
2039 "initially",
2040 "inner",
2041 "insert",
2042 "instead",
2043 "intersect",
2044 "into",
2045 "is",
2046 "isnull",
2047 "join",
2048 "key",
2049 "last",
2050 "left",
2051 "like",
2052 "limit",
2053 "natural",
2054 "no",
2055 "not",
2056 "nothing",
2057 "notnull",
2058 "null",
2059 "nulls",
2060 "of",
2061 "offset",
2062 "on",
2063 "or",
2064 "order",
2065 "others",
2066 "outer",
2067 "partition",
2068 "plan",
2069 "pragma",
2070 "preceding",
2071 "primary",
2072 "query",
2073 "raise",
2074 "range",
2075 "recursive",
2076 "references",
2077 "regexp",
2078 "reindex",
2079 "release",
2080 "rename",
2081 "replace",
2082 "restrict",
2083 "returning",
2084 "right",
2085 "rollback",
2086 "row",
2087 "rows",
2088 "savepoint",
2089 "select",
2090 "set",
2091 "table",
2092 "temp",
2093 "temporary",
2094 "then",
2095 "ties",
2096 "to",
2097 "transaction",
2098 "trigger",
2099 "unbounded",
2100 "union",
2101 "unique",
2102 "update",
2103 "using",
2104 "vacuum",
2105 "values",
2106 "view",
2107 "virtual",
2108 "when",
2109 "where",
2110 "window",
2111 "with",
2112 "without",
2113 ]
2114 .into_iter()
2115 .collect()
2116 });
2117}
2118
2119impl Generator {
2120 pub fn new() -> Self {
2126 Self::with_config(GeneratorConfig::default())
2127 }
2128
2129 pub fn with_config(config: GeneratorConfig) -> Self {
2134 Self::with_arc_config(Arc::new(config))
2135 }
2136
2137 pub(crate) fn with_arc_config(config: Arc<GeneratorConfig>) -> Self {
2142 Self {
2143 config,
2144 output: String::new(),
2145 unsupported_messages: Vec::new(),
2146 indent_level: 0,
2147 athena_hive_context: false,
2148 sqlite_inline_pk_columns: std::collections::HashSet::new(),
2149 merge_strip_qualifiers: Vec::new(),
2150 clickhouse_nullable_depth: 0,
2151 }
2152 }
2153
2154 fn add_column_aliases_to_query(expr: Expression) -> Expression {
2158 match expr {
2159 Expression::Select(mut select) => {
2160 select.expressions = select
2162 .expressions
2163 .into_iter()
2164 .map(|e| Self::add_alias_to_expression(e))
2165 .collect();
2166
2167 if let Some(ref mut from) = select.from {
2169 from.expressions = from
2170 .expressions
2171 .iter()
2172 .cloned()
2173 .map(|e| Self::add_column_aliases_to_query(e))
2174 .collect();
2175 }
2176
2177 Expression::Select(select)
2178 }
2179 Expression::Subquery(mut sq) => {
2180 sq.this = Self::add_column_aliases_to_query(sq.this);
2181 Expression::Subquery(sq)
2182 }
2183 Expression::Paren(mut p) => {
2184 p.this = Self::add_column_aliases_to_query(p.this);
2185 Expression::Paren(p)
2186 }
2187 other => other,
2189 }
2190 }
2191
2192 fn add_alias_to_expression(expr: Expression) -> Expression {
2195 use crate::expressions::Alias;
2196
2197 match &expr {
2198 Expression::Alias(_) => expr,
2200
2201 Expression::Column(col) => Expression::Alias(Box::new(Alias {
2203 this: expr.clone(),
2204 alias: col.name.clone(),
2205 column_aliases: Vec::new(),
2206 alias_explicit_as: false,
2207 alias_keyword: None,
2208 pre_alias_comments: Vec::new(),
2209 trailing_comments: Vec::new(),
2210 inferred_type: None,
2211 })),
2212
2213 Expression::Identifier(ident) => Expression::Alias(Box::new(Alias {
2215 this: expr.clone(),
2216 alias: ident.clone(),
2217 column_aliases: Vec::new(),
2218 alias_explicit_as: false,
2219 alias_keyword: None,
2220 pre_alias_comments: Vec::new(),
2221 trailing_comments: Vec::new(),
2222 inferred_type: None,
2223 })),
2224
2225 Expression::Subquery(sq) => {
2227 let processed = Self::add_column_aliases_to_query(Expression::Subquery(sq.clone()));
2228 if sq.alias.is_some() {
2230 processed
2231 } else {
2232 processed
2234 }
2235 }
2236
2237 Expression::Star(_) => expr,
2239
2240 _ => expr,
2243 }
2244 }
2245
2246 fn try_evaluate_constant(expr: &Expression) -> Option<i64> {
2250 match expr {
2251 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
2252 let Literal::Number(n) = lit.as_ref() else {
2253 unreachable!()
2254 };
2255 n.parse::<i64>().ok()
2256 }
2257 Expression::Add(op) => {
2258 let left = Self::try_evaluate_constant(&op.left)?;
2259 let right = Self::try_evaluate_constant(&op.right)?;
2260 Some(left + right)
2261 }
2262 Expression::Sub(op) => {
2263 let left = Self::try_evaluate_constant(&op.left)?;
2264 let right = Self::try_evaluate_constant(&op.right)?;
2265 Some(left - right)
2266 }
2267 Expression::Mul(op) => {
2268 let left = Self::try_evaluate_constant(&op.left)?;
2269 let right = Self::try_evaluate_constant(&op.right)?;
2270 Some(left * right)
2271 }
2272 Expression::Div(op) => {
2273 let left = Self::try_evaluate_constant(&op.left)?;
2274 let right = Self::try_evaluate_constant(&op.right)?;
2275 if right != 0 {
2276 Some(left / right)
2277 } else {
2278 None
2279 }
2280 }
2281 Expression::Paren(p) => Self::try_evaluate_constant(&p.this),
2282 _ => None,
2283 }
2284 }
2285
2286 fn is_reserved_keyword(&self, name: &str) -> bool {
2288 use crate::dialects::DialectType;
2289 let mut buf = [0u8; 128];
2290 let lower_ref: &str = if name.len() <= 128 {
2291 for (i, b) in name.bytes().enumerate() {
2292 buf[i] = b.to_ascii_lowercase();
2293 }
2294 std::str::from_utf8(&buf[..name.len()]).unwrap_or(name)
2296 } else {
2297 return false;
2298 };
2299
2300 match self.config.dialect {
2301 Some(DialectType::BigQuery) => reserved_keywords::BIGQUERY_RESERVED.contains(lower_ref),
2302 Some(DialectType::MySQL) | Some(DialectType::TiDB) => {
2303 reserved_keywords::MYSQL_RESERVED.contains(lower_ref)
2304 }
2305 Some(DialectType::Doris) => reserved_keywords::DORIS_RESERVED.contains(lower_ref),
2306 Some(DialectType::SingleStore) => {
2307 reserved_keywords::SINGLESTORE_RESERVED.contains(lower_ref)
2308 }
2309 Some(DialectType::StarRocks) => {
2310 reserved_keywords::STARROCKS_RESERVED.contains(lower_ref)
2311 }
2312 Some(DialectType::PostgreSQL)
2313 | Some(DialectType::CockroachDB)
2314 | Some(DialectType::Materialize)
2315 | Some(DialectType::RisingWave) => {
2316 reserved_keywords::POSTGRES_RESERVED.contains(lower_ref)
2317 }
2318 Some(DialectType::Redshift) => reserved_keywords::REDSHIFT_RESERVED.contains(lower_ref),
2319 Some(DialectType::Snowflake) => false,
2322 Some(DialectType::ClickHouse) => false,
2324 Some(DialectType::DuckDB) => reserved_keywords::DUCKDB_RESERVED.contains(lower_ref),
2325 Some(DialectType::Teradata) => false,
2327 Some(DialectType::TSQL)
2329 | Some(DialectType::Fabric)
2330 | Some(DialectType::Oracle)
2331 | Some(DialectType::Spark)
2332 | Some(DialectType::Databricks)
2333 | Some(DialectType::Hive)
2334 | Some(DialectType::Solr) => false,
2335 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
2336 reserved_keywords::PRESTO_TRINO_RESERVED.contains(lower_ref)
2337 }
2338 Some(DialectType::SQLite) => reserved_keywords::SQLITE_RESERVED.contains(lower_ref),
2339 Some(DialectType::Generic) | None => false,
2341 _ => reserved_keywords::SQL_RESERVED.contains(lower_ref),
2343 }
2344 }
2345
2346 fn normalize_func_name<'a>(&self, name: &'a str) -> Cow<'a, str> {
2348 match self.config.normalize_functions {
2349 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
2350 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
2351 NormalizeFunctions::None => Cow::Borrowed(name),
2352 }
2353 }
2354
2355 pub fn generate(&mut self, expr: &Expression) -> Result<String> {
2364 self.output.clear();
2365 self.unsupported_messages.clear();
2366 self.generate_expression(expr)?;
2367 if self.config.unsupported_level == UnsupportedLevel::Raise
2368 && !self.unsupported_messages.is_empty()
2369 {
2370 return Err(crate::error::Error::generate(
2371 self.format_unsupported_messages(),
2372 ));
2373 }
2374 Ok(std::mem::take(&mut self.output))
2375 }
2376
2377 pub fn unsupported_messages(&self) -> &[String] {
2379 &self.unsupported_messages
2380 }
2381
2382 fn unsupported(&mut self, message: impl Into<String>) -> Result<()> {
2383 let message = message.into();
2384 if self.config.unsupported_level == UnsupportedLevel::Immediate {
2385 return Err(crate::error::Error::generate(message));
2386 }
2387 self.unsupported_messages.push(message);
2388 Ok(())
2389 }
2390
2391 fn write_unsupported_comment(&mut self, message: &str) -> Result<()> {
2392 self.unsupported(message.to_string())?;
2393 self.write("/* ");
2394 self.write(message);
2395 self.write(" */");
2396 Ok(())
2397 }
2398
2399 fn format_unsupported_messages(&self) -> String {
2400 let limit = self.config.max_unsupported.max(1);
2401 if self.unsupported_messages.len() <= limit {
2402 return self.unsupported_messages.join("; ");
2403 }
2404
2405 let mut messages = self
2406 .unsupported_messages
2407 .iter()
2408 .take(limit)
2409 .cloned()
2410 .collect::<Vec<_>>();
2411 messages.push(format!(
2412 "... and {} more",
2413 self.unsupported_messages.len() - limit
2414 ));
2415 messages.join("; ")
2416 }
2417
2418 pub fn sql(expr: &Expression) -> Result<String> {
2424 let mut gen = Generator::new();
2425 gen.generate(expr)
2426 }
2427
2428 pub fn pretty_sql(expr: &Expression) -> Result<String> {
2433 let config = GeneratorConfig {
2434 pretty: true,
2435 ..Default::default()
2436 };
2437 let mut gen = Generator::with_config(config);
2438 let mut sql = gen.generate(expr)?;
2439 if !sql.ends_with(';') {
2441 sql.push(';');
2442 }
2443 Ok(sql)
2444 }
2445
2446 fn generate_expression(&mut self, expr: &Expression) -> Result<()> {
2447 #[cfg(feature = "stacker")]
2448 {
2449 let red_zone = if cfg!(debug_assertions) {
2450 4 * 1024 * 1024
2451 } else {
2452 1024 * 1024
2453 };
2454 stacker::maybe_grow(red_zone, 8 * 1024 * 1024, || {
2455 self.generate_expression_inner(expr)
2456 })
2457 }
2458 #[cfg(not(feature = "stacker"))]
2459 {
2460 self.generate_expression_inner(expr)
2461 }
2462 }
2463
2464 fn generate_expression_inner(&mut self, expr: &Expression) -> Result<()> {
2465 match expr {
2466 Expression::Select(select) => self.generate_select(select),
2467 Expression::Union(union) => self.generate_union(union),
2468 Expression::Intersect(intersect) => self.generate_intersect(intersect),
2469 Expression::Except(except) => self.generate_except(except),
2470 Expression::Insert(insert) => self.generate_insert(insert),
2471 Expression::Update(update) => self.generate_update(update),
2472 Expression::Delete(delete) => self.generate_delete(delete),
2473 Expression::Literal(lit) => self.generate_literal(lit),
2474 Expression::Boolean(b) => self.generate_boolean(b),
2475 Expression::Null(_) => {
2476 self.write_keyword("NULL");
2477 Ok(())
2478 }
2479 Expression::Identifier(id) => self.generate_identifier(id),
2480 Expression::Column(col) => self.generate_column(col),
2481 Expression::Pseudocolumn(pc) => self.generate_pseudocolumn(pc),
2482 Expression::Connect(c) => self.generate_connect_expr(c),
2483 Expression::Prior(p) => self.generate_prior(p),
2484 Expression::ConnectByRoot(cbr) => self.generate_connect_by_root(cbr),
2485 Expression::MatchRecognize(mr) => self.generate_match_recognize(mr),
2486 Expression::Table(table) => self.generate_table(table),
2487 Expression::StageReference(sr) => self.generate_stage_reference(sr),
2488 Expression::HistoricalData(hd) => self.generate_historical_data(hd),
2489 Expression::JoinedTable(jt) => self.generate_joined_table(jt),
2490 Expression::Star(star) => self.generate_star(star),
2491 Expression::BracedWildcard(expr) => self.generate_braced_wildcard(expr),
2492 Expression::Alias(alias) => self.generate_alias(alias),
2493 Expression::Cast(cast) => self.generate_cast(cast),
2494 Expression::Collation(coll) => self.generate_collation(coll),
2495 Expression::Case(case) => self.generate_case(case),
2496 Expression::Function(func) => self.generate_function(func),
2497 Expression::FunctionEmits(fe) => self.generate_function_emits(fe),
2498 Expression::AggregateFunction(func) => self.generate_aggregate_function(func),
2499 Expression::WindowFunction(wf) => self.generate_window_function(wf),
2500 Expression::WithinGroup(wg) => self.generate_within_group(wg),
2501 Expression::Interval(interval) => self.generate_interval(interval),
2502
2503 Expression::ConcatWs(f) => self.generate_concat_ws(f),
2505 Expression::Substring(f) => self.generate_substring(f),
2506 Expression::Upper(f) => self.generate_unary_func("UPPER", f),
2507 Expression::Lower(f) => self.generate_unary_func("LOWER", f),
2508 Expression::Length(f) => self.generate_unary_func("LENGTH", f),
2509 Expression::Trim(f) => self.generate_trim(f),
2510 Expression::LTrim(f) => self.generate_simple_func("LTRIM", &f.this),
2511 Expression::RTrim(f) => self.generate_simple_func("RTRIM", &f.this),
2512 Expression::Replace(f) => self.generate_replace(f),
2513 Expression::Reverse(f) => self.generate_simple_func("REVERSE", &f.this),
2514 Expression::Left(f) => self.generate_left_right("LEFT", f),
2515 Expression::Right(f) => self.generate_left_right("RIGHT", f),
2516 Expression::Repeat(f) => self.generate_repeat(f),
2517 Expression::Lpad(f) => self.generate_pad("LPAD", f),
2518 Expression::Rpad(f) => self.generate_pad("RPAD", f),
2519 Expression::Split(f) => self.generate_split(f),
2520 Expression::RegexpLike(f) => self.generate_regexp_like(f),
2521 Expression::RegexpReplace(f) => self.generate_regexp_replace(f),
2522 Expression::RegexpExtract(f) => self.generate_regexp_extract(f),
2523 Expression::Overlay(f) => self.generate_overlay(f),
2524
2525 Expression::Abs(f) => self.generate_simple_func("ABS", &f.this),
2527 Expression::Round(f) => self.generate_round(f),
2528 Expression::Floor(f) => self.generate_floor(f),
2529 Expression::Ceil(f) => self.generate_ceil(f),
2530 Expression::Power(f) => self.generate_power(f),
2531 Expression::Sqrt(f) => self.generate_sqrt_cbrt(f, "SQRT", "|/"),
2532 Expression::Cbrt(f) => self.generate_sqrt_cbrt(f, "CBRT", "||/"),
2533 Expression::Ln(f) => self.generate_simple_func("LN", &f.this),
2534 Expression::Log(f) => self.generate_log(f),
2535 Expression::Exp(f) => self.generate_simple_func("EXP", &f.this),
2536 Expression::Sign(f) => self.generate_simple_func("SIGN", &f.this),
2537 Expression::Greatest(f) => self.generate_vararg_func("GREATEST", &f.expressions),
2538 Expression::Least(f) => self.generate_vararg_func("LEAST", &f.expressions),
2539
2540 Expression::CurrentDate(_) => {
2542 self.write_keyword("CURRENT_DATE");
2543 Ok(())
2544 }
2545 Expression::CurrentTime(f) => self.generate_current_time(f),
2546 Expression::CurrentTimestamp(f) => self.generate_current_timestamp(f),
2547 Expression::AtTimeZone(f) => self.generate_at_time_zone(f),
2548 Expression::DateAdd(f) => self.generate_date_add(f, "DATE_ADD"),
2549 Expression::DateSub(f) => self.generate_date_add(f, "DATE_SUB"),
2550 Expression::DateDiff(f) => self.generate_datediff(f),
2551 Expression::DateTrunc(f) => self.generate_date_trunc(f),
2552 Expression::Extract(f) => self.generate_extract(f),
2553 Expression::ToDate(f) => self.generate_to_date(f),
2554 Expression::ToTimestamp(f) => self.generate_to_timestamp(f),
2555
2556 Expression::Coalesce(f) => {
2558 let func_name = f.original_name.as_deref().unwrap_or("COALESCE");
2560 self.generate_vararg_func(func_name, &f.expressions)
2561 }
2562 Expression::NullIf(f) => self.generate_binary_func("NULLIF", &f.this, &f.expression),
2563 Expression::IfFunc(f) => self.generate_if_func(f),
2564 Expression::IfNull(f) => self.generate_ifnull(f),
2565 Expression::Nvl(f) => self.generate_nvl(f),
2566 Expression::Nvl2(f) => self.generate_nvl2(f),
2567
2568 Expression::TryCast(cast) => self.generate_try_cast(cast),
2570 Expression::SafeCast(cast) => self.generate_safe_cast(cast),
2571
2572 Expression::Count(f) => self.generate_count(f),
2574 Expression::Sum(f) => self.generate_agg_func("SUM", f),
2575 Expression::Avg(f) => self.generate_agg_func("AVG", f),
2576 Expression::Min(f) => self.generate_agg_func("MIN", f),
2577 Expression::Max(f) => self.generate_agg_func("MAX", f),
2578 Expression::GroupConcat(f) => self.generate_group_concat(f),
2579 Expression::StringAgg(f) => self.generate_string_agg(f),
2580 Expression::ListAgg(f) => self.generate_listagg(f),
2581 Expression::ArrayAgg(f) => {
2582 let override_name = f
2585 .name
2586 .as_ref()
2587 .filter(|n| !n.eq_ignore_ascii_case("ARRAY_AGG"))
2588 .map(|n| n.to_ascii_uppercase());
2589 match override_name {
2590 Some(name) => self.generate_agg_func(&name, f),
2591 None => self.generate_agg_func("ARRAY_AGG", f),
2592 }
2593 }
2594 Expression::ArrayConcatAgg(f) => self.generate_agg_func("ARRAY_CONCAT_AGG", f),
2595 Expression::CountIf(f) => self.generate_agg_func("COUNT_IF", f),
2596 Expression::SumIf(f) => self.generate_sum_if(f),
2597 Expression::Stddev(f) => self.generate_agg_func("STDDEV", f),
2598 Expression::StddevPop(f) => self.generate_agg_func("STDDEV_POP", f),
2599 Expression::StddevSamp(f) => self.generate_stddev_samp(f),
2600 Expression::Variance(f) => self.generate_agg_func("VARIANCE", f),
2601 Expression::VarPop(f) => {
2602 let name = if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
2603 "VARIANCE_POP"
2604 } else {
2605 "VAR_POP"
2606 };
2607 self.generate_agg_func(name, f)
2608 }
2609 Expression::VarSamp(f) => self.generate_agg_func("VAR_SAMP", f),
2610 Expression::Skewness(f) => {
2611 let name = match self.config.dialect {
2612 Some(DialectType::Snowflake) => "SKEW",
2613 _ => "SKEWNESS",
2614 };
2615 self.generate_agg_func(name, f)
2616 }
2617 Expression::Median(f) => self.generate_agg_func("MEDIAN", f),
2618 Expression::Mode(f) => self.generate_agg_func("MODE", f),
2619 Expression::First(f) => self.generate_agg_func_with_ignore_nulls_bool("FIRST", f),
2620 Expression::Last(f) => self.generate_agg_func_with_ignore_nulls_bool("LAST", f),
2621 Expression::AnyValue(f) => self.generate_agg_func("ANY_VALUE", f),
2622 Expression::ApproxDistinct(f) => {
2623 match self.config.dialect {
2624 Some(DialectType::Hive)
2625 | Some(DialectType::Spark)
2626 | Some(DialectType::Databricks)
2627 | Some(DialectType::BigQuery) => {
2628 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2630 }
2631 Some(DialectType::Redshift) => {
2632 self.write_keyword("APPROXIMATE COUNT");
2634 self.write("(");
2635 self.write_keyword("DISTINCT");
2636 self.write(" ");
2637 self.generate_expression(&f.this)?;
2638 self.write(")");
2639 Ok(())
2640 }
2641 _ => self.generate_agg_func("APPROX_DISTINCT", f),
2642 }
2643 }
2644 Expression::ApproxCountDistinct(f) => {
2645 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2646 }
2647 Expression::ApproxPercentile(f) => self.generate_approx_percentile(f),
2648 Expression::Percentile(f) => self.generate_percentile("PERCENTILE", f),
2649 Expression::LogicalAnd(f) => {
2650 let name = match self.config.dialect {
2651 Some(DialectType::Snowflake) => "BOOLAND_AGG",
2652 Some(DialectType::Spark)
2653 | Some(DialectType::Databricks)
2654 | Some(DialectType::PostgreSQL)
2655 | Some(DialectType::DuckDB)
2656 | Some(DialectType::Redshift) => "BOOL_AND",
2657 Some(DialectType::Oracle)
2658 | Some(DialectType::SQLite)
2659 | Some(DialectType::MySQL) => "MIN",
2660 _ => "BOOL_AND",
2661 };
2662 self.generate_agg_func(name, f)
2663 }
2664 Expression::LogicalOr(f) => {
2665 let name = match self.config.dialect {
2666 Some(DialectType::Snowflake) => "BOOLOR_AGG",
2667 Some(DialectType::Spark)
2668 | Some(DialectType::Databricks)
2669 | Some(DialectType::PostgreSQL)
2670 | Some(DialectType::DuckDB)
2671 | Some(DialectType::Redshift) => "BOOL_OR",
2672 Some(DialectType::Oracle)
2673 | Some(DialectType::SQLite)
2674 | Some(DialectType::MySQL) => "MAX",
2675 _ => "BOOL_OR",
2676 };
2677 self.generate_agg_func(name, f)
2678 }
2679
2680 Expression::RowNumber(_) => {
2682 if self.config.dialect == Some(DialectType::ClickHouse) {
2683 self.write("row_number");
2684 } else {
2685 self.write_keyword("ROW_NUMBER");
2686 }
2687 self.write("()");
2688 Ok(())
2689 }
2690 Expression::Rank(r) => {
2691 self.write_keyword("RANK");
2692 self.write("(");
2693 if !r.args.is_empty() {
2695 for (i, arg) in r.args.iter().enumerate() {
2696 if i > 0 {
2697 self.write(", ");
2698 }
2699 self.generate_expression(arg)?;
2700 }
2701 } else if let Some(order_by) = &r.order_by {
2702 self.write_keyword(" ORDER BY ");
2704 for (i, ob) in order_by.iter().enumerate() {
2705 if i > 0 {
2706 self.write(", ");
2707 }
2708 self.generate_ordered(ob)?;
2709 }
2710 }
2711 self.write(")");
2712 Ok(())
2713 }
2714 Expression::DenseRank(dr) => {
2715 self.write_keyword("DENSE_RANK");
2716 self.write("(");
2717 for (i, arg) in dr.args.iter().enumerate() {
2719 if i > 0 {
2720 self.write(", ");
2721 }
2722 self.generate_expression(arg)?;
2723 }
2724 self.write(")");
2725 Ok(())
2726 }
2727 Expression::NTile(f) => self.generate_ntile(f),
2728 Expression::Lead(f) => self.generate_lead_lag("LEAD", f),
2729 Expression::Lag(f) => self.generate_lead_lag("LAG", f),
2730 Expression::FirstValue(f) => {
2731 self.generate_value_func_with_ignore_nulls_bool("FIRST_VALUE", f)
2732 }
2733 Expression::LastValue(f) => {
2734 self.generate_value_func_with_ignore_nulls_bool("LAST_VALUE", f)
2735 }
2736 Expression::NthValue(f) => self.generate_nth_value(f),
2737 Expression::PercentRank(pr) => {
2738 self.write_keyword("PERCENT_RANK");
2739 self.write("(");
2740 if !pr.args.is_empty() {
2742 for (i, arg) in pr.args.iter().enumerate() {
2743 if i > 0 {
2744 self.write(", ");
2745 }
2746 self.generate_expression(arg)?;
2747 }
2748 } else if let Some(order_by) = &pr.order_by {
2749 self.write_keyword(" ORDER BY ");
2751 for (i, ob) in order_by.iter().enumerate() {
2752 if i > 0 {
2753 self.write(", ");
2754 }
2755 self.generate_ordered(ob)?;
2756 }
2757 }
2758 self.write(")");
2759 Ok(())
2760 }
2761 Expression::CumeDist(cd) => {
2762 self.write_keyword("CUME_DIST");
2763 self.write("(");
2764 if !cd.args.is_empty() {
2766 for (i, arg) in cd.args.iter().enumerate() {
2767 if i > 0 {
2768 self.write(", ");
2769 }
2770 self.generate_expression(arg)?;
2771 }
2772 } else if let Some(order_by) = &cd.order_by {
2773 self.write_keyword(" ORDER BY ");
2775 for (i, ob) in order_by.iter().enumerate() {
2776 if i > 0 {
2777 self.write(", ");
2778 }
2779 self.generate_ordered(ob)?;
2780 }
2781 }
2782 self.write(")");
2783 Ok(())
2784 }
2785 Expression::PercentileCont(f) => self.generate_percentile("PERCENTILE_CONT", f),
2786 Expression::PercentileDisc(f) => self.generate_percentile("PERCENTILE_DISC", f),
2787
2788 Expression::Contains(f) => {
2790 self.generate_binary_func("CONTAINS", &f.this, &f.expression)
2791 }
2792 Expression::StartsWith(f) => {
2793 let name = match self.config.dialect {
2794 Some(DialectType::Spark) | Some(DialectType::Databricks) => "STARTSWITH",
2795 _ => "STARTS_WITH",
2796 };
2797 self.generate_binary_func(name, &f.this, &f.expression)
2798 }
2799 Expression::EndsWith(f) => {
2800 let name = match self.config.dialect {
2801 Some(DialectType::Snowflake) => "ENDSWITH",
2802 Some(DialectType::Spark) | Some(DialectType::Databricks) => "ENDSWITH",
2803 Some(DialectType::ClickHouse) => "endsWith",
2804 _ => "ENDS_WITH",
2805 };
2806 self.generate_binary_func(name, &f.this, &f.expression)
2807 }
2808 Expression::Position(f) => self.generate_position(f),
2809 Expression::Initcap(f) => match self.config.dialect {
2810 Some(DialectType::Presto)
2811 | Some(DialectType::Trino)
2812 | Some(DialectType::Athena) => {
2813 self.write_keyword("REGEXP_REPLACE");
2814 self.write("(");
2815 self.generate_expression(&f.this)?;
2816 self.write(", '(\\w)(\\w*)', x -> UPPER(x[1]) || LOWER(x[2]))");
2817 Ok(())
2818 }
2819 _ => self.generate_simple_func("INITCAP", &f.this),
2820 },
2821 Expression::Ascii(f) => self.generate_simple_func("ASCII", &f.this),
2822 Expression::Chr(f) => self.generate_simple_func("CHR", &f.this),
2823 Expression::CharFunc(f) => self.generate_char_func(f),
2824 Expression::Soundex(f) => self.generate_simple_func("SOUNDEX", &f.this),
2825 Expression::Levenshtein(f) => {
2826 self.generate_binary_func("LEVENSHTEIN", &f.this, &f.expression)
2827 }
2828
2829 Expression::ModFunc(f) => self.generate_mod_func(f),
2831 Expression::Random(_) => {
2832 self.write_keyword("RANDOM");
2833 self.write("()");
2834 Ok(())
2835 }
2836 Expression::Rand(f) => self.generate_rand(f),
2837 Expression::TruncFunc(f) => self.generate_truncate_func(f),
2838 Expression::Pi(_) => {
2839 self.write_keyword("PI");
2840 self.write("()");
2841 Ok(())
2842 }
2843 Expression::Radians(f) => self.generate_simple_func("RADIANS", &f.this),
2844 Expression::Degrees(f) => self.generate_simple_func("DEGREES", &f.this),
2845 Expression::Sin(f) => self.generate_simple_func("SIN", &f.this),
2846 Expression::Cos(f) => self.generate_simple_func("COS", &f.this),
2847 Expression::Tan(f) => self.generate_simple_func("TAN", &f.this),
2848 Expression::Asin(f) => self.generate_simple_func("ASIN", &f.this),
2849 Expression::Acos(f) => self.generate_simple_func("ACOS", &f.this),
2850 Expression::Atan(f) => self.generate_simple_func("ATAN", &f.this),
2851 Expression::Atan2(f) => {
2852 let name = f.original_name.as_deref().unwrap_or("ATAN2");
2853 self.generate_binary_func(name, &f.this, &f.expression)
2854 }
2855
2856 Expression::Decode(f) => self.generate_decode(f),
2858
2859 Expression::DateFormat(f) => self.generate_date_format("DATE_FORMAT", f),
2861 Expression::FormatDate(f) => self.generate_date_format("FORMAT_DATE", f),
2862 Expression::Year(f) => self.generate_simple_func("YEAR", &f.this),
2863 Expression::Month(f) => self.generate_simple_func("MONTH", &f.this),
2864 Expression::Day(f) => self.generate_simple_func("DAY", &f.this),
2865 Expression::Hour(f) => self.generate_simple_func("HOUR", &f.this),
2866 Expression::Minute(f) => self.generate_simple_func("MINUTE", &f.this),
2867 Expression::Second(f) => self.generate_simple_func("SECOND", &f.this),
2868 Expression::DayOfWeek(f) => {
2869 let name = match self.config.dialect {
2870 Some(DialectType::Presto)
2871 | Some(DialectType::Trino)
2872 | Some(DialectType::Athena) => "DAY_OF_WEEK",
2873 Some(DialectType::DuckDB) => "ISODOW",
2874 _ => "DAYOFWEEK",
2875 };
2876 self.generate_simple_func(name, &f.this)
2877 }
2878 Expression::DayOfMonth(f) => {
2879 let name = match self.config.dialect {
2880 Some(DialectType::Presto)
2881 | Some(DialectType::Trino)
2882 | Some(DialectType::Athena) => "DAY_OF_MONTH",
2883 _ => "DAYOFMONTH",
2884 };
2885 self.generate_simple_func(name, &f.this)
2886 }
2887 Expression::DayOfYear(f) => {
2888 let name = match self.config.dialect {
2889 Some(DialectType::Presto)
2890 | Some(DialectType::Trino)
2891 | Some(DialectType::Athena) => "DAY_OF_YEAR",
2892 _ => "DAYOFYEAR",
2893 };
2894 self.generate_simple_func(name, &f.this)
2895 }
2896 Expression::WeekOfYear(f) => {
2897 let name = match self.config.dialect {
2899 Some(DialectType::Hive)
2900 | Some(DialectType::DuckDB)
2901 | Some(DialectType::Spark)
2902 | Some(DialectType::Databricks)
2903 | Some(DialectType::MySQL) => "WEEKOFYEAR",
2904 _ => "WEEK_OF_YEAR",
2905 };
2906 self.generate_simple_func(name, &f.this)
2907 }
2908 Expression::Quarter(f) => self.generate_simple_func("QUARTER", &f.this),
2909 Expression::AddMonths(f) => {
2910 self.generate_binary_func("ADD_MONTHS", &f.this, &f.expression)
2911 }
2912 Expression::MonthsBetween(f) => {
2913 self.generate_binary_func("MONTHS_BETWEEN", &f.this, &f.expression)
2914 }
2915 Expression::LastDay(f) => self.generate_last_day(f),
2916 Expression::NextDay(f) => self.generate_binary_func("NEXT_DAY", &f.this, &f.expression),
2917 Expression::Epoch(f) => self.generate_simple_func("EPOCH", &f.this),
2918 Expression::EpochMs(f) => self.generate_simple_func("EPOCH_MS", &f.this),
2919 Expression::FromUnixtime(f) => self.generate_from_unixtime(f),
2920 Expression::UnixTimestamp(f) => self.generate_unix_timestamp(f),
2921 Expression::MakeDate(f) => self.generate_make_date(f),
2922 Expression::MakeTimestamp(f) => self.generate_make_timestamp(f),
2923 Expression::TimestampTrunc(f) => self.generate_date_trunc(f),
2924
2925 Expression::ArrayFunc(f) => self.generate_array_constructor(f),
2927 Expression::ArrayLength(f) => self.generate_simple_func("ARRAY_LENGTH", &f.this),
2928 Expression::ArraySize(f) => self.generate_simple_func("ARRAY_SIZE", &f.this),
2929 Expression::Cardinality(f) => self.generate_simple_func("CARDINALITY", &f.this),
2930 Expression::ArrayContains(f) => {
2931 self.generate_binary_func("ARRAY_CONTAINS", &f.this, &f.expression)
2932 }
2933 Expression::ArrayPosition(f) => {
2934 self.generate_binary_func("ARRAY_POSITION", &f.this, &f.expression)
2935 }
2936 Expression::ArrayAppend(f) => {
2937 self.generate_binary_func("ARRAY_APPEND", &f.this, &f.expression)
2938 }
2939 Expression::ArrayPrepend(f) => {
2940 self.generate_binary_func("ARRAY_PREPEND", &f.this, &f.expression)
2941 }
2942 Expression::ArrayConcat(f) => self.generate_vararg_func("ARRAY_CONCAT", &f.expressions),
2943 Expression::ArraySort(f) => self.generate_array_sort(f),
2944 Expression::ArrayReverse(f) => self.generate_simple_func("ARRAY_REVERSE", &f.this),
2945 Expression::ArrayDistinct(f) => self.generate_simple_func("ARRAY_DISTINCT", &f.this),
2946 Expression::ArrayJoin(f) => self.generate_array_join("ARRAY_JOIN", f),
2947 Expression::ArrayToString(f) => self.generate_array_join("ARRAY_TO_STRING", f),
2948 Expression::Unnest(f) => self.generate_unnest(f),
2949 Expression::Explode(f) => self.generate_simple_func("EXPLODE", &f.this),
2950 Expression::ExplodeOuter(f) => self.generate_simple_func("EXPLODE_OUTER", &f.this),
2951 Expression::ArrayFilter(f) => self.generate_array_filter(f),
2952 Expression::ArrayTransform(f) => self.generate_array_transform(f),
2953 Expression::ArrayFlatten(f) => self.generate_simple_func("FLATTEN", &f.this),
2954 Expression::ArrayCompact(f) => {
2955 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
2956 self.write("LIST_FILTER(");
2958 self.generate_expression(&f.this)?;
2959 self.write(", _u -> NOT _u IS NULL)");
2960 Ok(())
2961 } else {
2962 self.generate_simple_func("ARRAY_COMPACT", &f.this)
2963 }
2964 }
2965 Expression::ArrayIntersect(f) => {
2966 let func_name = f.original_name.as_deref().unwrap_or("ARRAY_INTERSECT");
2967 self.generate_vararg_func(func_name, &f.expressions)
2968 }
2969 Expression::ArrayUnion(f) => {
2970 self.generate_binary_func("ARRAY_UNION", &f.this, &f.expression)
2971 }
2972 Expression::ArrayExcept(f) => {
2973 self.generate_binary_func("ARRAY_EXCEPT", &f.this, &f.expression)
2974 }
2975 Expression::ArrayRemove(f) => {
2976 self.generate_binary_func("ARRAY_REMOVE", &f.this, &f.expression)
2977 }
2978 Expression::ArrayZip(f) => self.generate_vararg_func("ARRAYS_ZIP", &f.expressions),
2979 Expression::Sequence(f) => self.generate_sequence("SEQUENCE", f),
2980 Expression::Generate(f) => self.generate_sequence("GENERATE_SERIES", f),
2981
2982 Expression::StructFunc(f) => self.generate_struct_constructor(f),
2984 Expression::StructExtract(f) => self.generate_struct_extract(f),
2985 Expression::NamedStruct(f) => self.generate_named_struct(f),
2986
2987 Expression::MapFunc(f) => self.generate_map_constructor(f),
2989 Expression::MapFromEntries(f) => self.generate_simple_func("MAP_FROM_ENTRIES", &f.this),
2990 Expression::MapFromArrays(f) => {
2991 self.generate_binary_func("MAP_FROM_ARRAYS", &f.this, &f.expression)
2992 }
2993 Expression::MapKeys(f) => self.generate_simple_func("MAP_KEYS", &f.this),
2994 Expression::MapValues(f) => self.generate_simple_func("MAP_VALUES", &f.this),
2995 Expression::MapContainsKey(f) => {
2996 self.generate_binary_func("MAP_CONTAINS_KEY", &f.this, &f.expression)
2997 }
2998 Expression::MapConcat(f) => self.generate_vararg_func("MAP_CONCAT", &f.expressions),
2999 Expression::ElementAt(f) => {
3000 self.generate_binary_func("ELEMENT_AT", &f.this, &f.expression)
3001 }
3002 Expression::TransformKeys(f) => self.generate_transform_func("TRANSFORM_KEYS", f),
3003 Expression::TransformValues(f) => self.generate_transform_func("TRANSFORM_VALUES", f),
3004
3005 Expression::JsonExtract(f) => self.generate_json_extract("JSON_EXTRACT", f),
3007 Expression::JsonExtractScalar(f) => {
3008 self.generate_json_extract("JSON_EXTRACT_SCALAR", f)
3009 }
3010 Expression::JsonExtractPath(f) => self.generate_json_path("JSON_EXTRACT_PATH", f),
3011 Expression::JsonArray(f) => self.generate_vararg_func("JSON_ARRAY", &f.expressions),
3012 Expression::JsonObject(f) => self.generate_json_object(f),
3013 Expression::JsonQuery(f) => self.generate_json_extract("JSON_QUERY", f),
3014 Expression::JsonValue(f) => self.generate_json_extract("JSON_VALUE", f),
3015 Expression::JsonArrayLength(f) => {
3016 self.generate_simple_func("JSON_ARRAY_LENGTH", &f.this)
3017 }
3018 Expression::JsonKeys(f) => self.generate_simple_func("JSON_KEYS", &f.this),
3019 Expression::JsonType(f) => self.generate_simple_func("JSON_TYPE", &f.this),
3020 Expression::ParseJson(f) => {
3021 let name = match self.config.dialect {
3022 Some(DialectType::Presto)
3023 | Some(DialectType::Trino)
3024 | Some(DialectType::Athena) => "JSON_PARSE",
3025 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
3026 self.write_keyword("CAST");
3028 self.write("(");
3029 self.generate_expression(&f.this)?;
3030 self.write_keyword(" AS ");
3031 self.write_keyword("JSON");
3032 self.write(")");
3033 return Ok(());
3034 }
3035 Some(DialectType::Hive)
3036 | Some(DialectType::Spark)
3037 | Some(DialectType::MySQL)
3038 | Some(DialectType::SingleStore)
3039 | Some(DialectType::TiDB)
3040 | Some(DialectType::TSQL) => {
3041 self.generate_expression(&f.this)?;
3043 return Ok(());
3044 }
3045 Some(DialectType::DuckDB) => "JSON",
3046 _ => "PARSE_JSON",
3047 };
3048 self.generate_simple_func(name, &f.this)
3049 }
3050 Expression::ToJson(f) => self.generate_simple_func("TO_JSON", &f.this),
3051 Expression::JsonSet(f) => self.generate_json_modify("JSON_SET", f),
3052 Expression::JsonInsert(f) => self.generate_json_modify("JSON_INSERT", f),
3053 Expression::JsonRemove(f) => self.generate_json_path("JSON_REMOVE", f),
3054 Expression::JsonMergePatch(f) => {
3055 self.generate_binary_func("JSON_MERGE_PATCH", &f.this, &f.expression)
3056 }
3057 Expression::JsonArrayAgg(f) => self.generate_json_array_agg(f),
3058 Expression::JsonObjectAgg(f) => self.generate_json_object_agg(f),
3059
3060 Expression::Convert(f) => self.generate_convert(f),
3062 Expression::Typeof(f) => self.generate_simple_func("TYPEOF", &f.this),
3063
3064 Expression::Lambda(f) => self.generate_lambda(f),
3066 Expression::Parameter(f) => self.generate_parameter(f),
3067 Expression::Placeholder(f) => self.generate_placeholder(f),
3068 Expression::NamedArgument(f) => self.generate_named_argument(f),
3069 Expression::TableArgument(f) => self.generate_table_argument(f),
3070 Expression::SqlComment(f) => self.generate_sql_comment(f),
3071
3072 Expression::NullSafeEq(op) => self.generate_null_safe_eq(op),
3074 Expression::NullSafeNeq(op) => self.generate_null_safe_neq(op),
3075 Expression::Glob(op) => self.generate_binary_op(op, "GLOB"),
3076 Expression::SimilarTo(f) => self.generate_similar_to(f),
3077 Expression::Any(f) => self.generate_quantified("ANY", f),
3078 Expression::All(f) => self.generate_quantified("ALL", f),
3079 Expression::Overlaps(f) => self.generate_overlaps(f),
3080
3081 Expression::BitwiseLeftShift(op) => {
3083 if matches!(
3084 self.config.dialect,
3085 Some(DialectType::Presto) | Some(DialectType::Trino)
3086 ) {
3087 self.write_keyword("BITWISE_ARITHMETIC_SHIFT_LEFT");
3088 self.write("(");
3089 self.generate_expression(&op.left)?;
3090 self.write(", ");
3091 self.generate_expression(&op.right)?;
3092 self.write(")");
3093 Ok(())
3094 } else if matches!(
3095 self.config.dialect,
3096 Some(DialectType::Spark) | Some(DialectType::Databricks)
3097 ) {
3098 self.write_keyword("SHIFTLEFT");
3099 self.write("(");
3100 self.generate_expression(&op.left)?;
3101 self.write(", ");
3102 self.generate_expression(&op.right)?;
3103 self.write(")");
3104 Ok(())
3105 } else {
3106 self.generate_binary_op(op, "<<")
3107 }
3108 }
3109 Expression::BitwiseRightShift(op) => {
3110 if matches!(
3111 self.config.dialect,
3112 Some(DialectType::Presto) | Some(DialectType::Trino)
3113 ) {
3114 self.write_keyword("BITWISE_ARITHMETIC_SHIFT_RIGHT");
3115 self.write("(");
3116 self.generate_expression(&op.left)?;
3117 self.write(", ");
3118 self.generate_expression(&op.right)?;
3119 self.write(")");
3120 Ok(())
3121 } else if matches!(
3122 self.config.dialect,
3123 Some(DialectType::Spark) | Some(DialectType::Databricks)
3124 ) {
3125 self.write_keyword("SHIFTRIGHT");
3126 self.write("(");
3127 self.generate_expression(&op.left)?;
3128 self.write(", ");
3129 self.generate_expression(&op.right)?;
3130 self.write(")");
3131 Ok(())
3132 } else {
3133 self.generate_binary_op(op, ">>")
3134 }
3135 }
3136 Expression::BitwiseAndAgg(f) => self.generate_agg_func("BIT_AND", f),
3137 Expression::BitwiseOrAgg(f) => self.generate_agg_func("BIT_OR", f),
3138 Expression::BitwiseXorAgg(f) => self.generate_agg_func("BIT_XOR", f),
3139
3140 Expression::Subscript(s) => self.generate_subscript(s),
3142 Expression::Dot(d) => self.generate_dot_access(d),
3143 Expression::MethodCall(m) => self.generate_method_call(m),
3144 Expression::ArraySlice(s) => self.generate_array_slice(s),
3145
3146 Expression::And(op) => self.generate_connector_op(op, ConnectorOperator::And),
3147 Expression::Or(op) => self.generate_connector_op(op, ConnectorOperator::Or),
3148 Expression::Add(op) => self.generate_binary_op(op, "+"),
3149 Expression::Sub(op) => self.generate_binary_op(op, "-"),
3150 Expression::Mul(op) => self.generate_binary_op(op, "*"),
3151 Expression::Div(op) => self.generate_binary_op(op, "/"),
3152 Expression::IntDiv(f) => {
3153 use crate::dialects::DialectType;
3154 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
3155 self.generate_expression(&f.this)?;
3157 self.write(" // ");
3158 self.generate_expression(&f.expression)?;
3159 Ok(())
3160 } else if matches!(
3161 self.config.dialect,
3162 Some(DialectType::Hive | DialectType::Spark | DialectType::Databricks)
3163 ) {
3164 self.generate_expression(&f.this)?;
3166 self.write(" ");
3167 self.write_keyword("DIV");
3168 self.write(" ");
3169 self.generate_expression(&f.expression)?;
3170 Ok(())
3171 } else {
3172 self.write_keyword("DIV");
3174 self.write("(");
3175 self.generate_expression(&f.this)?;
3176 self.write(", ");
3177 self.generate_expression(&f.expression)?;
3178 self.write(")");
3179 Ok(())
3180 }
3181 }
3182 Expression::Mod(op) => {
3183 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
3184 self.generate_binary_op(op, "MOD")
3185 } else {
3186 self.generate_binary_op(op, "%")
3187 }
3188 }
3189 Expression::Eq(op) => self.generate_binary_op(op, "="),
3190 Expression::Neq(op) => self.generate_binary_op(op, "<>"),
3191 Expression::Lt(op) => self.generate_binary_op(op, "<"),
3192 Expression::Lte(op) => self.generate_binary_op(op, "<="),
3193 Expression::Gt(op) => self.generate_binary_op(op, ">"),
3194 Expression::Gte(op) => self.generate_binary_op(op, ">="),
3195 Expression::Like(op) => self.generate_like_op(op, "LIKE"),
3196 Expression::ILike(op) => self.generate_like_op(op, "ILIKE"),
3197 Expression::Match(op) => self.generate_binary_op(op, "MATCH"),
3198 Expression::Concat(op) => {
3199 if self.config.dialect == Some(DialectType::Solr) {
3201 self.generate_binary_op(op, "OR")
3202 } else if self.config.dialect == Some(DialectType::MySQL) {
3203 self.generate_mysql_concat_from_concat(op)
3204 } else {
3205 self.generate_binary_op(op, "||")
3206 }
3207 }
3208 Expression::BitwiseAnd(op) => {
3209 if matches!(
3211 self.config.dialect,
3212 Some(DialectType::Presto) | Some(DialectType::Trino)
3213 ) {
3214 self.write_keyword("BITWISE_AND");
3215 self.write("(");
3216 self.generate_expression(&op.left)?;
3217 self.write(", ");
3218 self.generate_expression(&op.right)?;
3219 self.write(")");
3220 Ok(())
3221 } else {
3222 self.generate_binary_op(op, "&")
3223 }
3224 }
3225 Expression::BitwiseOr(op) => {
3226 if matches!(
3228 self.config.dialect,
3229 Some(DialectType::Presto) | Some(DialectType::Trino)
3230 ) {
3231 self.write_keyword("BITWISE_OR");
3232 self.write("(");
3233 self.generate_expression(&op.left)?;
3234 self.write(", ");
3235 self.generate_expression(&op.right)?;
3236 self.write(")");
3237 Ok(())
3238 } else {
3239 self.generate_binary_op(op, "|")
3240 }
3241 }
3242 Expression::BitwiseXor(op) => {
3243 if matches!(
3245 self.config.dialect,
3246 Some(DialectType::Presto) | Some(DialectType::Trino)
3247 ) {
3248 self.write_keyword("BITWISE_XOR");
3249 self.write("(");
3250 self.generate_expression(&op.left)?;
3251 self.write(", ");
3252 self.generate_expression(&op.right)?;
3253 self.write(")");
3254 Ok(())
3255 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
3256 self.generate_binary_op(op, "#")
3257 } else {
3258 self.generate_binary_op(op, "^")
3259 }
3260 }
3261 Expression::Adjacent(op) => self.generate_binary_op(op, "-|-"),
3262 Expression::TsMatch(op) => self.generate_binary_op(op, "@@"),
3263 Expression::PropertyEQ(op) => self.generate_binary_op(op, ":="),
3264 Expression::ArrayContainsAll(op) => self.generate_binary_op(op, "@>"),
3265 Expression::ArrayContainedBy(op) => self.generate_binary_op(op, "<@"),
3266 Expression::ArrayOverlaps(op) => self.generate_binary_op(op, "&&"),
3267 Expression::JSONBContainsAllTopKeys(op) => self.generate_binary_op(op, "?&"),
3268 Expression::JSONBContainsAnyTopKeys(op) => self.generate_binary_op(op, "?|"),
3269 Expression::JSONBContains(f) => {
3270 self.generate_expression(&f.this)?;
3272 self.write_space();
3273 self.write("?");
3274 self.write_space();
3275 self.generate_expression(&f.expression)
3276 }
3277 Expression::JSONBDeleteAtPath(op) => self.generate_binary_op(op, "#-"),
3278 Expression::ExtendsLeft(op) => self.generate_binary_op(op, "&<"),
3279 Expression::ExtendsRight(op) => self.generate_binary_op(op, "&>"),
3280 Expression::Not(op) => self.generate_unary_op(op, "NOT"),
3281 Expression::Neg(op) => self.generate_unary_op(op, "-"),
3282 Expression::BitwiseNot(op) => {
3283 if matches!(
3285 self.config.dialect,
3286 Some(DialectType::Presto) | Some(DialectType::Trino)
3287 ) {
3288 self.write_keyword("BITWISE_NOT");
3289 self.write("(");
3290 self.generate_expression(&op.this)?;
3291 self.write(")");
3292 Ok(())
3293 } else {
3294 self.generate_unary_op(op, "~")
3295 }
3296 }
3297 Expression::In(in_expr) => self.generate_in(in_expr),
3298 Expression::Between(between) => self.generate_between(between),
3299 Expression::IsNull(is_null) => self.generate_is_null(is_null),
3300 Expression::IsTrue(is_true) => self.generate_is_true(is_true),
3301 Expression::IsFalse(is_false) => self.generate_is_false(is_false),
3302 Expression::IsJson(is_json) => self.generate_is_json(is_json),
3303 Expression::Is(is_expr) => self.generate_is(is_expr),
3304 Expression::Exists(exists) => self.generate_exists(exists),
3305 Expression::MemberOf(member_of) => self.generate_member_of(member_of),
3306 Expression::Subquery(subquery) => self.generate_subquery(subquery),
3307 Expression::Paren(paren) => {
3308 let skip_parens = matches!(&paren.this, Expression::JoinedTable(_));
3310
3311 if !skip_parens {
3312 self.write("(");
3313 if self.config.pretty {
3314 self.write_newline();
3315 self.indent_level += 1;
3316 self.write_indent();
3317 }
3318 }
3319 self.generate_expression(&paren.this)?;
3320 if !skip_parens {
3321 if self.config.pretty {
3322 self.write_newline();
3323 self.indent_level -= 1;
3324 self.write_indent();
3325 }
3326 self.write(")");
3327 }
3328 for comment in &paren.trailing_comments {
3330 self.write(" ");
3331 self.write_formatted_comment(comment);
3332 }
3333 Ok(())
3334 }
3335 Expression::Array(arr) => self.generate_array(arr),
3336 Expression::Tuple(tuple) => self.generate_tuple(tuple),
3337 Expression::PipeOperator(pipe) => self.generate_pipe_operator(pipe),
3338 Expression::Ordered(ordered) => self.generate_ordered(ordered),
3339 Expression::DataType(dt) => self.generate_data_type(dt),
3340 Expression::Raw(raw) => {
3341 self.write(&raw.sql);
3342 Ok(())
3343 }
3344 Expression::CreateTask(task) => self.generate_create_task(task),
3345 Expression::TryCatch(try_catch) => self.generate_try_catch(try_catch),
3346 Expression::Command(cmd) => {
3347 self.write(&cmd.this);
3348 Ok(())
3349 }
3350 Expression::Kill(kill) => {
3351 self.write_keyword("KILL");
3352 if let Some(kind) = &kill.kind {
3353 self.write_space();
3354 self.write_keyword(kind);
3355 }
3356 self.write_space();
3357 self.generate_expression(&kill.this)?;
3358 Ok(())
3359 }
3360 Expression::Execute(exec) => {
3361 self.write_keyword("EXECUTE");
3362 self.write_space();
3363 self.generate_expression(&exec.this)?;
3364 for (i, param) in exec.parameters.iter().enumerate() {
3365 if i == 0 {
3366 self.write_space();
3367 } else {
3368 self.write(", ");
3369 }
3370 self.write(¶m.name);
3371 if !param.positional {
3373 self.write(" = ");
3374 self.generate_expression(¶m.value)?;
3375 }
3376 if param.output {
3377 self.write_space();
3378 self.write_keyword("OUTPUT");
3379 }
3380 }
3381 if let Some(ref suffix) = exec.suffix {
3382 self.write_space();
3383 self.write(suffix);
3384 }
3385 Ok(())
3386 }
3387 Expression::Annotated(annotated) => {
3388 self.generate_expression(&annotated.this)?;
3389 for comment in &annotated.trailing_comments {
3390 self.write(" ");
3391 self.write_formatted_comment(comment);
3392 }
3393 Ok(())
3394 }
3395
3396 Expression::CreateTable(ct) => self.generate_create_table(ct),
3398 Expression::DropTable(dt) => self.generate_drop_table(dt),
3399 Expression::Undrop(u) => self.generate_undrop(u),
3400 Expression::AlterTable(at) => self.generate_alter_table(at),
3401 Expression::CreateIndex(ci) => self.generate_create_index(ci),
3402 Expression::DropIndex(di) => self.generate_drop_index(di),
3403 Expression::CreateView(cv) => self.generate_create_view(cv),
3404 Expression::DropView(dv) => self.generate_drop_view(dv),
3405 Expression::AlterView(av) => self.generate_alter_view(av),
3406 Expression::AlterIndex(ai) => self.generate_alter_index(ai),
3407 Expression::Truncate(tr) => self.generate_truncate(tr),
3408 Expression::Use(u) => self.generate_use(u),
3409 Expression::CreateSchema(cs) => self.generate_create_schema(cs),
3411 Expression::DropSchema(ds) => self.generate_drop_schema(ds),
3412 Expression::DropNamespace(dn) => self.generate_drop_namespace(dn),
3413 Expression::CreateDatabase(cd) => self.generate_create_database(cd),
3414 Expression::DropDatabase(dd) => self.generate_drop_database(dd),
3415 Expression::CreateFunction(cf) => self.generate_create_function(cf),
3416 Expression::DropFunction(df) => self.generate_drop_function(df),
3417 Expression::CreateProcedure(cp) => self.generate_create_procedure(cp),
3418 Expression::DropProcedure(dp) => self.generate_drop_procedure(dp),
3419 Expression::CreateSequence(cs) => self.generate_create_sequence(cs),
3420 Expression::CreateSynonym(cs) => {
3421 self.write_keyword("CREATE SYNONYM");
3422 self.write_space();
3423 self.generate_table(&cs.name)?;
3424 self.write_space();
3425 self.write_keyword("FOR");
3426 self.write_space();
3427 self.generate_table(&cs.target)?;
3428 Ok(())
3429 }
3430 Expression::DropSequence(ds) => self.generate_drop_sequence(ds),
3431 Expression::AlterSequence(als) => self.generate_alter_sequence(als),
3432 Expression::CreateTrigger(ct) => self.generate_create_trigger(ct),
3433 Expression::DropTrigger(dt) => self.generate_drop_trigger(dt),
3434 Expression::CreateType(ct) => self.generate_create_type(ct),
3435 Expression::DropType(dt) => self.generate_drop_type(dt),
3436 Expression::Describe(d) => self.generate_describe(d),
3437 Expression::Show(s) => self.generate_show(s),
3438
3439 Expression::Cache(c) => self.generate_cache(c),
3441 Expression::Uncache(u) => self.generate_uncache(u),
3442 Expression::LoadData(l) => self.generate_load_data(l),
3443 Expression::Pragma(p) => self.generate_pragma(p),
3444 Expression::Grant(g) => self.generate_grant(g),
3445 Expression::Revoke(r) => self.generate_revoke(r),
3446 Expression::Comment(c) => self.generate_comment(c),
3447 Expression::SetStatement(s) => self.generate_set_statement(s),
3448
3449 Expression::Pivot(pivot) => self.generate_pivot(pivot),
3451 Expression::Unpivot(unpivot) => self.generate_unpivot(unpivot),
3452
3453 Expression::Values(values) => self.generate_values(values),
3455
3456 Expression::AIAgg(e) => self.generate_ai_agg(e),
3458 Expression::AIClassify(e) => self.generate_ai_classify(e),
3459 Expression::AddPartition(e) => self.generate_add_partition(e),
3460 Expression::AlgorithmProperty(e) => self.generate_algorithm_property(e),
3461 Expression::Aliases(e) => self.generate_aliases(e),
3462 Expression::AllowedValuesProperty(e) => self.generate_allowed_values_property(e),
3463 Expression::AlterColumn(e) => self.generate_alter_column(e),
3464 Expression::AlterSession(e) => self.generate_alter_session(e),
3465 Expression::AlterSet(e) => self.generate_alter_set(e),
3466 Expression::AlterSortKey(e) => self.generate_alter_sort_key(e),
3467 Expression::Analyze(e) => self.generate_analyze(e),
3468 Expression::AnalyzeDelete(e) => self.generate_analyze_delete(e),
3469 Expression::AnalyzeHistogram(e) => self.generate_analyze_histogram(e),
3470 Expression::AnalyzeListChainedRows(e) => self.generate_analyze_list_chained_rows(e),
3471 Expression::AnalyzeSample(e) => self.generate_analyze_sample(e),
3472 Expression::AnalyzeStatistics(e) => self.generate_analyze_statistics(e),
3473 Expression::AnalyzeValidate(e) => self.generate_analyze_validate(e),
3474 Expression::AnalyzeWith(e) => self.generate_analyze_with(e),
3475 Expression::Anonymous(e) => self.generate_anonymous(e),
3476 Expression::AnonymousAggFunc(e) => self.generate_anonymous_agg_func(e),
3477 Expression::Apply(e) => self.generate_apply(e),
3478 Expression::ApproxPercentileEstimate(e) => self.generate_approx_percentile_estimate(e),
3479 Expression::ApproxQuantile(e) => self.generate_approx_quantile(e),
3480 Expression::ApproxQuantiles(e) => self.generate_approx_quantiles(e),
3481 Expression::ApproxTopK(e) => self.generate_approx_top_k(e),
3482 Expression::ApproxTopKAccumulate(e) => self.generate_approx_top_k_accumulate(e),
3483 Expression::ApproxTopKCombine(e) => self.generate_approx_top_k_combine(e),
3484 Expression::ApproxTopKEstimate(e) => self.generate_approx_top_k_estimate(e),
3485 Expression::ApproxTopSum(e) => self.generate_approx_top_sum(e),
3486 Expression::ArgMax(e) => self.generate_arg_max(e),
3487 Expression::ArgMin(e) => self.generate_arg_min(e),
3488 Expression::ArrayAll(e) => self.generate_array_all(e),
3489 Expression::ArrayAny(e) => self.generate_array_any(e),
3490 Expression::ArrayConstructCompact(e) => self.generate_array_construct_compact(e),
3491 Expression::ArraySum(e) => self.generate_array_sum(e),
3492 Expression::AtIndex(e) => self.generate_at_index(e),
3493 Expression::Attach(e) => self.generate_attach(e),
3494 Expression::AttachOption(e) => self.generate_attach_option(e),
3495 Expression::AutoIncrementProperty(e) => self.generate_auto_increment_property(e),
3496 Expression::AutoRefreshProperty(e) => self.generate_auto_refresh_property(e),
3497 Expression::BackupProperty(e) => self.generate_backup_property(e),
3498 Expression::Base64DecodeBinary(e) => self.generate_base64_decode_binary(e),
3499 Expression::Base64DecodeString(e) => self.generate_base64_decode_string(e),
3500 Expression::Base64Encode(e) => self.generate_base64_encode(e),
3501 Expression::BlockCompressionProperty(e) => self.generate_block_compression_property(e),
3502 Expression::Booland(e) => self.generate_booland(e),
3503 Expression::Boolor(e) => self.generate_boolor(e),
3504 Expression::BuildProperty(e) => self.generate_build_property(e),
3505 Expression::ByteString(e) => self.generate_byte_string(e),
3506 Expression::CaseSpecificColumnConstraint(e) => {
3507 self.generate_case_specific_column_constraint(e)
3508 }
3509 Expression::CastToStrType(e) => self.generate_cast_to_str_type(e),
3510 Expression::Changes(e) => self.generate_changes(e),
3511 Expression::CharacterSetColumnConstraint(e) => {
3512 self.generate_character_set_column_constraint(e)
3513 }
3514 Expression::CharacterSetProperty(e) => self.generate_character_set_property(e),
3515 Expression::CheckColumnConstraint(e) => self.generate_check_column_constraint(e),
3516 Expression::AssumeColumnConstraint(e) => self.generate_assume_column_constraint(e),
3517 Expression::CheckJson(e) => self.generate_check_json(e),
3518 Expression::CheckXml(e) => self.generate_check_xml(e),
3519 Expression::ChecksumProperty(e) => self.generate_checksum_property(e),
3520 Expression::Clone(e) => self.generate_clone(e),
3521 Expression::ClusterBy(e) => self.generate_cluster_by(e),
3522 Expression::ClusterByColumnsProperty(e) => self.generate_cluster_by_columns_property(e),
3523 Expression::ClusteredByProperty(e) => self.generate_clustered_by_property(e),
3524 Expression::CollateProperty(e) => self.generate_collate_property(e),
3525 Expression::ColumnConstraint(e) => self.generate_column_constraint(e),
3526 Expression::ColumnDef(e) => self.generate_column_def_expr(e),
3527 Expression::ColumnPosition(e) => self.generate_column_position(e),
3528 Expression::ColumnPrefix(e) => self.generate_column_prefix(e),
3529 Expression::Columns(e) => self.generate_columns(e),
3530 Expression::CombinedAggFunc(e) => self.generate_combined_agg_func(e),
3531 Expression::CombinedParameterizedAgg(e) => self.generate_combined_parameterized_agg(e),
3532 Expression::Commit(e) => self.generate_commit(e),
3533 Expression::Comprehension(e) => self.generate_comprehension(e),
3534 Expression::Compress(e) => self.generate_compress(e),
3535 Expression::CompressColumnConstraint(e) => self.generate_compress_column_constraint(e),
3536 Expression::ComputedColumnConstraint(e) => self.generate_computed_column_constraint(e),
3537 Expression::ConditionalInsert(e) => self.generate_conditional_insert(e),
3538 Expression::Constraint(e) => self.generate_constraint(e),
3539 Expression::ConvertTimezone(e) => self.generate_convert_timezone(e),
3540 Expression::ConvertToCharset(e) => self.generate_convert_to_charset(e),
3541 Expression::Copy(e) => self.generate_copy(e),
3542 Expression::CopyParameter(e) => self.generate_copy_parameter(e),
3543 Expression::Corr(e) => self.generate_corr(e),
3544 Expression::CosineDistance(e) => self.generate_cosine_distance(e),
3545 Expression::CovarPop(e) => self.generate_covar_pop(e),
3546 Expression::CovarSamp(e) => self.generate_covar_samp(e),
3547 Expression::Credentials(e) => self.generate_credentials(e),
3548 Expression::CredentialsProperty(e) => self.generate_credentials_property(e),
3549 Expression::Cte(e) => self.generate_cte(e),
3550 Expression::Cube(e) => self.generate_cube(e),
3551 Expression::CurrentDatetime(e) => self.generate_current_datetime(e),
3552 Expression::CurrentSchema(e) => self.generate_current_schema(e),
3553 Expression::CurrentSchemas(e) => self.generate_current_schemas(e),
3554 Expression::CurrentUser(e) => self.generate_current_user(e),
3555 Expression::DPipe(e) => self.generate_d_pipe(e),
3556 Expression::DataBlocksizeProperty(e) => self.generate_data_blocksize_property(e),
3557 Expression::DataDeletionProperty(e) => self.generate_data_deletion_property(e),
3558 Expression::Date(e) => self.generate_date_func(e),
3559 Expression::DateBin(e) => self.generate_date_bin(e),
3560 Expression::DateFormatColumnConstraint(e) => {
3561 self.generate_date_format_column_constraint(e)
3562 }
3563 Expression::DateFromParts(e) => self.generate_date_from_parts(e),
3564 Expression::Datetime(e) => self.generate_datetime(e),
3565 Expression::DatetimeAdd(e) => self.generate_datetime_add(e),
3566 Expression::DatetimeDiff(e) => self.generate_datetime_diff(e),
3567 Expression::DatetimeSub(e) => self.generate_datetime_sub(e),
3568 Expression::DatetimeTrunc(e) => self.generate_datetime_trunc(e),
3569 Expression::Dayname(e) => self.generate_dayname(e),
3570 Expression::Declare(e) => self.generate_declare(e),
3571 Expression::DeclareItem(e) => self.generate_declare_item(e),
3572 Expression::DecodeCase(e) => self.generate_decode_case(e),
3573 Expression::DecompressBinary(e) => self.generate_decompress_binary(e),
3574 Expression::DecompressString(e) => self.generate_decompress_string(e),
3575 Expression::Decrypt(e) => self.generate_decrypt(e),
3576 Expression::DecryptRaw(e) => self.generate_decrypt_raw(e),
3577 Expression::DefaultColumnConstraint(e) => {
3578 self.write_keyword("DEFAULT");
3579 self.write_space();
3580 self.generate_expression(&e.this)?;
3581 if let Some(ref col) = e.for_column {
3582 self.write_space();
3583 self.write_keyword("FOR");
3584 self.write_space();
3585 self.generate_identifier(col)?;
3586 }
3587 Ok(())
3588 }
3589 Expression::DefinerProperty(e) => self.generate_definer_property(e),
3590 Expression::Detach(e) => self.generate_detach(e),
3591 Expression::DictProperty(e) => self.generate_dict_property(e),
3592 Expression::DictRange(e) => self.generate_dict_range(e),
3593 Expression::Directory(e) => self.generate_directory(e),
3594 Expression::DistKeyProperty(e) => self.generate_dist_key_property(e),
3595 Expression::DistStyleProperty(e) => self.generate_dist_style_property(e),
3596 Expression::DistributeBy(e) => self.generate_distribute_by(e),
3597 Expression::DistributedByProperty(e) => self.generate_distributed_by_property(e),
3598 Expression::DotProduct(e) => self.generate_dot_product(e),
3599 Expression::DropPartition(e) => self.generate_drop_partition(e),
3600 Expression::DuplicateKeyProperty(e) => self.generate_duplicate_key_property(e),
3601 Expression::Elt(e) => self.generate_elt(e),
3602 Expression::Encode(e) => self.generate_encode(e),
3603 Expression::EncodeProperty(e) => self.generate_encode_property(e),
3604 Expression::Encrypt(e) => self.generate_encrypt(e),
3605 Expression::EncryptRaw(e) => self.generate_encrypt_raw(e),
3606 Expression::EngineProperty(e) => self.generate_engine_property(e),
3607 Expression::EnviromentProperty(e) => self.generate_enviroment_property(e),
3608 Expression::EphemeralColumnConstraint(e) => {
3609 self.generate_ephemeral_column_constraint(e)
3610 }
3611 Expression::EqualNull(e) => self.generate_equal_null(e),
3612 Expression::EuclideanDistance(e) => self.generate_euclidean_distance(e),
3613 Expression::ExecuteAsProperty(e) => self.generate_execute_as_property(e),
3614 Expression::Export(e) => self.generate_export(e),
3615 Expression::ExternalProperty(e) => self.generate_external_property(e),
3616 Expression::FallbackProperty(e) => self.generate_fallback_property(e),
3617 Expression::FarmFingerprint(e) => self.generate_farm_fingerprint(e),
3618 Expression::FeaturesAtTime(e) => self.generate_features_at_time(e),
3619 Expression::Fetch(e) => self.generate_fetch(e),
3620 Expression::FileFormatProperty(e) => self.generate_file_format_property(e),
3621 Expression::Filter(e) => self.generate_filter(e),
3622 Expression::Float64(e) => self.generate_float64(e),
3623 Expression::ForIn(e) => self.generate_for_in(e),
3624 Expression::ForeignKey(e) => self.generate_foreign_key(e),
3625 Expression::Format(e) => self.generate_format(e),
3626 Expression::FormatPhrase(e) => self.generate_format_phrase(e),
3627 Expression::FreespaceProperty(e) => self.generate_freespace_property(e),
3628 Expression::From(e) => self.generate_from(e),
3629 Expression::FromBase(e) => self.generate_from_base(e),
3630 Expression::FromTimeZone(e) => self.generate_from_time_zone(e),
3631 Expression::GapFill(e) => self.generate_gap_fill(e),
3632 Expression::GenerateDateArray(e) => self.generate_generate_date_array(e),
3633 Expression::GenerateEmbedding(e) => self.generate_generate_embedding(e),
3634 Expression::GenerateSeries(e) => self.generate_generate_series(e),
3635 Expression::GenerateTimestampArray(e) => self.generate_generate_timestamp_array(e),
3636 Expression::GeneratedAsIdentityColumnConstraint(e) => {
3637 self.generate_generated_as_identity_column_constraint(e)
3638 }
3639 Expression::GeneratedAsRowColumnConstraint(e) => {
3640 self.generate_generated_as_row_column_constraint(e)
3641 }
3642 Expression::Get(e) => self.generate_get(e),
3643 Expression::GetExtract(e) => self.generate_get_extract(e),
3644 Expression::Getbit(e) => self.generate_getbit(e),
3645 Expression::GrantPrincipal(e) => self.generate_grant_principal(e),
3646 Expression::GrantPrivilege(e) => self.generate_grant_privilege(e),
3647 Expression::Group(e) => self.generate_group(e),
3648 Expression::GroupBy(e) => self.generate_group_by(e),
3649 Expression::Grouping(e) => self.generate_grouping(e),
3650 Expression::GroupingId(e) => self.generate_grouping_id(e),
3651 Expression::GroupingSets(e) => self.generate_grouping_sets(e),
3652 Expression::HashAgg(e) => self.generate_hash_agg(e),
3653 Expression::Having(e) => self.generate_having(e),
3654 Expression::HavingMax(e) => self.generate_having_max(e),
3655 Expression::Heredoc(e) => self.generate_heredoc(e),
3656 Expression::HexEncode(e) => self.generate_hex_encode(e),
3657 Expression::Hll(e) => self.generate_hll(e),
3658 Expression::InOutColumnConstraint(e) => self.generate_in_out_column_constraint(e),
3659 Expression::IncludeProperty(e) => self.generate_include_property(e),
3660 Expression::Index(e) => self.generate_index(e),
3661 Expression::IndexColumnConstraint(e) => self.generate_index_column_constraint(e),
3662 Expression::IndexConstraintOption(e) => self.generate_index_constraint_option(e),
3663 Expression::IndexParameters(e) => self.generate_index_parameters(e),
3664 Expression::IndexTableHint(e) => self.generate_index_table_hint(e),
3665 Expression::InheritsProperty(e) => self.generate_inherits_property(e),
3666 Expression::InputModelProperty(e) => self.generate_input_model_property(e),
3667 Expression::InputOutputFormat(e) => self.generate_input_output_format(e),
3668 Expression::Install(e) => self.generate_install(e),
3669 Expression::IntervalOp(e) => self.generate_interval_op(e),
3670 Expression::IntervalSpan(e) => self.generate_interval_span(e),
3671 Expression::IntoClause(e) => self.generate_into_clause(e),
3672 Expression::Introducer(e) => self.generate_introducer(e),
3673 Expression::IsolatedLoadingProperty(e) => self.generate_isolated_loading_property(e),
3674 Expression::JSON(e) => self.generate_json(e),
3675 Expression::JSONArray(e) => self.generate_json_array(e),
3676 Expression::JSONArrayAgg(e) => self.generate_json_array_agg_struct(e),
3677 Expression::JSONArrayAppend(e) => self.generate_json_array_append(e),
3678 Expression::JSONArrayContains(e) => self.generate_json_array_contains(e),
3679 Expression::JSONArrayInsert(e) => self.generate_json_array_insert(e),
3680 Expression::JSONBExists(e) => self.generate_jsonb_exists(e),
3681 Expression::JSONBExtractScalar(e) => self.generate_jsonb_extract_scalar(e),
3682 Expression::JSONBObjectAgg(e) => self.generate_jsonb_object_agg(e),
3683 Expression::JSONObjectAgg(e) => self.generate_json_object_agg_struct(e),
3684 Expression::JSONColumnDef(e) => self.generate_json_column_def(e),
3685 Expression::JSONExists(e) => self.generate_json_exists(e),
3686 Expression::JSONCast(e) => self.generate_json_cast(e),
3687 Expression::JSONExtract(e) => self.generate_json_extract_path(e),
3688 Expression::JSONExtractArray(e) => self.generate_json_extract_array(e),
3689 Expression::JSONExtractQuote(e) => self.generate_json_extract_quote(e),
3690 Expression::JSONExtractScalar(e) => self.generate_json_extract_scalar(e),
3691 Expression::JSONFormat(e) => self.generate_json_format(e),
3692 Expression::JSONKeyValue(e) => self.generate_json_key_value(e),
3693 Expression::JSONKeys(e) => self.generate_json_keys(e),
3694 Expression::JSONKeysAtDepth(e) => self.generate_json_keys_at_depth(e),
3695 Expression::JSONPath(e) => self.generate_json_path_expr(e),
3696 Expression::JSONPathFilter(e) => self.generate_json_path_filter(e),
3697 Expression::JSONPathKey(e) => self.generate_json_path_key(e),
3698 Expression::JSONPathRecursive(e) => self.generate_json_path_recursive(e),
3699 Expression::JSONPathRoot(_) => self.generate_json_path_root(),
3700 Expression::JSONPathScript(e) => self.generate_json_path_script(e),
3701 Expression::JSONPathSelector(e) => self.generate_json_path_selector(e),
3702 Expression::JSONPathSlice(e) => self.generate_json_path_slice(e),
3703 Expression::JSONPathSubscript(e) => self.generate_json_path_subscript(e),
3704 Expression::JSONPathUnion(e) => self.generate_json_path_union(e),
3705 Expression::JSONRemove(e) => self.generate_json_remove(e),
3706 Expression::JSONSchema(e) => self.generate_json_schema(e),
3707 Expression::JSONSet(e) => self.generate_json_set(e),
3708 Expression::JSONStripNulls(e) => self.generate_json_strip_nulls(e),
3709 Expression::JSONTable(e) => self.generate_json_table(e),
3710 Expression::JSONType(e) => self.generate_json_type(e),
3711 Expression::JSONValue(e) => self.generate_json_value(e),
3712 Expression::JSONValueArray(e) => self.generate_json_value_array(e),
3713 Expression::JarowinklerSimilarity(e) => self.generate_jarowinkler_similarity(e),
3714 Expression::JoinHint(e) => self.generate_join_hint(e),
3715 Expression::JournalProperty(e) => self.generate_journal_property(e),
3716 Expression::LanguageProperty(e) => self.generate_language_property(e),
3717 Expression::Lateral(e) => self.generate_lateral(e),
3718 Expression::LikeProperty(e) => self.generate_like_property(e),
3719 Expression::Limit(e) => self.generate_limit(e),
3720 Expression::LimitOptions(e) => self.generate_limit_options(e),
3721 Expression::List(e) => self.generate_list(e),
3722 Expression::ToMap(e) => self.generate_tomap(e),
3723 Expression::Localtime(e) => self.generate_localtime(e),
3724 Expression::Localtimestamp(e) => self.generate_localtimestamp(e),
3725 Expression::LocationProperty(e) => self.generate_location_property(e),
3726 Expression::Lock(e) => self.generate_lock(e),
3727 Expression::LockProperty(e) => self.generate_lock_property(e),
3728 Expression::LockingProperty(e) => self.generate_locking_property(e),
3729 Expression::LockingStatement(e) => self.generate_locking_statement(e),
3730 Expression::LogProperty(e) => self.generate_log_property(e),
3731 Expression::MD5Digest(e) => self.generate_md5_digest(e),
3732 Expression::MLForecast(e) => self.generate_ml_forecast(e),
3733 Expression::MLTranslate(e) => self.generate_ml_translate(e),
3734 Expression::MakeInterval(e) => self.generate_make_interval(e),
3735 Expression::ManhattanDistance(e) => self.generate_manhattan_distance(e),
3736 Expression::Map(e) => self.generate_map(e),
3737 Expression::MapCat(e) => self.generate_map_cat(e),
3738 Expression::MapDelete(e) => self.generate_map_delete(e),
3739 Expression::MapInsert(e) => self.generate_map_insert(e),
3740 Expression::MapPick(e) => self.generate_map_pick(e),
3741 Expression::MaskingPolicyColumnConstraint(e) => {
3742 self.generate_masking_policy_column_constraint(e)
3743 }
3744 Expression::MatchAgainst(e) => self.generate_match_against(e),
3745 Expression::MatchRecognizeMeasure(e) => self.generate_match_recognize_measure(e),
3746 Expression::MaterializedProperty(e) => self.generate_materialized_property(e),
3747 Expression::Merge(e) => self.generate_merge(e),
3748 Expression::MergeBlockRatioProperty(e) => self.generate_merge_block_ratio_property(e),
3749 Expression::MergeTreeTTL(e) => self.generate_merge_tree_ttl(e),
3750 Expression::MergeTreeTTLAction(e) => self.generate_merge_tree_ttl_action(e),
3751 Expression::Minhash(e) => self.generate_minhash(e),
3752 Expression::ModelAttribute(e) => self.generate_model_attribute(e),
3753 Expression::Monthname(e) => self.generate_monthname(e),
3754 Expression::MultitableInserts(e) => self.generate_multitable_inserts(e),
3755 Expression::NextValueFor(e) => self.generate_next_value_for(e),
3756 Expression::Normal(e) => self.generate_normal(e),
3757 Expression::Normalize(e) => self.generate_normalize(e),
3758 Expression::NotNullColumnConstraint(e) => self.generate_not_null_column_constraint(e),
3759 Expression::Nullif(e) => self.generate_nullif(e),
3760 Expression::NumberToStr(e) => self.generate_number_to_str(e),
3761 Expression::ObjectAgg(e) => self.generate_object_agg(e),
3762 Expression::ObjectIdentifier(e) => self.generate_object_identifier(e),
3763 Expression::ObjectInsert(e) => self.generate_object_insert(e),
3764 Expression::Offset(e) => self.generate_offset(e),
3765 Expression::Qualify(e) => self.generate_qualify(e),
3766 Expression::OnCluster(e) => self.generate_on_cluster(e),
3767 Expression::OnCommitProperty(e) => self.generate_on_commit_property(e),
3768 Expression::OnCondition(e) => self.generate_on_condition(e),
3769 Expression::OnConflict(e) => self.generate_on_conflict(e),
3770 Expression::OnProperty(e) => self.generate_on_property(e),
3771 Expression::Opclass(e) => self.generate_opclass(e),
3772 Expression::OpenJSON(e) => self.generate_open_json(e),
3773 Expression::OpenJSONColumnDef(e) => self.generate_open_json_column_def(e),
3774 Expression::Operator(e) => self.generate_operator(e),
3775 Expression::OrderBy(e) => self.generate_order_by(e),
3776 Expression::OutputModelProperty(e) => self.generate_output_model_property(e),
3777 Expression::OverflowTruncateBehavior(e) => self.generate_overflow_truncate_behavior(e),
3778 Expression::ParameterizedAgg(e) => self.generate_parameterized_agg(e),
3779 Expression::ParseDatetime(e) => self.generate_parse_datetime(e),
3780 Expression::ParseIp(e) => self.generate_parse_ip(e),
3781 Expression::ParseJSON(e) => self.generate_parse_json(e),
3782 Expression::ParseTime(e) => self.generate_parse_time(e),
3783 Expression::ParseUrl(e) => self.generate_parse_url(e),
3784 Expression::Partition(e) => self.generate_partition_expr(e),
3785 Expression::PartitionBoundSpec(e) => self.generate_partition_bound_spec(e),
3786 Expression::PartitionByListProperty(e) => self.generate_partition_by_list_property(e),
3787 Expression::PartitionByRangeProperty(e) => self.generate_partition_by_range_property(e),
3788 Expression::PartitionByRangePropertyDynamic(e) => {
3789 self.generate_partition_by_range_property_dynamic(e)
3790 }
3791 Expression::PartitionByTruncate(e) => self.generate_partition_by_truncate(e),
3792 Expression::PartitionList(e) => self.generate_partition_list(e),
3793 Expression::PartitionRange(e) => self.generate_partition_range(e),
3794 Expression::PartitionByProperty(e) => self.generate_partition_by_property(e),
3795 Expression::PartitionedByBucket(e) => self.generate_partitioned_by_bucket(e),
3796 Expression::PartitionedByProperty(e) => self.generate_partitioned_by_property(e),
3797 Expression::PartitionedOfProperty(e) => self.generate_partitioned_of_property(e),
3798 Expression::PeriodForSystemTimeConstraint(e) => {
3799 self.generate_period_for_system_time_constraint(e)
3800 }
3801 Expression::PivotAlias(e) => self.generate_pivot_alias(e),
3802 Expression::PivotAny(e) => self.generate_pivot_any(e),
3803 Expression::Predict(e) => self.generate_predict(e),
3804 Expression::PreviousDay(e) => self.generate_previous_day(e),
3805 Expression::PrimaryKey(e) => self.generate_primary_key(e),
3806 Expression::PrimaryKeyColumnConstraint(e) => {
3807 self.generate_primary_key_column_constraint(e)
3808 }
3809 Expression::PathColumnConstraint(e) => self.generate_path_column_constraint(e),
3810 Expression::ProjectionDef(e) => self.generate_projection_def(e),
3811 Expression::OptionsProperty(e) => self.generate_options_property(e),
3812 Expression::Properties(e) => self.generate_properties(e),
3813 Expression::Property(e) => self.generate_property(e),
3814 Expression::PseudoType(e) => self.generate_pseudo_type(e),
3815 Expression::Put(e) => self.generate_put(e),
3816 Expression::Quantile(e) => self.generate_quantile(e),
3817 Expression::QueryBand(e) => self.generate_query_band(e),
3818 Expression::QueryOption(e) => self.generate_query_option(e),
3819 Expression::QueryTransform(e) => self.generate_query_transform(e),
3820 Expression::Randn(e) => self.generate_randn(e),
3821 Expression::Randstr(e) => self.generate_randstr(e),
3822 Expression::RangeBucket(e) => self.generate_range_bucket(e),
3823 Expression::RangeN(e) => self.generate_range_n(e),
3824 Expression::ReadCSV(e) => self.generate_read_csv(e),
3825 Expression::ReadParquet(e) => self.generate_read_parquet(e),
3826 Expression::RecursiveWithSearch(e) => self.generate_recursive_with_search(e),
3827 Expression::Reduce(e) => self.generate_reduce(e),
3828 Expression::Reference(e) => self.generate_reference(e),
3829 Expression::Refresh(e) => self.generate_refresh(e),
3830 Expression::RefreshTriggerProperty(e) => self.generate_refresh_trigger_property(e),
3831 Expression::RegexpCount(e) => self.generate_regexp_count(e),
3832 Expression::RegexpExtractAll(e) => self.generate_regexp_extract_all(e),
3833 Expression::RegexpFullMatch(e) => self.generate_regexp_full_match(e),
3834 Expression::RegexpILike(e) => self.generate_regexp_i_like(e),
3835 Expression::RegexpInstr(e) => self.generate_regexp_instr(e),
3836 Expression::RegexpSplit(e) => self.generate_regexp_split(e),
3837 Expression::RegrAvgx(e) => self.generate_regr_avgx(e),
3838 Expression::RegrAvgy(e) => self.generate_regr_avgy(e),
3839 Expression::RegrCount(e) => self.generate_regr_count(e),
3840 Expression::RegrIntercept(e) => self.generate_regr_intercept(e),
3841 Expression::RegrR2(e) => self.generate_regr_r2(e),
3842 Expression::RegrSlope(e) => self.generate_regr_slope(e),
3843 Expression::RegrSxx(e) => self.generate_regr_sxx(e),
3844 Expression::RegrSxy(e) => self.generate_regr_sxy(e),
3845 Expression::RegrSyy(e) => self.generate_regr_syy(e),
3846 Expression::RegrValx(e) => self.generate_regr_valx(e),
3847 Expression::RegrValy(e) => self.generate_regr_valy(e),
3848 Expression::RemoteWithConnectionModelProperty(e) => {
3849 self.generate_remote_with_connection_model_property(e)
3850 }
3851 Expression::RenameColumn(e) => self.generate_rename_column(e),
3852 Expression::ReplacePartition(e) => self.generate_replace_partition(e),
3853 Expression::Returning(e) => self.generate_returning(e),
3854 Expression::ReturnsProperty(e) => self.generate_returns_property(e),
3855 Expression::Rollback(e) => self.generate_rollback(e),
3856 Expression::Rollup(e) => self.generate_rollup(e),
3857 Expression::RowFormatDelimitedProperty(e) => {
3858 self.generate_row_format_delimited_property(e)
3859 }
3860 Expression::RowFormatProperty(e) => self.generate_row_format_property(e),
3861 Expression::RowFormatSerdeProperty(e) => self.generate_row_format_serde_property(e),
3862 Expression::SHA2(e) => self.generate_sha2(e),
3863 Expression::SHA2Digest(e) => self.generate_sha2_digest(e),
3864 Expression::SafeAdd(e) => self.generate_safe_add(e),
3865 Expression::SafeDivide(e) => self.generate_safe_divide(e),
3866 Expression::SafeMultiply(e) => self.generate_safe_multiply(e),
3867 Expression::SafeSubtract(e) => self.generate_safe_subtract(e),
3868 Expression::SampleProperty(e) => self.generate_sample_property(e),
3869 Expression::Schema(e) => self.generate_schema(e),
3870 Expression::SchemaCommentProperty(e) => self.generate_schema_comment_property(e),
3871 Expression::ScopeResolution(e) => self.generate_scope_resolution(e),
3872 Expression::Search(e) => self.generate_search(e),
3873 Expression::SearchIp(e) => self.generate_search_ip(e),
3874 Expression::SecurityProperty(e) => self.generate_security_property(e),
3875 Expression::SemanticView(e) => self.generate_semantic_view(e),
3876 Expression::SequenceProperties(e) => self.generate_sequence_properties(e),
3877 Expression::SerdeProperties(e) => self.generate_serde_properties(e),
3878 Expression::SessionParameter(e) => self.generate_session_parameter(e),
3879 Expression::Set(e) => self.generate_set(e),
3880 Expression::SetConfigProperty(e) => self.generate_set_config_property(e),
3881 Expression::SetItem(e) => self.generate_set_item(e),
3882 Expression::SetOperation(e) => self.generate_set_operation(e),
3883 Expression::SetProperty(e) => self.generate_set_property(e),
3884 Expression::SettingsProperty(e) => self.generate_settings_property(e),
3885 Expression::SharingProperty(e) => self.generate_sharing_property(e),
3886 Expression::Slice(e) => self.generate_slice(e),
3887 Expression::SortArray(e) => self.generate_sort_array(e),
3888 Expression::SortBy(e) => self.generate_sort_by(e),
3889 Expression::SortKeyProperty(e) => self.generate_sort_key_property(e),
3890 Expression::SplitPart(e) => self.generate_split_part(e),
3891 Expression::SqlReadWriteProperty(e) => self.generate_sql_read_write_property(e),
3892 Expression::SqlSecurityProperty(e) => self.generate_sql_security_property(e),
3893 Expression::StDistance(e) => self.generate_st_distance(e),
3894 Expression::StPoint(e) => self.generate_st_point(e),
3895 Expression::StabilityProperty(e) => self.generate_stability_property(e),
3896 Expression::StandardHash(e) => self.generate_standard_hash(e),
3897 Expression::StorageHandlerProperty(e) => self.generate_storage_handler_property(e),
3898 Expression::StrPosition(e) => self.generate_str_position(e),
3899 Expression::StrToDate(e) => self.generate_str_to_date(e),
3900 Expression::DateStrToDate(f) => self.generate_simple_func("DATE_STR_TO_DATE", &f.this),
3901 Expression::DateToDateStr(f) => self.generate_simple_func("DATE_TO_DATE_STR", &f.this),
3902 Expression::StrToMap(e) => self.generate_str_to_map(e),
3903 Expression::StrToTime(e) => self.generate_str_to_time(e),
3904 Expression::StrToUnix(e) => self.generate_str_to_unix(e),
3905 Expression::StringToArray(e) => self.generate_string_to_array(e),
3906 Expression::Struct(e) => self.generate_struct(e),
3907 Expression::Stuff(e) => self.generate_stuff(e),
3908 Expression::SubstringIndex(e) => self.generate_substring_index(e),
3909 Expression::Summarize(e) => self.generate_summarize(e),
3910 Expression::Systimestamp(e) => self.generate_systimestamp(e),
3911 Expression::TableAlias(e) => self.generate_table_alias(e),
3912 Expression::TableFromRows(e) => self.generate_table_from_rows(e),
3913 Expression::RowsFrom(e) => self.generate_rows_from(e),
3914 Expression::TableSample(e) => self.generate_table_sample(e),
3915 Expression::Tag(e) => self.generate_tag(e),
3916 Expression::Tags(e) => self.generate_tags(e),
3917 Expression::TemporaryProperty(e) => self.generate_temporary_property(e),
3918 Expression::Time(e) => self.generate_time_func(e),
3919 Expression::TimeAdd(e) => self.generate_time_add(e),
3920 Expression::TimeDiff(e) => self.generate_time_diff(e),
3921 Expression::TimeFromParts(e) => self.generate_time_from_parts(e),
3922 Expression::TimeSlice(e) => self.generate_time_slice(e),
3923 Expression::TimeStrToDate(e) => self.generate_time_str_to_date(e),
3924 Expression::TimeStrToTime(e) => self.generate_time_str_to_time(e),
3925 Expression::TimeSub(e) => self.generate_time_sub(e),
3926 Expression::TimeToStr(e) => self.generate_time_to_str(e),
3927 Expression::TimeToUnix(e) => self.generate_time_to_unix(e),
3928 Expression::TimeTrunc(e) => self.generate_time_trunc(e),
3929 Expression::TimeUnit(e) => self.generate_time_unit(e),
3930 Expression::Timestamp(e) => self.generate_timestamp_func(e),
3931 Expression::TimestampAdd(e) => self.generate_timestamp_add(e),
3932 Expression::TimestampDiff(e) => self.generate_timestamp_diff(e),
3933 Expression::TimestampFromParts(e) => self.generate_timestamp_from_parts(e),
3934 Expression::TimestampSub(e) => self.generate_timestamp_sub(e),
3935 Expression::TimestampTzFromParts(e) => self.generate_timestamp_tz_from_parts(e),
3936 Expression::ToBinary(e) => self.generate_to_binary(e),
3937 Expression::ToBoolean(e) => self.generate_to_boolean(e),
3938 Expression::ToChar(e) => self.generate_to_char(e),
3939 Expression::ToDecfloat(e) => self.generate_to_decfloat(e),
3940 Expression::ToDouble(e) => self.generate_to_double(e),
3941 Expression::ToFile(e) => self.generate_to_file(e),
3942 Expression::ToNumber(e) => self.generate_to_number(e),
3943 Expression::ToTableProperty(e) => self.generate_to_table_property(e),
3944 Expression::Transaction(e) => self.generate_transaction(e),
3945 Expression::Transform(e) => self.generate_transform(e),
3946 Expression::TransformModelProperty(e) => self.generate_transform_model_property(e),
3947 Expression::TransientProperty(e) => self.generate_transient_property(e),
3948 Expression::Translate(e) => self.generate_translate(e),
3949 Expression::TranslateCharacters(e) => self.generate_translate_characters(e),
3950 Expression::TruncateTable(e) => self.generate_truncate_table(e),
3951 Expression::TryBase64DecodeBinary(e) => self.generate_try_base64_decode_binary(e),
3952 Expression::TryBase64DecodeString(e) => self.generate_try_base64_decode_string(e),
3953 Expression::TryToDecfloat(e) => self.generate_try_to_decfloat(e),
3954 Expression::TsOrDsAdd(e) => self.generate_ts_or_ds_add(e),
3955 Expression::TsOrDsDiff(e) => self.generate_ts_or_ds_diff(e),
3956 Expression::TsOrDsToDate(e) => self.generate_ts_or_ds_to_date(e),
3957 Expression::TsOrDsToTime(e) => self.generate_ts_or_ds_to_time(e),
3958 Expression::Unhex(e) => self.generate_unhex(e),
3959 Expression::UnicodeString(e) => self.generate_unicode_string(e),
3960 Expression::Uniform(e) => self.generate_uniform(e),
3961 Expression::UniqueColumnConstraint(e) => self.generate_unique_column_constraint(e),
3962 Expression::UniqueKeyProperty(e) => self.generate_unique_key_property(e),
3963 Expression::RollupProperty(e) => self.generate_rollup_property(e),
3964 Expression::UnixToStr(e) => self.generate_unix_to_str(e),
3965 Expression::UnixToTime(e) => self.generate_unix_to_time(e),
3966 Expression::UnpivotColumns(e) => self.generate_unpivot_columns(e),
3967 Expression::UserDefinedFunction(e) => self.generate_user_defined_function(e),
3968 Expression::UsingTemplateProperty(e) => self.generate_using_template_property(e),
3969 Expression::UtcTime(e) => self.generate_utc_time(e),
3970 Expression::UtcTimestamp(e) => self.generate_utc_timestamp(e),
3971 Expression::Uuid(e) => self.generate_uuid(e),
3972 Expression::Var(v) => {
3973 if matches!(self.config.dialect, Some(DialectType::MySQL))
3974 && v.this.len() > 2
3975 && (v.this.starts_with("0x") || v.this.starts_with("0X"))
3976 && !v.this[2..].chars().all(|c| c.is_ascii_hexdigit())
3977 {
3978 return self.generate_identifier(&Identifier {
3979 name: v.this.clone(),
3980 quoted: true,
3981 trailing_comments: Vec::new(),
3982 span: None,
3983 });
3984 }
3985 self.write(&v.this);
3986 Ok(())
3987 }
3988 Expression::Variadic(e) => {
3989 self.write_keyword("VARIADIC");
3990 self.write_space();
3991 self.generate_expression(&e.this)?;
3992 Ok(())
3993 }
3994 Expression::VarMap(e) => self.generate_var_map(e),
3995 Expression::VectorSearch(e) => self.generate_vector_search(e),
3996 Expression::Version(e) => self.generate_version(e),
3997 Expression::ViewAttributeProperty(e) => self.generate_view_attribute_property(e),
3998 Expression::VolatileProperty(e) => self.generate_volatile_property(e),
3999 Expression::WatermarkColumnConstraint(e) => {
4000 self.generate_watermark_column_constraint(e)
4001 }
4002 Expression::Week(e) => self.generate_week(e),
4003 Expression::When(e) => self.generate_when(e),
4004 Expression::Whens(e) => self.generate_whens(e),
4005 Expression::Where(e) => self.generate_where(e),
4006 Expression::WidthBucket(e) => self.generate_width_bucket(e),
4007 Expression::Window(e) => self.generate_window(e),
4008 Expression::WindowSpec(e) => self.generate_window_spec(e),
4009 Expression::WithDataProperty(e) => self.generate_with_data_property(e),
4010 Expression::WithFill(e) => self.generate_with_fill(e),
4011 Expression::WithJournalTableProperty(e) => self.generate_with_journal_table_property(e),
4012 Expression::WithOperator(e) => self.generate_with_operator(e),
4013 Expression::WithProcedureOptions(e) => self.generate_with_procedure_options(e),
4014 Expression::WithSchemaBindingProperty(e) => {
4015 self.generate_with_schema_binding_property(e)
4016 }
4017 Expression::WithSystemVersioningProperty(e) => {
4018 self.generate_with_system_versioning_property(e)
4019 }
4020 Expression::WithTableHint(e) => self.generate_with_table_hint(e),
4021 Expression::XMLElement(e) => self.generate_xml_element(e),
4022 Expression::XMLGet(e) => self.generate_xml_get(e),
4023 Expression::XMLKeyValueOption(e) => self.generate_xml_key_value_option(e),
4024 Expression::XMLTable(e) => self.generate_xml_table(e),
4025 Expression::Xor(e) => self.generate_xor(e),
4026 Expression::Zipf(e) => self.generate_zipf(e),
4027 _ => self.write_unsupported_comment("unsupported expression"),
4028 }
4029 }
4030
4031 fn generate_select(&mut self, select: &Select) -> Result<()> {
4032 use crate::dialects::DialectType;
4033
4034 if let Some(exclude) = &select.exclude {
4038 if !exclude.is_empty() && !matches!(self.config.dialect, Some(DialectType::Redshift)) {
4039 let mut inner_select = select.clone();
4041 inner_select.exclude = None;
4042 let inner_expr = Expression::Select(Box::new(inner_select));
4043
4044 let subquery = crate::expressions::Subquery {
4046 this: inner_expr,
4047 alias: None,
4048 column_aliases: Vec::new(),
4049 alias_explicit_as: false,
4050 alias_keyword: None,
4051 order_by: None,
4052 limit: None,
4053 offset: None,
4054 distribute_by: None,
4055 sort_by: None,
4056 cluster_by: None,
4057 lateral: false,
4058 modifiers_inside: false,
4059 trailing_comments: Vec::new(),
4060 inferred_type: None,
4061 };
4062
4063 let star = Expression::Star(crate::expressions::Star {
4065 table: None,
4066 except: Some(
4067 exclude
4068 .iter()
4069 .map(|e| match e {
4070 Expression::Column(col) => col.name.clone(),
4071 Expression::Identifier(id) => id.clone(),
4072 _ => crate::expressions::Identifier::new("unknown".to_string()),
4073 })
4074 .collect(),
4075 ),
4076 replace: None,
4077 rename: None,
4078 trailing_comments: Vec::new(),
4079 span: None,
4080 });
4081
4082 let outer_select = Select {
4083 expressions: vec![star],
4084 from: Some(crate::expressions::From {
4085 expressions: vec![Expression::Subquery(Box::new(subquery))],
4086 }),
4087 ..Select::new()
4088 };
4089
4090 return self.generate_select(&outer_select);
4091 }
4092 }
4093
4094 for comment in &select.leading_comments {
4096 self.write_formatted_comment(comment);
4097 self.write(" ");
4098 }
4099
4100 if let Some(with) = &select.with {
4102 self.generate_with(with)?;
4103 if self.config.pretty {
4104 self.write_newline();
4105 self.write_indent();
4106 } else {
4107 self.write_space();
4108 }
4109 }
4110
4111 for comment in &select.post_select_comments {
4114 self.write_formatted_comment(comment);
4115 self.write(" ");
4116 }
4117
4118 self.write_keyword("SELECT");
4119
4120 if let Some(hint) = &select.hint {
4122 self.generate_hint(hint)?;
4123 }
4124
4125 let use_top_from_limit = matches!(
4129 self.config.dialect,
4130 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4131 ) && select.top.is_none()
4132 && select.limit.is_some()
4133 && select.offset.is_none(); let is_top_dialect = matches!(
4138 self.config.dialect,
4139 Some(DialectType::TSQL) | Some(DialectType::Teradata) | Some(DialectType::Fabric)
4140 );
4141 let keep_top_verbatim = !is_top_dialect
4142 && select.limit.is_none()
4143 && select
4144 .top
4145 .as_ref()
4146 .map_or(false, |top| top.percent || top.with_ties);
4147
4148 if select.distinct && (is_top_dialect || select.top.is_some()) {
4149 self.write_space();
4150 self.write_keyword("DISTINCT");
4151 }
4152
4153 if is_top_dialect || keep_top_verbatim {
4154 if let Some(top) = &select.top {
4155 self.write_space();
4156 self.write_keyword("TOP");
4157 if top.parenthesized {
4158 if matches!(&top.this, Expression::Subquery(_) | Expression::Paren(_)) {
4159 self.write_space();
4160 self.generate_expression(&top.this)?;
4161 } else {
4162 self.write(" (");
4163 self.generate_expression(&top.this)?;
4164 self.write(")");
4165 }
4166 } else {
4167 self.write_space();
4168 self.generate_expression(&top.this)?;
4169 }
4170 if top.percent {
4171 self.write_space();
4172 self.write_keyword("PERCENT");
4173 }
4174 if top.with_ties {
4175 self.write_space();
4176 self.write_keyword("WITH TIES");
4177 }
4178 } else if use_top_from_limit {
4179 if let Some(limit) = &select.limit {
4181 self.write_space();
4182 self.write_keyword("TOP");
4183 let is_simple_literal = matches!(&limit.this, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)));
4185 if is_simple_literal {
4186 self.write_space();
4187 self.generate_expression(&limit.this)?;
4188 } else {
4189 self.write(" (");
4190 self.generate_expression(&limit.this)?;
4191 self.write(")");
4192 }
4193 }
4194 }
4195 }
4196
4197 if select.distinct && !is_top_dialect && select.top.is_none() {
4198 self.write_space();
4199 self.write_keyword("DISTINCT");
4200 }
4201
4202 if let Some(distinct_on) = &select.distinct_on {
4204 self.write_space();
4205 self.write_keyword("ON");
4206 self.write(" (");
4207 for (i, expr) in distinct_on.iter().enumerate() {
4208 if i > 0 {
4209 self.write(", ");
4210 }
4211 self.generate_expression(expr)?;
4212 }
4213 self.write(")");
4214 }
4215
4216 for modifier in &select.operation_modifiers {
4218 self.write_space();
4219 self.write_keyword(modifier);
4220 }
4221
4222 if let Some(kind) = &select.kind {
4224 self.write_space();
4225 self.write_keyword("AS");
4226 self.write_space();
4227 self.write_keyword(kind);
4228 }
4229
4230 if !select.expressions.is_empty() {
4232 if self.config.pretty {
4233 self.write_newline();
4234 self.indent_level += 1;
4235 } else {
4236 self.write_space();
4237 }
4238 }
4239
4240 for (i, expr) in select.expressions.iter().enumerate() {
4241 if i > 0 {
4242 self.write(",");
4243 if self.config.pretty {
4244 self.write_newline();
4245 } else {
4246 self.write_space();
4247 }
4248 }
4249 if self.config.pretty {
4250 self.write_indent();
4251 }
4252 self.generate_expression(expr)?;
4253 }
4254
4255 if self.config.pretty && !select.expressions.is_empty() {
4256 self.indent_level -= 1;
4257 }
4258
4259 if let Some(exclude) = &select.exclude {
4264 if !exclude.is_empty() && matches!(self.config.dialect, Some(DialectType::Redshift)) {
4265 self.write_space();
4266 self.write_keyword("EXCLUDE");
4267 self.write(" (");
4268 for (i, col) in exclude.iter().enumerate() {
4269 if i > 0 {
4270 self.write(", ");
4271 }
4272 self.generate_expression(col)?;
4273 }
4274 self.write(")");
4275 }
4276 }
4277
4278 if let Some(into) = &select.into {
4281 if self.config.pretty {
4282 self.write_newline();
4283 self.write_indent();
4284 } else {
4285 self.write_space();
4286 }
4287 if into.bulk_collect {
4288 self.write_keyword("BULK COLLECT INTO");
4289 } else {
4290 self.write_keyword("INTO");
4291 }
4292 if into.temporary {
4293 self.write_space();
4294 self.write_keyword("TEMPORARY");
4295 }
4296 if into.unlogged {
4297 self.write_space();
4298 self.write_keyword("UNLOGGED");
4299 }
4300 self.write_space();
4301 if !into.expressions.is_empty() {
4303 for (i, expr) in into.expressions.iter().enumerate() {
4304 if i > 0 {
4305 self.write(", ");
4306 }
4307 self.generate_expression(expr)?;
4308 }
4309 } else {
4310 self.generate_expression(&into.this)?;
4311 }
4312 }
4313
4314 if let Some(from) = &select.from {
4316 if self.config.pretty {
4317 self.write_newline();
4318 self.write_indent();
4319 } else {
4320 self.write_space();
4321 }
4322 self.write_keyword("FROM");
4323 self.write_space();
4324
4325 let has_tablesample = from
4330 .expressions
4331 .iter()
4332 .any(|e| matches!(e, Expression::TableSample(_)));
4333 let is_cross_join_dialect = matches!(
4334 self.config.dialect,
4335 Some(DialectType::BigQuery)
4336 | Some(DialectType::Hive)
4337 | Some(DialectType::Spark)
4338 | Some(DialectType::Databricks)
4339 | Some(DialectType::SQLite)
4340 | Some(DialectType::ClickHouse)
4341 );
4342 let source_is_same_as_target = self.config.source_dialect.is_some()
4345 && self.config.source_dialect == self.config.dialect;
4346 let source_is_cross_join_dialect = matches!(
4347 self.config.source_dialect,
4348 Some(DialectType::BigQuery)
4349 | Some(DialectType::Hive)
4350 | Some(DialectType::Spark)
4351 | Some(DialectType::Databricks)
4352 | Some(DialectType::SQLite)
4353 | Some(DialectType::ClickHouse)
4354 );
4355 let use_cross_join = !has_tablesample
4356 && is_cross_join_dialect
4357 && (source_is_same_as_target
4358 || source_is_cross_join_dialect
4359 || self.config.source_dialect.is_none());
4360
4361 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
4363
4364 for (i, expr) in from.expressions.iter().enumerate() {
4365 if i > 0 {
4366 if use_cross_join {
4367 self.write(" CROSS JOIN ");
4368 } else {
4369 self.write(", ");
4370 }
4371 }
4372 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
4373 self.write("(");
4374 self.generate_expression(expr)?;
4375 self.write(")");
4376 } else {
4377 self.generate_expression(expr)?;
4378 }
4379 let leading = Self::extract_table_leading_comments(expr);
4382 for comment in &leading {
4383 self.write_space();
4384 self.write_formatted_comment(comment);
4385 }
4386 }
4387 }
4388
4389 if self.config.pretty {
4393 self.generate_joins_with_nesting(&select.joins)?;
4394 } else {
4395 for join in &select.joins {
4396 self.generate_join(join)?;
4397 }
4398 for join in select.joins.iter().rev() {
4400 if join.deferred_condition {
4401 self.generate_join_condition(join)?;
4402 }
4403 }
4404 }
4405
4406 for (lv_idx, lateral_view) in select.lateral_views.iter().enumerate() {
4408 self.generate_lateral_view(lateral_view, lv_idx)?;
4409 }
4410
4411 if let Some(prewhere) = &select.prewhere {
4413 self.write_clause_condition("PREWHERE", prewhere)?;
4414 }
4415
4416 if let Some(where_clause) = &select.where_clause {
4418 self.write_clause_condition("WHERE", &where_clause.this)?;
4419 }
4420
4421 if let Some(connect) = &select.connect {
4423 self.generate_connect(connect)?;
4424 }
4425
4426 if let Some(group_by) = &select.group_by {
4428 if self.config.pretty {
4429 for comment in &group_by.comments {
4431 self.write_newline();
4432 self.write_indent();
4433 self.write_formatted_comment(comment);
4434 }
4435 self.write_newline();
4436 self.write_indent();
4437 } else {
4438 self.write_space();
4439 for comment in &group_by.comments {
4441 self.write_formatted_comment(comment);
4442 self.write_space();
4443 }
4444 }
4445 let clickhouse_bare_modifiers =
4446 matches!(self.config.dialect, Some(DialectType::ClickHouse))
4447 && group_by.all.is_none()
4448 && (group_by.totals || !group_by.expressions.is_empty())
4449 && group_by.expressions.iter().all(|expr| match expr {
4450 Expression::Cube(c) => c.expressions.is_empty(),
4451 Expression::Rollup(r) => r.expressions.is_empty(),
4452 _ => false,
4453 });
4454
4455 if clickhouse_bare_modifiers {
4456 let trailing_cube = group_by
4457 .expressions
4458 .iter()
4459 .any(|expr| matches!(expr, Expression::Cube(c) if c.expressions.is_empty()));
4460 let trailing_rollup = group_by
4461 .expressions
4462 .iter()
4463 .any(|expr| matches!(expr, Expression::Rollup(r) if r.expressions.is_empty()));
4464
4465 if trailing_cube {
4466 self.write_keyword("WITH CUBE");
4467 } else if trailing_rollup {
4468 self.write_keyword("WITH ROLLUP");
4469 }
4470
4471 if group_by.totals {
4472 if trailing_cube || trailing_rollup {
4473 self.write_space();
4474 }
4475 self.write_keyword("WITH TOTALS");
4476 }
4477 } else {
4478 self.write_keyword("GROUP BY");
4479 match group_by.all {
4481 Some(true) => {
4482 self.write_space();
4483 self.write_keyword("ALL");
4484 }
4485 Some(false) => {
4486 self.write_space();
4487 self.write_keyword("DISTINCT");
4488 }
4489 None => {}
4490 }
4491 if !group_by.expressions.is_empty() {
4492 let mut trailing_cube = false;
4495 let mut trailing_rollup = false;
4496 let mut plain_expressions: Vec<&Expression> = Vec::new();
4497 let mut grouping_sets_expressions: Vec<&Expression> = Vec::new();
4498 let mut cube_expressions: Vec<&Expression> = Vec::new();
4499 let mut rollup_expressions: Vec<&Expression> = Vec::new();
4500
4501 for expr in &group_by.expressions {
4502 match expr {
4503 Expression::Cube(c) if c.expressions.is_empty() => {
4504 trailing_cube = true;
4505 }
4506 Expression::Rollup(r) if r.expressions.is_empty() => {
4507 trailing_rollup = true;
4508 }
4509 Expression::Function(f) if f.name == "CUBE" => {
4510 cube_expressions.push(expr);
4511 }
4512 Expression::Function(f) if f.name == "ROLLUP" => {
4513 rollup_expressions.push(expr);
4514 }
4515 Expression::Function(f) if f.name == "GROUPING SETS" => {
4516 grouping_sets_expressions.push(expr);
4517 }
4518 _ => {
4519 plain_expressions.push(expr);
4520 }
4521 }
4522 }
4523
4524 let mut regular_expressions: Vec<&Expression> = Vec::new();
4526 regular_expressions.extend(plain_expressions);
4527 regular_expressions.extend(grouping_sets_expressions);
4528 regular_expressions.extend(cube_expressions);
4529 regular_expressions.extend(rollup_expressions);
4530
4531 if self.config.pretty {
4532 self.write_newline();
4533 self.indent_level += 1;
4534 self.write_indent();
4535 } else {
4536 self.write_space();
4537 }
4538
4539 for (i, expr) in regular_expressions.iter().enumerate() {
4540 if i > 0 {
4541 if self.config.pretty {
4542 self.write(",");
4543 self.write_newline();
4544 self.write_indent();
4545 } else {
4546 self.write(", ");
4547 }
4548 }
4549 self.generate_expression(expr)?;
4550 }
4551
4552 if self.config.pretty {
4553 self.indent_level -= 1;
4554 }
4555
4556 if trailing_cube {
4558 self.write_space();
4559 self.write_keyword("WITH CUBE");
4560 } else if trailing_rollup {
4561 self.write_space();
4562 self.write_keyword("WITH ROLLUP");
4563 }
4564 }
4565
4566 if group_by.totals {
4568 self.write_space();
4569 self.write_keyword("WITH TOTALS");
4570 }
4571 }
4572 }
4573
4574 if let Some(having) = &select.having {
4576 if self.config.pretty {
4577 for comment in &having.comments {
4579 self.write_newline();
4580 self.write_indent();
4581 self.write_formatted_comment(comment);
4582 }
4583 } else {
4584 for comment in &having.comments {
4585 self.write_space();
4586 self.write_formatted_comment(comment);
4587 }
4588 }
4589 self.write_clause_condition("HAVING", &having.this)?;
4590 }
4591
4592 if select.qualify_after_window {
4594 if let Some(windows) = &select.windows {
4596 self.write_window_clause(windows)?;
4597 }
4598 if let Some(qualify) = &select.qualify {
4599 self.write_clause_condition("QUALIFY", &qualify.this)?;
4600 }
4601 } else {
4602 if let Some(qualify) = &select.qualify {
4604 self.write_clause_condition("QUALIFY", &qualify.this)?;
4605 }
4606 if let Some(windows) = &select.windows {
4607 self.write_window_clause(windows)?;
4608 }
4609 }
4610
4611 if let Some(distribute_by) = &select.distribute_by {
4613 self.write_clause_expressions("DISTRIBUTE BY", &distribute_by.expressions)?;
4614 }
4615
4616 if let Some(cluster_by) = &select.cluster_by {
4618 self.write_order_clause("CLUSTER BY", &cluster_by.expressions)?;
4619 }
4620
4621 if let Some(sort_by) = &select.sort_by {
4623 self.write_order_clause("SORT BY", &sort_by.expressions)?;
4624 }
4625
4626 if let Some(order_by) = &select.order_by {
4628 if self.config.pretty {
4629 for comment in &order_by.comments {
4631 self.write_newline();
4632 self.write_indent();
4633 self.write_formatted_comment(comment);
4634 }
4635 } else {
4636 for comment in &order_by.comments {
4637 self.write_space();
4638 self.write_formatted_comment(comment);
4639 }
4640 }
4641 let keyword = if order_by.siblings {
4642 "ORDER SIBLINGS BY"
4643 } else {
4644 "ORDER BY"
4645 };
4646 self.write_order_clause(keyword, &order_by.expressions)?;
4647 }
4648
4649 if select.order_by.is_none()
4651 && select.fetch.is_some()
4652 && matches!(
4653 self.config.dialect,
4654 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4655 )
4656 {
4657 if self.config.pretty {
4658 self.write_newline();
4659 self.write_indent();
4660 } else {
4661 self.write_space();
4662 }
4663 self.write_keyword("ORDER BY (SELECT NULL) OFFSET 0 ROWS");
4664 }
4665
4666 let is_presto_like = matches!(
4671 self.config.dialect,
4672 Some(DialectType::Presto) | Some(DialectType::Trino)
4673 );
4674
4675 if is_presto_like && select.offset.is_some() {
4676 if let Some(offset) = &select.offset {
4678 if self.config.pretty {
4679 self.write_newline();
4680 self.write_indent();
4681 } else {
4682 self.write_space();
4683 }
4684 self.write_keyword("OFFSET");
4685 self.write_space();
4686 self.write_limit_expr(&offset.this)?;
4687 if offset.rows == Some(true) {
4688 self.write_space();
4689 self.write_keyword("ROWS");
4690 }
4691 }
4692 if let Some(limit) = &select.limit {
4693 if self.config.pretty {
4694 self.write_newline();
4695 self.write_indent();
4696 } else {
4697 self.write_space();
4698 }
4699 self.write_keyword("LIMIT");
4700 self.write_space();
4701 self.write_limit_expr(&limit.this)?;
4702 if limit.percent {
4703 self.write_space();
4704 self.write_keyword("PERCENT");
4705 }
4706 for comment in &limit.comments {
4708 self.write(" ");
4709 self.write_formatted_comment(comment);
4710 }
4711 }
4712 } else {
4713 let fetch_as_limit = select.fetch.as_ref().map_or(false, |fetch| {
4715 !fetch.percent
4716 && !fetch.with_ties
4717 && fetch.count.is_some()
4718 && matches!(
4719 self.config.dialect,
4720 Some(DialectType::Spark)
4721 | Some(DialectType::Hive)
4722 | Some(DialectType::DuckDB)
4723 | Some(DialectType::SQLite)
4724 | Some(DialectType::MySQL)
4725 | Some(DialectType::BigQuery)
4726 | Some(DialectType::Databricks)
4727 | Some(DialectType::StarRocks)
4728 | Some(DialectType::Doris)
4729 | Some(DialectType::Athena)
4730 | Some(DialectType::ClickHouse)
4731 | Some(DialectType::Redshift)
4732 )
4733 });
4734
4735 if let Some(limit) = &select.limit {
4737 if !matches!(
4739 self.config.dialect,
4740 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4741 ) {
4742 if self.config.pretty {
4743 self.write_newline();
4744 self.write_indent();
4745 } else {
4746 self.write_space();
4747 }
4748 self.write_keyword("LIMIT");
4749 self.write_space();
4750 self.write_limit_expr(&limit.this)?;
4751 if limit.percent {
4752 self.write_space();
4753 self.write_keyword("PERCENT");
4754 }
4755 for comment in &limit.comments {
4757 self.write(" ");
4758 self.write_formatted_comment(comment);
4759 }
4760 }
4761 }
4762
4763 if select.top.is_some() && !is_top_dialect && select.limit.is_none() {
4765 if let Some(top) = &select.top {
4766 if !top.percent && !top.with_ties {
4767 if self.config.pretty {
4768 self.write_newline();
4769 self.write_indent();
4770 } else {
4771 self.write_space();
4772 }
4773 self.write_keyword("LIMIT");
4774 self.write_space();
4775 self.generate_expression(&top.this)?;
4776 }
4777 }
4778 }
4779
4780 if fetch_as_limit && select.offset.is_some() {
4783 if let Some(fetch) = &select.fetch {
4784 if self.config.pretty {
4785 self.write_newline();
4786 self.write_indent();
4787 } else {
4788 self.write_space();
4789 }
4790 self.write_keyword("LIMIT");
4791 self.write_space();
4792 self.generate_expression(fetch.count.as_ref().unwrap())?;
4793 }
4794 }
4795
4796 if let Some(offset) = &select.offset {
4800 if self.config.pretty {
4801 self.write_newline();
4802 self.write_indent();
4803 } else {
4804 self.write_space();
4805 }
4806 if matches!(self.config.dialect, Some(DialectType::TSQL)) {
4807 self.write_keyword("OFFSET");
4809 self.write_space();
4810 self.write_limit_expr(&offset.this)?;
4811 self.write_space();
4812 self.write_keyword("ROWS");
4813 if let Some(limit) = &select.limit {
4815 self.write_space();
4816 self.write_keyword("FETCH NEXT");
4817 self.write_space();
4818 self.write_limit_expr(&limit.this)?;
4819 self.write_space();
4820 self.write_keyword("ROWS ONLY");
4821 }
4822 } else {
4823 self.write_keyword("OFFSET");
4824 self.write_space();
4825 self.write_limit_expr(&offset.this)?;
4826 if offset.rows == Some(true) {
4828 self.write_space();
4829 self.write_keyword("ROWS");
4830 }
4831 }
4832 }
4833 }
4834
4835 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4837 if let Some(limit_by) = &select.limit_by {
4838 if !limit_by.is_empty() {
4839 self.write_space();
4840 self.write_keyword("BY");
4841 self.write_space();
4842 for (i, expr) in limit_by.iter().enumerate() {
4843 if i > 0 {
4844 self.write(", ");
4845 }
4846 self.generate_expression(expr)?;
4847 }
4848 }
4849 }
4850 }
4851
4852 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4854 if let Some(settings) = &select.settings {
4855 if self.config.pretty {
4856 self.write_newline();
4857 self.write_indent();
4858 } else {
4859 self.write_space();
4860 }
4861 self.write_keyword("SETTINGS");
4862 self.write_space();
4863 for (i, expr) in settings.iter().enumerate() {
4864 if i > 0 {
4865 self.write(", ");
4866 }
4867 self.generate_expression(expr)?;
4868 }
4869 }
4870
4871 if let Some(format_expr) = &select.format {
4872 if self.config.pretty {
4873 self.write_newline();
4874 self.write_indent();
4875 } else {
4876 self.write_space();
4877 }
4878 self.write_keyword("FORMAT");
4879 self.write_space();
4880 self.generate_expression(format_expr)?;
4881 }
4882 }
4883
4884 if let Some(fetch) = &select.fetch {
4886 let fetch_already_as_limit = select.offset.is_some()
4888 && !fetch.percent
4889 && !fetch.with_ties
4890 && fetch.count.is_some()
4891 && matches!(
4892 self.config.dialect,
4893 Some(DialectType::Spark)
4894 | Some(DialectType::Hive)
4895 | Some(DialectType::DuckDB)
4896 | Some(DialectType::SQLite)
4897 | Some(DialectType::MySQL)
4898 | Some(DialectType::BigQuery)
4899 | Some(DialectType::Databricks)
4900 | Some(DialectType::StarRocks)
4901 | Some(DialectType::Doris)
4902 | Some(DialectType::Athena)
4903 | Some(DialectType::ClickHouse)
4904 | Some(DialectType::Redshift)
4905 );
4906
4907 if fetch_already_as_limit {
4908 } else {
4910 if self.config.pretty {
4911 self.write_newline();
4912 self.write_indent();
4913 } else {
4914 self.write_space();
4915 }
4916
4917 let use_limit = !fetch.percent
4919 && !fetch.with_ties
4920 && fetch.count.is_some()
4921 && matches!(
4922 self.config.dialect,
4923 Some(DialectType::Spark)
4924 | Some(DialectType::Hive)
4925 | Some(DialectType::DuckDB)
4926 | Some(DialectType::SQLite)
4927 | Some(DialectType::MySQL)
4928 | Some(DialectType::BigQuery)
4929 | Some(DialectType::Databricks)
4930 | Some(DialectType::StarRocks)
4931 | Some(DialectType::Doris)
4932 | Some(DialectType::Athena)
4933 | Some(DialectType::ClickHouse)
4934 | Some(DialectType::Redshift)
4935 );
4936
4937 if use_limit {
4938 self.write_keyword("LIMIT");
4939 self.write_space();
4940 self.generate_expression(fetch.count.as_ref().unwrap())?;
4941 } else {
4942 self.write_keyword("FETCH");
4943 self.write_space();
4944 self.write_keyword(&fetch.direction);
4945 if let Some(ref count) = fetch.count {
4946 self.write_space();
4947 self.generate_expression(count)?;
4948 }
4949 if fetch.percent {
4950 self.write_space();
4951 self.write_keyword("PERCENT");
4952 }
4953 if fetch.rows {
4954 self.write_space();
4955 self.write_keyword("ROWS");
4956 }
4957 if fetch.with_ties {
4958 self.write_space();
4959 self.write_keyword("WITH TIES");
4960 } else {
4961 self.write_space();
4962 self.write_keyword("ONLY");
4963 }
4964 }
4965 } }
4967
4968 if let Some(sample) = &select.sample {
4970 use crate::dialects::DialectType;
4971 if self.config.pretty {
4972 self.write_newline();
4973 } else {
4974 self.write_space();
4975 }
4976
4977 if sample.is_using_sample {
4978 self.write_keyword("USING SAMPLE");
4980 self.generate_sample_body(sample)?;
4981 } else {
4982 self.write_keyword("TABLESAMPLE");
4983
4984 let snowflake_bernoulli =
4986 matches!(self.config.dialect, Some(DialectType::Snowflake))
4987 && !sample.explicit_method;
4988 if snowflake_bernoulli {
4989 self.write_space();
4990 self.write_keyword("BERNOULLI");
4991 }
4992
4993 if matches!(sample.method, SampleMethod::Bucket) {
4995 self.write_space();
4996 self.write("(");
4997 self.write_keyword("BUCKET");
4998 self.write_space();
4999 if let Some(ref num) = sample.bucket_numerator {
5000 self.generate_expression(num)?;
5001 }
5002 self.write_space();
5003 self.write_keyword("OUT OF");
5004 self.write_space();
5005 if let Some(ref denom) = sample.bucket_denominator {
5006 self.generate_expression(denom)?;
5007 }
5008 if let Some(ref field) = sample.bucket_field {
5009 self.write_space();
5010 self.write_keyword("ON");
5011 self.write_space();
5012 self.generate_expression(field)?;
5013 }
5014 self.write(")");
5015 } else if sample.unit_after_size {
5016 if sample.explicit_method && sample.method_before_size {
5018 self.write_space();
5019 match sample.method {
5020 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
5021 SampleMethod::System => self.write_keyword("SYSTEM"),
5022 SampleMethod::Block => self.write_keyword("BLOCK"),
5023 SampleMethod::Row => self.write_keyword("ROW"),
5024 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
5025 _ => {}
5026 }
5027 }
5028 self.write(" (");
5029 self.generate_expression(&sample.size)?;
5030 self.write_space();
5031 match sample.method {
5032 SampleMethod::Percent => self.write_keyword("PERCENT"),
5033 SampleMethod::Row => self.write_keyword("ROWS"),
5034 SampleMethod::Reservoir => self.write_keyword("ROWS"),
5035 _ => {
5036 self.write_keyword("PERCENT");
5037 }
5038 }
5039 self.write(")");
5040 } else {
5041 self.write_space();
5043 match sample.method {
5044 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
5045 SampleMethod::System => self.write_keyword("SYSTEM"),
5046 SampleMethod::Block => self.write_keyword("BLOCK"),
5047 SampleMethod::Row => self.write_keyword("ROW"),
5048 SampleMethod::Percent => self.write_keyword("BERNOULLI"),
5049 SampleMethod::Bucket => {}
5050 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
5051 }
5052 self.write(" (");
5053 self.generate_expression(&sample.size)?;
5054 if matches!(sample.method, SampleMethod::Percent) {
5055 self.write_space();
5056 self.write_keyword("PERCENT");
5057 }
5058 self.write(")");
5059 }
5060 }
5061
5062 if let Some(seed) = &sample.seed {
5063 self.write_space();
5064 let use_seed = sample.use_seed_keyword
5066 && !matches!(
5067 self.config.dialect,
5068 Some(crate::dialects::DialectType::Databricks)
5069 | Some(crate::dialects::DialectType::Spark)
5070 );
5071 if use_seed {
5072 self.write_keyword("SEED");
5073 } else {
5074 self.write_keyword("REPEATABLE");
5075 }
5076 self.write(" (");
5077 self.generate_expression(seed)?;
5078 self.write(")");
5079 }
5080 }
5081
5082 if self.config.locking_reads_supported {
5085 for lock in &select.locks {
5086 if self.config.pretty {
5087 self.write_newline();
5088 self.write_indent();
5089 } else {
5090 self.write_space();
5091 }
5092 self.generate_lock(lock)?;
5093 }
5094 }
5095
5096 if !select.for_xml.is_empty() {
5098 if self.config.pretty {
5099 self.write_newline();
5100 self.write_indent();
5101 } else {
5102 self.write_space();
5103 }
5104 self.write_keyword("FOR XML");
5105 for (i, opt) in select.for_xml.iter().enumerate() {
5106 if self.config.pretty {
5107 if i > 0 {
5108 self.write(",");
5109 }
5110 self.write_newline();
5111 self.write_indent();
5112 self.write(" "); } else {
5114 if i > 0 {
5115 self.write(",");
5116 }
5117 self.write_space();
5118 }
5119 self.generate_for_xml_option(opt)?;
5120 }
5121 }
5122
5123 if !select.for_json.is_empty() {
5125 if self.config.pretty {
5126 self.write_newline();
5127 self.write_indent();
5128 } else {
5129 self.write_space();
5130 }
5131 self.write_keyword("FOR JSON");
5132 for (i, opt) in select.for_json.iter().enumerate() {
5133 if self.config.pretty {
5134 if i > 0 {
5135 self.write(",");
5136 }
5137 self.write_newline();
5138 self.write_indent();
5139 self.write(" "); } else {
5141 if i > 0 {
5142 self.write(",");
5143 }
5144 self.write_space();
5145 }
5146 self.generate_for_xml_option(opt)?;
5147 }
5148 }
5149
5150 if let Some(ref option) = select.option {
5152 if matches!(
5153 self.config.dialect,
5154 Some(crate::dialects::DialectType::TSQL)
5155 | Some(crate::dialects::DialectType::Fabric)
5156 ) {
5157 self.write_space();
5158 self.write(option);
5159 }
5160 }
5161
5162 Ok(())
5163 }
5164
5165 fn generate_for_xml_option(&mut self, opt: &Expression) -> Result<()> {
5167 match opt {
5168 Expression::QueryOption(qo) => {
5169 if let Expression::Var(var) = &*qo.this {
5171 self.write(&var.this);
5172 } else {
5173 self.generate_expression(&qo.this)?;
5174 }
5175 if let Some(expr) = &qo.expression {
5177 self.write("(");
5178 self.generate_expression(expr)?;
5179 self.write(")");
5180 }
5181 }
5182 _ => {
5183 self.generate_expression(opt)?;
5184 }
5185 }
5186 Ok(())
5187 }
5188
5189 fn generate_with(&mut self, with: &With) -> Result<()> {
5190 use crate::dialects::DialectType;
5191
5192 for comment in &with.leading_comments {
5194 self.write_formatted_comment(comment);
5195 self.write(" ");
5196 }
5197 self.write_keyword("WITH");
5198 if with.recursive && self.config.cte_recursive_keyword_required {
5199 self.write_space();
5200 self.write_keyword("RECURSIVE");
5201 }
5202 self.write_space();
5203
5204 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
5206
5207 for (i, cte) in with.ctes.iter().enumerate() {
5208 if i > 0 {
5209 self.write(",");
5210 if self.config.pretty {
5211 self.write_space();
5212 } else {
5213 self.write(" ");
5214 }
5215 }
5216 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !cte.alias_first {
5217 self.generate_expression(&cte.this)?;
5218 self.write_space();
5219 self.write_keyword("AS");
5220 self.write_space();
5221 self.generate_identifier(&cte.alias)?;
5222 continue;
5223 }
5224 self.generate_identifier(&cte.alias)?;
5225 for comment in &cte.comments {
5227 self.write_space();
5228 self.write_formatted_comment(comment);
5229 }
5230 if !cte.columns.is_empty() && !skip_cte_columns {
5231 self.write("(");
5232 for (j, col) in cte.columns.iter().enumerate() {
5233 if j > 0 {
5234 self.write(", ");
5235 }
5236 self.generate_identifier(col)?;
5237 }
5238 self.write(")");
5239 }
5240 if !cte.key_expressions.is_empty() {
5242 self.write_space();
5243 self.write_keyword("USING KEY");
5244 self.write(" (");
5245 for (i, key) in cte.key_expressions.iter().enumerate() {
5246 if i > 0 {
5247 self.write(", ");
5248 }
5249 self.generate_identifier(key)?;
5250 }
5251 self.write(")");
5252 }
5253 self.write_space();
5254 self.write_keyword("AS");
5255 if let Some(materialized) = cte.materialized {
5257 self.write_space();
5258 if materialized {
5259 self.write_keyword("MATERIALIZED");
5260 } else {
5261 self.write_keyword("NOT MATERIALIZED");
5262 }
5263 }
5264 self.write(" (");
5265 if self.config.pretty {
5266 self.write_newline();
5267 self.indent_level += 1;
5268 self.write_indent();
5269 }
5270 let wrap_values_in_select = matches!(
5273 self.config.dialect,
5274 Some(DialectType::Spark) | Some(DialectType::Databricks)
5275 ) && matches!(&cte.this, Expression::Values(_));
5276
5277 if wrap_values_in_select {
5278 self.write_keyword("SELECT");
5279 self.write(" * ");
5280 self.write_keyword("FROM");
5281 self.write_space();
5282 }
5283 self.generate_expression(&cte.this)?;
5284 if self.config.pretty {
5285 self.write_newline();
5286 self.indent_level -= 1;
5287 self.write_indent();
5288 }
5289 self.write(")");
5290 }
5291
5292 if let Some(search) = &with.search {
5294 self.write_space();
5295 self.generate_expression(search)?;
5296 }
5297
5298 Ok(())
5299 }
5300
5301 fn generate_joins_with_nesting(&mut self, joins: &[Join]) -> Result<()> {
5305 let mut i = 0;
5306 while i < joins.len() {
5307 if joins[i].deferred_condition {
5308 let parent_group = joins[i].nesting_group;
5309
5310 self.generate_join_without_condition(&joins[i])?;
5313
5314 let child_start = i + 1;
5316 let mut child_end = child_start;
5317 while child_end < joins.len()
5318 && !joins[child_end].deferred_condition
5319 && joins[child_end].nesting_group == parent_group
5320 {
5321 child_end += 1;
5322 }
5323
5324 if child_start < child_end {
5326 self.indent_level += 1;
5327 for j in child_start..child_end {
5328 self.generate_join(&joins[j])?;
5329 }
5330 self.indent_level -= 1;
5331 }
5332
5333 self.generate_join_condition(&joins[i])?;
5335
5336 i = child_end;
5337 } else {
5338 self.generate_join(&joins[i])?;
5340 i += 1;
5341 }
5342 }
5343 Ok(())
5344 }
5345
5346 fn generate_join_without_condition(&mut self, join: &Join) -> Result<()> {
5349 let mut join_copy = join.clone();
5352 join_copy.on = None;
5353 join_copy.using = Vec::new();
5354 join_copy.deferred_condition = false;
5355 self.generate_join(&join_copy)
5356 }
5357
5358 fn generate_join(&mut self, join: &Join) -> Result<()> {
5359 if join.kind == JoinKind::Implicit {
5361 self.write(",");
5362 if self.config.pretty {
5363 self.write_newline();
5364 self.write_indent();
5365 } else {
5366 self.write_space();
5367 }
5368 self.generate_expression(&join.this)?;
5369 return Ok(());
5370 }
5371
5372 if self.config.pretty {
5373 self.write_newline();
5374 self.write_indent();
5375 } else {
5376 self.write_space();
5377 }
5378
5379 let hint_str = if self.config.join_hints {
5382 join.join_hint
5383 .as_ref()
5384 .map(|h| format!(" {}", h))
5385 .unwrap_or_default()
5386 } else {
5387 String::new()
5388 };
5389
5390 let clickhouse_join_keyword =
5391 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
5392 if let Some(hint) = &join.join_hint {
5393 let mut global = false;
5394 let mut strictness: Option<&'static str> = None;
5395 for part in hint.split_whitespace() {
5396 if part.eq_ignore_ascii_case("GLOBAL") {
5397 global = true;
5398 } else if part.eq_ignore_ascii_case("ALL") {
5399 strictness = Some("ALL");
5400 } else if part.eq_ignore_ascii_case("ANY") {
5401 strictness = Some("ANY");
5402 } else if part.eq_ignore_ascii_case("ASOF") {
5403 strictness = Some("ASOF");
5404 } else if part.eq_ignore_ascii_case("SEMI") {
5405 strictness = Some("SEMI");
5406 } else if part.eq_ignore_ascii_case("ANTI") {
5407 strictness = Some("ANTI");
5408 }
5409 }
5410
5411 if global || strictness.is_some() {
5412 let join_type = match join.kind {
5413 JoinKind::Left => {
5414 if join.use_outer_keyword {
5415 "LEFT OUTER"
5416 } else if join.use_inner_keyword {
5417 "LEFT INNER"
5418 } else {
5419 "LEFT"
5420 }
5421 }
5422 JoinKind::Right => {
5423 if join.use_outer_keyword {
5424 "RIGHT OUTER"
5425 } else if join.use_inner_keyword {
5426 "RIGHT INNER"
5427 } else {
5428 "RIGHT"
5429 }
5430 }
5431 JoinKind::Full => {
5432 if join.use_outer_keyword {
5433 "FULL OUTER"
5434 } else {
5435 "FULL"
5436 }
5437 }
5438 JoinKind::Inner => {
5439 if join.use_inner_keyword {
5440 "INNER"
5441 } else {
5442 ""
5443 }
5444 }
5445 _ => "",
5446 };
5447
5448 let mut parts = Vec::new();
5449 if global {
5450 parts.push("GLOBAL");
5451 }
5452 if !join_type.is_empty() {
5453 parts.push(join_type);
5454 }
5455 if let Some(strict) = strictness {
5456 parts.push(strict);
5457 }
5458 parts.push("JOIN");
5459 Some(parts.join(" "))
5460 } else {
5461 None
5462 }
5463 } else {
5464 None
5465 }
5466 } else {
5467 None
5468 };
5469
5470 if !join.comments.is_empty() {
5474 if self.config.pretty {
5475 let trimmed = self.output.trim_end().len();
5480 self.output.truncate(trimmed);
5481 for comment in &join.comments {
5482 self.write_newline();
5483 self.write_indent();
5484 self.write_formatted_comment(comment);
5485 }
5486 self.write_newline();
5487 self.write_indent();
5488 } else {
5489 for comment in &join.comments {
5490 self.write_formatted_comment(comment);
5491 self.write_space();
5492 }
5493 }
5494 }
5495
5496 let directed_str = if join.directed { " DIRECTED" } else { "" };
5497
5498 if let Some(keyword) = clickhouse_join_keyword {
5499 self.write_keyword(&keyword);
5500 } else {
5501 match join.kind {
5502 JoinKind::Inner => {
5503 if join.use_inner_keyword {
5504 if hint_str.is_empty() && directed_str.is_empty() {
5505 self.write_keyword("INNER JOIN");
5506 } else {
5507 self.write_keyword("INNER");
5508 if !hint_str.is_empty() {
5509 self.write_keyword(&hint_str);
5510 }
5511 if !directed_str.is_empty() {
5512 self.write_keyword(directed_str);
5513 }
5514 self.write_keyword(" JOIN");
5515 }
5516 } else {
5517 if !hint_str.is_empty() {
5518 self.write_keyword(hint_str.trim());
5519 self.write_keyword(" ");
5520 }
5521 if !directed_str.is_empty() {
5522 self.write_keyword("DIRECTED ");
5523 }
5524 self.write_keyword("JOIN");
5525 }
5526 }
5527 JoinKind::Left => {
5528 if join.use_outer_keyword {
5529 if hint_str.is_empty() && directed_str.is_empty() {
5530 self.write_keyword("LEFT OUTER JOIN");
5531 } else {
5532 self.write_keyword("LEFT OUTER");
5533 if !hint_str.is_empty() {
5534 self.write_keyword(&hint_str);
5535 }
5536 if !directed_str.is_empty() {
5537 self.write_keyword(directed_str);
5538 }
5539 self.write_keyword(" JOIN");
5540 }
5541 } else if join.use_inner_keyword {
5542 if hint_str.is_empty() && directed_str.is_empty() {
5543 self.write_keyword("LEFT INNER JOIN");
5544 } else {
5545 self.write_keyword("LEFT INNER");
5546 if !hint_str.is_empty() {
5547 self.write_keyword(&hint_str);
5548 }
5549 if !directed_str.is_empty() {
5550 self.write_keyword(directed_str);
5551 }
5552 self.write_keyword(" JOIN");
5553 }
5554 } else {
5555 if hint_str.is_empty() && directed_str.is_empty() {
5556 self.write_keyword("LEFT JOIN");
5557 } else {
5558 self.write_keyword("LEFT");
5559 if !hint_str.is_empty() {
5560 self.write_keyword(&hint_str);
5561 }
5562 if !directed_str.is_empty() {
5563 self.write_keyword(directed_str);
5564 }
5565 self.write_keyword(" JOIN");
5566 }
5567 }
5568 }
5569 JoinKind::Right => {
5570 if join.use_outer_keyword {
5571 if hint_str.is_empty() && directed_str.is_empty() {
5572 self.write_keyword("RIGHT OUTER JOIN");
5573 } else {
5574 self.write_keyword("RIGHT OUTER");
5575 if !hint_str.is_empty() {
5576 self.write_keyword(&hint_str);
5577 }
5578 if !directed_str.is_empty() {
5579 self.write_keyword(directed_str);
5580 }
5581 self.write_keyword(" JOIN");
5582 }
5583 } else if join.use_inner_keyword {
5584 if hint_str.is_empty() && directed_str.is_empty() {
5585 self.write_keyword("RIGHT INNER JOIN");
5586 } else {
5587 self.write_keyword("RIGHT INNER");
5588 if !hint_str.is_empty() {
5589 self.write_keyword(&hint_str);
5590 }
5591 if !directed_str.is_empty() {
5592 self.write_keyword(directed_str);
5593 }
5594 self.write_keyword(" JOIN");
5595 }
5596 } else {
5597 if hint_str.is_empty() && directed_str.is_empty() {
5598 self.write_keyword("RIGHT JOIN");
5599 } else {
5600 self.write_keyword("RIGHT");
5601 if !hint_str.is_empty() {
5602 self.write_keyword(&hint_str);
5603 }
5604 if !directed_str.is_empty() {
5605 self.write_keyword(directed_str);
5606 }
5607 self.write_keyword(" JOIN");
5608 }
5609 }
5610 }
5611 JoinKind::Full => {
5612 if join.use_outer_keyword {
5613 if hint_str.is_empty() && directed_str.is_empty() {
5614 self.write_keyword("FULL OUTER JOIN");
5615 } else {
5616 self.write_keyword("FULL OUTER");
5617 if !hint_str.is_empty() {
5618 self.write_keyword(&hint_str);
5619 }
5620 if !directed_str.is_empty() {
5621 self.write_keyword(directed_str);
5622 }
5623 self.write_keyword(" JOIN");
5624 }
5625 } else {
5626 if hint_str.is_empty() && directed_str.is_empty() {
5627 self.write_keyword("FULL JOIN");
5628 } else {
5629 self.write_keyword("FULL");
5630 if !hint_str.is_empty() {
5631 self.write_keyword(&hint_str);
5632 }
5633 if !directed_str.is_empty() {
5634 self.write_keyword(directed_str);
5635 }
5636 self.write_keyword(" JOIN");
5637 }
5638 }
5639 }
5640 JoinKind::Outer => {
5641 if directed_str.is_empty() {
5642 self.write_keyword("OUTER JOIN");
5643 } else {
5644 self.write_keyword("OUTER");
5645 self.write_keyword(directed_str);
5646 self.write_keyword(" JOIN");
5647 }
5648 }
5649 JoinKind::Cross => {
5650 if directed_str.is_empty() {
5651 self.write_keyword("CROSS JOIN");
5652 } else {
5653 self.write_keyword("CROSS");
5654 self.write_keyword(directed_str);
5655 self.write_keyword(" JOIN");
5656 }
5657 }
5658 JoinKind::Natural => {
5659 if join.use_inner_keyword {
5660 if directed_str.is_empty() {
5661 self.write_keyword("NATURAL INNER JOIN");
5662 } else {
5663 self.write_keyword("NATURAL INNER");
5664 self.write_keyword(directed_str);
5665 self.write_keyword(" JOIN");
5666 }
5667 } else {
5668 if directed_str.is_empty() {
5669 self.write_keyword("NATURAL JOIN");
5670 } else {
5671 self.write_keyword("NATURAL");
5672 self.write_keyword(directed_str);
5673 self.write_keyword(" JOIN");
5674 }
5675 }
5676 }
5677 JoinKind::NaturalLeft => {
5678 if join.use_outer_keyword {
5679 if directed_str.is_empty() {
5680 self.write_keyword("NATURAL LEFT OUTER JOIN");
5681 } else {
5682 self.write_keyword("NATURAL LEFT OUTER");
5683 self.write_keyword(directed_str);
5684 self.write_keyword(" JOIN");
5685 }
5686 } else {
5687 if directed_str.is_empty() {
5688 self.write_keyword("NATURAL LEFT JOIN");
5689 } else {
5690 self.write_keyword("NATURAL LEFT");
5691 self.write_keyword(directed_str);
5692 self.write_keyword(" JOIN");
5693 }
5694 }
5695 }
5696 JoinKind::NaturalRight => {
5697 if join.use_outer_keyword {
5698 if directed_str.is_empty() {
5699 self.write_keyword("NATURAL RIGHT OUTER JOIN");
5700 } else {
5701 self.write_keyword("NATURAL RIGHT OUTER");
5702 self.write_keyword(directed_str);
5703 self.write_keyword(" JOIN");
5704 }
5705 } else {
5706 if directed_str.is_empty() {
5707 self.write_keyword("NATURAL RIGHT JOIN");
5708 } else {
5709 self.write_keyword("NATURAL RIGHT");
5710 self.write_keyword(directed_str);
5711 self.write_keyword(" JOIN");
5712 }
5713 }
5714 }
5715 JoinKind::NaturalFull => {
5716 if join.use_outer_keyword {
5717 if directed_str.is_empty() {
5718 self.write_keyword("NATURAL FULL OUTER JOIN");
5719 } else {
5720 self.write_keyword("NATURAL FULL OUTER");
5721 self.write_keyword(directed_str);
5722 self.write_keyword(" JOIN");
5723 }
5724 } else {
5725 if directed_str.is_empty() {
5726 self.write_keyword("NATURAL FULL JOIN");
5727 } else {
5728 self.write_keyword("NATURAL FULL");
5729 self.write_keyword(directed_str);
5730 self.write_keyword(" JOIN");
5731 }
5732 }
5733 }
5734 JoinKind::Semi => self.write_keyword("SEMI JOIN"),
5735 JoinKind::Anti => self.write_keyword("ANTI JOIN"),
5736 JoinKind::LeftSemi => self.write_keyword("LEFT SEMI JOIN"),
5737 JoinKind::LeftAnti => self.write_keyword("LEFT ANTI JOIN"),
5738 JoinKind::RightSemi => self.write_keyword("RIGHT SEMI JOIN"),
5739 JoinKind::RightAnti => self.write_keyword("RIGHT ANTI JOIN"),
5740 JoinKind::CrossApply => {
5741 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
5743 self.write_keyword("CROSS APPLY");
5744 } else {
5745 self.write_keyword("INNER JOIN LATERAL");
5746 }
5747 }
5748 JoinKind::OuterApply => {
5749 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
5751 self.write_keyword("OUTER APPLY");
5752 } else {
5753 self.write_keyword("LEFT JOIN LATERAL");
5754 }
5755 }
5756 JoinKind::AsOf => self.write_keyword("ASOF JOIN"),
5757 JoinKind::AsOfLeft => {
5758 if join.use_outer_keyword {
5759 self.write_keyword("ASOF LEFT OUTER JOIN");
5760 } else {
5761 self.write_keyword("ASOF LEFT JOIN");
5762 }
5763 }
5764 JoinKind::AsOfRight => {
5765 if join.use_outer_keyword {
5766 self.write_keyword("ASOF RIGHT OUTER JOIN");
5767 } else {
5768 self.write_keyword("ASOF RIGHT JOIN");
5769 }
5770 }
5771 JoinKind::Lateral => self.write_keyword("LATERAL JOIN"),
5772 JoinKind::LeftLateral => {
5773 if join.use_outer_keyword {
5774 self.write_keyword("LEFT OUTER LATERAL JOIN");
5775 } else {
5776 self.write_keyword("LEFT LATERAL JOIN");
5777 }
5778 }
5779 JoinKind::Straight => self.write_keyword("STRAIGHT_JOIN"),
5780 JoinKind::Implicit => {
5781 use crate::dialects::DialectType;
5785 let is_cj_dialect = matches!(
5786 self.config.dialect,
5787 Some(DialectType::BigQuery)
5788 | Some(DialectType::Hive)
5789 | Some(DialectType::Spark)
5790 | Some(DialectType::Databricks)
5791 );
5792 let source_is_same = self.config.source_dialect.is_some()
5793 && self.config.source_dialect == self.config.dialect;
5794 let source_is_cj = matches!(
5795 self.config.source_dialect,
5796 Some(DialectType::BigQuery)
5797 | Some(DialectType::Hive)
5798 | Some(DialectType::Spark)
5799 | Some(DialectType::Databricks)
5800 );
5801 if is_cj_dialect
5802 && (source_is_same || source_is_cj || self.config.source_dialect.is_none())
5803 {
5804 self.write_keyword("CROSS JOIN");
5805 } else {
5806 self.output.truncate(self.output.trim_end().len());
5810 self.write(",");
5811 }
5812 }
5813 JoinKind::Array => self.write_keyword("ARRAY JOIN"),
5814 JoinKind::LeftArray => self.write_keyword("LEFT ARRAY JOIN"),
5815 JoinKind::Paste => self.write_keyword("PASTE JOIN"),
5816 JoinKind::Positional => self.write_keyword("POSITIONAL JOIN"),
5817 }
5818 }
5819
5820 if matches!(join.kind, JoinKind::Array | JoinKind::LeftArray) {
5822 match &join.this {
5823 Expression::Tuple(t) if t.expressions.is_empty() => {}
5824 Expression::Tuple(t) => {
5825 self.write_space();
5826 for (i, item) in t.expressions.iter().enumerate() {
5827 if i > 0 {
5828 self.write(", ");
5829 }
5830 self.generate_expression(item)?;
5831 }
5832 }
5833 other => {
5834 self.write_space();
5835 self.generate_expression(other)?;
5836 }
5837 }
5838 } else {
5839 self.write_space();
5840 self.generate_expression(&join.this)?;
5841 }
5842
5843 if !join.deferred_condition {
5845 if let Some(match_cond) = &join.match_condition {
5847 self.write_space();
5848 self.write_keyword("MATCH_CONDITION");
5849 self.write(" (");
5850 self.generate_expression(match_cond)?;
5851 self.write(")");
5852 }
5853
5854 if let Some(on) = &join.on {
5855 if self.config.pretty {
5856 self.write_newline();
5857 self.indent_level += 1;
5858 self.write_indent();
5859 self.write_keyword("ON");
5860 self.write_space();
5861 self.generate_join_on_condition(on)?;
5862 self.indent_level -= 1;
5863 } else {
5864 self.write_space();
5865 self.write_keyword("ON");
5866 self.write_space();
5867 self.generate_expression(on)?;
5868 }
5869 }
5870
5871 if !join.using.is_empty() {
5872 if self.config.pretty {
5873 self.write_newline();
5874 self.indent_level += 1;
5875 self.write_indent();
5876 self.write_keyword("USING");
5877 self.write(" (");
5878 for (i, col) in join.using.iter().enumerate() {
5879 if i > 0 {
5880 self.write(", ");
5881 }
5882 self.generate_identifier(col)?;
5883 }
5884 self.write(")");
5885 self.indent_level -= 1;
5886 } else {
5887 self.write_space();
5888 self.write_keyword("USING");
5889 self.write(" (");
5890 for (i, col) in join.using.iter().enumerate() {
5891 if i > 0 {
5892 self.write(", ");
5893 }
5894 self.generate_identifier(col)?;
5895 }
5896 self.write(")");
5897 }
5898 }
5899 }
5900
5901 for pivot in &join.pivots {
5903 self.write_space();
5904 self.generate_expression(pivot)?;
5905 }
5906
5907 Ok(())
5908 }
5909
5910 fn generate_join_condition(&mut self, join: &Join) -> Result<()> {
5912 if let Some(match_cond) = &join.match_condition {
5914 self.write_space();
5915 self.write_keyword("MATCH_CONDITION");
5916 self.write(" (");
5917 self.generate_expression(match_cond)?;
5918 self.write(")");
5919 }
5920
5921 if let Some(on) = &join.on {
5922 if self.config.pretty {
5923 self.write_newline();
5924 self.indent_level += 1;
5925 self.write_indent();
5926 self.write_keyword("ON");
5927 self.write_space();
5928 self.generate_join_on_condition(on)?;
5930 self.indent_level -= 1;
5931 } else {
5932 self.write_space();
5933 self.write_keyword("ON");
5934 self.write_space();
5935 self.generate_expression(on)?;
5936 }
5937 }
5938
5939 if !join.using.is_empty() {
5940 if self.config.pretty {
5941 self.write_newline();
5942 self.indent_level += 1;
5943 self.write_indent();
5944 self.write_keyword("USING");
5945 self.write(" (");
5946 for (i, col) in join.using.iter().enumerate() {
5947 if i > 0 {
5948 self.write(", ");
5949 }
5950 self.generate_identifier(col)?;
5951 }
5952 self.write(")");
5953 self.indent_level -= 1;
5954 } else {
5955 self.write_space();
5956 self.write_keyword("USING");
5957 self.write(" (");
5958 for (i, col) in join.using.iter().enumerate() {
5959 if i > 0 {
5960 self.write(", ");
5961 }
5962 self.generate_identifier(col)?;
5963 }
5964 self.write(")");
5965 }
5966 }
5967
5968 for pivot in &join.pivots {
5970 self.write_space();
5971 self.generate_expression(pivot)?;
5972 }
5973
5974 Ok(())
5975 }
5976
5977 fn generate_join_on_condition(&mut self, expr: &Expression) -> Result<()> {
5979 if let Expression::And(and_op) = expr {
5980 if let Some(conditions) = self.flatten_connector_terms(and_op, ConnectorOperator::And) {
5981 self.generate_expression(conditions[0])?;
5982 for condition in conditions.iter().skip(1) {
5983 self.write_newline();
5984 self.write_indent();
5985 self.write_keyword("AND");
5986 self.write_space();
5987 self.generate_expression(condition)?;
5988 }
5989 return Ok(());
5990 }
5991 }
5992
5993 self.generate_expression(expr)
5994 }
5995
5996 fn generate_joined_table(&mut self, jt: &JoinedTable) -> Result<()> {
5997 self.write("(");
5999 self.generate_expression(&jt.left)?;
6000
6001 for join in &jt.joins {
6003 self.generate_join(join)?;
6004 }
6005
6006 for (lv_idx, lv) in jt.lateral_views.iter().enumerate() {
6008 self.generate_lateral_view(lv, lv_idx)?;
6009 }
6010
6011 self.write(")");
6012
6013 if let Some(alias) = &jt.alias {
6015 self.write_space();
6016 self.write_keyword("AS");
6017 self.write_space();
6018 self.generate_identifier(alias)?;
6019 }
6020
6021 Ok(())
6022 }
6023
6024 fn generate_lateral_view(&mut self, lv: &LateralView, lv_index: usize) -> Result<()> {
6025 use crate::dialects::DialectType;
6026
6027 if self.config.pretty {
6028 self.write_newline();
6029 self.write_indent();
6030 } else {
6031 self.write_space();
6032 }
6033
6034 let use_lateral_join = matches!(
6037 self.config.dialect,
6038 Some(DialectType::PostgreSQL)
6039 | Some(DialectType::DuckDB)
6040 | Some(DialectType::Snowflake)
6041 | Some(DialectType::TSQL)
6042 | Some(DialectType::Presto)
6043 | Some(DialectType::Trino)
6044 | Some(DialectType::Athena)
6045 );
6046
6047 let use_unnest = matches!(
6049 self.config.dialect,
6050 Some(DialectType::DuckDB)
6051 | Some(DialectType::Presto)
6052 | Some(DialectType::Trino)
6053 | Some(DialectType::Athena)
6054 );
6055
6056 let (is_posexplode, is_inline, func_args) = match &lv.this {
6058 Expression::Explode(uf) => {
6059 (false, false, vec![uf.this.clone()])
6061 }
6062 Expression::Unnest(uf) => {
6063 let mut args = vec![uf.this.clone()];
6064 args.extend(uf.expressions.clone());
6065 (false, false, args)
6066 }
6067 Expression::Function(func) => {
6068 if func.name.eq_ignore_ascii_case("POSEXPLODE")
6069 || func.name.eq_ignore_ascii_case("POSEXPLODE_OUTER")
6070 {
6071 (true, false, func.args.clone())
6072 } else if func.name.eq_ignore_ascii_case("INLINE") {
6073 (false, true, func.args.clone())
6074 } else if func.name.eq_ignore_ascii_case("EXPLODE")
6075 || func.name.eq_ignore_ascii_case("EXPLODE_OUTER")
6076 {
6077 (false, false, func.args.clone())
6078 } else {
6079 (false, false, vec![])
6080 }
6081 }
6082 _ => (false, false, vec![]),
6083 };
6084
6085 if use_lateral_join {
6086 if lv.outer {
6088 self.write_keyword("LEFT JOIN LATERAL");
6089 } else {
6090 self.write_keyword("CROSS JOIN");
6091 }
6092 self.write_space();
6093
6094 if use_unnest && !func_args.is_empty() {
6095 let unnest_args = if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
6098 func_args
6100 .iter()
6101 .map(|a| {
6102 if let Expression::Function(ref f) = a {
6103 if f.name.eq_ignore_ascii_case("ARRAY") && f.args.len() == 1 {
6104 return Expression::ArrayFunc(Box::new(
6105 crate::expressions::ArrayConstructor {
6106 expressions: f.args.clone(),
6107 bracket_notation: true,
6108 use_list_keyword: false,
6109 },
6110 ));
6111 }
6112 }
6113 a.clone()
6114 })
6115 .collect::<Vec<_>>()
6116 } else if matches!(
6117 self.config.dialect,
6118 Some(DialectType::Presto)
6119 | Some(DialectType::Trino)
6120 | Some(DialectType::Athena)
6121 ) {
6122 func_args
6124 .iter()
6125 .map(|a| {
6126 if let Expression::Function(ref f) = a {
6127 if f.name.eq_ignore_ascii_case("ARRAY") && f.args.len() >= 1 {
6128 return Expression::ArrayFunc(Box::new(
6129 crate::expressions::ArrayConstructor {
6130 expressions: f.args.clone(),
6131 bracket_notation: true,
6132 use_list_keyword: false,
6133 },
6134 ));
6135 }
6136 }
6137 a.clone()
6138 })
6139 .collect::<Vec<_>>()
6140 } else {
6141 func_args
6142 };
6143
6144 if is_posexplode {
6146 self.write_keyword("LATERAL");
6147 self.write(" (");
6148 self.write_keyword("SELECT");
6149 self.write_space();
6150
6151 let pos_alias = if !lv.column_aliases.is_empty() {
6154 lv.column_aliases[0].clone()
6155 } else {
6156 Identifier::new("pos")
6157 };
6158 let data_aliases: Vec<Identifier> = if lv.column_aliases.len() > 1 {
6159 lv.column_aliases[1..].to_vec()
6160 } else {
6161 vec![Identifier::new("col")]
6162 };
6163
6164 self.generate_identifier(&pos_alias)?;
6166 self.write(" - 1");
6167 self.write_space();
6168 self.write_keyword("AS");
6169 self.write_space();
6170 self.generate_identifier(&pos_alias)?;
6171
6172 for data_col in &data_aliases {
6174 self.write(", ");
6175 self.generate_identifier(data_col)?;
6176 }
6177
6178 self.write_space();
6179 self.write_keyword("FROM");
6180 self.write_space();
6181 self.write_keyword("UNNEST");
6182 self.write("(");
6183 for (i, arg) in unnest_args.iter().enumerate() {
6184 if i > 0 {
6185 self.write(", ");
6186 }
6187 self.generate_expression(arg)?;
6188 }
6189 self.write(")");
6190 self.write_space();
6191 self.write_keyword("WITH ORDINALITY");
6192 self.write_space();
6193 self.write_keyword("AS");
6194 self.write_space();
6195
6196 let table_alias_ident = lv
6198 .table_alias
6199 .clone()
6200 .unwrap_or_else(|| Identifier::new("t"));
6201 self.generate_identifier(&table_alias_ident)?;
6202 self.write("(");
6203 for (i, data_col) in data_aliases.iter().enumerate() {
6204 if i > 0 {
6205 self.write(", ");
6206 }
6207 self.generate_identifier(data_col)?;
6208 }
6209 self.write(", ");
6210 self.generate_identifier(&pos_alias)?;
6211 self.write("))");
6212 } else if is_inline && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
6213 self.write_keyword("LATERAL");
6215 self.write(" (");
6216 self.write_keyword("SELECT");
6217 self.write_space();
6218 self.write_keyword("UNNEST");
6219 self.write("(");
6220 for (i, arg) in unnest_args.iter().enumerate() {
6221 if i > 0 {
6222 self.write(", ");
6223 }
6224 self.generate_expression(arg)?;
6225 }
6226 self.write(", ");
6227 self.write_keyword("max_depth");
6228 self.write(" => 2))");
6229
6230 if let Some(alias) = &lv.table_alias {
6232 self.write_space();
6233 self.write_keyword("AS");
6234 self.write_space();
6235 self.generate_identifier(alias)?;
6236 if !lv.column_aliases.is_empty() {
6237 self.write("(");
6238 for (i, col) in lv.column_aliases.iter().enumerate() {
6239 if i > 0 {
6240 self.write(", ");
6241 }
6242 self.generate_identifier(col)?;
6243 }
6244 self.write(")");
6245 }
6246 } else if !lv.column_aliases.is_empty() {
6247 self.write_space();
6249 self.write_keyword("AS");
6250 self.write_space();
6251 self.write(&format!("_u_{}", lv_index));
6252 self.write("(");
6253 for (i, col) in lv.column_aliases.iter().enumerate() {
6254 if i > 0 {
6255 self.write(", ");
6256 }
6257 self.generate_identifier(col)?;
6258 }
6259 self.write(")");
6260 }
6261 } else {
6262 self.write_keyword("UNNEST");
6263 self.write("(");
6264 for (i, arg) in unnest_args.iter().enumerate() {
6265 if i > 0 {
6266 self.write(", ");
6267 }
6268 self.generate_expression(arg)?;
6269 }
6270 self.write(")");
6271
6272 if let Some(alias) = &lv.table_alias {
6274 self.write_space();
6275 self.write_keyword("AS");
6276 self.write_space();
6277 self.generate_identifier(alias)?;
6278 if !lv.column_aliases.is_empty() {
6279 self.write("(");
6280 for (i, col) in lv.column_aliases.iter().enumerate() {
6281 if i > 0 {
6282 self.write(", ");
6283 }
6284 self.generate_identifier(col)?;
6285 }
6286 self.write(")");
6287 }
6288 } else if !lv.column_aliases.is_empty() {
6289 self.write_space();
6290 self.write_keyword("AS");
6291 self.write(" t(");
6292 for (i, col) in lv.column_aliases.iter().enumerate() {
6293 if i > 0 {
6294 self.write(", ");
6295 }
6296 self.generate_identifier(col)?;
6297 }
6298 self.write(")");
6299 }
6300 }
6301 } else {
6302 if !lv.outer {
6304 self.write_keyword("LATERAL");
6305 self.write_space();
6306 }
6307 self.generate_expression(&lv.this)?;
6308
6309 if let Some(alias) = &lv.table_alias {
6311 self.write_space();
6312 self.write_keyword("AS");
6313 self.write_space();
6314 self.generate_identifier(alias)?;
6315 if !lv.column_aliases.is_empty() {
6316 self.write("(");
6317 for (i, col) in lv.column_aliases.iter().enumerate() {
6318 if i > 0 {
6319 self.write(", ");
6320 }
6321 self.generate_identifier(col)?;
6322 }
6323 self.write(")");
6324 }
6325 } else if !lv.column_aliases.is_empty() {
6326 self.write_space();
6327 self.write_keyword("AS");
6328 self.write(" t(");
6329 for (i, col) in lv.column_aliases.iter().enumerate() {
6330 if i > 0 {
6331 self.write(", ");
6332 }
6333 self.generate_identifier(col)?;
6334 }
6335 self.write(")");
6336 }
6337 }
6338
6339 if lv.outer {
6341 self.write_space();
6342 self.write_keyword("ON TRUE");
6343 }
6344 } else {
6345 self.write_keyword("LATERAL VIEW");
6347 if lv.outer {
6348 self.write_space();
6349 self.write_keyword("OUTER");
6350 }
6351 if self.config.pretty {
6352 self.write_newline();
6353 self.write_indent();
6354 } else {
6355 self.write_space();
6356 }
6357 self.generate_expression(&lv.this)?;
6358
6359 if let Some(alias) = &lv.table_alias {
6361 self.write_space();
6362 self.generate_identifier(alias)?;
6363 }
6364
6365 if !lv.column_aliases.is_empty() {
6367 self.write_space();
6368 self.write_keyword("AS");
6369 self.write_space();
6370 for (i, col) in lv.column_aliases.iter().enumerate() {
6371 if i > 0 {
6372 self.write(", ");
6373 }
6374 self.generate_identifier(col)?;
6375 }
6376 }
6377 }
6378
6379 Ok(())
6380 }
6381
6382 fn generate_union(&mut self, outermost: &Union) -> Result<()> {
6383 let mut chain: Vec<&Union> = vec![outermost];
6388 let mut leftmost: &Expression = &outermost.left;
6389 while let Expression::Union(inner) = leftmost {
6390 chain.push(inner);
6391 leftmost = &inner.left;
6392 }
6393 if let Some(with) = &outermost.with {
6398 self.generate_with(with)?;
6399 self.write_space();
6400 }
6401
6402 self.generate_expression(leftmost)?;
6404
6405 for union in chain.iter().rev() {
6407 self.generate_union_step(union)?;
6408 }
6409 Ok(())
6410 }
6411
6412 fn generate_union_step(&mut self, union: &Union) -> Result<()> {
6414 if self.config.pretty {
6415 self.write_newline();
6416 self.write_indent();
6417 } else {
6418 self.write_space();
6419 }
6420
6421 if let Some(side) = &union.side {
6423 self.write_keyword(side);
6424 self.write_space();
6425 }
6426 if let Some(kind) = &union.kind {
6427 self.write_keyword(kind);
6428 self.write_space();
6429 }
6430
6431 self.write_keyword("UNION");
6432 if union.all {
6433 self.write_space();
6434 self.write_keyword("ALL");
6435 } else if union.distinct {
6436 self.write_space();
6437 self.write_keyword("DISTINCT");
6438 }
6439
6440 if union.corresponding || union.by_name {
6443 self.write_space();
6444 self.write_keyword("BY NAME");
6445 }
6446 if !union.on_columns.is_empty() {
6447 self.write_space();
6448 self.write_keyword("ON");
6449 self.write(" (");
6450 for (i, col) in union.on_columns.iter().enumerate() {
6451 if i > 0 {
6452 self.write(", ");
6453 }
6454 self.generate_expression(col)?;
6455 }
6456 self.write(")");
6457 }
6458
6459 if self.config.pretty {
6460 self.write_newline();
6461 self.write_indent();
6462 } else {
6463 self.write_space();
6464 }
6465 self.generate_expression(&union.right)?;
6466 if let Some(order_by) = &union.order_by {
6468 if self.config.pretty {
6469 self.write_newline();
6470 } else {
6471 self.write_space();
6472 }
6473 self.write_keyword("ORDER BY");
6474 self.write_space();
6475 for (i, ordered) in order_by.expressions.iter().enumerate() {
6476 if i > 0 {
6477 self.write(", ");
6478 }
6479 self.generate_ordered(ordered)?;
6480 }
6481 }
6482 if let Some(limit) = &union.limit {
6483 if self.config.pretty {
6484 self.write_newline();
6485 } else {
6486 self.write_space();
6487 }
6488 self.write_keyword("LIMIT");
6489 self.write_space();
6490 self.generate_expression(limit)?;
6491 }
6492 if let Some(offset) = &union.offset {
6493 if self.config.pretty {
6494 self.write_newline();
6495 } else {
6496 self.write_space();
6497 }
6498 self.write_keyword("OFFSET");
6499 self.write_space();
6500 self.generate_expression(offset)?;
6501 }
6502 if let Some(distribute_by) = &union.distribute_by {
6504 self.write_space();
6505 self.write_keyword("DISTRIBUTE BY");
6506 self.write_space();
6507 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6508 if i > 0 {
6509 self.write(", ");
6510 }
6511 self.generate_expression(expr)?;
6512 }
6513 }
6514 if let Some(sort_by) = &union.sort_by {
6516 self.write_space();
6517 self.write_keyword("SORT BY");
6518 self.write_space();
6519 for (i, ord) in sort_by.expressions.iter().enumerate() {
6520 if i > 0 {
6521 self.write(", ");
6522 }
6523 self.generate_ordered(ord)?;
6524 }
6525 }
6526 if let Some(cluster_by) = &union.cluster_by {
6528 self.write_space();
6529 self.write_keyword("CLUSTER BY");
6530 self.write_space();
6531 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6532 if i > 0 {
6533 self.write(", ");
6534 }
6535 self.generate_ordered(ord)?;
6536 }
6537 }
6538 Ok(())
6539 }
6540
6541 fn generate_intersect(&mut self, outermost: &Intersect) -> Result<()> {
6542 let mut chain: Vec<&Intersect> = vec![outermost];
6544 let mut leftmost: &Expression = &outermost.left;
6545 while let Expression::Intersect(inner) = leftmost {
6546 chain.push(inner);
6547 leftmost = &inner.left;
6548 }
6549
6550 if let Some(with) = &outermost.with {
6551 self.generate_with(with)?;
6552 self.write_space();
6553 }
6554
6555 self.generate_expression(leftmost)?;
6556
6557 for intersect in chain.iter().rev() {
6558 self.generate_intersect_step(intersect)?;
6559 }
6560 Ok(())
6561 }
6562
6563 fn generate_intersect_step(&mut self, intersect: &Intersect) -> Result<()> {
6565 if self.config.pretty {
6566 self.write_newline();
6567 self.write_indent();
6568 } else {
6569 self.write_space();
6570 }
6571
6572 if let Some(side) = &intersect.side {
6574 self.write_keyword(side);
6575 self.write_space();
6576 }
6577 if let Some(kind) = &intersect.kind {
6578 self.write_keyword(kind);
6579 self.write_space();
6580 }
6581
6582 self.write_keyword("INTERSECT");
6583 if intersect.all {
6584 self.write_space();
6585 self.write_keyword("ALL");
6586 } else if intersect.distinct {
6587 self.write_space();
6588 self.write_keyword("DISTINCT");
6589 }
6590
6591 if intersect.corresponding || intersect.by_name {
6594 self.write_space();
6595 self.write_keyword("BY NAME");
6596 }
6597 if !intersect.on_columns.is_empty() {
6598 self.write_space();
6599 self.write_keyword("ON");
6600 self.write(" (");
6601 for (i, col) in intersect.on_columns.iter().enumerate() {
6602 if i > 0 {
6603 self.write(", ");
6604 }
6605 self.generate_expression(col)?;
6606 }
6607 self.write(")");
6608 }
6609
6610 if self.config.pretty {
6611 self.write_newline();
6612 self.write_indent();
6613 } else {
6614 self.write_space();
6615 }
6616 self.generate_expression(&intersect.right)?;
6617 if let Some(order_by) = &intersect.order_by {
6619 if self.config.pretty {
6620 self.write_newline();
6621 } else {
6622 self.write_space();
6623 }
6624 self.write_keyword("ORDER BY");
6625 self.write_space();
6626 for (i, ordered) in order_by.expressions.iter().enumerate() {
6627 if i > 0 {
6628 self.write(", ");
6629 }
6630 self.generate_ordered(ordered)?;
6631 }
6632 }
6633 if let Some(limit) = &intersect.limit {
6634 if self.config.pretty {
6635 self.write_newline();
6636 } else {
6637 self.write_space();
6638 }
6639 self.write_keyword("LIMIT");
6640 self.write_space();
6641 self.generate_expression(limit)?;
6642 }
6643 if let Some(offset) = &intersect.offset {
6644 if self.config.pretty {
6645 self.write_newline();
6646 } else {
6647 self.write_space();
6648 }
6649 self.write_keyword("OFFSET");
6650 self.write_space();
6651 self.generate_expression(offset)?;
6652 }
6653 if let Some(distribute_by) = &intersect.distribute_by {
6655 self.write_space();
6656 self.write_keyword("DISTRIBUTE BY");
6657 self.write_space();
6658 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6659 if i > 0 {
6660 self.write(", ");
6661 }
6662 self.generate_expression(expr)?;
6663 }
6664 }
6665 if let Some(sort_by) = &intersect.sort_by {
6667 self.write_space();
6668 self.write_keyword("SORT BY");
6669 self.write_space();
6670 for (i, ord) in sort_by.expressions.iter().enumerate() {
6671 if i > 0 {
6672 self.write(", ");
6673 }
6674 self.generate_ordered(ord)?;
6675 }
6676 }
6677 if let Some(cluster_by) = &intersect.cluster_by {
6679 self.write_space();
6680 self.write_keyword("CLUSTER BY");
6681 self.write_space();
6682 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6683 if i > 0 {
6684 self.write(", ");
6685 }
6686 self.generate_ordered(ord)?;
6687 }
6688 }
6689 Ok(())
6690 }
6691
6692 fn generate_except(&mut self, outermost: &Except) -> Result<()> {
6693 let mut chain: Vec<&Except> = vec![outermost];
6695 let mut leftmost: &Expression = &outermost.left;
6696 while let Expression::Except(inner) = leftmost {
6697 chain.push(inner);
6698 leftmost = &inner.left;
6699 }
6700
6701 if let Some(with) = &outermost.with {
6702 self.generate_with(with)?;
6703 self.write_space();
6704 }
6705
6706 self.generate_expression(leftmost)?;
6707
6708 for except in chain.iter().rev() {
6709 self.generate_except_step(except)?;
6710 }
6711 Ok(())
6712 }
6713
6714 fn generate_except_step(&mut self, except: &Except) -> Result<()> {
6716 use crate::dialects::DialectType;
6717
6718 if self.config.pretty {
6719 self.write_newline();
6720 self.write_indent();
6721 } else {
6722 self.write_space();
6723 }
6724
6725 if let Some(side) = &except.side {
6727 self.write_keyword(side);
6728 self.write_space();
6729 }
6730 if let Some(kind) = &except.kind {
6731 self.write_keyword(kind);
6732 self.write_space();
6733 }
6734
6735 match self.config.dialect {
6737 Some(DialectType::Oracle) if !except.all => {
6738 self.write_keyword("MINUS");
6739 }
6740 Some(DialectType::ClickHouse) => {
6741 self.write_keyword("EXCEPT");
6742 let preserve_all = self.config.source_dialect.is_none()
6743 || matches!(self.config.source_dialect, Some(DialectType::ClickHouse));
6744 if except.all && preserve_all {
6745 self.write_space();
6746 self.write_keyword("ALL");
6747 }
6748 if except.distinct {
6749 self.write_space();
6750 self.write_keyword("DISTINCT");
6751 }
6752 }
6753 Some(DialectType::BigQuery) => {
6754 self.write_keyword("EXCEPT");
6756 if except.all {
6757 self.write_space();
6758 self.write_keyword("ALL");
6759 } else {
6760 self.write_space();
6761 self.write_keyword("DISTINCT");
6762 }
6763 }
6764 _ => {
6765 self.write_keyword("EXCEPT");
6766 if except.all {
6767 self.write_space();
6768 self.write_keyword("ALL");
6769 } else if except.distinct {
6770 self.write_space();
6771 self.write_keyword("DISTINCT");
6772 }
6773 }
6774 }
6775
6776 if except.corresponding || except.by_name {
6779 self.write_space();
6780 self.write_keyword("BY NAME");
6781 }
6782 if !except.on_columns.is_empty() {
6783 self.write_space();
6784 self.write_keyword("ON");
6785 self.write(" (");
6786 for (i, col) in except.on_columns.iter().enumerate() {
6787 if i > 0 {
6788 self.write(", ");
6789 }
6790 self.generate_expression(col)?;
6791 }
6792 self.write(")");
6793 }
6794
6795 if self.config.pretty {
6796 self.write_newline();
6797 self.write_indent();
6798 } else {
6799 self.write_space();
6800 }
6801 self.generate_expression(&except.right)?;
6802 if let Some(order_by) = &except.order_by {
6804 if self.config.pretty {
6805 self.write_newline();
6806 } else {
6807 self.write_space();
6808 }
6809 self.write_keyword("ORDER BY");
6810 self.write_space();
6811 for (i, ordered) in order_by.expressions.iter().enumerate() {
6812 if i > 0 {
6813 self.write(", ");
6814 }
6815 self.generate_ordered(ordered)?;
6816 }
6817 }
6818 if let Some(limit) = &except.limit {
6819 if self.config.pretty {
6820 self.write_newline();
6821 } else {
6822 self.write_space();
6823 }
6824 self.write_keyword("LIMIT");
6825 self.write_space();
6826 self.generate_expression(limit)?;
6827 }
6828 if let Some(offset) = &except.offset {
6829 if self.config.pretty {
6830 self.write_newline();
6831 } else {
6832 self.write_space();
6833 }
6834 self.write_keyword("OFFSET");
6835 self.write_space();
6836 self.generate_expression(offset)?;
6837 }
6838 if let Some(distribute_by) = &except.distribute_by {
6840 self.write_space();
6841 self.write_keyword("DISTRIBUTE BY");
6842 self.write_space();
6843 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6844 if i > 0 {
6845 self.write(", ");
6846 }
6847 self.generate_expression(expr)?;
6848 }
6849 }
6850 if let Some(sort_by) = &except.sort_by {
6852 self.write_space();
6853 self.write_keyword("SORT BY");
6854 self.write_space();
6855 for (i, ord) in sort_by.expressions.iter().enumerate() {
6856 if i > 0 {
6857 self.write(", ");
6858 }
6859 self.generate_ordered(ord)?;
6860 }
6861 }
6862 if let Some(cluster_by) = &except.cluster_by {
6864 self.write_space();
6865 self.write_keyword("CLUSTER BY");
6866 self.write_space();
6867 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6868 if i > 0 {
6869 self.write(", ");
6870 }
6871 self.generate_ordered(ord)?;
6872 }
6873 }
6874 Ok(())
6875 }
6876
6877 fn generate_insert(&mut self, insert: &Insert) -> Result<()> {
6878 let prepend_query_cte = if insert.with.is_none() {
6880 use crate::dialects::DialectType;
6881 let should_prepend = matches!(
6882 self.config.dialect,
6883 Some(DialectType::TSQL)
6884 | Some(DialectType::Fabric)
6885 | Some(DialectType::Spark)
6886 | Some(DialectType::Databricks)
6887 | Some(DialectType::Hive)
6888 );
6889 if should_prepend {
6890 if let Some(Expression::Select(select)) = &insert.query {
6891 select.with.clone()
6892 } else {
6893 None
6894 }
6895 } else {
6896 None
6897 }
6898 } else {
6899 None
6900 };
6901
6902 if let Some(with) = &insert.with {
6904 self.generate_with(with)?;
6905 self.write_space();
6906 } else if let Some(with) = &prepend_query_cte {
6907 self.generate_with(with)?;
6908 self.write_space();
6909 }
6910
6911 for comment in &insert.leading_comments {
6913 self.write_formatted_comment(comment);
6914 self.write(" ");
6915 }
6916
6917 if let Some(dir) = &insert.directory {
6919 self.write_keyword("INSERT OVERWRITE");
6920 if dir.local {
6921 self.write_space();
6922 self.write_keyword("LOCAL");
6923 }
6924 self.write_space();
6925 self.write_keyword("DIRECTORY");
6926 self.write_space();
6927 self.write("'");
6928 self.write(&dir.path);
6929 self.write("'");
6930
6931 if let Some(row_format) = &dir.row_format {
6933 self.write_space();
6934 self.write_keyword("ROW FORMAT");
6935 if row_format.delimited {
6936 self.write_space();
6937 self.write_keyword("DELIMITED");
6938 }
6939 if let Some(val) = &row_format.fields_terminated_by {
6940 self.write_space();
6941 self.write_keyword("FIELDS TERMINATED BY");
6942 self.write_space();
6943 self.generate_string_literal(val)?;
6944 }
6945 if let Some(val) = &row_format.collection_items_terminated_by {
6946 self.write_space();
6947 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
6948 self.write_space();
6949 self.write("'");
6950 self.write(val);
6951 self.write("'");
6952 }
6953 if let Some(val) = &row_format.map_keys_terminated_by {
6954 self.write_space();
6955 self.write_keyword("MAP KEYS TERMINATED BY");
6956 self.write_space();
6957 self.write("'");
6958 self.write(val);
6959 self.write("'");
6960 }
6961 if let Some(val) = &row_format.lines_terminated_by {
6962 self.write_space();
6963 self.write_keyword("LINES TERMINATED BY");
6964 self.write_space();
6965 self.write("'");
6966 self.write(val);
6967 self.write("'");
6968 }
6969 if let Some(val) = &row_format.null_defined_as {
6970 self.write_space();
6971 self.write_keyword("NULL DEFINED AS");
6972 self.write_space();
6973 self.write("'");
6974 self.write(val);
6975 self.write("'");
6976 }
6977 }
6978
6979 if let Some(format) = &dir.stored_as {
6981 self.write_space();
6982 self.write_keyword("STORED AS");
6983 self.write_space();
6984 self.write_keyword(format);
6985 }
6986
6987 if let Some(query) = &insert.query {
6989 self.write_space();
6990 self.generate_expression(query)?;
6991 }
6992
6993 return Ok(());
6994 }
6995
6996 if insert.is_replace {
6997 self.write_keyword("REPLACE INTO");
6999 } else if insert.overwrite {
7000 self.write_keyword("INSERT");
7002 if let Some(ref hint) = insert.hint {
7004 self.generate_hint(hint)?;
7005 }
7006 self.write(&self.config.insert_overwrite.to_ascii_uppercase());
7007 } else if let Some(ref action) = insert.conflict_action {
7008 self.write_keyword("INSERT OR");
7010 self.write_space();
7011 self.write_keyword(action);
7012 self.write_space();
7013 self.write_keyword("INTO");
7014 } else if insert.ignore {
7015 self.write_keyword("INSERT IGNORE INTO");
7017 } else {
7018 self.write_keyword("INSERT");
7019 if let Some(ref hint) = insert.hint {
7021 self.generate_hint(hint)?;
7022 }
7023 self.write_space();
7024 self.write_keyword("INTO");
7025 }
7026 if let Some(ref func) = insert.function_target {
7028 self.write_space();
7029 self.write_keyword("FUNCTION");
7030 self.write_space();
7031 self.generate_expression(func)?;
7032 } else {
7033 self.write_space();
7034 self.generate_table(&insert.table)?;
7035 }
7036
7037 if let Some(ref alias) = insert.alias {
7039 self.write_space();
7040 if insert.alias_explicit_as {
7041 self.write_keyword("AS");
7042 self.write_space();
7043 }
7044 self.generate_identifier(alias)?;
7045 }
7046
7047 if insert.if_exists {
7049 self.write_space();
7050 self.write_keyword("IF EXISTS");
7051 }
7052
7053 if let Some(ref replace_where) = insert.replace_where {
7055 if self.config.pretty {
7056 self.write_newline();
7057 self.write_indent();
7058 } else {
7059 self.write_space();
7060 }
7061 self.write_keyword("REPLACE WHERE");
7062 self.write_space();
7063 self.generate_expression(replace_where)?;
7064 }
7065
7066 if !insert.partition.is_empty() {
7068 self.write_space();
7069 self.write_keyword("PARTITION");
7070 self.write("(");
7071 for (i, (col, val)) in insert.partition.iter().enumerate() {
7072 if i > 0 {
7073 self.write(", ");
7074 }
7075 self.generate_identifier(col)?;
7076 if let Some(v) = val {
7077 self.write(" = ");
7078 self.generate_expression(v)?;
7079 }
7080 }
7081 self.write(")");
7082 }
7083
7084 if let Some(ref partition_by) = insert.partition_by {
7086 self.write_space();
7087 self.write_keyword("PARTITION BY");
7088 self.write_space();
7089 self.generate_expression(partition_by)?;
7090 }
7091
7092 if !insert.settings.is_empty() {
7094 self.write_space();
7095 self.write_keyword("SETTINGS");
7096 self.write_space();
7097 for (i, setting) in insert.settings.iter().enumerate() {
7098 if i > 0 {
7099 self.write(", ");
7100 }
7101 self.generate_expression(setting)?;
7102 }
7103 }
7104
7105 if !insert.columns.is_empty() {
7106 if insert.alias.is_some() && insert.alias_explicit_as {
7107 self.write("(");
7109 } else {
7110 self.write(" (");
7112 }
7113 for (i, col) in insert.columns.iter().enumerate() {
7114 if i > 0 {
7115 self.write(", ");
7116 }
7117 self.generate_identifier(col)?;
7118 }
7119 self.write(")");
7120 }
7121
7122 if let Some(ref output) = insert.output {
7124 self.generate_output_clause(output)?;
7125 }
7126
7127 if insert.by_name {
7129 self.write_space();
7130 self.write_keyword("BY NAME");
7131 }
7132
7133 if insert.default_values {
7134 self.write_space();
7135 self.write_keyword("DEFAULT VALUES");
7136 } else if let Some(query) = &insert.query {
7137 if self.config.pretty {
7138 self.write_newline();
7139 } else {
7140 self.write_space();
7141 }
7142 if prepend_query_cte.is_some() {
7144 if let Expression::Select(select) = query {
7145 let mut select_no_with = select.clone();
7146 select_no_with.with = None;
7147 self.generate_select(&select_no_with)?;
7148 } else {
7149 self.generate_expression(query)?;
7150 }
7151 } else {
7152 self.generate_expression(query)?;
7153 }
7154 } else if !insert.values.is_empty() {
7155 if self.config.pretty {
7156 self.write_newline();
7158 self.write_keyword("VALUES");
7159 self.write_newline();
7160 self.indent_level += 1;
7161 for (i, row) in insert.values.iter().enumerate() {
7162 if i > 0 {
7163 self.write(",");
7164 self.write_newline();
7165 }
7166 self.write_indent();
7167 self.write("(");
7168 for (j, val) in row.iter().enumerate() {
7169 if j > 0 {
7170 self.write(", ");
7171 }
7172 self.generate_expression(val)?;
7173 }
7174 self.write(")");
7175 }
7176 self.indent_level -= 1;
7177 } else {
7178 self.write_space();
7180 self.write_keyword("VALUES");
7181 for (i, row) in insert.values.iter().enumerate() {
7182 if i > 0 {
7183 self.write(",");
7184 }
7185 self.write(" (");
7186 for (j, val) in row.iter().enumerate() {
7187 if j > 0 {
7188 self.write(", ");
7189 }
7190 self.generate_expression(val)?;
7191 }
7192 self.write(")");
7193 }
7194 }
7195 }
7196
7197 if let Some(ref source) = insert.source {
7199 self.write_space();
7200 self.write_keyword("TABLE");
7201 self.write_space();
7202 self.generate_expression(source)?;
7203 }
7204
7205 if let Some(alias) = &insert.source_alias {
7207 self.write_space();
7208 self.write_keyword("AS");
7209 self.write_space();
7210 self.generate_identifier(alias)?;
7211 }
7212
7213 if let Some(on_conflict) = &insert.on_conflict {
7215 if !matches!(self.config.dialect, Some(DialectType::Materialize)) {
7216 self.write_space();
7217 self.generate_expression(on_conflict)?;
7218 }
7219 }
7220
7221 if !insert.returning.is_empty() {
7223 self.write_space();
7224 self.write_keyword("RETURNING");
7225 self.write_space();
7226 for (i, expr) in insert.returning.iter().enumerate() {
7227 if i > 0 {
7228 self.write(", ");
7229 }
7230 self.generate_expression(expr)?;
7231 }
7232 }
7233
7234 Ok(())
7235 }
7236
7237 fn generate_update(&mut self, update: &Update) -> Result<()> {
7238 for comment in &update.leading_comments {
7240 self.write_formatted_comment(comment);
7241 self.write(" ");
7242 }
7243
7244 if let Some(ref with) = update.with {
7246 self.generate_with(with)?;
7247 self.write_space();
7248 }
7249
7250 self.write_keyword("UPDATE");
7251 if let Some(hint) = &update.hint {
7252 self.generate_hint(hint)?;
7253 }
7254 self.write_space();
7255 self.generate_table(&update.table)?;
7256
7257 let mysql_like_update_from = matches!(
7258 self.config.dialect,
7259 Some(DialectType::MySQL) | Some(DialectType::SingleStore)
7260 ) && update.from_clause.is_some();
7261
7262 let mut set_pairs = update.set.clone();
7263
7264 let mut pre_set_joins = update.table_joins.clone();
7266 if mysql_like_update_from {
7267 let target_name = update
7268 .table
7269 .alias
7270 .as_ref()
7271 .map(|a| a.name.clone())
7272 .unwrap_or_else(|| update.table.name.name.clone());
7273
7274 for (col, _) in &mut set_pairs {
7275 if !col.name.contains('.') {
7276 col.name = format!("{}.{}", target_name, col.name);
7277 }
7278 }
7279
7280 if let Some(from_clause) = &update.from_clause {
7281 for table_expr in &from_clause.expressions {
7282 pre_set_joins.push(crate::expressions::Join {
7283 this: table_expr.clone(),
7284 on: Some(Expression::Boolean(crate::expressions::BooleanLiteral {
7285 value: true,
7286 })),
7287 using: Vec::new(),
7288 kind: crate::expressions::JoinKind::Inner,
7289 use_inner_keyword: false,
7290 use_outer_keyword: false,
7291 deferred_condition: false,
7292 join_hint: None,
7293 match_condition: None,
7294 pivots: Vec::new(),
7295 comments: Vec::new(),
7296 nesting_group: 0,
7297 directed: false,
7298 });
7299 }
7300 }
7301 for join in &update.from_joins {
7302 let mut join = join.clone();
7303 if join.on.is_none() && join.using.is_empty() {
7304 join.on = Some(Expression::Boolean(crate::expressions::BooleanLiteral {
7305 value: true,
7306 }));
7307 }
7308 pre_set_joins.push(join);
7309 }
7310 }
7311
7312 for extra_table in &update.extra_tables {
7314 self.write(", ");
7315 self.generate_table(extra_table)?;
7316 }
7317
7318 for join in &pre_set_joins {
7320 self.generate_join(join)?;
7322 }
7323
7324 let teradata_from_before_set = matches!(self.config.dialect, Some(DialectType::Teradata));
7326 if teradata_from_before_set && !mysql_like_update_from {
7327 if let Some(ref from_clause) = update.from_clause {
7328 self.write_space();
7329 self.write_keyword("FROM");
7330 self.write_space();
7331 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
7332 if i > 0 {
7333 self.write(", ");
7334 }
7335 self.generate_expression(table_expr)?;
7336 }
7337 }
7338 for join in &update.from_joins {
7339 self.generate_join(join)?;
7340 }
7341 }
7342
7343 self.write_space();
7344 self.write_keyword("SET");
7345 self.write_space();
7346
7347 for (i, (col, val)) in set_pairs.iter().enumerate() {
7348 if i > 0 {
7349 self.write(", ");
7350 }
7351 self.generate_identifier(col)?;
7352 self.write(" = ");
7353 self.generate_expression(val)?;
7354 }
7355
7356 if let Some(ref output) = update.output {
7358 self.generate_output_clause(output)?;
7359 }
7360
7361 if !mysql_like_update_from && !teradata_from_before_set {
7363 if let Some(ref from_clause) = update.from_clause {
7364 self.write_space();
7365 self.write_keyword("FROM");
7366 self.write_space();
7367 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
7369 if i > 0 {
7370 self.write(", ");
7371 }
7372 self.generate_expression(table_expr)?;
7373 }
7374 }
7375 }
7376
7377 if !mysql_like_update_from && !teradata_from_before_set {
7378 for join in &update.from_joins {
7380 self.generate_join(join)?;
7381 }
7382 }
7383
7384 if let Some(where_clause) = &update.where_clause {
7385 self.write_space();
7386 self.write_keyword("WHERE");
7387 self.write_space();
7388 self.generate_expression(&where_clause.this)?;
7389 }
7390
7391 if !update.returning.is_empty() {
7393 self.write_space();
7394 self.write_keyword("RETURNING");
7395 self.write_space();
7396 for (i, expr) in update.returning.iter().enumerate() {
7397 if i > 0 {
7398 self.write(", ");
7399 }
7400 self.generate_expression(expr)?;
7401 }
7402 }
7403
7404 if let Some(ref order_by) = update.order_by {
7406 self.write_space();
7407 self.generate_order_by(order_by)?;
7408 }
7409
7410 if let Some(ref limit) = update.limit {
7412 self.write_space();
7413 self.write_keyword("LIMIT");
7414 self.write_space();
7415 self.generate_expression(limit)?;
7416 }
7417
7418 Ok(())
7419 }
7420
7421 fn generate_delete(&mut self, delete: &Delete) -> Result<()> {
7422 if let Some(with) = &delete.with {
7424 self.generate_with(with)?;
7425 self.write_space();
7426 }
7427
7428 for comment in &delete.leading_comments {
7430 self.write_formatted_comment(comment);
7431 self.write(" ");
7432 }
7433
7434 if !delete.tables.is_empty() && !delete.tables_from_using {
7436 self.write_keyword("DELETE");
7438 if let Some(hint) = &delete.hint {
7439 self.generate_hint(hint)?;
7440 }
7441 self.write_space();
7442 for (i, tbl) in delete.tables.iter().enumerate() {
7443 if i > 0 {
7444 self.write(", ");
7445 }
7446 self.generate_table(tbl)?;
7447 }
7448 if let Some(ref output) = delete.output {
7450 self.generate_output_clause(output)?;
7451 }
7452 self.write_space();
7453 self.write_keyword("FROM");
7454 self.write_space();
7455 self.generate_table(&delete.table)?;
7456 } else if !delete.tables.is_empty() && delete.tables_from_using {
7457 self.write_keyword("DELETE");
7459 if let Some(hint) = &delete.hint {
7460 self.generate_hint(hint)?;
7461 }
7462 self.write_space();
7463 self.write_keyword("FROM");
7464 self.write_space();
7465 for (i, tbl) in delete.tables.iter().enumerate() {
7466 if i > 0 {
7467 self.write(", ");
7468 }
7469 self.generate_table(tbl)?;
7470 }
7471 } else if delete.no_from && matches!(self.config.dialect, Some(DialectType::BigQuery)) {
7472 self.write_keyword("DELETE");
7474 if let Some(hint) = &delete.hint {
7475 self.generate_hint(hint)?;
7476 }
7477 self.write_space();
7478 self.generate_table(&delete.table)?;
7479 } else {
7480 self.write_keyword("DELETE");
7481 if let Some(hint) = &delete.hint {
7482 self.generate_hint(hint)?;
7483 }
7484 self.write_space();
7485 self.write_keyword("FROM");
7486 self.write_space();
7487 self.generate_table(&delete.table)?;
7488 }
7489
7490 if let Some(ref on_cluster) = delete.on_cluster {
7492 self.write_space();
7493 self.generate_on_cluster(on_cluster)?;
7494 }
7495
7496 if let Some(ref idx) = delete.force_index {
7498 self.write_space();
7499 self.write_keyword("FORCE INDEX");
7500 self.write(" (");
7501 self.write(idx);
7502 self.write(")");
7503 }
7504
7505 if let Some(ref alias) = delete.alias {
7507 self.write_space();
7508 if delete.alias_explicit_as
7509 || matches!(self.config.dialect, Some(DialectType::BigQuery))
7510 {
7511 self.write_keyword("AS");
7512 self.write_space();
7513 }
7514 self.generate_identifier(alias)?;
7515 }
7516
7517 if !delete.tables_from_using {
7519 for join in &delete.joins {
7520 self.generate_join(join)?;
7521 }
7522 }
7523
7524 if !delete.using.is_empty() {
7526 self.write_space();
7527 self.write_keyword("USING");
7528 for (i, table) in delete.using.iter().enumerate() {
7529 if i > 0 {
7530 self.write(",");
7531 }
7532 self.write_space();
7533 if !table.hints.is_empty() && table.name.is_empty() {
7535 self.generate_expression(&table.hints[0])?;
7537 if let Some(ref alias) = table.alias {
7538 self.write_space();
7539 if table.alias_explicit_as {
7540 self.write_keyword("AS");
7541 self.write_space();
7542 }
7543 self.generate_identifier(alias)?;
7544 if !table.column_aliases.is_empty() {
7545 self.write("(");
7546 for (j, col_alias) in table.column_aliases.iter().enumerate() {
7547 if j > 0 {
7548 self.write(", ");
7549 }
7550 self.generate_identifier(col_alias)?;
7551 }
7552 self.write(")");
7553 }
7554 }
7555 } else {
7556 self.generate_table(table)?;
7557 }
7558 }
7559 }
7560
7561 if delete.tables_from_using {
7563 for join in &delete.joins {
7564 self.generate_join(join)?;
7565 }
7566 }
7567
7568 let output_already_emitted =
7570 !delete.tables.is_empty() && !delete.tables_from_using && delete.output.is_some();
7571 if !output_already_emitted {
7572 if let Some(ref output) = delete.output {
7573 self.generate_output_clause(output)?;
7574 }
7575 }
7576
7577 if let Some(where_clause) = &delete.where_clause {
7578 self.write_space();
7579 self.write_keyword("WHERE");
7580 self.write_space();
7581 self.generate_expression(&where_clause.this)?;
7582 }
7583
7584 if let Some(ref order_by) = delete.order_by {
7586 self.write_space();
7587 self.generate_order_by(order_by)?;
7588 }
7589
7590 if let Some(ref limit) = delete.limit {
7592 self.write_space();
7593 self.write_keyword("LIMIT");
7594 self.write_space();
7595 self.generate_expression(limit)?;
7596 }
7597
7598 if !delete.returning.is_empty() {
7600 self.write_space();
7601 self.write_keyword("RETURNING");
7602 self.write_space();
7603 for (i, expr) in delete.returning.iter().enumerate() {
7604 if i > 0 {
7605 self.write(", ");
7606 }
7607 self.generate_expression(expr)?;
7608 }
7609 }
7610
7611 Ok(())
7612 }
7613
7614 fn generate_create_table(&mut self, ct: &CreateTable) -> Result<()> {
7617 let saved_athena_hive_context = self.athena_hive_context;
7621 let is_clickhouse = matches!(self.config.dialect, Some(DialectType::ClickHouse));
7622 if matches!(
7623 self.config.dialect,
7624 Some(crate::dialects::DialectType::Athena)
7625 ) {
7626 let is_external = ct
7630 .table_modifier
7631 .as_ref()
7632 .map(|m| m.eq_ignore_ascii_case("EXTERNAL"))
7633 .unwrap_or(false);
7634 let has_as_select = ct.as_select.is_some();
7635 self.athena_hive_context = is_external || !has_as_select;
7636 }
7637
7638 if matches!(
7640 self.config.dialect,
7641 Some(crate::dialects::DialectType::TSQL)
7642 ) {
7643 if let Some(ref query) = ct.as_select {
7644 if let Some(with_cte) = &ct.with_cte {
7646 self.generate_with(with_cte)?;
7647 self.write_space();
7648 }
7649
7650 self.write_keyword("SELECT");
7652 self.write(" * ");
7653 self.write_keyword("INTO");
7654 self.write_space();
7655
7656 if ct.temporary {
7658 self.write("#");
7659 }
7660 self.generate_table(&ct.name)?;
7661
7662 self.write_space();
7663 self.write_keyword("FROM");
7664 self.write(" (");
7665 let aliased_query = Self::add_column_aliases_to_query(query.clone());
7667 self.generate_expression(&aliased_query)?;
7668 self.write(") ");
7669 self.write_keyword("AS");
7670 self.write(" temp");
7671 return Ok(());
7672 }
7673 }
7674
7675 if let Some(with_cte) = &ct.with_cte {
7677 self.generate_with(with_cte)?;
7678 self.write_space();
7679 }
7680
7681 for comment in &ct.leading_comments {
7683 self.write_formatted_comment(comment);
7684 self.write(" ");
7685 }
7686 self.write_keyword("CREATE");
7687
7688 if ct.or_replace {
7689 self.write_space();
7690 self.write_keyword("OR REPLACE");
7691 }
7692
7693 if ct.temporary {
7694 self.write_space();
7695 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
7697 self.write_keyword("GLOBAL TEMPORARY");
7698 } else {
7699 self.write_keyword("TEMPORARY");
7700 }
7701 }
7702
7703 let is_dictionary = ct
7705 .table_modifier
7706 .as_ref()
7707 .map(|m| m.eq_ignore_ascii_case("DICTIONARY"))
7708 .unwrap_or(false);
7709 if let Some(ref modifier) = ct.table_modifier {
7710 let skip_transient = modifier.eq_ignore_ascii_case("TRANSIENT")
7712 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None);
7713 let is_teradata_modifier = modifier.eq_ignore_ascii_case("VOLATILE")
7715 || modifier.eq_ignore_ascii_case("SET")
7716 || modifier.eq_ignore_ascii_case("MULTISET")
7717 || modifier.to_ascii_uppercase().contains("VOLATILE")
7718 || modifier.to_ascii_uppercase().starts_with("SET ")
7719 || modifier.to_ascii_uppercase().starts_with("MULTISET ");
7720 let skip_teradata =
7721 is_teradata_modifier && !matches!(self.config.dialect, Some(DialectType::Teradata));
7722 if !skip_transient && !skip_teradata {
7723 self.write_space();
7724 self.write_keyword(modifier);
7725 }
7726 }
7727
7728 if !is_dictionary {
7729 self.write_space();
7730 self.write_keyword("TABLE");
7731 }
7732
7733 if ct.if_not_exists {
7734 self.write_space();
7735 self.write_keyword("IF NOT EXISTS");
7736 }
7737
7738 self.write_space();
7739 self.generate_table(&ct.name)?;
7740
7741 if let Some(ref uuid) = ct.uuid {
7743 self.write_space();
7744 self.write_keyword("UUID");
7745 self.write(" '");
7746 self.write(uuid);
7747 self.write("'");
7748 }
7749
7750 if let Some(ref on_cluster) = ct.on_cluster {
7752 self.write_space();
7753 self.generate_on_cluster(on_cluster)?;
7754 }
7755
7756 if matches!(
7758 self.config.dialect,
7759 Some(crate::dialects::DialectType::Teradata)
7760 ) && !ct.teradata_post_name_options.is_empty()
7761 {
7762 for opt in &ct.teradata_post_name_options {
7763 self.write(", ");
7764 self.write(opt);
7765 }
7766 }
7767
7768 if ct.copy_grants {
7770 self.write_space();
7771 self.write_keyword("COPY GRANTS");
7772 }
7773
7774 if let Some(ref using_template) = ct.using_template {
7776 self.write_space();
7777 self.write_keyword("USING TEMPLATE");
7778 self.write_space();
7779 self.generate_expression(using_template)?;
7780 return Ok(());
7781 }
7782
7783 if is_clickhouse {
7785 if let Some(ref clone_source) = ct.clone_source {
7786 self.write_space();
7787 self.write_keyword("AS");
7788 self.write_space();
7789 self.generate_table(clone_source)?;
7790 }
7791 }
7792
7793 if !is_clickhouse {
7795 if let Some(ref clone_source) = ct.clone_source {
7796 self.write_space();
7797 if ct.is_copy && self.config.supports_table_copy {
7798 self.write_keyword("COPY");
7800 } else if ct.shallow_clone {
7801 self.write_keyword("SHALLOW CLONE");
7802 } else if ct.deep_clone {
7803 self.write_keyword("DEEP CLONE");
7804 } else {
7805 self.write_keyword("CLONE");
7806 }
7807 self.write_space();
7808 self.generate_table(clone_source)?;
7809 if let Some(ref at_clause) = ct.clone_at_clause {
7811 self.write_space();
7812 self.generate_expression(at_clause)?;
7813 }
7814 return Ok(());
7815 }
7816 }
7817
7818 if let Some(ref partition_of) = ct.partition_of {
7822 self.write_space();
7823
7824 if let Expression::PartitionedOfProperty(ref pop) = partition_of {
7826 self.write_keyword("PARTITION OF");
7828 self.write_space();
7829 self.generate_expression(&pop.this)?;
7830
7831 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
7833 self.write(" (");
7834 let mut first = true;
7835 for col in &ct.columns {
7836 if !first {
7837 self.write(", ");
7838 }
7839 first = false;
7840 self.generate_column_def(col)?;
7841 }
7842 for constraint in &ct.constraints {
7843 if !first {
7844 self.write(", ");
7845 }
7846 first = false;
7847 self.generate_table_constraint(constraint)?;
7848 }
7849 self.write(")");
7850 }
7851
7852 if let Expression::PartitionBoundSpec(_) = pop.expression.as_ref() {
7854 self.write_space();
7855 self.write_keyword("FOR VALUES");
7856 self.write_space();
7857 self.generate_expression(&pop.expression)?;
7858 } else {
7859 self.write_space();
7860 self.write_keyword("DEFAULT");
7861 }
7862 } else {
7863 self.generate_expression(partition_of)?;
7865
7866 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
7868 self.write(" (");
7869 let mut first = true;
7870 for col in &ct.columns {
7871 if !first {
7872 self.write(", ");
7873 }
7874 first = false;
7875 self.generate_column_def(col)?;
7876 }
7877 for constraint in &ct.constraints {
7878 if !first {
7879 self.write(", ");
7880 }
7881 first = false;
7882 self.generate_table_constraint(constraint)?;
7883 }
7884 self.write(")");
7885 }
7886 }
7887
7888 for prop in &ct.properties {
7890 self.write_space();
7891 self.generate_expression(prop)?;
7892 }
7893
7894 return Ok(());
7895 }
7896
7897 self.sqlite_inline_pk_columns.clear();
7900 if matches!(
7901 self.config.dialect,
7902 Some(crate::dialects::DialectType::SQLite)
7903 ) {
7904 for constraint in &ct.constraints {
7905 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7906 if columns.len() == 1 && name.is_none() {
7908 let pk_col_name = columns[0].name.to_ascii_lowercase();
7909 if ct
7911 .columns
7912 .iter()
7913 .any(|c| c.name.name.to_ascii_lowercase() == pk_col_name)
7914 {
7915 self.sqlite_inline_pk_columns.insert(pk_col_name);
7916 }
7917 }
7918 }
7919 }
7920 }
7921
7922 if !ct.columns.is_empty() {
7924 if self.config.pretty {
7925 self.write(" (");
7927 self.write_newline();
7928 self.indent_level += 1;
7929 for (i, col) in ct.columns.iter().enumerate() {
7930 if i > 0 {
7931 self.write(",");
7932 self.write_newline();
7933 }
7934 self.write_indent();
7935 self.generate_column_def(col)?;
7936 }
7937 for constraint in &ct.constraints {
7939 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7941 if columns.len() == 1
7942 && name.is_none()
7943 && self
7944 .sqlite_inline_pk_columns
7945 .contains(&columns[0].name.to_ascii_lowercase())
7946 {
7947 continue;
7948 }
7949 }
7950 self.write(",");
7951 self.write_newline();
7952 self.write_indent();
7953 self.generate_table_constraint(constraint)?;
7954 }
7955 self.indent_level -= 1;
7956 self.write_newline();
7957 self.write(")");
7958 } else {
7959 self.write(" (");
7960 for (i, col) in ct.columns.iter().enumerate() {
7961 if i > 0 {
7962 self.write(", ");
7963 }
7964 self.generate_column_def(col)?;
7965 }
7966 let mut first_constraint = true;
7968 for constraint in &ct.constraints {
7969 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7971 if columns.len() == 1
7972 && name.is_none()
7973 && self
7974 .sqlite_inline_pk_columns
7975 .contains(&columns[0].name.to_ascii_lowercase())
7976 {
7977 continue;
7978 }
7979 }
7980 if first_constraint {
7981 self.write(", ");
7982 first_constraint = false;
7983 } else {
7984 self.write(", ");
7985 }
7986 self.generate_table_constraint(constraint)?;
7987 }
7988 self.write(")");
7989 }
7990 } else if !ct.constraints.is_empty() {
7991 let has_like_only = ct
7993 .constraints
7994 .iter()
7995 .all(|c| matches!(c, TableConstraint::Like { .. }));
7996 let has_tags_only = ct
7997 .constraints
7998 .iter()
7999 .all(|c| matches!(c, TableConstraint::Tags(_)));
8000 let is_pg_like = matches!(
8004 self.config.dialect,
8005 Some(crate::dialects::DialectType::PostgreSQL)
8006 | Some(crate::dialects::DialectType::CockroachDB)
8007 | Some(crate::dialects::DialectType::Materialize)
8008 | Some(crate::dialects::DialectType::RisingWave)
8009 | Some(crate::dialects::DialectType::Redshift)
8010 | Some(crate::dialects::DialectType::Presto)
8011 | Some(crate::dialects::DialectType::Trino)
8012 | Some(crate::dialects::DialectType::Athena)
8013 );
8014 let use_parens = if has_like_only {
8015 is_pg_like
8016 } else {
8017 !has_tags_only
8018 };
8019 if self.config.pretty && use_parens {
8020 self.write(" (");
8021 self.write_newline();
8022 self.indent_level += 1;
8023 for (i, constraint) in ct.constraints.iter().enumerate() {
8024 if i > 0 {
8025 self.write(",");
8026 self.write_newline();
8027 }
8028 self.write_indent();
8029 self.generate_table_constraint(constraint)?;
8030 }
8031 self.indent_level -= 1;
8032 self.write_newline();
8033 self.write(")");
8034 } else {
8035 if use_parens {
8036 self.write(" (");
8037 } else {
8038 self.write_space();
8039 }
8040 for (i, constraint) in ct.constraints.iter().enumerate() {
8041 if i > 0 {
8042 self.write(", ");
8043 }
8044 self.generate_table_constraint(constraint)?;
8045 }
8046 if use_parens {
8047 self.write(")");
8048 }
8049 }
8050 }
8051
8052 if let Some(ref on_prop) = ct.on_property {
8054 self.write(" ");
8055 self.write_keyword("ON");
8056 self.write(" ");
8057 self.generate_expression(&on_prop.this)?;
8058 }
8059
8060 if !ct.with_partition_columns.is_empty() {
8062 if self.config.pretty {
8063 self.write_newline();
8064 } else {
8065 self.write_space();
8066 }
8067 self.write_keyword("WITH PARTITION COLUMNS");
8068 self.write(" (");
8069 if self.config.pretty {
8070 self.write_newline();
8071 self.indent_level += 1;
8072 for (i, col) in ct.with_partition_columns.iter().enumerate() {
8073 if i > 0 {
8074 self.write(",");
8075 self.write_newline();
8076 }
8077 self.write_indent();
8078 self.generate_column_def(col)?;
8079 }
8080 self.indent_level -= 1;
8081 self.write_newline();
8082 } else {
8083 for (i, col) in ct.with_partition_columns.iter().enumerate() {
8084 if i > 0 {
8085 self.write(", ");
8086 }
8087 self.generate_column_def(col)?;
8088 }
8089 }
8090 self.write(")");
8091 }
8092
8093 if let Some(ref conn) = ct.with_connection {
8095 if self.config.pretty {
8096 self.write_newline();
8097 } else {
8098 self.write_space();
8099 }
8100 self.write_keyword("WITH CONNECTION");
8101 self.write_space();
8102 self.generate_table(conn)?;
8103 }
8104
8105 if !is_clickhouse {
8108 for prop in &ct.properties {
8109 if let Expression::SchemaCommentProperty(_) = prop {
8110 if self.config.pretty {
8111 self.write_newline();
8112 } else {
8113 self.write_space();
8114 }
8115 self.generate_expression(prop)?;
8116 }
8117 }
8118 }
8119
8120 if !ct.with_properties.is_empty() {
8122 let is_snowflake_special_table = matches!(
8124 self.config.dialect,
8125 Some(crate::dialects::DialectType::Snowflake)
8126 ) && (ct.table_modifier.as_deref() == Some("ICEBERG")
8127 || ct.table_modifier.as_deref() == Some("DYNAMIC"));
8128 if is_snowflake_special_table {
8129 for (key, value) in &ct.with_properties {
8130 self.write_space();
8131 self.write(key);
8132 self.write("=");
8133 self.write(value);
8134 }
8135 } else if self.config.pretty {
8136 self.write_newline();
8137 self.write_keyword("WITH");
8138 self.write(" (");
8139 self.write_newline();
8140 self.indent_level += 1;
8141 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
8142 if i > 0 {
8143 self.write(",");
8144 self.write_newline();
8145 }
8146 self.write_indent();
8147 self.write(key);
8148 self.write("=");
8149 self.write(value);
8150 }
8151 self.indent_level -= 1;
8152 self.write_newline();
8153 self.write(")");
8154 } else {
8155 self.write_space();
8156 self.write_keyword("WITH");
8157 self.write(" (");
8158 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
8159 if i > 0 {
8160 self.write(", ");
8161 }
8162 self.write(key);
8163 self.write("=");
8164 self.write(value);
8165 }
8166 self.write(")");
8167 }
8168 }
8169
8170 let (pre_as_properties, post_as_properties): (Vec<&Expression>, Vec<&Expression>) =
8171 if is_clickhouse && ct.as_select.is_some() {
8172 let mut pre = Vec::new();
8173 let mut post = Vec::new();
8174 for prop in &ct.properties {
8175 if matches!(prop, Expression::SchemaCommentProperty(_)) {
8176 post.push(prop);
8177 } else {
8178 pre.push(prop);
8179 }
8180 }
8181 (pre, post)
8182 } else {
8183 (ct.properties.iter().collect(), Vec::new())
8184 };
8185
8186 for prop in pre_as_properties {
8188 if !is_clickhouse && matches!(prop, Expression::SchemaCommentProperty(_)) {
8190 continue;
8191 }
8192 if self.config.pretty {
8193 self.write_newline();
8194 } else {
8195 self.write_space();
8196 }
8197 if let Expression::Properties(props) = prop {
8201 let is_hive_dialect = matches!(
8202 self.config.dialect,
8203 Some(crate::dialects::DialectType::Hive)
8204 | Some(crate::dialects::DialectType::Spark)
8205 | Some(crate::dialects::DialectType::Databricks)
8206 | Some(crate::dialects::DialectType::Athena)
8207 );
8208 let is_doris_starrocks = matches!(
8209 self.config.dialect,
8210 Some(crate::dialects::DialectType::Doris)
8211 | Some(crate::dialects::DialectType::StarRocks)
8212 );
8213 if is_hive_dialect {
8214 self.generate_tblproperties_clause(&props.expressions)?;
8215 } else if is_doris_starrocks {
8216 self.generate_properties_clause(&props.expressions)?;
8217 } else {
8218 self.generate_options_clause(&props.expressions)?;
8219 }
8220 } else {
8221 self.generate_expression(prop)?;
8222 }
8223 }
8224
8225 for prop in &ct.post_table_properties {
8227 if let Expression::WithSystemVersioningProperty(ref svp) = prop {
8228 self.write(" WITH(");
8229 self.generate_system_versioning_content(svp)?;
8230 self.write(")");
8231 } else if let Expression::Properties(props) = prop {
8232 let is_doris_starrocks = matches!(
8234 self.config.dialect,
8235 Some(crate::dialects::DialectType::Doris)
8236 | Some(crate::dialects::DialectType::StarRocks)
8237 );
8238 self.write_space();
8239 if is_doris_starrocks {
8240 self.generate_properties_clause(&props.expressions)?;
8241 } else {
8242 self.generate_options_clause(&props.expressions)?;
8243 }
8244 } else {
8245 self.write_space();
8246 self.generate_expression(prop)?;
8247 }
8248 }
8249
8250 if let Some(ref rollup) = ct.rollup {
8253 if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
8254 self.write_space();
8255 self.generate_rollup_property(rollup)?;
8256 }
8257 }
8258
8259 let is_mysql_compatible = matches!(
8263 self.config.dialect,
8264 Some(DialectType::MySQL)
8265 | Some(DialectType::SingleStore)
8266 | Some(DialectType::Doris)
8267 | Some(DialectType::StarRocks)
8268 | None
8269 );
8270 let is_hive_compatible = matches!(
8271 self.config.dialect,
8272 Some(DialectType::Hive)
8273 | Some(DialectType::Spark)
8274 | Some(DialectType::Databricks)
8275 | Some(DialectType::Athena)
8276 );
8277 let mysql_pretty_options =
8278 self.config.pretty && matches!(self.config.dialect, Some(DialectType::MySQL));
8279 for (key, value) in &ct.mysql_table_options {
8280 let should_output = if is_mysql_compatible {
8282 true
8283 } else if is_hive_compatible && key == "COMMENT" {
8284 true } else {
8286 false
8287 };
8288 if should_output {
8289 if mysql_pretty_options {
8290 self.write_newline();
8291 self.write_indent();
8292 } else {
8293 self.write_space();
8294 }
8295 self.write_keyword(key);
8296 if key == "COMMENT" && !self.config.schema_comment_with_eq {
8298 self.write_space();
8299 } else {
8300 self.write("=");
8301 }
8302 self.write(value);
8303 }
8304 }
8305
8306 if ct.temporary
8308 && matches!(
8309 self.config.dialect,
8310 Some(DialectType::Spark) | Some(DialectType::Databricks)
8311 )
8312 && ct.as_select.is_none()
8313 {
8314 self.write_space();
8315 self.write_keyword("USING PARQUET");
8316 }
8317
8318 if !ct.inherits.is_empty() {
8320 self.write_space();
8321 self.write_keyword("INHERITS");
8322 self.write(" (");
8323 for (i, parent) in ct.inherits.iter().enumerate() {
8324 if i > 0 {
8325 self.write(", ");
8326 }
8327 self.generate_table(parent)?;
8328 }
8329 self.write(")");
8330 }
8331
8332 if let Some(ref query) = ct.as_select {
8334 self.write_space();
8335 self.write_keyword("AS");
8336 self.write_space();
8337 let source_is_clickhouse =
8338 matches!(self.config.source_dialect, Some(DialectType::ClickHouse));
8339 let wrap_as_select =
8340 ct.as_select_parenthesized && !(is_clickhouse && source_is_clickhouse);
8341 if wrap_as_select {
8342 self.write("(");
8343 }
8344 self.generate_expression(query)?;
8345 if wrap_as_select {
8346 self.write(")");
8347 }
8348
8349 if let Some(with_data) = ct.with_data {
8351 self.write_space();
8352 self.write_keyword("WITH");
8353 if !with_data {
8354 self.write_space();
8355 self.write_keyword("NO");
8356 }
8357 self.write_space();
8358 self.write_keyword("DATA");
8359 }
8360
8361 if let Some(with_statistics) = ct.with_statistics {
8363 self.write_space();
8364 self.write_keyword("AND");
8365 if !with_statistics {
8366 self.write_space();
8367 self.write_keyword("NO");
8368 }
8369 self.write_space();
8370 self.write_keyword("STATISTICS");
8371 }
8372
8373 for index in &ct.teradata_indexes {
8375 self.write_space();
8376 match index.kind {
8377 TeradataIndexKind::NoPrimary => {
8378 self.write_keyword("NO PRIMARY INDEX");
8379 }
8380 TeradataIndexKind::Primary => {
8381 self.write_keyword("PRIMARY INDEX");
8382 }
8383 TeradataIndexKind::PrimaryAmp => {
8384 self.write_keyword("PRIMARY AMP INDEX");
8385 }
8386 TeradataIndexKind::Unique => {
8387 self.write_keyword("UNIQUE INDEX");
8388 }
8389 TeradataIndexKind::UniquePrimary => {
8390 self.write_keyword("UNIQUE PRIMARY INDEX");
8391 }
8392 TeradataIndexKind::Secondary => {
8393 self.write_keyword("INDEX");
8394 }
8395 }
8396 if let Some(ref name) = index.name {
8398 self.write_space();
8399 self.write(name);
8400 }
8401 if !index.columns.is_empty() {
8403 self.write(" (");
8404 for (i, col) in index.columns.iter().enumerate() {
8405 if i > 0 {
8406 self.write(", ");
8407 }
8408 self.write(col);
8409 }
8410 self.write(")");
8411 }
8412 }
8413
8414 if let Some(ref on_commit) = ct.on_commit {
8416 self.write_space();
8417 self.write_keyword("ON COMMIT");
8418 self.write_space();
8419 match on_commit {
8420 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
8421 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
8422 }
8423 }
8424
8425 if !post_as_properties.is_empty() {
8426 for prop in post_as_properties {
8427 self.write_space();
8428 self.generate_expression(prop)?;
8429 }
8430 }
8431
8432 self.athena_hive_context = saved_athena_hive_context;
8434 return Ok(());
8435 }
8436
8437 if let Some(ref on_commit) = ct.on_commit {
8439 self.write_space();
8440 self.write_keyword("ON COMMIT");
8441 self.write_space();
8442 match on_commit {
8443 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
8444 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
8445 }
8446 }
8447
8448 self.athena_hive_context = saved_athena_hive_context;
8450
8451 Ok(())
8452 }
8453
8454 fn generate_column_def_expr(&mut self, col: &ColumnDef) -> Result<()> {
8457 self.generate_identifier(&col.name)?;
8459 if !matches!(col.data_type, DataType::Unknown) {
8461 self.write_space();
8462 self.generate_data_type(&col.data_type)?;
8463 }
8464 for constraint in &col.constraints {
8466 if let ColumnConstraint::Path(path_expr) = constraint {
8467 self.write_space();
8468 self.write_keyword("PATH");
8469 self.write_space();
8470 self.generate_expression(path_expr)?;
8471 }
8472 }
8473 Ok(())
8474 }
8475
8476 fn generate_column_def(&mut self, col: &ColumnDef) -> Result<()> {
8477 let has_computed_no_type = matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
8479 && col
8480 .constraints
8481 .iter()
8482 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
8483 let omit_computed_type = !self.config.computed_column_with_type
8485 && col
8486 .constraints
8487 .iter()
8488 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
8489
8490 let is_partition_column_spec = matches!(col.data_type, DataType::Unknown);
8493
8494 let has_no_type = col.no_type
8497 || (matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
8498 && col.constraints.is_empty());
8499
8500 self.generate_identifier(&col.name)?;
8501
8502 let serial_expansion = if matches!(
8504 self.config.dialect,
8505 Some(DialectType::Materialize) | Some(DialectType::PostgreSQL)
8506 ) {
8507 if let DataType::Custom { ref name } = col.data_type {
8508 if name.eq_ignore_ascii_case("SERIAL") {
8509 Some("INT")
8510 } else if name.eq_ignore_ascii_case("BIGSERIAL") {
8511 Some("BIGINT")
8512 } else if name.eq_ignore_ascii_case("SMALLSERIAL") {
8513 Some("SMALLINT")
8514 } else {
8515 None
8516 }
8517 } else {
8518 None
8519 }
8520 } else {
8521 None
8522 };
8523
8524 if !has_computed_no_type && !omit_computed_type && !is_partition_column_spec && !has_no_type
8525 {
8526 self.write_space();
8527 let saved_nullable_depth = self.clickhouse_nullable_depth;
8530 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
8531 self.clickhouse_nullable_depth = -1;
8532 }
8533 if let Some(int_type) = serial_expansion {
8534 self.write_keyword(int_type);
8536 } else if col.unsigned && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
8537 let unsigned_type = match &col.data_type {
8539 DataType::Int { .. } => Some("UINTEGER"),
8540 DataType::BigInt { .. } => Some("UBIGINT"),
8541 DataType::SmallInt { .. } => Some("USMALLINT"),
8542 DataType::TinyInt { .. } => Some("UTINYINT"),
8543 _ => None,
8544 };
8545 if let Some(utype) = unsigned_type {
8546 self.write_keyword(utype);
8547 } else {
8548 self.generate_data_type(&col.data_type)?;
8549 }
8550 } else {
8551 self.generate_data_type(&col.data_type)?;
8552 }
8553 self.clickhouse_nullable_depth = saved_nullable_depth;
8554 }
8555
8556 if col.unsigned && !matches!(self.config.dialect, Some(DialectType::DuckDB)) {
8559 self.write_space();
8560 self.write_keyword("UNSIGNED");
8561 }
8562 if col.zerofill {
8563 self.write_space();
8564 self.write_keyword("ZEROFILL");
8565 }
8566
8567 if let Some(ref charset) = col.character_set {
8571 self.write_space();
8572 self.write_keyword("CHARACTER SET");
8573 self.write_space();
8574 self.write(charset);
8575 }
8576
8577 if col.uppercase {
8578 self.write_space();
8579 self.write_keyword("UPPERCASE");
8580 }
8581
8582 if let Some(casespecific) = col.casespecific {
8583 self.write_space();
8584 if casespecific {
8585 self.write_keyword("CASESPECIFIC");
8586 } else {
8587 self.write_keyword("NOT CASESPECIFIC");
8588 }
8589 }
8590
8591 if let Some(ref format) = col.format {
8592 self.write_space();
8593 self.write_keyword("FORMAT");
8594 self.write(" '");
8595 self.write(format);
8596 self.write("'");
8597 }
8598
8599 if let Some(ref title) = col.title {
8600 self.write_space();
8601 self.write_keyword("TITLE");
8602 self.write(" '");
8603 self.write(title);
8604 self.write("'");
8605 }
8606
8607 if let Some(length) = col.inline_length {
8608 self.write_space();
8609 self.write_keyword("INLINE LENGTH");
8610 self.write(" ");
8611 self.write(&length.to_string());
8612 }
8613
8614 if let Some(ref compress) = col.compress {
8615 self.write_space();
8616 self.write_keyword("COMPRESS");
8617 if !compress.is_empty() {
8618 if compress.len() == 1 {
8620 if let Expression::Literal(lit) = &compress[0] {
8621 if let Literal::String(_) = lit.as_ref() {
8622 self.write_space();
8623 self.generate_expression(&compress[0])?;
8624 }
8625 } else {
8626 self.write(" (");
8627 self.generate_expression(&compress[0])?;
8628 self.write(")");
8629 }
8630 } else {
8631 self.write(" (");
8632 for (i, val) in compress.iter().enumerate() {
8633 if i > 0 {
8634 self.write(", ");
8635 }
8636 self.generate_expression(val)?;
8637 }
8638 self.write(")");
8639 }
8640 }
8641 }
8642
8643 if !col.constraint_order.is_empty() {
8646 let mut references_idx = 0;
8649 let mut check_idx = 0;
8650 let mut generated_idx = 0;
8651 let mut collate_idx = 0;
8652 let mut comment_idx = 0;
8653 let defer_not_null_after_identity = false;
8656 let mut pending_not_null_after_identity = false;
8657
8658 for constraint_type in &col.constraint_order {
8659 match constraint_type {
8660 ConstraintType::PrimaryKey => {
8661 if col.primary_key
8663 && !matches!(self.config.dialect, Some(DialectType::Materialize))
8664 {
8665 if let Some(ref cname) = col.primary_key_constraint_name {
8666 self.write_space();
8667 self.write_keyword("CONSTRAINT");
8668 self.write_space();
8669 self.write(cname);
8670 }
8671 self.write_space();
8672 self.write_keyword("PRIMARY KEY");
8673 if let Some(ref order) = col.primary_key_order {
8674 self.write_space();
8675 match order {
8676 SortOrder::Asc => self.write_keyword("ASC"),
8677 SortOrder::Desc => self.write_keyword("DESC"),
8678 }
8679 }
8680 }
8681 }
8682 ConstraintType::Unique => {
8683 if col.unique {
8684 if let Some(ref cname) = col.unique_constraint_name {
8685 self.write_space();
8686 self.write_keyword("CONSTRAINT");
8687 self.write_space();
8688 self.write(cname);
8689 }
8690 self.write_space();
8691 self.write_keyword("UNIQUE");
8692 if col.unique_nulls_not_distinct {
8694 self.write(" NULLS NOT DISTINCT");
8695 }
8696 }
8697 }
8698 ConstraintType::NotNull => {
8699 if col.nullable == Some(false) {
8700 if defer_not_null_after_identity {
8701 pending_not_null_after_identity = true;
8702 continue;
8703 }
8704 if let Some(ref cname) = col.not_null_constraint_name {
8705 self.write_space();
8706 self.write_keyword("CONSTRAINT");
8707 self.write_space();
8708 self.write(cname);
8709 }
8710 self.write_space();
8711 self.write_keyword("NOT NULL");
8712 }
8713 }
8714 ConstraintType::Null => {
8715 if col.nullable == Some(true) {
8716 self.write_space();
8717 self.write_keyword("NULL");
8718 }
8719 }
8720 ConstraintType::Default => {
8721 if let Some(ref default) = col.default {
8722 self.write_space();
8723 self.write_keyword("DEFAULT");
8724 self.write_space();
8725 self.generate_expression(default)?;
8726 }
8727 }
8728 ConstraintType::AutoIncrement => {
8729 if col.auto_increment {
8730 if matches!(
8732 self.config.dialect,
8733 Some(crate::dialects::DialectType::DuckDB)
8734 ) {
8735 } else if matches!(
8737 self.config.dialect,
8738 Some(crate::dialects::DialectType::Materialize)
8739 ) {
8740 if !matches!(col.nullable, Some(false)) {
8742 self.write_space();
8743 self.write_keyword("NOT NULL");
8744 }
8745 } else if matches!(
8746 self.config.dialect,
8747 Some(crate::dialects::DialectType::PostgreSQL)
8748 ) {
8749 self.write_space();
8751 self.generate_auto_increment_keyword(col)?;
8752 } else {
8753 self.write_space();
8754 self.generate_auto_increment_keyword(col)?;
8755 if pending_not_null_after_identity {
8756 self.write_space();
8757 self.write_keyword("NOT NULL");
8758 pending_not_null_after_identity = false;
8759 }
8760 }
8761 } }
8763 ConstraintType::References => {
8764 while references_idx < col.constraints.len() {
8766 if let ColumnConstraint::References(fk_ref) =
8767 &col.constraints[references_idx]
8768 {
8769 if let Some(ref name) = fk_ref.constraint_name {
8771 self.write_space();
8772 self.write_keyword("CONSTRAINT");
8773 self.write_space();
8774 self.write(name);
8775 }
8776 self.write_space();
8777 if fk_ref.has_foreign_key_keywords {
8778 self.write_keyword("FOREIGN KEY");
8779 self.write_space();
8780 }
8781 self.write_keyword("REFERENCES");
8782 self.write_space();
8783 self.generate_table(&fk_ref.table)?;
8784 if !fk_ref.columns.is_empty() {
8785 self.write(" (");
8786 for (i, c) in fk_ref.columns.iter().enumerate() {
8787 if i > 0 {
8788 self.write(", ");
8789 }
8790 self.generate_identifier(c)?;
8791 }
8792 self.write(")");
8793 }
8794 self.generate_referential_actions(fk_ref)?;
8795 references_idx += 1;
8796 break;
8797 }
8798 references_idx += 1;
8799 }
8800 }
8801 ConstraintType::Check => {
8802 while check_idx < col.constraints.len() {
8804 if let ColumnConstraint::Check(expr) = &col.constraints[check_idx] {
8805 if check_idx == 0 {
8807 if let Some(ref cname) = col.check_constraint_name {
8808 self.write_space();
8809 self.write_keyword("CONSTRAINT");
8810 self.write_space();
8811 self.write(cname);
8812 }
8813 }
8814 self.write_space();
8815 self.write_keyword("CHECK");
8816 self.write(" (");
8817 self.generate_expression(expr)?;
8818 self.write(")");
8819 check_idx += 1;
8820 break;
8821 }
8822 check_idx += 1;
8823 }
8824 }
8825 ConstraintType::GeneratedAsIdentity => {
8826 while generated_idx < col.constraints.len() {
8828 if let ColumnConstraint::GeneratedAsIdentity(gen) =
8829 &col.constraints[generated_idx]
8830 {
8831 self.write_space();
8832 if matches!(
8834 self.config.dialect,
8835 Some(crate::dialects::DialectType::Redshift)
8836 ) {
8837 self.write_keyword("IDENTITY");
8838 self.write("(");
8839 if let Some(ref start) = gen.start {
8840 self.generate_expression(start)?;
8841 } else {
8842 self.write("0");
8843 }
8844 self.write(", ");
8845 if let Some(ref incr) = gen.increment {
8846 self.generate_expression(incr)?;
8847 } else {
8848 self.write("1");
8849 }
8850 self.write(")");
8851 } else {
8852 self.write_keyword("GENERATED");
8853 if gen.always {
8854 self.write_space();
8855 self.write_keyword("ALWAYS");
8856 } else {
8857 self.write_space();
8858 self.write_keyword("BY DEFAULT");
8859 if gen.on_null {
8860 self.write_space();
8861 self.write_keyword("ON NULL");
8862 }
8863 }
8864 self.write_space();
8865 self.write_keyword("AS IDENTITY");
8866
8867 let has_options = gen.start.is_some()
8868 || gen.increment.is_some()
8869 || gen.minvalue.is_some()
8870 || gen.maxvalue.is_some()
8871 || gen.cycle.is_some();
8872 if has_options {
8873 self.write(" (");
8874 let mut first = true;
8875 if let Some(ref start) = gen.start {
8876 if !first {
8877 self.write(" ");
8878 }
8879 first = false;
8880 self.write_keyword("START WITH");
8881 self.write_space();
8882 self.generate_expression(start)?;
8883 }
8884 if let Some(ref incr) = gen.increment {
8885 if !first {
8886 self.write(" ");
8887 }
8888 first = false;
8889 self.write_keyword("INCREMENT BY");
8890 self.write_space();
8891 self.generate_expression(incr)?;
8892 }
8893 if let Some(ref minv) = gen.minvalue {
8894 if !first {
8895 self.write(" ");
8896 }
8897 first = false;
8898 self.write_keyword("MINVALUE");
8899 self.write_space();
8900 self.generate_expression(minv)?;
8901 }
8902 if let Some(ref maxv) = gen.maxvalue {
8903 if !first {
8904 self.write(" ");
8905 }
8906 first = false;
8907 self.write_keyword("MAXVALUE");
8908 self.write_space();
8909 self.generate_expression(maxv)?;
8910 }
8911 if let Some(cycle) = gen.cycle {
8912 if !first {
8913 self.write(" ");
8914 }
8915 if cycle {
8916 self.write_keyword("CYCLE");
8917 } else {
8918 self.write_keyword("NO CYCLE");
8919 }
8920 }
8921 self.write(")");
8922 }
8923 }
8924 generated_idx += 1;
8925 break;
8926 }
8927 generated_idx += 1;
8928 }
8929 }
8930 ConstraintType::Collate => {
8931 while collate_idx < col.constraints.len() {
8933 if let ColumnConstraint::Collate(collation) =
8934 &col.constraints[collate_idx]
8935 {
8936 self.write_space();
8937 self.write_keyword("COLLATE");
8938 self.write_space();
8939 self.generate_identifier(collation)?;
8940 collate_idx += 1;
8941 break;
8942 }
8943 collate_idx += 1;
8944 }
8945 }
8946 ConstraintType::Comment => {
8947 while comment_idx < col.constraints.len() {
8949 if let ColumnConstraint::Comment(comment) =
8950 &col.constraints[comment_idx]
8951 {
8952 self.write_space();
8953 self.write_keyword("COMMENT");
8954 self.write_space();
8955 self.generate_string_literal(comment)?;
8956 comment_idx += 1;
8957 break;
8958 }
8959 comment_idx += 1;
8960 }
8961 }
8962 ConstraintType::Tags => {
8963 for constraint in &col.constraints {
8965 if let ColumnConstraint::Tags(tags) = constraint {
8966 self.write_space();
8967 self.write_keyword("TAG");
8968 self.write(" (");
8969 for (i, expr) in tags.expressions.iter().enumerate() {
8970 if i > 0 {
8971 self.write(", ");
8972 }
8973 self.generate_expression(expr)?;
8974 }
8975 self.write(")");
8976 break;
8977 }
8978 }
8979 }
8980 ConstraintType::ComputedColumn => {
8981 for constraint in &col.constraints {
8983 if let ColumnConstraint::ComputedColumn(cc) = constraint {
8984 self.write_space();
8985 self.generate_computed_column_inline(cc)?;
8986 break;
8987 }
8988 }
8989 }
8990 ConstraintType::GeneratedAsRow => {
8991 for constraint in &col.constraints {
8993 if let ColumnConstraint::GeneratedAsRow(gar) = constraint {
8994 self.write_space();
8995 self.generate_generated_as_row_inline(gar)?;
8996 break;
8997 }
8998 }
8999 }
9000 ConstraintType::OnUpdate => {
9001 if let Some(ref expr) = col.on_update {
9002 self.write_space();
9003 self.write_keyword("ON UPDATE");
9004 self.write_space();
9005 self.generate_expression(expr)?;
9006 }
9007 }
9008 ConstraintType::Encode => {
9009 if let Some(ref encoding) = col.encoding {
9010 self.write_space();
9011 self.write_keyword("ENCODE");
9012 self.write_space();
9013 self.write(encoding);
9014 }
9015 }
9016 ConstraintType::Path => {
9017 for constraint in &col.constraints {
9019 if let ColumnConstraint::Path(path_expr) = constraint {
9020 self.write_space();
9021 self.write_keyword("PATH");
9022 self.write_space();
9023 self.generate_expression(path_expr)?;
9024 break;
9025 }
9026 }
9027 }
9028 }
9029 }
9030 if pending_not_null_after_identity {
9031 self.write_space();
9032 self.write_keyword("NOT NULL");
9033 }
9034 } else {
9035 if col.primary_key {
9037 self.write_space();
9038 self.write_keyword("PRIMARY KEY");
9039 if let Some(ref order) = col.primary_key_order {
9040 self.write_space();
9041 match order {
9042 SortOrder::Asc => self.write_keyword("ASC"),
9043 SortOrder::Desc => self.write_keyword("DESC"),
9044 }
9045 }
9046 }
9047
9048 if col.unique {
9049 self.write_space();
9050 self.write_keyword("UNIQUE");
9051 if col.unique_nulls_not_distinct {
9053 self.write(" NULLS NOT DISTINCT");
9054 }
9055 }
9056
9057 match col.nullable {
9058 Some(false) => {
9059 self.write_space();
9060 self.write_keyword("NOT NULL");
9061 }
9062 Some(true) => {
9063 self.write_space();
9064 self.write_keyword("NULL");
9065 }
9066 None => {}
9067 }
9068
9069 if let Some(ref default) = col.default {
9070 self.write_space();
9071 self.write_keyword("DEFAULT");
9072 self.write_space();
9073 self.generate_expression(default)?;
9074 }
9075
9076 if col.auto_increment {
9077 self.write_space();
9078 self.generate_auto_increment_keyword(col)?;
9079 }
9080
9081 for constraint in &col.constraints {
9083 match constraint {
9084 ColumnConstraint::References(fk_ref) => {
9085 self.write_space();
9086 if fk_ref.has_foreign_key_keywords {
9087 self.write_keyword("FOREIGN KEY");
9088 self.write_space();
9089 }
9090 self.write_keyword("REFERENCES");
9091 self.write_space();
9092 self.generate_table(&fk_ref.table)?;
9093 if !fk_ref.columns.is_empty() {
9094 self.write(" (");
9095 for (i, c) in fk_ref.columns.iter().enumerate() {
9096 if i > 0 {
9097 self.write(", ");
9098 }
9099 self.generate_identifier(c)?;
9100 }
9101 self.write(")");
9102 }
9103 self.generate_referential_actions(fk_ref)?;
9104 }
9105 ColumnConstraint::Check(expr) => {
9106 self.write_space();
9107 self.write_keyword("CHECK");
9108 self.write(" (");
9109 self.generate_expression(expr)?;
9110 self.write(")");
9111 }
9112 ColumnConstraint::GeneratedAsIdentity(gen) => {
9113 self.write_space();
9114 if matches!(
9116 self.config.dialect,
9117 Some(crate::dialects::DialectType::Redshift)
9118 ) {
9119 self.write_keyword("IDENTITY");
9120 self.write("(");
9121 if let Some(ref start) = gen.start {
9122 self.generate_expression(start)?;
9123 } else {
9124 self.write("0");
9125 }
9126 self.write(", ");
9127 if let Some(ref incr) = gen.increment {
9128 self.generate_expression(incr)?;
9129 } else {
9130 self.write("1");
9131 }
9132 self.write(")");
9133 } else {
9134 self.write_keyword("GENERATED");
9135 if gen.always {
9136 self.write_space();
9137 self.write_keyword("ALWAYS");
9138 } else {
9139 self.write_space();
9140 self.write_keyword("BY DEFAULT");
9141 if gen.on_null {
9142 self.write_space();
9143 self.write_keyword("ON NULL");
9144 }
9145 }
9146 self.write_space();
9147 self.write_keyword("AS IDENTITY");
9148
9149 let has_options = gen.start.is_some()
9150 || gen.increment.is_some()
9151 || gen.minvalue.is_some()
9152 || gen.maxvalue.is_some()
9153 || gen.cycle.is_some();
9154 if has_options {
9155 self.write(" (");
9156 let mut first = true;
9157 if let Some(ref start) = gen.start {
9158 if !first {
9159 self.write(" ");
9160 }
9161 first = false;
9162 self.write_keyword("START WITH");
9163 self.write_space();
9164 self.generate_expression(start)?;
9165 }
9166 if let Some(ref incr) = gen.increment {
9167 if !first {
9168 self.write(" ");
9169 }
9170 first = false;
9171 self.write_keyword("INCREMENT BY");
9172 self.write_space();
9173 self.generate_expression(incr)?;
9174 }
9175 if let Some(ref minv) = gen.minvalue {
9176 if !first {
9177 self.write(" ");
9178 }
9179 first = false;
9180 self.write_keyword("MINVALUE");
9181 self.write_space();
9182 self.generate_expression(minv)?;
9183 }
9184 if let Some(ref maxv) = gen.maxvalue {
9185 if !first {
9186 self.write(" ");
9187 }
9188 first = false;
9189 self.write_keyword("MAXVALUE");
9190 self.write_space();
9191 self.generate_expression(maxv)?;
9192 }
9193 if let Some(cycle) = gen.cycle {
9194 if !first {
9195 self.write(" ");
9196 }
9197 if cycle {
9198 self.write_keyword("CYCLE");
9199 } else {
9200 self.write_keyword("NO CYCLE");
9201 }
9202 }
9203 self.write(")");
9204 }
9205 }
9206 }
9207 ColumnConstraint::Collate(collation) => {
9208 self.write_space();
9209 self.write_keyword("COLLATE");
9210 self.write_space();
9211 self.generate_identifier(collation)?;
9212 }
9213 ColumnConstraint::Comment(comment) => {
9214 self.write_space();
9215 self.write_keyword("COMMENT");
9216 self.write_space();
9217 self.generate_string_literal(comment)?;
9218 }
9219 ColumnConstraint::Path(path_expr) => {
9220 self.write_space();
9221 self.write_keyword("PATH");
9222 self.write_space();
9223 self.generate_expression(path_expr)?;
9224 }
9225 _ => {} }
9227 }
9228
9229 if let Some(ref encoding) = col.encoding {
9231 self.write_space();
9232 self.write_keyword("ENCODE");
9233 self.write_space();
9234 self.write(encoding);
9235 }
9236 }
9237
9238 if let Some(ref codec) = col.codec {
9240 self.write_space();
9241 self.write_keyword("CODEC");
9242 self.write("(");
9243 self.write(codec);
9244 self.write(")");
9245 }
9246
9247 if let Some(visible) = col.visible {
9248 self.write_space();
9249 if visible {
9250 self.write_keyword("VISIBLE");
9251 } else {
9252 self.write_keyword("INVISIBLE");
9253 }
9254 }
9255
9256 if let Some(ref ephemeral) = col.ephemeral {
9258 self.write_space();
9259 self.write_keyword("EPHEMERAL");
9260 if let Some(ref expr) = ephemeral {
9261 self.write_space();
9262 self.generate_expression(expr)?;
9263 }
9264 }
9265
9266 if let Some(ref mat_expr) = col.materialized_expr {
9268 self.write_space();
9269 self.write_keyword("MATERIALIZED");
9270 self.write_space();
9271 self.generate_expression(mat_expr)?;
9272 }
9273
9274 if let Some(ref alias_expr) = col.alias_expr {
9276 self.write_space();
9277 self.write_keyword("ALIAS");
9278 self.write_space();
9279 self.generate_expression(alias_expr)?;
9280 }
9281
9282 if let Some(ref ttl_expr) = col.ttl_expr {
9284 self.write_space();
9285 self.write_keyword("TTL");
9286 self.write_space();
9287 self.generate_expression(ttl_expr)?;
9288 }
9289
9290 if col.not_for_replication
9292 && matches!(
9293 self.config.dialect,
9294 Some(crate::dialects::DialectType::TSQL)
9295 | Some(crate::dialects::DialectType::Fabric)
9296 )
9297 {
9298 self.write_space();
9299 self.write_keyword("NOT FOR REPLICATION");
9300 }
9301
9302 if !col.options.is_empty() {
9304 self.write_space();
9305 self.generate_options_clause(&col.options)?;
9306 }
9307
9308 if !col.primary_key
9311 && self
9312 .sqlite_inline_pk_columns
9313 .contains(&col.name.name.to_ascii_lowercase())
9314 {
9315 self.write_space();
9316 self.write_keyword("PRIMARY KEY");
9317 }
9318
9319 if serial_expansion.is_some() {
9322 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
9323 self.write_space();
9324 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY NOT NULL");
9325 } else if matches!(self.config.dialect, Some(DialectType::Materialize)) {
9326 self.write_space();
9327 self.write_keyword("NOT NULL");
9328 }
9329 }
9330
9331 Ok(())
9332 }
9333
9334 fn generate_table_constraint(&mut self, constraint: &TableConstraint) -> Result<()> {
9335 match constraint {
9336 TableConstraint::PrimaryKey {
9337 name,
9338 columns,
9339 include_columns,
9340 modifiers,
9341 has_constraint_keyword,
9342 } => {
9343 if let Some(ref n) = name {
9344 if *has_constraint_keyword {
9345 self.write_keyword("CONSTRAINT");
9346 self.write_space();
9347 self.generate_identifier(n)?;
9348 self.write_space();
9349 }
9350 }
9351 self.write_keyword("PRIMARY KEY");
9352 if let Some(ref clustered) = modifiers.clustered {
9354 self.write_space();
9355 self.write_keyword(clustered);
9356 }
9357 if let Some(ref n) = name {
9359 if !*has_constraint_keyword {
9360 self.write_space();
9361 self.generate_identifier(n)?;
9362 }
9363 }
9364 self.write(" (");
9365 for (i, col) in columns.iter().enumerate() {
9366 if i > 0 {
9367 self.write(", ");
9368 }
9369 self.generate_identifier(col)?;
9370 }
9371 self.write(")");
9372 if !include_columns.is_empty() {
9373 self.write_space();
9374 self.write_keyword("INCLUDE");
9375 self.write(" (");
9376 for (i, col) in include_columns.iter().enumerate() {
9377 if i > 0 {
9378 self.write(", ");
9379 }
9380 self.generate_identifier(col)?;
9381 }
9382 self.write(")");
9383 }
9384 self.generate_constraint_modifiers(modifiers);
9385 }
9386 TableConstraint::Unique {
9387 name,
9388 columns,
9389 columns_parenthesized,
9390 modifiers,
9391 has_constraint_keyword,
9392 nulls_not_distinct,
9393 } => {
9394 if let Some(ref n) = name {
9395 if *has_constraint_keyword {
9396 self.write_keyword("CONSTRAINT");
9397 self.write_space();
9398 self.generate_identifier(n)?;
9399 self.write_space();
9400 }
9401 }
9402 self.write_keyword("UNIQUE");
9403 if let Some(ref clustered) = modifiers.clustered {
9405 self.write_space();
9406 self.write_keyword(clustered);
9407 }
9408 if *nulls_not_distinct {
9410 self.write(" NULLS NOT DISTINCT");
9411 }
9412 if let Some(ref n) = name {
9414 if !*has_constraint_keyword {
9415 self.write_space();
9416 self.generate_identifier(n)?;
9417 }
9418 }
9419 if *columns_parenthesized {
9420 self.write(" (");
9421 for (i, col) in columns.iter().enumerate() {
9422 if i > 0 {
9423 self.write(", ");
9424 }
9425 self.generate_identifier(col)?;
9426 }
9427 self.write(")");
9428 } else {
9429 for col in columns.iter() {
9431 self.write_space();
9432 self.generate_identifier(col)?;
9433 }
9434 }
9435 self.generate_constraint_modifiers(modifiers);
9436 }
9437 TableConstraint::ForeignKey {
9438 name,
9439 columns,
9440 references,
9441 on_delete,
9442 on_update,
9443 modifiers,
9444 } => {
9445 if let Some(ref n) = name {
9446 self.write_keyword("CONSTRAINT");
9447 self.write_space();
9448 self.generate_identifier(n)?;
9449 self.write_space();
9450 }
9451 self.write_keyword("FOREIGN KEY");
9452 self.write(" (");
9453 for (i, col) in columns.iter().enumerate() {
9454 if i > 0 {
9455 self.write(", ");
9456 }
9457 self.generate_identifier(col)?;
9458 }
9459 self.write(")");
9460 if let Some(ref refs) = references {
9461 self.write(" ");
9462 self.write_keyword("REFERENCES");
9463 self.write_space();
9464 self.generate_table(&refs.table)?;
9465 if !refs.columns.is_empty() {
9466 if self.config.pretty {
9467 self.write(" (");
9468 self.write_newline();
9469 self.indent_level += 1;
9470 for (i, col) in refs.columns.iter().enumerate() {
9471 if i > 0 {
9472 self.write(",");
9473 self.write_newline();
9474 }
9475 self.write_indent();
9476 self.generate_identifier(col)?;
9477 }
9478 self.indent_level -= 1;
9479 self.write_newline();
9480 self.write_indent();
9481 self.write(")");
9482 } else {
9483 self.write(" (");
9484 for (i, col) in refs.columns.iter().enumerate() {
9485 if i > 0 {
9486 self.write(", ");
9487 }
9488 self.generate_identifier(col)?;
9489 }
9490 self.write(")");
9491 }
9492 }
9493 self.generate_referential_actions(refs)?;
9494 } else {
9495 if let Some(ref action) = on_delete {
9497 self.write_space();
9498 self.write_keyword("ON DELETE");
9499 self.write_space();
9500 self.generate_referential_action(action);
9501 }
9502 if let Some(ref action) = on_update {
9503 self.write_space();
9504 self.write_keyword("ON UPDATE");
9505 self.write_space();
9506 self.generate_referential_action(action);
9507 }
9508 }
9509 self.generate_constraint_modifiers(modifiers);
9510 }
9511 TableConstraint::Check {
9512 name,
9513 expression,
9514 modifiers,
9515 } => {
9516 if let Some(ref n) = name {
9517 self.write_keyword("CONSTRAINT");
9518 self.write_space();
9519 self.generate_identifier(n)?;
9520 self.write_space();
9521 }
9522 self.write_keyword("CHECK");
9523 self.write(" (");
9524 self.generate_expression(expression)?;
9525 self.write(")");
9526 self.generate_constraint_modifiers(modifiers);
9527 }
9528 TableConstraint::Assume { name, expression } => {
9529 if let Some(ref n) = name {
9530 self.write_keyword("CONSTRAINT");
9531 self.write_space();
9532 self.generate_identifier(n)?;
9533 self.write_space();
9534 }
9535 self.write_keyword("ASSUME");
9536 self.write(" (");
9537 self.generate_expression(expression)?;
9538 self.write(")");
9539 }
9540 TableConstraint::Default {
9541 name,
9542 expression,
9543 column,
9544 } => {
9545 if let Some(ref n) = name {
9546 self.write_keyword("CONSTRAINT");
9547 self.write_space();
9548 self.generate_identifier(n)?;
9549 self.write_space();
9550 }
9551 self.write_keyword("DEFAULT");
9552 self.write_space();
9553 self.generate_expression(expression)?;
9554 self.write_space();
9555 self.write_keyword("FOR");
9556 self.write_space();
9557 self.generate_identifier(column)?;
9558 }
9559 TableConstraint::Index {
9560 name,
9561 columns,
9562 kind,
9563 modifiers,
9564 use_key_keyword,
9565 expression,
9566 index_type,
9567 granularity,
9568 } => {
9569 if expression.is_some() {
9571 self.write_keyword("INDEX");
9572 if let Some(ref n) = name {
9573 self.write_space();
9574 self.generate_identifier(n)?;
9575 }
9576 if let Some(ref expr) = expression {
9577 self.write_space();
9578 self.generate_expression(expr)?;
9579 }
9580 if let Some(ref idx_type) = index_type {
9581 self.write_space();
9582 self.write_keyword("TYPE");
9583 self.write_space();
9584 self.generate_expression(idx_type)?;
9585 }
9586 if let Some(ref gran) = granularity {
9587 self.write_space();
9588 self.write_keyword("GRANULARITY");
9589 self.write_space();
9590 self.generate_expression(gran)?;
9591 }
9592 } else {
9593 use crate::dialects::DialectType;
9597 let index_keyword = if *use_key_keyword
9598 && !matches!(self.config.dialect, Some(DialectType::MySQL))
9599 {
9600 "KEY"
9601 } else {
9602 "INDEX"
9603 };
9604
9605 if let Some(ref k) = kind {
9607 self.write_keyword(k);
9608 if k != "UNIQUE" {
9610 self.write_space();
9611 self.write_keyword(index_keyword);
9612 }
9613 } else {
9614 self.write_keyword(index_keyword);
9615 }
9616
9617 if modifiers.using_before_columns && name.is_none() {
9619 if let Some(ref using) = modifiers.using {
9620 self.write_space();
9621 self.write_keyword("USING");
9622 self.write_space();
9623 self.write_keyword(using);
9624 }
9625 }
9626
9627 if let Some(ref n) = name {
9629 self.write_space();
9630 self.generate_identifier(n)?;
9631 }
9632
9633 if modifiers.using_before_columns && name.is_some() {
9635 if let Some(ref using) = modifiers.using {
9636 self.write_space();
9637 self.write_keyword("USING");
9638 self.write_space();
9639 self.write_keyword(using);
9640 }
9641 }
9642
9643 self.write(" (");
9645 for (i, col) in columns.iter().enumerate() {
9646 if i > 0 {
9647 self.write(", ");
9648 }
9649 self.generate_identifier(col)?;
9650 }
9651 self.write(")");
9652
9653 if !modifiers.using_before_columns {
9655 if let Some(ref using) = modifiers.using {
9656 self.write_space();
9657 self.write_keyword("USING");
9658 self.write_space();
9659 self.write_keyword(using);
9660 }
9661 }
9662
9663 self.generate_constraint_modifiers_without_using(modifiers);
9665 }
9666 }
9667 TableConstraint::Projection { name, expression } => {
9668 self.write_keyword("PROJECTION");
9670 self.write_space();
9671 self.generate_identifier(name)?;
9672 self.write(" (");
9673 self.generate_expression(expression)?;
9674 self.write(")");
9675 }
9676 TableConstraint::Like { source, options } => {
9677 self.write_keyword("LIKE");
9678 self.write_space();
9679 self.generate_table(source)?;
9680 for (action, prop) in options {
9681 self.write_space();
9682 match action {
9683 LikeOptionAction::Including => self.write_keyword("INCLUDING"),
9684 LikeOptionAction::Excluding => self.write_keyword("EXCLUDING"),
9685 }
9686 self.write_space();
9687 self.write_keyword(prop);
9688 }
9689 }
9690 TableConstraint::PeriodForSystemTime { start_col, end_col } => {
9691 self.write_keyword("PERIOD FOR SYSTEM_TIME");
9692 self.write(" (");
9693 self.generate_identifier(start_col)?;
9694 self.write(", ");
9695 self.generate_identifier(end_col)?;
9696 self.write(")");
9697 }
9698 TableConstraint::Exclude {
9699 name,
9700 using,
9701 elements,
9702 include_columns,
9703 where_clause,
9704 with_params,
9705 using_index_tablespace,
9706 modifiers: _,
9707 } => {
9708 if let Some(ref n) = name {
9709 self.write_keyword("CONSTRAINT");
9710 self.write_space();
9711 self.generate_identifier(n)?;
9712 self.write_space();
9713 }
9714 self.write_keyword("EXCLUDE");
9715 if let Some(ref method) = using {
9716 self.write_space();
9717 self.write_keyword("USING");
9718 self.write_space();
9719 self.write(method);
9720 self.write("(");
9721 } else {
9722 self.write(" (");
9723 }
9724 for (i, elem) in elements.iter().enumerate() {
9725 if i > 0 {
9726 self.write(", ");
9727 }
9728 self.write(&elem.expression);
9729 self.write_space();
9730 self.write_keyword("WITH");
9731 self.write_space();
9732 self.write(&elem.operator);
9733 }
9734 self.write(")");
9735 if !include_columns.is_empty() {
9736 self.write_space();
9737 self.write_keyword("INCLUDE");
9738 self.write(" (");
9739 for (i, col) in include_columns.iter().enumerate() {
9740 if i > 0 {
9741 self.write(", ");
9742 }
9743 self.generate_identifier(col)?;
9744 }
9745 self.write(")");
9746 }
9747 if !with_params.is_empty() {
9748 self.write_space();
9749 self.write_keyword("WITH");
9750 self.write(" (");
9751 for (i, (key, val)) in with_params.iter().enumerate() {
9752 if i > 0 {
9753 self.write(", ");
9754 }
9755 self.write(key);
9756 self.write("=");
9757 self.write(val);
9758 }
9759 self.write(")");
9760 }
9761 if let Some(ref tablespace) = using_index_tablespace {
9762 self.write_space();
9763 self.write_keyword("USING INDEX TABLESPACE");
9764 self.write_space();
9765 self.write(tablespace);
9766 }
9767 if let Some(ref where_expr) = where_clause {
9768 self.write_space();
9769 self.write_keyword("WHERE");
9770 self.write(" (");
9771 self.generate_expression(where_expr)?;
9772 self.write(")");
9773 }
9774 }
9775 TableConstraint::Tags(tags) => {
9776 self.write_keyword("TAG");
9777 self.write(" (");
9778 for (i, expr) in tags.expressions.iter().enumerate() {
9779 if i > 0 {
9780 self.write(", ");
9781 }
9782 self.generate_expression(expr)?;
9783 }
9784 self.write(")");
9785 }
9786 TableConstraint::InitiallyDeferred { deferred } => {
9787 self.write_keyword("INITIALLY");
9788 self.write_space();
9789 if *deferred {
9790 self.write_keyword("DEFERRED");
9791 } else {
9792 self.write_keyword("IMMEDIATE");
9793 }
9794 }
9795 }
9796 Ok(())
9797 }
9798
9799 fn generate_constraint_modifiers(&mut self, modifiers: &ConstraintModifiers) {
9800 if let Some(using) = &modifiers.using {
9802 self.write_space();
9803 self.write_keyword("USING");
9804 self.write_space();
9805 self.write_keyword(using);
9806 }
9807 if let Some(enforced) = modifiers.enforced {
9809 self.write_space();
9810 if enforced {
9811 self.write_keyword("ENFORCED");
9812 } else {
9813 self.write_keyword("NOT ENFORCED");
9814 }
9815 }
9816 if let Some(deferrable) = modifiers.deferrable {
9818 self.write_space();
9819 if deferrable {
9820 self.write_keyword("DEFERRABLE");
9821 } else {
9822 self.write_keyword("NOT DEFERRABLE");
9823 }
9824 }
9825 if let Some(initially_deferred) = modifiers.initially_deferred {
9827 self.write_space();
9828 if initially_deferred {
9829 self.write_keyword("INITIALLY DEFERRED");
9830 } else {
9831 self.write_keyword("INITIALLY IMMEDIATE");
9832 }
9833 }
9834 if modifiers.norely {
9836 self.write_space();
9837 self.write_keyword("NORELY");
9838 }
9839 if modifiers.rely {
9841 self.write_space();
9842 self.write_keyword("RELY");
9843 }
9844 if modifiers.not_valid {
9846 self.write_space();
9847 self.write_keyword("NOT VALID");
9848 }
9849 if let Some(on_conflict) = &modifiers.on_conflict {
9851 self.write_space();
9852 self.write_keyword("ON CONFLICT");
9853 self.write_space();
9854 self.write_keyword(on_conflict);
9855 }
9856 if !modifiers.with_options.is_empty() {
9858 self.write_space();
9859 self.write_keyword("WITH");
9860 self.write(" (");
9861 for (i, (key, value)) in modifiers.with_options.iter().enumerate() {
9862 if i > 0 {
9863 self.write(", ");
9864 }
9865 self.write(key);
9866 self.write("=");
9867 self.write(value);
9868 }
9869 self.write(")");
9870 }
9871 if let Some(ref fg) = modifiers.on_filegroup {
9873 self.write_space();
9874 self.write_keyword("ON");
9875 self.write_space();
9876 let _ = self.generate_identifier(fg);
9877 }
9878 }
9879
9880 fn generate_constraint_modifiers_without_using(&mut self, modifiers: &ConstraintModifiers) {
9882 if let Some(enforced) = modifiers.enforced {
9884 self.write_space();
9885 if enforced {
9886 self.write_keyword("ENFORCED");
9887 } else {
9888 self.write_keyword("NOT ENFORCED");
9889 }
9890 }
9891 if let Some(deferrable) = modifiers.deferrable {
9893 self.write_space();
9894 if deferrable {
9895 self.write_keyword("DEFERRABLE");
9896 } else {
9897 self.write_keyword("NOT DEFERRABLE");
9898 }
9899 }
9900 if let Some(initially_deferred) = modifiers.initially_deferred {
9902 self.write_space();
9903 if initially_deferred {
9904 self.write_keyword("INITIALLY DEFERRED");
9905 } else {
9906 self.write_keyword("INITIALLY IMMEDIATE");
9907 }
9908 }
9909 if modifiers.norely {
9911 self.write_space();
9912 self.write_keyword("NORELY");
9913 }
9914 if modifiers.rely {
9916 self.write_space();
9917 self.write_keyword("RELY");
9918 }
9919 if modifiers.not_valid {
9921 self.write_space();
9922 self.write_keyword("NOT VALID");
9923 }
9924 if let Some(on_conflict) = &modifiers.on_conflict {
9926 self.write_space();
9927 self.write_keyword("ON CONFLICT");
9928 self.write_space();
9929 self.write_keyword(on_conflict);
9930 }
9931 self.generate_index_specific_modifiers(modifiers);
9933 }
9934
9935 fn generate_index_specific_modifiers(&mut self, modifiers: &ConstraintModifiers) {
9937 if let Some(ref comment) = modifiers.comment {
9938 self.write_space();
9939 self.write_keyword("COMMENT");
9940 self.write(" '");
9941 self.write(comment);
9942 self.write("'");
9943 }
9944 if let Some(visible) = modifiers.visible {
9945 self.write_space();
9946 if visible {
9947 self.write_keyword("VISIBLE");
9948 } else {
9949 self.write_keyword("INVISIBLE");
9950 }
9951 }
9952 if let Some(ref attr) = modifiers.engine_attribute {
9953 self.write_space();
9954 self.write_keyword("ENGINE_ATTRIBUTE");
9955 self.write(" = '");
9956 self.write(attr);
9957 self.write("'");
9958 }
9959 if let Some(ref parser) = modifiers.with_parser {
9960 self.write_space();
9961 self.write_keyword("WITH PARSER");
9962 self.write_space();
9963 self.write(parser);
9964 }
9965 }
9966
9967 fn generate_referential_actions(&mut self, fk_ref: &ForeignKeyRef) -> Result<()> {
9968 if !fk_ref.match_after_actions {
9970 if let Some(ref match_type) = fk_ref.match_type {
9971 self.write_space();
9972 self.write_keyword("MATCH");
9973 self.write_space();
9974 match match_type {
9975 MatchType::Full => self.write_keyword("FULL"),
9976 MatchType::Partial => self.write_keyword("PARTIAL"),
9977 MatchType::Simple => self.write_keyword("SIMPLE"),
9978 }
9979 }
9980 }
9981
9982 if fk_ref.on_update_first {
9984 if let Some(ref action) = fk_ref.on_update {
9985 self.write_space();
9986 self.write_keyword("ON UPDATE");
9987 self.write_space();
9988 self.generate_referential_action(action);
9989 }
9990 if let Some(ref action) = fk_ref.on_delete {
9991 self.write_space();
9992 self.write_keyword("ON DELETE");
9993 self.write_space();
9994 self.generate_referential_action(action);
9995 }
9996 } else {
9997 if let Some(ref action) = fk_ref.on_delete {
9998 self.write_space();
9999 self.write_keyword("ON DELETE");
10000 self.write_space();
10001 self.generate_referential_action(action);
10002 }
10003 if let Some(ref action) = fk_ref.on_update {
10004 self.write_space();
10005 self.write_keyword("ON UPDATE");
10006 self.write_space();
10007 self.generate_referential_action(action);
10008 }
10009 }
10010
10011 if fk_ref.match_after_actions {
10013 if let Some(ref match_type) = fk_ref.match_type {
10014 self.write_space();
10015 self.write_keyword("MATCH");
10016 self.write_space();
10017 match match_type {
10018 MatchType::Full => self.write_keyword("FULL"),
10019 MatchType::Partial => self.write_keyword("PARTIAL"),
10020 MatchType::Simple => self.write_keyword("SIMPLE"),
10021 }
10022 }
10023 }
10024
10025 if let Some(deferrable) = fk_ref.deferrable {
10027 self.write_space();
10028 if deferrable {
10029 self.write_keyword("DEFERRABLE");
10030 } else {
10031 self.write_keyword("NOT DEFERRABLE");
10032 }
10033 }
10034
10035 Ok(())
10036 }
10037
10038 fn generate_referential_action(&mut self, action: &ReferentialAction) {
10039 match action {
10040 ReferentialAction::Cascade => self.write_keyword("CASCADE"),
10041 ReferentialAction::SetNull => self.write_keyword("SET NULL"),
10042 ReferentialAction::SetDefault => self.write_keyword("SET DEFAULT"),
10043 ReferentialAction::Restrict => self.write_keyword("RESTRICT"),
10044 ReferentialAction::NoAction => self.write_keyword("NO ACTION"),
10045 }
10046 }
10047
10048 fn generate_drop_table(&mut self, dt: &DropTable) -> Result<()> {
10049 if let Some(ref object_id_args) = dt.object_id_args {
10051 if matches!(
10052 self.config.dialect,
10053 Some(crate::dialects::DialectType::TSQL)
10054 | Some(crate::dialects::DialectType::Fabric)
10055 ) {
10056 self.write_keyword("IF NOT OBJECT_ID");
10057 self.write("(");
10058 self.write(object_id_args);
10059 self.write(")");
10060 self.write_space();
10061 self.write_keyword("IS NULL BEGIN DROP TABLE");
10062 self.write_space();
10063 for (i, table) in dt.names.iter().enumerate() {
10064 if i > 0 {
10065 self.write(", ");
10066 }
10067 self.generate_table(table)?;
10068 }
10069 self.write("; ");
10070 self.write_keyword("END");
10071 return Ok(());
10072 }
10073 }
10074
10075 let saved_athena_hive_context = self.athena_hive_context;
10077 if matches!(
10078 self.config.dialect,
10079 Some(crate::dialects::DialectType::Athena)
10080 ) {
10081 self.athena_hive_context = true;
10082 }
10083
10084 for comment in &dt.leading_comments {
10086 self.write_formatted_comment(comment);
10087 self.write_space();
10088 }
10089 if dt.iceberg {
10090 self.write_keyword("DROP ICEBERG TABLE");
10091 } else {
10092 self.write_keyword("DROP TABLE");
10093 }
10094
10095 if dt.if_exists {
10096 self.write_space();
10097 self.write_keyword("IF EXISTS");
10098 }
10099
10100 self.write_space();
10101 for (i, table) in dt.names.iter().enumerate() {
10102 if i > 0 {
10103 self.write(", ");
10104 }
10105 self.generate_table(table)?;
10106 }
10107
10108 if dt.cascade_constraints {
10109 self.write_space();
10110 self.write_keyword("CASCADE CONSTRAINTS");
10111 } else if dt.cascade {
10112 self.write_space();
10113 self.write_keyword("CASCADE");
10114 }
10115
10116 if dt.restrict {
10117 self.write_space();
10118 self.write_keyword("RESTRICT");
10119 }
10120
10121 if dt.purge {
10122 self.write_space();
10123 self.write_keyword("PURGE");
10124 }
10125
10126 if dt.sync {
10127 self.write_space();
10128 self.write_keyword("SYNC");
10129 }
10130
10131 self.athena_hive_context = saved_athena_hive_context;
10133
10134 Ok(())
10135 }
10136
10137 fn generate_undrop(&mut self, u: &Undrop) -> Result<()> {
10138 self.write_keyword("UNDROP");
10139 self.write_space();
10140 self.write_keyword(&u.kind);
10141 if u.if_exists {
10142 self.write_space();
10143 self.write_keyword("IF EXISTS");
10144 }
10145 self.write_space();
10146 self.generate_table(&u.name)?;
10147 Ok(())
10148 }
10149
10150 fn generate_alter_table(&mut self, at: &AlterTable) -> Result<()> {
10151 let saved_athena_hive_context = self.athena_hive_context;
10153 if matches!(
10154 self.config.dialect,
10155 Some(crate::dialects::DialectType::Athena)
10156 ) {
10157 self.athena_hive_context = true;
10158 }
10159
10160 self.write_keyword("ALTER");
10161 if let Some(ref modifier) = at.table_modifier {
10163 if !matches!(
10164 self.config.dialect,
10165 Some(crate::dialects::DialectType::DuckDB)
10166 ) {
10167 self.write_space();
10168 self.write_keyword(modifier);
10169 }
10170 }
10171 self.write(" ");
10172 self.write_keyword("TABLE");
10173 if at.if_exists {
10174 self.write_space();
10175 self.write_keyword("IF EXISTS");
10176 }
10177 self.write_space();
10178 self.generate_table(&at.name)?;
10179
10180 if let Some(ref on_cluster) = at.on_cluster {
10182 self.write_space();
10183 self.generate_on_cluster(on_cluster)?;
10184 }
10185
10186 if let Some(ref partition) = at.partition {
10188 self.write_space();
10189 self.write_keyword("PARTITION");
10190 self.write("(");
10191 for (i, (key, value)) in partition.iter().enumerate() {
10192 if i > 0 {
10193 self.write(", ");
10194 }
10195 self.generate_identifier(key)?;
10196 self.write(" = ");
10197 self.generate_expression(value)?;
10198 }
10199 self.write(")");
10200 }
10201
10202 if let Some(ref with_check) = at.with_check {
10204 self.write_space();
10205 self.write_keyword(with_check);
10206 }
10207
10208 if self.config.pretty {
10209 self.write_newline();
10211 self.indent_level += 1;
10212 for (i, action) in at.actions.iter().enumerate() {
10213 let is_continuation = i > 0
10215 && matches!(
10216 (&at.actions[i - 1], action),
10217 (
10218 AlterTableAction::AddColumn { .. },
10219 AlterTableAction::AddColumn { .. }
10220 ) | (
10221 AlterTableAction::AddConstraint(_),
10222 AlterTableAction::AddConstraint(_)
10223 )
10224 );
10225 if i > 0 {
10226 self.write(",");
10227 self.write_newline();
10228 }
10229 self.write_indent();
10230 self.generate_alter_action_with_continuation(action, is_continuation)?;
10231 }
10232 self.indent_level -= 1;
10233 } else {
10234 for (i, action) in at.actions.iter().enumerate() {
10235 let is_continuation = i > 0
10237 && matches!(
10238 (&at.actions[i - 1], action),
10239 (
10240 AlterTableAction::AddColumn { .. },
10241 AlterTableAction::AddColumn { .. }
10242 ) | (
10243 AlterTableAction::AddConstraint(_),
10244 AlterTableAction::AddConstraint(_)
10245 )
10246 );
10247 if i > 0 {
10248 self.write(",");
10249 }
10250 self.write_space();
10251 self.generate_alter_action_with_continuation(action, is_continuation)?;
10252 }
10253 }
10254
10255 if let Some(ref algorithm) = at.algorithm {
10257 self.write(", ");
10258 self.write_keyword("ALGORITHM");
10259 self.write("=");
10260 self.write_keyword(algorithm);
10261 }
10262 if let Some(ref lock) = at.lock {
10263 self.write(", ");
10264 self.write_keyword("LOCK");
10265 self.write("=");
10266 self.write_keyword(lock);
10267 }
10268
10269 self.athena_hive_context = saved_athena_hive_context;
10271
10272 Ok(())
10273 }
10274
10275 fn generate_alter_action_with_continuation(
10276 &mut self,
10277 action: &AlterTableAction,
10278 is_continuation: bool,
10279 ) -> Result<()> {
10280 match action {
10281 AlterTableAction::AddColumn {
10282 column,
10283 if_not_exists,
10284 position,
10285 } => {
10286 use crate::dialects::DialectType;
10287 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
10291 let is_tsql_like = matches!(
10292 self.config.dialect,
10293 Some(DialectType::TSQL) | Some(DialectType::Fabric)
10294 );
10295 let is_athena = matches!(self.config.dialect, Some(DialectType::Athena));
10297
10298 if is_continuation && (is_snowflake || is_tsql_like) {
10299 } else if is_snowflake {
10301 self.write_keyword("ADD");
10302 self.write_space();
10303 } else if is_athena {
10304 self.write_keyword("ADD COLUMNS");
10306 self.write(" (");
10307 } else if self.config.alter_table_include_column_keyword {
10308 self.write_keyword("ADD COLUMN");
10309 self.write_space();
10310 } else {
10311 self.write_keyword("ADD");
10313 self.write_space();
10314 }
10315
10316 if *if_not_exists {
10317 self.write_keyword("IF NOT EXISTS");
10318 self.write_space();
10319 }
10320 self.generate_column_def(column)?;
10321
10322 if is_athena {
10324 self.write(")");
10325 }
10326
10327 if let Some(pos) = position {
10329 self.write_space();
10330 match pos {
10331 ColumnPosition::First => self.write_keyword("FIRST"),
10332 ColumnPosition::After(col_name) => {
10333 self.write_keyword("AFTER");
10334 self.write_space();
10335 self.generate_identifier(col_name)?;
10336 }
10337 }
10338 }
10339 }
10340 AlterTableAction::DropColumn {
10341 name,
10342 if_exists,
10343 cascade,
10344 } => {
10345 self.write_keyword("DROP COLUMN");
10346 if *if_exists {
10347 self.write_space();
10348 self.write_keyword("IF EXISTS");
10349 }
10350 self.write_space();
10351 self.generate_identifier(name)?;
10352 if *cascade {
10353 self.write_space();
10354 self.write_keyword("CASCADE");
10355 }
10356 }
10357 AlterTableAction::DropColumns { names } => {
10358 self.write_keyword("DROP COLUMNS");
10359 self.write(" (");
10360 for (i, name) in names.iter().enumerate() {
10361 if i > 0 {
10362 self.write(", ");
10363 }
10364 self.generate_identifier(name)?;
10365 }
10366 self.write(")");
10367 }
10368 AlterTableAction::RenameColumn {
10369 old_name,
10370 new_name,
10371 if_exists,
10372 } => {
10373 self.write_keyword("RENAME COLUMN");
10374 if *if_exists {
10375 self.write_space();
10376 self.write_keyword("IF EXISTS");
10377 }
10378 self.write_space();
10379 self.generate_identifier(old_name)?;
10380 self.write_space();
10381 self.write_keyword("TO");
10382 self.write_space();
10383 self.generate_identifier(new_name)?;
10384 }
10385 AlterTableAction::AlterColumn {
10386 name,
10387 action,
10388 use_modify_keyword,
10389 } => {
10390 use crate::dialects::DialectType;
10391 let use_modify = *use_modify_keyword
10394 || (matches!(self.config.dialect, Some(DialectType::MySQL))
10395 && matches!(action, AlterColumnAction::SetDataType { .. }));
10396 if use_modify {
10397 self.write_keyword("MODIFY COLUMN");
10398 self.write_space();
10399 self.generate_identifier(name)?;
10400 if let AlterColumnAction::SetDataType {
10402 data_type,
10403 using: _,
10404 collate,
10405 } = action
10406 {
10407 self.write_space();
10408 self.generate_data_type(data_type)?;
10409 if let Some(collate_name) = collate {
10411 self.write_space();
10412 self.write_keyword("COLLATE");
10413 self.write_space();
10414 self.write(&format!("'{}'", collate_name));
10416 }
10417 } else {
10418 self.write_space();
10419 self.generate_alter_column_action(action)?;
10420 }
10421 } else if matches!(self.config.dialect, Some(DialectType::Hive))
10422 && matches!(action, AlterColumnAction::SetDataType { .. })
10423 {
10424 self.write_keyword("CHANGE COLUMN");
10426 self.write_space();
10427 self.generate_identifier(name)?;
10428 self.write_space();
10429 self.generate_identifier(name)?;
10430 if let AlterColumnAction::SetDataType { data_type, .. } = action {
10431 self.write_space();
10432 self.generate_data_type(data_type)?;
10433 }
10434 } else {
10435 self.write_keyword("ALTER COLUMN");
10436 self.write_space();
10437 self.generate_identifier(name)?;
10438 self.write_space();
10439 self.generate_alter_column_action(action)?;
10440 }
10441 }
10442 AlterTableAction::RenameTable(new_name) => {
10443 let mysql_like = matches!(
10445 self.config.dialect,
10446 Some(DialectType::MySQL)
10447 | Some(DialectType::Doris)
10448 | Some(DialectType::StarRocks)
10449 | Some(DialectType::SingleStore)
10450 );
10451 if mysql_like {
10452 self.write_keyword("RENAME");
10453 } else {
10454 self.write_keyword("RENAME TO");
10455 }
10456 self.write_space();
10457 let rename_table_with_db = !matches!(
10459 self.config.dialect,
10460 Some(DialectType::Doris)
10461 | Some(DialectType::DuckDB)
10462 | Some(DialectType::BigQuery)
10463 | Some(DialectType::PostgreSQL)
10464 );
10465 if !rename_table_with_db {
10466 let mut stripped = new_name.clone();
10467 stripped.schema = None;
10468 stripped.catalog = None;
10469 self.generate_table(&stripped)?;
10470 } else {
10471 self.generate_table(new_name)?;
10472 }
10473 }
10474 AlterTableAction::AddConstraint(constraint) => {
10475 if !is_continuation {
10478 self.write_keyword("ADD");
10479 self.write_space();
10480 }
10481 self.generate_table_constraint(constraint)?;
10482 }
10483 AlterTableAction::DropConstraint { name, if_exists } => {
10484 self.write_keyword("DROP CONSTRAINT");
10485 if *if_exists {
10486 self.write_space();
10487 self.write_keyword("IF EXISTS");
10488 }
10489 self.write_space();
10490 self.generate_identifier(name)?;
10491 }
10492 AlterTableAction::DropForeignKey { name } => {
10493 self.write_keyword("DROP FOREIGN KEY");
10494 self.write_space();
10495 self.generate_identifier(name)?;
10496 }
10497 AlterTableAction::DropPartition {
10498 partitions,
10499 if_exists,
10500 } => {
10501 self.write_keyword("DROP");
10502 if *if_exists {
10503 self.write_space();
10504 self.write_keyword("IF EXISTS");
10505 }
10506 for (i, partition) in partitions.iter().enumerate() {
10507 if i > 0 {
10508 self.write(",");
10509 }
10510 self.write_space();
10511 self.write_keyword("PARTITION");
10512 if partition.len() == 1 && partition[0].0.name == "__expr__" {
10514 self.write_space();
10516 self.generate_expression(&partition[0].1)?;
10517 } else if partition.len() == 1 && partition[0].0.name == "ALL" {
10518 self.write_space();
10520 self.write_keyword("ALL");
10521 } else if partition.len() == 1 && partition[0].0.name == "ID" {
10522 self.write_space();
10524 self.write_keyword("ID");
10525 self.write_space();
10526 self.generate_expression(&partition[0].1)?;
10527 } else {
10528 self.write("(");
10530 for (j, (key, value)) in partition.iter().enumerate() {
10531 if j > 0 {
10532 self.write(", ");
10533 }
10534 self.generate_identifier(key)?;
10535 self.write(" = ");
10536 self.generate_expression(value)?;
10537 }
10538 self.write(")");
10539 }
10540 }
10541 }
10542 AlterTableAction::Delete { where_clause } => {
10543 self.write_keyword("DELETE");
10544 self.write_space();
10545 self.write_keyword("WHERE");
10546 self.write_space();
10547 self.generate_expression(where_clause)?;
10548 }
10549 AlterTableAction::SwapWith(target) => {
10550 self.write_keyword("SWAP WITH");
10551 self.write_space();
10552 self.generate_table(target)?;
10553 }
10554 AlterTableAction::SetProperty { properties } => {
10555 use crate::dialects::DialectType;
10556 self.write_keyword("SET");
10557 let is_trino_presto = matches!(
10559 self.config.dialect,
10560 Some(DialectType::Trino) | Some(DialectType::Presto)
10561 );
10562 if is_trino_presto {
10563 self.write_space();
10564 self.write_keyword("PROPERTIES");
10565 }
10566 let eq = if is_trino_presto { " = " } else { "=" };
10567 for (i, (key, value)) in properties.iter().enumerate() {
10568 if i > 0 {
10569 self.write(",");
10570 }
10571 self.write_space();
10572 if key.contains(' ') {
10574 self.generate_string_literal(key)?;
10575 } else {
10576 self.write(key);
10577 }
10578 self.write(eq);
10579 self.generate_expression(value)?;
10580 }
10581 }
10582 AlterTableAction::UnsetProperty { properties } => {
10583 self.write_keyword("UNSET");
10584 for (i, name) in properties.iter().enumerate() {
10585 if i > 0 {
10586 self.write(",");
10587 }
10588 self.write_space();
10589 self.write(name);
10590 }
10591 }
10592 AlterTableAction::ClusterBy { expressions } => {
10593 self.write_keyword("CLUSTER BY");
10594 self.write(" (");
10595 for (i, expr) in expressions.iter().enumerate() {
10596 if i > 0 {
10597 self.write(", ");
10598 }
10599 self.generate_expression(expr)?;
10600 }
10601 self.write(")");
10602 }
10603 AlterTableAction::SetTag { expressions } => {
10604 self.write_keyword("SET TAG");
10605 for (i, (key, value)) in expressions.iter().enumerate() {
10606 if i > 0 {
10607 self.write(",");
10608 }
10609 self.write_space();
10610 self.write(key);
10611 self.write(" = ");
10612 self.generate_expression(value)?;
10613 }
10614 }
10615 AlterTableAction::UnsetTag { names } => {
10616 self.write_keyword("UNSET TAG");
10617 for (i, name) in names.iter().enumerate() {
10618 if i > 0 {
10619 self.write(",");
10620 }
10621 self.write_space();
10622 self.write(name);
10623 }
10624 }
10625 AlterTableAction::SetOptions { expressions } => {
10626 self.write_keyword("SET");
10627 self.write(" (");
10628 for (i, expr) in expressions.iter().enumerate() {
10629 if i > 0 {
10630 self.write(", ");
10631 }
10632 self.generate_expression(expr)?;
10633 }
10634 self.write(")");
10635 }
10636 AlterTableAction::AlterIndex { name, visible } => {
10637 self.write_keyword("ALTER INDEX");
10638 self.write_space();
10639 self.generate_identifier(name)?;
10640 self.write_space();
10641 if *visible {
10642 self.write_keyword("VISIBLE");
10643 } else {
10644 self.write_keyword("INVISIBLE");
10645 }
10646 }
10647 AlterTableAction::SetAttribute { attribute } => {
10648 self.write_keyword("SET");
10649 self.write_space();
10650 self.write_keyword(attribute);
10651 }
10652 AlterTableAction::SetStageFileFormat { options } => {
10653 self.write_keyword("SET");
10654 self.write_space();
10655 self.write_keyword("STAGE_FILE_FORMAT");
10656 self.write(" = (");
10657 if let Some(opts) = options {
10658 self.generate_space_separated_properties(opts)?;
10659 }
10660 self.write(")");
10661 }
10662 AlterTableAction::SetStageCopyOptions { options } => {
10663 self.write_keyword("SET");
10664 self.write_space();
10665 self.write_keyword("STAGE_COPY_OPTIONS");
10666 self.write(" = (");
10667 if let Some(opts) = options {
10668 self.generate_space_separated_properties(opts)?;
10669 }
10670 self.write(")");
10671 }
10672 AlterTableAction::AddColumns { columns, cascade } => {
10673 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
10676 if is_oracle {
10677 self.write_keyword("ADD");
10678 } else {
10679 self.write_keyword("ADD COLUMNS");
10680 }
10681 self.write(" (");
10682 for (i, col) in columns.iter().enumerate() {
10683 if i > 0 {
10684 self.write(", ");
10685 }
10686 self.generate_column_def(col)?;
10687 }
10688 self.write(")");
10689 if *cascade {
10690 self.write_space();
10691 self.write_keyword("CASCADE");
10692 }
10693 }
10694 AlterTableAction::ChangeColumn {
10695 old_name,
10696 new_name,
10697 data_type,
10698 comment,
10699 cascade,
10700 } => {
10701 use crate::dialects::DialectType;
10702 let is_spark = matches!(
10703 self.config.dialect,
10704 Some(DialectType::Spark) | Some(DialectType::Databricks)
10705 );
10706 let is_rename = old_name.name != new_name.name;
10707
10708 if is_spark {
10709 if is_rename {
10710 self.write_keyword("RENAME COLUMN");
10712 self.write_space();
10713 self.generate_identifier(old_name)?;
10714 self.write_space();
10715 self.write_keyword("TO");
10716 self.write_space();
10717 self.generate_identifier(new_name)?;
10718 } else if comment.is_some() {
10719 self.write_keyword("ALTER COLUMN");
10721 self.write_space();
10722 self.generate_identifier(old_name)?;
10723 self.write_space();
10724 self.write_keyword("COMMENT");
10725 self.write_space();
10726 self.write("'");
10727 self.write(comment.as_ref().unwrap());
10728 self.write("'");
10729 } else if data_type.is_some() {
10730 self.write_keyword("ALTER COLUMN");
10732 self.write_space();
10733 self.generate_identifier(old_name)?;
10734 self.write_space();
10735 self.write_keyword("TYPE");
10736 self.write_space();
10737 self.generate_data_type(data_type.as_ref().unwrap())?;
10738 } else {
10739 self.write_keyword("CHANGE COLUMN");
10741 self.write_space();
10742 self.generate_identifier(old_name)?;
10743 self.write_space();
10744 self.generate_identifier(new_name)?;
10745 }
10746 } else {
10747 if data_type.is_some() {
10749 self.write_keyword("CHANGE COLUMN");
10750 } else {
10751 self.write_keyword("CHANGE");
10752 }
10753 self.write_space();
10754 self.generate_identifier(old_name)?;
10755 self.write_space();
10756 self.generate_identifier(new_name)?;
10757 if let Some(ref dt) = data_type {
10758 self.write_space();
10759 self.generate_data_type(dt)?;
10760 }
10761 if let Some(ref c) = comment {
10762 self.write_space();
10763 self.write_keyword("COMMENT");
10764 self.write_space();
10765 self.write("'");
10766 self.write(c);
10767 self.write("'");
10768 }
10769 if *cascade {
10770 self.write_space();
10771 self.write_keyword("CASCADE");
10772 }
10773 }
10774 }
10775 AlterTableAction::AddPartition {
10776 partition,
10777 if_not_exists,
10778 location,
10779 } => {
10780 self.write_keyword("ADD");
10781 self.write_space();
10782 if *if_not_exists {
10783 self.write_keyword("IF NOT EXISTS");
10784 self.write_space();
10785 }
10786 self.generate_expression(partition)?;
10787 if let Some(ref loc) = location {
10788 self.write_space();
10789 self.write_keyword("LOCATION");
10790 self.write_space();
10791 self.generate_expression(loc)?;
10792 }
10793 }
10794 AlterTableAction::AlterSortKey {
10795 this,
10796 expressions,
10797 compound,
10798 } => {
10799 self.write_keyword("ALTER");
10801 if *compound {
10802 self.write_space();
10803 self.write_keyword("COMPOUND");
10804 }
10805 self.write_space();
10806 self.write_keyword("SORTKEY");
10807 self.write_space();
10808 if let Some(style) = this {
10809 self.write_keyword(style);
10810 } else if !expressions.is_empty() {
10811 self.write("(");
10812 for (i, expr) in expressions.iter().enumerate() {
10813 if i > 0 {
10814 self.write(", ");
10815 }
10816 self.generate_expression(expr)?;
10817 }
10818 self.write(")");
10819 }
10820 }
10821 AlterTableAction::AlterDistStyle { style, distkey } => {
10822 self.write_keyword("ALTER");
10824 self.write_space();
10825 self.write_keyword("DISTSTYLE");
10826 self.write_space();
10827 self.write_keyword(style);
10828 if let Some(col) = distkey {
10829 self.write_space();
10830 self.write_keyword("DISTKEY");
10831 self.write_space();
10832 self.generate_identifier(col)?;
10833 }
10834 }
10835 AlterTableAction::SetTableProperties { properties } => {
10836 self.write_keyword("SET TABLE PROPERTIES");
10838 self.write(" (");
10839 for (i, (key, value)) in properties.iter().enumerate() {
10840 if i > 0 {
10841 self.write(", ");
10842 }
10843 self.generate_expression(key)?;
10844 self.write(" = ");
10845 self.generate_expression(value)?;
10846 }
10847 self.write(")");
10848 }
10849 AlterTableAction::SetLocation { location } => {
10850 self.write_keyword("SET LOCATION");
10852 self.write_space();
10853 self.write("'");
10854 self.write(location);
10855 self.write("'");
10856 }
10857 AlterTableAction::SetFileFormat { format } => {
10858 self.write_keyword("SET FILE FORMAT");
10860 self.write_space();
10861 self.write_keyword(format);
10862 }
10863 AlterTableAction::ReplacePartition { partition, source } => {
10864 self.write_keyword("REPLACE PARTITION");
10866 self.write_space();
10867 self.generate_expression(partition)?;
10868 if let Some(src) = source {
10869 self.write_space();
10870 self.write_keyword("FROM");
10871 self.write_space();
10872 self.generate_expression(src)?;
10873 }
10874 }
10875 AlterTableAction::Raw { sql } => {
10876 self.write(sql);
10877 }
10878 }
10879 Ok(())
10880 }
10881
10882 fn generate_alter_column_action(&mut self, action: &AlterColumnAction) -> Result<()> {
10883 match action {
10884 AlterColumnAction::SetDataType {
10885 data_type,
10886 using,
10887 collate,
10888 } => {
10889 use crate::dialects::DialectType;
10890 let is_no_prefix = matches!(
10895 self.config.dialect,
10896 Some(DialectType::TSQL) | Some(DialectType::Fabric) | Some(DialectType::Hive)
10897 );
10898 let is_type_only = matches!(
10899 self.config.dialect,
10900 Some(DialectType::Redshift)
10901 | Some(DialectType::Spark)
10902 | Some(DialectType::Databricks)
10903 );
10904 if is_type_only {
10905 self.write_keyword("TYPE");
10906 self.write_space();
10907 } else if !is_no_prefix {
10908 self.write_keyword("SET DATA TYPE");
10909 self.write_space();
10910 }
10911 self.generate_data_type(data_type)?;
10912 if let Some(ref collation) = collate {
10913 self.write_space();
10914 self.write_keyword("COLLATE");
10915 self.write_space();
10916 self.write(collation);
10917 }
10918 if let Some(ref using_expr) = using {
10919 self.write_space();
10920 self.write_keyword("USING");
10921 self.write_space();
10922 self.generate_expression(using_expr)?;
10923 }
10924 }
10925 AlterColumnAction::SetDefault(expr) => {
10926 self.write_keyword("SET DEFAULT");
10927 self.write_space();
10928 self.generate_expression(expr)?;
10929 }
10930 AlterColumnAction::DropDefault => {
10931 self.write_keyword("DROP DEFAULT");
10932 }
10933 AlterColumnAction::SetNotNull => {
10934 self.write_keyword("SET NOT NULL");
10935 }
10936 AlterColumnAction::DropNotNull => {
10937 self.write_keyword("DROP NOT NULL");
10938 }
10939 AlterColumnAction::Comment(comment) => {
10940 self.write_keyword("COMMENT");
10941 self.write_space();
10942 self.generate_string_literal(comment)?;
10943 }
10944 AlterColumnAction::SetVisible => {
10945 self.write_keyword("SET VISIBLE");
10946 }
10947 AlterColumnAction::SetInvisible => {
10948 self.write_keyword("SET INVISIBLE");
10949 }
10950 }
10951 Ok(())
10952 }
10953
10954 fn generate_create_index(&mut self, ci: &CreateIndex) -> Result<()> {
10955 self.write_keyword("CREATE");
10956
10957 if ci.unique {
10958 self.write_space();
10959 self.write_keyword("UNIQUE");
10960 }
10961
10962 if let Some(ref clustered) = ci.clustered {
10964 self.write_space();
10965 self.write_keyword(clustered);
10966 }
10967
10968 self.write_space();
10969 self.write_keyword("INDEX");
10970
10971 if ci.concurrently {
10973 self.write_space();
10974 self.write_keyword("CONCURRENTLY");
10975 }
10976
10977 if ci.if_not_exists {
10978 self.write_space();
10979 self.write_keyword("IF NOT EXISTS");
10980 }
10981
10982 if !ci.name.name.is_empty() {
10984 self.write_space();
10985 self.generate_identifier(&ci.name)?;
10986 }
10987 self.write_space();
10988 self.write_keyword("ON");
10989 if matches!(self.config.dialect, Some(DialectType::Hive)) {
10991 self.write_space();
10992 self.write_keyword("TABLE");
10993 }
10994 self.write_space();
10995 self.generate_table(&ci.table)?;
10996
10997 if !ci.columns.is_empty() || ci.using.is_some() {
11000 let space_before_paren = false;
11001
11002 if let Some(ref using) = ci.using {
11003 self.write_space();
11004 self.write_keyword("USING");
11005 self.write_space();
11006 self.write(using);
11007 if space_before_paren {
11008 self.write(" (");
11009 } else {
11010 self.write("(");
11011 }
11012 } else {
11013 if space_before_paren {
11014 self.write(" (");
11015 } else {
11016 self.write("(");
11017 }
11018 }
11019 for (i, col) in ci.columns.iter().enumerate() {
11020 if i > 0 {
11021 self.write(", ");
11022 }
11023 self.generate_identifier(&col.column)?;
11024 if let Some(ref opclass) = col.opclass {
11025 self.write_space();
11026 self.write(opclass);
11027 }
11028 if col.desc {
11029 self.write_space();
11030 self.write_keyword("DESC");
11031 } else if col.asc {
11032 self.write_space();
11033 self.write_keyword("ASC");
11034 }
11035 if let Some(nulls_first) = col.nulls_first {
11036 self.write_space();
11037 self.write_keyword("NULLS");
11038 self.write_space();
11039 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
11040 }
11041 }
11042 self.write(")");
11043 }
11044
11045 if !ci.include_columns.is_empty() {
11047 self.write_space();
11048 self.write_keyword("INCLUDE");
11049 self.write(" (");
11050 for (i, col) in ci.include_columns.iter().enumerate() {
11051 if i > 0 {
11052 self.write(", ");
11053 }
11054 self.generate_identifier(col)?;
11055 }
11056 self.write(")");
11057 }
11058
11059 if !ci.with_options.is_empty() {
11061 self.write_space();
11062 self.write_keyword("WITH");
11063 self.write(" (");
11064 for (i, (key, value)) in ci.with_options.iter().enumerate() {
11065 if i > 0 {
11066 self.write(", ");
11067 }
11068 self.write(key);
11069 self.write("=");
11070 self.write(value);
11071 }
11072 self.write(")");
11073 }
11074
11075 if let Some(ref where_clause) = ci.where_clause {
11077 self.write_space();
11078 self.write_keyword("WHERE");
11079 self.write_space();
11080 self.generate_expression(where_clause)?;
11081 }
11082
11083 if let Some(ref on_fg) = ci.on_filegroup {
11085 self.write_space();
11086 self.write_keyword("ON");
11087 self.write_space();
11088 self.write(on_fg);
11089 }
11090
11091 Ok(())
11092 }
11093
11094 fn generate_drop_index(&mut self, di: &DropIndex) -> Result<()> {
11095 self.write_keyword("DROP INDEX");
11096
11097 if di.concurrently {
11098 self.write_space();
11099 self.write_keyword("CONCURRENTLY");
11100 }
11101
11102 if di.if_exists {
11103 self.write_space();
11104 self.write_keyword("IF EXISTS");
11105 }
11106
11107 self.write_space();
11108 self.generate_identifier(&di.name)?;
11109
11110 if let Some(ref table) = di.table {
11111 self.write_space();
11112 self.write_keyword("ON");
11113 self.write_space();
11114 self.generate_table(table)?;
11115 }
11116
11117 Ok(())
11118 }
11119
11120 fn generate_create_view(&mut self, cv: &CreateView) -> Result<()> {
11121 self.write_keyword("CREATE");
11122
11123 if let Some(ref algorithm) = cv.algorithm {
11125 self.write_space();
11126 self.write_keyword("ALGORITHM");
11127 self.write("=");
11128 self.write_keyword(algorithm);
11129 }
11130
11131 if let Some(ref definer) = cv.definer {
11133 self.write_space();
11134 self.write_keyword("DEFINER");
11135 self.write("=");
11136 self.write(definer);
11137 }
11138
11139 if cv.security_sql_style && !cv.security_after_name {
11141 if let Some(ref security) = cv.security {
11142 self.write_space();
11143 self.write_keyword("SQL SECURITY");
11144 self.write_space();
11145 match security {
11146 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
11147 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
11148 FunctionSecurity::None => self.write_keyword("NONE"),
11149 }
11150 }
11151 }
11152
11153 if cv.or_alter {
11154 self.write_space();
11155 self.write_keyword("OR ALTER");
11156 } else if cv.or_replace {
11157 self.write_space();
11158 self.write_keyword("OR REPLACE");
11159 }
11160
11161 if cv.temporary {
11162 self.write_space();
11163 self.write_keyword("TEMPORARY");
11164 }
11165
11166 if cv.materialized {
11167 self.write_space();
11168 self.write_keyword("MATERIALIZED");
11169 }
11170
11171 if cv.secure {
11173 self.write_space();
11174 self.write_keyword("SECURE");
11175 }
11176
11177 self.write_space();
11178 self.write_keyword("VIEW");
11179
11180 if cv.if_not_exists {
11181 self.write_space();
11182 self.write_keyword("IF NOT EXISTS");
11183 }
11184
11185 self.write_space();
11186 self.generate_table(&cv.name)?;
11187
11188 if let Some(ref on_cluster) = cv.on_cluster {
11190 self.write_space();
11191 self.generate_on_cluster(on_cluster)?;
11192 }
11193
11194 if let Some(ref to_table) = cv.to_table {
11196 self.write_space();
11197 self.write_keyword("TO");
11198 self.write_space();
11199 self.generate_table(to_table)?;
11200 }
11201
11202 if !cv.materialized {
11205 if !cv.columns.is_empty() {
11207 self.write(" (");
11208 for (i, col) in cv.columns.iter().enumerate() {
11209 if i > 0 {
11210 self.write(", ");
11211 }
11212 self.generate_identifier(&col.name)?;
11213 if !col.options.is_empty() {
11215 self.write_space();
11216 self.generate_options_clause(&col.options)?;
11217 }
11218 if let Some(ref comment) = col.comment {
11219 self.write_space();
11220 self.write_keyword("COMMENT");
11221 self.write_space();
11222 self.generate_string_literal(comment)?;
11223 }
11224 }
11225 self.write(")");
11226 }
11227
11228 if !cv.security_sql_style || cv.security_after_name {
11231 if let Some(ref security) = cv.security {
11232 self.write_space();
11233 if cv.security_sql_style {
11234 self.write_keyword("SQL SECURITY");
11235 } else {
11236 self.write_keyword("SECURITY");
11237 }
11238 self.write_space();
11239 match security {
11240 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
11241 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
11242 FunctionSecurity::None => self.write_keyword("NONE"),
11243 }
11244 }
11245 }
11246
11247 if cv.copy_grants {
11249 self.write_space();
11250 self.write_keyword("COPY GRANTS");
11251 }
11252 } else {
11253 if cv.copy_grants {
11255 self.write_space();
11256 self.write_keyword("COPY GRANTS");
11257 }
11258
11259 if let Some(ref schema) = cv.schema {
11261 self.write(" (");
11262 for (i, expr) in schema.expressions.iter().enumerate() {
11263 if i > 0 {
11264 self.write(", ");
11265 }
11266 self.generate_expression(expr)?;
11267 }
11268 self.write(")");
11269 } else if !cv.columns.is_empty() {
11270 self.write(" (");
11272 for (i, col) in cv.columns.iter().enumerate() {
11273 if i > 0 {
11274 self.write(", ");
11275 }
11276 self.generate_identifier(&col.name)?;
11277 if !col.options.is_empty() {
11279 self.write_space();
11280 self.generate_options_clause(&col.options)?;
11281 }
11282 if let Some(ref comment) = col.comment {
11283 self.write_space();
11284 self.write_keyword("COMMENT");
11285 self.write_space();
11286 self.generate_string_literal(comment)?;
11287 }
11288 }
11289 self.write(")");
11290 }
11291
11292 if let Some(ref unique_key) = cv.unique_key {
11294 self.write_space();
11295 self.write_keyword("KEY");
11296 self.write(" (");
11297 for (i, expr) in unique_key.expressions.iter().enumerate() {
11298 if i > 0 {
11299 self.write(", ");
11300 }
11301 self.generate_expression(expr)?;
11302 }
11303 self.write(")");
11304 }
11305 }
11306
11307 if let Some(ref row_access_policy) = cv.row_access_policy {
11308 self.write_space();
11309 self.write_keyword("WITH");
11310 self.write_space();
11311 self.write(row_access_policy);
11312 }
11313
11314 if let Some(ref comment) = cv.comment {
11316 self.write_space();
11317 self.write_keyword("COMMENT");
11318 self.write("=");
11319 self.generate_string_literal(comment)?;
11320 }
11321
11322 if !cv.tags.is_empty() {
11324 self.write_space();
11325 self.write_keyword("TAG");
11326 self.write(" (");
11327 for (i, (name, value)) in cv.tags.iter().enumerate() {
11328 if i > 0 {
11329 self.write(", ");
11330 }
11331 self.write(name);
11332 self.write("='");
11333 self.write(value);
11334 self.write("'");
11335 }
11336 self.write(")");
11337 }
11338
11339 if !cv.options.is_empty() {
11341 self.write_space();
11342 self.generate_options_clause(&cv.options)?;
11343 }
11344
11345 if let Some(ref build) = cv.build {
11347 self.write_space();
11348 self.write_keyword("BUILD");
11349 self.write_space();
11350 self.write_keyword(build);
11351 }
11352
11353 if let Some(ref refresh) = cv.refresh {
11355 self.write_space();
11356 self.generate_refresh_trigger_property(refresh)?;
11357 }
11358
11359 if let Some(auto_refresh) = cv.auto_refresh {
11361 self.write_space();
11362 self.write_keyword("AUTO REFRESH");
11363 self.write_space();
11364 if auto_refresh {
11365 self.write_keyword("YES");
11366 } else {
11367 self.write_keyword("NO");
11368 }
11369 }
11370
11371 for prop in &cv.table_properties {
11373 self.write_space();
11374 self.generate_expression(prop)?;
11375 }
11376
11377 if let Some(ref population) = cv.clickhouse_population {
11379 self.write_space();
11380 self.write_keyword(population);
11381 }
11382
11383 if !matches!(&cv.query, Expression::Null(_)) {
11385 self.write_space();
11386 self.write_keyword("AS");
11387 self.write_space();
11388
11389 if let Some(ref mode) = cv.locking_mode {
11391 self.write_keyword("LOCKING");
11392 self.write_space();
11393 self.write_keyword(mode);
11394 if let Some(ref access) = cv.locking_access {
11395 self.write_space();
11396 self.write_keyword("FOR");
11397 self.write_space();
11398 self.write_keyword(access);
11399 }
11400 self.write_space();
11401 }
11402
11403 if cv.query_parenthesized {
11404 self.write("(");
11405 }
11406 self.generate_expression(&cv.query)?;
11407 if cv.query_parenthesized {
11408 self.write(")");
11409 }
11410 }
11411
11412 if cv.no_schema_binding {
11414 self.write_space();
11415 self.write_keyword("WITH NO SCHEMA BINDING");
11416 }
11417
11418 Ok(())
11419 }
11420
11421 fn generate_drop_view(&mut self, dv: &DropView) -> Result<()> {
11422 self.write_keyword("DROP");
11423
11424 if dv.materialized {
11425 self.write_space();
11426 self.write_keyword("MATERIALIZED");
11427 }
11428
11429 self.write_space();
11430 self.write_keyword("VIEW");
11431
11432 if dv.if_exists {
11433 self.write_space();
11434 self.write_keyword("IF EXISTS");
11435 }
11436
11437 self.write_space();
11438 self.generate_table(&dv.name)?;
11439
11440 Ok(())
11441 }
11442
11443 fn generate_truncate(&mut self, tr: &Truncate) -> Result<()> {
11444 match tr.target {
11445 TruncateTarget::Database => self.write_keyword("TRUNCATE DATABASE"),
11446 TruncateTarget::Table => self.write_keyword("TRUNCATE TABLE"),
11447 }
11448 if tr.if_exists {
11449 self.write_space();
11450 self.write_keyword("IF EXISTS");
11451 }
11452 self.write_space();
11453 self.generate_table(&tr.table)?;
11454
11455 if let Some(ref on_cluster) = tr.on_cluster {
11457 self.write_space();
11458 self.generate_on_cluster(on_cluster)?;
11459 }
11460
11461 if !tr.extra_tables.is_empty() {
11463 let skip_first = if let Some(first) = tr.extra_tables.first() {
11465 first.table.name == tr.table.name && first.star
11466 } else {
11467 false
11468 };
11469
11470 let strip_star = matches!(
11472 self.config.dialect,
11473 Some(crate::dialects::DialectType::PostgreSQL)
11474 | Some(crate::dialects::DialectType::Redshift)
11475 );
11476 if skip_first && !strip_star {
11477 self.write("*");
11478 }
11479
11480 for (i, entry) in tr.extra_tables.iter().enumerate() {
11482 if i == 0 && skip_first {
11483 continue; }
11485 self.write(", ");
11486 self.generate_table(&entry.table)?;
11487 if entry.star && !strip_star {
11488 self.write("*");
11489 }
11490 }
11491 }
11492
11493 if let Some(identity) = &tr.identity {
11495 self.write_space();
11496 match identity {
11497 TruncateIdentity::Restart => self.write_keyword("RESTART IDENTITY"),
11498 TruncateIdentity::Continue => self.write_keyword("CONTINUE IDENTITY"),
11499 }
11500 }
11501
11502 if tr.cascade {
11503 self.write_space();
11504 self.write_keyword("CASCADE");
11505 }
11506
11507 if tr.restrict {
11508 self.write_space();
11509 self.write_keyword("RESTRICT");
11510 }
11511
11512 if let Some(ref partition) = tr.partition {
11514 self.write_space();
11515 self.generate_expression(partition)?;
11516 }
11517
11518 Ok(())
11519 }
11520
11521 fn generate_use(&mut self, u: &Use) -> Result<()> {
11522 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
11524 self.write_keyword("DATABASE");
11525 self.write_space();
11526 self.generate_identifier(&u.this)?;
11527 return Ok(());
11528 }
11529
11530 self.write_keyword("USE");
11531
11532 if let Some(kind) = &u.kind {
11533 self.write_space();
11534 match kind {
11535 UseKind::Database => self.write_keyword("DATABASE"),
11536 UseKind::Schema => self.write_keyword("SCHEMA"),
11537 UseKind::Role => self.write_keyword("ROLE"),
11538 UseKind::Warehouse => self.write_keyword("WAREHOUSE"),
11539 UseKind::Catalog => self.write_keyword("CATALOG"),
11540 UseKind::SecondaryRoles => self.write_keyword("SECONDARY ROLES"),
11541 }
11542 }
11543
11544 self.write_space();
11545 if matches!(&u.kind, Some(UseKind::SecondaryRoles)) {
11548 self.write(&u.this.name);
11549 } else {
11550 self.generate_identifier(&u.this)?;
11551 }
11552 Ok(())
11553 }
11554
11555 fn generate_cache(&mut self, c: &Cache) -> Result<()> {
11556 self.write_keyword("CACHE");
11557 if c.lazy {
11558 self.write_space();
11559 self.write_keyword("LAZY");
11560 }
11561 self.write_space();
11562 self.write_keyword("TABLE");
11563 self.write_space();
11564 self.generate_identifier(&c.table)?;
11565
11566 if !c.options.is_empty() {
11568 self.write_space();
11569 self.write_keyword("OPTIONS");
11570 self.write("(");
11571 for (i, (key, value)) in c.options.iter().enumerate() {
11572 if i > 0 {
11573 self.write(", ");
11574 }
11575 self.generate_expression(key)?;
11576 self.write(" = ");
11577 self.generate_expression(value)?;
11578 }
11579 self.write(")");
11580 }
11581
11582 if let Some(query) = &c.query {
11584 self.write_space();
11585 self.write_keyword("AS");
11586 self.write_space();
11587 self.generate_expression(query)?;
11588 }
11589
11590 Ok(())
11591 }
11592
11593 fn generate_uncache(&mut self, u: &Uncache) -> Result<()> {
11594 self.write_keyword("UNCACHE TABLE");
11595 if u.if_exists {
11596 self.write_space();
11597 self.write_keyword("IF EXISTS");
11598 }
11599 self.write_space();
11600 self.generate_identifier(&u.table)?;
11601 Ok(())
11602 }
11603
11604 fn generate_load_data(&mut self, l: &LoadData) -> Result<()> {
11605 self.write_keyword("LOAD DATA");
11606 if l.local {
11607 self.write_space();
11608 self.write_keyword("LOCAL");
11609 }
11610 self.write_space();
11611 self.write_keyword("INPATH");
11612 self.write_space();
11613 self.write("'");
11614 self.write(&l.inpath);
11615 self.write("'");
11616
11617 if l.overwrite {
11618 self.write_space();
11619 self.write_keyword("OVERWRITE");
11620 }
11621
11622 self.write_space();
11623 self.write_keyword("INTO TABLE");
11624 self.write_space();
11625 self.generate_expression(&l.table)?;
11626
11627 if !l.partition.is_empty() {
11629 self.write_space();
11630 self.write_keyword("PARTITION");
11631 self.write("(");
11632 for (i, (col, val)) in l.partition.iter().enumerate() {
11633 if i > 0 {
11634 self.write(", ");
11635 }
11636 self.generate_identifier(col)?;
11637 self.write(" = ");
11638 self.generate_expression(val)?;
11639 }
11640 self.write(")");
11641 }
11642
11643 if let Some(fmt) = &l.input_format {
11645 self.write_space();
11646 self.write_keyword("INPUTFORMAT");
11647 self.write_space();
11648 self.write("'");
11649 self.write(fmt);
11650 self.write("'");
11651 }
11652
11653 if let Some(serde) = &l.serde {
11655 self.write_space();
11656 self.write_keyword("SERDE");
11657 self.write_space();
11658 self.write("'");
11659 self.write(serde);
11660 self.write("'");
11661 }
11662
11663 Ok(())
11664 }
11665
11666 fn generate_pragma(&mut self, p: &Pragma) -> Result<()> {
11667 self.write_keyword("PRAGMA");
11668 self.write_space();
11669
11670 if let Some(schema) = &p.schema {
11672 self.generate_identifier(schema)?;
11673 self.write(".");
11674 }
11675
11676 self.generate_identifier(&p.name)?;
11678
11679 if p.use_assignment_syntax {
11681 self.write(" = ");
11682 if let Some(value) = &p.value {
11683 self.generate_expression(value)?;
11684 } else if let Some(arg) = p.args.first() {
11685 self.generate_expression(arg)?;
11686 }
11687 } else if !p.args.is_empty() {
11688 self.write("(");
11689 for (i, arg) in p.args.iter().enumerate() {
11690 if i > 0 {
11691 self.write(", ");
11692 }
11693 self.generate_expression(arg)?;
11694 }
11695 self.write(")");
11696 }
11697
11698 Ok(())
11699 }
11700
11701 fn generate_grant(&mut self, g: &Grant) -> Result<()> {
11702 self.write_keyword("GRANT");
11703 self.write_space();
11704
11705 for (i, privilege) in g.privileges.iter().enumerate() {
11707 if i > 0 {
11708 self.write(", ");
11709 }
11710 self.write_keyword(&privilege.name);
11711 if !privilege.columns.is_empty() {
11713 self.write("(");
11714 for (j, col) in privilege.columns.iter().enumerate() {
11715 if j > 0 {
11716 self.write(", ");
11717 }
11718 self.write(col);
11719 }
11720 self.write(")");
11721 }
11722 }
11723
11724 self.write_space();
11725 self.write_keyword("ON");
11726 self.write_space();
11727
11728 if let Some(kind) = &g.kind {
11730 self.write_keyword(kind);
11731 self.write_space();
11732 }
11733
11734 {
11736 use crate::dialects::DialectType;
11737 let should_upper = matches!(
11738 self.config.dialect,
11739 Some(DialectType::PostgreSQL)
11740 | Some(DialectType::CockroachDB)
11741 | Some(DialectType::Materialize)
11742 | Some(DialectType::RisingWave)
11743 ) && (g.kind.as_deref() == Some("FUNCTION")
11744 || g.kind.as_deref() == Some("PROCEDURE"));
11745 if should_upper {
11746 use crate::expressions::Identifier;
11747 let upper_id = Identifier {
11748 name: g.securable.name.to_ascii_uppercase(),
11749 quoted: g.securable.quoted,
11750 ..g.securable.clone()
11751 };
11752 self.generate_identifier(&upper_id)?;
11753 } else {
11754 self.generate_identifier(&g.securable)?;
11755 }
11756 }
11757
11758 if !g.function_params.is_empty() {
11760 self.write("(");
11761 for (i, param) in g.function_params.iter().enumerate() {
11762 if i > 0 {
11763 self.write(", ");
11764 }
11765 self.write(param);
11766 }
11767 self.write(")");
11768 }
11769
11770 self.write_space();
11771 self.write_keyword("TO");
11772 self.write_space();
11773
11774 for (i, principal) in g.principals.iter().enumerate() {
11776 if i > 0 {
11777 self.write(", ");
11778 }
11779 if principal.is_role {
11780 self.write_keyword("ROLE");
11781 self.write_space();
11782 } else if principal.is_group {
11783 self.write_keyword("GROUP");
11784 self.write_space();
11785 } else if principal.is_share {
11786 self.write_keyword("SHARE");
11787 self.write_space();
11788 }
11789 self.generate_identifier(&principal.name)?;
11790 }
11791
11792 if g.grant_option {
11794 self.write_space();
11795 self.write_keyword("WITH GRANT OPTION");
11796 }
11797
11798 if let Some(ref principal) = g.as_principal {
11800 self.write_space();
11801 self.write_keyword("AS");
11802 self.write_space();
11803 self.generate_identifier(principal)?;
11804 }
11805
11806 Ok(())
11807 }
11808
11809 fn generate_revoke(&mut self, r: &Revoke) -> Result<()> {
11810 self.write_keyword("REVOKE");
11811 self.write_space();
11812
11813 if r.grant_option {
11815 self.write_keyword("GRANT OPTION FOR");
11816 self.write_space();
11817 }
11818
11819 for (i, privilege) in r.privileges.iter().enumerate() {
11821 if i > 0 {
11822 self.write(", ");
11823 }
11824 self.write_keyword(&privilege.name);
11825 if !privilege.columns.is_empty() {
11827 self.write("(");
11828 for (j, col) in privilege.columns.iter().enumerate() {
11829 if j > 0 {
11830 self.write(", ");
11831 }
11832 self.write(col);
11833 }
11834 self.write(")");
11835 }
11836 }
11837
11838 self.write_space();
11839 self.write_keyword("ON");
11840 self.write_space();
11841
11842 if let Some(kind) = &r.kind {
11844 self.write_keyword(kind);
11845 self.write_space();
11846 }
11847
11848 {
11850 use crate::dialects::DialectType;
11851 let should_upper = matches!(
11852 self.config.dialect,
11853 Some(DialectType::PostgreSQL)
11854 | Some(DialectType::CockroachDB)
11855 | Some(DialectType::Materialize)
11856 | Some(DialectType::RisingWave)
11857 ) && (r.kind.as_deref() == Some("FUNCTION")
11858 || r.kind.as_deref() == Some("PROCEDURE"));
11859 if should_upper {
11860 use crate::expressions::Identifier;
11861 let upper_id = Identifier {
11862 name: r.securable.name.to_ascii_uppercase(),
11863 quoted: r.securable.quoted,
11864 ..r.securable.clone()
11865 };
11866 self.generate_identifier(&upper_id)?;
11867 } else {
11868 self.generate_identifier(&r.securable)?;
11869 }
11870 }
11871
11872 if !r.function_params.is_empty() {
11874 self.write("(");
11875 for (i, param) in r.function_params.iter().enumerate() {
11876 if i > 0 {
11877 self.write(", ");
11878 }
11879 self.write(param);
11880 }
11881 self.write(")");
11882 }
11883
11884 self.write_space();
11885 self.write_keyword("FROM");
11886 self.write_space();
11887
11888 for (i, principal) in r.principals.iter().enumerate() {
11890 if i > 0 {
11891 self.write(", ");
11892 }
11893 if principal.is_role {
11894 self.write_keyword("ROLE");
11895 self.write_space();
11896 } else if principal.is_group {
11897 self.write_keyword("GROUP");
11898 self.write_space();
11899 } else if principal.is_share {
11900 self.write_keyword("SHARE");
11901 self.write_space();
11902 }
11903 self.generate_identifier(&principal.name)?;
11904 }
11905
11906 if r.cascade {
11908 self.write_space();
11909 self.write_keyword("CASCADE");
11910 } else if r.restrict {
11911 self.write_space();
11912 self.write_keyword("RESTRICT");
11913 }
11914
11915 Ok(())
11916 }
11917
11918 fn generate_comment(&mut self, c: &Comment) -> Result<()> {
11919 self.write_keyword("COMMENT");
11920
11921 if c.exists {
11923 self.write_space();
11924 self.write_keyword("IF EXISTS");
11925 }
11926
11927 self.write_space();
11928 self.write_keyword("ON");
11929
11930 if c.materialized {
11932 self.write_space();
11933 self.write_keyword("MATERIALIZED");
11934 }
11935
11936 self.write_space();
11937 self.write_keyword(&c.kind);
11938 self.write_space();
11939
11940 self.generate_expression(&c.this)?;
11942
11943 self.write_space();
11944 self.write_keyword("IS");
11945 self.write_space();
11946
11947 self.generate_expression(&c.expression)?;
11949
11950 Ok(())
11951 }
11952
11953 fn generate_set_statement(&mut self, s: &SetStatement) -> Result<()> {
11954 self.write_keyword("SET");
11955
11956 for (i, item) in s.items.iter().enumerate() {
11957 if i > 0 {
11958 self.write(",");
11959 }
11960 self.write_space();
11961
11962 let has_variable_kind = item.kind.as_deref() == Some("VARIABLE");
11964 if let Some(ref kind) = item.kind {
11965 if has_variable_kind {
11969 if matches!(
11970 self.config.dialect,
11971 Some(DialectType::Spark | DialectType::Databricks | DialectType::DuckDB)
11972 ) {
11973 self.write_keyword("VARIABLE");
11974 self.write_space();
11975 }
11976 } else {
11977 self.write_keyword(kind);
11978 self.write_space();
11979 }
11980 }
11981
11982 let name_str = match &item.name {
11984 Expression::Identifier(id) => Some(id.name.as_str()),
11985 _ => None,
11986 };
11987
11988 let is_transaction = name_str == Some("TRANSACTION");
11989 let is_character_set = name_str == Some("CHARACTER SET");
11990 let is_names = name_str == Some("NAMES");
11991 let is_collate = name_str == Some("COLLATE");
11992 let is_value_only =
11993 matches!(&item.value, Expression::Identifier(id) if id.name.is_empty());
11994
11995 if is_transaction {
11996 self.write_keyword("TRANSACTION");
11998 if let Expression::Identifier(id) = &item.value {
11999 if !id.name.is_empty() {
12000 self.write_space();
12001 self.write(&id.name);
12002 }
12003 }
12004 } else if is_character_set {
12005 self.write_keyword("CHARACTER SET");
12007 self.write_space();
12008 self.generate_set_value(&item.value)?;
12009 } else if is_names {
12010 self.write_keyword("NAMES");
12012 self.write_space();
12013 self.generate_set_value(&item.value)?;
12014 } else if is_collate {
12015 self.write_keyword("COLLATE");
12017 self.write_space();
12018 self.generate_set_value(&item.value)?;
12019 } else if has_variable_kind {
12020 if let Some(ns) = name_str {
12023 self.write(ns);
12024 } else {
12025 self.generate_expression(&item.name)?;
12026 }
12027 self.write(" = ");
12028 self.generate_set_value(&item.value)?;
12029 } else if is_value_only {
12030 self.generate_expression(&item.name)?;
12032 } else if item.no_equals && matches!(self.config.dialect, Some(DialectType::TSQL)) {
12033 self.generate_expression(&item.name)?;
12035 self.write_space();
12036 self.generate_set_value(&item.value)?;
12037 } else {
12038 match &item.name {
12041 Expression::Identifier(id) => {
12042 self.write(&id.name);
12043 }
12044 _ => {
12045 self.generate_expression(&item.name)?;
12046 }
12047 }
12048 self.write(" = ");
12049 self.generate_set_value(&item.value)?;
12050 }
12051 }
12052
12053 Ok(())
12054 }
12055
12056 fn generate_set_value(&mut self, value: &Expression) -> Result<()> {
12059 if let Expression::Identifier(id) = value {
12060 match id.name.as_str() {
12061 "DEFAULT" | "ON" | "OFF" => {
12062 self.write_keyword(&id.name);
12063 return Ok(());
12064 }
12065 _ => {}
12066 }
12067 }
12068 self.generate_expression(value)
12069 }
12070
12071 fn generate_alter_view(&mut self, av: &AlterView) -> Result<()> {
12074 self.write_keyword("ALTER");
12075 if let Some(ref algorithm) = av.algorithm {
12077 self.write_space();
12078 self.write_keyword("ALGORITHM");
12079 self.write(" = ");
12080 self.write_keyword(algorithm);
12081 }
12082 if let Some(ref definer) = av.definer {
12083 self.write_space();
12084 self.write_keyword("DEFINER");
12085 self.write(" = ");
12086 self.write(definer);
12087 }
12088 if let Some(ref sql_security) = av.sql_security {
12089 self.write_space();
12090 self.write_keyword("SQL SECURITY");
12091 self.write(" = ");
12092 self.write_keyword(sql_security);
12093 }
12094 self.write_space();
12095 self.write_keyword("VIEW");
12096 self.write_space();
12097 self.generate_table(&av.name)?;
12098
12099 if !av.columns.is_empty() {
12101 self.write(" (");
12102 for (i, col) in av.columns.iter().enumerate() {
12103 if i > 0 {
12104 self.write(", ");
12105 }
12106 self.generate_identifier(&col.name)?;
12107 if let Some(ref comment) = col.comment {
12108 self.write_space();
12109 self.write_keyword("COMMENT");
12110 self.write(" ");
12111 self.generate_string_literal(comment)?;
12112 }
12113 }
12114 self.write(")");
12115 }
12116
12117 if let Some(ref opt) = av.with_option {
12119 self.write_space();
12120 self.write_keyword("WITH");
12121 self.write_space();
12122 self.write_keyword(opt);
12123 }
12124
12125 for action in &av.actions {
12126 self.write_space();
12127 match action {
12128 AlterViewAction::Rename(new_name) => {
12129 self.write_keyword("RENAME TO");
12130 self.write_space();
12131 self.generate_table(new_name)?;
12132 }
12133 AlterViewAction::OwnerTo(owner) => {
12134 self.write_keyword("OWNER TO");
12135 self.write_space();
12136 self.generate_identifier(owner)?;
12137 }
12138 AlterViewAction::SetSchema(schema) => {
12139 self.write_keyword("SET SCHEMA");
12140 self.write_space();
12141 self.generate_identifier(schema)?;
12142 }
12143 AlterViewAction::SetAuthorization(auth) => {
12144 self.write_keyword("SET AUTHORIZATION");
12145 self.write_space();
12146 self.write(auth);
12147 }
12148 AlterViewAction::AlterColumn { name, action } => {
12149 self.write_keyword("ALTER COLUMN");
12150 self.write_space();
12151 self.generate_identifier(name)?;
12152 self.write_space();
12153 self.generate_alter_column_action(action)?;
12154 }
12155 AlterViewAction::AsSelect(query) => {
12156 self.write_keyword("AS");
12157 self.write_space();
12158 self.generate_expression(query)?;
12159 }
12160 AlterViewAction::SetTblproperties(props) => {
12161 self.write_keyword("SET TBLPROPERTIES");
12162 self.write(" (");
12163 for (i, (key, value)) in props.iter().enumerate() {
12164 if i > 0 {
12165 self.write(", ");
12166 }
12167 self.generate_string_literal(key)?;
12168 self.write("=");
12169 self.generate_string_literal(value)?;
12170 }
12171 self.write(")");
12172 }
12173 AlterViewAction::UnsetTblproperties(keys) => {
12174 self.write_keyword("UNSET TBLPROPERTIES");
12175 self.write(" (");
12176 for (i, key) in keys.iter().enumerate() {
12177 if i > 0 {
12178 self.write(", ");
12179 }
12180 self.generate_string_literal(key)?;
12181 }
12182 self.write(")");
12183 }
12184 }
12185 }
12186
12187 Ok(())
12188 }
12189
12190 fn generate_alter_index(&mut self, ai: &AlterIndex) -> Result<()> {
12191 self.write_keyword("ALTER INDEX");
12192 self.write_space();
12193 self.generate_identifier(&ai.name)?;
12194
12195 if let Some(table) = &ai.table {
12196 self.write_space();
12197 self.write_keyword("ON");
12198 self.write_space();
12199 self.generate_table(table)?;
12200 }
12201
12202 for action in &ai.actions {
12203 self.write_space();
12204 match action {
12205 AlterIndexAction::Rename(new_name) => {
12206 self.write_keyword("RENAME TO");
12207 self.write_space();
12208 self.generate_identifier(new_name)?;
12209 }
12210 AlterIndexAction::SetTablespace(tablespace) => {
12211 self.write_keyword("SET TABLESPACE");
12212 self.write_space();
12213 self.generate_identifier(tablespace)?;
12214 }
12215 AlterIndexAction::Visible(visible) => {
12216 if *visible {
12217 self.write_keyword("VISIBLE");
12218 } else {
12219 self.write_keyword("INVISIBLE");
12220 }
12221 }
12222 }
12223 }
12224
12225 Ok(())
12226 }
12227
12228 fn generate_create_schema(&mut self, cs: &CreateSchema) -> Result<()> {
12229 for comment in &cs.leading_comments {
12231 self.write_formatted_comment(comment);
12232 self.write_space();
12233 }
12234
12235 let saved_athena_hive_context = self.athena_hive_context;
12237 if matches!(
12238 self.config.dialect,
12239 Some(crate::dialects::DialectType::Athena)
12240 ) {
12241 self.athena_hive_context = true;
12242 }
12243
12244 self.write_keyword("CREATE SCHEMA");
12245
12246 if cs.if_not_exists {
12247 self.write_space();
12248 self.write_keyword("IF NOT EXISTS");
12249 }
12250
12251 self.write_space();
12252 for (i, part) in cs.name.iter().enumerate() {
12253 if i > 0 {
12254 self.write(".");
12255 }
12256 self.generate_identifier(part)?;
12257 }
12258
12259 if let Some(ref clone_parts) = cs.clone_from {
12260 self.write_keyword(" CLONE ");
12261 for (i, part) in clone_parts.iter().enumerate() {
12262 if i > 0 {
12263 self.write(".");
12264 }
12265 self.generate_identifier(part)?;
12266 }
12267 }
12268
12269 if let Some(ref at_clause) = cs.at_clause {
12270 self.write_space();
12271 self.generate_expression(at_clause)?;
12272 }
12273
12274 if let Some(auth) = &cs.authorization {
12275 self.write_space();
12276 self.write_keyword("AUTHORIZATION");
12277 self.write_space();
12278 self.generate_identifier(auth)?;
12279 }
12280
12281 let with_properties: Vec<_> = cs
12284 .properties
12285 .iter()
12286 .filter(|p| matches!(p, Expression::Property(_)))
12287 .collect();
12288 let other_properties: Vec<_> = cs
12289 .properties
12290 .iter()
12291 .filter(|p| !matches!(p, Expression::Property(_)))
12292 .collect();
12293
12294 if !with_properties.is_empty() {
12296 self.write_space();
12297 self.write_keyword("WITH");
12298 self.write(" (");
12299 for (i, prop) in with_properties.iter().enumerate() {
12300 if i > 0 {
12301 self.write(", ");
12302 }
12303 self.generate_expression(prop)?;
12304 }
12305 self.write(")");
12306 }
12307
12308 for prop in other_properties {
12310 self.write_space();
12311 self.generate_expression(prop)?;
12312 }
12313
12314 self.athena_hive_context = saved_athena_hive_context;
12316
12317 Ok(())
12318 }
12319
12320 fn generate_drop_schema(&mut self, ds: &DropSchema) -> Result<()> {
12321 self.write_keyword("DROP SCHEMA");
12322
12323 if ds.if_exists {
12324 self.write_space();
12325 self.write_keyword("IF EXISTS");
12326 }
12327
12328 self.write_space();
12329 self.generate_identifier(&ds.name)?;
12330
12331 if ds.cascade {
12332 self.write_space();
12333 self.write_keyword("CASCADE");
12334 }
12335
12336 Ok(())
12337 }
12338
12339 fn generate_drop_namespace(&mut self, dn: &DropNamespace) -> Result<()> {
12340 self.write_keyword("DROP NAMESPACE");
12341
12342 if dn.if_exists {
12343 self.write_space();
12344 self.write_keyword("IF EXISTS");
12345 }
12346
12347 self.write_space();
12348 self.generate_identifier(&dn.name)?;
12349
12350 if dn.cascade {
12351 self.write_space();
12352 self.write_keyword("CASCADE");
12353 }
12354
12355 Ok(())
12356 }
12357
12358 fn generate_create_database(&mut self, cd: &CreateDatabase) -> Result<()> {
12359 self.write_keyword("CREATE DATABASE");
12360
12361 if cd.if_not_exists {
12362 self.write_space();
12363 self.write_keyword("IF NOT EXISTS");
12364 }
12365
12366 self.write_space();
12367 self.generate_identifier(&cd.name)?;
12368
12369 if let Some(ref clone_src) = cd.clone_from {
12370 self.write_keyword(" CLONE ");
12371 self.generate_identifier(clone_src)?;
12372 }
12373
12374 if let Some(ref at_clause) = cd.at_clause {
12376 self.write_space();
12377 self.generate_expression(at_clause)?;
12378 }
12379
12380 for option in &cd.options {
12381 self.write_space();
12382 match option {
12383 DatabaseOption::CharacterSet(charset) => {
12384 self.write_keyword("CHARACTER SET");
12385 self.write(" = ");
12386 self.write(&format!("'{}'", charset));
12387 }
12388 DatabaseOption::Collate(collate) => {
12389 self.write_keyword("COLLATE");
12390 self.write(" = ");
12391 self.write(&format!("'{}'", collate));
12392 }
12393 DatabaseOption::Owner(owner) => {
12394 self.write_keyword("OWNER");
12395 self.write(" = ");
12396 self.generate_identifier(owner)?;
12397 }
12398 DatabaseOption::Template(template) => {
12399 self.write_keyword("TEMPLATE");
12400 self.write(" = ");
12401 self.generate_identifier(template)?;
12402 }
12403 DatabaseOption::Encoding(encoding) => {
12404 self.write_keyword("ENCODING");
12405 self.write(" = ");
12406 self.write(&format!("'{}'", encoding));
12407 }
12408 DatabaseOption::Location(location) => {
12409 self.write_keyword("LOCATION");
12410 self.write(" = ");
12411 self.write(&format!("'{}'", location));
12412 }
12413 }
12414 }
12415
12416 Ok(())
12417 }
12418
12419 fn generate_drop_database(&mut self, dd: &DropDatabase) -> Result<()> {
12420 self.write_keyword("DROP DATABASE");
12421
12422 if dd.if_exists {
12423 self.write_space();
12424 self.write_keyword("IF EXISTS");
12425 }
12426
12427 self.write_space();
12428 self.generate_identifier(&dd.name)?;
12429
12430 if dd.sync {
12431 self.write_space();
12432 self.write_keyword("SYNC");
12433 }
12434
12435 Ok(())
12436 }
12437
12438 fn generate_create_function(&mut self, cf: &CreateFunction) -> Result<()> {
12439 self.write_keyword("CREATE");
12440
12441 if cf.or_alter {
12442 self.write_space();
12443 self.write_keyword("OR ALTER");
12444 } else if cf.or_replace {
12445 self.write_space();
12446 self.write_keyword("OR REPLACE");
12447 }
12448
12449 if cf.temporary {
12450 self.write_space();
12451 self.write_keyword("TEMPORARY");
12452 }
12453
12454 self.write_space();
12455 if cf.is_table_function {
12456 self.write_keyword("TABLE FUNCTION");
12457 } else {
12458 self.write_keyword("FUNCTION");
12459 }
12460
12461 if cf.if_not_exists {
12462 self.write_space();
12463 self.write_keyword("IF NOT EXISTS");
12464 }
12465
12466 self.write_space();
12467 self.generate_table(&cf.name)?;
12468 if cf.has_parens {
12469 let func_multiline = self.config.pretty
12470 && matches!(
12471 self.config.dialect,
12472 Some(crate::dialects::DialectType::TSQL)
12473 | Some(crate::dialects::DialectType::Fabric)
12474 )
12475 && !cf.parameters.is_empty();
12476 if func_multiline {
12477 self.write("(\n");
12478 self.indent_level += 2;
12479 self.write_indent();
12480 self.generate_function_parameters(&cf.parameters)?;
12481 self.write("\n");
12482 self.indent_level -= 2;
12483 self.write(")");
12484 } else {
12485 self.write("(");
12486 self.generate_function_parameters(&cf.parameters)?;
12487 self.write(")");
12488 }
12489 }
12490
12491 let use_multiline = self.config.pretty
12494 && matches!(
12495 self.config.dialect,
12496 Some(crate::dialects::DialectType::BigQuery)
12497 | Some(crate::dialects::DialectType::TSQL)
12498 | Some(crate::dialects::DialectType::Fabric)
12499 );
12500
12501 if cf.language_first {
12502 if let Some(lang) = &cf.language {
12504 if use_multiline {
12505 self.write_newline();
12506 } else {
12507 self.write_space();
12508 }
12509 self.write_keyword("LANGUAGE");
12510 self.write_space();
12511 self.write(lang);
12512 }
12513
12514 if let Some(sql_data) = &cf.sql_data_access {
12516 self.write_space();
12517 match sql_data {
12518 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
12519 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
12520 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
12521 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
12522 }
12523 }
12524
12525 if let Some(ref rtb) = cf.returns_table_body {
12526 if use_multiline {
12527 self.write_newline();
12528 } else {
12529 self.write_space();
12530 }
12531 self.write_keyword("RETURNS");
12532 self.write_space();
12533 self.write(rtb);
12534 } else if let Some(return_type) = &cf.return_type {
12535 if use_multiline {
12536 self.write_newline();
12537 } else {
12538 self.write_space();
12539 }
12540 self.write_keyword("RETURNS");
12541 self.write_space();
12542 self.generate_data_type(return_type)?;
12543 }
12544 } else {
12545 let is_duckdb = matches!(
12548 self.config.dialect,
12549 Some(crate::dialects::DialectType::DuckDB)
12550 );
12551 if let Some(ref rtb) = cf.returns_table_body {
12552 if !(is_duckdb && rtb.is_empty()) {
12553 if use_multiline {
12554 self.write_newline();
12555 } else {
12556 self.write_space();
12557 }
12558 self.write_keyword("RETURNS");
12559 self.write_space();
12560 self.write(rtb);
12561 }
12562 } else if let Some(return_type) = &cf.return_type {
12563 if !is_duckdb {
12565 let is_table_return = matches!(return_type, crate::expressions::DataType::Custom { ref name } if name.eq_ignore_ascii_case("TABLE"));
12566 if use_multiline {
12567 self.write_newline();
12568 } else {
12569 self.write_space();
12570 }
12571 self.write_keyword("RETURNS");
12572 self.write_space();
12573 if is_table_return {
12574 self.write_keyword("TABLE");
12575 } else {
12576 self.generate_data_type(return_type)?;
12577 }
12578 }
12579 }
12580 }
12581
12582 if !cf.property_order.is_empty() {
12584 let is_bigquery = matches!(
12586 self.config.dialect,
12587 Some(crate::dialects::DialectType::BigQuery)
12588 );
12589 let property_order = if is_bigquery {
12590 let mut reordered = Vec::new();
12592 let mut has_as = false;
12593 let mut has_options = false;
12594 for prop in &cf.property_order {
12595 match prop {
12596 FunctionPropertyKind::As => has_as = true,
12597 FunctionPropertyKind::Options => has_options = true,
12598 _ => {}
12599 }
12600 }
12601 if has_as && has_options {
12602 for prop in &cf.property_order {
12604 if *prop != FunctionPropertyKind::As
12605 && *prop != FunctionPropertyKind::Options
12606 {
12607 reordered.push(*prop);
12608 }
12609 }
12610 reordered.push(FunctionPropertyKind::Options);
12611 reordered.push(FunctionPropertyKind::As);
12612 reordered
12613 } else {
12614 cf.property_order.clone()
12615 }
12616 } else {
12617 cf.property_order.clone()
12618 };
12619
12620 for prop in &property_order {
12621 match prop {
12622 FunctionPropertyKind::Set => {
12623 self.generate_function_set_options(cf)?;
12624 }
12625 FunctionPropertyKind::As => {
12626 self.generate_function_body(cf)?;
12627 }
12628 FunctionPropertyKind::Using => {
12629 self.generate_function_using_resources(cf)?;
12630 }
12631 FunctionPropertyKind::Language => {
12632 if !cf.language_first {
12633 if let Some(lang) = &cf.language {
12635 let use_multiline = self.config.pretty
12637 && matches!(
12638 self.config.dialect,
12639 Some(crate::dialects::DialectType::BigQuery)
12640 );
12641 if use_multiline {
12642 self.write_newline();
12643 } else {
12644 self.write_space();
12645 }
12646 self.write_keyword("LANGUAGE");
12647 self.write_space();
12648 self.write(lang);
12649 }
12650 }
12651 }
12652 FunctionPropertyKind::Determinism => {
12653 self.generate_function_determinism(cf)?;
12654 }
12655 FunctionPropertyKind::NullInput => {
12656 self.generate_function_null_input(cf)?;
12657 }
12658 FunctionPropertyKind::Security => {
12659 self.generate_function_security(cf)?;
12660 }
12661 FunctionPropertyKind::SqlDataAccess => {
12662 if !cf.language_first {
12663 self.generate_function_sql_data_access(cf)?;
12665 }
12666 }
12667 FunctionPropertyKind::Options => {
12668 if !cf.options.is_empty() {
12669 self.write_space();
12670 self.generate_options_clause(&cf.options)?;
12671 }
12672 }
12673 FunctionPropertyKind::Environment => {
12674 if !cf.environment.is_empty() {
12675 self.write_space();
12676 self.generate_environment_clause(&cf.environment)?;
12677 }
12678 }
12679 FunctionPropertyKind::Handler => {
12680 if let Some(ref h) = cf.handler {
12681 self.write_space();
12682 self.write_keyword("HANDLER");
12683 if cf.handler_uses_eq {
12684 self.write(" = ");
12685 } else {
12686 self.write_space();
12687 }
12688 self.write("'");
12689 self.write(h);
12690 self.write("'");
12691 }
12692 }
12693 FunctionPropertyKind::RuntimeVersion => {
12694 if let Some(ref runtime_version) = cf.runtime_version {
12695 self.write_space();
12696 self.write_keyword("RUNTIME_VERSION");
12697 self.write("='");
12698 self.write(runtime_version);
12699 self.write("'");
12700 }
12701 }
12702 FunctionPropertyKind::Packages => {
12703 if let Some(ref packages) = cf.packages {
12704 self.write_space();
12705 self.write_keyword("PACKAGES");
12706 self.write("=(");
12707 for (i, package) in packages.iter().enumerate() {
12708 if i > 0 {
12709 self.write(", ");
12710 }
12711 self.write("'");
12712 self.write(package);
12713 self.write("'");
12714 }
12715 self.write(")");
12716 }
12717 }
12718 FunctionPropertyKind::ParameterStyle => {
12719 if let Some(ref ps) = cf.parameter_style {
12720 self.write_space();
12721 self.write_keyword("PARAMETER STYLE");
12722 self.write_space();
12723 self.write_keyword(ps);
12724 }
12725 }
12726 }
12727 }
12728
12729 if !cf.options.is_empty() && !cf.property_order.contains(&FunctionPropertyKind::Options)
12731 {
12732 self.write_space();
12733 self.generate_options_clause(&cf.options)?;
12734 }
12735
12736 if !cf.environment.is_empty()
12738 && !cf
12739 .property_order
12740 .contains(&FunctionPropertyKind::Environment)
12741 {
12742 self.write_space();
12743 self.generate_environment_clause(&cf.environment)?;
12744 }
12745 } else {
12746 if matches!(
12749 self.config.dialect,
12750 Some(crate::dialects::DialectType::BigQuery)
12751 ) {
12752 self.generate_function_determinism(cf)?;
12753 }
12754
12755 let use_multiline = self.config.pretty
12757 && matches!(
12758 self.config.dialect,
12759 Some(crate::dialects::DialectType::BigQuery)
12760 );
12761
12762 if !cf.language_first {
12763 if let Some(lang) = &cf.language {
12764 if use_multiline {
12765 self.write_newline();
12766 } else {
12767 self.write_space();
12768 }
12769 self.write_keyword("LANGUAGE");
12770 self.write_space();
12771 self.write(lang);
12772 }
12773
12774 self.generate_function_sql_data_access(cf)?;
12776 }
12777
12778 if !matches!(
12780 self.config.dialect,
12781 Some(crate::dialects::DialectType::BigQuery)
12782 ) {
12783 self.generate_function_determinism(cf)?;
12784 }
12785
12786 self.generate_function_null_input(cf)?;
12787 self.generate_function_security(cf)?;
12788 self.generate_function_set_options(cf)?;
12789
12790 if !cf.options.is_empty() {
12792 self.write_space();
12793 self.generate_options_clause(&cf.options)?;
12794 }
12795
12796 if !cf.environment.is_empty() {
12798 self.write_space();
12799 self.generate_environment_clause(&cf.environment)?;
12800 }
12801
12802 if let Some(ref h) = cf.handler {
12803 self.write_space();
12804 self.write_keyword("HANDLER");
12805 if cf.handler_uses_eq {
12806 self.write(" = ");
12807 } else {
12808 self.write_space();
12809 }
12810 self.write("'");
12811 self.write(h);
12812 self.write("'");
12813 }
12814
12815 if let Some(ref runtime_version) = cf.runtime_version {
12816 self.write_space();
12817 self.write_keyword("RUNTIME_VERSION");
12818 self.write("='");
12819 self.write(runtime_version);
12820 self.write("'");
12821 }
12822
12823 if let Some(ref packages) = cf.packages {
12824 self.write_space();
12825 self.write_keyword("PACKAGES");
12826 self.write("=(");
12827 for (i, package) in packages.iter().enumerate() {
12828 if i > 0 {
12829 self.write(", ");
12830 }
12831 self.write("'");
12832 self.write(package);
12833 self.write("'");
12834 }
12835 self.write(")");
12836 }
12837
12838 self.generate_function_body(cf)?;
12839 self.generate_function_using_resources(cf)?;
12840 }
12841
12842 Ok(())
12843 }
12844
12845 fn generate_function_set_options(&mut self, cf: &CreateFunction) -> Result<()> {
12847 for opt in &cf.set_options {
12848 self.write_space();
12849 self.write_keyword("SET");
12850 self.write_space();
12851 self.write(&opt.name);
12852 match &opt.value {
12853 FunctionSetValue::Value { value, use_to } => {
12854 if *use_to {
12855 self.write(" TO ");
12856 } else {
12857 self.write(" = ");
12858 }
12859 self.write(value);
12860 }
12861 FunctionSetValue::FromCurrent => {
12862 self.write_space();
12863 self.write_keyword("FROM CURRENT");
12864 }
12865 }
12866 }
12867 Ok(())
12868 }
12869
12870 fn generate_function_using_resources(&mut self, cf: &CreateFunction) -> Result<()> {
12871 if cf.using_resources.is_empty() {
12872 return Ok(());
12873 }
12874
12875 self.write_space();
12876 self.write_keyword("USING");
12877 for resource in &cf.using_resources {
12878 self.write_space();
12879 self.write_keyword(&resource.kind);
12880 self.write_space();
12881 self.generate_string_literal(&resource.uri)?;
12882 }
12883 Ok(())
12884 }
12885
12886 fn generate_function_body(&mut self, cf: &CreateFunction) -> Result<()> {
12888 if let Some(body) = &cf.body {
12889 self.write_space();
12891 let use_multiline = self.config.pretty
12893 && matches!(
12894 self.config.dialect,
12895 Some(crate::dialects::DialectType::BigQuery)
12896 );
12897 match body {
12898 FunctionBody::Block(block) => {
12899 self.write_keyword("AS");
12900 if matches!(
12901 self.config.dialect,
12902 Some(crate::dialects::DialectType::TSQL)
12903 ) {
12904 self.write(" BEGIN ");
12905 self.write(block);
12906 self.write(" END");
12907 } else if matches!(
12908 self.config.dialect,
12909 Some(crate::dialects::DialectType::PostgreSQL)
12910 ) {
12911 self.write(" $$");
12912 self.write(block);
12913 self.write("$$");
12914 } else {
12915 let escaped = self.escape_block_for_single_quote(block);
12917 if use_multiline {
12919 self.write_newline();
12920 } else {
12921 self.write(" ");
12922 }
12923 self.write("'");
12924 self.write(&escaped);
12925 self.write("'");
12926 }
12927 }
12928 FunctionBody::StringLiteral(s) => {
12929 self.write_keyword("AS");
12930 if use_multiline {
12932 self.write_newline();
12933 } else {
12934 self.write(" ");
12935 }
12936 self.write("'");
12937 self.write(s);
12938 self.write("'");
12939 }
12940 FunctionBody::Expression(expr) => {
12941 self.write_keyword("AS");
12942 self.write_space();
12943 self.generate_expression(expr)?;
12944 }
12945 FunctionBody::External(name) => {
12946 self.write_keyword("EXTERNAL NAME");
12947 self.write(" '");
12948 self.write(name);
12949 self.write("'");
12950 }
12951 FunctionBody::Return(expr) => {
12952 if matches!(
12953 self.config.dialect,
12954 Some(crate::dialects::DialectType::DuckDB)
12955 ) {
12956 self.write_keyword("AS");
12958 self.write_space();
12959 let is_table_return = cf.returns_table_body.is_some()
12961 || matches!(&cf.return_type, Some(crate::expressions::DataType::Custom { ref name }) if name.eq_ignore_ascii_case("TABLE"));
12962 if is_table_return {
12963 self.write_keyword("TABLE");
12964 self.write_space();
12965 }
12966 self.generate_expression(expr)?;
12967 } else {
12968 if self.config.create_function_return_as {
12969 self.write_keyword("AS");
12970 if self.config.pretty
12972 && matches!(
12973 self.config.dialect,
12974 Some(crate::dialects::DialectType::TSQL)
12975 | Some(crate::dialects::DialectType::Fabric)
12976 )
12977 {
12978 self.write_newline();
12979 } else {
12980 self.write_space();
12981 }
12982 }
12983 self.write_keyword("RETURN");
12984 self.write_space();
12985 self.generate_expression(expr)?;
12986 }
12987 }
12988 FunctionBody::Statements(stmts) => {
12989 self.write_keyword("AS");
12990 self.write(" BEGIN ");
12991 for (i, stmt) in stmts.iter().enumerate() {
12992 if i > 0 {
12993 self.write(" ");
12994 }
12995 self.generate_expression(stmt)?;
12996 self.write(";");
12997 }
12998 self.write(" END");
12999 }
13000 FunctionBody::RawBlock(text) => {
13001 self.write_newline();
13002 self.write(text);
13003 }
13004 FunctionBody::DollarQuoted { content, tag } => {
13005 self.write_keyword("AS");
13006 self.write(" ");
13007 let supports_dollar_quoting = matches!(
13009 self.config.dialect,
13010 Some(crate::dialects::DialectType::PostgreSQL)
13011 | Some(crate::dialects::DialectType::Databricks)
13012 | Some(crate::dialects::DialectType::Redshift)
13013 | Some(crate::dialects::DialectType::DuckDB)
13014 );
13015 if supports_dollar_quoting {
13016 self.write("$");
13018 if let Some(t) = tag {
13019 self.write(t);
13020 }
13021 self.write("$");
13022 self.write(content);
13023 self.write("$");
13024 if let Some(t) = tag {
13025 self.write(t);
13026 }
13027 self.write("$");
13028 } else {
13029 let escaped = self.escape_block_for_single_quote(content);
13031 self.write("'");
13032 self.write(&escaped);
13033 self.write("'");
13034 }
13035 }
13036 }
13037 }
13038 Ok(())
13039 }
13040
13041 fn generate_function_determinism(&mut self, cf: &CreateFunction) -> Result<()> {
13043 if let Some(det) = cf.deterministic {
13044 self.write_space();
13045 if matches!(
13046 self.config.dialect,
13047 Some(crate::dialects::DialectType::BigQuery)
13048 ) {
13049 if det {
13051 self.write_keyword("DETERMINISTIC");
13052 } else {
13053 self.write_keyword("NOT DETERMINISTIC");
13054 }
13055 } else {
13056 if det {
13058 self.write_keyword("IMMUTABLE");
13059 } else {
13060 self.write_keyword("VOLATILE");
13061 }
13062 }
13063 }
13064 Ok(())
13065 }
13066
13067 fn generate_function_null_input(&mut self, cf: &CreateFunction) -> Result<()> {
13069 if let Some(returns_null) = cf.returns_null_on_null_input {
13070 self.write_space();
13071 if returns_null {
13072 if cf.strict {
13073 self.write_keyword("STRICT");
13074 } else {
13075 self.write_keyword("RETURNS NULL ON NULL INPUT");
13076 }
13077 } else {
13078 self.write_keyword("CALLED ON NULL INPUT");
13079 }
13080 }
13081 Ok(())
13082 }
13083
13084 fn generate_function_security(&mut self, cf: &CreateFunction) -> Result<()> {
13086 if let Some(security) = &cf.security {
13087 self.write_space();
13088 if matches!(
13090 self.config.dialect,
13091 Some(crate::dialects::DialectType::MySQL)
13092 ) {
13093 self.write_keyword("SQL SECURITY");
13094 } else {
13095 self.write_keyword("SECURITY");
13096 }
13097 self.write_space();
13098 match security {
13099 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
13100 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
13101 FunctionSecurity::None => self.write_keyword("NONE"),
13102 }
13103 }
13104 Ok(())
13105 }
13106
13107 fn generate_function_sql_data_access(&mut self, cf: &CreateFunction) -> Result<()> {
13109 if let Some(sql_data) = &cf.sql_data_access {
13110 self.write_space();
13111 match sql_data {
13112 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
13113 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
13114 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
13115 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
13116 }
13117 }
13118 Ok(())
13119 }
13120
13121 fn generate_function_parameters(&mut self, params: &[FunctionParameter]) -> Result<()> {
13122 for (i, param) in params.iter().enumerate() {
13123 if i > 0 {
13124 self.write(", ");
13125 }
13126
13127 if let Some(mode) = ¶m.mode {
13128 if let Some(text) = ¶m.mode_text {
13129 self.write(text);
13130 } else {
13131 match mode {
13132 ParameterMode::In => self.write_keyword("IN"),
13133 ParameterMode::Out => self.write_keyword("OUT"),
13134 ParameterMode::InOut => self.write_keyword("INOUT"),
13135 ParameterMode::Variadic => self.write_keyword("VARIADIC"),
13136 }
13137 }
13138 self.write_space();
13139 }
13140
13141 if let Some(name) = ¶m.name {
13142 self.generate_identifier(name)?;
13143 let skip_type =
13145 matches!(¶m.data_type, DataType::Custom { name } if name.is_empty());
13146 if !skip_type {
13147 self.write_space();
13148 self.generate_data_type(¶m.data_type)?;
13149 }
13150 } else {
13151 self.generate_data_type(¶m.data_type)?;
13152 }
13153
13154 if let Some(default) = ¶m.default {
13155 if self.config.parameter_default_equals {
13156 self.write(" = ");
13157 } else {
13158 self.write(" DEFAULT ");
13159 }
13160 self.generate_expression(default)?;
13161 }
13162 }
13163
13164 Ok(())
13165 }
13166
13167 fn generate_drop_function(&mut self, df: &DropFunction) -> Result<()> {
13168 self.write_keyword("DROP FUNCTION");
13169
13170 if df.if_exists {
13171 self.write_space();
13172 self.write_keyword("IF EXISTS");
13173 }
13174
13175 self.write_space();
13176 self.generate_table(&df.name)?;
13177
13178 if let Some(params) = &df.parameters {
13179 self.write(" (");
13180 for (i, dt) in params.iter().enumerate() {
13181 if i > 0 {
13182 self.write(", ");
13183 }
13184 self.generate_data_type(dt)?;
13185 }
13186 self.write(")");
13187 }
13188
13189 if df.cascade {
13190 self.write_space();
13191 self.write_keyword("CASCADE");
13192 }
13193
13194 Ok(())
13195 }
13196
13197 fn generate_create_procedure(&mut self, cp: &CreateProcedure) -> Result<()> {
13198 self.write_keyword("CREATE");
13199
13200 if cp.or_alter {
13201 self.write_space();
13202 self.write_keyword("OR ALTER");
13203 } else if cp.or_replace {
13204 self.write_space();
13205 self.write_keyword("OR REPLACE");
13206 }
13207
13208 self.write_space();
13209 if cp.use_proc_keyword {
13210 self.write_keyword("PROC");
13211 } else {
13212 self.write_keyword("PROCEDURE");
13213 }
13214
13215 if cp.if_not_exists {
13216 self.write_space();
13217 self.write_keyword("IF NOT EXISTS");
13218 }
13219
13220 self.write_space();
13221 self.generate_table(&cp.name)?;
13222 if cp.has_parens {
13223 self.write("(");
13224 self.generate_function_parameters(&cp.parameters)?;
13225 self.write(")");
13226 } else if !cp.parameters.is_empty() {
13227 self.write_space();
13229 self.generate_function_parameters(&cp.parameters)?;
13230 }
13231
13232 if let Some(return_type) = &cp.return_type {
13234 self.write_space();
13235 self.write_keyword("RETURNS");
13236 self.write_space();
13237 self.generate_data_type(return_type)?;
13238 }
13239
13240 if let Some(execute_as) = &cp.execute_as {
13242 self.write_space();
13243 self.write_keyword("EXECUTE AS");
13244 self.write_space();
13245 self.write_keyword(execute_as);
13246 }
13247
13248 if let Some(lang) = &cp.language {
13249 self.write_space();
13250 self.write_keyword("LANGUAGE");
13251 self.write_space();
13252 self.write(lang);
13253 }
13254
13255 if let Some(security) = &cp.security {
13256 self.write_space();
13257 self.write_keyword("SECURITY");
13258 self.write_space();
13259 match security {
13260 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
13261 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
13262 FunctionSecurity::None => self.write_keyword("NONE"),
13263 }
13264 }
13265
13266 if !cp.with_options.is_empty() {
13268 self.write_space();
13269 self.write_keyword("WITH");
13270 self.write_space();
13271 for (i, opt) in cp.with_options.iter().enumerate() {
13272 if i > 0 {
13273 self.write(", ");
13274 }
13275 self.write(opt);
13276 }
13277 }
13278
13279 if let Some(body) = &cp.body {
13280 self.write_space();
13281 match body {
13282 FunctionBody::Block(block) => {
13283 self.write_keyword("AS");
13284 if matches!(
13285 self.config.dialect,
13286 Some(crate::dialects::DialectType::TSQL)
13287 ) {
13288 self.write(" BEGIN ");
13289 self.write(block);
13290 self.write(" END");
13291 } else if matches!(
13292 self.config.dialect,
13293 Some(crate::dialects::DialectType::PostgreSQL)
13294 ) {
13295 self.write(" $$");
13296 self.write(block);
13297 self.write("$$");
13298 } else {
13299 let escaped = self.escape_block_for_single_quote(block);
13301 self.write(" '");
13302 self.write(&escaped);
13303 self.write("'");
13304 }
13305 }
13306 FunctionBody::StringLiteral(s) => {
13307 self.write_keyword("AS");
13308 self.write(" '");
13309 self.write(s);
13310 self.write("'");
13311 }
13312 FunctionBody::Expression(expr) => {
13313 self.write_keyword("AS");
13314 self.write_space();
13315 self.generate_expression(expr)?;
13316 }
13317 FunctionBody::External(name) => {
13318 self.write_keyword("EXTERNAL NAME");
13319 self.write(" '");
13320 self.write(name);
13321 self.write("'");
13322 }
13323 FunctionBody::Return(expr) => {
13324 self.write_keyword("RETURN");
13325 self.write_space();
13326 self.generate_expression(expr)?;
13327 }
13328 FunctionBody::Statements(stmts) => {
13329 self.write_keyword("AS");
13330 self.write(" BEGIN ");
13331 for (i, stmt) in stmts.iter().enumerate() {
13332 if i > 0 {
13333 self.write(" ");
13334 }
13335 self.generate_expression(stmt)?;
13336 self.write(";");
13337 }
13338 self.write(" END");
13339 }
13340 FunctionBody::RawBlock(text) => {
13341 self.write_newline();
13342 self.write(text);
13343 }
13344 FunctionBody::DollarQuoted { content, tag } => {
13345 self.write_keyword("AS");
13346 self.write(" ");
13347 let supports_dollar_quoting = matches!(
13349 self.config.dialect,
13350 Some(crate::dialects::DialectType::PostgreSQL)
13351 | Some(crate::dialects::DialectType::Databricks)
13352 | Some(crate::dialects::DialectType::Redshift)
13353 | Some(crate::dialects::DialectType::DuckDB)
13354 );
13355 if supports_dollar_quoting {
13356 self.write("$");
13358 if let Some(t) = tag {
13359 self.write(t);
13360 }
13361 self.write("$");
13362 self.write(content);
13363 self.write("$");
13364 if let Some(t) = tag {
13365 self.write(t);
13366 }
13367 self.write("$");
13368 } else {
13369 let escaped = self.escape_block_for_single_quote(content);
13371 self.write("'");
13372 self.write(&escaped);
13373 self.write("'");
13374 }
13375 }
13376 }
13377 }
13378
13379 Ok(())
13380 }
13381
13382 fn generate_drop_procedure(&mut self, dp: &DropProcedure) -> Result<()> {
13383 self.write_keyword("DROP PROCEDURE");
13384
13385 if dp.if_exists {
13386 self.write_space();
13387 self.write_keyword("IF EXISTS");
13388 }
13389
13390 self.write_space();
13391 self.generate_table(&dp.name)?;
13392
13393 if let Some(params) = &dp.parameters {
13394 self.write(" (");
13395 for (i, dt) in params.iter().enumerate() {
13396 if i > 0 {
13397 self.write(", ");
13398 }
13399 self.generate_data_type(dt)?;
13400 }
13401 self.write(")");
13402 }
13403
13404 if dp.cascade {
13405 self.write_space();
13406 self.write_keyword("CASCADE");
13407 }
13408
13409 Ok(())
13410 }
13411
13412 fn generate_create_sequence(&mut self, cs: &CreateSequence) -> Result<()> {
13413 self.write_keyword("CREATE");
13414
13415 if cs.or_replace {
13416 self.write_space();
13417 self.write_keyword("OR REPLACE");
13418 }
13419
13420 if cs.temporary {
13421 self.write_space();
13422 self.write_keyword("TEMPORARY");
13423 }
13424
13425 self.write_space();
13426 self.write_keyword("SEQUENCE");
13427
13428 if cs.if_not_exists {
13429 self.write_space();
13430 self.write_keyword("IF NOT EXISTS");
13431 }
13432
13433 self.write_space();
13434 self.generate_table(&cs.name)?;
13435
13436 if let Some(as_type) = &cs.as_type {
13438 self.write_space();
13439 self.write_keyword("AS");
13440 self.write_space();
13441 self.generate_data_type(as_type)?;
13442 }
13443
13444 if let Some(comment) = &cs.comment {
13446 self.write_space();
13447 self.write_keyword("COMMENT");
13448 self.write("=");
13449 self.generate_string_literal(comment)?;
13450 }
13451
13452 if !cs.property_order.is_empty() {
13454 for prop in &cs.property_order {
13455 match prop {
13456 SeqPropKind::Start => {
13457 if let Some(start) = cs.start {
13458 self.write_space();
13459 self.write_keyword("START WITH");
13460 self.write(&format!(" {}", start));
13461 }
13462 }
13463 SeqPropKind::Increment => {
13464 if let Some(inc) = cs.increment {
13465 self.write_space();
13466 self.write_keyword("INCREMENT BY");
13467 self.write(&format!(" {}", inc));
13468 }
13469 }
13470 SeqPropKind::Minvalue => {
13471 if let Some(min) = &cs.minvalue {
13472 self.write_space();
13473 match min {
13474 SequenceBound::Value(v) => {
13475 self.write_keyword("MINVALUE");
13476 self.write(&format!(" {}", v));
13477 }
13478 SequenceBound::None => {
13479 self.write_keyword("NO MINVALUE");
13480 }
13481 }
13482 }
13483 }
13484 SeqPropKind::Maxvalue => {
13485 if let Some(max) = &cs.maxvalue {
13486 self.write_space();
13487 match max {
13488 SequenceBound::Value(v) => {
13489 self.write_keyword("MAXVALUE");
13490 self.write(&format!(" {}", v));
13491 }
13492 SequenceBound::None => {
13493 self.write_keyword("NO MAXVALUE");
13494 }
13495 }
13496 }
13497 }
13498 SeqPropKind::Cache => {
13499 if let Some(cache) = cs.cache {
13500 self.write_space();
13501 self.write_keyword("CACHE");
13502 self.write(&format!(" {}", cache));
13503 }
13504 }
13505 SeqPropKind::NoCache => {
13506 self.write_space();
13507 self.write_keyword("NO CACHE");
13508 }
13509 SeqPropKind::NoCacheWord => {
13510 self.write_space();
13511 self.write_keyword("NOCACHE");
13512 }
13513 SeqPropKind::Cycle => {
13514 self.write_space();
13515 self.write_keyword("CYCLE");
13516 }
13517 SeqPropKind::NoCycle => {
13518 self.write_space();
13519 self.write_keyword("NO CYCLE");
13520 }
13521 SeqPropKind::NoCycleWord => {
13522 self.write_space();
13523 self.write_keyword("NOCYCLE");
13524 }
13525 SeqPropKind::OwnedBy => {
13526 if !cs.owned_by_none {
13528 if let Some(owned) = &cs.owned_by {
13529 self.write_space();
13530 self.write_keyword("OWNED BY");
13531 self.write_space();
13532 self.generate_table(owned)?;
13533 }
13534 }
13535 }
13536 SeqPropKind::Order => {
13537 self.write_space();
13538 self.write_keyword("ORDER");
13539 }
13540 SeqPropKind::NoOrder => {
13541 self.write_space();
13542 self.write_keyword("NOORDER");
13543 }
13544 SeqPropKind::Comment => {
13545 }
13547 SeqPropKind::Sharing => {
13548 if let Some(val) = &cs.sharing {
13549 self.write_space();
13550 self.write(&format!("SHARING={}", val));
13551 }
13552 }
13553 SeqPropKind::Keep => {
13554 self.write_space();
13555 self.write_keyword("KEEP");
13556 }
13557 SeqPropKind::NoKeep => {
13558 self.write_space();
13559 self.write_keyword("NOKEEP");
13560 }
13561 SeqPropKind::Scale => {
13562 self.write_space();
13563 self.write_keyword("SCALE");
13564 if let Some(modifier) = &cs.scale_modifier {
13565 if !modifier.is_empty() {
13566 self.write_space();
13567 self.write_keyword(modifier);
13568 }
13569 }
13570 }
13571 SeqPropKind::NoScale => {
13572 self.write_space();
13573 self.write_keyword("NOSCALE");
13574 }
13575 SeqPropKind::Shard => {
13576 self.write_space();
13577 self.write_keyword("SHARD");
13578 if let Some(modifier) = &cs.shard_modifier {
13579 if !modifier.is_empty() {
13580 self.write_space();
13581 self.write_keyword(modifier);
13582 }
13583 }
13584 }
13585 SeqPropKind::NoShard => {
13586 self.write_space();
13587 self.write_keyword("NOSHARD");
13588 }
13589 SeqPropKind::Session => {
13590 self.write_space();
13591 self.write_keyword("SESSION");
13592 }
13593 SeqPropKind::Global => {
13594 self.write_space();
13595 self.write_keyword("GLOBAL");
13596 }
13597 SeqPropKind::NoMinvalueWord => {
13598 self.write_space();
13599 self.write_keyword("NOMINVALUE");
13600 }
13601 SeqPropKind::NoMaxvalueWord => {
13602 self.write_space();
13603 self.write_keyword("NOMAXVALUE");
13604 }
13605 }
13606 }
13607 } else {
13608 if let Some(inc) = cs.increment {
13610 self.write_space();
13611 self.write_keyword("INCREMENT BY");
13612 self.write(&format!(" {}", inc));
13613 }
13614
13615 if let Some(min) = &cs.minvalue {
13616 self.write_space();
13617 match min {
13618 SequenceBound::Value(v) => {
13619 self.write_keyword("MINVALUE");
13620 self.write(&format!(" {}", v));
13621 }
13622 SequenceBound::None => {
13623 self.write_keyword("NO MINVALUE");
13624 }
13625 }
13626 }
13627
13628 if let Some(max) = &cs.maxvalue {
13629 self.write_space();
13630 match max {
13631 SequenceBound::Value(v) => {
13632 self.write_keyword("MAXVALUE");
13633 self.write(&format!(" {}", v));
13634 }
13635 SequenceBound::None => {
13636 self.write_keyword("NO MAXVALUE");
13637 }
13638 }
13639 }
13640
13641 if let Some(start) = cs.start {
13642 self.write_space();
13643 self.write_keyword("START WITH");
13644 self.write(&format!(" {}", start));
13645 }
13646
13647 if let Some(cache) = cs.cache {
13648 self.write_space();
13649 self.write_keyword("CACHE");
13650 self.write(&format!(" {}", cache));
13651 }
13652
13653 if cs.cycle {
13654 self.write_space();
13655 self.write_keyword("CYCLE");
13656 }
13657
13658 if let Some(owned) = &cs.owned_by {
13659 self.write_space();
13660 self.write_keyword("OWNED BY");
13661 self.write_space();
13662 self.generate_table(owned)?;
13663 }
13664 }
13665
13666 Ok(())
13667 }
13668
13669 fn generate_drop_sequence(&mut self, ds: &DropSequence) -> Result<()> {
13670 self.write_keyword("DROP SEQUENCE");
13671
13672 if ds.if_exists {
13673 self.write_space();
13674 self.write_keyword("IF EXISTS");
13675 }
13676
13677 self.write_space();
13678 self.generate_table(&ds.name)?;
13679
13680 if ds.cascade {
13681 self.write_space();
13682 self.write_keyword("CASCADE");
13683 }
13684
13685 Ok(())
13686 }
13687
13688 fn generate_alter_sequence(&mut self, als: &AlterSequence) -> Result<()> {
13689 self.write_keyword("ALTER SEQUENCE");
13690
13691 if als.if_exists {
13692 self.write_space();
13693 self.write_keyword("IF EXISTS");
13694 }
13695
13696 self.write_space();
13697 self.generate_table(&als.name)?;
13698
13699 if let Some(inc) = als.increment {
13700 self.write_space();
13701 self.write_keyword("INCREMENT BY");
13702 self.write(&format!(" {}", inc));
13703 }
13704
13705 if let Some(min) = &als.minvalue {
13706 self.write_space();
13707 match min {
13708 SequenceBound::Value(v) => {
13709 self.write_keyword("MINVALUE");
13710 self.write(&format!(" {}", v));
13711 }
13712 SequenceBound::None => {
13713 self.write_keyword("NO MINVALUE");
13714 }
13715 }
13716 }
13717
13718 if let Some(max) = &als.maxvalue {
13719 self.write_space();
13720 match max {
13721 SequenceBound::Value(v) => {
13722 self.write_keyword("MAXVALUE");
13723 self.write(&format!(" {}", v));
13724 }
13725 SequenceBound::None => {
13726 self.write_keyword("NO MAXVALUE");
13727 }
13728 }
13729 }
13730
13731 if let Some(start) = als.start {
13732 self.write_space();
13733 self.write_keyword("START WITH");
13734 self.write(&format!(" {}", start));
13735 }
13736
13737 if let Some(restart) = &als.restart {
13738 self.write_space();
13739 self.write_keyword("RESTART");
13740 if let Some(val) = restart {
13741 self.write_keyword(" WITH");
13742 self.write(&format!(" {}", val));
13743 }
13744 }
13745
13746 if let Some(cache) = als.cache {
13747 self.write_space();
13748 self.write_keyword("CACHE");
13749 self.write(&format!(" {}", cache));
13750 }
13751
13752 if let Some(cycle) = als.cycle {
13753 self.write_space();
13754 if cycle {
13755 self.write_keyword("CYCLE");
13756 } else {
13757 self.write_keyword("NO CYCLE");
13758 }
13759 }
13760
13761 if let Some(owned) = &als.owned_by {
13762 self.write_space();
13763 self.write_keyword("OWNED BY");
13764 self.write_space();
13765 if let Some(table) = owned {
13766 self.generate_table(table)?;
13767 } else {
13768 self.write_keyword("NONE");
13769 }
13770 }
13771
13772 Ok(())
13773 }
13774
13775 fn generate_create_trigger(&mut self, ct: &CreateTrigger) -> Result<()> {
13776 self.write_keyword("CREATE");
13777
13778 if ct.or_alter {
13779 self.write_space();
13780 self.write_keyword("OR ALTER");
13781 } else if ct.or_replace {
13782 self.write_space();
13783 self.write_keyword("OR REPLACE");
13784 }
13785
13786 if ct.constraint {
13787 self.write_space();
13788 self.write_keyword("CONSTRAINT");
13789 }
13790
13791 self.write_space();
13792 self.write_keyword("TRIGGER");
13793 self.write_space();
13794 self.generate_identifier(&ct.name)?;
13795
13796 self.write_space();
13797 match ct.timing {
13798 TriggerTiming::Before => self.write_keyword("BEFORE"),
13799 TriggerTiming::After => self.write_keyword("AFTER"),
13800 TriggerTiming::InsteadOf => self.write_keyword("INSTEAD OF"),
13801 }
13802
13803 for (i, event) in ct.events.iter().enumerate() {
13805 if i > 0 {
13806 self.write_keyword(" OR");
13807 }
13808 self.write_space();
13809 match event {
13810 TriggerEvent::Insert => self.write_keyword("INSERT"),
13811 TriggerEvent::Update(cols) => {
13812 self.write_keyword("UPDATE");
13813 if let Some(cols) = cols {
13814 self.write_space();
13815 self.write_keyword("OF");
13816 for (j, col) in cols.iter().enumerate() {
13817 if j > 0 {
13818 self.write(",");
13819 }
13820 self.write_space();
13821 self.generate_identifier(col)?;
13822 }
13823 }
13824 }
13825 TriggerEvent::Delete => self.write_keyword("DELETE"),
13826 TriggerEvent::Truncate => self.write_keyword("TRUNCATE"),
13827 }
13828 }
13829
13830 self.write_space();
13831 self.write_keyword("ON");
13832 self.write_space();
13833 self.generate_table(&ct.table)?;
13834
13835 if let Some(ref_clause) = &ct.referencing {
13837 self.write_space();
13838 self.write_keyword("REFERENCING");
13839 if let Some(old_table) = &ref_clause.old_table {
13840 self.write_space();
13841 self.write_keyword("OLD TABLE AS");
13842 self.write_space();
13843 self.generate_identifier(old_table)?;
13844 }
13845 if let Some(new_table) = &ref_clause.new_table {
13846 self.write_space();
13847 self.write_keyword("NEW TABLE AS");
13848 self.write_space();
13849 self.generate_identifier(new_table)?;
13850 }
13851 if let Some(old_row) = &ref_clause.old_row {
13852 self.write_space();
13853 self.write_keyword("OLD ROW AS");
13854 self.write_space();
13855 self.generate_identifier(old_row)?;
13856 }
13857 if let Some(new_row) = &ref_clause.new_row {
13858 self.write_space();
13859 self.write_keyword("NEW ROW AS");
13860 self.write_space();
13861 self.generate_identifier(new_row)?;
13862 }
13863 }
13864
13865 if let Some(deferrable) = ct.deferrable {
13867 self.write_space();
13868 if deferrable {
13869 self.write_keyword("DEFERRABLE");
13870 } else {
13871 self.write_keyword("NOT DEFERRABLE");
13872 }
13873 }
13874
13875 if let Some(initially) = ct.initially_deferred {
13876 self.write_space();
13877 self.write_keyword("INITIALLY");
13878 self.write_space();
13879 if initially {
13880 self.write_keyword("DEFERRED");
13881 } else {
13882 self.write_keyword("IMMEDIATE");
13883 }
13884 }
13885
13886 if let Some(for_each) = ct.for_each {
13887 self.write_space();
13888 self.write_keyword("FOR EACH");
13889 self.write_space();
13890 match for_each {
13891 TriggerForEach::Row => self.write_keyword("ROW"),
13892 TriggerForEach::Statement => self.write_keyword("STATEMENT"),
13893 }
13894 }
13895
13896 if let Some(when) = &ct.when {
13898 self.write_space();
13899 self.write_keyword("WHEN");
13900 if ct.when_paren {
13901 self.write(" (");
13902 self.generate_expression(when)?;
13903 self.write(")");
13904 } else {
13905 self.write_space();
13906 self.generate_expression(when)?;
13907 }
13908 }
13909
13910 self.write_space();
13912 match &ct.body {
13913 TriggerBody::Execute { function, args } => {
13914 self.write_keyword("EXECUTE FUNCTION");
13915 self.write_space();
13916 self.generate_table(function)?;
13917 self.write("(");
13918 for (i, arg) in args.iter().enumerate() {
13919 if i > 0 {
13920 self.write(", ");
13921 }
13922 self.generate_expression(arg)?;
13923 }
13924 self.write(")");
13925 }
13926 TriggerBody::Block(block) => {
13927 self.write_keyword("BEGIN");
13928 self.write_space();
13929 self.write(block);
13930 self.write_space();
13931 self.write_keyword("END");
13932 }
13933 }
13934
13935 Ok(())
13936 }
13937
13938 fn generate_drop_trigger(&mut self, dt: &DropTrigger) -> Result<()> {
13939 self.write_keyword("DROP TRIGGER");
13940
13941 if dt.if_exists {
13942 self.write_space();
13943 self.write_keyword("IF EXISTS");
13944 }
13945
13946 self.write_space();
13947 self.generate_identifier(&dt.name)?;
13948
13949 if let Some(table) = &dt.table {
13950 self.write_space();
13951 self.write_keyword("ON");
13952 self.write_space();
13953 self.generate_table(table)?;
13954 }
13955
13956 if dt.cascade {
13957 self.write_space();
13958 self.write_keyword("CASCADE");
13959 }
13960
13961 Ok(())
13962 }
13963
13964 fn generate_create_type(&mut self, ct: &CreateType) -> Result<()> {
13965 self.write_keyword("CREATE TYPE");
13966
13967 if ct.if_not_exists {
13968 self.write_space();
13969 self.write_keyword("IF NOT EXISTS");
13970 }
13971
13972 self.write_space();
13973 self.generate_table(&ct.name)?;
13974
13975 self.write_space();
13976 self.write_keyword("AS");
13977 self.write_space();
13978
13979 match &ct.definition {
13980 TypeDefinition::Enum(values) => {
13981 self.write_keyword("ENUM");
13982 self.write(" (");
13983 for (i, val) in values.iter().enumerate() {
13984 if i > 0 {
13985 self.write(", ");
13986 }
13987 self.write(&format!("'{}'", val));
13988 }
13989 self.write(")");
13990 }
13991 TypeDefinition::Composite(attrs) => {
13992 self.write("(");
13993 for (i, attr) in attrs.iter().enumerate() {
13994 if i > 0 {
13995 self.write(", ");
13996 }
13997 self.generate_identifier(&attr.name)?;
13998 self.write_space();
13999 self.generate_data_type(&attr.data_type)?;
14000 if let Some(collate) = &attr.collate {
14001 self.write_space();
14002 self.write_keyword("COLLATE");
14003 self.write_space();
14004 self.generate_identifier(collate)?;
14005 }
14006 }
14007 self.write(")");
14008 }
14009 TypeDefinition::Range {
14010 subtype,
14011 subtype_diff,
14012 canonical,
14013 } => {
14014 self.write_keyword("RANGE");
14015 self.write(" (");
14016 self.write_keyword("SUBTYPE");
14017 self.write(" = ");
14018 self.generate_data_type(subtype)?;
14019 if let Some(diff) = subtype_diff {
14020 self.write(", ");
14021 self.write_keyword("SUBTYPE_DIFF");
14022 self.write(" = ");
14023 self.write(diff);
14024 }
14025 if let Some(canon) = canonical {
14026 self.write(", ");
14027 self.write_keyword("CANONICAL");
14028 self.write(" = ");
14029 self.write(canon);
14030 }
14031 self.write(")");
14032 }
14033 TypeDefinition::Base {
14034 input,
14035 output,
14036 internallength,
14037 } => {
14038 self.write("(");
14039 self.write_keyword("INPUT");
14040 self.write(" = ");
14041 self.write(input);
14042 self.write(", ");
14043 self.write_keyword("OUTPUT");
14044 self.write(" = ");
14045 self.write(output);
14046 if let Some(len) = internallength {
14047 self.write(", ");
14048 self.write_keyword("INTERNALLENGTH");
14049 self.write(" = ");
14050 self.write(&len.to_string());
14051 }
14052 self.write(")");
14053 }
14054 TypeDefinition::Domain {
14055 base_type,
14056 default,
14057 constraints,
14058 } => {
14059 self.generate_data_type(base_type)?;
14060 if let Some(def) = default {
14061 self.write_space();
14062 self.write_keyword("DEFAULT");
14063 self.write_space();
14064 self.generate_expression(def)?;
14065 }
14066 for constr in constraints {
14067 self.write_space();
14068 if let Some(name) = &constr.name {
14069 self.write_keyword("CONSTRAINT");
14070 self.write_space();
14071 self.generate_identifier(name)?;
14072 self.write_space();
14073 }
14074 self.write_keyword("CHECK");
14075 self.write(" (");
14076 self.generate_expression(&constr.check)?;
14077 self.write(")");
14078 }
14079 }
14080 }
14081
14082 Ok(())
14083 }
14084
14085 fn generate_create_task(&mut self, task: &crate::expressions::CreateTask) -> Result<()> {
14086 self.write_keyword("CREATE");
14087 if task.or_replace {
14088 self.write_space();
14089 self.write_keyword("OR REPLACE");
14090 }
14091 self.write_space();
14092 self.write_keyword("TASK");
14093 if task.if_not_exists {
14094 self.write_space();
14095 self.write_keyword("IF NOT EXISTS");
14096 }
14097 self.write_space();
14098 self.write(&task.name);
14099 if !task.properties.is_empty() {
14100 if !task.properties.starts_with('\n') && !task.properties.starts_with(' ') {
14102 self.write_space();
14103 }
14104 self.write(&task.properties);
14105 }
14106 self.write_space();
14107 self.write_keyword("AS");
14108 self.write_space();
14109 self.generate_expression(&task.body)?;
14110 Ok(())
14111 }
14112
14113 fn generate_try_catch(&mut self, try_catch: &TryCatch) -> Result<()> {
14114 self.write_keyword("BEGIN TRY");
14115 self.generate_tsql_block_statements(&try_catch.try_body)?;
14116 self.write_keyword("END TRY");
14117
14118 if let Some(catch_body) = &try_catch.catch_body {
14119 if self.config.pretty {
14120 self.write_newline();
14121 self.write_indent();
14122 } else {
14123 self.write_space();
14124 }
14125 self.write_keyword("BEGIN CATCH");
14126 self.generate_tsql_block_statements(catch_body)?;
14127 self.write_keyword("END CATCH");
14128 }
14129
14130 Ok(())
14131 }
14132
14133 fn generate_tsql_block_statements(&mut self, statements: &[Expression]) -> Result<()> {
14134 if statements.is_empty() {
14135 self.write_space();
14136 return Ok(());
14137 }
14138
14139 if self.config.pretty {
14140 self.indent_level += 1;
14141 for stmt in statements {
14142 self.write_newline();
14143 self.write_indent();
14144 self.generate_expression(stmt)?;
14145 self.write(";");
14146 }
14147 self.indent_level -= 1;
14148 self.write_newline();
14149 self.write_indent();
14150 } else {
14151 self.write_space();
14152 for (i, stmt) in statements.iter().enumerate() {
14153 if i > 0 {
14154 self.write_space();
14155 }
14156 self.generate_expression(stmt)?;
14157 self.write(";");
14158 }
14159 self.write_space();
14160 }
14161
14162 Ok(())
14163 }
14164
14165 fn generate_drop_type(&mut self, dt: &DropType) -> Result<()> {
14166 self.write_keyword("DROP TYPE");
14167
14168 if dt.if_exists {
14169 self.write_space();
14170 self.write_keyword("IF EXISTS");
14171 }
14172
14173 self.write_space();
14174 self.generate_table(&dt.name)?;
14175
14176 if dt.cascade {
14177 self.write_space();
14178 self.write_keyword("CASCADE");
14179 }
14180
14181 Ok(())
14182 }
14183
14184 fn generate_describe(&mut self, d: &Describe) -> Result<()> {
14185 let saved_athena_hive_context = self.athena_hive_context;
14187 if matches!(
14188 self.config.dialect,
14189 Some(crate::dialects::DialectType::Athena)
14190 ) {
14191 self.athena_hive_context = true;
14192 }
14193
14194 for comment in &d.leading_comments {
14196 self.write_formatted_comment(comment);
14197 self.write(" ");
14198 }
14199
14200 self.write_keyword("DESCRIBE");
14201
14202 if d.extended {
14203 self.write_space();
14204 self.write_keyword("EXTENDED");
14205 } else if d.formatted {
14206 self.write_space();
14207 self.write_keyword("FORMATTED");
14208 }
14209
14210 if let Some(ref style) = d.style {
14212 self.write_space();
14213 self.write_keyword(style);
14214 }
14215
14216 let should_output_kind = match self.config.dialect {
14218 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
14220 false
14221 }
14222 Some(DialectType::Snowflake) => true,
14224 _ => d.kind.is_some(),
14225 };
14226 if should_output_kind {
14227 if let Some(ref kind) = d.kind {
14228 self.write_space();
14229 self.write_keyword(kind);
14230 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
14231 self.write_space();
14232 self.write_keyword("TABLE");
14233 }
14234 }
14235
14236 self.write_space();
14237 self.generate_expression(&d.target)?;
14238
14239 if !d.params.is_empty() {
14241 self.write("(");
14242 for (i, param) in d.params.iter().enumerate() {
14243 if i > 0 {
14244 self.write(", ");
14245 }
14246 self.write(param);
14247 }
14248 self.write(")");
14249 }
14250
14251 if let Some(ref partition) = d.partition {
14253 self.write_space();
14254 self.generate_expression(partition)?;
14255 }
14256
14257 if d.as_json {
14259 self.write_space();
14260 self.write_keyword("AS JSON");
14261 }
14262
14263 for (name, value) in &d.properties {
14265 self.write_space();
14266 self.write(name);
14267 self.write("=");
14268 self.write(value);
14269 }
14270
14271 self.athena_hive_context = saved_athena_hive_context;
14273
14274 Ok(())
14275 }
14276
14277 fn generate_show(&mut self, s: &Show) -> Result<()> {
14280 self.write_keyword("SHOW");
14281 self.write_space();
14282
14283 let show_terse = s.terse
14286 && !matches!(
14287 s.this.as_str(),
14288 "PRIMARY KEYS" | "UNIQUE KEYS" | "IMPORTED KEYS"
14289 );
14290 if show_terse {
14291 self.write_keyword("TERSE");
14292 self.write_space();
14293 }
14294
14295 self.write_keyword(&s.this);
14297
14298 if let Some(ref target_expr) = s.target {
14300 self.write_space();
14301 self.generate_expression(target_expr)?;
14302 }
14303
14304 if s.history {
14306 self.write_space();
14307 self.write_keyword("HISTORY");
14308 }
14309
14310 if let Some(ref for_target) = s.for_target {
14312 self.write_space();
14313 self.write_keyword("FOR");
14314 self.write_space();
14315 self.generate_expression(for_target)?;
14316 }
14317
14318 use crate::dialects::DialectType;
14322 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
14323 let is_mysql = matches!(self.config.dialect, Some(DialectType::MySQL));
14324 let mysql_tables_scope_as_from = is_mysql
14325 && matches!(s.this.as_str(), "TABLES" | "FULL TABLES")
14326 && s.scope_kind.as_deref() == Some("SCHEMA")
14327 && s.scope.is_some()
14328 && s.from.is_none();
14329
14330 if !is_snowflake && s.from.is_some() {
14331 if let Some(ref scope_kind) = s.scope_kind {
14335 self.write_space();
14336 self.write_keyword("IN");
14337 self.write_space();
14338 self.write_keyword(scope_kind);
14339 if let Some(ref scope) = s.scope {
14340 self.write_space();
14341 self.generate_expression(scope)?;
14342 }
14343 } else if let Some(ref scope) = s.scope {
14344 self.write_space();
14345 self.write_keyword("IN");
14346 self.write_space();
14347 self.generate_expression(scope)?;
14348 }
14349
14350 if let Some(ref from) = s.from {
14352 self.write_space();
14353 self.write_keyword("FROM");
14354 self.write_space();
14355 self.generate_expression(from)?;
14356 }
14357
14358 if let Some(ref db) = s.db {
14360 self.write_space();
14361 self.write_keyword("FROM");
14362 self.write_space();
14363 self.generate_expression(db)?;
14364 }
14365
14366 if let Some(ref like) = s.like {
14368 self.write_space();
14369 self.write_keyword("LIKE");
14370 self.write_space();
14371 self.generate_expression(like)?;
14372 }
14373 } else {
14374 if let Some(ref like) = s.like {
14378 self.write_space();
14379 self.write_keyword("LIKE");
14380 self.write_space();
14381 self.generate_expression(like)?;
14382 }
14383
14384 if mysql_tables_scope_as_from {
14386 self.write_space();
14387 self.write_keyword("FROM");
14388 self.write_space();
14389 self.generate_expression(s.scope.as_ref().unwrap())?;
14390 } else if let Some(ref scope_kind) = s.scope_kind {
14391 self.write_space();
14392 self.write_keyword("IN");
14393 self.write_space();
14394 self.write_keyword(scope_kind);
14395 if let Some(ref scope) = s.scope {
14396 self.write_space();
14397 self.generate_expression(scope)?;
14398 }
14399 } else if let Some(ref scope) = s.scope {
14400 self.write_space();
14401 self.write_keyword("IN");
14402 self.write_space();
14403 self.generate_expression(scope)?;
14404 }
14405 }
14406
14407 if let Some(ref starts_with) = s.starts_with {
14409 self.write_space();
14410 self.write_keyword("STARTS WITH");
14411 self.write_space();
14412 self.generate_expression(starts_with)?;
14413 }
14414
14415 if let Some(ref limit) = s.limit {
14417 self.write_space();
14418 self.generate_limit(limit)?;
14419 }
14420
14421 if is_snowflake {
14423 if let Some(ref from) = s.from {
14424 self.write_space();
14425 self.write_keyword("FROM");
14426 self.write_space();
14427 self.generate_expression(from)?;
14428 }
14429 }
14430
14431 if let Some(ref where_clause) = s.where_clause {
14433 self.write_space();
14434 self.write_keyword("WHERE");
14435 self.write_space();
14436 self.generate_expression(where_clause)?;
14437 }
14438
14439 if let Some(is_mutex) = s.mutex {
14441 self.write_space();
14442 if is_mutex {
14443 self.write_keyword("MUTEX");
14444 } else {
14445 self.write_keyword("STATUS");
14446 }
14447 }
14448
14449 if !s.privileges.is_empty() {
14451 self.write_space();
14452 self.write_keyword("WITH PRIVILEGES");
14453 self.write_space();
14454 for (i, priv_name) in s.privileges.iter().enumerate() {
14455 if i > 0 {
14456 self.write(", ");
14457 }
14458 self.write_keyword(priv_name);
14459 }
14460 }
14461
14462 Ok(())
14463 }
14464
14465 fn generate_literal(&mut self, lit: &Literal) -> Result<()> {
14468 use crate::dialects::DialectType;
14469 match lit {
14470 Literal::String(s) => {
14471 self.generate_string_literal(s)?;
14472 }
14473 Literal::Number(n) => {
14474 if matches!(self.config.dialect, Some(DialectType::MySQL))
14475 && n.len() > 2
14476 && (n.starts_with("0x") || n.starts_with("0X"))
14477 && !n[2..].chars().all(|c| c.is_ascii_hexdigit())
14478 {
14479 return self.generate_identifier(&Identifier {
14480 name: n.clone(),
14481 quoted: true,
14482 trailing_comments: Vec::new(),
14483 span: None,
14484 });
14485 }
14486 let n = if n.contains('_')
14490 && !matches!(
14491 self.config.dialect,
14492 Some(DialectType::ClickHouse)
14493 | Some(DialectType::DuckDB)
14494 | Some(DialectType::PostgreSQL)
14495 | Some(DialectType::Hive)
14496 | Some(DialectType::Spark)
14497 | Some(DialectType::Databricks)
14498 ) {
14499 std::borrow::Cow::Owned(n.replace('_', ""))
14500 } else {
14501 std::borrow::Cow::Borrowed(n.as_str())
14502 };
14503 if n.starts_with('.') {
14506 self.write("0");
14507 self.write(&n);
14508 } else if n.starts_with("-.") {
14509 self.write("-0");
14511 self.write(&n[1..]);
14512 } else {
14513 self.write(&n);
14514 }
14515 }
14516 Literal::HexString(h) => {
14517 match self.config.dialect {
14519 Some(DialectType::Spark)
14520 | Some(DialectType::Databricks)
14521 | Some(DialectType::Teradata) => self.write("X'"),
14522 _ => self.write("x'"),
14523 }
14524 self.write(h);
14525 self.write("'");
14526 }
14527 Literal::HexNumber(h) => {
14528 match self.config.dialect {
14532 Some(DialectType::BigQuery)
14533 | Some(DialectType::ClickHouse)
14534 | Some(DialectType::TSQL)
14535 | Some(DialectType::Fabric) => {
14536 self.write("0x");
14537 self.write(h);
14538 }
14539 _ => {
14540 if let Ok(val) = u64::from_str_radix(h, 16) {
14542 self.write(&val.to_string());
14543 } else {
14544 self.write("0x");
14546 self.write(h);
14547 }
14548 }
14549 }
14550 }
14551 Literal::BitString(b) => {
14552 self.write("B'");
14554 self.write(b);
14555 self.write("'");
14556 }
14557 Literal::ByteString(b) => {
14558 self.write("b'");
14560 self.write_escaped_byte_string(b);
14562 self.write("'");
14563 }
14564 Literal::NationalString(s) => {
14565 let keep_n_prefix = matches!(
14568 self.config.dialect,
14569 Some(DialectType::TSQL)
14570 | Some(DialectType::Oracle)
14571 | Some(DialectType::MySQL)
14572 | None
14573 );
14574 if keep_n_prefix {
14575 self.write("N'");
14576 } else {
14577 self.write("'");
14578 }
14579 self.write(s);
14580 self.write("'");
14581 }
14582 Literal::Date(d) => {
14583 self.generate_date_literal(d)?;
14584 }
14585 Literal::Time(t) => {
14586 self.generate_time_literal(t)?;
14587 }
14588 Literal::Timestamp(ts) => {
14589 self.generate_timestamp_literal(ts)?;
14590 }
14591 Literal::Datetime(dt) => {
14592 self.generate_datetime_literal(dt)?;
14593 }
14594 Literal::TripleQuotedString(s, _quote_char) => {
14595 if matches!(
14597 self.config.dialect,
14598 Some(crate::dialects::DialectType::BigQuery)
14599 | Some(crate::dialects::DialectType::DuckDB)
14600 | Some(crate::dialects::DialectType::Snowflake)
14601 | Some(crate::dialects::DialectType::Spark)
14602 | Some(crate::dialects::DialectType::Hive)
14603 | Some(crate::dialects::DialectType::Presto)
14604 | Some(crate::dialects::DialectType::Trino)
14605 | Some(crate::dialects::DialectType::PostgreSQL)
14606 | Some(crate::dialects::DialectType::MySQL)
14607 | Some(crate::dialects::DialectType::Redshift)
14608 | Some(crate::dialects::DialectType::TSQL)
14609 | Some(crate::dialects::DialectType::Oracle)
14610 | Some(crate::dialects::DialectType::ClickHouse)
14611 | Some(crate::dialects::DialectType::Databricks)
14612 | Some(crate::dialects::DialectType::SQLite)
14613 ) {
14614 self.generate_string_literal(s)?;
14615 } else {
14616 let quotes = format!("{0}{0}{0}", _quote_char);
14618 self.write("es);
14619 self.write(s);
14620 self.write("es);
14621 }
14622 }
14623 Literal::EscapeString(s) => {
14624 use crate::dialects::DialectType;
14628 let content = if let Some(c) = s.strip_prefix("e:") {
14629 c
14630 } else if let Some(c) = s.strip_prefix("E:") {
14631 c
14632 } else {
14633 s.as_str()
14634 };
14635
14636 if matches!(
14638 self.config.dialect,
14639 Some(DialectType::MySQL) | Some(DialectType::TiDB)
14640 ) {
14641 self.write(content);
14642 } else {
14643 let prefix = if matches!(
14645 self.config.dialect,
14646 Some(DialectType::SingleStore)
14647 | Some(DialectType::DuckDB)
14648 | Some(DialectType::PostgreSQL)
14649 | Some(DialectType::CockroachDB)
14650 | Some(DialectType::Materialize)
14651 | Some(DialectType::RisingWave)
14652 ) {
14653 "e'"
14654 } else {
14655 "E'"
14656 };
14657
14658 let normalized = content.replace("\\'", "''");
14660 self.write(prefix);
14661 self.write(&normalized);
14662 self.write("'");
14663 }
14664 }
14665 Literal::DollarString(s) => {
14666 use crate::dialects::DialectType;
14669 let (_tag, content) = crate::tokens::parse_dollar_string_token(s);
14671 let escape_backslash = matches!(
14673 self.config.dialect,
14674 Some(DialectType::ClickHouse) | Some(DialectType::Snowflake)
14675 );
14676 let use_backslash_quote =
14680 matches!(self.config.dialect, Some(DialectType::Snowflake));
14681
14682 let mut escaped = String::with_capacity(content.len() + 4);
14683 for ch in content.chars() {
14684 if escape_backslash && ch == '\\' {
14685 escaped.push('\\');
14687 escaped.push('\\');
14688 } else if ch == '\'' {
14689 if use_backslash_quote {
14690 escaped.push('\\');
14691 escaped.push('\'');
14692 } else {
14693 escaped.push('\'');
14694 escaped.push('\'');
14695 }
14696 } else {
14697 escaped.push(ch);
14698 }
14699 }
14700 self.write("'");
14701 self.write(&escaped);
14702 self.write("'");
14703 }
14704 Literal::RawString(s) => {
14705 use crate::dialects::DialectType;
14711
14712 let escape_backslash = matches!(
14714 self.config.dialect,
14715 Some(DialectType::BigQuery)
14716 | Some(DialectType::MySQL)
14717 | Some(DialectType::SingleStore)
14718 | Some(DialectType::TiDB)
14719 | Some(DialectType::Hive)
14720 | Some(DialectType::Spark)
14721 | Some(DialectType::Databricks)
14722 | Some(DialectType::Drill)
14723 | Some(DialectType::Snowflake)
14724 | Some(DialectType::Redshift)
14725 | Some(DialectType::ClickHouse)
14726 );
14727
14728 let backslash_escapes_quote = matches!(
14731 self.config.dialect,
14732 Some(DialectType::BigQuery)
14733 | Some(DialectType::Hive)
14734 | Some(DialectType::Spark)
14735 | Some(DialectType::Databricks)
14736 | Some(DialectType::Drill)
14737 | Some(DialectType::Snowflake)
14738 | Some(DialectType::Redshift)
14739 );
14740
14741 let supports_escape_sequences = escape_backslash;
14744
14745 let mut escaped = String::with_capacity(s.len() + 4);
14746 for ch in s.chars() {
14747 if escape_backslash && ch == '\\' {
14748 escaped.push('\\');
14750 escaped.push('\\');
14751 } else if ch == '\'' {
14752 if backslash_escapes_quote {
14753 escaped.push('\\');
14755 escaped.push('\'');
14756 } else {
14757 escaped.push('\'');
14759 escaped.push('\'');
14760 }
14761 } else if supports_escape_sequences {
14762 match ch {
14765 '\n' => {
14766 escaped.push('\\');
14767 escaped.push('n');
14768 }
14769 '\r' => {
14770 escaped.push('\\');
14771 escaped.push('r');
14772 }
14773 '\t' => {
14774 escaped.push('\\');
14775 escaped.push('t');
14776 }
14777 '\x07' => {
14778 escaped.push('\\');
14779 escaped.push('a');
14780 }
14781 '\x08' => {
14782 escaped.push('\\');
14783 escaped.push('b');
14784 }
14785 '\x0C' => {
14786 escaped.push('\\');
14787 escaped.push('f');
14788 }
14789 '\x0B' => {
14790 escaped.push('\\');
14791 escaped.push('v');
14792 }
14793 _ => escaped.push(ch),
14794 }
14795 } else {
14796 escaped.push(ch);
14797 }
14798 }
14799 self.write("'");
14800 self.write(&escaped);
14801 self.write("'");
14802 }
14803 }
14804 Ok(())
14805 }
14806
14807 fn generate_date_literal(&mut self, d: &str) -> Result<()> {
14809 use crate::dialects::DialectType;
14810
14811 match self.config.dialect {
14812 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
14814 self.write("CAST('");
14815 self.write(d);
14816 self.write("' AS DATE)");
14817 }
14818 Some(DialectType::BigQuery) => {
14821 self.write("CAST('");
14822 self.write(d);
14823 self.write("' AS DATE)");
14824 }
14825 Some(DialectType::Exasol) => {
14828 self.write("CAST('");
14829 self.write(d);
14830 self.write("' AS DATE)");
14831 }
14832 Some(DialectType::Snowflake) => {
14835 self.write("CAST('");
14836 self.write(d);
14837 self.write("' AS DATE)");
14838 }
14839 Some(DialectType::PostgreSQL)
14841 | Some(DialectType::MySQL)
14842 | Some(DialectType::SingleStore)
14843 | Some(DialectType::TiDB)
14844 | Some(DialectType::Redshift) => {
14845 self.write("CAST('");
14846 self.write(d);
14847 self.write("' AS DATE)");
14848 }
14849 Some(DialectType::DuckDB)
14851 | Some(DialectType::Presto)
14852 | Some(DialectType::Trino)
14853 | Some(DialectType::Athena)
14854 | Some(DialectType::Spark)
14855 | Some(DialectType::Databricks)
14856 | Some(DialectType::Hive) => {
14857 self.write("CAST('");
14858 self.write(d);
14859 self.write("' AS DATE)");
14860 }
14861 Some(DialectType::Oracle) => {
14863 self.write("TO_DATE('");
14864 self.write(d);
14865 self.write("', 'YYYY-MM-DD')");
14866 }
14867 _ => {
14869 self.write_keyword("DATE");
14870 self.write(" '");
14871 self.write(d);
14872 self.write("'");
14873 }
14874 }
14875 Ok(())
14876 }
14877
14878 fn generate_time_literal(&mut self, t: &str) -> Result<()> {
14880 use crate::dialects::DialectType;
14881
14882 match self.config.dialect {
14883 Some(DialectType::TSQL) => {
14885 self.write("CAST('");
14886 self.write(t);
14887 self.write("' AS TIME)");
14888 }
14889 _ => {
14891 self.write_keyword("TIME");
14892 self.write(" '");
14893 self.write(t);
14894 self.write("'");
14895 }
14896 }
14897 Ok(())
14898 }
14899
14900 fn generate_dremio_date_expression(&mut self, expr: &Expression) -> Result<()> {
14902 use crate::expressions::Literal;
14903
14904 match expr {
14905 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Date(_)) => {
14906 let Literal::Date(d) = lit.as_ref() else {
14907 unreachable!()
14908 };
14909 self.write("CAST('");
14911 self.write(d);
14912 self.write("' AS DATE)");
14913 }
14914 _ => {
14915 self.generate_expression(expr)?;
14917 }
14918 }
14919 Ok(())
14920 }
14921
14922 fn generate_timestamp_literal(&mut self, ts: &str) -> Result<()> {
14924 use crate::dialects::DialectType;
14925
14926 match self.config.dialect {
14927 Some(DialectType::TSQL) => {
14929 self.write("CAST('");
14930 self.write(ts);
14931 self.write("' AS DATETIME2)");
14932 }
14933 Some(DialectType::BigQuery) => {
14936 self.write("CAST('");
14937 self.write(ts);
14938 self.write("' AS TIMESTAMP)");
14939 }
14940 Some(DialectType::Snowflake) => {
14943 self.write("CAST('");
14944 self.write(ts);
14945 self.write("' AS TIMESTAMP)");
14946 }
14947 Some(DialectType::Dremio) => {
14950 self.write("CAST('");
14951 self.write(ts);
14952 self.write("' AS TIMESTAMP)");
14953 }
14954 Some(DialectType::Exasol) => {
14957 self.write("CAST('");
14958 self.write(ts);
14959 self.write("' AS TIMESTAMP)");
14960 }
14961 Some(DialectType::Oracle) => {
14964 self.write("TO_TIMESTAMP('");
14965 self.write(ts);
14966 self.write("', 'YYYY-MM-DD HH24:MI:SS.FF6')");
14967 }
14968 Some(DialectType::Presto) | Some(DialectType::Trino) => {
14970 if Self::timestamp_has_timezone(ts) {
14971 self.write("CAST('");
14972 self.write(ts);
14973 self.write("' AS TIMESTAMP WITH TIME ZONE)");
14974 } else {
14975 self.write("CAST('");
14976 self.write(ts);
14977 self.write("' AS TIMESTAMP)");
14978 }
14979 }
14980 Some(DialectType::ClickHouse) => {
14982 self.write("CAST('");
14983 self.write(ts);
14984 self.write("' AS Nullable(DateTime))");
14985 }
14986 Some(DialectType::Spark) => {
14988 self.write("CAST('");
14989 self.write(ts);
14990 self.write("' AS TIMESTAMP)");
14991 }
14992 Some(DialectType::Redshift) => {
14995 if ts == "epoch" {
14996 self.write_keyword("TIMESTAMP");
14997 self.write(" '");
14998 self.write(ts);
14999 self.write("'");
15000 } else {
15001 self.write("CAST('");
15002 self.write(ts);
15003 self.write("' AS TIMESTAMP)");
15004 }
15005 }
15006 Some(DialectType::PostgreSQL)
15008 | Some(DialectType::Hive)
15009 | Some(DialectType::SQLite)
15010 | Some(DialectType::DuckDB)
15011 | Some(DialectType::Athena)
15012 | Some(DialectType::Drill)
15013 | Some(DialectType::Teradata) => {
15014 self.write("CAST('");
15015 self.write(ts);
15016 self.write("' AS TIMESTAMP)");
15017 }
15018 Some(DialectType::MySQL) | Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
15020 self.write("CAST('");
15021 self.write(ts);
15022 self.write("' AS DATETIME)");
15023 }
15024 Some(DialectType::Databricks) => {
15026 self.write("CAST('");
15027 self.write(ts);
15028 self.write("' AS TIMESTAMP_NTZ)");
15029 }
15030 _ => {
15032 self.write_keyword("TIMESTAMP");
15033 self.write(" '");
15034 self.write(ts);
15035 self.write("'");
15036 }
15037 }
15038 Ok(())
15039 }
15040
15041 fn timestamp_has_timezone(ts: &str) -> bool {
15044 let ts_lower = ts.to_ascii_lowercase();
15048
15049 let continent_prefixes = [
15051 "africa/",
15052 "america/",
15053 "antarctica/",
15054 "arctic/",
15055 "asia/",
15056 "atlantic/",
15057 "australia/",
15058 "europe/",
15059 "indian/",
15060 "pacific/",
15061 "etc/",
15062 "brazil/",
15063 "canada/",
15064 "chile/",
15065 "mexico/",
15066 "us/",
15067 ];
15068
15069 for prefix in &continent_prefixes {
15070 if ts_lower.contains(prefix) {
15071 return true;
15072 }
15073 }
15074
15075 let tz_abbrevs = [
15078 " utc", " gmt", " cet", " cest", " eet", " eest", " wet", " west", " est", " edt",
15079 " cst", " cdt", " mst", " mdt", " pst", " pdt", " ist", " bst", " jst", " kst", " hkt",
15080 " sgt", " aest", " aedt", " acst", " acdt", " awst",
15081 ];
15082
15083 for abbrev in &tz_abbrevs {
15084 if ts_lower.ends_with(abbrev) {
15085 return true;
15086 }
15087 }
15088
15089 let trimmed = ts.trim();
15093 if let Some(last_space) = trimmed.rfind(' ') {
15094 let suffix = &trimmed[last_space + 1..];
15095 if (suffix.starts_with('+') || suffix.starts_with('-')) && suffix.len() > 1 {
15096 let rest = &suffix[1..];
15098 if rest.chars().all(|c| c.is_ascii_digit() || c == ':') {
15099 return true;
15100 }
15101 }
15102 }
15103
15104 false
15105 }
15106
15107 fn generate_datetime_literal(&mut self, dt: &str) -> Result<()> {
15109 use crate::dialects::DialectType;
15110
15111 match self.config.dialect {
15112 Some(DialectType::BigQuery) => {
15115 self.write("CAST('");
15116 self.write(dt);
15117 self.write("' AS DATETIME)");
15118 }
15119 Some(DialectType::DuckDB) => {
15121 self.write("CAST('");
15122 self.write(dt);
15123 self.write("' AS TIMESTAMP)");
15124 }
15125 _ => {
15128 self.write_keyword("DATETIME");
15129 self.write(" '");
15130 self.write(dt);
15131 self.write("'");
15132 }
15133 }
15134 Ok(())
15135 }
15136
15137 fn generate_string_literal(&mut self, s: &str) -> Result<()> {
15139 use crate::dialects::DialectType;
15140
15141 match self.config.dialect {
15142 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
15146 self.write("'");
15148 for c in s.chars() {
15149 match c {
15150 '\'' => self.write("\\'"),
15151 '\\' => self.write("\\\\"),
15152 '\n' => self.write("\\n"),
15153 '\r' => self.write("\\r"),
15154 '\t' => self.write("\\t"),
15155 '\0' => self.write("\\0"),
15156 _ => self.output.push(c),
15157 }
15158 }
15159 self.write("'");
15160 }
15161 Some(DialectType::Drill) => {
15162 self.write("'");
15165 for c in s.chars() {
15166 match c {
15167 '\'' => self.write("''"),
15168 '\\' => self.write("\\\\"),
15169 '\n' => self.write("\\n"),
15170 '\r' => self.write("\\r"),
15171 '\t' => self.write("\\t"),
15172 '\0' => self.write("\\0"),
15173 _ => self.output.push(c),
15174 }
15175 }
15176 self.write("'");
15177 }
15178 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB) => {
15179 self.write("'");
15180 for c in s.chars() {
15181 match c {
15182 '\'' => self.write("''"),
15184 '\\' => self.write("\\\\"),
15185 '\n' => self.write("\\n"),
15186 '\r' => self.write("\\r"),
15187 '\t' => self.write("\\t"),
15188 '\0' => self.output.push('\0'),
15190 _ => self.output.push(c),
15191 }
15192 }
15193 self.write("'");
15194 }
15195 Some(DialectType::BigQuery) => {
15197 self.write("'");
15198 for c in s.chars() {
15199 match c {
15200 '\'' => self.write("\\'"),
15201 '\\' => self.write("\\\\"),
15202 '\n' => self.write("\\n"),
15203 '\r' => self.write("\\r"),
15204 '\t' => self.write("\\t"),
15205 '\0' => self.write("\\0"),
15206 '\x07' => self.write("\\a"),
15207 '\x08' => self.write("\\b"),
15208 '\x0C' => self.write("\\f"),
15209 '\x0B' => self.write("\\v"),
15210 _ => self.output.push(c),
15211 }
15212 }
15213 self.write("'");
15214 }
15215 Some(DialectType::Athena) => {
15219 if self.athena_hive_context {
15220 self.write("'");
15222 for c in s.chars() {
15223 match c {
15224 '\'' => self.write("\\'"),
15225 '\\' => self.write("\\\\"),
15226 '\n' => self.write("\\n"),
15227 '\r' => self.write("\\r"),
15228 '\t' => self.write("\\t"),
15229 '\0' => self.write("\\0"),
15230 _ => self.output.push(c),
15231 }
15232 }
15233 self.write("'");
15234 } else {
15235 self.write("'");
15237 for c in s.chars() {
15238 match c {
15239 '\'' => self.write("''"),
15240 _ => self.output.push(c),
15242 }
15243 }
15244 self.write("'");
15245 }
15246 }
15247 Some(DialectType::Snowflake) => {
15252 self.write("'");
15253 for c in s.chars() {
15254 match c {
15255 '\'' => self.write("\\'"),
15256 '\n' => self.write("\\n"),
15259 '\r' => self.write("\\r"),
15260 '\t' => self.write("\\t"),
15261 _ => self.output.push(c),
15262 }
15263 }
15264 self.write("'");
15265 }
15266 Some(DialectType::PostgreSQL) => {
15268 self.write("'");
15269 for c in s.chars() {
15270 match c {
15271 '\'' => self.write("''"),
15272 _ => self.output.push(c),
15273 }
15274 }
15275 self.write("'");
15276 }
15277 Some(DialectType::Redshift) => {
15279 self.write("'");
15280 for c in s.chars() {
15281 match c {
15282 '\'' => self.write("\\'"),
15283 _ => self.output.push(c),
15284 }
15285 }
15286 self.write("'");
15287 }
15288 Some(DialectType::Oracle) => {
15290 self.write("'");
15291 for ch in s.chars() {
15292 if ch == '\'' {
15293 self.output.push_str("''");
15294 } else {
15295 self.output.push(ch);
15296 }
15297 }
15298 self.write("'");
15299 }
15300 Some(DialectType::ClickHouse) => {
15303 self.write("'");
15304 for c in s.chars() {
15305 match c {
15306 '\'' => self.write("''"),
15307 '\\' => self.write("\\\\"),
15308 '\n' => self.write("\\n"),
15309 '\r' => self.write("\\r"),
15310 '\t' => self.write("\\t"),
15311 '\0' => self.write("\\0"),
15312 '\x07' => self.write("\\a"),
15313 '\x08' => self.write("\\b"),
15314 '\x0C' => self.write("\\f"),
15315 '\x0B' => self.write("\\v"),
15316 c if c.is_control() || (c as u32) < 0x20 => {
15318 let byte = c as u32;
15319 if byte < 256 {
15320 self.write(&format!("\\x{:02X}", byte));
15321 } else {
15322 self.output.push(c);
15323 }
15324 }
15325 _ => self.output.push(c),
15326 }
15327 }
15328 self.write("'");
15329 }
15330 _ => {
15333 self.write("'");
15334 for ch in s.chars() {
15335 if ch == '\'' {
15336 self.output.push_str("''");
15337 } else {
15338 self.output.push(ch);
15339 }
15340 }
15341 self.write("'");
15342 }
15343 }
15344 Ok(())
15345 }
15346
15347 fn write_escaped_byte_string(&mut self, s: &str) {
15350 for c in s.chars() {
15351 match c {
15352 '\'' => self.write("\\'"),
15354 '\\' => self.write("\\\\"),
15356 _ if !c.is_control() => self.output.push(c),
15358 _ => {
15360 let byte = c as u32;
15361 if byte < 256 {
15362 self.write(&format!("\\x{:02x}", byte));
15363 } else {
15364 for b in c.to_string().as_bytes() {
15366 self.write(&format!("\\x{:02x}", b));
15367 }
15368 }
15369 }
15370 }
15371 }
15372 }
15373
15374 fn generate_boolean(&mut self, b: &BooleanLiteral) -> Result<()> {
15375 use crate::dialects::DialectType;
15376
15377 match self.config.dialect {
15379 Some(DialectType::TSQL) => {
15382 self.write(if b.value { "1" } else { "0" });
15383 }
15384 Some(DialectType::Oracle) => {
15386 self.write(if b.value { "1" } else { "0" });
15387 }
15388 Some(DialectType::MySQL) => {
15390 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
15391 }
15392 _ => {
15394 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
15395 }
15396 }
15397 Ok(())
15398 }
15399
15400 fn generate_alias_identifier(&mut self, id: &Identifier) -> Result<()> {
15403 let name = &id.name;
15404 let quote_style = &self.config.identifier_quote_style;
15405
15406 let needs_quoting = id.quoted || self.is_reserved_keyword(name);
15410
15411 let output_name = if self.config.normalize_identifiers && !id.quoted {
15413 name.to_ascii_lowercase()
15414 } else {
15415 name.to_string()
15416 };
15417
15418 if needs_quoting {
15419 let quote_style = if matches!(self.config.dialect, Some(DialectType::ClickHouse))
15420 && matches!(self.config.source_dialect, Some(DialectType::ClickHouse))
15421 && quote_style.start == '"'
15422 && output_name.contains('"')
15423 {
15424 &IdentifierQuoteStyle::BACKTICK
15425 } else {
15426 quote_style
15427 };
15428 let escaped_name = if quote_style.start == quote_style.end {
15430 output_name.replace(
15431 quote_style.end,
15432 &format!("{}{}", quote_style.end, quote_style.end),
15433 )
15434 } else {
15435 output_name.replace(
15436 quote_style.end,
15437 &format!("{}{}", quote_style.end, quote_style.end),
15438 )
15439 };
15440 self.write(&format!(
15441 "{}{}{}",
15442 quote_style.start, escaped_name, quote_style.end
15443 ));
15444 } else {
15445 self.write(&output_name);
15446 }
15447
15448 for comment in &id.trailing_comments {
15450 self.write(" ");
15451 self.write_formatted_comment(comment);
15452 }
15453 Ok(())
15454 }
15455
15456 fn generate_identifier(&mut self, id: &Identifier) -> Result<()> {
15457 use crate::dialects::DialectType;
15458
15459 let name = &id.name;
15460
15461 let quote_style = if matches!(self.config.dialect, Some(DialectType::Athena))
15463 && self.athena_hive_context
15464 {
15465 &IdentifierQuoteStyle::BACKTICK
15466 } else {
15467 &self.config.identifier_quote_style
15468 };
15469
15470 let starts_with_digit = name.chars().next().map_or(false, |c| c.is_ascii_digit());
15477 let needs_digit_quoting = starts_with_digit
15478 && !self.config.identifiers_can_start_with_digit
15479 && self.config.dialect.is_some();
15480 let mysql_invalid_hex_identifier = matches!(self.config.dialect, Some(DialectType::MySQL))
15481 && name.len() > 2
15482 && (name.starts_with("0x") || name.starts_with("0X"))
15483 && !name[2..].chars().all(|c| c.is_ascii_hexdigit());
15484 let clickhouse_unsafe_identifier =
15485 matches!(self.config.dialect, Some(DialectType::ClickHouse))
15486 && matches!(self.config.source_dialect, Some(DialectType::ClickHouse))
15487 && !name.starts_with('{')
15488 && !name.contains('(')
15489 && !name.contains(')')
15490 && name != "?"
15491 && name
15492 .chars()
15493 .any(|c| !(c.is_ascii_alphanumeric() || c == '_'));
15494 let needs_quoting = id.quoted
15495 || self.is_reserved_keyword(name)
15496 || self.config.always_quote_identifiers
15497 || needs_digit_quoting
15498 || mysql_invalid_hex_identifier
15499 || clickhouse_unsafe_identifier;
15500
15501 let (base_name, suffix) = if needs_quoting {
15504 if let Some(paren_pos) = name.find('(') {
15506 let base = &name[..paren_pos];
15507 let rest = &name[paren_pos..];
15508 if rest.starts_with('(')
15510 && (rest.ends_with(')') || rest.ends_with(") ASC") || rest.ends_with(") DESC"))
15511 {
15512 let close_paren = rest.find(')').unwrap_or(rest.len());
15514 let inside = &rest[1..close_paren];
15515 if inside.chars().all(|c| c.is_ascii_digit()) {
15516 (base.to_string(), rest.to_string())
15517 } else {
15518 (name.to_string(), String::new())
15519 }
15520 } else {
15521 (name.to_string(), String::new())
15522 }
15523 } else if name.ends_with(" ASC") {
15524 let base = &name[..name.len() - 4];
15525 (base.to_string(), " ASC".to_string())
15526 } else if name.ends_with(" DESC") {
15527 let base = &name[..name.len() - 5];
15528 (base.to_string(), " DESC".to_string())
15529 } else {
15530 (name.to_string(), String::new())
15531 }
15532 } else {
15533 (name.to_string(), String::new())
15534 };
15535
15536 let output_name = if self.config.normalize_identifiers && !id.quoted {
15540 base_name.to_ascii_lowercase()
15541 } else if matches!(self.config.dialect, Some(DialectType::Exasol))
15542 && !id.quoted
15543 && self.is_reserved_keyword(name)
15544 {
15545 base_name.to_ascii_uppercase()
15548 } else {
15549 base_name
15550 };
15551
15552 if needs_quoting {
15553 let escaped_name = if quote_style.start == quote_style.end {
15555 output_name.replace(
15557 quote_style.end,
15558 &format!("{}{}", quote_style.end, quote_style.end),
15559 )
15560 } else {
15561 output_name.replace(
15563 quote_style.end,
15564 &format!("{}{}", quote_style.end, quote_style.end),
15565 )
15566 };
15567 self.write(&format!(
15568 "{}{}{}{}",
15569 quote_style.start, escaped_name, quote_style.end, suffix
15570 ));
15571 } else {
15572 self.write(&output_name);
15573 }
15574
15575 for comment in &id.trailing_comments {
15577 self.write(" ");
15578 self.write_formatted_comment(comment);
15579 }
15580 Ok(())
15581 }
15582
15583 fn generate_column(&mut self, col: &Column) -> Result<()> {
15584 use crate::dialects::DialectType;
15585
15586 if let Some(table) = &col.table {
15587 let is_exasol_local_prefix = matches!(self.config.dialect, Some(DialectType::Exasol))
15591 && !table.quoted
15592 && table.name.eq_ignore_ascii_case("LOCAL");
15593
15594 if is_exasol_local_prefix {
15595 self.write("LOCAL");
15597 } else {
15598 self.generate_identifier(table)?;
15599 }
15600 self.write(".");
15601 }
15602 self.generate_identifier(&col.name)?;
15603 if col.join_mark && self.config.supports_column_join_marks {
15606 self.write(" (+)");
15607 }
15608 for comment in &col.trailing_comments {
15610 self.write_space();
15611 self.write_formatted_comment(comment);
15612 }
15613 Ok(())
15614 }
15615
15616 fn generate_pseudocolumn(&mut self, pc: &Pseudocolumn) -> Result<()> {
15619 use crate::dialects::DialectType;
15620 use crate::expressions::PseudocolumnType;
15621
15622 if pc.kind == PseudocolumnType::Sysdate
15624 && !matches!(
15625 self.config.dialect,
15626 Some(DialectType::Oracle) | Some(DialectType::Redshift) | None
15627 )
15628 {
15629 self.write_keyword("CURRENT_TIMESTAMP");
15630 if matches!(
15632 self.config.dialect,
15633 Some(DialectType::MySQL)
15634 | Some(DialectType::ClickHouse)
15635 | Some(DialectType::Spark)
15636 | Some(DialectType::Databricks)
15637 | Some(DialectType::Hive)
15638 ) {
15639 self.write("()");
15640 }
15641 } else {
15642 self.write(pc.kind.as_str());
15643 }
15644 Ok(())
15645 }
15646
15647 fn generate_connect(&mut self, connect: &Connect) -> Result<()> {
15649 use crate::dialects::DialectType;
15650
15651 let supports_connect_by = matches!(
15654 self.config.dialect,
15655 Some(DialectType::Oracle) | Some(DialectType::Snowflake)
15656 );
15657
15658 if !supports_connect_by && self.config.dialect.is_some() {
15659 if self.config.pretty {
15661 self.write_newline();
15662 } else {
15663 self.write_space();
15664 }
15665 self.write_unsupported_comment(
15666 "CONNECT BY requires manual conversion to recursive CTE",
15667 )?;
15668 }
15669
15670 if let Some(start) = &connect.start {
15672 if self.config.pretty {
15673 self.write_newline();
15674 } else {
15675 self.write_space();
15676 }
15677 self.write_keyword("START WITH");
15678 self.write_space();
15679 self.generate_expression(start)?;
15680 }
15681
15682 if self.config.pretty {
15684 self.write_newline();
15685 } else {
15686 self.write_space();
15687 }
15688 self.write_keyword("CONNECT BY");
15689 if connect.nocycle {
15690 self.write_space();
15691 self.write_keyword("NOCYCLE");
15692 }
15693 self.write_space();
15694 self.generate_expression(&connect.connect)?;
15695
15696 Ok(())
15697 }
15698
15699 fn generate_connect_expr(&mut self, connect: &Connect) -> Result<()> {
15701 self.generate_connect(connect)
15702 }
15703
15704 fn generate_prior(&mut self, prior: &Prior) -> Result<()> {
15706 self.write_keyword("PRIOR");
15707 self.write_space();
15708 self.generate_expression(&prior.this)?;
15709 Ok(())
15710 }
15711
15712 fn generate_connect_by_root(&mut self, cbr: &ConnectByRoot) -> Result<()> {
15715 self.write_keyword("CONNECT_BY_ROOT");
15716 self.write_space();
15717 self.generate_expression(&cbr.this)?;
15718 Ok(())
15719 }
15720
15721 fn generate_match_recognize(&mut self, mr: &MatchRecognize) -> Result<()> {
15723 use crate::dialects::DialectType;
15724
15725 let supports_match_recognize = matches!(
15727 self.config.dialect,
15728 Some(DialectType::Oracle)
15729 | Some(DialectType::Snowflake)
15730 | Some(DialectType::Presto)
15731 | Some(DialectType::Trino)
15732 );
15733
15734 if let Some(source) = &mr.this {
15736 self.generate_expression(source)?;
15737 }
15738
15739 if !supports_match_recognize {
15740 self.write_unsupported_comment("MATCH_RECOGNIZE not supported in this dialect")?;
15741 return Ok(());
15742 }
15743
15744 if self.config.pretty {
15746 self.write_newline();
15747 } else {
15748 self.write_space();
15749 }
15750
15751 self.write_keyword("MATCH_RECOGNIZE");
15752 self.write(" (");
15753
15754 if self.config.pretty {
15755 self.indent_level += 1;
15756 }
15757
15758 let mut needs_separator = false;
15759
15760 if let Some(partition_by) = &mr.partition_by {
15762 if !partition_by.is_empty() {
15763 if self.config.pretty {
15764 self.write_newline();
15765 self.write_indent();
15766 }
15767 self.write_keyword("PARTITION BY");
15768 self.write_space();
15769 for (i, expr) in partition_by.iter().enumerate() {
15770 if i > 0 {
15771 self.write(", ");
15772 }
15773 self.generate_expression(expr)?;
15774 }
15775 needs_separator = true;
15776 }
15777 }
15778
15779 if let Some(order_by) = &mr.order_by {
15781 if !order_by.is_empty() {
15782 if needs_separator {
15783 if self.config.pretty {
15784 self.write_newline();
15785 self.write_indent();
15786 } else {
15787 self.write_space();
15788 }
15789 } else if self.config.pretty {
15790 self.write_newline();
15791 self.write_indent();
15792 }
15793 self.write_keyword("ORDER BY");
15794 if self.config.pretty {
15796 self.indent_level += 1;
15797 for (i, ordered) in order_by.iter().enumerate() {
15798 if i > 0 {
15799 self.write(",");
15800 }
15801 self.write_newline();
15802 self.write_indent();
15803 self.generate_ordered(ordered)?;
15804 }
15805 self.indent_level -= 1;
15806 } else {
15807 self.write_space();
15808 for (i, ordered) in order_by.iter().enumerate() {
15809 if i > 0 {
15810 self.write(", ");
15811 }
15812 self.generate_ordered(ordered)?;
15813 }
15814 }
15815 needs_separator = true;
15816 }
15817 }
15818
15819 if let Some(measures) = &mr.measures {
15821 if !measures.is_empty() {
15822 if needs_separator {
15823 if self.config.pretty {
15824 self.write_newline();
15825 self.write_indent();
15826 } else {
15827 self.write_space();
15828 }
15829 } else if self.config.pretty {
15830 self.write_newline();
15831 self.write_indent();
15832 }
15833 self.write_keyword("MEASURES");
15834 if self.config.pretty {
15836 self.indent_level += 1;
15837 for (i, measure) in measures.iter().enumerate() {
15838 if i > 0 {
15839 self.write(",");
15840 }
15841 self.write_newline();
15842 self.write_indent();
15843 if let Some(semantics) = &measure.window_frame {
15845 match semantics {
15846 MatchRecognizeSemantics::Running => {
15847 self.write_keyword("RUNNING");
15848 self.write_space();
15849 }
15850 MatchRecognizeSemantics::Final => {
15851 self.write_keyword("FINAL");
15852 self.write_space();
15853 }
15854 }
15855 }
15856 self.generate_expression(&measure.this)?;
15857 }
15858 self.indent_level -= 1;
15859 } else {
15860 self.write_space();
15861 for (i, measure) in measures.iter().enumerate() {
15862 if i > 0 {
15863 self.write(", ");
15864 }
15865 if let Some(semantics) = &measure.window_frame {
15867 match semantics {
15868 MatchRecognizeSemantics::Running => {
15869 self.write_keyword("RUNNING");
15870 self.write_space();
15871 }
15872 MatchRecognizeSemantics::Final => {
15873 self.write_keyword("FINAL");
15874 self.write_space();
15875 }
15876 }
15877 }
15878 self.generate_expression(&measure.this)?;
15879 }
15880 }
15881 needs_separator = true;
15882 }
15883 }
15884
15885 if let Some(rows) = &mr.rows {
15887 if needs_separator {
15888 if self.config.pretty {
15889 self.write_newline();
15890 self.write_indent();
15891 } else {
15892 self.write_space();
15893 }
15894 } else if self.config.pretty {
15895 self.write_newline();
15896 self.write_indent();
15897 }
15898 match rows {
15899 MatchRecognizeRows::OneRowPerMatch => {
15900 self.write_keyword("ONE ROW PER MATCH");
15901 }
15902 MatchRecognizeRows::AllRowsPerMatch => {
15903 self.write_keyword("ALL ROWS PER MATCH");
15904 }
15905 MatchRecognizeRows::AllRowsPerMatchShowEmptyMatches => {
15906 self.write_keyword("ALL ROWS PER MATCH SHOW EMPTY MATCHES");
15907 }
15908 MatchRecognizeRows::AllRowsPerMatchOmitEmptyMatches => {
15909 self.write_keyword("ALL ROWS PER MATCH OMIT EMPTY MATCHES");
15910 }
15911 MatchRecognizeRows::AllRowsPerMatchWithUnmatchedRows => {
15912 self.write_keyword("ALL ROWS PER MATCH WITH UNMATCHED ROWS");
15913 }
15914 }
15915 needs_separator = true;
15916 }
15917
15918 if let Some(after) = &mr.after {
15920 if needs_separator {
15921 if self.config.pretty {
15922 self.write_newline();
15923 self.write_indent();
15924 } else {
15925 self.write_space();
15926 }
15927 } else if self.config.pretty {
15928 self.write_newline();
15929 self.write_indent();
15930 }
15931 match after {
15932 MatchRecognizeAfter::PastLastRow => {
15933 self.write_keyword("AFTER MATCH SKIP PAST LAST ROW");
15934 }
15935 MatchRecognizeAfter::ToNextRow => {
15936 self.write_keyword("AFTER MATCH SKIP TO NEXT ROW");
15937 }
15938 MatchRecognizeAfter::ToFirst(ident) => {
15939 self.write_keyword("AFTER MATCH SKIP TO FIRST");
15940 self.write_space();
15941 self.generate_identifier(ident)?;
15942 }
15943 MatchRecognizeAfter::ToLast(ident) => {
15944 self.write_keyword("AFTER MATCH SKIP TO LAST");
15945 self.write_space();
15946 self.generate_identifier(ident)?;
15947 }
15948 }
15949 needs_separator = true;
15950 }
15951
15952 if let Some(pattern) = &mr.pattern {
15954 if needs_separator {
15955 if self.config.pretty {
15956 self.write_newline();
15957 self.write_indent();
15958 } else {
15959 self.write_space();
15960 }
15961 } else if self.config.pretty {
15962 self.write_newline();
15963 self.write_indent();
15964 }
15965 self.write_keyword("PATTERN");
15966 self.write_space();
15967 self.write("(");
15968 self.write(pattern);
15969 self.write(")");
15970 needs_separator = true;
15971 }
15972
15973 if let Some(define) = &mr.define {
15975 if !define.is_empty() {
15976 if needs_separator {
15977 if self.config.pretty {
15978 self.write_newline();
15979 self.write_indent();
15980 } else {
15981 self.write_space();
15982 }
15983 } else if self.config.pretty {
15984 self.write_newline();
15985 self.write_indent();
15986 }
15987 self.write_keyword("DEFINE");
15988 if self.config.pretty {
15990 self.indent_level += 1;
15991 for (i, (name, expr)) in define.iter().enumerate() {
15992 if i > 0 {
15993 self.write(",");
15994 }
15995 self.write_newline();
15996 self.write_indent();
15997 self.generate_identifier(name)?;
15998 self.write(" AS ");
15999 self.generate_expression(expr)?;
16000 }
16001 self.indent_level -= 1;
16002 } else {
16003 self.write_space();
16004 for (i, (name, expr)) in define.iter().enumerate() {
16005 if i > 0 {
16006 self.write(", ");
16007 }
16008 self.generate_identifier(name)?;
16009 self.write(" AS ");
16010 self.generate_expression(expr)?;
16011 }
16012 }
16013 }
16014 }
16015
16016 if self.config.pretty {
16017 self.indent_level -= 1;
16018 self.write_newline();
16019 }
16020 self.write(")");
16021
16022 if let Some(alias) = &mr.alias {
16024 self.write(" ");
16025 if mr.alias_explicit_as {
16026 self.write_keyword("AS");
16027 self.write(" ");
16028 }
16029 self.generate_identifier(alias)?;
16030 }
16031
16032 Ok(())
16033 }
16034
16035 fn generate_hint(&mut self, hint: &Hint) -> Result<()> {
16037 use crate::dialects::DialectType;
16038
16039 let supports_hints = matches!(
16041 self.config.dialect,
16042 None | Some(DialectType::Oracle) | Some(DialectType::MySQL) |
16044 Some(DialectType::Spark) | Some(DialectType::Hive) |
16045 Some(DialectType::Databricks) | Some(DialectType::PostgreSQL)
16046 );
16047
16048 if !supports_hints || hint.expressions.is_empty() {
16049 return Ok(());
16050 }
16051
16052 let mut hint_strings: Vec<String> = Vec::new();
16055 for expr in &hint.expressions {
16056 match expr {
16057 HintExpression::Raw(text) => {
16058 let parsed = self.parse_raw_hint_text(text);
16060 hint_strings.extend(parsed);
16061 }
16062 _ => {
16063 hint_strings.push(self.hint_expression_to_string(expr)?);
16064 }
16065 }
16066 }
16067
16068 let use_multiline = self.config.pretty && hint_strings.len() > 1;
16072
16073 if use_multiline {
16074 self.write(" /*+ ");
16076 for (i, hint_str) in hint_strings.iter().enumerate() {
16077 if i > 0 {
16078 self.write_newline();
16079 self.write(" "); }
16081 self.write(hint_str);
16082 }
16083 self.write(" */");
16084 } else {
16085 self.write(" /*+ ");
16087 let sep = match self.config.dialect {
16088 Some(DialectType::Spark) | Some(DialectType::Databricks) => ", ",
16089 _ => " ",
16090 };
16091 for (i, hint_str) in hint_strings.iter().enumerate() {
16092 if i > 0 {
16093 self.write(sep);
16094 }
16095 self.write(hint_str);
16096 }
16097 self.write(" */");
16098 }
16099
16100 Ok(())
16101 }
16102
16103 fn parse_raw_hint_text(&self, text: &str) -> Vec<String> {
16107 let mut results = Vec::new();
16108 let mut chars = text.chars().peekable();
16109 let mut current = String::new();
16110 let mut paren_depth = 0;
16111 let mut has_unparseable_content = false;
16112 let mut position_after_last_function = 0;
16113 let mut char_position = 0;
16114
16115 while let Some(c) = chars.next() {
16116 char_position += c.len_utf8();
16117 match c {
16118 '(' => {
16119 paren_depth += 1;
16120 current.push(c);
16121 }
16122 ')' => {
16123 paren_depth -= 1;
16124 current.push(c);
16125 if paren_depth == 0 {
16127 let trimmed = current.trim().to_string();
16128 if !trimmed.is_empty() {
16129 let formatted = self.format_hint_function(&trimmed);
16131 results.push(formatted);
16132 }
16133 current.clear();
16134 position_after_last_function = char_position;
16135 }
16136 }
16137 ' ' | '\t' | '\n' | ',' if paren_depth == 0 => {
16138 }
16140 _ if paren_depth == 0 => {
16141 current.push(c);
16143 }
16144 _ => {
16145 current.push(c);
16146 }
16147 }
16148 }
16149
16150 let remaining_text = text[position_after_last_function..].trim();
16152 if !remaining_text.is_empty() {
16153 let words: Vec<&str> = remaining_text.split_whitespace().collect();
16157 let looks_like_hint_functions = words.iter().all(|word| {
16158 word.contains('(') || (word.chars().all(|c| c.is_ascii_uppercase() || c == '_'))
16160 });
16161
16162 if !looks_like_hint_functions && words.len() > 1 {
16163 has_unparseable_content = true;
16164 }
16165 }
16166
16167 if has_unparseable_content {
16169 return vec![text.trim().to_string()];
16170 }
16171
16172 if results.is_empty() {
16174 results.push(text.trim().to_string());
16175 }
16176
16177 results
16178 }
16179
16180 fn format_hint_function(&self, hint: &str) -> String {
16183 if !self.config.pretty {
16184 return hint.to_string();
16185 }
16186
16187 if let Some(paren_pos) = hint.find('(') {
16189 if hint.ends_with(')') {
16190 let name = &hint[..paren_pos];
16191 let args_str = &hint[paren_pos + 1..hint.len() - 1];
16192
16193 let args: Vec<&str> = args_str.split_whitespace().collect();
16195
16196 let total_args_width: usize =
16198 args.iter().map(|s| s.len()).sum::<usize>() + args.len().saturating_sub(1); if total_args_width > self.config.max_text_width && !args.is_empty() {
16202 let mut result = format!("{}(\n", name);
16203 for arg in &args {
16204 result.push_str(" "); result.push_str(arg);
16206 result.push('\n');
16207 }
16208 result.push_str(" )"); return result;
16210 }
16211 }
16212 }
16213
16214 hint.to_string()
16215 }
16216
16217 fn hint_expression_to_string(&mut self, expr: &HintExpression) -> Result<String> {
16219 match expr {
16220 HintExpression::Function { name, args } => {
16221 let arg_strings: Vec<String> = args
16223 .iter()
16224 .map(|arg| {
16225 let mut gen = Generator::with_arc_config(self.config.clone());
16226 gen.generate_expression(arg)?;
16227 Ok(gen.output)
16228 })
16229 .collect::<Result<Vec<_>>>()?;
16230
16231 let total_args_width: usize = arg_strings.iter().map(|s| s.len()).sum::<usize>()
16233 + arg_strings.len().saturating_sub(1); let args_multiline =
16238 self.config.pretty && total_args_width > self.config.max_text_width;
16239
16240 if args_multiline && !arg_strings.is_empty() {
16241 let mut result = format!("{}(\n", name);
16243 for arg_str in &arg_strings {
16244 result.push_str(" "); result.push_str(arg_str);
16246 result.push('\n');
16247 }
16248 result.push_str(" )"); Ok(result)
16250 } else {
16251 let args_str = arg_strings.join(" ");
16253 Ok(format!("{}({})", name, args_str))
16254 }
16255 }
16256 HintExpression::Identifier(name) => Ok(name.clone()),
16257 HintExpression::Raw(text) => {
16258 if self.config.pretty {
16260 Ok(self.format_hint_function(text))
16261 } else {
16262 Ok(text.clone())
16263 }
16264 }
16265 }
16266 }
16267
16268 fn generate_table(&mut self, table: &TableRef) -> Result<()> {
16269 if table.only {
16271 self.write_keyword("ONLY");
16272 self.write_space();
16273 }
16274
16275 if let Some(ref identifier_func) = table.identifier_func {
16277 self.generate_expression(identifier_func)?;
16278 if !table.name.name.is_empty() {
16280 if let Some(catalog) = &table.catalog {
16281 self.write(".");
16282 self.generate_identifier(catalog)?;
16283 }
16284 if let Some(schema) = &table.schema {
16285 self.write(".");
16286 self.generate_identifier(schema)?;
16287 }
16288 self.write(".");
16289 self.generate_identifier(&table.name)?;
16290 }
16291 } else {
16292 if let Some(catalog) = &table.catalog {
16293 self.generate_identifier(catalog)?;
16294 self.write(".");
16295 }
16296 if let Some(schema) = &table.schema {
16297 self.generate_identifier(schema)?;
16298 self.write(".");
16299 }
16300 self.generate_identifier(&table.name)?;
16301 }
16302
16303 if let Some(changes) = &table.changes {
16305 self.write(" ");
16306 self.generate_changes(changes)?;
16307 }
16308
16309 if !table.partitions.is_empty() {
16311 self.write_space();
16312 self.write_keyword("PARTITION");
16313 self.write("(");
16314 for (i, partition) in table.partitions.iter().enumerate() {
16315 if i > 0 {
16316 self.write(", ");
16317 }
16318 self.generate_identifier(partition)?;
16319 }
16320 self.write(")");
16321 }
16322
16323 if table.changes.is_none() {
16326 if let Some(when) = &table.when {
16327 self.write_space();
16328 self.generate_historical_data(when)?;
16329 }
16330 }
16331
16332 let system_time_post_alias = matches!(self.config.dialect, Some(DialectType::BigQuery));
16334 if !system_time_post_alias {
16335 if let Some(ref system_time) = table.system_time {
16336 self.write_space();
16337 self.write(system_time);
16338 }
16339 }
16340
16341 if let Some(ref version) = table.version {
16343 self.write_space();
16344 self.generate_version(version)?;
16345 }
16346
16347 let alias_post_tablesample = self.config.alias_post_tablesample;
16351
16352 if alias_post_tablesample {
16353 self.generate_table_sample_clause(table)?;
16355 }
16356
16357 let is_sqlite_hint = matches!(self.config.dialect, Some(DialectType::SQLite))
16360 && table.hints.iter().any(|h| {
16361 if let Expression::Identifier(id) = h {
16362 id.name.starts_with("INDEXED BY") || id.name == "NOT INDEXED"
16363 } else {
16364 false
16365 }
16366 });
16367 if !table.hints.is_empty() && !is_sqlite_hint {
16368 for hint in &table.hints {
16369 self.write_space();
16370 self.generate_expression(hint)?;
16371 }
16372 }
16373
16374 if let Some(alias) = &table.alias {
16375 self.write_space();
16376 let always_use_as = self.config.dialect.is_none()
16379 || matches!(
16380 self.config.dialect,
16381 Some(DialectType::Generic)
16382 | Some(DialectType::PostgreSQL)
16383 | Some(DialectType::Redshift)
16384 | Some(DialectType::Snowflake)
16385 | Some(DialectType::BigQuery)
16386 | Some(DialectType::DuckDB)
16387 | Some(DialectType::Presto)
16388 | Some(DialectType::Trino)
16389 | Some(DialectType::TSQL)
16390 | Some(DialectType::Fabric)
16391 | Some(DialectType::MySQL)
16392 | Some(DialectType::Spark)
16393 | Some(DialectType::Hive)
16394 | Some(DialectType::SQLite)
16395 | Some(DialectType::Drill)
16396 );
16397 let is_stage_ref = table.name.name.starts_with('@');
16398 let suppress_as = matches!(self.config.dialect, Some(DialectType::Oracle));
16400 if !suppress_as && (table.alias_explicit_as || always_use_as || is_stage_ref) {
16401 self.write_keyword("AS");
16402 self.write_space();
16403 }
16404 self.generate_identifier(alias)?;
16405
16406 if !table.column_aliases.is_empty() && self.config.supports_table_alias_columns {
16409 self.write("(");
16410 for (i, col_alias) in table.column_aliases.iter().enumerate() {
16411 if i > 0 {
16412 self.write(", ");
16413 }
16414 self.generate_identifier(col_alias)?;
16415 }
16416 self.write(")");
16417 }
16418 }
16419
16420 if system_time_post_alias {
16422 if let Some(ref system_time) = table.system_time {
16423 self.write_space();
16424 self.write(system_time);
16425 }
16426 }
16427
16428 if !alias_post_tablesample {
16430 self.generate_table_sample_clause(table)?;
16431 }
16432
16433 if is_sqlite_hint {
16435 for hint in &table.hints {
16436 self.write_space();
16437 self.generate_expression(hint)?;
16438 }
16439 }
16440
16441 if table.final_ && matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
16443 self.write_space();
16444 self.write_keyword("FINAL");
16445 }
16446
16447 for comment in &table.trailing_comments {
16449 self.write_space();
16450 self.write_formatted_comment(comment);
16451 }
16452 Ok(())
16456 }
16457
16458 fn generate_table_sample_clause(&mut self, table: &TableRef) -> Result<()> {
16460 if let Some(ref ts) = table.table_sample {
16461 self.write_space();
16462 if ts.is_using_sample {
16463 self.write_keyword("USING SAMPLE");
16464 } else {
16465 self.write_keyword(self.config.tablesample_keywords);
16467 }
16468 self.generate_sample_body(ts)?;
16469 if let Some(ref seed) = ts.seed {
16471 self.write_space();
16472 self.write_keyword(self.config.tablesample_seed_keyword);
16473 self.write(" (");
16474 self.generate_expression(seed)?;
16475 self.write(")");
16476 }
16477 }
16478 Ok(())
16479 }
16480
16481 fn generate_stage_reference(&mut self, sr: &StageReference) -> Result<()> {
16482 if sr.quoted {
16486 self.write("'");
16487 }
16488
16489 self.write(&sr.name);
16490 if let Some(path) = &sr.path {
16491 self.write(path);
16492 }
16493
16494 if sr.quoted {
16495 self.write("'");
16496 }
16497
16498 let has_options = sr.file_format.is_some() || sr.pattern.is_some();
16500 if has_options {
16501 self.write(" (");
16502 let mut first = true;
16503
16504 if let Some(file_format) = &sr.file_format {
16505 if !first {
16506 self.write(", ");
16507 }
16508 self.write_keyword("FILE_FORMAT");
16509 self.write(" => ");
16510 self.generate_expression(file_format)?;
16511 first = false;
16512 }
16513
16514 if let Some(pattern) = &sr.pattern {
16515 if !first {
16516 self.write(", ");
16517 }
16518 self.write_keyword("PATTERN");
16519 self.write(" => '");
16520 self.write(pattern);
16521 self.write("'");
16522 }
16523
16524 self.write(")");
16525 }
16526 Ok(())
16527 }
16528
16529 fn generate_star(&mut self, star: &Star) -> Result<()> {
16530 use crate::dialects::DialectType;
16531
16532 if let Some(table) = &star.table {
16533 self.generate_identifier(table)?;
16534 self.write(".");
16535 }
16536 self.write("*");
16537
16538 if let Some(except) = &star.except {
16540 if !except.is_empty() {
16541 self.write_space();
16542 match self.config.dialect {
16544 Some(DialectType::BigQuery) => self.write_keyword("EXCEPT"),
16545 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => {
16546 self.write_keyword("EXCLUDE")
16547 }
16548 _ => self.write_keyword("EXCEPT"), }
16550 self.write(" (");
16551 for (i, col) in except.iter().enumerate() {
16552 if i > 0 {
16553 self.write(", ");
16554 }
16555 self.generate_identifier(col)?;
16556 }
16557 self.write(")");
16558 }
16559 }
16560
16561 if let Some(replace) = &star.replace {
16563 if !replace.is_empty() {
16564 self.write_space();
16565 self.write_keyword("REPLACE");
16566 self.write(" (");
16567 for (i, alias) in replace.iter().enumerate() {
16568 if i > 0 {
16569 self.write(", ");
16570 }
16571 self.generate_expression(&alias.this)?;
16572 self.write_space();
16573 self.write_keyword("AS");
16574 self.write_space();
16575 self.generate_identifier(&alias.alias)?;
16576 }
16577 self.write(")");
16578 }
16579 }
16580
16581 if let Some(rename) = &star.rename {
16583 if !rename.is_empty() {
16584 self.write_space();
16585 self.write_keyword("RENAME");
16586 self.write(" (");
16587 for (i, (old_name, new_name)) in rename.iter().enumerate() {
16588 if i > 0 {
16589 self.write(", ");
16590 }
16591 self.generate_identifier(old_name)?;
16592 self.write_space();
16593 self.write_keyword("AS");
16594 self.write_space();
16595 self.generate_identifier(new_name)?;
16596 }
16597 self.write(")");
16598 }
16599 }
16600
16601 for comment in &star.trailing_comments {
16603 self.write_space();
16604 self.write_formatted_comment(comment);
16605 }
16606
16607 Ok(())
16608 }
16609
16610 fn generate_braced_wildcard(&mut self, expr: &Expression) -> Result<()> {
16612 self.write("{");
16613 match expr {
16614 Expression::Star(star) => {
16615 self.generate_star(star)?;
16617 }
16618 Expression::ILike(ilike) => {
16619 self.generate_expression(&ilike.left)?;
16621 self.write_space();
16622 self.write_keyword("ILIKE");
16623 self.write_space();
16624 self.generate_expression(&ilike.right)?;
16625 }
16626 _ => {
16627 self.generate_expression(expr)?;
16628 }
16629 }
16630 self.write("}");
16631 Ok(())
16632 }
16633
16634 fn generate_alias(&mut self, alias: &Alias) -> Result<()> {
16635 match &alias.this {
16639 Expression::Column(col) => {
16640 if let Some(table) = &col.table {
16642 self.generate_identifier(table)?;
16643 self.write(".");
16644 }
16645 self.generate_identifier(&col.name)?;
16646 }
16647 _ => {
16648 self.generate_expression(&alias.this)?;
16649 }
16650 }
16651
16652 if !alias.pre_alias_comments.is_empty() && !alias.trailing_comments.is_empty() {
16656 for comment in &alias.pre_alias_comments {
16657 self.write_space();
16658 self.write_formatted_comment(comment);
16659 }
16660 }
16661
16662 use crate::dialects::DialectType;
16663
16664 let is_table_source = matches!(
16670 &alias.this,
16671 Expression::JSONTable(_)
16672 | Expression::XMLTable(_)
16673 | Expression::TableFromRows(_)
16674 | Expression::Unnest(_)
16675 | Expression::MatchRecognize(_)
16676 | Expression::Select(_)
16677 | Expression::Subquery(_)
16678 | Expression::Paren(_)
16679 );
16680 let dialect_skips_table_alias_as = matches!(self.config.dialect, Some(DialectType::Oracle));
16681 let skip_as = is_table_source && dialect_skips_table_alias_as;
16682
16683 self.write_space();
16684 if !skip_as {
16685 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
16686 if let Some(ref alias_keyword) = alias.alias_keyword {
16687 self.write(alias_keyword);
16688 } else {
16689 self.write_keyword("AS");
16690 }
16691 } else {
16692 self.write_keyword("AS");
16693 }
16694 self.write_space();
16695 }
16696
16697 let skip_column_aliases = matches!(self.config.dialect, Some(DialectType::BigQuery));
16699
16700 if alias.alias.is_empty() && !alias.column_aliases.is_empty() && !skip_column_aliases {
16702 self.write("(");
16704 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
16705 if i > 0 {
16706 self.write(", ");
16707 }
16708 self.generate_alias_identifier(col_alias)?;
16709 }
16710 self.write(")");
16711 } else if !alias.column_aliases.is_empty() && !skip_column_aliases {
16712 self.generate_alias_identifier(&alias.alias)?;
16714 self.write("(");
16715 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
16716 if i > 0 {
16717 self.write(", ");
16718 }
16719 self.generate_alias_identifier(col_alias)?;
16720 }
16721 self.write(")");
16722 } else {
16723 self.generate_alias_identifier(&alias.alias)?;
16725 }
16726
16727 for comment in &alias.trailing_comments {
16729 self.write_space();
16730 self.write_formatted_comment(comment);
16731 }
16732
16733 if alias.trailing_comments.is_empty() {
16738 for comment in &alias.pre_alias_comments {
16739 self.write_space();
16740 self.write_formatted_comment(comment);
16741 }
16742 }
16743
16744 Ok(())
16745 }
16746
16747 fn generate_cast(&mut self, cast: &Cast) -> Result<()> {
16748 use crate::dialects::DialectType;
16749
16750 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
16752 self.generate_expression(&cast.this)?;
16753 self.write(" :> ");
16754 self.generate_data_type(&cast.to)?;
16755 return Ok(());
16756 }
16757
16758 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
16760 let is_unknown_type = matches!(cast.to, DataType::Unknown)
16761 || matches!(cast.to, DataType::Custom { ref name } if name.is_empty());
16762 if is_unknown_type {
16763 if let Some(format) = &cast.format {
16764 self.write_keyword("CAST");
16765 self.write("(");
16766 self.generate_expression(&cast.this)?;
16767 self.write_space();
16768 self.write_keyword("AS");
16769 self.write_space();
16770 self.write_keyword("FORMAT");
16771 self.write_space();
16772 self.generate_expression(format)?;
16773 self.write(")");
16774 return Ok(());
16775 }
16776 }
16777 }
16778
16779 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
16782 if let Some(format) = &cast.format {
16783 let is_date = matches!(cast.to, DataType::Date);
16785 let is_timestamp = matches!(cast.to, DataType::Timestamp { .. });
16786
16787 if is_date || is_timestamp {
16788 let func_name = if is_date { "TO_DATE" } else { "TO_TIMESTAMP" };
16789 self.write_keyword(func_name);
16790 self.write("(");
16791 self.generate_expression(&cast.this)?;
16792 self.write(", ");
16793
16794 if let Expression::Literal(lit) = format.as_ref() {
16797 if let Literal::String(fmt_str) = lit.as_ref() {
16798 let normalized = self.normalize_oracle_format(fmt_str);
16799 self.write("'");
16800 self.write(&normalized);
16801 self.write("'");
16802 }
16803 } else {
16804 self.generate_expression(format)?;
16805 }
16806
16807 self.write(")");
16808 return Ok(());
16809 }
16810 }
16811 }
16812
16813 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
16816 if let Expression::Array(arr) = &cast.this {
16817 self.generate_data_type(&cast.to)?;
16818 self.write("[");
16820 for (i, expr) in arr.expressions.iter().enumerate() {
16821 if i > 0 {
16822 self.write(", ");
16823 }
16824 self.generate_expression(expr)?;
16825 }
16826 self.write("]");
16827 return Ok(());
16828 }
16829 if matches!(&cast.this, Expression::ArrayFunc(_)) {
16830 self.generate_data_type(&cast.to)?;
16831 self.generate_expression(&cast.this)?;
16832 return Ok(());
16833 }
16834 }
16835
16836 if matches!(
16839 self.config.dialect,
16840 Some(DialectType::DuckDB) | Some(DialectType::Presto) | Some(DialectType::Trino)
16841 ) {
16842 if let Expression::Struct(ref s) = cast.this {
16843 let all_unnamed = s.fields.iter().all(|(name, _)| name.is_none());
16844 if all_unnamed && matches!(cast.to, DataType::Struct { .. }) {
16845 self.write_keyword("CAST");
16846 self.write("(");
16847 self.generate_struct_as_row(s)?;
16848 self.write_space();
16849 self.write_keyword("AS");
16850 self.write_space();
16851 self.generate_data_type(&cast.to)?;
16852 self.write(")");
16853 return Ok(());
16854 }
16855 }
16856 }
16857
16858 let use_double_colon = cast.double_colon_syntax && self.dialect_prefers_double_colon();
16861
16862 if use_double_colon {
16863 self.generate_expression(&cast.this)?;
16865 self.write("::");
16866 self.generate_data_type(&cast.to)?;
16867 } else {
16868 self.write_keyword("CAST");
16870 self.write("(");
16871 self.generate_expression(&cast.this)?;
16872 self.write_space();
16873 self.write_keyword("AS");
16874 self.write_space();
16875 if matches!(
16878 self.config.dialect,
16879 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB)
16880 ) {
16881 match &cast.to {
16882 DataType::Custom { ref name } => {
16883 if name.eq_ignore_ascii_case("LONGTEXT")
16884 || name.eq_ignore_ascii_case("MEDIUMTEXT")
16885 || name.eq_ignore_ascii_case("TINYTEXT")
16886 || name.eq_ignore_ascii_case("LONGBLOB")
16887 || name.eq_ignore_ascii_case("MEDIUMBLOB")
16888 || name.eq_ignore_ascii_case("TINYBLOB")
16889 {
16890 self.write_keyword("CHAR");
16891 } else {
16892 self.generate_data_type(&cast.to)?;
16893 }
16894 }
16895 DataType::VarChar { length, .. } => {
16896 self.write_keyword("CHAR");
16898 if let Some(n) = length {
16899 self.write(&format!("({})", n));
16900 }
16901 }
16902 DataType::Text => {
16903 self.write_keyword("CHAR");
16905 }
16906 DataType::Timestamp {
16907 precision,
16908 timezone: false,
16909 } => {
16910 self.write_keyword("DATETIME");
16912 if let Some(p) = precision {
16913 self.write(&format!("({})", p));
16914 }
16915 }
16916 _ => {
16917 self.generate_data_type(&cast.to)?;
16918 }
16919 }
16920 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
16921 match &cast.to {
16923 DataType::String { length } => {
16924 self.write_keyword("VARCHAR");
16925 if let Some(n) = length {
16926 self.write(&format!("({})", n));
16927 }
16928 }
16929 _ => {
16930 self.generate_data_type(&cast.to)?;
16931 }
16932 }
16933 } else {
16934 self.generate_data_type(&cast.to)?;
16935 }
16936
16937 if let Some(default) = &cast.default {
16939 self.write_space();
16940 self.write_keyword("DEFAULT");
16941 self.write_space();
16942 self.generate_expression(default)?;
16943 self.write_space();
16944 self.write_keyword("ON");
16945 self.write_space();
16946 self.write_keyword("CONVERSION");
16947 self.write_space();
16948 self.write_keyword("ERROR");
16949 }
16950
16951 if let Some(format) = &cast.format {
16954 if matches!(
16956 self.config.dialect,
16957 Some(crate::dialects::DialectType::Oracle)
16958 ) {
16959 self.write(", ");
16960 } else {
16961 self.write_space();
16962 self.write_keyword("FORMAT");
16963 self.write_space();
16964 }
16965 self.generate_expression(format)?;
16966 }
16967
16968 self.write(")");
16969 for comment in &cast.trailing_comments {
16971 self.write_space();
16972 self.write_formatted_comment(comment);
16973 }
16974 }
16975 Ok(())
16976 }
16977
16978 fn generate_struct_as_row(&mut self, s: &crate::expressions::Struct) -> Result<()> {
16981 self.write_keyword("ROW");
16982 self.write("(");
16983 for (i, (_, expr)) in s.fields.iter().enumerate() {
16984 if i > 0 {
16985 self.write(", ");
16986 }
16987 if let Expression::Struct(ref inner_s) = expr {
16989 self.generate_struct_as_row(inner_s)?;
16990 } else {
16991 self.generate_expression(expr)?;
16992 }
16993 }
16994 self.write(")");
16995 Ok(())
16996 }
16997
16998 fn normalize_oracle_format(&self, format: &str) -> String {
17001 let mut result = String::new();
17004 let chars: Vec<char> = format.chars().collect();
17005 let mut i = 0;
17006
17007 while i < chars.len() {
17008 if i + 1 < chars.len() && chars[i] == 'H' && chars[i + 1] == 'H' {
17009 if i + 2 < chars.len() {
17011 let next = chars[i + 2];
17012 if next == '1' || next == '2' {
17013 result.push('H');
17015 result.push('H');
17016 i += 2;
17017 continue;
17018 }
17019 }
17020 result.push_str("HH12");
17022 i += 2;
17023 } else {
17024 result.push(chars[i]);
17025 i += 1;
17026 }
17027 }
17028
17029 result
17030 }
17031
17032 fn dialect_prefers_double_colon(&self) -> bool {
17035 matches!(self.config.dialect, Some(DialectType::ClickHouse))
17036 }
17037
17038 fn generate_mod_func(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
17040 use crate::dialects::DialectType;
17041
17042 let use_percent_operator = matches!(
17044 self.config.dialect,
17045 Some(DialectType::Snowflake)
17046 | Some(DialectType::MySQL)
17047 | Some(DialectType::Presto)
17048 | Some(DialectType::Trino)
17049 | Some(DialectType::PostgreSQL)
17050 | Some(DialectType::DuckDB)
17051 | Some(DialectType::Hive)
17052 | Some(DialectType::Spark)
17053 | Some(DialectType::Databricks)
17054 | Some(DialectType::Athena)
17055 );
17056
17057 if use_percent_operator {
17058 let needs_paren = |e: &Expression| matches!(e, Expression::Add(_) | Expression::Sub(_));
17061 if needs_paren(&f.this) {
17062 self.write("(");
17063 self.generate_expression(&f.this)?;
17064 self.write(")");
17065 } else {
17066 self.generate_expression(&f.this)?;
17067 }
17068 self.write(" % ");
17069 if needs_paren(&f.expression) {
17070 self.write("(");
17071 self.generate_expression(&f.expression)?;
17072 self.write(")");
17073 } else {
17074 self.generate_expression(&f.expression)?;
17075 }
17076 Ok(())
17077 } else {
17078 self.generate_binary_func("MOD", &f.this, &f.expression)
17079 }
17080 }
17081
17082 fn generate_ifnull(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
17084 use crate::dialects::DialectType;
17085
17086 let func_name = match self.config.dialect {
17088 Some(DialectType::Snowflake) => "COALESCE",
17089 _ => "IFNULL",
17090 };
17091
17092 self.generate_binary_func(func_name, &f.this, &f.expression)
17093 }
17094
17095 fn generate_nvl(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
17097 if let Some(ref original_name) = f.original_name {
17099 return self.generate_binary_func(original_name, &f.this, &f.expression);
17100 }
17101
17102 use crate::dialects::DialectType;
17104 let func_name = match self.config.dialect {
17105 Some(DialectType::Snowflake)
17106 | Some(DialectType::ClickHouse)
17107 | Some(DialectType::PostgreSQL)
17108 | Some(DialectType::Presto)
17109 | Some(DialectType::Trino)
17110 | Some(DialectType::Athena)
17111 | Some(DialectType::DuckDB)
17112 | Some(DialectType::BigQuery)
17113 | Some(DialectType::Spark)
17114 | Some(DialectType::Databricks)
17115 | Some(DialectType::Hive) => "COALESCE",
17116 Some(DialectType::MySQL)
17117 | Some(DialectType::Doris)
17118 | Some(DialectType::StarRocks)
17119 | Some(DialectType::SingleStore)
17120 | Some(DialectType::TiDB) => "IFNULL",
17121 _ => "NVL",
17122 };
17123
17124 self.generate_binary_func(func_name, &f.this, &f.expression)
17125 }
17126
17127 fn generate_stddev_samp(&mut self, f: &crate::expressions::AggFunc) -> Result<()> {
17129 use crate::dialects::DialectType;
17130
17131 let func_name = match self.config.dialect {
17133 Some(DialectType::Snowflake) => "STDDEV",
17134 _ => "STDDEV_SAMP",
17135 };
17136
17137 self.generate_agg_func(func_name, f)
17138 }
17139
17140 fn generate_collation(&mut self, coll: &CollationExpr) -> Result<()> {
17141 self.generate_expression(&coll.this)?;
17142 self.write_space();
17143 self.write_keyword("COLLATE");
17144 self.write_space();
17145 if coll.quoted {
17146 self.write("'");
17148 self.write(&coll.collation);
17149 self.write("'");
17150 } else if coll.double_quoted {
17151 self.write("\"");
17153 self.write(&coll.collation);
17154 self.write("\"");
17155 } else {
17156 self.write(&coll.collation);
17158 }
17159 Ok(())
17160 }
17161
17162 fn generate_case(&mut self, case: &Case) -> Result<()> {
17163 let multiline_case = if self.config.pretty {
17165 let mut statements: Vec<String> = Vec::new();
17167 let operand_str = if let Some(operand) = &case.operand {
17168 let s = self.generate_to_string(operand)?;
17169 statements.push(format!("CASE {}", s));
17170 s
17171 } else {
17172 statements.push("CASE".to_string());
17173 String::new()
17174 };
17175 let _ = operand_str;
17176 for (condition, result) in &case.whens {
17177 statements.push(format!("WHEN {}", self.generate_to_string(condition)?));
17178 statements.push(format!("THEN {}", self.generate_to_string(result)?));
17179 }
17180 if let Some(else_) = &case.else_ {
17181 statements.push(format!("ELSE {}", self.generate_to_string(else_)?));
17182 }
17183 statements.push("END".to_string());
17184 self.too_wide(&statements)
17185 } else {
17186 false
17187 };
17188
17189 self.write_keyword("CASE");
17190 if let Some(operand) = &case.operand {
17191 self.write_space();
17192 self.generate_expression(operand)?;
17193 }
17194 if multiline_case {
17195 self.indent_level += 1;
17196 }
17197 for (condition, result) in &case.whens {
17198 if multiline_case {
17199 self.write_newline();
17200 self.write_indent();
17201 } else {
17202 self.write_space();
17203 }
17204 self.write_keyword("WHEN");
17205 self.write_space();
17206 self.generate_expression(condition)?;
17207 if multiline_case {
17208 self.write_newline();
17209 self.write_indent();
17210 } else {
17211 self.write_space();
17212 }
17213 self.write_keyword("THEN");
17214 self.write_space();
17215 self.generate_expression(result)?;
17216 }
17217 if let Some(else_) = &case.else_ {
17218 if multiline_case {
17219 self.write_newline();
17220 self.write_indent();
17221 } else {
17222 self.write_space();
17223 }
17224 self.write_keyword("ELSE");
17225 self.write_space();
17226 self.generate_expression(else_)?;
17227 }
17228 if multiline_case {
17229 self.indent_level -= 1;
17230 self.write_newline();
17231 self.write_indent();
17232 } else {
17233 self.write_space();
17234 }
17235 self.write_keyword("END");
17236 for comment in &case.comments {
17238 self.write(" ");
17239 self.write_formatted_comment(comment);
17240 }
17241 Ok(())
17242 }
17243
17244 fn generate_function(&mut self, func: &Function) -> Result<()> {
17245 let normalized_name = self.normalize_func_name(&func.name);
17247
17248 if matches!(self.config.dialect, Some(DialectType::DuckDB))
17250 && func.name.eq_ignore_ascii_case("ARRAY_CONSTRUCT_COMPACT")
17251 {
17252 self.write("LIST_FILTER(");
17253 self.write("[");
17254 for (i, arg) in func.args.iter().enumerate() {
17255 if i > 0 {
17256 self.write(", ");
17257 }
17258 self.generate_expression(arg)?;
17259 }
17260 self.write("], _u -> NOT _u IS NULL)");
17261 return Ok(());
17262 }
17263
17264 if matches!(self.config.dialect, Some(DialectType::Snowflake))
17267 && func.name.eq_ignore_ascii_case("TO_VARIANT")
17268 && func.args.len() == 1
17269 {
17270 let array_expressions = match &func.args[0] {
17271 Expression::ArrayFunc(arr) => Some(&arr.expressions),
17272 Expression::Array(arr) => Some(&arr.expressions),
17273 _ => None,
17274 };
17275 if let Some(expressions) = array_expressions {
17276 self.write_keyword("TO_VARIANT");
17277 self.write("(");
17278 self.write_keyword("ARRAY_CONSTRUCT");
17279 self.write("(");
17280 for (i, arg) in expressions.iter().enumerate() {
17281 if i > 0 {
17282 self.write(", ");
17283 }
17284 self.generate_expression(arg)?;
17285 }
17286 self.write(")");
17287 self.write(")");
17288 return Ok(());
17289 }
17290 }
17291
17292 if func.name.eq_ignore_ascii_case("STRUCT")
17294 && !matches!(
17295 self.config.dialect,
17296 Some(DialectType::BigQuery)
17297 | Some(DialectType::Spark)
17298 | Some(DialectType::Databricks)
17299 | Some(DialectType::Hive)
17300 | None
17301 )
17302 {
17303 return self.generate_struct_function_cross_dialect(func);
17304 }
17305
17306 if func.name.eq_ignore_ascii_case("__SS_JSON_PATH_QMARK__") && func.args.len() == 2 {
17309 self.generate_expression(&func.args[0])?;
17310 self.write("::?");
17311 if let Expression::Literal(lit) = &func.args[1] {
17313 if let crate::expressions::Literal::String(key) = lit.as_ref() {
17314 self.write(key);
17315 }
17316 } else {
17317 self.generate_expression(&func.args[1])?;
17318 }
17319 return Ok(());
17320 }
17321
17322 if func.name.eq_ignore_ascii_case("__PG_BITWISE_XOR__") && func.args.len() == 2 {
17324 self.generate_expression(&func.args[0])?;
17325 self.write(" # ");
17326 self.generate_expression(&func.args[1])?;
17327 return Ok(());
17328 }
17329
17330 if matches!(
17332 self.config.dialect,
17333 Some(DialectType::Spark | DialectType::Databricks | DialectType::Hive)
17334 ) && func.name.eq_ignore_ascii_case("TRY")
17335 && func.args.len() == 1
17336 {
17337 self.generate_expression(&func.args[0])?;
17338 return Ok(());
17339 }
17340
17341 if self.config.dialect == Some(DialectType::ClickHouse)
17343 && func.name.eq_ignore_ascii_case("TOSTARTOFDAY")
17344 && func.args.len() == 1
17345 {
17346 self.write("dateTrunc('DAY', ");
17347 self.generate_expression(&func.args[0])?;
17348 self.write(")");
17349 return Ok(());
17350 }
17351
17352 if self.config.dialect == Some(DialectType::ClickHouse)
17354 && func.name.eq_ignore_ascii_case("DATE_TRUNC")
17355 && func.args.len() == 2
17356 {
17357 self.write("dateTrunc(");
17358 self.generate_expression(&func.args[0])?;
17359 self.write(", ");
17360 self.generate_expression(&func.args[1])?;
17361 self.write(")");
17362 return Ok(());
17363 }
17364
17365 if matches!(
17367 self.config.dialect,
17368 Some(DialectType::Presto | DialectType::Trino | DialectType::Athena)
17369 ) && func.name.eq_ignore_ascii_case("SUBSTRING")
17370 {
17371 self.write_keyword("SUBSTR");
17372 self.write("(");
17373 for (i, arg) in func.args.iter().enumerate() {
17374 if i > 0 {
17375 self.write(", ");
17376 }
17377 self.generate_expression(arg)?;
17378 }
17379 self.write(")");
17380 return Ok(());
17381 }
17382
17383 if self.config.dialect == Some(DialectType::Snowflake)
17384 && func.name.eq_ignore_ascii_case("LIST_DISTINCT")
17385 && func.args.len() == 1
17386 {
17387 self.write_keyword("ARRAY_DISTINCT");
17388 self.write("(");
17389 self.write_keyword("ARRAY_COMPACT");
17390 self.write("(");
17391 self.generate_expression(&func.args[0])?;
17392 self.write("))");
17393 return Ok(());
17394 }
17395
17396 if self.config.dialect == Some(DialectType::Snowflake)
17397 && func.name.eq_ignore_ascii_case("LIST")
17398 && func.args.len() == 1
17399 && !matches!(func.args.first(), Some(Expression::Select(_)))
17400 {
17401 self.write_keyword("ARRAY_AGG");
17402 self.write("(");
17403 self.generate_expression(&func.args[0])?;
17404 self.write(")");
17405 return Ok(());
17406 }
17407
17408 if self.config.dialect == Some(DialectType::Redshift)
17410 && func.name.eq_ignore_ascii_case("CONCAT")
17411 && func.args.len() >= 2
17412 {
17413 for (i, arg) in func.args.iter().enumerate() {
17414 if i > 0 {
17415 self.write(" || ");
17416 }
17417 self.generate_expression(arg)?;
17418 }
17419 return Ok(());
17420 }
17421
17422 if self.config.dialect == Some(DialectType::Redshift)
17424 && func.name.eq_ignore_ascii_case("CONCAT_WS")
17425 && func.args.len() >= 2
17426 {
17427 let sep = &func.args[0];
17428 for (i, arg) in func.args.iter().skip(1).enumerate() {
17429 if i > 0 {
17430 self.write(" || ");
17431 self.generate_expression(sep)?;
17432 self.write(" || ");
17433 }
17434 self.generate_expression(arg)?;
17435 }
17436 return Ok(());
17437 }
17438
17439 if self.config.dialect == Some(DialectType::Redshift)
17442 && (func.name.eq_ignore_ascii_case("DATEDIFF")
17443 || func.name.eq_ignore_ascii_case("DATE_DIFF"))
17444 && func.args.len() == 3
17445 {
17446 self.write_keyword("DATEDIFF");
17447 self.write("(");
17448 self.write_redshift_date_part(&func.args[0]);
17450 self.write(", ");
17451 self.generate_expression(&func.args[1])?;
17452 self.write(", ");
17453 self.generate_expression(&func.args[2])?;
17454 self.write(")");
17455 return Ok(());
17456 }
17457
17458 if self.config.dialect == Some(DialectType::Redshift)
17461 && (func.name.eq_ignore_ascii_case("DATEADD")
17462 || func.name.eq_ignore_ascii_case("DATE_ADD"))
17463 && func.args.len() == 3
17464 {
17465 self.write_keyword("DATEADD");
17466 self.write("(");
17467 self.write_redshift_date_part(&func.args[0]);
17469 self.write(", ");
17470 self.generate_expression(&func.args[1])?;
17471 self.write(", ");
17472 self.generate_expression(&func.args[2])?;
17473 self.write(")");
17474 return Ok(());
17475 }
17476
17477 if func.name.eq_ignore_ascii_case("UUID_STRING")
17479 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None)
17480 {
17481 if matches!(
17482 self.config.dialect,
17483 Some(DialectType::Hive | DialectType::Spark | DialectType::Databricks)
17484 ) {
17485 self.write_keyword("CAST");
17486 self.write("(");
17487 self.write_keyword("UUID");
17488 self.write("() ");
17489 self.write_keyword("AS");
17490 self.write(" ");
17491 self.write_keyword("STRING");
17492 self.write(")");
17493 return Ok(());
17494 }
17495
17496 if matches!(
17497 self.config.dialect,
17498 Some(DialectType::Presto | DialectType::Trino)
17499 ) {
17500 self.write_keyword("CAST");
17501 self.write("(");
17502 self.write_keyword("UUID");
17503 self.write("() ");
17504 self.write_keyword("AS");
17505 self.write(" ");
17506 self.write_keyword("VARCHAR");
17507 self.write(")");
17508 return Ok(());
17509 }
17510
17511 if self.config.dialect == Some(DialectType::DuckDB) && func.args.len() == 2 {
17512 self.write("(SELECT LOWER(SUBSTRING(h, 1, 8) || '-' || SUBSTRING(h, 9, 4) || '-' || '5' || SUBSTRING(h, 14, 3) || '-' || FORMAT('{:02x}', CAST('0x' || SUBSTRING(h, 17, 2) AS INT) & 63 | 128) || SUBSTRING(h, 19, 2) || '-' || SUBSTRING(h, 21, 12)) FROM (SELECT SUBSTRING(SHA1(UNHEX(REPLACE(");
17513 self.generate_expression(&func.args[0])?;
17514 self.write(", '-', '')) || ENCODE(");
17515 self.generate_expression(&func.args[1])?;
17516 self.write(")), 1, 32) AS h))");
17517 return Ok(());
17518 }
17519
17520 let func_name = match self.config.dialect {
17521 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
17522 Some(DialectType::BigQuery) => "GENERATE_UUID",
17523 _ => "UUID",
17524 };
17525 self.write_keyword(func_name);
17526 self.write("()");
17527 return Ok(());
17528 }
17529
17530 if matches!(self.config.dialect, Some(DialectType::Snowflake))
17534 && func.name.eq_ignore_ascii_case("GENERATOR")
17535 {
17536 let has_positional_args =
17537 !func.args.is_empty() && !matches!(&func.args[0], Expression::NamedArgument(_));
17538 if has_positional_args {
17539 let param_names = ["ROWCOUNT", "TIMELIMIT"];
17540 self.write_keyword("GENERATOR");
17541 self.write("(");
17542 for (i, arg) in func.args.iter().enumerate() {
17543 if i > 0 {
17544 self.write(", ");
17545 }
17546 if i < param_names.len() {
17547 self.write_keyword(param_names[i]);
17548 self.write(" => ");
17549 self.generate_expression(arg)?;
17550 } else {
17551 self.generate_expression(arg)?;
17552 }
17553 }
17554 self.write(")");
17555 return Ok(());
17556 }
17557 }
17558
17559 if self.config.dialect == Some(DialectType::Redshift)
17562 && func.name.eq_ignore_ascii_case("DATE_TRUNC")
17563 && func.args.len() == 2
17564 {
17565 self.write_keyword("DATE_TRUNC");
17566 self.write("(");
17567 self.write_redshift_date_part_quoted(&func.args[0]);
17569 self.write(", ");
17570 self.generate_expression(&func.args[1])?;
17571 self.write(")");
17572 return Ok(());
17573 }
17574
17575 if matches!(
17577 self.config.dialect,
17578 Some(DialectType::TSQL) | Some(DialectType::Fabric)
17579 ) && (func.name.eq_ignore_ascii_case("DATE_PART")
17580 || func.name.eq_ignore_ascii_case("DATEPART"))
17581 && func.args.len() == 2
17582 {
17583 self.write_keyword("DATEPART");
17584 self.write("(");
17585 self.generate_expression(&func.args[0])?;
17586 self.write(", ");
17587 self.generate_expression(&func.args[1])?;
17588 self.write(")");
17589 return Ok(());
17590 }
17591
17592 if matches!(
17594 self.config.dialect,
17595 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
17596 ) && (func.name.eq_ignore_ascii_case("DATE_PART")
17597 || func.name.eq_ignore_ascii_case("DATEPART"))
17598 && func.args.len() == 2
17599 {
17600 self.write_keyword("EXTRACT");
17601 self.write("(");
17602 match &func.args[0] {
17604 Expression::Literal(lit)
17605 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
17606 {
17607 let crate::expressions::Literal::String(s) = lit.as_ref() else {
17608 unreachable!()
17609 };
17610 self.write(&s.to_ascii_lowercase());
17611 }
17612 _ => self.generate_expression(&func.args[0])?,
17613 }
17614 self.write_space();
17615 self.write_keyword("FROM");
17616 self.write_space();
17617 self.generate_expression(&func.args[1])?;
17618 self.write(")");
17619 return Ok(());
17620 }
17621
17622 if self.config.dialect == Some(DialectType::PostgreSQL)
17624 && matches!(
17625 func.name.to_ascii_uppercase().as_str(),
17626 "DATE_ADD" | "DATE_SUB"
17627 )
17628 && func.args.len() == 2
17629 && matches!(func.args[1], Expression::Interval(_))
17630 {
17631 self.generate_expression(&func.args[0])?;
17632 self.write_space();
17633 if func.name.eq_ignore_ascii_case("DATE_SUB") {
17634 self.write("-");
17635 } else {
17636 self.write("+");
17637 }
17638 self.write_space();
17639 self.generate_expression(&func.args[1])?;
17640 return Ok(());
17641 }
17642
17643 if self.config.dialect == Some(DialectType::Dremio)
17646 && (func.name.eq_ignore_ascii_case("DATE_PART")
17647 || func.name.eq_ignore_ascii_case("DATEPART"))
17648 && func.args.len() == 2
17649 {
17650 self.write_keyword("EXTRACT");
17651 self.write("(");
17652 self.generate_expression(&func.args[0])?;
17653 self.write_space();
17654 self.write_keyword("FROM");
17655 self.write_space();
17656 self.generate_dremio_date_expression(&func.args[1])?;
17658 self.write(")");
17659 return Ok(());
17660 }
17661
17662 if self.config.dialect == Some(DialectType::Dremio)
17664 && func.name.eq_ignore_ascii_case("CURRENT_DATE_UTC")
17665 && func.args.is_empty()
17666 {
17667 self.write_keyword("CURRENT_DATE_UTC");
17668 return Ok(());
17669 }
17670
17671 if self.config.dialect == Some(DialectType::Dremio)
17675 && func.name.eq_ignore_ascii_case("DATETYPE")
17676 && func.args.len() == 3
17677 {
17678 fn get_int_literal(expr: &Expression) -> Option<i64> {
17680 if let Expression::Literal(lit) = expr {
17681 if let crate::expressions::Literal::Number(s) = lit.as_ref() {
17682 s.parse::<i64>().ok()
17683 } else {
17684 None
17685 }
17686 } else {
17687 None
17688 }
17689 }
17690
17691 if let (Some(year), Some(month), Some(day)) = (
17693 get_int_literal(&func.args[0]),
17694 get_int_literal(&func.args[1]),
17695 get_int_literal(&func.args[2]),
17696 ) {
17697 self.write_keyword("DATE");
17699 self.write(&format!("('{:04}-{:02}-{:02}')", year, month, day));
17700 return Ok(());
17701 }
17702
17703 self.write_keyword("CAST");
17705 self.write("(");
17706 self.write_keyword("CONCAT");
17707 self.write("(");
17708 self.generate_expression(&func.args[0])?;
17709 self.write(", '-', ");
17710 self.generate_expression(&func.args[1])?;
17711 self.write(", '-', ");
17712 self.generate_expression(&func.args[2])?;
17713 self.write(")");
17714 self.write_space();
17715 self.write_keyword("AS");
17716 self.write_space();
17717 self.write_keyword("DATE");
17718 self.write(")");
17719 return Ok(());
17720 }
17721
17722 let is_presto_like = matches!(
17725 self.config.dialect,
17726 Some(DialectType::Presto) | Some(DialectType::Trino)
17727 );
17728 if is_presto_like && func.name.eq_ignore_ascii_case("DATE_ADD") && func.args.len() == 3 {
17729 self.write_keyword("DATE_ADD");
17730 self.write("(");
17731 self.generate_expression(&func.args[0])?;
17733 self.write(", ");
17734 let interval = &func.args[1];
17736 let needs_cast = !self.returns_integer_type(interval);
17737 if needs_cast {
17738 self.write_keyword("CAST");
17739 self.write("(");
17740 }
17741 self.generate_expression(interval)?;
17742 if needs_cast {
17743 self.write_space();
17744 self.write_keyword("AS");
17745 self.write_space();
17746 self.write_keyword("BIGINT");
17747 self.write(")");
17748 }
17749 self.write(", ");
17750 self.generate_expression(&func.args[2])?;
17752 self.write(")");
17753 return Ok(());
17754 }
17755
17756 let use_brackets = func.use_bracket_syntax;
17758
17759 let has_ordinality = func.name.len() >= 16
17764 && func.name[func.name.len() - 16..].eq_ignore_ascii_case(" WITH ORDINALITY");
17765 let output_name = if has_ordinality {
17766 let base_name = &func.name[..func.name.len() - " WITH ORDINALITY".len()];
17767 self.normalize_func_name(base_name)
17768 } else {
17769 normalized_name.clone()
17770 };
17771
17772 let quote_source_clickhouse_function =
17775 matches!(self.config.dialect, Some(DialectType::ClickHouse))
17776 && matches!(self.config.source_dialect, Some(DialectType::ClickHouse))
17777 && func.quoted;
17778
17779 if quote_source_clickhouse_function {
17780 self.generate_identifier(&Identifier {
17781 name: func.name.clone(),
17782 quoted: true,
17783 trailing_comments: Vec::new(),
17784 span: None,
17785 })?;
17786 } else if func.name.contains('.') && !has_ordinality {
17787 if func.quoted {
17790 self.write("`");
17791 self.write(&func.name);
17792 self.write("`");
17793 } else {
17794 self.write(&func.name);
17795 }
17796 } else {
17797 self.write(&output_name);
17798 }
17799
17800 let force_parens = func.no_parens && func.args.is_empty() && !func.distinct && {
17803 let needs_parens = if func.name.eq_ignore_ascii_case("CURRENT_USER")
17804 || func.name.eq_ignore_ascii_case("SESSION_USER")
17805 || func.name.eq_ignore_ascii_case("SYSTEM_USER")
17806 {
17807 matches!(
17808 self.config.dialect,
17809 Some(DialectType::Snowflake)
17810 | Some(DialectType::Spark)
17811 | Some(DialectType::Databricks)
17812 | Some(DialectType::Hive)
17813 )
17814 } else {
17815 false
17816 };
17817 !needs_parens
17818 };
17819 if force_parens {
17820 for comment in &func.trailing_comments {
17822 self.write_space();
17823 self.write_formatted_comment(comment);
17824 }
17825 return Ok(());
17826 }
17827
17828 if func.name.eq_ignore_ascii_case("CUBE")
17830 || func.name.eq_ignore_ascii_case("ROLLUP")
17831 || func.name.eq_ignore_ascii_case("GROUPING SETS")
17832 {
17833 self.write(" (");
17834 } else if use_brackets {
17835 self.write("[");
17836 } else {
17837 self.write("(");
17838 }
17839 if func.distinct {
17840 self.write_keyword("DISTINCT");
17841 self.write_space();
17842 }
17843
17844 let compact_pretty_func = matches!(self.config.dialect, Some(DialectType::Snowflake))
17846 && (func.name.eq_ignore_ascii_case("TABLE")
17847 || func.name.eq_ignore_ascii_case("FLATTEN"));
17848 let is_grouping_func = func.name.eq_ignore_ascii_case("GROUPING SETS")
17850 || func.name.eq_ignore_ascii_case("CUBE")
17851 || func.name.eq_ignore_ascii_case("ROLLUP");
17852 let should_split = if self.config.pretty && !func.args.is_empty() && !compact_pretty_func {
17853 if is_grouping_func {
17854 true
17855 } else {
17856 let mut expr_strings: Vec<String> = Vec::with_capacity(func.args.len());
17858 for arg in &func.args {
17859 let mut temp_gen = Generator::with_arc_config(self.config.clone());
17860 Arc::make_mut(&mut temp_gen.config).pretty = false; temp_gen.generate_expression(arg)?;
17862 expr_strings.push(temp_gen.output);
17863 }
17864 self.too_wide(&expr_strings)
17865 }
17866 } else {
17867 false
17868 };
17869
17870 if should_split {
17871 self.write_newline();
17873 self.indent_level += 1;
17874 for (i, arg) in func.args.iter().enumerate() {
17875 self.write_indent();
17876 self.generate_expression(arg)?;
17877 if i + 1 < func.args.len() {
17878 self.write(",");
17879 }
17880 self.write_newline();
17881 }
17882 self.indent_level -= 1;
17883 self.write_indent();
17884 } else {
17885 for (i, arg) in func.args.iter().enumerate() {
17887 if i > 0 {
17888 self.write(", ");
17889 }
17890 self.generate_expression(arg)?;
17891 }
17892 }
17893
17894 if use_brackets {
17895 self.write("]");
17896 } else {
17897 self.write(")");
17898 }
17899 if has_ordinality {
17901 self.write_space();
17902 self.write_keyword("WITH ORDINALITY");
17903 }
17904 for comment in &func.trailing_comments {
17906 self.write_space();
17907 self.write_formatted_comment(comment);
17908 }
17909 Ok(())
17910 }
17911
17912 fn generate_function_emits(&mut self, fe: &FunctionEmits) -> Result<()> {
17913 self.generate_expression(&fe.this)?;
17914 self.write_keyword(" EMITS ");
17915 self.generate_expression(&fe.emits)?;
17916 Ok(())
17917 }
17918
17919 fn generate_aggregate_function(&mut self, func: &AggregateFunction) -> Result<()> {
17920 let mut normalized_name = self.normalize_func_name(&func.name);
17922
17923 if func.name.eq_ignore_ascii_case("MAX_BY") || func.name.eq_ignore_ascii_case("MIN_BY") {
17925 let is_max = func.name.eq_ignore_ascii_case("MAX_BY");
17926 match self.config.dialect {
17927 Some(DialectType::ClickHouse) => {
17928 normalized_name = if is_max {
17929 Cow::Borrowed("argMax")
17930 } else {
17931 Cow::Borrowed("argMin")
17932 };
17933 }
17934 Some(DialectType::DuckDB) => {
17935 normalized_name = if is_max {
17936 Cow::Borrowed("ARG_MAX")
17937 } else {
17938 Cow::Borrowed("ARG_MIN")
17939 };
17940 }
17941 _ => {}
17942 }
17943 }
17944 self.write(normalized_name.as_ref());
17945 self.write("(");
17946 if func.distinct {
17947 self.write_keyword("DISTINCT");
17948 self.write_space();
17949 }
17950
17951 let is_count = normalized_name.eq_ignore_ascii_case("COUNT");
17955 let needs_multi_arg_transform =
17956 func.distinct && is_count && func.args.len() > 1 && !self.config.multi_arg_distinct;
17957
17958 if needs_multi_arg_transform {
17959 self.write_keyword("CASE");
17961 for arg in &func.args {
17962 self.write_space();
17963 self.write_keyword("WHEN");
17964 self.write_space();
17965 self.generate_expression(arg)?;
17966 self.write_space();
17967 self.write_keyword("IS NULL THEN NULL");
17968 }
17969 self.write_space();
17970 self.write_keyword("ELSE");
17971 self.write(" (");
17972 for (i, arg) in func.args.iter().enumerate() {
17973 if i > 0 {
17974 self.write(", ");
17975 }
17976 self.generate_expression(arg)?;
17977 }
17978 self.write(")");
17979 self.write_space();
17980 self.write_keyword("END");
17981 } else {
17982 for (i, arg) in func.args.iter().enumerate() {
17983 if i > 0 {
17984 self.write(", ");
17985 }
17986 self.generate_expression(arg)?;
17987 }
17988 }
17989
17990 let clickhouse_ignore_nulls_outside =
17992 matches!(self.config.dialect, Some(DialectType::ClickHouse));
17993 if self.config.ignore_nulls_in_func
17994 && !matches!(
17995 self.config.dialect,
17996 Some(DialectType::DuckDB) | Some(DialectType::ClickHouse)
17997 )
17998 {
17999 if let Some(ignore) = func.ignore_nulls {
18000 self.write_space();
18001 if ignore {
18002 self.write_keyword("IGNORE NULLS");
18003 } else {
18004 self.write_keyword("RESPECT NULLS");
18005 }
18006 }
18007 }
18008
18009 if !func.order_by.is_empty() {
18011 self.write_space();
18012 self.write_keyword("ORDER BY");
18013 self.write_space();
18014 for (i, ord) in func.order_by.iter().enumerate() {
18015 if i > 0 {
18016 self.write(", ");
18017 }
18018 self.generate_ordered(ord)?;
18019 }
18020 }
18021
18022 if let Some(limit) = &func.limit {
18024 self.write_space();
18025 self.write_keyword("LIMIT");
18026 self.write_space();
18027 if let Expression::Tuple(t) = limit.as_ref() {
18029 if t.expressions.len() == 2 {
18030 self.generate_expression(&t.expressions[0])?;
18031 self.write(", ");
18032 self.generate_expression(&t.expressions[1])?;
18033 } else {
18034 self.generate_expression(limit)?;
18035 }
18036 } else {
18037 self.generate_expression(limit)?;
18038 }
18039 }
18040
18041 self.write(")");
18042
18043 if (!self.config.ignore_nulls_in_func || clickhouse_ignore_nulls_outside)
18045 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
18046 {
18047 if let Some(ignore) = func.ignore_nulls {
18048 self.write_space();
18049 if ignore {
18050 self.write_keyword("IGNORE NULLS");
18051 } else {
18052 self.write_keyword("RESPECT NULLS");
18053 }
18054 }
18055 }
18056
18057 if let Some(filter) = &func.filter {
18058 self.write_space();
18059 self.write_keyword("FILTER");
18060 self.write("(");
18061 self.write_keyword("WHERE");
18062 self.write_space();
18063 self.generate_expression(filter)?;
18064 self.write(")");
18065 }
18066
18067 Ok(())
18068 }
18069
18070 fn generate_window_function(&mut self, wf: &WindowFunction) -> Result<()> {
18071 self.generate_expression(&wf.this)?;
18072
18073 if let Some(keep) = &wf.keep {
18075 self.write_space();
18076 self.write_keyword("KEEP");
18077 self.write(" (");
18078 self.write_keyword("DENSE_RANK");
18079 self.write_space();
18080 if keep.first {
18081 self.write_keyword("FIRST");
18082 } else {
18083 self.write_keyword("LAST");
18084 }
18085 self.write_space();
18086 self.write_keyword("ORDER BY");
18087 self.write_space();
18088 for (i, ord) in keep.order_by.iter().enumerate() {
18089 if i > 0 {
18090 self.write(", ");
18091 }
18092 self.generate_ordered(ord)?;
18093 }
18094 self.write(")");
18095 }
18096
18097 let has_over = !wf.over.partition_by.is_empty()
18099 || !wf.over.order_by.is_empty()
18100 || wf.over.frame.is_some()
18101 || wf.over.window_name.is_some();
18102
18103 if has_over {
18105 self.write_space();
18106 self.write_keyword("OVER");
18107
18108 let has_specs = !wf.over.partition_by.is_empty()
18110 || !wf.over.order_by.is_empty()
18111 || wf.over.frame.is_some();
18112
18113 if wf.over.window_name.is_some() && !has_specs {
18114 self.write_space();
18116 self.write(&wf.over.window_name.as_ref().unwrap().name);
18117 } else {
18118 self.write(" (");
18120 self.generate_over(&wf.over)?;
18121 self.write(")");
18122 }
18123 } else if wf.keep.is_none() {
18124 self.write_space();
18126 self.write_keyword("OVER");
18127 self.write(" ()");
18128 }
18129
18130 Ok(())
18131 }
18132
18133 fn generate_within_group(&mut self, wg: &WithinGroup) -> Result<()> {
18135 self.generate_expression(&wg.this)?;
18136 self.write_space();
18137 self.write_keyword("WITHIN GROUP");
18138 self.write(" (");
18139 self.write_keyword("ORDER BY");
18140 self.write_space();
18141 for (i, ord) in wg.order_by.iter().enumerate() {
18142 if i > 0 {
18143 self.write(", ");
18144 }
18145 self.generate_ordered(ord)?;
18146 }
18147 self.write(")");
18148 Ok(())
18149 }
18150
18151 fn generate_over(&mut self, over: &Over) -> Result<()> {
18153 let mut has_content = false;
18154
18155 if let Some(name) = &over.window_name {
18157 self.write(&name.name);
18158 has_content = true;
18159 }
18160
18161 if !over.partition_by.is_empty() {
18163 if has_content {
18164 self.write_space();
18165 }
18166 self.write_keyword("PARTITION BY");
18167 self.write_space();
18168 for (i, expr) in over.partition_by.iter().enumerate() {
18169 if i > 0 {
18170 self.write(", ");
18171 }
18172 self.generate_expression(expr)?;
18173 }
18174 has_content = true;
18175 }
18176
18177 if !over.order_by.is_empty() {
18179 if has_content {
18180 self.write_space();
18181 }
18182 self.write_keyword("ORDER BY");
18183 self.write_space();
18184 for (i, ordered) in over.order_by.iter().enumerate() {
18185 if i > 0 {
18186 self.write(", ");
18187 }
18188 self.generate_ordered(ordered)?;
18189 }
18190 has_content = true;
18191 }
18192
18193 if let Some(frame) = &over.frame {
18195 if has_content {
18196 self.write_space();
18197 }
18198 self.generate_window_frame(frame)?;
18199 }
18200
18201 Ok(())
18202 }
18203
18204 fn generate_window_frame(&mut self, frame: &WindowFrame) -> Result<()> {
18205 let lowercase_frame = self.config.lowercase_window_frame_keywords;
18207
18208 if !lowercase_frame {
18210 if let Some(kind_text) = &frame.kind_text {
18211 self.write(kind_text);
18212 } else {
18213 match frame.kind {
18214 WindowFrameKind::Rows => self.write_keyword("ROWS"),
18215 WindowFrameKind::Range => self.write_keyword("RANGE"),
18216 WindowFrameKind::Groups => self.write_keyword("GROUPS"),
18217 }
18218 }
18219 } else {
18220 match frame.kind {
18221 WindowFrameKind::Rows => self.write("rows"),
18222 WindowFrameKind::Range => self.write("range"),
18223 WindowFrameKind::Groups => self.write("groups"),
18224 }
18225 }
18226
18227 self.write_space();
18230 let should_normalize = self.config.normalize_window_frame_between
18231 && frame.end.is_none()
18232 && matches!(
18233 frame.start,
18234 WindowFrameBound::Preceding(_)
18235 | WindowFrameBound::Following(_)
18236 | WindowFrameBound::UnboundedPreceding
18237 | WindowFrameBound::UnboundedFollowing
18238 );
18239
18240 if let Some(end) = &frame.end {
18241 self.write_keyword("BETWEEN");
18243 self.write_space();
18244 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
18245 self.write_space();
18246 self.write_keyword("AND");
18247 self.write_space();
18248 self.generate_window_frame_bound(end, frame.end_side_text.as_deref())?;
18249 } else if should_normalize {
18250 self.write_keyword("BETWEEN");
18252 self.write_space();
18253 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
18254 self.write_space();
18255 self.write_keyword("AND");
18256 self.write_space();
18257 self.write_keyword("CURRENT ROW");
18258 } else {
18259 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
18261 }
18262
18263 if let Some(exclude) = &frame.exclude {
18265 self.write_space();
18266 self.write_keyword("EXCLUDE");
18267 self.write_space();
18268 match exclude {
18269 WindowFrameExclude::CurrentRow => self.write_keyword("CURRENT ROW"),
18270 WindowFrameExclude::Group => self.write_keyword("GROUP"),
18271 WindowFrameExclude::Ties => self.write_keyword("TIES"),
18272 WindowFrameExclude::NoOthers => self.write_keyword("NO OTHERS"),
18273 }
18274 }
18275
18276 Ok(())
18277 }
18278
18279 fn generate_window_frame_bound(
18280 &mut self,
18281 bound: &WindowFrameBound,
18282 side_text: Option<&str>,
18283 ) -> Result<()> {
18284 let lowercase_frame = self.config.lowercase_window_frame_keywords;
18286
18287 match bound {
18288 WindowFrameBound::CurrentRow => {
18289 self.write_keyword("CURRENT ROW");
18290 }
18291 WindowFrameBound::UnboundedPreceding => {
18292 self.write_keyword("UNBOUNDED");
18293 self.write_space();
18294 if lowercase_frame {
18295 self.write("preceding");
18296 } else if let Some(text) = side_text {
18297 self.write(text);
18298 } else {
18299 self.write_keyword("PRECEDING");
18300 }
18301 }
18302 WindowFrameBound::UnboundedFollowing => {
18303 self.write_keyword("UNBOUNDED");
18304 self.write_space();
18305 if lowercase_frame {
18306 self.write("following");
18307 } else if let Some(text) = side_text {
18308 self.write(text);
18309 } else {
18310 self.write_keyword("FOLLOWING");
18311 }
18312 }
18313 WindowFrameBound::Preceding(expr) => {
18314 self.generate_expression(expr)?;
18315 self.write_space();
18316 if lowercase_frame {
18317 self.write("preceding");
18318 } else if let Some(text) = side_text {
18319 self.write(text);
18320 } else {
18321 self.write_keyword("PRECEDING");
18322 }
18323 }
18324 WindowFrameBound::Following(expr) => {
18325 self.generate_expression(expr)?;
18326 self.write_space();
18327 if lowercase_frame {
18328 self.write("following");
18329 } else if let Some(text) = side_text {
18330 self.write(text);
18331 } else {
18332 self.write_keyword("FOLLOWING");
18333 }
18334 }
18335 WindowFrameBound::BarePreceding => {
18336 if lowercase_frame {
18337 self.write("preceding");
18338 } else if let Some(text) = side_text {
18339 self.write(text);
18340 } else {
18341 self.write_keyword("PRECEDING");
18342 }
18343 }
18344 WindowFrameBound::BareFollowing => {
18345 if lowercase_frame {
18346 self.write("following");
18347 } else if let Some(text) = side_text {
18348 self.write(text);
18349 } else {
18350 self.write_keyword("FOLLOWING");
18351 }
18352 }
18353 WindowFrameBound::Value(expr) => {
18354 self.generate_expression(expr)?;
18356 }
18357 }
18358 Ok(())
18359 }
18360
18361 fn generate_interval(&mut self, interval: &Interval) -> Result<()> {
18362 let skip_interval_keyword = matches!(self.config.dialect, Some(DialectType::Oracle))
18365 && matches!(&interval.unit, Some(IntervalUnitSpec::ExprSpan(_)))
18366 && !matches!(&interval.this, Some(Expression::Literal(_)));
18367
18368 if self.config.single_string_interval {
18371 if let (
18372 Some(Expression::Literal(lit)),
18373 Some(IntervalUnitSpec::Simple {
18374 ref unit,
18375 ref use_plural,
18376 }),
18377 ) = (&interval.this, &interval.unit)
18378 {
18379 if let Literal::String(ref val) = lit.as_ref() {
18380 self.write_keyword("INTERVAL");
18381 self.write_space();
18382 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
18383 let unit_str = self.interval_unit_str(unit, effective_plural);
18384 self.write("'");
18385 self.write(val);
18386 self.write(" ");
18387 self.write(&unit_str);
18388 self.write("'");
18389 return Ok(());
18390 }
18391 }
18392 }
18393
18394 if !skip_interval_keyword {
18395 self.write_keyword("INTERVAL");
18396 }
18397
18398 if let Some(ref value) = interval.this {
18400 if !skip_interval_keyword {
18401 self.write_space();
18402 }
18403 let needs_parens = interval.unit.is_some()
18407 && matches!(
18408 value,
18409 Expression::Add(_)
18410 | Expression::Sub(_)
18411 | Expression::Mul(_)
18412 | Expression::Div(_)
18413 | Expression::Mod(_)
18414 | Expression::BitwiseAnd(_)
18415 | Expression::BitwiseOr(_)
18416 | Expression::BitwiseXor(_)
18417 );
18418 if needs_parens {
18419 self.write("(");
18420 }
18421 self.generate_expression(value)?;
18422 if needs_parens {
18423 self.write(")");
18424 }
18425 }
18426
18427 if let Some(ref unit_spec) = interval.unit {
18429 self.write_space();
18430 self.write_interval_unit_spec(unit_spec)?;
18431 }
18432
18433 Ok(())
18434 }
18435
18436 fn interval_unit_str(&self, unit: &IntervalUnit, use_plural: bool) -> &'static str {
18438 match (unit, use_plural) {
18439 (IntervalUnit::Year, false) => "YEAR",
18440 (IntervalUnit::Year, true) => "YEARS",
18441 (IntervalUnit::Quarter, false) => "QUARTER",
18442 (IntervalUnit::Quarter, true) => "QUARTERS",
18443 (IntervalUnit::Month, false) => "MONTH",
18444 (IntervalUnit::Month, true) => "MONTHS",
18445 (IntervalUnit::Week, false) => "WEEK",
18446 (IntervalUnit::Week, true) => "WEEKS",
18447 (IntervalUnit::Day, false) => "DAY",
18448 (IntervalUnit::Day, true) => "DAYS",
18449 (IntervalUnit::Hour, false) => "HOUR",
18450 (IntervalUnit::Hour, true) => "HOURS",
18451 (IntervalUnit::Minute, false) => "MINUTE",
18452 (IntervalUnit::Minute, true) => "MINUTES",
18453 (IntervalUnit::Second, false) => "SECOND",
18454 (IntervalUnit::Second, true) => "SECONDS",
18455 (IntervalUnit::Millisecond, false) => "MILLISECOND",
18456 (IntervalUnit::Millisecond, true) => "MILLISECONDS",
18457 (IntervalUnit::Microsecond, false) => "MICROSECOND",
18458 (IntervalUnit::Microsecond, true) => "MICROSECONDS",
18459 (IntervalUnit::Nanosecond, false) => "NANOSECOND",
18460 (IntervalUnit::Nanosecond, true) => "NANOSECONDS",
18461 }
18462 }
18463
18464 fn write_interval_unit_spec(&mut self, unit_spec: &IntervalUnitSpec) -> Result<()> {
18465 match unit_spec {
18466 IntervalUnitSpec::Simple { unit, use_plural } => {
18467 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
18469 self.write_simple_interval_unit(unit, effective_plural);
18470 }
18471 IntervalUnitSpec::Span(span) => {
18472 self.write_simple_interval_unit(&span.this, false);
18473 self.write_space();
18474 self.write_keyword("TO");
18475 self.write_space();
18476 self.write_simple_interval_unit(&span.expression, false);
18477 }
18478 IntervalUnitSpec::ExprSpan(span) => {
18479 self.generate_expression(&span.this)?;
18481 self.write_space();
18482 self.write_keyword("TO");
18483 self.write_space();
18484 self.generate_expression(&span.expression)?;
18485 }
18486 IntervalUnitSpec::Expr(expr) => {
18487 self.generate_expression(expr)?;
18488 }
18489 }
18490 Ok(())
18491 }
18492
18493 fn write_simple_interval_unit(&mut self, unit: &IntervalUnit, use_plural: bool) {
18494 match (unit, use_plural) {
18496 (IntervalUnit::Year, false) => self.write_keyword("YEAR"),
18497 (IntervalUnit::Year, true) => self.write_keyword("YEARS"),
18498 (IntervalUnit::Quarter, false) => self.write_keyword("QUARTER"),
18499 (IntervalUnit::Quarter, true) => self.write_keyword("QUARTERS"),
18500 (IntervalUnit::Month, false) => self.write_keyword("MONTH"),
18501 (IntervalUnit::Month, true) => self.write_keyword("MONTHS"),
18502 (IntervalUnit::Week, false) => self.write_keyword("WEEK"),
18503 (IntervalUnit::Week, true) => self.write_keyword("WEEKS"),
18504 (IntervalUnit::Day, false) => self.write_keyword("DAY"),
18505 (IntervalUnit::Day, true) => self.write_keyword("DAYS"),
18506 (IntervalUnit::Hour, false) => self.write_keyword("HOUR"),
18507 (IntervalUnit::Hour, true) => self.write_keyword("HOURS"),
18508 (IntervalUnit::Minute, false) => self.write_keyword("MINUTE"),
18509 (IntervalUnit::Minute, true) => self.write_keyword("MINUTES"),
18510 (IntervalUnit::Second, false) => self.write_keyword("SECOND"),
18511 (IntervalUnit::Second, true) => self.write_keyword("SECONDS"),
18512 (IntervalUnit::Millisecond, false) => self.write_keyword("MILLISECOND"),
18513 (IntervalUnit::Millisecond, true) => self.write_keyword("MILLISECONDS"),
18514 (IntervalUnit::Microsecond, false) => self.write_keyword("MICROSECOND"),
18515 (IntervalUnit::Microsecond, true) => self.write_keyword("MICROSECONDS"),
18516 (IntervalUnit::Nanosecond, false) => self.write_keyword("NANOSECOND"),
18517 (IntervalUnit::Nanosecond, true) => self.write_keyword("NANOSECONDS"),
18518 }
18519 }
18520
18521 fn write_redshift_date_part(&mut self, expr: &Expression) {
18524 let part_str = self.extract_date_part_string(expr);
18525 if let Some(part) = part_str {
18526 let normalized = self.normalize_date_part(&part);
18527 self.write_keyword(&normalized);
18528 } else {
18529 let _ = self.generate_expression(expr);
18531 }
18532 }
18533
18534 fn write_redshift_date_part_quoted(&mut self, expr: &Expression) {
18537 let part_str = self.extract_date_part_string(expr);
18538 if let Some(part) = part_str {
18539 let normalized = self.normalize_date_part(&part);
18540 self.write("'");
18541 self.write(&normalized);
18542 self.write("'");
18543 } else {
18544 let _ = self.generate_expression(expr);
18546 }
18547 }
18548
18549 fn extract_date_part_string(&self, expr: &Expression) -> Option<String> {
18551 match expr {
18552 Expression::Literal(lit)
18553 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
18554 {
18555 let crate::expressions::Literal::String(s) = lit.as_ref() else {
18556 unreachable!()
18557 };
18558 Some(s.clone())
18559 }
18560 Expression::Identifier(id) => Some(id.name.clone()),
18561 Expression::Var(v) => Some(v.this.clone()),
18562 Expression::Column(col) if col.table.is_none() => {
18563 Some(col.name.name.clone())
18565 }
18566 _ => None,
18567 }
18568 }
18569
18570 fn normalize_date_part(&self, part: &str) -> String {
18573 let mut buf = [0u8; 64];
18574 let lower: &str = if part.len() <= 64 {
18575 for (i, b) in part.bytes().enumerate() {
18576 buf[i] = b.to_ascii_lowercase();
18577 }
18578 std::str::from_utf8(&buf[..part.len()]).unwrap_or(part)
18579 } else {
18580 return part.to_ascii_uppercase();
18581 };
18582 match lower {
18583 "day" | "days" | "d" => "DAY".to_string(),
18584 "month" | "months" | "mon" | "mons" | "mm" => "MONTH".to_string(),
18585 "year" | "years" | "y" | "yy" | "yyyy" => "YEAR".to_string(),
18586 "week" | "weeks" | "w" | "wk" => "WEEK".to_string(),
18587 "hour" | "hours" | "h" | "hh" => "HOUR".to_string(),
18588 "minute" | "minutes" | "m" | "mi" | "n" => "MINUTE".to_string(),
18589 "second" | "seconds" | "s" | "ss" => "SECOND".to_string(),
18590 "millisecond" | "milliseconds" | "ms" => "MILLISECOND".to_string(),
18591 "microsecond" | "microseconds" | "us" => "MICROSECOND".to_string(),
18592 "quarter" | "quarters" | "q" | "qq" => "QUARTER".to_string(),
18593 _ => part.to_ascii_uppercase(),
18594 }
18595 }
18596
18597 fn write_datetime_field(&mut self, field: &DateTimeField) {
18598 match field {
18599 DateTimeField::Year => self.write_keyword("YEAR"),
18600 DateTimeField::Month => self.write_keyword("MONTH"),
18601 DateTimeField::Day => self.write_keyword("DAY"),
18602 DateTimeField::Hour => self.write_keyword("HOUR"),
18603 DateTimeField::Minute => self.write_keyword("MINUTE"),
18604 DateTimeField::Second => self.write_keyword("SECOND"),
18605 DateTimeField::Millisecond => self.write_keyword("MILLISECOND"),
18606 DateTimeField::Microsecond => self.write_keyword("MICROSECOND"),
18607 DateTimeField::DayOfWeek => {
18608 let name = match self.config.dialect {
18609 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFWEEK",
18610 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "WEEKDAY",
18611 _ => "DOW",
18612 };
18613 self.write_keyword(name);
18614 }
18615 DateTimeField::DayOfYear => {
18616 let name = match self.config.dialect {
18617 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFYEAR",
18618 _ => "DOY",
18619 };
18620 self.write_keyword(name);
18621 }
18622 DateTimeField::Week => self.write_keyword("WEEK"),
18623 DateTimeField::WeekWithModifier(modifier) => {
18624 self.write_keyword("WEEK");
18625 self.write("(");
18626 self.write(modifier);
18627 self.write(")");
18628 }
18629 DateTimeField::Quarter => self.write_keyword("QUARTER"),
18630 DateTimeField::Epoch => self.write_keyword("EPOCH"),
18631 DateTimeField::Timezone => self.write_keyword("TIMEZONE"),
18632 DateTimeField::TimezoneHour => self.write_keyword("TIMEZONE_HOUR"),
18633 DateTimeField::TimezoneMinute => self.write_keyword("TIMEZONE_MINUTE"),
18634 DateTimeField::Date => self.write_keyword("DATE"),
18635 DateTimeField::Time => self.write_keyword("TIME"),
18636 DateTimeField::Custom(name) => self.write(name),
18637 }
18638 }
18639
18640 fn write_datetime_field_lower(&mut self, field: &DateTimeField) {
18642 match field {
18643 DateTimeField::Year => self.write("year"),
18644 DateTimeField::Month => self.write("month"),
18645 DateTimeField::Day => self.write("day"),
18646 DateTimeField::Hour => self.write("hour"),
18647 DateTimeField::Minute => self.write("minute"),
18648 DateTimeField::Second => self.write("second"),
18649 DateTimeField::Millisecond => self.write("millisecond"),
18650 DateTimeField::Microsecond => self.write("microsecond"),
18651 DateTimeField::DayOfWeek => self.write("dow"),
18652 DateTimeField::DayOfYear => self.write("doy"),
18653 DateTimeField::Week => self.write("week"),
18654 DateTimeField::WeekWithModifier(modifier) => {
18655 self.write("week(");
18656 self.write(modifier);
18657 self.write(")");
18658 }
18659 DateTimeField::Quarter => self.write("quarter"),
18660 DateTimeField::Epoch => self.write("epoch"),
18661 DateTimeField::Timezone => self.write("timezone"),
18662 DateTimeField::TimezoneHour => self.write("timezone_hour"),
18663 DateTimeField::TimezoneMinute => self.write("timezone_minute"),
18664 DateTimeField::Date => self.write("date"),
18665 DateTimeField::Time => self.write("time"),
18666 DateTimeField::Custom(name) => self.write(name),
18667 }
18668 }
18669
18670 fn generate_simple_func(&mut self, name: &str, arg: &Expression) -> Result<()> {
18673 self.write_keyword(name);
18674 self.write("(");
18675 self.generate_expression(arg)?;
18676 self.write(")");
18677 Ok(())
18678 }
18679
18680 fn generate_unary_func(
18682 &mut self,
18683 default_name: &str,
18684 f: &crate::expressions::UnaryFunc,
18685 ) -> Result<()> {
18686 let name = f.original_name.as_deref().unwrap_or(default_name);
18687 self.write_keyword(name);
18688 self.write("(");
18689 self.generate_expression(&f.this)?;
18690 self.write(")");
18691 Ok(())
18692 }
18693
18694 fn generate_sqrt_cbrt(
18696 &mut self,
18697 f: &crate::expressions::UnaryFunc,
18698 func_name: &str,
18699 _op: &str,
18700 ) -> Result<()> {
18701 self.write_keyword(func_name);
18704 self.write("(");
18705 self.generate_expression(&f.this)?;
18706 self.write(")");
18707 Ok(())
18708 }
18709
18710 fn generate_binary_func(
18711 &mut self,
18712 name: &str,
18713 arg1: &Expression,
18714 arg2: &Expression,
18715 ) -> Result<()> {
18716 self.write_keyword(name);
18717 self.write("(");
18718 self.generate_expression(arg1)?;
18719 self.write(", ");
18720 self.generate_expression(arg2)?;
18721 self.write(")");
18722 Ok(())
18723 }
18724
18725 fn generate_char_func(&mut self, f: &crate::expressions::CharFunc) -> Result<()> {
18729 let func_name = f.name.as_deref().unwrap_or("CHAR");
18731 self.write_keyword(func_name);
18732 self.write("(");
18733 for (i, arg) in f.args.iter().enumerate() {
18734 if i > 0 {
18735 self.write(", ");
18736 }
18737 self.generate_expression(arg)?;
18738 }
18739 if let Some(ref charset) = f.charset {
18740 self.write(" ");
18741 self.write_keyword("USING");
18742 self.write(" ");
18743 self.write(charset);
18744 }
18745 self.write(")");
18746 Ok(())
18747 }
18748
18749 fn generate_power(&mut self, f: &BinaryFunc) -> Result<()> {
18750 use crate::dialects::DialectType;
18751
18752 match self.config.dialect {
18753 Some(DialectType::Teradata) => {
18754 self.generate_expression(&f.this)?;
18756 self.write(" ** ");
18757 self.generate_expression(&f.expression)?;
18758 Ok(())
18759 }
18760 _ => {
18761 self.generate_binary_func("POWER", &f.this, &f.expression)
18763 }
18764 }
18765 }
18766
18767 fn generate_vararg_func(&mut self, name: &str, args: &[Expression]) -> Result<()> {
18768 self.write_func_name(name);
18769 self.write("(");
18770 for (i, arg) in args.iter().enumerate() {
18771 if i > 0 {
18772 self.write(", ");
18773 }
18774 self.generate_expression(arg)?;
18775 }
18776 self.write(")");
18777 Ok(())
18778 }
18779
18780 fn generate_concat_ws(&mut self, f: &ConcatWs) -> Result<()> {
18783 self.write_keyword("CONCAT_WS");
18784 self.write("(");
18785 self.generate_expression(&f.separator)?;
18786 for expr in &f.expressions {
18787 self.write(", ");
18788 self.generate_expression(expr)?;
18789 }
18790 self.write(")");
18791 Ok(())
18792 }
18793
18794 fn collect_concat_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
18795 if let Expression::Concat(op) = expr {
18796 Self::collect_concat_operands(&op.left, out);
18797 Self::collect_concat_operands(&op.right, out);
18798 } else {
18799 out.push(expr);
18800 }
18801 }
18802
18803 fn generate_mysql_concat_from_concat(&mut self, op: &BinaryOp) -> Result<()> {
18804 let mut operands = Vec::new();
18805 Self::collect_concat_operands(&op.left, &mut operands);
18806 Self::collect_concat_operands(&op.right, &mut operands);
18807
18808 self.write_keyword("CONCAT");
18809 self.write("(");
18810 for (i, operand) in operands.iter().enumerate() {
18811 if i > 0 {
18812 self.write(", ");
18813 }
18814 self.generate_expression(operand)?;
18815 }
18816 self.write(")");
18817 Ok(())
18818 }
18819
18820 fn collect_dpipe_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
18821 if let Expression::DPipe(dpipe) = expr {
18822 Self::collect_dpipe_operands(&dpipe.this, out);
18823 Self::collect_dpipe_operands(&dpipe.expression, out);
18824 } else {
18825 out.push(expr);
18826 }
18827 }
18828
18829 fn generate_mysql_concat_from_dpipe(&mut self, e: &DPipe) -> Result<()> {
18830 let mut operands = Vec::new();
18831 Self::collect_dpipe_operands(&e.this, &mut operands);
18832 Self::collect_dpipe_operands(&e.expression, &mut operands);
18833
18834 self.write_keyword("CONCAT");
18835 self.write("(");
18836 for (i, operand) in operands.iter().enumerate() {
18837 if i > 0 {
18838 self.write(", ");
18839 }
18840 self.generate_expression(operand)?;
18841 }
18842 self.write(")");
18843 Ok(())
18844 }
18845
18846 fn generate_substring(&mut self, f: &SubstringFunc) -> Result<()> {
18847 let use_substr = matches!(
18849 self.config.dialect,
18850 Some(
18851 DialectType::Oracle
18852 | DialectType::Presto
18853 | DialectType::Trino
18854 | DialectType::Athena
18855 )
18856 );
18857 if use_substr {
18858 self.write_keyword("SUBSTR");
18859 } else {
18860 self.write_keyword("SUBSTRING");
18861 }
18862 self.write("(");
18863 self.generate_expression(&f.this)?;
18864 let force_from_for = matches!(self.config.dialect, Some(DialectType::PostgreSQL));
18866 let use_comma_syntax = matches!(
18868 self.config.dialect,
18869 Some(DialectType::Spark)
18870 | Some(DialectType::Hive)
18871 | Some(DialectType::Databricks)
18872 | Some(DialectType::TSQL)
18873 | Some(DialectType::Fabric)
18874 );
18875 if (f.from_for_syntax || force_from_for) && !use_comma_syntax {
18876 self.write_space();
18878 self.write_keyword("FROM");
18879 self.write_space();
18880 self.generate_expression(&f.start)?;
18881 if let Some(length) = &f.length {
18882 self.write_space();
18883 self.write_keyword("FOR");
18884 self.write_space();
18885 self.generate_expression(length)?;
18886 }
18887 } else {
18888 self.write(", ");
18890 self.generate_expression(&f.start)?;
18891 if let Some(length) = &f.length {
18892 self.write(", ");
18893 self.generate_expression(length)?;
18894 }
18895 }
18896 self.write(")");
18897 Ok(())
18898 }
18899
18900 fn generate_overlay(&mut self, f: &OverlayFunc) -> Result<()> {
18901 self.write_keyword("OVERLAY");
18902 self.write("(");
18903 self.generate_expression(&f.this)?;
18904 self.write_space();
18905 self.write_keyword("PLACING");
18906 self.write_space();
18907 self.generate_expression(&f.replacement)?;
18908 self.write_space();
18909 self.write_keyword("FROM");
18910 self.write_space();
18911 self.generate_expression(&f.from)?;
18912 if let Some(length) = &f.length {
18913 self.write_space();
18914 self.write_keyword("FOR");
18915 self.write_space();
18916 self.generate_expression(length)?;
18917 }
18918 self.write(")");
18919 Ok(())
18920 }
18921
18922 fn generate_trim(&mut self, f: &TrimFunc) -> Result<()> {
18923 if f.position_explicit && f.characters.is_none() {
18926 match f.position {
18927 TrimPosition::Leading => {
18928 self.write_keyword("LTRIM");
18929 self.write("(");
18930 self.generate_expression(&f.this)?;
18931 self.write(")");
18932 return Ok(());
18933 }
18934 TrimPosition::Trailing => {
18935 self.write_keyword("RTRIM");
18936 self.write("(");
18937 self.generate_expression(&f.this)?;
18938 self.write(")");
18939 return Ok(());
18940 }
18941 TrimPosition::Both => {
18942 }
18945 }
18946 }
18947
18948 self.write_keyword("TRIM");
18949 self.write("(");
18950 let force_standard = f.characters.is_some()
18953 && !f.sql_standard_syntax
18954 && matches!(
18955 self.config.dialect,
18956 Some(DialectType::Hive)
18957 | Some(DialectType::Spark)
18958 | Some(DialectType::Databricks)
18959 | Some(DialectType::ClickHouse)
18960 );
18961 let use_standard = (f.sql_standard_syntax || force_standard)
18962 && !(f.position_explicit
18963 && f.characters.is_none()
18964 && matches!(f.position, TrimPosition::Both));
18965 if use_standard {
18966 if f.position_explicit {
18969 match f.position {
18970 TrimPosition::Both => self.write_keyword("BOTH"),
18971 TrimPosition::Leading => self.write_keyword("LEADING"),
18972 TrimPosition::Trailing => self.write_keyword("TRAILING"),
18973 }
18974 self.write_space();
18975 }
18976 if let Some(chars) = &f.characters {
18977 self.generate_expression(chars)?;
18978 self.write_space();
18979 }
18980 self.write_keyword("FROM");
18981 self.write_space();
18982 self.generate_expression(&f.this)?;
18983 } else {
18984 self.generate_expression(&f.this)?;
18986 if let Some(chars) = &f.characters {
18987 self.write(", ");
18988 self.generate_expression(chars)?;
18989 }
18990 }
18991 self.write(")");
18992 Ok(())
18993 }
18994
18995 fn generate_replace(&mut self, f: &ReplaceFunc) -> Result<()> {
18996 self.write_keyword("REPLACE");
18997 self.write("(");
18998 self.generate_expression(&f.this)?;
18999 self.write(", ");
19000 self.generate_expression(&f.old)?;
19001 self.write(", ");
19002 self.generate_expression(&f.new)?;
19003 self.write(")");
19004 Ok(())
19005 }
19006
19007 fn generate_left_right(&mut self, name: &str, f: &LeftRightFunc) -> Result<()> {
19008 self.write_keyword(name);
19009 self.write("(");
19010 self.generate_expression(&f.this)?;
19011 self.write(", ");
19012 self.generate_expression(&f.length)?;
19013 self.write(")");
19014 Ok(())
19015 }
19016
19017 fn generate_repeat(&mut self, f: &RepeatFunc) -> Result<()> {
19018 self.write_keyword("REPEAT");
19019 self.write("(");
19020 self.generate_expression(&f.this)?;
19021 self.write(", ");
19022 self.generate_expression(&f.times)?;
19023 self.write(")");
19024 Ok(())
19025 }
19026
19027 fn generate_pad(&mut self, name: &str, f: &PadFunc) -> Result<()> {
19028 self.write_keyword(name);
19029 self.write("(");
19030 self.generate_expression(&f.this)?;
19031 self.write(", ");
19032 self.generate_expression(&f.length)?;
19033 if let Some(fill) = &f.fill {
19034 self.write(", ");
19035 self.generate_expression(fill)?;
19036 }
19037 self.write(")");
19038 Ok(())
19039 }
19040
19041 fn generate_split(&mut self, f: &SplitFunc) -> Result<()> {
19042 self.write_keyword("SPLIT");
19043 self.write("(");
19044 self.generate_expression(&f.this)?;
19045 self.write(", ");
19046 self.generate_expression(&f.delimiter)?;
19047 self.write(")");
19048 Ok(())
19049 }
19050
19051 fn generate_regexp_like(&mut self, f: &RegexpFunc) -> Result<()> {
19052 use crate::dialects::DialectType;
19053 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) && f.flags.is_none() {
19055 self.generate_expression(&f.this)?;
19056 self.write(" ~ ");
19057 self.generate_expression(&f.pattern)?;
19058 } else if matches!(self.config.dialect, Some(DialectType::Exasol)) && f.flags.is_none() {
19059 self.generate_expression(&f.this)?;
19061 self.write_keyword(" REGEXP_LIKE ");
19062 self.generate_expression(&f.pattern)?;
19063 } else if matches!(
19064 self.config.dialect,
19065 Some(DialectType::SingleStore)
19066 | Some(DialectType::Spark)
19067 | Some(DialectType::Hive)
19068 | Some(DialectType::Databricks)
19069 ) && f.flags.is_none()
19070 {
19071 self.generate_expression(&f.this)?;
19073 self.write_keyword(" RLIKE ");
19074 self.generate_expression(&f.pattern)?;
19075 } else if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
19076 self.write_keyword("REGEXP");
19078 self.write("(");
19079 self.generate_expression(&f.this)?;
19080 self.write(", ");
19081 self.generate_expression(&f.pattern)?;
19082 if let Some(flags) = &f.flags {
19083 self.write(", ");
19084 self.generate_expression(flags)?;
19085 }
19086 self.write(")");
19087 } else {
19088 self.write_keyword("REGEXP_LIKE");
19089 self.write("(");
19090 self.generate_expression(&f.this)?;
19091 self.write(", ");
19092 self.generate_expression(&f.pattern)?;
19093 if let Some(flags) = &f.flags {
19094 self.write(", ");
19095 self.generate_expression(flags)?;
19096 }
19097 self.write(")");
19098 }
19099 Ok(())
19100 }
19101
19102 fn generate_regexp_replace(&mut self, f: &RegexpReplaceFunc) -> Result<()> {
19103 self.write_keyword("REGEXP_REPLACE");
19104 self.write("(");
19105 self.generate_expression(&f.this)?;
19106 self.write(", ");
19107 self.generate_expression(&f.pattern)?;
19108 self.write(", ");
19109 self.generate_expression(&f.replacement)?;
19110 if let Some(flags) = &f.flags {
19111 self.write(", ");
19112 self.generate_expression(flags)?;
19113 }
19114 self.write(")");
19115 Ok(())
19116 }
19117
19118 fn generate_regexp_extract(&mut self, f: &RegexpExtractFunc) -> Result<()> {
19119 self.write_keyword("REGEXP_EXTRACT");
19120 self.write("(");
19121 self.generate_expression(&f.this)?;
19122 self.write(", ");
19123 self.generate_expression(&f.pattern)?;
19124 if let Some(group) = &f.group {
19125 self.write(", ");
19126 self.generate_expression(group)?;
19127 }
19128 self.write(")");
19129 Ok(())
19130 }
19131
19132 fn generate_round(&mut self, f: &RoundFunc) -> Result<()> {
19135 self.write_keyword("ROUND");
19136 self.write("(");
19137 self.generate_expression(&f.this)?;
19138 if let Some(decimals) = &f.decimals {
19139 self.write(", ");
19140 self.generate_expression(decimals)?;
19141 }
19142 self.write(")");
19143 Ok(())
19144 }
19145
19146 fn generate_floor(&mut self, f: &FloorFunc) -> Result<()> {
19147 self.write_keyword("FLOOR");
19148 self.write("(");
19149 self.generate_expression(&f.this)?;
19150 if let Some(to) = &f.to {
19152 self.write(" ");
19153 self.write_keyword("TO");
19154 self.write(" ");
19155 self.generate_expression(to)?;
19156 } else if let Some(scale) = &f.scale {
19157 self.write(", ");
19158 self.generate_expression(scale)?;
19159 }
19160 self.write(")");
19161 Ok(())
19162 }
19163
19164 fn generate_ceil(&mut self, f: &CeilFunc) -> Result<()> {
19165 self.write_keyword("CEIL");
19166 self.write("(");
19167 self.generate_expression(&f.this)?;
19168 if let Some(to) = &f.to {
19170 self.write(" ");
19171 self.write_keyword("TO");
19172 self.write(" ");
19173 self.generate_expression(to)?;
19174 } else if let Some(decimals) = &f.decimals {
19175 self.write(", ");
19176 self.generate_expression(decimals)?;
19177 }
19178 self.write(")");
19179 Ok(())
19180 }
19181
19182 fn generate_log(&mut self, f: &LogFunc) -> Result<()> {
19183 use crate::expressions::Literal;
19184
19185 if let Some(base) = &f.base {
19186 if self.is_log_base_none() {
19189 if matches!(base, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(s) if s == "2"))
19190 {
19191 self.write_func_name("LOG2");
19192 self.write("(");
19193 self.generate_expression(&f.this)?;
19194 self.write(")");
19195 return Ok(());
19196 } else if matches!(base, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(s) if s == "10"))
19197 {
19198 self.write_func_name("LOG10");
19199 self.write("(");
19200 self.generate_expression(&f.this)?;
19201 self.write(")");
19202 return Ok(());
19203 }
19204 }
19206
19207 self.write_func_name("LOG");
19208 self.write("(");
19209 if self.is_log_value_first() {
19210 self.generate_expression(&f.this)?;
19212 self.write(", ");
19213 self.generate_expression(base)?;
19214 } else {
19215 self.generate_expression(base)?;
19217 self.write(", ");
19218 self.generate_expression(&f.this)?;
19219 }
19220 self.write(")");
19221 } else {
19222 self.write_func_name("LOG");
19224 self.write("(");
19225 self.generate_expression(&f.this)?;
19226 self.write(")");
19227 }
19228 Ok(())
19229 }
19230
19231 fn is_log_value_first(&self) -> bool {
19234 use crate::dialects::DialectType;
19235 matches!(
19236 self.config.dialect,
19237 Some(DialectType::BigQuery)
19238 | Some(DialectType::TSQL)
19239 | Some(DialectType::Tableau)
19240 | Some(DialectType::Fabric)
19241 )
19242 }
19243
19244 fn is_log_base_none(&self) -> bool {
19247 use crate::dialects::DialectType;
19248 matches!(
19249 self.config.dialect,
19250 Some(DialectType::Presto)
19251 | Some(DialectType::Trino)
19252 | Some(DialectType::ClickHouse)
19253 | Some(DialectType::Athena)
19254 )
19255 }
19256
19257 fn generate_current_time(&mut self, f: &CurrentTime) -> Result<()> {
19260 self.write_keyword("CURRENT_TIME");
19261 if let Some(precision) = f.precision {
19262 self.write(&format!("({})", precision));
19263 } else if matches!(
19264 self.config.dialect,
19265 Some(crate::dialects::DialectType::MySQL)
19266 | Some(crate::dialects::DialectType::SingleStore)
19267 | Some(crate::dialects::DialectType::TiDB)
19268 ) {
19269 self.write("()");
19270 }
19271 Ok(())
19272 }
19273
19274 fn generate_current_timestamp(&mut self, f: &CurrentTimestamp) -> Result<()> {
19275 use crate::dialects::DialectType;
19276
19277 if f.sysdate {
19279 match self.config.dialect {
19280 Some(DialectType::Oracle) | Some(DialectType::Redshift) => {
19281 self.write_keyword("SYSDATE");
19282 return Ok(());
19283 }
19284 Some(DialectType::Snowflake) => {
19285 self.write_keyword("SYSDATE");
19287 self.write("()");
19288 return Ok(());
19289 }
19290 _ => {
19291 }
19293 }
19294 }
19295
19296 self.write_keyword("CURRENT_TIMESTAMP");
19297 if let Some(precision) = f.precision {
19299 self.write(&format!("({})", precision));
19300 } else if matches!(
19301 self.config.dialect,
19302 Some(crate::dialects::DialectType::MySQL)
19303 | Some(crate::dialects::DialectType::SingleStore)
19304 | Some(crate::dialects::DialectType::TiDB)
19305 | Some(crate::dialects::DialectType::Spark)
19306 | Some(crate::dialects::DialectType::Hive)
19307 | Some(crate::dialects::DialectType::Databricks)
19308 | Some(crate::dialects::DialectType::ClickHouse)
19309 | Some(crate::dialects::DialectType::BigQuery)
19310 | Some(crate::dialects::DialectType::Snowflake)
19311 | Some(crate::dialects::DialectType::Exasol)
19312 ) {
19313 self.write("()");
19314 }
19315 Ok(())
19316 }
19317
19318 fn generate_at_time_zone(&mut self, f: &AtTimeZone) -> Result<()> {
19319 if self.config.dialect == Some(DialectType::Exasol) {
19321 self.write_keyword("CONVERT_TZ");
19322 self.write("(");
19323 self.generate_expression(&f.this)?;
19324 self.write(", 'UTC', ");
19325 self.generate_expression(&f.zone)?;
19326 self.write(")");
19327 return Ok(());
19328 }
19329
19330 self.generate_expression(&f.this)?;
19331 self.write_space();
19332 self.write_keyword("AT TIME ZONE");
19333 self.write_space();
19334 self.generate_expression(&f.zone)?;
19335 Ok(())
19336 }
19337
19338 fn generate_date_add(&mut self, f: &DateAddFunc, name: &str) -> Result<()> {
19339 use crate::dialects::DialectType;
19340
19341 let is_presto_like = matches!(
19344 self.config.dialect,
19345 Some(DialectType::Presto) | Some(DialectType::Trino)
19346 );
19347
19348 if is_presto_like {
19349 self.write_keyword(name);
19350 self.write("(");
19351 self.write("'");
19353 self.write_simple_interval_unit(&f.unit, false);
19354 self.write("'");
19355 self.write(", ");
19356 let needs_cast = !self.returns_integer_type(&f.interval);
19358 if needs_cast {
19359 self.write_keyword("CAST");
19360 self.write("(");
19361 }
19362 self.generate_expression(&f.interval)?;
19363 if needs_cast {
19364 self.write_space();
19365 self.write_keyword("AS");
19366 self.write_space();
19367 self.write_keyword("BIGINT");
19368 self.write(")");
19369 }
19370 self.write(", ");
19371 self.generate_expression(&f.this)?;
19372 self.write(")");
19373 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
19374 self.generate_expression(&f.this)?;
19375 self.write_space();
19376 if name.eq_ignore_ascii_case("DATE_SUB") {
19377 self.write("-");
19378 } else {
19379 self.write("+");
19380 }
19381 self.write_space();
19382 self.write_keyword("INTERVAL");
19383 self.write_space();
19384 self.write("'");
19385 let mut interval_gen = Generator::with_arc_config(self.config.clone());
19386 let interval_sql = interval_gen.generate(&f.interval)?;
19387 self.write(&interval_sql);
19388 self.write(" ");
19389 self.write_simple_interval_unit(&f.unit, false);
19390 self.write("'");
19391 } else {
19392 self.write_keyword(name);
19393 self.write("(");
19394 self.generate_expression(&f.this)?;
19395 self.write(", ");
19396 self.write_keyword("INTERVAL");
19397 self.write_space();
19398 self.generate_expression(&f.interval)?;
19399 self.write_space();
19400 self.write_simple_interval_unit(&f.unit, false); self.write(")");
19402 }
19403 Ok(())
19404 }
19405
19406 fn returns_integer_type(&self, expr: &Expression) -> bool {
19409 use crate::expressions::{DataType, Literal};
19410 match expr {
19411 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
19413 let Literal::Number(n) = lit.as_ref() else {
19414 unreachable!()
19415 };
19416 !n.contains('.')
19417 }
19418
19419 Expression::Floor(f) => self.returns_integer_type(&f.this),
19421
19422 Expression::Round(f) => {
19424 f.decimals.is_none() && self.returns_integer_type(&f.this)
19426 }
19427
19428 Expression::Sign(f) => self.returns_integer_type(&f.this),
19430
19431 Expression::Abs(f) => self.returns_integer_type(&f.this),
19433
19434 Expression::Mul(op) => {
19436 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
19437 }
19438 Expression::Add(op) => {
19439 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
19440 }
19441 Expression::Sub(op) => {
19442 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
19443 }
19444 Expression::Mod(op) => self.returns_integer_type(&op.left),
19445
19446 Expression::Cast(c) => matches!(
19448 &c.to,
19449 DataType::BigInt { .. }
19450 | DataType::Int { .. }
19451 | DataType::SmallInt { .. }
19452 | DataType::TinyInt { .. }
19453 ),
19454
19455 Expression::Neg(op) => self.returns_integer_type(&op.this),
19457
19458 Expression::Paren(p) => self.returns_integer_type(&p.this),
19460
19461 _ => false,
19464 }
19465 }
19466
19467 fn generate_datediff(&mut self, f: &DateDiffFunc) -> Result<()> {
19468 self.write_keyword("DATEDIFF");
19469 self.write("(");
19470 if let Some(unit) = &f.unit {
19471 self.write_simple_interval_unit(unit, false); self.write(", ");
19473 }
19474 self.generate_expression(&f.this)?;
19475 self.write(", ");
19476 self.generate_expression(&f.expression)?;
19477 self.write(")");
19478 Ok(())
19479 }
19480
19481 fn generate_date_trunc(&mut self, f: &DateTruncFunc) -> Result<()> {
19482 if self.config.dialect == Some(DialectType::ClickHouse) {
19483 self.write("dateTrunc");
19484 } else {
19485 self.write_keyword("DATE_TRUNC");
19486 }
19487 self.write("('");
19488 self.write_datetime_field(&f.unit);
19489 self.write("', ");
19490 self.generate_expression(&f.this)?;
19491 self.write(")");
19492 Ok(())
19493 }
19494
19495 fn generate_last_day(&mut self, f: &LastDayFunc) -> Result<()> {
19496 use crate::dialects::DialectType;
19497 use crate::expressions::DateTimeField;
19498
19499 self.write_keyword("LAST_DAY");
19500 self.write("(");
19501 self.generate_expression(&f.this)?;
19502 if let Some(unit) = &f.unit {
19503 self.write(", ");
19504 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
19507 if let DateTimeField::WeekWithModifier(_) = unit {
19508 self.write_keyword("WEEK");
19509 } else {
19510 self.write_datetime_field(unit);
19511 }
19512 } else {
19513 self.write_datetime_field(unit);
19514 }
19515 }
19516 self.write(")");
19517 Ok(())
19518 }
19519
19520 fn generate_extract(&mut self, f: &ExtractFunc) -> Result<()> {
19521 if matches!(
19523 self.config.dialect,
19524 Some(DialectType::TSQL) | Some(DialectType::Fabric)
19525 ) {
19526 self.write_keyword("DATEPART");
19527 self.write("(");
19528 self.write_datetime_field(&f.field);
19529 self.write(", ");
19530 self.generate_expression(&f.this)?;
19531 self.write(")");
19532 return Ok(());
19533 }
19534 self.write_keyword("EXTRACT");
19535 self.write("(");
19536 if matches!(
19538 self.config.dialect,
19539 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
19540 ) {
19541 self.write_datetime_field_lower(&f.field);
19542 } else {
19543 self.write_datetime_field(&f.field);
19544 }
19545 self.write_space();
19546 self.write_keyword("FROM");
19547 self.write_space();
19548 self.generate_expression(&f.this)?;
19549 self.write(")");
19550 Ok(())
19551 }
19552
19553 fn generate_to_date(&mut self, f: &ToDateFunc) -> Result<()> {
19554 self.write_keyword("TO_DATE");
19555 self.write("(");
19556 self.generate_expression(&f.this)?;
19557 if let Some(format) = &f.format {
19558 self.write(", ");
19559 self.generate_expression(format)?;
19560 }
19561 self.write(")");
19562 Ok(())
19563 }
19564
19565 fn generate_to_timestamp(&mut self, f: &ToTimestampFunc) -> Result<()> {
19566 self.write_keyword("TO_TIMESTAMP");
19567 self.write("(");
19568 self.generate_expression(&f.this)?;
19569 if let Some(format) = &f.format {
19570 self.write(", ");
19571 self.generate_expression(format)?;
19572 }
19573 self.write(")");
19574 Ok(())
19575 }
19576
19577 fn generate_if_func(&mut self, f: &IfFunc) -> Result<()> {
19580 use crate::dialects::DialectType;
19581
19582 if self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic) {
19584 self.write_keyword("CASE WHEN");
19585 self.write_space();
19586 self.generate_expression(&f.condition)?;
19587 self.write_space();
19588 self.write_keyword("THEN");
19589 self.write_space();
19590 self.generate_expression(&f.true_value)?;
19591 if let Some(false_val) = &f.false_value {
19592 self.write_space();
19593 self.write_keyword("ELSE");
19594 self.write_space();
19595 self.generate_expression(false_val)?;
19596 }
19597 self.write_space();
19598 self.write_keyword("END");
19599 return Ok(());
19600 }
19601
19602 if self.config.dialect == Some(DialectType::Exasol) {
19604 self.write_keyword("IF");
19605 self.write_space();
19606 self.generate_expression(&f.condition)?;
19607 self.write_space();
19608 self.write_keyword("THEN");
19609 self.write_space();
19610 self.generate_expression(&f.true_value)?;
19611 if let Some(false_val) = &f.false_value {
19612 self.write_space();
19613 self.write_keyword("ELSE");
19614 self.write_space();
19615 self.generate_expression(false_val)?;
19616 }
19617 self.write_space();
19618 self.write_keyword("ENDIF");
19619 return Ok(());
19620 }
19621
19622 let func_name = match self.config.dialect {
19624 Some(DialectType::ClickHouse) => f.original_name.as_deref().unwrap_or("IF"),
19625 Some(DialectType::Snowflake) => "IFF",
19626 Some(DialectType::SQLite) | Some(DialectType::TSQL) => "IIF",
19627 Some(DialectType::Drill) => "`IF`",
19628 _ => "IF",
19629 };
19630 self.write(func_name);
19631 self.write("(");
19632 self.generate_expression(&f.condition)?;
19633 self.write(", ");
19634 self.generate_expression(&f.true_value)?;
19635 if let Some(false_val) = &f.false_value {
19636 self.write(", ");
19637 self.generate_expression(false_val)?;
19638 }
19639 self.write(")");
19640 Ok(())
19641 }
19642
19643 fn generate_nvl2(&mut self, f: &Nvl2Func) -> Result<()> {
19644 self.write_keyword("NVL2");
19645 self.write("(");
19646 self.generate_expression(&f.this)?;
19647 self.write(", ");
19648 self.generate_expression(&f.true_value)?;
19649 self.write(", ");
19650 self.generate_expression(&f.false_value)?;
19651 self.write(")");
19652 Ok(())
19653 }
19654
19655 fn generate_count(&mut self, f: &CountFunc) -> Result<()> {
19658 let count_name = match self.config.normalize_functions {
19660 NormalizeFunctions::Upper => "COUNT".to_string(),
19661 NormalizeFunctions::Lower => "count".to_string(),
19662 NormalizeFunctions::None => f
19663 .original_name
19664 .clone()
19665 .unwrap_or_else(|| "COUNT".to_string()),
19666 };
19667 self.write(&count_name);
19668 self.write("(");
19669 if f.distinct {
19670 self.write_keyword("DISTINCT");
19671 self.write_space();
19672 }
19673 if f.star {
19674 self.write("*");
19675 } else if let Some(ref expr) = f.this {
19676 if let Expression::Tuple(tuple) = expr {
19678 let needs_transform =
19682 f.distinct && tuple.expressions.len() > 1 && !self.config.multi_arg_distinct;
19683
19684 if needs_transform {
19685 self.write_keyword("CASE");
19687 for e in &tuple.expressions {
19688 self.write_space();
19689 self.write_keyword("WHEN");
19690 self.write_space();
19691 self.generate_expression(e)?;
19692 self.write_space();
19693 self.write_keyword("IS NULL THEN NULL");
19694 }
19695 self.write_space();
19696 self.write_keyword("ELSE");
19697 self.write(" (");
19698 for (i, e) in tuple.expressions.iter().enumerate() {
19699 if i > 0 {
19700 self.write(", ");
19701 }
19702 self.generate_expression(e)?;
19703 }
19704 self.write(")");
19705 self.write_space();
19706 self.write_keyword("END");
19707 } else {
19708 for (i, e) in tuple.expressions.iter().enumerate() {
19709 if i > 0 {
19710 self.write(", ");
19711 }
19712 self.generate_expression(e)?;
19713 }
19714 }
19715 } else {
19716 self.generate_expression(expr)?;
19717 }
19718 }
19719 let clickhouse_ignore_nulls_outside =
19720 matches!(self.config.dialect, Some(DialectType::ClickHouse));
19721 if let Some(ignore) = f.ignore_nulls.filter(|_| !clickhouse_ignore_nulls_outside) {
19722 self.write_space();
19723 if ignore {
19724 self.write_keyword("IGNORE NULLS");
19725 } else {
19726 self.write_keyword("RESPECT NULLS");
19727 }
19728 }
19729 self.write(")");
19730 if let Some(ignore) = f.ignore_nulls.filter(|_| clickhouse_ignore_nulls_outside) {
19731 self.write_space();
19732 if ignore {
19733 self.write_keyword("IGNORE NULLS");
19734 } else {
19735 self.write_keyword("RESPECT NULLS");
19736 }
19737 }
19738 if let Some(ref filter) = f.filter {
19739 self.write_space();
19740 self.write_keyword("FILTER");
19741 self.write("(");
19742 self.write_keyword("WHERE");
19743 self.write_space();
19744 self.generate_expression(filter)?;
19745 self.write(")");
19746 }
19747 Ok(())
19748 }
19749
19750 fn generate_agg_func(&mut self, name: &str, f: &AggFunc) -> Result<()> {
19751 let func_name: Cow<'_, str> = match self.config.normalize_functions {
19753 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
19754 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
19755 NormalizeFunctions::None => {
19756 if let Some(ref original) = f.name {
19759 Cow::Owned(original.clone())
19760 } else {
19761 Cow::Owned(name.to_ascii_lowercase())
19762 }
19763 }
19764 };
19765 self.write(func_name.as_ref());
19766 self.write("(");
19767 if f.distinct {
19768 self.write_keyword("DISTINCT");
19769 self.write_space();
19770 }
19771 let is_zero_arg_mode =
19774 name.eq_ignore_ascii_case("MODE") && matches!(f.this, Expression::Null(_));
19775 if !is_zero_arg_mode {
19776 self.generate_expression(&f.this)?;
19777 }
19778 if self.config.ignore_nulls_in_func
19781 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
19782 {
19783 match f.ignore_nulls {
19784 Some(true) => {
19785 self.write_space();
19786 self.write_keyword("IGNORE NULLS");
19787 }
19788 Some(false) => {
19789 self.write_space();
19790 self.write_keyword("RESPECT NULLS");
19791 }
19792 None => {}
19793 }
19794 }
19795 if let Some((ref expr, is_max)) = f.having_max {
19798 self.write_space();
19799 self.write_keyword("HAVING");
19800 self.write_space();
19801 if is_max {
19802 self.write_keyword("MAX");
19803 } else {
19804 self.write_keyword("MIN");
19805 }
19806 self.write_space();
19807 self.generate_expression(expr)?;
19808 }
19809 if !f.order_by.is_empty() {
19811 self.write_space();
19812 self.write_keyword("ORDER BY");
19813 self.write_space();
19814 for (i, ord) in f.order_by.iter().enumerate() {
19815 if i > 0 {
19816 self.write(", ");
19817 }
19818 self.generate_ordered(ord)?;
19819 }
19820 }
19821 if let Some(ref limit) = f.limit {
19823 self.write_space();
19824 self.write_keyword("LIMIT");
19825 self.write_space();
19826 if let Expression::Tuple(t) = limit.as_ref() {
19828 if t.expressions.len() == 2 {
19829 self.generate_expression(&t.expressions[0])?;
19830 self.write(", ");
19831 self.generate_expression(&t.expressions[1])?;
19832 } else {
19833 self.generate_expression(limit)?;
19834 }
19835 } else {
19836 self.generate_expression(limit)?;
19837 }
19838 }
19839 self.write(")");
19840 if !self.config.ignore_nulls_in_func
19843 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
19844 {
19845 match f.ignore_nulls {
19846 Some(true) => {
19847 self.write_space();
19848 self.write_keyword("IGNORE NULLS");
19849 }
19850 Some(false) => {
19851 self.write_space();
19852 self.write_keyword("RESPECT NULLS");
19853 }
19854 None => {}
19855 }
19856 }
19857 if let Some(ref filter) = f.filter {
19858 self.write_space();
19859 self.write_keyword("FILTER");
19860 self.write("(");
19861 self.write_keyword("WHERE");
19862 self.write_space();
19863 self.generate_expression(filter)?;
19864 self.write(")");
19865 }
19866 Ok(())
19867 }
19868
19869 fn generate_agg_func_with_ignore_nulls_bool(&mut self, name: &str, f: &AggFunc) -> Result<()> {
19872 if matches!(self.config.dialect, Some(DialectType::Hive)) && f.ignore_nulls == Some(true) {
19874 let func_name: Cow<'_, str> = match self.config.normalize_functions {
19876 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
19877 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
19878 NormalizeFunctions::None => {
19879 if let Some(ref original) = f.name {
19880 Cow::Owned(original.clone())
19881 } else {
19882 Cow::Owned(name.to_ascii_lowercase())
19883 }
19884 }
19885 };
19886 self.write(func_name.as_ref());
19887 self.write("(");
19888 if f.distinct {
19889 self.write_keyword("DISTINCT");
19890 self.write_space();
19891 }
19892 if !matches!(f.this, Expression::Null(_)) {
19893 self.generate_expression(&f.this)?;
19894 }
19895 self.write(", ");
19896 self.write_keyword("TRUE");
19897 self.write(")");
19898 return Ok(());
19899 }
19900 self.generate_agg_func(name, f)
19901 }
19902
19903 fn generate_group_concat(&mut self, f: &GroupConcatFunc) -> Result<()> {
19904 self.write_keyword("GROUP_CONCAT");
19905 self.write("(");
19906 if f.distinct {
19907 self.write_keyword("DISTINCT");
19908 self.write_space();
19909 }
19910 self.generate_expression(&f.this)?;
19911 if let Some(ref order_by) = f.order_by {
19912 self.write_space();
19913 self.write_keyword("ORDER BY");
19914 self.write_space();
19915 for (i, ord) in order_by.iter().enumerate() {
19916 if i > 0 {
19917 self.write(", ");
19918 }
19919 self.generate_ordered(ord)?;
19920 }
19921 }
19922 if let Some(ref sep) = f.separator {
19923 if matches!(
19926 self.config.dialect,
19927 Some(crate::dialects::DialectType::SQLite)
19928 ) {
19929 self.write(", ");
19930 self.generate_expression(sep)?;
19931 } else {
19932 self.write_space();
19933 self.write_keyword("SEPARATOR");
19934 self.write_space();
19935 self.generate_expression(sep)?;
19936 }
19937 }
19938 if let Some(ref limit) = f.limit {
19939 self.write_space();
19940 self.write_keyword("LIMIT");
19941 self.write_space();
19942 self.generate_expression(limit)?;
19943 }
19944 self.write(")");
19945 if let Some(ref filter) = f.filter {
19946 self.write_space();
19947 self.write_keyword("FILTER");
19948 self.write("(");
19949 self.write_keyword("WHERE");
19950 self.write_space();
19951 self.generate_expression(filter)?;
19952 self.write(")");
19953 }
19954 Ok(())
19955 }
19956
19957 fn generate_string_agg(&mut self, f: &StringAggFunc) -> Result<()> {
19958 let is_tsql = matches!(
19959 self.config.dialect,
19960 Some(crate::dialects::DialectType::TSQL)
19961 );
19962 self.write_keyword("STRING_AGG");
19963 self.write("(");
19964 if f.distinct {
19965 self.write_keyword("DISTINCT");
19966 self.write_space();
19967 }
19968 self.generate_expression(&f.this)?;
19969 if let Some(ref separator) = f.separator {
19970 self.write(", ");
19971 self.generate_expression(separator)?;
19972 }
19973 if !is_tsql {
19975 if let Some(ref order_by) = f.order_by {
19976 self.write_space();
19977 self.write_keyword("ORDER BY");
19978 self.write_space();
19979 for (i, ord) in order_by.iter().enumerate() {
19980 if i > 0 {
19981 self.write(", ");
19982 }
19983 self.generate_ordered(ord)?;
19984 }
19985 }
19986 }
19987 if let Some(ref limit) = f.limit {
19988 self.write_space();
19989 self.write_keyword("LIMIT");
19990 self.write_space();
19991 self.generate_expression(limit)?;
19992 }
19993 self.write(")");
19994 if is_tsql {
19996 if let Some(ref order_by) = f.order_by {
19997 self.write_space();
19998 self.write_keyword("WITHIN GROUP");
19999 self.write(" (");
20000 self.write_keyword("ORDER BY");
20001 self.write_space();
20002 for (i, ord) in order_by.iter().enumerate() {
20003 if i > 0 {
20004 self.write(", ");
20005 }
20006 self.generate_ordered(ord)?;
20007 }
20008 self.write(")");
20009 }
20010 }
20011 if let Some(ref filter) = f.filter {
20012 self.write_space();
20013 self.write_keyword("FILTER");
20014 self.write("(");
20015 self.write_keyword("WHERE");
20016 self.write_space();
20017 self.generate_expression(filter)?;
20018 self.write(")");
20019 }
20020 Ok(())
20021 }
20022
20023 fn generate_listagg(&mut self, f: &ListAggFunc) -> Result<()> {
20024 use crate::dialects::DialectType;
20025 self.write_keyword("LISTAGG");
20026 self.write("(");
20027 if f.distinct {
20028 self.write_keyword("DISTINCT");
20029 self.write_space();
20030 }
20031 self.generate_expression(&f.this)?;
20032 if let Some(ref sep) = f.separator {
20033 self.write(", ");
20034 self.generate_expression(sep)?;
20035 } else if matches!(
20036 self.config.dialect,
20037 Some(DialectType::Trino) | Some(DialectType::Presto)
20038 ) {
20039 self.write(", ','");
20041 }
20042 if let Some(ref overflow) = f.on_overflow {
20043 self.write_space();
20044 self.write_keyword("ON OVERFLOW");
20045 self.write_space();
20046 match overflow {
20047 ListAggOverflow::Error => self.write_keyword("ERROR"),
20048 ListAggOverflow::Truncate { filler, with_count } => {
20049 self.write_keyword("TRUNCATE");
20050 if let Some(ref fill) = filler {
20051 self.write_space();
20052 self.generate_expression(fill)?;
20053 }
20054 if *with_count {
20055 self.write_space();
20056 self.write_keyword("WITH COUNT");
20057 } else {
20058 self.write_space();
20059 self.write_keyword("WITHOUT COUNT");
20060 }
20061 }
20062 }
20063 }
20064 self.write(")");
20065 if let Some(ref order_by) = f.order_by {
20066 self.write_space();
20067 self.write_keyword("WITHIN GROUP");
20068 self.write(" (");
20069 self.write_keyword("ORDER BY");
20070 self.write_space();
20071 for (i, ord) in order_by.iter().enumerate() {
20072 if i > 0 {
20073 self.write(", ");
20074 }
20075 self.generate_ordered(ord)?;
20076 }
20077 self.write(")");
20078 }
20079 if let Some(ref filter) = f.filter {
20080 self.write_space();
20081 self.write_keyword("FILTER");
20082 self.write("(");
20083 self.write_keyword("WHERE");
20084 self.write_space();
20085 self.generate_expression(filter)?;
20086 self.write(")");
20087 }
20088 Ok(())
20089 }
20090
20091 fn generate_sum_if(&mut self, f: &SumIfFunc) -> Result<()> {
20092 self.write_keyword("SUM_IF");
20093 self.write("(");
20094 self.generate_expression(&f.this)?;
20095 self.write(", ");
20096 self.generate_expression(&f.condition)?;
20097 self.write(")");
20098 if let Some(ref filter) = f.filter {
20099 self.write_space();
20100 self.write_keyword("FILTER");
20101 self.write("(");
20102 self.write_keyword("WHERE");
20103 self.write_space();
20104 self.generate_expression(filter)?;
20105 self.write(")");
20106 }
20107 Ok(())
20108 }
20109
20110 fn generate_approx_percentile(&mut self, f: &ApproxPercentileFunc) -> Result<()> {
20111 self.write_keyword("APPROX_PERCENTILE");
20112 self.write("(");
20113 self.generate_expression(&f.this)?;
20114 self.write(", ");
20115 self.generate_expression(&f.percentile)?;
20116 if let Some(ref acc) = f.accuracy {
20117 self.write(", ");
20118 self.generate_expression(acc)?;
20119 }
20120 self.write(")");
20121 if let Some(ref filter) = f.filter {
20122 self.write_space();
20123 self.write_keyword("FILTER");
20124 self.write("(");
20125 self.write_keyword("WHERE");
20126 self.write_space();
20127 self.generate_expression(filter)?;
20128 self.write(")");
20129 }
20130 Ok(())
20131 }
20132
20133 fn generate_percentile(&mut self, name: &str, f: &PercentileFunc) -> Result<()> {
20134 self.write_keyword(name);
20135 self.write("(");
20136 self.generate_expression(&f.percentile)?;
20137 self.write(")");
20138 if let Some(ref order_by) = f.order_by {
20139 self.write_space();
20140 self.write_keyword("WITHIN GROUP");
20141 self.write(" (");
20142 self.write_keyword("ORDER BY");
20143 self.write_space();
20144 self.generate_expression(&f.this)?;
20145 for ord in order_by.iter() {
20146 if ord.desc {
20147 self.write_space();
20148 self.write_keyword("DESC");
20149 }
20150 }
20151 self.write(")");
20152 }
20153 if let Some(ref filter) = f.filter {
20154 self.write_space();
20155 self.write_keyword("FILTER");
20156 self.write("(");
20157 self.write_keyword("WHERE");
20158 self.write_space();
20159 self.generate_expression(filter)?;
20160 self.write(")");
20161 }
20162 Ok(())
20163 }
20164
20165 fn generate_ntile(&mut self, f: &NTileFunc) -> Result<()> {
20168 self.write_keyword("NTILE");
20169 self.write("(");
20170 if let Some(num_buckets) = &f.num_buckets {
20171 self.generate_expression(num_buckets)?;
20172 }
20173 if let Some(order_by) = &f.order_by {
20174 self.write_keyword(" ORDER BY ");
20175 for (i, ob) in order_by.iter().enumerate() {
20176 if i > 0 {
20177 self.write(", ");
20178 }
20179 self.generate_ordered(ob)?;
20180 }
20181 }
20182 self.write(")");
20183 Ok(())
20184 }
20185
20186 fn generate_lead_lag(&mut self, name: &str, f: &LeadLagFunc) -> Result<()> {
20187 self.write_keyword(name);
20188 self.write("(");
20189 self.generate_expression(&f.this)?;
20190 if let Some(ref offset) = f.offset {
20191 self.write(", ");
20192 self.generate_expression(offset)?;
20193 if let Some(ref default) = f.default {
20194 self.write(", ");
20195 self.generate_expression(default)?;
20196 }
20197 }
20198 if self.config.ignore_nulls_in_func {
20200 match f.ignore_nulls {
20201 Some(true) => {
20202 self.write_space();
20203 self.write_keyword("IGNORE NULLS");
20204 }
20205 Some(false) => {
20206 self.write_space();
20207 self.write_keyword("RESPECT NULLS");
20208 }
20209 None => {}
20210 }
20211 }
20212 self.write(")");
20213 if !self.config.ignore_nulls_in_func {
20215 match f.ignore_nulls {
20216 Some(true) => {
20217 self.write_space();
20218 self.write_keyword("IGNORE NULLS");
20219 }
20220 Some(false) => {
20221 self.write_space();
20222 self.write_keyword("RESPECT NULLS");
20223 }
20224 None => {}
20225 }
20226 }
20227 Ok(())
20228 }
20229
20230 fn generate_value_func(&mut self, name: &str, f: &ValueFunc) -> Result<()> {
20231 self.write_keyword(name);
20232 self.write("(");
20233 self.generate_expression(&f.this)?;
20234 if !f.order_by.is_empty() {
20236 self.write_space();
20237 self.write_keyword("ORDER BY");
20238 self.write_space();
20239 for (i, ordered) in f.order_by.iter().enumerate() {
20240 if i > 0 {
20241 self.write(", ");
20242 }
20243 self.generate_ordered(ordered)?;
20244 }
20245 }
20246 if self.config.ignore_nulls_in_func {
20248 match f.ignore_nulls {
20249 Some(true) => {
20250 self.write_space();
20251 self.write_keyword("IGNORE NULLS");
20252 }
20253 Some(false) => {
20254 self.write_space();
20255 self.write_keyword("RESPECT NULLS");
20256 }
20257 None => {}
20258 }
20259 }
20260 self.write(")");
20261 if !self.config.ignore_nulls_in_func {
20263 match f.ignore_nulls {
20264 Some(true) => {
20265 self.write_space();
20266 self.write_keyword("IGNORE NULLS");
20267 }
20268 Some(false) => {
20269 self.write_space();
20270 self.write_keyword("RESPECT NULLS");
20271 }
20272 None => {}
20273 }
20274 }
20275 Ok(())
20276 }
20277
20278 fn generate_value_func_with_ignore_nulls_bool(
20281 &mut self,
20282 name: &str,
20283 f: &ValueFunc,
20284 ) -> Result<()> {
20285 if matches!(self.config.dialect, Some(DialectType::Hive)) && f.ignore_nulls == Some(true) {
20286 self.write_keyword(name);
20287 self.write("(");
20288 self.generate_expression(&f.this)?;
20289 self.write(", ");
20290 self.write_keyword("TRUE");
20291 self.write(")");
20292 return Ok(());
20293 }
20294 self.generate_value_func(name, f)
20295 }
20296
20297 fn generate_nth_value(&mut self, f: &NthValueFunc) -> Result<()> {
20298 self.write_keyword("NTH_VALUE");
20299 self.write("(");
20300 self.generate_expression(&f.this)?;
20301 self.write(", ");
20302 self.generate_expression(&f.offset)?;
20303 if self.config.ignore_nulls_in_func {
20305 match f.ignore_nulls {
20306 Some(true) => {
20307 self.write_space();
20308 self.write_keyword("IGNORE NULLS");
20309 }
20310 Some(false) => {
20311 self.write_space();
20312 self.write_keyword("RESPECT NULLS");
20313 }
20314 None => {}
20315 }
20316 }
20317 self.write(")");
20318 if matches!(
20320 self.config.dialect,
20321 Some(crate::dialects::DialectType::Snowflake)
20322 ) {
20323 match f.from_first {
20324 Some(true) => {
20325 self.write_space();
20326 self.write_keyword("FROM FIRST");
20327 }
20328 Some(false) => {
20329 self.write_space();
20330 self.write_keyword("FROM LAST");
20331 }
20332 None => {}
20333 }
20334 }
20335 if !self.config.ignore_nulls_in_func {
20337 match f.ignore_nulls {
20338 Some(true) => {
20339 self.write_space();
20340 self.write_keyword("IGNORE NULLS");
20341 }
20342 Some(false) => {
20343 self.write_space();
20344 self.write_keyword("RESPECT NULLS");
20345 }
20346 None => {}
20347 }
20348 }
20349 Ok(())
20350 }
20351
20352 fn generate_position(&mut self, f: &PositionFunc) -> Result<()> {
20355 if matches!(
20358 self.config.dialect,
20359 Some(crate::dialects::DialectType::ClickHouse)
20360 ) {
20361 self.write_keyword("POSITION");
20362 self.write("(");
20363 self.generate_expression(&f.string)?;
20364 self.write(", ");
20365 self.generate_expression(&f.substring)?;
20366 if let Some(ref start) = f.start {
20367 self.write(", ");
20368 self.generate_expression(start)?;
20369 }
20370 self.write(")");
20371 return Ok(());
20372 }
20373
20374 self.write_keyword("POSITION");
20375 self.write("(");
20376 self.generate_expression(&f.substring)?;
20377 self.write_space();
20378 self.write_keyword("IN");
20379 self.write_space();
20380 self.generate_expression(&f.string)?;
20381 if let Some(ref start) = f.start {
20382 self.write(", ");
20383 self.generate_expression(start)?;
20384 }
20385 self.write(")");
20386 Ok(())
20387 }
20388
20389 fn generate_rand(&mut self, f: &Rand) -> Result<()> {
20392 if f.lower.is_some() || f.upper.is_some() {
20394 self.write_keyword("RANDOM");
20395 self.write("(");
20396 if let Some(ref lower) = f.lower {
20397 self.generate_expression(lower)?;
20398 }
20399 if let Some(ref upper) = f.upper {
20400 self.write(", ");
20401 self.generate_expression(upper)?;
20402 }
20403 self.write(")");
20404 return Ok(());
20405 }
20406 let func_name = match self.config.dialect {
20408 Some(crate::dialects::DialectType::Snowflake)
20409 | Some(crate::dialects::DialectType::DuckDB) => "RANDOM",
20410 _ => "RAND",
20411 };
20412 self.write_keyword(func_name);
20413 self.write("(");
20414 if !matches!(
20416 self.config.dialect,
20417 Some(crate::dialects::DialectType::DuckDB)
20418 ) {
20419 if let Some(ref seed) = f.seed {
20420 self.generate_expression(seed)?;
20421 }
20422 }
20423 self.write(")");
20424 Ok(())
20425 }
20426
20427 fn generate_truncate_func(&mut self, f: &TruncateFunc) -> Result<()> {
20428 self.write_keyword("TRUNCATE");
20429 self.write("(");
20430 self.generate_expression(&f.this)?;
20431 if let Some(ref decimals) = f.decimals {
20432 self.write(", ");
20433 self.generate_expression(decimals)?;
20434 }
20435 self.write(")");
20436 Ok(())
20437 }
20438
20439 fn generate_decode(&mut self, f: &DecodeFunc) -> Result<()> {
20442 self.write_keyword("DECODE");
20443 self.write("(");
20444 self.generate_expression(&f.this)?;
20445 for (search, result) in &f.search_results {
20446 self.write(", ");
20447 self.generate_expression(search)?;
20448 self.write(", ");
20449 self.generate_expression(result)?;
20450 }
20451 if let Some(ref default) = f.default {
20452 self.write(", ");
20453 self.generate_expression(default)?;
20454 }
20455 self.write(")");
20456 Ok(())
20457 }
20458
20459 fn generate_date_format(&mut self, name: &str, f: &DateFormatFunc) -> Result<()> {
20462 self.write_keyword(name);
20463 self.write("(");
20464 self.generate_expression(&f.this)?;
20465 self.write(", ");
20466 self.generate_expression(&f.format)?;
20467 self.write(")");
20468 Ok(())
20469 }
20470
20471 fn generate_from_unixtime(&mut self, f: &FromUnixtimeFunc) -> Result<()> {
20472 self.write_keyword("FROM_UNIXTIME");
20473 self.write("(");
20474 self.generate_expression(&f.this)?;
20475 if let Some(ref format) = f.format {
20476 self.write(", ");
20477 self.generate_expression(format)?;
20478 }
20479 self.write(")");
20480 Ok(())
20481 }
20482
20483 fn generate_unix_timestamp(&mut self, f: &UnixTimestampFunc) -> Result<()> {
20484 self.write_keyword("UNIX_TIMESTAMP");
20485 self.write("(");
20486 if let Some(ref expr) = f.this {
20487 self.generate_expression(expr)?;
20488 if let Some(ref format) = f.format {
20489 self.write(", ");
20490 self.generate_expression(format)?;
20491 }
20492 } else if matches!(
20493 self.config.dialect,
20494 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
20495 ) {
20496 self.write_keyword("CURRENT_TIMESTAMP");
20498 self.write("()");
20499 }
20500 self.write(")");
20501 Ok(())
20502 }
20503
20504 fn generate_make_date(&mut self, f: &MakeDateFunc) -> Result<()> {
20505 self.write_keyword("MAKE_DATE");
20506 self.write("(");
20507 self.generate_expression(&f.year)?;
20508 self.write(", ");
20509 self.generate_expression(&f.month)?;
20510 self.write(", ");
20511 self.generate_expression(&f.day)?;
20512 self.write(")");
20513 Ok(())
20514 }
20515
20516 fn generate_make_timestamp(&mut self, f: &MakeTimestampFunc) -> Result<()> {
20517 self.write_keyword("MAKE_TIMESTAMP");
20518 self.write("(");
20519 self.generate_expression(&f.year)?;
20520 self.write(", ");
20521 self.generate_expression(&f.month)?;
20522 self.write(", ");
20523 self.generate_expression(&f.day)?;
20524 self.write(", ");
20525 self.generate_expression(&f.hour)?;
20526 self.write(", ");
20527 self.generate_expression(&f.minute)?;
20528 self.write(", ");
20529 self.generate_expression(&f.second)?;
20530 if let Some(ref tz) = f.timezone {
20531 self.write(", ");
20532 self.generate_expression(tz)?;
20533 }
20534 self.write(")");
20535 Ok(())
20536 }
20537
20538 fn extract_struct_field_names(expr: &Expression) -> Option<Vec<String>> {
20540 match expr {
20541 Expression::Struct(s) => {
20542 if s.fields.iter().all(|(name, _)| name.is_some()) {
20543 Some(
20544 s.fields
20545 .iter()
20546 .map(|(name, _)| name.as_deref().unwrap_or("").to_string())
20547 .collect(),
20548 )
20549 } else {
20550 None
20551 }
20552 }
20553 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
20554 if f.args.iter().all(|a| matches!(a, Expression::Alias(_))) {
20556 Some(
20557 f.args
20558 .iter()
20559 .filter_map(|a| {
20560 if let Expression::Alias(alias) = a {
20561 Some(alias.alias.name.clone())
20562 } else {
20563 None
20564 }
20565 })
20566 .collect(),
20567 )
20568 } else {
20569 None
20570 }
20571 }
20572 _ => None,
20573 }
20574 }
20575
20576 fn struct_has_unnamed_fields(expr: &Expression) -> bool {
20578 match expr {
20579 Expression::Struct(s) => s.fields.iter().any(|(name, _)| name.is_none()),
20580 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
20581 f.args.iter().any(|a| !matches!(a, Expression::Alias(_)))
20582 }
20583 _ => false,
20584 }
20585 }
20586
20587 fn struct_field_count(expr: &Expression) -> usize {
20589 match expr {
20590 Expression::Struct(s) => s.fields.len(),
20591 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => f.args.len(),
20592 _ => 0,
20593 }
20594 }
20595
20596 fn apply_struct_field_names(expr: &Expression, field_names: &[String]) -> Expression {
20598 match expr {
20599 Expression::Struct(s) => {
20600 let mut new_fields = Vec::with_capacity(s.fields.len());
20601 for (i, (name, value)) in s.fields.iter().enumerate() {
20602 if name.is_none() && i < field_names.len() {
20603 new_fields.push((Some(field_names[i].clone()), value.clone()));
20604 } else {
20605 new_fields.push((name.clone(), value.clone()));
20606 }
20607 }
20608 Expression::Struct(Box::new(crate::expressions::Struct { fields: new_fields }))
20609 }
20610 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
20611 let mut new_args = Vec::with_capacity(f.args.len());
20612 for (i, arg) in f.args.iter().enumerate() {
20613 if !matches!(arg, Expression::Alias(_)) && i < field_names.len() {
20614 new_args.push(Expression::Alias(Box::new(crate::expressions::Alias {
20616 this: arg.clone(),
20617 alias: crate::expressions::Identifier::new(field_names[i].clone()),
20618 column_aliases: Vec::new(),
20619 alias_explicit_as: false,
20620 alias_keyword: None,
20621 pre_alias_comments: Vec::new(),
20622 trailing_comments: Vec::new(),
20623 inferred_type: None,
20624 })));
20625 } else {
20626 new_args.push(arg.clone());
20627 }
20628 }
20629 Expression::Function(Box::new(crate::expressions::Function {
20630 name: f.name.clone(),
20631 args: new_args,
20632 distinct: f.distinct,
20633 trailing_comments: f.trailing_comments.clone(),
20634 use_bracket_syntax: f.use_bracket_syntax,
20635 no_parens: f.no_parens,
20636 quoted: f.quoted,
20637 span: None,
20638 inferred_type: None,
20639 }))
20640 }
20641 _ => expr.clone(),
20642 }
20643 }
20644
20645 fn inherit_struct_field_names(expressions: &[Expression]) -> Vec<Expression> {
20649 let first = match expressions.first() {
20650 Some(e) => e,
20651 None => return expressions.to_vec(),
20652 };
20653
20654 let field_names = match Self::extract_struct_field_names(first) {
20655 Some(names) if !names.is_empty() => names,
20656 _ => return expressions.to_vec(),
20657 };
20658
20659 let mut result = Vec::with_capacity(expressions.len());
20660 for (idx, expr) in expressions.iter().enumerate() {
20661 if idx == 0 {
20662 result.push(expr.clone());
20663 continue;
20664 }
20665 if Self::struct_field_count(expr) == field_names.len()
20667 && Self::struct_has_unnamed_fields(expr)
20668 {
20669 result.push(Self::apply_struct_field_names(expr, &field_names));
20670 } else {
20671 result.push(expr.clone());
20672 }
20673 }
20674 result
20675 }
20676
20677 fn generate_array_constructor(&mut self, f: &ArrayConstructor) -> Result<()> {
20680 let needs_inheritance = matches!(
20683 self.config.dialect,
20684 Some(DialectType::DuckDB)
20685 | Some(DialectType::Spark)
20686 | Some(DialectType::Databricks)
20687 | Some(DialectType::Hive)
20688 | Some(DialectType::Snowflake)
20689 | Some(DialectType::Presto)
20690 | Some(DialectType::Trino)
20691 );
20692 let propagated: Vec<Expression>;
20693 let expressions = if needs_inheritance && f.expressions.len() > 1 {
20694 propagated = Self::inherit_struct_field_names(&f.expressions);
20695 &propagated
20696 } else {
20697 &f.expressions
20698 };
20699
20700 let should_split = if self.config.pretty && !expressions.is_empty() {
20702 let mut expr_strings: Vec<String> = Vec::with_capacity(expressions.len());
20703 for expr in expressions {
20704 let mut temp_gen = Generator::with_arc_config(self.config.clone());
20705 Arc::make_mut(&mut temp_gen.config).pretty = false;
20706 temp_gen.generate_expression(expr)?;
20707 expr_strings.push(temp_gen.output);
20708 }
20709 self.too_wide(&expr_strings)
20710 } else {
20711 false
20712 };
20713
20714 if f.bracket_notation {
20715 let (open, close) = match self.config.dialect {
20719 None
20720 | Some(DialectType::Generic)
20721 | Some(DialectType::Spark)
20722 | Some(DialectType::Databricks)
20723 | Some(DialectType::Hive) => {
20724 self.write_keyword("ARRAY");
20725 ("(", ")")
20726 }
20727 Some(DialectType::Presto)
20728 | Some(DialectType::Trino)
20729 | Some(DialectType::PostgreSQL)
20730 | Some(DialectType::Redshift)
20731 | Some(DialectType::Materialize)
20732 | Some(DialectType::RisingWave)
20733 | Some(DialectType::CockroachDB) => {
20734 self.write_keyword("ARRAY");
20735 ("[", "]")
20736 }
20737 _ => ("[", "]"),
20738 };
20739 self.write(open);
20740 if should_split {
20741 self.write_newline();
20742 self.indent_level += 1;
20743 for (i, expr) in expressions.iter().enumerate() {
20744 self.write_indent();
20745 self.generate_expression(expr)?;
20746 if i + 1 < expressions.len() {
20747 self.write(",");
20748 }
20749 self.write_newline();
20750 }
20751 self.indent_level -= 1;
20752 self.write_indent();
20753 } else {
20754 for (i, expr) in expressions.iter().enumerate() {
20755 if i > 0 {
20756 self.write(", ");
20757 }
20758 self.generate_expression(expr)?;
20759 }
20760 }
20761 self.write(close);
20762 } else {
20763 if f.use_list_keyword {
20765 self.write_keyword("LIST");
20766 } else {
20767 self.write_keyword("ARRAY");
20768 }
20769 let has_subquery = expressions
20772 .iter()
20773 .any(|e| matches!(e, Expression::Select(_)));
20774 let (open, close) = if matches!(
20775 self.config.dialect,
20776 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive)
20777 ) || (matches!(self.config.dialect, Some(DialectType::BigQuery))
20778 && has_subquery)
20779 {
20780 ("(", ")")
20781 } else {
20782 ("[", "]")
20783 };
20784 self.write(open);
20785 if should_split {
20786 self.write_newline();
20787 self.indent_level += 1;
20788 for (i, expr) in expressions.iter().enumerate() {
20789 self.write_indent();
20790 self.generate_expression(expr)?;
20791 if i + 1 < expressions.len() {
20792 self.write(",");
20793 }
20794 self.write_newline();
20795 }
20796 self.indent_level -= 1;
20797 self.write_indent();
20798 } else {
20799 for (i, expr) in expressions.iter().enumerate() {
20800 if i > 0 {
20801 self.write(", ");
20802 }
20803 self.generate_expression(expr)?;
20804 }
20805 }
20806 self.write(close);
20807 }
20808 Ok(())
20809 }
20810
20811 fn generate_array_sort(&mut self, f: &ArraySortFunc) -> Result<()> {
20812 self.write_keyword("ARRAY_SORT");
20813 self.write("(");
20814 self.generate_expression(&f.this)?;
20815 if let Some(ref comp) = f.comparator {
20816 self.write(", ");
20817 self.generate_expression(comp)?;
20818 }
20819 self.write(")");
20820 Ok(())
20821 }
20822
20823 fn generate_array_join(&mut self, name: &str, f: &ArrayJoinFunc) -> Result<()> {
20824 self.write_keyword(name);
20825 self.write("(");
20826 self.generate_expression(&f.this)?;
20827 self.write(", ");
20828 self.generate_expression(&f.separator)?;
20829 if let Some(ref null_rep) = f.null_replacement {
20830 self.write(", ");
20831 self.generate_expression(null_rep)?;
20832 }
20833 self.write(")");
20834 Ok(())
20835 }
20836
20837 fn generate_unnest(&mut self, f: &UnnestFunc) -> Result<()> {
20838 self.write_keyword("UNNEST");
20839 self.write("(");
20840 self.generate_expression(&f.this)?;
20841 for extra in &f.expressions {
20842 self.write(", ");
20843 self.generate_expression(extra)?;
20844 }
20845 self.write(")");
20846 if f.with_ordinality {
20847 self.write_space();
20848 if self.config.unnest_with_ordinality {
20849 self.write_keyword("WITH ORDINALITY");
20851 } else if f.offset_alias.is_some() {
20852 if let Some(ref alias) = f.alias {
20855 self.write_keyword("AS");
20856 self.write_space();
20857 self.generate_identifier(alias)?;
20858 self.write_space();
20859 }
20860 self.write_keyword("WITH OFFSET");
20861 if let Some(ref offset_alias) = f.offset_alias {
20862 self.write_space();
20863 self.write_keyword("AS");
20864 self.write_space();
20865 self.generate_identifier(offset_alias)?;
20866 }
20867 } else {
20868 self.write_keyword("WITH OFFSET");
20870 if f.alias.is_none() {
20871 self.write(" AS offset");
20872 }
20873 }
20874 }
20875 if let Some(ref alias) = f.alias {
20876 let should_add_alias = if !f.with_ordinality {
20878 true
20879 } else if self.config.unnest_with_ordinality {
20880 true
20882 } else if f.offset_alias.is_some() {
20883 false
20885 } else {
20886 true
20888 };
20889 if should_add_alias {
20890 self.write_space();
20891 self.write_keyword("AS");
20892 self.write_space();
20893 self.generate_identifier(alias)?;
20894 }
20895 }
20896 Ok(())
20897 }
20898
20899 fn generate_array_filter(&mut self, f: &ArrayFilterFunc) -> Result<()> {
20900 self.write_keyword("FILTER");
20901 self.write("(");
20902 self.generate_expression(&f.this)?;
20903 self.write(", ");
20904 self.generate_expression(&f.filter)?;
20905 self.write(")");
20906 Ok(())
20907 }
20908
20909 fn generate_array_transform(&mut self, f: &ArrayTransformFunc) -> Result<()> {
20910 self.write_keyword("TRANSFORM");
20911 self.write("(");
20912 self.generate_expression(&f.this)?;
20913 self.write(", ");
20914 self.generate_expression(&f.transform)?;
20915 self.write(")");
20916 Ok(())
20917 }
20918
20919 fn generate_sequence(&mut self, name: &str, f: &SequenceFunc) -> Result<()> {
20920 self.write_keyword(name);
20921 self.write("(");
20922 self.generate_expression(&f.start)?;
20923 self.write(", ");
20924 self.generate_expression(&f.stop)?;
20925 if let Some(ref step) = f.step {
20926 self.write(", ");
20927 self.generate_expression(step)?;
20928 }
20929 self.write(")");
20930 Ok(())
20931 }
20932
20933 fn generate_struct_constructor(&mut self, f: &StructConstructor) -> Result<()> {
20936 self.write_keyword("STRUCT");
20937 self.write("(");
20938 for (i, (name, expr)) in f.fields.iter().enumerate() {
20939 if i > 0 {
20940 self.write(", ");
20941 }
20942 if let Some(ref id) = name {
20943 self.generate_identifier(id)?;
20944 self.write(" ");
20945 self.write_keyword("AS");
20946 self.write(" ");
20947 }
20948 self.generate_expression(expr)?;
20949 }
20950 self.write(")");
20951 Ok(())
20952 }
20953
20954 fn generate_struct_function_cross_dialect(&mut self, func: &Function) -> Result<()> {
20956 let mut names: Vec<Option<String>> = Vec::new();
20959 let mut values: Vec<&Expression> = Vec::new();
20960 let mut all_named = true;
20961
20962 for arg in &func.args {
20963 match arg {
20964 Expression::Alias(a) => {
20965 names.push(Some(a.alias.name.clone()));
20966 values.push(&a.this);
20967 }
20968 _ => {
20969 names.push(None);
20970 values.push(arg);
20971 all_named = false;
20972 }
20973 }
20974 }
20975
20976 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
20977 self.write("{");
20979 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
20980 if i > 0 {
20981 self.write(", ");
20982 }
20983 if let Some(n) = name {
20984 self.write("'");
20985 self.write(n);
20986 self.write("'");
20987 } else {
20988 self.write("'_");
20989 self.write(&i.to_string());
20990 self.write("'");
20991 }
20992 self.write(": ");
20993 self.generate_expression(value)?;
20994 }
20995 self.write("}");
20996 return Ok(());
20997 }
20998
20999 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
21000 self.write_keyword("OBJECT_CONSTRUCT");
21002 self.write("(");
21003 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
21004 if i > 0 {
21005 self.write(", ");
21006 }
21007 if let Some(n) = name {
21008 self.write("'");
21009 self.write(n);
21010 self.write("'");
21011 } else {
21012 self.write("'_");
21013 self.write(&i.to_string());
21014 self.write("'");
21015 }
21016 self.write(", ");
21017 self.generate_expression(value)?;
21018 }
21019 self.write(")");
21020 return Ok(());
21021 }
21022
21023 if matches!(
21024 self.config.dialect,
21025 Some(DialectType::Presto) | Some(DialectType::Trino)
21026 ) {
21027 if all_named && !names.is_empty() {
21028 self.write_keyword("CAST");
21031 self.write("(");
21032 self.write_keyword("ROW");
21033 self.write("(");
21034 for (i, value) in values.iter().enumerate() {
21035 if i > 0 {
21036 self.write(", ");
21037 }
21038 self.generate_expression(value)?;
21039 }
21040 self.write(")");
21041 self.write(" ");
21042 self.write_keyword("AS");
21043 self.write(" ");
21044 self.write_keyword("ROW");
21045 self.write("(");
21046 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
21047 if i > 0 {
21048 self.write(", ");
21049 }
21050 if let Some(n) = name {
21051 self.write(n);
21052 }
21053 self.write(" ");
21054 let type_str = Self::infer_sql_type_for_presto(value);
21055 self.write_keyword(&type_str);
21056 }
21057 self.write(")");
21058 self.write(")");
21059 } else {
21060 self.write_keyword("ROW");
21062 self.write("(");
21063 for (i, value) in values.iter().enumerate() {
21064 if i > 0 {
21065 self.write(", ");
21066 }
21067 self.generate_expression(value)?;
21068 }
21069 self.write(")");
21070 }
21071 return Ok(());
21072 }
21073
21074 self.write_keyword("ROW");
21076 self.write("(");
21077 for (i, value) in values.iter().enumerate() {
21078 if i > 0 {
21079 self.write(", ");
21080 }
21081 self.generate_expression(value)?;
21082 }
21083 self.write(")");
21084 Ok(())
21085 }
21086
21087 fn infer_sql_type_for_presto(expr: &Expression) -> String {
21089 match expr {
21090 Expression::Literal(lit)
21091 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
21092 {
21093 "VARCHAR".to_string()
21094 }
21095 Expression::Literal(lit)
21096 if matches!(lit.as_ref(), crate::expressions::Literal::Number(_)) =>
21097 {
21098 let crate::expressions::Literal::Number(n) = lit.as_ref() else {
21099 unreachable!()
21100 };
21101 if n.contains('.') {
21102 "DOUBLE".to_string()
21103 } else {
21104 "INTEGER".to_string()
21105 }
21106 }
21107 Expression::Boolean(_) => "BOOLEAN".to_string(),
21108 Expression::Literal(lit)
21109 if matches!(lit.as_ref(), crate::expressions::Literal::Date(_)) =>
21110 {
21111 "DATE".to_string()
21112 }
21113 Expression::Literal(lit)
21114 if matches!(lit.as_ref(), crate::expressions::Literal::Timestamp(_)) =>
21115 {
21116 "TIMESTAMP".to_string()
21117 }
21118 Expression::Literal(lit)
21119 if matches!(lit.as_ref(), crate::expressions::Literal::Datetime(_)) =>
21120 {
21121 "TIMESTAMP".to_string()
21122 }
21123 Expression::Array(_) | Expression::ArrayFunc(_) => {
21124 "ARRAY(VARCHAR)".to_string()
21126 }
21127 Expression::Struct(_) | Expression::StructFunc(_) => "ROW".to_string(),
21129 Expression::Function(f) => {
21130 if f.name.eq_ignore_ascii_case("STRUCT") {
21131 "ROW".to_string()
21132 } else if f.name.eq_ignore_ascii_case("CURRENT_DATE") {
21133 "DATE".to_string()
21134 } else if f.name.eq_ignore_ascii_case("CURRENT_TIMESTAMP")
21135 || f.name.eq_ignore_ascii_case("NOW")
21136 {
21137 "TIMESTAMP".to_string()
21138 } else {
21139 "VARCHAR".to_string()
21140 }
21141 }
21142 _ => "VARCHAR".to_string(),
21143 }
21144 }
21145
21146 fn generate_struct_extract(&mut self, f: &StructExtractFunc) -> Result<()> {
21147 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
21149 self.write_keyword("STRUCT_EXTRACT");
21150 self.write("(");
21151 self.generate_expression(&f.this)?;
21152 self.write(", ");
21153 self.write("'");
21155 self.write(&f.field.name);
21156 self.write("'");
21157 self.write(")");
21158 return Ok(());
21159 }
21160 self.generate_expression(&f.this)?;
21161 self.write(".");
21162 self.generate_identifier(&f.field)
21163 }
21164
21165 fn generate_named_struct(&mut self, f: &NamedStructFunc) -> Result<()> {
21166 if matches!(
21167 self.config.dialect,
21168 Some(DialectType::Spark | DialectType::Databricks)
21169 ) {
21170 self.write_keyword("STRUCT");
21171 self.write("(");
21172 for (i, (name, value)) in f.pairs.iter().enumerate() {
21173 if i > 0 {
21174 self.write(", ");
21175 }
21176 self.generate_expression(value)?;
21177 self.write(" ");
21178 self.write_keyword("AS");
21179 self.write(" ");
21180 if let Expression::Literal(lit) = name {
21181 if let Literal::String(field_name) = lit.as_ref() {
21182 self.generate_identifier(&Identifier::new(field_name))?;
21183 } else {
21184 self.generate_expression(name)?;
21185 }
21186 } else {
21187 self.generate_expression(name)?;
21188 }
21189 }
21190 self.write(")");
21191 return Ok(());
21192 }
21193
21194 self.write_keyword("NAMED_STRUCT");
21195 self.write("(");
21196 for (i, (name, value)) in f.pairs.iter().enumerate() {
21197 if i > 0 {
21198 self.write(", ");
21199 }
21200 self.generate_expression(name)?;
21201 self.write(", ");
21202 self.generate_expression(value)?;
21203 }
21204 self.write(")");
21205 Ok(())
21206 }
21207
21208 fn generate_map_constructor(&mut self, f: &MapConstructor) -> Result<()> {
21211 if f.curly_brace_syntax {
21212 if f.with_map_keyword {
21214 self.write_keyword("MAP");
21215 self.write(" ");
21216 }
21217 self.write("{");
21218 for (i, (key, val)) in f.keys.iter().zip(f.values.iter()).enumerate() {
21219 if i > 0 {
21220 self.write(", ");
21221 }
21222 self.generate_expression(key)?;
21223 self.write(": ");
21224 self.generate_expression(val)?;
21225 }
21226 self.write("}");
21227 } else {
21228 self.write_keyword("MAP");
21230 self.write("(");
21231 self.write_keyword("ARRAY");
21232 self.write("[");
21233 for (i, key) in f.keys.iter().enumerate() {
21234 if i > 0 {
21235 self.write(", ");
21236 }
21237 self.generate_expression(key)?;
21238 }
21239 self.write("], ");
21240 self.write_keyword("ARRAY");
21241 self.write("[");
21242 for (i, val) in f.values.iter().enumerate() {
21243 if i > 0 {
21244 self.write(", ");
21245 }
21246 self.generate_expression(val)?;
21247 }
21248 self.write("])");
21249 }
21250 Ok(())
21251 }
21252
21253 fn generate_transform_func(&mut self, name: &str, f: &TransformFunc) -> Result<()> {
21254 self.write_keyword(name);
21255 self.write("(");
21256 self.generate_expression(&f.this)?;
21257 self.write(", ");
21258 self.generate_expression(&f.transform)?;
21259 self.write(")");
21260 Ok(())
21261 }
21262
21263 fn generate_json_extract(&mut self, name: &str, f: &JsonExtractFunc) -> Result<()> {
21266 use crate::dialects::DialectType;
21267
21268 let use_arrow = f.arrow_syntax && self.dialect_supports_json_arrow();
21270
21271 if use_arrow {
21272 self.generate_expression(&f.this)?;
21274 if name == "JSON_EXTRACT_SCALAR" || name == "JSON_EXTRACT_PATH_TEXT" {
21275 self.write(" ->> ");
21276 } else {
21277 self.write(" -> ");
21278 }
21279 self.generate_expression(&f.path)?;
21280 return Ok(());
21281 }
21282
21283 if f.hash_arrow_syntax
21285 && matches!(
21286 self.config.dialect,
21287 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
21288 )
21289 {
21290 self.generate_expression(&f.this)?;
21291 self.write(" #>> ");
21292 self.generate_expression(&f.path)?;
21293 return Ok(());
21294 }
21295
21296 let func_name = if matches!(self.config.dialect, Some(DialectType::Redshift)) {
21299 match name {
21300 "JSON_EXTRACT_SCALAR"
21301 | "JSON_EXTRACT_PATH_TEXT"
21302 | "JSON_EXTRACT"
21303 | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH_TEXT",
21304 _ => name,
21305 }
21306 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
21307 match name {
21308 "JSON_EXTRACT_SCALAR" | "JSON_EXTRACT_PATH_TEXT" => "JSON_EXTRACT_PATH_TEXT",
21309 "JSON_EXTRACT" | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH",
21310 _ => name,
21311 }
21312 } else {
21313 name
21314 };
21315
21316 self.write_keyword(func_name);
21317 self.write("(");
21318 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
21320 if let Expression::Cast(ref cast) = f.this {
21321 if matches!(cast.to, crate::expressions::DataType::Json) {
21322 self.generate_expression(&cast.this)?;
21323 } else {
21324 self.generate_expression(&f.this)?;
21325 }
21326 } else {
21327 self.generate_expression(&f.this)?;
21328 }
21329 } else {
21330 self.generate_expression(&f.this)?;
21331 }
21332 if matches!(
21335 self.config.dialect,
21336 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
21337 ) && (func_name == "JSON_EXTRACT_PATH" || func_name == "JSON_EXTRACT_PATH_TEXT")
21338 {
21339 if let Expression::Literal(ref lit) = f.path {
21340 if let Literal::String(ref s) = lit.as_ref() {
21341 let parts = Self::decompose_json_path(s);
21342 for part in &parts {
21343 self.write(", '");
21344 self.write(part);
21345 self.write("'");
21346 }
21347 }
21348 } else {
21349 self.write(", ");
21350 self.generate_expression(&f.path)?;
21351 }
21352 } else {
21353 self.write(", ");
21354 self.generate_expression(&f.path)?;
21355 }
21356
21357 if let Some(ref wrapper) = f.wrapper_option {
21360 self.write_space();
21361 self.write_keyword(wrapper);
21362 }
21363 if let Some(ref quotes) = f.quotes_option {
21364 self.write_space();
21365 self.write_keyword(quotes);
21366 if f.on_scalar_string {
21367 self.write_space();
21368 self.write_keyword("ON SCALAR STRING");
21369 }
21370 }
21371 if let Some(ref on_err) = f.on_error {
21372 self.write_space();
21373 self.write_keyword(on_err);
21374 }
21375 if let Some(ref ret_type) = f.returning {
21376 self.write_space();
21377 self.write_keyword("RETURNING");
21378 self.write_space();
21379 self.generate_data_type(ret_type)?;
21380 }
21381
21382 self.write(")");
21383 Ok(())
21384 }
21385
21386 fn dialect_supports_json_arrow(&self) -> bool {
21388 use crate::dialects::DialectType;
21389 match self.config.dialect {
21390 Some(DialectType::PostgreSQL) => true,
21392 Some(DialectType::MySQL) => true,
21393 Some(DialectType::DuckDB) => true,
21394 Some(DialectType::CockroachDB) => true,
21395 Some(DialectType::StarRocks) => true,
21396 Some(DialectType::SQLite) => true,
21397 _ => false,
21399 }
21400 }
21401
21402 fn generate_json_path(&mut self, name: &str, f: &JsonPathFunc) -> Result<()> {
21403 use crate::dialects::DialectType;
21404
21405 if matches!(
21407 self.config.dialect,
21408 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
21409 ) && name == "JSON_EXTRACT_PATH"
21410 {
21411 self.generate_expression(&f.this)?;
21412 self.write(" #> ");
21413 if f.paths.len() == 1 {
21414 self.generate_expression(&f.paths[0])?;
21415 } else {
21416 self.write_keyword("ARRAY");
21418 self.write("[");
21419 for (i, path) in f.paths.iter().enumerate() {
21420 if i > 0 {
21421 self.write(", ");
21422 }
21423 self.generate_expression(path)?;
21424 }
21425 self.write("]");
21426 }
21427 return Ok(());
21428 }
21429
21430 self.write_keyword(name);
21431 self.write("(");
21432 self.generate_expression(&f.this)?;
21433 for path in &f.paths {
21434 self.write(", ");
21435 self.generate_expression(path)?;
21436 }
21437 self.write(")");
21438 Ok(())
21439 }
21440
21441 fn generate_json_object(&mut self, f: &JsonObjectFunc) -> Result<()> {
21442 use crate::dialects::DialectType;
21443
21444 self.write_keyword("JSON_OBJECT");
21445 self.write("(");
21446 if f.star {
21447 self.write("*");
21448 } else {
21449 let use_comma_syntax = self.config.json_key_value_pair_sep == ","
21453 || matches!(
21454 self.config.dialect,
21455 Some(DialectType::BigQuery)
21456 | Some(DialectType::MySQL)
21457 | Some(DialectType::SQLite)
21458 );
21459
21460 for (i, (key, value)) in f.pairs.iter().enumerate() {
21461 if i > 0 {
21462 self.write(", ");
21463 }
21464 self.generate_expression(key)?;
21465 if use_comma_syntax {
21466 self.write(", ");
21467 } else {
21468 self.write(": ");
21469 }
21470 self.generate_expression(value)?;
21471 }
21472 }
21473 if let Some(null_handling) = f.null_handling {
21474 self.write_space();
21475 match null_handling {
21476 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
21477 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
21478 }
21479 }
21480 if f.with_unique_keys {
21481 self.write_space();
21482 self.write_keyword("WITH UNIQUE KEYS");
21483 }
21484 if let Some(ref ret_type) = f.returning_type {
21485 self.write_space();
21486 self.write_keyword("RETURNING");
21487 self.write_space();
21488 self.generate_data_type(ret_type)?;
21489 if f.format_json {
21490 self.write_space();
21491 self.write_keyword("FORMAT JSON");
21492 }
21493 if let Some(ref enc) = f.encoding {
21494 self.write_space();
21495 self.write_keyword("ENCODING");
21496 self.write_space();
21497 self.write(enc);
21498 }
21499 }
21500 self.write(")");
21501 Ok(())
21502 }
21503
21504 fn generate_json_modify(&mut self, name: &str, f: &JsonModifyFunc) -> Result<()> {
21505 self.write_keyword(name);
21506 self.write("(");
21507 self.generate_expression(&f.this)?;
21508 for (path, value) in &f.path_values {
21509 self.write(", ");
21510 self.generate_expression(path)?;
21511 self.write(", ");
21512 self.generate_expression(value)?;
21513 }
21514 self.write(")");
21515 Ok(())
21516 }
21517
21518 fn generate_json_array_agg(&mut self, f: &JsonArrayAggFunc) -> Result<()> {
21519 self.write_keyword("JSON_ARRAYAGG");
21520 self.write("(");
21521 self.generate_expression(&f.this)?;
21522 if let Some(ref order_by) = f.order_by {
21523 self.write_space();
21524 self.write_keyword("ORDER BY");
21525 self.write_space();
21526 for (i, ord) in order_by.iter().enumerate() {
21527 if i > 0 {
21528 self.write(", ");
21529 }
21530 self.generate_ordered(ord)?;
21531 }
21532 }
21533 if let Some(null_handling) = f.null_handling {
21534 self.write_space();
21535 match null_handling {
21536 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
21537 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
21538 }
21539 }
21540 self.write(")");
21541 if let Some(ref filter) = f.filter {
21542 self.write_space();
21543 self.write_keyword("FILTER");
21544 self.write("(");
21545 self.write_keyword("WHERE");
21546 self.write_space();
21547 self.generate_expression(filter)?;
21548 self.write(")");
21549 }
21550 Ok(())
21551 }
21552
21553 fn generate_json_object_agg(&mut self, f: &JsonObjectAggFunc) -> Result<()> {
21554 self.write_keyword("JSON_OBJECTAGG");
21555 self.write("(");
21556 self.generate_expression(&f.key)?;
21557 self.write(": ");
21558 self.generate_expression(&f.value)?;
21559 if let Some(null_handling) = f.null_handling {
21560 self.write_space();
21561 match null_handling {
21562 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
21563 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
21564 }
21565 }
21566 self.write(")");
21567 if let Some(ref filter) = f.filter {
21568 self.write_space();
21569 self.write_keyword("FILTER");
21570 self.write("(");
21571 self.write_keyword("WHERE");
21572 self.write_space();
21573 self.generate_expression(filter)?;
21574 self.write(")");
21575 }
21576 Ok(())
21577 }
21578
21579 fn generate_convert(&mut self, f: &ConvertFunc) -> Result<()> {
21582 use crate::dialects::DialectType;
21583
21584 if self.config.dialect == Some(DialectType::Redshift) {
21586 self.write_keyword("CAST");
21587 self.write("(");
21588 self.generate_expression(&f.this)?;
21589 self.write_space();
21590 self.write_keyword("AS");
21591 self.write_space();
21592 self.generate_data_type(&f.to)?;
21593 self.write(")");
21594 return Ok(());
21595 }
21596
21597 self.write_keyword("CONVERT");
21598 self.write("(");
21599 self.generate_data_type(&f.to)?;
21600 self.write(", ");
21601 self.generate_expression(&f.this)?;
21602 if let Some(ref style) = f.style {
21603 self.write(", ");
21604 self.generate_expression(style)?;
21605 }
21606 self.write(")");
21607 Ok(())
21608 }
21609
21610 fn generate_lambda(&mut self, f: &LambdaExpr) -> Result<()> {
21613 if f.colon {
21614 self.write_keyword("LAMBDA");
21616 self.write_space();
21617 for (i, param) in f.parameters.iter().enumerate() {
21618 if i > 0 {
21619 self.write(", ");
21620 }
21621 self.generate_identifier(param)?;
21622 }
21623 self.write(" : ");
21624 } else {
21625 if f.parameters.len() == 1 {
21627 self.generate_identifier(&f.parameters[0])?;
21628 } else {
21629 self.write("(");
21630 for (i, param) in f.parameters.iter().enumerate() {
21631 if i > 0 {
21632 self.write(", ");
21633 }
21634 self.generate_identifier(param)?;
21635 }
21636 self.write(")");
21637 }
21638 self.write(" -> ");
21639 }
21640 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
21641 if let Expression::Lambda(inner) = &f.body {
21642 self.generate_lambda_with_parenthesized_single_param(inner)?;
21643 return Ok(());
21644 }
21645 }
21646
21647 self.generate_expression(&f.body)
21648 }
21649
21650 fn generate_lambda_with_parenthesized_single_param(&mut self, f: &LambdaExpr) -> Result<()> {
21651 if f.colon {
21652 return self.generate_lambda(f);
21653 }
21654
21655 self.write("(");
21656 for (i, param) in f.parameters.iter().enumerate() {
21657 if i > 0 {
21658 self.write(", ");
21659 }
21660 self.generate_identifier(param)?;
21661 }
21662 self.write(") -> ");
21663 self.generate_expression(&f.body)
21664 }
21665
21666 fn generate_named_argument(&mut self, f: &NamedArgument) -> Result<()> {
21667 self.generate_identifier(&f.name)?;
21668 match f.separator {
21669 NamedArgSeparator::DArrow => self.write(" => "),
21670 NamedArgSeparator::ColonEq => self.write(" := "),
21671 NamedArgSeparator::Eq => self.write(" = "),
21672 }
21673 self.generate_expression(&f.value)
21674 }
21675
21676 fn generate_table_argument(&mut self, f: &TableArgument) -> Result<()> {
21677 self.write_keyword(&f.prefix);
21678 self.write(" ");
21679 self.generate_expression(&f.this)
21680 }
21681
21682 fn generate_parameter(&mut self, f: &Parameter) -> Result<()> {
21683 match f.style {
21684 ParameterStyle::Question => self.write("?"),
21685 ParameterStyle::Dollar => {
21686 self.write("$");
21687 if let Some(idx) = f.index {
21688 self.write(&idx.to_string());
21689 } else if let Some(ref name) = f.name {
21690 self.write(name);
21692 }
21693 }
21694 ParameterStyle::DollarBrace => {
21695 self.write("${");
21697 if let Some(ref name) = f.name {
21698 self.write(name);
21699 }
21700 if let Some(ref expr) = f.expression {
21701 self.write(":");
21702 self.write(expr);
21703 }
21704 self.write("}");
21705 }
21706 ParameterStyle::Colon => {
21707 self.write(":");
21708 if let Some(idx) = f.index {
21709 self.write(&idx.to_string());
21710 } else if let Some(ref name) = f.name {
21711 self.write(name);
21712 }
21713 }
21714 ParameterStyle::At => {
21715 self.write("@");
21716 if let Some(ref name) = f.name {
21717 if f.string_quoted {
21718 self.write("'");
21719 self.write(name);
21720 self.write("'");
21721 } else if f.quoted {
21722 self.write("\"");
21723 self.write(name);
21724 self.write("\"");
21725 } else {
21726 self.write(name);
21727 }
21728 }
21729 }
21730 ParameterStyle::DoubleAt => {
21731 self.write("@@");
21732 if let Some(ref name) = f.name {
21733 self.write(name);
21734 }
21735 }
21736 ParameterStyle::DoubleDollar => {
21737 self.write("$$");
21738 if let Some(ref name) = f.name {
21739 self.write(name);
21740 }
21741 }
21742 ParameterStyle::Percent => {
21743 if let Some(ref name) = f.name {
21744 self.write("%(");
21746 self.write(name);
21747 self.write(")s");
21748 } else {
21749 self.write("%s");
21751 }
21752 }
21753 ParameterStyle::Brace => {
21754 self.write("{");
21757 if let Some(ref name) = f.name {
21758 self.write(name);
21759 }
21760 if let Some(ref expr) = f.expression {
21761 self.write(": ");
21762 self.write(expr);
21763 }
21764 self.write("}");
21765 }
21766 }
21767 Ok(())
21768 }
21769
21770 fn generate_placeholder(&mut self, f: &Placeholder) -> Result<()> {
21771 self.write("?");
21772 if let Some(idx) = f.index {
21773 self.write(&idx.to_string());
21774 }
21775 Ok(())
21776 }
21777
21778 fn generate_sql_comment(&mut self, f: &SqlComment) -> Result<()> {
21779 if f.is_block {
21780 self.write("/*");
21781 self.write(&f.text);
21782 self.write("*/");
21783 } else {
21784 self.write("--");
21785 self.write(&f.text);
21786 }
21787 Ok(())
21788 }
21789
21790 fn generate_similar_to(&mut self, f: &SimilarToExpr) -> Result<()> {
21793 self.generate_expression(&f.this)?;
21794 if f.not {
21795 self.write_space();
21796 self.write_keyword("NOT");
21797 }
21798 self.write_space();
21799 self.write_keyword("SIMILAR TO");
21800 self.write_space();
21801 self.generate_expression(&f.pattern)?;
21802 if let Some(ref escape) = f.escape {
21803 self.write_space();
21804 self.write_keyword("ESCAPE");
21805 self.write_space();
21806 self.generate_expression(escape)?;
21807 }
21808 Ok(())
21809 }
21810
21811 fn generate_quantified(&mut self, name: &str, f: &QuantifiedExpr) -> Result<()> {
21812 self.generate_expression(&f.this)?;
21813 self.write_space();
21814 if let Some(op) = &f.op {
21816 match op {
21817 QuantifiedOp::Eq => self.write("="),
21818 QuantifiedOp::Neq => self.write("<>"),
21819 QuantifiedOp::Lt => self.write("<"),
21820 QuantifiedOp::Lte => self.write("<="),
21821 QuantifiedOp::Gt => self.write(">"),
21822 QuantifiedOp::Gte => self.write(">="),
21823 }
21824 self.write_space();
21825 }
21826 self.write_keyword(name);
21827
21828 if matches!(&f.subquery, Expression::Subquery(_)) {
21830 self.write_space();
21831 self.generate_expression(&f.subquery)?;
21832 } else {
21833 self.write("(");
21834
21835 let is_statement = matches!(
21836 &f.subquery,
21837 Expression::Select(_)
21838 | Expression::Union(_)
21839 | Expression::Intersect(_)
21840 | Expression::Except(_)
21841 );
21842
21843 if self.config.pretty && is_statement {
21844 self.write_newline();
21845 self.indent_level += 1;
21846 self.write_indent();
21847 }
21848 self.generate_expression(&f.subquery)?;
21849 if self.config.pretty && is_statement {
21850 self.write_newline();
21851 self.indent_level -= 1;
21852 self.write_indent();
21853 }
21854 self.write(")");
21855 }
21856 Ok(())
21857 }
21858
21859 fn generate_overlaps(&mut self, f: &OverlapsExpr) -> Result<()> {
21860 if let (Some(this), Some(expr)) = (&f.this, &f.expression) {
21862 self.generate_expression(this)?;
21863 self.write_space();
21864 self.write_keyword("OVERLAPS");
21865 self.write_space();
21866 self.generate_expression(expr)?;
21867 } else if let (Some(ls), Some(le), Some(rs), Some(re)) =
21868 (&f.left_start, &f.left_end, &f.right_start, &f.right_end)
21869 {
21870 self.write("(");
21872 self.generate_expression(ls)?;
21873 self.write(", ");
21874 self.generate_expression(le)?;
21875 self.write(")");
21876 self.write_space();
21877 self.write_keyword("OVERLAPS");
21878 self.write_space();
21879 self.write("(");
21880 self.generate_expression(rs)?;
21881 self.write(", ");
21882 self.generate_expression(re)?;
21883 self.write(")");
21884 }
21885 Ok(())
21886 }
21887
21888 fn generate_try_cast(&mut self, cast: &Cast) -> Result<()> {
21891 use crate::dialects::DialectType;
21892
21893 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
21895 self.generate_expression(&cast.this)?;
21896 self.write(" !:> ");
21897 self.generate_data_type(&cast.to)?;
21898 return Ok(());
21899 }
21900
21901 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
21903 self.write_keyword("TRYCAST");
21904 self.write("(");
21905 self.generate_expression(&cast.this)?;
21906 self.write_space();
21907 self.write_keyword("AS");
21908 self.write_space();
21909 self.generate_data_type(&cast.to)?;
21910 self.write(")");
21911 return Ok(());
21912 }
21913
21914 let keyword = if matches!(
21916 self.config.dialect,
21917 Some(DialectType::Hive)
21918 | Some(DialectType::MySQL)
21919 | Some(DialectType::SQLite)
21920 | Some(DialectType::Oracle)
21921 | Some(DialectType::ClickHouse)
21922 | Some(DialectType::Redshift)
21923 | Some(DialectType::PostgreSQL)
21924 | Some(DialectType::StarRocks)
21925 | Some(DialectType::Doris)
21926 ) {
21927 "CAST"
21928 } else {
21929 "TRY_CAST"
21930 };
21931
21932 self.write_keyword(keyword);
21933 self.write("(");
21934 self.generate_expression(&cast.this)?;
21935 self.write_space();
21936 self.write_keyword("AS");
21937 self.write_space();
21938 self.generate_data_type(&cast.to)?;
21939
21940 if let Some(format) = &cast.format {
21942 self.write_space();
21943 self.write_keyword("FORMAT");
21944 self.write_space();
21945 self.generate_expression(format)?;
21946 }
21947
21948 self.write(")");
21949 Ok(())
21950 }
21951
21952 fn generate_safe_cast(&mut self, cast: &Cast) -> Result<()> {
21953 self.write_keyword("SAFE_CAST");
21954 self.write("(");
21955 self.generate_expression(&cast.this)?;
21956 self.write_space();
21957 self.write_keyword("AS");
21958 self.write_space();
21959 self.generate_data_type(&cast.to)?;
21960
21961 if let Some(format) = &cast.format {
21963 self.write_space();
21964 self.write_keyword("FORMAT");
21965 self.write_space();
21966 self.generate_expression(format)?;
21967 }
21968
21969 self.write(")");
21970 Ok(())
21971 }
21972
21973 fn generate_subscript(&mut self, s: &Subscript) -> Result<()> {
21976 let needs_parens = matches!(&s.this, Expression::JsonExtract(ref f) if f.arrow_syntax);
21980 if needs_parens {
21981 self.write("(");
21982 }
21983 self.generate_expression(&s.this)?;
21984 if needs_parens {
21985 self.write(")");
21986 }
21987 self.write("[");
21988 self.generate_expression(&s.index)?;
21989 self.write("]");
21990 Ok(())
21991 }
21992
21993 fn generate_dot_access(&mut self, d: &DotAccess) -> Result<()> {
21994 self.generate_expression(&d.this)?;
21995 let use_colon = matches!(self.config.dialect, Some(DialectType::Snowflake))
21998 && matches!(
21999 &d.this,
22000 Expression::Cast(_) | Expression::SafeCast(_) | Expression::TryCast(_)
22001 );
22002 if use_colon {
22003 self.write(":");
22004 } else {
22005 self.write(".");
22006 }
22007 self.generate_identifier(&d.field)
22008 }
22009
22010 fn generate_method_call(&mut self, m: &MethodCall) -> Result<()> {
22011 self.generate_expression(&m.this)?;
22012 self.write(".");
22013 if m.method.quoted {
22016 let q = self.config.identifier_quote;
22017 self.write(&format!("{}{}{}", q, m.method.name, q));
22018 } else {
22019 self.write(&m.method.name);
22020 }
22021 self.write("(");
22022 for (i, arg) in m.args.iter().enumerate() {
22023 if i > 0 {
22024 self.write(", ");
22025 }
22026 self.generate_expression(arg)?;
22027 }
22028 self.write(")");
22029 Ok(())
22030 }
22031
22032 fn generate_array_slice(&mut self, s: &ArraySlice) -> Result<()> {
22033 let needs_parens = matches!(
22036 &s.this,
22037 Expression::JsonExtract(f) if f.arrow_syntax
22038 ) || matches!(
22039 &s.this,
22040 Expression::JsonExtractScalar(f) if f.arrow_syntax
22041 );
22042
22043 if needs_parens {
22044 self.write("(");
22045 }
22046 self.generate_expression(&s.this)?;
22047 if needs_parens {
22048 self.write(")");
22049 }
22050 self.write("[");
22051 if let Some(start) = &s.start {
22052 self.generate_expression(start)?;
22053 }
22054 self.write(":");
22055 if let Some(end) = &s.end {
22056 self.generate_expression(end)?;
22057 }
22058 self.write("]");
22059 Ok(())
22060 }
22061
22062 fn generate_binary_op(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
22063 match &op.left {
22067 Expression::Column(col) => {
22068 if let Some(table) = &col.table {
22071 self.generate_identifier(table)?;
22072 self.write(".");
22073 }
22074 self.generate_identifier(&col.name)?;
22075 if col.join_mark && self.config.supports_column_join_marks {
22077 self.write(" (+)");
22078 }
22079 if op.left_comments.is_empty() {
22081 for comment in &col.trailing_comments {
22082 self.write_space();
22083 self.write_formatted_comment(comment);
22084 }
22085 }
22086 }
22087 Expression::Add(inner_op)
22088 | Expression::Sub(inner_op)
22089 | Expression::Mul(inner_op)
22090 | Expression::Div(inner_op)
22091 | Expression::Concat(inner_op) => {
22092 self.generate_binary_op_no_trailing(inner_op, match &op.left {
22094 Expression::Add(_) => "+",
22095 Expression::Sub(_) => "-",
22096 Expression::Mul(_) => "*",
22097 Expression::Div(_) => "/",
22098 Expression::Concat(_) => "||",
22099 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
22100 })?;
22101 }
22102 _ => {
22103 self.generate_expression(&op.left)?;
22104 }
22105 }
22106 for comment in &op.left_comments {
22108 self.write_space();
22109 self.write_formatted_comment(comment);
22110 }
22111 if self.config.pretty
22112 && matches!(self.config.dialect, Some(DialectType::Snowflake))
22113 && (operator == "AND" || operator == "OR")
22114 {
22115 self.write_newline();
22116 self.write_indent();
22117 self.write_keyword(operator);
22118 } else {
22119 self.write_space();
22120 if operator.chars().all(|c| c.is_alphabetic()) {
22121 self.write_keyword(operator);
22122 } else {
22123 self.write(operator);
22124 }
22125 }
22126 for comment in &op.operator_comments {
22128 self.write_space();
22129 self.write_formatted_comment(comment);
22130 }
22131 self.write_space();
22132 self.generate_expression(&op.right)?;
22133 for comment in &op.trailing_comments {
22135 self.write_space();
22136 self.write_formatted_comment(comment);
22137 }
22138 Ok(())
22139 }
22140
22141 fn generate_connector_op(&mut self, op: &BinaryOp, connector: ConnectorOperator) -> Result<()> {
22142 let keyword = connector.keyword();
22143 let Some(terms) = self.flatten_connector_terms(op, connector) else {
22144 return self.generate_binary_op(op, keyword);
22145 };
22146
22147 let wrap_clickhouse_or_term = |generator: &mut Self, term: &Expression| -> Result<()> {
22148 let should_wrap = matches!(connector, ConnectorOperator::Or)
22149 && matches!(generator.config.dialect, Some(DialectType::ClickHouse))
22150 && matches!(
22151 generator.config.source_dialect,
22152 Some(DialectType::ClickHouse)
22153 )
22154 && matches!(term, Expression::And(_));
22155 if should_wrap {
22156 generator.write("(");
22157 generator.generate_expression(term)?;
22158 generator.write(")");
22159 } else {
22160 generator.generate_expression(term)?;
22161 }
22162 Ok(())
22163 };
22164
22165 wrap_clickhouse_or_term(self, terms[0])?;
22166 for term in terms.iter().skip(1) {
22167 if self.config.pretty && matches!(self.config.dialect, Some(DialectType::Snowflake)) {
22168 self.write_newline();
22169 self.write_indent();
22170 self.write_keyword(keyword);
22171 } else {
22172 self.write_space();
22173 self.write_keyword(keyword);
22174 }
22175 self.write_space();
22176 wrap_clickhouse_or_term(self, term)?;
22177 }
22178
22179 Ok(())
22180 }
22181
22182 fn flatten_connector_terms<'a>(
22183 &self,
22184 root: &'a BinaryOp,
22185 connector: ConnectorOperator,
22186 ) -> Option<Vec<&'a Expression>> {
22187 if !root.left_comments.is_empty()
22188 || !root.operator_comments.is_empty()
22189 || !root.trailing_comments.is_empty()
22190 {
22191 return None;
22192 }
22193
22194 let mut terms = Vec::new();
22195 let mut stack: Vec<&Expression> = vec![&root.right, &root.left];
22196
22197 while let Some(expr) = stack.pop() {
22198 match (connector, expr) {
22199 (ConnectorOperator::And, Expression::And(inner))
22200 if inner.left_comments.is_empty()
22201 && inner.operator_comments.is_empty()
22202 && inner.trailing_comments.is_empty() =>
22203 {
22204 stack.push(&inner.right);
22205 stack.push(&inner.left);
22206 }
22207 (ConnectorOperator::Or, Expression::Or(inner))
22208 if inner.left_comments.is_empty()
22209 && inner.operator_comments.is_empty()
22210 && inner.trailing_comments.is_empty() =>
22211 {
22212 stack.push(&inner.right);
22213 stack.push(&inner.left);
22214 }
22215 _ => terms.push(expr),
22216 }
22217 }
22218
22219 if terms.len() > 1 {
22220 Some(terms)
22221 } else {
22222 None
22223 }
22224 }
22225
22226 fn generate_like_op(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
22228 self.generate_expression(&op.left)?;
22229 self.write_space();
22230 if operator == "ILIKE" && matches!(self.config.dialect, Some(DialectType::Drill)) {
22232 self.write("`ILIKE`");
22233 } else {
22234 self.write_keyword(operator);
22235 }
22236 if let Some(quantifier) = &op.quantifier {
22237 self.write_space();
22238 self.write_keyword(quantifier);
22239 let is_any =
22244 quantifier.eq_ignore_ascii_case("ANY") || quantifier.eq_ignore_ascii_case("SOME");
22245 if !(is_any && matches!(&op.right, Expression::Paren(_))) {
22246 self.write_space();
22247 }
22248 } else {
22249 self.write_space();
22250 }
22251 self.generate_expression(&op.right)?;
22252 if let Some(escape) = &op.escape {
22253 self.write_space();
22254 self.write_keyword("ESCAPE");
22255 self.write_space();
22256 self.generate_expression(escape)?;
22257 }
22258 Ok(())
22259 }
22260
22261 fn generate_null_safe_eq(&mut self, op: &BinaryOp) -> Result<()> {
22264 use crate::dialects::DialectType;
22265 self.generate_expression(&op.left)?;
22266 self.write_space();
22267 if matches!(self.config.dialect, Some(DialectType::MySQL)) {
22268 self.write("<=>");
22269 } else {
22270 self.write_keyword("IS NOT DISTINCT FROM");
22271 }
22272 self.write_space();
22273 self.generate_expression(&op.right)?;
22274 Ok(())
22275 }
22276
22277 fn generate_null_safe_neq(&mut self, op: &BinaryOp) -> Result<()> {
22279 self.generate_expression(&op.left)?;
22280 self.write_space();
22281 self.write_keyword("IS DISTINCT FROM");
22282 self.write_space();
22283 self.generate_expression(&op.right)?;
22284 Ok(())
22285 }
22286
22287 fn generate_binary_op_no_trailing(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
22289 match &op.left {
22291 Expression::Column(col) => {
22292 if let Some(table) = &col.table {
22293 self.generate_identifier(table)?;
22294 self.write(".");
22295 }
22296 self.generate_identifier(&col.name)?;
22297 if col.join_mark && self.config.supports_column_join_marks {
22299 self.write(" (+)");
22300 }
22301 }
22302 Expression::Add(inner_op)
22303 | Expression::Sub(inner_op)
22304 | Expression::Mul(inner_op)
22305 | Expression::Div(inner_op)
22306 | Expression::Concat(inner_op) => {
22307 self.generate_binary_op_no_trailing(inner_op, match &op.left {
22308 Expression::Add(_) => "+",
22309 Expression::Sub(_) => "-",
22310 Expression::Mul(_) => "*",
22311 Expression::Div(_) => "/",
22312 Expression::Concat(_) => "||",
22313 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
22314 })?;
22315 }
22316 _ => {
22317 self.generate_expression(&op.left)?;
22318 }
22319 }
22320 for comment in &op.left_comments {
22322 self.write_space();
22323 self.write_formatted_comment(comment);
22324 }
22325 self.write_space();
22326 if operator.chars().all(|c| c.is_alphabetic()) {
22327 self.write_keyword(operator);
22328 } else {
22329 self.write(operator);
22330 }
22331 for comment in &op.operator_comments {
22333 self.write_space();
22334 self.write_formatted_comment(comment);
22335 }
22336 self.write_space();
22337 match &op.right {
22340 Expression::Column(col) => {
22341 if let Some(table) = &col.table {
22342 self.generate_identifier(table)?;
22343 self.write(".");
22344 }
22345 self.generate_identifier(&col.name)?;
22346 if col.join_mark && self.config.supports_column_join_marks {
22348 self.write(" (+)");
22349 }
22350 }
22351 _ => {
22352 self.generate_expression(&op.right)?;
22353 }
22354 }
22355 Ok(())
22357 }
22358
22359 fn generate_unary_op(&mut self, op: &UnaryOp, operator: &str) -> Result<()> {
22360 if operator.chars().all(|c| c.is_alphabetic()) {
22361 self.write_keyword(operator);
22362 self.write_space();
22363 } else {
22364 self.write(operator);
22365 if matches!(&op.this, Expression::Neg(_) | Expression::BitwiseNot(_)) {
22367 self.write_space();
22368 }
22369 }
22370 self.generate_expression(&op.this)
22371 }
22372
22373 fn generate_in(&mut self, in_expr: &In) -> Result<()> {
22374 let is_generic =
22378 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
22379 let use_prefix_not =
22380 in_expr.not && is_generic && self.config.not_in_style == NotInStyle::Prefix;
22381 if use_prefix_not {
22382 self.write_keyword("NOT");
22383 self.write_space();
22384 }
22385 self.generate_expression(&in_expr.this)?;
22386 if in_expr.global {
22387 self.write_space();
22388 self.write_keyword("GLOBAL");
22389 }
22390 if in_expr.not && !use_prefix_not {
22391 self.write_space();
22392 self.write_keyword("NOT");
22393 }
22394 self.write_space();
22395 self.write_keyword("IN");
22396
22397 if let Some(unnest_expr) = &in_expr.unnest {
22399 self.write_space();
22400 self.write_keyword("UNNEST");
22401 self.write("(");
22402 self.generate_expression(unnest_expr)?;
22403 self.write(")");
22404 return Ok(());
22405 }
22406
22407 if let Some(query) = &in_expr.query {
22408 let is_bare = in_expr.expressions.is_empty()
22411 && !matches!(
22412 query,
22413 Expression::Select(_)
22414 | Expression::Union(_)
22415 | Expression::Intersect(_)
22416 | Expression::Except(_)
22417 | Expression::Subquery(_)
22418 );
22419 if is_bare {
22420 self.write_space();
22422 self.generate_expression(query)?;
22423 } else {
22424 self.write(" (");
22426 let is_statement = matches!(
22427 query,
22428 Expression::Select(_)
22429 | Expression::Union(_)
22430 | Expression::Intersect(_)
22431 | Expression::Except(_)
22432 | Expression::Subquery(_)
22433 );
22434 if self.config.pretty && is_statement {
22435 self.write_newline();
22436 self.indent_level += 1;
22437 self.write_indent();
22438 }
22439 self.generate_expression(query)?;
22440 if self.config.pretty && is_statement {
22441 self.write_newline();
22442 self.indent_level -= 1;
22443 self.write_indent();
22444 }
22445 self.write(")");
22446 }
22447 } else {
22448 let is_duckdb = matches!(
22452 self.config.dialect,
22453 Some(crate::dialects::DialectType::DuckDB)
22454 );
22455 let is_clickhouse = matches!(
22456 self.config.dialect,
22457 Some(crate::dialects::DialectType::ClickHouse)
22458 );
22459 let single_expr = in_expr.expressions.len() == 1;
22460 if is_clickhouse && single_expr {
22461 if let Expression::Array(arr) = &in_expr.expressions[0] {
22462 self.write(" (");
22464 for (i, expr) in arr.expressions.iter().enumerate() {
22465 if i > 0 {
22466 self.write(", ");
22467 }
22468 self.generate_expression(expr)?;
22469 }
22470 self.write(")");
22471 } else if in_expr.is_field {
22472 self.write_space();
22473 self.generate_expression(&in_expr.expressions[0])?;
22474 } else {
22475 self.write(" (");
22476 self.generate_expression(&in_expr.expressions[0])?;
22477 self.write(")");
22478 }
22479 } else {
22480 let is_bare_ref = single_expr
22481 && matches!(
22482 &in_expr.expressions[0],
22483 Expression::Column(_) | Expression::Identifier(_) | Expression::Dot(_)
22484 );
22485 if (is_duckdb && is_bare_ref) || (in_expr.is_field && single_expr) {
22486 self.write_space();
22489 self.generate_expression(&in_expr.expressions[0])?;
22490 } else {
22491 self.write(" (");
22493 for (i, expr) in in_expr.expressions.iter().enumerate() {
22494 if i > 0 {
22495 self.write(", ");
22496 }
22497 self.generate_expression(expr)?;
22498 }
22499 self.write(")");
22500 }
22501 }
22502 }
22503
22504 Ok(())
22505 }
22506
22507 fn generate_between(&mut self, between: &Between) -> Result<()> {
22508 let use_prefix_not = between.not
22510 && (self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic));
22511 if use_prefix_not {
22512 self.write_keyword("NOT");
22513 self.write_space();
22514 }
22515 self.generate_expression(&between.this)?;
22516 if between.not && !use_prefix_not {
22517 self.write_space();
22518 self.write_keyword("NOT");
22519 }
22520 self.write_space();
22521 self.write_keyword("BETWEEN");
22522 if let Some(sym) = between.symmetric {
22524 if sym {
22525 self.write(" SYMMETRIC");
22526 } else {
22527 self.write(" ASYMMETRIC");
22528 }
22529 }
22530 self.write_space();
22531 self.generate_expression(&between.low)?;
22532 self.write_space();
22533 self.write_keyword("AND");
22534 self.write_space();
22535 self.generate_expression(&between.high)
22536 }
22537
22538 fn generate_is_null(&mut self, is_null: &IsNull) -> Result<()> {
22539 let use_prefix_not = is_null.not
22541 && (self.config.dialect.is_none()
22542 || self.config.dialect == Some(DialectType::Generic)
22543 || is_null.postfix_form);
22544 if use_prefix_not {
22545 self.write_keyword("NOT");
22547 self.write_space();
22548 self.generate_expression(&is_null.this)?;
22549 self.write_space();
22550 self.write_keyword("IS");
22551 self.write_space();
22552 self.write_keyword("NULL");
22553 } else {
22554 self.generate_expression(&is_null.this)?;
22555 self.write_space();
22556 self.write_keyword("IS");
22557 if is_null.not {
22558 self.write_space();
22559 self.write_keyword("NOT");
22560 }
22561 self.write_space();
22562 self.write_keyword("NULL");
22563 }
22564 Ok(())
22565 }
22566
22567 fn generate_is_true(&mut self, is_true: &IsTrueFalse) -> Result<()> {
22568 self.generate_expression(&is_true.this)?;
22569 self.write_space();
22570 self.write_keyword("IS");
22571 if is_true.not {
22572 self.write_space();
22573 self.write_keyword("NOT");
22574 }
22575 self.write_space();
22576 self.write_keyword("TRUE");
22577 Ok(())
22578 }
22579
22580 fn generate_is_false(&mut self, is_false: &IsTrueFalse) -> Result<()> {
22581 self.generate_expression(&is_false.this)?;
22582 self.write_space();
22583 self.write_keyword("IS");
22584 if is_false.not {
22585 self.write_space();
22586 self.write_keyword("NOT");
22587 }
22588 self.write_space();
22589 self.write_keyword("FALSE");
22590 Ok(())
22591 }
22592
22593 fn generate_is_json(&mut self, is_json: &IsJson) -> Result<()> {
22594 self.generate_expression(&is_json.this)?;
22595 self.write_space();
22596 self.write_keyword("IS");
22597 if is_json.negated {
22598 self.write_space();
22599 self.write_keyword("NOT");
22600 }
22601 self.write_space();
22602 self.write_keyword("JSON");
22603
22604 if let Some(ref json_type) = is_json.json_type {
22606 self.write_space();
22607 self.write_keyword(json_type);
22608 }
22609
22610 match &is_json.unique_keys {
22612 Some(JsonUniqueKeys::With) => {
22613 self.write_space();
22614 self.write_keyword("WITH UNIQUE KEYS");
22615 }
22616 Some(JsonUniqueKeys::Without) => {
22617 self.write_space();
22618 self.write_keyword("WITHOUT UNIQUE KEYS");
22619 }
22620 Some(JsonUniqueKeys::Shorthand) => {
22621 self.write_space();
22622 self.write_keyword("UNIQUE KEYS");
22623 }
22624 None => {}
22625 }
22626
22627 Ok(())
22628 }
22629
22630 fn generate_is(&mut self, is_expr: &BinaryOp) -> Result<()> {
22631 self.generate_expression(&is_expr.left)?;
22632 self.write_space();
22633 self.write_keyword("IS");
22634 self.write_space();
22635 self.generate_expression(&is_expr.right)
22636 }
22637
22638 fn generate_exists(&mut self, exists: &Exists) -> Result<()> {
22639 if exists.not {
22640 self.write_keyword("NOT");
22641 self.write_space();
22642 }
22643 self.write_keyword("EXISTS");
22644 self.write("(");
22645 let is_statement = matches!(
22646 &exists.this,
22647 Expression::Select(_)
22648 | Expression::Union(_)
22649 | Expression::Intersect(_)
22650 | Expression::Except(_)
22651 );
22652 if self.config.pretty && is_statement {
22653 self.write_newline();
22654 self.indent_level += 1;
22655 self.write_indent();
22656 self.generate_expression(&exists.this)?;
22657 self.write_newline();
22658 self.indent_level -= 1;
22659 self.write_indent();
22660 self.write(")");
22661 } else {
22662 self.generate_expression(&exists.this)?;
22663 self.write(")");
22664 }
22665 Ok(())
22666 }
22667
22668 fn generate_member_of(&mut self, op: &BinaryOp) -> Result<()> {
22669 self.generate_expression(&op.left)?;
22670 self.write_space();
22671 self.write_keyword("MEMBER OF");
22672 self.write("(");
22673 self.generate_expression(&op.right)?;
22674 self.write(")");
22675 Ok(())
22676 }
22677
22678 fn generate_subquery(&mut self, subquery: &Subquery) -> Result<()> {
22679 if subquery.lateral {
22680 self.write_keyword("LATERAL");
22681 self.write_space();
22682 }
22683
22684 let skip_outer_parens = if let Expression::Paren(ref p) = &subquery.this {
22688 matches!(
22689 &p.this,
22690 Expression::Select(_)
22691 | Expression::Union(_)
22692 | Expression::Intersect(_)
22693 | Expression::Except(_)
22694 | Expression::Subquery(_)
22695 )
22696 } else {
22697 false
22698 };
22699
22700 let is_statement = matches!(
22702 &subquery.this,
22703 Expression::Select(_)
22704 | Expression::Union(_)
22705 | Expression::Intersect(_)
22706 | Expression::Except(_)
22707 | Expression::Merge(_)
22708 );
22709
22710 if !skip_outer_parens {
22711 self.write("(");
22712 if self.config.pretty && is_statement {
22713 self.write_newline();
22714 self.indent_level += 1;
22715 self.write_indent();
22716 }
22717 }
22718 self.generate_expression(&subquery.this)?;
22719
22720 if subquery.modifiers_inside {
22722 if let Some(order_by) = &subquery.order_by {
22724 self.write_space();
22725 self.write_keyword("ORDER BY");
22726 self.write_space();
22727 for (i, ord) in order_by.expressions.iter().enumerate() {
22728 if i > 0 {
22729 self.write(", ");
22730 }
22731 self.generate_ordered(ord)?;
22732 }
22733 }
22734
22735 if let Some(limit) = &subquery.limit {
22736 self.write_space();
22737 self.write_keyword("LIMIT");
22738 self.write_space();
22739 self.generate_expression(&limit.this)?;
22740 if limit.percent {
22741 self.write_space();
22742 self.write_keyword("PERCENT");
22743 }
22744 }
22745
22746 if let Some(offset) = &subquery.offset {
22747 self.write_space();
22748 self.write_keyword("OFFSET");
22749 self.write_space();
22750 self.generate_expression(&offset.this)?;
22751 }
22752 }
22753
22754 if !skip_outer_parens {
22755 if self.config.pretty && is_statement {
22756 self.write_newline();
22757 self.indent_level -= 1;
22758 self.write_indent();
22759 }
22760 self.write(")");
22761 }
22762
22763 if !subquery.modifiers_inside {
22765 if let Some(order_by) = &subquery.order_by {
22766 self.write_space();
22767 self.write_keyword("ORDER BY");
22768 self.write_space();
22769 for (i, ord) in order_by.expressions.iter().enumerate() {
22770 if i > 0 {
22771 self.write(", ");
22772 }
22773 self.generate_ordered(ord)?;
22774 }
22775 }
22776
22777 if let Some(limit) = &subquery.limit {
22778 self.write_space();
22779 self.write_keyword("LIMIT");
22780 self.write_space();
22781 self.generate_expression(&limit.this)?;
22782 if limit.percent {
22783 self.write_space();
22784 self.write_keyword("PERCENT");
22785 }
22786 }
22787
22788 if let Some(offset) = &subquery.offset {
22789 self.write_space();
22790 self.write_keyword("OFFSET");
22791 self.write_space();
22792 self.generate_expression(&offset.this)?;
22793 }
22794
22795 if let Some(distribute_by) = &subquery.distribute_by {
22797 self.write_space();
22798 self.write_keyword("DISTRIBUTE BY");
22799 self.write_space();
22800 for (i, expr) in distribute_by.expressions.iter().enumerate() {
22801 if i > 0 {
22802 self.write(", ");
22803 }
22804 self.generate_expression(expr)?;
22805 }
22806 }
22807
22808 if let Some(sort_by) = &subquery.sort_by {
22810 self.write_space();
22811 self.write_keyword("SORT BY");
22812 self.write_space();
22813 for (i, ord) in sort_by.expressions.iter().enumerate() {
22814 if i > 0 {
22815 self.write(", ");
22816 }
22817 self.generate_ordered(ord)?;
22818 }
22819 }
22820
22821 if let Some(cluster_by) = &subquery.cluster_by {
22823 self.write_space();
22824 self.write_keyword("CLUSTER BY");
22825 self.write_space();
22826 for (i, ord) in cluster_by.expressions.iter().enumerate() {
22827 if i > 0 {
22828 self.write(", ");
22829 }
22830 self.generate_ordered(ord)?;
22831 }
22832 }
22833 }
22834
22835 if let Some(alias) = &subquery.alias {
22836 self.write_space();
22837 let skip_as = matches!(self.config.dialect, Some(DialectType::Oracle))
22838 || (matches!(self.config.dialect, Some(DialectType::ClickHouse))
22839 && !subquery.alias_explicit_as);
22840 if !skip_as {
22841 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
22842 self.write(subquery.alias_keyword.as_deref().unwrap_or("AS"));
22843 } else {
22844 self.write_keyword("AS");
22845 }
22846 self.write_space();
22847 }
22848 self.generate_identifier(alias)?;
22849 if !subquery.column_aliases.is_empty() {
22850 self.write("(");
22851 for (i, col) in subquery.column_aliases.iter().enumerate() {
22852 if i > 0 {
22853 self.write(", ");
22854 }
22855 self.generate_identifier(col)?;
22856 }
22857 self.write(")");
22858 }
22859 }
22860 for comment in &subquery.trailing_comments {
22862 self.write(" ");
22863 self.write_formatted_comment(comment);
22864 }
22865 Ok(())
22866 }
22867
22868 fn generate_pivot(&mut self, pivot: &Pivot) -> Result<()> {
22869 if let Some(ref with) = pivot.with {
22871 self.generate_with(with)?;
22872 self.write_space();
22873 }
22874
22875 let direction = if pivot.unpivot { "UNPIVOT" } else { "PIVOT" };
22876
22877 let is_redshift_unpivot = pivot.unpivot
22881 && pivot.expressions.is_empty()
22882 && pivot.fields.is_empty()
22883 && pivot.using.is_empty()
22884 && pivot.into.is_none()
22885 && !matches!(&pivot.this, Expression::Null(_));
22886
22887 if is_redshift_unpivot {
22888 self.write_keyword("UNPIVOT");
22890 self.write_space();
22891 self.generate_expression(&pivot.this)?;
22892 if let Some(alias) = &pivot.alias {
22894 self.write_space();
22895 self.write_keyword("AS");
22896 self.write_space();
22897 self.write(&alias.name);
22899 }
22900 return Ok(());
22901 }
22902
22903 let is_simplified = !pivot.using.is_empty()
22905 || pivot.into.is_some()
22906 || (pivot.fields.is_empty()
22907 && !pivot.expressions.is_empty()
22908 && !matches!(&pivot.this, Expression::Null(_)));
22909
22910 if is_simplified {
22911 self.write_keyword(direction);
22915 self.write_space();
22916 self.generate_expression(&pivot.this)?;
22917
22918 if !pivot.expressions.is_empty() {
22919 self.write_space();
22920 self.write_keyword("ON");
22921 self.write_space();
22922 for (i, expr) in pivot.expressions.iter().enumerate() {
22923 if i > 0 {
22924 self.write(", ");
22925 }
22926 self.generate_expression(expr)?;
22927 }
22928 }
22929
22930 if let Some(into) = &pivot.into {
22932 self.write_space();
22933 self.write_keyword("INTO");
22934 self.write_space();
22935 self.generate_expression(into)?;
22936 }
22937
22938 if !pivot.using.is_empty() {
22940 self.write_space();
22941 self.write_keyword("USING");
22942 self.write_space();
22943 for (i, expr) in pivot.using.iter().enumerate() {
22944 if i > 0 {
22945 self.write(", ");
22946 }
22947 self.generate_expression(expr)?;
22948 }
22949 }
22950
22951 if let Some(group) = &pivot.group {
22953 self.write_space();
22954 self.generate_expression(group)?;
22955 }
22956 } else {
22957 if !matches!(&pivot.this, Expression::Null(_)) {
22962 self.generate_expression(&pivot.this)?;
22963 self.write_space();
22964 }
22965 self.write_keyword(direction);
22966 self.write("(");
22967
22968 for (i, expr) in pivot.expressions.iter().enumerate() {
22970 if i > 0 {
22971 self.write(", ");
22972 }
22973 self.generate_expression(expr)?;
22974 }
22975
22976 if !pivot.fields.is_empty() {
22978 if !pivot.expressions.is_empty() {
22979 self.write_space();
22980 }
22981 self.write_keyword("FOR");
22982 self.write_space();
22983 for (i, field) in pivot.fields.iter().enumerate() {
22984 if i > 0 {
22985 self.write_space();
22986 }
22987 self.generate_expression(field)?;
22989 }
22990 }
22991
22992 if let Some(default_val) = &pivot.default_on_null {
22994 self.write_space();
22995 self.write_keyword("DEFAULT ON NULL");
22996 self.write(" (");
22997 self.generate_expression(default_val)?;
22998 self.write(")");
22999 }
23000
23001 if let Some(group) = &pivot.group {
23003 self.write_space();
23004 self.generate_expression(group)?;
23005 }
23006
23007 self.write(")");
23008 }
23009
23010 if let Some(alias) = &pivot.alias {
23012 self.write_space();
23013 self.write_keyword("AS");
23014 self.write_space();
23015 self.generate_identifier(alias)?;
23016 }
23017
23018 Ok(())
23019 }
23020
23021 fn generate_unpivot(&mut self, unpivot: &Unpivot) -> Result<()> {
23022 self.generate_expression(&unpivot.this)?;
23023 self.write_space();
23024 self.write_keyword("UNPIVOT");
23025 if let Some(include) = unpivot.include_nulls {
23027 self.write_space();
23028 if include {
23029 self.write_keyword("INCLUDE NULLS");
23030 } else {
23031 self.write_keyword("EXCLUDE NULLS");
23032 }
23033 self.write_space();
23034 }
23035 self.write("(");
23036 if unpivot.value_column_parenthesized {
23037 self.write("(");
23038 }
23039 self.generate_identifier(&unpivot.value_column)?;
23040 for extra_col in &unpivot.extra_value_columns {
23042 self.write(", ");
23043 self.generate_identifier(extra_col)?;
23044 }
23045 if unpivot.value_column_parenthesized {
23046 self.write(")");
23047 }
23048 self.write_space();
23049 self.write_keyword("FOR");
23050 self.write_space();
23051 self.generate_identifier(&unpivot.name_column)?;
23052 self.write_space();
23053 self.write_keyword("IN");
23054 self.write(" (");
23055 for (i, col) in unpivot.columns.iter().enumerate() {
23056 if i > 0 {
23057 self.write(", ");
23058 }
23059 self.generate_expression(col)?;
23060 }
23061 self.write("))");
23062 if let Some(alias) = &unpivot.alias {
23063 self.write_space();
23064 self.write_keyword("AS");
23065 self.write_space();
23066 self.generate_identifier(alias)?;
23067 }
23068 Ok(())
23069 }
23070
23071 fn generate_values(&mut self, values: &Values) -> Result<()> {
23072 self.write_keyword("VALUES");
23073 for (i, row) in values.expressions.iter().enumerate() {
23074 if i > 0 {
23075 self.write(",");
23076 }
23077 self.write(" (");
23078 for (j, expr) in row.expressions.iter().enumerate() {
23079 if j > 0 {
23080 self.write(", ");
23081 }
23082 self.generate_expression(expr)?;
23083 }
23084 self.write(")");
23085 }
23086 if let Some(alias) = &values.alias {
23087 self.write_space();
23088 self.write_keyword("AS");
23089 self.write_space();
23090 self.generate_identifier(alias)?;
23091 if !values.column_aliases.is_empty() {
23092 self.write("(");
23093 for (i, col) in values.column_aliases.iter().enumerate() {
23094 if i > 0 {
23095 self.write(", ");
23096 }
23097 self.generate_identifier(col)?;
23098 }
23099 self.write(")");
23100 }
23101 }
23102 Ok(())
23103 }
23104
23105 fn generate_array(&mut self, arr: &Array) -> Result<()> {
23106 let needs_inheritance = matches!(
23108 self.config.dialect,
23109 Some(DialectType::DuckDB)
23110 | Some(DialectType::Spark)
23111 | Some(DialectType::Databricks)
23112 | Some(DialectType::Hive)
23113 | Some(DialectType::Snowflake)
23114 | Some(DialectType::Presto)
23115 | Some(DialectType::Trino)
23116 );
23117 let propagated: Vec<Expression>;
23118 let expressions = if needs_inheritance && arr.expressions.len() > 1 {
23119 propagated = Self::inherit_struct_field_names(&arr.expressions);
23120 &propagated
23121 } else {
23122 &arr.expressions
23123 };
23124
23125 let use_parens =
23128 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
23129 if !self.config.array_bracket_only {
23130 self.write_keyword("ARRAY");
23131 }
23132 if use_parens {
23133 self.write("(");
23134 } else {
23135 self.write("[");
23136 }
23137 for (i, expr) in expressions.iter().enumerate() {
23138 if i > 0 {
23139 self.write(", ");
23140 }
23141 self.generate_expression(expr)?;
23142 }
23143 if use_parens {
23144 self.write(")");
23145 } else {
23146 self.write("]");
23147 }
23148 Ok(())
23149 }
23150
23151 fn generate_tuple(&mut self, tuple: &Tuple) -> Result<()> {
23152 if tuple.expressions.len() == 2 {
23155 if let Expression::TableAlias(_) = &tuple.expressions[1] {
23156 self.generate_expression(&tuple.expressions[0])?;
23158 self.write_space();
23159 self.write_keyword("AS");
23160 self.write_space();
23161 self.generate_expression(&tuple.expressions[1])?;
23162 return Ok(());
23163 }
23164 }
23165
23166 let expand_tuple = if self.config.pretty && tuple.expressions.len() > 1 {
23169 let mut expr_strings: Vec<String> = Vec::with_capacity(tuple.expressions.len());
23170 for expr in &tuple.expressions {
23171 expr_strings.push(self.generate_to_string(expr)?);
23172 }
23173 self.too_wide(&expr_strings)
23174 } else {
23175 false
23176 };
23177
23178 if expand_tuple {
23179 self.write("(");
23180 self.write_newline();
23181 self.indent_level += 1;
23182 for (i, expr) in tuple.expressions.iter().enumerate() {
23183 if i > 0 {
23184 self.write(",");
23185 self.write_newline();
23186 }
23187 self.write_indent();
23188 self.generate_expression(expr)?;
23189 }
23190 self.indent_level -= 1;
23191 self.write_newline();
23192 self.write_indent();
23193 self.write(")");
23194 } else {
23195 self.write("(");
23196 for (i, expr) in tuple.expressions.iter().enumerate() {
23197 if i > 0 {
23198 self.write(", ");
23199 }
23200 self.generate_expression(expr)?;
23201 }
23202 self.write(")");
23203 }
23204 Ok(())
23205 }
23206
23207 fn generate_pipe_operator(&mut self, pipe: &PipeOperator) -> Result<()> {
23208 self.generate_expression(&pipe.this)?;
23209 self.write(" |> ");
23210 self.generate_expression(&pipe.expression)?;
23211 Ok(())
23212 }
23213
23214 fn generate_ordered(&mut self, ordered: &Ordered) -> Result<()> {
23215 self.generate_expression(&ordered.this)?;
23216 if ordered.desc {
23217 self.write_space();
23218 self.write_keyword("DESC");
23219 } else if ordered.explicit_asc {
23220 self.write_space();
23221 self.write_keyword("ASC");
23222 }
23223 if let Some(nulls_first) = ordered.nulls_first {
23224 if self.config.null_ordering_supported
23225 || !matches!(self.config.dialect, Some(DialectType::Fabric))
23226 {
23227 let is_asc = !ordered.desc;
23241 let is_nulls_are_large = matches!(
23242 self.config.dialect,
23243 Some(DialectType::Oracle)
23244 | Some(DialectType::PostgreSQL)
23245 | Some(DialectType::Redshift)
23246 | Some(DialectType::Snowflake)
23247 );
23248 let is_nulls_are_last = matches!(
23249 self.config.dialect,
23250 Some(DialectType::Dremio)
23251 | Some(DialectType::DuckDB)
23252 | Some(DialectType::Presto)
23253 | Some(DialectType::Trino)
23254 | Some(DialectType::Athena)
23255 | Some(DialectType::ClickHouse)
23256 | Some(DialectType::Drill)
23257 | Some(DialectType::Exasol)
23258 );
23259
23260 let is_default_nulls = if is_nulls_are_large {
23262 (is_asc && !nulls_first) || (!is_asc && nulls_first)
23264 } else if is_nulls_are_last {
23265 !nulls_first
23267 } else {
23268 false
23269 };
23270
23271 if !is_default_nulls {
23272 self.write_space();
23273 self.write_keyword("NULLS");
23274 self.write_space();
23275 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
23276 }
23277 }
23278 }
23279 if let Some(ref with_fill) = ordered.with_fill {
23281 self.write_space();
23282 self.generate_with_fill(with_fill)?;
23283 }
23284 Ok(())
23285 }
23286
23287 fn write_clickhouse_type(&mut self, type_str: &str) {
23289 if self.clickhouse_nullable_depth < 0 {
23290 self.write(type_str);
23292 } else {
23293 self.write(&format!("Nullable({})", type_str));
23294 }
23295 }
23296
23297 fn generate_data_type(&mut self, dt: &DataType) -> Result<()> {
23298 use crate::dialects::DialectType;
23299
23300 match dt {
23301 DataType::Boolean => {
23302 match self.config.dialect {
23304 Some(DialectType::TSQL) => self.write_keyword("BIT"),
23305 Some(DialectType::MySQL) => self.write_keyword("BOOLEAN"), Some(DialectType::Oracle) => {
23307 self.write_keyword("NUMBER(1)")
23309 }
23310 Some(DialectType::ClickHouse) => self.write("Bool"), _ => self.write_keyword("BOOLEAN"),
23312 }
23313 }
23314 DataType::TinyInt { length } => {
23315 match self.config.dialect {
23319 Some(DialectType::PostgreSQL)
23320 | Some(DialectType::Redshift)
23321 | Some(DialectType::Oracle)
23322 | Some(DialectType::Exasol) => {
23323 self.write_keyword("SMALLINT");
23324 }
23325 Some(DialectType::Teradata) => {
23326 self.write_keyword("BYTEINT");
23328 }
23329 Some(DialectType::Dremio) => {
23330 self.write_keyword("INT");
23332 }
23333 Some(DialectType::ClickHouse) => {
23334 self.write_clickhouse_type("Int8");
23335 }
23336 _ => {
23337 self.write_keyword("TINYINT");
23338 }
23339 }
23340 if let Some(n) = length {
23341 if !matches!(
23342 self.config.dialect,
23343 Some(DialectType::Dremio) | Some(DialectType::ClickHouse)
23344 ) {
23345 self.write(&format!("({})", n));
23346 }
23347 }
23348 }
23349 DataType::SmallInt { length } => {
23350 match self.config.dialect {
23352 Some(DialectType::Dremio) => {
23353 self.write_keyword("INT");
23354 }
23355 Some(DialectType::SQLite) | Some(DialectType::Drill) => {
23356 self.write_keyword("INTEGER");
23357 }
23358 Some(DialectType::BigQuery) => {
23359 self.write_keyword("INT64");
23360 }
23361 Some(DialectType::ClickHouse) => {
23362 self.write_clickhouse_type("Int16");
23363 }
23364 _ => {
23365 self.write_keyword("SMALLINT");
23366 if let Some(n) = length {
23367 self.write(&format!("({})", n));
23368 }
23369 }
23370 }
23371 }
23372 DataType::Int {
23373 length,
23374 integer_spelling: _,
23375 } => {
23376 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
23378 self.write_keyword("INT64");
23379 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23380 self.write_clickhouse_type("Int32");
23381 } else {
23382 let use_integer = match self.config.dialect {
23384 Some(DialectType::TSQL)
23385 | Some(DialectType::Fabric)
23386 | Some(DialectType::Presto)
23387 | Some(DialectType::Trino)
23388 | Some(DialectType::SQLite)
23389 | Some(DialectType::Redshift) => true,
23390 _ => false,
23391 };
23392 if use_integer {
23393 self.write_keyword("INTEGER");
23394 } else {
23395 self.write_keyword("INT");
23396 }
23397 if let Some(n) = length {
23398 self.write(&format!("({})", n));
23399 }
23400 }
23401 }
23402 DataType::BigInt { length } => {
23403 match self.config.dialect {
23405 Some(DialectType::Oracle) => {
23406 self.write_keyword("INT");
23408 }
23409 Some(DialectType::ClickHouse) => {
23410 self.write_clickhouse_type("Int64");
23411 }
23412 _ => {
23413 self.write_keyword("BIGINT");
23414 if let Some(n) = length {
23415 self.write(&format!("({})", n));
23416 }
23417 }
23418 }
23419 }
23420 DataType::Float {
23421 precision,
23422 scale,
23423 real_spelling,
23424 } => {
23425 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23429 self.write_clickhouse_type("Float32");
23430 } else if *real_spelling
23431 && !matches!(
23432 self.config.dialect,
23433 Some(DialectType::Spark)
23434 | Some(DialectType::Databricks)
23435 | Some(DialectType::Hive)
23436 | Some(DialectType::Snowflake)
23437 | Some(DialectType::MySQL)
23438 | Some(DialectType::BigQuery)
23439 )
23440 {
23441 self.write_keyword("REAL")
23442 } else {
23443 match self.config.dialect {
23444 Some(DialectType::PostgreSQL) => self.write_keyword("REAL"),
23445 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
23446 _ => self.write_keyword("FLOAT"),
23447 }
23448 }
23449 if !matches!(
23452 self.config.dialect,
23453 Some(DialectType::Spark)
23454 | Some(DialectType::Databricks)
23455 | Some(DialectType::Hive)
23456 | Some(DialectType::Presto)
23457 | Some(DialectType::Trino)
23458 ) {
23459 if let Some(p) = precision {
23460 self.write(&format!("({}", p));
23461 if let Some(s) = scale {
23462 self.write(&format!(", {})", s));
23463 } else {
23464 self.write(")");
23465 }
23466 }
23467 }
23468 }
23469 DataType::Double { precision, scale } => {
23470 match self.config.dialect {
23472 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23473 self.write_keyword("FLOAT")
23474 } Some(DialectType::Oracle) => self.write_keyword("DOUBLE PRECISION"),
23476 Some(DialectType::ClickHouse) => self.write_clickhouse_type("Float64"),
23477 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
23478 Some(DialectType::SQLite) => self.write_keyword("REAL"),
23479 Some(DialectType::PostgreSQL)
23480 | Some(DialectType::Redshift)
23481 | Some(DialectType::Teradata)
23482 | Some(DialectType::Materialize) => self.write_keyword("DOUBLE PRECISION"),
23483 _ => self.write_keyword("DOUBLE"),
23484 }
23485 if let Some(p) = precision {
23487 self.write(&format!("({}", p));
23488 if let Some(s) = scale {
23489 self.write(&format!(", {})", s));
23490 } else {
23491 self.write(")");
23492 }
23493 }
23494 }
23495 DataType::Decimal { precision, scale } => {
23496 match self.config.dialect {
23498 Some(DialectType::ClickHouse) => {
23499 self.write("Decimal");
23500 if let Some(p) = precision {
23501 self.write(&format!("({}", p));
23502 if let Some(s) = scale {
23503 self.write(&format!(", {}", s));
23504 }
23505 self.write(")");
23506 }
23507 }
23508 Some(DialectType::Oracle) => {
23509 self.write_keyword("NUMBER");
23511 if let Some(p) = precision {
23512 self.write(&format!("({}", p));
23513 if let Some(s) = scale {
23514 self.write(&format!(", {}", s));
23515 }
23516 self.write(")");
23517 }
23518 }
23519 Some(DialectType::BigQuery) => {
23520 self.write_keyword("NUMERIC");
23522 if let Some(p) = precision {
23523 self.write(&format!("({}", p));
23524 if let Some(s) = scale {
23525 self.write(&format!(", {}", s));
23526 }
23527 self.write(")");
23528 }
23529 }
23530 _ => {
23531 self.write_keyword("DECIMAL");
23532 if let Some(p) = precision {
23533 self.write(&format!("({}", p));
23534 if let Some(s) = scale {
23535 self.write(&format!(", {}", s));
23536 }
23537 self.write(")");
23538 }
23539 }
23540 }
23541 }
23542 DataType::Char { length } => {
23543 match self.config.dialect {
23545 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
23546 self.write_keyword("TEXT");
23548 }
23549 Some(DialectType::Hive)
23550 | Some(DialectType::Spark)
23551 | Some(DialectType::Databricks) => {
23552 if length.is_some()
23555 && !matches!(self.config.dialect, Some(DialectType::Hive))
23556 {
23557 self.write_keyword("CHAR");
23558 if let Some(n) = length {
23559 self.write(&format!("({})", n));
23560 }
23561 } else {
23562 self.write_keyword("STRING");
23563 }
23564 }
23565 Some(DialectType::Dremio) => {
23566 self.write_keyword("VARCHAR");
23568 if let Some(n) = length {
23569 self.write(&format!("({})", n));
23570 }
23571 }
23572 _ => {
23573 self.write_keyword("CHAR");
23574 if let Some(n) = length {
23575 self.write(&format!("({})", n));
23576 }
23577 }
23578 }
23579 }
23580 DataType::VarChar {
23581 length,
23582 parenthesized_length,
23583 } => {
23584 match self.config.dialect {
23586 Some(DialectType::Oracle) => {
23587 self.write_keyword("VARCHAR2");
23588 if let Some(n) = length {
23589 self.write(&format!("({})", n));
23590 }
23591 }
23592 Some(DialectType::DuckDB) => {
23593 self.write_keyword("TEXT");
23595 if let Some(n) = length {
23596 self.write(&format!("({})", n));
23597 }
23598 }
23599 Some(DialectType::SQLite) => {
23600 self.write_keyword("TEXT");
23602 if let Some(n) = length {
23603 self.write(&format!("({})", n));
23604 }
23605 }
23606 Some(DialectType::MySQL) if length.is_none() => {
23607 self.write_keyword("TEXT");
23609 }
23610 Some(DialectType::Hive)
23611 | Some(DialectType::Spark)
23612 | Some(DialectType::Databricks)
23613 if length.is_none() =>
23614 {
23615 self.write_keyword("STRING");
23617 }
23618 _ => {
23619 self.write_keyword("VARCHAR");
23620 if let Some(n) = length {
23621 if *parenthesized_length {
23623 self.write(&format!("(({}))", n));
23624 } else {
23625 self.write(&format!("({})", n));
23626 }
23627 }
23628 }
23629 }
23630 }
23631 DataType::Text => {
23632 match self.config.dialect {
23634 Some(DialectType::Oracle) => self.write_keyword("CLOB"),
23635 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23636 self.write_keyword("VARCHAR(MAX)")
23637 }
23638 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
23639 Some(DialectType::Snowflake)
23640 | Some(DialectType::Dremio)
23641 | Some(DialectType::Drill) => self.write_keyword("VARCHAR"),
23642 Some(DialectType::Exasol) => self.write_keyword("LONG VARCHAR"),
23643 Some(DialectType::Presto)
23644 | Some(DialectType::Trino)
23645 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
23646 Some(DialectType::Spark)
23647 | Some(DialectType::Databricks)
23648 | Some(DialectType::Hive) => self.write_keyword("STRING"),
23649 Some(DialectType::Redshift) => self.write_keyword("VARCHAR(MAX)"),
23650 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
23651 self.write_keyword("STRING")
23652 }
23653 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
23654 _ => self.write_keyword("TEXT"),
23655 }
23656 }
23657 DataType::TextWithLength { length } => {
23658 match self.config.dialect {
23660 Some(DialectType::Oracle) => self.write(&format!("CLOB({})", length)),
23661 Some(DialectType::Hive)
23662 | Some(DialectType::Spark)
23663 | Some(DialectType::Databricks) => {
23664 self.write(&format!("VARCHAR({})", length));
23665 }
23666 Some(DialectType::Redshift) => self.write(&format!("VARCHAR({})", length)),
23667 Some(DialectType::BigQuery) => self.write(&format!("STRING({})", length)),
23668 Some(DialectType::Snowflake)
23669 | Some(DialectType::Presto)
23670 | Some(DialectType::Trino)
23671 | Some(DialectType::Athena)
23672 | Some(DialectType::Drill)
23673 | Some(DialectType::Dremio) => {
23674 self.write(&format!("VARCHAR({})", length));
23675 }
23676 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23677 self.write(&format!("VARCHAR({})", length))
23678 }
23679 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
23680 self.write(&format!("STRING({})", length))
23681 }
23682 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
23683 _ => self.write(&format!("TEXT({})", length)),
23684 }
23685 }
23686 DataType::String { length } => {
23687 match self.config.dialect {
23689 Some(DialectType::ClickHouse) => {
23690 self.write("String");
23692 if let Some(n) = length {
23693 self.write(&format!("({})", n));
23694 }
23695 }
23696 Some(DialectType::BigQuery)
23697 | Some(DialectType::Hive)
23698 | Some(DialectType::Spark)
23699 | Some(DialectType::Databricks)
23700 | Some(DialectType::StarRocks)
23701 | Some(DialectType::Doris) => {
23702 self.write_keyword("STRING");
23703 if let Some(n) = length {
23704 self.write(&format!("({})", n));
23705 }
23706 }
23707 Some(DialectType::PostgreSQL) => {
23708 if let Some(n) = length {
23710 self.write_keyword("VARCHAR");
23711 self.write(&format!("({})", n));
23712 } else {
23713 self.write_keyword("TEXT");
23714 }
23715 }
23716 Some(DialectType::Redshift) => {
23717 if let Some(n) = length {
23719 self.write_keyword("VARCHAR");
23720 self.write(&format!("({})", n));
23721 } else {
23722 self.write_keyword("VARCHAR(MAX)");
23723 }
23724 }
23725 Some(DialectType::MySQL) => {
23726 if let Some(n) = length {
23728 self.write_keyword("VARCHAR");
23729 self.write(&format!("({})", n));
23730 } else {
23731 self.write_keyword("TEXT");
23732 }
23733 }
23734 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23735 if let Some(n) = length {
23737 self.write_keyword("VARCHAR");
23738 self.write(&format!("({})", n));
23739 } else {
23740 self.write_keyword("VARCHAR(MAX)");
23741 }
23742 }
23743 Some(DialectType::Oracle) => {
23744 self.write_keyword("CLOB");
23746 }
23747 Some(DialectType::DuckDB) | Some(DialectType::Materialize) => {
23748 self.write_keyword("TEXT");
23750 if let Some(n) = length {
23751 self.write(&format!("({})", n));
23752 }
23753 }
23754 Some(DialectType::Presto)
23755 | Some(DialectType::Trino)
23756 | Some(DialectType::Drill)
23757 | Some(DialectType::Dremio) => {
23758 self.write_keyword("VARCHAR");
23760 if let Some(n) = length {
23761 self.write(&format!("({})", n));
23762 }
23763 }
23764 Some(DialectType::Snowflake) => {
23765 self.write_keyword("STRING");
23768 if let Some(n) = length {
23769 self.write(&format!("({})", n));
23770 }
23771 }
23772 _ => {
23773 self.write_keyword("STRING");
23775 if let Some(n) = length {
23776 self.write(&format!("({})", n));
23777 }
23778 }
23779 }
23780 }
23781 DataType::Binary { length } => {
23782 match self.config.dialect {
23784 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
23785 self.write_keyword("BYTEA");
23786 if let Some(n) = length {
23787 self.write(&format!("({})", n));
23788 }
23789 }
23790 Some(DialectType::Redshift) => {
23791 self.write_keyword("VARBYTE");
23792 if let Some(n) = length {
23793 self.write(&format!("({})", n));
23794 }
23795 }
23796 Some(DialectType::DuckDB)
23797 | Some(DialectType::SQLite)
23798 | Some(DialectType::Oracle) => {
23799 self.write_keyword("BLOB");
23801 if let Some(n) = length {
23802 self.write(&format!("({})", n));
23803 }
23804 }
23805 Some(DialectType::Presto)
23806 | Some(DialectType::Trino)
23807 | Some(DialectType::Athena)
23808 | Some(DialectType::Drill)
23809 | Some(DialectType::Dremio) => {
23810 self.write_keyword("VARBINARY");
23812 if let Some(n) = length {
23813 self.write(&format!("({})", n));
23814 }
23815 }
23816 Some(DialectType::ClickHouse) => {
23817 if self.clickhouse_nullable_depth < 0 {
23819 self.write("BINARY");
23820 } else {
23821 self.write("Nullable(BINARY");
23822 }
23823 if let Some(n) = length {
23824 self.write(&format!("({})", n));
23825 }
23826 if self.clickhouse_nullable_depth >= 0 {
23827 self.write(")");
23828 }
23829 }
23830 _ => {
23831 self.write_keyword("BINARY");
23832 if let Some(n) = length {
23833 self.write(&format!("({})", n));
23834 }
23835 }
23836 }
23837 }
23838 DataType::VarBinary { length } => {
23839 match self.config.dialect {
23841 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
23842 self.write_keyword("BYTEA");
23843 if let Some(n) = length {
23844 self.write(&format!("({})", n));
23845 }
23846 }
23847 Some(DialectType::Redshift) => {
23848 self.write_keyword("VARBYTE");
23849 if let Some(n) = length {
23850 self.write(&format!("({})", n));
23851 }
23852 }
23853 Some(DialectType::DuckDB)
23854 | Some(DialectType::SQLite)
23855 | Some(DialectType::Oracle) => {
23856 self.write_keyword("BLOB");
23858 if let Some(n) = length {
23859 self.write(&format!("({})", n));
23860 }
23861 }
23862 Some(DialectType::Exasol) => {
23863 self.write_keyword("VARCHAR");
23865 }
23866 Some(DialectType::Spark)
23867 | Some(DialectType::Hive)
23868 | Some(DialectType::Databricks) => {
23869 self.write_keyword("BINARY");
23871 if let Some(n) = length {
23872 self.write(&format!("({})", n));
23873 }
23874 }
23875 Some(DialectType::ClickHouse) => {
23876 self.write_clickhouse_type("String");
23878 }
23879 _ => {
23880 self.write_keyword("VARBINARY");
23881 if let Some(n) = length {
23882 self.write(&format!("({})", n));
23883 }
23884 }
23885 }
23886 }
23887 DataType::Blob => {
23888 match self.config.dialect {
23890 Some(DialectType::PostgreSQL) => self.write_keyword("BYTEA"),
23891 Some(DialectType::Redshift) => self.write_keyword("VARBYTE"),
23892 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23893 self.write_keyword("VARBINARY")
23894 }
23895 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
23896 Some(DialectType::Exasol) => self.write_keyword("VARCHAR"),
23897 Some(DialectType::Presto)
23898 | Some(DialectType::Trino)
23899 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
23900 Some(DialectType::DuckDB) => {
23901 self.write_keyword("VARBINARY");
23904 }
23905 Some(DialectType::Spark)
23906 | Some(DialectType::Databricks)
23907 | Some(DialectType::Hive) => self.write_keyword("BINARY"),
23908 Some(DialectType::ClickHouse) => {
23909 self.write("Nullable(String)");
23913 }
23914 _ => self.write_keyword("BLOB"),
23915 }
23916 }
23917 DataType::Bit { length } => {
23918 match self.config.dialect {
23920 Some(DialectType::Dremio)
23921 | Some(DialectType::Spark)
23922 | Some(DialectType::Databricks)
23923 | Some(DialectType::Hive)
23924 | Some(DialectType::Snowflake)
23925 | Some(DialectType::BigQuery)
23926 | Some(DialectType::Presto)
23927 | Some(DialectType::Trino)
23928 | Some(DialectType::ClickHouse)
23929 | Some(DialectType::Redshift) => {
23930 self.write_keyword("BOOLEAN");
23932 }
23933 _ => {
23934 self.write_keyword("BIT");
23935 if let Some(n) = length {
23936 self.write(&format!("({})", n));
23937 }
23938 }
23939 }
23940 }
23941 DataType::VarBit { length } => {
23942 self.write_keyword("VARBIT");
23943 if let Some(n) = length {
23944 self.write(&format!("({})", n));
23945 }
23946 }
23947 DataType::Date => self.write_keyword("DATE"),
23948 DataType::Time {
23949 precision,
23950 timezone,
23951 } => {
23952 if *timezone {
23953 match self.config.dialect {
23955 Some(DialectType::DuckDB) => {
23956 self.write_keyword("TIMETZ");
23958 }
23959 Some(DialectType::PostgreSQL) => {
23960 self.write_keyword("TIMETZ");
23962 if let Some(p) = precision {
23963 self.write(&format!("({})", p));
23964 }
23965 }
23966 _ => {
23967 self.write_keyword("TIME");
23969 if let Some(p) = precision {
23970 self.write(&format!("({})", p));
23971 }
23972 self.write_keyword(" WITH TIME ZONE");
23973 }
23974 }
23975 } else {
23976 if matches!(
23978 self.config.dialect,
23979 Some(DialectType::Spark)
23980 | Some(DialectType::Databricks)
23981 | Some(DialectType::Hive)
23982 ) {
23983 self.write_keyword("TIMESTAMP");
23984 } else {
23985 self.write_keyword("TIME");
23986 if let Some(p) = precision {
23987 self.write(&format!("({})", p));
23988 }
23989 }
23990 }
23991 }
23992 DataType::Timestamp {
23993 precision,
23994 timezone,
23995 } => {
23996 match self.config.dialect {
23998 Some(DialectType::ClickHouse) => {
23999 self.write("DateTime");
24000 if let Some(p) = precision {
24001 self.write(&format!("({})", p));
24002 }
24003 }
24004 Some(DialectType::TSQL) => {
24005 if *timezone {
24006 self.write_keyword("DATETIMEOFFSET");
24007 } else {
24008 self.write_keyword("DATETIME2");
24009 }
24010 if let Some(p) = precision {
24011 self.write(&format!("({})", p));
24012 }
24013 }
24014 Some(DialectType::MySQL) => {
24015 self.write_keyword("TIMESTAMP");
24017 if let Some(p) = precision {
24018 self.write(&format!("({})", p));
24019 }
24020 }
24021 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
24022 self.write_keyword("DATETIME");
24024 if let Some(p) = precision {
24025 self.write(&format!("({})", p));
24026 }
24027 }
24028 Some(DialectType::BigQuery) => {
24029 if *timezone {
24031 self.write_keyword("TIMESTAMP");
24032 } else {
24033 self.write_keyword("DATETIME");
24034 }
24035 }
24036 Some(DialectType::DuckDB) => {
24037 if *timezone {
24039 self.write_keyword("TIMESTAMPTZ");
24040 } else {
24041 self.write_keyword("TIMESTAMP");
24042 if let Some(p) = precision {
24043 self.write(&format!("({})", p));
24044 }
24045 }
24046 }
24047 _ => {
24048 if *timezone && !self.config.tz_to_with_time_zone {
24049 self.write_keyword("TIMESTAMPTZ");
24051 if let Some(p) = precision {
24052 self.write(&format!("({})", p));
24053 }
24054 } else {
24055 self.write_keyword("TIMESTAMP");
24056 if let Some(p) = precision {
24057 self.write(&format!("({})", p));
24058 }
24059 if *timezone {
24060 self.write_space();
24061 self.write_keyword("WITH TIME ZONE");
24062 }
24063 }
24064 }
24065 }
24066 }
24067 DataType::Interval { unit, to } => {
24068 self.write_keyword("INTERVAL");
24069 if let Some(u) = unit {
24070 self.write_space();
24071 self.write_keyword(u);
24072 }
24073 if let Some(t) = to {
24075 self.write_space();
24076 self.write_keyword("TO");
24077 self.write_space();
24078 self.write_keyword(t);
24079 }
24080 }
24081 DataType::Json => {
24082 match self.config.dialect {
24084 Some(DialectType::Oracle) => self.write_keyword("JSON"), Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"), Some(DialectType::MySQL) => self.write_keyword("JSON"),
24087 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
24088 _ => self.write_keyword("JSON"),
24089 }
24090 }
24091 DataType::JsonB => {
24092 match self.config.dialect {
24094 Some(DialectType::PostgreSQL) => self.write_keyword("JSONB"),
24095 Some(DialectType::Doris) => self.write_keyword("JSONB"),
24096 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
24097 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
24098 Some(DialectType::DuckDB) => self.write_keyword("JSON"), _ => self.write_keyword("JSON"), }
24101 }
24102 DataType::Uuid => {
24103 match self.config.dialect {
24105 Some(DialectType::TSQL) => self.write_keyword("UNIQUEIDENTIFIER"),
24106 Some(DialectType::MySQL) => self.write_keyword("CHAR(36)"),
24107 Some(DialectType::Oracle) => self.write_keyword("RAW(16)"),
24108 Some(DialectType::BigQuery)
24109 | Some(DialectType::Spark)
24110 | Some(DialectType::Databricks) => self.write_keyword("STRING"),
24111 _ => self.write_keyword("UUID"),
24112 }
24113 }
24114 DataType::Array {
24115 element_type,
24116 dimension,
24117 } => {
24118 match self.config.dialect {
24120 Some(DialectType::PostgreSQL)
24121 | Some(DialectType::Redshift)
24122 | Some(DialectType::DuckDB) => {
24123 self.generate_data_type(element_type)?;
24125 if let Some(dim) = dimension {
24126 self.write(&format!("[{}]", dim));
24127 } else {
24128 self.write("[]");
24129 }
24130 }
24131 Some(DialectType::BigQuery) => {
24132 self.write_keyword("ARRAY<");
24133 self.generate_data_type(element_type)?;
24134 self.write(">");
24135 }
24136 Some(DialectType::Snowflake)
24137 | Some(DialectType::Presto)
24138 | Some(DialectType::Trino)
24139 | Some(DialectType::ClickHouse) => {
24140 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
24142 self.write("Array(");
24143 } else {
24144 self.write_keyword("ARRAY(");
24145 }
24146 self.generate_data_type(element_type)?;
24147 self.write(")");
24148 }
24149 Some(DialectType::TSQL)
24150 | Some(DialectType::MySQL)
24151 | Some(DialectType::Oracle) => {
24152 match self.config.dialect {
24155 Some(DialectType::MySQL) => self.write_keyword("JSON"),
24156 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
24157 _ => self.write_keyword("JSON"),
24158 }
24159 }
24160 _ => {
24161 self.write_keyword("ARRAY<");
24163 self.generate_data_type(element_type)?;
24164 self.write(">");
24165 }
24166 }
24167 }
24168 DataType::List { element_type } => {
24169 self.generate_data_type(element_type)?;
24171 self.write_keyword(" LIST");
24172 }
24173 DataType::Map {
24174 key_type,
24175 value_type,
24176 } => {
24177 match self.config.dialect {
24179 Some(DialectType::Materialize) => {
24180 self.write_keyword("MAP[");
24182 self.generate_data_type(key_type)?;
24183 self.write(" => ");
24184 self.generate_data_type(value_type)?;
24185 self.write("]");
24186 }
24187 Some(DialectType::Snowflake)
24188 | Some(DialectType::RisingWave)
24189 | Some(DialectType::DuckDB)
24190 | Some(DialectType::Presto)
24191 | Some(DialectType::Trino)
24192 | Some(DialectType::Athena) => {
24193 self.write_keyword("MAP(");
24194 self.generate_data_type(key_type)?;
24195 self.write(", ");
24196 self.generate_data_type(value_type)?;
24197 self.write(")");
24198 }
24199 Some(DialectType::ClickHouse) => {
24200 self.write("Map(");
24203 self.clickhouse_nullable_depth = -1; self.generate_data_type(key_type)?;
24205 self.clickhouse_nullable_depth = 0;
24206 self.write(", ");
24207 self.generate_data_type(value_type)?;
24208 self.write(")");
24209 }
24210 _ => {
24211 self.write_keyword("MAP<");
24212 self.generate_data_type(key_type)?;
24213 self.write(", ");
24214 self.generate_data_type(value_type)?;
24215 self.write(">");
24216 }
24217 }
24218 }
24219 DataType::Vector {
24220 element_type,
24221 dimension,
24222 } => {
24223 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
24224 self.write_keyword("VECTOR(");
24226 if let Some(dim) = dimension {
24227 self.write(&dim.to_string());
24228 }
24229 let type_alias = element_type.as_ref().and_then(|et| match et.as_ref() {
24231 DataType::TinyInt { .. } => Some("I8"),
24232 DataType::SmallInt { .. } => Some("I16"),
24233 DataType::Int { .. } => Some("I32"),
24234 DataType::BigInt { .. } => Some("I64"),
24235 DataType::Float { .. } => Some("F32"),
24236 DataType::Double { .. } => Some("F64"),
24237 _ => None,
24238 });
24239 if let Some(alias) = type_alias {
24240 if dimension.is_some() {
24241 self.write(", ");
24242 }
24243 self.write(alias);
24244 }
24245 self.write(")");
24246 } else {
24247 self.write_keyword("VECTOR(");
24249 if let Some(ref et) = element_type {
24250 self.generate_data_type(et)?;
24251 if dimension.is_some() {
24252 self.write(", ");
24253 }
24254 }
24255 if let Some(dim) = dimension {
24256 self.write(&dim.to_string());
24257 }
24258 self.write(")");
24259 }
24260 }
24261 DataType::Object { fields, modifier } => {
24262 self.write_keyword("OBJECT(");
24263 for (i, (name, dt, not_null)) in fields.iter().enumerate() {
24264 if i > 0 {
24265 self.write(", ");
24266 }
24267 self.write(name);
24268 self.write(" ");
24269 self.generate_data_type(dt)?;
24270 if *not_null {
24271 self.write_keyword(" NOT NULL");
24272 }
24273 }
24274 self.write(")");
24275 if let Some(mod_str) = modifier {
24276 self.write(" ");
24277 self.write_keyword(mod_str);
24278 }
24279 }
24280 DataType::Struct { fields, nested } => {
24281 match self.config.dialect {
24283 Some(DialectType::Snowflake) => {
24284 self.write_keyword("OBJECT(");
24286 for (i, field) in fields.iter().enumerate() {
24287 if i > 0 {
24288 self.write(", ");
24289 }
24290 if !field.name.is_empty() {
24291 self.write(&field.name);
24292 self.write(" ");
24293 }
24294 self.generate_data_type(&field.data_type)?;
24295 }
24296 self.write(")");
24297 }
24298 Some(DialectType::Presto) | Some(DialectType::Trino) => {
24299 self.write_keyword("ROW(");
24301 for (i, field) in fields.iter().enumerate() {
24302 if i > 0 {
24303 self.write(", ");
24304 }
24305 if !field.name.is_empty() {
24306 self.write(&field.name);
24307 self.write(" ");
24308 }
24309 self.generate_data_type(&field.data_type)?;
24310 }
24311 self.write(")");
24312 }
24313 Some(DialectType::DuckDB) => {
24314 self.write_keyword("STRUCT(");
24316 for (i, field) in fields.iter().enumerate() {
24317 if i > 0 {
24318 self.write(", ");
24319 }
24320 if !field.name.is_empty() {
24321 self.write(&field.name);
24322 self.write(" ");
24323 }
24324 self.generate_data_type(&field.data_type)?;
24325 }
24326 self.write(")");
24327 }
24328 Some(DialectType::ClickHouse) => {
24329 self.write("Tuple(");
24331 for (i, field) in fields.iter().enumerate() {
24332 if i > 0 {
24333 self.write(", ");
24334 }
24335 if !field.name.is_empty() {
24336 self.write(&field.name);
24337 self.write(" ");
24338 }
24339 self.generate_data_type(&field.data_type)?;
24340 }
24341 self.write(")");
24342 }
24343 Some(DialectType::SingleStore) => {
24344 self.write_keyword("RECORD(");
24346 for (i, field) in fields.iter().enumerate() {
24347 if i > 0 {
24348 self.write(", ");
24349 }
24350 if !field.name.is_empty() {
24351 self.write(&field.name);
24352 self.write(" ");
24353 }
24354 self.generate_data_type(&field.data_type)?;
24355 }
24356 self.write(")");
24357 }
24358 _ => {
24359 let force_angle_brackets = matches!(
24361 self.config.dialect,
24362 Some(DialectType::Hive)
24363 | Some(DialectType::Spark)
24364 | Some(DialectType::Databricks)
24365 );
24366 if *nested && !force_angle_brackets {
24367 self.write_keyword("STRUCT(");
24368 for (i, field) in fields.iter().enumerate() {
24369 if i > 0 {
24370 self.write(", ");
24371 }
24372 if !field.name.is_empty() {
24373 self.write(&field.name);
24374 self.write(" ");
24375 }
24376 self.generate_data_type(&field.data_type)?;
24377 }
24378 self.write(")");
24379 } else {
24380 self.write_keyword("STRUCT<");
24381 for (i, field) in fields.iter().enumerate() {
24382 if i > 0 {
24383 self.write(", ");
24384 }
24385 if !field.name.is_empty() {
24386 self.write(&field.name);
24388 self.write(self.config.struct_field_sep);
24389 }
24390 self.generate_data_type(&field.data_type)?;
24392 if let Some(comment) = &field.comment {
24394 self.write(" COMMENT '");
24395 self.write(comment);
24396 self.write("'");
24397 }
24398 if !field.options.is_empty() {
24400 self.write(" ");
24401 self.generate_options_clause(&field.options)?;
24402 }
24403 }
24404 self.write(">");
24405 }
24406 }
24407 }
24408 }
24409 DataType::Enum {
24410 values,
24411 assignments,
24412 } => {
24413 if self.config.dialect == Some(DialectType::ClickHouse) {
24416 self.write("Enum(");
24417 } else {
24418 self.write_keyword("ENUM(");
24419 }
24420 for (i, val) in values.iter().enumerate() {
24421 if i > 0 {
24422 self.write(", ");
24423 }
24424 self.write("'");
24425 self.write(val);
24426 self.write("'");
24427 if let Some(Some(assignment)) = assignments.get(i) {
24428 self.write(" = ");
24429 self.write(assignment);
24430 }
24431 }
24432 self.write(")");
24433 }
24434 DataType::Set { values } => {
24435 self.write_keyword("SET(");
24437 for (i, val) in values.iter().enumerate() {
24438 if i > 0 {
24439 self.write(", ");
24440 }
24441 self.write("'");
24442 self.write(val);
24443 self.write("'");
24444 }
24445 self.write(")");
24446 }
24447 DataType::Union { fields } => {
24448 self.write_keyword("UNION(");
24450 for (i, (name, dt)) in fields.iter().enumerate() {
24451 if i > 0 {
24452 self.write(", ");
24453 }
24454 if !name.is_empty() {
24455 self.write(name);
24456 self.write(" ");
24457 }
24458 self.generate_data_type(dt)?;
24459 }
24460 self.write(")");
24461 }
24462 DataType::Nullable { inner } => {
24463 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
24465 self.write("Nullable(");
24466 let saved_depth = self.clickhouse_nullable_depth;
24468 self.clickhouse_nullable_depth = -1;
24469 self.generate_data_type(inner)?;
24470 self.clickhouse_nullable_depth = saved_depth;
24471 self.write(")");
24472 } else {
24473 match inner.as_ref() {
24475 DataType::Custom { name } if name.eq_ignore_ascii_case("DATETIME") => {
24476 self.generate_data_type(&DataType::Timestamp {
24477 precision: None,
24478 timezone: false,
24479 })?;
24480 }
24481 _ => {
24482 self.generate_data_type(inner)?;
24483 }
24484 }
24485 }
24486 }
24487 DataType::Custom { name } => {
24488 let name_upper = name.to_ascii_uppercase();
24490 match self.config.dialect {
24491 Some(DialectType::ClickHouse) => {
24492 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
24493 (name_upper[..idx].to_string(), &name[idx..])
24494 } else {
24495 (name_upper.clone(), "")
24496 };
24497 let mapped = match base_upper.as_str() {
24498 "DATETIME" | "TIMESTAMPTZ" | "TIMESTAMP" | "TIMESTAMPNTZ"
24499 | "SMALLDATETIME" | "DATETIME2" => "DateTime",
24500 "DATETIME64" => "DateTime64",
24501 "DATE32" => "Date32",
24502 "INT" => "Int32",
24503 "MEDIUMINT" => "Int32",
24504 "INT8" => "Int8",
24505 "INT16" => "Int16",
24506 "INT32" => "Int32",
24507 "INT64" => "Int64",
24508 "INT128" => "Int128",
24509 "INT256" => "Int256",
24510 "UINT8" => "UInt8",
24511 "UINT16" => "UInt16",
24512 "UINT32" => "UInt32",
24513 "UINT64" => "UInt64",
24514 "UINT128" => "UInt128",
24515 "UINT256" => "UInt256",
24516 "FLOAT32" => "Float32",
24517 "FLOAT64" => "Float64",
24518 "DECIMAL32" => "Decimal32",
24519 "DECIMAL64" => "Decimal64",
24520 "DECIMAL128" => "Decimal128",
24521 "DECIMAL256" => "Decimal256",
24522 "ENUM" => "Enum",
24523 "ENUM8" => "Enum8",
24524 "ENUM16" => "Enum16",
24525 "FIXEDSTRING" => "FixedString",
24526 "NESTED" => "Nested",
24527 "LOWCARDINALITY" => "LowCardinality",
24528 "NULLABLE" => "Nullable",
24529 "IPV4" => "IPv4",
24530 "IPV6" => "IPv6",
24531 "POINT" => "Point",
24532 "RING" => "Ring",
24533 "LINESTRING" => "LineString",
24534 "MULTILINESTRING" => "MultiLineString",
24535 "POLYGON" => "Polygon",
24536 "MULTIPOLYGON" => "MultiPolygon",
24537 "AGGREGATEFUNCTION" => "AggregateFunction",
24538 "SIMPLEAGGREGATEFUNCTION" => "SimpleAggregateFunction",
24539 "DYNAMIC" => "Dynamic",
24540 _ => "",
24541 };
24542 if mapped.is_empty() {
24543 self.write(name);
24544 } else {
24545 self.write(mapped);
24546 if matches!(base_upper.as_str(), "ENUM8" | "ENUM16")
24547 && !suffix.is_empty()
24548 {
24549 let escaped_suffix = suffix
24550 .replace('\\', "\\\\")
24551 .replace('\t', "\\t")
24552 .replace('\n', "\\n")
24553 .replace('\r', "\\r");
24554 self.write(&escaped_suffix);
24555 } else {
24556 self.write(suffix);
24557 }
24558 }
24559 }
24560 Some(DialectType::MySQL)
24561 if name_upper == "TIMESTAMPTZ" || name_upper == "TIMESTAMPLTZ" =>
24562 {
24563 self.write_keyword("TIMESTAMP");
24565 }
24566 Some(DialectType::TSQL) if name_upper == "VARIANT" => {
24567 self.write_keyword("SQL_VARIANT");
24568 }
24569 Some(DialectType::DuckDB) if name_upper == "DECFLOAT" => {
24570 self.write_keyword("DECIMAL(38, 5)");
24571 }
24572 Some(DialectType::Exasol) => {
24573 match name_upper.as_str() {
24575 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => self.write_keyword("VARCHAR"),
24577 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => self.write_keyword("VARCHAR"),
24579 "MEDIUMINT" => self.write_keyword("INT"),
24581 "DECIMAL32" | "DECIMAL64" | "DECIMAL128" | "DECIMAL256" => {
24583 self.write_keyword("DECIMAL")
24584 }
24585 "DATETIME" => self.write_keyword("TIMESTAMP"),
24587 "TIMESTAMPLTZ" => self.write_keyword("TIMESTAMP WITH LOCAL TIME ZONE"),
24588 _ => self.write(name),
24589 }
24590 }
24591 Some(DialectType::Dremio) => {
24592 match name_upper.as_str() {
24594 "TIMESTAMPNTZ" | "DATETIME" => self.write_keyword("TIMESTAMP"),
24595 "ARRAY" => self.write_keyword("LIST"),
24596 "NCHAR" => self.write_keyword("VARCHAR"),
24597 _ => self.write(name),
24598 }
24599 }
24600 _ => {
24602 let (base_upper, _args_str) = if let Some(idx) = name_upper.find('(') {
24604 (name_upper[..idx].to_string(), Some(&name[idx..]))
24605 } else {
24606 (name_upper.clone(), None)
24607 };
24608
24609 match base_upper.as_str() {
24610 "INT64"
24611 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
24612 {
24613 self.write_keyword("BIGINT");
24614 }
24615 "FLOAT64"
24616 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
24617 {
24618 self.write_keyword("DOUBLE");
24619 }
24620 "BOOL"
24621 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
24622 {
24623 self.write_keyword("BOOLEAN");
24624 }
24625 "BYTES"
24626 if matches!(
24627 self.config.dialect,
24628 Some(DialectType::Spark)
24629 | Some(DialectType::Hive)
24630 | Some(DialectType::Databricks)
24631 ) =>
24632 {
24633 self.write_keyword("BINARY");
24634 }
24635 "BYTES"
24636 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
24637 {
24638 self.write_keyword("VARBINARY");
24639 }
24640 "DATETIME2" | "SMALLDATETIME"
24642 if !matches!(
24643 self.config.dialect,
24644 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24645 ) =>
24646 {
24647 if matches!(
24649 self.config.dialect,
24650 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
24651 ) {
24652 self.write_keyword("TIMESTAMP");
24653 if let Some(args) = _args_str {
24654 self.write(args);
24655 }
24656 } else {
24657 self.write_keyword("TIMESTAMP");
24658 }
24659 }
24660 "DATETIMEOFFSET"
24662 if !matches!(
24663 self.config.dialect,
24664 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24665 ) =>
24666 {
24667 if matches!(
24668 self.config.dialect,
24669 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
24670 ) {
24671 self.write_keyword("TIMESTAMPTZ");
24672 if let Some(args) = _args_str {
24673 self.write(args);
24674 }
24675 } else {
24676 self.write_keyword("TIMESTAMPTZ");
24677 }
24678 }
24679 "UNIQUEIDENTIFIER"
24681 if !matches!(
24682 self.config.dialect,
24683 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24684 ) =>
24685 {
24686 match self.config.dialect {
24687 Some(DialectType::Spark)
24688 | Some(DialectType::Databricks)
24689 | Some(DialectType::Hive) => self.write_keyword("STRING"),
24690 _ => self.write_keyword("UUID"),
24691 }
24692 }
24693 "BIT"
24695 if !matches!(
24696 self.config.dialect,
24697 Some(DialectType::TSQL)
24698 | Some(DialectType::Fabric)
24699 | Some(DialectType::PostgreSQL)
24700 | Some(DialectType::MySQL)
24701 | Some(DialectType::DuckDB)
24702 ) =>
24703 {
24704 self.write_keyword("BOOLEAN");
24705 }
24706 "NVARCHAR"
24708 if !matches!(
24709 self.config.dialect,
24710 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24711 ) =>
24712 {
24713 match self.config.dialect {
24714 Some(DialectType::Oracle) => {
24715 self.write_keyword("NVARCHAR2");
24717 if let Some(args) = _args_str {
24718 self.write(args);
24719 }
24720 }
24721 Some(DialectType::BigQuery) => {
24722 self.write_keyword("STRING");
24724 }
24725 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
24726 self.write_keyword("TEXT");
24727 if let Some(args) = _args_str {
24728 self.write(args);
24729 }
24730 }
24731 Some(DialectType::Hive) => {
24732 self.write_keyword("STRING");
24734 }
24735 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
24736 if _args_str.is_some() {
24737 self.write_keyword("VARCHAR");
24738 self.write(_args_str.unwrap());
24739 } else {
24740 self.write_keyword("STRING");
24741 }
24742 }
24743 _ => {
24744 self.write_keyword("VARCHAR");
24745 if let Some(args) = _args_str {
24746 self.write(args);
24747 }
24748 }
24749 }
24750 }
24751 "NCHAR"
24753 if !matches!(
24754 self.config.dialect,
24755 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24756 ) =>
24757 {
24758 match self.config.dialect {
24759 Some(DialectType::Oracle) => {
24760 self.write_keyword("NCHAR");
24762 if let Some(args) = _args_str {
24763 self.write(args);
24764 }
24765 }
24766 Some(DialectType::BigQuery) => {
24767 self.write_keyword("STRING");
24769 }
24770 Some(DialectType::Hive) => {
24771 self.write_keyword("STRING");
24773 }
24774 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
24775 self.write_keyword("TEXT");
24776 if let Some(args) = _args_str {
24777 self.write(args);
24778 }
24779 }
24780 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
24781 if _args_str.is_some() {
24782 self.write_keyword("CHAR");
24783 self.write(_args_str.unwrap());
24784 } else {
24785 self.write_keyword("STRING");
24786 }
24787 }
24788 _ => {
24789 self.write_keyword("CHAR");
24790 if let Some(args) = _args_str {
24791 self.write(args);
24792 }
24793 }
24794 }
24795 }
24796 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => match self.config.dialect {
24799 Some(DialectType::MySQL)
24800 | Some(DialectType::SingleStore)
24801 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
24802 Some(DialectType::Spark)
24803 | Some(DialectType::Databricks)
24804 | Some(DialectType::Hive) => self.write_keyword("TEXT"),
24805 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
24806 Some(DialectType::Presto)
24807 | Some(DialectType::Trino)
24808 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
24809 Some(DialectType::Snowflake)
24810 | Some(DialectType::Redshift)
24811 | Some(DialectType::Dremio) => self.write_keyword("VARCHAR"),
24812 _ => self.write_keyword("TEXT"),
24813 },
24814 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => match self.config.dialect {
24817 Some(DialectType::MySQL)
24818 | Some(DialectType::SingleStore)
24819 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
24820 Some(DialectType::Spark)
24821 | Some(DialectType::Databricks)
24822 | Some(DialectType::Hive) => self.write_keyword("BLOB"),
24823 Some(DialectType::DuckDB) => self.write_keyword("VARBINARY"),
24824 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
24825 Some(DialectType::Presto)
24826 | Some(DialectType::Trino)
24827 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
24828 Some(DialectType::Snowflake)
24829 | Some(DialectType::Redshift)
24830 | Some(DialectType::Dremio) => self.write_keyword("VARBINARY"),
24831 _ => self.write_keyword("BLOB"),
24832 },
24833 "LONGVARCHAR" => match self.config.dialect {
24835 Some(DialectType::SQLite) => self.write_keyword("TEXT"),
24836 _ => self.write_keyword("VARCHAR"),
24837 },
24838 "DATETIME" => {
24840 match self.config.dialect {
24841 Some(DialectType::MySQL)
24842 | Some(DialectType::Doris)
24843 | Some(DialectType::StarRocks)
24844 | Some(DialectType::TSQL)
24845 | Some(DialectType::Fabric)
24846 | Some(DialectType::BigQuery)
24847 | Some(DialectType::SQLite)
24848 | Some(DialectType::Snowflake) => {
24849 self.write_keyword("DATETIME");
24850 if let Some(args) = _args_str {
24851 self.write(args);
24852 }
24853 }
24854 Some(_) => {
24855 self.write_keyword("TIMESTAMP");
24857 if let Some(args) = _args_str {
24858 self.write(args);
24859 }
24860 }
24861 None => {
24862 self.write(name);
24864 }
24865 }
24866 }
24867 "VARCHAR2"
24869 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
24870 {
24871 match self.config.dialect {
24872 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
24873 self.write_keyword("TEXT");
24874 }
24875 Some(DialectType::Hive)
24876 | Some(DialectType::Spark)
24877 | Some(DialectType::Databricks)
24878 | Some(DialectType::BigQuery)
24879 | Some(DialectType::ClickHouse)
24880 | Some(DialectType::StarRocks)
24881 | Some(DialectType::Doris) => {
24882 self.write_keyword("STRING");
24883 }
24884 _ => {
24885 self.write_keyword("VARCHAR");
24886 if let Some(args) = _args_str {
24887 self.write(args);
24888 }
24889 }
24890 }
24891 }
24892 "NVARCHAR2"
24893 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
24894 {
24895 match self.config.dialect {
24896 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
24897 self.write_keyword("TEXT");
24898 }
24899 Some(DialectType::Hive)
24900 | Some(DialectType::Spark)
24901 | Some(DialectType::Databricks)
24902 | Some(DialectType::BigQuery)
24903 | Some(DialectType::ClickHouse)
24904 | Some(DialectType::StarRocks)
24905 | Some(DialectType::Doris) => {
24906 self.write_keyword("STRING");
24907 }
24908 _ => {
24909 self.write_keyword("VARCHAR");
24910 if let Some(args) = _args_str {
24911 self.write(args);
24912 }
24913 }
24914 }
24915 }
24916 _ => self.write(name),
24917 }
24918 }
24919 }
24920 }
24921 DataType::Geometry { subtype, srid } => {
24922 match self.config.dialect {
24924 Some(DialectType::MySQL) => {
24925 if let Some(sub) = subtype {
24927 self.write_keyword(sub);
24928 if let Some(s) = srid {
24929 self.write(" SRID ");
24930 self.write(&s.to_string());
24931 }
24932 } else {
24933 self.write_keyword("GEOMETRY");
24934 }
24935 }
24936 Some(DialectType::BigQuery) => {
24937 self.write_keyword("GEOGRAPHY");
24939 }
24940 Some(DialectType::Teradata) => {
24941 self.write_keyword("ST_GEOMETRY");
24943 if subtype.is_some() || srid.is_some() {
24944 self.write("(");
24945 if let Some(sub) = subtype {
24946 self.write_keyword(sub);
24947 }
24948 if let Some(s) = srid {
24949 if subtype.is_some() {
24950 self.write(", ");
24951 }
24952 self.write(&s.to_string());
24953 }
24954 self.write(")");
24955 }
24956 }
24957 _ => {
24958 self.write_keyword("GEOMETRY");
24960 if subtype.is_some() || srid.is_some() {
24961 self.write("(");
24962 if let Some(sub) = subtype {
24963 self.write_keyword(sub);
24964 }
24965 if let Some(s) = srid {
24966 if subtype.is_some() {
24967 self.write(", ");
24968 }
24969 self.write(&s.to_string());
24970 }
24971 self.write(")");
24972 }
24973 }
24974 }
24975 }
24976 DataType::Geography { subtype, srid } => {
24977 match self.config.dialect {
24979 Some(DialectType::MySQL) => {
24980 if let Some(sub) = subtype {
24982 self.write_keyword(sub);
24983 } else {
24984 self.write_keyword("GEOMETRY");
24985 }
24986 let effective_srid = srid.unwrap_or(4326);
24988 self.write(" SRID ");
24989 self.write(&effective_srid.to_string());
24990 }
24991 Some(DialectType::BigQuery) => {
24992 self.write_keyword("GEOGRAPHY");
24994 }
24995 Some(DialectType::Snowflake) => {
24996 self.write_keyword("GEOGRAPHY");
24998 }
24999 _ => {
25000 self.write_keyword("GEOGRAPHY");
25002 if subtype.is_some() || srid.is_some() {
25003 self.write("(");
25004 if let Some(sub) = subtype {
25005 self.write_keyword(sub);
25006 }
25007 if let Some(s) = srid {
25008 if subtype.is_some() {
25009 self.write(", ");
25010 }
25011 self.write(&s.to_string());
25012 }
25013 self.write(")");
25014 }
25015 }
25016 }
25017 }
25018 DataType::CharacterSet { name } => {
25019 self.write_keyword("CHAR CHARACTER SET ");
25021 self.write(name);
25022 }
25023 _ => self.write("UNKNOWN"),
25024 }
25025 Ok(())
25026 }
25027
25028 #[inline]
25031 fn write(&mut self, s: &str) {
25032 self.output.push_str(s);
25033 }
25034
25035 #[inline]
25036 fn write_space(&mut self) {
25037 self.output.push(' ');
25038 }
25039
25040 #[inline]
25041 fn write_keyword(&mut self, keyword: &str) {
25042 if self.config.uppercase_keywords {
25043 self.output.push_str(keyword);
25044 } else {
25045 for b in keyword.bytes() {
25046 self.output.push(b.to_ascii_lowercase() as char);
25047 }
25048 }
25049 }
25050
25051 fn write_func_name(&mut self, name: &str) {
25053 let normalized = self.normalize_func_name(name);
25054 self.output.push_str(normalized.as_ref());
25055 }
25056
25057 fn convert_strptime_to_exasol_format(format: &str) -> String {
25061 let mut result = String::new();
25062 let chars: Vec<char> = format.chars().collect();
25063 let mut i = 0;
25064 while i < chars.len() {
25065 if chars[i] == '%' && i + 1 < chars.len() {
25066 let spec = chars[i + 1];
25067 let exasol_spec = match spec {
25068 'Y' => "YYYY",
25069 'y' => "YY",
25070 'm' => "MM",
25071 'd' => "DD",
25072 'H' => "HH",
25073 'M' => "MI",
25074 'S' => "SS",
25075 'a' => "DY", 'A' => "DAY", 'b' => "MON", 'B' => "MONTH", 'I' => "H12", 'u' => "ID", 'V' => "IW", 'G' => "IYYY", 'W' => "UW", 'U' => "UW", 'z' => "Z", _ => {
25087 result.push('%');
25089 result.push(spec);
25090 i += 2;
25091 continue;
25092 }
25093 };
25094 result.push_str(exasol_spec);
25095 i += 2;
25096 } else {
25097 result.push(chars[i]);
25098 i += 1;
25099 }
25100 }
25101 result
25102 }
25103
25104 fn convert_strptime_to_postgres_format(format: &str) -> String {
25108 let mut result = String::new();
25109 let chars: Vec<char> = format.chars().collect();
25110 let mut i = 0;
25111 while i < chars.len() {
25112 if chars[i] == '%' && i + 1 < chars.len() {
25113 if chars[i + 1] == '-' && i + 2 < chars.len() {
25115 let spec = chars[i + 2];
25116 let pg_spec = match spec {
25117 'd' => "FMDD",
25118 'm' => "FMMM",
25119 'H' => "FMHH24",
25120 'M' => "FMMI",
25121 'S' => "FMSS",
25122 _ => {
25123 result.push('%');
25124 result.push('-');
25125 result.push(spec);
25126 i += 3;
25127 continue;
25128 }
25129 };
25130 result.push_str(pg_spec);
25131 i += 3;
25132 continue;
25133 }
25134 let spec = chars[i + 1];
25135 let pg_spec = match spec {
25136 'Y' => "YYYY",
25137 'y' => "YY",
25138 'm' => "MM",
25139 'd' => "DD",
25140 'H' => "HH24",
25141 'I' => "HH12",
25142 'M' => "MI",
25143 'S' => "SS",
25144 'f' => "US", 'u' => "D", 'j' => "DDD", 'z' => "OF", 'Z' => "TZ", 'A' => "TMDay", 'a' => "TMDy", 'b' => "TMMon", 'B' => "TMMonth", 'U' => "WW", _ => {
25155 result.push('%');
25157 result.push(spec);
25158 i += 2;
25159 continue;
25160 }
25161 };
25162 result.push_str(pg_spec);
25163 i += 2;
25164 } else {
25165 result.push(chars[i]);
25166 i += 1;
25167 }
25168 }
25169 result
25170 }
25171
25172 fn write_limit_expr(&mut self, expr: &Expression) -> Result<()> {
25174 if self.config.limit_only_literals {
25175 if let Some(value) = Self::try_evaluate_constant(expr) {
25176 self.write(&value.to_string());
25177 return Ok(());
25178 }
25179 }
25180 self.generate_expression(expr)
25181 }
25182
25183 fn write_formatted_comment(&mut self, comment: &str) {
25187 let content = if comment.starts_with("/*") && comment.ends_with("*/") {
25190 &comment[2..comment.len() - 2]
25193 } else if comment.starts_with("--") {
25194 &comment[2..]
25197 } else {
25198 comment
25200 };
25201 if content.trim().is_empty() {
25203 return;
25204 }
25205 let sanitized = content.replace("*/", "* /").replace("/*", "/ *");
25208 let content = &sanitized;
25209 self.output.push_str("/*");
25211 if !content.starts_with(' ') {
25212 self.output.push(' ');
25213 }
25214 self.output.push_str(content);
25215 if !content.ends_with(' ') {
25216 self.output.push(' ');
25217 }
25218 self.output.push_str("*/");
25219 }
25220
25221 fn escape_block_for_single_quote(&self, block: &str) -> String {
25224 let escape_backslash = matches!(
25225 self.config.dialect,
25226 Some(crate::dialects::DialectType::Snowflake)
25227 );
25228 let mut escaped = String::with_capacity(block.len() + 4);
25229 for ch in block.chars() {
25230 if ch == '\'' {
25231 escaped.push('\\');
25232 escaped.push('\'');
25233 } else if escape_backslash && ch == '\\' {
25234 escaped.push('\\');
25235 escaped.push('\\');
25236 } else {
25237 escaped.push(ch);
25238 }
25239 }
25240 escaped
25241 }
25242
25243 fn write_newline(&mut self) {
25244 self.output.push('\n');
25245 }
25246
25247 fn write_indent(&mut self) {
25248 for _ in 0..self.indent_level {
25249 self.output.push_str(self.config.indent);
25250 }
25251 }
25252
25253 fn too_wide(&self, args: &[String]) -> bool {
25259 args.iter().map(|s| s.len()).sum::<usize>() > self.config.max_text_width
25260 }
25261
25262 fn generate_to_string(&self, expr: &Expression) -> Result<String> {
25265 let config = GeneratorConfig {
25266 pretty: false,
25267 dialect: self.config.dialect,
25268 ..Default::default()
25269 };
25270 let mut gen = Generator::with_config(config);
25271 gen.generate_expression(expr)?;
25272 Ok(gen.output)
25273 }
25274
25275 fn write_clause_condition(&mut self, keyword: &str, condition: &Expression) -> Result<()> {
25278 if self.config.pretty {
25279 self.write_newline();
25280 self.write_indent();
25281 self.write_keyword(keyword);
25282 self.write_newline();
25283 self.indent_level += 1;
25284 self.write_indent();
25285 self.generate_expression(condition)?;
25286 self.indent_level -= 1;
25287 } else {
25288 self.write_space();
25289 self.write_keyword(keyword);
25290 self.write_space();
25291 self.generate_expression(condition)?;
25292 }
25293 Ok(())
25294 }
25295
25296 fn write_clause_expressions(&mut self, keyword: &str, exprs: &[Expression]) -> Result<()> {
25299 if exprs.is_empty() {
25300 return Ok(());
25301 }
25302
25303 if self.config.pretty {
25304 self.write_newline();
25305 self.write_indent();
25306 self.write_keyword(keyword);
25307 self.write_newline();
25308 self.indent_level += 1;
25309 for (i, expr) in exprs.iter().enumerate() {
25310 if i > 0 {
25311 self.write(",");
25312 self.write_newline();
25313 }
25314 self.write_indent();
25315 self.generate_expression(expr)?;
25316 }
25317 self.indent_level -= 1;
25318 } else {
25319 self.write_space();
25320 self.write_keyword(keyword);
25321 self.write_space();
25322 for (i, expr) in exprs.iter().enumerate() {
25323 if i > 0 {
25324 self.write(", ");
25325 }
25326 self.generate_expression(expr)?;
25327 }
25328 }
25329 Ok(())
25330 }
25331
25332 fn write_order_clause(&mut self, keyword: &str, orderings: &[Ordered]) -> Result<()> {
25334 if orderings.is_empty() {
25335 return Ok(());
25336 }
25337
25338 if self.config.pretty {
25339 self.write_newline();
25340 self.write_indent();
25341 self.write_keyword(keyword);
25342 self.write_newline();
25343 self.indent_level += 1;
25344 for (i, ordered) in orderings.iter().enumerate() {
25345 if i > 0 {
25346 self.write(",");
25347 self.write_newline();
25348 }
25349 self.write_indent();
25350 self.generate_ordered(ordered)?;
25351 }
25352 self.indent_level -= 1;
25353 } else {
25354 self.write_space();
25355 self.write_keyword(keyword);
25356 self.write_space();
25357 for (i, ordered) in orderings.iter().enumerate() {
25358 if i > 0 {
25359 self.write(", ");
25360 }
25361 self.generate_ordered(ordered)?;
25362 }
25363 }
25364 Ok(())
25365 }
25366
25367 fn write_window_clause(&mut self, windows: &[NamedWindow]) -> Result<()> {
25369 if windows.is_empty() {
25370 return Ok(());
25371 }
25372
25373 if self.config.pretty {
25374 self.write_newline();
25375 self.write_indent();
25376 self.write_keyword("WINDOW");
25377 self.write_newline();
25378 self.indent_level += 1;
25379 for (i, named_window) in windows.iter().enumerate() {
25380 if i > 0 {
25381 self.write(",");
25382 self.write_newline();
25383 }
25384 self.write_indent();
25385 self.generate_identifier(&named_window.name)?;
25386 self.write_space();
25387 self.write_keyword("AS");
25388 self.write(" (");
25389 self.generate_over(&named_window.spec)?;
25390 self.write(")");
25391 }
25392 self.indent_level -= 1;
25393 } else {
25394 self.write_space();
25395 self.write_keyword("WINDOW");
25396 self.write_space();
25397 for (i, named_window) in windows.iter().enumerate() {
25398 if i > 0 {
25399 self.write(", ");
25400 }
25401 self.generate_identifier(&named_window.name)?;
25402 self.write_space();
25403 self.write_keyword("AS");
25404 self.write(" (");
25405 self.generate_over(&named_window.spec)?;
25406 self.write(")");
25407 }
25408 }
25409 Ok(())
25410 }
25411
25412 fn generate_ai_agg(&mut self, e: &AIAgg) -> Result<()> {
25414 self.write_keyword("AI_AGG");
25416 self.write("(");
25417 self.generate_expression(&e.this)?;
25418 self.write(", ");
25419 self.generate_expression(&e.expression)?;
25420 self.write(")");
25421 Ok(())
25422 }
25423
25424 fn generate_ai_classify(&mut self, e: &AIClassify) -> Result<()> {
25425 self.write_keyword("AI_CLASSIFY");
25427 self.write("(");
25428 self.generate_expression(&e.this)?;
25429 if let Some(categories) = &e.categories {
25430 self.write(", ");
25431 self.generate_expression(categories)?;
25432 }
25433 if let Some(config) = &e.config {
25434 self.write(", ");
25435 self.generate_expression(config)?;
25436 }
25437 self.write(")");
25438 Ok(())
25439 }
25440
25441 fn generate_add_partition(&mut self, e: &AddPartition) -> Result<()> {
25442 self.write_keyword("ADD");
25444 self.write_space();
25445 if e.exists {
25446 self.write_keyword("IF NOT EXISTS");
25447 self.write_space();
25448 }
25449 self.generate_expression(&e.this)?;
25450 if let Some(location) = &e.location {
25451 self.write_space();
25452 self.generate_expression(location)?;
25453 }
25454 Ok(())
25455 }
25456
25457 fn generate_algorithm_property(&mut self, e: &AlgorithmProperty) -> Result<()> {
25458 self.write_keyword("ALGORITHM");
25460 self.write("=");
25461 self.generate_expression(&e.this)?;
25462 Ok(())
25463 }
25464
25465 fn generate_aliases(&mut self, e: &Aliases) -> Result<()> {
25466 self.generate_expression(&e.this)?;
25468 self.write_space();
25469 self.write_keyword("AS");
25470 self.write(" (");
25471 for (i, expr) in e.expressions.iter().enumerate() {
25472 if i > 0 {
25473 self.write(", ");
25474 }
25475 self.generate_expression(expr)?;
25476 }
25477 self.write(")");
25478 Ok(())
25479 }
25480
25481 fn generate_allowed_values_property(&mut self, e: &AllowedValuesProperty) -> Result<()> {
25482 self.write_keyword("ALLOWED_VALUES");
25484 self.write_space();
25485 for (i, expr) in e.expressions.iter().enumerate() {
25486 if i > 0 {
25487 self.write(", ");
25488 }
25489 self.generate_expression(expr)?;
25490 }
25491 Ok(())
25492 }
25493
25494 fn generate_alter_column(&mut self, e: &AlterColumn) -> Result<()> {
25495 self.write_keyword("ALTER COLUMN");
25497 self.write_space();
25498 self.generate_expression(&e.this)?;
25499
25500 if let Some(dtype) = &e.dtype {
25501 self.write_space();
25502 self.write_keyword("SET DATA TYPE");
25503 self.write_space();
25504 self.generate_expression(dtype)?;
25505 if let Some(collate) = &e.collate {
25506 self.write_space();
25507 self.write_keyword("COLLATE");
25508 self.write_space();
25509 self.generate_expression(collate)?;
25510 }
25511 if let Some(using) = &e.using {
25512 self.write_space();
25513 self.write_keyword("USING");
25514 self.write_space();
25515 self.generate_expression(using)?;
25516 }
25517 } else if let Some(default) = &e.default {
25518 self.write_space();
25519 self.write_keyword("SET DEFAULT");
25520 self.write_space();
25521 self.generate_expression(default)?;
25522 } else if let Some(comment) = &e.comment {
25523 self.write_space();
25524 self.write_keyword("COMMENT");
25525 self.write_space();
25526 self.generate_expression(comment)?;
25527 } else if let Some(drop) = &e.drop {
25528 self.write_space();
25529 self.write_keyword("DROP");
25530 self.write_space();
25531 self.generate_expression(drop)?;
25532 } else if let Some(visible) = &e.visible {
25533 self.write_space();
25534 self.generate_expression(visible)?;
25535 } else if let Some(rename_to) = &e.rename_to {
25536 self.write_space();
25537 self.write_keyword("RENAME TO");
25538 self.write_space();
25539 self.generate_expression(rename_to)?;
25540 } else if let Some(allow_null) = &e.allow_null {
25541 self.write_space();
25542 self.generate_expression(allow_null)?;
25543 }
25544 Ok(())
25545 }
25546
25547 fn generate_alter_session(&mut self, e: &AlterSession) -> Result<()> {
25548 self.write_keyword("ALTER SESSION");
25550 self.write_space();
25551 if e.unset.is_some() {
25552 self.write_keyword("UNSET");
25553 } else {
25554 self.write_keyword("SET");
25555 }
25556 self.write_space();
25557 for (i, expr) in e.expressions.iter().enumerate() {
25558 if i > 0 {
25559 self.write(", ");
25560 }
25561 self.generate_expression(expr)?;
25562 }
25563 Ok(())
25564 }
25565
25566 fn generate_alter_set(&mut self, e: &AlterSet) -> Result<()> {
25567 self.write_keyword("SET");
25569
25570 if let Some(opt) = &e.option {
25572 self.write_space();
25573 self.generate_expression(opt)?;
25574 }
25575
25576 if !e.expressions.is_empty() {
25579 let is_properties = e
25581 .expressions
25582 .iter()
25583 .any(|expr| matches!(expr, Expression::Eq(_)));
25584 if is_properties && e.option.is_none() {
25585 self.write_space();
25586 self.write_keyword("PROPERTIES");
25587 }
25588 self.write_space();
25589 for (i, expr) in e.expressions.iter().enumerate() {
25590 if i > 0 {
25591 self.write(", ");
25592 }
25593 self.generate_expression(expr)?;
25594 }
25595 }
25596
25597 if let Some(file_format) = &e.file_format {
25599 self.write(" ");
25600 self.write_keyword("STAGE_FILE_FORMAT");
25601 self.write(" = (");
25602 self.generate_space_separated_properties(file_format)?;
25603 self.write(")");
25604 }
25605
25606 if let Some(copy_options) = &e.copy_options {
25608 self.write(" ");
25609 self.write_keyword("STAGE_COPY_OPTIONS");
25610 self.write(" = (");
25611 self.generate_space_separated_properties(copy_options)?;
25612 self.write(")");
25613 }
25614
25615 if let Some(tag) = &e.tag {
25617 self.write(" ");
25618 self.write_keyword("TAG");
25619 self.write(" ");
25620 self.generate_expression(tag)?;
25621 }
25622
25623 Ok(())
25624 }
25625
25626 fn generate_space_separated_properties(&mut self, expr: &Expression) -> Result<()> {
25628 match expr {
25629 Expression::Tuple(t) => {
25630 for (i, prop) in t.expressions.iter().enumerate() {
25631 if i > 0 {
25632 self.write(" ");
25633 }
25634 self.generate_expression(prop)?;
25635 }
25636 }
25637 _ => {
25638 self.generate_expression(expr)?;
25639 }
25640 }
25641 Ok(())
25642 }
25643
25644 fn generate_alter_sort_key(&mut self, e: &AlterSortKey) -> Result<()> {
25645 self.write_keyword("ALTER");
25647 if e.compound.is_some() {
25648 self.write_space();
25649 self.write_keyword("COMPOUND");
25650 }
25651 self.write_space();
25652 self.write_keyword("SORTKEY");
25653 self.write_space();
25654 if let Some(this) = &e.this {
25655 self.generate_expression(this)?;
25656 } else if !e.expressions.is_empty() {
25657 self.write("(");
25658 for (i, expr) in e.expressions.iter().enumerate() {
25659 if i > 0 {
25660 self.write(", ");
25661 }
25662 self.generate_expression(expr)?;
25663 }
25664 self.write(")");
25665 }
25666 Ok(())
25667 }
25668
25669 fn generate_analyze(&mut self, e: &Analyze) -> Result<()> {
25670 self.write_keyword("ANALYZE");
25672 if !e.options.is_empty() {
25673 self.write_space();
25674 for (i, opt) in e.options.iter().enumerate() {
25675 if i > 0 {
25676 self.write_space();
25677 }
25678 if let Expression::Identifier(id) = opt {
25680 self.write_keyword(&id.name);
25681 } else {
25682 self.generate_expression(opt)?;
25683 }
25684 }
25685 }
25686 if let Some(kind) = &e.kind {
25687 self.write_space();
25688 self.write_keyword(kind);
25689 }
25690 if let Some(this) = &e.this {
25691 self.write_space();
25692 self.generate_expression(this)?;
25693 }
25694 if !e.columns.is_empty() {
25696 self.write("(");
25697 for (i, col) in e.columns.iter().enumerate() {
25698 if i > 0 {
25699 self.write(", ");
25700 }
25701 self.write(col);
25702 }
25703 self.write(")");
25704 }
25705 if let Some(partition) = &e.partition {
25706 self.write_space();
25707 self.generate_expression(partition)?;
25708 }
25709 if let Some(mode) = &e.mode {
25710 self.write_space();
25711 self.generate_expression(mode)?;
25712 }
25713 if let Some(expression) = &e.expression {
25714 self.write_space();
25715 self.generate_expression(expression)?;
25716 }
25717 if !e.properties.is_empty() {
25718 self.write_space();
25719 self.write_keyword(self.config.with_properties_prefix);
25720 self.write(" (");
25721 for (i, prop) in e.properties.iter().enumerate() {
25722 if i > 0 {
25723 self.write(", ");
25724 }
25725 self.generate_expression(prop)?;
25726 }
25727 self.write(")");
25728 }
25729 Ok(())
25730 }
25731
25732 fn generate_analyze_delete(&mut self, e: &AnalyzeDelete) -> Result<()> {
25733 self.write_keyword("DELETE");
25735 if let Some(kind) = &e.kind {
25736 self.write_space();
25737 self.write_keyword(kind);
25738 }
25739 self.write_space();
25740 self.write_keyword("STATISTICS");
25741 Ok(())
25742 }
25743
25744 fn generate_analyze_histogram(&mut self, e: &AnalyzeHistogram) -> Result<()> {
25745 if let Expression::Identifier(id) = e.this.as_ref() {
25748 self.write_keyword(&id.name);
25749 } else {
25750 self.generate_expression(&e.this)?;
25751 }
25752 self.write_space();
25753 self.write_keyword("HISTOGRAM ON");
25754 self.write_space();
25755 for (i, expr) in e.expressions.iter().enumerate() {
25756 if i > 0 {
25757 self.write(", ");
25758 }
25759 self.generate_expression(expr)?;
25760 }
25761 if let Some(expression) = &e.expression {
25762 self.write_space();
25763 self.generate_expression(expression)?;
25764 }
25765 if let Some(update_options) = &e.update_options {
25766 self.write_space();
25767 self.generate_expression(update_options)?;
25768 self.write_space();
25769 self.write_keyword("UPDATE");
25770 }
25771 Ok(())
25772 }
25773
25774 fn generate_analyze_list_chained_rows(&mut self, e: &AnalyzeListChainedRows) -> Result<()> {
25775 self.write_keyword("LIST CHAINED ROWS");
25777 if let Some(expression) = &e.expression {
25778 self.write_space();
25779 self.write_keyword("INTO");
25780 self.write_space();
25781 self.generate_expression(expression)?;
25782 }
25783 Ok(())
25784 }
25785
25786 fn generate_analyze_sample(&mut self, e: &AnalyzeSample) -> Result<()> {
25787 self.write_keyword("SAMPLE");
25789 self.write_space();
25790 if let Some(sample) = &e.sample {
25791 self.generate_expression(sample)?;
25792 self.write_space();
25793 }
25794 self.write_keyword(&e.kind);
25795 Ok(())
25796 }
25797
25798 fn generate_analyze_statistics(&mut self, e: &AnalyzeStatistics) -> Result<()> {
25799 self.write_keyword(&e.kind);
25801 if let Some(option) = &e.option {
25802 self.write_space();
25803 self.generate_expression(option)?;
25804 }
25805 self.write_space();
25806 self.write_keyword("STATISTICS");
25807 if let Some(this) = &e.this {
25808 self.write_space();
25809 self.generate_expression(this)?;
25810 }
25811 if !e.expressions.is_empty() {
25812 self.write_space();
25813 for (i, expr) in e.expressions.iter().enumerate() {
25814 if i > 0 {
25815 self.write(", ");
25816 }
25817 self.generate_expression(expr)?;
25818 }
25819 }
25820 Ok(())
25821 }
25822
25823 fn generate_analyze_validate(&mut self, e: &AnalyzeValidate) -> Result<()> {
25824 self.write_keyword("VALIDATE");
25826 self.write_space();
25827 self.write_keyword(&e.kind);
25828 if let Some(this) = &e.this {
25829 self.write_space();
25830 if let Expression::Identifier(id) = this.as_ref() {
25832 self.write_keyword(&id.name);
25833 } else {
25834 self.generate_expression(this)?;
25835 }
25836 }
25837 if let Some(expression) = &e.expression {
25838 self.write_space();
25839 self.write_keyword("INTO");
25840 self.write_space();
25841 self.generate_expression(expression)?;
25842 }
25843 Ok(())
25844 }
25845
25846 fn generate_analyze_with(&mut self, e: &AnalyzeWith) -> Result<()> {
25847 self.write_keyword("WITH");
25849 self.write_space();
25850 for (i, expr) in e.expressions.iter().enumerate() {
25851 if i > 0 {
25852 self.write(", ");
25853 }
25854 self.generate_expression(expr)?;
25855 }
25856 Ok(())
25857 }
25858
25859 fn generate_anonymous(&mut self, e: &Anonymous) -> Result<()> {
25860 self.generate_expression(&e.this)?;
25863 self.write("(");
25864 for (i, arg) in e.expressions.iter().enumerate() {
25865 if i > 0 {
25866 self.write(", ");
25867 }
25868 self.generate_expression(arg)?;
25869 }
25870 self.write(")");
25871 Ok(())
25872 }
25873
25874 fn generate_anonymous_agg_func(&mut self, e: &AnonymousAggFunc) -> Result<()> {
25875 self.generate_expression(&e.this)?;
25877 self.write("(");
25878 for (i, arg) in e.expressions.iter().enumerate() {
25879 if i > 0 {
25880 self.write(", ");
25881 }
25882 self.generate_expression(arg)?;
25883 }
25884 self.write(")");
25885 Ok(())
25886 }
25887
25888 fn generate_apply(&mut self, e: &Apply) -> Result<()> {
25889 self.generate_expression(&e.this)?;
25891 self.write_space();
25892 self.write_keyword("APPLY");
25893 self.write("(");
25894 self.generate_expression(&e.expression)?;
25895 self.write(")");
25896 Ok(())
25897 }
25898
25899 fn generate_approx_percentile_estimate(&mut self, e: &ApproxPercentileEstimate) -> Result<()> {
25900 self.write_keyword("APPROX_PERCENTILE_ESTIMATE");
25902 self.write("(");
25903 self.generate_expression(&e.this)?;
25904 if let Some(percentile) = &e.percentile {
25905 self.write(", ");
25906 self.generate_expression(percentile)?;
25907 }
25908 self.write(")");
25909 Ok(())
25910 }
25911
25912 fn generate_approx_quantile(&mut self, e: &ApproxQuantile) -> Result<()> {
25913 self.write_keyword("APPROX_QUANTILE");
25915 self.write("(");
25916 self.generate_expression(&e.this)?;
25917 if let Some(quantile) = &e.quantile {
25918 self.write(", ");
25919 self.generate_expression(quantile)?;
25920 }
25921 if let Some(accuracy) = &e.accuracy {
25922 self.write(", ");
25923 self.generate_expression(accuracy)?;
25924 }
25925 if let Some(weight) = &e.weight {
25926 self.write(", ");
25927 self.generate_expression(weight)?;
25928 }
25929 self.write(")");
25930 Ok(())
25931 }
25932
25933 fn generate_approx_quantiles(&mut self, e: &ApproxQuantiles) -> Result<()> {
25934 self.write_keyword("APPROX_QUANTILES");
25936 self.write("(");
25937 self.generate_expression(&e.this)?;
25938 if let Some(expression) = &e.expression {
25939 self.write(", ");
25940 self.generate_expression(expression)?;
25941 }
25942 self.write(")");
25943 Ok(())
25944 }
25945
25946 fn generate_approx_top_k(&mut self, e: &ApproxTopK) -> Result<()> {
25947 self.write_keyword("APPROX_TOP_K");
25949 self.write("(");
25950 self.generate_expression(&e.this)?;
25951 if let Some(expression) = &e.expression {
25952 self.write(", ");
25953 self.generate_expression(expression)?;
25954 }
25955 if let Some(counters) = &e.counters {
25956 self.write(", ");
25957 self.generate_expression(counters)?;
25958 }
25959 self.write(")");
25960 Ok(())
25961 }
25962
25963 fn generate_approx_top_k_accumulate(&mut self, e: &ApproxTopKAccumulate) -> Result<()> {
25964 self.write_keyword("APPROX_TOP_K_ACCUMULATE");
25966 self.write("(");
25967 self.generate_expression(&e.this)?;
25968 if let Some(expression) = &e.expression {
25969 self.write(", ");
25970 self.generate_expression(expression)?;
25971 }
25972 self.write(")");
25973 Ok(())
25974 }
25975
25976 fn generate_approx_top_k_combine(&mut self, e: &ApproxTopKCombine) -> Result<()> {
25977 self.write_keyword("APPROX_TOP_K_COMBINE");
25979 self.write("(");
25980 self.generate_expression(&e.this)?;
25981 if let Some(expression) = &e.expression {
25982 self.write(", ");
25983 self.generate_expression(expression)?;
25984 }
25985 self.write(")");
25986 Ok(())
25987 }
25988
25989 fn generate_approx_top_k_estimate(&mut self, e: &ApproxTopKEstimate) -> Result<()> {
25990 self.write_keyword("APPROX_TOP_K_ESTIMATE");
25992 self.write("(");
25993 self.generate_expression(&e.this)?;
25994 if let Some(expression) = &e.expression {
25995 self.write(", ");
25996 self.generate_expression(expression)?;
25997 }
25998 self.write(")");
25999 Ok(())
26000 }
26001
26002 fn generate_approx_top_sum(&mut self, e: &ApproxTopSum) -> Result<()> {
26003 self.write_keyword("APPROX_TOP_SUM");
26005 self.write("(");
26006 self.generate_expression(&e.this)?;
26007 self.write(", ");
26008 self.generate_expression(&e.expression)?;
26009 if let Some(count) = &e.count {
26010 self.write(", ");
26011 self.generate_expression(count)?;
26012 }
26013 self.write(")");
26014 Ok(())
26015 }
26016
26017 fn generate_arg_max(&mut self, e: &ArgMax) -> Result<()> {
26018 self.write_keyword("ARG_MAX");
26020 self.write("(");
26021 self.generate_expression(&e.this)?;
26022 self.write(", ");
26023 self.generate_expression(&e.expression)?;
26024 if let Some(count) = &e.count {
26025 self.write(", ");
26026 self.generate_expression(count)?;
26027 }
26028 self.write(")");
26029 Ok(())
26030 }
26031
26032 fn generate_arg_min(&mut self, e: &ArgMin) -> Result<()> {
26033 self.write_keyword("ARG_MIN");
26035 self.write("(");
26036 self.generate_expression(&e.this)?;
26037 self.write(", ");
26038 self.generate_expression(&e.expression)?;
26039 if let Some(count) = &e.count {
26040 self.write(", ");
26041 self.generate_expression(count)?;
26042 }
26043 self.write(")");
26044 Ok(())
26045 }
26046
26047 fn generate_array_all(&mut self, e: &ArrayAll) -> Result<()> {
26048 self.write_keyword("ARRAY_ALL");
26050 self.write("(");
26051 self.generate_expression(&e.this)?;
26052 self.write(", ");
26053 self.generate_expression(&e.expression)?;
26054 self.write(")");
26055 Ok(())
26056 }
26057
26058 fn generate_array_any(&mut self, e: &ArrayAny) -> Result<()> {
26059 self.write_keyword("ARRAY_ANY");
26061 self.write("(");
26062 self.generate_expression(&e.this)?;
26063 self.write(", ");
26064 self.generate_expression(&e.expression)?;
26065 self.write(")");
26066 Ok(())
26067 }
26068
26069 fn generate_array_construct_compact(&mut self, e: &ArrayConstructCompact) -> Result<()> {
26070 self.write_keyword("ARRAY_CONSTRUCT_COMPACT");
26072 self.write("(");
26073 for (i, expr) in e.expressions.iter().enumerate() {
26074 if i > 0 {
26075 self.write(", ");
26076 }
26077 self.generate_expression(expr)?;
26078 }
26079 self.write(")");
26080 Ok(())
26081 }
26082
26083 fn generate_array_sum(&mut self, e: &ArraySum) -> Result<()> {
26084 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
26086 self.write("arraySum");
26087 } else {
26088 self.write_keyword("ARRAY_SUM");
26089 }
26090 self.write("(");
26091 self.generate_expression(&e.this)?;
26092 if let Some(expression) = &e.expression {
26093 self.write(", ");
26094 self.generate_expression(expression)?;
26095 }
26096 self.write(")");
26097 Ok(())
26098 }
26099
26100 fn generate_at_index(&mut self, e: &AtIndex) -> Result<()> {
26101 self.generate_expression(&e.this)?;
26103 self.write_space();
26104 self.write_keyword("AT");
26105 self.write_space();
26106 self.generate_expression(&e.expression)?;
26107 Ok(())
26108 }
26109
26110 fn generate_attach(&mut self, e: &Attach) -> Result<()> {
26111 self.write_keyword("ATTACH");
26113 if e.exists {
26114 self.write_space();
26115 self.write_keyword("IF NOT EXISTS");
26116 }
26117 self.write_space();
26118 self.generate_expression(&e.this)?;
26119 if !e.expressions.is_empty() {
26120 self.write(" (");
26121 for (i, expr) in e.expressions.iter().enumerate() {
26122 if i > 0 {
26123 self.write(", ");
26124 }
26125 self.generate_expression(expr)?;
26126 }
26127 self.write(")");
26128 }
26129 Ok(())
26130 }
26131
26132 fn generate_attach_option(&mut self, e: &AttachOption) -> Result<()> {
26133 self.generate_expression(&e.this)?;
26136 if let Some(expression) = &e.expression {
26137 self.write_space();
26138 self.generate_expression(expression)?;
26139 }
26140 Ok(())
26141 }
26142
26143 fn generate_auto_increment_keyword(
26147 &mut self,
26148 col: &crate::expressions::ColumnDef,
26149 ) -> Result<()> {
26150 use crate::dialects::DialectType;
26151 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
26152 self.write_keyword("IDENTITY");
26153 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26154 self.write("(");
26155 if let Some(ref start) = col.auto_increment_start {
26156 self.generate_expression(start)?;
26157 } else {
26158 self.write("0");
26159 }
26160 self.write(", ");
26161 if let Some(ref inc) = col.auto_increment_increment {
26162 self.generate_expression(inc)?;
26163 } else {
26164 self.write("1");
26165 }
26166 self.write(")");
26167 }
26168 } else if matches!(
26169 self.config.dialect,
26170 Some(DialectType::Snowflake) | Some(DialectType::SQLite)
26171 ) {
26172 self.write_keyword("AUTOINCREMENT");
26173 if let Some(ref start) = col.auto_increment_start {
26174 self.write_space();
26175 self.write_keyword("START");
26176 self.write_space();
26177 self.generate_expression(start)?;
26178 }
26179 if let Some(ref inc) = col.auto_increment_increment {
26180 self.write_space();
26181 self.write_keyword("INCREMENT");
26182 self.write_space();
26183 self.generate_expression(inc)?;
26184 }
26185 if let Some(order) = col.auto_increment_order {
26186 self.write_space();
26187 if order {
26188 self.write_keyword("ORDER");
26189 } else {
26190 self.write_keyword("NOORDER");
26191 }
26192 }
26193 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
26194 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
26195 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26196 self.write(" (");
26197 let mut first = true;
26198 if let Some(ref start) = col.auto_increment_start {
26199 self.write_keyword("START WITH");
26200 self.write_space();
26201 self.generate_expression(start)?;
26202 first = false;
26203 }
26204 if let Some(ref inc) = col.auto_increment_increment {
26205 if !first {
26206 self.write_space();
26207 }
26208 self.write_keyword("INCREMENT BY");
26209 self.write_space();
26210 self.generate_expression(inc)?;
26211 }
26212 self.write(")");
26213 }
26214 } else if matches!(self.config.dialect, Some(DialectType::Databricks)) {
26215 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26218 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
26219 } else {
26220 self.write_keyword("GENERATED ALWAYS AS IDENTITY");
26221 }
26222 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26223 self.write(" (");
26224 let mut first = true;
26225 if let Some(ref start) = col.auto_increment_start {
26226 self.write_keyword("START WITH");
26227 self.write_space();
26228 self.generate_expression(start)?;
26229 first = false;
26230 }
26231 if let Some(ref inc) = col.auto_increment_increment {
26232 if !first {
26233 self.write_space();
26234 }
26235 self.write_keyword("INCREMENT BY");
26236 self.write_space();
26237 self.generate_expression(inc)?;
26238 }
26239 self.write(")");
26240 }
26241 } else if matches!(
26242 self.config.dialect,
26243 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26244 ) {
26245 self.write_keyword("IDENTITY");
26246 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26247 self.write("(");
26248 if let Some(ref start) = col.auto_increment_start {
26249 self.generate_expression(start)?;
26250 } else {
26251 self.write("0");
26252 }
26253 self.write(", ");
26254 if let Some(ref inc) = col.auto_increment_increment {
26255 self.generate_expression(inc)?;
26256 } else {
26257 self.write("1");
26258 }
26259 self.write(")");
26260 }
26261 } else {
26262 self.write_keyword("AUTO_INCREMENT");
26263 if let Some(ref start) = col.auto_increment_start {
26264 self.write_space();
26265 self.write_keyword("START");
26266 self.write_space();
26267 self.generate_expression(start)?;
26268 }
26269 if let Some(ref inc) = col.auto_increment_increment {
26270 self.write_space();
26271 self.write_keyword("INCREMENT");
26272 self.write_space();
26273 self.generate_expression(inc)?;
26274 }
26275 if let Some(order) = col.auto_increment_order {
26276 self.write_space();
26277 if order {
26278 self.write_keyword("ORDER");
26279 } else {
26280 self.write_keyword("NOORDER");
26281 }
26282 }
26283 }
26284 Ok(())
26285 }
26286
26287 fn generate_auto_increment_property(&mut self, e: &AutoIncrementProperty) -> Result<()> {
26288 self.write_keyword("AUTO_INCREMENT");
26290 self.write("=");
26291 self.generate_expression(&e.this)?;
26292 Ok(())
26293 }
26294
26295 fn generate_auto_refresh_property(&mut self, e: &AutoRefreshProperty) -> Result<()> {
26296 self.write_keyword("AUTO_REFRESH");
26298 self.write("=");
26299 self.generate_expression(&e.this)?;
26300 Ok(())
26301 }
26302
26303 fn generate_backup_property(&mut self, e: &BackupProperty) -> Result<()> {
26304 self.write_keyword("BACKUP");
26306 self.write_space();
26307 self.generate_expression(&e.this)?;
26308 Ok(())
26309 }
26310
26311 fn generate_base64_decode_binary(&mut self, e: &Base64DecodeBinary) -> Result<()> {
26312 self.write_keyword("BASE64_DECODE_BINARY");
26314 self.write("(");
26315 self.generate_expression(&e.this)?;
26316 if let Some(alphabet) = &e.alphabet {
26317 self.write(", ");
26318 self.generate_expression(alphabet)?;
26319 }
26320 self.write(")");
26321 Ok(())
26322 }
26323
26324 fn generate_base64_decode_string(&mut self, e: &Base64DecodeString) -> Result<()> {
26325 self.write_keyword("BASE64_DECODE_STRING");
26327 self.write("(");
26328 self.generate_expression(&e.this)?;
26329 if let Some(alphabet) = &e.alphabet {
26330 self.write(", ");
26331 self.generate_expression(alphabet)?;
26332 }
26333 self.write(")");
26334 Ok(())
26335 }
26336
26337 fn generate_base64_encode(&mut self, e: &Base64Encode) -> Result<()> {
26338 self.write_keyword("BASE64_ENCODE");
26340 self.write("(");
26341 self.generate_expression(&e.this)?;
26342 if let Some(max_line_length) = &e.max_line_length {
26343 self.write(", ");
26344 self.generate_expression(max_line_length)?;
26345 }
26346 if let Some(alphabet) = &e.alphabet {
26347 self.write(", ");
26348 self.generate_expression(alphabet)?;
26349 }
26350 self.write(")");
26351 Ok(())
26352 }
26353
26354 fn generate_block_compression_property(&mut self, e: &BlockCompressionProperty) -> Result<()> {
26355 self.write_keyword("BLOCKCOMPRESSION");
26357 self.write("=");
26358 if let Some(autotemp) = &e.autotemp {
26359 self.write_keyword("AUTOTEMP");
26360 self.write("(");
26361 self.generate_expression(autotemp)?;
26362 self.write(")");
26363 }
26364 if let Some(always) = &e.always {
26365 self.generate_expression(always)?;
26366 }
26367 if let Some(default) = &e.default {
26368 self.generate_expression(default)?;
26369 }
26370 if let Some(manual) = &e.manual {
26371 self.generate_expression(manual)?;
26372 }
26373 if let Some(never) = &e.never {
26374 self.generate_expression(never)?;
26375 }
26376 Ok(())
26377 }
26378
26379 fn generate_booland(&mut self, e: &Booland) -> Result<()> {
26380 self.write("((");
26382 self.generate_expression(&e.this)?;
26383 self.write(") ");
26384 self.write_keyword("AND");
26385 self.write(" (");
26386 self.generate_expression(&e.expression)?;
26387 self.write("))");
26388 Ok(())
26389 }
26390
26391 fn generate_boolor(&mut self, e: &Boolor) -> Result<()> {
26392 self.write("((");
26394 self.generate_expression(&e.this)?;
26395 self.write(") ");
26396 self.write_keyword("OR");
26397 self.write(" (");
26398 self.generate_expression(&e.expression)?;
26399 self.write("))");
26400 Ok(())
26401 }
26402
26403 fn generate_build_property(&mut self, e: &BuildProperty) -> Result<()> {
26404 self.write_keyword("BUILD");
26406 self.write_space();
26407 self.generate_expression(&e.this)?;
26408 Ok(())
26409 }
26410
26411 fn generate_byte_string(&mut self, e: &ByteString) -> Result<()> {
26412 self.generate_expression(&e.this)?;
26414 Ok(())
26415 }
26416
26417 fn generate_case_specific_column_constraint(
26418 &mut self,
26419 e: &CaseSpecificColumnConstraint,
26420 ) -> Result<()> {
26421 if e.not_.is_some() {
26423 self.write_keyword("NOT");
26424 self.write_space();
26425 }
26426 self.write_keyword("CASESPECIFIC");
26427 Ok(())
26428 }
26429
26430 fn generate_cast_to_str_type(&mut self, e: &CastToStrType) -> Result<()> {
26431 self.write_keyword("CAST");
26433 self.write("(");
26434 self.generate_expression(&e.this)?;
26435 if self.config.dialect == Some(DialectType::ClickHouse) {
26436 self.write(", ");
26438 } else {
26439 self.write_space();
26440 self.write_keyword("AS");
26441 self.write_space();
26442 }
26443 if let Some(to) = &e.to {
26444 self.generate_expression(to)?;
26445 }
26446 self.write(")");
26447 Ok(())
26448 }
26449
26450 fn generate_changes(&mut self, e: &Changes) -> Result<()> {
26451 self.write_keyword("CHANGES");
26454 self.write(" (");
26455 if let Some(information) = &e.information {
26456 self.write_keyword("INFORMATION");
26457 self.write(" => ");
26458 self.generate_expression(information)?;
26459 }
26460 self.write(")");
26461 if let Some(at_before) = &e.at_before {
26463 self.write(" ");
26464 self.generate_expression(at_before)?;
26465 }
26466 if let Some(end) = &e.end {
26467 self.write(" ");
26468 self.generate_expression(end)?;
26469 }
26470 Ok(())
26471 }
26472
26473 fn generate_character_set_column_constraint(
26474 &mut self,
26475 e: &CharacterSetColumnConstraint,
26476 ) -> Result<()> {
26477 self.write_keyword("CHARACTER SET");
26479 self.write_space();
26480 self.generate_expression(&e.this)?;
26481 Ok(())
26482 }
26483
26484 fn generate_character_set_property(&mut self, e: &CharacterSetProperty) -> Result<()> {
26485 if e.default.is_some() {
26487 self.write_keyword("DEFAULT");
26488 self.write_space();
26489 }
26490 self.write_keyword("CHARACTER SET");
26491 self.write("=");
26492 self.generate_expression(&e.this)?;
26493 Ok(())
26494 }
26495
26496 fn generate_check_column_constraint(&mut self, e: &CheckColumnConstraint) -> Result<()> {
26497 self.write_keyword("CHECK");
26499 self.write(" (");
26500 self.generate_expression(&e.this)?;
26501 self.write(")");
26502 if e.enforced.is_some() {
26503 self.write_space();
26504 self.write_keyword("ENFORCED");
26505 }
26506 Ok(())
26507 }
26508
26509 fn generate_assume_column_constraint(&mut self, e: &AssumeColumnConstraint) -> Result<()> {
26510 self.write_keyword("ASSUME");
26512 self.write(" (");
26513 self.generate_expression(&e.this)?;
26514 self.write(")");
26515 Ok(())
26516 }
26517
26518 fn generate_check_json(&mut self, e: &CheckJson) -> Result<()> {
26519 self.write_keyword("CHECK_JSON");
26521 self.write("(");
26522 self.generate_expression(&e.this)?;
26523 self.write(")");
26524 Ok(())
26525 }
26526
26527 fn generate_check_xml(&mut self, e: &CheckXml) -> Result<()> {
26528 self.write_keyword("CHECK_XML");
26530 self.write("(");
26531 self.generate_expression(&e.this)?;
26532 self.write(")");
26533 Ok(())
26534 }
26535
26536 fn generate_checksum_property(&mut self, e: &ChecksumProperty) -> Result<()> {
26537 self.write_keyword("CHECKSUM");
26539 self.write("=");
26540 if e.on.is_some() {
26541 self.write_keyword("ON");
26542 } else if e.default.is_some() {
26543 self.write_keyword("DEFAULT");
26544 } else {
26545 self.write_keyword("OFF");
26546 }
26547 Ok(())
26548 }
26549
26550 fn generate_clone(&mut self, e: &Clone) -> Result<()> {
26551 if e.shallow.is_some() {
26553 self.write_keyword("SHALLOW");
26554 self.write_space();
26555 }
26556 if e.copy.is_some() {
26557 self.write_keyword("COPY");
26558 } else {
26559 self.write_keyword("CLONE");
26560 }
26561 self.write_space();
26562 self.generate_expression(&e.this)?;
26563 Ok(())
26564 }
26565
26566 fn generate_cluster_by(&mut self, e: &ClusterBy) -> Result<()> {
26567 self.write_keyword("CLUSTER BY");
26569 self.write(" (");
26570 for (i, ord) in e.expressions.iter().enumerate() {
26571 if i > 0 {
26572 self.write(", ");
26573 }
26574 self.generate_ordered(ord)?;
26575 }
26576 self.write(")");
26577 Ok(())
26578 }
26579
26580 fn generate_cluster_by_columns_property(&mut self, e: &ClusterByColumnsProperty) -> Result<()> {
26581 self.write_keyword("CLUSTER BY");
26583 self.write_space();
26584 for (i, col) in e.columns.iter().enumerate() {
26585 if i > 0 {
26586 self.write(", ");
26587 }
26588 self.generate_identifier(col)?;
26589 }
26590 Ok(())
26591 }
26592
26593 fn generate_clustered_by_property(&mut self, e: &ClusteredByProperty) -> Result<()> {
26594 self.write_keyword("CLUSTERED BY");
26596 self.write(" (");
26597 for (i, expr) in e.expressions.iter().enumerate() {
26598 if i > 0 {
26599 self.write(", ");
26600 }
26601 self.generate_expression(expr)?;
26602 }
26603 self.write(")");
26604 if let Some(sorted_by) = &e.sorted_by {
26605 self.write_space();
26606 self.write_keyword("SORTED BY");
26607 self.write(" (");
26608 if let Expression::Tuple(t) = sorted_by.as_ref() {
26610 for (i, expr) in t.expressions.iter().enumerate() {
26611 if i > 0 {
26612 self.write(", ");
26613 }
26614 self.generate_expression(expr)?;
26615 }
26616 } else {
26617 self.generate_expression(sorted_by)?;
26618 }
26619 self.write(")");
26620 }
26621 if let Some(buckets) = &e.buckets {
26622 self.write_space();
26623 self.write_keyword("INTO");
26624 self.write_space();
26625 self.generate_expression(buckets)?;
26626 self.write_space();
26627 self.write_keyword("BUCKETS");
26628 }
26629 Ok(())
26630 }
26631
26632 fn generate_collate_property(&mut self, e: &CollateProperty) -> Result<()> {
26633 if e.default.is_some() {
26637 self.write_keyword("DEFAULT");
26638 self.write_space();
26639 }
26640 self.write_keyword("COLLATE");
26641 match self.config.dialect {
26643 Some(DialectType::BigQuery) => self.write_space(),
26644 _ => self.write("="),
26645 }
26646 self.generate_expression(&e.this)?;
26647 Ok(())
26648 }
26649
26650 fn generate_column_constraint(&mut self, e: &ColumnConstraint) -> Result<()> {
26651 match e {
26653 ColumnConstraint::NotNull => {
26654 self.write_keyword("NOT NULL");
26655 }
26656 ColumnConstraint::Null => {
26657 self.write_keyword("NULL");
26658 }
26659 ColumnConstraint::Unique => {
26660 self.write_keyword("UNIQUE");
26661 }
26662 ColumnConstraint::PrimaryKey => {
26663 self.write_keyword("PRIMARY KEY");
26664 }
26665 ColumnConstraint::Default(expr) => {
26666 self.write_keyword("DEFAULT");
26667 self.write_space();
26668 self.generate_expression(expr)?;
26669 }
26670 ColumnConstraint::Check(expr) => {
26671 self.write_keyword("CHECK");
26672 self.write(" (");
26673 self.generate_expression(expr)?;
26674 self.write(")");
26675 }
26676 ColumnConstraint::References(fk_ref) => {
26677 if fk_ref.has_foreign_key_keywords {
26678 self.write_keyword("FOREIGN KEY");
26679 self.write_space();
26680 }
26681 self.write_keyword("REFERENCES");
26682 self.write_space();
26683 self.generate_table(&fk_ref.table)?;
26684 if !fk_ref.columns.is_empty() {
26685 self.write(" (");
26686 for (i, col) in fk_ref.columns.iter().enumerate() {
26687 if i > 0 {
26688 self.write(", ");
26689 }
26690 self.generate_identifier(col)?;
26691 }
26692 self.write(")");
26693 }
26694 }
26695 ColumnConstraint::GeneratedAsIdentity(gen) => {
26696 self.write_keyword("GENERATED");
26697 self.write_space();
26698 if gen.always {
26699 self.write_keyword("ALWAYS");
26700 } else {
26701 self.write_keyword("BY DEFAULT");
26702 if gen.on_null {
26703 self.write_space();
26704 self.write_keyword("ON NULL");
26705 }
26706 }
26707 self.write_space();
26708 self.write_keyword("AS IDENTITY");
26709 }
26710 ColumnConstraint::Collate(collation) => {
26711 self.write_keyword("COLLATE");
26712 self.write_space();
26713 self.generate_identifier(collation)?;
26714 }
26715 ColumnConstraint::Comment(comment) => {
26716 self.write_keyword("COMMENT");
26717 self.write(" '");
26718 self.write(comment);
26719 self.write("'");
26720 }
26721 ColumnConstraint::ComputedColumn(cc) => {
26722 self.generate_computed_column_inline(cc)?;
26723 }
26724 ColumnConstraint::GeneratedAsRow(gar) => {
26725 self.generate_generated_as_row_inline(gar)?;
26726 }
26727 ColumnConstraint::Tags(tags) => {
26728 self.write_keyword("TAG");
26729 self.write(" (");
26730 for (i, expr) in tags.expressions.iter().enumerate() {
26731 if i > 0 {
26732 self.write(", ");
26733 }
26734 self.generate_expression(expr)?;
26735 }
26736 self.write(")");
26737 }
26738 ColumnConstraint::Path(path_expr) => {
26739 self.write_keyword("PATH");
26740 self.write_space();
26741 self.generate_expression(path_expr)?;
26742 }
26743 }
26744 Ok(())
26745 }
26746
26747 fn generate_column_position(&mut self, e: &ColumnPosition) -> Result<()> {
26748 match e {
26750 ColumnPosition::First => {
26751 self.write_keyword("FIRST");
26752 }
26753 ColumnPosition::After(ident) => {
26754 self.write_keyword("AFTER");
26755 self.write_space();
26756 self.generate_identifier(ident)?;
26757 }
26758 }
26759 Ok(())
26760 }
26761
26762 fn generate_column_prefix(&mut self, e: &ColumnPrefix) -> Result<()> {
26763 self.generate_expression(&e.this)?;
26765 self.write("(");
26766 self.generate_expression(&e.expression)?;
26767 self.write(")");
26768 Ok(())
26769 }
26770
26771 fn generate_columns(&mut self, e: &Columns) -> Result<()> {
26772 if let Some(ref unpack) = e.unpack {
26775 if let Expression::Boolean(b) = unpack.as_ref() {
26776 if b.value {
26777 self.write("*");
26778 }
26779 }
26780 }
26781 self.write_keyword("COLUMNS");
26782 self.write("(");
26783 self.generate_expression(&e.this)?;
26784 self.write(")");
26785 Ok(())
26786 }
26787
26788 fn generate_combined_agg_func(&mut self, e: &CombinedAggFunc) -> Result<()> {
26789 self.generate_expression(&e.this)?;
26791 self.write("(");
26792 for (i, expr) in e.expressions.iter().enumerate() {
26793 if i > 0 {
26794 self.write(", ");
26795 }
26796 self.generate_expression(expr)?;
26797 }
26798 self.write(")");
26799 Ok(())
26800 }
26801
26802 fn generate_combined_parameterized_agg(&mut self, e: &CombinedParameterizedAgg) -> Result<()> {
26803 self.generate_expression(&e.this)?;
26805 self.write("(");
26806 for (i, param) in e.params.iter().enumerate() {
26807 if i > 0 {
26808 self.write(", ");
26809 }
26810 self.generate_expression(param)?;
26811 }
26812 self.write(")(");
26813 for (i, expr) in e.expressions.iter().enumerate() {
26814 if i > 0 {
26815 self.write(", ");
26816 }
26817 self.generate_expression(expr)?;
26818 }
26819 self.write(")");
26820 Ok(())
26821 }
26822
26823 fn generate_commit(&mut self, e: &Commit) -> Result<()> {
26824 self.write_keyword("COMMIT");
26826
26827 if e.this.is_none()
26829 && matches!(
26830 self.config.dialect,
26831 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26832 )
26833 {
26834 self.write_space();
26835 self.write_keyword("TRANSACTION");
26836 }
26837
26838 if let Some(this) = &e.this {
26840 let is_transaction_marker = matches!(
26842 this.as_ref(),
26843 Expression::Identifier(id) if id.name == "TRANSACTION"
26844 );
26845
26846 self.write_space();
26847 self.write_keyword("TRANSACTION");
26848
26849 if !is_transaction_marker {
26851 self.write_space();
26852 self.generate_expression(this)?;
26853 }
26854 }
26855
26856 if let Some(durability) = &e.durability {
26858 self.write_space();
26859 self.write_keyword("WITH");
26860 self.write(" (");
26861 self.write_keyword("DELAYED_DURABILITY");
26862 self.write(" = ");
26863 if let Expression::Boolean(BooleanLiteral { value: true }) = durability.as_ref() {
26864 self.write_keyword("ON");
26865 } else {
26866 self.write_keyword("OFF");
26867 }
26868 self.write(")");
26869 }
26870
26871 if let Some(chain) = &e.chain {
26873 self.write_space();
26874 if let Expression::Boolean(BooleanLiteral { value: false }) = chain.as_ref() {
26875 self.write_keyword("AND NO CHAIN");
26876 } else {
26877 self.write_keyword("AND CHAIN");
26878 }
26879 }
26880 Ok(())
26881 }
26882
26883 fn generate_comprehension(&mut self, e: &Comprehension) -> Result<()> {
26884 self.write("[");
26886 self.generate_expression(&e.this)?;
26887 self.write_space();
26888 self.write_keyword("FOR");
26889 self.write_space();
26890 self.generate_expression(&e.expression)?;
26891 if let Some(pos) = &e.position {
26893 self.write(", ");
26894 self.generate_expression(pos)?;
26895 }
26896 if let Some(iterator) = &e.iterator {
26897 self.write_space();
26898 self.write_keyword("IN");
26899 self.write_space();
26900 self.generate_expression(iterator)?;
26901 }
26902 if let Some(condition) = &e.condition {
26903 self.write_space();
26904 self.write_keyword("IF");
26905 self.write_space();
26906 self.generate_expression(condition)?;
26907 }
26908 self.write("]");
26909 Ok(())
26910 }
26911
26912 fn generate_compress(&mut self, e: &Compress) -> Result<()> {
26913 self.write_keyword("COMPRESS");
26915 self.write("(");
26916 self.generate_expression(&e.this)?;
26917 if let Some(method) = &e.method {
26918 self.write(", '");
26919 self.write(method);
26920 self.write("'");
26921 }
26922 self.write(")");
26923 Ok(())
26924 }
26925
26926 fn generate_compress_column_constraint(&mut self, e: &CompressColumnConstraint) -> Result<()> {
26927 self.write_keyword("COMPRESS");
26929 if let Some(this) = &e.this {
26930 self.write_space();
26931 self.generate_expression(this)?;
26932 }
26933 Ok(())
26934 }
26935
26936 fn generate_computed_column_constraint(&mut self, e: &ComputedColumnConstraint) -> Result<()> {
26937 self.write_keyword("AS");
26939 self.write_space();
26940 self.generate_expression(&e.this)?;
26941 if e.not_null.is_some() {
26942 self.write_space();
26943 self.write_keyword("PERSISTED NOT NULL");
26944 } else if e.persisted.is_some() {
26945 self.write_space();
26946 self.write_keyword("PERSISTED");
26947 }
26948 Ok(())
26949 }
26950
26951 fn generate_computed_column_inline(&mut self, cc: &ComputedColumn) -> Result<()> {
26955 let computed_expr = if matches!(
26956 self.config.dialect,
26957 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26958 ) {
26959 match &*cc.expression {
26960 Expression::Year(y) if !matches!(&y.this, Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
26961 {
26962 let wrapped = Expression::Cast(Box::new(Cast {
26963 this: y.this.clone(),
26964 to: DataType::Date,
26965 trailing_comments: Vec::new(),
26966 double_colon_syntax: false,
26967 format: None,
26968 default: None,
26969 inferred_type: None,
26970 }));
26971 Expression::Year(Box::new(UnaryFunc::new(wrapped)))
26972 }
26973 Expression::Function(f)
26974 if f.name.eq_ignore_ascii_case("YEAR")
26975 && f.args.len() == 1
26976 && !matches!(&f.args[0], Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
26977 {
26978 let wrapped = Expression::Cast(Box::new(Cast {
26979 this: f.args[0].clone(),
26980 to: DataType::Date,
26981 trailing_comments: Vec::new(),
26982 double_colon_syntax: false,
26983 format: None,
26984 default: None,
26985 inferred_type: None,
26986 }));
26987 Expression::Function(Box::new(Function::new("YEAR".to_string(), vec![wrapped])))
26988 }
26989 _ => *cc.expression.clone(),
26990 }
26991 } else {
26992 *cc.expression.clone()
26993 };
26994
26995 match cc.persistence_kind.as_deref() {
26996 Some("STORED") | Some("VIRTUAL") => {
26997 self.write_keyword("GENERATED ALWAYS AS");
26999 self.write(" (");
27000 self.generate_expression(&computed_expr)?;
27001 self.write(")");
27002 self.write_space();
27003 if cc.persisted {
27004 self.write_keyword("STORED");
27005 } else {
27006 self.write_keyword("VIRTUAL");
27007 }
27008 }
27009 Some("PERSISTED") => {
27010 self.write_keyword("AS");
27012 self.write(" (");
27013 self.generate_expression(&computed_expr)?;
27014 self.write(")");
27015 self.write_space();
27016 self.write_keyword("PERSISTED");
27017 if let Some(ref dt) = cc.data_type {
27019 self.write_space();
27020 self.generate_data_type(dt)?;
27021 }
27022 if cc.not_null {
27023 self.write_space();
27024 self.write_keyword("NOT NULL");
27025 }
27026 }
27027 _ => {
27028 if matches!(
27031 self.config.dialect,
27032 Some(DialectType::Spark)
27033 | Some(DialectType::Databricks)
27034 | Some(DialectType::Hive)
27035 ) {
27036 self.write_keyword("GENERATED ALWAYS AS");
27037 self.write(" (");
27038 self.generate_expression(&computed_expr)?;
27039 self.write(")");
27040 } else if matches!(
27041 self.config.dialect,
27042 Some(DialectType::TSQL) | Some(DialectType::Fabric)
27043 ) {
27044 self.write_keyword("AS");
27045 let omit_parens = matches!(computed_expr, Expression::Year(_))
27046 || matches!(&computed_expr, Expression::Function(f) if f.name.eq_ignore_ascii_case("YEAR"));
27047 if omit_parens {
27048 self.write_space();
27049 self.generate_expression(&computed_expr)?;
27050 } else {
27051 self.write(" (");
27052 self.generate_expression(&computed_expr)?;
27053 self.write(")");
27054 }
27055 } else {
27056 self.write_keyword("AS");
27057 self.write(" (");
27058 self.generate_expression(&computed_expr)?;
27059 self.write(")");
27060 }
27061 }
27062 }
27063 Ok(())
27064 }
27065
27066 fn generate_generated_as_row_inline(&mut self, gar: &GeneratedAsRow) -> Result<()> {
27069 self.write_keyword("GENERATED ALWAYS AS ROW ");
27070 if gar.start {
27071 self.write_keyword("START");
27072 } else {
27073 self.write_keyword("END");
27074 }
27075 if gar.hidden {
27076 self.write_space();
27077 self.write_keyword("HIDDEN");
27078 }
27079 Ok(())
27080 }
27081
27082 fn generate_system_versioning_content(
27084 &mut self,
27085 e: &WithSystemVersioningProperty,
27086 ) -> Result<()> {
27087 let mut parts = Vec::new();
27088
27089 if let Some(this) = &e.this {
27090 let mut s = String::from("HISTORY_TABLE=");
27091 let mut gen = Generator::with_arc_config(self.config.clone());
27092 gen.generate_expression(this)?;
27093 s.push_str(&gen.output);
27094 parts.push(s);
27095 }
27096
27097 if let Some(data_consistency) = &e.data_consistency {
27098 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
27099 let mut gen = Generator::with_arc_config(self.config.clone());
27100 gen.generate_expression(data_consistency)?;
27101 s.push_str(&gen.output);
27102 parts.push(s);
27103 }
27104
27105 if let Some(retention_period) = &e.retention_period {
27106 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
27107 let mut gen = Generator::with_arc_config(self.config.clone());
27108 gen.generate_expression(retention_period)?;
27109 s.push_str(&gen.output);
27110 parts.push(s);
27111 }
27112
27113 self.write_keyword("SYSTEM_VERSIONING");
27114 self.write("=");
27115
27116 if !parts.is_empty() {
27117 self.write_keyword("ON");
27118 self.write("(");
27119 self.write(&parts.join(", "));
27120 self.write(")");
27121 } else if e.on.is_some() {
27122 self.write_keyword("ON");
27123 } else {
27124 self.write_keyword("OFF");
27125 }
27126
27127 Ok(())
27128 }
27129
27130 fn generate_conditional_insert(&mut self, e: &ConditionalInsert) -> Result<()> {
27131 if e.else_.is_some() {
27134 self.write_keyword("ELSE");
27135 self.write_space();
27136 } else if let Some(expression) = &e.expression {
27137 self.write_keyword("WHEN");
27138 self.write_space();
27139 self.generate_expression(expression)?;
27140 self.write_space();
27141 self.write_keyword("THEN");
27142 self.write_space();
27143 }
27144
27145 if let Expression::Insert(insert) = e.this.as_ref() {
27148 self.write_keyword("INTO");
27149 self.write_space();
27150 self.generate_table(&insert.table)?;
27151
27152 if !insert.columns.is_empty() {
27154 self.write(" (");
27155 for (i, col) in insert.columns.iter().enumerate() {
27156 if i > 0 {
27157 self.write(", ");
27158 }
27159 self.generate_identifier(col)?;
27160 }
27161 self.write(")");
27162 }
27163
27164 if !insert.values.is_empty() {
27166 self.write_space();
27167 self.write_keyword("VALUES");
27168 for (row_idx, row) in insert.values.iter().enumerate() {
27169 if row_idx > 0 {
27170 self.write(", ");
27171 }
27172 self.write(" (");
27173 for (i, val) in row.iter().enumerate() {
27174 if i > 0 {
27175 self.write(", ");
27176 }
27177 self.generate_expression(val)?;
27178 }
27179 self.write(")");
27180 }
27181 }
27182 } else {
27183 self.generate_expression(&e.this)?;
27185 }
27186 Ok(())
27187 }
27188
27189 fn generate_constraint(&mut self, e: &Constraint) -> Result<()> {
27190 self.write_keyword("CONSTRAINT");
27192 self.write_space();
27193 self.generate_expression(&e.this)?;
27194 if !e.expressions.is_empty() {
27195 self.write_space();
27196 for (i, expr) in e.expressions.iter().enumerate() {
27197 if i > 0 {
27198 self.write_space();
27199 }
27200 self.generate_expression(expr)?;
27201 }
27202 }
27203 Ok(())
27204 }
27205
27206 fn generate_convert_timezone(&mut self, e: &ConvertTimezone) -> Result<()> {
27207 self.write_keyword("CONVERT_TIMEZONE");
27209 self.write("(");
27210 let mut first = true;
27211 if let Some(source_tz) = &e.source_tz {
27212 self.generate_expression(source_tz)?;
27213 first = false;
27214 }
27215 if let Some(target_tz) = &e.target_tz {
27216 if !first {
27217 self.write(", ");
27218 }
27219 self.generate_expression(target_tz)?;
27220 first = false;
27221 }
27222 if let Some(timestamp) = &e.timestamp {
27223 if !first {
27224 self.write(", ");
27225 }
27226 self.generate_expression(timestamp)?;
27227 }
27228 self.write(")");
27229 Ok(())
27230 }
27231
27232 fn generate_convert_to_charset(&mut self, e: &ConvertToCharset) -> Result<()> {
27233 self.write_keyword("CONVERT");
27235 self.write("(");
27236 self.generate_expression(&e.this)?;
27237 if let Some(dest) = &e.dest {
27238 self.write_space();
27239 self.write_keyword("USING");
27240 self.write_space();
27241 self.generate_expression(dest)?;
27242 }
27243 self.write(")");
27244 Ok(())
27245 }
27246
27247 fn generate_copy(&mut self, e: &CopyStmt) -> Result<()> {
27248 self.write_keyword("COPY");
27249 if e.is_into {
27250 self.write_space();
27251 self.write_keyword("INTO");
27252 }
27253 self.write_space();
27254
27255 if let Expression::Literal(lit) = &e.this {
27257 if let Literal::String(s) = lit.as_ref() {
27258 if s.starts_with('@') {
27259 self.write(s);
27260 } else {
27261 self.generate_expression(&e.this)?;
27262 }
27263 }
27264 } else {
27265 self.generate_expression(&e.this)?;
27266 }
27267
27268 if e.kind {
27270 if self.config.pretty {
27272 self.write_newline();
27273 } else {
27274 self.write_space();
27275 }
27276 self.write_keyword("FROM");
27277 self.write_space();
27278 } else if !e.files.is_empty() {
27279 if self.config.pretty {
27281 self.write_newline();
27282 } else {
27283 self.write_space();
27284 }
27285 self.write_keyword("TO");
27286 self.write_space();
27287 }
27288
27289 for (i, file) in e.files.iter().enumerate() {
27291 if i > 0 {
27292 self.write_space();
27293 }
27294 if let Expression::Literal(lit) = file {
27296 if let Literal::String(s) = lit.as_ref() {
27297 if s.starts_with('@') {
27298 self.write(s);
27299 } else {
27300 self.generate_expression(file)?;
27301 }
27302 }
27303 } else if let Expression::Identifier(id) = file {
27304 if id.quoted {
27306 self.write("`");
27307 self.write(&id.name);
27308 self.write("`");
27309 } else {
27310 self.generate_expression(file)?;
27311 }
27312 } else {
27313 self.generate_expression(file)?;
27314 }
27315 }
27316
27317 if !e.with_wrapped {
27319 if let Some(ref creds) = e.credentials {
27320 if let Some(ref storage) = creds.storage {
27321 if self.config.pretty {
27322 self.write_newline();
27323 } else {
27324 self.write_space();
27325 }
27326 self.write_keyword("STORAGE_INTEGRATION");
27327 self.write(" = ");
27328 self.write(storage);
27329 }
27330 if creds.credentials.is_empty() {
27331 if self.config.pretty {
27333 self.write_newline();
27334 } else {
27335 self.write_space();
27336 }
27337 self.write_keyword("CREDENTIALS");
27338 self.write(" = ()");
27339 } else {
27340 if self.config.pretty {
27341 self.write_newline();
27342 } else {
27343 self.write_space();
27344 }
27345 self.write_keyword("CREDENTIALS");
27346 if creds.credentials.len() == 1 && creds.credentials[0].0.is_empty() {
27349 self.write(" '");
27351 self.write(&creds.credentials[0].1);
27352 self.write("'");
27353 } else {
27354 self.write(" = (");
27356 for (i, (k, v)) in creds.credentials.iter().enumerate() {
27357 if i > 0 {
27358 self.write_space();
27359 }
27360 self.write(k);
27361 self.write("='");
27362 self.write(v);
27363 self.write("'");
27364 }
27365 self.write(")");
27366 }
27367 }
27368 if let Some(ref encryption) = creds.encryption {
27369 self.write_space();
27370 self.write_keyword("ENCRYPTION");
27371 self.write(" = ");
27372 self.write(encryption);
27373 }
27374 }
27375 }
27376
27377 if !e.params.is_empty() {
27379 if e.with_wrapped {
27380 self.write_space();
27382 self.write_keyword("WITH");
27383 self.write(" (");
27384 for (i, param) in e.params.iter().enumerate() {
27385 if i > 0 {
27386 self.write(", ");
27387 }
27388 self.generate_copy_param_with_format(param)?;
27389 }
27390 self.write(")");
27391 } else {
27392 for param in &e.params {
27396 if self.config.pretty {
27397 self.write_newline();
27398 } else {
27399 self.write_space();
27400 }
27401 self.write(¶m.name);
27403 if let Some(ref value) = param.value {
27404 if param.eq {
27406 self.write(" = ");
27407 } else {
27408 self.write(" ");
27409 }
27410 if !param.values.is_empty() {
27411 self.write("(");
27412 for (i, v) in param.values.iter().enumerate() {
27413 if i > 0 {
27414 self.write_space();
27415 }
27416 self.generate_copy_nested_param(v)?;
27417 }
27418 self.write(")");
27419 } else {
27420 self.generate_copy_param_value(value)?;
27422 }
27423 } else if !param.values.is_empty() {
27424 if param.eq {
27426 self.write(" = (");
27427 } else {
27428 self.write(" (");
27429 }
27430 let is_key_value_pairs = param
27435 .values
27436 .first()
27437 .map_or(false, |v| matches!(v, Expression::Eq(_)));
27438 let sep = if is_key_value_pairs && param.eq {
27439 " "
27440 } else {
27441 ", "
27442 };
27443 for (i, v) in param.values.iter().enumerate() {
27444 if i > 0 {
27445 self.write(sep);
27446 }
27447 self.generate_copy_nested_param(v)?;
27448 }
27449 self.write(")");
27450 }
27451 }
27452 }
27453 }
27454
27455 Ok(())
27456 }
27457
27458 fn generate_copy_param_with_format(&mut self, param: &CopyParameter) -> Result<()> {
27461 self.write_keyword(¶m.name);
27462 if !param.values.is_empty() {
27463 self.write(" = (");
27465 for (i, v) in param.values.iter().enumerate() {
27466 if i > 0 {
27467 self.write(", ");
27468 }
27469 self.generate_copy_nested_param(v)?;
27470 }
27471 self.write(")");
27472 } else if let Some(ref value) = param.value {
27473 if param.eq {
27474 self.write(" = ");
27475 } else {
27476 self.write(" ");
27477 }
27478 self.generate_expression(value)?;
27479 }
27480 Ok(())
27481 }
27482
27483 fn generate_copy_nested_param(&mut self, expr: &Expression) -> Result<()> {
27485 match expr {
27486 Expression::Eq(eq) => {
27487 match &eq.left {
27489 Expression::Column(c) => self.write(&c.name.name),
27490 _ => self.generate_expression(&eq.left)?,
27491 }
27492 self.write("=");
27493 match &eq.right {
27495 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
27496 let Literal::String(s) = lit.as_ref() else {
27497 unreachable!()
27498 };
27499 self.write("'");
27500 self.write(s);
27501 self.write("'");
27502 }
27503 Expression::Tuple(t) => {
27504 self.write("(");
27506 if self.config.pretty {
27507 self.write_newline();
27508 self.indent_level += 1;
27509 for (i, item) in t.expressions.iter().enumerate() {
27510 if i > 0 {
27511 self.write(", ");
27512 }
27513 self.write_indent();
27514 self.generate_expression(item)?;
27515 }
27516 self.write_newline();
27517 self.indent_level -= 1;
27518 } else {
27519 for (i, item) in t.expressions.iter().enumerate() {
27520 if i > 0 {
27521 self.write(", ");
27522 }
27523 self.generate_expression(item)?;
27524 }
27525 }
27526 self.write(")");
27527 }
27528 _ => self.generate_expression(&eq.right)?,
27529 }
27530 Ok(())
27531 }
27532 Expression::Column(c) => {
27533 self.write(&c.name.name);
27535 Ok(())
27536 }
27537 _ => self.generate_expression(expr),
27538 }
27539 }
27540
27541 fn generate_copy_param_value(&mut self, expr: &Expression) -> Result<()> {
27544 match expr {
27545 Expression::Column(c) => {
27546 if c.name.quoted {
27548 self.write("\"");
27549 self.write(&c.name.name);
27550 self.write("\"");
27551 } else {
27552 self.write(&c.name.name);
27553 }
27554 Ok(())
27555 }
27556 Expression::Identifier(id) => {
27557 if id.quoted {
27559 self.write("\"");
27560 self.write(&id.name);
27561 self.write("\"");
27562 } else {
27563 self.write(&id.name);
27564 }
27565 Ok(())
27566 }
27567 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
27568 let Literal::String(s) = lit.as_ref() else {
27569 unreachable!()
27570 };
27571 self.write("'");
27573 self.write(s);
27574 self.write("'");
27575 Ok(())
27576 }
27577 _ => self.generate_expression(expr),
27578 }
27579 }
27580
27581 fn generate_copy_parameter(&mut self, e: &CopyParameter) -> Result<()> {
27582 self.write_keyword(&e.name);
27583 if let Some(ref value) = e.value {
27584 if e.eq {
27585 self.write(" = ");
27586 } else {
27587 self.write(" ");
27588 }
27589 self.generate_expression(value)?;
27590 }
27591 if !e.values.is_empty() {
27592 if e.eq {
27593 self.write(" = ");
27594 } else {
27595 self.write(" ");
27596 }
27597 self.write("(");
27598 for (i, v) in e.values.iter().enumerate() {
27599 if i > 0 {
27600 self.write(", ");
27601 }
27602 self.generate_expression(v)?;
27603 }
27604 self.write(")");
27605 }
27606 Ok(())
27607 }
27608
27609 fn generate_corr(&mut self, e: &Corr) -> Result<()> {
27610 self.write_keyword("CORR");
27612 self.write("(");
27613 self.generate_expression(&e.this)?;
27614 self.write(", ");
27615 self.generate_expression(&e.expression)?;
27616 self.write(")");
27617 Ok(())
27618 }
27619
27620 fn generate_cosine_distance(&mut self, e: &CosineDistance) -> Result<()> {
27621 self.write_keyword("COSINE_DISTANCE");
27623 self.write("(");
27624 self.generate_expression(&e.this)?;
27625 self.write(", ");
27626 self.generate_expression(&e.expression)?;
27627 self.write(")");
27628 Ok(())
27629 }
27630
27631 fn generate_covar_pop(&mut self, e: &CovarPop) -> Result<()> {
27632 self.write_keyword("COVAR_POP");
27634 self.write("(");
27635 self.generate_expression(&e.this)?;
27636 self.write(", ");
27637 self.generate_expression(&e.expression)?;
27638 self.write(")");
27639 Ok(())
27640 }
27641
27642 fn generate_covar_samp(&mut self, e: &CovarSamp) -> Result<()> {
27643 self.write_keyword("COVAR_SAMP");
27645 self.write("(");
27646 self.generate_expression(&e.this)?;
27647 self.write(", ");
27648 self.generate_expression(&e.expression)?;
27649 self.write(")");
27650 Ok(())
27651 }
27652
27653 fn generate_credentials(&mut self, e: &Credentials) -> Result<()> {
27654 self.write_keyword("CREDENTIALS");
27656 self.write(" (");
27657 for (i, (key, value)) in e.credentials.iter().enumerate() {
27658 if i > 0 {
27659 self.write(", ");
27660 }
27661 self.write(key);
27662 self.write("='");
27663 self.write(value);
27664 self.write("'");
27665 }
27666 self.write(")");
27667 Ok(())
27668 }
27669
27670 fn generate_credentials_property(&mut self, e: &CredentialsProperty) -> Result<()> {
27671 self.write_keyword("CREDENTIALS");
27673 self.write("=(");
27674 for (i, expr) in e.expressions.iter().enumerate() {
27675 if i > 0 {
27676 self.write(", ");
27677 }
27678 self.generate_expression(expr)?;
27679 }
27680 self.write(")");
27681 Ok(())
27682 }
27683
27684 fn generate_cte(&mut self, e: &Cte) -> Result<()> {
27685 use crate::dialects::DialectType;
27686
27687 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !e.alias_first {
27690 self.generate_expression(&e.this)?;
27691 self.write_space();
27692 self.write_keyword("AS");
27693 self.write_space();
27694 self.generate_identifier(&e.alias)?;
27695 return Ok(());
27696 }
27697 self.write(&e.alias.name);
27698
27699 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
27701
27702 if !e.columns.is_empty() && !skip_cte_columns {
27703 self.write("(");
27704 for (i, col) in e.columns.iter().enumerate() {
27705 if i > 0 {
27706 self.write(", ");
27707 }
27708 self.write(&col.name);
27709 }
27710 self.write(")");
27711 }
27712 if !e.key_expressions.is_empty() {
27714 self.write_space();
27715 self.write_keyword("USING KEY");
27716 self.write(" (");
27717 for (i, key) in e.key_expressions.iter().enumerate() {
27718 if i > 0 {
27719 self.write(", ");
27720 }
27721 self.write(&key.name);
27722 }
27723 self.write(")");
27724 }
27725 self.write_space();
27726 self.write_keyword("AS");
27727 self.write_space();
27728 if let Some(materialized) = e.materialized {
27729 if materialized {
27730 self.write_keyword("MATERIALIZED");
27731 } else {
27732 self.write_keyword("NOT MATERIALIZED");
27733 }
27734 self.write_space();
27735 }
27736 self.write("(");
27737 self.generate_expression(&e.this)?;
27738 self.write(")");
27739 Ok(())
27740 }
27741
27742 fn generate_cube(&mut self, e: &Cube) -> Result<()> {
27743 if e.expressions.is_empty() {
27745 self.write_keyword("WITH CUBE");
27746 } else {
27747 self.write_keyword("CUBE");
27748 self.write("(");
27749 for (i, expr) in e.expressions.iter().enumerate() {
27750 if i > 0 {
27751 self.write(", ");
27752 }
27753 self.generate_expression(expr)?;
27754 }
27755 self.write(")");
27756 }
27757 Ok(())
27758 }
27759
27760 fn generate_current_datetime(&mut self, e: &CurrentDatetime) -> Result<()> {
27761 self.write_keyword("CURRENT_DATETIME");
27763 if let Some(this) = &e.this {
27764 self.write("(");
27765 self.generate_expression(this)?;
27766 self.write(")");
27767 }
27768 Ok(())
27769 }
27770
27771 fn generate_current_schema(&mut self, _e: &CurrentSchema) -> Result<()> {
27772 self.write_keyword("CURRENT_SCHEMA");
27774 Ok(())
27775 }
27776
27777 fn generate_current_schemas(&mut self, e: &CurrentSchemas) -> Result<()> {
27778 self.write_keyword("CURRENT_SCHEMAS");
27780 self.write("(");
27781 if !matches!(
27783 self.config.dialect,
27784 Some(crate::dialects::DialectType::Snowflake)
27785 ) {
27786 if let Some(this) = &e.this {
27787 self.generate_expression(this)?;
27788 }
27789 }
27790 self.write(")");
27791 Ok(())
27792 }
27793
27794 fn generate_current_user(&mut self, e: &CurrentUser) -> Result<()> {
27795 self.write_keyword("CURRENT_USER");
27797 let needs_parens = e.this.is_some()
27799 || matches!(
27800 self.config.dialect,
27801 Some(DialectType::Snowflake)
27802 | Some(DialectType::Spark)
27803 | Some(DialectType::Hive)
27804 | Some(DialectType::DuckDB)
27805 | Some(DialectType::BigQuery)
27806 | Some(DialectType::MySQL)
27807 | Some(DialectType::Databricks)
27808 );
27809 if needs_parens {
27810 self.write("()");
27811 }
27812 Ok(())
27813 }
27814
27815 fn generate_d_pipe(&mut self, e: &DPipe) -> Result<()> {
27816 if self.config.dialect == Some(DialectType::Solr) {
27818 self.generate_expression(&e.this)?;
27819 self.write(" ");
27820 self.write_keyword("OR");
27821 self.write(" ");
27822 self.generate_expression(&e.expression)?;
27823 } else if self.config.dialect == Some(DialectType::MySQL) {
27824 self.generate_mysql_concat_from_dpipe(e)?;
27825 } else {
27826 self.generate_expression(&e.this)?;
27828 self.write(" || ");
27829 self.generate_expression(&e.expression)?;
27830 }
27831 Ok(())
27832 }
27833
27834 fn generate_data_blocksize_property(&mut self, e: &DataBlocksizeProperty) -> Result<()> {
27835 self.write_keyword("DATABLOCKSIZE");
27837 self.write("=");
27838 if let Some(size) = e.size {
27839 self.write(&size.to_string());
27840 if let Some(units) = &e.units {
27841 self.write_space();
27842 self.generate_expression(units)?;
27843 }
27844 } else if e.minimum.is_some() {
27845 self.write_keyword("MINIMUM");
27846 } else if e.maximum.is_some() {
27847 self.write_keyword("MAXIMUM");
27848 } else if e.default.is_some() {
27849 self.write_keyword("DEFAULT");
27850 }
27851 Ok(())
27852 }
27853
27854 fn generate_data_deletion_property(&mut self, e: &DataDeletionProperty) -> Result<()> {
27855 self.write_keyword("DATA_DELETION");
27857 self.write("=");
27858
27859 let is_on = matches!(&*e.on, Expression::Boolean(BooleanLiteral { value: true }));
27860 let has_options = e.filter_column.is_some() || e.retention_period.is_some();
27861
27862 if is_on {
27863 self.write_keyword("ON");
27864 if has_options {
27865 self.write("(");
27866 let mut first = true;
27867 if let Some(filter_column) = &e.filter_column {
27868 self.write_keyword("FILTER_COLUMN");
27869 self.write("=");
27870 self.generate_expression(filter_column)?;
27871 first = false;
27872 }
27873 if let Some(retention_period) = &e.retention_period {
27874 if !first {
27875 self.write(", ");
27876 }
27877 self.write_keyword("RETENTION_PERIOD");
27878 self.write("=");
27879 self.generate_expression(retention_period)?;
27880 }
27881 self.write(")");
27882 }
27883 } else {
27884 self.write_keyword("OFF");
27885 }
27886 Ok(())
27887 }
27888
27889 fn generate_date_func(&mut self, e: &UnaryFunc) -> Result<()> {
27893 use crate::dialects::DialectType;
27894 use crate::expressions::Literal;
27895
27896 match self.config.dialect {
27897 Some(DialectType::Exasol) => {
27899 self.write_keyword("TO_DATE");
27900 self.write("(");
27901 match &e.this {
27903 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
27904 let Literal::String(s) = lit.as_ref() else {
27905 unreachable!()
27906 };
27907 self.write("'");
27908 self.write(s);
27909 self.write("'");
27910 }
27911 _ => {
27912 self.generate_expression(&e.this)?;
27913 }
27914 }
27915 self.write(")");
27916 }
27917 _ => {
27919 self.write_keyword("DATE");
27920 self.write("(");
27921 self.generate_expression(&e.this)?;
27922 self.write(")");
27923 }
27924 }
27925 Ok(())
27926 }
27927
27928 fn generate_date_bin(&mut self, e: &DateBin) -> Result<()> {
27929 self.write_keyword("DATE_BIN");
27931 self.write("(");
27932 self.generate_expression(&e.this)?;
27933 self.write(", ");
27934 self.generate_expression(&e.expression)?;
27935 if let Some(origin) = &e.origin {
27936 self.write(", ");
27937 self.generate_expression(origin)?;
27938 }
27939 self.write(")");
27940 Ok(())
27941 }
27942
27943 fn generate_date_format_column_constraint(
27944 &mut self,
27945 e: &DateFormatColumnConstraint,
27946 ) -> Result<()> {
27947 self.write_keyword("FORMAT");
27949 self.write_space();
27950 self.generate_expression(&e.this)?;
27951 Ok(())
27952 }
27953
27954 fn generate_date_from_parts(&mut self, e: &DateFromParts) -> Result<()> {
27955 self.write_keyword("DATE_FROM_PARTS");
27957 self.write("(");
27958 let mut first = true;
27959 if let Some(year) = &e.year {
27960 self.generate_expression(year)?;
27961 first = false;
27962 }
27963 if let Some(month) = &e.month {
27964 if !first {
27965 self.write(", ");
27966 }
27967 self.generate_expression(month)?;
27968 first = false;
27969 }
27970 if let Some(day) = &e.day {
27971 if !first {
27972 self.write(", ");
27973 }
27974 self.generate_expression(day)?;
27975 }
27976 self.write(")");
27977 Ok(())
27978 }
27979
27980 fn generate_datetime(&mut self, e: &Datetime) -> Result<()> {
27981 self.write_keyword("DATETIME");
27983 self.write("(");
27984 self.generate_expression(&e.this)?;
27985 if let Some(expr) = &e.expression {
27986 self.write(", ");
27987 self.generate_expression(expr)?;
27988 }
27989 self.write(")");
27990 Ok(())
27991 }
27992
27993 fn generate_datetime_add(&mut self, e: &DatetimeAdd) -> Result<()> {
27994 self.write_keyword("DATETIME_ADD");
27996 self.write("(");
27997 self.generate_expression(&e.this)?;
27998 self.write(", ");
27999 self.generate_expression(&e.expression)?;
28000 if let Some(unit) = &e.unit {
28001 self.write(", ");
28002 self.write_keyword(unit);
28003 }
28004 self.write(")");
28005 Ok(())
28006 }
28007
28008 fn generate_datetime_diff(&mut self, e: &DatetimeDiff) -> Result<()> {
28009 self.write_keyword("DATETIME_DIFF");
28011 self.write("(");
28012 self.generate_expression(&e.this)?;
28013 self.write(", ");
28014 self.generate_expression(&e.expression)?;
28015 if let Some(unit) = &e.unit {
28016 self.write(", ");
28017 self.write_keyword(unit);
28018 }
28019 self.write(")");
28020 Ok(())
28021 }
28022
28023 fn generate_datetime_sub(&mut self, e: &DatetimeSub) -> Result<()> {
28024 self.write_keyword("DATETIME_SUB");
28026 self.write("(");
28027 self.generate_expression(&e.this)?;
28028 self.write(", ");
28029 self.generate_expression(&e.expression)?;
28030 if let Some(unit) = &e.unit {
28031 self.write(", ");
28032 self.write_keyword(unit);
28033 }
28034 self.write(")");
28035 Ok(())
28036 }
28037
28038 fn generate_datetime_trunc(&mut self, e: &DatetimeTrunc) -> Result<()> {
28039 self.write_keyword("DATETIME_TRUNC");
28041 self.write("(");
28042 self.generate_expression(&e.this)?;
28043 self.write(", ");
28044 self.write_keyword(&e.unit);
28045 if let Some(zone) = &e.zone {
28046 self.write(", ");
28047 self.generate_expression(zone)?;
28048 }
28049 self.write(")");
28050 Ok(())
28051 }
28052
28053 fn generate_dayname(&mut self, e: &Dayname) -> Result<()> {
28054 self.write_keyword("DAYNAME");
28056 self.write("(");
28057 self.generate_expression(&e.this)?;
28058 self.write(")");
28059 Ok(())
28060 }
28061
28062 fn generate_declare(&mut self, e: &Declare) -> Result<()> {
28063 self.write_keyword("DECLARE");
28065 self.write_space();
28066 if e.replace {
28067 self.write_keyword("OR");
28068 self.write_space();
28069 self.write_keyword("REPLACE");
28070 self.write_space();
28071 }
28072 for (i, expr) in e.expressions.iter().enumerate() {
28073 if i > 0 {
28074 self.write(", ");
28075 }
28076 self.generate_expression(expr)?;
28077 }
28078 Ok(())
28079 }
28080
28081 fn generate_declare_item(&mut self, e: &DeclareItem) -> Result<()> {
28082 use crate::dialects::DialectType;
28083
28084 self.generate_expression(&e.this)?;
28086 for name in &e.additional_names {
28088 self.write(", ");
28089 self.generate_expression(name)?;
28090 }
28091 if let Some(kind) = &e.kind {
28092 self.write_space();
28093 match self.config.dialect {
28097 Some(DialectType::BigQuery) => {
28098 self.write(kind);
28099 }
28100 Some(DialectType::TSQL) => {
28101 let is_complex_table = kind.starts_with("TABLE")
28105 && (kind.contains("CLUSTERED") || kind.contains("INDEX"));
28106 if is_complex_table {
28107 self.write(kind);
28108 } else if kind == "INT" {
28109 self.write("INTEGER");
28110 } else if kind.starts_with("TABLE") {
28111 let normalized = kind
28113 .replace(" INT ", " INTEGER ")
28114 .replace(" INT,", " INTEGER,")
28115 .replace(" INT)", " INTEGER)")
28116 .replace("(INT ", "(INTEGER ");
28117 self.write(&normalized);
28118 } else {
28119 self.write(kind);
28120 }
28121 }
28122 _ => {
28123 if e.has_as {
28124 self.write_keyword("AS");
28125 self.write_space();
28126 }
28127 self.write(kind);
28128 }
28129 }
28130 }
28131 if let Some(default) = &e.default {
28132 match self.config.dialect {
28134 Some(DialectType::BigQuery) => {
28135 self.write_space();
28136 self.write_keyword("DEFAULT");
28137 self.write_space();
28138 }
28139 _ => {
28140 self.write(" = ");
28141 }
28142 }
28143 self.generate_expression(default)?;
28144 }
28145 Ok(())
28146 }
28147
28148 fn generate_decode_case(&mut self, e: &DecodeCase) -> Result<()> {
28149 self.write_keyword("DECODE");
28151 self.write("(");
28152 for (i, expr) in e.expressions.iter().enumerate() {
28153 if i > 0 {
28154 self.write(", ");
28155 }
28156 self.generate_expression(expr)?;
28157 }
28158 self.write(")");
28159 Ok(())
28160 }
28161
28162 fn generate_decompress_binary(&mut self, e: &DecompressBinary) -> Result<()> {
28163 self.write_keyword("DECOMPRESS");
28165 self.write("(");
28166 self.generate_expression(&e.this)?;
28167 self.write(", '");
28168 self.write(&e.method);
28169 self.write("')");
28170 Ok(())
28171 }
28172
28173 fn generate_decompress_string(&mut self, e: &DecompressString) -> Result<()> {
28174 self.write_keyword("DECOMPRESS");
28176 self.write("(");
28177 self.generate_expression(&e.this)?;
28178 self.write(", '");
28179 self.write(&e.method);
28180 self.write("')");
28181 Ok(())
28182 }
28183
28184 fn generate_decrypt(&mut self, e: &Decrypt) -> Result<()> {
28185 self.write_keyword("DECRYPT");
28187 self.write("(");
28188 self.generate_expression(&e.this)?;
28189 if let Some(passphrase) = &e.passphrase {
28190 self.write(", ");
28191 self.generate_expression(passphrase)?;
28192 }
28193 if let Some(aad) = &e.aad {
28194 self.write(", ");
28195 self.generate_expression(aad)?;
28196 }
28197 if let Some(method) = &e.encryption_method {
28198 self.write(", ");
28199 self.generate_expression(method)?;
28200 }
28201 self.write(")");
28202 Ok(())
28203 }
28204
28205 fn generate_decrypt_raw(&mut self, e: &DecryptRaw) -> Result<()> {
28206 self.write_keyword("DECRYPT_RAW");
28208 self.write("(");
28209 self.generate_expression(&e.this)?;
28210 if let Some(key) = &e.key {
28211 self.write(", ");
28212 self.generate_expression(key)?;
28213 }
28214 if let Some(iv) = &e.iv {
28215 self.write(", ");
28216 self.generate_expression(iv)?;
28217 }
28218 if let Some(aad) = &e.aad {
28219 self.write(", ");
28220 self.generate_expression(aad)?;
28221 }
28222 if let Some(method) = &e.encryption_method {
28223 self.write(", ");
28224 self.generate_expression(method)?;
28225 }
28226 self.write(")");
28227 Ok(())
28228 }
28229
28230 fn generate_definer_property(&mut self, e: &DefinerProperty) -> Result<()> {
28231 self.write_keyword("DEFINER");
28233 self.write(" = ");
28234 self.generate_expression(&e.this)?;
28235 Ok(())
28236 }
28237
28238 fn generate_detach(&mut self, e: &Detach) -> Result<()> {
28239 self.write_keyword("DETACH");
28241 if e.exists {
28242 self.write_keyword(" DATABASE IF EXISTS");
28243 }
28244 self.write_space();
28245 self.generate_expression(&e.this)?;
28246 Ok(())
28247 }
28248
28249 fn generate_dict_property(&mut self, e: &DictProperty) -> Result<()> {
28250 let property_name = match e.this.as_ref() {
28251 Expression::Identifier(id) => id.name.as_str(),
28252 Expression::Var(v) => v.this.as_str(),
28253 _ => "DICTIONARY",
28254 };
28255 self.write_keyword(property_name);
28256 self.write("(");
28257 self.write(&e.kind);
28258 if let Some(settings) = &e.settings {
28259 self.write("(");
28260 if let Expression::Tuple(t) = settings.as_ref() {
28261 if self.config.pretty && !t.expressions.is_empty() {
28262 self.write_newline();
28263 self.indent_level += 1;
28264 for (i, pair) in t.expressions.iter().enumerate() {
28265 if i > 0 {
28266 self.write(",");
28267 self.write_newline();
28268 }
28269 self.write_indent();
28270 if let Expression::Tuple(pair_tuple) = pair {
28271 if let Some(k) = pair_tuple.expressions.first() {
28272 self.generate_expression(k)?;
28273 }
28274 if let Some(v) = pair_tuple.expressions.get(1) {
28275 self.write(" ");
28276 self.generate_expression(v)?;
28277 }
28278 } else {
28279 self.generate_expression(pair)?;
28280 }
28281 }
28282 self.indent_level -= 1;
28283 self.write_newline();
28284 self.write_indent();
28285 } else {
28286 for (i, pair) in t.expressions.iter().enumerate() {
28287 if i > 0 {
28288 self.write(" ");
28290 }
28291 if let Expression::Tuple(pair_tuple) = pair {
28292 if let Some(k) = pair_tuple.expressions.first() {
28293 self.generate_expression(k)?;
28294 }
28295 if let Some(v) = pair_tuple.expressions.get(1) {
28296 self.write(" ");
28297 self.generate_expression(v)?;
28298 }
28299 } else {
28300 self.generate_expression(pair)?;
28301 }
28302 }
28303 }
28304 } else {
28305 self.generate_expression(settings)?;
28306 }
28307 self.write(")");
28308 } else {
28309 self.write("()");
28311 }
28312 self.write(")");
28313 Ok(())
28314 }
28315
28316 fn generate_dict_range(&mut self, e: &DictRange) -> Result<()> {
28317 let property_name = match e.this.as_ref() {
28318 Expression::Identifier(id) => id.name.as_str(),
28319 Expression::Var(v) => v.this.as_str(),
28320 _ => "RANGE",
28321 };
28322 self.write_keyword(property_name);
28323 self.write("(");
28324 if let Some(min) = &e.min {
28325 self.write_keyword("MIN");
28326 self.write_space();
28327 self.generate_expression(min)?;
28328 }
28329 if let Some(max) = &e.max {
28330 self.write_space();
28331 self.write_keyword("MAX");
28332 self.write_space();
28333 self.generate_expression(max)?;
28334 }
28335 self.write(")");
28336 Ok(())
28337 }
28338
28339 fn generate_directory(&mut self, e: &Directory) -> Result<()> {
28340 if e.local.is_some() {
28342 self.write_keyword("LOCAL ");
28343 }
28344 self.write_keyword("DIRECTORY");
28345 self.write_space();
28346 self.generate_expression(&e.this)?;
28347 if let Some(row_format) = &e.row_format {
28348 self.write_space();
28349 self.generate_expression(row_format)?;
28350 }
28351 Ok(())
28352 }
28353
28354 fn generate_dist_key_property(&mut self, e: &DistKeyProperty) -> Result<()> {
28355 self.write_keyword("DISTKEY");
28357 self.write("(");
28358 self.generate_expression(&e.this)?;
28359 self.write(")");
28360 Ok(())
28361 }
28362
28363 fn generate_dist_style_property(&mut self, e: &DistStyleProperty) -> Result<()> {
28364 self.write_keyword("DISTSTYLE");
28366 self.write_space();
28367 self.generate_expression(&e.this)?;
28368 Ok(())
28369 }
28370
28371 fn generate_distribute_by(&mut self, e: &DistributeBy) -> Result<()> {
28372 self.write_keyword("DISTRIBUTE BY");
28374 self.write_space();
28375 for (i, expr) in e.expressions.iter().enumerate() {
28376 if i > 0 {
28377 self.write(", ");
28378 }
28379 self.generate_expression(expr)?;
28380 }
28381 Ok(())
28382 }
28383
28384 fn generate_distributed_by_property(&mut self, e: &DistributedByProperty) -> Result<()> {
28385 self.write_keyword("DISTRIBUTED BY");
28387 self.write_space();
28388 self.write(&e.kind);
28389 if !e.expressions.is_empty() {
28390 self.write(" (");
28391 for (i, expr) in e.expressions.iter().enumerate() {
28392 if i > 0 {
28393 self.write(", ");
28394 }
28395 self.generate_expression(expr)?;
28396 }
28397 self.write(")");
28398 }
28399 if let Some(buckets) = &e.buckets {
28400 self.write_space();
28401 self.write_keyword("BUCKETS");
28402 self.write_space();
28403 self.generate_expression(buckets)?;
28404 }
28405 if let Some(order) = &e.order {
28406 self.write_space();
28407 self.generate_expression(order)?;
28408 }
28409 Ok(())
28410 }
28411
28412 fn generate_dot_product(&mut self, e: &DotProduct) -> Result<()> {
28413 self.write_keyword("DOT_PRODUCT");
28415 self.write("(");
28416 self.generate_expression(&e.this)?;
28417 self.write(", ");
28418 self.generate_expression(&e.expression)?;
28419 self.write(")");
28420 Ok(())
28421 }
28422
28423 fn generate_drop_partition(&mut self, e: &DropPartition) -> Result<()> {
28424 self.write_keyword("DROP");
28426 if e.exists {
28427 self.write_keyword(" IF EXISTS ");
28428 } else {
28429 self.write_space();
28430 }
28431 for (i, expr) in e.expressions.iter().enumerate() {
28432 if i > 0 {
28433 self.write(", ");
28434 }
28435 self.generate_expression(expr)?;
28436 }
28437 Ok(())
28438 }
28439
28440 fn generate_duplicate_key_property(&mut self, e: &DuplicateKeyProperty) -> Result<()> {
28441 self.write_keyword("DUPLICATE KEY");
28443 self.write(" (");
28444 for (i, expr) in e.expressions.iter().enumerate() {
28445 if i > 0 {
28446 self.write(", ");
28447 }
28448 self.generate_expression(expr)?;
28449 }
28450 self.write(")");
28451 Ok(())
28452 }
28453
28454 fn generate_elt(&mut self, e: &Elt) -> Result<()> {
28455 self.write_keyword("ELT");
28457 self.write("(");
28458 self.generate_expression(&e.this)?;
28459 for expr in &e.expressions {
28460 self.write(", ");
28461 self.generate_expression(expr)?;
28462 }
28463 self.write(")");
28464 Ok(())
28465 }
28466
28467 fn generate_encode(&mut self, e: &Encode) -> Result<()> {
28468 self.write_keyword("ENCODE");
28470 self.write("(");
28471 self.generate_expression(&e.this)?;
28472 if let Some(charset) = &e.charset {
28473 self.write(", ");
28474 self.generate_expression(charset)?;
28475 }
28476 self.write(")");
28477 Ok(())
28478 }
28479
28480 fn generate_encode_property(&mut self, e: &EncodeProperty) -> Result<()> {
28481 if e.key.is_some() {
28483 self.write_keyword("KEY ");
28484 }
28485 self.write_keyword("ENCODE");
28486 self.write_space();
28487 self.generate_expression(&e.this)?;
28488 if !e.properties.is_empty() {
28489 self.write(" (");
28490 for (i, prop) in e.properties.iter().enumerate() {
28491 if i > 0 {
28492 self.write(", ");
28493 }
28494 self.generate_expression(prop)?;
28495 }
28496 self.write(")");
28497 }
28498 Ok(())
28499 }
28500
28501 fn generate_encrypt(&mut self, e: &Encrypt) -> Result<()> {
28502 self.write_keyword("ENCRYPT");
28504 self.write("(");
28505 self.generate_expression(&e.this)?;
28506 if let Some(passphrase) = &e.passphrase {
28507 self.write(", ");
28508 self.generate_expression(passphrase)?;
28509 }
28510 if let Some(aad) = &e.aad {
28511 self.write(", ");
28512 self.generate_expression(aad)?;
28513 }
28514 if let Some(method) = &e.encryption_method {
28515 self.write(", ");
28516 self.generate_expression(method)?;
28517 }
28518 self.write(")");
28519 Ok(())
28520 }
28521
28522 fn generate_encrypt_raw(&mut self, e: &EncryptRaw) -> Result<()> {
28523 self.write_keyword("ENCRYPT_RAW");
28525 self.write("(");
28526 self.generate_expression(&e.this)?;
28527 if let Some(key) = &e.key {
28528 self.write(", ");
28529 self.generate_expression(key)?;
28530 }
28531 if let Some(iv) = &e.iv {
28532 self.write(", ");
28533 self.generate_expression(iv)?;
28534 }
28535 if let Some(aad) = &e.aad {
28536 self.write(", ");
28537 self.generate_expression(aad)?;
28538 }
28539 if let Some(method) = &e.encryption_method {
28540 self.write(", ");
28541 self.generate_expression(method)?;
28542 }
28543 self.write(")");
28544 Ok(())
28545 }
28546
28547 fn generate_engine_property(&mut self, e: &EngineProperty) -> Result<()> {
28548 self.write_keyword("ENGINE");
28550 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
28551 self.write("=");
28552 } else {
28553 self.write(" = ");
28554 }
28555 self.generate_expression(&e.this)?;
28556 Ok(())
28557 }
28558
28559 fn generate_enviroment_property(&mut self, e: &EnviromentProperty) -> Result<()> {
28560 self.write_keyword("ENVIRONMENT");
28562 self.write(" (");
28563 for (i, expr) in e.expressions.iter().enumerate() {
28564 if i > 0 {
28565 self.write(", ");
28566 }
28567 self.generate_expression(expr)?;
28568 }
28569 self.write(")");
28570 Ok(())
28571 }
28572
28573 fn generate_ephemeral_column_constraint(
28574 &mut self,
28575 e: &EphemeralColumnConstraint,
28576 ) -> Result<()> {
28577 self.write_keyword("EPHEMERAL");
28579 if let Some(this) = &e.this {
28580 self.write_space();
28581 self.generate_expression(this)?;
28582 }
28583 Ok(())
28584 }
28585
28586 fn generate_equal_null(&mut self, e: &EqualNull) -> Result<()> {
28587 self.write_keyword("EQUAL_NULL");
28589 self.write("(");
28590 self.generate_expression(&e.this)?;
28591 self.write(", ");
28592 self.generate_expression(&e.expression)?;
28593 self.write(")");
28594 Ok(())
28595 }
28596
28597 fn generate_euclidean_distance(&mut self, e: &EuclideanDistance) -> Result<()> {
28598 use crate::dialects::DialectType;
28599
28600 match self.config.dialect {
28602 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
28603 self.generate_expression(&e.this)?;
28604 self.write(" <-> ");
28605 self.generate_expression(&e.expression)?;
28606 }
28607 _ => {
28608 self.write_keyword("EUCLIDEAN_DISTANCE");
28610 self.write("(");
28611 self.generate_expression(&e.this)?;
28612 self.write(", ");
28613 self.generate_expression(&e.expression)?;
28614 self.write(")");
28615 }
28616 }
28617 Ok(())
28618 }
28619
28620 fn generate_execute_as_property(&mut self, e: &ExecuteAsProperty) -> Result<()> {
28621 self.write_keyword("EXECUTE AS");
28623 self.write_space();
28624 self.generate_expression(&e.this)?;
28625 Ok(())
28626 }
28627
28628 fn generate_export(&mut self, e: &Export) -> Result<()> {
28629 self.write_keyword("EXPORT DATA");
28631 if let Some(connection) = &e.connection {
28632 self.write_space();
28633 self.write_keyword("WITH CONNECTION");
28634 self.write_space();
28635 self.generate_expression(connection)?;
28636 }
28637 if !e.options.is_empty() {
28638 self.write_space();
28639 self.generate_options_clause(&e.options)?;
28640 }
28641 self.write_space();
28642 self.write_keyword("AS");
28643 self.write_space();
28644 self.generate_expression(&e.this)?;
28645 Ok(())
28646 }
28647
28648 fn generate_external_property(&mut self, e: &ExternalProperty) -> Result<()> {
28649 self.write_keyword("EXTERNAL");
28651 if let Some(this) = &e.this {
28652 self.write_space();
28653 self.generate_expression(this)?;
28654 }
28655 Ok(())
28656 }
28657
28658 fn generate_fallback_property(&mut self, e: &FallbackProperty) -> Result<()> {
28659 if e.no.is_some() {
28661 self.write_keyword("NO ");
28662 }
28663 self.write_keyword("FALLBACK");
28664 if e.protection.is_some() {
28665 self.write_keyword(" PROTECTION");
28666 }
28667 Ok(())
28668 }
28669
28670 fn generate_farm_fingerprint(&mut self, e: &FarmFingerprint) -> Result<()> {
28671 self.write_keyword("FARM_FINGERPRINT");
28673 self.write("(");
28674 for (i, expr) in e.expressions.iter().enumerate() {
28675 if i > 0 {
28676 self.write(", ");
28677 }
28678 self.generate_expression(expr)?;
28679 }
28680 self.write(")");
28681 Ok(())
28682 }
28683
28684 fn generate_features_at_time(&mut self, e: &FeaturesAtTime) -> Result<()> {
28685 self.write_keyword("FEATURES_AT_TIME");
28687 self.write("(");
28688 self.generate_expression(&e.this)?;
28689 if let Some(time) = &e.time {
28690 self.write(", ");
28691 self.generate_expression(time)?;
28692 }
28693 if let Some(num_rows) = &e.num_rows {
28694 self.write(", ");
28695 self.generate_expression(num_rows)?;
28696 }
28697 if let Some(ignore_nulls) = &e.ignore_feature_nulls {
28698 self.write(", ");
28699 self.generate_expression(ignore_nulls)?;
28700 }
28701 self.write(")");
28702 Ok(())
28703 }
28704
28705 fn generate_fetch(&mut self, e: &Fetch) -> Result<()> {
28706 let use_limit = !e.percent
28708 && !e.with_ties
28709 && e.count.is_some()
28710 && matches!(
28711 self.config.dialect,
28712 Some(DialectType::Spark)
28713 | Some(DialectType::Hive)
28714 | Some(DialectType::DuckDB)
28715 | Some(DialectType::SQLite)
28716 | Some(DialectType::MySQL)
28717 | Some(DialectType::BigQuery)
28718 | Some(DialectType::Databricks)
28719 | Some(DialectType::StarRocks)
28720 | Some(DialectType::Doris)
28721 | Some(DialectType::Athena)
28722 | Some(DialectType::ClickHouse)
28723 );
28724
28725 if use_limit {
28726 self.write_keyword("LIMIT");
28727 self.write_space();
28728 self.generate_expression(e.count.as_ref().unwrap())?;
28729 return Ok(());
28730 }
28731
28732 self.write_keyword("FETCH");
28734 if !e.direction.is_empty() {
28735 self.write_space();
28736 self.write_keyword(&e.direction);
28737 }
28738 if let Some(count) = &e.count {
28739 self.write_space();
28740 self.generate_expression(count)?;
28741 }
28742 if e.percent {
28744 self.write_keyword(" PERCENT");
28745 }
28746 if e.rows {
28747 self.write_keyword(" ROWS");
28748 }
28749 if e.with_ties {
28750 self.write_keyword(" WITH TIES");
28751 } else if e.rows {
28752 self.write_keyword(" ONLY");
28753 } else {
28754 self.write_keyword(" ROWS ONLY");
28755 }
28756 Ok(())
28757 }
28758
28759 fn generate_file_format_property(&mut self, e: &FileFormatProperty) -> Result<()> {
28760 if e.hive_format.is_some() {
28764 self.write_keyword("STORED AS");
28766 self.write_space();
28767 if let Some(this) = &e.this {
28768 if let Expression::Identifier(id) = this.as_ref() {
28770 self.write_keyword(&id.name.to_ascii_uppercase());
28771 } else {
28772 self.generate_expression(this)?;
28773 }
28774 }
28775 } else if matches!(self.config.dialect, Some(DialectType::Hive)) {
28776 self.write_keyword("STORED AS");
28778 self.write_space();
28779 if let Some(this) = &e.this {
28780 if let Expression::Identifier(id) = this.as_ref() {
28781 self.write_keyword(&id.name.to_ascii_uppercase());
28782 } else {
28783 self.generate_expression(this)?;
28784 }
28785 }
28786 } else if matches!(
28787 self.config.dialect,
28788 Some(DialectType::Spark) | Some(DialectType::Databricks)
28789 ) {
28790 self.write_keyword("USING");
28792 self.write_space();
28793 if let Some(this) = &e.this {
28794 self.generate_expression(this)?;
28795 }
28796 } else {
28797 self.write_keyword("FILE_FORMAT");
28799 self.write(" = ");
28800 if let Some(this) = &e.this {
28801 self.generate_expression(this)?;
28802 } else if !e.expressions.is_empty() {
28803 self.write("(");
28804 for (i, expr) in e.expressions.iter().enumerate() {
28805 if i > 0 {
28806 self.write(", ");
28807 }
28808 self.generate_expression(expr)?;
28809 }
28810 self.write(")");
28811 }
28812 }
28813 Ok(())
28814 }
28815
28816 fn generate_filter(&mut self, e: &Filter) -> Result<()> {
28817 self.generate_expression(&e.this)?;
28819 self.write_space();
28820 self.write_keyword("FILTER");
28821 self.write("(");
28822 self.write_keyword("WHERE");
28823 self.write_space();
28824 self.generate_expression(&e.expression)?;
28825 self.write(")");
28826 Ok(())
28827 }
28828
28829 fn generate_float64(&mut self, e: &Float64) -> Result<()> {
28830 self.write_keyword("FLOAT64");
28832 self.write("(");
28833 self.generate_expression(&e.this)?;
28834 if let Some(expr) = &e.expression {
28835 self.write(", ");
28836 self.generate_expression(expr)?;
28837 }
28838 self.write(")");
28839 Ok(())
28840 }
28841
28842 fn generate_for_in(&mut self, e: &ForIn) -> Result<()> {
28843 self.write_keyword("FOR");
28845 self.write_space();
28846 self.generate_expression(&e.this)?;
28847 self.write_space();
28848 self.write_keyword("DO");
28849 self.write_space();
28850 self.generate_expression(&e.expression)?;
28851 Ok(())
28852 }
28853
28854 fn generate_foreign_key(&mut self, e: &ForeignKey) -> Result<()> {
28855 self.write_keyword("FOREIGN KEY");
28857 if !e.expressions.is_empty() {
28858 self.write(" (");
28859 for (i, expr) in e.expressions.iter().enumerate() {
28860 if i > 0 {
28861 self.write(", ");
28862 }
28863 self.generate_expression(expr)?;
28864 }
28865 self.write(")");
28866 }
28867 if let Some(reference) = &e.reference {
28868 self.write_space();
28869 self.generate_expression(reference)?;
28870 }
28871 if let Some(delete) = &e.delete {
28872 self.write_space();
28873 self.write_keyword("ON DELETE");
28874 self.write_space();
28875 self.generate_expression(delete)?;
28876 }
28877 if let Some(update) = &e.update {
28878 self.write_space();
28879 self.write_keyword("ON UPDATE");
28880 self.write_space();
28881 self.generate_expression(update)?;
28882 }
28883 if !e.options.is_empty() {
28884 self.write_space();
28885 for (i, opt) in e.options.iter().enumerate() {
28886 if i > 0 {
28887 self.write_space();
28888 }
28889 self.generate_expression(opt)?;
28890 }
28891 }
28892 Ok(())
28893 }
28894
28895 fn generate_format(&mut self, e: &Format) -> Result<()> {
28896 self.write_keyword("FORMAT");
28898 self.write("(");
28899 self.generate_expression(&e.this)?;
28900 for expr in &e.expressions {
28901 self.write(", ");
28902 self.generate_expression(expr)?;
28903 }
28904 self.write(")");
28905 Ok(())
28906 }
28907
28908 fn generate_format_phrase(&mut self, e: &FormatPhrase) -> Result<()> {
28909 self.generate_expression(&e.this)?;
28911 self.write(" (");
28912 self.write_keyword("FORMAT");
28913 self.write(" '");
28914 self.write(&e.format);
28915 self.write("')");
28916 Ok(())
28917 }
28918
28919 fn generate_freespace_property(&mut self, e: &FreespaceProperty) -> Result<()> {
28920 self.write_keyword("FREESPACE");
28922 self.write("=");
28923 self.generate_expression(&e.this)?;
28924 if e.percent.is_some() {
28925 self.write_keyword(" PERCENT");
28926 }
28927 Ok(())
28928 }
28929
28930 fn generate_from(&mut self, e: &From) -> Result<()> {
28931 self.write_keyword("FROM");
28933 self.write_space();
28934
28935 use crate::dialects::DialectType;
28939 let has_tablesample = e
28940 .expressions
28941 .iter()
28942 .any(|expr| matches!(expr, Expression::TableSample(_)));
28943 let is_cross_join_dialect = matches!(
28944 self.config.dialect,
28945 Some(DialectType::BigQuery)
28946 | Some(DialectType::Hive)
28947 | Some(DialectType::Spark)
28948 | Some(DialectType::Databricks)
28949 | Some(DialectType::SQLite)
28950 | Some(DialectType::ClickHouse)
28951 );
28952 let source_is_same_as_target2 = self.config.source_dialect.is_some()
28953 && self.config.source_dialect == self.config.dialect;
28954 let source_is_cross_join_dialect2 = matches!(
28955 self.config.source_dialect,
28956 Some(DialectType::BigQuery)
28957 | Some(DialectType::Hive)
28958 | Some(DialectType::Spark)
28959 | Some(DialectType::Databricks)
28960 | Some(DialectType::SQLite)
28961 | Some(DialectType::ClickHouse)
28962 );
28963 let use_cross_join = !has_tablesample
28964 && is_cross_join_dialect
28965 && (source_is_same_as_target2
28966 || source_is_cross_join_dialect2
28967 || self.config.source_dialect.is_none());
28968
28969 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
28971
28972 for (i, expr) in e.expressions.iter().enumerate() {
28973 if i > 0 {
28974 if use_cross_join {
28975 self.write(" CROSS JOIN ");
28976 } else {
28977 self.write(", ");
28978 }
28979 }
28980 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
28981 self.write("(");
28982 self.generate_expression(expr)?;
28983 self.write(")");
28984 } else {
28985 self.generate_expression(expr)?;
28986 }
28987 let leading = Self::extract_table_leading_comments(expr);
28990 for comment in &leading {
28991 self.write_space();
28992 self.write_formatted_comment(comment);
28993 }
28994 }
28995 Ok(())
28996 }
28997
28998 fn extract_table_leading_comments(expr: &Expression) -> Vec<String> {
29000 match expr {
29001 Expression::Table(t) => t.leading_comments.clone(),
29002 Expression::Pivot(p) => {
29003 if let Expression::Table(t) = &p.this {
29004 t.leading_comments.clone()
29005 } else {
29006 Vec::new()
29007 }
29008 }
29009 _ => Vec::new(),
29010 }
29011 }
29012
29013 fn generate_from_base(&mut self, e: &FromBase) -> Result<()> {
29014 self.write_keyword("FROM_BASE");
29016 self.write("(");
29017 self.generate_expression(&e.this)?;
29018 self.write(", ");
29019 self.generate_expression(&e.expression)?;
29020 self.write(")");
29021 Ok(())
29022 }
29023
29024 fn generate_from_time_zone(&mut self, e: &FromTimeZone) -> Result<()> {
29025 self.generate_expression(&e.this)?;
29027 if let Some(zone) = &e.zone {
29028 self.write_space();
29029 self.write_keyword("AT TIME ZONE");
29030 self.write_space();
29031 self.generate_expression(zone)?;
29032 self.write_space();
29033 self.write_keyword("AT TIME ZONE");
29034 self.write(" 'UTC'");
29035 }
29036 Ok(())
29037 }
29038
29039 fn generate_gap_fill(&mut self, e: &GapFill) -> Result<()> {
29040 self.write_keyword("GAP_FILL");
29042 self.write("(");
29043 self.generate_expression(&e.this)?;
29044 if let Some(ts_column) = &e.ts_column {
29045 self.write(", ");
29046 self.generate_expression(ts_column)?;
29047 }
29048 if let Some(bucket_width) = &e.bucket_width {
29049 self.write(", ");
29050 self.generate_expression(bucket_width)?;
29051 }
29052 if let Some(partitioning_columns) = &e.partitioning_columns {
29053 self.write(", ");
29054 self.generate_expression(partitioning_columns)?;
29055 }
29056 if let Some(value_columns) = &e.value_columns {
29057 self.write(", ");
29058 self.generate_expression(value_columns)?;
29059 }
29060 self.write(")");
29061 Ok(())
29062 }
29063
29064 fn generate_generate_date_array(&mut self, e: &GenerateDateArray) -> Result<()> {
29065 self.write_keyword("GENERATE_DATE_ARRAY");
29067 self.write("(");
29068 let mut first = true;
29069 if let Some(start) = &e.start {
29070 self.generate_expression(start)?;
29071 first = false;
29072 }
29073 if let Some(end) = &e.end {
29074 if !first {
29075 self.write(", ");
29076 }
29077 self.generate_expression(end)?;
29078 first = false;
29079 }
29080 if let Some(step) = &e.step {
29081 if !first {
29082 self.write(", ");
29083 }
29084 self.generate_expression(step)?;
29085 }
29086 self.write(")");
29087 Ok(())
29088 }
29089
29090 fn generate_generate_embedding(&mut self, e: &GenerateEmbedding) -> Result<()> {
29091 self.write_keyword("ML.GENERATE_EMBEDDING");
29093 self.write("(");
29094 self.generate_expression(&e.this)?;
29095 self.write(", ");
29096 self.generate_expression(&e.expression)?;
29097 if let Some(params) = &e.params_struct {
29098 self.write(", ");
29099 self.generate_expression(params)?;
29100 }
29101 self.write(")");
29102 Ok(())
29103 }
29104
29105 fn generate_generate_series(&mut self, e: &GenerateSeries) -> Result<()> {
29106 let fn_name = match self.config.dialect {
29108 Some(DialectType::Presto)
29109 | Some(DialectType::Trino)
29110 | Some(DialectType::Athena)
29111 | Some(DialectType::Spark)
29112 | Some(DialectType::Databricks)
29113 | Some(DialectType::Hive) => "SEQUENCE",
29114 _ => "GENERATE_SERIES",
29115 };
29116 self.write_keyword(fn_name);
29117 self.write("(");
29118 let mut first = true;
29119 if let Some(start) = &e.start {
29120 self.generate_expression(start)?;
29121 first = false;
29122 }
29123 if let Some(end) = &e.end {
29124 if !first {
29125 self.write(", ");
29126 }
29127 self.generate_expression(end)?;
29128 first = false;
29129 }
29130 if let Some(step) = &e.step {
29131 if !first {
29132 self.write(", ");
29133 }
29134 if matches!(
29137 self.config.dialect,
29138 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
29139 ) {
29140 if let Some(converted) = self.convert_week_interval_to_day(step) {
29141 self.generate_expression(&converted)?;
29142 } else {
29143 self.generate_expression(step)?;
29144 }
29145 } else {
29146 self.generate_expression(step)?;
29147 }
29148 }
29149 self.write(")");
29150 Ok(())
29151 }
29152
29153 fn convert_week_interval_to_day(&self, expr: &Expression) -> Option<Expression> {
29156 use crate::expressions::*;
29157 if let Expression::Interval(ref iv) = expr {
29158 let (is_week, count_str) = if let Some(IntervalUnitSpec::Simple {
29160 unit: IntervalUnit::Week,
29161 ..
29162 }) = &iv.unit
29163 {
29164 let count = match &iv.this {
29166 Some(Expression::Literal(lit)) => match lit.as_ref() {
29167 Literal::String(s) | Literal::Number(s) => s.clone(),
29168 _ => return None,
29169 },
29170 _ => return None,
29171 };
29172 (true, count)
29173 } else if iv.unit.is_none() {
29174 if let Some(Expression::Literal(lit)) = &iv.this {
29176 if let Literal::String(s) = lit.as_ref() {
29177 let parts: Vec<&str> = s.trim().splitn(2, char::is_whitespace).collect();
29178 if parts.len() == 2 && parts[1].eq_ignore_ascii_case("WEEK") {
29179 (true, parts[0].to_string())
29180 } else {
29181 (false, String::new())
29182 }
29183 } else {
29184 (false, String::new())
29185 }
29186 } else {
29187 (false, String::new())
29188 }
29189 } else {
29190 (false, String::new())
29191 };
29192
29193 if is_week {
29194 let count_expr = Expression::Literal(Box::new(Literal::Number(count_str)));
29196 let day_interval = Expression::Interval(Box::new(Interval {
29197 this: Some(Expression::Literal(Box::new(Literal::String(
29198 "7".to_string(),
29199 )))),
29200 unit: Some(IntervalUnitSpec::Simple {
29201 unit: IntervalUnit::Day,
29202 use_plural: false,
29203 }),
29204 }));
29205 let mul = Expression::Mul(Box::new(BinaryOp {
29206 left: count_expr,
29207 right: day_interval,
29208 left_comments: vec![],
29209 operator_comments: vec![],
29210 trailing_comments: vec![],
29211 inferred_type: None,
29212 }));
29213 return Some(Expression::Paren(Box::new(Paren {
29214 this: mul,
29215 trailing_comments: vec![],
29216 })));
29217 }
29218 }
29219 None
29220 }
29221
29222 fn generate_generate_timestamp_array(&mut self, e: &GenerateTimestampArray) -> Result<()> {
29223 self.write_keyword("GENERATE_TIMESTAMP_ARRAY");
29225 self.write("(");
29226 let mut first = true;
29227 if let Some(start) = &e.start {
29228 self.generate_expression(start)?;
29229 first = false;
29230 }
29231 if let Some(end) = &e.end {
29232 if !first {
29233 self.write(", ");
29234 }
29235 self.generate_expression(end)?;
29236 first = false;
29237 }
29238 if let Some(step) = &e.step {
29239 if !first {
29240 self.write(", ");
29241 }
29242 self.generate_expression(step)?;
29243 }
29244 self.write(")");
29245 Ok(())
29246 }
29247
29248 fn generate_generated_as_identity_column_constraint(
29249 &mut self,
29250 e: &GeneratedAsIdentityColumnConstraint,
29251 ) -> Result<()> {
29252 use crate::dialects::DialectType;
29253
29254 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
29256 self.write_keyword("AUTOINCREMENT");
29257 if let Some(start) = &e.start {
29258 self.write_keyword(" START ");
29259 self.generate_expression(start)?;
29260 }
29261 if let Some(increment) = &e.increment {
29262 self.write_keyword(" INCREMENT ");
29263 self.generate_expression(increment)?;
29264 }
29265 return Ok(());
29266 }
29267
29268 self.write_keyword("GENERATED");
29270 if let Some(this) = &e.this {
29271 if let Expression::Boolean(b) = this.as_ref() {
29273 if b.value {
29274 self.write_keyword(" ALWAYS");
29275 } else {
29276 self.write_keyword(" BY DEFAULT");
29277 if e.on_null.is_some() {
29278 self.write_keyword(" ON NULL");
29279 }
29280 }
29281 } else {
29282 self.write_keyword(" ALWAYS");
29283 }
29284 }
29285 self.write_keyword(" AS IDENTITY");
29286 let has_options = e.start.is_some()
29288 || e.increment.is_some()
29289 || e.minvalue.is_some()
29290 || e.maxvalue.is_some();
29291 if has_options {
29292 self.write(" (");
29293 let mut first = true;
29294 if let Some(start) = &e.start {
29295 self.write_keyword("START WITH ");
29296 self.generate_expression(start)?;
29297 first = false;
29298 }
29299 if let Some(increment) = &e.increment {
29300 if !first {
29301 self.write(" ");
29302 }
29303 self.write_keyword("INCREMENT BY ");
29304 self.generate_expression(increment)?;
29305 first = false;
29306 }
29307 if let Some(minvalue) = &e.minvalue {
29308 if !first {
29309 self.write(" ");
29310 }
29311 self.write_keyword("MINVALUE ");
29312 self.generate_expression(minvalue)?;
29313 first = false;
29314 }
29315 if let Some(maxvalue) = &e.maxvalue {
29316 if !first {
29317 self.write(" ");
29318 }
29319 self.write_keyword("MAXVALUE ");
29320 self.generate_expression(maxvalue)?;
29321 }
29322 self.write(")");
29323 }
29324 Ok(())
29325 }
29326
29327 fn generate_generated_as_row_column_constraint(
29328 &mut self,
29329 e: &GeneratedAsRowColumnConstraint,
29330 ) -> Result<()> {
29331 self.write_keyword("GENERATED ALWAYS AS ROW ");
29333 if e.start.is_some() {
29334 self.write_keyword("START");
29335 } else {
29336 self.write_keyword("END");
29337 }
29338 if e.hidden.is_some() {
29339 self.write_keyword(" HIDDEN");
29340 }
29341 Ok(())
29342 }
29343
29344 fn generate_get(&mut self, e: &Get) -> Result<()> {
29345 self.write_keyword("GET");
29347 self.write_space();
29348 self.generate_expression(&e.this)?;
29349 if let Some(target) = &e.target {
29350 self.write_space();
29351 self.generate_expression(target)?;
29352 }
29353 for prop in &e.properties {
29354 self.write_space();
29355 self.generate_expression(prop)?;
29356 }
29357 Ok(())
29358 }
29359
29360 fn generate_get_extract(&mut self, e: &GetExtract) -> Result<()> {
29361 self.generate_expression(&e.this)?;
29363 self.write("[");
29364 self.generate_expression(&e.expression)?;
29365 self.write("]");
29366 Ok(())
29367 }
29368
29369 fn generate_getbit(&mut self, e: &Getbit) -> Result<()> {
29370 self.write_keyword("GETBIT");
29372 self.write("(");
29373 self.generate_expression(&e.this)?;
29374 self.write(", ");
29375 self.generate_expression(&e.expression)?;
29376 self.write(")");
29377 Ok(())
29378 }
29379
29380 fn generate_grant_principal(&mut self, e: &GrantPrincipal) -> Result<()> {
29381 if e.is_role {
29383 self.write_keyword("ROLE");
29384 self.write_space();
29385 } else if e.is_group {
29386 self.write_keyword("GROUP");
29387 self.write_space();
29388 } else if e.is_share {
29389 self.write_keyword("SHARE");
29390 self.write_space();
29391 }
29392 self.write(&e.name.name);
29393 Ok(())
29394 }
29395
29396 fn generate_grant_privilege(&mut self, e: &GrantPrivilege) -> Result<()> {
29397 self.generate_expression(&e.this)?;
29399 if !e.expressions.is_empty() {
29400 self.write("(");
29401 for (i, expr) in e.expressions.iter().enumerate() {
29402 if i > 0 {
29403 self.write(", ");
29404 }
29405 self.generate_expression(expr)?;
29406 }
29407 self.write(")");
29408 }
29409 Ok(())
29410 }
29411
29412 fn generate_group(&mut self, e: &Group) -> Result<()> {
29413 self.write_keyword("GROUP BY");
29415 match e.all {
29417 Some(true) => {
29418 self.write_space();
29419 self.write_keyword("ALL");
29420 }
29421 Some(false) => {
29422 self.write_space();
29423 self.write_keyword("DISTINCT");
29424 }
29425 None => {}
29426 }
29427 if !e.expressions.is_empty() {
29428 self.write_space();
29429 for (i, expr) in e.expressions.iter().enumerate() {
29430 if i > 0 {
29431 self.write(", ");
29432 }
29433 self.generate_expression(expr)?;
29434 }
29435 }
29436 if let Some(cube) = &e.cube {
29438 if !e.expressions.is_empty() {
29439 self.write(", ");
29440 } else {
29441 self.write_space();
29442 }
29443 self.generate_expression(cube)?;
29444 }
29445 if let Some(rollup) = &e.rollup {
29446 if !e.expressions.is_empty() || e.cube.is_some() {
29447 self.write(", ");
29448 } else {
29449 self.write_space();
29450 }
29451 self.generate_expression(rollup)?;
29452 }
29453 if let Some(grouping_sets) = &e.grouping_sets {
29454 if !e.expressions.is_empty() || e.cube.is_some() || e.rollup.is_some() {
29455 self.write(", ");
29456 } else {
29457 self.write_space();
29458 }
29459 self.generate_expression(grouping_sets)?;
29460 }
29461 if let Some(totals) = &e.totals {
29462 self.write_space();
29463 self.write_keyword("WITH TOTALS");
29464 self.generate_expression(totals)?;
29465 }
29466 Ok(())
29467 }
29468
29469 fn generate_group_by(&mut self, e: &GroupBy) -> Result<()> {
29470 self.write_keyword("GROUP BY");
29472 match e.all {
29474 Some(true) => {
29475 self.write_space();
29476 self.write_keyword("ALL");
29477 }
29478 Some(false) => {
29479 self.write_space();
29480 self.write_keyword("DISTINCT");
29481 }
29482 None => {}
29483 }
29484
29485 let mut trailing_cube = false;
29488 let mut trailing_rollup = false;
29489 let mut regular_expressions: Vec<&Expression> = Vec::new();
29490
29491 for expr in &e.expressions {
29492 match expr {
29493 Expression::Cube(c) if c.expressions.is_empty() => {
29494 trailing_cube = true;
29495 }
29496 Expression::Rollup(r) if r.expressions.is_empty() => {
29497 trailing_rollup = true;
29498 }
29499 _ => {
29500 regular_expressions.push(expr);
29501 }
29502 }
29503 }
29504
29505 if self.config.pretty {
29507 self.write_newline();
29508 self.indent_level += 1;
29509 for (i, expr) in regular_expressions.iter().enumerate() {
29510 if i > 0 {
29511 self.write(",");
29512 self.write_newline();
29513 }
29514 self.write_indent();
29515 self.generate_expression(expr)?;
29516 }
29517 self.indent_level -= 1;
29518 } else {
29519 self.write_space();
29520 for (i, expr) in regular_expressions.iter().enumerate() {
29521 if i > 0 {
29522 self.write(", ");
29523 }
29524 self.generate_expression(expr)?;
29525 }
29526 }
29527
29528 if trailing_cube {
29530 self.write_space();
29531 self.write_keyword("WITH CUBE");
29532 } else if trailing_rollup {
29533 self.write_space();
29534 self.write_keyword("WITH ROLLUP");
29535 }
29536
29537 if e.totals {
29539 self.write_space();
29540 self.write_keyword("WITH TOTALS");
29541 }
29542
29543 Ok(())
29544 }
29545
29546 fn generate_grouping(&mut self, e: &Grouping) -> Result<()> {
29547 self.write_keyword("GROUPING");
29549 self.write("(");
29550 for (i, expr) in e.expressions.iter().enumerate() {
29551 if i > 0 {
29552 self.write(", ");
29553 }
29554 self.generate_expression(expr)?;
29555 }
29556 self.write(")");
29557 Ok(())
29558 }
29559
29560 fn generate_grouping_id(&mut self, e: &GroupingId) -> Result<()> {
29561 self.write_keyword("GROUPING_ID");
29563 self.write("(");
29564 for (i, expr) in e.expressions.iter().enumerate() {
29565 if i > 0 {
29566 self.write(", ");
29567 }
29568 self.generate_expression(expr)?;
29569 }
29570 self.write(")");
29571 Ok(())
29572 }
29573
29574 fn generate_grouping_sets(&mut self, e: &GroupingSets) -> Result<()> {
29575 self.write_keyword("GROUPING SETS");
29577 self.write(" (");
29578 for (i, expr) in e.expressions.iter().enumerate() {
29579 if i > 0 {
29580 self.write(", ");
29581 }
29582 self.generate_expression(expr)?;
29583 }
29584 self.write(")");
29585 Ok(())
29586 }
29587
29588 fn generate_hash_agg(&mut self, e: &HashAgg) -> Result<()> {
29589 self.write_keyword("HASH_AGG");
29591 self.write("(");
29592 self.generate_expression(&e.this)?;
29593 for expr in &e.expressions {
29594 self.write(", ");
29595 self.generate_expression(expr)?;
29596 }
29597 self.write(")");
29598 Ok(())
29599 }
29600
29601 fn generate_having(&mut self, e: &Having) -> Result<()> {
29602 self.write_keyword("HAVING");
29604 self.write_space();
29605 self.generate_expression(&e.this)?;
29606 Ok(())
29607 }
29608
29609 fn generate_having_max(&mut self, e: &HavingMax) -> Result<()> {
29610 self.generate_expression(&e.this)?;
29612 self.write_space();
29613 self.write_keyword("HAVING");
29614 self.write_space();
29615 if e.max.is_some() {
29616 self.write_keyword("MAX");
29617 } else {
29618 self.write_keyword("MIN");
29619 }
29620 self.write_space();
29621 self.generate_expression(&e.expression)?;
29622 Ok(())
29623 }
29624
29625 fn generate_heredoc(&mut self, e: &Heredoc) -> Result<()> {
29626 use crate::dialects::DialectType;
29627 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
29629 if let Expression::Literal(ref lit) = *e.this {
29631 if let Literal::String(ref s) = lit.as_ref() {
29632 return self.generate_string_literal(s);
29633 }
29634 }
29635 }
29636 if matches!(
29638 self.config.dialect,
29639 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
29640 ) {
29641 self.write("$");
29642 if let Some(tag) = &e.tag {
29643 self.generate_expression(tag)?;
29644 }
29645 self.write("$");
29646 self.generate_expression(&e.this)?;
29647 self.write("$");
29648 if let Some(tag) = &e.tag {
29649 self.generate_expression(tag)?;
29650 }
29651 self.write("$");
29652 return Ok(());
29653 }
29654 self.write("$");
29656 if let Some(tag) = &e.tag {
29657 self.generate_expression(tag)?;
29658 }
29659 self.write("$");
29660 self.generate_expression(&e.this)?;
29661 self.write("$");
29662 if let Some(tag) = &e.tag {
29663 self.generate_expression(tag)?;
29664 }
29665 self.write("$");
29666 Ok(())
29667 }
29668
29669 fn generate_hex_encode(&mut self, e: &HexEncode) -> Result<()> {
29670 self.write_keyword("HEX_ENCODE");
29672 self.write("(");
29673 self.generate_expression(&e.this)?;
29674 self.write(")");
29675 Ok(())
29676 }
29677
29678 fn generate_historical_data(&mut self, e: &HistoricalData) -> Result<()> {
29679 match e.this.as_ref() {
29682 Expression::Identifier(id) => self.write(&id.name),
29683 other => self.generate_expression(other)?,
29684 }
29685 self.write(" (");
29686 self.write(&e.kind);
29687 self.write(" => ");
29688 self.generate_expression(&e.expression)?;
29689 self.write(")");
29690 Ok(())
29691 }
29692
29693 fn generate_hll(&mut self, e: &Hll) -> Result<()> {
29694 self.write_keyword("HLL");
29696 self.write("(");
29697 self.generate_expression(&e.this)?;
29698 for expr in &e.expressions {
29699 self.write(", ");
29700 self.generate_expression(expr)?;
29701 }
29702 self.write(")");
29703 Ok(())
29704 }
29705
29706 fn generate_in_out_column_constraint(&mut self, e: &InOutColumnConstraint) -> Result<()> {
29707 if e.input_.is_some() && e.output.is_some() {
29709 self.write_keyword("IN OUT");
29710 } else if e.input_.is_some() {
29711 self.write_keyword("IN");
29712 } else if e.output.is_some() {
29713 self.write_keyword("OUT");
29714 }
29715 Ok(())
29716 }
29717
29718 fn generate_include_property(&mut self, e: &IncludeProperty) -> Result<()> {
29719 self.write_keyword("INCLUDE");
29721 self.write_space();
29722 self.generate_expression(&e.this)?;
29723 if let Some(column_def) = &e.column_def {
29724 self.write_space();
29725 self.generate_expression(column_def)?;
29726 }
29727 if let Some(alias) = &e.alias {
29728 self.write_space();
29729 self.write_keyword("AS");
29730 self.write_space();
29731 self.write(alias);
29732 }
29733 Ok(())
29734 }
29735
29736 fn generate_index(&mut self, e: &Index) -> Result<()> {
29737 if e.unique {
29739 self.write_keyword("UNIQUE");
29740 self.write_space();
29741 }
29742 if e.primary.is_some() {
29743 self.write_keyword("PRIMARY");
29744 self.write_space();
29745 }
29746 if e.amp.is_some() {
29747 self.write_keyword("AMP");
29748 self.write_space();
29749 }
29750 if e.table.is_none() {
29751 self.write_keyword("INDEX");
29752 self.write_space();
29753 }
29754 if let Some(name) = &e.this {
29755 self.generate_expression(name)?;
29756 self.write_space();
29757 }
29758 if let Some(table) = &e.table {
29759 self.write_keyword("ON");
29760 self.write_space();
29761 self.generate_expression(table)?;
29762 }
29763 if !e.params.is_empty() {
29764 self.write("(");
29765 for (i, param) in e.params.iter().enumerate() {
29766 if i > 0 {
29767 self.write(", ");
29768 }
29769 self.generate_expression(param)?;
29770 }
29771 self.write(")");
29772 }
29773 Ok(())
29774 }
29775
29776 fn generate_index_column_constraint(&mut self, e: &IndexColumnConstraint) -> Result<()> {
29777 if let Some(kind) = &e.kind {
29779 self.write(kind);
29780 self.write_space();
29781 }
29782 self.write_keyword("INDEX");
29783 if let Some(this) = &e.this {
29784 self.write_space();
29785 self.generate_expression(this)?;
29786 }
29787 if let Some(index_type) = &e.index_type {
29788 self.write_space();
29789 self.write_keyword("USING");
29790 self.write_space();
29791 self.generate_expression(index_type)?;
29792 }
29793 if !e.expressions.is_empty() {
29794 self.write(" (");
29795 for (i, expr) in e.expressions.iter().enumerate() {
29796 if i > 0 {
29797 self.write(", ");
29798 }
29799 self.generate_expression(expr)?;
29800 }
29801 self.write(")");
29802 }
29803 for opt in &e.options {
29804 self.write_space();
29805 self.generate_expression(opt)?;
29806 }
29807 Ok(())
29808 }
29809
29810 fn generate_index_constraint_option(&mut self, e: &IndexConstraintOption) -> Result<()> {
29811 if let Some(key_block_size) = &e.key_block_size {
29813 self.write_keyword("KEY_BLOCK_SIZE");
29814 self.write(" = ");
29815 self.generate_expression(key_block_size)?;
29816 } else if let Some(using) = &e.using {
29817 self.write_keyword("USING");
29818 self.write_space();
29819 self.generate_expression(using)?;
29820 } else if let Some(parser) = &e.parser {
29821 self.write_keyword("WITH PARSER");
29822 self.write_space();
29823 self.generate_expression(parser)?;
29824 } else if let Some(comment) = &e.comment {
29825 self.write_keyword("COMMENT");
29826 self.write_space();
29827 self.generate_expression(comment)?;
29828 } else if let Some(visible) = &e.visible {
29829 self.generate_expression(visible)?;
29830 } else if let Some(engine_attr) = &e.engine_attr {
29831 self.write_keyword("ENGINE_ATTRIBUTE");
29832 self.write(" = ");
29833 self.generate_expression(engine_attr)?;
29834 } else if let Some(secondary_engine_attr) = &e.secondary_engine_attr {
29835 self.write_keyword("SECONDARY_ENGINE_ATTRIBUTE");
29836 self.write(" = ");
29837 self.generate_expression(secondary_engine_attr)?;
29838 }
29839 Ok(())
29840 }
29841
29842 fn generate_index_parameters(&mut self, e: &IndexParameters) -> Result<()> {
29843 if let Some(using) = &e.using {
29845 self.write_keyword("USING");
29846 self.write_space();
29847 self.generate_expression(using)?;
29848 }
29849 if !e.columns.is_empty() {
29850 self.write("(");
29851 for (i, col) in e.columns.iter().enumerate() {
29852 if i > 0 {
29853 self.write(", ");
29854 }
29855 self.generate_expression(col)?;
29856 }
29857 self.write(")");
29858 }
29859 if let Some(partition_by) = &e.partition_by {
29860 self.write_space();
29861 self.write_keyword("PARTITION BY");
29862 self.write_space();
29863 self.generate_expression(partition_by)?;
29864 }
29865 if let Some(where_) = &e.where_ {
29866 self.write_space();
29867 self.generate_expression(where_)?;
29868 }
29869 if let Some(include) = &e.include {
29870 self.write_space();
29871 self.write_keyword("INCLUDE");
29872 self.write(" (");
29873 self.generate_expression(include)?;
29874 self.write(")");
29875 }
29876 if let Some(with_storage) = &e.with_storage {
29877 self.write_space();
29878 self.write_keyword("WITH");
29879 self.write(" (");
29880 self.generate_expression(with_storage)?;
29881 self.write(")");
29882 }
29883 if let Some(tablespace) = &e.tablespace {
29884 self.write_space();
29885 self.write_keyword("USING INDEX TABLESPACE");
29886 self.write_space();
29887 self.generate_expression(tablespace)?;
29888 }
29889 Ok(())
29890 }
29891
29892 fn generate_index_table_hint(&mut self, e: &IndexTableHint) -> Result<()> {
29893 if let Expression::Identifier(id) = &*e.this {
29897 self.write_keyword(&id.name);
29898 } else {
29899 self.generate_expression(&e.this)?;
29900 }
29901 self.write_space();
29902 self.write_keyword("INDEX");
29903 if let Some(target) = &e.target {
29904 self.write_space();
29905 self.write_keyword("FOR");
29906 self.write_space();
29907 if let Expression::Identifier(id) = &**target {
29908 self.write_keyword(&id.name);
29909 } else {
29910 self.generate_expression(target)?;
29911 }
29912 }
29913 self.write(" (");
29915 for (i, expr) in e.expressions.iter().enumerate() {
29916 if i > 0 {
29917 self.write(", ");
29918 }
29919 self.generate_expression(expr)?;
29920 }
29921 self.write(")");
29922 Ok(())
29923 }
29924
29925 fn generate_inherits_property(&mut self, e: &InheritsProperty) -> Result<()> {
29926 self.write_keyword("INHERITS");
29928 self.write(" (");
29929 for (i, expr) in e.expressions.iter().enumerate() {
29930 if i > 0 {
29931 self.write(", ");
29932 }
29933 self.generate_expression(expr)?;
29934 }
29935 self.write(")");
29936 Ok(())
29937 }
29938
29939 fn generate_input_model_property(&mut self, e: &InputModelProperty) -> Result<()> {
29940 self.write_keyword("INPUT");
29942 self.write("(");
29943 self.generate_expression(&e.this)?;
29944 self.write(")");
29945 Ok(())
29946 }
29947
29948 fn generate_input_output_format(&mut self, e: &InputOutputFormat) -> Result<()> {
29949 if let Some(input_format) = &e.input_format {
29951 self.write_keyword("INPUTFORMAT");
29952 self.write_space();
29953 self.generate_expression(input_format)?;
29954 }
29955 if let Some(output_format) = &e.output_format {
29956 if e.input_format.is_some() {
29957 self.write(" ");
29958 }
29959 self.write_keyword("OUTPUTFORMAT");
29960 self.write_space();
29961 self.generate_expression(output_format)?;
29962 }
29963 Ok(())
29964 }
29965
29966 fn generate_install(&mut self, e: &Install) -> Result<()> {
29967 if e.force.is_some() {
29969 self.write_keyword("FORCE");
29970 self.write_space();
29971 }
29972 self.write_keyword("INSTALL");
29973 self.write_space();
29974 self.generate_expression(&e.this)?;
29975 if let Some(from) = &e.from_ {
29976 self.write_space();
29977 self.write_keyword("FROM");
29978 self.write_space();
29979 self.generate_expression(from)?;
29980 }
29981 Ok(())
29982 }
29983
29984 fn generate_interval_op(&mut self, e: &IntervalOp) -> Result<()> {
29985 self.write_keyword("INTERVAL");
29987 self.write_space();
29988 self.generate_expression(&e.expression)?;
29990 if let Some(unit) = &e.unit {
29991 self.write_space();
29992 self.write(unit);
29993 }
29994 Ok(())
29995 }
29996
29997 fn generate_interval_span(&mut self, e: &IntervalSpan) -> Result<()> {
29998 self.write(&format!("{:?}", e.this).to_ascii_uppercase());
30000 self.write_space();
30001 self.write_keyword("TO");
30002 self.write_space();
30003 self.write(&format!("{:?}", e.expression).to_ascii_uppercase());
30004 Ok(())
30005 }
30006
30007 fn generate_into_clause(&mut self, e: &IntoClause) -> Result<()> {
30008 self.write_keyword("INTO");
30010 if e.temporary {
30011 self.write_keyword(" TEMPORARY");
30012 }
30013 if e.unlogged.is_some() {
30014 self.write_keyword(" UNLOGGED");
30015 }
30016 if let Some(this) = &e.this {
30017 self.write_space();
30018 self.generate_expression(this)?;
30019 }
30020 if !e.expressions.is_empty() {
30021 self.write(" (");
30022 for (i, expr) in e.expressions.iter().enumerate() {
30023 if i > 0 {
30024 self.write(", ");
30025 }
30026 self.generate_expression(expr)?;
30027 }
30028 self.write(")");
30029 }
30030 Ok(())
30031 }
30032
30033 fn generate_introducer(&mut self, e: &Introducer) -> Result<()> {
30034 self.generate_expression(&e.this)?;
30036 self.write_space();
30037 self.generate_expression(&e.expression)?;
30038 Ok(())
30039 }
30040
30041 fn generate_isolated_loading_property(&mut self, e: &IsolatedLoadingProperty) -> Result<()> {
30042 self.write_keyword("WITH");
30044 if e.no.is_some() {
30045 self.write_keyword(" NO");
30046 }
30047 if e.concurrent.is_some() {
30048 self.write_keyword(" CONCURRENT");
30049 }
30050 self.write_keyword(" ISOLATED LOADING");
30051 if let Some(target) = &e.target {
30052 self.write_space();
30053 self.generate_expression(target)?;
30054 }
30055 Ok(())
30056 }
30057
30058 fn generate_json(&mut self, e: &JSON) -> Result<()> {
30059 self.write_keyword("JSON");
30061 if let Some(this) = &e.this {
30062 self.write_space();
30063 self.generate_expression(this)?;
30064 }
30065 if let Some(with_) = &e.with_ {
30066 if let Expression::Boolean(b) = with_.as_ref() {
30068 if b.value {
30069 self.write_keyword(" WITH");
30070 } else {
30071 self.write_keyword(" WITHOUT");
30072 }
30073 }
30074 }
30075 if e.unique {
30076 self.write_keyword(" UNIQUE KEYS");
30077 }
30078 Ok(())
30079 }
30080
30081 fn generate_json_array(&mut self, e: &JSONArray) -> Result<()> {
30082 self.write_keyword("JSON_ARRAY");
30084 self.write("(");
30085 for (i, expr) in e.expressions.iter().enumerate() {
30086 if i > 0 {
30087 self.write(", ");
30088 }
30089 self.generate_expression(expr)?;
30090 }
30091 if let Some(null_handling) = &e.null_handling {
30092 self.write_space();
30093 self.generate_expression(null_handling)?;
30094 }
30095 if let Some(return_type) = &e.return_type {
30096 self.write_space();
30097 self.write_keyword("RETURNING");
30098 self.write_space();
30099 self.generate_expression(return_type)?;
30100 }
30101 if e.strict.is_some() {
30102 self.write_space();
30103 self.write_keyword("STRICT");
30104 }
30105 self.write(")");
30106 Ok(())
30107 }
30108
30109 fn generate_json_array_agg_struct(&mut self, e: &JSONArrayAgg) -> Result<()> {
30110 self.write_keyword("JSON_ARRAYAGG");
30112 self.write("(");
30113 self.generate_expression(&e.this)?;
30114 if let Some(order) = &e.order {
30115 self.write_space();
30116 if let Expression::OrderBy(ob) = order.as_ref() {
30118 self.write_keyword("ORDER BY");
30119 self.write_space();
30120 for (i, ord) in ob.expressions.iter().enumerate() {
30121 if i > 0 {
30122 self.write(", ");
30123 }
30124 self.generate_ordered(ord)?;
30125 }
30126 } else {
30127 self.generate_expression(order)?;
30129 }
30130 }
30131 if let Some(null_handling) = &e.null_handling {
30132 self.write_space();
30133 self.generate_expression(null_handling)?;
30134 }
30135 if let Some(return_type) = &e.return_type {
30136 self.write_space();
30137 self.write_keyword("RETURNING");
30138 self.write_space();
30139 self.generate_expression(return_type)?;
30140 }
30141 if e.strict.is_some() {
30142 self.write_space();
30143 self.write_keyword("STRICT");
30144 }
30145 self.write(")");
30146 Ok(())
30147 }
30148
30149 fn generate_json_object_agg_struct(&mut self, e: &JSONObjectAgg) -> Result<()> {
30150 self.write_keyword("JSON_OBJECTAGG");
30152 self.write("(");
30153 for (i, expr) in e.expressions.iter().enumerate() {
30154 if i > 0 {
30155 self.write(", ");
30156 }
30157 self.generate_expression(expr)?;
30158 }
30159 if let Some(null_handling) = &e.null_handling {
30160 self.write_space();
30161 self.generate_expression(null_handling)?;
30162 }
30163 if let Some(unique_keys) = &e.unique_keys {
30164 self.write_space();
30165 if let Expression::Boolean(b) = unique_keys.as_ref() {
30166 if b.value {
30167 self.write_keyword("WITH UNIQUE KEYS");
30168 } else {
30169 self.write_keyword("WITHOUT UNIQUE KEYS");
30170 }
30171 }
30172 }
30173 if let Some(return_type) = &e.return_type {
30174 self.write_space();
30175 self.write_keyword("RETURNING");
30176 self.write_space();
30177 self.generate_expression(return_type)?;
30178 }
30179 self.write(")");
30180 Ok(())
30181 }
30182
30183 fn generate_json_array_append(&mut self, e: &JSONArrayAppend) -> Result<()> {
30184 self.write_keyword("JSON_ARRAY_APPEND");
30186 self.write("(");
30187 self.generate_expression(&e.this)?;
30188 for expr in &e.expressions {
30189 self.write(", ");
30190 self.generate_expression(expr)?;
30191 }
30192 self.write(")");
30193 Ok(())
30194 }
30195
30196 fn generate_json_array_contains(&mut self, e: &JSONArrayContains) -> Result<()> {
30197 self.write_keyword("JSON_ARRAY_CONTAINS");
30199 self.write("(");
30200 self.generate_expression(&e.this)?;
30201 self.write(", ");
30202 self.generate_expression(&e.expression)?;
30203 self.write(")");
30204 Ok(())
30205 }
30206
30207 fn generate_json_array_insert(&mut self, e: &JSONArrayInsert) -> Result<()> {
30208 self.write_keyword("JSON_ARRAY_INSERT");
30210 self.write("(");
30211 self.generate_expression(&e.this)?;
30212 for expr in &e.expressions {
30213 self.write(", ");
30214 self.generate_expression(expr)?;
30215 }
30216 self.write(")");
30217 Ok(())
30218 }
30219
30220 fn generate_jsonb_exists(&mut self, e: &JSONBExists) -> Result<()> {
30221 self.write_keyword("JSONB_EXISTS");
30223 self.write("(");
30224 self.generate_expression(&e.this)?;
30225 if let Some(path) = &e.path {
30226 self.write(", ");
30227 self.generate_expression(path)?;
30228 }
30229 self.write(")");
30230 Ok(())
30231 }
30232
30233 fn generate_jsonb_extract_scalar(&mut self, e: &JSONBExtractScalar) -> Result<()> {
30234 self.write_keyword("JSONB_EXTRACT_SCALAR");
30236 self.write("(");
30237 self.generate_expression(&e.this)?;
30238 self.write(", ");
30239 self.generate_expression(&e.expression)?;
30240 self.write(")");
30241 Ok(())
30242 }
30243
30244 fn generate_jsonb_object_agg(&mut self, e: &JSONBObjectAgg) -> Result<()> {
30245 self.write_keyword("JSONB_OBJECT_AGG");
30247 self.write("(");
30248 self.generate_expression(&e.this)?;
30249 self.write(", ");
30250 self.generate_expression(&e.expression)?;
30251 self.write(")");
30252 Ok(())
30253 }
30254
30255 fn generate_json_column_def(&mut self, e: &JSONColumnDef) -> Result<()> {
30256 if let Some(nested_schema) = &e.nested_schema {
30258 self.write_keyword("NESTED");
30259 if let Some(path) = &e.path {
30260 self.write_space();
30261 self.write_keyword("PATH");
30262 self.write_space();
30263 self.generate_expression(path)?;
30264 }
30265 self.write_space();
30266 self.generate_expression(nested_schema)?;
30267 } else {
30268 if let Some(this) = &e.this {
30269 self.generate_expression(this)?;
30270 }
30271 if let Some(kind) = &e.kind {
30272 self.write_space();
30273 self.write(kind);
30274 }
30275 if e.format_json {
30276 self.write_space();
30277 self.write_keyword("FORMAT JSON");
30278 }
30279 if let Some(path) = &e.path {
30280 self.write_space();
30281 self.write_keyword("PATH");
30282 self.write_space();
30283 self.generate_expression(path)?;
30284 }
30285 if e.ordinality.is_some() {
30286 self.write_keyword(" FOR ORDINALITY");
30287 }
30288 }
30289 Ok(())
30290 }
30291
30292 fn generate_json_exists(&mut self, e: &JSONExists) -> Result<()> {
30293 self.write_keyword("JSON_EXISTS");
30295 self.write("(");
30296 self.generate_expression(&e.this)?;
30297 if let Some(path) = &e.path {
30298 self.write(", ");
30299 self.generate_expression(path)?;
30300 }
30301 if let Some(passing) = &e.passing {
30302 self.write_space();
30303 self.write_keyword("PASSING");
30304 self.write_space();
30305 self.generate_expression(passing)?;
30306 }
30307 if let Some(on_condition) = &e.on_condition {
30308 self.write_space();
30309 self.generate_expression(on_condition)?;
30310 }
30311 self.write(")");
30312 Ok(())
30313 }
30314
30315 fn generate_json_cast(&mut self, e: &JSONCast) -> Result<()> {
30316 self.generate_expression(&e.this)?;
30317 self.write(".:");
30318 if Self::data_type_has_nested_expressions(&e.to) {
30322 let saved = std::mem::take(&mut self.output);
30324 self.generate_data_type(&e.to)?;
30325 let type_sql = std::mem::replace(&mut self.output, saved);
30326 self.write("\"");
30327 self.write(&type_sql);
30328 self.write("\"");
30329 } else {
30330 self.generate_data_type(&e.to)?;
30331 }
30332 Ok(())
30333 }
30334
30335 fn data_type_has_nested_expressions(dt: &DataType) -> bool {
30338 matches!(
30339 dt,
30340 DataType::Array { .. } | DataType::Map { .. } | DataType::Struct { .. }
30341 )
30342 }
30343
30344 fn generate_json_extract_array(&mut self, e: &JSONExtractArray) -> Result<()> {
30345 self.write_keyword("JSON_EXTRACT_ARRAY");
30347 self.write("(");
30348 self.generate_expression(&e.this)?;
30349 if let Some(expr) = &e.expression {
30350 self.write(", ");
30351 self.generate_expression(expr)?;
30352 }
30353 self.write(")");
30354 Ok(())
30355 }
30356
30357 fn generate_json_extract_quote(&mut self, e: &JSONExtractQuote) -> Result<()> {
30358 if let Some(option) = &e.option {
30360 self.generate_expression(option)?;
30361 self.write_space();
30362 }
30363 self.write_keyword("QUOTES");
30364 if e.scalar.is_some() {
30365 self.write_keyword(" SCALAR_ONLY");
30366 }
30367 Ok(())
30368 }
30369
30370 fn generate_json_extract_scalar(&mut self, e: &JSONExtractScalar) -> Result<()> {
30371 self.write_keyword("JSON_EXTRACT_SCALAR");
30373 self.write("(");
30374 self.generate_expression(&e.this)?;
30375 self.write(", ");
30376 self.generate_expression(&e.expression)?;
30377 self.write(")");
30378 Ok(())
30379 }
30380
30381 fn generate_json_extract_path(&mut self, e: &JSONExtract) -> Result<()> {
30382 if e.variant_extract.is_some() {
30386 use crate::dialects::DialectType;
30387 if matches!(self.config.dialect, Some(DialectType::Databricks)) {
30388 self.generate_expression(&e.this)?;
30392 self.write(":");
30393 match e.expression.as_ref() {
30394 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
30395 let Literal::String(s) = lit.as_ref() else {
30396 unreachable!()
30397 };
30398 self.write_databricks_json_path(s);
30399 }
30400 _ => {
30401 self.generate_expression(&e.expression)?;
30403 }
30404 }
30405 } else {
30406 self.write_keyword("GET_PATH");
30408 self.write("(");
30409 self.generate_expression(&e.this)?;
30410 self.write(", ");
30411 self.generate_expression(&e.expression)?;
30412 self.write(")");
30413 }
30414 } else {
30415 self.write_keyword("JSON_EXTRACT");
30416 self.write("(");
30417 self.generate_expression(&e.this)?;
30418 self.write(", ");
30419 self.generate_expression(&e.expression)?;
30420 for expr in &e.expressions {
30421 self.write(", ");
30422 self.generate_expression(expr)?;
30423 }
30424 self.write(")");
30425 }
30426 Ok(())
30427 }
30428
30429 fn write_databricks_json_path(&mut self, path: &str) {
30433 if path.starts_with("[\"") || path.starts_with("['") {
30436 self.write(path);
30437 return;
30438 }
30439 let mut first = true;
30443 for segment in path.split('.') {
30444 if !first {
30445 self.write(".");
30446 }
30447 first = false;
30448 if let Some(bracket_pos) = segment.find('[') {
30450 let key = &segment[..bracket_pos];
30451 let subscript = &segment[bracket_pos..];
30452 if key.is_empty() {
30453 self.write(segment);
30455 } else if Self::is_safe_json_path_key(key) {
30456 self.write(key);
30457 self.write(subscript);
30458 } else {
30459 self.write("[\"");
30460 self.write(key);
30461 self.write("\"]");
30462 self.write(subscript);
30463 }
30464 } else if Self::is_safe_json_path_key(segment) {
30465 self.write(segment);
30466 } else {
30467 self.write("[\"");
30468 self.write(segment);
30469 self.write("\"]");
30470 }
30471 }
30472 }
30473
30474 fn is_safe_json_path_key(key: &str) -> bool {
30477 if key.is_empty() {
30478 return false;
30479 }
30480 let mut chars = key.chars();
30481 let first = chars.next().unwrap();
30482 if first != '_' && !first.is_ascii_alphabetic() {
30483 return false;
30484 }
30485 chars.all(|c| c == '_' || c.is_ascii_alphanumeric())
30486 }
30487
30488 fn generate_json_format(&mut self, e: &JSONFormat) -> Result<()> {
30489 if let Some(this) = &e.this {
30492 self.generate_expression(this)?;
30493 self.write_space();
30494 }
30495 self.write_keyword("FORMAT JSON");
30496 Ok(())
30497 }
30498
30499 fn generate_json_key_value(&mut self, e: &JSONKeyValue) -> Result<()> {
30500 self.generate_expression(&e.this)?;
30502 self.write(": ");
30503 self.generate_expression(&e.expression)?;
30504 Ok(())
30505 }
30506
30507 fn generate_json_keys(&mut self, e: &JSONKeys) -> Result<()> {
30508 self.write_keyword("JSON_KEYS");
30510 self.write("(");
30511 self.generate_expression(&e.this)?;
30512 if let Some(expr) = &e.expression {
30513 self.write(", ");
30514 self.generate_expression(expr)?;
30515 }
30516 for expr in &e.expressions {
30517 self.write(", ");
30518 self.generate_expression(expr)?;
30519 }
30520 self.write(")");
30521 Ok(())
30522 }
30523
30524 fn generate_json_keys_at_depth(&mut self, e: &JSONKeysAtDepth) -> Result<()> {
30525 self.write_keyword("JSON_KEYS");
30527 self.write("(");
30528 self.generate_expression(&e.this)?;
30529 if let Some(expr) = &e.expression {
30530 self.write(", ");
30531 self.generate_expression(expr)?;
30532 }
30533 self.write(")");
30534 Ok(())
30535 }
30536
30537 fn generate_json_path_expr(&mut self, e: &JSONPath) -> Result<()> {
30538 let mut path_str = String::new();
30541 for expr in &e.expressions {
30542 match expr {
30543 Expression::JSONPathRoot(_) => {
30544 path_str.push('$');
30545 }
30546 Expression::JSONPathKey(k) => {
30547 if let Expression::Literal(lit) = k.this.as_ref() {
30549 if let crate::expressions::Literal::String(s) = lit.as_ref() {
30550 path_str.push('.');
30551 let needs_quoting = s.chars().any(|c| !c.is_alphanumeric() && c != '_');
30553 if needs_quoting {
30554 path_str.push('"');
30555 path_str.push_str(s);
30556 path_str.push('"');
30557 } else {
30558 path_str.push_str(s);
30559 }
30560 }
30561 }
30562 }
30563 Expression::JSONPathSubscript(s) => {
30564 if let Expression::Literal(lit) = s.this.as_ref() {
30566 if let crate::expressions::Literal::Number(n) = lit.as_ref() {
30567 path_str.push('[');
30568 path_str.push_str(n);
30569 path_str.push(']');
30570 }
30571 }
30572 }
30573 _ => {
30574 let mut temp_gen = Self::with_arc_config(self.config.clone());
30576 temp_gen.generate_expression(expr)?;
30577 path_str.push_str(&temp_gen.output);
30578 }
30579 }
30580 }
30581 self.write("'");
30583 self.write(&path_str);
30584 self.write("'");
30585 Ok(())
30586 }
30587
30588 fn generate_json_path_filter(&mut self, e: &JSONPathFilter) -> Result<()> {
30589 self.write("?(");
30591 self.generate_expression(&e.this)?;
30592 self.write(")");
30593 Ok(())
30594 }
30595
30596 fn generate_json_path_key(&mut self, e: &JSONPathKey) -> Result<()> {
30597 self.write(".");
30599 self.generate_expression(&e.this)?;
30600 Ok(())
30601 }
30602
30603 fn generate_json_path_recursive(&mut self, e: &JSONPathRecursive) -> Result<()> {
30604 self.write("..");
30606 if let Some(this) = &e.this {
30607 self.generate_expression(this)?;
30608 }
30609 Ok(())
30610 }
30611
30612 fn generate_json_path_root(&mut self) -> Result<()> {
30613 self.write("$");
30615 Ok(())
30616 }
30617
30618 fn generate_json_path_script(&mut self, e: &JSONPathScript) -> Result<()> {
30619 self.write("(");
30621 self.generate_expression(&e.this)?;
30622 self.write(")");
30623 Ok(())
30624 }
30625
30626 fn generate_json_path_selector(&mut self, e: &JSONPathSelector) -> Result<()> {
30627 self.generate_expression(&e.this)?;
30629 Ok(())
30630 }
30631
30632 fn generate_json_path_slice(&mut self, e: &JSONPathSlice) -> Result<()> {
30633 self.write("[");
30635 if let Some(start) = &e.start {
30636 self.generate_expression(start)?;
30637 }
30638 self.write(":");
30639 if let Some(end) = &e.end {
30640 self.generate_expression(end)?;
30641 }
30642 if let Some(step) = &e.step {
30643 self.write(":");
30644 self.generate_expression(step)?;
30645 }
30646 self.write("]");
30647 Ok(())
30648 }
30649
30650 fn generate_json_path_subscript(&mut self, e: &JSONPathSubscript) -> Result<()> {
30651 self.write("[");
30653 self.generate_expression(&e.this)?;
30654 self.write("]");
30655 Ok(())
30656 }
30657
30658 fn generate_json_path_union(&mut self, e: &JSONPathUnion) -> Result<()> {
30659 self.write("[");
30661 for (i, expr) in e.expressions.iter().enumerate() {
30662 if i > 0 {
30663 self.write(", ");
30664 }
30665 self.generate_expression(expr)?;
30666 }
30667 self.write("]");
30668 Ok(())
30669 }
30670
30671 fn generate_json_remove(&mut self, e: &JSONRemove) -> Result<()> {
30672 self.write_keyword("JSON_REMOVE");
30674 self.write("(");
30675 self.generate_expression(&e.this)?;
30676 for expr in &e.expressions {
30677 self.write(", ");
30678 self.generate_expression(expr)?;
30679 }
30680 self.write(")");
30681 Ok(())
30682 }
30683
30684 fn generate_json_schema(&mut self, e: &JSONSchema) -> Result<()> {
30685 self.write_keyword("COLUMNS");
30688 self.write("(");
30689
30690 if self.config.pretty && !e.expressions.is_empty() {
30691 let mut expr_strings: Vec<String> = Vec::with_capacity(e.expressions.len());
30693 for expr in &e.expressions {
30694 let mut temp_gen = Generator::with_arc_config(self.config.clone());
30695 temp_gen.generate_expression(expr)?;
30696 expr_strings.push(temp_gen.output);
30697 }
30698
30699 if self.too_wide(&expr_strings) {
30701 self.write_newline();
30703 self.indent_level += 1;
30704 for (i, expr_str) in expr_strings.iter().enumerate() {
30705 if i > 0 {
30706 self.write(",");
30707 self.write_newline();
30708 }
30709 self.write_indent();
30710 self.write(expr_str);
30711 }
30712 self.write_newline();
30713 self.indent_level -= 1;
30714 self.write_indent();
30715 } else {
30716 for (i, expr_str) in expr_strings.iter().enumerate() {
30718 if i > 0 {
30719 self.write(", ");
30720 }
30721 self.write(expr_str);
30722 }
30723 }
30724 } else {
30725 for (i, expr) in e.expressions.iter().enumerate() {
30727 if i > 0 {
30728 self.write(", ");
30729 }
30730 self.generate_expression(expr)?;
30731 }
30732 }
30733 self.write(")");
30734 Ok(())
30735 }
30736
30737 fn generate_json_set(&mut self, e: &JSONSet) -> Result<()> {
30738 self.write_keyword("JSON_SET");
30740 self.write("(");
30741 self.generate_expression(&e.this)?;
30742 for expr in &e.expressions {
30743 self.write(", ");
30744 self.generate_expression(expr)?;
30745 }
30746 self.write(")");
30747 Ok(())
30748 }
30749
30750 fn generate_json_strip_nulls(&mut self, e: &JSONStripNulls) -> Result<()> {
30751 self.write_keyword("JSON_STRIP_NULLS");
30753 self.write("(");
30754 self.generate_expression(&e.this)?;
30755 if let Some(expr) = &e.expression {
30756 self.write(", ");
30757 self.generate_expression(expr)?;
30758 }
30759 self.write(")");
30760 Ok(())
30761 }
30762
30763 fn generate_json_table(&mut self, e: &JSONTable) -> Result<()> {
30764 self.write_keyword("JSON_TABLE");
30766 self.write("(");
30767 self.generate_expression(&e.this)?;
30768 if let Some(path) = &e.path {
30769 self.write(", ");
30770 self.generate_expression(path)?;
30771 }
30772 if let Some(error_handling) = &e.error_handling {
30773 self.write_space();
30774 self.generate_expression(error_handling)?;
30775 }
30776 if let Some(empty_handling) = &e.empty_handling {
30777 self.write_space();
30778 self.generate_expression(empty_handling)?;
30779 }
30780 if let Some(schema) = &e.schema {
30781 self.write_space();
30782 self.generate_expression(schema)?;
30783 }
30784 self.write(")");
30785 Ok(())
30786 }
30787
30788 fn generate_json_type(&mut self, e: &JSONType) -> Result<()> {
30789 self.write_keyword("JSON_TYPE");
30791 self.write("(");
30792 self.generate_expression(&e.this)?;
30793 self.write(")");
30794 Ok(())
30795 }
30796
30797 fn generate_json_value(&mut self, e: &JSONValue) -> Result<()> {
30798 self.write_keyword("JSON_VALUE");
30800 self.write("(");
30801 self.generate_expression(&e.this)?;
30802 if let Some(path) = &e.path {
30803 self.write(", ");
30804 self.generate_expression(path)?;
30805 }
30806 if let Some(returning) = &e.returning {
30807 self.write_space();
30808 self.write_keyword("RETURNING");
30809 self.write_space();
30810 self.generate_expression(returning)?;
30811 }
30812 if let Some(on_condition) = &e.on_condition {
30813 self.write_space();
30814 self.generate_expression(on_condition)?;
30815 }
30816 self.write(")");
30817 Ok(())
30818 }
30819
30820 fn generate_json_value_array(&mut self, e: &JSONValueArray) -> Result<()> {
30821 self.write_keyword("JSON_VALUE_ARRAY");
30823 self.write("(");
30824 self.generate_expression(&e.this)?;
30825 self.write(")");
30826 Ok(())
30827 }
30828
30829 fn generate_jarowinkler_similarity(&mut self, e: &JarowinklerSimilarity) -> Result<()> {
30830 self.write_keyword("JAROWINKLER_SIMILARITY");
30832 self.write("(");
30833 self.generate_expression(&e.this)?;
30834 self.write(", ");
30835 self.generate_expression(&e.expression)?;
30836 self.write(")");
30837 Ok(())
30838 }
30839
30840 fn generate_join_hint(&mut self, e: &JoinHint) -> Result<()> {
30841 self.generate_expression(&e.this)?;
30843 self.write("(");
30844 for (i, expr) in e.expressions.iter().enumerate() {
30845 if i > 0 {
30846 self.write(", ");
30847 }
30848 self.generate_expression(expr)?;
30849 }
30850 self.write(")");
30851 Ok(())
30852 }
30853
30854 fn generate_journal_property(&mut self, e: &JournalProperty) -> Result<()> {
30855 if e.no.is_some() {
30857 self.write_keyword("NO ");
30858 }
30859 if let Some(local) = &e.local {
30860 self.generate_expression(local)?;
30861 self.write_space();
30862 }
30863 if e.dual.is_some() {
30864 self.write_keyword("DUAL ");
30865 }
30866 if e.before.is_some() {
30867 self.write_keyword("BEFORE ");
30868 }
30869 if e.after.is_some() {
30870 self.write_keyword("AFTER ");
30871 }
30872 self.write_keyword("JOURNAL");
30873 Ok(())
30874 }
30875
30876 fn generate_language_property(&mut self, e: &LanguageProperty) -> Result<()> {
30877 self.write_keyword("LANGUAGE");
30879 self.write_space();
30880 self.generate_expression(&e.this)?;
30881 Ok(())
30882 }
30883
30884 fn generate_lateral(&mut self, e: &Lateral) -> Result<()> {
30885 if e.view.is_some() {
30887 self.write_keyword("LATERAL VIEW");
30889 if e.outer.is_some() {
30890 self.write_space();
30891 self.write_keyword("OUTER");
30892 }
30893 self.write_space();
30894 self.generate_expression(&e.this)?;
30895 if let Some(alias) = &e.alias {
30896 self.write_space();
30897 self.write(alias);
30898 }
30899 } else {
30900 self.write_keyword("LATERAL");
30902 self.write_space();
30903 self.generate_expression(&e.this)?;
30904 if e.ordinality.is_some() {
30905 self.write_space();
30906 self.write_keyword("WITH ORDINALITY");
30907 }
30908 if let Some(alias) = &e.alias {
30909 self.write_space();
30910 self.write_keyword("AS");
30911 self.write_space();
30912 self.write(alias);
30913 if !e.column_aliases.is_empty() {
30914 self.write("(");
30915 for (i, col) in e.column_aliases.iter().enumerate() {
30916 if i > 0 {
30917 self.write(", ");
30918 }
30919 self.write(col);
30920 }
30921 self.write(")");
30922 }
30923 }
30924 }
30925 Ok(())
30926 }
30927
30928 fn generate_like_property(&mut self, e: &LikeProperty) -> Result<()> {
30929 self.write_keyword("LIKE");
30931 self.write_space();
30932 self.generate_expression(&e.this)?;
30933 for expr in &e.expressions {
30934 self.write_space();
30935 self.generate_expression(expr)?;
30936 }
30937 Ok(())
30938 }
30939
30940 fn generate_limit(&mut self, e: &Limit) -> Result<()> {
30941 self.write_keyword("LIMIT");
30942 self.write_space();
30943 self.write_limit_expr(&e.this)?;
30944 if e.percent {
30945 self.write_space();
30946 self.write_keyword("PERCENT");
30947 }
30948 for comment in &e.comments {
30950 self.write(" ");
30951 self.write_formatted_comment(comment);
30952 }
30953 Ok(())
30954 }
30955
30956 fn generate_limit_options(&mut self, e: &LimitOptions) -> Result<()> {
30957 if e.percent.is_some() {
30959 self.write_keyword(" PERCENT");
30960 }
30961 if e.rows.is_some() {
30962 self.write_keyword(" ROWS");
30963 }
30964 if e.with_ties.is_some() {
30965 self.write_keyword(" WITH TIES");
30966 } else if e.rows.is_some() {
30967 self.write_keyword(" ONLY");
30968 }
30969 Ok(())
30970 }
30971
30972 fn generate_list(&mut self, e: &List) -> Result<()> {
30973 use crate::dialects::DialectType;
30974 let is_materialize = matches!(self.config.dialect, Some(DialectType::Materialize));
30975
30976 if e.expressions.len() == 1 {
30978 if let Expression::Select(_) = &e.expressions[0] {
30979 self.write_keyword("LIST");
30980 self.write("(");
30981 self.generate_expression(&e.expressions[0])?;
30982 self.write(")");
30983 return Ok(());
30984 }
30985 }
30986
30987 if is_materialize {
30989 self.write_keyword("LIST");
30990 self.write("[");
30991 for (i, expr) in e.expressions.iter().enumerate() {
30992 if i > 0 {
30993 self.write(", ");
30994 }
30995 self.generate_expression(expr)?;
30996 }
30997 self.write("]");
30998 } else {
30999 self.write_keyword("LIST");
31001 self.write("(");
31002 for (i, expr) in e.expressions.iter().enumerate() {
31003 if i > 0 {
31004 self.write(", ");
31005 }
31006 self.generate_expression(expr)?;
31007 }
31008 self.write(")");
31009 }
31010 Ok(())
31011 }
31012
31013 fn generate_tomap(&mut self, e: &ToMap) -> Result<()> {
31014 if let Expression::Select(_) = &*e.this {
31016 self.write_keyword("MAP");
31017 self.write("(");
31018 self.generate_expression(&e.this)?;
31019 self.write(")");
31020 return Ok(());
31021 }
31022
31023 let is_duckdb = matches!(self.config.dialect, Some(DialectType::DuckDB));
31024
31025 self.write_keyword("MAP");
31027 if is_duckdb {
31028 self.write(" {");
31029 } else {
31030 self.write("[");
31031 }
31032 if let Expression::Struct(s) = &*e.this {
31033 for (i, (_, expr)) in s.fields.iter().enumerate() {
31034 if i > 0 {
31035 self.write(", ");
31036 }
31037 if let Expression::PropertyEQ(op) = expr {
31038 self.generate_expression(&op.left)?;
31039 if is_duckdb {
31040 self.write(": ");
31041 } else {
31042 self.write(" => ");
31043 }
31044 self.generate_expression(&op.right)?;
31045 } else {
31046 self.generate_expression(expr)?;
31047 }
31048 }
31049 }
31050 if is_duckdb {
31051 self.write("}");
31052 } else {
31053 self.write("]");
31054 }
31055 Ok(())
31056 }
31057
31058 fn generate_localtime(&mut self, e: &Localtime) -> Result<()> {
31059 self.write_keyword("LOCALTIME");
31061 if let Some(precision) = &e.this {
31062 self.write("(");
31063 self.generate_expression(precision)?;
31064 self.write(")");
31065 }
31066 Ok(())
31067 }
31068
31069 fn generate_localtimestamp(&mut self, e: &Localtimestamp) -> Result<()> {
31070 self.write_keyword("LOCALTIMESTAMP");
31072 if let Some(precision) = &e.this {
31073 self.write("(");
31074 self.generate_expression(precision)?;
31075 self.write(")");
31076 }
31077 Ok(())
31078 }
31079
31080 fn generate_location_property(&mut self, e: &LocationProperty) -> Result<()> {
31081 self.write_keyword("LOCATION");
31083 self.write_space();
31084 self.generate_expression(&e.this)?;
31085 Ok(())
31086 }
31087
31088 fn generate_lock(&mut self, e: &Lock) -> Result<()> {
31089 if e.update.is_some() {
31091 if e.key.is_some() {
31092 self.write_keyword("FOR NO KEY UPDATE");
31093 } else {
31094 self.write_keyword("FOR UPDATE");
31095 }
31096 } else {
31097 if e.key.is_some() {
31098 self.write_keyword("FOR KEY SHARE");
31099 } else {
31100 self.write_keyword("FOR SHARE");
31101 }
31102 }
31103 if !e.expressions.is_empty() {
31104 self.write_keyword(" OF ");
31105 for (i, expr) in e.expressions.iter().enumerate() {
31106 if i > 0 {
31107 self.write(", ");
31108 }
31109 self.generate_expression(expr)?;
31110 }
31111 }
31112 if let Some(wait) = &e.wait {
31117 match wait.as_ref() {
31118 Expression::Boolean(b) => {
31119 if b.value {
31120 self.write_keyword(" NOWAIT");
31121 } else {
31122 self.write_keyword(" SKIP LOCKED");
31123 }
31124 }
31125 _ => {
31126 self.write_keyword(" WAIT ");
31128 self.generate_expression(wait)?;
31129 }
31130 }
31131 }
31132 Ok(())
31133 }
31134
31135 fn generate_lock_property(&mut self, e: &LockProperty) -> Result<()> {
31136 self.write_keyword("LOCK");
31138 self.write_space();
31139 self.generate_expression(&e.this)?;
31140 Ok(())
31141 }
31142
31143 fn generate_locking_property(&mut self, e: &LockingProperty) -> Result<()> {
31144 self.write_keyword("LOCKING");
31146 self.write_space();
31147 self.write(&e.kind);
31148 if let Some(this) = &e.this {
31149 self.write_space();
31150 self.generate_expression(this)?;
31151 }
31152 if let Some(for_or_in) = &e.for_or_in {
31153 self.write_space();
31154 self.generate_expression(for_or_in)?;
31155 }
31156 if let Some(lock_type) = &e.lock_type {
31157 self.write_space();
31158 self.generate_expression(lock_type)?;
31159 }
31160 if e.override_.is_some() {
31161 self.write_keyword(" OVERRIDE");
31162 }
31163 Ok(())
31164 }
31165
31166 fn generate_locking_statement(&mut self, e: &LockingStatement) -> Result<()> {
31167 self.generate_expression(&e.this)?;
31169 self.write_space();
31170 self.generate_expression(&e.expression)?;
31171 Ok(())
31172 }
31173
31174 fn generate_log_property(&mut self, e: &LogProperty) -> Result<()> {
31175 if e.no.is_some() {
31177 self.write_keyword("NO ");
31178 }
31179 self.write_keyword("LOG");
31180 Ok(())
31181 }
31182
31183 fn generate_md5_digest(&mut self, e: &MD5Digest) -> Result<()> {
31184 self.write_keyword("MD5");
31186 self.write("(");
31187 self.generate_expression(&e.this)?;
31188 for expr in &e.expressions {
31189 self.write(", ");
31190 self.generate_expression(expr)?;
31191 }
31192 self.write(")");
31193 Ok(())
31194 }
31195
31196 fn generate_ml_forecast(&mut self, e: &MLForecast) -> Result<()> {
31197 self.write_keyword("ML.FORECAST");
31199 self.write("(");
31200 self.generate_expression(&e.this)?;
31201 if let Some(expression) = &e.expression {
31202 self.write(", ");
31203 self.generate_expression(expression)?;
31204 }
31205 if let Some(params) = &e.params_struct {
31206 self.write(", ");
31207 self.generate_expression(params)?;
31208 }
31209 self.write(")");
31210 Ok(())
31211 }
31212
31213 fn generate_ml_translate(&mut self, e: &MLTranslate) -> Result<()> {
31214 self.write_keyword("ML.TRANSLATE");
31216 self.write("(");
31217 self.generate_expression(&e.this)?;
31218 self.write(", ");
31219 self.generate_expression(&e.expression)?;
31220 if let Some(params) = &e.params_struct {
31221 self.write(", ");
31222 self.generate_expression(params)?;
31223 }
31224 self.write(")");
31225 Ok(())
31226 }
31227
31228 fn generate_make_interval(&mut self, e: &MakeInterval) -> Result<()> {
31229 self.write_keyword("MAKE_INTERVAL");
31231 self.write("(");
31232 let mut first = true;
31233 if let Some(year) = &e.year {
31234 self.write("years => ");
31235 self.generate_expression(year)?;
31236 first = false;
31237 }
31238 if let Some(month) = &e.month {
31239 if !first {
31240 self.write(", ");
31241 }
31242 self.write("months => ");
31243 self.generate_expression(month)?;
31244 first = false;
31245 }
31246 if let Some(week) = &e.week {
31247 if !first {
31248 self.write(", ");
31249 }
31250 self.write("weeks => ");
31251 self.generate_expression(week)?;
31252 first = false;
31253 }
31254 if let Some(day) = &e.day {
31255 if !first {
31256 self.write(", ");
31257 }
31258 self.write("days => ");
31259 self.generate_expression(day)?;
31260 first = false;
31261 }
31262 if let Some(hour) = &e.hour {
31263 if !first {
31264 self.write(", ");
31265 }
31266 self.write("hours => ");
31267 self.generate_expression(hour)?;
31268 first = false;
31269 }
31270 if let Some(minute) = &e.minute {
31271 if !first {
31272 self.write(", ");
31273 }
31274 self.write("mins => ");
31275 self.generate_expression(minute)?;
31276 first = false;
31277 }
31278 if let Some(second) = &e.second {
31279 if !first {
31280 self.write(", ");
31281 }
31282 self.write("secs => ");
31283 self.generate_expression(second)?;
31284 }
31285 self.write(")");
31286 Ok(())
31287 }
31288
31289 fn generate_manhattan_distance(&mut self, e: &ManhattanDistance) -> Result<()> {
31290 self.write_keyword("MANHATTAN_DISTANCE");
31292 self.write("(");
31293 self.generate_expression(&e.this)?;
31294 self.write(", ");
31295 self.generate_expression(&e.expression)?;
31296 self.write(")");
31297 Ok(())
31298 }
31299
31300 fn generate_map(&mut self, e: &Map) -> Result<()> {
31301 self.write_keyword("MAP");
31303 self.write("(");
31304 for (i, (key, value)) in e.keys.iter().zip(e.values.iter()).enumerate() {
31305 if i > 0 {
31306 self.write(", ");
31307 }
31308 self.generate_expression(key)?;
31309 self.write(", ");
31310 self.generate_expression(value)?;
31311 }
31312 self.write(")");
31313 Ok(())
31314 }
31315
31316 fn generate_map_cat(&mut self, e: &MapCat) -> Result<()> {
31317 self.write_keyword("MAP_CAT");
31319 self.write("(");
31320 self.generate_expression(&e.this)?;
31321 self.write(", ");
31322 self.generate_expression(&e.expression)?;
31323 self.write(")");
31324 Ok(())
31325 }
31326
31327 fn generate_map_delete(&mut self, e: &MapDelete) -> Result<()> {
31328 self.write_keyword("MAP_DELETE");
31330 self.write("(");
31331 self.generate_expression(&e.this)?;
31332 for expr in &e.expressions {
31333 self.write(", ");
31334 self.generate_expression(expr)?;
31335 }
31336 self.write(")");
31337 Ok(())
31338 }
31339
31340 fn generate_map_insert(&mut self, e: &MapInsert) -> Result<()> {
31341 self.write_keyword("MAP_INSERT");
31343 self.write("(");
31344 self.generate_expression(&e.this)?;
31345 if let Some(key) = &e.key {
31346 self.write(", ");
31347 self.generate_expression(key)?;
31348 }
31349 if let Some(value) = &e.value {
31350 self.write(", ");
31351 self.generate_expression(value)?;
31352 }
31353 if let Some(update_flag) = &e.update_flag {
31354 self.write(", ");
31355 self.generate_expression(update_flag)?;
31356 }
31357 self.write(")");
31358 Ok(())
31359 }
31360
31361 fn generate_map_pick(&mut self, e: &MapPick) -> Result<()> {
31362 self.write_keyword("MAP_PICK");
31364 self.write("(");
31365 self.generate_expression(&e.this)?;
31366 for expr in &e.expressions {
31367 self.write(", ");
31368 self.generate_expression(expr)?;
31369 }
31370 self.write(")");
31371 Ok(())
31372 }
31373
31374 fn generate_masking_policy_column_constraint(
31375 &mut self,
31376 e: &MaskingPolicyColumnConstraint,
31377 ) -> Result<()> {
31378 self.write_keyword("MASKING POLICY");
31380 self.write_space();
31381 self.generate_expression(&e.this)?;
31382 if !e.expressions.is_empty() {
31383 self.write_keyword(" USING");
31384 self.write(" (");
31385 for (i, expr) in e.expressions.iter().enumerate() {
31386 if i > 0 {
31387 self.write(", ");
31388 }
31389 self.generate_expression(expr)?;
31390 }
31391 self.write(")");
31392 }
31393 Ok(())
31394 }
31395
31396 fn generate_match_against(&mut self, e: &MatchAgainst) -> Result<()> {
31397 if matches!(
31398 self.config.dialect,
31399 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
31400 ) {
31401 if e.expressions.len() > 1 {
31402 self.write("(");
31403 }
31404 for (i, expr) in e.expressions.iter().enumerate() {
31405 if i > 0 {
31406 self.write_keyword(" OR ");
31407 }
31408 self.generate_expression(expr)?;
31409 self.write_space();
31410 self.write("@@");
31411 self.write_space();
31412 self.generate_expression(&e.this)?;
31413 }
31414 if e.expressions.len() > 1 {
31415 self.write(")");
31416 }
31417 return Ok(());
31418 }
31419
31420 self.write_keyword("MATCH");
31422 self.write("(");
31423 for (i, expr) in e.expressions.iter().enumerate() {
31424 if i > 0 {
31425 self.write(", ");
31426 }
31427 self.generate_expression(expr)?;
31428 }
31429 self.write(")");
31430 self.write_keyword(" AGAINST");
31431 self.write("(");
31432 self.generate_expression(&e.this)?;
31433 if let Some(modifier) = &e.modifier {
31434 self.write_space();
31435 self.generate_expression(modifier)?;
31436 }
31437 self.write(")");
31438 Ok(())
31439 }
31440
31441 fn generate_match_recognize_measure(&mut self, e: &MatchRecognizeMeasure) -> Result<()> {
31442 if let Some(window_frame) = &e.window_frame {
31444 self.write(&format!("{:?}", window_frame).to_ascii_uppercase());
31445 self.write_space();
31446 }
31447 self.generate_expression(&e.this)?;
31448 Ok(())
31449 }
31450
31451 fn generate_materialized_property(&mut self, e: &MaterializedProperty) -> Result<()> {
31452 self.write_keyword("MATERIALIZED");
31454 if let Some(this) = &e.this {
31455 self.write_space();
31456 self.generate_expression(this)?;
31457 }
31458 Ok(())
31459 }
31460
31461 fn generate_merge(&mut self, e: &Merge) -> Result<()> {
31462 if let Some(with_) = &e.with_ {
31465 if let Expression::With(with_clause) = with_.as_ref() {
31466 self.generate_with(with_clause)?;
31467 self.write_space();
31468 } else {
31469 self.generate_expression(with_)?;
31470 self.write_space();
31471 }
31472 }
31473 self.write_keyword("MERGE INTO");
31474 self.write_space();
31475 if matches!(self.config.dialect, Some(crate::DialectType::Oracle)) {
31476 if let Expression::Alias(alias) = e.this.as_ref() {
31477 self.generate_expression(&alias.this)?;
31478 self.write_space();
31479 self.generate_identifier(&alias.alias)?;
31480 } else {
31481 self.generate_expression(&e.this)?;
31482 }
31483 } else {
31484 self.generate_expression(&e.this)?;
31485 }
31486
31487 if self.config.pretty {
31489 self.write_newline();
31490 self.write_indent();
31491 } else {
31492 self.write_space();
31493 }
31494 self.write_keyword("USING");
31495 self.write_space();
31496 self.generate_expression(&e.using)?;
31497
31498 if let Some(on) = &e.on {
31500 if self.config.pretty {
31501 self.write_newline();
31502 self.write_indent();
31503 } else {
31504 self.write_space();
31505 }
31506 self.write_keyword("ON");
31507 self.write_space();
31508 self.generate_expression(on)?;
31509 }
31510 if let Some(using_cond) = &e.using_cond {
31512 self.write_space();
31513 self.write_keyword("USING");
31514 self.write_space();
31515 self.write("(");
31516 if let Expression::Tuple(tuple) = using_cond.as_ref() {
31518 for (i, col) in tuple.expressions.iter().enumerate() {
31519 if i > 0 {
31520 self.write(", ");
31521 }
31522 self.generate_expression(col)?;
31523 }
31524 } else {
31525 self.generate_expression(using_cond)?;
31526 }
31527 self.write(")");
31528 }
31529 let saved_merge_strip = std::mem::take(&mut self.merge_strip_qualifiers);
31531 if matches!(
31532 self.config.dialect,
31533 Some(crate::DialectType::PostgreSQL)
31534 | Some(crate::DialectType::Redshift)
31535 | Some(crate::DialectType::Trino)
31536 | Some(crate::DialectType::Presto)
31537 | Some(crate::DialectType::Athena)
31538 ) {
31539 let mut names = Vec::new();
31540 match e.this.as_ref() {
31541 Expression::Alias(a) => {
31542 if let Expression::Table(t) = &a.this {
31544 names.push(t.name.name.clone());
31545 } else if let Expression::Identifier(id) = &a.this {
31546 names.push(id.name.clone());
31547 }
31548 names.push(a.alias.name.clone());
31549 }
31550 Expression::Table(t) => {
31551 names.push(t.name.name.clone());
31552 }
31553 Expression::Identifier(id) => {
31554 names.push(id.name.clone());
31555 }
31556 _ => {}
31557 }
31558 self.merge_strip_qualifiers = names;
31559 }
31560
31561 if let Some(whens) = &e.whens {
31563 if self.config.pretty {
31564 self.write_newline();
31565 self.write_indent();
31566 } else {
31567 self.write_space();
31568 }
31569 self.generate_expression(whens)?;
31570 }
31571
31572 self.merge_strip_qualifiers = saved_merge_strip;
31574
31575 if let Some(returning) = &e.returning {
31577 if self.config.pretty {
31578 self.write_newline();
31579 self.write_indent();
31580 } else {
31581 self.write_space();
31582 }
31583 self.generate_expression(returning)?;
31584 }
31585 Ok(())
31586 }
31587
31588 fn generate_merge_block_ratio_property(&mut self, e: &MergeBlockRatioProperty) -> Result<()> {
31589 if e.no.is_some() {
31591 self.write_keyword("NO MERGEBLOCKRATIO");
31592 } else if e.default.is_some() {
31593 self.write_keyword("DEFAULT MERGEBLOCKRATIO");
31594 } else {
31595 self.write_keyword("MERGEBLOCKRATIO");
31596 self.write("=");
31597 if let Some(this) = &e.this {
31598 self.generate_expression(this)?;
31599 }
31600 if e.percent.is_some() {
31601 self.write_keyword(" PERCENT");
31602 }
31603 }
31604 Ok(())
31605 }
31606
31607 fn generate_merge_tree_ttl(&mut self, e: &MergeTreeTTL) -> Result<()> {
31608 self.write_keyword("TTL");
31610 let pretty_clickhouse = self.config.pretty
31611 && matches!(
31612 self.config.dialect,
31613 Some(crate::dialects::DialectType::ClickHouse)
31614 );
31615
31616 if pretty_clickhouse {
31617 self.write_newline();
31618 self.indent_level += 1;
31619 for (i, expr) in e.expressions.iter().enumerate() {
31620 if i > 0 {
31621 self.write(",");
31622 self.write_newline();
31623 }
31624 self.write_indent();
31625 self.generate_expression(expr)?;
31626 }
31627 self.indent_level -= 1;
31628 } else {
31629 self.write_space();
31630 for (i, expr) in e.expressions.iter().enumerate() {
31631 if i > 0 {
31632 self.write(", ");
31633 }
31634 self.generate_expression(expr)?;
31635 }
31636 }
31637
31638 if let Some(where_) = &e.where_ {
31639 if pretty_clickhouse {
31640 self.write_newline();
31641 if let Expression::Where(w) = where_.as_ref() {
31642 self.write_indent();
31643 self.write_keyword("WHERE");
31644 self.write_newline();
31645 self.indent_level += 1;
31646 self.write_indent();
31647 self.generate_expression(&w.this)?;
31648 self.indent_level -= 1;
31649 } else {
31650 self.write_indent();
31651 self.generate_expression(where_)?;
31652 }
31653 } else {
31654 self.write_space();
31655 self.generate_expression(where_)?;
31656 }
31657 }
31658 if let Some(group) = &e.group {
31659 if pretty_clickhouse {
31660 self.write_newline();
31661 if let Expression::Group(g) = group.as_ref() {
31662 self.write_indent();
31663 self.write_keyword("GROUP BY");
31664 self.write_newline();
31665 self.indent_level += 1;
31666 for (i, expr) in g.expressions.iter().enumerate() {
31667 if i > 0 {
31668 self.write(",");
31669 self.write_newline();
31670 }
31671 self.write_indent();
31672 self.generate_expression(expr)?;
31673 }
31674 self.indent_level -= 1;
31675 } else {
31676 self.write_indent();
31677 self.generate_expression(group)?;
31678 }
31679 } else {
31680 self.write_space();
31681 self.generate_expression(group)?;
31682 }
31683 }
31684 if let Some(aggregates) = &e.aggregates {
31685 if pretty_clickhouse {
31686 self.write_newline();
31687 self.write_indent();
31688 self.write_keyword("SET");
31689 self.write_newline();
31690 self.indent_level += 1;
31691 if let Expression::Tuple(t) = aggregates.as_ref() {
31692 for (i, agg) in t.expressions.iter().enumerate() {
31693 if i > 0 {
31694 self.write(",");
31695 self.write_newline();
31696 }
31697 self.write_indent();
31698 self.generate_expression(agg)?;
31699 }
31700 } else {
31701 self.write_indent();
31702 self.generate_expression(aggregates)?;
31703 }
31704 self.indent_level -= 1;
31705 } else {
31706 self.write_space();
31707 self.write_keyword("SET");
31708 self.write_space();
31709 if let Expression::Tuple(t) = aggregates.as_ref() {
31710 for (i, agg) in t.expressions.iter().enumerate() {
31711 if i > 0 {
31712 self.write(", ");
31713 }
31714 self.generate_expression(agg)?;
31715 }
31716 } else {
31717 self.generate_expression(aggregates)?;
31718 }
31719 }
31720 }
31721 Ok(())
31722 }
31723
31724 fn generate_merge_tree_ttl_action(&mut self, e: &MergeTreeTTLAction) -> Result<()> {
31725 self.generate_expression(&e.this)?;
31727 if e.delete.is_some() {
31728 self.write_keyword(" DELETE");
31729 }
31730 if let Some(recompress) = &e.recompress {
31731 self.write_keyword(" RECOMPRESS ");
31732 self.generate_expression(recompress)?;
31733 }
31734 if let Some(to_disk) = &e.to_disk {
31735 self.write_keyword(" TO DISK ");
31736 self.generate_expression(to_disk)?;
31737 }
31738 if let Some(to_volume) = &e.to_volume {
31739 self.write_keyword(" TO VOLUME ");
31740 self.generate_expression(to_volume)?;
31741 }
31742 Ok(())
31743 }
31744
31745 fn generate_minhash(&mut self, e: &Minhash) -> Result<()> {
31746 self.write_keyword("MINHASH");
31748 self.write("(");
31749 self.generate_expression(&e.this)?;
31750 for expr in &e.expressions {
31751 self.write(", ");
31752 self.generate_expression(expr)?;
31753 }
31754 self.write(")");
31755 Ok(())
31756 }
31757
31758 fn generate_model_attribute(&mut self, e: &ModelAttribute) -> Result<()> {
31759 self.generate_expression(&e.this)?;
31761 self.write("!");
31762 self.generate_expression(&e.expression)?;
31763 Ok(())
31764 }
31765
31766 fn generate_monthname(&mut self, e: &Monthname) -> Result<()> {
31767 self.write_keyword("MONTHNAME");
31769 self.write("(");
31770 self.generate_expression(&e.this)?;
31771 self.write(")");
31772 Ok(())
31773 }
31774
31775 fn generate_multitable_inserts(&mut self, e: &MultitableInserts) -> Result<()> {
31776 for comment in &e.leading_comments {
31778 self.write_formatted_comment(comment);
31779 if self.config.pretty {
31780 self.write_newline();
31781 self.write_indent();
31782 } else {
31783 self.write_space();
31784 }
31785 }
31786 self.write_keyword("INSERT");
31788 if e.overwrite {
31789 self.write_space();
31790 self.write_keyword("OVERWRITE");
31791 }
31792 self.write_space();
31793 self.write(&e.kind);
31794 if self.config.pretty {
31795 self.indent_level += 1;
31796 for expr in &e.expressions {
31797 self.write_newline();
31798 self.write_indent();
31799 self.generate_expression(expr)?;
31800 }
31801 self.indent_level -= 1;
31802 } else {
31803 for expr in &e.expressions {
31804 self.write_space();
31805 self.generate_expression(expr)?;
31806 }
31807 }
31808 if let Some(source) = &e.source {
31809 if self.config.pretty {
31810 self.write_newline();
31811 self.write_indent();
31812 } else {
31813 self.write_space();
31814 }
31815 self.generate_expression(source)?;
31816 }
31817 Ok(())
31818 }
31819
31820 fn generate_next_value_for(&mut self, e: &NextValueFor) -> Result<()> {
31821 self.write_keyword("NEXT VALUE FOR");
31823 self.write_space();
31824 self.generate_expression(&e.this)?;
31825 if let Some(order) = &e.order {
31826 self.write_space();
31827 self.write_keyword("OVER");
31828 self.write(" (");
31829 self.generate_expression(order)?;
31830 self.write(")");
31831 }
31832 Ok(())
31833 }
31834
31835 fn generate_normal(&mut self, e: &Normal) -> Result<()> {
31836 self.write_keyword("NORMAL");
31838 self.write("(");
31839 self.generate_expression(&e.this)?;
31840 if let Some(stddev) = &e.stddev {
31841 self.write(", ");
31842 self.generate_expression(stddev)?;
31843 }
31844 if let Some(gen) = &e.gen {
31845 self.write(", ");
31846 self.generate_expression(gen)?;
31847 }
31848 self.write(")");
31849 Ok(())
31850 }
31851
31852 fn generate_normalize(&mut self, e: &Normalize) -> Result<()> {
31853 if e.is_casefold.is_some() {
31855 self.write_keyword("NORMALIZE_AND_CASEFOLD");
31856 } else {
31857 self.write_keyword("NORMALIZE");
31858 }
31859 self.write("(");
31860 self.generate_expression(&e.this)?;
31861 if let Some(form) = &e.form {
31862 self.write(", ");
31863 self.generate_expression(form)?;
31864 }
31865 self.write(")");
31866 Ok(())
31867 }
31868
31869 fn generate_not_null_column_constraint(&mut self, e: &NotNullColumnConstraint) -> Result<()> {
31870 if e.allow_null.is_none() {
31872 self.write_keyword("NOT ");
31873 }
31874 self.write_keyword("NULL");
31875 Ok(())
31876 }
31877
31878 fn generate_nullif(&mut self, e: &Nullif) -> Result<()> {
31879 self.write_keyword("NULLIF");
31881 self.write("(");
31882 self.generate_expression(&e.this)?;
31883 self.write(", ");
31884 self.generate_expression(&e.expression)?;
31885 self.write(")");
31886 Ok(())
31887 }
31888
31889 fn generate_number_to_str(&mut self, e: &NumberToStr) -> Result<()> {
31890 self.write_keyword("FORMAT");
31892 self.write("(");
31893 self.generate_expression(&e.this)?;
31894 self.write(", '");
31895 self.write(&e.format);
31896 self.write("'");
31897 if let Some(culture) = &e.culture {
31898 self.write(", ");
31899 self.generate_expression(culture)?;
31900 }
31901 self.write(")");
31902 Ok(())
31903 }
31904
31905 fn generate_object_agg(&mut self, e: &ObjectAgg) -> Result<()> {
31906 self.write_keyword("OBJECT_AGG");
31908 self.write("(");
31909 self.generate_expression(&e.this)?;
31910 self.write(", ");
31911 self.generate_expression(&e.expression)?;
31912 self.write(")");
31913 Ok(())
31914 }
31915
31916 fn generate_object_identifier(&mut self, e: &ObjectIdentifier) -> Result<()> {
31917 self.generate_expression(&e.this)?;
31919 Ok(())
31920 }
31921
31922 fn generate_object_insert(&mut self, e: &ObjectInsert) -> Result<()> {
31923 self.write_keyword("OBJECT_INSERT");
31925 self.write("(");
31926 self.generate_expression(&e.this)?;
31927 if let Some(key) = &e.key {
31928 self.write(", ");
31929 self.generate_expression(key)?;
31930 }
31931 if let Some(value) = &e.value {
31932 self.write(", ");
31933 self.generate_expression(value)?;
31934 }
31935 if let Some(update_flag) = &e.update_flag {
31936 self.write(", ");
31937 self.generate_expression(update_flag)?;
31938 }
31939 self.write(")");
31940 Ok(())
31941 }
31942
31943 fn generate_offset(&mut self, e: &Offset) -> Result<()> {
31944 self.write_keyword("OFFSET");
31946 self.write_space();
31947 self.generate_expression(&e.this)?;
31948 if e.rows == Some(true)
31950 && matches!(
31951 self.config.dialect,
31952 Some(crate::dialects::DialectType::TSQL)
31953 | Some(crate::dialects::DialectType::Oracle)
31954 )
31955 {
31956 self.write_space();
31957 self.write_keyword("ROWS");
31958 }
31959 Ok(())
31960 }
31961
31962 fn generate_qualify(&mut self, e: &Qualify) -> Result<()> {
31963 self.write_keyword("QUALIFY");
31965 self.write_space();
31966 self.generate_expression(&e.this)?;
31967 Ok(())
31968 }
31969
31970 fn generate_on_cluster(&mut self, e: &OnCluster) -> Result<()> {
31971 self.write_keyword("ON CLUSTER");
31973 self.write_space();
31974 self.generate_expression(&e.this)?;
31975 Ok(())
31976 }
31977
31978 fn generate_on_commit_property(&mut self, e: &OnCommitProperty) -> Result<()> {
31979 self.write_keyword("ON COMMIT");
31981 if e.delete.is_some() {
31982 self.write_keyword(" DELETE ROWS");
31983 } else {
31984 self.write_keyword(" PRESERVE ROWS");
31985 }
31986 Ok(())
31987 }
31988
31989 fn generate_on_condition(&mut self, e: &OnCondition) -> Result<()> {
31990 if let Some(empty) = &e.empty {
31992 self.generate_expression(empty)?;
31993 self.write_keyword(" ON EMPTY");
31994 }
31995 if let Some(error) = &e.error {
31996 if e.empty.is_some() {
31997 self.write_space();
31998 }
31999 self.generate_expression(error)?;
32000 self.write_keyword(" ON ERROR");
32001 }
32002 if let Some(null) = &e.null {
32003 if e.empty.is_some() || e.error.is_some() {
32004 self.write_space();
32005 }
32006 self.generate_expression(null)?;
32007 self.write_keyword(" ON NULL");
32008 }
32009 Ok(())
32010 }
32011
32012 fn generate_on_conflict(&mut self, e: &OnConflict) -> Result<()> {
32013 if matches!(self.config.dialect, Some(DialectType::Materialize)) {
32015 return Ok(());
32016 }
32017 if e.duplicate.is_some() {
32019 self.write_keyword("ON DUPLICATE KEY UPDATE");
32021 for (i, expr) in e.expressions.iter().enumerate() {
32022 if i > 0 {
32023 self.write(",");
32024 }
32025 self.write_space();
32026 self.generate_expression(expr)?;
32027 }
32028 return Ok(());
32029 } else {
32030 self.write_keyword("ON CONFLICT");
32031 }
32032 if let Some(constraint) = &e.constraint {
32033 self.write_keyword(" ON CONSTRAINT ");
32034 self.generate_expression(constraint)?;
32035 }
32036 if let Some(conflict_keys) = &e.conflict_keys {
32037 if let Expression::Tuple(t) = conflict_keys.as_ref() {
32039 self.write("(");
32040 for (i, expr) in t.expressions.iter().enumerate() {
32041 if i > 0 {
32042 self.write(", ");
32043 }
32044 self.generate_expression(expr)?;
32045 }
32046 self.write(")");
32047 } else {
32048 self.write("(");
32049 self.generate_expression(conflict_keys)?;
32050 self.write(")");
32051 }
32052 }
32053 if let Some(index_predicate) = &e.index_predicate {
32054 self.write_keyword(" WHERE ");
32055 self.generate_expression(index_predicate)?;
32056 }
32057 if let Some(action) = &e.action {
32058 if let Expression::Identifier(id) = action.as_ref() {
32060 if id.name.eq_ignore_ascii_case("NOTHING") {
32061 self.write_keyword(" DO NOTHING");
32062 } else {
32063 self.write_keyword(" DO ");
32064 self.generate_expression(action)?;
32065 }
32066 } else if let Expression::Tuple(t) = action.as_ref() {
32067 self.write_keyword(" DO UPDATE SET ");
32069 for (i, expr) in t.expressions.iter().enumerate() {
32070 if i > 0 {
32071 self.write(", ");
32072 }
32073 self.generate_expression(expr)?;
32074 }
32075 } else {
32076 self.write_keyword(" DO ");
32077 self.generate_expression(action)?;
32078 }
32079 }
32080 if let Some(where_) = &e.where_ {
32082 self.write_keyword(" WHERE ");
32083 self.generate_expression(where_)?;
32084 }
32085 Ok(())
32086 }
32087
32088 fn generate_on_property(&mut self, e: &OnProperty) -> Result<()> {
32089 self.write_keyword("ON");
32091 self.write_space();
32092 self.generate_expression(&e.this)?;
32093 Ok(())
32094 }
32095
32096 fn generate_opclass(&mut self, e: &Opclass) -> Result<()> {
32097 self.generate_expression(&e.this)?;
32099 self.write_space();
32100 self.generate_expression(&e.expression)?;
32101 Ok(())
32102 }
32103
32104 fn generate_open_json(&mut self, e: &OpenJSON) -> Result<()> {
32105 self.write_keyword("OPENJSON");
32107 self.write("(");
32108 self.generate_expression(&e.this)?;
32109 if let Some(path) = &e.path {
32110 self.write(", ");
32111 self.generate_expression(path)?;
32112 }
32113 self.write(")");
32114 if !e.expressions.is_empty() {
32115 self.write_keyword(" WITH");
32116 if self.config.pretty {
32117 self.write(" (\n");
32118 self.indent_level += 2;
32119 for (i, expr) in e.expressions.iter().enumerate() {
32120 if i > 0 {
32121 self.write(",\n");
32122 }
32123 self.write_indent();
32124 self.generate_expression(expr)?;
32125 }
32126 self.write("\n");
32127 self.indent_level -= 2;
32128 self.write(")");
32129 } else {
32130 self.write(" (");
32131 for (i, expr) in e.expressions.iter().enumerate() {
32132 if i > 0 {
32133 self.write(", ");
32134 }
32135 self.generate_expression(expr)?;
32136 }
32137 self.write(")");
32138 }
32139 }
32140 Ok(())
32141 }
32142
32143 fn generate_open_json_column_def(&mut self, e: &OpenJSONColumnDef) -> Result<()> {
32144 self.generate_expression(&e.this)?;
32146 self.write_space();
32147 if let Some(ref dt) = e.data_type {
32149 self.generate_data_type(dt)?;
32150 } else if !e.kind.is_empty() {
32151 self.write(&e.kind);
32152 }
32153 if let Some(path) = &e.path {
32154 self.write_space();
32155 self.generate_expression(path)?;
32156 }
32157 if e.as_json.is_some() {
32158 self.write_keyword(" AS JSON");
32159 }
32160 Ok(())
32161 }
32162
32163 fn generate_operator(&mut self, e: &Operator) -> Result<()> {
32164 self.generate_expression(&e.this)?;
32166 self.write_space();
32167 if let Some(op) = &e.operator {
32168 self.write_keyword("OPERATOR");
32169 self.write("(");
32170 self.generate_expression(op)?;
32171 self.write(")");
32172 }
32173 for comment in &e.comments {
32175 self.write_space();
32176 self.write_formatted_comment(comment);
32177 }
32178 self.write_space();
32179 self.generate_expression(&e.expression)?;
32180 Ok(())
32181 }
32182
32183 fn generate_order_by(&mut self, e: &OrderBy) -> Result<()> {
32184 self.write_keyword("ORDER BY");
32186 let pretty_clickhouse_single_paren = self.config.pretty
32187 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
32188 && e.expressions.len() == 1
32189 && matches!(e.expressions[0].this, Expression::Paren(ref p) if !matches!(p.this, Expression::Tuple(_)));
32190 let clickhouse_single_tuple = matches!(self.config.dialect, Some(DialectType::ClickHouse))
32191 && e.expressions.len() == 1
32192 && matches!(e.expressions[0].this, Expression::Tuple(_))
32193 && !e.expressions[0].desc
32194 && e.expressions[0].nulls_first.is_none();
32195
32196 if pretty_clickhouse_single_paren {
32197 self.write_space();
32198 if let Expression::Paren(p) = &e.expressions[0].this {
32199 self.write("(");
32200 self.write_newline();
32201 self.indent_level += 1;
32202 self.write_indent();
32203 self.generate_expression(&p.this)?;
32204 self.indent_level -= 1;
32205 self.write_newline();
32206 self.write(")");
32207 }
32208 return Ok(());
32209 }
32210
32211 if clickhouse_single_tuple {
32212 self.write_space();
32213 if let Expression::Tuple(t) = &e.expressions[0].this {
32214 self.write("(");
32215 for (i, expr) in t.expressions.iter().enumerate() {
32216 if i > 0 {
32217 self.write(", ");
32218 }
32219 self.generate_expression(expr)?;
32220 }
32221 self.write(")");
32222 }
32223 return Ok(());
32224 }
32225
32226 self.write_space();
32227 for (i, ordered) in e.expressions.iter().enumerate() {
32228 if i > 0 {
32229 self.write(", ");
32230 }
32231 self.generate_expression(&ordered.this)?;
32232 if ordered.desc {
32233 self.write_space();
32234 self.write_keyword("DESC");
32235 } else if ordered.explicit_asc {
32236 self.write_space();
32237 self.write_keyword("ASC");
32238 }
32239 if let Some(nulls_first) = ordered.nulls_first {
32240 let skip_nulls_last =
32242 !nulls_first && matches!(self.config.dialect, Some(DialectType::Dremio));
32243 if !skip_nulls_last {
32244 self.write_space();
32245 self.write_keyword("NULLS");
32246 self.write_space();
32247 if nulls_first {
32248 self.write_keyword("FIRST");
32249 } else {
32250 self.write_keyword("LAST");
32251 }
32252 }
32253 }
32254 }
32255 Ok(())
32256 }
32257
32258 fn generate_output_model_property(&mut self, e: &OutputModelProperty) -> Result<()> {
32259 self.write_keyword("OUTPUT");
32261 self.write("(");
32262 if self.config.pretty {
32263 self.indent_level += 1;
32264 self.write_newline();
32265 self.write_indent();
32266 self.generate_expression(&e.this)?;
32267 self.indent_level -= 1;
32268 self.write_newline();
32269 } else {
32270 self.generate_expression(&e.this)?;
32271 }
32272 self.write(")");
32273 Ok(())
32274 }
32275
32276 fn generate_overflow_truncate_behavior(&mut self, e: &OverflowTruncateBehavior) -> Result<()> {
32277 self.write_keyword("TRUNCATE");
32279 if let Some(this) = &e.this {
32280 self.write_space();
32281 self.generate_expression(this)?;
32282 }
32283 if e.with_count.is_some() {
32284 self.write_keyword(" WITH COUNT");
32285 } else {
32286 self.write_keyword(" WITHOUT COUNT");
32287 }
32288 Ok(())
32289 }
32290
32291 fn generate_parameterized_agg(&mut self, e: &ParameterizedAgg) -> Result<()> {
32292 self.generate_expression(&e.this)?;
32294 self.write("(");
32295 for (i, expr) in e.expressions.iter().enumerate() {
32296 if i > 0 {
32297 self.write(", ");
32298 }
32299 self.generate_expression(expr)?;
32300 }
32301 self.write(")(");
32302 for (i, param) in e.params.iter().enumerate() {
32303 if i > 0 {
32304 self.write(", ");
32305 }
32306 self.generate_expression(param)?;
32307 }
32308 self.write(")");
32309 Ok(())
32310 }
32311
32312 fn generate_parse_datetime(&mut self, e: &ParseDatetime) -> Result<()> {
32313 self.write_keyword("PARSE_DATETIME");
32315 self.write("(");
32316 if let Some(format) = &e.format {
32317 self.write("'");
32318 self.write(format);
32319 self.write("', ");
32320 }
32321 self.generate_expression(&e.this)?;
32322 if let Some(zone) = &e.zone {
32323 self.write(", ");
32324 self.generate_expression(zone)?;
32325 }
32326 self.write(")");
32327 Ok(())
32328 }
32329
32330 fn generate_parse_ip(&mut self, e: &ParseIp) -> Result<()> {
32331 self.write_keyword("PARSE_IP");
32333 self.write("(");
32334 self.generate_expression(&e.this)?;
32335 if let Some(type_) = &e.type_ {
32336 self.write(", ");
32337 self.generate_expression(type_)?;
32338 }
32339 if let Some(permissive) = &e.permissive {
32340 self.write(", ");
32341 self.generate_expression(permissive)?;
32342 }
32343 self.write(")");
32344 Ok(())
32345 }
32346
32347 fn generate_parse_json(&mut self, e: &ParseJSON) -> Result<()> {
32348 self.write_keyword("PARSE_JSON");
32350 self.write("(");
32351 self.generate_expression(&e.this)?;
32352 if let Some(expression) = &e.expression {
32353 self.write(", ");
32354 self.generate_expression(expression)?;
32355 }
32356 self.write(")");
32357 Ok(())
32358 }
32359
32360 fn generate_parse_time(&mut self, e: &ParseTime) -> Result<()> {
32361 self.write_keyword("PARSE_TIME");
32363 self.write("(");
32364 self.write(&format!("'{}'", e.format));
32365 self.write(", ");
32366 self.generate_expression(&e.this)?;
32367 self.write(")");
32368 Ok(())
32369 }
32370
32371 fn generate_parse_url(&mut self, e: &ParseUrl) -> Result<()> {
32372 self.write_keyword("PARSE_URL");
32374 self.write("(");
32375 self.generate_expression(&e.this)?;
32376 if let Some(part) = &e.part_to_extract {
32377 self.write(", ");
32378 self.generate_expression(part)?;
32379 }
32380 if let Some(key) = &e.key {
32381 self.write(", ");
32382 self.generate_expression(key)?;
32383 }
32384 if let Some(permissive) = &e.permissive {
32385 self.write(", ");
32386 self.generate_expression(permissive)?;
32387 }
32388 self.write(")");
32389 Ok(())
32390 }
32391
32392 fn generate_partition_expr(&mut self, e: &Partition) -> Result<()> {
32393 if e.subpartition {
32395 self.write_keyword("SUBPARTITION");
32396 } else {
32397 self.write_keyword("PARTITION");
32398 }
32399 self.write("(");
32400 for (i, expr) in e.expressions.iter().enumerate() {
32401 if i > 0 {
32402 self.write(", ");
32403 }
32404 self.generate_expression(expr)?;
32405 }
32406 self.write(")");
32407 Ok(())
32408 }
32409
32410 fn generate_partition_bound_spec(&mut self, e: &PartitionBoundSpec) -> Result<()> {
32411 if let Some(this) = &e.this {
32413 if let Some(expression) = &e.expression {
32414 self.write_keyword("WITH");
32416 self.write(" (");
32417 self.write_keyword("MODULUS");
32418 self.write_space();
32419 self.generate_expression(this)?;
32420 self.write(", ");
32421 self.write_keyword("REMAINDER");
32422 self.write_space();
32423 self.generate_expression(expression)?;
32424 self.write(")");
32425 } else {
32426 self.write_keyword("IN");
32428 self.write(" (");
32429 self.generate_partition_bound_values(this)?;
32430 self.write(")");
32431 }
32432 } else if let (Some(from), Some(to)) = (&e.from_expressions, &e.to_expressions) {
32433 self.write_keyword("FROM");
32435 self.write(" (");
32436 self.generate_partition_bound_values(from)?;
32437 self.write(") ");
32438 self.write_keyword("TO");
32439 self.write(" (");
32440 self.generate_partition_bound_values(to)?;
32441 self.write(")");
32442 }
32443 Ok(())
32444 }
32445
32446 fn generate_partition_bound_values(&mut self, expr: &Expression) -> Result<()> {
32449 if let Expression::Tuple(t) = expr {
32450 for (i, e) in t.expressions.iter().enumerate() {
32451 if i > 0 {
32452 self.write(", ");
32453 }
32454 self.generate_expression(e)?;
32455 }
32456 Ok(())
32457 } else {
32458 self.generate_expression(expr)
32459 }
32460 }
32461
32462 fn generate_partition_by_list_property(&mut self, e: &PartitionByListProperty) -> Result<()> {
32463 self.write_keyword("PARTITION BY LIST");
32465 if let Some(partition_exprs) = &e.partition_expressions {
32466 self.write(" (");
32467 self.generate_doris_partition_expressions(partition_exprs)?;
32469 self.write(")");
32470 }
32471 if let Some(create_exprs) = &e.create_expressions {
32472 self.write(" (");
32473 self.generate_doris_partition_definitions(create_exprs)?;
32475 self.write(")");
32476 }
32477 Ok(())
32478 }
32479
32480 fn generate_partition_by_range_property(&mut self, e: &PartitionByRangeProperty) -> Result<()> {
32481 self.write_keyword("PARTITION BY RANGE");
32483 if let Some(partition_exprs) = &e.partition_expressions {
32484 self.write(" (");
32485 self.generate_doris_partition_expressions(partition_exprs)?;
32487 self.write(")");
32488 }
32489 if let Some(create_exprs) = &e.create_expressions {
32490 self.write(" (");
32491 self.generate_doris_partition_definitions(create_exprs)?;
32493 self.write(")");
32494 }
32495 Ok(())
32496 }
32497
32498 fn generate_doris_partition_expressions(&mut self, expr: &Expression) -> Result<()> {
32500 if let Expression::Tuple(t) = expr {
32501 for (i, e) in t.expressions.iter().enumerate() {
32502 if i > 0 {
32503 self.write(", ");
32504 }
32505 self.generate_expression(e)?;
32506 }
32507 } else {
32508 self.generate_expression(expr)?;
32509 }
32510 Ok(())
32511 }
32512
32513 fn generate_doris_partition_definitions(&mut self, expr: &Expression) -> Result<()> {
32515 match expr {
32516 Expression::Tuple(t) => {
32517 for (i, part) in t.expressions.iter().enumerate() {
32519 if i > 0 {
32520 self.write(", ");
32521 }
32522 if let Expression::Partition(p) = part {
32524 for (j, inner) in p.expressions.iter().enumerate() {
32525 if j > 0 {
32526 self.write(", ");
32527 }
32528 self.generate_expression(inner)?;
32529 }
32530 } else {
32531 self.generate_expression(part)?;
32532 }
32533 }
32534 }
32535 Expression::PartitionByRangePropertyDynamic(_) => {
32536 self.generate_expression(expr)?;
32538 }
32539 _ => {
32540 self.generate_expression(expr)?;
32541 }
32542 }
32543 Ok(())
32544 }
32545
32546 fn generate_partition_by_range_property_dynamic(
32547 &mut self,
32548 e: &PartitionByRangePropertyDynamic,
32549 ) -> Result<()> {
32550 if e.use_start_end {
32551 if let Some(start) = &e.start {
32553 self.write_keyword("START");
32554 self.write(" (");
32555 self.generate_expression(start)?;
32556 self.write(")");
32557 }
32558 if let Some(end) = &e.end {
32559 self.write_space();
32560 self.write_keyword("END");
32561 self.write(" (");
32562 self.generate_expression(end)?;
32563 self.write(")");
32564 }
32565 if let Some(every) = &e.every {
32566 self.write_space();
32567 self.write_keyword("EVERY");
32568 self.write(" (");
32569 self.generate_doris_interval(every)?;
32571 self.write(")");
32572 }
32573 } else {
32574 if let Some(start) = &e.start {
32576 self.write_keyword("FROM");
32577 self.write(" (");
32578 self.generate_expression(start)?;
32579 self.write(")");
32580 }
32581 if let Some(end) = &e.end {
32582 self.write_space();
32583 self.write_keyword("TO");
32584 self.write(" (");
32585 self.generate_expression(end)?;
32586 self.write(")");
32587 }
32588 if let Some(every) = &e.every {
32589 self.write_space();
32590 self.generate_doris_interval(every)?;
32592 }
32593 }
32594 Ok(())
32595 }
32596
32597 fn generate_doris_interval(&mut self, expr: &Expression) -> Result<()> {
32599 if let Expression::Interval(interval) = expr {
32600 self.write_keyword("INTERVAL");
32601 if let Some(ref value) = interval.this {
32602 self.write_space();
32603 match value {
32607 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(s) if s.chars().all(|c| c.is_ascii_digit() || c == '.' || c == '-') && !s.is_empty()) => {
32608 if let Literal::String(s) = lit.as_ref() {
32609 self.write(s);
32610 }
32611 }
32612 _ => {
32613 self.generate_expression(value)?;
32614 }
32615 }
32616 }
32617 if let Some(ref unit_spec) = interval.unit {
32618 self.write_space();
32619 self.write_interval_unit_spec(unit_spec)?;
32620 }
32621 Ok(())
32622 } else {
32623 self.generate_expression(expr)
32624 }
32625 }
32626
32627 fn generate_partition_by_truncate(&mut self, e: &PartitionByTruncate) -> Result<()> {
32628 self.write_keyword("TRUNCATE");
32630 self.write("(");
32631 self.generate_expression(&e.expression)?;
32632 self.write(", ");
32633 self.generate_expression(&e.this)?;
32634 self.write(")");
32635 Ok(())
32636 }
32637
32638 fn generate_partition_list(&mut self, e: &PartitionList) -> Result<()> {
32639 self.write_keyword("PARTITION");
32641 self.write_space();
32642 self.generate_expression(&e.this)?;
32643 self.write_space();
32644 self.write_keyword("VALUES IN");
32645 self.write(" (");
32646 for (i, expr) in e.expressions.iter().enumerate() {
32647 if i > 0 {
32648 self.write(", ");
32649 }
32650 self.generate_expression(expr)?;
32651 }
32652 self.write(")");
32653 Ok(())
32654 }
32655
32656 fn generate_partition_range(&mut self, e: &PartitionRange) -> Result<()> {
32657 if e.expressions.is_empty() && e.expression.is_some() {
32660 self.generate_expression(&e.this)?;
32662 self.write_space();
32663 self.write_keyword("TO");
32664 self.write_space();
32665 self.generate_expression(e.expression.as_ref().unwrap())?;
32666 return Ok(());
32667 }
32668
32669 self.write_keyword("PARTITION");
32671 self.write_space();
32672 self.generate_expression(&e.this)?;
32673 self.write_space();
32674
32675 if e.expressions.len() == 1 {
32677 self.write_keyword("VALUES LESS THAN");
32679 self.write(" (");
32680 self.generate_expression(&e.expressions[0])?;
32681 self.write(")");
32682 } else if !e.expressions.is_empty() {
32683 self.write_keyword("VALUES");
32685 self.write(" [");
32686 for (i, expr) in e.expressions.iter().enumerate() {
32687 if i > 0 {
32688 self.write(", ");
32689 }
32690 if let Expression::Tuple(t) = expr {
32692 self.write("(");
32693 for (j, inner) in t.expressions.iter().enumerate() {
32694 if j > 0 {
32695 self.write(", ");
32696 }
32697 self.generate_expression(inner)?;
32698 }
32699 self.write(")");
32700 } else {
32701 self.write("(");
32702 self.generate_expression(expr)?;
32703 self.write(")");
32704 }
32705 }
32706 self.write(")");
32707 }
32708 Ok(())
32709 }
32710
32711 fn generate_partitioned_by_bucket(&mut self, e: &PartitionedByBucket) -> Result<()> {
32712 self.write_keyword("BUCKET");
32714 self.write("(");
32715 self.generate_expression(&e.this)?;
32716 self.write(", ");
32717 self.generate_expression(&e.expression)?;
32718 self.write(")");
32719 Ok(())
32720 }
32721
32722 fn generate_partition_by_property(&mut self, e: &PartitionByProperty) -> Result<()> {
32723 self.write_keyword("PARTITION BY");
32725 self.write_space();
32726 for (i, expr) in e.expressions.iter().enumerate() {
32727 if i > 0 {
32728 self.write(", ");
32729 }
32730 self.generate_expression(expr)?;
32731 }
32732 Ok(())
32733 }
32734
32735 fn generate_partitioned_by_property(&mut self, e: &PartitionedByProperty) -> Result<()> {
32736 if matches!(
32738 self.config.dialect,
32739 Some(crate::dialects::DialectType::Teradata)
32740 | Some(crate::dialects::DialectType::ClickHouse)
32741 ) {
32742 self.write_keyword("PARTITION BY");
32743 } else {
32744 self.write_keyword("PARTITIONED BY");
32745 }
32746 self.write_space();
32747 if self.config.pretty {
32749 if let Expression::Tuple(ref tuple) = *e.this {
32750 self.write("(");
32751 self.write_newline();
32752 self.indent_level += 1;
32753 for (i, expr) in tuple.expressions.iter().enumerate() {
32754 if i > 0 {
32755 self.write(",");
32756 self.write_newline();
32757 }
32758 self.write_indent();
32759 self.generate_expression(expr)?;
32760 }
32761 self.indent_level -= 1;
32762 self.write_newline();
32763 self.write(")");
32764 } else {
32765 self.generate_expression(&e.this)?;
32766 }
32767 } else {
32768 self.generate_expression(&e.this)?;
32769 }
32770 Ok(())
32771 }
32772
32773 fn generate_partitioned_of_property(&mut self, e: &PartitionedOfProperty) -> Result<()> {
32774 self.write_keyword("PARTITION OF");
32776 self.write_space();
32777 self.generate_expression(&e.this)?;
32778 if let Expression::PartitionBoundSpec(_) = e.expression.as_ref() {
32780 self.write_space();
32781 self.write_keyword("FOR VALUES");
32782 self.write_space();
32783 self.generate_expression(&e.expression)?;
32784 } else {
32785 self.write_space();
32786 self.write_keyword("DEFAULT");
32787 }
32788 Ok(())
32789 }
32790
32791 fn generate_period_for_system_time_constraint(
32792 &mut self,
32793 e: &PeriodForSystemTimeConstraint,
32794 ) -> Result<()> {
32795 self.write_keyword("PERIOD FOR SYSTEM_TIME");
32797 self.write(" (");
32798 self.generate_expression(&e.this)?;
32799 self.write(", ");
32800 self.generate_expression(&e.expression)?;
32801 self.write(")");
32802 Ok(())
32803 }
32804
32805 fn generate_pivot_alias(&mut self, e: &PivotAlias) -> Result<()> {
32806 self.generate_expression(&e.this)?;
32809 self.write_space();
32810 self.write_keyword("AS");
32811 self.write_space();
32812 if self.config.unpivot_aliases_are_identifiers {
32814 match &e.alias {
32815 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
32816 let Literal::String(s) = lit.as_ref() else {
32817 unreachable!()
32818 };
32819 self.generate_identifier(&Identifier::new(s.clone()))?;
32821 }
32822 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
32823 let Literal::Number(n) = lit.as_ref() else {
32824 unreachable!()
32825 };
32826 let mut id = Identifier::new(n.clone());
32828 id.quoted = true;
32829 self.generate_identifier(&id)?;
32830 }
32831 other => {
32832 self.generate_expression(other)?;
32833 }
32834 }
32835 } else {
32836 self.generate_expression(&e.alias)?;
32837 }
32838 Ok(())
32839 }
32840
32841 fn generate_pivot_any(&mut self, e: &PivotAny) -> Result<()> {
32842 self.write_keyword("ANY");
32844 if let Some(this) = &e.this {
32845 self.write_space();
32846 self.generate_expression(this)?;
32847 }
32848 Ok(())
32849 }
32850
32851 fn generate_predict(&mut self, e: &Predict) -> Result<()> {
32852 self.write_keyword("ML.PREDICT");
32854 self.write("(");
32855 self.write_keyword("MODEL");
32856 self.write_space();
32857 self.generate_expression(&e.this)?;
32858 self.write(", ");
32859 self.generate_expression(&e.expression)?;
32860 if let Some(params) = &e.params_struct {
32861 self.write(", ");
32862 self.generate_expression(params)?;
32863 }
32864 self.write(")");
32865 Ok(())
32866 }
32867
32868 fn generate_previous_day(&mut self, e: &PreviousDay) -> Result<()> {
32869 self.write_keyword("PREVIOUS_DAY");
32871 self.write("(");
32872 self.generate_expression(&e.this)?;
32873 self.write(", ");
32874 self.generate_expression(&e.expression)?;
32875 self.write(")");
32876 Ok(())
32877 }
32878
32879 fn generate_primary_key(&mut self, e: &PrimaryKey) -> Result<()> {
32880 self.write_keyword("PRIMARY KEY");
32882 if let Some(name) = &e.this {
32883 self.write_space();
32884 self.generate_expression(name)?;
32885 }
32886 if !e.expressions.is_empty() {
32887 self.write(" (");
32888 for (i, expr) in e.expressions.iter().enumerate() {
32889 if i > 0 {
32890 self.write(", ");
32891 }
32892 self.generate_expression(expr)?;
32893 }
32894 self.write(")");
32895 }
32896 if let Some(include) = &e.include {
32897 self.write_space();
32898 self.generate_expression(include)?;
32899 }
32900 if !e.options.is_empty() {
32901 self.write_space();
32902 for (i, opt) in e.options.iter().enumerate() {
32903 if i > 0 {
32904 self.write_space();
32905 }
32906 self.generate_expression(opt)?;
32907 }
32908 }
32909 Ok(())
32910 }
32911
32912 fn generate_primary_key_column_constraint(
32913 &mut self,
32914 _e: &PrimaryKeyColumnConstraint,
32915 ) -> Result<()> {
32916 self.write_keyword("PRIMARY KEY");
32918 Ok(())
32919 }
32920
32921 fn generate_path_column_constraint(&mut self, e: &PathColumnConstraint) -> Result<()> {
32922 self.write_keyword("PATH");
32924 self.write_space();
32925 self.generate_expression(&e.this)?;
32926 Ok(())
32927 }
32928
32929 fn generate_projection_def(&mut self, e: &ProjectionDef) -> Result<()> {
32930 self.write_keyword("PROJECTION");
32932 self.write_space();
32933 self.generate_expression(&e.this)?;
32934 self.write(" (");
32935 self.generate_expression(&e.expression)?;
32936 self.write(")");
32937 Ok(())
32938 }
32939
32940 fn generate_properties(&mut self, e: &Properties) -> Result<()> {
32941 for (i, prop) in e.expressions.iter().enumerate() {
32943 if i > 0 {
32944 self.write(", ");
32945 }
32946 self.generate_expression(prop)?;
32947 }
32948 Ok(())
32949 }
32950
32951 fn generate_property(&mut self, e: &Property) -> Result<()> {
32952 self.generate_expression(&e.this)?;
32954 if let Some(value) = &e.value {
32955 self.write("=");
32956 self.generate_expression(value)?;
32957 }
32958 Ok(())
32959 }
32960
32961 fn generate_options_property(&mut self, e: &OptionsProperty) -> Result<()> {
32962 self.write_keyword("OPTIONS");
32963 if e.entries.is_empty() {
32964 self.write(" ()");
32965 return Ok(());
32966 }
32967
32968 if self.config.pretty {
32969 self.write(" (");
32970 self.write_newline();
32971 self.indent_level += 1;
32972 for (i, entry) in e.entries.iter().enumerate() {
32973 if i > 0 {
32974 self.write(",");
32975 self.write_newline();
32976 }
32977 self.write_indent();
32978 self.generate_identifier(&entry.key)?;
32979 self.write("=");
32980 self.generate_expression(&entry.value)?;
32981 }
32982 self.indent_level -= 1;
32983 self.write_newline();
32984 self.write(")");
32985 } else {
32986 self.write(" (");
32987 for (i, entry) in e.entries.iter().enumerate() {
32988 if i > 0 {
32989 self.write(", ");
32990 }
32991 self.generate_identifier(&entry.key)?;
32992 self.write("=");
32993 self.generate_expression(&entry.value)?;
32994 }
32995 self.write(")");
32996 }
32997 Ok(())
32998 }
32999
33000 fn generate_options_clause(&mut self, options: &[Expression]) -> Result<()> {
33002 self.write_keyword("OPTIONS");
33003 self.write(" (");
33004 for (i, opt) in options.iter().enumerate() {
33005 if i > 0 {
33006 self.write(", ");
33007 }
33008 self.generate_option_expression(opt)?;
33009 }
33010 self.write(")");
33011 Ok(())
33012 }
33013
33014 fn generate_properties_clause(&mut self, properties: &[Expression]) -> Result<()> {
33016 self.write_keyword("PROPERTIES");
33017 self.write(" (");
33018 for (i, prop) in properties.iter().enumerate() {
33019 if i > 0 {
33020 self.write(", ");
33021 }
33022 self.generate_option_expression(prop)?;
33023 }
33024 self.write(")");
33025 Ok(())
33026 }
33027
33028 fn generate_environment_clause(&mut self, environment: &[Expression]) -> Result<()> {
33030 self.write_keyword("ENVIRONMENT");
33031 self.write(" (");
33032 for (i, env_item) in environment.iter().enumerate() {
33033 if i > 0 {
33034 self.write(", ");
33035 }
33036 self.generate_environment_expression(env_item)?;
33037 }
33038 self.write(")");
33039 Ok(())
33040 }
33041
33042 fn generate_environment_expression(&mut self, expr: &Expression) -> Result<()> {
33044 match expr {
33045 Expression::Eq(eq) => {
33046 self.generate_expression(&eq.left)?;
33048 self.write(" = ");
33049 self.generate_expression(&eq.right)?;
33050 Ok(())
33051 }
33052 _ => self.generate_expression(expr),
33053 }
33054 }
33055
33056 fn generate_tblproperties_clause(&mut self, options: &[Expression]) -> Result<()> {
33058 self.write_keyword("TBLPROPERTIES");
33059 if self.config.pretty {
33060 self.write(" (");
33061 self.write_newline();
33062 self.indent_level += 1;
33063 for (i, opt) in options.iter().enumerate() {
33064 if i > 0 {
33065 self.write(",");
33066 self.write_newline();
33067 }
33068 self.write_indent();
33069 self.generate_option_expression(opt)?;
33070 }
33071 self.indent_level -= 1;
33072 self.write_newline();
33073 self.write(")");
33074 } else {
33075 self.write(" (");
33076 for (i, opt) in options.iter().enumerate() {
33077 if i > 0 {
33078 self.write(", ");
33079 }
33080 self.generate_option_expression(opt)?;
33081 }
33082 self.write(")");
33083 }
33084 Ok(())
33085 }
33086
33087 fn generate_option_expression(&mut self, expr: &Expression) -> Result<()> {
33089 match expr {
33090 Expression::Eq(eq) => {
33091 self.generate_expression(&eq.left)?;
33093 self.write("=");
33094 self.generate_expression(&eq.right)?;
33095 Ok(())
33096 }
33097 _ => self.generate_expression(expr),
33098 }
33099 }
33100
33101 fn generate_pseudo_type(&mut self, e: &PseudoType) -> Result<()> {
33102 self.generate_expression(&e.this)?;
33104 Ok(())
33105 }
33106
33107 fn generate_put(&mut self, e: &PutStmt) -> Result<()> {
33108 self.write_keyword("PUT");
33110 self.write_space();
33111
33112 if e.source_quoted {
33114 self.write("'");
33115 self.write(&e.source);
33116 self.write("'");
33117 } else {
33118 self.write(&e.source);
33119 }
33120
33121 self.write_space();
33122
33123 if let Expression::Literal(lit) = &e.target {
33125 if let Literal::String(s) = lit.as_ref() {
33126 self.write(s);
33127 }
33128 } else {
33129 self.generate_expression(&e.target)?;
33130 }
33131
33132 for param in &e.params {
33134 self.write_space();
33135 self.write(¶m.name);
33136 if let Some(ref value) = param.value {
33137 self.write("=");
33138 self.generate_expression(value)?;
33139 }
33140 }
33141
33142 Ok(())
33143 }
33144
33145 fn generate_quantile(&mut self, e: &Quantile) -> Result<()> {
33146 self.write_keyword("QUANTILE");
33148 self.write("(");
33149 self.generate_expression(&e.this)?;
33150 if let Some(quantile) = &e.quantile {
33151 self.write(", ");
33152 self.generate_expression(quantile)?;
33153 }
33154 self.write(")");
33155 Ok(())
33156 }
33157
33158 fn generate_query_band(&mut self, e: &QueryBand) -> Result<()> {
33159 if matches!(
33161 self.config.dialect,
33162 Some(crate::dialects::DialectType::Teradata)
33163 ) {
33164 self.write_keyword("SET");
33165 self.write_space();
33166 }
33167 self.write_keyword("QUERY_BAND");
33168 self.write(" = ");
33169 self.generate_expression(&e.this)?;
33170 if e.update.is_some() {
33171 self.write_space();
33172 self.write_keyword("UPDATE");
33173 }
33174 if let Some(scope) = &e.scope {
33175 self.write_space();
33176 self.write_keyword("FOR");
33177 self.write_space();
33178 self.generate_expression(scope)?;
33179 }
33180 Ok(())
33181 }
33182
33183 fn generate_query_option(&mut self, e: &QueryOption) -> Result<()> {
33184 self.generate_expression(&e.this)?;
33186 if let Some(expression) = &e.expression {
33187 self.write(" = ");
33188 self.generate_expression(expression)?;
33189 }
33190 Ok(())
33191 }
33192
33193 fn generate_query_transform(&mut self, e: &QueryTransform) -> Result<()> {
33194 self.write_keyword("TRANSFORM");
33196 self.write("(");
33197 for (i, expr) in e.expressions.iter().enumerate() {
33198 if i > 0 {
33199 self.write(", ");
33200 }
33201 self.generate_expression(expr)?;
33202 }
33203 self.write(")");
33204 if let Some(row_format_before) = &e.row_format_before {
33205 self.write_space();
33206 self.generate_expression(row_format_before)?;
33207 }
33208 if let Some(record_writer) = &e.record_writer {
33209 self.write_space();
33210 self.write_keyword("RECORDWRITER");
33211 self.write_space();
33212 self.generate_expression(record_writer)?;
33213 }
33214 if let Some(command_script) = &e.command_script {
33215 self.write_space();
33216 self.write_keyword("USING");
33217 self.write_space();
33218 self.generate_expression(command_script)?;
33219 }
33220 if let Some(schema) = &e.schema {
33221 self.write_space();
33222 self.write_keyword("AS");
33223 self.write_space();
33224 self.generate_expression(schema)?;
33225 }
33226 if let Some(row_format_after) = &e.row_format_after {
33227 self.write_space();
33228 self.generate_expression(row_format_after)?;
33229 }
33230 if let Some(record_reader) = &e.record_reader {
33231 self.write_space();
33232 self.write_keyword("RECORDREADER");
33233 self.write_space();
33234 self.generate_expression(record_reader)?;
33235 }
33236 Ok(())
33237 }
33238
33239 fn generate_randn(&mut self, e: &Randn) -> Result<()> {
33240 self.write_keyword("RANDN");
33242 self.write("(");
33243 if let Some(this) = &e.this {
33244 self.generate_expression(this)?;
33245 }
33246 self.write(")");
33247 Ok(())
33248 }
33249
33250 fn generate_randstr(&mut self, e: &Randstr) -> Result<()> {
33251 self.write_keyword("RANDSTR");
33253 self.write("(");
33254 self.generate_expression(&e.this)?;
33255 if let Some(generator) = &e.generator {
33256 self.write(", ");
33257 self.generate_expression(generator)?;
33258 }
33259 self.write(")");
33260 Ok(())
33261 }
33262
33263 fn generate_range_bucket(&mut self, e: &RangeBucket) -> Result<()> {
33264 self.write_keyword("RANGE_BUCKET");
33266 self.write("(");
33267 self.generate_expression(&e.this)?;
33268 self.write(", ");
33269 self.generate_expression(&e.expression)?;
33270 self.write(")");
33271 Ok(())
33272 }
33273
33274 fn generate_range_n(&mut self, e: &RangeN) -> Result<()> {
33275 self.write_keyword("RANGE_N");
33277 self.write("(");
33278 self.generate_expression(&e.this)?;
33279 self.write_space();
33280 self.write_keyword("BETWEEN");
33281 self.write_space();
33282 for (i, expr) in e.expressions.iter().enumerate() {
33283 if i > 0 {
33284 self.write(", ");
33285 }
33286 self.generate_expression(expr)?;
33287 }
33288 if let Some(each) = &e.each {
33289 self.write_space();
33290 self.write_keyword("EACH");
33291 self.write_space();
33292 self.generate_expression(each)?;
33293 }
33294 self.write(")");
33295 Ok(())
33296 }
33297
33298 fn generate_read_csv(&mut self, e: &ReadCSV) -> Result<()> {
33299 self.write_keyword("READ_CSV");
33301 self.write("(");
33302 self.generate_expression(&e.this)?;
33303 for expr in &e.expressions {
33304 self.write(", ");
33305 self.generate_expression(expr)?;
33306 }
33307 self.write(")");
33308 Ok(())
33309 }
33310
33311 fn generate_read_parquet(&mut self, e: &ReadParquet) -> Result<()> {
33312 self.write_keyword("READ_PARQUET");
33314 self.write("(");
33315 for (i, expr) in e.expressions.iter().enumerate() {
33316 if i > 0 {
33317 self.write(", ");
33318 }
33319 self.generate_expression(expr)?;
33320 }
33321 self.write(")");
33322 Ok(())
33323 }
33324
33325 fn generate_recursive_with_search(&mut self, e: &RecursiveWithSearch) -> Result<()> {
33326 if e.kind == "CYCLE" {
33329 self.write_keyword("CYCLE");
33330 } else {
33331 self.write_keyword("SEARCH");
33332 self.write_space();
33333 self.write(&e.kind);
33334 self.write_space();
33335 self.write_keyword("FIRST BY");
33336 }
33337 self.write_space();
33338 self.generate_expression(&e.this)?;
33339 self.write_space();
33340 self.write_keyword("SET");
33341 self.write_space();
33342 self.generate_expression(&e.expression)?;
33343 if let Some(using) = &e.using {
33344 self.write_space();
33345 self.write_keyword("USING");
33346 self.write_space();
33347 self.generate_expression(using)?;
33348 }
33349 Ok(())
33350 }
33351
33352 fn generate_reduce(&mut self, e: &Reduce) -> Result<()> {
33353 self.write_keyword("REDUCE");
33355 self.write("(");
33356 self.generate_expression(&e.this)?;
33357 if let Some(initial) = &e.initial {
33358 self.write(", ");
33359 self.generate_expression(initial)?;
33360 }
33361 if let Some(merge) = &e.merge {
33362 self.write(", ");
33363 self.generate_expression(merge)?;
33364 }
33365 if let Some(finish) = &e.finish {
33366 self.write(", ");
33367 self.generate_expression(finish)?;
33368 }
33369 self.write(")");
33370 Ok(())
33371 }
33372
33373 fn generate_reference(&mut self, e: &Reference) -> Result<()> {
33374 self.write_keyword("REFERENCES");
33376 self.write_space();
33377 self.generate_expression(&e.this)?;
33378 if !e.expressions.is_empty() {
33379 self.write(" (");
33380 for (i, expr) in e.expressions.iter().enumerate() {
33381 if i > 0 {
33382 self.write(", ");
33383 }
33384 self.generate_expression(expr)?;
33385 }
33386 self.write(")");
33387 }
33388 for opt in &e.options {
33389 self.write_space();
33390 self.generate_expression(opt)?;
33391 }
33392 Ok(())
33393 }
33394
33395 fn generate_refresh(&mut self, e: &Refresh) -> Result<()> {
33396 self.write_keyword("REFRESH");
33398 if !e.kind.is_empty() {
33399 self.write_space();
33400 self.write_keyword(&e.kind);
33401 }
33402 self.write_space();
33403 self.generate_expression(&e.this)?;
33404 Ok(())
33405 }
33406
33407 fn generate_refresh_trigger_property(&mut self, e: &RefreshTriggerProperty) -> Result<()> {
33408 self.write_keyword("REFRESH");
33410 self.write_space();
33411 self.write_keyword(&e.method);
33412
33413 if let Some(ref kind) = e.kind {
33414 self.write_space();
33415 self.write_keyword("ON");
33416 self.write_space();
33417 self.write_keyword(kind);
33418
33419 if let Some(ref every) = e.every {
33421 self.write_space();
33422 self.write_keyword("EVERY");
33423 self.write_space();
33424 self.generate_expression(every)?;
33425 if let Some(ref unit) = e.unit {
33426 self.write_space();
33427 self.write_keyword(unit);
33428 }
33429 }
33430
33431 if let Some(ref starts) = e.starts {
33433 self.write_space();
33434 self.write_keyword("STARTS");
33435 self.write_space();
33436 self.generate_expression(starts)?;
33437 }
33438 }
33439 Ok(())
33440 }
33441
33442 fn generate_regexp_count(&mut self, e: &RegexpCount) -> Result<()> {
33443 self.write_keyword("REGEXP_COUNT");
33445 self.write("(");
33446 self.generate_expression(&e.this)?;
33447 self.write(", ");
33448 self.generate_expression(&e.expression)?;
33449 if let Some(position) = &e.position {
33450 self.write(", ");
33451 self.generate_expression(position)?;
33452 }
33453 if let Some(parameters) = &e.parameters {
33454 self.write(", ");
33455 self.generate_expression(parameters)?;
33456 }
33457 self.write(")");
33458 Ok(())
33459 }
33460
33461 fn generate_regexp_extract_all(&mut self, e: &RegexpExtractAll) -> Result<()> {
33462 self.write_keyword("REGEXP_EXTRACT_ALL");
33464 self.write("(");
33465 self.generate_expression(&e.this)?;
33466 self.write(", ");
33467 self.generate_expression(&e.expression)?;
33468 if let Some(group) = &e.group {
33469 self.write(", ");
33470 self.generate_expression(group)?;
33471 }
33472 self.write(")");
33473 Ok(())
33474 }
33475
33476 fn generate_regexp_full_match(&mut self, e: &RegexpFullMatch) -> Result<()> {
33477 self.write_keyword("REGEXP_FULL_MATCH");
33479 self.write("(");
33480 self.generate_expression(&e.this)?;
33481 self.write(", ");
33482 self.generate_expression(&e.expression)?;
33483 self.write(")");
33484 Ok(())
33485 }
33486
33487 fn generate_regexp_i_like(&mut self, e: &RegexpILike) -> Result<()> {
33488 use crate::dialects::DialectType;
33489 if matches!(
33491 self.config.dialect,
33492 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
33493 ) && e.flag.is_none()
33494 {
33495 self.generate_expression(&e.this)?;
33496 self.write(" ~* ");
33497 self.generate_expression(&e.expression)?;
33498 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
33499 self.write_keyword("REGEXP_LIKE");
33501 self.write("(");
33502 self.generate_expression(&e.this)?;
33503 self.write(", ");
33504 self.generate_expression(&e.expression)?;
33505 self.write(", ");
33506 if let Some(flag) = &e.flag {
33507 self.generate_expression(flag)?;
33508 } else {
33509 self.write("'i'");
33510 }
33511 self.write(")");
33512 } else {
33513 self.generate_expression(&e.this)?;
33515 self.write_space();
33516 self.write_keyword("REGEXP_ILIKE");
33517 self.write_space();
33518 self.generate_expression(&e.expression)?;
33519 if let Some(flag) = &e.flag {
33520 self.write(", ");
33521 self.generate_expression(flag)?;
33522 }
33523 }
33524 Ok(())
33525 }
33526
33527 fn generate_regexp_instr(&mut self, e: &RegexpInstr) -> Result<()> {
33528 self.write_keyword("REGEXP_INSTR");
33530 self.write("(");
33531 self.generate_expression(&e.this)?;
33532 self.write(", ");
33533 self.generate_expression(&e.expression)?;
33534 if let Some(position) = &e.position {
33535 self.write(", ");
33536 self.generate_expression(position)?;
33537 }
33538 if let Some(occurrence) = &e.occurrence {
33539 self.write(", ");
33540 self.generate_expression(occurrence)?;
33541 }
33542 if let Some(option) = &e.option {
33543 self.write(", ");
33544 self.generate_expression(option)?;
33545 }
33546 if let Some(parameters) = &e.parameters {
33547 self.write(", ");
33548 self.generate_expression(parameters)?;
33549 }
33550 if let Some(group) = &e.group {
33551 self.write(", ");
33552 self.generate_expression(group)?;
33553 }
33554 self.write(")");
33555 Ok(())
33556 }
33557
33558 fn generate_regexp_split(&mut self, e: &RegexpSplit) -> Result<()> {
33559 self.write_keyword("REGEXP_SPLIT");
33561 self.write("(");
33562 self.generate_expression(&e.this)?;
33563 self.write(", ");
33564 self.generate_expression(&e.expression)?;
33565 if let Some(limit) = &e.limit {
33566 self.write(", ");
33567 self.generate_expression(limit)?;
33568 }
33569 self.write(")");
33570 Ok(())
33571 }
33572
33573 fn generate_regr_avgx(&mut self, e: &RegrAvgx) -> Result<()> {
33574 self.write_keyword("REGR_AVGX");
33576 self.write("(");
33577 self.generate_expression(&e.this)?;
33578 self.write(", ");
33579 self.generate_expression(&e.expression)?;
33580 self.write(")");
33581 Ok(())
33582 }
33583
33584 fn generate_regr_avgy(&mut self, e: &RegrAvgy) -> Result<()> {
33585 self.write_keyword("REGR_AVGY");
33587 self.write("(");
33588 self.generate_expression(&e.this)?;
33589 self.write(", ");
33590 self.generate_expression(&e.expression)?;
33591 self.write(")");
33592 Ok(())
33593 }
33594
33595 fn generate_regr_count(&mut self, e: &RegrCount) -> Result<()> {
33596 self.write_keyword("REGR_COUNT");
33598 self.write("(");
33599 self.generate_expression(&e.this)?;
33600 self.write(", ");
33601 self.generate_expression(&e.expression)?;
33602 self.write(")");
33603 Ok(())
33604 }
33605
33606 fn generate_regr_intercept(&mut self, e: &RegrIntercept) -> Result<()> {
33607 self.write_keyword("REGR_INTERCEPT");
33609 self.write("(");
33610 self.generate_expression(&e.this)?;
33611 self.write(", ");
33612 self.generate_expression(&e.expression)?;
33613 self.write(")");
33614 Ok(())
33615 }
33616
33617 fn generate_regr_r2(&mut self, e: &RegrR2) -> Result<()> {
33618 self.write_keyword("REGR_R2");
33620 self.write("(");
33621 self.generate_expression(&e.this)?;
33622 self.write(", ");
33623 self.generate_expression(&e.expression)?;
33624 self.write(")");
33625 Ok(())
33626 }
33627
33628 fn generate_regr_slope(&mut self, e: &RegrSlope) -> Result<()> {
33629 self.write_keyword("REGR_SLOPE");
33631 self.write("(");
33632 self.generate_expression(&e.this)?;
33633 self.write(", ");
33634 self.generate_expression(&e.expression)?;
33635 self.write(")");
33636 Ok(())
33637 }
33638
33639 fn generate_regr_sxx(&mut self, e: &RegrSxx) -> Result<()> {
33640 self.write_keyword("REGR_SXX");
33642 self.write("(");
33643 self.generate_expression(&e.this)?;
33644 self.write(", ");
33645 self.generate_expression(&e.expression)?;
33646 self.write(")");
33647 Ok(())
33648 }
33649
33650 fn generate_regr_sxy(&mut self, e: &RegrSxy) -> Result<()> {
33651 self.write_keyword("REGR_SXY");
33653 self.write("(");
33654 self.generate_expression(&e.this)?;
33655 self.write(", ");
33656 self.generate_expression(&e.expression)?;
33657 self.write(")");
33658 Ok(())
33659 }
33660
33661 fn generate_regr_syy(&mut self, e: &RegrSyy) -> Result<()> {
33662 self.write_keyword("REGR_SYY");
33664 self.write("(");
33665 self.generate_expression(&e.this)?;
33666 self.write(", ");
33667 self.generate_expression(&e.expression)?;
33668 self.write(")");
33669 Ok(())
33670 }
33671
33672 fn generate_regr_valx(&mut self, e: &RegrValx) -> Result<()> {
33673 self.write_keyword("REGR_VALX");
33675 self.write("(");
33676 self.generate_expression(&e.this)?;
33677 self.write(", ");
33678 self.generate_expression(&e.expression)?;
33679 self.write(")");
33680 Ok(())
33681 }
33682
33683 fn generate_regr_valy(&mut self, e: &RegrValy) -> Result<()> {
33684 self.write_keyword("REGR_VALY");
33686 self.write("(");
33687 self.generate_expression(&e.this)?;
33688 self.write(", ");
33689 self.generate_expression(&e.expression)?;
33690 self.write(")");
33691 Ok(())
33692 }
33693
33694 fn generate_remote_with_connection_model_property(
33695 &mut self,
33696 e: &RemoteWithConnectionModelProperty,
33697 ) -> Result<()> {
33698 self.write_keyword("REMOTE WITH CONNECTION");
33700 self.write_space();
33701 self.generate_expression(&e.this)?;
33702 Ok(())
33703 }
33704
33705 fn generate_rename_column(&mut self, e: &RenameColumn) -> Result<()> {
33706 self.write_keyword("RENAME COLUMN");
33708 if e.exists {
33709 self.write_space();
33710 self.write_keyword("IF EXISTS");
33711 }
33712 self.write_space();
33713 self.generate_expression(&e.this)?;
33714 if let Some(to) = &e.to {
33715 self.write_space();
33716 self.write_keyword("TO");
33717 self.write_space();
33718 self.generate_expression(to)?;
33719 }
33720 Ok(())
33721 }
33722
33723 fn generate_replace_partition(&mut self, e: &ReplacePartition) -> Result<()> {
33724 self.write_keyword("REPLACE PARTITION");
33726 self.write_space();
33727 self.generate_expression(&e.expression)?;
33728 if let Some(source) = &e.source {
33729 self.write_space();
33730 self.write_keyword("FROM");
33731 self.write_space();
33732 self.generate_expression(source)?;
33733 }
33734 Ok(())
33735 }
33736
33737 fn generate_returning(&mut self, e: &Returning) -> Result<()> {
33738 let keyword = match self.config.dialect {
33741 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "OUTPUT",
33742 _ => "RETURNING",
33743 };
33744 self.write_keyword(keyword);
33745 self.write_space();
33746 for (i, expr) in e.expressions.iter().enumerate() {
33747 if i > 0 {
33748 self.write(", ");
33749 }
33750 self.generate_expression(expr)?;
33751 }
33752 if let Some(into) = &e.into {
33753 self.write_space();
33754 self.write_keyword("INTO");
33755 self.write_space();
33756 self.generate_expression(into)?;
33757 }
33758 Ok(())
33759 }
33760
33761 fn generate_output_clause(&mut self, output: &OutputClause) -> Result<()> {
33762 self.write_space();
33764 self.write_keyword("OUTPUT");
33765 self.write_space();
33766 for (i, expr) in output.columns.iter().enumerate() {
33767 if i > 0 {
33768 self.write(", ");
33769 }
33770 self.generate_expression(expr)?;
33771 }
33772 if let Some(into_table) = &output.into_table {
33773 self.write_space();
33774 self.write_keyword("INTO");
33775 self.write_space();
33776 self.generate_expression(into_table)?;
33777 }
33778 Ok(())
33779 }
33780
33781 fn generate_returns_property(&mut self, e: &ReturnsProperty) -> Result<()> {
33782 self.write_keyword("RETURNS");
33784 if e.is_table.is_some() {
33785 self.write_space();
33786 self.write_keyword("TABLE");
33787 }
33788 if let Some(table) = &e.table {
33789 self.write_space();
33790 self.generate_expression(table)?;
33791 } else if let Some(this) = &e.this {
33792 self.write_space();
33793 self.generate_expression(this)?;
33794 }
33795 if e.null.is_some() {
33796 self.write_space();
33797 self.write_keyword("NULL ON NULL INPUT");
33798 }
33799 Ok(())
33800 }
33801
33802 fn generate_rollback(&mut self, e: &Rollback) -> Result<()> {
33803 self.write_keyword("ROLLBACK");
33805
33806 if e.this.is_none()
33808 && matches!(
33809 self.config.dialect,
33810 Some(DialectType::TSQL) | Some(DialectType::Fabric)
33811 )
33812 {
33813 self.write_space();
33814 self.write_keyword("TRANSACTION");
33815 }
33816
33817 if let Some(this) = &e.this {
33819 let is_transaction_marker = matches!(
33821 this.as_ref(),
33822 Expression::Identifier(id) if id.name == "TRANSACTION"
33823 );
33824
33825 self.write_space();
33826 self.write_keyword("TRANSACTION");
33827
33828 if !is_transaction_marker {
33830 self.write_space();
33831 self.generate_expression(this)?;
33832 }
33833 }
33834
33835 if let Some(savepoint) = &e.savepoint {
33837 self.write_space();
33838 self.write_keyword("TO");
33839 self.write_space();
33840 self.generate_expression(savepoint)?;
33841 }
33842 Ok(())
33843 }
33844
33845 fn generate_rollup(&mut self, e: &Rollup) -> Result<()> {
33846 if e.expressions.is_empty() {
33848 self.write_keyword("WITH ROLLUP");
33849 } else {
33850 self.write_keyword("ROLLUP");
33851 self.write("(");
33852 for (i, expr) in e.expressions.iter().enumerate() {
33853 if i > 0 {
33854 self.write(", ");
33855 }
33856 self.generate_expression(expr)?;
33857 }
33858 self.write(")");
33859 }
33860 Ok(())
33861 }
33862
33863 fn generate_row_format_delimited_property(
33864 &mut self,
33865 e: &RowFormatDelimitedProperty,
33866 ) -> Result<()> {
33867 self.write_keyword("ROW FORMAT DELIMITED");
33869 if let Some(fields) = &e.fields {
33870 self.write_space();
33871 self.write_keyword("FIELDS TERMINATED BY");
33872 self.write_space();
33873 self.generate_expression(fields)?;
33874 }
33875 if let Some(escaped) = &e.escaped {
33876 self.write_space();
33877 self.write_keyword("ESCAPED BY");
33878 self.write_space();
33879 self.generate_expression(escaped)?;
33880 }
33881 if let Some(items) = &e.collection_items {
33882 self.write_space();
33883 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
33884 self.write_space();
33885 self.generate_expression(items)?;
33886 }
33887 if let Some(keys) = &e.map_keys {
33888 self.write_space();
33889 self.write_keyword("MAP KEYS TERMINATED BY");
33890 self.write_space();
33891 self.generate_expression(keys)?;
33892 }
33893 if let Some(lines) = &e.lines {
33894 self.write_space();
33895 self.write_keyword("LINES TERMINATED BY");
33896 self.write_space();
33897 self.generate_expression(lines)?;
33898 }
33899 if let Some(null) = &e.null {
33900 self.write_space();
33901 self.write_keyword("NULL DEFINED AS");
33902 self.write_space();
33903 self.generate_expression(null)?;
33904 }
33905 if let Some(serde) = &e.serde {
33906 self.write_space();
33907 self.generate_expression(serde)?;
33908 }
33909 Ok(())
33910 }
33911
33912 fn generate_row_format_property(&mut self, e: &RowFormatProperty) -> Result<()> {
33913 self.write_keyword("ROW FORMAT");
33915 self.write_space();
33916 self.generate_expression(&e.this)?;
33917 Ok(())
33918 }
33919
33920 fn generate_row_format_serde_property(&mut self, e: &RowFormatSerdeProperty) -> Result<()> {
33921 self.write_keyword("ROW FORMAT SERDE");
33923 self.write_space();
33924 self.generate_expression(&e.this)?;
33925 if let Some(props) = &e.serde_properties {
33926 self.write_space();
33927 self.generate_expression(props)?;
33929 }
33930 Ok(())
33931 }
33932
33933 fn generate_sha2(&mut self, e: &SHA2) -> Result<()> {
33934 self.write_keyword("SHA2");
33936 self.write("(");
33937 self.generate_expression(&e.this)?;
33938 if let Some(length) = e.length {
33939 self.write(", ");
33940 self.write(&length.to_string());
33941 }
33942 self.write(")");
33943 Ok(())
33944 }
33945
33946 fn generate_sha2_digest(&mut self, e: &SHA2Digest) -> Result<()> {
33947 self.write_keyword("SHA2_DIGEST");
33949 self.write("(");
33950 self.generate_expression(&e.this)?;
33951 if let Some(length) = e.length {
33952 self.write(", ");
33953 self.write(&length.to_string());
33954 }
33955 self.write(")");
33956 Ok(())
33957 }
33958
33959 fn generate_safe_add(&mut self, e: &SafeAdd) -> Result<()> {
33960 let name = if matches!(
33961 self.config.dialect,
33962 Some(crate::dialects::DialectType::Spark)
33963 | Some(crate::dialects::DialectType::Databricks)
33964 ) {
33965 "TRY_ADD"
33966 } else {
33967 "SAFE_ADD"
33968 };
33969 self.write_keyword(name);
33970 self.write("(");
33971 self.generate_expression(&e.this)?;
33972 self.write(", ");
33973 self.generate_expression(&e.expression)?;
33974 self.write(")");
33975 Ok(())
33976 }
33977
33978 fn generate_safe_divide(&mut self, e: &SafeDivide) -> Result<()> {
33979 self.write_keyword("SAFE_DIVIDE");
33981 self.write("(");
33982 self.generate_expression(&e.this)?;
33983 self.write(", ");
33984 self.generate_expression(&e.expression)?;
33985 self.write(")");
33986 Ok(())
33987 }
33988
33989 fn generate_safe_multiply(&mut self, e: &SafeMultiply) -> Result<()> {
33990 let name = if matches!(
33991 self.config.dialect,
33992 Some(crate::dialects::DialectType::Spark)
33993 | Some(crate::dialects::DialectType::Databricks)
33994 ) {
33995 "TRY_MULTIPLY"
33996 } else {
33997 "SAFE_MULTIPLY"
33998 };
33999 self.write_keyword(name);
34000 self.write("(");
34001 self.generate_expression(&e.this)?;
34002 self.write(", ");
34003 self.generate_expression(&e.expression)?;
34004 self.write(")");
34005 Ok(())
34006 }
34007
34008 fn generate_safe_subtract(&mut self, e: &SafeSubtract) -> Result<()> {
34009 let name = if matches!(
34010 self.config.dialect,
34011 Some(crate::dialects::DialectType::Spark)
34012 | Some(crate::dialects::DialectType::Databricks)
34013 ) {
34014 "TRY_SUBTRACT"
34015 } else {
34016 "SAFE_SUBTRACT"
34017 };
34018 self.write_keyword(name);
34019 self.write("(");
34020 self.generate_expression(&e.this)?;
34021 self.write(", ");
34022 self.generate_expression(&e.expression)?;
34023 self.write(")");
34024 Ok(())
34025 }
34026
34027 fn generate_sample_body(&mut self, sample: &Sample) -> Result<()> {
34030 if matches!(sample.method, SampleMethod::Bucket) {
34032 self.write(" (");
34033 self.write_keyword("BUCKET");
34034 self.write_space();
34035 if let Some(ref num) = sample.bucket_numerator {
34036 self.generate_expression(num)?;
34037 }
34038 self.write_space();
34039 self.write_keyword("OUT OF");
34040 self.write_space();
34041 if let Some(ref denom) = sample.bucket_denominator {
34042 self.generate_expression(denom)?;
34043 }
34044 if let Some(ref field) = sample.bucket_field {
34045 self.write_space();
34046 self.write_keyword("ON");
34047 self.write_space();
34048 self.generate_expression(field)?;
34049 }
34050 self.write(")");
34051 return Ok(());
34052 }
34053
34054 let is_snowflake = matches!(
34056 self.config.dialect,
34057 Some(crate::dialects::DialectType::Snowflake)
34058 );
34059 let is_postgres = matches!(
34060 self.config.dialect,
34061 Some(crate::dialects::DialectType::PostgreSQL)
34062 | Some(crate::dialects::DialectType::Redshift)
34063 );
34064 let is_databricks = matches!(
34066 self.config.dialect,
34067 Some(crate::dialects::DialectType::Databricks)
34068 );
34069 let is_spark = matches!(
34070 self.config.dialect,
34071 Some(crate::dialects::DialectType::Spark)
34072 );
34073 let suppress_method = is_databricks || is_spark || sample.suppress_method_output;
34074 let force_method = is_postgres && matches!(sample.method, SampleMethod::Bernoulli);
34076 if !suppress_method && (sample.explicit_method || is_snowflake || force_method) {
34077 self.write_space();
34078 if !sample.explicit_method && (is_snowflake || force_method) {
34079 self.write_keyword("BERNOULLI");
34081 } else {
34082 match sample.method {
34083 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
34084 SampleMethod::System => self.write_keyword("SYSTEM"),
34085 SampleMethod::Block => self.write_keyword("BLOCK"),
34086 SampleMethod::Row => self.write_keyword("ROW"),
34087 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
34088 SampleMethod::Percent => self.write_keyword("SYSTEM"),
34089 SampleMethod::Bucket => {} }
34091 }
34092 }
34093
34094 let emit_size_no_parens = !self.config.tablesample_requires_parens;
34096 if emit_size_no_parens {
34097 self.write_space();
34098 match &sample.size {
34099 Expression::Tuple(tuple) => {
34100 for (i, expr) in tuple.expressions.iter().enumerate() {
34101 if i > 0 {
34102 self.write(", ");
34103 }
34104 self.generate_expression(expr)?;
34105 }
34106 }
34107 expr => self.generate_expression(expr)?,
34108 }
34109 } else {
34110 self.write(" (");
34111 self.generate_expression(&sample.size)?;
34112 }
34113
34114 let is_rows_method = matches!(
34116 sample.method,
34117 SampleMethod::Reservoir | SampleMethod::Row | SampleMethod::Bucket
34118 );
34119 let is_percent = matches!(
34120 sample.method,
34121 SampleMethod::Percent
34122 | SampleMethod::System
34123 | SampleMethod::Bernoulli
34124 | SampleMethod::Block
34125 );
34126
34127 let is_presto = matches!(
34131 self.config.dialect,
34132 Some(crate::dialects::DialectType::Presto)
34133 | Some(crate::dialects::DialectType::Trino)
34134 | Some(crate::dialects::DialectType::Athena)
34135 );
34136 let should_output_unit = if is_databricks || is_spark {
34137 is_percent || is_rows_method || sample.unit_after_size
34139 } else if is_snowflake || is_postgres || is_presto {
34140 sample.unit_after_size
34141 } else {
34142 sample.unit_after_size || (sample.explicit_method && (is_rows_method || is_percent))
34143 };
34144
34145 if should_output_unit {
34146 self.write_space();
34147 if sample.is_percent {
34148 self.write_keyword("PERCENT");
34149 } else if is_rows_method && !sample.unit_after_size {
34150 self.write_keyword("ROWS");
34151 } else if sample.unit_after_size {
34152 match sample.method {
34153 SampleMethod::Percent
34154 | SampleMethod::System
34155 | SampleMethod::Bernoulli
34156 | SampleMethod::Block => {
34157 self.write_keyword("PERCENT");
34158 }
34159 SampleMethod::Row | SampleMethod::Reservoir => {
34160 self.write_keyword("ROWS");
34161 }
34162 _ => self.write_keyword("ROWS"),
34163 }
34164 } else {
34165 self.write_keyword("PERCENT");
34166 }
34167 }
34168
34169 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
34170 if let Some(ref offset) = sample.offset {
34171 self.write_space();
34172 self.write_keyword("OFFSET");
34173 self.write_space();
34174 self.generate_expression(offset)?;
34175 }
34176 }
34177 if !emit_size_no_parens {
34178 self.write(")");
34179 }
34180
34181 Ok(())
34182 }
34183
34184 fn generate_sample_property(&mut self, e: &SampleProperty) -> Result<()> {
34185 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
34187 self.write_keyword("SAMPLE BY");
34188 } else {
34189 self.write_keyword("SAMPLE");
34190 }
34191 self.write_space();
34192 self.generate_expression(&e.this)?;
34193 Ok(())
34194 }
34195
34196 fn generate_schema(&mut self, e: &Schema) -> Result<()> {
34197 if let Some(this) = &e.this {
34199 self.generate_expression(this)?;
34200 }
34201 if !e.expressions.is_empty() {
34202 if e.this.is_some() {
34204 self.write_space();
34205 }
34206 self.write("(");
34207 for (i, expr) in e.expressions.iter().enumerate() {
34208 if i > 0 {
34209 self.write(", ");
34210 }
34211 self.generate_expression(expr)?;
34212 }
34213 self.write(")");
34214 }
34215 Ok(())
34216 }
34217
34218 fn generate_schema_comment_property(&mut self, e: &SchemaCommentProperty) -> Result<()> {
34219 self.write_keyword("COMMENT");
34221 self.write_space();
34222 self.generate_expression(&e.this)?;
34223 Ok(())
34224 }
34225
34226 fn generate_scope_resolution(&mut self, e: &ScopeResolution) -> Result<()> {
34227 if let Some(this) = &e.this {
34229 self.generate_expression(this)?;
34230 self.write("::");
34231 }
34232 self.generate_expression(&e.expression)?;
34233 Ok(())
34234 }
34235
34236 fn generate_search(&mut self, e: &Search) -> Result<()> {
34237 self.write_keyword("SEARCH");
34239 self.write("(");
34240 self.generate_expression(&e.this)?;
34241 self.write(", ");
34242 self.generate_expression(&e.expression)?;
34243 if let Some(json_scope) = &e.json_scope {
34244 self.write(", ");
34245 self.generate_expression(json_scope)?;
34246 }
34247 if let Some(analyzer) = &e.analyzer {
34248 self.write(", ");
34249 self.generate_expression(analyzer)?;
34250 }
34251 if let Some(analyzer_options) = &e.analyzer_options {
34252 self.write(", ");
34253 self.generate_expression(analyzer_options)?;
34254 }
34255 if let Some(search_mode) = &e.search_mode {
34256 self.write(", ");
34257 self.generate_expression(search_mode)?;
34258 }
34259 self.write(")");
34260 Ok(())
34261 }
34262
34263 fn generate_search_ip(&mut self, e: &SearchIp) -> Result<()> {
34264 self.write_keyword("SEARCH_IP");
34266 self.write("(");
34267 self.generate_expression(&e.this)?;
34268 self.write(", ");
34269 self.generate_expression(&e.expression)?;
34270 self.write(")");
34271 Ok(())
34272 }
34273
34274 fn generate_security_property(&mut self, e: &SecurityProperty) -> Result<()> {
34275 self.write_keyword("SECURITY");
34277 self.write_space();
34278 self.generate_expression(&e.this)?;
34279 Ok(())
34280 }
34281
34282 fn generate_semantic_view(&mut self, e: &SemanticView) -> Result<()> {
34283 self.write("SEMANTIC_VIEW(");
34285
34286 if self.config.pretty {
34287 self.write_newline();
34289 self.indent_level += 1;
34290 self.write_indent();
34291 self.generate_expression(&e.this)?;
34292
34293 if let Some(metrics) = &e.metrics {
34294 self.write_newline();
34295 self.write_indent();
34296 self.write_keyword("METRICS");
34297 self.write_space();
34298 self.generate_semantic_view_tuple(metrics)?;
34299 }
34300 if let Some(dimensions) = &e.dimensions {
34301 self.write_newline();
34302 self.write_indent();
34303 self.write_keyword("DIMENSIONS");
34304 self.write_space();
34305 self.generate_semantic_view_tuple(dimensions)?;
34306 }
34307 if let Some(facts) = &e.facts {
34308 self.write_newline();
34309 self.write_indent();
34310 self.write_keyword("FACTS");
34311 self.write_space();
34312 self.generate_semantic_view_tuple(facts)?;
34313 }
34314 if let Some(where_) = &e.where_ {
34315 self.write_newline();
34316 self.write_indent();
34317 self.write_keyword("WHERE");
34318 self.write_space();
34319 self.generate_expression(where_)?;
34320 }
34321 self.write_newline();
34322 self.indent_level -= 1;
34323 self.write_indent();
34324 } else {
34325 self.generate_expression(&e.this)?;
34327 if let Some(metrics) = &e.metrics {
34328 self.write_space();
34329 self.write_keyword("METRICS");
34330 self.write_space();
34331 self.generate_semantic_view_tuple(metrics)?;
34332 }
34333 if let Some(dimensions) = &e.dimensions {
34334 self.write_space();
34335 self.write_keyword("DIMENSIONS");
34336 self.write_space();
34337 self.generate_semantic_view_tuple(dimensions)?;
34338 }
34339 if let Some(facts) = &e.facts {
34340 self.write_space();
34341 self.write_keyword("FACTS");
34342 self.write_space();
34343 self.generate_semantic_view_tuple(facts)?;
34344 }
34345 if let Some(where_) = &e.where_ {
34346 self.write_space();
34347 self.write_keyword("WHERE");
34348 self.write_space();
34349 self.generate_expression(where_)?;
34350 }
34351 }
34352 self.write(")");
34353 Ok(())
34354 }
34355
34356 fn generate_semantic_view_tuple(&mut self, expr: &Expression) -> Result<()> {
34358 if let Expression::Tuple(t) = expr {
34359 for (i, e) in t.expressions.iter().enumerate() {
34360 if i > 0 {
34361 self.write(", ");
34362 }
34363 self.generate_expression(e)?;
34364 }
34365 } else {
34366 self.generate_expression(expr)?;
34367 }
34368 Ok(())
34369 }
34370
34371 fn generate_sequence_properties(&mut self, e: &SequenceProperties) -> Result<()> {
34372 if let Some(start) = &e.start {
34374 self.write_keyword("START WITH");
34375 self.write_space();
34376 self.generate_expression(start)?;
34377 }
34378 if let Some(increment) = &e.increment {
34379 self.write_space();
34380 self.write_keyword("INCREMENT BY");
34381 self.write_space();
34382 self.generate_expression(increment)?;
34383 }
34384 if let Some(minvalue) = &e.minvalue {
34385 self.write_space();
34386 self.write_keyword("MINVALUE");
34387 self.write_space();
34388 self.generate_expression(minvalue)?;
34389 }
34390 if let Some(maxvalue) = &e.maxvalue {
34391 self.write_space();
34392 self.write_keyword("MAXVALUE");
34393 self.write_space();
34394 self.generate_expression(maxvalue)?;
34395 }
34396 if let Some(cache) = &e.cache {
34397 self.write_space();
34398 self.write_keyword("CACHE");
34399 self.write_space();
34400 self.generate_expression(cache)?;
34401 }
34402 if let Some(owned) = &e.owned {
34403 self.write_space();
34404 self.write_keyword("OWNED BY");
34405 self.write_space();
34406 self.generate_expression(owned)?;
34407 }
34408 for opt in &e.options {
34409 self.write_space();
34410 self.generate_expression(opt)?;
34411 }
34412 Ok(())
34413 }
34414
34415 fn generate_serde_properties(&mut self, e: &SerdeProperties) -> Result<()> {
34416 if e.with_.is_some() {
34418 self.write_keyword("WITH");
34419 self.write_space();
34420 }
34421 self.write_keyword("SERDEPROPERTIES");
34422 self.write(" (");
34423 for (i, expr) in e.expressions.iter().enumerate() {
34424 if i > 0 {
34425 self.write(", ");
34426 }
34427 match expr {
34429 Expression::Eq(eq) => {
34430 self.generate_expression(&eq.left)?;
34431 self.write("=");
34432 self.generate_expression(&eq.right)?;
34433 }
34434 _ => self.generate_expression(expr)?,
34435 }
34436 }
34437 self.write(")");
34438 Ok(())
34439 }
34440
34441 fn generate_session_parameter(&mut self, e: &SessionParameter) -> Result<()> {
34442 self.write("@@");
34444 if let Some(kind) = &e.kind {
34445 self.write(kind);
34446 self.write(".");
34447 }
34448 self.generate_expression(&e.this)?;
34449 Ok(())
34450 }
34451
34452 fn generate_set(&mut self, e: &Set) -> Result<()> {
34453 if e.unset.is_some() {
34455 self.write_keyword("UNSET");
34456 } else {
34457 self.write_keyword("SET");
34458 }
34459 if e.tag.is_some() {
34460 self.write_space();
34461 self.write_keyword("TAG");
34462 }
34463 if !e.expressions.is_empty() {
34464 self.write_space();
34465 for (i, expr) in e.expressions.iter().enumerate() {
34466 if i > 0 {
34467 self.write(", ");
34468 }
34469 self.generate_expression(expr)?;
34470 }
34471 }
34472 Ok(())
34473 }
34474
34475 fn generate_set_config_property(&mut self, e: &SetConfigProperty) -> Result<()> {
34476 self.write_keyword("SET");
34478 self.write_space();
34479 self.generate_expression(&e.this)?;
34480 Ok(())
34481 }
34482
34483 fn generate_set_item(&mut self, e: &SetItem) -> Result<()> {
34484 if let Some(kind) = &e.kind {
34486 self.write_keyword(kind);
34487 self.write_space();
34488 }
34489 self.generate_expression(&e.name)?;
34490 self.write(" = ");
34491 self.generate_expression(&e.value)?;
34492 Ok(())
34493 }
34494
34495 fn generate_set_operation(&mut self, e: &SetOperation) -> Result<()> {
34496 if let Some(with_) = &e.with_ {
34498 self.generate_expression(with_)?;
34499 self.write_space();
34500 }
34501 self.generate_expression(&e.this)?;
34502 self.write_space();
34503 if let Some(kind) = &e.kind {
34505 self.write_keyword(kind);
34506 }
34507 if e.distinct {
34508 self.write_space();
34509 self.write_keyword("DISTINCT");
34510 } else {
34511 self.write_space();
34512 self.write_keyword("ALL");
34513 }
34514 if e.by_name.is_some() {
34515 self.write_space();
34516 self.write_keyword("BY NAME");
34517 }
34518 self.write_space();
34519 self.generate_expression(&e.expression)?;
34520 Ok(())
34521 }
34522
34523 fn generate_set_property(&mut self, e: &SetProperty) -> Result<()> {
34524 if e.multi.is_some() {
34526 self.write_keyword("MULTISET");
34527 } else {
34528 self.write_keyword("SET");
34529 }
34530 Ok(())
34531 }
34532
34533 fn generate_settings_property(&mut self, e: &SettingsProperty) -> Result<()> {
34534 self.write_keyword("SETTINGS");
34536 if self.config.pretty && e.expressions.len() > 1 {
34537 self.indent_level += 1;
34539 for (i, expr) in e.expressions.iter().enumerate() {
34540 if i > 0 {
34541 self.write(",");
34542 }
34543 self.write_newline();
34544 self.write_indent();
34545 self.generate_expression(expr)?;
34546 }
34547 self.indent_level -= 1;
34548 } else {
34549 self.write_space();
34550 for (i, expr) in e.expressions.iter().enumerate() {
34551 if i > 0 {
34552 self.write(", ");
34553 }
34554 self.generate_expression(expr)?;
34555 }
34556 }
34557 Ok(())
34558 }
34559
34560 fn generate_sharing_property(&mut self, e: &SharingProperty) -> Result<()> {
34561 self.write_keyword("SHARING");
34563 if let Some(this) = &e.this {
34564 self.write(" = ");
34565 self.generate_expression(this)?;
34566 }
34567 Ok(())
34568 }
34569
34570 fn generate_slice(&mut self, e: &Slice) -> Result<()> {
34571 if let Some(begin) = &e.this {
34573 self.generate_expression(begin)?;
34574 }
34575 self.write(":");
34576 if let Some(end) = &e.expression {
34577 self.generate_expression(end)?;
34578 }
34579 if let Some(step) = &e.step {
34580 self.write(":");
34581 self.generate_expression(step)?;
34582 }
34583 Ok(())
34584 }
34585
34586 fn generate_sort_array(&mut self, e: &SortArray) -> Result<()> {
34587 self.write_keyword("SORT_ARRAY");
34589 self.write("(");
34590 self.generate_expression(&e.this)?;
34591 if let Some(asc) = &e.asc {
34592 self.write(", ");
34593 self.generate_expression(asc)?;
34594 }
34595 self.write(")");
34596 Ok(())
34597 }
34598
34599 fn generate_sort_by(&mut self, e: &SortBy) -> Result<()> {
34600 self.write_keyword("SORT BY");
34602 self.write_space();
34603 for (i, expr) in e.expressions.iter().enumerate() {
34604 if i > 0 {
34605 self.write(", ");
34606 }
34607 self.generate_ordered(expr)?;
34608 }
34609 Ok(())
34610 }
34611
34612 fn generate_sort_key_property(&mut self, e: &SortKeyProperty) -> Result<()> {
34613 if e.compound.is_some() {
34615 self.write_keyword("COMPOUND");
34616 self.write_space();
34617 }
34618 self.write_keyword("SORTKEY");
34619 self.write("(");
34620 if let Expression::Tuple(t) = e.this.as_ref() {
34622 for (i, expr) in t.expressions.iter().enumerate() {
34623 if i > 0 {
34624 self.write(", ");
34625 }
34626 self.generate_expression(expr)?;
34627 }
34628 } else {
34629 self.generate_expression(&e.this)?;
34630 }
34631 self.write(")");
34632 Ok(())
34633 }
34634
34635 fn generate_split_part(&mut self, e: &SplitPart) -> Result<()> {
34636 self.write_keyword("SPLIT_PART");
34638 self.write("(");
34639 self.generate_expression(&e.this)?;
34640 if let Some(delimiter) = &e.delimiter {
34641 self.write(", ");
34642 self.generate_expression(delimiter)?;
34643 }
34644 if let Some(part_index) = &e.part_index {
34645 self.write(", ");
34646 self.generate_expression(part_index)?;
34647 }
34648 self.write(")");
34649 Ok(())
34650 }
34651
34652 fn generate_sql_read_write_property(&mut self, e: &SqlReadWriteProperty) -> Result<()> {
34653 self.generate_expression(&e.this)?;
34655 Ok(())
34656 }
34657
34658 fn generate_sql_security_property(&mut self, e: &SqlSecurityProperty) -> Result<()> {
34659 self.write_keyword("SQL SECURITY");
34661 self.write_space();
34662 self.generate_expression(&e.this)?;
34663 Ok(())
34664 }
34665
34666 fn generate_st_distance(&mut self, e: &StDistance) -> Result<()> {
34667 self.write_keyword("ST_DISTANCE");
34669 self.write("(");
34670 self.generate_expression(&e.this)?;
34671 self.write(", ");
34672 self.generate_expression(&e.expression)?;
34673 if let Some(use_spheroid) = &e.use_spheroid {
34674 self.write(", ");
34675 self.generate_expression(use_spheroid)?;
34676 }
34677 self.write(")");
34678 Ok(())
34679 }
34680
34681 fn generate_st_point(&mut self, e: &StPoint) -> Result<()> {
34682 self.write_keyword("ST_POINT");
34684 self.write("(");
34685 self.generate_expression(&e.this)?;
34686 self.write(", ");
34687 self.generate_expression(&e.expression)?;
34688 self.write(")");
34689 Ok(())
34690 }
34691
34692 fn generate_stability_property(&mut self, e: &StabilityProperty) -> Result<()> {
34693 self.generate_expression(&e.this)?;
34695 Ok(())
34696 }
34697
34698 fn generate_standard_hash(&mut self, e: &StandardHash) -> Result<()> {
34699 self.write_keyword("STANDARD_HASH");
34701 self.write("(");
34702 self.generate_expression(&e.this)?;
34703 if let Some(expression) = &e.expression {
34704 self.write(", ");
34705 self.generate_expression(expression)?;
34706 }
34707 self.write(")");
34708 Ok(())
34709 }
34710
34711 fn generate_storage_handler_property(&mut self, e: &StorageHandlerProperty) -> Result<()> {
34712 self.write_keyword("STORED BY");
34714 self.write_space();
34715 self.generate_expression(&e.this)?;
34716 Ok(())
34717 }
34718
34719 fn generate_str_position(&mut self, e: &StrPosition) -> Result<()> {
34720 use crate::dialects::DialectType;
34723 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
34724 self.write_keyword("CHARINDEX");
34726 self.write("(");
34727 if let Some(substr) = &e.substr {
34728 self.generate_expression(substr)?;
34729 self.write(", ");
34730 }
34731 self.generate_expression(&e.this)?;
34732 if let Some(position) = &e.position {
34733 self.write(", ");
34734 self.generate_expression(position)?;
34735 }
34736 self.write(")");
34737 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
34738 self.write_keyword("POSITION");
34739 self.write("(");
34740 self.generate_expression(&e.this)?;
34741 if let Some(substr) = &e.substr {
34742 self.write(", ");
34743 self.generate_expression(substr)?;
34744 }
34745 if let Some(position) = &e.position {
34746 self.write(", ");
34747 self.generate_expression(position)?;
34748 }
34749 if let Some(occurrence) = &e.occurrence {
34750 self.write(", ");
34751 self.generate_expression(occurrence)?;
34752 }
34753 self.write(")");
34754 } else if matches!(
34755 self.config.dialect,
34756 Some(DialectType::SQLite)
34757 | Some(DialectType::Oracle)
34758 | Some(DialectType::BigQuery)
34759 | Some(DialectType::Teradata)
34760 ) {
34761 self.write_keyword("INSTR");
34762 self.write("(");
34763 self.generate_expression(&e.this)?;
34764 if let Some(substr) = &e.substr {
34765 self.write(", ");
34766 self.generate_expression(substr)?;
34767 }
34768 if let Some(position) = &e.position {
34769 self.write(", ");
34770 self.generate_expression(position)?;
34771 } else if e.occurrence.is_some() {
34772 self.write(", 1");
34775 }
34776 if let Some(occurrence) = &e.occurrence {
34777 self.write(", ");
34778 self.generate_expression(occurrence)?;
34779 }
34780 self.write(")");
34781 } else if matches!(
34782 self.config.dialect,
34783 Some(DialectType::MySQL)
34784 | Some(DialectType::SingleStore)
34785 | Some(DialectType::Doris)
34786 | Some(DialectType::StarRocks)
34787 | Some(DialectType::Hive)
34788 | Some(DialectType::Spark)
34789 | Some(DialectType::Databricks)
34790 ) {
34791 self.write_keyword("LOCATE");
34793 self.write("(");
34794 if let Some(substr) = &e.substr {
34795 self.generate_expression(substr)?;
34796 self.write(", ");
34797 }
34798 self.generate_expression(&e.this)?;
34799 if let Some(position) = &e.position {
34800 self.write(", ");
34801 self.generate_expression(position)?;
34802 }
34803 self.write(")");
34804 } else if matches!(self.config.dialect, Some(DialectType::TSQL)) {
34805 self.write_keyword("CHARINDEX");
34807 self.write("(");
34808 if let Some(substr) = &e.substr {
34809 self.generate_expression(substr)?;
34810 self.write(", ");
34811 }
34812 self.generate_expression(&e.this)?;
34813 if let Some(position) = &e.position {
34814 self.write(", ");
34815 self.generate_expression(position)?;
34816 }
34817 self.write(")");
34818 } else if matches!(
34819 self.config.dialect,
34820 Some(DialectType::PostgreSQL)
34821 | Some(DialectType::Materialize)
34822 | Some(DialectType::RisingWave)
34823 | Some(DialectType::Redshift)
34824 ) {
34825 self.write_keyword("POSITION");
34827 self.write("(");
34828 if let Some(substr) = &e.substr {
34829 self.generate_expression(substr)?;
34830 self.write(" IN ");
34831 }
34832 self.generate_expression(&e.this)?;
34833 self.write(")");
34834 } else {
34835 self.write_keyword("STRPOS");
34836 self.write("(");
34837 self.generate_expression(&e.this)?;
34838 if let Some(substr) = &e.substr {
34839 self.write(", ");
34840 self.generate_expression(substr)?;
34841 }
34842 if let Some(position) = &e.position {
34843 self.write(", ");
34844 self.generate_expression(position)?;
34845 }
34846 if let Some(occurrence) = &e.occurrence {
34847 self.write(", ");
34848 self.generate_expression(occurrence)?;
34849 }
34850 self.write(")");
34851 }
34852 Ok(())
34853 }
34854
34855 fn generate_str_to_date(&mut self, e: &StrToDate) -> Result<()> {
34856 match self.config.dialect {
34857 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
34858 self.write_keyword("TO_DATE");
34860 self.write("(");
34861 self.generate_expression(&e.this)?;
34862 if let Some(format) = &e.format {
34863 self.write(", '");
34864 self.write(&Self::strftime_to_java_format(format));
34865 self.write("'");
34866 }
34867 self.write(")");
34868 }
34869 Some(DialectType::DuckDB) => {
34870 self.write_keyword("CAST");
34872 self.write("(");
34873 self.write_keyword("STRPTIME");
34874 self.write("(");
34875 self.generate_expression(&e.this)?;
34876 if let Some(format) = &e.format {
34877 self.write(", '");
34878 self.write(format);
34879 self.write("'");
34880 }
34881 self.write(")");
34882 self.write_keyword(" AS ");
34883 self.write_keyword("DATE");
34884 self.write(")");
34885 }
34886 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
34887 self.write_keyword("TO_DATE");
34889 self.write("(");
34890 self.generate_expression(&e.this)?;
34891 if let Some(format) = &e.format {
34892 self.write(", '");
34893 self.write(&Self::strftime_to_postgres_format(format));
34894 self.write("'");
34895 }
34896 self.write(")");
34897 }
34898 Some(DialectType::BigQuery) => {
34899 self.write_keyword("PARSE_DATE");
34901 self.write("(");
34902 if let Some(format) = &e.format {
34903 self.write("'");
34904 self.write(format);
34905 self.write("'");
34906 self.write(", ");
34907 }
34908 self.generate_expression(&e.this)?;
34909 self.write(")");
34910 }
34911 Some(DialectType::Teradata) => {
34912 self.write_keyword("CAST");
34914 self.write("(");
34915 self.generate_expression(&e.this)?;
34916 self.write_keyword(" AS ");
34917 self.write_keyword("DATE");
34918 if let Some(format) = &e.format {
34919 self.write_keyword(" FORMAT ");
34920 self.write("'");
34921 self.write(&Self::strftime_to_teradata_format(format));
34922 self.write("'");
34923 }
34924 self.write(")");
34925 }
34926 _ => {
34927 self.write_keyword("STR_TO_DATE");
34929 self.write("(");
34930 self.generate_expression(&e.this)?;
34931 if let Some(format) = &e.format {
34932 self.write(", '");
34933 self.write(format);
34934 self.write("'");
34935 }
34936 self.write(")");
34937 }
34938 }
34939 Ok(())
34940 }
34941
34942 fn strftime_to_teradata_format(fmt: &str) -> String {
34944 let mut result = String::with_capacity(fmt.len() * 2);
34945 let bytes = fmt.as_bytes();
34946 let len = bytes.len();
34947 let mut i = 0;
34948 while i < len {
34949 if bytes[i] == b'%' && i + 1 < len {
34950 let replacement = match bytes[i + 1] {
34951 b'Y' => "YYYY",
34952 b'y' => "YY",
34953 b'm' => "MM",
34954 b'B' => "MMMM",
34955 b'b' => "MMM",
34956 b'd' => "DD",
34957 b'j' => "DDD",
34958 b'H' => "HH",
34959 b'M' => "MI",
34960 b'S' => "SS",
34961 b'f' => "SSSSSS",
34962 b'A' => "EEEE",
34963 b'a' => "EEE",
34964 _ => {
34965 result.push('%');
34966 i += 1;
34967 continue;
34968 }
34969 };
34970 result.push_str(replacement);
34971 i += 2;
34972 } else {
34973 result.push(bytes[i] as char);
34974 i += 1;
34975 }
34976 }
34977 result
34978 }
34979
34980 pub fn strftime_to_java_format_static(fmt: &str) -> String {
34983 Self::strftime_to_java_format(fmt)
34984 }
34985
34986 fn strftime_to_java_format(fmt: &str) -> String {
34988 let mut result = String::with_capacity(fmt.len() * 2);
34989 let bytes = fmt.as_bytes();
34990 let len = bytes.len();
34991 let mut i = 0;
34992 while i < len {
34993 if bytes[i] == b'%' && i + 1 < len {
34994 if bytes[i + 1] == b'-' && i + 2 < len {
34996 let replacement = match bytes[i + 2] {
34997 b'd' => "d",
34998 b'm' => "M",
34999 b'H' => "H",
35000 b'M' => "m",
35001 b'S' => "s",
35002 _ => {
35003 result.push('%');
35004 i += 1;
35005 continue;
35006 }
35007 };
35008 result.push_str(replacement);
35009 i += 3;
35010 } else {
35011 let replacement = match bytes[i + 1] {
35012 b'Y' => "yyyy",
35013 b'y' => "yy",
35014 b'm' => "MM",
35015 b'B' => "MMMM",
35016 b'b' => "MMM",
35017 b'd' => "dd",
35018 b'j' => "DDD",
35019 b'H' => "HH",
35020 b'M' => "mm",
35021 b'S' => "ss",
35022 b'f' => "SSSSSS",
35023 b'A' => "EEEE",
35024 b'a' => "EEE",
35025 _ => {
35026 result.push('%');
35027 i += 1;
35028 continue;
35029 }
35030 };
35031 result.push_str(replacement);
35032 i += 2;
35033 }
35034 } else {
35035 result.push(bytes[i] as char);
35036 i += 1;
35037 }
35038 }
35039 result
35040 }
35041
35042 fn strftime_to_tsql_format(fmt: &str) -> String {
35045 let mut result = String::with_capacity(fmt.len() * 2);
35046 let bytes = fmt.as_bytes();
35047 let len = bytes.len();
35048 let mut i = 0;
35049 while i < len {
35050 if bytes[i] == b'%' && i + 1 < len {
35051 if bytes[i + 1] == b'-' && i + 2 < len {
35053 let replacement = match bytes[i + 2] {
35054 b'd' => "d",
35055 b'm' => "M",
35056 b'H' => "H",
35057 b'M' => "m",
35058 b'S' => "s",
35059 _ => {
35060 result.push('%');
35061 i += 1;
35062 continue;
35063 }
35064 };
35065 result.push_str(replacement);
35066 i += 3;
35067 } else {
35068 let replacement = match bytes[i + 1] {
35069 b'Y' => "yyyy",
35070 b'y' => "yy",
35071 b'm' => "MM",
35072 b'B' => "MMMM",
35073 b'b' => "MMM",
35074 b'd' => "dd",
35075 b'j' => "DDD",
35076 b'H' => "HH",
35077 b'M' => "mm",
35078 b'S' => "ss",
35079 b'f' => "ffffff",
35080 b'A' => "dddd",
35081 b'a' => "ddd",
35082 _ => {
35083 result.push('%');
35084 i += 1;
35085 continue;
35086 }
35087 };
35088 result.push_str(replacement);
35089 i += 2;
35090 }
35091 } else {
35092 result.push(bytes[i] as char);
35093 i += 1;
35094 }
35095 }
35096 result
35097 }
35098
35099 fn decompose_json_path(path: &str) -> Vec<String> {
35102 let mut parts = Vec::new();
35103 let path = if path.starts_with("$.") {
35105 &path[2..]
35106 } else if path.starts_with('$') {
35107 &path[1..]
35108 } else {
35109 path
35110 };
35111 if path.is_empty() {
35112 return parts;
35113 }
35114 let mut current = String::new();
35115 let chars: Vec<char> = path.chars().collect();
35116 let mut i = 0;
35117 while i < chars.len() {
35118 match chars[i] {
35119 '.' => {
35120 if !current.is_empty() {
35121 parts.push(current.clone());
35122 current.clear();
35123 }
35124 i += 1;
35125 }
35126 '[' => {
35127 if !current.is_empty() {
35128 parts.push(current.clone());
35129 current.clear();
35130 }
35131 i += 1;
35132 let mut bracket_content = String::new();
35134 while i < chars.len() && chars[i] != ']' {
35135 if chars[i] == '"' || chars[i] == '\'' {
35137 let quote = chars[i];
35138 i += 1;
35139 while i < chars.len() && chars[i] != quote {
35140 bracket_content.push(chars[i]);
35141 i += 1;
35142 }
35143 if i < chars.len() {
35144 i += 1;
35145 } } else {
35147 bracket_content.push(chars[i]);
35148 i += 1;
35149 }
35150 }
35151 if i < chars.len() {
35152 i += 1;
35153 } if bracket_content != "*" {
35156 parts.push(bracket_content);
35157 }
35158 }
35159 _ => {
35160 current.push(chars[i]);
35161 i += 1;
35162 }
35163 }
35164 }
35165 if !current.is_empty() {
35166 parts.push(current);
35167 }
35168 parts
35169 }
35170
35171 fn strftime_to_postgres_format(fmt: &str) -> String {
35173 let mut result = String::with_capacity(fmt.len() * 2);
35174 let bytes = fmt.as_bytes();
35175 let len = bytes.len();
35176 let mut i = 0;
35177 while i < len {
35178 if bytes[i] == b'%' && i + 1 < len {
35179 if bytes[i + 1] == b'-' && i + 2 < len {
35181 let replacement = match bytes[i + 2] {
35182 b'd' => "FMDD",
35183 b'm' => "FMMM",
35184 b'H' => "FMHH24",
35185 b'M' => "FMMI",
35186 b'S' => "FMSS",
35187 _ => {
35188 result.push('%');
35189 i += 1;
35190 continue;
35191 }
35192 };
35193 result.push_str(replacement);
35194 i += 3;
35195 } else {
35196 let replacement = match bytes[i + 1] {
35197 b'Y' => "YYYY",
35198 b'y' => "YY",
35199 b'm' => "MM",
35200 b'B' => "Month",
35201 b'b' => "Mon",
35202 b'd' => "DD",
35203 b'j' => "DDD",
35204 b'H' => "HH24",
35205 b'M' => "MI",
35206 b'S' => "SS",
35207 b'f' => "US",
35208 b'A' => "Day",
35209 b'a' => "Dy",
35210 _ => {
35211 result.push('%');
35212 i += 1;
35213 continue;
35214 }
35215 };
35216 result.push_str(replacement);
35217 i += 2;
35218 }
35219 } else {
35220 result.push(bytes[i] as char);
35221 i += 1;
35222 }
35223 }
35224 result
35225 }
35226
35227 fn strftime_to_snowflake_format(fmt: &str) -> String {
35229 let mut result = String::with_capacity(fmt.len() * 2);
35230 let bytes = fmt.as_bytes();
35231 let len = bytes.len();
35232 let mut i = 0;
35233 while i < len {
35234 if bytes[i] == b'%' && i + 1 < len {
35235 if bytes[i + 1] == b'-' && i + 2 < len {
35237 let replacement = match bytes[i + 2] {
35238 b'd' => "dd",
35239 b'm' => "mm",
35240 _ => {
35241 result.push('%');
35242 i += 1;
35243 continue;
35244 }
35245 };
35246 result.push_str(replacement);
35247 i += 3;
35248 } else {
35249 let replacement = match bytes[i + 1] {
35250 b'Y' => "yyyy",
35251 b'y' => "yy",
35252 b'm' => "mm",
35253 b'd' => "DD",
35254 b'H' => "hh24",
35255 b'M' => "mi",
35256 b'S' => "ss",
35257 b'f' => "ff",
35258 _ => {
35259 result.push('%');
35260 i += 1;
35261 continue;
35262 }
35263 };
35264 result.push_str(replacement);
35265 i += 2;
35266 }
35267 } else {
35268 result.push(bytes[i] as char);
35269 i += 1;
35270 }
35271 }
35272 result
35273 }
35274
35275 fn generate_str_to_map(&mut self, e: &StrToMap) -> Result<()> {
35276 self.write_keyword("STR_TO_MAP");
35278 self.write("(");
35279 self.generate_expression(&e.this)?;
35280 let needs_defaults = matches!(
35282 self.config.dialect,
35283 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
35284 );
35285 if let Some(pair_delim) = &e.pair_delim {
35286 self.write(", ");
35287 self.generate_expression(pair_delim)?;
35288 } else if needs_defaults {
35289 self.write(", ','");
35290 }
35291 if let Some(key_value_delim) = &e.key_value_delim {
35292 self.write(", ");
35293 self.generate_expression(key_value_delim)?;
35294 } else if needs_defaults {
35295 self.write(", ':'");
35296 }
35297 self.write(")");
35298 Ok(())
35299 }
35300
35301 fn generate_str_to_time(&mut self, e: &StrToTime) -> Result<()> {
35302 let is_strftime = e.format.contains('%');
35304 let to_strftime = |f: &str| -> String {
35306 if is_strftime {
35307 f.to_string()
35308 } else {
35309 Self::snowflake_format_to_strftime(f)
35310 }
35311 };
35312 let to_java = |f: &str| -> String {
35314 if is_strftime {
35315 Self::strftime_to_java_format(f)
35316 } else {
35317 Self::snowflake_format_to_spark(f)
35318 }
35319 };
35320 let to_pg = |f: &str| -> String {
35322 if is_strftime {
35323 Self::strftime_to_postgres_format(f)
35324 } else {
35325 Self::convert_strptime_to_postgres_format(f)
35326 }
35327 };
35328
35329 match self.config.dialect {
35330 Some(DialectType::Exasol) => {
35331 self.write_keyword("TO_DATE");
35332 self.write("(");
35333 self.generate_expression(&e.this)?;
35334 self.write(", '");
35335 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
35336 self.write("'");
35337 self.write(")");
35338 }
35339 Some(DialectType::BigQuery) => {
35340 let fmt = to_strftime(&e.format);
35342 let fmt = fmt.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
35344 self.write_keyword("PARSE_TIMESTAMP");
35345 self.write("('");
35346 self.write(&fmt);
35347 self.write("', ");
35348 self.generate_expression(&e.this)?;
35349 self.write(")");
35350 }
35351 Some(DialectType::Hive) => {
35352 let java_fmt = to_java(&e.format);
35355 if java_fmt == "yyyy-MM-dd HH:mm:ss"
35356 || java_fmt == "yyyy-MM-dd"
35357 || e.format == "yyyy-MM-dd HH:mm:ss"
35358 || e.format == "yyyy-MM-dd"
35359 {
35360 self.write_keyword("CAST");
35361 self.write("(");
35362 self.generate_expression(&e.this)?;
35363 self.write(" ");
35364 self.write_keyword("AS TIMESTAMP");
35365 self.write(")");
35366 } else {
35367 self.write_keyword("CAST");
35369 self.write("(");
35370 self.write_keyword("FROM_UNIXTIME");
35371 self.write("(");
35372 self.write_keyword("UNIX_TIMESTAMP");
35373 self.write("(");
35374 self.generate_expression(&e.this)?;
35375 self.write(", '");
35376 self.write(&java_fmt);
35377 self.write("')");
35378 self.write(") ");
35379 self.write_keyword("AS TIMESTAMP");
35380 self.write(")");
35381 }
35382 }
35383 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
35384 let java_fmt = to_java(&e.format);
35386 self.write_keyword("TO_TIMESTAMP");
35387 self.write("(");
35388 self.generate_expression(&e.this)?;
35389 self.write(", '");
35390 self.write(&java_fmt);
35391 self.write("')");
35392 }
35393 Some(DialectType::MySQL) => {
35394 let mut fmt = to_strftime(&e.format);
35396 fmt = fmt.replace("%-d", "%e");
35398 fmt = fmt.replace("%-m", "%c");
35399 fmt = fmt.replace("%H:%M:%S", "%T");
35400 self.write_keyword("STR_TO_DATE");
35401 self.write("(");
35402 self.generate_expression(&e.this)?;
35403 self.write(", '");
35404 self.write(&fmt);
35405 self.write("')");
35406 }
35407 Some(DialectType::Drill) => {
35408 let java_fmt = to_java(&e.format);
35410 let java_fmt = java_fmt.replace('T', "''T''");
35412 self.write_keyword("TO_TIMESTAMP");
35413 self.write("(");
35414 self.generate_expression(&e.this)?;
35415 self.write(", '");
35416 self.write(&java_fmt);
35417 self.write("')");
35418 }
35419 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
35420 let mut fmt = to_strftime(&e.format);
35422 fmt = fmt.replace("%-d", "%e");
35424 fmt = fmt.replace("%-m", "%c");
35425 fmt = fmt.replace("%H:%M:%S", "%T");
35426 self.write_keyword("DATE_PARSE");
35427 self.write("(");
35428 self.generate_expression(&e.this)?;
35429 self.write(", '");
35430 self.write(&fmt);
35431 self.write("')");
35432 }
35433 Some(DialectType::DuckDB) => {
35434 let fmt = to_strftime(&e.format);
35436 self.write_keyword("STRPTIME");
35437 self.write("(");
35438 self.generate_expression(&e.this)?;
35439 self.write(", '");
35440 self.write(&fmt);
35441 self.write("')");
35442 }
35443 Some(DialectType::PostgreSQL)
35444 | Some(DialectType::Redshift)
35445 | Some(DialectType::Materialize) => {
35446 let pg_fmt = to_pg(&e.format);
35448 self.write_keyword("TO_TIMESTAMP");
35449 self.write("(");
35450 self.generate_expression(&e.this)?;
35451 self.write(", '");
35452 self.write(&pg_fmt);
35453 self.write("')");
35454 }
35455 Some(DialectType::Oracle) => {
35456 let pg_fmt = to_pg(&e.format);
35458 self.write_keyword("TO_TIMESTAMP");
35459 self.write("(");
35460 self.generate_expression(&e.this)?;
35461 self.write(", '");
35462 self.write(&pg_fmt);
35463 self.write("')");
35464 }
35465 Some(DialectType::Snowflake) => {
35466 self.write_keyword("TO_TIMESTAMP");
35468 self.write("(");
35469 self.generate_expression(&e.this)?;
35470 self.write(", '");
35471 self.write(&e.format);
35472 self.write("')");
35473 }
35474 _ => {
35475 self.write_keyword("STR_TO_TIME");
35477 self.write("(");
35478 self.generate_expression(&e.this)?;
35479 self.write(", '");
35480 self.write(&e.format);
35481 self.write("'");
35482 self.write(")");
35483 }
35484 }
35485 Ok(())
35486 }
35487
35488 fn snowflake_format_to_strftime(format: &str) -> String {
35490 let mut result = String::new();
35491 let chars: Vec<char> = format.chars().collect();
35492 let mut i = 0;
35493 while i < chars.len() {
35494 let remaining = &format[i..];
35495 if remaining.starts_with("yyyy") {
35496 result.push_str("%Y");
35497 i += 4;
35498 } else if remaining.starts_with("yy") {
35499 result.push_str("%y");
35500 i += 2;
35501 } else if remaining.starts_with("mmmm") {
35502 result.push_str("%B"); i += 4;
35504 } else if remaining.starts_with("mon") {
35505 result.push_str("%b"); i += 3;
35507 } else if remaining.starts_with("mm") {
35508 result.push_str("%m");
35509 i += 2;
35510 } else if remaining.starts_with("DD") {
35511 result.push_str("%d");
35512 i += 2;
35513 } else if remaining.starts_with("dy") {
35514 result.push_str("%a"); i += 2;
35516 } else if remaining.starts_with("hh24") {
35517 result.push_str("%H");
35518 i += 4;
35519 } else if remaining.starts_with("hh12") {
35520 result.push_str("%I");
35521 i += 4;
35522 } else if remaining.starts_with("hh") {
35523 result.push_str("%H");
35524 i += 2;
35525 } else if remaining.starts_with("mi") {
35526 result.push_str("%M");
35527 i += 2;
35528 } else if remaining.starts_with("ss") {
35529 result.push_str("%S");
35530 i += 2;
35531 } else if remaining.starts_with("ff") {
35532 result.push_str("%f");
35534 i += 2;
35535 while i < chars.len() && chars[i].is_ascii_digit() {
35537 i += 1;
35538 }
35539 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
35540 result.push_str("%p");
35541 i += 2;
35542 } else if remaining.starts_with("tz") {
35543 result.push_str("%Z");
35544 i += 2;
35545 } else {
35546 result.push(chars[i]);
35547 i += 1;
35548 }
35549 }
35550 result
35551 }
35552
35553 fn snowflake_format_to_spark(format: &str) -> String {
35555 let mut result = String::new();
35556 let chars: Vec<char> = format.chars().collect();
35557 let mut i = 0;
35558 while i < chars.len() {
35559 let remaining = &format[i..];
35560 if remaining.starts_with("yyyy") {
35561 result.push_str("yyyy");
35562 i += 4;
35563 } else if remaining.starts_with("yy") {
35564 result.push_str("yy");
35565 i += 2;
35566 } else if remaining.starts_with("mmmm") {
35567 result.push_str("MMMM"); i += 4;
35569 } else if remaining.starts_with("mon") {
35570 result.push_str("MMM"); i += 3;
35572 } else if remaining.starts_with("mm") {
35573 result.push_str("MM");
35574 i += 2;
35575 } else if remaining.starts_with("DD") {
35576 result.push_str("dd");
35577 i += 2;
35578 } else if remaining.starts_with("dy") {
35579 result.push_str("EEE"); i += 2;
35581 } else if remaining.starts_with("hh24") {
35582 result.push_str("HH");
35583 i += 4;
35584 } else if remaining.starts_with("hh12") {
35585 result.push_str("hh");
35586 i += 4;
35587 } else if remaining.starts_with("hh") {
35588 result.push_str("HH");
35589 i += 2;
35590 } else if remaining.starts_with("mi") {
35591 result.push_str("mm");
35592 i += 2;
35593 } else if remaining.starts_with("ss") {
35594 result.push_str("ss");
35595 i += 2;
35596 } else if remaining.starts_with("ff") {
35597 result.push_str("SSS"); i += 2;
35599 while i < chars.len() && chars[i].is_ascii_digit() {
35601 i += 1;
35602 }
35603 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
35604 result.push_str("a");
35605 i += 2;
35606 } else if remaining.starts_with("tz") {
35607 result.push_str("z");
35608 i += 2;
35609 } else {
35610 result.push(chars[i]);
35611 i += 1;
35612 }
35613 }
35614 result
35615 }
35616
35617 fn generate_str_to_unix(&mut self, e: &StrToUnix) -> Result<()> {
35618 match self.config.dialect {
35619 Some(DialectType::DuckDB) => {
35620 self.write_keyword("EPOCH");
35622 self.write("(");
35623 self.write_keyword("STRPTIME");
35624 self.write("(");
35625 if let Some(this) = &e.this {
35626 self.generate_expression(this)?;
35627 }
35628 if let Some(format) = &e.format {
35629 self.write(", '");
35630 self.write(format);
35631 self.write("'");
35632 }
35633 self.write("))");
35634 }
35635 Some(DialectType::Hive) => {
35636 self.write_keyword("UNIX_TIMESTAMP");
35638 self.write("(");
35639 if let Some(this) = &e.this {
35640 self.generate_expression(this)?;
35641 }
35642 if let Some(format) = &e.format {
35643 let java_fmt = Self::strftime_to_java_format(format);
35644 if java_fmt != "yyyy-MM-dd HH:mm:ss" {
35645 self.write(", '");
35646 self.write(&java_fmt);
35647 self.write("'");
35648 }
35649 }
35650 self.write(")");
35651 }
35652 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
35653 self.write_keyword("UNIX_TIMESTAMP");
35655 self.write("(");
35656 if let Some(this) = &e.this {
35657 self.generate_expression(this)?;
35658 }
35659 if let Some(format) = &e.format {
35660 self.write(", '");
35661 self.write(format);
35662 self.write("'");
35663 }
35664 self.write(")");
35665 }
35666 Some(DialectType::Presto) | Some(DialectType::Trino) => {
35667 let c_fmt = e.format.as_deref().unwrap_or("%Y-%m-%d %T");
35670 let java_fmt = Self::strftime_to_java_format(c_fmt);
35671 self.write_keyword("TO_UNIXTIME");
35672 self.write("(");
35673 self.write_keyword("COALESCE");
35674 self.write("(");
35675 self.write_keyword("TRY");
35676 self.write("(");
35677 self.write_keyword("DATE_PARSE");
35678 self.write("(");
35679 self.write_keyword("CAST");
35680 self.write("(");
35681 if let Some(this) = &e.this {
35682 self.generate_expression(this)?;
35683 }
35684 self.write(" ");
35685 self.write_keyword("AS VARCHAR");
35686 self.write("), '");
35687 self.write(c_fmt);
35688 self.write("')), ");
35689 self.write_keyword("PARSE_DATETIME");
35690 self.write("(");
35691 self.write_keyword("DATE_FORMAT");
35692 self.write("(");
35693 self.write_keyword("CAST");
35694 self.write("(");
35695 if let Some(this) = &e.this {
35696 self.generate_expression(this)?;
35697 }
35698 self.write(" ");
35699 self.write_keyword("AS TIMESTAMP");
35700 self.write("), '");
35701 self.write(c_fmt);
35702 self.write("'), '");
35703 self.write(&java_fmt);
35704 self.write("')))");
35705 }
35706 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
35707 self.write_keyword("UNIX_TIMESTAMP");
35709 self.write("(");
35710 if let Some(this) = &e.this {
35711 self.generate_expression(this)?;
35712 }
35713 if let Some(format) = &e.format {
35714 let java_fmt = Self::strftime_to_java_format(format);
35715 self.write(", '");
35716 self.write(&java_fmt);
35717 self.write("'");
35718 }
35719 self.write(")");
35720 }
35721 _ => {
35722 self.write_keyword("STR_TO_UNIX");
35724 self.write("(");
35725 if let Some(this) = &e.this {
35726 self.generate_expression(this)?;
35727 }
35728 if let Some(format) = &e.format {
35729 self.write(", '");
35730 self.write(format);
35731 self.write("'");
35732 }
35733 self.write(")");
35734 }
35735 }
35736 Ok(())
35737 }
35738
35739 fn generate_string_to_array(&mut self, e: &StringToArray) -> Result<()> {
35740 self.write_keyword("STRING_TO_ARRAY");
35742 self.write("(");
35743 self.generate_expression(&e.this)?;
35744 if let Some(expression) = &e.expression {
35745 self.write(", ");
35746 self.generate_expression(expression)?;
35747 }
35748 if let Some(null_val) = &e.null {
35749 self.write(", ");
35750 self.generate_expression(null_val)?;
35751 }
35752 self.write(")");
35753 Ok(())
35754 }
35755
35756 fn generate_struct(&mut self, e: &Struct) -> Result<()> {
35757 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
35758 self.write_keyword("OBJECT_CONSTRUCT");
35760 self.write("(");
35761 for (i, (name, expr)) in e.fields.iter().enumerate() {
35762 if i > 0 {
35763 self.write(", ");
35764 }
35765 if let Some(name) = name {
35766 self.write("'");
35767 self.write(name);
35768 self.write("'");
35769 self.write(", ");
35770 } else {
35771 self.write("'_");
35772 self.write(&i.to_string());
35773 self.write("'");
35774 self.write(", ");
35775 }
35776 self.generate_expression(expr)?;
35777 }
35778 self.write(")");
35779 } else if self.config.struct_curly_brace_notation {
35780 self.write("{");
35782 for (i, (name, expr)) in e.fields.iter().enumerate() {
35783 if i > 0 {
35784 self.write(", ");
35785 }
35786 if let Some(name) = name {
35787 self.write("'");
35789 self.write(name);
35790 self.write("'");
35791 self.write(": ");
35792 } else {
35793 self.write("'_");
35795 self.write(&i.to_string());
35796 self.write("'");
35797 self.write(": ");
35798 }
35799 self.generate_expression(expr)?;
35800 }
35801 self.write("}");
35802 } else {
35803 let value_as_name = matches!(
35807 self.config.dialect,
35808 Some(DialectType::BigQuery)
35809 | Some(DialectType::Spark)
35810 | Some(DialectType::Databricks)
35811 | Some(DialectType::Hive)
35812 );
35813 self.write_keyword("STRUCT");
35814 self.write("(");
35815 for (i, (name, expr)) in e.fields.iter().enumerate() {
35816 if i > 0 {
35817 self.write(", ");
35818 }
35819 if let Some(name) = name {
35820 if value_as_name {
35821 self.generate_expression(expr)?;
35823 self.write_space();
35824 self.write_keyword("AS");
35825 self.write_space();
35826 let needs_quoting = name.contains(' ') || name.contains('-');
35828 if needs_quoting {
35829 if matches!(
35830 self.config.dialect,
35831 Some(DialectType::Spark)
35832 | Some(DialectType::Databricks)
35833 | Some(DialectType::Hive)
35834 ) {
35835 self.write("`");
35836 self.write(name);
35837 self.write("`");
35838 } else {
35839 self.write(name);
35840 }
35841 } else {
35842 self.write(name);
35843 }
35844 } else {
35845 self.write(name);
35847 self.write_space();
35848 self.write_keyword("AS");
35849 self.write_space();
35850 self.generate_expression(expr)?;
35851 }
35852 } else {
35853 self.generate_expression(expr)?;
35854 }
35855 }
35856 self.write(")");
35857 }
35858 Ok(())
35859 }
35860
35861 fn generate_stuff(&mut self, e: &Stuff) -> Result<()> {
35862 self.write_keyword("STUFF");
35864 self.write("(");
35865 self.generate_expression(&e.this)?;
35866 if let Some(start) = &e.start {
35867 self.write(", ");
35868 self.generate_expression(start)?;
35869 }
35870 if let Some(length) = e.length {
35871 self.write(", ");
35872 self.write(&length.to_string());
35873 }
35874 self.write(", ");
35875 self.generate_expression(&e.expression)?;
35876 self.write(")");
35877 Ok(())
35878 }
35879
35880 fn generate_substring_index(&mut self, e: &SubstringIndex) -> Result<()> {
35881 self.write_keyword("SUBSTRING_INDEX");
35883 self.write("(");
35884 self.generate_expression(&e.this)?;
35885 if let Some(delimiter) = &e.delimiter {
35886 self.write(", ");
35887 self.generate_expression(delimiter)?;
35888 }
35889 if let Some(count) = &e.count {
35890 self.write(", ");
35891 self.generate_expression(count)?;
35892 }
35893 self.write(")");
35894 Ok(())
35895 }
35896
35897 fn generate_summarize(&mut self, e: &Summarize) -> Result<()> {
35898 self.write_keyword("SUMMARIZE");
35900 if e.table.is_some() {
35901 self.write_space();
35902 self.write_keyword("TABLE");
35903 }
35904 self.write_space();
35905 self.generate_expression(&e.this)?;
35906 Ok(())
35907 }
35908
35909 fn generate_systimestamp(&mut self, _e: &Systimestamp) -> Result<()> {
35910 self.write_keyword("SYSTIMESTAMP");
35912 Ok(())
35913 }
35914
35915 fn generate_table_alias(&mut self, e: &TableAlias) -> Result<()> {
35916 if let Some(this) = &e.this {
35918 self.generate_expression(this)?;
35919 }
35920 if !e.columns.is_empty() {
35921 self.write("(");
35922 for (i, col) in e.columns.iter().enumerate() {
35923 if i > 0 {
35924 self.write(", ");
35925 }
35926 self.generate_expression(col)?;
35927 }
35928 self.write(")");
35929 }
35930 Ok(())
35931 }
35932
35933 fn generate_table_from_rows(&mut self, e: &TableFromRows) -> Result<()> {
35934 self.write_keyword("TABLE");
35936 self.write("(");
35937 self.generate_expression(&e.this)?;
35938 self.write(")");
35939 if let Some(alias) = &e.alias {
35940 self.write_space();
35941 self.write_keyword("AS");
35942 self.write_space();
35943 self.write(alias);
35944 }
35945 Ok(())
35946 }
35947
35948 fn generate_rows_from(&mut self, e: &RowsFrom) -> Result<()> {
35949 self.write_keyword("ROWS FROM");
35951 self.write(" (");
35952 for (i, expr) in e.expressions.iter().enumerate() {
35953 if i > 0 {
35954 self.write(", ");
35955 }
35956 match expr {
35960 Expression::Tuple(tuple) if tuple.expressions.len() == 2 => {
35961 self.generate_expression(&tuple.expressions[0])?;
35963 self.write_space();
35964 self.write_keyword("AS");
35965 self.write_space();
35966 self.generate_expression(&tuple.expressions[1])?;
35967 }
35968 _ => {
35969 self.generate_expression(expr)?;
35970 }
35971 }
35972 }
35973 self.write(")");
35974 if e.ordinality {
35975 self.write_space();
35976 self.write_keyword("WITH ORDINALITY");
35977 }
35978 if let Some(alias) = &e.alias {
35979 self.write_space();
35980 self.write_keyword("AS");
35981 self.write_space();
35982 self.generate_expression(alias)?;
35983 }
35984 Ok(())
35985 }
35986
35987 fn generate_table_sample(&mut self, e: &TableSample) -> Result<()> {
35988 use crate::dialects::DialectType;
35989
35990 if let (Some(this), Some(sample)) = (&e.this, &e.sample) {
35992 if self.config.alias_post_tablesample {
35994 if let Expression::Subquery(ref s) = **this {
35996 if let Some(ref alias) = s.alias {
35997 let mut subquery_no_alias = (**s).clone();
35999 subquery_no_alias.alias = None;
36000 subquery_no_alias.column_aliases = Vec::new();
36001 self.generate_expression(&Expression::Subquery(Box::new(
36002 subquery_no_alias,
36003 )))?;
36004 self.write_space();
36005 self.write_keyword(self.config.tablesample_keywords);
36006 self.generate_sample_body(sample)?;
36007 if let Some(ref seed) = sample.seed {
36008 self.write_space();
36009 let use_seed = sample.use_seed_keyword
36010 && !matches!(
36011 self.config.dialect,
36012 Some(crate::dialects::DialectType::Databricks)
36013 | Some(crate::dialects::DialectType::Spark)
36014 );
36015 if use_seed {
36016 self.write_keyword("SEED");
36017 } else {
36018 self.write_keyword("REPEATABLE");
36019 }
36020 self.write(" (");
36021 self.generate_expression(seed)?;
36022 self.write(")");
36023 }
36024 self.write_space();
36025 self.write_keyword("AS");
36026 self.write_space();
36027 self.generate_identifier(alias)?;
36028 return Ok(());
36029 }
36030 } else if let Expression::Alias(ref a) = **this {
36031 self.generate_expression(&a.this)?;
36033 self.write_space();
36034 self.write_keyword(self.config.tablesample_keywords);
36035 self.generate_sample_body(sample)?;
36036 if let Some(ref seed) = sample.seed {
36037 self.write_space();
36038 let use_seed = sample.use_seed_keyword
36039 && !matches!(
36040 self.config.dialect,
36041 Some(crate::dialects::DialectType::Databricks)
36042 | Some(crate::dialects::DialectType::Spark)
36043 );
36044 if use_seed {
36045 self.write_keyword("SEED");
36046 } else {
36047 self.write_keyword("REPEATABLE");
36048 }
36049 self.write(" (");
36050 self.generate_expression(seed)?;
36051 self.write(")");
36052 }
36053 self.write_space();
36055 self.write_keyword("AS");
36056 self.write_space();
36057 self.generate_identifier(&a.alias)?;
36058 return Ok(());
36059 }
36060 }
36061 self.generate_expression(this)?;
36063 self.write_space();
36064 self.write_keyword(self.config.tablesample_keywords);
36065 self.generate_sample_body(sample)?;
36066 if let Some(ref seed) = sample.seed {
36068 self.write_space();
36069 let use_seed = sample.use_seed_keyword
36071 && !matches!(
36072 self.config.dialect,
36073 Some(crate::dialects::DialectType::Databricks)
36074 | Some(crate::dialects::DialectType::Spark)
36075 );
36076 if use_seed {
36077 self.write_keyword("SEED");
36078 } else {
36079 self.write_keyword("REPEATABLE");
36080 }
36081 self.write(" (");
36082 self.generate_expression(seed)?;
36083 self.write(")");
36084 }
36085 return Ok(());
36086 }
36087
36088 self.write_keyword(self.config.tablesample_keywords);
36090 if let Some(method) = &e.method {
36091 self.write_space();
36092 self.write_keyword(method);
36093 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
36094 self.write_space();
36096 self.write_keyword("BERNOULLI");
36097 }
36098 if let (Some(numerator), Some(denominator)) = (&e.bucket_numerator, &e.bucket_denominator) {
36099 self.write_space();
36100 self.write_keyword("BUCKET");
36101 self.write_space();
36102 self.generate_expression(numerator)?;
36103 self.write_space();
36104 self.write_keyword("OUT OF");
36105 self.write_space();
36106 self.generate_expression(denominator)?;
36107 if let Some(field) = &e.bucket_field {
36108 self.write_space();
36109 self.write_keyword("ON");
36110 self.write_space();
36111 self.generate_expression(field)?;
36112 }
36113 } else if !e.expressions.is_empty() {
36114 self.write(" (");
36115 for (i, expr) in e.expressions.iter().enumerate() {
36116 if i > 0 {
36117 self.write(", ");
36118 }
36119 self.generate_expression(expr)?;
36120 }
36121 self.write(")");
36122 } else if let Some(percent) = &e.percent {
36123 self.write(" (");
36124 self.generate_expression(percent)?;
36125 self.write_space();
36126 self.write_keyword("PERCENT");
36127 self.write(")");
36128 }
36129 Ok(())
36130 }
36131
36132 fn generate_tag(&mut self, e: &Tag) -> Result<()> {
36133 if let Some(prefix) = &e.prefix {
36135 self.generate_expression(prefix)?;
36136 }
36137 if let Some(this) = &e.this {
36138 self.generate_expression(this)?;
36139 }
36140 if let Some(postfix) = &e.postfix {
36141 self.generate_expression(postfix)?;
36142 }
36143 Ok(())
36144 }
36145
36146 fn generate_tags(&mut self, e: &Tags) -> Result<()> {
36147 self.write_keyword("TAG");
36149 self.write(" (");
36150 for (i, expr) in e.expressions.iter().enumerate() {
36151 if i > 0 {
36152 self.write(", ");
36153 }
36154 self.generate_expression(expr)?;
36155 }
36156 self.write(")");
36157 Ok(())
36158 }
36159
36160 fn generate_temporary_property(&mut self, e: &TemporaryProperty) -> Result<()> {
36161 if let Some(this) = &e.this {
36163 self.generate_expression(this)?;
36164 self.write_space();
36165 }
36166 self.write_keyword("TEMPORARY");
36167 Ok(())
36168 }
36169
36170 fn generate_time_func(&mut self, e: &UnaryFunc) -> Result<()> {
36173 self.write_keyword("TIME");
36175 self.write("(");
36176 self.generate_expression(&e.this)?;
36177 self.write(")");
36178 Ok(())
36179 }
36180
36181 fn generate_time_add(&mut self, e: &TimeAdd) -> Result<()> {
36182 self.write_keyword("TIME_ADD");
36184 self.write("(");
36185 self.generate_expression(&e.this)?;
36186 self.write(", ");
36187 self.generate_expression(&e.expression)?;
36188 if let Some(unit) = &e.unit {
36189 self.write(", ");
36190 self.write_keyword(unit);
36191 }
36192 self.write(")");
36193 Ok(())
36194 }
36195
36196 fn generate_time_diff(&mut self, e: &TimeDiff) -> Result<()> {
36197 self.write_keyword("TIME_DIFF");
36199 self.write("(");
36200 self.generate_expression(&e.this)?;
36201 self.write(", ");
36202 self.generate_expression(&e.expression)?;
36203 if let Some(unit) = &e.unit {
36204 self.write(", ");
36205 self.write_keyword(unit);
36206 }
36207 self.write(")");
36208 Ok(())
36209 }
36210
36211 fn generate_time_from_parts(&mut self, e: &TimeFromParts) -> Result<()> {
36212 self.write_keyword("TIME_FROM_PARTS");
36214 self.write("(");
36215 let mut first = true;
36216 if let Some(hour) = &e.hour {
36217 self.generate_expression(hour)?;
36218 first = false;
36219 }
36220 if let Some(minute) = &e.min {
36221 if !first {
36222 self.write(", ");
36223 }
36224 self.generate_expression(minute)?;
36225 first = false;
36226 }
36227 if let Some(second) = &e.sec {
36228 if !first {
36229 self.write(", ");
36230 }
36231 self.generate_expression(second)?;
36232 first = false;
36233 }
36234 if let Some(ns) = &e.nano {
36235 if !first {
36236 self.write(", ");
36237 }
36238 self.generate_expression(ns)?;
36239 }
36240 self.write(")");
36241 Ok(())
36242 }
36243
36244 fn generate_time_slice(&mut self, e: &TimeSlice) -> Result<()> {
36245 self.write_keyword("TIME_SLICE");
36247 self.write("(");
36248 self.generate_expression(&e.this)?;
36249 self.write(", ");
36250 self.generate_expression(&e.expression)?;
36251 self.write(", ");
36252 self.write_keyword(&e.unit);
36253 self.write(")");
36254 Ok(())
36255 }
36256
36257 fn generate_time_str_to_time(&mut self, e: &TimeStrToTime) -> Result<()> {
36258 self.write_keyword("TIME_STR_TO_TIME");
36260 self.write("(");
36261 self.generate_expression(&e.this)?;
36262 self.write(")");
36263 Ok(())
36264 }
36265
36266 fn generate_time_sub(&mut self, e: &TimeSub) -> Result<()> {
36267 self.write_keyword("TIME_SUB");
36269 self.write("(");
36270 self.generate_expression(&e.this)?;
36271 self.write(", ");
36272 self.generate_expression(&e.expression)?;
36273 if let Some(unit) = &e.unit {
36274 self.write(", ");
36275 self.write_keyword(unit);
36276 }
36277 self.write(")");
36278 Ok(())
36279 }
36280
36281 fn generate_time_to_str(&mut self, e: &TimeToStr) -> Result<()> {
36282 match self.config.dialect {
36283 Some(DialectType::Exasol) => {
36284 self.write_keyword("TO_CHAR");
36286 self.write("(");
36287 self.generate_expression(&e.this)?;
36288 self.write(", '");
36289 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
36290 self.write("'");
36291 self.write(")");
36292 }
36293 Some(DialectType::PostgreSQL)
36294 | Some(DialectType::Redshift)
36295 | Some(DialectType::Materialize) => {
36296 self.write_keyword("TO_CHAR");
36298 self.write("(");
36299 self.generate_expression(&e.this)?;
36300 self.write(", '");
36301 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
36302 self.write("'");
36303 self.write(")");
36304 }
36305 Some(DialectType::Oracle) => {
36306 self.write_keyword("TO_CHAR");
36308 self.write("(");
36309 self.generate_expression(&e.this)?;
36310 self.write(", '");
36311 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
36312 self.write("'");
36313 self.write(")");
36314 }
36315 Some(DialectType::Drill) => {
36316 self.write_keyword("TO_CHAR");
36318 self.write("(");
36319 self.generate_expression(&e.this)?;
36320 self.write(", '");
36321 self.write(&Self::strftime_to_java_format(&e.format));
36322 self.write("'");
36323 self.write(")");
36324 }
36325 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
36326 self.write_keyword("FORMAT");
36328 self.write("(");
36329 self.generate_expression(&e.this)?;
36330 self.write(", '");
36331 self.write(&Self::strftime_to_tsql_format(&e.format));
36332 self.write("'");
36333 self.write(")");
36334 }
36335 Some(DialectType::DuckDB) => {
36336 self.write_keyword("STRFTIME");
36338 self.write("(");
36339 self.generate_expression(&e.this)?;
36340 self.write(", '");
36341 self.write(&e.format);
36342 self.write("'");
36343 self.write(")");
36344 }
36345 Some(DialectType::BigQuery) => {
36346 let fmt = e.format.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
36349 self.write_keyword("FORMAT_DATE");
36350 self.write("('");
36351 self.write(&fmt);
36352 self.write("', ");
36353 self.generate_expression(&e.this)?;
36354 self.write(")");
36355 }
36356 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
36357 self.write_keyword("DATE_FORMAT");
36359 self.write("(");
36360 self.generate_expression(&e.this)?;
36361 self.write(", '");
36362 self.write(&Self::strftime_to_java_format(&e.format));
36363 self.write("'");
36364 self.write(")");
36365 }
36366 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
36367 self.write_keyword("DATE_FORMAT");
36369 self.write("(");
36370 self.generate_expression(&e.this)?;
36371 self.write(", '");
36372 self.write(&e.format);
36373 self.write("'");
36374 self.write(")");
36375 }
36376 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
36377 self.write_keyword("DATE_FORMAT");
36379 self.write("(");
36380 self.generate_expression(&e.this)?;
36381 self.write(", '");
36382 self.write(&e.format);
36383 self.write("'");
36384 self.write(")");
36385 }
36386 _ => {
36387 self.write_keyword("TIME_TO_STR");
36389 self.write("(");
36390 self.generate_expression(&e.this)?;
36391 self.write(", '");
36392 self.write(&e.format);
36393 self.write("'");
36394 self.write(")");
36395 }
36396 }
36397 Ok(())
36398 }
36399
36400 fn generate_time_to_unix(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
36401 match self.config.dialect {
36402 Some(DialectType::DuckDB) => {
36403 self.write_keyword("EPOCH");
36405 self.write("(");
36406 self.generate_expression(&e.this)?;
36407 self.write(")");
36408 }
36409 Some(DialectType::Hive)
36410 | Some(DialectType::Spark)
36411 | Some(DialectType::Databricks)
36412 | Some(DialectType::Doris)
36413 | Some(DialectType::StarRocks)
36414 | Some(DialectType::Drill) => {
36415 self.write_keyword("UNIX_TIMESTAMP");
36417 self.write("(");
36418 self.generate_expression(&e.this)?;
36419 self.write(")");
36420 }
36421 Some(DialectType::Presto) | Some(DialectType::Trino) => {
36422 self.write_keyword("TO_UNIXTIME");
36424 self.write("(");
36425 self.generate_expression(&e.this)?;
36426 self.write(")");
36427 }
36428 _ => {
36429 self.write_keyword("TIME_TO_UNIX");
36431 self.write("(");
36432 self.generate_expression(&e.this)?;
36433 self.write(")");
36434 }
36435 }
36436 Ok(())
36437 }
36438
36439 fn generate_time_str_to_date(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
36440 match self.config.dialect {
36441 Some(DialectType::Hive) => {
36442 self.write_keyword("TO_DATE");
36444 self.write("(");
36445 self.generate_expression(&e.this)?;
36446 self.write(")");
36447 }
36448 _ => {
36449 self.write_keyword("TIME_STR_TO_DATE");
36451 self.write("(");
36452 self.generate_expression(&e.this)?;
36453 self.write(")");
36454 }
36455 }
36456 Ok(())
36457 }
36458
36459 fn generate_time_trunc(&mut self, e: &TimeTrunc) -> Result<()> {
36460 self.write_keyword("TIME_TRUNC");
36462 self.write("(");
36463 self.generate_expression(&e.this)?;
36464 self.write(", ");
36465 self.write_keyword(&e.unit);
36466 self.write(")");
36467 Ok(())
36468 }
36469
36470 fn generate_time_unit(&mut self, e: &TimeUnit) -> Result<()> {
36471 if let Some(unit) = &e.unit {
36473 self.write_keyword(unit);
36474 }
36475 Ok(())
36476 }
36477
36478 fn generate_timestamp_func(&mut self, e: &TimestampFunc) -> Result<()> {
36482 use crate::dialects::DialectType;
36483 use crate::expressions::Literal;
36484
36485 match self.config.dialect {
36486 Some(DialectType::Exasol) => {
36488 self.write_keyword("TO_TIMESTAMP");
36489 self.write("(");
36490 if let Some(this) = &e.this {
36492 match this.as_ref() {
36493 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
36494 let Literal::String(s) = lit.as_ref() else {
36495 unreachable!()
36496 };
36497 self.write("'");
36498 self.write(s);
36499 self.write("'");
36500 }
36501 _ => {
36502 self.generate_expression(this)?;
36503 }
36504 }
36505 }
36506 self.write(")");
36507 }
36508 _ => {
36510 self.write_keyword("TIMESTAMP");
36511 self.write("(");
36512 if let Some(this) = &e.this {
36513 self.generate_expression(this)?;
36514 }
36515 if let Some(zone) = &e.zone {
36516 self.write(", ");
36517 self.generate_expression(zone)?;
36518 }
36519 self.write(")");
36520 }
36521 }
36522 Ok(())
36523 }
36524
36525 fn generate_timestamp_add(&mut self, e: &TimestampAdd) -> Result<()> {
36526 self.write_keyword("TIMESTAMP_ADD");
36528 self.write("(");
36529 self.generate_expression(&e.this)?;
36530 self.write(", ");
36531 self.generate_expression(&e.expression)?;
36532 if let Some(unit) = &e.unit {
36533 self.write(", ");
36534 self.write_keyword(unit);
36535 }
36536 self.write(")");
36537 Ok(())
36538 }
36539
36540 fn generate_timestamp_diff(&mut self, e: &TimestampDiff) -> Result<()> {
36541 self.write_keyword("TIMESTAMP_DIFF");
36543 self.write("(");
36544 self.generate_expression(&e.this)?;
36545 self.write(", ");
36546 self.generate_expression(&e.expression)?;
36547 if let Some(unit) = &e.unit {
36548 self.write(", ");
36549 self.write_keyword(unit);
36550 }
36551 self.write(")");
36552 Ok(())
36553 }
36554
36555 fn generate_timestamp_from_parts(&mut self, e: &TimestampFromParts) -> Result<()> {
36556 self.write_keyword("TIMESTAMP_FROM_PARTS");
36558 self.write("(");
36559 if let Some(this) = &e.this {
36560 self.generate_expression(this)?;
36561 }
36562 if let Some(expression) = &e.expression {
36563 self.write(", ");
36564 self.generate_expression(expression)?;
36565 }
36566 if let Some(zone) = &e.zone {
36567 self.write(", ");
36568 self.generate_expression(zone)?;
36569 }
36570 if let Some(milli) = &e.milli {
36571 self.write(", ");
36572 self.generate_expression(milli)?;
36573 }
36574 self.write(")");
36575 Ok(())
36576 }
36577
36578 fn generate_timestamp_sub(&mut self, e: &TimestampSub) -> Result<()> {
36579 self.write_keyword("TIMESTAMP_SUB");
36581 self.write("(");
36582 self.generate_expression(&e.this)?;
36583 self.write(", ");
36584 self.write_keyword("INTERVAL");
36585 self.write_space();
36586 self.generate_expression(&e.expression)?;
36587 if let Some(unit) = &e.unit {
36588 self.write_space();
36589 self.write_keyword(unit);
36590 }
36591 self.write(")");
36592 Ok(())
36593 }
36594
36595 fn generate_timestamp_tz_from_parts(&mut self, e: &TimestampTzFromParts) -> Result<()> {
36596 self.write_keyword("TIMESTAMP_TZ_FROM_PARTS");
36598 self.write("(");
36599 if let Some(zone) = &e.zone {
36600 self.generate_expression(zone)?;
36601 }
36602 self.write(")");
36603 Ok(())
36604 }
36605
36606 fn generate_to_binary(&mut self, e: &ToBinary) -> Result<()> {
36607 self.write_keyword("TO_BINARY");
36609 self.write("(");
36610 self.generate_expression(&e.this)?;
36611 if let Some(format) = &e.format {
36612 self.write(", '");
36613 self.write(format);
36614 self.write("'");
36615 }
36616 self.write(")");
36617 Ok(())
36618 }
36619
36620 fn generate_to_boolean(&mut self, e: &ToBoolean) -> Result<()> {
36621 self.write_keyword("TO_BOOLEAN");
36623 self.write("(");
36624 self.generate_expression(&e.this)?;
36625 self.write(")");
36626 Ok(())
36627 }
36628
36629 fn generate_to_char(&mut self, e: &ToChar) -> Result<()> {
36630 self.write_keyword("TO_CHAR");
36632 self.write("(");
36633 self.generate_expression(&e.this)?;
36634 if let Some(format) = &e.format {
36635 self.write(", '");
36636 self.write(format);
36637 self.write("'");
36638 }
36639 if let Some(nlsparam) = &e.nlsparam {
36640 self.write(", ");
36641 self.generate_expression(nlsparam)?;
36642 }
36643 self.write(")");
36644 Ok(())
36645 }
36646
36647 fn generate_to_decfloat(&mut self, e: &ToDecfloat) -> Result<()> {
36648 self.write_keyword("TO_DECFLOAT");
36650 self.write("(");
36651 self.generate_expression(&e.this)?;
36652 if let Some(format) = &e.format {
36653 self.write(", '");
36654 self.write(format);
36655 self.write("'");
36656 }
36657 self.write(")");
36658 Ok(())
36659 }
36660
36661 fn generate_to_double(&mut self, e: &ToDouble) -> Result<()> {
36662 self.write_keyword("TO_DOUBLE");
36664 self.write("(");
36665 self.generate_expression(&e.this)?;
36666 if let Some(format) = &e.format {
36667 self.write(", '");
36668 self.write(format);
36669 self.write("'");
36670 }
36671 self.write(")");
36672 Ok(())
36673 }
36674
36675 fn generate_to_file(&mut self, e: &ToFile) -> Result<()> {
36676 self.write_keyword("TO_FILE");
36678 self.write("(");
36679 self.generate_expression(&e.this)?;
36680 if let Some(path) = &e.path {
36681 self.write(", ");
36682 self.generate_expression(path)?;
36683 }
36684 self.write(")");
36685 Ok(())
36686 }
36687
36688 fn generate_to_number(&mut self, e: &ToNumber) -> Result<()> {
36689 let is_safe = e.safe.is_some();
36692 if is_safe {
36693 self.write_keyword("TRY_TO_NUMBER");
36694 } else {
36695 self.write_keyword("TO_NUMBER");
36696 }
36697 self.write("(");
36698 self.generate_expression(&e.this)?;
36699 let precision_is_snowflake_default = e.precision.is_none()
36700 || matches!(
36701 e.precision.as_deref(),
36702 Some(Expression::Literal(lit))
36703 if matches!(lit.as_ref(), Literal::Number(n) if n == "0")
36704 );
36705 let is_snowflake_default_precision =
36706 matches!(self.config.dialect, Some(DialectType::Snowflake))
36707 && e.nlsparam.is_none()
36708 && e.scale.is_none()
36709 && matches!(
36710 e.format.as_deref(),
36711 Some(Expression::Literal(lit))
36712 if matches!(lit.as_ref(), Literal::Number(n) if n == "38")
36713 )
36714 && precision_is_snowflake_default;
36715
36716 if !is_snowflake_default_precision {
36717 if let Some(format) = &e.format {
36718 self.write(", ");
36719 self.generate_expression(format)?;
36720 }
36721 if let Some(nlsparam) = &e.nlsparam {
36722 self.write(", ");
36723 self.generate_expression(nlsparam)?;
36724 }
36725 if let Some(precision) = &e.precision {
36726 self.write(", ");
36727 self.generate_expression(precision)?;
36728 }
36729 if let Some(scale) = &e.scale {
36730 self.write(", ");
36731 self.generate_expression(scale)?;
36732 }
36733 }
36734 self.write(")");
36735 Ok(())
36736 }
36737
36738 fn generate_to_table_property(&mut self, e: &ToTableProperty) -> Result<()> {
36739 self.write_keyword("TO_TABLE");
36741 self.write_space();
36742 self.generate_expression(&e.this)?;
36743 Ok(())
36744 }
36745
36746 fn generate_transaction(&mut self, e: &Transaction) -> Result<()> {
36747 let mark_text = e.mark.as_ref().map(|m| match m.as_ref() {
36749 Expression::Identifier(id) => id.name.clone(),
36750 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
36751 let Literal::String(s) = lit.as_ref() else {
36752 unreachable!()
36753 };
36754 s.clone()
36755 }
36756 _ => String::new(),
36757 });
36758
36759 let is_start = mark_text.as_ref().map_or(false, |s| s == "START");
36760 let has_transaction_keyword = mark_text.as_ref().map_or(false, |s| s == "TRANSACTION");
36761 let has_with_mark = e.mark.as_ref().map_or(false, |m| {
36762 matches!(m.as_ref(), Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)))
36763 });
36764
36765 let use_start_transaction = matches!(
36767 self.config.dialect,
36768 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
36769 );
36770 let strip_transaction = matches!(
36772 self.config.dialect,
36773 Some(DialectType::Snowflake)
36774 | Some(DialectType::PostgreSQL)
36775 | Some(DialectType::Redshift)
36776 | Some(DialectType::MySQL)
36777 | Some(DialectType::Hive)
36778 | Some(DialectType::Spark)
36779 | Some(DialectType::Databricks)
36780 | Some(DialectType::DuckDB)
36781 | Some(DialectType::Oracle)
36782 | Some(DialectType::Doris)
36783 | Some(DialectType::StarRocks)
36784 | Some(DialectType::Materialize)
36785 | Some(DialectType::ClickHouse)
36786 );
36787
36788 if is_start || use_start_transaction {
36789 self.write_keyword("START TRANSACTION");
36791 if let Some(modes) = &e.modes {
36792 self.write_space();
36793 self.generate_expression(modes)?;
36794 }
36795 } else {
36796 self.write_keyword("BEGIN");
36798
36799 let is_kind = e.this.as_ref().map_or(false, |t| {
36801 if let Expression::Identifier(id) = t.as_ref() {
36802 id.name.eq_ignore_ascii_case("DEFERRED")
36803 || id.name.eq_ignore_ascii_case("IMMEDIATE")
36804 || id.name.eq_ignore_ascii_case("EXCLUSIVE")
36805 } else {
36806 false
36807 }
36808 });
36809
36810 if is_kind {
36812 if let Some(this) = &e.this {
36813 self.write_space();
36814 if let Expression::Identifier(id) = this.as_ref() {
36815 self.write_keyword(&id.name);
36816 }
36817 }
36818 }
36819
36820 if (has_transaction_keyword || has_with_mark) && !strip_transaction {
36822 self.write_space();
36823 self.write_keyword("TRANSACTION");
36824 }
36825
36826 if !is_kind {
36828 if let Some(this) = &e.this {
36829 self.write_space();
36830 self.generate_expression(this)?;
36831 }
36832 }
36833
36834 if has_with_mark {
36836 self.write_space();
36837 self.write_keyword("WITH MARK");
36838 if let Some(Expression::Literal(lit)) = e.mark.as_deref() {
36839 if let Literal::String(desc) = lit.as_ref() {
36840 if !desc.is_empty() {
36841 self.write_space();
36842 self.write(&format!("'{}'", desc));
36843 }
36844 }
36845 }
36846 }
36847
36848 if let Some(modes) = &e.modes {
36850 self.write_space();
36851 self.generate_expression(modes)?;
36852 }
36853 }
36854 Ok(())
36855 }
36856
36857 fn generate_transform(&mut self, e: &Transform) -> Result<()> {
36858 self.write_keyword("TRANSFORM");
36860 self.write("(");
36861 self.generate_expression(&e.this)?;
36862 self.write(", ");
36863 self.generate_expression(&e.expression)?;
36864 self.write(")");
36865 Ok(())
36866 }
36867
36868 fn generate_transform_model_property(&mut self, e: &TransformModelProperty) -> Result<()> {
36869 self.write_keyword("TRANSFORM");
36871 self.write("(");
36872 if self.config.pretty && !e.expressions.is_empty() {
36873 self.indent_level += 1;
36874 for (i, expr) in e.expressions.iter().enumerate() {
36875 if i > 0 {
36876 self.write(",");
36877 }
36878 self.write_newline();
36879 self.write_indent();
36880 self.generate_expression(expr)?;
36881 }
36882 self.indent_level -= 1;
36883 self.write_newline();
36884 self.write(")");
36885 } else {
36886 for (i, expr) in e.expressions.iter().enumerate() {
36887 if i > 0 {
36888 self.write(", ");
36889 }
36890 self.generate_expression(expr)?;
36891 }
36892 self.write(")");
36893 }
36894 Ok(())
36895 }
36896
36897 fn generate_transient_property(&mut self, e: &TransientProperty) -> Result<()> {
36898 use crate::dialects::DialectType;
36899 if let Some(this) = &e.this {
36901 self.generate_expression(this)?;
36902 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
36903 self.write_space();
36904 }
36905 }
36906 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
36907 self.write_keyword("TRANSIENT");
36908 }
36909 Ok(())
36910 }
36911
36912 fn generate_translate(&mut self, e: &Translate) -> Result<()> {
36913 self.write_keyword("TRANSLATE");
36915 self.write("(");
36916 self.generate_expression(&e.this)?;
36917 if let Some(from) = &e.from_ {
36918 self.write(", ");
36919 self.generate_expression(from)?;
36920 }
36921 if let Some(to) = &e.to {
36922 self.write(", ");
36923 self.generate_expression(to)?;
36924 }
36925 self.write(")");
36926 Ok(())
36927 }
36928
36929 fn generate_translate_characters(&mut self, e: &TranslateCharacters) -> Result<()> {
36930 self.write_keyword("TRANSLATE");
36932 self.write("(");
36933 self.generate_expression(&e.this)?;
36934 self.write_space();
36935 self.write_keyword("USING");
36936 self.write_space();
36937 self.generate_expression(&e.expression)?;
36938 if e.with_error.is_some() {
36939 self.write_space();
36940 self.write_keyword("WITH ERROR");
36941 }
36942 self.write(")");
36943 Ok(())
36944 }
36945
36946 fn generate_truncate_table(&mut self, e: &TruncateTable) -> Result<()> {
36947 self.write_keyword("TRUNCATE TABLE");
36949 self.write_space();
36950 for (i, expr) in e.expressions.iter().enumerate() {
36951 if i > 0 {
36952 self.write(", ");
36953 }
36954 self.generate_expression(expr)?;
36955 }
36956 Ok(())
36957 }
36958
36959 fn generate_try_base64_decode_binary(&mut self, e: &TryBase64DecodeBinary) -> Result<()> {
36960 self.write_keyword("TRY_BASE64_DECODE_BINARY");
36962 self.write("(");
36963 self.generate_expression(&e.this)?;
36964 if let Some(alphabet) = &e.alphabet {
36965 self.write(", ");
36966 self.generate_expression(alphabet)?;
36967 }
36968 self.write(")");
36969 Ok(())
36970 }
36971
36972 fn generate_try_base64_decode_string(&mut self, e: &TryBase64DecodeString) -> Result<()> {
36973 self.write_keyword("TRY_BASE64_DECODE_STRING");
36975 self.write("(");
36976 self.generate_expression(&e.this)?;
36977 if let Some(alphabet) = &e.alphabet {
36978 self.write(", ");
36979 self.generate_expression(alphabet)?;
36980 }
36981 self.write(")");
36982 Ok(())
36983 }
36984
36985 fn generate_try_to_decfloat(&mut self, e: &TryToDecfloat) -> Result<()> {
36986 self.write_keyword("TRY_TO_DECFLOAT");
36988 self.write("(");
36989 self.generate_expression(&e.this)?;
36990 if let Some(format) = &e.format {
36991 self.write(", '");
36992 self.write(format);
36993 self.write("'");
36994 }
36995 self.write(")");
36996 Ok(())
36997 }
36998
36999 fn generate_ts_or_ds_add(&mut self, e: &TsOrDsAdd) -> Result<()> {
37000 self.write_keyword("TS_OR_DS_ADD");
37002 self.write("(");
37003 self.generate_expression(&e.this)?;
37004 self.write(", ");
37005 self.generate_expression(&e.expression)?;
37006 if let Some(unit) = &e.unit {
37007 self.write(", ");
37008 self.write_keyword(unit);
37009 }
37010 if let Some(return_type) = &e.return_type {
37011 self.write(", ");
37012 self.generate_expression(return_type)?;
37013 }
37014 self.write(")");
37015 Ok(())
37016 }
37017
37018 fn generate_ts_or_ds_diff(&mut self, e: &TsOrDsDiff) -> Result<()> {
37019 self.write_keyword("TS_OR_DS_DIFF");
37021 self.write("(");
37022 self.generate_expression(&e.this)?;
37023 self.write(", ");
37024 self.generate_expression(&e.expression)?;
37025 if let Some(unit) = &e.unit {
37026 self.write(", ");
37027 self.write_keyword(unit);
37028 }
37029 self.write(")");
37030 Ok(())
37031 }
37032
37033 fn generate_ts_or_ds_to_date(&mut self, e: &TsOrDsToDate) -> Result<()> {
37034 let default_time_format = "%Y-%m-%d %H:%M:%S";
37035 let default_date_format = "%Y-%m-%d";
37036 let has_non_default_format = e.format.as_ref().map_or(false, |f| {
37037 f != default_time_format && f != default_date_format
37038 });
37039
37040 if has_non_default_format {
37041 let fmt = e.format.as_ref().unwrap();
37043 match self.config.dialect {
37044 Some(DialectType::MySQL) | Some(DialectType::StarRocks) => {
37045 let str_to_time = crate::expressions::StrToTime {
37048 this: Box::new((*e.this).clone()),
37049 format: fmt.clone(),
37050 zone: None,
37051 safe: None,
37052 target_type: None,
37053 };
37054 self.generate_str_to_time(&str_to_time)?;
37055 }
37056 Some(DialectType::Hive)
37057 | Some(DialectType::Spark)
37058 | Some(DialectType::Databricks) => {
37059 self.write_keyword("TO_DATE");
37061 self.write("(");
37062 self.generate_expression(&e.this)?;
37063 self.write(", '");
37064 self.write(&Self::strftime_to_java_format(fmt));
37065 self.write("')");
37066 }
37067 Some(DialectType::Snowflake) => {
37068 self.write_keyword("TO_DATE");
37070 self.write("(");
37071 self.generate_expression(&e.this)?;
37072 self.write(", '");
37073 self.write(&Self::strftime_to_snowflake_format(fmt));
37074 self.write("')");
37075 }
37076 Some(DialectType::Doris) => {
37077 self.write_keyword("TO_DATE");
37079 self.write("(");
37080 self.generate_expression(&e.this)?;
37081 self.write(")");
37082 }
37083 _ => {
37084 self.write_keyword("CAST");
37086 self.write("(");
37087 let str_to_time = crate::expressions::StrToTime {
37088 this: Box::new((*e.this).clone()),
37089 format: fmt.clone(),
37090 zone: None,
37091 safe: None,
37092 target_type: None,
37093 };
37094 self.generate_str_to_time(&str_to_time)?;
37095 self.write_keyword(" AS ");
37096 self.write_keyword("DATE");
37097 self.write(")");
37098 }
37099 }
37100 } else {
37101 match self.config.dialect {
37103 Some(DialectType::MySQL)
37104 | Some(DialectType::SQLite)
37105 | Some(DialectType::StarRocks) => {
37106 self.write_keyword("DATE");
37108 self.write("(");
37109 self.generate_expression(&e.this)?;
37110 self.write(")");
37111 }
37112 Some(DialectType::Hive)
37113 | Some(DialectType::Spark)
37114 | Some(DialectType::Databricks)
37115 | Some(DialectType::Snowflake)
37116 | Some(DialectType::Doris) => {
37117 self.write_keyword("TO_DATE");
37119 self.write("(");
37120 self.generate_expression(&e.this)?;
37121 self.write(")");
37122 }
37123 Some(DialectType::Presto)
37124 | Some(DialectType::Trino)
37125 | Some(DialectType::Athena) => {
37126 self.write_keyword("CAST");
37128 self.write("(");
37129 self.write_keyword("CAST");
37130 self.write("(");
37131 self.generate_expression(&e.this)?;
37132 self.write_keyword(" AS ");
37133 self.write_keyword("TIMESTAMP");
37134 self.write(")");
37135 self.write_keyword(" AS ");
37136 self.write_keyword("DATE");
37137 self.write(")");
37138 }
37139 Some(DialectType::ClickHouse) => {
37140 self.write_keyword("CAST");
37142 self.write("(");
37143 self.generate_expression(&e.this)?;
37144 self.write_keyword(" AS ");
37145 self.write("Nullable(DATE)");
37146 self.write(")");
37147 }
37148 _ => {
37149 self.write_keyword("CAST");
37151 self.write("(");
37152 self.generate_expression(&e.this)?;
37153 self.write_keyword(" AS ");
37154 self.write_keyword("DATE");
37155 self.write(")");
37156 }
37157 }
37158 }
37159 Ok(())
37160 }
37161
37162 fn generate_ts_or_ds_to_time(&mut self, e: &TsOrDsToTime) -> Result<()> {
37163 self.write_keyword("TS_OR_DS_TO_TIME");
37165 self.write("(");
37166 self.generate_expression(&e.this)?;
37167 if let Some(format) = &e.format {
37168 self.write(", '");
37169 self.write(format);
37170 self.write("'");
37171 }
37172 self.write(")");
37173 Ok(())
37174 }
37175
37176 fn generate_unhex(&mut self, e: &Unhex) -> Result<()> {
37177 self.write_keyword("UNHEX");
37179 self.write("(");
37180 self.generate_expression(&e.this)?;
37181 if let Some(expression) = &e.expression {
37182 self.write(", ");
37183 self.generate_expression(expression)?;
37184 }
37185 self.write(")");
37186 Ok(())
37187 }
37188
37189 fn generate_unicode_string(&mut self, e: &UnicodeString) -> Result<()> {
37190 self.write("U&");
37192 self.generate_expression(&e.this)?;
37193 if let Some(escape) = &e.escape {
37194 self.write_space();
37195 self.write_keyword("UESCAPE");
37196 self.write_space();
37197 self.generate_expression(escape)?;
37198 }
37199 Ok(())
37200 }
37201
37202 fn generate_uniform(&mut self, e: &Uniform) -> Result<()> {
37203 self.write_keyword("UNIFORM");
37205 self.write("(");
37206 self.generate_expression(&e.this)?;
37207 self.write(", ");
37208 self.generate_expression(&e.expression)?;
37209 if let Some(gen) = &e.gen {
37210 self.write(", ");
37211 self.generate_expression(gen)?;
37212 }
37213 if let Some(seed) = &e.seed {
37214 self.write(", ");
37215 self.generate_expression(seed)?;
37216 }
37217 self.write(")");
37218 Ok(())
37219 }
37220
37221 fn generate_unique_column_constraint(&mut self, e: &UniqueColumnConstraint) -> Result<()> {
37222 self.write_keyword("UNIQUE");
37224 if e.nulls.is_some() {
37226 self.write(" NULLS NOT DISTINCT");
37227 }
37228 if let Some(this) = &e.this {
37229 self.write_space();
37230 self.generate_expression(this)?;
37231 }
37232 if let Some(index_type) = &e.index_type {
37233 self.write(" USING ");
37234 self.generate_expression(index_type)?;
37235 }
37236 if let Some(on_conflict) = &e.on_conflict {
37237 self.write_space();
37238 self.generate_expression(on_conflict)?;
37239 }
37240 for opt in &e.options {
37241 self.write_space();
37242 self.generate_expression(opt)?;
37243 }
37244 Ok(())
37245 }
37246
37247 fn generate_unique_key_property(&mut self, e: &UniqueKeyProperty) -> Result<()> {
37248 self.write_keyword("UNIQUE KEY");
37250 self.write(" (");
37251 for (i, expr) in e.expressions.iter().enumerate() {
37252 if i > 0 {
37253 self.write(", ");
37254 }
37255 self.generate_expression(expr)?;
37256 }
37257 self.write(")");
37258 Ok(())
37259 }
37260
37261 fn generate_rollup_property(&mut self, e: &RollupProperty) -> Result<()> {
37262 self.write_keyword("ROLLUP");
37264 self.write(" (");
37265 for (i, index) in e.expressions.iter().enumerate() {
37266 if i > 0 {
37267 self.write(", ");
37268 }
37269 self.generate_identifier(&index.name)?;
37270 self.write("(");
37271 for (j, col) in index.expressions.iter().enumerate() {
37272 if j > 0 {
37273 self.write(", ");
37274 }
37275 self.generate_identifier(col)?;
37276 }
37277 self.write(")");
37278 }
37279 self.write(")");
37280 Ok(())
37281 }
37282
37283 fn generate_unix_to_str(&mut self, e: &UnixToStr) -> Result<()> {
37284 match self.config.dialect {
37285 Some(DialectType::DuckDB) => {
37286 self.write_keyword("STRFTIME");
37288 self.write("(");
37289 self.write_keyword("TO_TIMESTAMP");
37290 self.write("(");
37291 self.generate_expression(&e.this)?;
37292 self.write("), '");
37293 if let Some(format) = &e.format {
37294 self.write(format);
37295 }
37296 self.write("')");
37297 }
37298 Some(DialectType::Hive) => {
37299 self.write_keyword("FROM_UNIXTIME");
37301 self.write("(");
37302 self.generate_expression(&e.this)?;
37303 if let Some(format) = &e.format {
37304 if format != "yyyy-MM-dd HH:mm:ss" {
37305 self.write(", '");
37306 self.write(format);
37307 self.write("'");
37308 }
37309 }
37310 self.write(")");
37311 }
37312 Some(DialectType::Presto) | Some(DialectType::Trino) => {
37313 self.write_keyword("DATE_FORMAT");
37315 self.write("(");
37316 self.write_keyword("FROM_UNIXTIME");
37317 self.write("(");
37318 self.generate_expression(&e.this)?;
37319 self.write("), '");
37320 if let Some(format) = &e.format {
37321 self.write(format);
37322 }
37323 self.write("')");
37324 }
37325 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
37326 self.write_keyword("FROM_UNIXTIME");
37328 self.write("(");
37329 self.generate_expression(&e.this)?;
37330 if let Some(format) = &e.format {
37331 self.write(", '");
37332 self.write(format);
37333 self.write("'");
37334 }
37335 self.write(")");
37336 }
37337 _ => {
37338 self.write_keyword("UNIX_TO_STR");
37340 self.write("(");
37341 self.generate_expression(&e.this)?;
37342 if let Some(format) = &e.format {
37343 self.write(", '");
37344 self.write(format);
37345 self.write("'");
37346 }
37347 self.write(")");
37348 }
37349 }
37350 Ok(())
37351 }
37352
37353 fn generate_unix_to_time(&mut self, e: &UnixToTime) -> Result<()> {
37354 use crate::dialects::DialectType;
37355 let scale = e.scale.unwrap_or(0); match self.config.dialect {
37358 Some(DialectType::Snowflake) => {
37359 self.write_keyword("TO_TIMESTAMP");
37361 self.write("(");
37362 self.generate_expression(&e.this)?;
37363 if let Some(s) = e.scale {
37364 if s > 0 {
37365 self.write(", ");
37366 self.write(&s.to_string());
37367 }
37368 }
37369 self.write(")");
37370 }
37371 Some(DialectType::BigQuery) => {
37372 match scale {
37375 0 => {
37376 self.write_keyword("TIMESTAMP_SECONDS");
37377 self.write("(");
37378 self.generate_expression(&e.this)?;
37379 self.write(")");
37380 }
37381 3 => {
37382 self.write_keyword("TIMESTAMP_MILLIS");
37383 self.write("(");
37384 self.generate_expression(&e.this)?;
37385 self.write(")");
37386 }
37387 6 => {
37388 self.write_keyword("TIMESTAMP_MICROS");
37389 self.write("(");
37390 self.generate_expression(&e.this)?;
37391 self.write(")");
37392 }
37393 _ => {
37394 self.write_keyword("TIMESTAMP_SECONDS");
37396 self.write("(CAST(");
37397 self.generate_expression(&e.this)?;
37398 self.write(&format!(" / POWER(10, {}) AS INT64))", scale));
37399 }
37400 }
37401 }
37402 Some(DialectType::Spark) => {
37403 match scale {
37408 0 => {
37409 self.write_keyword("CAST");
37410 self.write("(");
37411 self.write_keyword("FROM_UNIXTIME");
37412 self.write("(");
37413 self.generate_expression(&e.this)?;
37414 self.write(") ");
37415 self.write_keyword("AS TIMESTAMP");
37416 self.write(")");
37417 }
37418 3 => {
37419 self.write_keyword("TIMESTAMP_MILLIS");
37420 self.write("(");
37421 self.generate_expression(&e.this)?;
37422 self.write(")");
37423 }
37424 6 => {
37425 self.write_keyword("TIMESTAMP_MICROS");
37426 self.write("(");
37427 self.generate_expression(&e.this)?;
37428 self.write(")");
37429 }
37430 _ => {
37431 self.write_keyword("TIMESTAMP_SECONDS");
37432 self.write("(");
37433 self.generate_expression(&e.this)?;
37434 self.write(&format!(" / POWER(10, {}))", scale));
37435 }
37436 }
37437 }
37438 Some(DialectType::Databricks) => {
37439 match scale {
37443 0 => {
37444 self.write_keyword("CAST");
37445 self.write("(");
37446 self.write_keyword("FROM_UNIXTIME");
37447 self.write("(");
37448 self.generate_expression(&e.this)?;
37449 self.write(") ");
37450 self.write_keyword("AS TIMESTAMP");
37451 self.write(")");
37452 }
37453 3 => {
37454 self.write_keyword("TIMESTAMP_MILLIS");
37455 self.write("(");
37456 self.generate_expression(&e.this)?;
37457 self.write(")");
37458 }
37459 6 => {
37460 self.write_keyword("TIMESTAMP_MICROS");
37461 self.write("(");
37462 self.generate_expression(&e.this)?;
37463 self.write(")");
37464 }
37465 _ => {
37466 self.write_keyword("TIMESTAMP_SECONDS");
37467 self.write("(");
37468 self.generate_expression(&e.this)?;
37469 self.write(&format!(" / POWER(10, {}))", scale));
37470 }
37471 }
37472 }
37473 Some(DialectType::Hive) => {
37474 if scale == 0 {
37476 self.write_keyword("FROM_UNIXTIME");
37477 self.write("(");
37478 self.generate_expression(&e.this)?;
37479 self.write(")");
37480 } else {
37481 self.write_keyword("FROM_UNIXTIME");
37482 self.write("(");
37483 self.generate_expression(&e.this)?;
37484 self.write(&format!(" / POWER(10, {})", scale));
37485 self.write(")");
37486 }
37487 }
37488 Some(DialectType::Presto) | Some(DialectType::Trino) => {
37489 if scale == 0 {
37492 self.write_keyword("FROM_UNIXTIME");
37493 self.write("(");
37494 self.generate_expression(&e.this)?;
37495 self.write(")");
37496 } else {
37497 self.write_keyword("FROM_UNIXTIME");
37498 self.write("(CAST(");
37499 self.generate_expression(&e.this)?;
37500 self.write(&format!(" AS DOUBLE) / POW(10, {}))", scale));
37501 }
37502 }
37503 Some(DialectType::DuckDB) => {
37504 match scale {
37508 0 => {
37509 self.write_keyword("TO_TIMESTAMP");
37510 self.write("(");
37511 self.generate_expression(&e.this)?;
37512 self.write(")");
37513 }
37514 3 => {
37515 self.write_keyword("EPOCH_MS");
37516 self.write("(");
37517 self.generate_expression(&e.this)?;
37518 self.write(")");
37519 }
37520 6 => {
37521 self.write_keyword("MAKE_TIMESTAMP");
37522 self.write("(");
37523 self.generate_expression(&e.this)?;
37524 self.write(")");
37525 }
37526 _ => {
37527 self.write_keyword("TO_TIMESTAMP");
37528 self.write("(");
37529 self.generate_expression(&e.this)?;
37530 self.write(&format!(" / POWER(10, {}))", scale));
37531 self.write_keyword(" AT TIME ZONE");
37532 self.write(" 'UTC'");
37533 }
37534 }
37535 }
37536 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
37537 self.write_keyword("FROM_UNIXTIME");
37539 self.write("(");
37540 self.generate_expression(&e.this)?;
37541 self.write(")");
37542 }
37543 Some(DialectType::Oracle) => {
37544 self.write("TO_DATE('1970-01-01', 'YYYY-MM-DD') + (");
37546 self.generate_expression(&e.this)?;
37547 self.write(" / 86400)");
37548 }
37549 Some(DialectType::Redshift) => {
37550 self.write("(TIMESTAMP 'epoch' + ");
37553 if scale == 0 {
37554 self.generate_expression(&e.this)?;
37555 } else {
37556 self.write("(");
37557 self.generate_expression(&e.this)?;
37558 self.write(&format!(" / POWER(10, {}))", scale));
37559 }
37560 self.write(" * INTERVAL '1 SECOND')");
37561 }
37562 Some(DialectType::Exasol) => {
37563 self.write_keyword("FROM_POSIX_TIME");
37565 self.write("(");
37566 self.generate_expression(&e.this)?;
37567 self.write(")");
37568 }
37569 _ => {
37570 self.write_keyword("TO_TIMESTAMP");
37572 self.write("(");
37573 self.generate_expression(&e.this)?;
37574 if let Some(s) = e.scale {
37575 self.write(", ");
37576 self.write(&s.to_string());
37577 }
37578 self.write(")");
37579 }
37580 }
37581 Ok(())
37582 }
37583
37584 fn generate_unpivot_columns(&mut self, e: &UnpivotColumns) -> Result<()> {
37585 if !matches!(&*e.this, Expression::Null(_)) {
37587 self.write_keyword("NAME");
37588 self.write_space();
37589 self.generate_expression(&e.this)?;
37590 }
37591 if !e.expressions.is_empty() {
37592 self.write_space();
37593 self.write_keyword("VALUE");
37594 self.write_space();
37595 for (i, expr) in e.expressions.iter().enumerate() {
37596 if i > 0 {
37597 self.write(", ");
37598 }
37599 self.generate_expression(expr)?;
37600 }
37601 }
37602 Ok(())
37603 }
37604
37605 fn generate_user_defined_function(&mut self, e: &UserDefinedFunction) -> Result<()> {
37606 if e.wrapped.is_some() {
37608 self.write("(");
37609 }
37610 self.generate_expression(&e.this)?;
37611 if e.wrapped.is_some() {
37612 self.write(")");
37613 }
37614 self.write("(");
37615 for (i, expr) in e.expressions.iter().enumerate() {
37616 if i > 0 {
37617 self.write(", ");
37618 }
37619 self.generate_expression(expr)?;
37620 }
37621 self.write(")");
37622 Ok(())
37623 }
37624
37625 fn generate_using_template_property(&mut self, e: &UsingTemplateProperty) -> Result<()> {
37626 self.write_keyword("USING TEMPLATE");
37628 self.write_space();
37629 self.generate_expression(&e.this)?;
37630 Ok(())
37631 }
37632
37633 fn generate_utc_time(&mut self, _e: &UtcTime) -> Result<()> {
37634 self.write_keyword("UTC_TIME");
37636 Ok(())
37637 }
37638
37639 fn generate_utc_timestamp(&mut self, _e: &UtcTimestamp) -> Result<()> {
37640 if matches!(
37641 self.config.dialect,
37642 Some(crate::dialects::DialectType::ClickHouse)
37643 ) {
37644 self.write_keyword("CURRENT_TIMESTAMP");
37645 self.write("('UTC')");
37646 } else {
37647 self.write_keyword("UTC_TIMESTAMP");
37648 }
37649 Ok(())
37650 }
37651
37652 fn generate_uuid(&mut self, e: &Uuid) -> Result<()> {
37653 use crate::dialects::DialectType;
37654 let func_name = match self.config.dialect {
37656 Some(DialectType::Snowflake) => "UUID_STRING",
37657 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
37658 Some(DialectType::BigQuery) => "GENERATE_UUID",
37659 _ => {
37660 if let Some(name) = &e.name {
37661 name.as_str()
37662 } else {
37663 "UUID"
37664 }
37665 }
37666 };
37667 self.write_keyword(func_name);
37668 self.write("(");
37669 if let Some(this) = &e.this {
37670 self.generate_expression(this)?;
37671 }
37672 self.write(")");
37673 Ok(())
37674 }
37675
37676 fn generate_var_map(&mut self, e: &VarMap) -> Result<()> {
37677 self.write_keyword("MAP");
37679 self.write("(");
37680 let mut first = true;
37681 for (k, v) in e.keys.iter().zip(e.values.iter()) {
37682 if !first {
37683 self.write(", ");
37684 }
37685 self.generate_expression(k)?;
37686 self.write(", ");
37687 self.generate_expression(v)?;
37688 first = false;
37689 }
37690 self.write(")");
37691 Ok(())
37692 }
37693
37694 fn generate_vector_search(&mut self, e: &VectorSearch) -> Result<()> {
37695 self.write_keyword("VECTOR_SEARCH");
37697 self.write("(");
37698 self.generate_expression(&e.this)?;
37699 if let Some(col) = &e.column_to_search {
37700 self.write(", ");
37701 self.generate_expression(col)?;
37702 }
37703 if let Some(query_table) = &e.query_table {
37704 self.write(", ");
37705 self.generate_expression(query_table)?;
37706 }
37707 if let Some(query_col) = &e.query_column_to_search {
37708 self.write(", ");
37709 self.generate_expression(query_col)?;
37710 }
37711 if let Some(top_k) = &e.top_k {
37712 self.write(", ");
37713 self.generate_expression(top_k)?;
37714 }
37715 if let Some(dist_type) = &e.distance_type {
37716 self.write(", ");
37717 self.generate_expression(dist_type)?;
37718 }
37719 self.write(")");
37720 Ok(())
37721 }
37722
37723 fn generate_version(&mut self, e: &Version) -> Result<()> {
37724 use crate::dialects::DialectType;
37730 let skip_for = matches!(
37731 self.config.dialect,
37732 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
37733 );
37734 if !skip_for {
37735 self.write_keyword("FOR");
37736 self.write_space();
37737 }
37738 match e.this.as_ref() {
37740 Expression::Identifier(ident) => {
37741 self.write_keyword(&ident.name);
37742 }
37743 _ => {
37744 self.generate_expression(&e.this)?;
37745 }
37746 }
37747 self.write_space();
37748 self.write_keyword(&e.kind);
37749 if let Some(expression) = &e.expression {
37750 self.write_space();
37751 self.generate_expression(expression)?;
37752 }
37753 Ok(())
37754 }
37755
37756 fn generate_view_attribute_property(&mut self, e: &ViewAttributeProperty) -> Result<()> {
37757 self.generate_expression(&e.this)?;
37759 Ok(())
37760 }
37761
37762 fn generate_volatile_property(&mut self, e: &VolatileProperty) -> Result<()> {
37763 if e.this.is_some() {
37765 self.write_keyword("NOT VOLATILE");
37766 } else {
37767 self.write_keyword("VOLATILE");
37768 }
37769 Ok(())
37770 }
37771
37772 fn generate_watermark_column_constraint(
37773 &mut self,
37774 e: &WatermarkColumnConstraint,
37775 ) -> Result<()> {
37776 self.write_keyword("WATERMARK FOR");
37778 self.write_space();
37779 self.generate_expression(&e.this)?;
37780 self.write_space();
37781 self.write_keyword("AS");
37782 self.write_space();
37783 self.generate_expression(&e.expression)?;
37784 Ok(())
37785 }
37786
37787 fn generate_week(&mut self, e: &Week) -> Result<()> {
37788 self.write_keyword("WEEK");
37790 self.write("(");
37791 self.generate_expression(&e.this)?;
37792 if let Some(mode) = &e.mode {
37793 self.write(", ");
37794 self.generate_expression(mode)?;
37795 }
37796 self.write(")");
37797 Ok(())
37798 }
37799
37800 fn generate_when(&mut self, e: &When) -> Result<()> {
37801 self.write_keyword("WHEN");
37805 self.write_space();
37806
37807 if let Some(matched) = &e.matched {
37809 match matched.as_ref() {
37811 Expression::Boolean(b) if b.value => {
37812 self.write_keyword("MATCHED");
37813 }
37814 _ => {
37815 self.write_keyword("NOT MATCHED");
37816 }
37817 }
37818 } else {
37819 self.write_keyword("NOT MATCHED");
37820 }
37821
37822 if self.config.matched_by_source {
37827 if let Some(source) = &e.source {
37828 if let Expression::Boolean(b) = source.as_ref() {
37829 if b.value {
37830 self.write_space();
37832 self.write_keyword("BY SOURCE");
37833 }
37834 } else {
37836 self.write_space();
37838 self.write_keyword("BY SOURCE");
37839 }
37840 }
37841 }
37842
37843 if let Some(condition) = &e.condition {
37845 self.write_space();
37846 self.write_keyword("AND");
37847 self.write_space();
37848 self.generate_expression(condition)?;
37849 }
37850
37851 self.write_space();
37852 self.write_keyword("THEN");
37853 self.write_space();
37854
37855 self.generate_merge_action(&e.then)?;
37858
37859 Ok(())
37860 }
37861
37862 fn generate_merge_action(&mut self, action: &Expression) -> Result<()> {
37863 match action {
37864 Expression::Tuple(tuple) => {
37865 let elements = &tuple.expressions;
37866 if elements.is_empty() {
37867 return self.generate_expression(action);
37868 }
37869 match &elements[0] {
37871 Expression::Var(v) if v.this == "INSERT" => {
37872 self.write_keyword("INSERT");
37873 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
37875 self.write(" *");
37876 if let Some(Expression::Where(w)) = elements.get(2) {
37877 self.write_space();
37878 self.generate_where(w)?;
37879 }
37880 } else {
37881 let mut values_idx = 1;
37882 if elements.len() > 1 {
37884 if let Expression::Tuple(cols) = &elements[1] {
37885 if elements.len() > 2 {
37887 self.write(" (");
37889 for (i, col) in cols.expressions.iter().enumerate() {
37890 if i > 0 {
37891 self.write(", ");
37892 }
37893 if !self.merge_strip_qualifiers.is_empty() {
37895 let stripped = self.strip_merge_qualifier(col);
37896 self.generate_expression(&stripped)?;
37897 } else {
37898 self.generate_expression(col)?;
37899 }
37900 }
37901 self.write(")");
37902 values_idx = 2;
37903 } else {
37904 values_idx = 1;
37906 }
37907 }
37908 }
37909 let mut next_idx = values_idx;
37910 if values_idx < elements.len()
37912 && !matches!(&elements[values_idx], Expression::Where(_))
37913 {
37914 let is_row = matches!(&elements[values_idx], Expression::Var(v) if v.this == "ROW");
37916 if !is_row {
37917 self.write_space();
37918 self.write_keyword("VALUES");
37919 }
37920 self.write(" ");
37921 if let Expression::Tuple(vals) = &elements[values_idx] {
37922 self.write("(");
37923 for (i, val) in vals.expressions.iter().enumerate() {
37924 if i > 0 {
37925 self.write(", ");
37926 }
37927 self.generate_expression(val)?;
37928 }
37929 self.write(")");
37930 } else {
37931 self.generate_expression(&elements[values_idx])?;
37932 }
37933 next_idx += 1;
37934 }
37935 if let Some(Expression::Where(w)) = elements.get(next_idx) {
37936 self.write_space();
37937 self.generate_where(w)?;
37938 }
37939 } }
37941 Expression::Var(v) if v.this == "UPDATE" => {
37942 self.write_keyword("UPDATE");
37943 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
37945 self.write(" *");
37946 if let Some(Expression::Where(w)) = elements.get(2) {
37947 self.write_space();
37948 self.generate_where(w)?;
37949 }
37950 } else if elements.len() > 1 {
37951 self.write_space();
37952 self.write_keyword("SET");
37953 if self.config.pretty {
37955 self.write_newline();
37956 self.indent_level += 1;
37957 self.write_indent();
37958 } else {
37959 self.write_space();
37960 }
37961 if let Expression::Tuple(assignments) = &elements[1] {
37962 for (i, assignment) in assignments.expressions.iter().enumerate() {
37963 if i > 0 {
37964 if self.config.pretty {
37965 self.write(",");
37966 self.write_newline();
37967 self.write_indent();
37968 } else {
37969 self.write(", ");
37970 }
37971 }
37972 if !self.merge_strip_qualifiers.is_empty() {
37974 self.generate_merge_set_assignment(assignment)?;
37975 } else {
37976 self.generate_expression(assignment)?;
37977 }
37978 }
37979 } else {
37980 self.generate_expression(&elements[1])?;
37981 }
37982 if self.config.pretty {
37983 self.indent_level -= 1;
37984 }
37985 if let Some(Expression::Where(w)) = elements.get(2) {
37986 self.write_space();
37987 self.generate_where(w)?;
37988 }
37989 }
37990 }
37991 Expression::Var(v) if v.this == "DELETE" => {
37992 self.write_keyword("DELETE");
37993 if let Some(Expression::Where(w)) = elements.get(1) {
37994 self.write_space();
37995 self.generate_where(w)?;
37996 }
37997 }
37998 _ => {
37999 self.generate_expression(action)?;
38001 }
38002 }
38003 }
38004 Expression::Var(v)
38005 if v.this == "INSERT"
38006 || v.this == "UPDATE"
38007 || v.this == "DELETE"
38008 || v.this == "DO NOTHING" =>
38009 {
38010 self.write_keyword(&v.this);
38011 }
38012 _ => {
38013 self.generate_expression(action)?;
38014 }
38015 }
38016 Ok(())
38017 }
38018
38019 fn generate_merge_set_assignment(&mut self, assignment: &Expression) -> Result<()> {
38021 match assignment {
38022 Expression::Eq(eq) => {
38023 let stripped_left = self.strip_merge_qualifier(&eq.left);
38025 self.generate_expression(&stripped_left)?;
38026 self.write(" = ");
38027 self.generate_expression(&eq.right)?;
38028 Ok(())
38029 }
38030 other => self.generate_expression(other),
38031 }
38032 }
38033
38034 fn strip_merge_qualifier(&self, expr: &Expression) -> Expression {
38036 match expr {
38037 Expression::Column(col) => {
38038 if let Some(ref table_ident) = col.table {
38039 if self
38040 .merge_strip_qualifiers
38041 .iter()
38042 .any(|n| n.eq_ignore_ascii_case(&table_ident.name))
38043 {
38044 let mut col = col.clone();
38046 col.table = None;
38047 return Expression::Column(col);
38048 }
38049 }
38050 expr.clone()
38051 }
38052 Expression::Dot(dot) => {
38053 if let Expression::Identifier(id) = &dot.this {
38055 if self
38056 .merge_strip_qualifiers
38057 .iter()
38058 .any(|n| n.eq_ignore_ascii_case(&id.name))
38059 {
38060 return Expression::Identifier(dot.field.clone());
38061 }
38062 }
38063 expr.clone()
38064 }
38065 _ => expr.clone(),
38066 }
38067 }
38068
38069 fn generate_whens(&mut self, e: &Whens) -> Result<()> {
38070 for (i, expr) in e.expressions.iter().enumerate() {
38072 if i > 0 {
38073 if self.config.pretty {
38075 self.write_newline();
38076 self.write_indent();
38077 } else {
38078 self.write_space();
38079 }
38080 }
38081 self.generate_expression(expr)?;
38082 }
38083 Ok(())
38084 }
38085
38086 fn generate_where(&mut self, e: &Where) -> Result<()> {
38087 self.write_keyword("WHERE");
38089 self.write_space();
38090 self.generate_expression(&e.this)?;
38091 Ok(())
38092 }
38093
38094 fn generate_width_bucket(&mut self, e: &WidthBucket) -> Result<()> {
38095 self.write_keyword("WIDTH_BUCKET");
38097 self.write("(");
38098 self.generate_expression(&e.this)?;
38099 if let Some(min_value) = &e.min_value {
38100 self.write(", ");
38101 self.generate_expression(min_value)?;
38102 }
38103 if let Some(max_value) = &e.max_value {
38104 self.write(", ");
38105 self.generate_expression(max_value)?;
38106 }
38107 if let Some(num_buckets) = &e.num_buckets {
38108 self.write(", ");
38109 self.generate_expression(num_buckets)?;
38110 }
38111 self.write(")");
38112 Ok(())
38113 }
38114
38115 fn generate_window(&mut self, e: &WindowSpec) -> Result<()> {
38116 self.generate_window_spec(e)
38118 }
38119
38120 fn generate_window_spec(&mut self, e: &WindowSpec) -> Result<()> {
38121 let mut has_content = false;
38123
38124 if !e.partition_by.is_empty() {
38126 self.write_keyword("PARTITION BY");
38127 self.write_space();
38128 for (i, expr) in e.partition_by.iter().enumerate() {
38129 if i > 0 {
38130 self.write(", ");
38131 }
38132 self.generate_expression(expr)?;
38133 }
38134 has_content = true;
38135 }
38136
38137 if !e.order_by.is_empty() {
38139 if has_content {
38140 self.write_space();
38141 }
38142 self.write_keyword("ORDER BY");
38143 self.write_space();
38144 for (i, ordered) in e.order_by.iter().enumerate() {
38145 if i > 0 {
38146 self.write(", ");
38147 }
38148 self.generate_expression(&ordered.this)?;
38149 if ordered.desc {
38150 self.write_space();
38151 self.write_keyword("DESC");
38152 } else if ordered.explicit_asc {
38153 self.write_space();
38154 self.write_keyword("ASC");
38155 }
38156 if let Some(nulls_first) = ordered.nulls_first {
38157 self.write_space();
38158 self.write_keyword("NULLS");
38159 self.write_space();
38160 if nulls_first {
38161 self.write_keyword("FIRST");
38162 } else {
38163 self.write_keyword("LAST");
38164 }
38165 }
38166 }
38167 has_content = true;
38168 }
38169
38170 if let Some(frame) = &e.frame {
38172 if has_content {
38173 self.write_space();
38174 }
38175 self.generate_window_frame(frame)?;
38176 }
38177
38178 Ok(())
38179 }
38180
38181 fn generate_with_data_property(&mut self, e: &WithDataProperty) -> Result<()> {
38182 self.write_keyword("WITH");
38184 self.write_space();
38185 if e.no.is_some() {
38186 self.write_keyword("NO");
38187 self.write_space();
38188 }
38189 self.write_keyword("DATA");
38190
38191 if let Some(statistics) = &e.statistics {
38193 self.write_space();
38194 self.write_keyword("AND");
38195 self.write_space();
38196 match statistics.as_ref() {
38198 Expression::Boolean(b) if !b.value => {
38199 self.write_keyword("NO");
38200 self.write_space();
38201 }
38202 _ => {}
38203 }
38204 self.write_keyword("STATISTICS");
38205 }
38206 Ok(())
38207 }
38208
38209 fn generate_with_fill(&mut self, e: &WithFill) -> Result<()> {
38210 self.write_keyword("WITH FILL");
38212
38213 if let Some(from_) = &e.from_ {
38214 self.write_space();
38215 self.write_keyword("FROM");
38216 self.write_space();
38217 self.generate_expression(from_)?;
38218 }
38219
38220 if let Some(to) = &e.to {
38221 self.write_space();
38222 self.write_keyword("TO");
38223 self.write_space();
38224 self.generate_expression(to)?;
38225 }
38226
38227 if let Some(step) = &e.step {
38228 self.write_space();
38229 self.write_keyword("STEP");
38230 self.write_space();
38231 self.generate_expression(step)?;
38232 }
38233
38234 if let Some(staleness) = &e.staleness {
38235 self.write_space();
38236 self.write_keyword("STALENESS");
38237 self.write_space();
38238 self.generate_expression(staleness)?;
38239 }
38240
38241 if let Some(interpolate) = &e.interpolate {
38242 self.write_space();
38243 self.write_keyword("INTERPOLATE");
38244 self.write(" (");
38245 self.generate_interpolate_item(interpolate)?;
38247 self.write(")");
38248 }
38249
38250 Ok(())
38251 }
38252
38253 fn generate_interpolate_item(&mut self, expr: &Expression) -> Result<()> {
38255 match expr {
38256 Expression::Alias(alias) => {
38257 self.generate_identifier(&alias.alias)?;
38259 self.write_space();
38260 self.write_keyword("AS");
38261 self.write_space();
38262 self.generate_expression(&alias.this)?;
38263 }
38264 Expression::Tuple(tuple) => {
38265 for (i, item) in tuple.expressions.iter().enumerate() {
38266 if i > 0 {
38267 self.write(", ");
38268 }
38269 self.generate_interpolate_item(item)?;
38270 }
38271 }
38272 other => {
38273 self.generate_expression(other)?;
38274 }
38275 }
38276 Ok(())
38277 }
38278
38279 fn generate_with_journal_table_property(&mut self, e: &WithJournalTableProperty) -> Result<()> {
38280 self.write_keyword("WITH JOURNAL TABLE");
38282 self.write("=");
38283 self.generate_expression(&e.this)?;
38284 Ok(())
38285 }
38286
38287 fn generate_with_operator(&mut self, e: &WithOperator) -> Result<()> {
38288 self.generate_expression(&e.this)?;
38290 self.write_space();
38291 self.write_keyword("WITH");
38292 self.write_space();
38293 self.write_keyword(&e.op);
38294 Ok(())
38295 }
38296
38297 fn generate_with_procedure_options(&mut self, e: &WithProcedureOptions) -> Result<()> {
38298 self.write_keyword("WITH");
38300 self.write_space();
38301 for (i, expr) in e.expressions.iter().enumerate() {
38302 if i > 0 {
38303 self.write(", ");
38304 }
38305 self.generate_expression(expr)?;
38306 }
38307 Ok(())
38308 }
38309
38310 fn generate_with_schema_binding_property(
38311 &mut self,
38312 e: &WithSchemaBindingProperty,
38313 ) -> Result<()> {
38314 self.write_keyword("WITH");
38316 self.write_space();
38317 self.generate_expression(&e.this)?;
38318 Ok(())
38319 }
38320
38321 fn generate_with_system_versioning_property(
38322 &mut self,
38323 e: &WithSystemVersioningProperty,
38324 ) -> Result<()> {
38325 let mut parts = Vec::new();
38331
38332 if let Some(this) = &e.this {
38333 let mut s = String::from("HISTORY_TABLE=");
38335 let mut gen = Generator::new();
38336 gen.generate_expression(this)?;
38337 s.push_str(&gen.output);
38338 parts.push(s);
38339 }
38340
38341 if let Some(data_consistency) = &e.data_consistency {
38342 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
38343 let mut gen = Generator::new();
38344 gen.generate_expression(data_consistency)?;
38345 s.push_str(&gen.output);
38346 parts.push(s);
38347 }
38348
38349 if let Some(retention_period) = &e.retention_period {
38350 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
38351 let mut gen = Generator::new();
38352 gen.generate_expression(retention_period)?;
38353 s.push_str(&gen.output);
38354 parts.push(s);
38355 }
38356
38357 self.write_keyword("SYSTEM_VERSIONING");
38358 self.write("=");
38359
38360 if !parts.is_empty() {
38361 self.write_keyword("ON");
38362 self.write("(");
38363 self.write(&parts.join(", "));
38364 self.write(")");
38365 } else if e.on.is_some() {
38366 self.write_keyword("ON");
38367 } else {
38368 self.write_keyword("OFF");
38369 }
38370
38371 if e.with_.is_some() {
38373 let inner = self.output.clone();
38374 self.output.clear();
38375 self.write("WITH(");
38376 self.write(&inner);
38377 self.write(")");
38378 }
38379
38380 Ok(())
38381 }
38382
38383 fn generate_with_table_hint(&mut self, e: &WithTableHint) -> Result<()> {
38384 self.write_keyword("WITH");
38386 self.write(" (");
38387 for (i, expr) in e.expressions.iter().enumerate() {
38388 if i > 0 {
38389 self.write(", ");
38390 }
38391 self.generate_expression(expr)?;
38392 }
38393 self.write(")");
38394 Ok(())
38395 }
38396
38397 fn generate_xml_element(&mut self, e: &XMLElement) -> Result<()> {
38398 self.write_keyword("XMLELEMENT");
38401 self.write("(");
38402
38403 if e.evalname.is_some() {
38404 self.write_keyword("EVALNAME");
38405 } else {
38406 self.write_keyword("NAME");
38407 }
38408 self.write_space();
38409 self.generate_expression(&e.this)?;
38410
38411 for expr in &e.expressions {
38412 self.write(", ");
38413 self.generate_expression(expr)?;
38414 }
38415 self.write(")");
38416 Ok(())
38417 }
38418
38419 fn generate_xml_get(&mut self, e: &XMLGet) -> Result<()> {
38420 self.write_keyword("XMLGET");
38422 self.write("(");
38423 self.generate_expression(&e.this)?;
38424 self.write(", ");
38425 self.generate_expression(&e.expression)?;
38426 if let Some(instance) = &e.instance {
38427 self.write(", ");
38428 self.generate_expression(instance)?;
38429 }
38430 self.write(")");
38431 Ok(())
38432 }
38433
38434 fn generate_xml_key_value_option(&mut self, e: &XMLKeyValueOption) -> Result<()> {
38435 self.generate_expression(&e.this)?;
38437 if let Some(expression) = &e.expression {
38438 self.write("(");
38439 self.generate_expression(expression)?;
38440 self.write(")");
38441 }
38442 Ok(())
38443 }
38444
38445 fn generate_xml_table(&mut self, e: &XMLTable) -> Result<()> {
38446 self.write_keyword("XMLTABLE");
38448 self.write("(");
38449
38450 if self.config.pretty {
38451 self.indent_level += 1;
38452 self.write_newline();
38453 self.write_indent();
38454 self.generate_expression(&e.this)?;
38455
38456 if let Some(passing) = &e.passing {
38457 self.write_newline();
38458 self.write_indent();
38459 self.write_keyword("PASSING");
38460 if let Expression::Tuple(tuple) = passing.as_ref() {
38461 for expr in &tuple.expressions {
38462 self.write_newline();
38463 self.indent_level += 1;
38464 self.write_indent();
38465 self.generate_expression(expr)?;
38466 self.indent_level -= 1;
38467 }
38468 } else {
38469 self.write_newline();
38470 self.indent_level += 1;
38471 self.write_indent();
38472 self.generate_expression(passing)?;
38473 self.indent_level -= 1;
38474 }
38475 }
38476
38477 if e.by_ref.is_some() {
38478 self.write_newline();
38479 self.write_indent();
38480 self.write_keyword("RETURNING SEQUENCE BY REF");
38481 }
38482
38483 if !e.columns.is_empty() {
38484 self.write_newline();
38485 self.write_indent();
38486 self.write_keyword("COLUMNS");
38487 for (i, col) in e.columns.iter().enumerate() {
38488 self.write_newline();
38489 self.indent_level += 1;
38490 self.write_indent();
38491 self.generate_expression(col)?;
38492 self.indent_level -= 1;
38493 if i < e.columns.len() - 1 {
38494 self.write(",");
38495 }
38496 }
38497 }
38498
38499 self.indent_level -= 1;
38500 self.write_newline();
38501 self.write_indent();
38502 self.write(")");
38503 return Ok(());
38504 }
38505
38506 if let Some(namespaces) = &e.namespaces {
38508 self.write_keyword("XMLNAMESPACES");
38509 self.write("(");
38510 if let Expression::Tuple(tuple) = namespaces.as_ref() {
38512 for (i, expr) in tuple.expressions.iter().enumerate() {
38513 if i > 0 {
38514 self.write(", ");
38515 }
38516 if !matches!(expr, Expression::Alias(_)) {
38519 self.write_keyword("DEFAULT");
38520 self.write_space();
38521 }
38522 self.generate_expression(expr)?;
38523 }
38524 } else {
38525 if !matches!(namespaces.as_ref(), Expression::Alias(_)) {
38527 self.write_keyword("DEFAULT");
38528 self.write_space();
38529 }
38530 self.generate_expression(namespaces)?;
38531 }
38532 self.write("), ");
38533 }
38534
38535 self.generate_expression(&e.this)?;
38537
38538 if let Some(passing) = &e.passing {
38540 self.write_space();
38541 self.write_keyword("PASSING");
38542 self.write_space();
38543 if let Expression::Tuple(tuple) = passing.as_ref() {
38545 for (i, expr) in tuple.expressions.iter().enumerate() {
38546 if i > 0 {
38547 self.write(", ");
38548 }
38549 self.generate_expression(expr)?;
38550 }
38551 } else {
38552 self.generate_expression(passing)?;
38553 }
38554 }
38555
38556 if e.by_ref.is_some() {
38558 self.write_space();
38559 self.write_keyword("RETURNING SEQUENCE BY REF");
38560 }
38561
38562 if !e.columns.is_empty() {
38564 self.write_space();
38565 self.write_keyword("COLUMNS");
38566 self.write_space();
38567 for (i, col) in e.columns.iter().enumerate() {
38568 if i > 0 {
38569 self.write(", ");
38570 }
38571 self.generate_expression(col)?;
38572 }
38573 }
38574
38575 self.write(")");
38576 Ok(())
38577 }
38578
38579 fn generate_xor(&mut self, e: &Xor) -> Result<()> {
38580 if let Some(this) = &e.this {
38583 self.generate_expression(this)?;
38584 if let Some(expression) = &e.expression {
38585 self.write_space();
38586 self.write_keyword("XOR");
38587 self.write_space();
38588 self.generate_expression(expression)?;
38589 }
38590 }
38591
38592 for (i, expr) in e.expressions.iter().enumerate() {
38594 if i > 0 || e.this.is_some() {
38595 self.write_space();
38596 self.write_keyword("XOR");
38597 self.write_space();
38598 }
38599 self.generate_expression(expr)?;
38600 }
38601 Ok(())
38602 }
38603
38604 fn generate_zipf(&mut self, e: &Zipf) -> Result<()> {
38605 self.write_keyword("ZIPF");
38607 self.write("(");
38608 self.generate_expression(&e.this)?;
38609 if let Some(elementcount) = &e.elementcount {
38610 self.write(", ");
38611 self.generate_expression(elementcount)?;
38612 }
38613 if let Some(gen) = &e.gen {
38614 self.write(", ");
38615 self.generate_expression(gen)?;
38616 }
38617 self.write(")");
38618 Ok(())
38619 }
38620}
38621
38622impl Default for Generator {
38623 fn default() -> Self {
38624 Self::new()
38625 }
38626}
38627
38628#[cfg(test)]
38629mod tests {
38630 use super::*;
38631 use crate::parser::Parser;
38632
38633 fn roundtrip(sql: &str) -> String {
38634 let ast = Parser::parse_sql(sql).unwrap();
38635 Generator::sql(&ast[0]).unwrap()
38636 }
38637
38638 #[test]
38639 fn test_simple_select() {
38640 let result = roundtrip("SELECT 1");
38641 assert_eq!(result, "SELECT 1");
38642 }
38643
38644 #[test]
38645 fn test_select_from() {
38646 let result = roundtrip("SELECT a, b FROM t");
38647 assert_eq!(result, "SELECT a, b FROM t");
38648 }
38649
38650 #[test]
38651 fn test_select_where() {
38652 let result = roundtrip("SELECT * FROM t WHERE x = 1");
38653 assert_eq!(result, "SELECT * FROM t WHERE x = 1");
38654 }
38655
38656 #[test]
38657 fn test_select_join() {
38658 let result = roundtrip("SELECT * FROM a JOIN b ON a.id = b.id");
38659 assert_eq!(result, "SELECT * FROM a JOIN b ON a.id = b.id");
38660 }
38661
38662 #[test]
38663 fn test_insert() {
38664 let result = roundtrip("INSERT INTO t (a, b) VALUES (1, 2)");
38665 assert_eq!(result, "INSERT INTO t (a, b) VALUES (1, 2)");
38666 }
38667
38668 #[test]
38669 fn test_pretty_print() {
38670 let ast = Parser::parse_sql("SELECT a, b FROM t WHERE x = 1").unwrap();
38671 let result = Generator::pretty_sql(&ast[0]).unwrap();
38672 assert!(result.contains('\n'));
38673 }
38674
38675 #[test]
38676 fn test_window_function() {
38677 let result = roundtrip("SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)");
38678 assert_eq!(
38679 result,
38680 "SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)"
38681 );
38682 }
38683
38684 #[test]
38685 fn test_window_function_with_frame() {
38686 let result = roundtrip("SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
38687 assert_eq!(result, "SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
38688 }
38689
38690 #[test]
38691 fn test_aggregate_with_filter() {
38692 let result = roundtrip("SELECT COUNT(*) FILTER (WHERE status = 1) FROM orders");
38693 assert_eq!(
38694 result,
38695 "SELECT COUNT(*) FILTER(WHERE status = 1) FROM orders"
38696 );
38697 }
38698
38699 #[test]
38700 fn test_subscript() {
38701 let result = roundtrip("SELECT arr[0]");
38702 assert_eq!(result, "SELECT arr[0]");
38703 }
38704
38705 #[test]
38707 fn test_create_table() {
38708 let result = roundtrip("CREATE TABLE users (id INT, name VARCHAR(100))");
38709 assert_eq!(result, "CREATE TABLE users (id INT, name VARCHAR(100))");
38710 }
38711
38712 #[test]
38713 fn test_create_table_with_constraints() {
38714 let result = roundtrip(
38715 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)",
38716 );
38717 assert_eq!(
38718 result,
38719 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)"
38720 );
38721 }
38722
38723 #[test]
38724 fn test_create_table_if_not_exists() {
38725 let result = roundtrip("CREATE TABLE IF NOT EXISTS t (id INT)");
38726 assert_eq!(result, "CREATE TABLE IF NOT EXISTS t (id INT)");
38727 }
38728
38729 #[test]
38730 fn test_drop_table() {
38731 let result = roundtrip("DROP TABLE users");
38732 assert_eq!(result, "DROP TABLE users");
38733 }
38734
38735 #[test]
38736 fn test_drop_table_if_exists_cascade() {
38737 let result = roundtrip("DROP TABLE IF EXISTS users CASCADE");
38738 assert_eq!(result, "DROP TABLE IF EXISTS users CASCADE");
38739 }
38740
38741 #[test]
38742 fn test_alter_table_add_column() {
38743 let result = roundtrip("ALTER TABLE users ADD COLUMN email VARCHAR(255)");
38744 assert_eq!(result, "ALTER TABLE users ADD COLUMN email VARCHAR(255)");
38745 }
38746
38747 #[test]
38748 fn test_alter_table_drop_column() {
38749 let result = roundtrip("ALTER TABLE users DROP COLUMN email");
38750 assert_eq!(result, "ALTER TABLE users DROP COLUMN email");
38751 }
38752
38753 #[test]
38754 fn test_create_index() {
38755 let result = roundtrip("CREATE INDEX idx_name ON users(name)");
38756 assert_eq!(result, "CREATE INDEX idx_name ON users(name)");
38757 }
38758
38759 #[test]
38760 fn test_create_unique_index() {
38761 let result = roundtrip("CREATE UNIQUE INDEX idx_email ON users(email)");
38762 assert_eq!(result, "CREATE UNIQUE INDEX idx_email ON users(email)");
38763 }
38764
38765 #[test]
38766 fn test_drop_index() {
38767 let result = roundtrip("DROP INDEX idx_name");
38768 assert_eq!(result, "DROP INDEX idx_name");
38769 }
38770
38771 #[test]
38772 fn test_create_view() {
38773 let result = roundtrip("CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1");
38774 assert_eq!(
38775 result,
38776 "CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1"
38777 );
38778 }
38779
38780 #[test]
38781 fn test_drop_view() {
38782 let result = roundtrip("DROP VIEW active_users");
38783 assert_eq!(result, "DROP VIEW active_users");
38784 }
38785
38786 #[test]
38787 fn test_truncate() {
38788 let result = roundtrip("TRUNCATE TABLE users");
38789 assert_eq!(result, "TRUNCATE TABLE users");
38790 }
38791
38792 #[test]
38793 fn test_string_literal_escaping_default() {
38794 let result = roundtrip("SELECT 'hello'");
38796 assert_eq!(result, "SELECT 'hello'");
38797
38798 let result = roundtrip("SELECT 'it''s a test'");
38800 assert_eq!(result, "SELECT 'it''s a test'");
38801 }
38802
38803 #[test]
38804 fn test_not_in_style_prefix_default_generic() {
38805 let result = roundtrip("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')");
38806 assert_eq!(
38807 result,
38808 "SELECT id FROM users WHERE NOT status IN ('deleted', 'banned')"
38809 );
38810 }
38811
38812 #[test]
38813 fn test_not_in_style_infix_generic_override() {
38814 let ast =
38815 Parser::parse_sql("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')")
38816 .unwrap();
38817 let config = GeneratorConfig {
38818 not_in_style: NotInStyle::Infix,
38819 ..Default::default()
38820 };
38821 let mut gen = Generator::with_config(config);
38822 let result = gen.generate(&ast[0]).unwrap();
38823 assert_eq!(
38824 result,
38825 "SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')"
38826 );
38827 }
38828
38829 #[test]
38830 fn test_string_literal_escaping_mysql() {
38831 use crate::dialects::DialectType;
38832
38833 let config = GeneratorConfig {
38834 dialect: Some(DialectType::MySQL),
38835 ..Default::default()
38836 };
38837
38838 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
38839 let mut gen = Generator::with_config(config.clone());
38840 let result = gen.generate(&ast[0]).unwrap();
38841 assert_eq!(result, "SELECT 'hello'");
38842
38843 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
38845 let mut gen = Generator::with_config(config.clone());
38846 let result = gen.generate(&ast[0]).unwrap();
38847 assert_eq!(result, "SELECT 'it''s'");
38848 }
38849
38850 #[test]
38851 fn test_string_literal_escaping_postgres() {
38852 use crate::dialects::DialectType;
38853
38854 let config = GeneratorConfig {
38855 dialect: Some(DialectType::PostgreSQL),
38856 ..Default::default()
38857 };
38858
38859 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
38860 let mut gen = Generator::with_config(config.clone());
38861 let result = gen.generate(&ast[0]).unwrap();
38862 assert_eq!(result, "SELECT 'hello'");
38863
38864 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
38866 let mut gen = Generator::with_config(config.clone());
38867 let result = gen.generate(&ast[0]).unwrap();
38868 assert_eq!(result, "SELECT 'it''s'");
38869 }
38870
38871 #[test]
38872 fn test_string_literal_escaping_bigquery() {
38873 use crate::dialects::DialectType;
38874
38875 let config = GeneratorConfig {
38876 dialect: Some(DialectType::BigQuery),
38877 ..Default::default()
38878 };
38879
38880 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
38881 let mut gen = Generator::with_config(config.clone());
38882 let result = gen.generate(&ast[0]).unwrap();
38883 assert_eq!(result, "SELECT 'hello'");
38884
38885 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
38887 let mut gen = Generator::with_config(config.clone());
38888 let result = gen.generate(&ast[0]).unwrap();
38889 assert_eq!(result, "SELECT 'it\\'s'");
38890 }
38891
38892 #[test]
38893 fn test_generate_deep_and_chain_without_stack_growth() {
38894 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
38895 Expression::column("c0"),
38896 Expression::number(0),
38897 )));
38898
38899 for i in 1..2500 {
38900 let predicate = Expression::Eq(Box::new(BinaryOp::new(
38901 Expression::column(format!("c{i}")),
38902 Expression::number(i as i64),
38903 )));
38904 expr = Expression::And(Box::new(BinaryOp::new(expr, predicate)));
38905 }
38906
38907 let sql = Generator::sql(&expr).expect("deep AND chain should generate");
38908 assert!(sql.contains("c2499 = 2499"), "{}", sql);
38909 }
38910
38911 #[test]
38912 fn test_generate_deep_or_chain_without_stack_growth() {
38913 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
38914 Expression::column("c0"),
38915 Expression::number(0),
38916 )));
38917
38918 for i in 1..2500 {
38919 let predicate = Expression::Eq(Box::new(BinaryOp::new(
38920 Expression::column(format!("c{i}")),
38921 Expression::number(i as i64),
38922 )));
38923 expr = Expression::Or(Box::new(BinaryOp::new(expr, predicate)));
38924 }
38925
38926 let sql = Generator::sql(&expr).expect("deep OR chain should generate");
38927 assert!(sql.contains("c2499 = 2499"), "{}", sql);
38928 }
38929}