1use crate::error::Result;
14use crate::expressions::*;
15use crate::DialectType;
16
17pub struct Generator {
42 config: GeneratorConfig,
43 output: String,
44 unsupported_messages: Vec<String>,
45 indent_level: usize,
46 athena_hive_context: bool,
49 sqlite_inline_pk_columns: std::collections::HashSet<String>,
51 merge_strip_qualifiers: Vec<String>,
53 clickhouse_nullable_depth: i32,
58}
59
60#[derive(Debug, Clone, Copy, PartialEq, Default)]
66pub enum NormalizeFunctions {
67 #[default]
69 Upper,
70 Lower,
72 None,
74}
75
76#[derive(Debug, Clone, Copy, PartialEq, Default)]
78pub enum LimitFetchStyle {
79 #[default]
81 Limit,
82 Top,
84 FetchFirst,
86}
87
88#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
90pub enum NotInStyle {
91 #[default]
93 Prefix,
94 Infix,
96}
97
98#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
100pub enum UnsupportedLevel {
101 Ignore,
103 #[default]
105 Warn,
106 Raise,
108 Immediate,
110}
111
112#[derive(Debug, Clone, Copy, PartialEq, Eq)]
113enum ConnectorOperator {
114 And,
115 Or,
116}
117
118impl ConnectorOperator {
119 fn keyword(self) -> &'static str {
120 match self {
121 Self::And => "AND",
122 Self::Or => "OR",
123 }
124 }
125}
126
127#[derive(Debug, Clone, Copy, PartialEq)]
129pub struct IdentifierQuoteStyle {
130 pub start: char,
132 pub end: char,
134}
135
136impl Default for IdentifierQuoteStyle {
137 fn default() -> Self {
138 Self {
139 start: '"',
140 end: '"',
141 }
142 }
143}
144
145impl IdentifierQuoteStyle {
146 pub const DOUBLE_QUOTE: Self = Self {
148 start: '"',
149 end: '"',
150 };
151 pub const BACKTICK: Self = Self {
153 start: '`',
154 end: '`',
155 };
156 pub const BRACKET: Self = Self {
158 start: '[',
159 end: ']',
160 };
161}
162
163#[derive(Debug, Clone)]
185pub struct GeneratorConfig {
186 pub pretty: bool,
189 pub indent: String,
191 pub max_text_width: usize,
193 pub identifier_quote: char,
195 pub identifier_quote_style: IdentifierQuoteStyle,
197 pub uppercase_keywords: bool,
199 pub normalize_identifiers: bool,
201 pub dialect: Option<crate::dialects::DialectType>,
203 pub source_dialect: Option<crate::dialects::DialectType>,
205 pub unsupported_level: UnsupportedLevel,
207 pub max_unsupported: usize,
209 pub normalize_functions: NormalizeFunctions,
211 pub string_escape: char,
213 pub case_sensitive_identifiers: bool,
215 pub identifiers_can_start_with_digit: bool,
217 pub always_quote_identifiers: bool,
220 pub not_in_style: NotInStyle,
222
223 pub null_ordering_supported: bool,
227 pub ignore_nulls_in_func: bool,
230 pub nvl2_supported: bool,
232
233 pub limit_fetch_style: LimitFetchStyle,
236 pub limit_is_top: bool,
238 pub limit_only_literals: bool,
240
241 pub single_string_interval: bool,
244 pub interval_allows_plural_form: bool,
246
247 pub cte_recursive_keyword_required: bool,
250
251 pub values_as_table: bool,
254 pub wrap_derived_values: bool,
256
257 pub tablesample_seed_keyword: &'static str,
260 pub tablesample_requires_parens: bool,
262 pub tablesample_size_is_rows: bool,
264 pub tablesample_keywords: &'static str,
266 pub tablesample_with_method: bool,
268 pub alias_post_tablesample: bool,
270
271 pub aggregate_filter_supported: bool,
274 pub multi_arg_distinct: bool,
276 pub quantified_no_paren_space: bool,
278 pub supports_median: bool,
280
281 pub supports_select_into: bool,
284 pub locking_reads_supported: bool,
286
287 pub rename_table_with_db: bool,
290 pub semi_anti_join_with_side: bool,
292 pub supports_table_alias_columns: bool,
294 pub join_hints: bool,
296 pub table_hints: bool,
298 pub query_hints: bool,
300 pub query_hint_sep: &'static str,
302 pub supports_column_join_marks: bool,
304
305 pub index_using_no_space: bool,
309 pub supports_unlogged_tables: bool,
311 pub supports_create_table_like: bool,
313 pub like_property_inside_schema: bool,
315 pub alter_table_include_column_keyword: bool,
317 pub supports_table_copy: bool,
319 pub alter_set_type: &'static str,
321 pub alter_set_wrapped: bool,
323
324 pub tz_to_with_time_zone: bool,
327 pub supports_convert_timezone: bool,
329
330 pub json_type_required_for_extraction: bool,
333 pub json_path_bracketed_key_supported: bool,
335 pub json_path_single_quote_escape: bool,
337 pub quote_json_path: bool,
339 pub json_key_value_pair_sep: &'static str,
341
342 pub copy_params_are_wrapped: bool,
345 pub copy_params_eq_required: bool,
347 pub copy_has_into_keyword: bool,
349
350 pub supports_window_exclude: bool,
353 pub unnest_with_ordinality: bool,
355 pub lowercase_window_frame_keywords: bool,
358 pub normalize_window_frame_between: bool,
361
362 pub array_concat_is_var_len: bool,
365 pub array_size_dim_required: Option<bool>,
368 pub can_implement_array_any: bool,
370 pub array_size_name: &'static str,
372
373 pub supports_between_flags: bool,
376
377 pub is_bool_allowed: bool,
380 pub ensure_bools: bool,
382
383 pub extract_allows_quotes: bool,
386 pub normalize_extract_date_parts: bool,
388
389 pub try_supported: bool,
392 pub supports_uescape: bool,
394 pub supports_to_number: bool,
396 pub supports_single_arg_concat: bool,
398 pub last_day_supports_date_part: bool,
400 pub supports_exploding_projections: bool,
402 pub supports_unix_seconds: bool,
404 pub supports_like_quantifiers: bool,
406 pub supports_decode_case: bool,
408 pub set_op_modifiers: bool,
410 pub update_statement_supports_from: bool,
412
413 pub collate_is_func: bool,
416
417 pub duplicate_key_update_with_set: bool,
420 pub insert_overwrite: &'static str,
422
423 pub returning_end: bool,
426
427 pub matched_by_source: bool,
430
431 pub create_function_return_as: bool,
434 pub parameter_default_equals: bool,
436
437 pub computed_column_with_type: bool,
440
441 pub unpivot_aliases_are_identifiers: bool,
444
445 pub star_except: &'static str,
448
449 pub hex_func: &'static str,
452
453 pub with_properties_prefix: &'static str,
456
457 pub pad_fill_pattern_is_required: bool,
460
461 pub index_on: &'static str,
464
465 pub groupings_sep: &'static str,
468
469 pub struct_delimiter: (&'static str, &'static str),
472 pub struct_curly_brace_notation: bool,
474 pub array_bracket_only: bool,
476 pub struct_field_sep: &'static str,
478
479 pub except_intersect_support_all_clause: bool,
482
483 pub parameter_token: &'static str,
486 pub named_placeholder_token: &'static str,
488
489 pub data_type_specifiers_allowed: bool,
492
493 pub schema_comment_with_eq: bool,
497}
498
499impl Default for GeneratorConfig {
500 fn default() -> Self {
501 Self {
502 pretty: false,
504 indent: " ".to_string(),
505 max_text_width: 80,
506 identifier_quote: '"',
507 identifier_quote_style: IdentifierQuoteStyle::DOUBLE_QUOTE,
508 uppercase_keywords: true,
509 normalize_identifiers: false,
510 dialect: None,
511 source_dialect: None,
512 unsupported_level: UnsupportedLevel::Warn,
513 max_unsupported: 3,
514 normalize_functions: NormalizeFunctions::Upper,
515 string_escape: '\'',
516 case_sensitive_identifiers: false,
517 identifiers_can_start_with_digit: false,
518 always_quote_identifiers: false,
519 not_in_style: NotInStyle::Prefix,
520
521 null_ordering_supported: true,
523 ignore_nulls_in_func: false,
524 nvl2_supported: true,
525
526 limit_fetch_style: LimitFetchStyle::Limit,
528 limit_is_top: false,
529 limit_only_literals: false,
530
531 single_string_interval: false,
533 interval_allows_plural_form: true,
534
535 cte_recursive_keyword_required: true,
537
538 values_as_table: true,
540 wrap_derived_values: true,
541
542 tablesample_seed_keyword: "SEED",
544 tablesample_requires_parens: true,
545 tablesample_size_is_rows: true,
546 tablesample_keywords: "TABLESAMPLE",
547 tablesample_with_method: true,
548 alias_post_tablesample: false,
549
550 aggregate_filter_supported: true,
552 multi_arg_distinct: true,
553 quantified_no_paren_space: false,
554 supports_median: true,
555
556 supports_select_into: false,
558 locking_reads_supported: true,
559
560 rename_table_with_db: true,
562 semi_anti_join_with_side: true,
563 supports_table_alias_columns: true,
564 join_hints: true,
565 table_hints: true,
566 query_hints: true,
567 query_hint_sep: ", ",
568 supports_column_join_marks: false,
569
570 index_using_no_space: false,
572 supports_unlogged_tables: false,
573 supports_create_table_like: true,
574 like_property_inside_schema: false,
575 alter_table_include_column_keyword: true,
576 supports_table_copy: true,
577 alter_set_type: "SET DATA TYPE",
578 alter_set_wrapped: false,
579
580 tz_to_with_time_zone: false,
582 supports_convert_timezone: false,
583
584 json_type_required_for_extraction: false,
586 json_path_bracketed_key_supported: true,
587 json_path_single_quote_escape: false,
588 quote_json_path: true,
589 json_key_value_pair_sep: ":",
590
591 copy_params_are_wrapped: true,
593 copy_params_eq_required: false,
594 copy_has_into_keyword: true,
595
596 supports_window_exclude: false,
598 unnest_with_ordinality: true,
599 lowercase_window_frame_keywords: false,
600 normalize_window_frame_between: false,
601
602 array_concat_is_var_len: true,
604 array_size_dim_required: None,
605 can_implement_array_any: false,
606 array_size_name: "ARRAY_LENGTH",
607
608 supports_between_flags: false,
610
611 is_bool_allowed: true,
613 ensure_bools: false,
614
615 extract_allows_quotes: true,
617 normalize_extract_date_parts: false,
618
619 try_supported: true,
621 supports_uescape: true,
622 supports_to_number: true,
623 supports_single_arg_concat: true,
624 last_day_supports_date_part: true,
625 supports_exploding_projections: true,
626 supports_unix_seconds: false,
627 supports_like_quantifiers: true,
628 supports_decode_case: true,
629 set_op_modifiers: true,
630 update_statement_supports_from: true,
631
632 collate_is_func: false,
634
635 duplicate_key_update_with_set: true,
637 insert_overwrite: " OVERWRITE TABLE",
638
639 returning_end: true,
641
642 matched_by_source: true,
644
645 create_function_return_as: true,
647 parameter_default_equals: false,
648
649 computed_column_with_type: true,
651
652 unpivot_aliases_are_identifiers: true,
654
655 star_except: "EXCEPT",
657
658 hex_func: "HEX",
660
661 with_properties_prefix: "WITH",
663
664 pad_fill_pattern_is_required: false,
666
667 index_on: "ON",
669
670 groupings_sep: ",",
672
673 struct_delimiter: ("<", ">"),
675 struct_curly_brace_notation: false,
676 array_bracket_only: false,
677 struct_field_sep: " ",
678
679 except_intersect_support_all_clause: true,
681
682 parameter_token: "@",
684 named_placeholder_token: ":",
685
686 data_type_specifiers_allowed: false,
688
689 schema_comment_with_eq: true,
691 }
692 }
693}
694
695mod reserved_keywords {
698 use std::collections::HashSet;
699 use std::sync::LazyLock;
700
701 pub static SQL_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
703 [
704 "all",
705 "alter",
706 "and",
707 "any",
708 "array",
709 "as",
710 "asc",
711 "at",
712 "authorization",
713 "begin",
714 "between",
715 "both",
716 "by",
717 "case",
718 "cast",
719 "check",
720 "collate",
721 "column",
722 "commit",
723 "constraint",
724 "create",
725 "cross",
726 "cube",
727 "current",
728 "current_date",
729 "current_time",
730 "current_timestamp",
731 "current_user",
732 "default",
733 "delete",
734 "desc",
735 "distinct",
736 "drop",
737 "else",
738 "end",
739 "escape",
740 "except",
741 "execute",
742 "exists",
743 "external",
744 "false",
745 "fetch",
746 "filter",
747 "for",
748 "foreign",
749 "from",
750 "full",
751 "function",
752 "grant",
753 "group",
754 "grouping",
755 "having",
756 "if",
757 "in",
758 "index",
759 "inner",
760 "insert",
761 "intersect",
762 "interval",
763 "into",
764 "is",
765 "join",
766 "key",
767 "leading",
768 "left",
769 "like",
770 "limit",
771 "local",
772 "localtime",
773 "localtimestamp",
774 "match",
775 "merge",
776 "natural",
777 "no",
778 "not",
779 "null",
780 "of",
781 "offset",
782 "on",
783 "only",
784 "or",
785 "order",
786 "outer",
787 "over",
788 "partition",
789 "primary",
790 "procedure",
791 "range",
792 "references",
793 "right",
794 "rollback",
795 "rollup",
796 "row",
797 "rows",
798 "select",
799 "session_user",
800 "set",
801 "some",
802 "table",
803 "tablesample",
804 "then",
805 "to",
806 "trailing",
807 "true",
808 "truncate",
809 "union",
810 "unique",
811 "unknown",
812 "update",
813 "user",
814 "using",
815 "values",
816 "view",
817 "when",
818 "where",
819 "window",
820 "with",
821 ]
822 .into_iter()
823 .collect()
824 });
825
826 pub static BIGQUERY_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
829 let mut set = SQL_RESERVED.clone();
830 set.extend([
831 "assert_rows_modified",
832 "at",
833 "contains",
834 "cube",
835 "current",
836 "define",
837 "enum",
838 "escape",
839 "exclude",
840 "following",
841 "for",
842 "groups",
843 "hash",
844 "ignore",
845 "lateral",
846 "lookup",
847 "new",
848 "no",
849 "nulls",
850 "of",
851 "over",
852 "preceding",
853 "proto",
854 "qualify",
855 "recursive",
856 "respect",
857 "struct",
858 "tablesample",
859 "treat",
860 "unbounded",
861 "unnest",
862 "window",
863 "within",
864 ]);
865 set.remove("grant");
867 set.remove("key");
868 set.remove("index");
869 set.remove("values");
870 set.remove("table");
871 set
872 });
873
874 pub static MYSQL_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
876 let mut set = SQL_RESERVED.clone();
877 set.extend([
878 "accessible",
879 "add",
880 "analyze",
881 "asensitive",
882 "before",
883 "bigint",
884 "binary",
885 "blob",
886 "call",
887 "cascade",
888 "change",
889 "char",
890 "character",
891 "condition",
892 "continue",
893 "convert",
894 "current_date",
895 "current_time",
896 "current_timestamp",
897 "current_user",
898 "cursor",
899 "database",
900 "databases",
901 "day_hour",
902 "day_microsecond",
903 "day_minute",
904 "day_second",
905 "dec",
906 "decimal",
907 "declare",
908 "delayed",
909 "describe",
910 "deterministic",
911 "distinctrow",
912 "div",
913 "double",
914 "dual",
915 "each",
916 "elseif",
917 "enclosed",
918 "escaped",
919 "exit",
920 "explain",
921 "float",
922 "float4",
923 "float8",
924 "force",
925 "get",
926 "high_priority",
927 "hour_microsecond",
928 "hour_minute",
929 "hour_second",
930 "ignore",
931 "infile",
932 "inout",
933 "insensitive",
934 "int",
935 "int1",
936 "int2",
937 "int3",
938 "int4",
939 "int8",
940 "integer",
941 "iterate",
942 "keys",
943 "kill",
944 "leave",
945 "linear",
946 "lines",
947 "load",
948 "lock",
949 "long",
950 "longblob",
951 "longtext",
952 "loop",
953 "low_priority",
954 "master_ssl_verify_server_cert",
955 "maxvalue",
956 "mediumblob",
957 "mediumint",
958 "mediumtext",
959 "middleint",
960 "minute_microsecond",
961 "minute_second",
962 "mod",
963 "modifies",
964 "no_write_to_binlog",
965 "numeric",
966 "optimize",
967 "option",
968 "optionally",
969 "out",
970 "outfile",
971 "precision",
972 "purge",
973 "read",
974 "reads",
975 "real",
976 "regexp",
977 "release",
978 "rename",
979 "repeat",
980 "replace",
981 "require",
982 "resignal",
983 "restrict",
984 "return",
985 "revoke",
986 "rlike",
987 "schema",
988 "schemas",
989 "second_microsecond",
990 "sensitive",
991 "separator",
992 "show",
993 "signal",
994 "smallint",
995 "spatial",
996 "specific",
997 "sql",
998 "sql_big_result",
999 "sql_calc_found_rows",
1000 "sql_small_result",
1001 "sqlexception",
1002 "sqlstate",
1003 "sqlwarning",
1004 "ssl",
1005 "starting",
1006 "straight_join",
1007 "terminated",
1008 "text",
1009 "tinyblob",
1010 "tinyint",
1011 "tinytext",
1012 "trigger",
1013 "undo",
1014 "unlock",
1015 "unsigned",
1016 "usage",
1017 "utc_date",
1018 "utc_time",
1019 "utc_timestamp",
1020 "varbinary",
1021 "varchar",
1022 "varcharacter",
1023 "varying",
1024 "while",
1025 "write",
1026 "xor",
1027 "year_month",
1028 "zerofill",
1029 ]);
1030 set.remove("table");
1031 set
1032 });
1033
1034 pub static DORIS_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1037 let mut set = MYSQL_RESERVED.clone();
1038 set.extend([
1039 "aggregate",
1040 "anti",
1041 "array",
1042 "backend",
1043 "backup",
1044 "begin",
1045 "bitmap",
1046 "boolean",
1047 "broker",
1048 "buckets",
1049 "cached",
1050 "cancel",
1051 "cast",
1052 "catalog",
1053 "charset",
1054 "cluster",
1055 "collation",
1056 "columns",
1057 "comment",
1058 "commit",
1059 "config",
1060 "connection",
1061 "count",
1062 "current",
1063 "data",
1064 "date",
1065 "datetime",
1066 "day",
1067 "deferred",
1068 "distributed",
1069 "dynamic",
1070 "enable",
1071 "end",
1072 "events",
1073 "export",
1074 "external",
1075 "fields",
1076 "first",
1077 "follower",
1078 "format",
1079 "free",
1080 "frontend",
1081 "full",
1082 "functions",
1083 "global",
1084 "grants",
1085 "hash",
1086 "help",
1087 "hour",
1088 "install",
1089 "intermediate",
1090 "json",
1091 "label",
1092 "last",
1093 "less",
1094 "level",
1095 "link",
1096 "local",
1097 "location",
1098 "max",
1099 "merge",
1100 "min",
1101 "minute",
1102 "modify",
1103 "month",
1104 "name",
1105 "names",
1106 "negative",
1107 "nulls",
1108 "observer",
1109 "offset",
1110 "only",
1111 "open",
1112 "overwrite",
1113 "password",
1114 "path",
1115 "plan",
1116 "plugin",
1117 "plugins",
1118 "policy",
1119 "process",
1120 "properties",
1121 "property",
1122 "query",
1123 "quota",
1124 "recover",
1125 "refresh",
1126 "repair",
1127 "replica",
1128 "repository",
1129 "resource",
1130 "restore",
1131 "resume",
1132 "role",
1133 "roles",
1134 "rollback",
1135 "rollup",
1136 "routine",
1137 "sample",
1138 "second",
1139 "semi",
1140 "session",
1141 "signed",
1142 "snapshot",
1143 "start",
1144 "stats",
1145 "status",
1146 "stop",
1147 "stream",
1148 "string",
1149 "sum",
1150 "tables",
1151 "tablet",
1152 "temporary",
1153 "text",
1154 "timestamp",
1155 "transaction",
1156 "trash",
1157 "trim",
1158 "truncate",
1159 "type",
1160 "user",
1161 "value",
1162 "variables",
1163 "verbose",
1164 "version",
1165 "view",
1166 "warnings",
1167 "week",
1168 "work",
1169 "year",
1170 ]);
1171 set
1172 });
1173
1174 pub static POSTGRES_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1176 let mut set = SQL_RESERVED.clone();
1177 set.extend([
1178 "analyse",
1179 "analyze",
1180 "asymmetric",
1181 "binary",
1182 "collation",
1183 "concurrently",
1184 "current_catalog",
1185 "current_role",
1186 "current_schema",
1187 "deferrable",
1188 "do",
1189 "freeze",
1190 "ilike",
1191 "initially",
1192 "isnull",
1193 "lateral",
1194 "notnull",
1195 "placing",
1196 "returning",
1197 "similar",
1198 "symmetric",
1199 "variadic",
1200 "verbose",
1201 ]);
1202 set.remove("default");
1204 set.remove("interval");
1205 set.remove("match");
1206 set.remove("offset");
1207 set.remove("table");
1208 set
1209 });
1210
1211 pub static REDSHIFT_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1215 [
1216 "aes128",
1217 "aes256",
1218 "all",
1219 "allowoverwrite",
1220 "analyse",
1221 "analyze",
1222 "and",
1223 "any",
1224 "array",
1225 "as",
1226 "asc",
1227 "authorization",
1228 "az64",
1229 "backup",
1230 "between",
1231 "binary",
1232 "blanksasnull",
1233 "both",
1234 "bytedict",
1235 "bzip2",
1236 "case",
1237 "cast",
1238 "check",
1239 "collate",
1240 "column",
1241 "constraint",
1242 "create",
1243 "credentials",
1244 "cross",
1245 "current_date",
1246 "current_time",
1247 "current_timestamp",
1248 "current_user",
1249 "current_user_id",
1250 "default",
1251 "deferrable",
1252 "deflate",
1253 "defrag",
1254 "delta",
1255 "delta32k",
1256 "desc",
1257 "disable",
1258 "distinct",
1259 "do",
1260 "else",
1261 "emptyasnull",
1262 "enable",
1263 "encode",
1264 "encrypt",
1265 "encryption",
1266 "end",
1267 "except",
1268 "explicit",
1269 "false",
1270 "for",
1271 "foreign",
1272 "freeze",
1273 "from",
1274 "full",
1275 "globaldict256",
1276 "globaldict64k",
1277 "grant",
1278 "group",
1279 "gzip",
1280 "having",
1281 "identity",
1282 "ignore",
1283 "ilike",
1284 "in",
1285 "initially",
1286 "inner",
1287 "intersect",
1288 "interval",
1289 "into",
1290 "is",
1291 "isnull",
1292 "join",
1293 "leading",
1294 "left",
1295 "like",
1296 "limit",
1297 "localtime",
1298 "localtimestamp",
1299 "lun",
1300 "luns",
1301 "lzo",
1302 "lzop",
1303 "minus",
1304 "mostly16",
1305 "mostly32",
1306 "mostly8",
1307 "natural",
1308 "new",
1309 "not",
1310 "notnull",
1311 "null",
1312 "nulls",
1313 "off",
1314 "offline",
1315 "offset",
1316 "oid",
1317 "old",
1318 "on",
1319 "only",
1320 "open",
1321 "or",
1322 "order",
1323 "outer",
1324 "overlaps",
1325 "parallel",
1326 "partition",
1327 "percent",
1328 "permissions",
1329 "pivot",
1330 "placing",
1331 "primary",
1332 "raw",
1333 "readratio",
1334 "recover",
1335 "references",
1336 "rejectlog",
1337 "resort",
1338 "respect",
1339 "restore",
1340 "right",
1341 "select",
1342 "session_user",
1343 "similar",
1344 "snapshot",
1345 "some",
1346 "sysdate",
1347 "system",
1348 "table",
1349 "tag",
1350 "tdes",
1351 "text255",
1352 "text32k",
1353 "then",
1354 "timestamp",
1355 "to",
1356 "top",
1357 "trailing",
1358 "true",
1359 "truncatecolumns",
1360 "type",
1361 "union",
1362 "unique",
1363 "unnest",
1364 "unpivot",
1365 "user",
1366 "using",
1367 "verbose",
1368 "wallet",
1369 "when",
1370 "where",
1371 "with",
1372 "without",
1373 ]
1374 .into_iter()
1375 .collect()
1376 });
1377
1378 pub static DUCKDB_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1380 let mut set = POSTGRES_RESERVED.clone();
1381 set.extend([
1382 "anti",
1383 "asof",
1384 "columns",
1385 "describe",
1386 "groups",
1387 "macro",
1388 "pivot",
1389 "pivot_longer",
1390 "pivot_wider",
1391 "qualify",
1392 "replace",
1393 "respect",
1394 "semi",
1395 "show",
1396 "table",
1397 "unpivot",
1398 ]);
1399 set.remove("at");
1400 set.remove("key");
1401 set.remove("row");
1402 set
1403 });
1404
1405 pub static PRESTO_TRINO_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1407 let mut set = SQL_RESERVED.clone();
1408 set.extend([
1409 "alter",
1410 "and",
1411 "as",
1412 "between",
1413 "by",
1414 "case",
1415 "cast",
1416 "constraint",
1417 "create",
1418 "cross",
1419 "cube",
1420 "current_catalog",
1421 "current_date",
1422 "current_path",
1423 "current_role",
1424 "current_schema",
1425 "current_time",
1426 "current_timestamp",
1427 "current_user",
1428 "deallocate",
1429 "delete",
1430 "describe",
1431 "distinct",
1432 "drop",
1433 "else",
1434 "end",
1435 "escape",
1436 "except",
1437 "execute",
1438 "exists",
1439 "extract",
1440 "false",
1441 "for",
1442 "from",
1443 "full",
1444 "group",
1445 "grouping",
1446 "having",
1447 "in",
1448 "inner",
1449 "insert",
1450 "intersect",
1451 "into",
1452 "is",
1453 "join",
1454 "json_array",
1455 "json_exists",
1456 "json_object",
1457 "json_query",
1458 "json_table",
1459 "json_value",
1460 "left",
1461 "like",
1462 "listagg",
1463 "localtime",
1464 "localtimestamp",
1465 "natural",
1466 "normalize",
1467 "not",
1468 "null",
1469 "on",
1470 "or",
1471 "order",
1472 "outer",
1473 "prepare",
1474 "recursive",
1475 "right",
1476 "rollup",
1477 "select",
1478 "skip",
1479 "table",
1480 "then",
1481 "trim",
1482 "true",
1483 "uescape",
1484 "union",
1485 "unnest",
1486 "using",
1487 "values",
1488 "when",
1489 "where",
1490 "with",
1491 ]);
1492 set.remove("key");
1494 set
1495 });
1496
1497 pub static STARROCKS_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1500 [
1501 "add",
1502 "all",
1503 "alter",
1504 "analyze",
1505 "and",
1506 "array",
1507 "as",
1508 "asc",
1509 "between",
1510 "bigint",
1511 "bitmap",
1512 "both",
1513 "by",
1514 "case",
1515 "char",
1516 "character",
1517 "check",
1518 "collate",
1519 "column",
1520 "compaction",
1521 "convert",
1522 "create",
1523 "cross",
1524 "cube",
1525 "current_date",
1526 "current_role",
1527 "current_time",
1528 "current_timestamp",
1529 "current_user",
1530 "database",
1531 "databases",
1532 "decimal",
1533 "decimalv2",
1534 "decimal32",
1535 "decimal64",
1536 "decimal128",
1537 "default",
1538 "deferred",
1539 "delete",
1540 "dense_rank",
1541 "desc",
1542 "describe",
1543 "distinct",
1544 "double",
1545 "drop",
1546 "dual",
1547 "else",
1548 "except",
1549 "exists",
1550 "explain",
1551 "false",
1552 "first_value",
1553 "float",
1554 "for",
1555 "force",
1556 "from",
1557 "full",
1558 "function",
1559 "grant",
1560 "group",
1561 "grouping",
1562 "grouping_id",
1563 "groups",
1564 "having",
1565 "hll",
1566 "host",
1567 "if",
1568 "ignore",
1569 "immediate",
1570 "in",
1571 "index",
1572 "infile",
1573 "inner",
1574 "insert",
1575 "int",
1576 "integer",
1577 "intersect",
1578 "into",
1579 "is",
1580 "join",
1581 "json",
1582 "key",
1583 "keys",
1584 "kill",
1585 "lag",
1586 "largeint",
1587 "last_value",
1588 "lateral",
1589 "lead",
1590 "left",
1591 "like",
1592 "limit",
1593 "load",
1594 "localtime",
1595 "localtimestamp",
1596 "maxvalue",
1597 "minus",
1598 "mod",
1599 "not",
1600 "ntile",
1601 "null",
1602 "on",
1603 "or",
1604 "order",
1605 "outer",
1606 "outfile",
1607 "over",
1608 "partition",
1609 "percentile",
1610 "primary",
1611 "procedure",
1612 "qualify",
1613 "range",
1614 "rank",
1615 "read",
1616 "regexp",
1617 "release",
1618 "rename",
1619 "replace",
1620 "revoke",
1621 "right",
1622 "rlike",
1623 "row",
1624 "row_number",
1625 "rows",
1626 "schema",
1627 "schemas",
1628 "select",
1629 "set",
1630 "set_var",
1631 "show",
1632 "smallint",
1633 "system",
1634 "table",
1635 "terminated",
1636 "text",
1637 "then",
1638 "tinyint",
1639 "to",
1640 "true",
1641 "union",
1642 "unique",
1643 "unsigned",
1644 "update",
1645 "use",
1646 "using",
1647 "values",
1648 "varchar",
1649 "when",
1650 "where",
1651 "with",
1652 ]
1653 .into_iter()
1654 .collect()
1655 });
1656
1657 pub static SINGLESTORE_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1660 let mut set = MYSQL_RESERVED.clone();
1661 set.extend([
1662 "abs",
1665 "account",
1666 "acos",
1667 "adddate",
1668 "addtime",
1669 "admin",
1670 "aes_decrypt",
1671 "aes_encrypt",
1672 "aggregate",
1673 "aggregates",
1674 "aggregator",
1675 "anti_join",
1676 "any_value",
1677 "approx_count_distinct",
1678 "approx_percentile",
1679 "arrange",
1680 "arrangement",
1681 "asin",
1682 "atan",
1683 "atan2",
1684 "attach",
1685 "autostats",
1686 "avro",
1687 "background",
1688 "backup",
1689 "batch",
1690 "batches",
1691 "boot_strapping",
1692 "ceil",
1693 "ceiling",
1694 "coercibility",
1695 "columnar",
1696 "columnstore",
1697 "compile",
1698 "concurrent",
1699 "connection_id",
1700 "cos",
1701 "cot",
1702 "current_security_groups",
1703 "current_security_roles",
1704 "dayname",
1705 "dayofmonth",
1706 "dayofweek",
1707 "dayofyear",
1708 "degrees",
1709 "dot_product",
1710 "dump",
1711 "durability",
1712 "earliest",
1713 "echo",
1714 "election",
1715 "euclidean_distance",
1716 "exp",
1717 "extractor",
1718 "extractors",
1719 "floor",
1720 "foreground",
1721 "found_rows",
1722 "from_base64",
1723 "from_days",
1724 "from_unixtime",
1725 "fs",
1726 "fulltext",
1727 "gc",
1728 "gcs",
1729 "geography",
1730 "geography_area",
1731 "geography_contains",
1732 "geography_distance",
1733 "geography_intersects",
1734 "geography_latitude",
1735 "geography_length",
1736 "geography_longitude",
1737 "geographypoint",
1738 "geography_point",
1739 "geography_within_distance",
1740 "geometry",
1741 "geometry_area",
1742 "geometry_contains",
1743 "geometry_distance",
1744 "geometry_filter",
1745 "geometry_intersects",
1746 "geometry_length",
1747 "geometrypoint",
1748 "geometry_point",
1749 "geometry_within_distance",
1750 "geometry_x",
1751 "geometry_y",
1752 "greatest",
1753 "groups",
1754 "group_concat",
1755 "gzip",
1756 "hdfs",
1757 "hex",
1758 "highlight",
1759 "ifnull",
1760 "ilike",
1761 "inet_aton",
1762 "inet_ntoa",
1763 "inet6_aton",
1764 "inet6_ntoa",
1765 "initcap",
1766 "instr",
1767 "interpreter_mode",
1768 "isnull",
1769 "json",
1770 "json_agg",
1771 "json_array_contains_double",
1772 "json_array_contains_json",
1773 "json_array_contains_string",
1774 "json_delete_key",
1775 "json_extract_double",
1776 "json_extract_json",
1777 "json_extract_string",
1778 "json_extract_bigint",
1779 "json_get_type",
1780 "json_length",
1781 "json_set_double",
1782 "json_set_json",
1783 "json_set_string",
1784 "kafka",
1785 "lag",
1786 "last_day",
1787 "last_insert_id",
1788 "latest",
1789 "lcase",
1790 "lead",
1791 "leaf",
1792 "least",
1793 "leaves",
1794 "length",
1795 "license",
1796 "links",
1797 "llvm",
1798 "ln",
1799 "load",
1800 "locate",
1801 "log",
1802 "log10",
1803 "log2",
1804 "lpad",
1805 "lz4",
1806 "management",
1807 "match",
1808 "mbc",
1809 "md5",
1810 "median",
1811 "memsql",
1812 "memsql_deserialize",
1813 "memsql_serialize",
1814 "metadata",
1815 "microsecond",
1816 "minute",
1817 "model",
1818 "monthname",
1819 "months_between",
1820 "mpl",
1821 "namespace",
1822 "node",
1823 "noparam",
1824 "now",
1825 "nth_value",
1826 "ntile",
1827 "nullcols",
1828 "nullif",
1829 "object",
1830 "octet_length",
1831 "offsets",
1832 "online",
1833 "optimizer",
1834 "orphan",
1835 "parquet",
1836 "partitions",
1837 "pause",
1838 "percentile_cont",
1839 "percentile_disc",
1840 "periodic",
1841 "persisted",
1842 "pi",
1843 "pipeline",
1844 "pipelines",
1845 "plancache",
1846 "plugins",
1847 "pool",
1848 "pools",
1849 "pow",
1850 "power",
1851 "process",
1852 "processlist",
1853 "profile",
1854 "profiles",
1855 "quarter",
1856 "queries",
1857 "query",
1858 "radians",
1859 "rand",
1860 "record",
1861 "reduce",
1862 "redundancy",
1863 "regexp_match",
1864 "regexp_substr",
1865 "remote",
1866 "replication",
1867 "resource",
1868 "resource_pool",
1869 "restore",
1870 "retry",
1871 "role",
1872 "roles",
1873 "round",
1874 "rpad",
1875 "rtrim",
1876 "running",
1877 "s3",
1878 "scalar",
1879 "sec_to_time",
1880 "second",
1881 "security_lists_intersect",
1882 "semi_join",
1883 "sha",
1884 "sha1",
1885 "sha2",
1886 "shard",
1887 "sharded",
1888 "sharded_id",
1889 "sigmoid",
1890 "sign",
1891 "sin",
1892 "skip",
1893 "sleep",
1894 "snapshot",
1895 "soname",
1896 "sparse",
1897 "spatial_check_index",
1898 "split",
1899 "sqrt",
1900 "standalone",
1901 "std",
1902 "stddev",
1903 "stddev_pop",
1904 "stddev_samp",
1905 "stop",
1906 "str_to_date",
1907 "subdate",
1908 "substr",
1909 "substring_index",
1910 "success",
1911 "synchronize",
1912 "table_checksum",
1913 "tan",
1914 "task",
1915 "timediff",
1916 "time_bucket",
1917 "time_format",
1918 "time_to_sec",
1919 "timestampadd",
1920 "timestampdiff",
1921 "to_base64",
1922 "to_char",
1923 "to_date",
1924 "to_days",
1925 "to_json",
1926 "to_number",
1927 "to_seconds",
1928 "to_timestamp",
1929 "tracelogs",
1930 "transform",
1931 "trim",
1932 "trunc",
1933 "truncate",
1934 "ucase",
1935 "unhex",
1936 "unix_timestamp",
1937 "utc_date",
1938 "utc_time",
1939 "utc_timestamp",
1940 "vacuum",
1941 "variance",
1942 "var_pop",
1943 "var_samp",
1944 "vector_sub",
1945 "voting",
1946 "week",
1947 "weekday",
1948 "weekofyear",
1949 "workload",
1950 "year",
1951 ]);
1952 set.remove("all");
1954 set
1955 });
1956
1957 pub static SQLITE_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1961 [
1963 "abort",
1964 "action",
1965 "add",
1966 "after",
1967 "all",
1968 "alter",
1969 "always",
1970 "analyze",
1971 "and",
1972 "as",
1973 "asc",
1974 "attach",
1975 "autoincrement",
1976 "before",
1977 "begin",
1978 "between",
1979 "by",
1980 "cascade",
1981 "case",
1982 "cast",
1983 "check",
1984 "collate",
1985 "column",
1986 "commit",
1987 "conflict",
1988 "constraint",
1989 "create",
1990 "cross",
1991 "current",
1992 "current_date",
1993 "current_time",
1994 "current_timestamp",
1995 "database",
1996 "default",
1997 "deferrable",
1998 "deferred",
1999 "delete",
2000 "desc",
2001 "detach",
2002 "distinct",
2003 "do",
2004 "drop",
2005 "each",
2006 "else",
2007 "end",
2008 "escape",
2009 "except",
2010 "exclude",
2011 "exclusive",
2012 "exists",
2013 "explain",
2014 "fail",
2015 "filter",
2016 "first",
2017 "following",
2018 "for",
2019 "foreign",
2020 "from",
2021 "full",
2022 "generated",
2023 "glob",
2024 "group",
2025 "groups",
2026 "having",
2027 "if",
2028 "ignore",
2029 "immediate",
2030 "in",
2031 "index",
2032 "indexed",
2033 "initially",
2034 "inner",
2035 "insert",
2036 "instead",
2037 "intersect",
2038 "into",
2039 "is",
2040 "isnull",
2041 "join",
2042 "key",
2043 "last",
2044 "left",
2045 "like",
2046 "limit",
2047 "natural",
2048 "no",
2049 "not",
2050 "nothing",
2051 "notnull",
2052 "null",
2053 "nulls",
2054 "of",
2055 "offset",
2056 "on",
2057 "or",
2058 "order",
2059 "others",
2060 "outer",
2061 "partition",
2062 "plan",
2063 "pragma",
2064 "preceding",
2065 "primary",
2066 "query",
2067 "raise",
2068 "range",
2069 "recursive",
2070 "references",
2071 "regexp",
2072 "reindex",
2073 "release",
2074 "rename",
2075 "replace",
2076 "restrict",
2077 "returning",
2078 "right",
2079 "rollback",
2080 "row",
2081 "rows",
2082 "savepoint",
2083 "select",
2084 "set",
2085 "table",
2086 "temp",
2087 "temporary",
2088 "then",
2089 "ties",
2090 "to",
2091 "transaction",
2092 "trigger",
2093 "unbounded",
2094 "union",
2095 "unique",
2096 "update",
2097 "using",
2098 "vacuum",
2099 "values",
2100 "view",
2101 "virtual",
2102 "when",
2103 "where",
2104 "window",
2105 "with",
2106 "without",
2107 ]
2108 .into_iter()
2109 .collect()
2110 });
2111}
2112
2113impl Generator {
2114 pub fn new() -> Self {
2120 Self::with_config(GeneratorConfig::default())
2121 }
2122
2123 pub fn with_config(config: GeneratorConfig) -> Self {
2128 Self {
2129 config,
2130 output: String::new(),
2131 unsupported_messages: Vec::new(),
2132 indent_level: 0,
2133 athena_hive_context: false,
2134 sqlite_inline_pk_columns: std::collections::HashSet::new(),
2135 merge_strip_qualifiers: Vec::new(),
2136 clickhouse_nullable_depth: 0,
2137 }
2138 }
2139
2140 fn add_column_aliases_to_query(expr: Expression) -> Expression {
2144 match expr {
2145 Expression::Select(mut select) => {
2146 select.expressions = select
2148 .expressions
2149 .into_iter()
2150 .map(|e| Self::add_alias_to_expression(e))
2151 .collect();
2152
2153 if let Some(ref mut from) = select.from {
2155 from.expressions = from
2156 .expressions
2157 .iter()
2158 .cloned()
2159 .map(|e| Self::add_column_aliases_to_query(e))
2160 .collect();
2161 }
2162
2163 Expression::Select(select)
2164 }
2165 Expression::Subquery(mut sq) => {
2166 sq.this = Self::add_column_aliases_to_query(sq.this);
2167 Expression::Subquery(sq)
2168 }
2169 Expression::Paren(mut p) => {
2170 p.this = Self::add_column_aliases_to_query(p.this);
2171 Expression::Paren(p)
2172 }
2173 other => other,
2175 }
2176 }
2177
2178 fn add_alias_to_expression(expr: Expression) -> Expression {
2181 use crate::expressions::Alias;
2182
2183 match &expr {
2184 Expression::Alias(_) => expr,
2186
2187 Expression::Column(col) => Expression::Alias(Box::new(Alias {
2189 this: expr.clone(),
2190 alias: col.name.clone(),
2191 column_aliases: Vec::new(),
2192 pre_alias_comments: Vec::new(),
2193 trailing_comments: Vec::new(),
2194 inferred_type: None,
2195 })),
2196
2197 Expression::Identifier(ident) => Expression::Alias(Box::new(Alias {
2199 this: expr.clone(),
2200 alias: ident.clone(),
2201 column_aliases: Vec::new(),
2202 pre_alias_comments: Vec::new(),
2203 trailing_comments: Vec::new(),
2204 inferred_type: None,
2205 })),
2206
2207 Expression::Subquery(sq) => {
2209 let processed = Self::add_column_aliases_to_query(Expression::Subquery(sq.clone()));
2210 if sq.alias.is_some() {
2212 processed
2213 } else {
2214 processed
2216 }
2217 }
2218
2219 Expression::Star(_) => expr,
2221
2222 _ => expr,
2225 }
2226 }
2227
2228 fn try_evaluate_constant(expr: &Expression) -> Option<i64> {
2232 match expr {
2233 Expression::Literal(Literal::Number(n)) => n.parse::<i64>().ok(),
2234 Expression::Add(op) => {
2235 let left = Self::try_evaluate_constant(&op.left)?;
2236 let right = Self::try_evaluate_constant(&op.right)?;
2237 Some(left + right)
2238 }
2239 Expression::Sub(op) => {
2240 let left = Self::try_evaluate_constant(&op.left)?;
2241 let right = Self::try_evaluate_constant(&op.right)?;
2242 Some(left - right)
2243 }
2244 Expression::Mul(op) => {
2245 let left = Self::try_evaluate_constant(&op.left)?;
2246 let right = Self::try_evaluate_constant(&op.right)?;
2247 Some(left * right)
2248 }
2249 Expression::Div(op) => {
2250 let left = Self::try_evaluate_constant(&op.left)?;
2251 let right = Self::try_evaluate_constant(&op.right)?;
2252 if right != 0 {
2253 Some(left / right)
2254 } else {
2255 None
2256 }
2257 }
2258 Expression::Paren(p) => Self::try_evaluate_constant(&p.this),
2259 _ => None,
2260 }
2261 }
2262
2263 fn is_reserved_keyword(&self, name: &str) -> bool {
2265 use crate::dialects::DialectType;
2266 let lower = name.to_lowercase();
2267 let lower_ref = lower.as_str();
2268
2269 match self.config.dialect {
2270 Some(DialectType::BigQuery) => reserved_keywords::BIGQUERY_RESERVED.contains(lower_ref),
2271 Some(DialectType::MySQL) | Some(DialectType::TiDB) => {
2272 reserved_keywords::MYSQL_RESERVED.contains(lower_ref)
2273 }
2274 Some(DialectType::Doris) => reserved_keywords::DORIS_RESERVED.contains(lower_ref),
2275 Some(DialectType::SingleStore) => {
2276 reserved_keywords::SINGLESTORE_RESERVED.contains(lower_ref)
2277 }
2278 Some(DialectType::StarRocks) => {
2279 reserved_keywords::STARROCKS_RESERVED.contains(lower_ref)
2280 }
2281 Some(DialectType::PostgreSQL)
2282 | Some(DialectType::CockroachDB)
2283 | Some(DialectType::Materialize)
2284 | Some(DialectType::RisingWave) => {
2285 reserved_keywords::POSTGRES_RESERVED.contains(lower_ref)
2286 }
2287 Some(DialectType::Redshift) => reserved_keywords::REDSHIFT_RESERVED.contains(lower_ref),
2288 Some(DialectType::Snowflake) => false,
2291 Some(DialectType::ClickHouse) => false,
2293 Some(DialectType::DuckDB) => reserved_keywords::DUCKDB_RESERVED.contains(lower_ref),
2294 Some(DialectType::Teradata) => false,
2296 Some(DialectType::TSQL)
2298 | Some(DialectType::Fabric)
2299 | Some(DialectType::Oracle)
2300 | Some(DialectType::Spark)
2301 | Some(DialectType::Databricks)
2302 | Some(DialectType::Hive)
2303 | Some(DialectType::Solr) => false,
2304 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
2305 reserved_keywords::PRESTO_TRINO_RESERVED.contains(lower_ref)
2306 }
2307 Some(DialectType::SQLite) => reserved_keywords::SQLITE_RESERVED.contains(lower_ref),
2308 Some(DialectType::Generic) | None => false,
2310 _ => reserved_keywords::SQL_RESERVED.contains(lower_ref),
2312 }
2313 }
2314
2315 fn normalize_func_name(&self, name: &str) -> String {
2317 match self.config.normalize_functions {
2318 NormalizeFunctions::Upper => name.to_uppercase(),
2319 NormalizeFunctions::Lower => name.to_lowercase(),
2320 NormalizeFunctions::None => name.to_string(),
2321 }
2322 }
2323
2324 pub fn generate(&mut self, expr: &Expression) -> Result<String> {
2333 self.output.clear();
2334 self.unsupported_messages.clear();
2335 self.generate_expression(expr)?;
2336 if self.config.unsupported_level == UnsupportedLevel::Raise
2337 && !self.unsupported_messages.is_empty()
2338 {
2339 return Err(crate::error::Error::generate(
2340 self.format_unsupported_messages(),
2341 ));
2342 }
2343 Ok(std::mem::take(&mut self.output))
2344 }
2345
2346 pub fn unsupported_messages(&self) -> &[String] {
2348 &self.unsupported_messages
2349 }
2350
2351 fn unsupported(&mut self, message: impl Into<String>) -> Result<()> {
2352 let message = message.into();
2353 if self.config.unsupported_level == UnsupportedLevel::Immediate {
2354 return Err(crate::error::Error::generate(message));
2355 }
2356 self.unsupported_messages.push(message);
2357 Ok(())
2358 }
2359
2360 fn write_unsupported_comment(&mut self, message: &str) -> Result<()> {
2361 self.unsupported(message.to_string())?;
2362 self.write("/* ");
2363 self.write(message);
2364 self.write(" */");
2365 Ok(())
2366 }
2367
2368 fn format_unsupported_messages(&self) -> String {
2369 let limit = self.config.max_unsupported.max(1);
2370 if self.unsupported_messages.len() <= limit {
2371 return self.unsupported_messages.join("; ");
2372 }
2373
2374 let mut messages = self
2375 .unsupported_messages
2376 .iter()
2377 .take(limit)
2378 .cloned()
2379 .collect::<Vec<_>>();
2380 messages.push(format!(
2381 "... and {} more",
2382 self.unsupported_messages.len() - limit
2383 ));
2384 messages.join("; ")
2385 }
2386
2387 pub fn sql(expr: &Expression) -> Result<String> {
2393 let mut gen = Generator::new();
2394 gen.generate(expr)
2395 }
2396
2397 pub fn pretty_sql(expr: &Expression) -> Result<String> {
2402 let config = GeneratorConfig {
2403 pretty: true,
2404 ..Default::default()
2405 };
2406 let mut gen = Generator::with_config(config);
2407 let mut sql = gen.generate(expr)?;
2408 if !sql.ends_with(';') {
2410 sql.push(';');
2411 }
2412 Ok(sql)
2413 }
2414
2415 fn generate_expression(&mut self, expr: &Expression) -> Result<()> {
2416 match expr {
2417 Expression::Select(select) => self.generate_select(select),
2418 Expression::Union(union) => self.generate_union(union),
2419 Expression::Intersect(intersect) => self.generate_intersect(intersect),
2420 Expression::Except(except) => self.generate_except(except),
2421 Expression::Insert(insert) => self.generate_insert(insert),
2422 Expression::Update(update) => self.generate_update(update),
2423 Expression::Delete(delete) => self.generate_delete(delete),
2424 Expression::Literal(lit) => self.generate_literal(lit),
2425 Expression::Boolean(b) => self.generate_boolean(b),
2426 Expression::Null(_) => {
2427 self.write_keyword("NULL");
2428 Ok(())
2429 }
2430 Expression::Identifier(id) => self.generate_identifier(id),
2431 Expression::Column(col) => self.generate_column(col),
2432 Expression::Pseudocolumn(pc) => self.generate_pseudocolumn(pc),
2433 Expression::Connect(c) => self.generate_connect_expr(c),
2434 Expression::Prior(p) => self.generate_prior(p),
2435 Expression::ConnectByRoot(cbr) => self.generate_connect_by_root(cbr),
2436 Expression::MatchRecognize(mr) => self.generate_match_recognize(mr),
2437 Expression::Table(table) => self.generate_table(table),
2438 Expression::StageReference(sr) => self.generate_stage_reference(sr),
2439 Expression::HistoricalData(hd) => self.generate_historical_data(hd),
2440 Expression::JoinedTable(jt) => self.generate_joined_table(jt),
2441 Expression::Star(star) => self.generate_star(star),
2442 Expression::BracedWildcard(expr) => self.generate_braced_wildcard(expr),
2443 Expression::Alias(alias) => self.generate_alias(alias),
2444 Expression::Cast(cast) => self.generate_cast(cast),
2445 Expression::Collation(coll) => self.generate_collation(coll),
2446 Expression::Case(case) => self.generate_case(case),
2447 Expression::Function(func) => self.generate_function(func),
2448 Expression::AggregateFunction(func) => self.generate_aggregate_function(func),
2449 Expression::WindowFunction(wf) => self.generate_window_function(wf),
2450 Expression::WithinGroup(wg) => self.generate_within_group(wg),
2451 Expression::Interval(interval) => self.generate_interval(interval),
2452
2453 Expression::ConcatWs(f) => self.generate_concat_ws(f),
2455 Expression::Substring(f) => self.generate_substring(f),
2456 Expression::Upper(f) => self.generate_unary_func("UPPER", f),
2457 Expression::Lower(f) => self.generate_unary_func("LOWER", f),
2458 Expression::Length(f) => self.generate_unary_func("LENGTH", f),
2459 Expression::Trim(f) => self.generate_trim(f),
2460 Expression::LTrim(f) => self.generate_simple_func("LTRIM", &f.this),
2461 Expression::RTrim(f) => self.generate_simple_func("RTRIM", &f.this),
2462 Expression::Replace(f) => self.generate_replace(f),
2463 Expression::Reverse(f) => self.generate_simple_func("REVERSE", &f.this),
2464 Expression::Left(f) => self.generate_left_right("LEFT", f),
2465 Expression::Right(f) => self.generate_left_right("RIGHT", f),
2466 Expression::Repeat(f) => self.generate_repeat(f),
2467 Expression::Lpad(f) => self.generate_pad("LPAD", f),
2468 Expression::Rpad(f) => self.generate_pad("RPAD", f),
2469 Expression::Split(f) => self.generate_split(f),
2470 Expression::RegexpLike(f) => self.generate_regexp_like(f),
2471 Expression::RegexpReplace(f) => self.generate_regexp_replace(f),
2472 Expression::RegexpExtract(f) => self.generate_regexp_extract(f),
2473 Expression::Overlay(f) => self.generate_overlay(f),
2474
2475 Expression::Abs(f) => self.generate_simple_func("ABS", &f.this),
2477 Expression::Round(f) => self.generate_round(f),
2478 Expression::Floor(f) => self.generate_floor(f),
2479 Expression::Ceil(f) => self.generate_ceil(f),
2480 Expression::Power(f) => self.generate_power(f),
2481 Expression::Sqrt(f) => self.generate_sqrt_cbrt(f, "SQRT", "|/"),
2482 Expression::Cbrt(f) => self.generate_sqrt_cbrt(f, "CBRT", "||/"),
2483 Expression::Ln(f) => self.generate_simple_func("LN", &f.this),
2484 Expression::Log(f) => self.generate_log(f),
2485 Expression::Exp(f) => self.generate_simple_func("EXP", &f.this),
2486 Expression::Sign(f) => self.generate_simple_func("SIGN", &f.this),
2487 Expression::Greatest(f) => self.generate_vararg_func("GREATEST", &f.expressions),
2488 Expression::Least(f) => self.generate_vararg_func("LEAST", &f.expressions),
2489
2490 Expression::CurrentDate(_) => {
2492 self.write_keyword("CURRENT_DATE");
2493 Ok(())
2494 }
2495 Expression::CurrentTime(f) => self.generate_current_time(f),
2496 Expression::CurrentTimestamp(f) => self.generate_current_timestamp(f),
2497 Expression::AtTimeZone(f) => self.generate_at_time_zone(f),
2498 Expression::DateAdd(f) => self.generate_date_add(f, "DATE_ADD"),
2499 Expression::DateSub(f) => self.generate_date_add(f, "DATE_SUB"),
2500 Expression::DateDiff(f) => self.generate_datediff(f),
2501 Expression::DateTrunc(f) => self.generate_date_trunc(f),
2502 Expression::Extract(f) => self.generate_extract(f),
2503 Expression::ToDate(f) => self.generate_to_date(f),
2504 Expression::ToTimestamp(f) => self.generate_to_timestamp(f),
2505
2506 Expression::Coalesce(f) => {
2508 let func_name = f.original_name.as_deref().unwrap_or("COALESCE");
2510 self.generate_vararg_func(func_name, &f.expressions)
2511 }
2512 Expression::NullIf(f) => self.generate_binary_func("NULLIF", &f.this, &f.expression),
2513 Expression::IfFunc(f) => self.generate_if_func(f),
2514 Expression::IfNull(f) => self.generate_ifnull(f),
2515 Expression::Nvl(f) => self.generate_nvl(f),
2516 Expression::Nvl2(f) => self.generate_nvl2(f),
2517
2518 Expression::TryCast(cast) => self.generate_try_cast(cast),
2520 Expression::SafeCast(cast) => self.generate_safe_cast(cast),
2521
2522 Expression::Count(f) => self.generate_count(f),
2524 Expression::Sum(f) => self.generate_agg_func("SUM", f),
2525 Expression::Avg(f) => self.generate_agg_func("AVG", f),
2526 Expression::Min(f) => self.generate_agg_func("MIN", f),
2527 Expression::Max(f) => self.generate_agg_func("MAX", f),
2528 Expression::GroupConcat(f) => self.generate_group_concat(f),
2529 Expression::StringAgg(f) => self.generate_string_agg(f),
2530 Expression::ListAgg(f) => self.generate_listagg(f),
2531 Expression::ArrayAgg(f) => {
2532 let override_name = f
2535 .name
2536 .as_ref()
2537 .filter(|n| n.to_uppercase() != "ARRAY_AGG")
2538 .map(|n| n.to_uppercase());
2539 match override_name {
2540 Some(name) => self.generate_agg_func(&name, f),
2541 None => self.generate_agg_func("ARRAY_AGG", f),
2542 }
2543 }
2544 Expression::ArrayConcatAgg(f) => self.generate_agg_func("ARRAY_CONCAT_AGG", f),
2545 Expression::CountIf(f) => self.generate_agg_func("COUNT_IF", f),
2546 Expression::SumIf(f) => self.generate_sum_if(f),
2547 Expression::Stddev(f) => self.generate_agg_func("STDDEV", f),
2548 Expression::StddevPop(f) => self.generate_agg_func("STDDEV_POP", f),
2549 Expression::StddevSamp(f) => self.generate_stddev_samp(f),
2550 Expression::Variance(f) => self.generate_agg_func("VARIANCE", f),
2551 Expression::VarPop(f) => {
2552 let name = if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
2553 "VARIANCE_POP"
2554 } else {
2555 "VAR_POP"
2556 };
2557 self.generate_agg_func(name, f)
2558 }
2559 Expression::VarSamp(f) => self.generate_agg_func("VAR_SAMP", f),
2560 Expression::Skewness(f) => {
2561 let name = match self.config.dialect {
2562 Some(DialectType::Snowflake) => "SKEW",
2563 _ => "SKEWNESS",
2564 };
2565 self.generate_agg_func(name, f)
2566 }
2567 Expression::Median(f) => self.generate_agg_func("MEDIAN", f),
2568 Expression::Mode(f) => self.generate_agg_func("MODE", f),
2569 Expression::First(f) => self.generate_agg_func("FIRST", f),
2570 Expression::Last(f) => self.generate_agg_func("LAST", f),
2571 Expression::AnyValue(f) => self.generate_agg_func("ANY_VALUE", f),
2572 Expression::ApproxDistinct(f) => {
2573 match self.config.dialect {
2574 Some(DialectType::Hive)
2575 | Some(DialectType::Spark)
2576 | Some(DialectType::Databricks)
2577 | Some(DialectType::BigQuery) => {
2578 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2580 }
2581 Some(DialectType::Redshift) => {
2582 self.write_keyword("APPROXIMATE COUNT");
2584 self.write("(");
2585 self.write_keyword("DISTINCT");
2586 self.write(" ");
2587 self.generate_expression(&f.this)?;
2588 self.write(")");
2589 Ok(())
2590 }
2591 _ => self.generate_agg_func("APPROX_DISTINCT", f),
2592 }
2593 }
2594 Expression::ApproxCountDistinct(f) => {
2595 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2596 }
2597 Expression::ApproxPercentile(f) => self.generate_approx_percentile(f),
2598 Expression::Percentile(f) => self.generate_percentile("PERCENTILE", f),
2599 Expression::LogicalAnd(f) => {
2600 let name = match self.config.dialect {
2601 Some(DialectType::Snowflake) => "BOOLAND_AGG",
2602 Some(DialectType::Spark)
2603 | Some(DialectType::Databricks)
2604 | Some(DialectType::PostgreSQL)
2605 | Some(DialectType::DuckDB)
2606 | Some(DialectType::Redshift) => "BOOL_AND",
2607 Some(DialectType::Oracle)
2608 | Some(DialectType::SQLite)
2609 | Some(DialectType::MySQL) => "MIN",
2610 _ => "BOOL_AND",
2611 };
2612 self.generate_agg_func(name, f)
2613 }
2614 Expression::LogicalOr(f) => {
2615 let name = match self.config.dialect {
2616 Some(DialectType::Snowflake) => "BOOLOR_AGG",
2617 Some(DialectType::Spark)
2618 | Some(DialectType::Databricks)
2619 | Some(DialectType::PostgreSQL)
2620 | Some(DialectType::DuckDB)
2621 | Some(DialectType::Redshift) => "BOOL_OR",
2622 Some(DialectType::Oracle)
2623 | Some(DialectType::SQLite)
2624 | Some(DialectType::MySQL) => "MAX",
2625 _ => "BOOL_OR",
2626 };
2627 self.generate_agg_func(name, f)
2628 }
2629
2630 Expression::RowNumber(_) => {
2632 if self.config.dialect == Some(DialectType::ClickHouse) {
2633 self.write("row_number");
2634 } else {
2635 self.write_keyword("ROW_NUMBER");
2636 }
2637 self.write("()");
2638 Ok(())
2639 }
2640 Expression::Rank(r) => {
2641 self.write_keyword("RANK");
2642 self.write("(");
2643 if !r.args.is_empty() {
2645 for (i, arg) in r.args.iter().enumerate() {
2646 if i > 0 {
2647 self.write(", ");
2648 }
2649 self.generate_expression(arg)?;
2650 }
2651 } else if let Some(order_by) = &r.order_by {
2652 self.write_keyword(" ORDER BY ");
2654 for (i, ob) in order_by.iter().enumerate() {
2655 if i > 0 {
2656 self.write(", ");
2657 }
2658 self.generate_ordered(ob)?;
2659 }
2660 }
2661 self.write(")");
2662 Ok(())
2663 }
2664 Expression::DenseRank(dr) => {
2665 self.write_keyword("DENSE_RANK");
2666 self.write("(");
2667 for (i, arg) in dr.args.iter().enumerate() {
2669 if i > 0 {
2670 self.write(", ");
2671 }
2672 self.generate_expression(arg)?;
2673 }
2674 self.write(")");
2675 Ok(())
2676 }
2677 Expression::NTile(f) => self.generate_ntile(f),
2678 Expression::Lead(f) => self.generate_lead_lag("LEAD", f),
2679 Expression::Lag(f) => self.generate_lead_lag("LAG", f),
2680 Expression::FirstValue(f) => self.generate_value_func("FIRST_VALUE", f),
2681 Expression::LastValue(f) => self.generate_value_func("LAST_VALUE", f),
2682 Expression::NthValue(f) => self.generate_nth_value(f),
2683 Expression::PercentRank(pr) => {
2684 self.write_keyword("PERCENT_RANK");
2685 self.write("(");
2686 if !pr.args.is_empty() {
2688 for (i, arg) in pr.args.iter().enumerate() {
2689 if i > 0 {
2690 self.write(", ");
2691 }
2692 self.generate_expression(arg)?;
2693 }
2694 } else if let Some(order_by) = &pr.order_by {
2695 self.write_keyword(" ORDER BY ");
2697 for (i, ob) in order_by.iter().enumerate() {
2698 if i > 0 {
2699 self.write(", ");
2700 }
2701 self.generate_ordered(ob)?;
2702 }
2703 }
2704 self.write(")");
2705 Ok(())
2706 }
2707 Expression::CumeDist(cd) => {
2708 self.write_keyword("CUME_DIST");
2709 self.write("(");
2710 if !cd.args.is_empty() {
2712 for (i, arg) in cd.args.iter().enumerate() {
2713 if i > 0 {
2714 self.write(", ");
2715 }
2716 self.generate_expression(arg)?;
2717 }
2718 } else if let Some(order_by) = &cd.order_by {
2719 self.write_keyword(" ORDER BY ");
2721 for (i, ob) in order_by.iter().enumerate() {
2722 if i > 0 {
2723 self.write(", ");
2724 }
2725 self.generate_ordered(ob)?;
2726 }
2727 }
2728 self.write(")");
2729 Ok(())
2730 }
2731 Expression::PercentileCont(f) => self.generate_percentile("PERCENTILE_CONT", f),
2732 Expression::PercentileDisc(f) => self.generate_percentile("PERCENTILE_DISC", f),
2733
2734 Expression::Contains(f) => {
2736 self.generate_binary_func("CONTAINS", &f.this, &f.expression)
2737 }
2738 Expression::StartsWith(f) => {
2739 let name = match self.config.dialect {
2740 Some(DialectType::Spark) | Some(DialectType::Databricks) => "STARTSWITH",
2741 _ => "STARTS_WITH",
2742 };
2743 self.generate_binary_func(name, &f.this, &f.expression)
2744 }
2745 Expression::EndsWith(f) => {
2746 let name = match self.config.dialect {
2747 Some(DialectType::Snowflake) => "ENDSWITH",
2748 Some(DialectType::Spark) | Some(DialectType::Databricks) => "ENDSWITH",
2749 Some(DialectType::ClickHouse) => "endsWith",
2750 _ => "ENDS_WITH",
2751 };
2752 self.generate_binary_func(name, &f.this, &f.expression)
2753 }
2754 Expression::Position(f) => self.generate_position(f),
2755 Expression::Initcap(f) => match self.config.dialect {
2756 Some(DialectType::Presto)
2757 | Some(DialectType::Trino)
2758 | Some(DialectType::Athena) => {
2759 self.write_keyword("REGEXP_REPLACE");
2760 self.write("(");
2761 self.generate_expression(&f.this)?;
2762 self.write(", '(\\w)(\\w*)', x -> UPPER(x[1]) || LOWER(x[2]))");
2763 Ok(())
2764 }
2765 _ => self.generate_simple_func("INITCAP", &f.this),
2766 },
2767 Expression::Ascii(f) => self.generate_simple_func("ASCII", &f.this),
2768 Expression::Chr(f) => self.generate_simple_func("CHR", &f.this),
2769 Expression::CharFunc(f) => self.generate_char_func(f),
2770 Expression::Soundex(f) => self.generate_simple_func("SOUNDEX", &f.this),
2771 Expression::Levenshtein(f) => {
2772 self.generate_binary_func("LEVENSHTEIN", &f.this, &f.expression)
2773 }
2774
2775 Expression::ModFunc(f) => self.generate_mod_func(f),
2777 Expression::Random(_) => {
2778 self.write_keyword("RANDOM");
2779 self.write("()");
2780 Ok(())
2781 }
2782 Expression::Rand(f) => self.generate_rand(f),
2783 Expression::TruncFunc(f) => self.generate_truncate_func(f),
2784 Expression::Pi(_) => {
2785 self.write_keyword("PI");
2786 self.write("()");
2787 Ok(())
2788 }
2789 Expression::Radians(f) => self.generate_simple_func("RADIANS", &f.this),
2790 Expression::Degrees(f) => self.generate_simple_func("DEGREES", &f.this),
2791 Expression::Sin(f) => self.generate_simple_func("SIN", &f.this),
2792 Expression::Cos(f) => self.generate_simple_func("COS", &f.this),
2793 Expression::Tan(f) => self.generate_simple_func("TAN", &f.this),
2794 Expression::Asin(f) => self.generate_simple_func("ASIN", &f.this),
2795 Expression::Acos(f) => self.generate_simple_func("ACOS", &f.this),
2796 Expression::Atan(f) => self.generate_simple_func("ATAN", &f.this),
2797 Expression::Atan2(f) => {
2798 let name = f.original_name.as_deref().unwrap_or("ATAN2");
2799 self.generate_binary_func(name, &f.this, &f.expression)
2800 }
2801
2802 Expression::Decode(f) => self.generate_decode(f),
2804
2805 Expression::DateFormat(f) => self.generate_date_format("DATE_FORMAT", f),
2807 Expression::FormatDate(f) => self.generate_date_format("FORMAT_DATE", f),
2808 Expression::Year(f) => self.generate_simple_func("YEAR", &f.this),
2809 Expression::Month(f) => self.generate_simple_func("MONTH", &f.this),
2810 Expression::Day(f) => self.generate_simple_func("DAY", &f.this),
2811 Expression::Hour(f) => self.generate_simple_func("HOUR", &f.this),
2812 Expression::Minute(f) => self.generate_simple_func("MINUTE", &f.this),
2813 Expression::Second(f) => self.generate_simple_func("SECOND", &f.this),
2814 Expression::DayOfWeek(f) => {
2815 let name = match self.config.dialect {
2816 Some(DialectType::Presto)
2817 | Some(DialectType::Trino)
2818 | Some(DialectType::Athena) => "DAY_OF_WEEK",
2819 Some(DialectType::DuckDB) => "ISODOW",
2820 _ => "DAYOFWEEK",
2821 };
2822 self.generate_simple_func(name, &f.this)
2823 }
2824 Expression::DayOfMonth(f) => {
2825 let name = match self.config.dialect {
2826 Some(DialectType::Presto)
2827 | Some(DialectType::Trino)
2828 | Some(DialectType::Athena) => "DAY_OF_MONTH",
2829 _ => "DAYOFMONTH",
2830 };
2831 self.generate_simple_func(name, &f.this)
2832 }
2833 Expression::DayOfYear(f) => {
2834 let name = match self.config.dialect {
2835 Some(DialectType::Presto)
2836 | Some(DialectType::Trino)
2837 | Some(DialectType::Athena) => "DAY_OF_YEAR",
2838 _ => "DAYOFYEAR",
2839 };
2840 self.generate_simple_func(name, &f.this)
2841 }
2842 Expression::WeekOfYear(f) => {
2843 let name = match self.config.dialect {
2845 Some(DialectType::Hive)
2846 | Some(DialectType::DuckDB)
2847 | Some(DialectType::Spark)
2848 | Some(DialectType::Databricks)
2849 | Some(DialectType::MySQL) => "WEEKOFYEAR",
2850 _ => "WEEK_OF_YEAR",
2851 };
2852 self.generate_simple_func(name, &f.this)
2853 }
2854 Expression::Quarter(f) => self.generate_simple_func("QUARTER", &f.this),
2855 Expression::AddMonths(f) => {
2856 self.generate_binary_func("ADD_MONTHS", &f.this, &f.expression)
2857 }
2858 Expression::MonthsBetween(f) => {
2859 self.generate_binary_func("MONTHS_BETWEEN", &f.this, &f.expression)
2860 }
2861 Expression::LastDay(f) => self.generate_last_day(f),
2862 Expression::NextDay(f) => self.generate_binary_func("NEXT_DAY", &f.this, &f.expression),
2863 Expression::Epoch(f) => self.generate_simple_func("EPOCH", &f.this),
2864 Expression::EpochMs(f) => self.generate_simple_func("EPOCH_MS", &f.this),
2865 Expression::FromUnixtime(f) => self.generate_from_unixtime(f),
2866 Expression::UnixTimestamp(f) => self.generate_unix_timestamp(f),
2867 Expression::MakeDate(f) => self.generate_make_date(f),
2868 Expression::MakeTimestamp(f) => self.generate_make_timestamp(f),
2869 Expression::TimestampTrunc(f) => self.generate_date_trunc(f),
2870
2871 Expression::ArrayFunc(f) => self.generate_array_constructor(f),
2873 Expression::ArrayLength(f) => self.generate_simple_func("ARRAY_LENGTH", &f.this),
2874 Expression::ArraySize(f) => self.generate_simple_func("ARRAY_SIZE", &f.this),
2875 Expression::Cardinality(f) => self.generate_simple_func("CARDINALITY", &f.this),
2876 Expression::ArrayContains(f) => {
2877 self.generate_binary_func("ARRAY_CONTAINS", &f.this, &f.expression)
2878 }
2879 Expression::ArrayPosition(f) => {
2880 self.generate_binary_func("ARRAY_POSITION", &f.this, &f.expression)
2881 }
2882 Expression::ArrayAppend(f) => {
2883 self.generate_binary_func("ARRAY_APPEND", &f.this, &f.expression)
2884 }
2885 Expression::ArrayPrepend(f) => {
2886 self.generate_binary_func("ARRAY_PREPEND", &f.this, &f.expression)
2887 }
2888 Expression::ArrayConcat(f) => self.generate_vararg_func("ARRAY_CONCAT", &f.expressions),
2889 Expression::ArraySort(f) => self.generate_array_sort(f),
2890 Expression::ArrayReverse(f) => self.generate_simple_func("ARRAY_REVERSE", &f.this),
2891 Expression::ArrayDistinct(f) => self.generate_simple_func("ARRAY_DISTINCT", &f.this),
2892 Expression::ArrayJoin(f) => self.generate_array_join("ARRAY_JOIN", f),
2893 Expression::ArrayToString(f) => self.generate_array_join("ARRAY_TO_STRING", f),
2894 Expression::Unnest(f) => self.generate_unnest(f),
2895 Expression::Explode(f) => self.generate_simple_func("EXPLODE", &f.this),
2896 Expression::ExplodeOuter(f) => self.generate_simple_func("EXPLODE_OUTER", &f.this),
2897 Expression::ArrayFilter(f) => self.generate_array_filter(f),
2898 Expression::ArrayTransform(f) => self.generate_array_transform(f),
2899 Expression::ArrayFlatten(f) => self.generate_simple_func("FLATTEN", &f.this),
2900 Expression::ArrayCompact(f) => {
2901 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
2902 self.write("LIST_FILTER(");
2904 self.generate_expression(&f.this)?;
2905 self.write(", _u -> NOT _u IS NULL)");
2906 Ok(())
2907 } else {
2908 self.generate_simple_func("ARRAY_COMPACT", &f.this)
2909 }
2910 }
2911 Expression::ArrayIntersect(f) => {
2912 let func_name = f.original_name.as_deref().unwrap_or("ARRAY_INTERSECT");
2913 self.generate_vararg_func(func_name, &f.expressions)
2914 }
2915 Expression::ArrayUnion(f) => {
2916 self.generate_binary_func("ARRAY_UNION", &f.this, &f.expression)
2917 }
2918 Expression::ArrayExcept(f) => {
2919 self.generate_binary_func("ARRAY_EXCEPT", &f.this, &f.expression)
2920 }
2921 Expression::ArrayRemove(f) => {
2922 self.generate_binary_func("ARRAY_REMOVE", &f.this, &f.expression)
2923 }
2924 Expression::ArrayZip(f) => self.generate_vararg_func("ARRAYS_ZIP", &f.expressions),
2925 Expression::Sequence(f) => self.generate_sequence("SEQUENCE", f),
2926 Expression::Generate(f) => self.generate_sequence("GENERATE_SERIES", f),
2927
2928 Expression::StructFunc(f) => self.generate_struct_constructor(f),
2930 Expression::StructExtract(f) => self.generate_struct_extract(f),
2931 Expression::NamedStruct(f) => self.generate_named_struct(f),
2932
2933 Expression::MapFunc(f) => self.generate_map_constructor(f),
2935 Expression::MapFromEntries(f) => self.generate_simple_func("MAP_FROM_ENTRIES", &f.this),
2936 Expression::MapFromArrays(f) => {
2937 self.generate_binary_func("MAP_FROM_ARRAYS", &f.this, &f.expression)
2938 }
2939 Expression::MapKeys(f) => self.generate_simple_func("MAP_KEYS", &f.this),
2940 Expression::MapValues(f) => self.generate_simple_func("MAP_VALUES", &f.this),
2941 Expression::MapContainsKey(f) => {
2942 self.generate_binary_func("MAP_CONTAINS_KEY", &f.this, &f.expression)
2943 }
2944 Expression::MapConcat(f) => self.generate_vararg_func("MAP_CONCAT", &f.expressions),
2945 Expression::ElementAt(f) => {
2946 self.generate_binary_func("ELEMENT_AT", &f.this, &f.expression)
2947 }
2948 Expression::TransformKeys(f) => self.generate_transform_func("TRANSFORM_KEYS", f),
2949 Expression::TransformValues(f) => self.generate_transform_func("TRANSFORM_VALUES", f),
2950
2951 Expression::JsonExtract(f) => self.generate_json_extract("JSON_EXTRACT", f),
2953 Expression::JsonExtractScalar(f) => {
2954 self.generate_json_extract("JSON_EXTRACT_SCALAR", f)
2955 }
2956 Expression::JsonExtractPath(f) => self.generate_json_path("JSON_EXTRACT_PATH", f),
2957 Expression::JsonArray(f) => self.generate_vararg_func("JSON_ARRAY", &f.expressions),
2958 Expression::JsonObject(f) => self.generate_json_object(f),
2959 Expression::JsonQuery(f) => self.generate_json_extract("JSON_QUERY", f),
2960 Expression::JsonValue(f) => self.generate_json_extract("JSON_VALUE", f),
2961 Expression::JsonArrayLength(f) => {
2962 self.generate_simple_func("JSON_ARRAY_LENGTH", &f.this)
2963 }
2964 Expression::JsonKeys(f) => self.generate_simple_func("JSON_KEYS", &f.this),
2965 Expression::JsonType(f) => self.generate_simple_func("JSON_TYPE", &f.this),
2966 Expression::ParseJson(f) => {
2967 let name = match self.config.dialect {
2968 Some(DialectType::Presto)
2969 | Some(DialectType::Trino)
2970 | Some(DialectType::Athena) => "JSON_PARSE",
2971 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
2972 self.write_keyword("CAST");
2974 self.write("(");
2975 self.generate_expression(&f.this)?;
2976 self.write_keyword(" AS ");
2977 self.write_keyword("JSON");
2978 self.write(")");
2979 return Ok(());
2980 }
2981 Some(DialectType::Hive)
2982 | Some(DialectType::Spark)
2983 | Some(DialectType::MySQL)
2984 | Some(DialectType::SingleStore)
2985 | Some(DialectType::TiDB)
2986 | Some(DialectType::TSQL) => {
2987 self.generate_expression(&f.this)?;
2989 return Ok(());
2990 }
2991 Some(DialectType::DuckDB) => "JSON",
2992 _ => "PARSE_JSON",
2993 };
2994 self.generate_simple_func(name, &f.this)
2995 }
2996 Expression::ToJson(f) => self.generate_simple_func("TO_JSON", &f.this),
2997 Expression::JsonSet(f) => self.generate_json_modify("JSON_SET", f),
2998 Expression::JsonInsert(f) => self.generate_json_modify("JSON_INSERT", f),
2999 Expression::JsonRemove(f) => self.generate_json_path("JSON_REMOVE", f),
3000 Expression::JsonMergePatch(f) => {
3001 self.generate_binary_func("JSON_MERGE_PATCH", &f.this, &f.expression)
3002 }
3003 Expression::JsonArrayAgg(f) => self.generate_json_array_agg(f),
3004 Expression::JsonObjectAgg(f) => self.generate_json_object_agg(f),
3005
3006 Expression::Convert(f) => self.generate_convert(f),
3008 Expression::Typeof(f) => self.generate_simple_func("TYPEOF", &f.this),
3009
3010 Expression::Lambda(f) => self.generate_lambda(f),
3012 Expression::Parameter(f) => self.generate_parameter(f),
3013 Expression::Placeholder(f) => self.generate_placeholder(f),
3014 Expression::NamedArgument(f) => self.generate_named_argument(f),
3015 Expression::TableArgument(f) => self.generate_table_argument(f),
3016 Expression::SqlComment(f) => self.generate_sql_comment(f),
3017
3018 Expression::NullSafeEq(op) => self.generate_null_safe_eq(op),
3020 Expression::NullSafeNeq(op) => self.generate_null_safe_neq(op),
3021 Expression::Glob(op) => self.generate_binary_op(op, "GLOB"),
3022 Expression::SimilarTo(f) => self.generate_similar_to(f),
3023 Expression::Any(f) => self.generate_quantified("ANY", f),
3024 Expression::All(f) => self.generate_quantified("ALL", f),
3025 Expression::Overlaps(f) => self.generate_overlaps(f),
3026
3027 Expression::BitwiseLeftShift(op) => {
3029 if matches!(
3030 self.config.dialect,
3031 Some(DialectType::Presto) | Some(DialectType::Trino)
3032 ) {
3033 self.write_keyword("BITWISE_ARITHMETIC_SHIFT_LEFT");
3034 self.write("(");
3035 self.generate_expression(&op.left)?;
3036 self.write(", ");
3037 self.generate_expression(&op.right)?;
3038 self.write(")");
3039 Ok(())
3040 } else if matches!(
3041 self.config.dialect,
3042 Some(DialectType::Spark) | Some(DialectType::Databricks)
3043 ) {
3044 self.write_keyword("SHIFTLEFT");
3045 self.write("(");
3046 self.generate_expression(&op.left)?;
3047 self.write(", ");
3048 self.generate_expression(&op.right)?;
3049 self.write(")");
3050 Ok(())
3051 } else {
3052 self.generate_binary_op(op, "<<")
3053 }
3054 }
3055 Expression::BitwiseRightShift(op) => {
3056 if matches!(
3057 self.config.dialect,
3058 Some(DialectType::Presto) | Some(DialectType::Trino)
3059 ) {
3060 self.write_keyword("BITWISE_ARITHMETIC_SHIFT_RIGHT");
3061 self.write("(");
3062 self.generate_expression(&op.left)?;
3063 self.write(", ");
3064 self.generate_expression(&op.right)?;
3065 self.write(")");
3066 Ok(())
3067 } else if matches!(
3068 self.config.dialect,
3069 Some(DialectType::Spark) | Some(DialectType::Databricks)
3070 ) {
3071 self.write_keyword("SHIFTRIGHT");
3072 self.write("(");
3073 self.generate_expression(&op.left)?;
3074 self.write(", ");
3075 self.generate_expression(&op.right)?;
3076 self.write(")");
3077 Ok(())
3078 } else {
3079 self.generate_binary_op(op, ">>")
3080 }
3081 }
3082 Expression::BitwiseAndAgg(f) => self.generate_agg_func("BIT_AND", f),
3083 Expression::BitwiseOrAgg(f) => self.generate_agg_func("BIT_OR", f),
3084 Expression::BitwiseXorAgg(f) => self.generate_agg_func("BIT_XOR", f),
3085
3086 Expression::Subscript(s) => self.generate_subscript(s),
3088 Expression::Dot(d) => self.generate_dot_access(d),
3089 Expression::MethodCall(m) => self.generate_method_call(m),
3090 Expression::ArraySlice(s) => self.generate_array_slice(s),
3091
3092 Expression::And(op) => self.generate_connector_op(op, ConnectorOperator::And),
3093 Expression::Or(op) => self.generate_connector_op(op, ConnectorOperator::Or),
3094 Expression::Add(op) => self.generate_binary_op(op, "+"),
3095 Expression::Sub(op) => self.generate_binary_op(op, "-"),
3096 Expression::Mul(op) => self.generate_binary_op(op, "*"),
3097 Expression::Div(op) => self.generate_binary_op(op, "/"),
3098 Expression::IntDiv(f) => {
3099 use crate::dialects::DialectType;
3100 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
3101 self.generate_expression(&f.this)?;
3103 self.write(" // ");
3104 self.generate_expression(&f.expression)?;
3105 Ok(())
3106 } else if matches!(
3107 self.config.dialect,
3108 Some(DialectType::Hive | DialectType::Spark | DialectType::Databricks)
3109 ) {
3110 self.generate_expression(&f.this)?;
3112 self.write(" ");
3113 self.write_keyword("DIV");
3114 self.write(" ");
3115 self.generate_expression(&f.expression)?;
3116 Ok(())
3117 } else {
3118 self.write_keyword("DIV");
3120 self.write("(");
3121 self.generate_expression(&f.this)?;
3122 self.write(", ");
3123 self.generate_expression(&f.expression)?;
3124 self.write(")");
3125 Ok(())
3126 }
3127 }
3128 Expression::Mod(op) => {
3129 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
3130 self.generate_binary_op(op, "MOD")
3131 } else {
3132 self.generate_binary_op(op, "%")
3133 }
3134 }
3135 Expression::Eq(op) => self.generate_binary_op(op, "="),
3136 Expression::Neq(op) => self.generate_binary_op(op, "<>"),
3137 Expression::Lt(op) => self.generate_binary_op(op, "<"),
3138 Expression::Lte(op) => self.generate_binary_op(op, "<="),
3139 Expression::Gt(op) => self.generate_binary_op(op, ">"),
3140 Expression::Gte(op) => self.generate_binary_op(op, ">="),
3141 Expression::Like(op) => self.generate_like_op(op, "LIKE"),
3142 Expression::ILike(op) => self.generate_like_op(op, "ILIKE"),
3143 Expression::Match(op) => self.generate_binary_op(op, "MATCH"),
3144 Expression::Concat(op) => {
3145 if self.config.dialect == Some(DialectType::Solr) {
3147 self.generate_binary_op(op, "OR")
3148 } else if self.config.dialect == Some(DialectType::MySQL) {
3149 self.generate_mysql_concat_from_concat(op)
3150 } else {
3151 self.generate_binary_op(op, "||")
3152 }
3153 }
3154 Expression::BitwiseAnd(op) => {
3155 if matches!(
3157 self.config.dialect,
3158 Some(DialectType::Presto) | Some(DialectType::Trino)
3159 ) {
3160 self.write_keyword("BITWISE_AND");
3161 self.write("(");
3162 self.generate_expression(&op.left)?;
3163 self.write(", ");
3164 self.generate_expression(&op.right)?;
3165 self.write(")");
3166 Ok(())
3167 } else {
3168 self.generate_binary_op(op, "&")
3169 }
3170 }
3171 Expression::BitwiseOr(op) => {
3172 if matches!(
3174 self.config.dialect,
3175 Some(DialectType::Presto) | Some(DialectType::Trino)
3176 ) {
3177 self.write_keyword("BITWISE_OR");
3178 self.write("(");
3179 self.generate_expression(&op.left)?;
3180 self.write(", ");
3181 self.generate_expression(&op.right)?;
3182 self.write(")");
3183 Ok(())
3184 } else {
3185 self.generate_binary_op(op, "|")
3186 }
3187 }
3188 Expression::BitwiseXor(op) => {
3189 if matches!(
3191 self.config.dialect,
3192 Some(DialectType::Presto) | Some(DialectType::Trino)
3193 ) {
3194 self.write_keyword("BITWISE_XOR");
3195 self.write("(");
3196 self.generate_expression(&op.left)?;
3197 self.write(", ");
3198 self.generate_expression(&op.right)?;
3199 self.write(")");
3200 Ok(())
3201 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
3202 self.generate_binary_op(op, "#")
3203 } else {
3204 self.generate_binary_op(op, "^")
3205 }
3206 }
3207 Expression::Adjacent(op) => self.generate_binary_op(op, "-|-"),
3208 Expression::TsMatch(op) => self.generate_binary_op(op, "@@"),
3209 Expression::PropertyEQ(op) => self.generate_binary_op(op, ":="),
3210 Expression::ArrayContainsAll(op) => self.generate_binary_op(op, "@>"),
3211 Expression::ArrayContainedBy(op) => self.generate_binary_op(op, "<@"),
3212 Expression::ArrayOverlaps(op) => self.generate_binary_op(op, "&&"),
3213 Expression::JSONBContainsAllTopKeys(op) => self.generate_binary_op(op, "?&"),
3214 Expression::JSONBContainsAnyTopKeys(op) => self.generate_binary_op(op, "?|"),
3215 Expression::JSONBContains(f) => {
3216 self.generate_expression(&f.this)?;
3218 self.write_space();
3219 self.write("?");
3220 self.write_space();
3221 self.generate_expression(&f.expression)
3222 }
3223 Expression::JSONBDeleteAtPath(op) => self.generate_binary_op(op, "#-"),
3224 Expression::ExtendsLeft(op) => self.generate_binary_op(op, "&<"),
3225 Expression::ExtendsRight(op) => self.generate_binary_op(op, "&>"),
3226 Expression::Not(op) => self.generate_unary_op(op, "NOT"),
3227 Expression::Neg(op) => self.generate_unary_op(op, "-"),
3228 Expression::BitwiseNot(op) => {
3229 if matches!(
3231 self.config.dialect,
3232 Some(DialectType::Presto) | Some(DialectType::Trino)
3233 ) {
3234 self.write_keyword("BITWISE_NOT");
3235 self.write("(");
3236 self.generate_expression(&op.this)?;
3237 self.write(")");
3238 Ok(())
3239 } else {
3240 self.generate_unary_op(op, "~")
3241 }
3242 }
3243 Expression::In(in_expr) => self.generate_in(in_expr),
3244 Expression::Between(between) => self.generate_between(between),
3245 Expression::IsNull(is_null) => self.generate_is_null(is_null),
3246 Expression::IsTrue(is_true) => self.generate_is_true(is_true),
3247 Expression::IsFalse(is_false) => self.generate_is_false(is_false),
3248 Expression::IsJson(is_json) => self.generate_is_json(is_json),
3249 Expression::Is(is_expr) => self.generate_is(is_expr),
3250 Expression::Exists(exists) => self.generate_exists(exists),
3251 Expression::MemberOf(member_of) => self.generate_member_of(member_of),
3252 Expression::Subquery(subquery) => self.generate_subquery(subquery),
3253 Expression::Paren(paren) => {
3254 let skip_parens = matches!(&paren.this, Expression::JoinedTable(_));
3256
3257 if !skip_parens {
3258 self.write("(");
3259 if self.config.pretty {
3260 self.write_newline();
3261 self.indent_level += 1;
3262 self.write_indent();
3263 }
3264 }
3265 self.generate_expression(&paren.this)?;
3266 if !skip_parens {
3267 if self.config.pretty {
3268 self.write_newline();
3269 self.indent_level -= 1;
3270 self.write_indent();
3271 }
3272 self.write(")");
3273 }
3274 for comment in &paren.trailing_comments {
3276 self.write(" ");
3277 self.write_formatted_comment(comment);
3278 }
3279 Ok(())
3280 }
3281 Expression::Array(arr) => self.generate_array(arr),
3282 Expression::Tuple(tuple) => self.generate_tuple(tuple),
3283 Expression::PipeOperator(pipe) => self.generate_pipe_operator(pipe),
3284 Expression::Ordered(ordered) => self.generate_ordered(ordered),
3285 Expression::DataType(dt) => self.generate_data_type(dt),
3286 Expression::Raw(raw) => {
3287 self.write(&raw.sql);
3288 Ok(())
3289 }
3290 Expression::Command(cmd) => {
3291 self.write(&cmd.this);
3292 Ok(())
3293 }
3294 Expression::Kill(kill) => {
3295 self.write_keyword("KILL");
3296 if let Some(kind) = &kill.kind {
3297 self.write_space();
3298 self.write_keyword(kind);
3299 }
3300 self.write_space();
3301 self.generate_expression(&kill.this)?;
3302 Ok(())
3303 }
3304 Expression::Execute(exec) => {
3305 self.write_keyword("EXEC");
3306 self.write_space();
3307 self.generate_expression(&exec.this)?;
3308 for (i, param) in exec.parameters.iter().enumerate() {
3309 if i == 0 {
3310 self.write_space();
3311 } else {
3312 self.write(", ");
3313 }
3314 self.write(¶m.name);
3315 self.write("=");
3316 self.generate_expression(¶m.value)?;
3317 }
3318 Ok(())
3319 }
3320 Expression::Annotated(annotated) => {
3321 self.generate_expression(&annotated.this)?;
3322 for comment in &annotated.trailing_comments {
3323 self.write(" ");
3324 self.write_formatted_comment(comment);
3325 }
3326 Ok(())
3327 }
3328
3329 Expression::CreateTable(ct) => self.generate_create_table(ct),
3331 Expression::DropTable(dt) => self.generate_drop_table(dt),
3332 Expression::AlterTable(at) => self.generate_alter_table(at),
3333 Expression::CreateIndex(ci) => self.generate_create_index(ci),
3334 Expression::DropIndex(di) => self.generate_drop_index(di),
3335 Expression::CreateView(cv) => self.generate_create_view(cv),
3336 Expression::DropView(dv) => self.generate_drop_view(dv),
3337 Expression::AlterView(av) => self.generate_alter_view(av),
3338 Expression::AlterIndex(ai) => self.generate_alter_index(ai),
3339 Expression::Truncate(tr) => self.generate_truncate(tr),
3340 Expression::Use(u) => self.generate_use(u),
3341 Expression::CreateSchema(cs) => self.generate_create_schema(cs),
3343 Expression::DropSchema(ds) => self.generate_drop_schema(ds),
3344 Expression::DropNamespace(dn) => self.generate_drop_namespace(dn),
3345 Expression::CreateDatabase(cd) => self.generate_create_database(cd),
3346 Expression::DropDatabase(dd) => self.generate_drop_database(dd),
3347 Expression::CreateFunction(cf) => self.generate_create_function(cf),
3348 Expression::DropFunction(df) => self.generate_drop_function(df),
3349 Expression::CreateProcedure(cp) => self.generate_create_procedure(cp),
3350 Expression::DropProcedure(dp) => self.generate_drop_procedure(dp),
3351 Expression::CreateSequence(cs) => self.generate_create_sequence(cs),
3352 Expression::DropSequence(ds) => self.generate_drop_sequence(ds),
3353 Expression::AlterSequence(als) => self.generate_alter_sequence(als),
3354 Expression::CreateTrigger(ct) => self.generate_create_trigger(ct),
3355 Expression::DropTrigger(dt) => self.generate_drop_trigger(dt),
3356 Expression::CreateType(ct) => self.generate_create_type(ct),
3357 Expression::DropType(dt) => self.generate_drop_type(dt),
3358 Expression::Describe(d) => self.generate_describe(d),
3359 Expression::Show(s) => self.generate_show(s),
3360
3361 Expression::Cache(c) => self.generate_cache(c),
3363 Expression::Uncache(u) => self.generate_uncache(u),
3364 Expression::LoadData(l) => self.generate_load_data(l),
3365 Expression::Pragma(p) => self.generate_pragma(p),
3366 Expression::Grant(g) => self.generate_grant(g),
3367 Expression::Revoke(r) => self.generate_revoke(r),
3368 Expression::Comment(c) => self.generate_comment(c),
3369 Expression::SetStatement(s) => self.generate_set_statement(s),
3370
3371 Expression::Pivot(pivot) => self.generate_pivot(pivot),
3373 Expression::Unpivot(unpivot) => self.generate_unpivot(unpivot),
3374
3375 Expression::Values(values) => self.generate_values(values),
3377
3378 Expression::AIAgg(e) => self.generate_ai_agg(e),
3380 Expression::AIClassify(e) => self.generate_ai_classify(e),
3381 Expression::AddPartition(e) => self.generate_add_partition(e),
3382 Expression::AlgorithmProperty(e) => self.generate_algorithm_property(e),
3383 Expression::Aliases(e) => self.generate_aliases(e),
3384 Expression::AllowedValuesProperty(e) => self.generate_allowed_values_property(e),
3385 Expression::AlterColumn(e) => self.generate_alter_column(e),
3386 Expression::AlterSession(e) => self.generate_alter_session(e),
3387 Expression::AlterSet(e) => self.generate_alter_set(e),
3388 Expression::AlterSortKey(e) => self.generate_alter_sort_key(e),
3389 Expression::Analyze(e) => self.generate_analyze(e),
3390 Expression::AnalyzeDelete(e) => self.generate_analyze_delete(e),
3391 Expression::AnalyzeHistogram(e) => self.generate_analyze_histogram(e),
3392 Expression::AnalyzeListChainedRows(e) => self.generate_analyze_list_chained_rows(e),
3393 Expression::AnalyzeSample(e) => self.generate_analyze_sample(e),
3394 Expression::AnalyzeStatistics(e) => self.generate_analyze_statistics(e),
3395 Expression::AnalyzeValidate(e) => self.generate_analyze_validate(e),
3396 Expression::AnalyzeWith(e) => self.generate_analyze_with(e),
3397 Expression::Anonymous(e) => self.generate_anonymous(e),
3398 Expression::AnonymousAggFunc(e) => self.generate_anonymous_agg_func(e),
3399 Expression::Apply(e) => self.generate_apply(e),
3400 Expression::ApproxPercentileEstimate(e) => self.generate_approx_percentile_estimate(e),
3401 Expression::ApproxQuantile(e) => self.generate_approx_quantile(e),
3402 Expression::ApproxQuantiles(e) => self.generate_approx_quantiles(e),
3403 Expression::ApproxTopK(e) => self.generate_approx_top_k(e),
3404 Expression::ApproxTopKAccumulate(e) => self.generate_approx_top_k_accumulate(e),
3405 Expression::ApproxTopKCombine(e) => self.generate_approx_top_k_combine(e),
3406 Expression::ApproxTopKEstimate(e) => self.generate_approx_top_k_estimate(e),
3407 Expression::ApproxTopSum(e) => self.generate_approx_top_sum(e),
3408 Expression::ArgMax(e) => self.generate_arg_max(e),
3409 Expression::ArgMin(e) => self.generate_arg_min(e),
3410 Expression::ArrayAll(e) => self.generate_array_all(e),
3411 Expression::ArrayAny(e) => self.generate_array_any(e),
3412 Expression::ArrayConstructCompact(e) => self.generate_array_construct_compact(e),
3413 Expression::ArraySum(e) => self.generate_array_sum(e),
3414 Expression::AtIndex(e) => self.generate_at_index(e),
3415 Expression::Attach(e) => self.generate_attach(e),
3416 Expression::AttachOption(e) => self.generate_attach_option(e),
3417 Expression::AutoIncrementProperty(e) => self.generate_auto_increment_property(e),
3418 Expression::AutoRefreshProperty(e) => self.generate_auto_refresh_property(e),
3419 Expression::BackupProperty(e) => self.generate_backup_property(e),
3420 Expression::Base64DecodeBinary(e) => self.generate_base64_decode_binary(e),
3421 Expression::Base64DecodeString(e) => self.generate_base64_decode_string(e),
3422 Expression::Base64Encode(e) => self.generate_base64_encode(e),
3423 Expression::BlockCompressionProperty(e) => self.generate_block_compression_property(e),
3424 Expression::Booland(e) => self.generate_booland(e),
3425 Expression::Boolor(e) => self.generate_boolor(e),
3426 Expression::BuildProperty(e) => self.generate_build_property(e),
3427 Expression::ByteString(e) => self.generate_byte_string(e),
3428 Expression::CaseSpecificColumnConstraint(e) => {
3429 self.generate_case_specific_column_constraint(e)
3430 }
3431 Expression::CastToStrType(e) => self.generate_cast_to_str_type(e),
3432 Expression::Changes(e) => self.generate_changes(e),
3433 Expression::CharacterSetColumnConstraint(e) => {
3434 self.generate_character_set_column_constraint(e)
3435 }
3436 Expression::CharacterSetProperty(e) => self.generate_character_set_property(e),
3437 Expression::CheckColumnConstraint(e) => self.generate_check_column_constraint(e),
3438 Expression::CheckJson(e) => self.generate_check_json(e),
3439 Expression::CheckXml(e) => self.generate_check_xml(e),
3440 Expression::ChecksumProperty(e) => self.generate_checksum_property(e),
3441 Expression::Clone(e) => self.generate_clone(e),
3442 Expression::ClusterBy(e) => self.generate_cluster_by(e),
3443 Expression::ClusterByColumnsProperty(e) => self.generate_cluster_by_columns_property(e),
3444 Expression::ClusteredByProperty(e) => self.generate_clustered_by_property(e),
3445 Expression::CollateProperty(e) => self.generate_collate_property(e),
3446 Expression::ColumnConstraint(e) => self.generate_column_constraint(e),
3447 Expression::ColumnDef(e) => self.generate_column_def_expr(e),
3448 Expression::ColumnPosition(e) => self.generate_column_position(e),
3449 Expression::ColumnPrefix(e) => self.generate_column_prefix(e),
3450 Expression::Columns(e) => self.generate_columns(e),
3451 Expression::CombinedAggFunc(e) => self.generate_combined_agg_func(e),
3452 Expression::CombinedParameterizedAgg(e) => self.generate_combined_parameterized_agg(e),
3453 Expression::Commit(e) => self.generate_commit(e),
3454 Expression::Comprehension(e) => self.generate_comprehension(e),
3455 Expression::Compress(e) => self.generate_compress(e),
3456 Expression::CompressColumnConstraint(e) => self.generate_compress_column_constraint(e),
3457 Expression::ComputedColumnConstraint(e) => self.generate_computed_column_constraint(e),
3458 Expression::ConditionalInsert(e) => self.generate_conditional_insert(e),
3459 Expression::Constraint(e) => self.generate_constraint(e),
3460 Expression::ConvertTimezone(e) => self.generate_convert_timezone(e),
3461 Expression::ConvertToCharset(e) => self.generate_convert_to_charset(e),
3462 Expression::Copy(e) => self.generate_copy(e),
3463 Expression::CopyParameter(e) => self.generate_copy_parameter(e),
3464 Expression::Corr(e) => self.generate_corr(e),
3465 Expression::CosineDistance(e) => self.generate_cosine_distance(e),
3466 Expression::CovarPop(e) => self.generate_covar_pop(e),
3467 Expression::CovarSamp(e) => self.generate_covar_samp(e),
3468 Expression::Credentials(e) => self.generate_credentials(e),
3469 Expression::CredentialsProperty(e) => self.generate_credentials_property(e),
3470 Expression::Cte(e) => self.generate_cte(e),
3471 Expression::Cube(e) => self.generate_cube(e),
3472 Expression::CurrentDatetime(e) => self.generate_current_datetime(e),
3473 Expression::CurrentSchema(e) => self.generate_current_schema(e),
3474 Expression::CurrentSchemas(e) => self.generate_current_schemas(e),
3475 Expression::CurrentUser(e) => self.generate_current_user(e),
3476 Expression::DPipe(e) => self.generate_d_pipe(e),
3477 Expression::DataBlocksizeProperty(e) => self.generate_data_blocksize_property(e),
3478 Expression::DataDeletionProperty(e) => self.generate_data_deletion_property(e),
3479 Expression::Date(e) => self.generate_date_func(e),
3480 Expression::DateBin(e) => self.generate_date_bin(e),
3481 Expression::DateFormatColumnConstraint(e) => {
3482 self.generate_date_format_column_constraint(e)
3483 }
3484 Expression::DateFromParts(e) => self.generate_date_from_parts(e),
3485 Expression::Datetime(e) => self.generate_datetime(e),
3486 Expression::DatetimeAdd(e) => self.generate_datetime_add(e),
3487 Expression::DatetimeDiff(e) => self.generate_datetime_diff(e),
3488 Expression::DatetimeSub(e) => self.generate_datetime_sub(e),
3489 Expression::DatetimeTrunc(e) => self.generate_datetime_trunc(e),
3490 Expression::Dayname(e) => self.generate_dayname(e),
3491 Expression::Declare(e) => self.generate_declare(e),
3492 Expression::DeclareItem(e) => self.generate_declare_item(e),
3493 Expression::DecodeCase(e) => self.generate_decode_case(e),
3494 Expression::DecompressBinary(e) => self.generate_decompress_binary(e),
3495 Expression::DecompressString(e) => self.generate_decompress_string(e),
3496 Expression::Decrypt(e) => self.generate_decrypt(e),
3497 Expression::DecryptRaw(e) => self.generate_decrypt_raw(e),
3498 Expression::DefinerProperty(e) => self.generate_definer_property(e),
3499 Expression::Detach(e) => self.generate_detach(e),
3500 Expression::DictProperty(e) => self.generate_dict_property(e),
3501 Expression::DictRange(e) => self.generate_dict_range(e),
3502 Expression::Directory(e) => self.generate_directory(e),
3503 Expression::DistKeyProperty(e) => self.generate_dist_key_property(e),
3504 Expression::DistStyleProperty(e) => self.generate_dist_style_property(e),
3505 Expression::DistributeBy(e) => self.generate_distribute_by(e),
3506 Expression::DistributedByProperty(e) => self.generate_distributed_by_property(e),
3507 Expression::DotProduct(e) => self.generate_dot_product(e),
3508 Expression::DropPartition(e) => self.generate_drop_partition(e),
3509 Expression::DuplicateKeyProperty(e) => self.generate_duplicate_key_property(e),
3510 Expression::Elt(e) => self.generate_elt(e),
3511 Expression::Encode(e) => self.generate_encode(e),
3512 Expression::EncodeProperty(e) => self.generate_encode_property(e),
3513 Expression::Encrypt(e) => self.generate_encrypt(e),
3514 Expression::EncryptRaw(e) => self.generate_encrypt_raw(e),
3515 Expression::EngineProperty(e) => self.generate_engine_property(e),
3516 Expression::EnviromentProperty(e) => self.generate_enviroment_property(e),
3517 Expression::EphemeralColumnConstraint(e) => {
3518 self.generate_ephemeral_column_constraint(e)
3519 }
3520 Expression::EqualNull(e) => self.generate_equal_null(e),
3521 Expression::EuclideanDistance(e) => self.generate_euclidean_distance(e),
3522 Expression::ExecuteAsProperty(e) => self.generate_execute_as_property(e),
3523 Expression::Export(e) => self.generate_export(e),
3524 Expression::ExternalProperty(e) => self.generate_external_property(e),
3525 Expression::FallbackProperty(e) => self.generate_fallback_property(e),
3526 Expression::FarmFingerprint(e) => self.generate_farm_fingerprint(e),
3527 Expression::FeaturesAtTime(e) => self.generate_features_at_time(e),
3528 Expression::Fetch(e) => self.generate_fetch(e),
3529 Expression::FileFormatProperty(e) => self.generate_file_format_property(e),
3530 Expression::Filter(e) => self.generate_filter(e),
3531 Expression::Float64(e) => self.generate_float64(e),
3532 Expression::ForIn(e) => self.generate_for_in(e),
3533 Expression::ForeignKey(e) => self.generate_foreign_key(e),
3534 Expression::Format(e) => self.generate_format(e),
3535 Expression::FormatPhrase(e) => self.generate_format_phrase(e),
3536 Expression::FreespaceProperty(e) => self.generate_freespace_property(e),
3537 Expression::From(e) => self.generate_from(e),
3538 Expression::FromBase(e) => self.generate_from_base(e),
3539 Expression::FromTimeZone(e) => self.generate_from_time_zone(e),
3540 Expression::GapFill(e) => self.generate_gap_fill(e),
3541 Expression::GenerateDateArray(e) => self.generate_generate_date_array(e),
3542 Expression::GenerateEmbedding(e) => self.generate_generate_embedding(e),
3543 Expression::GenerateSeries(e) => self.generate_generate_series(e),
3544 Expression::GenerateTimestampArray(e) => self.generate_generate_timestamp_array(e),
3545 Expression::GeneratedAsIdentityColumnConstraint(e) => {
3546 self.generate_generated_as_identity_column_constraint(e)
3547 }
3548 Expression::GeneratedAsRowColumnConstraint(e) => {
3549 self.generate_generated_as_row_column_constraint(e)
3550 }
3551 Expression::Get(e) => self.generate_get(e),
3552 Expression::GetExtract(e) => self.generate_get_extract(e),
3553 Expression::Getbit(e) => self.generate_getbit(e),
3554 Expression::GrantPrincipal(e) => self.generate_grant_principal(e),
3555 Expression::GrantPrivilege(e) => self.generate_grant_privilege(e),
3556 Expression::Group(e) => self.generate_group(e),
3557 Expression::GroupBy(e) => self.generate_group_by(e),
3558 Expression::Grouping(e) => self.generate_grouping(e),
3559 Expression::GroupingId(e) => self.generate_grouping_id(e),
3560 Expression::GroupingSets(e) => self.generate_grouping_sets(e),
3561 Expression::HashAgg(e) => self.generate_hash_agg(e),
3562 Expression::Having(e) => self.generate_having(e),
3563 Expression::HavingMax(e) => self.generate_having_max(e),
3564 Expression::Heredoc(e) => self.generate_heredoc(e),
3565 Expression::HexEncode(e) => self.generate_hex_encode(e),
3566 Expression::Hll(e) => self.generate_hll(e),
3567 Expression::InOutColumnConstraint(e) => self.generate_in_out_column_constraint(e),
3568 Expression::IncludeProperty(e) => self.generate_include_property(e),
3569 Expression::Index(e) => self.generate_index(e),
3570 Expression::IndexColumnConstraint(e) => self.generate_index_column_constraint(e),
3571 Expression::IndexConstraintOption(e) => self.generate_index_constraint_option(e),
3572 Expression::IndexParameters(e) => self.generate_index_parameters(e),
3573 Expression::IndexTableHint(e) => self.generate_index_table_hint(e),
3574 Expression::InheritsProperty(e) => self.generate_inherits_property(e),
3575 Expression::InputModelProperty(e) => self.generate_input_model_property(e),
3576 Expression::InputOutputFormat(e) => self.generate_input_output_format(e),
3577 Expression::Install(e) => self.generate_install(e),
3578 Expression::IntervalOp(e) => self.generate_interval_op(e),
3579 Expression::IntervalSpan(e) => self.generate_interval_span(e),
3580 Expression::IntoClause(e) => self.generate_into_clause(e),
3581 Expression::Introducer(e) => self.generate_introducer(e),
3582 Expression::IsolatedLoadingProperty(e) => self.generate_isolated_loading_property(e),
3583 Expression::JSON(e) => self.generate_json(e),
3584 Expression::JSONArray(e) => self.generate_json_array(e),
3585 Expression::JSONArrayAgg(e) => self.generate_json_array_agg_struct(e),
3586 Expression::JSONArrayAppend(e) => self.generate_json_array_append(e),
3587 Expression::JSONArrayContains(e) => self.generate_json_array_contains(e),
3588 Expression::JSONArrayInsert(e) => self.generate_json_array_insert(e),
3589 Expression::JSONBExists(e) => self.generate_jsonb_exists(e),
3590 Expression::JSONBExtractScalar(e) => self.generate_jsonb_extract_scalar(e),
3591 Expression::JSONBObjectAgg(e) => self.generate_jsonb_object_agg(e),
3592 Expression::JSONObjectAgg(e) => self.generate_json_object_agg_struct(e),
3593 Expression::JSONColumnDef(e) => self.generate_json_column_def(e),
3594 Expression::JSONExists(e) => self.generate_json_exists(e),
3595 Expression::JSONCast(e) => self.generate_json_cast(e),
3596 Expression::JSONExtract(e) => self.generate_json_extract_path(e),
3597 Expression::JSONExtractArray(e) => self.generate_json_extract_array(e),
3598 Expression::JSONExtractQuote(e) => self.generate_json_extract_quote(e),
3599 Expression::JSONExtractScalar(e) => self.generate_json_extract_scalar(e),
3600 Expression::JSONFormat(e) => self.generate_json_format(e),
3601 Expression::JSONKeyValue(e) => self.generate_json_key_value(e),
3602 Expression::JSONKeys(e) => self.generate_json_keys(e),
3603 Expression::JSONKeysAtDepth(e) => self.generate_json_keys_at_depth(e),
3604 Expression::JSONPath(e) => self.generate_json_path_expr(e),
3605 Expression::JSONPathFilter(e) => self.generate_json_path_filter(e),
3606 Expression::JSONPathKey(e) => self.generate_json_path_key(e),
3607 Expression::JSONPathRecursive(e) => self.generate_json_path_recursive(e),
3608 Expression::JSONPathRoot(_) => self.generate_json_path_root(),
3609 Expression::JSONPathScript(e) => self.generate_json_path_script(e),
3610 Expression::JSONPathSelector(e) => self.generate_json_path_selector(e),
3611 Expression::JSONPathSlice(e) => self.generate_json_path_slice(e),
3612 Expression::JSONPathSubscript(e) => self.generate_json_path_subscript(e),
3613 Expression::JSONPathUnion(e) => self.generate_json_path_union(e),
3614 Expression::JSONRemove(e) => self.generate_json_remove(e),
3615 Expression::JSONSchema(e) => self.generate_json_schema(e),
3616 Expression::JSONSet(e) => self.generate_json_set(e),
3617 Expression::JSONStripNulls(e) => self.generate_json_strip_nulls(e),
3618 Expression::JSONTable(e) => self.generate_json_table(e),
3619 Expression::JSONType(e) => self.generate_json_type(e),
3620 Expression::JSONValue(e) => self.generate_json_value(e),
3621 Expression::JSONValueArray(e) => self.generate_json_value_array(e),
3622 Expression::JarowinklerSimilarity(e) => self.generate_jarowinkler_similarity(e),
3623 Expression::JoinHint(e) => self.generate_join_hint(e),
3624 Expression::JournalProperty(e) => self.generate_journal_property(e),
3625 Expression::LanguageProperty(e) => self.generate_language_property(e),
3626 Expression::Lateral(e) => self.generate_lateral(e),
3627 Expression::LikeProperty(e) => self.generate_like_property(e),
3628 Expression::Limit(e) => self.generate_limit(e),
3629 Expression::LimitOptions(e) => self.generate_limit_options(e),
3630 Expression::List(e) => self.generate_list(e),
3631 Expression::ToMap(e) => self.generate_tomap(e),
3632 Expression::Localtime(e) => self.generate_localtime(e),
3633 Expression::Localtimestamp(e) => self.generate_localtimestamp(e),
3634 Expression::LocationProperty(e) => self.generate_location_property(e),
3635 Expression::Lock(e) => self.generate_lock(e),
3636 Expression::LockProperty(e) => self.generate_lock_property(e),
3637 Expression::LockingProperty(e) => self.generate_locking_property(e),
3638 Expression::LockingStatement(e) => self.generate_locking_statement(e),
3639 Expression::LogProperty(e) => self.generate_log_property(e),
3640 Expression::MD5Digest(e) => self.generate_md5_digest(e),
3641 Expression::MLForecast(e) => self.generate_ml_forecast(e),
3642 Expression::MLTranslate(e) => self.generate_ml_translate(e),
3643 Expression::MakeInterval(e) => self.generate_make_interval(e),
3644 Expression::ManhattanDistance(e) => self.generate_manhattan_distance(e),
3645 Expression::Map(e) => self.generate_map(e),
3646 Expression::MapCat(e) => self.generate_map_cat(e),
3647 Expression::MapDelete(e) => self.generate_map_delete(e),
3648 Expression::MapInsert(e) => self.generate_map_insert(e),
3649 Expression::MapPick(e) => self.generate_map_pick(e),
3650 Expression::MaskingPolicyColumnConstraint(e) => {
3651 self.generate_masking_policy_column_constraint(e)
3652 }
3653 Expression::MatchAgainst(e) => self.generate_match_against(e),
3654 Expression::MatchRecognizeMeasure(e) => self.generate_match_recognize_measure(e),
3655 Expression::MaterializedProperty(e) => self.generate_materialized_property(e),
3656 Expression::Merge(e) => self.generate_merge(e),
3657 Expression::MergeBlockRatioProperty(e) => self.generate_merge_block_ratio_property(e),
3658 Expression::MergeTreeTTL(e) => self.generate_merge_tree_ttl(e),
3659 Expression::MergeTreeTTLAction(e) => self.generate_merge_tree_ttl_action(e),
3660 Expression::Minhash(e) => self.generate_minhash(e),
3661 Expression::ModelAttribute(e) => self.generate_model_attribute(e),
3662 Expression::Monthname(e) => self.generate_monthname(e),
3663 Expression::MultitableInserts(e) => self.generate_multitable_inserts(e),
3664 Expression::NextValueFor(e) => self.generate_next_value_for(e),
3665 Expression::Normal(e) => self.generate_normal(e),
3666 Expression::Normalize(e) => self.generate_normalize(e),
3667 Expression::NotNullColumnConstraint(e) => self.generate_not_null_column_constraint(e),
3668 Expression::Nullif(e) => self.generate_nullif(e),
3669 Expression::NumberToStr(e) => self.generate_number_to_str(e),
3670 Expression::ObjectAgg(e) => self.generate_object_agg(e),
3671 Expression::ObjectIdentifier(e) => self.generate_object_identifier(e),
3672 Expression::ObjectInsert(e) => self.generate_object_insert(e),
3673 Expression::Offset(e) => self.generate_offset(e),
3674 Expression::Qualify(e) => self.generate_qualify(e),
3675 Expression::OnCluster(e) => self.generate_on_cluster(e),
3676 Expression::OnCommitProperty(e) => self.generate_on_commit_property(e),
3677 Expression::OnCondition(e) => self.generate_on_condition(e),
3678 Expression::OnConflict(e) => self.generate_on_conflict(e),
3679 Expression::OnProperty(e) => self.generate_on_property(e),
3680 Expression::Opclass(e) => self.generate_opclass(e),
3681 Expression::OpenJSON(e) => self.generate_open_json(e),
3682 Expression::OpenJSONColumnDef(e) => self.generate_open_json_column_def(e),
3683 Expression::Operator(e) => self.generate_operator(e),
3684 Expression::OrderBy(e) => self.generate_order_by(e),
3685 Expression::OutputModelProperty(e) => self.generate_output_model_property(e),
3686 Expression::OverflowTruncateBehavior(e) => self.generate_overflow_truncate_behavior(e),
3687 Expression::ParameterizedAgg(e) => self.generate_parameterized_agg(e),
3688 Expression::ParseDatetime(e) => self.generate_parse_datetime(e),
3689 Expression::ParseIp(e) => self.generate_parse_ip(e),
3690 Expression::ParseJSON(e) => self.generate_parse_json(e),
3691 Expression::ParseTime(e) => self.generate_parse_time(e),
3692 Expression::ParseUrl(e) => self.generate_parse_url(e),
3693 Expression::Partition(e) => self.generate_partition_expr(e),
3694 Expression::PartitionBoundSpec(e) => self.generate_partition_bound_spec(e),
3695 Expression::PartitionByListProperty(e) => self.generate_partition_by_list_property(e),
3696 Expression::PartitionByRangeProperty(e) => self.generate_partition_by_range_property(e),
3697 Expression::PartitionByRangePropertyDynamic(e) => {
3698 self.generate_partition_by_range_property_dynamic(e)
3699 }
3700 Expression::PartitionByTruncate(e) => self.generate_partition_by_truncate(e),
3701 Expression::PartitionList(e) => self.generate_partition_list(e),
3702 Expression::PartitionRange(e) => self.generate_partition_range(e),
3703 Expression::PartitionByProperty(e) => self.generate_partition_by_property(e),
3704 Expression::PartitionedByBucket(e) => self.generate_partitioned_by_bucket(e),
3705 Expression::PartitionedByProperty(e) => self.generate_partitioned_by_property(e),
3706 Expression::PartitionedOfProperty(e) => self.generate_partitioned_of_property(e),
3707 Expression::PeriodForSystemTimeConstraint(e) => {
3708 self.generate_period_for_system_time_constraint(e)
3709 }
3710 Expression::PivotAlias(e) => self.generate_pivot_alias(e),
3711 Expression::PivotAny(e) => self.generate_pivot_any(e),
3712 Expression::Predict(e) => self.generate_predict(e),
3713 Expression::PreviousDay(e) => self.generate_previous_day(e),
3714 Expression::PrimaryKey(e) => self.generate_primary_key(e),
3715 Expression::PrimaryKeyColumnConstraint(e) => {
3716 self.generate_primary_key_column_constraint(e)
3717 }
3718 Expression::PathColumnConstraint(e) => self.generate_path_column_constraint(e),
3719 Expression::ProjectionDef(e) => self.generate_projection_def(e),
3720 Expression::OptionsProperty(e) => self.generate_options_property(e),
3721 Expression::Properties(e) => self.generate_properties(e),
3722 Expression::Property(e) => self.generate_property(e),
3723 Expression::PseudoType(e) => self.generate_pseudo_type(e),
3724 Expression::Put(e) => self.generate_put(e),
3725 Expression::Quantile(e) => self.generate_quantile(e),
3726 Expression::QueryBand(e) => self.generate_query_band(e),
3727 Expression::QueryOption(e) => self.generate_query_option(e),
3728 Expression::QueryTransform(e) => self.generate_query_transform(e),
3729 Expression::Randn(e) => self.generate_randn(e),
3730 Expression::Randstr(e) => self.generate_randstr(e),
3731 Expression::RangeBucket(e) => self.generate_range_bucket(e),
3732 Expression::RangeN(e) => self.generate_range_n(e),
3733 Expression::ReadCSV(e) => self.generate_read_csv(e),
3734 Expression::ReadParquet(e) => self.generate_read_parquet(e),
3735 Expression::RecursiveWithSearch(e) => self.generate_recursive_with_search(e),
3736 Expression::Reduce(e) => self.generate_reduce(e),
3737 Expression::Reference(e) => self.generate_reference(e),
3738 Expression::Refresh(e) => self.generate_refresh(e),
3739 Expression::RefreshTriggerProperty(e) => self.generate_refresh_trigger_property(e),
3740 Expression::RegexpCount(e) => self.generate_regexp_count(e),
3741 Expression::RegexpExtractAll(e) => self.generate_regexp_extract_all(e),
3742 Expression::RegexpFullMatch(e) => self.generate_regexp_full_match(e),
3743 Expression::RegexpILike(e) => self.generate_regexp_i_like(e),
3744 Expression::RegexpInstr(e) => self.generate_regexp_instr(e),
3745 Expression::RegexpSplit(e) => self.generate_regexp_split(e),
3746 Expression::RegrAvgx(e) => self.generate_regr_avgx(e),
3747 Expression::RegrAvgy(e) => self.generate_regr_avgy(e),
3748 Expression::RegrCount(e) => self.generate_regr_count(e),
3749 Expression::RegrIntercept(e) => self.generate_regr_intercept(e),
3750 Expression::RegrR2(e) => self.generate_regr_r2(e),
3751 Expression::RegrSlope(e) => self.generate_regr_slope(e),
3752 Expression::RegrSxx(e) => self.generate_regr_sxx(e),
3753 Expression::RegrSxy(e) => self.generate_regr_sxy(e),
3754 Expression::RegrSyy(e) => self.generate_regr_syy(e),
3755 Expression::RegrValx(e) => self.generate_regr_valx(e),
3756 Expression::RegrValy(e) => self.generate_regr_valy(e),
3757 Expression::RemoteWithConnectionModelProperty(e) => {
3758 self.generate_remote_with_connection_model_property(e)
3759 }
3760 Expression::RenameColumn(e) => self.generate_rename_column(e),
3761 Expression::ReplacePartition(e) => self.generate_replace_partition(e),
3762 Expression::Returning(e) => self.generate_returning(e),
3763 Expression::ReturnsProperty(e) => self.generate_returns_property(e),
3764 Expression::Rollback(e) => self.generate_rollback(e),
3765 Expression::Rollup(e) => self.generate_rollup(e),
3766 Expression::RowFormatDelimitedProperty(e) => {
3767 self.generate_row_format_delimited_property(e)
3768 }
3769 Expression::RowFormatProperty(e) => self.generate_row_format_property(e),
3770 Expression::RowFormatSerdeProperty(e) => self.generate_row_format_serde_property(e),
3771 Expression::SHA2(e) => self.generate_sha2(e),
3772 Expression::SHA2Digest(e) => self.generate_sha2_digest(e),
3773 Expression::SafeAdd(e) => self.generate_safe_add(e),
3774 Expression::SafeDivide(e) => self.generate_safe_divide(e),
3775 Expression::SafeMultiply(e) => self.generate_safe_multiply(e),
3776 Expression::SafeSubtract(e) => self.generate_safe_subtract(e),
3777 Expression::SampleProperty(e) => self.generate_sample_property(e),
3778 Expression::Schema(e) => self.generate_schema(e),
3779 Expression::SchemaCommentProperty(e) => self.generate_schema_comment_property(e),
3780 Expression::ScopeResolution(e) => self.generate_scope_resolution(e),
3781 Expression::Search(e) => self.generate_search(e),
3782 Expression::SearchIp(e) => self.generate_search_ip(e),
3783 Expression::SecurityProperty(e) => self.generate_security_property(e),
3784 Expression::SemanticView(e) => self.generate_semantic_view(e),
3785 Expression::SequenceProperties(e) => self.generate_sequence_properties(e),
3786 Expression::SerdeProperties(e) => self.generate_serde_properties(e),
3787 Expression::SessionParameter(e) => self.generate_session_parameter(e),
3788 Expression::Set(e) => self.generate_set(e),
3789 Expression::SetConfigProperty(e) => self.generate_set_config_property(e),
3790 Expression::SetItem(e) => self.generate_set_item(e),
3791 Expression::SetOperation(e) => self.generate_set_operation(e),
3792 Expression::SetProperty(e) => self.generate_set_property(e),
3793 Expression::SettingsProperty(e) => self.generate_settings_property(e),
3794 Expression::SharingProperty(e) => self.generate_sharing_property(e),
3795 Expression::Slice(e) => self.generate_slice(e),
3796 Expression::SortArray(e) => self.generate_sort_array(e),
3797 Expression::SortBy(e) => self.generate_sort_by(e),
3798 Expression::SortKeyProperty(e) => self.generate_sort_key_property(e),
3799 Expression::SplitPart(e) => self.generate_split_part(e),
3800 Expression::SqlReadWriteProperty(e) => self.generate_sql_read_write_property(e),
3801 Expression::SqlSecurityProperty(e) => self.generate_sql_security_property(e),
3802 Expression::StDistance(e) => self.generate_st_distance(e),
3803 Expression::StPoint(e) => self.generate_st_point(e),
3804 Expression::StabilityProperty(e) => self.generate_stability_property(e),
3805 Expression::StandardHash(e) => self.generate_standard_hash(e),
3806 Expression::StorageHandlerProperty(e) => self.generate_storage_handler_property(e),
3807 Expression::StrPosition(e) => self.generate_str_position(e),
3808 Expression::StrToDate(e) => self.generate_str_to_date(e),
3809 Expression::DateStrToDate(f) => self.generate_simple_func("DATE_STR_TO_DATE", &f.this),
3810 Expression::DateToDateStr(f) => self.generate_simple_func("DATE_TO_DATE_STR", &f.this),
3811 Expression::StrToMap(e) => self.generate_str_to_map(e),
3812 Expression::StrToTime(e) => self.generate_str_to_time(e),
3813 Expression::StrToUnix(e) => self.generate_str_to_unix(e),
3814 Expression::StringToArray(e) => self.generate_string_to_array(e),
3815 Expression::Struct(e) => self.generate_struct(e),
3816 Expression::Stuff(e) => self.generate_stuff(e),
3817 Expression::SubstringIndex(e) => self.generate_substring_index(e),
3818 Expression::Summarize(e) => self.generate_summarize(e),
3819 Expression::Systimestamp(e) => self.generate_systimestamp(e),
3820 Expression::TableAlias(e) => self.generate_table_alias(e),
3821 Expression::TableFromRows(e) => self.generate_table_from_rows(e),
3822 Expression::RowsFrom(e) => self.generate_rows_from(e),
3823 Expression::TableSample(e) => self.generate_table_sample(e),
3824 Expression::Tag(e) => self.generate_tag(e),
3825 Expression::Tags(e) => self.generate_tags(e),
3826 Expression::TemporaryProperty(e) => self.generate_temporary_property(e),
3827 Expression::Time(e) => self.generate_time_func(e),
3828 Expression::TimeAdd(e) => self.generate_time_add(e),
3829 Expression::TimeDiff(e) => self.generate_time_diff(e),
3830 Expression::TimeFromParts(e) => self.generate_time_from_parts(e),
3831 Expression::TimeSlice(e) => self.generate_time_slice(e),
3832 Expression::TimeStrToDate(e) => self.generate_time_str_to_date(e),
3833 Expression::TimeStrToTime(e) => self.generate_time_str_to_time(e),
3834 Expression::TimeSub(e) => self.generate_time_sub(e),
3835 Expression::TimeToStr(e) => self.generate_time_to_str(e),
3836 Expression::TimeToUnix(e) => self.generate_time_to_unix(e),
3837 Expression::TimeTrunc(e) => self.generate_time_trunc(e),
3838 Expression::TimeUnit(e) => self.generate_time_unit(e),
3839 Expression::Timestamp(e) => self.generate_timestamp_func(e),
3840 Expression::TimestampAdd(e) => self.generate_timestamp_add(e),
3841 Expression::TimestampDiff(e) => self.generate_timestamp_diff(e),
3842 Expression::TimestampFromParts(e) => self.generate_timestamp_from_parts(e),
3843 Expression::TimestampSub(e) => self.generate_timestamp_sub(e),
3844 Expression::TimestampTzFromParts(e) => self.generate_timestamp_tz_from_parts(e),
3845 Expression::ToBinary(e) => self.generate_to_binary(e),
3846 Expression::ToBoolean(e) => self.generate_to_boolean(e),
3847 Expression::ToChar(e) => self.generate_to_char(e),
3848 Expression::ToDecfloat(e) => self.generate_to_decfloat(e),
3849 Expression::ToDouble(e) => self.generate_to_double(e),
3850 Expression::ToFile(e) => self.generate_to_file(e),
3851 Expression::ToNumber(e) => self.generate_to_number(e),
3852 Expression::ToTableProperty(e) => self.generate_to_table_property(e),
3853 Expression::Transaction(e) => self.generate_transaction(e),
3854 Expression::Transform(e) => self.generate_transform(e),
3855 Expression::TransformModelProperty(e) => self.generate_transform_model_property(e),
3856 Expression::TransientProperty(e) => self.generate_transient_property(e),
3857 Expression::Translate(e) => self.generate_translate(e),
3858 Expression::TranslateCharacters(e) => self.generate_translate_characters(e),
3859 Expression::TruncateTable(e) => self.generate_truncate_table(e),
3860 Expression::TryBase64DecodeBinary(e) => self.generate_try_base64_decode_binary(e),
3861 Expression::TryBase64DecodeString(e) => self.generate_try_base64_decode_string(e),
3862 Expression::TryToDecfloat(e) => self.generate_try_to_decfloat(e),
3863 Expression::TsOrDsAdd(e) => self.generate_ts_or_ds_add(e),
3864 Expression::TsOrDsDiff(e) => self.generate_ts_or_ds_diff(e),
3865 Expression::TsOrDsToDate(e) => self.generate_ts_or_ds_to_date(e),
3866 Expression::TsOrDsToTime(e) => self.generate_ts_or_ds_to_time(e),
3867 Expression::Unhex(e) => self.generate_unhex(e),
3868 Expression::UnicodeString(e) => self.generate_unicode_string(e),
3869 Expression::Uniform(e) => self.generate_uniform(e),
3870 Expression::UniqueColumnConstraint(e) => self.generate_unique_column_constraint(e),
3871 Expression::UniqueKeyProperty(e) => self.generate_unique_key_property(e),
3872 Expression::RollupProperty(e) => self.generate_rollup_property(e),
3873 Expression::UnixToStr(e) => self.generate_unix_to_str(e),
3874 Expression::UnixToTime(e) => self.generate_unix_to_time(e),
3875 Expression::UnpivotColumns(e) => self.generate_unpivot_columns(e),
3876 Expression::UserDefinedFunction(e) => self.generate_user_defined_function(e),
3877 Expression::UsingTemplateProperty(e) => self.generate_using_template_property(e),
3878 Expression::UtcTime(e) => self.generate_utc_time(e),
3879 Expression::UtcTimestamp(e) => self.generate_utc_timestamp(e),
3880 Expression::Uuid(e) => self.generate_uuid(e),
3881 Expression::Var(v) => {
3882 if matches!(self.config.dialect, Some(DialectType::MySQL))
3883 && v.this.len() > 2
3884 && (v.this.starts_with("0x") || v.this.starts_with("0X"))
3885 && !v.this[2..].chars().all(|c| c.is_ascii_hexdigit())
3886 {
3887 return self.generate_identifier(&Identifier {
3888 name: v.this.clone(),
3889 quoted: true,
3890 trailing_comments: Vec::new(),
3891 span: None,
3892 });
3893 }
3894 self.write(&v.this);
3895 Ok(())
3896 }
3897 Expression::Variadic(e) => {
3898 self.write_keyword("VARIADIC");
3899 self.write_space();
3900 self.generate_expression(&e.this)?;
3901 Ok(())
3902 }
3903 Expression::VarMap(e) => self.generate_var_map(e),
3904 Expression::VectorSearch(e) => self.generate_vector_search(e),
3905 Expression::Version(e) => self.generate_version(e),
3906 Expression::ViewAttributeProperty(e) => self.generate_view_attribute_property(e),
3907 Expression::VolatileProperty(e) => self.generate_volatile_property(e),
3908 Expression::WatermarkColumnConstraint(e) => {
3909 self.generate_watermark_column_constraint(e)
3910 }
3911 Expression::Week(e) => self.generate_week(e),
3912 Expression::When(e) => self.generate_when(e),
3913 Expression::Whens(e) => self.generate_whens(e),
3914 Expression::Where(e) => self.generate_where(e),
3915 Expression::WidthBucket(e) => self.generate_width_bucket(e),
3916 Expression::Window(e) => self.generate_window(e),
3917 Expression::WindowSpec(e) => self.generate_window_spec(e),
3918 Expression::WithDataProperty(e) => self.generate_with_data_property(e),
3919 Expression::WithFill(e) => self.generate_with_fill(e),
3920 Expression::WithJournalTableProperty(e) => self.generate_with_journal_table_property(e),
3921 Expression::WithOperator(e) => self.generate_with_operator(e),
3922 Expression::WithProcedureOptions(e) => self.generate_with_procedure_options(e),
3923 Expression::WithSchemaBindingProperty(e) => {
3924 self.generate_with_schema_binding_property(e)
3925 }
3926 Expression::WithSystemVersioningProperty(e) => {
3927 self.generate_with_system_versioning_property(e)
3928 }
3929 Expression::WithTableHint(e) => self.generate_with_table_hint(e),
3930 Expression::XMLElement(e) => self.generate_xml_element(e),
3931 Expression::XMLGet(e) => self.generate_xml_get(e),
3932 Expression::XMLKeyValueOption(e) => self.generate_xml_key_value_option(e),
3933 Expression::XMLTable(e) => self.generate_xml_table(e),
3934 Expression::Xor(e) => self.generate_xor(e),
3935 Expression::Zipf(e) => self.generate_zipf(e),
3936 _ => self.write_unsupported_comment("unsupported expression"),
3937 }
3938 }
3939
3940 fn generate_select(&mut self, select: &Select) -> Result<()> {
3941 use crate::dialects::DialectType;
3942
3943 for comment in &select.leading_comments {
3945 self.write_formatted_comment(comment);
3946 self.write(" ");
3947 }
3948
3949 if let Some(with) = &select.with {
3951 self.generate_with(with)?;
3952 if self.config.pretty {
3953 self.write_newline();
3954 self.write_indent();
3955 } else {
3956 self.write_space();
3957 }
3958 }
3959
3960 for comment in &select.post_select_comments {
3963 self.write_formatted_comment(comment);
3964 self.write(" ");
3965 }
3966
3967 self.write_keyword("SELECT");
3968
3969 if let Some(hint) = &select.hint {
3971 self.generate_hint(hint)?;
3972 }
3973
3974 let use_top_from_limit = matches!(self.config.dialect, Some(DialectType::TSQL))
3978 && select.top.is_none()
3979 && select.limit.is_some()
3980 && select.offset.is_none(); let is_top_dialect = matches!(
3985 self.config.dialect,
3986 Some(DialectType::TSQL) | Some(DialectType::Teradata) | Some(DialectType::Fabric)
3987 );
3988 let keep_top_verbatim = !is_top_dialect
3989 && select.limit.is_none()
3990 && select
3991 .top
3992 .as_ref()
3993 .map_or(false, |top| top.percent || top.with_ties);
3994
3995 if select.distinct && (is_top_dialect || select.top.is_some()) {
3996 self.write_space();
3997 self.write_keyword("DISTINCT");
3998 }
3999
4000 if is_top_dialect || keep_top_verbatim {
4001 if let Some(top) = &select.top {
4002 self.write_space();
4003 self.write_keyword("TOP");
4004 if top.parenthesized {
4005 self.write(" (");
4006 self.generate_expression(&top.this)?;
4007 self.write(")");
4008 } else {
4009 self.write_space();
4010 self.generate_expression(&top.this)?;
4011 }
4012 if top.percent {
4013 self.write_space();
4014 self.write_keyword("PERCENT");
4015 }
4016 if top.with_ties {
4017 self.write_space();
4018 self.write_keyword("WITH TIES");
4019 }
4020 } else if use_top_from_limit {
4021 if let Some(limit) = &select.limit {
4023 self.write_space();
4024 self.write_keyword("TOP");
4025 let is_simple_literal =
4027 matches!(&limit.this, Expression::Literal(Literal::Number(_)));
4028 if is_simple_literal {
4029 self.write_space();
4030 self.generate_expression(&limit.this)?;
4031 } else {
4032 self.write(" (");
4033 self.generate_expression(&limit.this)?;
4034 self.write(")");
4035 }
4036 }
4037 }
4038 }
4039
4040 if select.distinct && !is_top_dialect && select.top.is_none() {
4041 self.write_space();
4042 self.write_keyword("DISTINCT");
4043 }
4044
4045 if let Some(distinct_on) = &select.distinct_on {
4047 self.write_space();
4048 self.write_keyword("ON");
4049 self.write(" (");
4050 for (i, expr) in distinct_on.iter().enumerate() {
4051 if i > 0 {
4052 self.write(", ");
4053 }
4054 self.generate_expression(expr)?;
4055 }
4056 self.write(")");
4057 }
4058
4059 for modifier in &select.operation_modifiers {
4061 self.write_space();
4062 self.write_keyword(modifier);
4063 }
4064
4065 if let Some(kind) = &select.kind {
4067 self.write_space();
4068 self.write_keyword("AS");
4069 self.write_space();
4070 self.write_keyword(kind);
4071 }
4072
4073 if !select.expressions.is_empty() {
4075 if self.config.pretty {
4076 self.write_newline();
4077 self.indent_level += 1;
4078 } else {
4079 self.write_space();
4080 }
4081 }
4082
4083 for (i, expr) in select.expressions.iter().enumerate() {
4084 if i > 0 {
4085 self.write(",");
4086 if self.config.pretty {
4087 self.write_newline();
4088 } else {
4089 self.write_space();
4090 }
4091 }
4092 if self.config.pretty {
4093 self.write_indent();
4094 }
4095 self.generate_expression(expr)?;
4096 }
4097
4098 if self.config.pretty && !select.expressions.is_empty() {
4099 self.indent_level -= 1;
4100 }
4101
4102 if let Some(into) = &select.into {
4105 if self.config.pretty {
4106 self.write_newline();
4107 self.write_indent();
4108 } else {
4109 self.write_space();
4110 }
4111 if into.bulk_collect {
4112 self.write_keyword("BULK COLLECT INTO");
4113 } else {
4114 self.write_keyword("INTO");
4115 }
4116 if into.temporary {
4117 self.write_space();
4118 self.write_keyword("TEMPORARY");
4119 }
4120 if into.unlogged {
4121 self.write_space();
4122 self.write_keyword("UNLOGGED");
4123 }
4124 self.write_space();
4125 if !into.expressions.is_empty() {
4127 for (i, expr) in into.expressions.iter().enumerate() {
4128 if i > 0 {
4129 self.write(", ");
4130 }
4131 self.generate_expression(expr)?;
4132 }
4133 } else {
4134 self.generate_expression(&into.this)?;
4135 }
4136 }
4137
4138 if let Some(from) = &select.from {
4140 if self.config.pretty {
4141 self.write_newline();
4142 self.write_indent();
4143 } else {
4144 self.write_space();
4145 }
4146 self.write_keyword("FROM");
4147 self.write_space();
4148
4149 let has_tablesample = from
4154 .expressions
4155 .iter()
4156 .any(|e| matches!(e, Expression::TableSample(_)));
4157 let is_cross_join_dialect = matches!(
4158 self.config.dialect,
4159 Some(DialectType::BigQuery)
4160 | Some(DialectType::Hive)
4161 | Some(DialectType::Spark)
4162 | Some(DialectType::Databricks)
4163 | Some(DialectType::SQLite)
4164 | Some(DialectType::ClickHouse)
4165 );
4166 let source_is_same_as_target = self.config.source_dialect.is_some()
4169 && self.config.source_dialect == self.config.dialect;
4170 let source_is_cross_join_dialect = matches!(
4171 self.config.source_dialect,
4172 Some(DialectType::BigQuery)
4173 | Some(DialectType::Hive)
4174 | Some(DialectType::Spark)
4175 | Some(DialectType::Databricks)
4176 | Some(DialectType::SQLite)
4177 | Some(DialectType::ClickHouse)
4178 );
4179 let use_cross_join = !has_tablesample
4180 && is_cross_join_dialect
4181 && (source_is_same_as_target
4182 || source_is_cross_join_dialect
4183 || self.config.source_dialect.is_none());
4184
4185 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
4187
4188 for (i, expr) in from.expressions.iter().enumerate() {
4189 if i > 0 {
4190 if use_cross_join {
4191 self.write(" CROSS JOIN ");
4192 } else {
4193 self.write(", ");
4194 }
4195 }
4196 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
4197 self.write("(");
4198 self.generate_expression(expr)?;
4199 self.write(")");
4200 } else {
4201 self.generate_expression(expr)?;
4202 }
4203 }
4204 }
4205
4206 if self.config.pretty {
4210 self.generate_joins_with_nesting(&select.joins)?;
4211 } else {
4212 for join in &select.joins {
4213 self.generate_join(join)?;
4214 }
4215 for join in select.joins.iter().rev() {
4217 if join.deferred_condition {
4218 self.generate_join_condition(join)?;
4219 }
4220 }
4221 }
4222
4223 for lateral_view in &select.lateral_views {
4225 self.generate_lateral_view(lateral_view)?;
4226 }
4227
4228 if let Some(prewhere) = &select.prewhere {
4230 self.write_clause_condition("PREWHERE", prewhere)?;
4231 }
4232
4233 if let Some(where_clause) = &select.where_clause {
4235 self.write_clause_condition("WHERE", &where_clause.this)?;
4236 }
4237
4238 if let Some(connect) = &select.connect {
4240 self.generate_connect(connect)?;
4241 }
4242
4243 if let Some(group_by) = &select.group_by {
4245 if self.config.pretty {
4246 for comment in &group_by.comments {
4248 self.write_newline();
4249 self.write_indent();
4250 self.write_formatted_comment(comment);
4251 }
4252 self.write_newline();
4253 self.write_indent();
4254 } else {
4255 self.write_space();
4256 for comment in &group_by.comments {
4258 self.write_formatted_comment(comment);
4259 self.write_space();
4260 }
4261 }
4262 self.write_keyword("GROUP BY");
4263 match group_by.all {
4265 Some(true) => {
4266 self.write_space();
4267 self.write_keyword("ALL");
4268 }
4269 Some(false) => {
4270 self.write_space();
4271 self.write_keyword("DISTINCT");
4272 }
4273 None => {}
4274 }
4275 if !group_by.expressions.is_empty() {
4276 let mut trailing_cube = false;
4279 let mut trailing_rollup = false;
4280 let mut plain_expressions: Vec<&Expression> = Vec::new();
4281 let mut grouping_sets_expressions: Vec<&Expression> = Vec::new();
4282 let mut cube_expressions: Vec<&Expression> = Vec::new();
4283 let mut rollup_expressions: Vec<&Expression> = Vec::new();
4284
4285 for expr in &group_by.expressions {
4286 match expr {
4287 Expression::Cube(c) if c.expressions.is_empty() => {
4288 trailing_cube = true;
4289 }
4290 Expression::Rollup(r) if r.expressions.is_empty() => {
4291 trailing_rollup = true;
4292 }
4293 Expression::Function(f) if f.name == "CUBE" => {
4294 cube_expressions.push(expr);
4295 }
4296 Expression::Function(f) if f.name == "ROLLUP" => {
4297 rollup_expressions.push(expr);
4298 }
4299 Expression::Function(f) if f.name == "GROUPING SETS" => {
4300 grouping_sets_expressions.push(expr);
4301 }
4302 _ => {
4303 plain_expressions.push(expr);
4304 }
4305 }
4306 }
4307
4308 let mut regular_expressions: Vec<&Expression> = Vec::new();
4310 regular_expressions.extend(plain_expressions);
4311 regular_expressions.extend(grouping_sets_expressions);
4312 regular_expressions.extend(cube_expressions);
4313 regular_expressions.extend(rollup_expressions);
4314
4315 if self.config.pretty {
4316 self.write_newline();
4317 self.indent_level += 1;
4318 self.write_indent();
4319 } else {
4320 self.write_space();
4321 }
4322
4323 for (i, expr) in regular_expressions.iter().enumerate() {
4324 if i > 0 {
4325 if self.config.pretty {
4326 self.write(",");
4327 self.write_newline();
4328 self.write_indent();
4329 } else {
4330 self.write(", ");
4331 }
4332 }
4333 self.generate_expression(expr)?;
4334 }
4335
4336 if self.config.pretty {
4337 self.indent_level -= 1;
4338 }
4339
4340 if trailing_cube {
4342 self.write_space();
4343 self.write_keyword("WITH CUBE");
4344 } else if trailing_rollup {
4345 self.write_space();
4346 self.write_keyword("WITH ROLLUP");
4347 }
4348 }
4349
4350 if group_by.totals {
4352 self.write_space();
4353 self.write_keyword("WITH TOTALS");
4354 }
4355 }
4356
4357 if let Some(having) = &select.having {
4359 if self.config.pretty {
4360 for comment in &having.comments {
4362 self.write_newline();
4363 self.write_indent();
4364 self.write_formatted_comment(comment);
4365 }
4366 } else {
4367 for comment in &having.comments {
4368 self.write_space();
4369 self.write_formatted_comment(comment);
4370 }
4371 }
4372 self.write_clause_condition("HAVING", &having.this)?;
4373 }
4374
4375 if select.qualify_after_window {
4377 if let Some(windows) = &select.windows {
4379 self.write_window_clause(windows)?;
4380 }
4381 if let Some(qualify) = &select.qualify {
4382 self.write_clause_condition("QUALIFY", &qualify.this)?;
4383 }
4384 } else {
4385 if let Some(qualify) = &select.qualify {
4387 self.write_clause_condition("QUALIFY", &qualify.this)?;
4388 }
4389 if let Some(windows) = &select.windows {
4390 self.write_window_clause(windows)?;
4391 }
4392 }
4393
4394 if let Some(distribute_by) = &select.distribute_by {
4396 self.write_clause_expressions("DISTRIBUTE BY", &distribute_by.expressions)?;
4397 }
4398
4399 if let Some(cluster_by) = &select.cluster_by {
4401 self.write_order_clause("CLUSTER BY", &cluster_by.expressions)?;
4402 }
4403
4404 if let Some(sort_by) = &select.sort_by {
4406 self.write_order_clause("SORT BY", &sort_by.expressions)?;
4407 }
4408
4409 if let Some(order_by) = &select.order_by {
4411 if self.config.pretty {
4412 for comment in &order_by.comments {
4414 self.write_newline();
4415 self.write_indent();
4416 self.write_formatted_comment(comment);
4417 }
4418 } else {
4419 for comment in &order_by.comments {
4420 self.write_space();
4421 self.write_formatted_comment(comment);
4422 }
4423 }
4424 let keyword = if order_by.siblings {
4425 "ORDER SIBLINGS BY"
4426 } else {
4427 "ORDER BY"
4428 };
4429 self.write_order_clause(keyword, &order_by.expressions)?;
4430 }
4431
4432 if select.order_by.is_none()
4434 && select.fetch.is_some()
4435 && matches!(
4436 self.config.dialect,
4437 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4438 )
4439 {
4440 if self.config.pretty {
4441 self.write_newline();
4442 self.write_indent();
4443 } else {
4444 self.write_space();
4445 }
4446 self.write_keyword("ORDER BY (SELECT NULL) OFFSET 0 ROWS");
4447 }
4448
4449 let is_presto_like = matches!(
4454 self.config.dialect,
4455 Some(DialectType::Presto) | Some(DialectType::Trino)
4456 );
4457
4458 if is_presto_like && select.offset.is_some() {
4459 if let Some(offset) = &select.offset {
4461 if self.config.pretty {
4462 self.write_newline();
4463 self.write_indent();
4464 } else {
4465 self.write_space();
4466 }
4467 self.write_keyword("OFFSET");
4468 self.write_space();
4469 self.write_limit_expr(&offset.this)?;
4470 if offset.rows == Some(true) {
4471 self.write_space();
4472 self.write_keyword("ROWS");
4473 }
4474 }
4475 if let Some(limit) = &select.limit {
4476 if self.config.pretty {
4477 self.write_newline();
4478 self.write_indent();
4479 } else {
4480 self.write_space();
4481 }
4482 self.write_keyword("LIMIT");
4483 self.write_space();
4484 self.write_limit_expr(&limit.this)?;
4485 if limit.percent {
4486 self.write_space();
4487 self.write_keyword("PERCENT");
4488 }
4489 for comment in &limit.comments {
4491 self.write(" ");
4492 self.write_formatted_comment(comment);
4493 }
4494 }
4495 } else {
4496 let fetch_as_limit = select.fetch.as_ref().map_or(false, |fetch| {
4498 !fetch.percent
4499 && !fetch.with_ties
4500 && fetch.count.is_some()
4501 && matches!(
4502 self.config.dialect,
4503 Some(DialectType::Spark)
4504 | Some(DialectType::Hive)
4505 | Some(DialectType::DuckDB)
4506 | Some(DialectType::SQLite)
4507 | Some(DialectType::MySQL)
4508 | Some(DialectType::BigQuery)
4509 | Some(DialectType::Databricks)
4510 | Some(DialectType::StarRocks)
4511 | Some(DialectType::Doris)
4512 | Some(DialectType::Athena)
4513 | Some(DialectType::ClickHouse)
4514 | Some(DialectType::Redshift)
4515 )
4516 });
4517
4518 if let Some(limit) = &select.limit {
4520 if !matches!(self.config.dialect, Some(DialectType::TSQL)) {
4522 if self.config.pretty {
4523 self.write_newline();
4524 self.write_indent();
4525 } else {
4526 self.write_space();
4527 }
4528 self.write_keyword("LIMIT");
4529 self.write_space();
4530 self.write_limit_expr(&limit.this)?;
4531 if limit.percent {
4532 self.write_space();
4533 self.write_keyword("PERCENT");
4534 }
4535 for comment in &limit.comments {
4537 self.write(" ");
4538 self.write_formatted_comment(comment);
4539 }
4540 }
4541 }
4542
4543 if select.top.is_some() && !is_top_dialect && select.limit.is_none() {
4545 if let Some(top) = &select.top {
4546 if !top.percent && !top.with_ties {
4547 if self.config.pretty {
4548 self.write_newline();
4549 self.write_indent();
4550 } else {
4551 self.write_space();
4552 }
4553 self.write_keyword("LIMIT");
4554 self.write_space();
4555 self.generate_expression(&top.this)?;
4556 }
4557 }
4558 }
4559
4560 if fetch_as_limit && select.offset.is_some() {
4563 if let Some(fetch) = &select.fetch {
4564 if self.config.pretty {
4565 self.write_newline();
4566 self.write_indent();
4567 } else {
4568 self.write_space();
4569 }
4570 self.write_keyword("LIMIT");
4571 self.write_space();
4572 self.generate_expression(fetch.count.as_ref().unwrap())?;
4573 }
4574 }
4575
4576 if let Some(offset) = &select.offset {
4580 if self.config.pretty {
4581 self.write_newline();
4582 self.write_indent();
4583 } else {
4584 self.write_space();
4585 }
4586 if matches!(self.config.dialect, Some(DialectType::TSQL)) {
4587 self.write_keyword("OFFSET");
4589 self.write_space();
4590 self.write_limit_expr(&offset.this)?;
4591 self.write_space();
4592 self.write_keyword("ROWS");
4593 if let Some(limit) = &select.limit {
4595 self.write_space();
4596 self.write_keyword("FETCH NEXT");
4597 self.write_space();
4598 self.write_limit_expr(&limit.this)?;
4599 self.write_space();
4600 self.write_keyword("ROWS ONLY");
4601 }
4602 } else {
4603 self.write_keyword("OFFSET");
4604 self.write_space();
4605 self.write_limit_expr(&offset.this)?;
4606 if offset.rows == Some(true) {
4608 self.write_space();
4609 self.write_keyword("ROWS");
4610 }
4611 }
4612 }
4613 }
4614
4615 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4617 if let Some(limit_by) = &select.limit_by {
4618 if !limit_by.is_empty() {
4619 self.write_space();
4620 self.write_keyword("BY");
4621 self.write_space();
4622 for (i, expr) in limit_by.iter().enumerate() {
4623 if i > 0 {
4624 self.write(", ");
4625 }
4626 self.generate_expression(expr)?;
4627 }
4628 }
4629 }
4630 }
4631
4632 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4634 if let Some(settings) = &select.settings {
4635 if self.config.pretty {
4636 self.write_newline();
4637 self.write_indent();
4638 } else {
4639 self.write_space();
4640 }
4641 self.write_keyword("SETTINGS");
4642 self.write_space();
4643 for (i, expr) in settings.iter().enumerate() {
4644 if i > 0 {
4645 self.write(", ");
4646 }
4647 self.generate_expression(expr)?;
4648 }
4649 }
4650
4651 if let Some(format_expr) = &select.format {
4652 if self.config.pretty {
4653 self.write_newline();
4654 self.write_indent();
4655 } else {
4656 self.write_space();
4657 }
4658 self.write_keyword("FORMAT");
4659 self.write_space();
4660 self.generate_expression(format_expr)?;
4661 }
4662 }
4663
4664 if let Some(fetch) = &select.fetch {
4666 let fetch_already_as_limit = select.offset.is_some()
4668 && !fetch.percent
4669 && !fetch.with_ties
4670 && fetch.count.is_some()
4671 && matches!(
4672 self.config.dialect,
4673 Some(DialectType::Spark)
4674 | Some(DialectType::Hive)
4675 | Some(DialectType::DuckDB)
4676 | Some(DialectType::SQLite)
4677 | Some(DialectType::MySQL)
4678 | Some(DialectType::BigQuery)
4679 | Some(DialectType::Databricks)
4680 | Some(DialectType::StarRocks)
4681 | Some(DialectType::Doris)
4682 | Some(DialectType::Athena)
4683 | Some(DialectType::ClickHouse)
4684 | Some(DialectType::Redshift)
4685 );
4686
4687 if fetch_already_as_limit {
4688 } else {
4690 if self.config.pretty {
4691 self.write_newline();
4692 self.write_indent();
4693 } else {
4694 self.write_space();
4695 }
4696
4697 let use_limit = !fetch.percent
4699 && !fetch.with_ties
4700 && fetch.count.is_some()
4701 && matches!(
4702 self.config.dialect,
4703 Some(DialectType::Spark)
4704 | Some(DialectType::Hive)
4705 | Some(DialectType::DuckDB)
4706 | Some(DialectType::SQLite)
4707 | Some(DialectType::MySQL)
4708 | Some(DialectType::BigQuery)
4709 | Some(DialectType::Databricks)
4710 | Some(DialectType::StarRocks)
4711 | Some(DialectType::Doris)
4712 | Some(DialectType::Athena)
4713 | Some(DialectType::ClickHouse)
4714 | Some(DialectType::Redshift)
4715 );
4716
4717 if use_limit {
4718 self.write_keyword("LIMIT");
4719 self.write_space();
4720 self.generate_expression(fetch.count.as_ref().unwrap())?;
4721 } else {
4722 self.write_keyword("FETCH");
4723 self.write_space();
4724 self.write_keyword(&fetch.direction);
4725 if let Some(ref count) = fetch.count {
4726 self.write_space();
4727 self.generate_expression(count)?;
4728 }
4729 if fetch.percent {
4730 self.write_space();
4731 self.write_keyword("PERCENT");
4732 }
4733 if fetch.rows {
4734 self.write_space();
4735 self.write_keyword("ROWS");
4736 }
4737 if fetch.with_ties {
4738 self.write_space();
4739 self.write_keyword("WITH TIES");
4740 } else {
4741 self.write_space();
4742 self.write_keyword("ONLY");
4743 }
4744 }
4745 } }
4747
4748 if let Some(sample) = &select.sample {
4750 use crate::dialects::DialectType;
4751 if self.config.pretty {
4752 self.write_newline();
4753 } else {
4754 self.write_space();
4755 }
4756
4757 if sample.is_using_sample {
4758 self.write_keyword("USING SAMPLE");
4760 self.generate_sample_body(sample)?;
4761 } else {
4762 self.write_keyword("TABLESAMPLE");
4763
4764 let snowflake_bernoulli =
4766 matches!(self.config.dialect, Some(DialectType::Snowflake))
4767 && !sample.explicit_method;
4768 if snowflake_bernoulli {
4769 self.write_space();
4770 self.write_keyword("BERNOULLI");
4771 }
4772
4773 if matches!(sample.method, SampleMethod::Bucket) {
4775 self.write_space();
4776 self.write("(");
4777 self.write_keyword("BUCKET");
4778 self.write_space();
4779 if let Some(ref num) = sample.bucket_numerator {
4780 self.generate_expression(num)?;
4781 }
4782 self.write_space();
4783 self.write_keyword("OUT OF");
4784 self.write_space();
4785 if let Some(ref denom) = sample.bucket_denominator {
4786 self.generate_expression(denom)?;
4787 }
4788 if let Some(ref field) = sample.bucket_field {
4789 self.write_space();
4790 self.write_keyword("ON");
4791 self.write_space();
4792 self.generate_expression(field)?;
4793 }
4794 self.write(")");
4795 } else if sample.unit_after_size {
4796 if sample.explicit_method && sample.method_before_size {
4798 self.write_space();
4799 match sample.method {
4800 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
4801 SampleMethod::System => self.write_keyword("SYSTEM"),
4802 SampleMethod::Block => self.write_keyword("BLOCK"),
4803 SampleMethod::Row => self.write_keyword("ROW"),
4804 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
4805 _ => {}
4806 }
4807 }
4808 self.write(" (");
4809 self.generate_expression(&sample.size)?;
4810 self.write_space();
4811 match sample.method {
4812 SampleMethod::Percent => self.write_keyword("PERCENT"),
4813 SampleMethod::Row => self.write_keyword("ROWS"),
4814 SampleMethod::Reservoir => self.write_keyword("ROWS"),
4815 _ => {
4816 self.write_keyword("PERCENT");
4817 }
4818 }
4819 self.write(")");
4820 } else {
4821 self.write_space();
4823 match sample.method {
4824 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
4825 SampleMethod::System => self.write_keyword("SYSTEM"),
4826 SampleMethod::Block => self.write_keyword("BLOCK"),
4827 SampleMethod::Row => self.write_keyword("ROW"),
4828 SampleMethod::Percent => self.write_keyword("BERNOULLI"),
4829 SampleMethod::Bucket => {}
4830 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
4831 }
4832 self.write(" (");
4833 self.generate_expression(&sample.size)?;
4834 if matches!(sample.method, SampleMethod::Percent) {
4835 self.write_space();
4836 self.write_keyword("PERCENT");
4837 }
4838 self.write(")");
4839 }
4840 }
4841
4842 if let Some(seed) = &sample.seed {
4843 self.write_space();
4844 let use_seed = sample.use_seed_keyword
4846 && !matches!(
4847 self.config.dialect,
4848 Some(crate::dialects::DialectType::Databricks)
4849 | Some(crate::dialects::DialectType::Spark)
4850 );
4851 if use_seed {
4852 self.write_keyword("SEED");
4853 } else {
4854 self.write_keyword("REPEATABLE");
4855 }
4856 self.write(" (");
4857 self.generate_expression(seed)?;
4858 self.write(")");
4859 }
4860 }
4861
4862 if self.config.locking_reads_supported {
4865 for lock in &select.locks {
4866 if self.config.pretty {
4867 self.write_newline();
4868 self.write_indent();
4869 } else {
4870 self.write_space();
4871 }
4872 self.generate_lock(lock)?;
4873 }
4874 }
4875
4876 if !select.for_xml.is_empty() {
4878 if self.config.pretty {
4879 self.write_newline();
4880 self.write_indent();
4881 } else {
4882 self.write_space();
4883 }
4884 self.write_keyword("FOR XML");
4885 for (i, opt) in select.for_xml.iter().enumerate() {
4886 if self.config.pretty {
4887 if i > 0 {
4888 self.write(",");
4889 }
4890 self.write_newline();
4891 self.write_indent();
4892 self.write(" "); } else {
4894 if i > 0 {
4895 self.write(",");
4896 }
4897 self.write_space();
4898 }
4899 self.generate_for_xml_option(opt)?;
4900 }
4901 }
4902
4903 if let Some(ref option) = select.option {
4905 if matches!(
4906 self.config.dialect,
4907 Some(crate::dialects::DialectType::TSQL)
4908 | Some(crate::dialects::DialectType::Fabric)
4909 ) {
4910 self.write_space();
4911 self.write(option);
4912 }
4913 }
4914
4915 Ok(())
4916 }
4917
4918 fn generate_for_xml_option(&mut self, opt: &Expression) -> Result<()> {
4920 match opt {
4921 Expression::QueryOption(qo) => {
4922 if let Expression::Var(var) = &*qo.this {
4924 self.write(&var.this);
4925 } else {
4926 self.generate_expression(&qo.this)?;
4927 }
4928 if let Some(expr) = &qo.expression {
4930 self.write("(");
4931 self.generate_expression(expr)?;
4932 self.write(")");
4933 }
4934 }
4935 _ => {
4936 self.generate_expression(opt)?;
4937 }
4938 }
4939 Ok(())
4940 }
4941
4942 fn generate_with(&mut self, with: &With) -> Result<()> {
4943 use crate::dialects::DialectType;
4944
4945 for comment in &with.leading_comments {
4947 self.write_formatted_comment(comment);
4948 self.write(" ");
4949 }
4950 self.write_keyword("WITH");
4951 if with.recursive && self.config.cte_recursive_keyword_required {
4952 self.write_space();
4953 self.write_keyword("RECURSIVE");
4954 }
4955 self.write_space();
4956
4957 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
4959
4960 for (i, cte) in with.ctes.iter().enumerate() {
4961 if i > 0 {
4962 self.write(",");
4963 if self.config.pretty {
4964 self.write_space();
4965 } else {
4966 self.write(" ");
4967 }
4968 }
4969 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !cte.alias_first {
4970 self.generate_expression(&cte.this)?;
4971 self.write_space();
4972 self.write_keyword("AS");
4973 self.write_space();
4974 self.generate_identifier(&cte.alias)?;
4975 continue;
4976 }
4977 self.generate_identifier(&cte.alias)?;
4978 for comment in &cte.comments {
4980 self.write_space();
4981 self.write_formatted_comment(comment);
4982 }
4983 if !cte.columns.is_empty() && !skip_cte_columns {
4984 self.write("(");
4985 for (j, col) in cte.columns.iter().enumerate() {
4986 if j > 0 {
4987 self.write(", ");
4988 }
4989 self.generate_identifier(col)?;
4990 }
4991 self.write(")");
4992 }
4993 if !cte.key_expressions.is_empty() {
4995 self.write_space();
4996 self.write_keyword("USING KEY");
4997 self.write(" (");
4998 for (i, key) in cte.key_expressions.iter().enumerate() {
4999 if i > 0 {
5000 self.write(", ");
5001 }
5002 self.generate_identifier(key)?;
5003 }
5004 self.write(")");
5005 }
5006 self.write_space();
5007 self.write_keyword("AS");
5008 if let Some(materialized) = cte.materialized {
5010 self.write_space();
5011 if materialized {
5012 self.write_keyword("MATERIALIZED");
5013 } else {
5014 self.write_keyword("NOT MATERIALIZED");
5015 }
5016 }
5017 self.write(" (");
5018 if self.config.pretty {
5019 self.write_newline();
5020 self.indent_level += 1;
5021 self.write_indent();
5022 }
5023 let wrap_values_in_select = matches!(
5026 self.config.dialect,
5027 Some(DialectType::Spark) | Some(DialectType::Databricks)
5028 ) && matches!(&cte.this, Expression::Values(_));
5029
5030 if wrap_values_in_select {
5031 self.write_keyword("SELECT");
5032 self.write(" * ");
5033 self.write_keyword("FROM");
5034 self.write_space();
5035 }
5036 self.generate_expression(&cte.this)?;
5037 if self.config.pretty {
5038 self.write_newline();
5039 self.indent_level -= 1;
5040 self.write_indent();
5041 }
5042 self.write(")");
5043 }
5044
5045 if let Some(search) = &with.search {
5047 self.write_space();
5048 self.generate_expression(search)?;
5049 }
5050
5051 Ok(())
5052 }
5053
5054 fn generate_joins_with_nesting(&mut self, joins: &[Join]) -> Result<()> {
5058 let mut i = 0;
5059 while i < joins.len() {
5060 if joins[i].deferred_condition {
5061 let parent_group = joins[i].nesting_group;
5062
5063 self.generate_join_without_condition(&joins[i])?;
5066
5067 let child_start = i + 1;
5069 let mut child_end = child_start;
5070 while child_end < joins.len()
5071 && !joins[child_end].deferred_condition
5072 && joins[child_end].nesting_group == parent_group
5073 {
5074 child_end += 1;
5075 }
5076
5077 if child_start < child_end {
5079 self.indent_level += 1;
5080 for j in child_start..child_end {
5081 self.generate_join(&joins[j])?;
5082 }
5083 self.indent_level -= 1;
5084 }
5085
5086 self.generate_join_condition(&joins[i])?;
5088
5089 i = child_end;
5090 } else {
5091 self.generate_join(&joins[i])?;
5093 i += 1;
5094 }
5095 }
5096 Ok(())
5097 }
5098
5099 fn generate_join_without_condition(&mut self, join: &Join) -> Result<()> {
5102 let mut join_copy = join.clone();
5105 join_copy.on = None;
5106 join_copy.using = Vec::new();
5107 join_copy.deferred_condition = false;
5108 self.generate_join(&join_copy)
5109 }
5110
5111 fn generate_join(&mut self, join: &Join) -> Result<()> {
5112 if join.kind == JoinKind::Implicit {
5114 self.write(",");
5115 if self.config.pretty {
5116 self.write_newline();
5117 self.write_indent();
5118 } else {
5119 self.write_space();
5120 }
5121 self.generate_expression(&join.this)?;
5122 return Ok(());
5123 }
5124
5125 if self.config.pretty {
5126 self.write_newline();
5127 self.write_indent();
5128 } else {
5129 self.write_space();
5130 }
5131
5132 let hint_str = if self.config.join_hints {
5135 join.join_hint
5136 .as_ref()
5137 .map(|h| format!(" {}", h))
5138 .unwrap_or_default()
5139 } else {
5140 String::new()
5141 };
5142
5143 let clickhouse_join_keyword =
5144 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
5145 if let Some(hint) = &join.join_hint {
5146 let mut global = false;
5147 let mut strictness: Option<&'static str> = None;
5148 for part in hint.split_whitespace() {
5149 match part.to_uppercase().as_str() {
5150 "GLOBAL" => global = true,
5151 "ANY" => strictness = Some("ANY"),
5152 "ASOF" => strictness = Some("ASOF"),
5153 "SEMI" => strictness = Some("SEMI"),
5154 "ANTI" => strictness = Some("ANTI"),
5155 _ => {}
5156 }
5157 }
5158
5159 if global || strictness.is_some() {
5160 let join_type = match join.kind {
5161 JoinKind::Left => {
5162 if join.use_outer_keyword {
5163 "LEFT OUTER"
5164 } else if join.use_inner_keyword {
5165 "LEFT INNER"
5166 } else {
5167 "LEFT"
5168 }
5169 }
5170 JoinKind::Right => {
5171 if join.use_outer_keyword {
5172 "RIGHT OUTER"
5173 } else if join.use_inner_keyword {
5174 "RIGHT INNER"
5175 } else {
5176 "RIGHT"
5177 }
5178 }
5179 JoinKind::Full => {
5180 if join.use_outer_keyword {
5181 "FULL OUTER"
5182 } else {
5183 "FULL"
5184 }
5185 }
5186 JoinKind::Inner => {
5187 if join.use_inner_keyword {
5188 "INNER"
5189 } else {
5190 ""
5191 }
5192 }
5193 _ => "",
5194 };
5195
5196 let mut parts = Vec::new();
5197 if global {
5198 parts.push("GLOBAL");
5199 }
5200 if !join_type.is_empty() {
5201 parts.push(join_type);
5202 }
5203 if let Some(strict) = strictness {
5204 parts.push(strict);
5205 }
5206 parts.push("JOIN");
5207 Some(parts.join(" "))
5208 } else {
5209 None
5210 }
5211 } else {
5212 None
5213 }
5214 } else {
5215 None
5216 };
5217
5218 if !join.comments.is_empty() {
5222 if self.config.pretty {
5223 let trimmed = self.output.trim_end().len();
5228 self.output.truncate(trimmed);
5229 for comment in &join.comments {
5230 self.write_newline();
5231 self.write_indent();
5232 self.write_formatted_comment(comment);
5233 }
5234 self.write_newline();
5235 self.write_indent();
5236 } else {
5237 for comment in &join.comments {
5238 self.write_formatted_comment(comment);
5239 self.write_space();
5240 }
5241 }
5242 }
5243
5244 let directed_str = if join.directed { " DIRECTED" } else { "" };
5245
5246 if let Some(keyword) = clickhouse_join_keyword {
5247 self.write_keyword(&keyword);
5248 } else {
5249 match join.kind {
5250 JoinKind::Inner => {
5251 if join.use_inner_keyword {
5252 self.write_keyword(&format!("INNER{}{} JOIN", hint_str, directed_str));
5253 } else {
5254 self.write_keyword(&format!(
5255 "{}{}JOIN",
5256 if hint_str.is_empty() {
5257 String::new()
5258 } else {
5259 format!("{} ", hint_str.trim())
5260 },
5261 if directed_str.is_empty() {
5262 ""
5263 } else {
5264 "DIRECTED "
5265 }
5266 ));
5267 }
5268 }
5269 JoinKind::Left => {
5270 if join.use_outer_keyword {
5271 self.write_keyword(&format!("LEFT OUTER{}{} JOIN", hint_str, directed_str));
5272 } else if join.use_inner_keyword {
5273 self.write_keyword(&format!("LEFT INNER{}{} JOIN", hint_str, directed_str));
5274 } else {
5275 self.write_keyword(&format!("LEFT{}{} JOIN", hint_str, directed_str));
5276 }
5277 }
5278 JoinKind::Right => {
5279 if join.use_outer_keyword {
5280 self.write_keyword(&format!(
5281 "RIGHT OUTER{}{} JOIN",
5282 hint_str, directed_str
5283 ));
5284 } else if join.use_inner_keyword {
5285 self.write_keyword(&format!(
5286 "RIGHT INNER{}{} JOIN",
5287 hint_str, directed_str
5288 ));
5289 } else {
5290 self.write_keyword(&format!("RIGHT{}{} JOIN", hint_str, directed_str));
5291 }
5292 }
5293 JoinKind::Full => {
5294 if join.use_outer_keyword {
5295 self.write_keyword(&format!("FULL OUTER{}{} JOIN", hint_str, directed_str));
5296 } else {
5297 self.write_keyword(&format!("FULL{}{} JOIN", hint_str, directed_str));
5298 }
5299 }
5300 JoinKind::Outer => self.write_keyword(&format!("OUTER{} JOIN", directed_str)),
5301 JoinKind::Cross => self.write_keyword(&format!("CROSS{} JOIN", directed_str)),
5302 JoinKind::Natural => {
5303 if join.use_inner_keyword {
5304 self.write_keyword(&format!("NATURAL INNER{} JOIN", directed_str));
5305 } else {
5306 self.write_keyword(&format!("NATURAL{} JOIN", directed_str));
5307 }
5308 }
5309 JoinKind::NaturalLeft => {
5310 if join.use_outer_keyword {
5311 self.write_keyword(&format!("NATURAL LEFT OUTER{} JOIN", directed_str));
5312 } else {
5313 self.write_keyword(&format!("NATURAL LEFT{} JOIN", directed_str));
5314 }
5315 }
5316 JoinKind::NaturalRight => {
5317 if join.use_outer_keyword {
5318 self.write_keyword(&format!("NATURAL RIGHT OUTER{} JOIN", directed_str));
5319 } else {
5320 self.write_keyword(&format!("NATURAL RIGHT{} JOIN", directed_str));
5321 }
5322 }
5323 JoinKind::NaturalFull => {
5324 if join.use_outer_keyword {
5325 self.write_keyword(&format!("NATURAL FULL OUTER{} JOIN", directed_str));
5326 } else {
5327 self.write_keyword(&format!("NATURAL FULL{} JOIN", directed_str));
5328 }
5329 }
5330 JoinKind::Semi => self.write_keyword("SEMI JOIN"),
5331 JoinKind::Anti => self.write_keyword("ANTI JOIN"),
5332 JoinKind::LeftSemi => self.write_keyword("LEFT SEMI JOIN"),
5333 JoinKind::LeftAnti => self.write_keyword("LEFT ANTI JOIN"),
5334 JoinKind::RightSemi => self.write_keyword("RIGHT SEMI JOIN"),
5335 JoinKind::RightAnti => self.write_keyword("RIGHT ANTI JOIN"),
5336 JoinKind::CrossApply => {
5337 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
5339 self.write_keyword("CROSS APPLY");
5340 } else {
5341 self.write_keyword("INNER JOIN LATERAL");
5342 }
5343 }
5344 JoinKind::OuterApply => {
5345 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
5347 self.write_keyword("OUTER APPLY");
5348 } else {
5349 self.write_keyword("LEFT JOIN LATERAL");
5350 }
5351 }
5352 JoinKind::AsOf => self.write_keyword("ASOF JOIN"),
5353 JoinKind::AsOfLeft => {
5354 if join.use_outer_keyword {
5355 self.write_keyword("ASOF LEFT OUTER JOIN");
5356 } else {
5357 self.write_keyword("ASOF LEFT JOIN");
5358 }
5359 }
5360 JoinKind::AsOfRight => {
5361 if join.use_outer_keyword {
5362 self.write_keyword("ASOF RIGHT OUTER JOIN");
5363 } else {
5364 self.write_keyword("ASOF RIGHT JOIN");
5365 }
5366 }
5367 JoinKind::Lateral => self.write_keyword("LATERAL JOIN"),
5368 JoinKind::LeftLateral => {
5369 if join.use_outer_keyword {
5370 self.write_keyword("LEFT OUTER LATERAL JOIN");
5371 } else {
5372 self.write_keyword("LEFT LATERAL JOIN");
5373 }
5374 }
5375 JoinKind::Straight => self.write_keyword("STRAIGHT_JOIN"),
5376 JoinKind::Implicit => {
5377 use crate::dialects::DialectType;
5381 let is_cj_dialect = matches!(
5382 self.config.dialect,
5383 Some(DialectType::BigQuery)
5384 | Some(DialectType::Hive)
5385 | Some(DialectType::Spark)
5386 | Some(DialectType::Databricks)
5387 );
5388 let source_is_same = self.config.source_dialect.is_some()
5389 && self.config.source_dialect == self.config.dialect;
5390 let source_is_cj = matches!(
5391 self.config.source_dialect,
5392 Some(DialectType::BigQuery)
5393 | Some(DialectType::Hive)
5394 | Some(DialectType::Spark)
5395 | Some(DialectType::Databricks)
5396 );
5397 if is_cj_dialect
5398 && (source_is_same || source_is_cj || self.config.source_dialect.is_none())
5399 {
5400 self.write_keyword("CROSS JOIN");
5401 } else {
5402 self.output.truncate(self.output.trim_end().len());
5406 self.write(",");
5407 }
5408 }
5409 JoinKind::Array => self.write_keyword("ARRAY JOIN"),
5410 JoinKind::LeftArray => self.write_keyword("LEFT ARRAY JOIN"),
5411 JoinKind::Paste => self.write_keyword("PASTE JOIN"),
5412 }
5413 }
5414
5415 if matches!(join.kind, JoinKind::Array | JoinKind::LeftArray) {
5417 self.write_space();
5418 match &join.this {
5419 Expression::Tuple(t) => {
5420 for (i, item) in t.expressions.iter().enumerate() {
5421 if i > 0 {
5422 self.write(", ");
5423 }
5424 self.generate_expression(item)?;
5425 }
5426 }
5427 other => {
5428 self.generate_expression(other)?;
5429 }
5430 }
5431 } else {
5432 self.write_space();
5433 self.generate_expression(&join.this)?;
5434 }
5435
5436 if !join.deferred_condition {
5438 if let Some(match_cond) = &join.match_condition {
5440 self.write_space();
5441 self.write_keyword("MATCH_CONDITION");
5442 self.write(" (");
5443 self.generate_expression(match_cond)?;
5444 self.write(")");
5445 }
5446
5447 if let Some(on) = &join.on {
5448 if self.config.pretty {
5449 self.write_newline();
5450 self.indent_level += 1;
5451 self.write_indent();
5452 self.write_keyword("ON");
5453 self.write_space();
5454 self.generate_join_on_condition(on)?;
5455 self.indent_level -= 1;
5456 } else {
5457 self.write_space();
5458 self.write_keyword("ON");
5459 self.write_space();
5460 self.generate_expression(on)?;
5461 }
5462 }
5463
5464 if !join.using.is_empty() {
5465 if self.config.pretty {
5466 self.write_newline();
5467 self.indent_level += 1;
5468 self.write_indent();
5469 self.write_keyword("USING");
5470 self.write(" (");
5471 for (i, col) in join.using.iter().enumerate() {
5472 if i > 0 {
5473 self.write(", ");
5474 }
5475 self.generate_identifier(col)?;
5476 }
5477 self.write(")");
5478 self.indent_level -= 1;
5479 } else {
5480 self.write_space();
5481 self.write_keyword("USING");
5482 self.write(" (");
5483 for (i, col) in join.using.iter().enumerate() {
5484 if i > 0 {
5485 self.write(", ");
5486 }
5487 self.generate_identifier(col)?;
5488 }
5489 self.write(")");
5490 }
5491 }
5492 }
5493
5494 for pivot in &join.pivots {
5496 self.write_space();
5497 self.generate_expression(pivot)?;
5498 }
5499
5500 Ok(())
5501 }
5502
5503 fn generate_join_condition(&mut self, join: &Join) -> Result<()> {
5505 if let Some(match_cond) = &join.match_condition {
5507 self.write_space();
5508 self.write_keyword("MATCH_CONDITION");
5509 self.write(" (");
5510 self.generate_expression(match_cond)?;
5511 self.write(")");
5512 }
5513
5514 if let Some(on) = &join.on {
5515 if self.config.pretty {
5516 self.write_newline();
5517 self.indent_level += 1;
5518 self.write_indent();
5519 self.write_keyword("ON");
5520 self.write_space();
5521 self.generate_join_on_condition(on)?;
5523 self.indent_level -= 1;
5524 } else {
5525 self.write_space();
5526 self.write_keyword("ON");
5527 self.write_space();
5528 self.generate_expression(on)?;
5529 }
5530 }
5531
5532 if !join.using.is_empty() {
5533 if self.config.pretty {
5534 self.write_newline();
5535 self.indent_level += 1;
5536 self.write_indent();
5537 self.write_keyword("USING");
5538 self.write(" (");
5539 for (i, col) in join.using.iter().enumerate() {
5540 if i > 0 {
5541 self.write(", ");
5542 }
5543 self.generate_identifier(col)?;
5544 }
5545 self.write(")");
5546 self.indent_level -= 1;
5547 } else {
5548 self.write_space();
5549 self.write_keyword("USING");
5550 self.write(" (");
5551 for (i, col) in join.using.iter().enumerate() {
5552 if i > 0 {
5553 self.write(", ");
5554 }
5555 self.generate_identifier(col)?;
5556 }
5557 self.write(")");
5558 }
5559 }
5560
5561 for pivot in &join.pivots {
5563 self.write_space();
5564 self.generate_expression(pivot)?;
5565 }
5566
5567 Ok(())
5568 }
5569
5570 fn generate_join_on_condition(&mut self, expr: &Expression) -> Result<()> {
5572 if let Expression::And(and_op) = expr {
5573 if let Some(conditions) = self.flatten_connector_terms(and_op, ConnectorOperator::And) {
5574 self.generate_expression(conditions[0])?;
5575 for condition in conditions.iter().skip(1) {
5576 self.write_newline();
5577 self.write_indent();
5578 self.write_keyword("AND");
5579 self.write_space();
5580 self.generate_expression(condition)?;
5581 }
5582 return Ok(());
5583 }
5584 }
5585
5586 self.generate_expression(expr)
5587 }
5588
5589 fn generate_joined_table(&mut self, jt: &JoinedTable) -> Result<()> {
5590 self.write("(");
5592 self.generate_expression(&jt.left)?;
5593
5594 for join in &jt.joins {
5596 self.generate_join(join)?;
5597 }
5598
5599 for lv in &jt.lateral_views {
5601 self.generate_lateral_view(lv)?;
5602 }
5603
5604 self.write(")");
5605
5606 if let Some(alias) = &jt.alias {
5608 self.write_space();
5609 self.write_keyword("AS");
5610 self.write_space();
5611 self.generate_identifier(alias)?;
5612 }
5613
5614 Ok(())
5615 }
5616
5617 fn generate_lateral_view(&mut self, lv: &LateralView) -> Result<()> {
5618 use crate::dialects::DialectType;
5619
5620 if self.config.pretty {
5621 self.write_newline();
5622 self.write_indent();
5623 } else {
5624 self.write_space();
5625 }
5626
5627 let use_lateral_join = matches!(
5630 self.config.dialect,
5631 Some(DialectType::PostgreSQL)
5632 | Some(DialectType::DuckDB)
5633 | Some(DialectType::Snowflake)
5634 | Some(DialectType::TSQL)
5635 | Some(DialectType::Presto)
5636 | Some(DialectType::Trino)
5637 | Some(DialectType::Athena)
5638 );
5639
5640 let use_unnest = matches!(
5642 self.config.dialect,
5643 Some(DialectType::DuckDB)
5644 | Some(DialectType::Presto)
5645 | Some(DialectType::Trino)
5646 | Some(DialectType::Athena)
5647 );
5648
5649 let (is_posexplode, func_args) = match &lv.this {
5651 Expression::Explode(uf) => {
5652 (false, vec![uf.this.clone()])
5654 }
5655 Expression::Unnest(uf) => {
5656 let mut args = vec![uf.this.clone()];
5657 args.extend(uf.expressions.clone());
5658 (false, args)
5659 }
5660 Expression::Function(func) => {
5661 let name = func.name.to_uppercase();
5662 if name == "POSEXPLODE" || name == "POSEXPLODE_OUTER" {
5663 (true, func.args.clone())
5664 } else if name == "EXPLODE" || name == "EXPLODE_OUTER" || name == "INLINE" {
5665 (false, func.args.clone())
5666 } else {
5667 (false, vec![])
5668 }
5669 }
5670 _ => (false, vec![]),
5671 };
5672
5673 if use_lateral_join {
5674 if lv.outer {
5676 self.write_keyword("LEFT JOIN LATERAL");
5677 } else {
5678 self.write_keyword("CROSS JOIN");
5679 }
5680 self.write_space();
5681
5682 if use_unnest && !func_args.is_empty() {
5683 let unnest_args = if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
5686 func_args
5688 .iter()
5689 .map(|a| {
5690 if let Expression::Function(ref f) = a {
5691 if f.name.to_uppercase() == "ARRAY" && f.args.len() == 1 {
5692 return Expression::ArrayFunc(Box::new(
5693 crate::expressions::ArrayConstructor {
5694 expressions: f.args.clone(),
5695 bracket_notation: true,
5696 use_list_keyword: false,
5697 },
5698 ));
5699 }
5700 }
5701 a.clone()
5702 })
5703 .collect::<Vec<_>>()
5704 } else if matches!(
5705 self.config.dialect,
5706 Some(DialectType::Presto)
5707 | Some(DialectType::Trino)
5708 | Some(DialectType::Athena)
5709 ) {
5710 func_args
5712 .iter()
5713 .map(|a| {
5714 if let Expression::Function(ref f) = a {
5715 if f.name.to_uppercase() == "ARRAY" && f.args.len() >= 1 {
5716 return Expression::ArrayFunc(Box::new(
5717 crate::expressions::ArrayConstructor {
5718 expressions: f.args.clone(),
5719 bracket_notation: true,
5720 use_list_keyword: false,
5721 },
5722 ));
5723 }
5724 }
5725 a.clone()
5726 })
5727 .collect::<Vec<_>>()
5728 } else {
5729 func_args
5730 };
5731
5732 if is_posexplode {
5734 self.write_keyword("LATERAL");
5735 self.write(" (");
5736 self.write_keyword("SELECT");
5737 self.write_space();
5738
5739 let pos_alias = if !lv.column_aliases.is_empty() {
5742 lv.column_aliases[0].clone()
5743 } else {
5744 Identifier::new("pos")
5745 };
5746 let data_aliases: Vec<Identifier> = if lv.column_aliases.len() > 1 {
5747 lv.column_aliases[1..].to_vec()
5748 } else {
5749 vec![Identifier::new("col")]
5750 };
5751
5752 self.generate_identifier(&pos_alias)?;
5754 self.write(" - 1");
5755 self.write_space();
5756 self.write_keyword("AS");
5757 self.write_space();
5758 self.generate_identifier(&pos_alias)?;
5759
5760 for data_col in &data_aliases {
5762 self.write(", ");
5763 self.generate_identifier(data_col)?;
5764 }
5765
5766 self.write_space();
5767 self.write_keyword("FROM");
5768 self.write_space();
5769 self.write_keyword("UNNEST");
5770 self.write("(");
5771 for (i, arg) in unnest_args.iter().enumerate() {
5772 if i > 0 {
5773 self.write(", ");
5774 }
5775 self.generate_expression(arg)?;
5776 }
5777 self.write(")");
5778 self.write_space();
5779 self.write_keyword("WITH ORDINALITY");
5780 self.write_space();
5781 self.write_keyword("AS");
5782 self.write_space();
5783
5784 let table_alias_ident = lv
5786 .table_alias
5787 .clone()
5788 .unwrap_or_else(|| Identifier::new("t"));
5789 self.generate_identifier(&table_alias_ident)?;
5790 self.write("(");
5791 for (i, data_col) in data_aliases.iter().enumerate() {
5792 if i > 0 {
5793 self.write(", ");
5794 }
5795 self.generate_identifier(data_col)?;
5796 }
5797 self.write(", ");
5798 self.generate_identifier(&pos_alias)?;
5799 self.write("))");
5800 } else {
5801 self.write_keyword("UNNEST");
5802 self.write("(");
5803 for (i, arg) in unnest_args.iter().enumerate() {
5804 if i > 0 {
5805 self.write(", ");
5806 }
5807 self.generate_expression(arg)?;
5808 }
5809 self.write(")");
5810
5811 if let Some(alias) = &lv.table_alias {
5813 self.write_space();
5814 self.write_keyword("AS");
5815 self.write_space();
5816 self.generate_identifier(alias)?;
5817 if !lv.column_aliases.is_empty() {
5818 self.write("(");
5819 for (i, col) in lv.column_aliases.iter().enumerate() {
5820 if i > 0 {
5821 self.write(", ");
5822 }
5823 self.generate_identifier(col)?;
5824 }
5825 self.write(")");
5826 }
5827 } else if !lv.column_aliases.is_empty() {
5828 self.write_space();
5829 self.write_keyword("AS");
5830 self.write(" t(");
5831 for (i, col) in lv.column_aliases.iter().enumerate() {
5832 if i > 0 {
5833 self.write(", ");
5834 }
5835 self.generate_identifier(col)?;
5836 }
5837 self.write(")");
5838 }
5839 }
5840 } else {
5841 if !lv.outer {
5843 self.write_keyword("LATERAL");
5844 self.write_space();
5845 }
5846 self.generate_expression(&lv.this)?;
5847
5848 if let Some(alias) = &lv.table_alias {
5850 self.write_space();
5851 self.write_keyword("AS");
5852 self.write_space();
5853 self.generate_identifier(alias)?;
5854 if !lv.column_aliases.is_empty() {
5855 self.write("(");
5856 for (i, col) in lv.column_aliases.iter().enumerate() {
5857 if i > 0 {
5858 self.write(", ");
5859 }
5860 self.generate_identifier(col)?;
5861 }
5862 self.write(")");
5863 }
5864 } else if !lv.column_aliases.is_empty() {
5865 self.write_space();
5866 self.write_keyword("AS");
5867 self.write(" t(");
5868 for (i, col) in lv.column_aliases.iter().enumerate() {
5869 if i > 0 {
5870 self.write(", ");
5871 }
5872 self.generate_identifier(col)?;
5873 }
5874 self.write(")");
5875 }
5876 }
5877
5878 if lv.outer {
5880 self.write_space();
5881 self.write_keyword("ON TRUE");
5882 }
5883 } else {
5884 self.write_keyword("LATERAL VIEW");
5886 if lv.outer {
5887 self.write_space();
5888 self.write_keyword("OUTER");
5889 }
5890 if self.config.pretty {
5891 self.write_newline();
5892 self.write_indent();
5893 } else {
5894 self.write_space();
5895 }
5896 self.generate_expression(&lv.this)?;
5897
5898 if let Some(alias) = &lv.table_alias {
5900 self.write_space();
5901 self.generate_identifier(alias)?;
5902 }
5903
5904 if !lv.column_aliases.is_empty() {
5906 self.write_space();
5907 self.write_keyword("AS");
5908 self.write_space();
5909 for (i, col) in lv.column_aliases.iter().enumerate() {
5910 if i > 0 {
5911 self.write(", ");
5912 }
5913 self.generate_identifier(col)?;
5914 }
5915 }
5916 }
5917
5918 Ok(())
5919 }
5920
5921 fn generate_union(&mut self, union: &Union) -> Result<()> {
5922 if let Some(with) = &union.with {
5924 self.generate_with(with)?;
5925 self.write_space();
5926 }
5927 self.generate_expression(&union.left)?;
5928 if self.config.pretty {
5929 self.write_newline();
5930 self.write_indent();
5931 } else {
5932 self.write_space();
5933 }
5934
5935 if let Some(side) = &union.side {
5937 self.write_keyword(side);
5938 self.write_space();
5939 }
5940 if let Some(kind) = &union.kind {
5941 self.write_keyword(kind);
5942 self.write_space();
5943 }
5944
5945 self.write_keyword("UNION");
5946 if union.all {
5947 self.write_space();
5948 self.write_keyword("ALL");
5949 } else if union.distinct {
5950 self.write_space();
5951 self.write_keyword("DISTINCT");
5952 }
5953
5954 if union.corresponding || union.by_name {
5957 self.write_space();
5958 self.write_keyword("BY NAME");
5959 }
5960 if !union.on_columns.is_empty() {
5961 self.write_space();
5962 self.write_keyword("ON");
5963 self.write(" (");
5964 for (i, col) in union.on_columns.iter().enumerate() {
5965 if i > 0 {
5966 self.write(", ");
5967 }
5968 self.generate_expression(col)?;
5969 }
5970 self.write(")");
5971 }
5972
5973 if self.config.pretty {
5974 self.write_newline();
5975 self.write_indent();
5976 } else {
5977 self.write_space();
5978 }
5979 self.generate_expression(&union.right)?;
5980 if let Some(order_by) = &union.order_by {
5982 if self.config.pretty {
5983 self.write_newline();
5984 } else {
5985 self.write_space();
5986 }
5987 self.write_keyword("ORDER BY");
5988 self.write_space();
5989 for (i, ordered) in order_by.expressions.iter().enumerate() {
5990 if i > 0 {
5991 self.write(", ");
5992 }
5993 self.generate_ordered(ordered)?;
5994 }
5995 }
5996 if let Some(limit) = &union.limit {
5997 if self.config.pretty {
5998 self.write_newline();
5999 } else {
6000 self.write_space();
6001 }
6002 self.write_keyword("LIMIT");
6003 self.write_space();
6004 self.generate_expression(limit)?;
6005 }
6006 if let Some(offset) = &union.offset {
6007 if self.config.pretty {
6008 self.write_newline();
6009 } else {
6010 self.write_space();
6011 }
6012 self.write_keyword("OFFSET");
6013 self.write_space();
6014 self.generate_expression(offset)?;
6015 }
6016 if let Some(distribute_by) = &union.distribute_by {
6018 self.write_space();
6019 self.write_keyword("DISTRIBUTE BY");
6020 self.write_space();
6021 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6022 if i > 0 {
6023 self.write(", ");
6024 }
6025 self.generate_expression(expr)?;
6026 }
6027 }
6028 if let Some(sort_by) = &union.sort_by {
6030 self.write_space();
6031 self.write_keyword("SORT BY");
6032 self.write_space();
6033 for (i, ord) in sort_by.expressions.iter().enumerate() {
6034 if i > 0 {
6035 self.write(", ");
6036 }
6037 self.generate_ordered(ord)?;
6038 }
6039 }
6040 if let Some(cluster_by) = &union.cluster_by {
6042 self.write_space();
6043 self.write_keyword("CLUSTER BY");
6044 self.write_space();
6045 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6046 if i > 0 {
6047 self.write(", ");
6048 }
6049 self.generate_ordered(ord)?;
6050 }
6051 }
6052 Ok(())
6053 }
6054
6055 fn generate_intersect(&mut self, intersect: &Intersect) -> Result<()> {
6056 if let Some(with) = &intersect.with {
6058 self.generate_with(with)?;
6059 self.write_space();
6060 }
6061 self.generate_expression(&intersect.left)?;
6062 if self.config.pretty {
6063 self.write_newline();
6064 self.write_indent();
6065 } else {
6066 self.write_space();
6067 }
6068
6069 if let Some(side) = &intersect.side {
6071 self.write_keyword(side);
6072 self.write_space();
6073 }
6074 if let Some(kind) = &intersect.kind {
6075 self.write_keyword(kind);
6076 self.write_space();
6077 }
6078
6079 self.write_keyword("INTERSECT");
6080 if intersect.all {
6081 self.write_space();
6082 self.write_keyword("ALL");
6083 } else if intersect.distinct {
6084 self.write_space();
6085 self.write_keyword("DISTINCT");
6086 }
6087
6088 if intersect.corresponding || intersect.by_name {
6091 self.write_space();
6092 self.write_keyword("BY NAME");
6093 }
6094 if !intersect.on_columns.is_empty() {
6095 self.write_space();
6096 self.write_keyword("ON");
6097 self.write(" (");
6098 for (i, col) in intersect.on_columns.iter().enumerate() {
6099 if i > 0 {
6100 self.write(", ");
6101 }
6102 self.generate_expression(col)?;
6103 }
6104 self.write(")");
6105 }
6106
6107 if self.config.pretty {
6108 self.write_newline();
6109 self.write_indent();
6110 } else {
6111 self.write_space();
6112 }
6113 self.generate_expression(&intersect.right)?;
6114 if let Some(order_by) = &intersect.order_by {
6116 if self.config.pretty {
6117 self.write_newline();
6118 } else {
6119 self.write_space();
6120 }
6121 self.write_keyword("ORDER BY");
6122 self.write_space();
6123 for (i, ordered) in order_by.expressions.iter().enumerate() {
6124 if i > 0 {
6125 self.write(", ");
6126 }
6127 self.generate_ordered(ordered)?;
6128 }
6129 }
6130 if let Some(limit) = &intersect.limit {
6131 if self.config.pretty {
6132 self.write_newline();
6133 } else {
6134 self.write_space();
6135 }
6136 self.write_keyword("LIMIT");
6137 self.write_space();
6138 self.generate_expression(limit)?;
6139 }
6140 if let Some(offset) = &intersect.offset {
6141 if self.config.pretty {
6142 self.write_newline();
6143 } else {
6144 self.write_space();
6145 }
6146 self.write_keyword("OFFSET");
6147 self.write_space();
6148 self.generate_expression(offset)?;
6149 }
6150 if let Some(distribute_by) = &intersect.distribute_by {
6152 self.write_space();
6153 self.write_keyword("DISTRIBUTE BY");
6154 self.write_space();
6155 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6156 if i > 0 {
6157 self.write(", ");
6158 }
6159 self.generate_expression(expr)?;
6160 }
6161 }
6162 if let Some(sort_by) = &intersect.sort_by {
6164 self.write_space();
6165 self.write_keyword("SORT BY");
6166 self.write_space();
6167 for (i, ord) in sort_by.expressions.iter().enumerate() {
6168 if i > 0 {
6169 self.write(", ");
6170 }
6171 self.generate_ordered(ord)?;
6172 }
6173 }
6174 if let Some(cluster_by) = &intersect.cluster_by {
6176 self.write_space();
6177 self.write_keyword("CLUSTER BY");
6178 self.write_space();
6179 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6180 if i > 0 {
6181 self.write(", ");
6182 }
6183 self.generate_ordered(ord)?;
6184 }
6185 }
6186 Ok(())
6187 }
6188
6189 fn generate_except(&mut self, except: &Except) -> Result<()> {
6190 use crate::dialects::DialectType;
6191
6192 if let Some(with) = &except.with {
6194 self.generate_with(with)?;
6195 self.write_space();
6196 }
6197
6198 self.generate_expression(&except.left)?;
6199 if self.config.pretty {
6200 self.write_newline();
6201 self.write_indent();
6202 } else {
6203 self.write_space();
6204 }
6205
6206 if let Some(side) = &except.side {
6208 self.write_keyword(side);
6209 self.write_space();
6210 }
6211 if let Some(kind) = &except.kind {
6212 self.write_keyword(kind);
6213 self.write_space();
6214 }
6215
6216 match self.config.dialect {
6218 Some(DialectType::Oracle) if !except.all => {
6219 self.write_keyword("MINUS");
6220 }
6221 Some(DialectType::ClickHouse) => {
6222 self.write_keyword("EXCEPT");
6224 if except.distinct {
6225 self.write_space();
6226 self.write_keyword("DISTINCT");
6227 }
6228 }
6229 Some(DialectType::BigQuery) => {
6230 self.write_keyword("EXCEPT");
6232 if except.all {
6233 self.write_space();
6234 self.write_keyword("ALL");
6235 } else {
6236 self.write_space();
6237 self.write_keyword("DISTINCT");
6238 }
6239 }
6240 _ => {
6241 self.write_keyword("EXCEPT");
6242 if except.all {
6243 self.write_space();
6244 self.write_keyword("ALL");
6245 } else if except.distinct {
6246 self.write_space();
6247 self.write_keyword("DISTINCT");
6248 }
6249 }
6250 }
6251
6252 if except.corresponding || except.by_name {
6255 self.write_space();
6256 self.write_keyword("BY NAME");
6257 }
6258 if !except.on_columns.is_empty() {
6259 self.write_space();
6260 self.write_keyword("ON");
6261 self.write(" (");
6262 for (i, col) in except.on_columns.iter().enumerate() {
6263 if i > 0 {
6264 self.write(", ");
6265 }
6266 self.generate_expression(col)?;
6267 }
6268 self.write(")");
6269 }
6270
6271 if self.config.pretty {
6272 self.write_newline();
6273 self.write_indent();
6274 } else {
6275 self.write_space();
6276 }
6277 self.generate_expression(&except.right)?;
6278 if let Some(order_by) = &except.order_by {
6280 if self.config.pretty {
6281 self.write_newline();
6282 } else {
6283 self.write_space();
6284 }
6285 self.write_keyword("ORDER BY");
6286 self.write_space();
6287 for (i, ordered) in order_by.expressions.iter().enumerate() {
6288 if i > 0 {
6289 self.write(", ");
6290 }
6291 self.generate_ordered(ordered)?;
6292 }
6293 }
6294 if let Some(limit) = &except.limit {
6295 if self.config.pretty {
6296 self.write_newline();
6297 } else {
6298 self.write_space();
6299 }
6300 self.write_keyword("LIMIT");
6301 self.write_space();
6302 self.generate_expression(limit)?;
6303 }
6304 if let Some(offset) = &except.offset {
6305 if self.config.pretty {
6306 self.write_newline();
6307 } else {
6308 self.write_space();
6309 }
6310 self.write_keyword("OFFSET");
6311 self.write_space();
6312 self.generate_expression(offset)?;
6313 }
6314 if let Some(distribute_by) = &except.distribute_by {
6316 self.write_space();
6317 self.write_keyword("DISTRIBUTE BY");
6318 self.write_space();
6319 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6320 if i > 0 {
6321 self.write(", ");
6322 }
6323 self.generate_expression(expr)?;
6324 }
6325 }
6326 if let Some(sort_by) = &except.sort_by {
6328 self.write_space();
6329 self.write_keyword("SORT BY");
6330 self.write_space();
6331 for (i, ord) in sort_by.expressions.iter().enumerate() {
6332 if i > 0 {
6333 self.write(", ");
6334 }
6335 self.generate_ordered(ord)?;
6336 }
6337 }
6338 if let Some(cluster_by) = &except.cluster_by {
6340 self.write_space();
6341 self.write_keyword("CLUSTER BY");
6342 self.write_space();
6343 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6344 if i > 0 {
6345 self.write(", ");
6346 }
6347 self.generate_ordered(ord)?;
6348 }
6349 }
6350 Ok(())
6351 }
6352
6353 fn generate_insert(&mut self, insert: &Insert) -> Result<()> {
6354 let prepend_query_cte = if insert.with.is_none() {
6356 use crate::dialects::DialectType;
6357 let should_prepend = matches!(
6358 self.config.dialect,
6359 Some(DialectType::TSQL)
6360 | Some(DialectType::Fabric)
6361 | Some(DialectType::Spark)
6362 | Some(DialectType::Databricks)
6363 | Some(DialectType::Hive)
6364 );
6365 if should_prepend {
6366 if let Some(Expression::Select(select)) = &insert.query {
6367 select.with.clone()
6368 } else {
6369 None
6370 }
6371 } else {
6372 None
6373 }
6374 } else {
6375 None
6376 };
6377
6378 if let Some(with) = &insert.with {
6380 self.generate_with(with)?;
6381 self.write_space();
6382 } else if let Some(with) = &prepend_query_cte {
6383 self.generate_with(with)?;
6384 self.write_space();
6385 }
6386
6387 for comment in &insert.leading_comments {
6389 self.write_formatted_comment(comment);
6390 self.write(" ");
6391 }
6392
6393 if let Some(dir) = &insert.directory {
6395 self.write_keyword("INSERT OVERWRITE");
6396 if dir.local {
6397 self.write_space();
6398 self.write_keyword("LOCAL");
6399 }
6400 self.write_space();
6401 self.write_keyword("DIRECTORY");
6402 self.write_space();
6403 self.write("'");
6404 self.write(&dir.path);
6405 self.write("'");
6406
6407 if let Some(row_format) = &dir.row_format {
6409 self.write_space();
6410 self.write_keyword("ROW FORMAT");
6411 if row_format.delimited {
6412 self.write_space();
6413 self.write_keyword("DELIMITED");
6414 }
6415 if let Some(val) = &row_format.fields_terminated_by {
6416 self.write_space();
6417 self.write_keyword("FIELDS TERMINATED BY");
6418 self.write_space();
6419 self.write("'");
6420 self.write(val);
6421 self.write("'");
6422 }
6423 if let Some(val) = &row_format.collection_items_terminated_by {
6424 self.write_space();
6425 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
6426 self.write_space();
6427 self.write("'");
6428 self.write(val);
6429 self.write("'");
6430 }
6431 if let Some(val) = &row_format.map_keys_terminated_by {
6432 self.write_space();
6433 self.write_keyword("MAP KEYS TERMINATED BY");
6434 self.write_space();
6435 self.write("'");
6436 self.write(val);
6437 self.write("'");
6438 }
6439 if let Some(val) = &row_format.lines_terminated_by {
6440 self.write_space();
6441 self.write_keyword("LINES TERMINATED BY");
6442 self.write_space();
6443 self.write("'");
6444 self.write(val);
6445 self.write("'");
6446 }
6447 if let Some(val) = &row_format.null_defined_as {
6448 self.write_space();
6449 self.write_keyword("NULL DEFINED AS");
6450 self.write_space();
6451 self.write("'");
6452 self.write(val);
6453 self.write("'");
6454 }
6455 }
6456
6457 if let Some(format) = &dir.stored_as {
6459 self.write_space();
6460 self.write_keyword("STORED AS");
6461 self.write_space();
6462 self.write_keyword(format);
6463 }
6464
6465 if let Some(query) = &insert.query {
6467 self.write_space();
6468 self.generate_expression(query)?;
6469 }
6470
6471 return Ok(());
6472 }
6473
6474 if insert.is_replace {
6475 self.write_keyword("REPLACE INTO");
6477 } else if insert.overwrite {
6478 self.write_keyword("INSERT");
6480 if let Some(ref hint) = insert.hint {
6482 self.generate_hint(hint)?;
6483 }
6484 self.write(&self.config.insert_overwrite.to_uppercase());
6485 } else if let Some(ref action) = insert.conflict_action {
6486 self.write_keyword("INSERT OR");
6488 self.write_space();
6489 self.write_keyword(action);
6490 self.write_space();
6491 self.write_keyword("INTO");
6492 } else if insert.ignore {
6493 self.write_keyword("INSERT IGNORE INTO");
6495 } else {
6496 self.write_keyword("INSERT");
6497 if let Some(ref hint) = insert.hint {
6499 self.generate_hint(hint)?;
6500 }
6501 self.write_space();
6502 self.write_keyword("INTO");
6503 }
6504 if let Some(ref func) = insert.function_target {
6506 self.write_space();
6507 self.write_keyword("FUNCTION");
6508 self.write_space();
6509 self.generate_expression(func)?;
6510 } else {
6511 self.write_space();
6512 self.generate_table(&insert.table)?;
6513 }
6514
6515 if let Some(ref alias) = insert.alias {
6517 self.write_space();
6518 if insert.alias_explicit_as {
6519 self.write_keyword("AS");
6520 self.write_space();
6521 }
6522 self.generate_identifier(alias)?;
6523 }
6524
6525 if insert.if_exists {
6527 self.write_space();
6528 self.write_keyword("IF EXISTS");
6529 }
6530
6531 if let Some(ref replace_where) = insert.replace_where {
6533 if self.config.pretty {
6534 self.write_newline();
6535 self.write_indent();
6536 } else {
6537 self.write_space();
6538 }
6539 self.write_keyword("REPLACE WHERE");
6540 self.write_space();
6541 self.generate_expression(replace_where)?;
6542 }
6543
6544 if !insert.partition.is_empty() {
6546 self.write_space();
6547 self.write_keyword("PARTITION");
6548 self.write("(");
6549 for (i, (col, val)) in insert.partition.iter().enumerate() {
6550 if i > 0 {
6551 self.write(", ");
6552 }
6553 self.generate_identifier(col)?;
6554 if let Some(v) = val {
6555 self.write(" = ");
6556 self.generate_expression(v)?;
6557 }
6558 }
6559 self.write(")");
6560 }
6561
6562 if let Some(ref partition_by) = insert.partition_by {
6564 self.write_space();
6565 self.write_keyword("PARTITION BY");
6566 self.write_space();
6567 self.generate_expression(partition_by)?;
6568 }
6569
6570 if !insert.settings.is_empty() {
6572 self.write_space();
6573 self.write_keyword("SETTINGS");
6574 self.write_space();
6575 for (i, setting) in insert.settings.iter().enumerate() {
6576 if i > 0 {
6577 self.write(", ");
6578 }
6579 self.generate_expression(setting)?;
6580 }
6581 }
6582
6583 if !insert.columns.is_empty() {
6584 if insert.alias.is_some() && insert.alias_explicit_as {
6585 self.write("(");
6587 } else {
6588 self.write(" (");
6590 }
6591 for (i, col) in insert.columns.iter().enumerate() {
6592 if i > 0 {
6593 self.write(", ");
6594 }
6595 self.generate_identifier(col)?;
6596 }
6597 self.write(")");
6598 }
6599
6600 if let Some(ref output) = insert.output {
6602 self.generate_output_clause(output)?;
6603 }
6604
6605 if insert.by_name {
6607 self.write_space();
6608 self.write_keyword("BY NAME");
6609 }
6610
6611 if insert.default_values {
6612 self.write_space();
6613 self.write_keyword("DEFAULT VALUES");
6614 } else if let Some(query) = &insert.query {
6615 if self.config.pretty {
6616 self.write_newline();
6617 } else {
6618 self.write_space();
6619 }
6620 if prepend_query_cte.is_some() {
6622 if let Expression::Select(select) = query {
6623 let mut select_no_with = select.clone();
6624 select_no_with.with = None;
6625 self.generate_select(&select_no_with)?;
6626 } else {
6627 self.generate_expression(query)?;
6628 }
6629 } else {
6630 self.generate_expression(query)?;
6631 }
6632 } else if !insert.values.is_empty() {
6633 if self.config.pretty {
6634 self.write_newline();
6636 self.write_keyword("VALUES");
6637 self.write_newline();
6638 self.indent_level += 1;
6639 for (i, row) in insert.values.iter().enumerate() {
6640 if i > 0 {
6641 self.write(",");
6642 self.write_newline();
6643 }
6644 self.write_indent();
6645 self.write("(");
6646 for (j, val) in row.iter().enumerate() {
6647 if j > 0 {
6648 self.write(", ");
6649 }
6650 self.generate_expression(val)?;
6651 }
6652 self.write(")");
6653 }
6654 self.indent_level -= 1;
6655 } else {
6656 self.write_space();
6658 self.write_keyword("VALUES");
6659 for (i, row) in insert.values.iter().enumerate() {
6660 if i > 0 {
6661 self.write(",");
6662 }
6663 self.write(" (");
6664 for (j, val) in row.iter().enumerate() {
6665 if j > 0 {
6666 self.write(", ");
6667 }
6668 self.generate_expression(val)?;
6669 }
6670 self.write(")");
6671 }
6672 }
6673 }
6674
6675 if let Some(ref source) = insert.source {
6677 self.write_space();
6678 self.write_keyword("TABLE");
6679 self.write_space();
6680 self.generate_expression(source)?;
6681 }
6682
6683 if let Some(alias) = &insert.source_alias {
6685 self.write_space();
6686 self.write_keyword("AS");
6687 self.write_space();
6688 self.generate_identifier(alias)?;
6689 }
6690
6691 if let Some(on_conflict) = &insert.on_conflict {
6693 if !matches!(self.config.dialect, Some(DialectType::Materialize)) {
6694 self.write_space();
6695 self.generate_expression(on_conflict)?;
6696 }
6697 }
6698
6699 if !insert.returning.is_empty() {
6701 self.write_space();
6702 self.write_keyword("RETURNING");
6703 self.write_space();
6704 for (i, expr) in insert.returning.iter().enumerate() {
6705 if i > 0 {
6706 self.write(", ");
6707 }
6708 self.generate_expression(expr)?;
6709 }
6710 }
6711
6712 Ok(())
6713 }
6714
6715 fn generate_update(&mut self, update: &Update) -> Result<()> {
6716 for comment in &update.leading_comments {
6718 self.write_formatted_comment(comment);
6719 self.write(" ");
6720 }
6721
6722 if let Some(ref with) = update.with {
6724 self.generate_with(with)?;
6725 self.write_space();
6726 }
6727
6728 self.write_keyword("UPDATE");
6729 self.write_space();
6730 self.generate_table(&update.table)?;
6731
6732 let mysql_like_update_from = matches!(
6733 self.config.dialect,
6734 Some(DialectType::MySQL) | Some(DialectType::SingleStore)
6735 ) && update.from_clause.is_some();
6736
6737 let mut set_pairs = update.set.clone();
6738
6739 let mut pre_set_joins = update.table_joins.clone();
6741 if mysql_like_update_from {
6742 let target_name = update
6743 .table
6744 .alias
6745 .as_ref()
6746 .map(|a| a.name.clone())
6747 .unwrap_or_else(|| update.table.name.name.clone());
6748
6749 for (col, _) in &mut set_pairs {
6750 if !col.name.contains('.') {
6751 col.name = format!("{}.{}", target_name, col.name);
6752 }
6753 }
6754
6755 if let Some(from_clause) = &update.from_clause {
6756 for table_expr in &from_clause.expressions {
6757 pre_set_joins.push(crate::expressions::Join {
6758 this: table_expr.clone(),
6759 on: Some(Expression::Boolean(crate::expressions::BooleanLiteral {
6760 value: true,
6761 })),
6762 using: Vec::new(),
6763 kind: crate::expressions::JoinKind::Inner,
6764 use_inner_keyword: false,
6765 use_outer_keyword: false,
6766 deferred_condition: false,
6767 join_hint: None,
6768 match_condition: None,
6769 pivots: Vec::new(),
6770 comments: Vec::new(),
6771 nesting_group: 0,
6772 directed: false,
6773 });
6774 }
6775 }
6776 for join in &update.from_joins {
6777 let mut join = join.clone();
6778 if join.on.is_none() && join.using.is_empty() {
6779 join.on = Some(Expression::Boolean(crate::expressions::BooleanLiteral {
6780 value: true,
6781 }));
6782 }
6783 pre_set_joins.push(join);
6784 }
6785 }
6786
6787 for extra_table in &update.extra_tables {
6789 self.write(", ");
6790 self.generate_table(extra_table)?;
6791 }
6792
6793 for join in &pre_set_joins {
6795 self.generate_join(join)?;
6797 }
6798
6799 let teradata_from_before_set = matches!(self.config.dialect, Some(DialectType::Teradata));
6801 if teradata_from_before_set && !mysql_like_update_from {
6802 if let Some(ref from_clause) = update.from_clause {
6803 self.write_space();
6804 self.write_keyword("FROM");
6805 self.write_space();
6806 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
6807 if i > 0 {
6808 self.write(", ");
6809 }
6810 self.generate_expression(table_expr)?;
6811 }
6812 }
6813 for join in &update.from_joins {
6814 self.generate_join(join)?;
6815 }
6816 }
6817
6818 self.write_space();
6819 self.write_keyword("SET");
6820 self.write_space();
6821
6822 for (i, (col, val)) in set_pairs.iter().enumerate() {
6823 if i > 0 {
6824 self.write(", ");
6825 }
6826 self.generate_identifier(col)?;
6827 self.write(" = ");
6828 self.generate_expression(val)?;
6829 }
6830
6831 if let Some(ref output) = update.output {
6833 self.generate_output_clause(output)?;
6834 }
6835
6836 if !mysql_like_update_from && !teradata_from_before_set {
6838 if let Some(ref from_clause) = update.from_clause {
6839 self.write_space();
6840 self.write_keyword("FROM");
6841 self.write_space();
6842 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
6844 if i > 0 {
6845 self.write(", ");
6846 }
6847 self.generate_expression(table_expr)?;
6848 }
6849 }
6850 }
6851
6852 if !mysql_like_update_from && !teradata_from_before_set {
6853 for join in &update.from_joins {
6855 self.generate_join(join)?;
6856 }
6857 }
6858
6859 if let Some(where_clause) = &update.where_clause {
6860 self.write_space();
6861 self.write_keyword("WHERE");
6862 self.write_space();
6863 self.generate_expression(&where_clause.this)?;
6864 }
6865
6866 if !update.returning.is_empty() {
6868 self.write_space();
6869 self.write_keyword("RETURNING");
6870 self.write_space();
6871 for (i, expr) in update.returning.iter().enumerate() {
6872 if i > 0 {
6873 self.write(", ");
6874 }
6875 self.generate_expression(expr)?;
6876 }
6877 }
6878
6879 if let Some(ref order_by) = update.order_by {
6881 self.write_space();
6882 self.generate_order_by(order_by)?;
6883 }
6884
6885 if let Some(ref limit) = update.limit {
6887 self.write_space();
6888 self.write_keyword("LIMIT");
6889 self.write_space();
6890 self.generate_expression(limit)?;
6891 }
6892
6893 Ok(())
6894 }
6895
6896 fn generate_delete(&mut self, delete: &Delete) -> Result<()> {
6897 if let Some(with) = &delete.with {
6899 self.generate_with(with)?;
6900 self.write_space();
6901 }
6902
6903 for comment in &delete.leading_comments {
6905 self.write_formatted_comment(comment);
6906 self.write(" ");
6907 }
6908
6909 if !delete.tables.is_empty() && !delete.tables_from_using {
6911 self.write_keyword("DELETE");
6913 self.write_space();
6914 for (i, tbl) in delete.tables.iter().enumerate() {
6915 if i > 0 {
6916 self.write(", ");
6917 }
6918 self.generate_table(tbl)?;
6919 }
6920 if let Some(ref output) = delete.output {
6922 self.generate_output_clause(output)?;
6923 }
6924 self.write_space();
6925 self.write_keyword("FROM");
6926 self.write_space();
6927 self.generate_table(&delete.table)?;
6928 } else if !delete.tables.is_empty() && delete.tables_from_using {
6929 self.write_keyword("DELETE FROM");
6931 self.write_space();
6932 for (i, tbl) in delete.tables.iter().enumerate() {
6933 if i > 0 {
6934 self.write(", ");
6935 }
6936 self.generate_table(tbl)?;
6937 }
6938 } else if delete.no_from && matches!(self.config.dialect, Some(DialectType::BigQuery)) {
6939 self.write_keyword("DELETE");
6941 self.write_space();
6942 self.generate_table(&delete.table)?;
6943 } else {
6944 self.write_keyword("DELETE FROM");
6945 self.write_space();
6946 self.generate_table(&delete.table)?;
6947 }
6948
6949 if let Some(ref on_cluster) = delete.on_cluster {
6951 self.write_space();
6952 self.generate_on_cluster(on_cluster)?;
6953 }
6954
6955 if let Some(ref idx) = delete.force_index {
6957 self.write_space();
6958 self.write_keyword("FORCE INDEX");
6959 self.write(" (");
6960 self.write(idx);
6961 self.write(")");
6962 }
6963
6964 if let Some(ref alias) = delete.alias {
6966 self.write_space();
6967 if delete.alias_explicit_as
6968 || matches!(self.config.dialect, Some(DialectType::BigQuery))
6969 {
6970 self.write_keyword("AS");
6971 self.write_space();
6972 }
6973 self.generate_identifier(alias)?;
6974 }
6975
6976 if !delete.tables_from_using {
6978 for join in &delete.joins {
6979 self.generate_join(join)?;
6980 }
6981 }
6982
6983 if !delete.using.is_empty() {
6985 self.write_space();
6986 self.write_keyword("USING");
6987 for (i, table) in delete.using.iter().enumerate() {
6988 if i > 0 {
6989 self.write(",");
6990 }
6991 self.write_space();
6992 if !table.hints.is_empty() && table.name.is_empty() {
6994 self.generate_expression(&table.hints[0])?;
6996 if let Some(ref alias) = table.alias {
6997 self.write_space();
6998 if table.alias_explicit_as {
6999 self.write_keyword("AS");
7000 self.write_space();
7001 }
7002 self.generate_identifier(alias)?;
7003 if !table.column_aliases.is_empty() {
7004 self.write("(");
7005 for (j, col_alias) in table.column_aliases.iter().enumerate() {
7006 if j > 0 {
7007 self.write(", ");
7008 }
7009 self.generate_identifier(col_alias)?;
7010 }
7011 self.write(")");
7012 }
7013 }
7014 } else {
7015 self.generate_table(table)?;
7016 }
7017 }
7018 }
7019
7020 if delete.tables_from_using {
7022 for join in &delete.joins {
7023 self.generate_join(join)?;
7024 }
7025 }
7026
7027 let output_already_emitted =
7029 !delete.tables.is_empty() && !delete.tables_from_using && delete.output.is_some();
7030 if !output_already_emitted {
7031 if let Some(ref output) = delete.output {
7032 self.generate_output_clause(output)?;
7033 }
7034 }
7035
7036 if let Some(where_clause) = &delete.where_clause {
7037 self.write_space();
7038 self.write_keyword("WHERE");
7039 self.write_space();
7040 self.generate_expression(&where_clause.this)?;
7041 }
7042
7043 if let Some(ref order_by) = delete.order_by {
7045 self.write_space();
7046 self.generate_order_by(order_by)?;
7047 }
7048
7049 if let Some(ref limit) = delete.limit {
7051 self.write_space();
7052 self.write_keyword("LIMIT");
7053 self.write_space();
7054 self.generate_expression(limit)?;
7055 }
7056
7057 if !delete.returning.is_empty() {
7059 self.write_space();
7060 self.write_keyword("RETURNING");
7061 self.write_space();
7062 for (i, expr) in delete.returning.iter().enumerate() {
7063 if i > 0 {
7064 self.write(", ");
7065 }
7066 self.generate_expression(expr)?;
7067 }
7068 }
7069
7070 Ok(())
7071 }
7072
7073 fn generate_create_table(&mut self, ct: &CreateTable) -> Result<()> {
7076 let saved_athena_hive_context = self.athena_hive_context;
7080 let is_clickhouse = matches!(self.config.dialect, Some(DialectType::ClickHouse));
7081 if matches!(
7082 self.config.dialect,
7083 Some(crate::dialects::DialectType::Athena)
7084 ) {
7085 let is_external = ct
7089 .table_modifier
7090 .as_ref()
7091 .map(|m| m.eq_ignore_ascii_case("EXTERNAL"))
7092 .unwrap_or(false);
7093 let has_as_select = ct.as_select.is_some();
7094 self.athena_hive_context = is_external || !has_as_select;
7095 }
7096
7097 if matches!(
7099 self.config.dialect,
7100 Some(crate::dialects::DialectType::TSQL)
7101 ) {
7102 if let Some(ref query) = ct.as_select {
7103 if let Some(with_cte) = &ct.with_cte {
7105 self.generate_with(with_cte)?;
7106 self.write_space();
7107 }
7108
7109 self.write_keyword("SELECT");
7111 self.write(" * ");
7112 self.write_keyword("INTO");
7113 self.write_space();
7114
7115 if ct.temporary {
7117 self.write("#");
7118 }
7119 self.generate_table(&ct.name)?;
7120
7121 self.write_space();
7122 self.write_keyword("FROM");
7123 self.write(" (");
7124 let aliased_query = Self::add_column_aliases_to_query(query.clone());
7126 self.generate_expression(&aliased_query)?;
7127 self.write(") ");
7128 self.write_keyword("AS");
7129 self.write(" temp");
7130 return Ok(());
7131 }
7132 }
7133
7134 if let Some(with_cte) = &ct.with_cte {
7136 self.generate_with(with_cte)?;
7137 self.write_space();
7138 }
7139
7140 for comment in &ct.leading_comments {
7142 self.write_formatted_comment(comment);
7143 self.write(" ");
7144 }
7145 self.write_keyword("CREATE");
7146
7147 if ct.or_replace {
7148 self.write_space();
7149 self.write_keyword("OR REPLACE");
7150 }
7151
7152 if ct.temporary {
7153 self.write_space();
7154 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
7156 self.write_keyword("GLOBAL TEMPORARY");
7157 } else {
7158 self.write_keyword("TEMPORARY");
7159 }
7160 }
7161
7162 let is_dictionary = ct
7164 .table_modifier
7165 .as_ref()
7166 .map(|m| m.eq_ignore_ascii_case("DICTIONARY"))
7167 .unwrap_or(false);
7168 if let Some(ref modifier) = ct.table_modifier {
7169 let skip_transient = modifier.eq_ignore_ascii_case("TRANSIENT")
7171 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None);
7172 let is_teradata_modifier = modifier.eq_ignore_ascii_case("VOLATILE")
7174 || modifier.eq_ignore_ascii_case("SET")
7175 || modifier.eq_ignore_ascii_case("MULTISET")
7176 || modifier.to_uppercase().contains("VOLATILE")
7177 || modifier.to_uppercase().starts_with("SET ")
7178 || modifier.to_uppercase().starts_with("MULTISET ");
7179 let skip_teradata =
7180 is_teradata_modifier && !matches!(self.config.dialect, Some(DialectType::Teradata));
7181 if !skip_transient && !skip_teradata {
7182 self.write_space();
7183 self.write_keyword(modifier);
7184 }
7185 }
7186
7187 if !is_dictionary {
7188 self.write_space();
7189 self.write_keyword("TABLE");
7190 }
7191
7192 if ct.if_not_exists {
7193 self.write_space();
7194 self.write_keyword("IF NOT EXISTS");
7195 }
7196
7197 self.write_space();
7198 self.generate_table(&ct.name)?;
7199
7200 if let Some(ref on_cluster) = ct.on_cluster {
7202 self.write_space();
7203 self.generate_on_cluster(on_cluster)?;
7204 }
7205
7206 if matches!(
7208 self.config.dialect,
7209 Some(crate::dialects::DialectType::Teradata)
7210 ) && !ct.teradata_post_name_options.is_empty()
7211 {
7212 for opt in &ct.teradata_post_name_options {
7213 self.write(", ");
7214 self.write(opt);
7215 }
7216 }
7217
7218 if ct.copy_grants {
7220 self.write_space();
7221 self.write_keyword("COPY GRANTS");
7222 }
7223
7224 if let Some(ref using_template) = ct.using_template {
7226 self.write_space();
7227 self.write_keyword("USING TEMPLATE");
7228 self.write_space();
7229 self.generate_expression(using_template)?;
7230 return Ok(());
7231 }
7232
7233 if let Some(ref clone_source) = ct.clone_source {
7235 self.write_space();
7236 if ct.is_copy && self.config.supports_table_copy {
7237 self.write_keyword("COPY");
7239 } else if ct.shallow_clone {
7240 self.write_keyword("SHALLOW CLONE");
7241 } else {
7242 self.write_keyword("CLONE");
7243 }
7244 self.write_space();
7245 self.generate_table(clone_source)?;
7246 if let Some(ref at_clause) = ct.clone_at_clause {
7248 self.write_space();
7249 self.generate_expression(at_clause)?;
7250 }
7251 return Ok(());
7252 }
7253
7254 if let Some(ref partition_of) = ct.partition_of {
7258 self.write_space();
7259
7260 if let Expression::PartitionedOfProperty(ref pop) = partition_of {
7262 self.write_keyword("PARTITION OF");
7264 self.write_space();
7265 self.generate_expression(&pop.this)?;
7266
7267 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
7269 self.write(" (");
7270 let mut first = true;
7271 for col in &ct.columns {
7272 if !first {
7273 self.write(", ");
7274 }
7275 first = false;
7276 self.generate_column_def(col)?;
7277 }
7278 for constraint in &ct.constraints {
7279 if !first {
7280 self.write(", ");
7281 }
7282 first = false;
7283 self.generate_table_constraint(constraint)?;
7284 }
7285 self.write(")");
7286 }
7287
7288 if let Expression::PartitionBoundSpec(_) = pop.expression.as_ref() {
7290 self.write_space();
7291 self.write_keyword("FOR VALUES");
7292 self.write_space();
7293 self.generate_expression(&pop.expression)?;
7294 } else {
7295 self.write_space();
7296 self.write_keyword("DEFAULT");
7297 }
7298 } else {
7299 self.generate_expression(partition_of)?;
7301
7302 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
7304 self.write(" (");
7305 let mut first = true;
7306 for col in &ct.columns {
7307 if !first {
7308 self.write(", ");
7309 }
7310 first = false;
7311 self.generate_column_def(col)?;
7312 }
7313 for constraint in &ct.constraints {
7314 if !first {
7315 self.write(", ");
7316 }
7317 first = false;
7318 self.generate_table_constraint(constraint)?;
7319 }
7320 self.write(")");
7321 }
7322 }
7323
7324 for prop in &ct.properties {
7326 self.write_space();
7327 self.generate_expression(prop)?;
7328 }
7329
7330 return Ok(());
7331 }
7332
7333 self.sqlite_inline_pk_columns.clear();
7336 if matches!(
7337 self.config.dialect,
7338 Some(crate::dialects::DialectType::SQLite)
7339 ) {
7340 for constraint in &ct.constraints {
7341 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7342 if columns.len() == 1 && name.is_none() {
7344 let pk_col_name = columns[0].name.to_lowercase();
7345 if ct
7347 .columns
7348 .iter()
7349 .any(|c| c.name.name.to_lowercase() == pk_col_name)
7350 {
7351 self.sqlite_inline_pk_columns.insert(pk_col_name);
7352 }
7353 }
7354 }
7355 }
7356 }
7357
7358 if !ct.columns.is_empty() {
7360 if self.config.pretty {
7361 self.write(" (");
7363 self.write_newline();
7364 self.indent_level += 1;
7365 for (i, col) in ct.columns.iter().enumerate() {
7366 if i > 0 {
7367 self.write(",");
7368 self.write_newline();
7369 }
7370 self.write_indent();
7371 self.generate_column_def(col)?;
7372 }
7373 for constraint in &ct.constraints {
7375 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7377 if columns.len() == 1
7378 && name.is_none()
7379 && self
7380 .sqlite_inline_pk_columns
7381 .contains(&columns[0].name.to_lowercase())
7382 {
7383 continue;
7384 }
7385 }
7386 self.write(",");
7387 self.write_newline();
7388 self.write_indent();
7389 self.generate_table_constraint(constraint)?;
7390 }
7391 self.indent_level -= 1;
7392 self.write_newline();
7393 self.write(")");
7394 } else {
7395 self.write(" (");
7396 for (i, col) in ct.columns.iter().enumerate() {
7397 if i > 0 {
7398 self.write(", ");
7399 }
7400 self.generate_column_def(col)?;
7401 }
7402 let mut first_constraint = true;
7404 for constraint in &ct.constraints {
7405 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7407 if columns.len() == 1
7408 && name.is_none()
7409 && self
7410 .sqlite_inline_pk_columns
7411 .contains(&columns[0].name.to_lowercase())
7412 {
7413 continue;
7414 }
7415 }
7416 if first_constraint {
7417 self.write(", ");
7418 first_constraint = false;
7419 } else {
7420 self.write(", ");
7421 }
7422 self.generate_table_constraint(constraint)?;
7423 }
7424 self.write(")");
7425 }
7426 } else if !ct.constraints.is_empty() {
7427 let has_like_only = ct
7429 .constraints
7430 .iter()
7431 .all(|c| matches!(c, TableConstraint::Like { .. }));
7432 let has_tags_only = ct
7433 .constraints
7434 .iter()
7435 .all(|c| matches!(c, TableConstraint::Tags(_)));
7436 let is_pg_like = matches!(
7440 self.config.dialect,
7441 Some(crate::dialects::DialectType::PostgreSQL)
7442 | Some(crate::dialects::DialectType::CockroachDB)
7443 | Some(crate::dialects::DialectType::Materialize)
7444 | Some(crate::dialects::DialectType::RisingWave)
7445 | Some(crate::dialects::DialectType::Redshift)
7446 | Some(crate::dialects::DialectType::Presto)
7447 | Some(crate::dialects::DialectType::Trino)
7448 | Some(crate::dialects::DialectType::Athena)
7449 );
7450 let use_parens = if has_like_only {
7451 is_pg_like
7452 } else {
7453 !has_tags_only
7454 };
7455 if self.config.pretty && use_parens {
7456 self.write(" (");
7457 self.write_newline();
7458 self.indent_level += 1;
7459 for (i, constraint) in ct.constraints.iter().enumerate() {
7460 if i > 0 {
7461 self.write(",");
7462 self.write_newline();
7463 }
7464 self.write_indent();
7465 self.generate_table_constraint(constraint)?;
7466 }
7467 self.indent_level -= 1;
7468 self.write_newline();
7469 self.write(")");
7470 } else {
7471 if use_parens {
7472 self.write(" (");
7473 } else {
7474 self.write_space();
7475 }
7476 for (i, constraint) in ct.constraints.iter().enumerate() {
7477 if i > 0 {
7478 self.write(", ");
7479 }
7480 self.generate_table_constraint(constraint)?;
7481 }
7482 if use_parens {
7483 self.write(")");
7484 }
7485 }
7486 }
7487
7488 if let Some(ref on_prop) = ct.on_property {
7490 self.write(" ");
7491 self.write_keyword("ON");
7492 self.write(" ");
7493 self.generate_expression(&on_prop.this)?;
7494 }
7495
7496 if !is_clickhouse {
7499 for prop in &ct.properties {
7500 if let Expression::SchemaCommentProperty(_) = prop {
7501 if self.config.pretty {
7502 self.write_newline();
7503 } else {
7504 self.write_space();
7505 }
7506 self.generate_expression(prop)?;
7507 }
7508 }
7509 }
7510
7511 if !ct.with_properties.is_empty() {
7513 let is_snowflake_special_table = matches!(
7515 self.config.dialect,
7516 Some(crate::dialects::DialectType::Snowflake)
7517 ) && (ct.table_modifier.as_deref() == Some("ICEBERG")
7518 || ct.table_modifier.as_deref() == Some("DYNAMIC"));
7519 if is_snowflake_special_table {
7520 for (key, value) in &ct.with_properties {
7521 self.write_space();
7522 self.write(key);
7523 self.write("=");
7524 self.write(value);
7525 }
7526 } else if self.config.pretty {
7527 self.write_newline();
7528 self.write_keyword("WITH");
7529 self.write(" (");
7530 self.write_newline();
7531 self.indent_level += 1;
7532 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
7533 if i > 0 {
7534 self.write(",");
7535 self.write_newline();
7536 }
7537 self.write_indent();
7538 self.write(key);
7539 self.write("=");
7540 self.write(value);
7541 }
7542 self.indent_level -= 1;
7543 self.write_newline();
7544 self.write(")");
7545 } else {
7546 self.write_space();
7547 self.write_keyword("WITH");
7548 self.write(" (");
7549 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
7550 if i > 0 {
7551 self.write(", ");
7552 }
7553 self.write(key);
7554 self.write("=");
7555 self.write(value);
7556 }
7557 self.write(")");
7558 }
7559 }
7560
7561 let (pre_as_properties, post_as_properties): (Vec<&Expression>, Vec<&Expression>) =
7562 if is_clickhouse && ct.as_select.is_some() {
7563 let mut pre = Vec::new();
7564 let mut post = Vec::new();
7565 for prop in &ct.properties {
7566 if matches!(prop, Expression::SchemaCommentProperty(_)) {
7567 post.push(prop);
7568 } else {
7569 pre.push(prop);
7570 }
7571 }
7572 (pre, post)
7573 } else {
7574 (ct.properties.iter().collect(), Vec::new())
7575 };
7576
7577 for prop in pre_as_properties {
7579 if !is_clickhouse && matches!(prop, Expression::SchemaCommentProperty(_)) {
7581 continue;
7582 }
7583 if self.config.pretty {
7584 self.write_newline();
7585 } else {
7586 self.write_space();
7587 }
7588 if let Expression::Properties(props) = prop {
7592 let is_hive_dialect = matches!(
7593 self.config.dialect,
7594 Some(crate::dialects::DialectType::Hive)
7595 | Some(crate::dialects::DialectType::Spark)
7596 | Some(crate::dialects::DialectType::Databricks)
7597 | Some(crate::dialects::DialectType::Athena)
7598 );
7599 let is_doris_starrocks = matches!(
7600 self.config.dialect,
7601 Some(crate::dialects::DialectType::Doris)
7602 | Some(crate::dialects::DialectType::StarRocks)
7603 );
7604 if is_hive_dialect {
7605 self.generate_tblproperties_clause(&props.expressions)?;
7606 } else if is_doris_starrocks {
7607 self.generate_properties_clause(&props.expressions)?;
7608 } else {
7609 self.generate_options_clause(&props.expressions)?;
7610 }
7611 } else {
7612 self.generate_expression(prop)?;
7613 }
7614 }
7615
7616 for prop in &ct.post_table_properties {
7618 if let Expression::WithSystemVersioningProperty(ref svp) = prop {
7619 self.write(" WITH(");
7620 self.generate_system_versioning_content(svp)?;
7621 self.write(")");
7622 } else if let Expression::Properties(props) = prop {
7623 let is_doris_starrocks = matches!(
7625 self.config.dialect,
7626 Some(crate::dialects::DialectType::Doris)
7627 | Some(crate::dialects::DialectType::StarRocks)
7628 );
7629 self.write_space();
7630 if is_doris_starrocks {
7631 self.generate_properties_clause(&props.expressions)?;
7632 } else {
7633 self.generate_options_clause(&props.expressions)?;
7634 }
7635 } else {
7636 self.write_space();
7637 self.generate_expression(prop)?;
7638 }
7639 }
7640
7641 if let Some(ref rollup) = ct.rollup {
7644 if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
7645 self.write_space();
7646 self.generate_rollup_property(rollup)?;
7647 }
7648 }
7649
7650 let is_mysql_compatible = matches!(
7654 self.config.dialect,
7655 Some(DialectType::MySQL)
7656 | Some(DialectType::SingleStore)
7657 | Some(DialectType::Doris)
7658 | Some(DialectType::StarRocks)
7659 | None
7660 );
7661 let is_hive_compatible = matches!(
7662 self.config.dialect,
7663 Some(DialectType::Hive)
7664 | Some(DialectType::Spark)
7665 | Some(DialectType::Databricks)
7666 | Some(DialectType::Athena)
7667 );
7668 let mysql_pretty_options =
7669 self.config.pretty && matches!(self.config.dialect, Some(DialectType::MySQL));
7670 for (key, value) in &ct.mysql_table_options {
7671 let should_output = if is_mysql_compatible {
7673 true
7674 } else if is_hive_compatible && key == "COMMENT" {
7675 true } else {
7677 false
7678 };
7679 if should_output {
7680 if mysql_pretty_options {
7681 self.write_newline();
7682 self.write_indent();
7683 } else {
7684 self.write_space();
7685 }
7686 self.write_keyword(key);
7687 if key == "COMMENT" && !self.config.schema_comment_with_eq {
7689 self.write_space();
7690 } else {
7691 self.write("=");
7692 }
7693 self.write(value);
7694 }
7695 }
7696
7697 if ct.temporary
7699 && matches!(
7700 self.config.dialect,
7701 Some(DialectType::Spark) | Some(DialectType::Databricks)
7702 )
7703 && ct.as_select.is_none()
7704 {
7705 self.write_space();
7706 self.write_keyword("USING PARQUET");
7707 }
7708
7709 if !ct.inherits.is_empty() {
7711 self.write_space();
7712 self.write_keyword("INHERITS");
7713 self.write(" (");
7714 for (i, parent) in ct.inherits.iter().enumerate() {
7715 if i > 0 {
7716 self.write(", ");
7717 }
7718 self.generate_table(parent)?;
7719 }
7720 self.write(")");
7721 }
7722
7723 if let Some(ref query) = ct.as_select {
7725 self.write_space();
7726 self.write_keyword("AS");
7727 self.write_space();
7728 if ct.as_select_parenthesized {
7729 self.write("(");
7730 }
7731 self.generate_expression(query)?;
7732 if ct.as_select_parenthesized {
7733 self.write(")");
7734 }
7735
7736 if let Some(with_data) = ct.with_data {
7738 self.write_space();
7739 self.write_keyword("WITH");
7740 if !with_data {
7741 self.write_space();
7742 self.write_keyword("NO");
7743 }
7744 self.write_space();
7745 self.write_keyword("DATA");
7746 }
7747
7748 if let Some(with_statistics) = ct.with_statistics {
7750 self.write_space();
7751 self.write_keyword("AND");
7752 if !with_statistics {
7753 self.write_space();
7754 self.write_keyword("NO");
7755 }
7756 self.write_space();
7757 self.write_keyword("STATISTICS");
7758 }
7759
7760 for index in &ct.teradata_indexes {
7762 self.write_space();
7763 match index.kind {
7764 TeradataIndexKind::NoPrimary => {
7765 self.write_keyword("NO PRIMARY INDEX");
7766 }
7767 TeradataIndexKind::Primary => {
7768 self.write_keyword("PRIMARY INDEX");
7769 }
7770 TeradataIndexKind::PrimaryAmp => {
7771 self.write_keyword("PRIMARY AMP INDEX");
7772 }
7773 TeradataIndexKind::Unique => {
7774 self.write_keyword("UNIQUE INDEX");
7775 }
7776 TeradataIndexKind::UniquePrimary => {
7777 self.write_keyword("UNIQUE PRIMARY INDEX");
7778 }
7779 TeradataIndexKind::Secondary => {
7780 self.write_keyword("INDEX");
7781 }
7782 }
7783 if let Some(ref name) = index.name {
7785 self.write_space();
7786 self.write(name);
7787 }
7788 if !index.columns.is_empty() {
7790 self.write(" (");
7791 for (i, col) in index.columns.iter().enumerate() {
7792 if i > 0 {
7793 self.write(", ");
7794 }
7795 self.write(col);
7796 }
7797 self.write(")");
7798 }
7799 }
7800
7801 if let Some(ref on_commit) = ct.on_commit {
7803 self.write_space();
7804 self.write_keyword("ON COMMIT");
7805 self.write_space();
7806 match on_commit {
7807 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
7808 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
7809 }
7810 }
7811
7812 if !post_as_properties.is_empty() {
7813 for prop in post_as_properties {
7814 self.write_space();
7815 self.generate_expression(prop)?;
7816 }
7817 }
7818
7819 self.athena_hive_context = saved_athena_hive_context;
7821 return Ok(());
7822 }
7823
7824 if let Some(ref on_commit) = ct.on_commit {
7826 self.write_space();
7827 self.write_keyword("ON COMMIT");
7828 self.write_space();
7829 match on_commit {
7830 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
7831 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
7832 }
7833 }
7834
7835 self.athena_hive_context = saved_athena_hive_context;
7837
7838 Ok(())
7839 }
7840
7841 fn generate_column_def_expr(&mut self, col: &ColumnDef) -> Result<()> {
7844 self.generate_identifier(&col.name)?;
7846 if !matches!(col.data_type, DataType::Unknown) {
7848 self.write_space();
7849 self.generate_data_type(&col.data_type)?;
7850 }
7851 for constraint in &col.constraints {
7853 if let ColumnConstraint::Path(path_expr) = constraint {
7854 self.write_space();
7855 self.write_keyword("PATH");
7856 self.write_space();
7857 self.generate_expression(path_expr)?;
7858 }
7859 }
7860 Ok(())
7861 }
7862
7863 fn generate_column_def(&mut self, col: &ColumnDef) -> Result<()> {
7864 let has_computed_no_type = matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
7866 && col
7867 .constraints
7868 .iter()
7869 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
7870 let omit_computed_type = !self.config.computed_column_with_type
7872 && col
7873 .constraints
7874 .iter()
7875 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
7876
7877 let is_partition_column_spec = matches!(col.data_type, DataType::Unknown);
7880
7881 let has_no_type = col.no_type
7884 || (matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
7885 && col.constraints.is_empty());
7886
7887 self.generate_identifier(&col.name)?;
7888
7889 let serial_expansion = if matches!(
7891 self.config.dialect,
7892 Some(DialectType::Materialize) | Some(DialectType::PostgreSQL)
7893 ) {
7894 if let DataType::Custom { ref name } = col.data_type {
7895 match name.to_uppercase().as_str() {
7896 "SERIAL" => Some("INT"),
7897 "BIGSERIAL" => Some("BIGINT"),
7898 "SMALLSERIAL" => Some("SMALLINT"),
7899 _ => None,
7900 }
7901 } else {
7902 None
7903 }
7904 } else {
7905 None
7906 };
7907
7908 if !has_computed_no_type && !omit_computed_type && !is_partition_column_spec && !has_no_type
7909 {
7910 self.write_space();
7911 let saved_nullable_depth = self.clickhouse_nullable_depth;
7914 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
7915 self.clickhouse_nullable_depth = -1;
7916 }
7917 if let Some(int_type) = serial_expansion {
7918 self.write_keyword(int_type);
7920 } else if col.unsigned && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
7921 let unsigned_type = match &col.data_type {
7923 DataType::Int { .. } => Some("UINTEGER"),
7924 DataType::BigInt { .. } => Some("UBIGINT"),
7925 DataType::SmallInt { .. } => Some("USMALLINT"),
7926 DataType::TinyInt { .. } => Some("UTINYINT"),
7927 _ => None,
7928 };
7929 if let Some(utype) = unsigned_type {
7930 self.write_keyword(utype);
7931 } else {
7932 self.generate_data_type(&col.data_type)?;
7933 }
7934 } else {
7935 self.generate_data_type(&col.data_type)?;
7936 }
7937 self.clickhouse_nullable_depth = saved_nullable_depth;
7938 }
7939
7940 if col.unsigned && !matches!(self.config.dialect, Some(DialectType::DuckDB)) {
7943 self.write_space();
7944 self.write_keyword("UNSIGNED");
7945 }
7946 if col.zerofill {
7947 self.write_space();
7948 self.write_keyword("ZEROFILL");
7949 }
7950
7951 if let Some(ref charset) = col.character_set {
7955 self.write_space();
7956 self.write_keyword("CHARACTER SET");
7957 self.write_space();
7958 self.write(charset);
7959 }
7960
7961 if col.uppercase {
7962 self.write_space();
7963 self.write_keyword("UPPERCASE");
7964 }
7965
7966 if let Some(casespecific) = col.casespecific {
7967 self.write_space();
7968 if casespecific {
7969 self.write_keyword("CASESPECIFIC");
7970 } else {
7971 self.write_keyword("NOT CASESPECIFIC");
7972 }
7973 }
7974
7975 if let Some(ref format) = col.format {
7976 self.write_space();
7977 self.write_keyword("FORMAT");
7978 self.write(" '");
7979 self.write(format);
7980 self.write("'");
7981 }
7982
7983 if let Some(ref title) = col.title {
7984 self.write_space();
7985 self.write_keyword("TITLE");
7986 self.write(" '");
7987 self.write(title);
7988 self.write("'");
7989 }
7990
7991 if let Some(length) = col.inline_length {
7992 self.write_space();
7993 self.write_keyword("INLINE LENGTH");
7994 self.write(" ");
7995 self.write(&length.to_string());
7996 }
7997
7998 if let Some(ref compress) = col.compress {
7999 self.write_space();
8000 self.write_keyword("COMPRESS");
8001 if !compress.is_empty() {
8002 if compress.len() == 1 {
8004 if let Expression::Literal(Literal::String(_)) = &compress[0] {
8005 self.write_space();
8006 self.generate_expression(&compress[0])?;
8007 } else {
8008 self.write(" (");
8009 self.generate_expression(&compress[0])?;
8010 self.write(")");
8011 }
8012 } else {
8013 self.write(" (");
8014 for (i, val) in compress.iter().enumerate() {
8015 if i > 0 {
8016 self.write(", ");
8017 }
8018 self.generate_expression(val)?;
8019 }
8020 self.write(")");
8021 }
8022 }
8023 }
8024
8025 if !col.constraint_order.is_empty() {
8028 let mut references_idx = 0;
8031 let mut check_idx = 0;
8032 let mut generated_idx = 0;
8033 let mut collate_idx = 0;
8034 let mut comment_idx = 0;
8035 let defer_not_null_after_identity = false;
8038 let mut pending_not_null_after_identity = false;
8039
8040 for constraint_type in &col.constraint_order {
8041 match constraint_type {
8042 ConstraintType::PrimaryKey => {
8043 if col.primary_key
8045 && !matches!(self.config.dialect, Some(DialectType::Materialize))
8046 {
8047 if let Some(ref cname) = col.primary_key_constraint_name {
8048 self.write_space();
8049 self.write_keyword("CONSTRAINT");
8050 self.write_space();
8051 self.write(cname);
8052 }
8053 self.write_space();
8054 self.write_keyword("PRIMARY KEY");
8055 if let Some(ref order) = col.primary_key_order {
8056 self.write_space();
8057 match order {
8058 SortOrder::Asc => self.write_keyword("ASC"),
8059 SortOrder::Desc => self.write_keyword("DESC"),
8060 }
8061 }
8062 }
8063 }
8064 ConstraintType::Unique => {
8065 if col.unique {
8066 if let Some(ref cname) = col.unique_constraint_name {
8067 self.write_space();
8068 self.write_keyword("CONSTRAINT");
8069 self.write_space();
8070 self.write(cname);
8071 }
8072 self.write_space();
8073 self.write_keyword("UNIQUE");
8074 if col.unique_nulls_not_distinct {
8076 self.write(" NULLS NOT DISTINCT");
8077 }
8078 }
8079 }
8080 ConstraintType::NotNull => {
8081 if col.nullable == Some(false) {
8082 if defer_not_null_after_identity {
8083 pending_not_null_after_identity = true;
8084 continue;
8085 }
8086 if let Some(ref cname) = col.not_null_constraint_name {
8087 self.write_space();
8088 self.write_keyword("CONSTRAINT");
8089 self.write_space();
8090 self.write(cname);
8091 }
8092 self.write_space();
8093 self.write_keyword("NOT NULL");
8094 }
8095 }
8096 ConstraintType::Null => {
8097 if col.nullable == Some(true) {
8098 self.write_space();
8099 self.write_keyword("NULL");
8100 }
8101 }
8102 ConstraintType::Default => {
8103 if let Some(ref default) = col.default {
8104 self.write_space();
8105 self.write_keyword("DEFAULT");
8106 self.write_space();
8107 self.generate_expression(default)?;
8108 }
8109 }
8110 ConstraintType::AutoIncrement => {
8111 if col.auto_increment {
8112 if matches!(
8114 self.config.dialect,
8115 Some(crate::dialects::DialectType::DuckDB)
8116 ) {
8117 } else if matches!(
8119 self.config.dialect,
8120 Some(crate::dialects::DialectType::Materialize)
8121 ) {
8122 if !matches!(col.nullable, Some(false)) {
8124 self.write_space();
8125 self.write_keyword("NOT NULL");
8126 }
8127 } else if matches!(
8128 self.config.dialect,
8129 Some(crate::dialects::DialectType::PostgreSQL)
8130 ) {
8131 self.write_space();
8133 self.generate_auto_increment_keyword(col)?;
8134 } else {
8135 self.write_space();
8136 self.generate_auto_increment_keyword(col)?;
8137 if pending_not_null_after_identity {
8138 self.write_space();
8139 self.write_keyword("NOT NULL");
8140 pending_not_null_after_identity = false;
8141 }
8142 }
8143 } }
8145 ConstraintType::References => {
8146 while references_idx < col.constraints.len() {
8148 if let ColumnConstraint::References(fk_ref) =
8149 &col.constraints[references_idx]
8150 {
8151 if let Some(ref name) = fk_ref.constraint_name {
8153 self.write_space();
8154 self.write_keyword("CONSTRAINT");
8155 self.write_space();
8156 self.write(name);
8157 }
8158 self.write_space();
8159 if fk_ref.has_foreign_key_keywords {
8160 self.write_keyword("FOREIGN KEY");
8161 self.write_space();
8162 }
8163 self.write_keyword("REFERENCES");
8164 self.write_space();
8165 self.generate_table(&fk_ref.table)?;
8166 if !fk_ref.columns.is_empty() {
8167 self.write(" (");
8168 for (i, c) in fk_ref.columns.iter().enumerate() {
8169 if i > 0 {
8170 self.write(", ");
8171 }
8172 self.generate_identifier(c)?;
8173 }
8174 self.write(")");
8175 }
8176 self.generate_referential_actions(fk_ref)?;
8177 references_idx += 1;
8178 break;
8179 }
8180 references_idx += 1;
8181 }
8182 }
8183 ConstraintType::Check => {
8184 while check_idx < col.constraints.len() {
8186 if let ColumnConstraint::Check(expr) = &col.constraints[check_idx] {
8187 if check_idx == 0 {
8189 if let Some(ref cname) = col.check_constraint_name {
8190 self.write_space();
8191 self.write_keyword("CONSTRAINT");
8192 self.write_space();
8193 self.write(cname);
8194 }
8195 }
8196 self.write_space();
8197 self.write_keyword("CHECK");
8198 self.write(" (");
8199 self.generate_expression(expr)?;
8200 self.write(")");
8201 check_idx += 1;
8202 break;
8203 }
8204 check_idx += 1;
8205 }
8206 }
8207 ConstraintType::GeneratedAsIdentity => {
8208 while generated_idx < col.constraints.len() {
8210 if let ColumnConstraint::GeneratedAsIdentity(gen) =
8211 &col.constraints[generated_idx]
8212 {
8213 self.write_space();
8214 if matches!(
8216 self.config.dialect,
8217 Some(crate::dialects::DialectType::Redshift)
8218 ) {
8219 self.write_keyword("IDENTITY");
8220 self.write("(");
8221 if let Some(ref start) = gen.start {
8222 self.generate_expression(start)?;
8223 } else {
8224 self.write("0");
8225 }
8226 self.write(", ");
8227 if let Some(ref incr) = gen.increment {
8228 self.generate_expression(incr)?;
8229 } else {
8230 self.write("1");
8231 }
8232 self.write(")");
8233 } else {
8234 self.write_keyword("GENERATED");
8235 if gen.always {
8236 self.write_space();
8237 self.write_keyword("ALWAYS");
8238 } else {
8239 self.write_space();
8240 self.write_keyword("BY DEFAULT");
8241 if gen.on_null {
8242 self.write_space();
8243 self.write_keyword("ON NULL");
8244 }
8245 }
8246 self.write_space();
8247 self.write_keyword("AS IDENTITY");
8248
8249 let has_options = gen.start.is_some()
8250 || gen.increment.is_some()
8251 || gen.minvalue.is_some()
8252 || gen.maxvalue.is_some()
8253 || gen.cycle.is_some();
8254 if has_options {
8255 self.write(" (");
8256 let mut first = true;
8257 if let Some(ref start) = gen.start {
8258 if !first {
8259 self.write(" ");
8260 }
8261 first = false;
8262 self.write_keyword("START WITH");
8263 self.write_space();
8264 self.generate_expression(start)?;
8265 }
8266 if let Some(ref incr) = gen.increment {
8267 if !first {
8268 self.write(" ");
8269 }
8270 first = false;
8271 self.write_keyword("INCREMENT BY");
8272 self.write_space();
8273 self.generate_expression(incr)?;
8274 }
8275 if let Some(ref minv) = gen.minvalue {
8276 if !first {
8277 self.write(" ");
8278 }
8279 first = false;
8280 self.write_keyword("MINVALUE");
8281 self.write_space();
8282 self.generate_expression(minv)?;
8283 }
8284 if let Some(ref maxv) = gen.maxvalue {
8285 if !first {
8286 self.write(" ");
8287 }
8288 first = false;
8289 self.write_keyword("MAXVALUE");
8290 self.write_space();
8291 self.generate_expression(maxv)?;
8292 }
8293 if let Some(cycle) = gen.cycle {
8294 if !first {
8295 self.write(" ");
8296 }
8297 if cycle {
8298 self.write_keyword("CYCLE");
8299 } else {
8300 self.write_keyword("NO CYCLE");
8301 }
8302 }
8303 self.write(")");
8304 }
8305 }
8306 generated_idx += 1;
8307 break;
8308 }
8309 generated_idx += 1;
8310 }
8311 }
8312 ConstraintType::Collate => {
8313 while collate_idx < col.constraints.len() {
8315 if let ColumnConstraint::Collate(collation) =
8316 &col.constraints[collate_idx]
8317 {
8318 self.write_space();
8319 self.write_keyword("COLLATE");
8320 self.write_space();
8321 self.generate_identifier(collation)?;
8322 collate_idx += 1;
8323 break;
8324 }
8325 collate_idx += 1;
8326 }
8327 }
8328 ConstraintType::Comment => {
8329 while comment_idx < col.constraints.len() {
8331 if let ColumnConstraint::Comment(comment) =
8332 &col.constraints[comment_idx]
8333 {
8334 self.write_space();
8335 self.write_keyword("COMMENT");
8336 self.write_space();
8337 self.generate_string_literal(comment)?;
8338 comment_idx += 1;
8339 break;
8340 }
8341 comment_idx += 1;
8342 }
8343 }
8344 ConstraintType::Tags => {
8345 for constraint in &col.constraints {
8347 if let ColumnConstraint::Tags(tags) = constraint {
8348 self.write_space();
8349 self.write_keyword("TAG");
8350 self.write(" (");
8351 for (i, expr) in tags.expressions.iter().enumerate() {
8352 if i > 0 {
8353 self.write(", ");
8354 }
8355 self.generate_expression(expr)?;
8356 }
8357 self.write(")");
8358 break;
8359 }
8360 }
8361 }
8362 ConstraintType::ComputedColumn => {
8363 for constraint in &col.constraints {
8365 if let ColumnConstraint::ComputedColumn(cc) = constraint {
8366 self.write_space();
8367 self.generate_computed_column_inline(cc)?;
8368 break;
8369 }
8370 }
8371 }
8372 ConstraintType::GeneratedAsRow => {
8373 for constraint in &col.constraints {
8375 if let ColumnConstraint::GeneratedAsRow(gar) = constraint {
8376 self.write_space();
8377 self.generate_generated_as_row_inline(gar)?;
8378 break;
8379 }
8380 }
8381 }
8382 ConstraintType::OnUpdate => {
8383 if let Some(ref expr) = col.on_update {
8384 self.write_space();
8385 self.write_keyword("ON UPDATE");
8386 self.write_space();
8387 self.generate_expression(expr)?;
8388 }
8389 }
8390 ConstraintType::Encode => {
8391 if let Some(ref encoding) = col.encoding {
8392 self.write_space();
8393 self.write_keyword("ENCODE");
8394 self.write_space();
8395 self.write(encoding);
8396 }
8397 }
8398 ConstraintType::Path => {
8399 for constraint in &col.constraints {
8401 if let ColumnConstraint::Path(path_expr) = constraint {
8402 self.write_space();
8403 self.write_keyword("PATH");
8404 self.write_space();
8405 self.generate_expression(path_expr)?;
8406 break;
8407 }
8408 }
8409 }
8410 }
8411 }
8412 if pending_not_null_after_identity {
8413 self.write_space();
8414 self.write_keyword("NOT NULL");
8415 }
8416 } else {
8417 if col.primary_key {
8419 self.write_space();
8420 self.write_keyword("PRIMARY KEY");
8421 if let Some(ref order) = col.primary_key_order {
8422 self.write_space();
8423 match order {
8424 SortOrder::Asc => self.write_keyword("ASC"),
8425 SortOrder::Desc => self.write_keyword("DESC"),
8426 }
8427 }
8428 }
8429
8430 if col.unique {
8431 self.write_space();
8432 self.write_keyword("UNIQUE");
8433 if col.unique_nulls_not_distinct {
8435 self.write(" NULLS NOT DISTINCT");
8436 }
8437 }
8438
8439 match col.nullable {
8440 Some(false) => {
8441 self.write_space();
8442 self.write_keyword("NOT NULL");
8443 }
8444 Some(true) => {
8445 self.write_space();
8446 self.write_keyword("NULL");
8447 }
8448 None => {}
8449 }
8450
8451 if let Some(ref default) = col.default {
8452 self.write_space();
8453 self.write_keyword("DEFAULT");
8454 self.write_space();
8455 self.generate_expression(default)?;
8456 }
8457
8458 if col.auto_increment {
8459 self.write_space();
8460 self.generate_auto_increment_keyword(col)?;
8461 }
8462
8463 for constraint in &col.constraints {
8465 match constraint {
8466 ColumnConstraint::References(fk_ref) => {
8467 self.write_space();
8468 if fk_ref.has_foreign_key_keywords {
8469 self.write_keyword("FOREIGN KEY");
8470 self.write_space();
8471 }
8472 self.write_keyword("REFERENCES");
8473 self.write_space();
8474 self.generate_table(&fk_ref.table)?;
8475 if !fk_ref.columns.is_empty() {
8476 self.write(" (");
8477 for (i, c) in fk_ref.columns.iter().enumerate() {
8478 if i > 0 {
8479 self.write(", ");
8480 }
8481 self.generate_identifier(c)?;
8482 }
8483 self.write(")");
8484 }
8485 self.generate_referential_actions(fk_ref)?;
8486 }
8487 ColumnConstraint::Check(expr) => {
8488 self.write_space();
8489 self.write_keyword("CHECK");
8490 self.write(" (");
8491 self.generate_expression(expr)?;
8492 self.write(")");
8493 }
8494 ColumnConstraint::GeneratedAsIdentity(gen) => {
8495 self.write_space();
8496 if matches!(
8498 self.config.dialect,
8499 Some(crate::dialects::DialectType::Redshift)
8500 ) {
8501 self.write_keyword("IDENTITY");
8502 self.write("(");
8503 if let Some(ref start) = gen.start {
8504 self.generate_expression(start)?;
8505 } else {
8506 self.write("0");
8507 }
8508 self.write(", ");
8509 if let Some(ref incr) = gen.increment {
8510 self.generate_expression(incr)?;
8511 } else {
8512 self.write("1");
8513 }
8514 self.write(")");
8515 } else {
8516 self.write_keyword("GENERATED");
8517 if gen.always {
8518 self.write_space();
8519 self.write_keyword("ALWAYS");
8520 } else {
8521 self.write_space();
8522 self.write_keyword("BY DEFAULT");
8523 if gen.on_null {
8524 self.write_space();
8525 self.write_keyword("ON NULL");
8526 }
8527 }
8528 self.write_space();
8529 self.write_keyword("AS IDENTITY");
8530
8531 let has_options = gen.start.is_some()
8532 || gen.increment.is_some()
8533 || gen.minvalue.is_some()
8534 || gen.maxvalue.is_some()
8535 || gen.cycle.is_some();
8536 if has_options {
8537 self.write(" (");
8538 let mut first = true;
8539 if let Some(ref start) = gen.start {
8540 if !first {
8541 self.write(" ");
8542 }
8543 first = false;
8544 self.write_keyword("START WITH");
8545 self.write_space();
8546 self.generate_expression(start)?;
8547 }
8548 if let Some(ref incr) = gen.increment {
8549 if !first {
8550 self.write(" ");
8551 }
8552 first = false;
8553 self.write_keyword("INCREMENT BY");
8554 self.write_space();
8555 self.generate_expression(incr)?;
8556 }
8557 if let Some(ref minv) = gen.minvalue {
8558 if !first {
8559 self.write(" ");
8560 }
8561 first = false;
8562 self.write_keyword("MINVALUE");
8563 self.write_space();
8564 self.generate_expression(minv)?;
8565 }
8566 if let Some(ref maxv) = gen.maxvalue {
8567 if !first {
8568 self.write(" ");
8569 }
8570 first = false;
8571 self.write_keyword("MAXVALUE");
8572 self.write_space();
8573 self.generate_expression(maxv)?;
8574 }
8575 if let Some(cycle) = gen.cycle {
8576 if !first {
8577 self.write(" ");
8578 }
8579 if cycle {
8580 self.write_keyword("CYCLE");
8581 } else {
8582 self.write_keyword("NO CYCLE");
8583 }
8584 }
8585 self.write(")");
8586 }
8587 }
8588 }
8589 ColumnConstraint::Collate(collation) => {
8590 self.write_space();
8591 self.write_keyword("COLLATE");
8592 self.write_space();
8593 self.generate_identifier(collation)?;
8594 }
8595 ColumnConstraint::Comment(comment) => {
8596 self.write_space();
8597 self.write_keyword("COMMENT");
8598 self.write_space();
8599 self.generate_string_literal(comment)?;
8600 }
8601 ColumnConstraint::Path(path_expr) => {
8602 self.write_space();
8603 self.write_keyword("PATH");
8604 self.write_space();
8605 self.generate_expression(path_expr)?;
8606 }
8607 _ => {} }
8609 }
8610
8611 if let Some(ref encoding) = col.encoding {
8613 self.write_space();
8614 self.write_keyword("ENCODE");
8615 self.write_space();
8616 self.write(encoding);
8617 }
8618 }
8619
8620 if let Some(ref codec) = col.codec {
8622 self.write_space();
8623 self.write_keyword("CODEC");
8624 self.write("(");
8625 self.write(codec);
8626 self.write(")");
8627 }
8628
8629 if let Some(ref ephemeral) = col.ephemeral {
8631 self.write_space();
8632 self.write_keyword("EPHEMERAL");
8633 if let Some(ref expr) = ephemeral {
8634 self.write_space();
8635 self.generate_expression(expr)?;
8636 }
8637 }
8638
8639 if let Some(ref mat_expr) = col.materialized_expr {
8641 self.write_space();
8642 self.write_keyword("MATERIALIZED");
8643 self.write_space();
8644 self.generate_expression(mat_expr)?;
8645 }
8646
8647 if let Some(ref alias_expr) = col.alias_expr {
8649 self.write_space();
8650 self.write_keyword("ALIAS");
8651 self.write_space();
8652 self.generate_expression(alias_expr)?;
8653 }
8654
8655 if let Some(ref ttl_expr) = col.ttl_expr {
8657 self.write_space();
8658 self.write_keyword("TTL");
8659 self.write_space();
8660 self.generate_expression(ttl_expr)?;
8661 }
8662
8663 if col.not_for_replication
8665 && matches!(
8666 self.config.dialect,
8667 Some(crate::dialects::DialectType::TSQL)
8668 | Some(crate::dialects::DialectType::Fabric)
8669 )
8670 {
8671 self.write_space();
8672 self.write_keyword("NOT FOR REPLICATION");
8673 }
8674
8675 if !col.options.is_empty() {
8677 self.write_space();
8678 self.generate_options_clause(&col.options)?;
8679 }
8680
8681 if !col.primary_key
8684 && self
8685 .sqlite_inline_pk_columns
8686 .contains(&col.name.name.to_lowercase())
8687 {
8688 self.write_space();
8689 self.write_keyword("PRIMARY KEY");
8690 }
8691
8692 if serial_expansion.is_some() {
8695 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
8696 self.write_space();
8697 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY NOT NULL");
8698 } else if matches!(self.config.dialect, Some(DialectType::Materialize)) {
8699 self.write_space();
8700 self.write_keyword("NOT NULL");
8701 }
8702 }
8703
8704 Ok(())
8705 }
8706
8707 fn generate_table_constraint(&mut self, constraint: &TableConstraint) -> Result<()> {
8708 match constraint {
8709 TableConstraint::PrimaryKey {
8710 name,
8711 columns,
8712 include_columns,
8713 modifiers,
8714 has_constraint_keyword,
8715 } => {
8716 if let Some(ref n) = name {
8717 if *has_constraint_keyword {
8718 self.write_keyword("CONSTRAINT");
8719 self.write_space();
8720 self.generate_identifier(n)?;
8721 self.write_space();
8722 }
8723 }
8724 self.write_keyword("PRIMARY KEY");
8725 if let Some(ref clustered) = modifiers.clustered {
8727 self.write_space();
8728 self.write_keyword(clustered);
8729 }
8730 if let Some(ref n) = name {
8732 if !*has_constraint_keyword {
8733 self.write_space();
8734 self.generate_identifier(n)?;
8735 }
8736 }
8737 self.write(" (");
8738 for (i, col) in columns.iter().enumerate() {
8739 if i > 0 {
8740 self.write(", ");
8741 }
8742 self.generate_identifier(col)?;
8743 }
8744 self.write(")");
8745 if !include_columns.is_empty() {
8746 self.write_space();
8747 self.write_keyword("INCLUDE");
8748 self.write(" (");
8749 for (i, col) in include_columns.iter().enumerate() {
8750 if i > 0 {
8751 self.write(", ");
8752 }
8753 self.generate_identifier(col)?;
8754 }
8755 self.write(")");
8756 }
8757 self.generate_constraint_modifiers(modifiers);
8758 }
8759 TableConstraint::Unique {
8760 name,
8761 columns,
8762 columns_parenthesized,
8763 modifiers,
8764 has_constraint_keyword,
8765 nulls_not_distinct,
8766 } => {
8767 if let Some(ref n) = name {
8768 if *has_constraint_keyword {
8769 self.write_keyword("CONSTRAINT");
8770 self.write_space();
8771 self.generate_identifier(n)?;
8772 self.write_space();
8773 }
8774 }
8775 self.write_keyword("UNIQUE");
8776 if let Some(ref clustered) = modifiers.clustered {
8778 self.write_space();
8779 self.write_keyword(clustered);
8780 }
8781 if *nulls_not_distinct {
8783 self.write(" NULLS NOT DISTINCT");
8784 }
8785 if let Some(ref n) = name {
8787 if !*has_constraint_keyword {
8788 self.write_space();
8789 self.generate_identifier(n)?;
8790 }
8791 }
8792 if *columns_parenthesized {
8793 self.write(" (");
8794 for (i, col) in columns.iter().enumerate() {
8795 if i > 0 {
8796 self.write(", ");
8797 }
8798 self.generate_identifier(col)?;
8799 }
8800 self.write(")");
8801 } else {
8802 for col in columns.iter() {
8804 self.write_space();
8805 self.generate_identifier(col)?;
8806 }
8807 }
8808 self.generate_constraint_modifiers(modifiers);
8809 }
8810 TableConstraint::ForeignKey {
8811 name,
8812 columns,
8813 references,
8814 on_delete,
8815 on_update,
8816 modifiers,
8817 } => {
8818 if let Some(ref n) = name {
8819 self.write_keyword("CONSTRAINT");
8820 self.write_space();
8821 self.generate_identifier(n)?;
8822 self.write_space();
8823 }
8824 self.write_keyword("FOREIGN KEY");
8825 self.write(" (");
8826 for (i, col) in columns.iter().enumerate() {
8827 if i > 0 {
8828 self.write(", ");
8829 }
8830 self.generate_identifier(col)?;
8831 }
8832 self.write(")");
8833 if let Some(ref refs) = references {
8834 self.write(" ");
8835 self.write_keyword("REFERENCES");
8836 self.write_space();
8837 self.generate_table(&refs.table)?;
8838 if !refs.columns.is_empty() {
8839 if self.config.pretty {
8840 self.write(" (");
8841 self.write_newline();
8842 self.indent_level += 1;
8843 for (i, col) in refs.columns.iter().enumerate() {
8844 if i > 0 {
8845 self.write(",");
8846 self.write_newline();
8847 }
8848 self.write_indent();
8849 self.generate_identifier(col)?;
8850 }
8851 self.indent_level -= 1;
8852 self.write_newline();
8853 self.write_indent();
8854 self.write(")");
8855 } else {
8856 self.write(" (");
8857 for (i, col) in refs.columns.iter().enumerate() {
8858 if i > 0 {
8859 self.write(", ");
8860 }
8861 self.generate_identifier(col)?;
8862 }
8863 self.write(")");
8864 }
8865 }
8866 self.generate_referential_actions(refs)?;
8867 } else {
8868 if let Some(ref action) = on_delete {
8870 self.write_space();
8871 self.write_keyword("ON DELETE");
8872 self.write_space();
8873 self.generate_referential_action(action);
8874 }
8875 if let Some(ref action) = on_update {
8876 self.write_space();
8877 self.write_keyword("ON UPDATE");
8878 self.write_space();
8879 self.generate_referential_action(action);
8880 }
8881 }
8882 self.generate_constraint_modifiers(modifiers);
8883 }
8884 TableConstraint::Check {
8885 name,
8886 expression,
8887 modifiers,
8888 } => {
8889 if let Some(ref n) = name {
8890 self.write_keyword("CONSTRAINT");
8891 self.write_space();
8892 self.generate_identifier(n)?;
8893 self.write_space();
8894 }
8895 self.write_keyword("CHECK");
8896 self.write(" (");
8897 self.generate_expression(expression)?;
8898 self.write(")");
8899 self.generate_constraint_modifiers(modifiers);
8900 }
8901 TableConstraint::Index {
8902 name,
8903 columns,
8904 kind,
8905 modifiers,
8906 use_key_keyword,
8907 expression,
8908 index_type,
8909 granularity,
8910 } => {
8911 if expression.is_some() {
8913 self.write_keyword("INDEX");
8914 if let Some(ref n) = name {
8915 self.write_space();
8916 self.generate_identifier(n)?;
8917 }
8918 if let Some(ref expr) = expression {
8919 self.write_space();
8920 self.generate_expression(expr)?;
8921 }
8922 if let Some(ref idx_type) = index_type {
8923 self.write_space();
8924 self.write_keyword("TYPE");
8925 self.write_space();
8926 self.generate_expression(idx_type)?;
8927 }
8928 if let Some(ref gran) = granularity {
8929 self.write_space();
8930 self.write_keyword("GRANULARITY");
8931 self.write_space();
8932 self.generate_expression(gran)?;
8933 }
8934 } else {
8935 use crate::dialects::DialectType;
8939 let index_keyword = if *use_key_keyword
8940 && !matches!(self.config.dialect, Some(DialectType::MySQL))
8941 {
8942 "KEY"
8943 } else {
8944 "INDEX"
8945 };
8946
8947 if let Some(ref k) = kind {
8949 self.write_keyword(k);
8950 if k != "UNIQUE" {
8952 self.write_space();
8953 self.write_keyword(index_keyword);
8954 }
8955 } else {
8956 self.write_keyword(index_keyword);
8957 }
8958
8959 if modifiers.using_before_columns && name.is_none() {
8961 if let Some(ref using) = modifiers.using {
8962 self.write_space();
8963 self.write_keyword("USING");
8964 self.write_space();
8965 self.write_keyword(using);
8966 }
8967 }
8968
8969 if let Some(ref n) = name {
8971 self.write_space();
8972 self.generate_identifier(n)?;
8973 }
8974
8975 if modifiers.using_before_columns && name.is_some() {
8977 if let Some(ref using) = modifiers.using {
8978 self.write_space();
8979 self.write_keyword("USING");
8980 self.write_space();
8981 self.write_keyword(using);
8982 }
8983 }
8984
8985 self.write(" (");
8987 for (i, col) in columns.iter().enumerate() {
8988 if i > 0 {
8989 self.write(", ");
8990 }
8991 self.generate_identifier(col)?;
8992 }
8993 self.write(")");
8994
8995 if !modifiers.using_before_columns {
8997 if let Some(ref using) = modifiers.using {
8998 self.write_space();
8999 self.write_keyword("USING");
9000 self.write_space();
9001 self.write_keyword(using);
9002 }
9003 }
9004
9005 self.generate_constraint_modifiers_without_using(modifiers);
9007 }
9008 }
9009 TableConstraint::Projection { name, expression } => {
9010 self.write_keyword("PROJECTION");
9012 self.write_space();
9013 self.generate_identifier(name)?;
9014 self.write(" (");
9015 self.generate_expression(expression)?;
9016 self.write(")");
9017 }
9018 TableConstraint::Like { source, options } => {
9019 self.write_keyword("LIKE");
9020 self.write_space();
9021 self.generate_table(source)?;
9022 for (action, prop) in options {
9023 self.write_space();
9024 match action {
9025 LikeOptionAction::Including => self.write_keyword("INCLUDING"),
9026 LikeOptionAction::Excluding => self.write_keyword("EXCLUDING"),
9027 }
9028 self.write_space();
9029 self.write_keyword(prop);
9030 }
9031 }
9032 TableConstraint::PeriodForSystemTime { start_col, end_col } => {
9033 self.write_keyword("PERIOD FOR SYSTEM_TIME");
9034 self.write(" (");
9035 self.generate_identifier(start_col)?;
9036 self.write(", ");
9037 self.generate_identifier(end_col)?;
9038 self.write(")");
9039 }
9040 TableConstraint::Exclude {
9041 name,
9042 using,
9043 elements,
9044 include_columns,
9045 where_clause,
9046 with_params,
9047 using_index_tablespace,
9048 modifiers: _,
9049 } => {
9050 if let Some(ref n) = name {
9051 self.write_keyword("CONSTRAINT");
9052 self.write_space();
9053 self.generate_identifier(n)?;
9054 self.write_space();
9055 }
9056 self.write_keyword("EXCLUDE");
9057 if let Some(ref method) = using {
9058 self.write_space();
9059 self.write_keyword("USING");
9060 self.write_space();
9061 self.write(method);
9062 self.write("(");
9063 } else {
9064 self.write(" (");
9065 }
9066 for (i, elem) in elements.iter().enumerate() {
9067 if i > 0 {
9068 self.write(", ");
9069 }
9070 self.write(&elem.expression);
9071 self.write_space();
9072 self.write_keyword("WITH");
9073 self.write_space();
9074 self.write(&elem.operator);
9075 }
9076 self.write(")");
9077 if !include_columns.is_empty() {
9078 self.write_space();
9079 self.write_keyword("INCLUDE");
9080 self.write(" (");
9081 for (i, col) in include_columns.iter().enumerate() {
9082 if i > 0 {
9083 self.write(", ");
9084 }
9085 self.generate_identifier(col)?;
9086 }
9087 self.write(")");
9088 }
9089 if !with_params.is_empty() {
9090 self.write_space();
9091 self.write_keyword("WITH");
9092 self.write(" (");
9093 for (i, (key, val)) in with_params.iter().enumerate() {
9094 if i > 0 {
9095 self.write(", ");
9096 }
9097 self.write(key);
9098 self.write("=");
9099 self.write(val);
9100 }
9101 self.write(")");
9102 }
9103 if let Some(ref tablespace) = using_index_tablespace {
9104 self.write_space();
9105 self.write_keyword("USING INDEX TABLESPACE");
9106 self.write_space();
9107 self.write(tablespace);
9108 }
9109 if let Some(ref where_expr) = where_clause {
9110 self.write_space();
9111 self.write_keyword("WHERE");
9112 self.write(" (");
9113 self.generate_expression(where_expr)?;
9114 self.write(")");
9115 }
9116 }
9117 TableConstraint::Tags(tags) => {
9118 self.write_keyword("TAG");
9119 self.write(" (");
9120 for (i, expr) in tags.expressions.iter().enumerate() {
9121 if i > 0 {
9122 self.write(", ");
9123 }
9124 self.generate_expression(expr)?;
9125 }
9126 self.write(")");
9127 }
9128 TableConstraint::InitiallyDeferred { deferred } => {
9129 self.write_keyword("INITIALLY");
9130 self.write_space();
9131 if *deferred {
9132 self.write_keyword("DEFERRED");
9133 } else {
9134 self.write_keyword("IMMEDIATE");
9135 }
9136 }
9137 }
9138 Ok(())
9139 }
9140
9141 fn generate_constraint_modifiers(&mut self, modifiers: &ConstraintModifiers) {
9142 if let Some(using) = &modifiers.using {
9144 self.write_space();
9145 self.write_keyword("USING");
9146 self.write_space();
9147 self.write_keyword(using);
9148 }
9149 if let Some(enforced) = modifiers.enforced {
9151 self.write_space();
9152 if enforced {
9153 self.write_keyword("ENFORCED");
9154 } else {
9155 self.write_keyword("NOT ENFORCED");
9156 }
9157 }
9158 if let Some(deferrable) = modifiers.deferrable {
9160 self.write_space();
9161 if deferrable {
9162 self.write_keyword("DEFERRABLE");
9163 } else {
9164 self.write_keyword("NOT DEFERRABLE");
9165 }
9166 }
9167 if let Some(initially_deferred) = modifiers.initially_deferred {
9169 self.write_space();
9170 if initially_deferred {
9171 self.write_keyword("INITIALLY DEFERRED");
9172 } else {
9173 self.write_keyword("INITIALLY IMMEDIATE");
9174 }
9175 }
9176 if modifiers.norely {
9178 self.write_space();
9179 self.write_keyword("NORELY");
9180 }
9181 if modifiers.rely {
9183 self.write_space();
9184 self.write_keyword("RELY");
9185 }
9186 if modifiers.not_valid {
9188 self.write_space();
9189 self.write_keyword("NOT VALID");
9190 }
9191 if let Some(on_conflict) = &modifiers.on_conflict {
9193 self.write_space();
9194 self.write_keyword("ON CONFLICT");
9195 self.write_space();
9196 self.write_keyword(on_conflict);
9197 }
9198 if !modifiers.with_options.is_empty() {
9200 self.write_space();
9201 self.write_keyword("WITH");
9202 self.write(" (");
9203 for (i, (key, value)) in modifiers.with_options.iter().enumerate() {
9204 if i > 0 {
9205 self.write(", ");
9206 }
9207 self.write(key);
9208 self.write("=");
9209 self.write(value);
9210 }
9211 self.write(")");
9212 }
9213 if let Some(ref fg) = modifiers.on_filegroup {
9215 self.write_space();
9216 self.write_keyword("ON");
9217 self.write_space();
9218 let _ = self.generate_identifier(fg);
9219 }
9220 }
9221
9222 fn generate_constraint_modifiers_without_using(&mut self, modifiers: &ConstraintModifiers) {
9224 if let Some(enforced) = modifiers.enforced {
9226 self.write_space();
9227 if enforced {
9228 self.write_keyword("ENFORCED");
9229 } else {
9230 self.write_keyword("NOT ENFORCED");
9231 }
9232 }
9233 if let Some(deferrable) = modifiers.deferrable {
9235 self.write_space();
9236 if deferrable {
9237 self.write_keyword("DEFERRABLE");
9238 } else {
9239 self.write_keyword("NOT DEFERRABLE");
9240 }
9241 }
9242 if let Some(initially_deferred) = modifiers.initially_deferred {
9244 self.write_space();
9245 if initially_deferred {
9246 self.write_keyword("INITIALLY DEFERRED");
9247 } else {
9248 self.write_keyword("INITIALLY IMMEDIATE");
9249 }
9250 }
9251 if modifiers.norely {
9253 self.write_space();
9254 self.write_keyword("NORELY");
9255 }
9256 if modifiers.rely {
9258 self.write_space();
9259 self.write_keyword("RELY");
9260 }
9261 if modifiers.not_valid {
9263 self.write_space();
9264 self.write_keyword("NOT VALID");
9265 }
9266 if let Some(on_conflict) = &modifiers.on_conflict {
9268 self.write_space();
9269 self.write_keyword("ON CONFLICT");
9270 self.write_space();
9271 self.write_keyword(on_conflict);
9272 }
9273 self.generate_index_specific_modifiers(modifiers);
9275 }
9276
9277 fn generate_index_specific_modifiers(&mut self, modifiers: &ConstraintModifiers) {
9279 if let Some(ref comment) = modifiers.comment {
9280 self.write_space();
9281 self.write_keyword("COMMENT");
9282 self.write(" '");
9283 self.write(comment);
9284 self.write("'");
9285 }
9286 if let Some(visible) = modifiers.visible {
9287 self.write_space();
9288 if visible {
9289 self.write_keyword("VISIBLE");
9290 } else {
9291 self.write_keyword("INVISIBLE");
9292 }
9293 }
9294 if let Some(ref attr) = modifiers.engine_attribute {
9295 self.write_space();
9296 self.write_keyword("ENGINE_ATTRIBUTE");
9297 self.write(" = '");
9298 self.write(attr);
9299 self.write("'");
9300 }
9301 if let Some(ref parser) = modifiers.with_parser {
9302 self.write_space();
9303 self.write_keyword("WITH PARSER");
9304 self.write_space();
9305 self.write(parser);
9306 }
9307 }
9308
9309 fn generate_referential_actions(&mut self, fk_ref: &ForeignKeyRef) -> Result<()> {
9310 if !fk_ref.match_after_actions {
9312 if let Some(ref match_type) = fk_ref.match_type {
9313 self.write_space();
9314 self.write_keyword("MATCH");
9315 self.write_space();
9316 match match_type {
9317 MatchType::Full => self.write_keyword("FULL"),
9318 MatchType::Partial => self.write_keyword("PARTIAL"),
9319 MatchType::Simple => self.write_keyword("SIMPLE"),
9320 }
9321 }
9322 }
9323
9324 if fk_ref.on_update_first {
9326 if let Some(ref action) = fk_ref.on_update {
9327 self.write_space();
9328 self.write_keyword("ON UPDATE");
9329 self.write_space();
9330 self.generate_referential_action(action);
9331 }
9332 if let Some(ref action) = fk_ref.on_delete {
9333 self.write_space();
9334 self.write_keyword("ON DELETE");
9335 self.write_space();
9336 self.generate_referential_action(action);
9337 }
9338 } else {
9339 if let Some(ref action) = fk_ref.on_delete {
9340 self.write_space();
9341 self.write_keyword("ON DELETE");
9342 self.write_space();
9343 self.generate_referential_action(action);
9344 }
9345 if let Some(ref action) = fk_ref.on_update {
9346 self.write_space();
9347 self.write_keyword("ON UPDATE");
9348 self.write_space();
9349 self.generate_referential_action(action);
9350 }
9351 }
9352
9353 if fk_ref.match_after_actions {
9355 if let Some(ref match_type) = fk_ref.match_type {
9356 self.write_space();
9357 self.write_keyword("MATCH");
9358 self.write_space();
9359 match match_type {
9360 MatchType::Full => self.write_keyword("FULL"),
9361 MatchType::Partial => self.write_keyword("PARTIAL"),
9362 MatchType::Simple => self.write_keyword("SIMPLE"),
9363 }
9364 }
9365 }
9366
9367 if let Some(deferrable) = fk_ref.deferrable {
9369 self.write_space();
9370 if deferrable {
9371 self.write_keyword("DEFERRABLE");
9372 } else {
9373 self.write_keyword("NOT DEFERRABLE");
9374 }
9375 }
9376
9377 Ok(())
9378 }
9379
9380 fn generate_referential_action(&mut self, action: &ReferentialAction) {
9381 match action {
9382 ReferentialAction::Cascade => self.write_keyword("CASCADE"),
9383 ReferentialAction::SetNull => self.write_keyword("SET NULL"),
9384 ReferentialAction::SetDefault => self.write_keyword("SET DEFAULT"),
9385 ReferentialAction::Restrict => self.write_keyword("RESTRICT"),
9386 ReferentialAction::NoAction => self.write_keyword("NO ACTION"),
9387 }
9388 }
9389
9390 fn generate_drop_table(&mut self, dt: &DropTable) -> Result<()> {
9391 let saved_athena_hive_context = self.athena_hive_context;
9393 if matches!(
9394 self.config.dialect,
9395 Some(crate::dialects::DialectType::Athena)
9396 ) {
9397 self.athena_hive_context = true;
9398 }
9399
9400 for comment in &dt.leading_comments {
9402 self.write_formatted_comment(comment);
9403 self.write_space();
9404 }
9405 self.write_keyword("DROP TABLE");
9406
9407 if dt.if_exists {
9408 self.write_space();
9409 self.write_keyword("IF EXISTS");
9410 }
9411
9412 self.write_space();
9413 for (i, table) in dt.names.iter().enumerate() {
9414 if i > 0 {
9415 self.write(", ");
9416 }
9417 self.generate_table(table)?;
9418 }
9419
9420 if dt.cascade_constraints {
9421 self.write_space();
9422 self.write_keyword("CASCADE CONSTRAINTS");
9423 } else if dt.cascade {
9424 self.write_space();
9425 self.write_keyword("CASCADE");
9426 }
9427
9428 if dt.purge {
9429 self.write_space();
9430 self.write_keyword("PURGE");
9431 }
9432
9433 self.athena_hive_context = saved_athena_hive_context;
9435
9436 Ok(())
9437 }
9438
9439 fn generate_alter_table(&mut self, at: &AlterTable) -> Result<()> {
9440 let saved_athena_hive_context = self.athena_hive_context;
9442 if matches!(
9443 self.config.dialect,
9444 Some(crate::dialects::DialectType::Athena)
9445 ) {
9446 self.athena_hive_context = true;
9447 }
9448
9449 self.write_keyword("ALTER TABLE");
9450 if at.if_exists {
9451 self.write_space();
9452 self.write_keyword("IF EXISTS");
9453 }
9454 self.write_space();
9455 self.generate_table(&at.name)?;
9456
9457 if let Some(ref on_cluster) = at.on_cluster {
9459 self.write_space();
9460 self.generate_on_cluster(on_cluster)?;
9461 }
9462
9463 if let Some(ref partition) = at.partition {
9465 self.write_space();
9466 self.write_keyword("PARTITION");
9467 self.write("(");
9468 for (i, (key, value)) in partition.iter().enumerate() {
9469 if i > 0 {
9470 self.write(", ");
9471 }
9472 self.generate_identifier(key)?;
9473 self.write(" = ");
9474 self.generate_expression(value)?;
9475 }
9476 self.write(")");
9477 }
9478
9479 if let Some(ref with_check) = at.with_check {
9481 self.write_space();
9482 self.write_keyword(with_check);
9483 }
9484
9485 if self.config.pretty {
9486 self.write_newline();
9488 self.indent_level += 1;
9489 for (i, action) in at.actions.iter().enumerate() {
9490 let is_continuation = i > 0
9492 && matches!(
9493 (&at.actions[i - 1], action),
9494 (
9495 AlterTableAction::AddColumn { .. },
9496 AlterTableAction::AddColumn { .. }
9497 ) | (
9498 AlterTableAction::AddConstraint(_),
9499 AlterTableAction::AddConstraint(_)
9500 )
9501 );
9502 if i > 0 {
9503 self.write(",");
9504 self.write_newline();
9505 }
9506 self.write_indent();
9507 self.generate_alter_action_with_continuation(action, is_continuation)?;
9508 }
9509 self.indent_level -= 1;
9510 } else {
9511 for (i, action) in at.actions.iter().enumerate() {
9512 let is_continuation = i > 0
9514 && matches!(
9515 (&at.actions[i - 1], action),
9516 (
9517 AlterTableAction::AddColumn { .. },
9518 AlterTableAction::AddColumn { .. }
9519 ) | (
9520 AlterTableAction::AddConstraint(_),
9521 AlterTableAction::AddConstraint(_)
9522 )
9523 );
9524 if i > 0 {
9525 self.write(",");
9526 }
9527 self.write_space();
9528 self.generate_alter_action_with_continuation(action, is_continuation)?;
9529 }
9530 }
9531
9532 if let Some(ref algorithm) = at.algorithm {
9534 self.write(", ");
9535 self.write_keyword("ALGORITHM");
9536 self.write("=");
9537 self.write_keyword(algorithm);
9538 }
9539 if let Some(ref lock) = at.lock {
9540 self.write(", ");
9541 self.write_keyword("LOCK");
9542 self.write("=");
9543 self.write_keyword(lock);
9544 }
9545
9546 self.athena_hive_context = saved_athena_hive_context;
9548
9549 Ok(())
9550 }
9551
9552 fn generate_alter_action_with_continuation(
9553 &mut self,
9554 action: &AlterTableAction,
9555 is_continuation: bool,
9556 ) -> Result<()> {
9557 match action {
9558 AlterTableAction::AddColumn {
9559 column,
9560 if_not_exists,
9561 position,
9562 } => {
9563 use crate::dialects::DialectType;
9564 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
9568 let is_tsql_like = matches!(
9569 self.config.dialect,
9570 Some(DialectType::TSQL) | Some(DialectType::Fabric)
9571 );
9572 let is_athena = matches!(self.config.dialect, Some(DialectType::Athena));
9574
9575 if is_continuation && (is_snowflake || is_tsql_like) {
9576 } else if is_snowflake {
9578 self.write_keyword("ADD");
9579 self.write_space();
9580 } else if is_athena {
9581 self.write_keyword("ADD COLUMNS");
9583 self.write(" (");
9584 } else if self.config.alter_table_include_column_keyword {
9585 self.write_keyword("ADD COLUMN");
9586 self.write_space();
9587 } else {
9588 self.write_keyword("ADD");
9590 self.write_space();
9591 }
9592
9593 if *if_not_exists {
9594 self.write_keyword("IF NOT EXISTS");
9595 self.write_space();
9596 }
9597 self.generate_column_def(column)?;
9598
9599 if is_athena {
9601 self.write(")");
9602 }
9603
9604 if let Some(pos) = position {
9606 self.write_space();
9607 match pos {
9608 ColumnPosition::First => self.write_keyword("FIRST"),
9609 ColumnPosition::After(col_name) => {
9610 self.write_keyword("AFTER");
9611 self.write_space();
9612 self.generate_identifier(col_name)?;
9613 }
9614 }
9615 }
9616 }
9617 AlterTableAction::DropColumn {
9618 name,
9619 if_exists,
9620 cascade,
9621 } => {
9622 self.write_keyword("DROP COLUMN");
9623 if *if_exists {
9624 self.write_space();
9625 self.write_keyword("IF EXISTS");
9626 }
9627 self.write_space();
9628 self.generate_identifier(name)?;
9629 if *cascade {
9630 self.write_space();
9631 self.write_keyword("CASCADE");
9632 }
9633 }
9634 AlterTableAction::DropColumns { names } => {
9635 self.write_keyword("DROP COLUMNS");
9636 self.write(" (");
9637 for (i, name) in names.iter().enumerate() {
9638 if i > 0 {
9639 self.write(", ");
9640 }
9641 self.generate_identifier(name)?;
9642 }
9643 self.write(")");
9644 }
9645 AlterTableAction::RenameColumn {
9646 old_name,
9647 new_name,
9648 if_exists,
9649 } => {
9650 self.write_keyword("RENAME COLUMN");
9651 if *if_exists {
9652 self.write_space();
9653 self.write_keyword("IF EXISTS");
9654 }
9655 self.write_space();
9656 self.generate_identifier(old_name)?;
9657 self.write_space();
9658 self.write_keyword("TO");
9659 self.write_space();
9660 self.generate_identifier(new_name)?;
9661 }
9662 AlterTableAction::AlterColumn {
9663 name,
9664 action,
9665 use_modify_keyword,
9666 } => {
9667 use crate::dialects::DialectType;
9668 let use_modify = *use_modify_keyword
9671 || (matches!(self.config.dialect, Some(DialectType::MySQL))
9672 && matches!(action, AlterColumnAction::SetDataType { .. }));
9673 if use_modify {
9674 self.write_keyword("MODIFY COLUMN");
9675 self.write_space();
9676 self.generate_identifier(name)?;
9677 if let AlterColumnAction::SetDataType {
9679 data_type,
9680 using: _,
9681 collate,
9682 } = action
9683 {
9684 self.write_space();
9685 self.generate_data_type(data_type)?;
9686 if let Some(collate_name) = collate {
9688 self.write_space();
9689 self.write_keyword("COLLATE");
9690 self.write_space();
9691 self.write(&format!("'{}'", collate_name));
9693 }
9694 } else {
9695 self.write_space();
9696 self.generate_alter_column_action(action)?;
9697 }
9698 } else if matches!(self.config.dialect, Some(DialectType::Hive))
9699 && matches!(action, AlterColumnAction::SetDataType { .. })
9700 {
9701 self.write_keyword("CHANGE COLUMN");
9703 self.write_space();
9704 self.generate_identifier(name)?;
9705 self.write_space();
9706 self.generate_identifier(name)?;
9707 if let AlterColumnAction::SetDataType { data_type, .. } = action {
9708 self.write_space();
9709 self.generate_data_type(data_type)?;
9710 }
9711 } else {
9712 self.write_keyword("ALTER COLUMN");
9713 self.write_space();
9714 self.generate_identifier(name)?;
9715 self.write_space();
9716 self.generate_alter_column_action(action)?;
9717 }
9718 }
9719 AlterTableAction::RenameTable(new_name) => {
9720 let mysql_like = matches!(
9722 self.config.dialect,
9723 Some(DialectType::MySQL)
9724 | Some(DialectType::Doris)
9725 | Some(DialectType::StarRocks)
9726 | Some(DialectType::SingleStore)
9727 );
9728 if mysql_like {
9729 self.write_keyword("RENAME");
9730 } else {
9731 self.write_keyword("RENAME TO");
9732 }
9733 self.write_space();
9734 let rename_table_with_db = !matches!(
9736 self.config.dialect,
9737 Some(DialectType::Doris)
9738 | Some(DialectType::DuckDB)
9739 | Some(DialectType::BigQuery)
9740 | Some(DialectType::PostgreSQL)
9741 );
9742 if !rename_table_with_db {
9743 let mut stripped = new_name.clone();
9744 stripped.schema = None;
9745 stripped.catalog = None;
9746 self.generate_table(&stripped)?;
9747 } else {
9748 self.generate_table(new_name)?;
9749 }
9750 }
9751 AlterTableAction::AddConstraint(constraint) => {
9752 if !is_continuation {
9755 self.write_keyword("ADD");
9756 self.write_space();
9757 }
9758 self.generate_table_constraint(constraint)?;
9759 }
9760 AlterTableAction::DropConstraint { name, if_exists } => {
9761 self.write_keyword("DROP CONSTRAINT");
9762 if *if_exists {
9763 self.write_space();
9764 self.write_keyword("IF EXISTS");
9765 }
9766 self.write_space();
9767 self.generate_identifier(name)?;
9768 }
9769 AlterTableAction::DropForeignKey { name } => {
9770 self.write_keyword("DROP FOREIGN KEY");
9771 self.write_space();
9772 self.generate_identifier(name)?;
9773 }
9774 AlterTableAction::DropPartition {
9775 partitions,
9776 if_exists,
9777 } => {
9778 self.write_keyword("DROP");
9779 if *if_exists {
9780 self.write_space();
9781 self.write_keyword("IF EXISTS");
9782 }
9783 for (i, partition) in partitions.iter().enumerate() {
9784 if i > 0 {
9785 self.write(",");
9786 }
9787 self.write_space();
9788 self.write_keyword("PARTITION");
9789 if partition.len() == 1 && partition[0].0.name == "__expr__" {
9791 self.write_space();
9793 self.generate_expression(&partition[0].1)?;
9794 } else if partition.len() == 1 && partition[0].0.name == "ALL" {
9795 self.write_space();
9797 self.write_keyword("ALL");
9798 } else if partition.len() == 1 && partition[0].0.name == "ID" {
9799 self.write_space();
9801 self.write_keyword("ID");
9802 self.write_space();
9803 self.generate_expression(&partition[0].1)?;
9804 } else {
9805 self.write("(");
9807 for (j, (key, value)) in partition.iter().enumerate() {
9808 if j > 0 {
9809 self.write(", ");
9810 }
9811 self.generate_identifier(key)?;
9812 self.write(" = ");
9813 self.generate_expression(value)?;
9814 }
9815 self.write(")");
9816 }
9817 }
9818 }
9819 AlterTableAction::Delete { where_clause } => {
9820 self.write_keyword("DELETE");
9821 self.write_space();
9822 self.write_keyword("WHERE");
9823 self.write_space();
9824 self.generate_expression(where_clause)?;
9825 }
9826 AlterTableAction::SwapWith(target) => {
9827 self.write_keyword("SWAP WITH");
9828 self.write_space();
9829 self.generate_table(target)?;
9830 }
9831 AlterTableAction::SetProperty { properties } => {
9832 use crate::dialects::DialectType;
9833 self.write_keyword("SET");
9834 let is_trino_presto = matches!(
9836 self.config.dialect,
9837 Some(DialectType::Trino) | Some(DialectType::Presto)
9838 );
9839 if is_trino_presto {
9840 self.write_space();
9841 self.write_keyword("PROPERTIES");
9842 }
9843 let eq = if is_trino_presto { " = " } else { "=" };
9844 for (i, (key, value)) in properties.iter().enumerate() {
9845 if i > 0 {
9846 self.write(",");
9847 }
9848 self.write_space();
9849 if key.contains(' ') {
9851 self.generate_string_literal(key)?;
9852 } else {
9853 self.write(key);
9854 }
9855 self.write(eq);
9856 self.generate_expression(value)?;
9857 }
9858 }
9859 AlterTableAction::UnsetProperty { properties } => {
9860 self.write_keyword("UNSET");
9861 for (i, name) in properties.iter().enumerate() {
9862 if i > 0 {
9863 self.write(",");
9864 }
9865 self.write_space();
9866 self.write(name);
9867 }
9868 }
9869 AlterTableAction::ClusterBy { expressions } => {
9870 self.write_keyword("CLUSTER BY");
9871 self.write(" (");
9872 for (i, expr) in expressions.iter().enumerate() {
9873 if i > 0 {
9874 self.write(", ");
9875 }
9876 self.generate_expression(expr)?;
9877 }
9878 self.write(")");
9879 }
9880 AlterTableAction::SetTag { expressions } => {
9881 self.write_keyword("SET TAG");
9882 for (i, (key, value)) in expressions.iter().enumerate() {
9883 if i > 0 {
9884 self.write(",");
9885 }
9886 self.write_space();
9887 self.write(key);
9888 self.write(" = ");
9889 self.generate_expression(value)?;
9890 }
9891 }
9892 AlterTableAction::UnsetTag { names } => {
9893 self.write_keyword("UNSET TAG");
9894 for (i, name) in names.iter().enumerate() {
9895 if i > 0 {
9896 self.write(",");
9897 }
9898 self.write_space();
9899 self.write(name);
9900 }
9901 }
9902 AlterTableAction::SetOptions { expressions } => {
9903 self.write_keyword("SET");
9904 self.write(" (");
9905 for (i, expr) in expressions.iter().enumerate() {
9906 if i > 0 {
9907 self.write(", ");
9908 }
9909 self.generate_expression(expr)?;
9910 }
9911 self.write(")");
9912 }
9913 AlterTableAction::AlterIndex { name, visible } => {
9914 self.write_keyword("ALTER INDEX");
9915 self.write_space();
9916 self.generate_identifier(name)?;
9917 self.write_space();
9918 if *visible {
9919 self.write_keyword("VISIBLE");
9920 } else {
9921 self.write_keyword("INVISIBLE");
9922 }
9923 }
9924 AlterTableAction::SetAttribute { attribute } => {
9925 self.write_keyword("SET");
9926 self.write_space();
9927 self.write_keyword(attribute);
9928 }
9929 AlterTableAction::SetStageFileFormat { options } => {
9930 self.write_keyword("SET");
9931 self.write_space();
9932 self.write_keyword("STAGE_FILE_FORMAT");
9933 self.write(" = (");
9934 if let Some(opts) = options {
9935 self.generate_space_separated_properties(opts)?;
9936 }
9937 self.write(")");
9938 }
9939 AlterTableAction::SetStageCopyOptions { options } => {
9940 self.write_keyword("SET");
9941 self.write_space();
9942 self.write_keyword("STAGE_COPY_OPTIONS");
9943 self.write(" = (");
9944 if let Some(opts) = options {
9945 self.generate_space_separated_properties(opts)?;
9946 }
9947 self.write(")");
9948 }
9949 AlterTableAction::AddColumns { columns, cascade } => {
9950 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
9953 if is_oracle {
9954 self.write_keyword("ADD");
9955 } else {
9956 self.write_keyword("ADD COLUMNS");
9957 }
9958 self.write(" (");
9959 for (i, col) in columns.iter().enumerate() {
9960 if i > 0 {
9961 self.write(", ");
9962 }
9963 self.generate_column_def(col)?;
9964 }
9965 self.write(")");
9966 if *cascade {
9967 self.write_space();
9968 self.write_keyword("CASCADE");
9969 }
9970 }
9971 AlterTableAction::ChangeColumn {
9972 old_name,
9973 new_name,
9974 data_type,
9975 comment,
9976 cascade,
9977 } => {
9978 use crate::dialects::DialectType;
9979 let is_spark = matches!(
9980 self.config.dialect,
9981 Some(DialectType::Spark) | Some(DialectType::Databricks)
9982 );
9983 let is_rename = old_name.name != new_name.name;
9984
9985 if is_spark {
9986 if is_rename {
9987 self.write_keyword("RENAME COLUMN");
9989 self.write_space();
9990 self.generate_identifier(old_name)?;
9991 self.write_space();
9992 self.write_keyword("TO");
9993 self.write_space();
9994 self.generate_identifier(new_name)?;
9995 } else if comment.is_some() {
9996 self.write_keyword("ALTER COLUMN");
9998 self.write_space();
9999 self.generate_identifier(old_name)?;
10000 self.write_space();
10001 self.write_keyword("COMMENT");
10002 self.write_space();
10003 self.write("'");
10004 self.write(comment.as_ref().unwrap());
10005 self.write("'");
10006 } else if data_type.is_some() {
10007 self.write_keyword("ALTER COLUMN");
10009 self.write_space();
10010 self.generate_identifier(old_name)?;
10011 self.write_space();
10012 self.write_keyword("TYPE");
10013 self.write_space();
10014 self.generate_data_type(data_type.as_ref().unwrap())?;
10015 } else {
10016 self.write_keyword("CHANGE COLUMN");
10018 self.write_space();
10019 self.generate_identifier(old_name)?;
10020 self.write_space();
10021 self.generate_identifier(new_name)?;
10022 }
10023 } else {
10024 if data_type.is_some() {
10026 self.write_keyword("CHANGE COLUMN");
10027 } else {
10028 self.write_keyword("CHANGE");
10029 }
10030 self.write_space();
10031 self.generate_identifier(old_name)?;
10032 self.write_space();
10033 self.generate_identifier(new_name)?;
10034 if let Some(ref dt) = data_type {
10035 self.write_space();
10036 self.generate_data_type(dt)?;
10037 }
10038 if let Some(ref c) = comment {
10039 self.write_space();
10040 self.write_keyword("COMMENT");
10041 self.write_space();
10042 self.write("'");
10043 self.write(c);
10044 self.write("'");
10045 }
10046 if *cascade {
10047 self.write_space();
10048 self.write_keyword("CASCADE");
10049 }
10050 }
10051 }
10052 AlterTableAction::AddPartition {
10053 partition,
10054 if_not_exists,
10055 location,
10056 } => {
10057 self.write_keyword("ADD");
10058 self.write_space();
10059 if *if_not_exists {
10060 self.write_keyword("IF NOT EXISTS");
10061 self.write_space();
10062 }
10063 self.generate_expression(partition)?;
10064 if let Some(ref loc) = location {
10065 self.write_space();
10066 self.write_keyword("LOCATION");
10067 self.write_space();
10068 self.generate_expression(loc)?;
10069 }
10070 }
10071 AlterTableAction::AlterSortKey {
10072 this,
10073 expressions,
10074 compound,
10075 } => {
10076 self.write_keyword("ALTER");
10078 if *compound {
10079 self.write_space();
10080 self.write_keyword("COMPOUND");
10081 }
10082 self.write_space();
10083 self.write_keyword("SORTKEY");
10084 self.write_space();
10085 if let Some(style) = this {
10086 self.write_keyword(style);
10087 } else if !expressions.is_empty() {
10088 self.write("(");
10089 for (i, expr) in expressions.iter().enumerate() {
10090 if i > 0 {
10091 self.write(", ");
10092 }
10093 self.generate_expression(expr)?;
10094 }
10095 self.write(")");
10096 }
10097 }
10098 AlterTableAction::AlterDistStyle { style, distkey } => {
10099 self.write_keyword("ALTER");
10101 self.write_space();
10102 self.write_keyword("DISTSTYLE");
10103 self.write_space();
10104 self.write_keyword(style);
10105 if let Some(col) = distkey {
10106 self.write_space();
10107 self.write_keyword("DISTKEY");
10108 self.write_space();
10109 self.generate_identifier(col)?;
10110 }
10111 }
10112 AlterTableAction::SetTableProperties { properties } => {
10113 self.write_keyword("SET TABLE PROPERTIES");
10115 self.write(" (");
10116 for (i, (key, value)) in properties.iter().enumerate() {
10117 if i > 0 {
10118 self.write(", ");
10119 }
10120 self.generate_expression(key)?;
10121 self.write(" = ");
10122 self.generate_expression(value)?;
10123 }
10124 self.write(")");
10125 }
10126 AlterTableAction::SetLocation { location } => {
10127 self.write_keyword("SET LOCATION");
10129 self.write_space();
10130 self.write("'");
10131 self.write(location);
10132 self.write("'");
10133 }
10134 AlterTableAction::SetFileFormat { format } => {
10135 self.write_keyword("SET FILE FORMAT");
10137 self.write_space();
10138 self.write_keyword(format);
10139 }
10140 AlterTableAction::ReplacePartition { partition, source } => {
10141 self.write_keyword("REPLACE PARTITION");
10143 self.write_space();
10144 self.generate_expression(partition)?;
10145 if let Some(src) = source {
10146 self.write_space();
10147 self.write_keyword("FROM");
10148 self.write_space();
10149 self.generate_expression(src)?;
10150 }
10151 }
10152 AlterTableAction::Raw { sql } => {
10153 self.write(sql);
10154 }
10155 }
10156 Ok(())
10157 }
10158
10159 fn generate_alter_column_action(&mut self, action: &AlterColumnAction) -> Result<()> {
10160 match action {
10161 AlterColumnAction::SetDataType {
10162 data_type,
10163 using,
10164 collate,
10165 } => {
10166 use crate::dialects::DialectType;
10167 let is_no_prefix = matches!(
10172 self.config.dialect,
10173 Some(DialectType::TSQL) | Some(DialectType::Fabric) | Some(DialectType::Hive)
10174 );
10175 let is_type_only = matches!(
10176 self.config.dialect,
10177 Some(DialectType::Redshift)
10178 | Some(DialectType::Spark)
10179 | Some(DialectType::Databricks)
10180 );
10181 if is_type_only {
10182 self.write_keyword("TYPE");
10183 self.write_space();
10184 } else if !is_no_prefix {
10185 self.write_keyword("SET DATA TYPE");
10186 self.write_space();
10187 }
10188 self.generate_data_type(data_type)?;
10189 if let Some(ref collation) = collate {
10190 self.write_space();
10191 self.write_keyword("COLLATE");
10192 self.write_space();
10193 self.write(collation);
10194 }
10195 if let Some(ref using_expr) = using {
10196 self.write_space();
10197 self.write_keyword("USING");
10198 self.write_space();
10199 self.generate_expression(using_expr)?;
10200 }
10201 }
10202 AlterColumnAction::SetDefault(expr) => {
10203 self.write_keyword("SET DEFAULT");
10204 self.write_space();
10205 self.generate_expression(expr)?;
10206 }
10207 AlterColumnAction::DropDefault => {
10208 self.write_keyword("DROP DEFAULT");
10209 }
10210 AlterColumnAction::SetNotNull => {
10211 self.write_keyword("SET NOT NULL");
10212 }
10213 AlterColumnAction::DropNotNull => {
10214 self.write_keyword("DROP NOT NULL");
10215 }
10216 AlterColumnAction::Comment(comment) => {
10217 self.write_keyword("COMMENT");
10218 self.write_space();
10219 self.generate_string_literal(comment)?;
10220 }
10221 AlterColumnAction::SetVisible => {
10222 self.write_keyword("SET VISIBLE");
10223 }
10224 AlterColumnAction::SetInvisible => {
10225 self.write_keyword("SET INVISIBLE");
10226 }
10227 }
10228 Ok(())
10229 }
10230
10231 fn generate_create_index(&mut self, ci: &CreateIndex) -> Result<()> {
10232 self.write_keyword("CREATE");
10233
10234 if ci.unique {
10235 self.write_space();
10236 self.write_keyword("UNIQUE");
10237 }
10238
10239 if let Some(ref clustered) = ci.clustered {
10241 self.write_space();
10242 self.write_keyword(clustered);
10243 }
10244
10245 self.write_space();
10246 self.write_keyword("INDEX");
10247
10248 if ci.concurrently {
10250 self.write_space();
10251 self.write_keyword("CONCURRENTLY");
10252 }
10253
10254 if ci.if_not_exists {
10255 self.write_space();
10256 self.write_keyword("IF NOT EXISTS");
10257 }
10258
10259 if !ci.name.name.is_empty() {
10261 self.write_space();
10262 self.generate_identifier(&ci.name)?;
10263 }
10264 self.write_space();
10265 self.write_keyword("ON");
10266 if matches!(self.config.dialect, Some(DialectType::Hive)) {
10268 self.write_space();
10269 self.write_keyword("TABLE");
10270 }
10271 self.write_space();
10272 self.generate_table(&ci.table)?;
10273
10274 if !ci.columns.is_empty() || ci.using.is_some() {
10277 let space_before_paren = false;
10278
10279 if let Some(ref using) = ci.using {
10280 self.write_space();
10281 self.write_keyword("USING");
10282 self.write_space();
10283 self.write(using);
10284 if space_before_paren {
10285 self.write(" (");
10286 } else {
10287 self.write("(");
10288 }
10289 } else {
10290 if space_before_paren {
10291 self.write(" (");
10292 } else {
10293 self.write("(");
10294 }
10295 }
10296 for (i, col) in ci.columns.iter().enumerate() {
10297 if i > 0 {
10298 self.write(", ");
10299 }
10300 self.generate_identifier(&col.column)?;
10301 if let Some(ref opclass) = col.opclass {
10302 self.write_space();
10303 self.write(opclass);
10304 }
10305 if col.desc {
10306 self.write_space();
10307 self.write_keyword("DESC");
10308 } else if col.asc {
10309 self.write_space();
10310 self.write_keyword("ASC");
10311 }
10312 if let Some(nulls_first) = col.nulls_first {
10313 self.write_space();
10314 self.write_keyword("NULLS");
10315 self.write_space();
10316 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
10317 }
10318 }
10319 self.write(")");
10320 }
10321
10322 if !ci.include_columns.is_empty() {
10324 self.write_space();
10325 self.write_keyword("INCLUDE");
10326 self.write(" (");
10327 for (i, col) in ci.include_columns.iter().enumerate() {
10328 if i > 0 {
10329 self.write(", ");
10330 }
10331 self.generate_identifier(col)?;
10332 }
10333 self.write(")");
10334 }
10335
10336 if !ci.with_options.is_empty() {
10338 self.write_space();
10339 self.write_keyword("WITH");
10340 self.write(" (");
10341 for (i, (key, value)) in ci.with_options.iter().enumerate() {
10342 if i > 0 {
10343 self.write(", ");
10344 }
10345 self.write(key);
10346 self.write("=");
10347 self.write(value);
10348 }
10349 self.write(")");
10350 }
10351
10352 if let Some(ref where_clause) = ci.where_clause {
10354 self.write_space();
10355 self.write_keyword("WHERE");
10356 self.write_space();
10357 self.generate_expression(where_clause)?;
10358 }
10359
10360 if let Some(ref on_fg) = ci.on_filegroup {
10362 self.write_space();
10363 self.write_keyword("ON");
10364 self.write_space();
10365 self.write(on_fg);
10366 }
10367
10368 Ok(())
10369 }
10370
10371 fn generate_drop_index(&mut self, di: &DropIndex) -> Result<()> {
10372 self.write_keyword("DROP INDEX");
10373
10374 if di.concurrently {
10375 self.write_space();
10376 self.write_keyword("CONCURRENTLY");
10377 }
10378
10379 if di.if_exists {
10380 self.write_space();
10381 self.write_keyword("IF EXISTS");
10382 }
10383
10384 self.write_space();
10385 self.generate_identifier(&di.name)?;
10386
10387 if let Some(ref table) = di.table {
10388 self.write_space();
10389 self.write_keyword("ON");
10390 self.write_space();
10391 self.generate_table(table)?;
10392 }
10393
10394 Ok(())
10395 }
10396
10397 fn generate_create_view(&mut self, cv: &CreateView) -> Result<()> {
10398 self.write_keyword("CREATE");
10399
10400 if let Some(ref algorithm) = cv.algorithm {
10402 self.write_space();
10403 self.write_keyword("ALGORITHM");
10404 self.write("=");
10405 self.write_keyword(algorithm);
10406 }
10407
10408 if let Some(ref definer) = cv.definer {
10410 self.write_space();
10411 self.write_keyword("DEFINER");
10412 self.write("=");
10413 self.write(definer);
10414 }
10415
10416 if cv.security_sql_style {
10418 if let Some(ref security) = cv.security {
10419 self.write_space();
10420 self.write_keyword("SQL SECURITY");
10421 self.write_space();
10422 match security {
10423 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
10424 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
10425 FunctionSecurity::None => self.write_keyword("NONE"),
10426 }
10427 }
10428 }
10429
10430 if cv.or_replace {
10431 self.write_space();
10432 self.write_keyword("OR REPLACE");
10433 }
10434
10435 if cv.temporary {
10436 self.write_space();
10437 self.write_keyword("TEMPORARY");
10438 }
10439
10440 if cv.materialized {
10441 self.write_space();
10442 self.write_keyword("MATERIALIZED");
10443 }
10444
10445 if cv.secure {
10447 self.write_space();
10448 self.write_keyword("SECURE");
10449 }
10450
10451 self.write_space();
10452 self.write_keyword("VIEW");
10453
10454 if cv.if_not_exists {
10455 self.write_space();
10456 self.write_keyword("IF NOT EXISTS");
10457 }
10458
10459 self.write_space();
10460 self.generate_table(&cv.name)?;
10461
10462 if let Some(ref on_cluster) = cv.on_cluster {
10464 self.write_space();
10465 self.generate_on_cluster(on_cluster)?;
10466 }
10467
10468 if let Some(ref to_table) = cv.to_table {
10470 self.write_space();
10471 self.write_keyword("TO");
10472 self.write_space();
10473 self.generate_table(to_table)?;
10474 }
10475
10476 if !cv.materialized {
10479 if !cv.columns.is_empty() {
10481 self.write(" (");
10482 for (i, col) in cv.columns.iter().enumerate() {
10483 if i > 0 {
10484 self.write(", ");
10485 }
10486 self.generate_identifier(&col.name)?;
10487 if !col.options.is_empty() {
10489 self.write_space();
10490 self.generate_options_clause(&col.options)?;
10491 }
10492 if let Some(ref comment) = col.comment {
10493 self.write_space();
10494 self.write_keyword("COMMENT");
10495 self.write_space();
10496 self.generate_string_literal(comment)?;
10497 }
10498 }
10499 self.write(")");
10500 }
10501
10502 if !cv.security_sql_style {
10504 if let Some(ref security) = cv.security {
10505 self.write_space();
10506 self.write_keyword("SECURITY");
10507 self.write_space();
10508 match security {
10509 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
10510 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
10511 FunctionSecurity::None => self.write_keyword("NONE"),
10512 }
10513 }
10514 }
10515
10516 if cv.copy_grants {
10518 self.write_space();
10519 self.write_keyword("COPY GRANTS");
10520 }
10521 } else {
10522 if cv.copy_grants {
10524 self.write_space();
10525 self.write_keyword("COPY GRANTS");
10526 }
10527
10528 if let Some(ref schema) = cv.schema {
10530 self.write(" (");
10531 for (i, expr) in schema.expressions.iter().enumerate() {
10532 if i > 0 {
10533 self.write(", ");
10534 }
10535 self.generate_expression(expr)?;
10536 }
10537 self.write(")");
10538 } else if !cv.columns.is_empty() {
10539 self.write(" (");
10541 for (i, col) in cv.columns.iter().enumerate() {
10542 if i > 0 {
10543 self.write(", ");
10544 }
10545 self.generate_identifier(&col.name)?;
10546 if !col.options.is_empty() {
10548 self.write_space();
10549 self.generate_options_clause(&col.options)?;
10550 }
10551 if let Some(ref comment) = col.comment {
10552 self.write_space();
10553 self.write_keyword("COMMENT");
10554 self.write_space();
10555 self.generate_string_literal(comment)?;
10556 }
10557 }
10558 self.write(")");
10559 }
10560
10561 if let Some(ref unique_key) = cv.unique_key {
10563 self.write_space();
10564 self.write_keyword("KEY");
10565 self.write(" (");
10566 for (i, expr) in unique_key.expressions.iter().enumerate() {
10567 if i > 0 {
10568 self.write(", ");
10569 }
10570 self.generate_expression(expr)?;
10571 }
10572 self.write(")");
10573 }
10574 }
10575
10576 if let Some(ref comment) = cv.comment {
10578 self.write_space();
10579 self.write_keyword("COMMENT");
10580 self.write("=");
10581 self.generate_string_literal(comment)?;
10582 }
10583
10584 if !cv.tags.is_empty() {
10586 self.write_space();
10587 self.write_keyword("TAG");
10588 self.write(" (");
10589 for (i, (name, value)) in cv.tags.iter().enumerate() {
10590 if i > 0 {
10591 self.write(", ");
10592 }
10593 self.write(name);
10594 self.write("='");
10595 self.write(value);
10596 self.write("'");
10597 }
10598 self.write(")");
10599 }
10600
10601 if !cv.options.is_empty() {
10603 self.write_space();
10604 self.generate_options_clause(&cv.options)?;
10605 }
10606
10607 if let Some(ref build) = cv.build {
10609 self.write_space();
10610 self.write_keyword("BUILD");
10611 self.write_space();
10612 self.write_keyword(build);
10613 }
10614
10615 if let Some(ref refresh) = cv.refresh {
10617 self.write_space();
10618 self.generate_refresh_trigger_property(refresh)?;
10619 }
10620
10621 if let Some(auto_refresh) = cv.auto_refresh {
10623 self.write_space();
10624 self.write_keyword("AUTO REFRESH");
10625 self.write_space();
10626 if auto_refresh {
10627 self.write_keyword("YES");
10628 } else {
10629 self.write_keyword("NO");
10630 }
10631 }
10632
10633 for prop in &cv.table_properties {
10635 self.write_space();
10636 self.generate_expression(prop)?;
10637 }
10638
10639 if !matches!(&cv.query, Expression::Null(_)) {
10641 self.write_space();
10642 self.write_keyword("AS");
10643 self.write_space();
10644
10645 if let Some(ref mode) = cv.locking_mode {
10647 self.write_keyword("LOCKING");
10648 self.write_space();
10649 self.write_keyword(mode);
10650 if let Some(ref access) = cv.locking_access {
10651 self.write_space();
10652 self.write_keyword("FOR");
10653 self.write_space();
10654 self.write_keyword(access);
10655 }
10656 self.write_space();
10657 }
10658
10659 if cv.query_parenthesized {
10660 self.write("(");
10661 }
10662 self.generate_expression(&cv.query)?;
10663 if cv.query_parenthesized {
10664 self.write(")");
10665 }
10666 }
10667
10668 if cv.no_schema_binding {
10670 self.write_space();
10671 self.write_keyword("WITH NO SCHEMA BINDING");
10672 }
10673
10674 Ok(())
10675 }
10676
10677 fn generate_drop_view(&mut self, dv: &DropView) -> Result<()> {
10678 self.write_keyword("DROP");
10679
10680 if dv.materialized {
10681 self.write_space();
10682 self.write_keyword("MATERIALIZED");
10683 }
10684
10685 self.write_space();
10686 self.write_keyword("VIEW");
10687
10688 if dv.if_exists {
10689 self.write_space();
10690 self.write_keyword("IF EXISTS");
10691 }
10692
10693 self.write_space();
10694 self.generate_table(&dv.name)?;
10695
10696 Ok(())
10697 }
10698
10699 fn generate_truncate(&mut self, tr: &Truncate) -> Result<()> {
10700 match tr.target {
10701 TruncateTarget::Database => self.write_keyword("TRUNCATE DATABASE"),
10702 TruncateTarget::Table => self.write_keyword("TRUNCATE TABLE"),
10703 }
10704 if tr.if_exists {
10705 self.write_space();
10706 self.write_keyword("IF EXISTS");
10707 }
10708 self.write_space();
10709 self.generate_table(&tr.table)?;
10710
10711 if let Some(ref on_cluster) = tr.on_cluster {
10713 self.write_space();
10714 self.generate_on_cluster(on_cluster)?;
10715 }
10716
10717 if !tr.extra_tables.is_empty() {
10719 let skip_first = if let Some(first) = tr.extra_tables.first() {
10721 first.table.name == tr.table.name && first.star
10722 } else {
10723 false
10724 };
10725
10726 let strip_star = matches!(
10728 self.config.dialect,
10729 Some(crate::dialects::DialectType::PostgreSQL)
10730 | Some(crate::dialects::DialectType::Redshift)
10731 );
10732 if skip_first && !strip_star {
10733 self.write("*");
10734 }
10735
10736 for (i, entry) in tr.extra_tables.iter().enumerate() {
10738 if i == 0 && skip_first {
10739 continue; }
10741 self.write(", ");
10742 self.generate_table(&entry.table)?;
10743 if entry.star && !strip_star {
10744 self.write("*");
10745 }
10746 }
10747 }
10748
10749 if let Some(identity) = &tr.identity {
10751 self.write_space();
10752 match identity {
10753 TruncateIdentity::Restart => self.write_keyword("RESTART IDENTITY"),
10754 TruncateIdentity::Continue => self.write_keyword("CONTINUE IDENTITY"),
10755 }
10756 }
10757
10758 if tr.cascade {
10759 self.write_space();
10760 self.write_keyword("CASCADE");
10761 }
10762
10763 if tr.restrict {
10764 self.write_space();
10765 self.write_keyword("RESTRICT");
10766 }
10767
10768 if let Some(ref partition) = tr.partition {
10770 self.write_space();
10771 self.generate_expression(partition)?;
10772 }
10773
10774 Ok(())
10775 }
10776
10777 fn generate_use(&mut self, u: &Use) -> Result<()> {
10778 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
10780 self.write_keyword("DATABASE");
10781 self.write_space();
10782 self.generate_identifier(&u.this)?;
10783 return Ok(());
10784 }
10785
10786 self.write_keyword("USE");
10787
10788 if let Some(kind) = &u.kind {
10789 self.write_space();
10790 match kind {
10791 UseKind::Database => self.write_keyword("DATABASE"),
10792 UseKind::Schema => self.write_keyword("SCHEMA"),
10793 UseKind::Role => self.write_keyword("ROLE"),
10794 UseKind::Warehouse => self.write_keyword("WAREHOUSE"),
10795 UseKind::Catalog => self.write_keyword("CATALOG"),
10796 UseKind::SecondaryRoles => self.write_keyword("SECONDARY ROLES"),
10797 }
10798 }
10799
10800 self.write_space();
10801 if matches!(&u.kind, Some(UseKind::SecondaryRoles)) {
10804 self.write(&u.this.name);
10805 } else {
10806 self.generate_identifier(&u.this)?;
10807 }
10808 Ok(())
10809 }
10810
10811 fn generate_cache(&mut self, c: &Cache) -> Result<()> {
10812 self.write_keyword("CACHE");
10813 if c.lazy {
10814 self.write_space();
10815 self.write_keyword("LAZY");
10816 }
10817 self.write_space();
10818 self.write_keyword("TABLE");
10819 self.write_space();
10820 self.generate_identifier(&c.table)?;
10821
10822 if !c.options.is_empty() {
10824 self.write_space();
10825 self.write_keyword("OPTIONS");
10826 self.write("(");
10827 for (i, (key, value)) in c.options.iter().enumerate() {
10828 if i > 0 {
10829 self.write(", ");
10830 }
10831 self.generate_expression(key)?;
10832 self.write(" = ");
10833 self.generate_expression(value)?;
10834 }
10835 self.write(")");
10836 }
10837
10838 if let Some(query) = &c.query {
10840 self.write_space();
10841 self.write_keyword("AS");
10842 self.write_space();
10843 self.generate_expression(query)?;
10844 }
10845
10846 Ok(())
10847 }
10848
10849 fn generate_uncache(&mut self, u: &Uncache) -> Result<()> {
10850 self.write_keyword("UNCACHE TABLE");
10851 if u.if_exists {
10852 self.write_space();
10853 self.write_keyword("IF EXISTS");
10854 }
10855 self.write_space();
10856 self.generate_identifier(&u.table)?;
10857 Ok(())
10858 }
10859
10860 fn generate_load_data(&mut self, l: &LoadData) -> Result<()> {
10861 self.write_keyword("LOAD DATA");
10862 if l.local {
10863 self.write_space();
10864 self.write_keyword("LOCAL");
10865 }
10866 self.write_space();
10867 self.write_keyword("INPATH");
10868 self.write_space();
10869 self.write("'");
10870 self.write(&l.inpath);
10871 self.write("'");
10872
10873 if l.overwrite {
10874 self.write_space();
10875 self.write_keyword("OVERWRITE");
10876 }
10877
10878 self.write_space();
10879 self.write_keyword("INTO TABLE");
10880 self.write_space();
10881 self.generate_expression(&l.table)?;
10882
10883 if !l.partition.is_empty() {
10885 self.write_space();
10886 self.write_keyword("PARTITION");
10887 self.write("(");
10888 for (i, (col, val)) in l.partition.iter().enumerate() {
10889 if i > 0 {
10890 self.write(", ");
10891 }
10892 self.generate_identifier(col)?;
10893 self.write(" = ");
10894 self.generate_expression(val)?;
10895 }
10896 self.write(")");
10897 }
10898
10899 if let Some(fmt) = &l.input_format {
10901 self.write_space();
10902 self.write_keyword("INPUTFORMAT");
10903 self.write_space();
10904 self.write("'");
10905 self.write(fmt);
10906 self.write("'");
10907 }
10908
10909 if let Some(serde) = &l.serde {
10911 self.write_space();
10912 self.write_keyword("SERDE");
10913 self.write_space();
10914 self.write("'");
10915 self.write(serde);
10916 self.write("'");
10917 }
10918
10919 Ok(())
10920 }
10921
10922 fn generate_pragma(&mut self, p: &Pragma) -> Result<()> {
10923 self.write_keyword("PRAGMA");
10924 self.write_space();
10925
10926 if let Some(schema) = &p.schema {
10928 self.generate_identifier(schema)?;
10929 self.write(".");
10930 }
10931
10932 self.generate_identifier(&p.name)?;
10934
10935 if let Some(value) = &p.value {
10937 self.write(" = ");
10938 self.generate_expression(value)?;
10939 } else if !p.args.is_empty() {
10940 self.write("(");
10941 for (i, arg) in p.args.iter().enumerate() {
10942 if i > 0 {
10943 self.write(", ");
10944 }
10945 self.generate_expression(arg)?;
10946 }
10947 self.write(")");
10948 }
10949
10950 Ok(())
10951 }
10952
10953 fn generate_grant(&mut self, g: &Grant) -> Result<()> {
10954 self.write_keyword("GRANT");
10955 self.write_space();
10956
10957 for (i, privilege) in g.privileges.iter().enumerate() {
10959 if i > 0 {
10960 self.write(", ");
10961 }
10962 self.write_keyword(&privilege.name);
10963 if !privilege.columns.is_empty() {
10965 self.write("(");
10966 for (j, col) in privilege.columns.iter().enumerate() {
10967 if j > 0 {
10968 self.write(", ");
10969 }
10970 self.write(col);
10971 }
10972 self.write(")");
10973 }
10974 }
10975
10976 self.write_space();
10977 self.write_keyword("ON");
10978 self.write_space();
10979
10980 if let Some(kind) = &g.kind {
10982 self.write_keyword(kind);
10983 self.write_space();
10984 }
10985
10986 {
10988 use crate::dialects::DialectType;
10989 let should_upper = matches!(
10990 self.config.dialect,
10991 Some(DialectType::PostgreSQL)
10992 | Some(DialectType::CockroachDB)
10993 | Some(DialectType::Materialize)
10994 | Some(DialectType::RisingWave)
10995 ) && (g.kind.as_deref() == Some("FUNCTION")
10996 || g.kind.as_deref() == Some("PROCEDURE"));
10997 if should_upper {
10998 use crate::expressions::Identifier;
10999 let upper_id = Identifier {
11000 name: g.securable.name.to_uppercase(),
11001 quoted: g.securable.quoted,
11002 ..g.securable.clone()
11003 };
11004 self.generate_identifier(&upper_id)?;
11005 } else {
11006 self.generate_identifier(&g.securable)?;
11007 }
11008 }
11009
11010 if !g.function_params.is_empty() {
11012 self.write("(");
11013 for (i, param) in g.function_params.iter().enumerate() {
11014 if i > 0 {
11015 self.write(", ");
11016 }
11017 self.write(param);
11018 }
11019 self.write(")");
11020 }
11021
11022 self.write_space();
11023 self.write_keyword("TO");
11024 self.write_space();
11025
11026 for (i, principal) in g.principals.iter().enumerate() {
11028 if i > 0 {
11029 self.write(", ");
11030 }
11031 if principal.is_role {
11032 self.write_keyword("ROLE");
11033 self.write_space();
11034 } else if principal.is_group {
11035 self.write_keyword("GROUP");
11036 self.write_space();
11037 }
11038 self.generate_identifier(&principal.name)?;
11039 }
11040
11041 if g.grant_option {
11043 self.write_space();
11044 self.write_keyword("WITH GRANT OPTION");
11045 }
11046
11047 if let Some(ref principal) = g.as_principal {
11049 self.write_space();
11050 self.write_keyword("AS");
11051 self.write_space();
11052 self.generate_identifier(principal)?;
11053 }
11054
11055 Ok(())
11056 }
11057
11058 fn generate_revoke(&mut self, r: &Revoke) -> Result<()> {
11059 self.write_keyword("REVOKE");
11060 self.write_space();
11061
11062 if r.grant_option {
11064 self.write_keyword("GRANT OPTION FOR");
11065 self.write_space();
11066 }
11067
11068 for (i, privilege) in r.privileges.iter().enumerate() {
11070 if i > 0 {
11071 self.write(", ");
11072 }
11073 self.write_keyword(&privilege.name);
11074 if !privilege.columns.is_empty() {
11076 self.write("(");
11077 for (j, col) in privilege.columns.iter().enumerate() {
11078 if j > 0 {
11079 self.write(", ");
11080 }
11081 self.write(col);
11082 }
11083 self.write(")");
11084 }
11085 }
11086
11087 self.write_space();
11088 self.write_keyword("ON");
11089 self.write_space();
11090
11091 if let Some(kind) = &r.kind {
11093 self.write_keyword(kind);
11094 self.write_space();
11095 }
11096
11097 {
11099 use crate::dialects::DialectType;
11100 let should_upper = matches!(
11101 self.config.dialect,
11102 Some(DialectType::PostgreSQL)
11103 | Some(DialectType::CockroachDB)
11104 | Some(DialectType::Materialize)
11105 | Some(DialectType::RisingWave)
11106 ) && (r.kind.as_deref() == Some("FUNCTION")
11107 || r.kind.as_deref() == Some("PROCEDURE"));
11108 if should_upper {
11109 use crate::expressions::Identifier;
11110 let upper_id = Identifier {
11111 name: r.securable.name.to_uppercase(),
11112 quoted: r.securable.quoted,
11113 ..r.securable.clone()
11114 };
11115 self.generate_identifier(&upper_id)?;
11116 } else {
11117 self.generate_identifier(&r.securable)?;
11118 }
11119 }
11120
11121 if !r.function_params.is_empty() {
11123 self.write("(");
11124 for (i, param) in r.function_params.iter().enumerate() {
11125 if i > 0 {
11126 self.write(", ");
11127 }
11128 self.write(param);
11129 }
11130 self.write(")");
11131 }
11132
11133 self.write_space();
11134 self.write_keyword("FROM");
11135 self.write_space();
11136
11137 for (i, principal) in r.principals.iter().enumerate() {
11139 if i > 0 {
11140 self.write(", ");
11141 }
11142 if principal.is_role {
11143 self.write_keyword("ROLE");
11144 self.write_space();
11145 } else if principal.is_group {
11146 self.write_keyword("GROUP");
11147 self.write_space();
11148 }
11149 self.generate_identifier(&principal.name)?;
11150 }
11151
11152 if r.cascade {
11154 self.write_space();
11155 self.write_keyword("CASCADE");
11156 } else if r.restrict {
11157 self.write_space();
11158 self.write_keyword("RESTRICT");
11159 }
11160
11161 Ok(())
11162 }
11163
11164 fn generate_comment(&mut self, c: &Comment) -> Result<()> {
11165 self.write_keyword("COMMENT");
11166
11167 if c.exists {
11169 self.write_space();
11170 self.write_keyword("IF EXISTS");
11171 }
11172
11173 self.write_space();
11174 self.write_keyword("ON");
11175
11176 if c.materialized {
11178 self.write_space();
11179 self.write_keyword("MATERIALIZED");
11180 }
11181
11182 self.write_space();
11183 self.write_keyword(&c.kind);
11184 self.write_space();
11185
11186 self.generate_expression(&c.this)?;
11188
11189 self.write_space();
11190 self.write_keyword("IS");
11191 self.write_space();
11192
11193 self.generate_expression(&c.expression)?;
11195
11196 Ok(())
11197 }
11198
11199 fn generate_set_statement(&mut self, s: &SetStatement) -> Result<()> {
11200 self.write_keyword("SET");
11201
11202 for (i, item) in s.items.iter().enumerate() {
11203 if i > 0 {
11204 self.write(",");
11205 }
11206 self.write_space();
11207
11208 if let Some(ref kind) = item.kind {
11210 self.write_keyword(kind);
11211 self.write_space();
11212 }
11213
11214 let name_str = match &item.name {
11216 Expression::Identifier(id) => Some(id.name.as_str()),
11217 _ => None,
11218 };
11219
11220 let is_transaction = name_str == Some("TRANSACTION");
11221 let is_character_set = name_str == Some("CHARACTER SET");
11222 let is_names = name_str == Some("NAMES");
11223 let is_collate = name_str == Some("COLLATE");
11224 let has_variable_kind = item.kind.as_deref() == Some("VARIABLE");
11225 let name_has_variable_prefix = name_str.map_or(false, |n| n.starts_with("VARIABLE "));
11226 let is_variable = has_variable_kind || name_has_variable_prefix;
11227 let is_value_only =
11228 matches!(&item.value, Expression::Identifier(id) if id.name.is_empty());
11229
11230 if is_transaction {
11231 self.write_keyword("TRANSACTION");
11233 if let Expression::Identifier(id) = &item.value {
11234 if !id.name.is_empty() {
11235 self.write_space();
11236 self.write(&id.name);
11237 }
11238 }
11239 } else if is_character_set {
11240 self.write_keyword("CHARACTER SET");
11242 self.write_space();
11243 self.generate_set_value(&item.value)?;
11244 } else if is_names {
11245 self.write_keyword("NAMES");
11247 self.write_space();
11248 self.generate_set_value(&item.value)?;
11249 } else if is_collate {
11250 self.write_keyword("COLLATE");
11252 self.write_space();
11253 self.generate_set_value(&item.value)?;
11254 } else if is_variable {
11255 if name_has_variable_prefix && !has_variable_kind {
11259 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
11260 self.write_keyword("VARIABLE");
11261 self.write_space();
11262 }
11263 }
11264 if let Some(ns) = name_str {
11266 let var_name = if name_has_variable_prefix {
11267 &ns["VARIABLE ".len()..]
11268 } else {
11269 ns
11270 };
11271 self.write(var_name);
11272 } else {
11273 self.generate_expression(&item.name)?;
11274 }
11275 self.write(" = ");
11276 self.generate_set_value(&item.value)?;
11277 } else if is_value_only {
11278 self.generate_expression(&item.name)?;
11280 } else if item.no_equals && matches!(self.config.dialect, Some(DialectType::TSQL)) {
11281 self.generate_expression(&item.name)?;
11283 self.write_space();
11284 self.generate_set_value(&item.value)?;
11285 } else {
11286 match &item.name {
11289 Expression::Identifier(id) => {
11290 self.write(&id.name);
11291 }
11292 _ => {
11293 self.generate_expression(&item.name)?;
11294 }
11295 }
11296 self.write(" = ");
11297 self.generate_set_value(&item.value)?;
11298 }
11299 }
11300
11301 Ok(())
11302 }
11303
11304 fn generate_set_value(&mut self, value: &Expression) -> Result<()> {
11307 if let Expression::Identifier(id) = value {
11308 match id.name.as_str() {
11309 "DEFAULT" | "ON" | "OFF" => {
11310 self.write_keyword(&id.name);
11311 return Ok(());
11312 }
11313 _ => {}
11314 }
11315 }
11316 self.generate_expression(value)
11317 }
11318
11319 fn generate_alter_view(&mut self, av: &AlterView) -> Result<()> {
11322 self.write_keyword("ALTER");
11323 if let Some(ref algorithm) = av.algorithm {
11325 self.write_space();
11326 self.write_keyword("ALGORITHM");
11327 self.write(" = ");
11328 self.write_keyword(algorithm);
11329 }
11330 if let Some(ref definer) = av.definer {
11331 self.write_space();
11332 self.write_keyword("DEFINER");
11333 self.write(" = ");
11334 self.write(definer);
11335 }
11336 if let Some(ref sql_security) = av.sql_security {
11337 self.write_space();
11338 self.write_keyword("SQL SECURITY");
11339 self.write(" = ");
11340 self.write_keyword(sql_security);
11341 }
11342 self.write_space();
11343 self.write_keyword("VIEW");
11344 self.write_space();
11345 self.generate_table(&av.name)?;
11346
11347 if !av.columns.is_empty() {
11349 self.write(" (");
11350 for (i, col) in av.columns.iter().enumerate() {
11351 if i > 0 {
11352 self.write(", ");
11353 }
11354 self.generate_identifier(&col.name)?;
11355 if let Some(ref comment) = col.comment {
11356 self.write_space();
11357 self.write_keyword("COMMENT");
11358 self.write(" ");
11359 self.generate_string_literal(comment)?;
11360 }
11361 }
11362 self.write(")");
11363 }
11364
11365 if let Some(ref opt) = av.with_option {
11367 self.write_space();
11368 self.write_keyword("WITH");
11369 self.write_space();
11370 self.write_keyword(opt);
11371 }
11372
11373 for action in &av.actions {
11374 self.write_space();
11375 match action {
11376 AlterViewAction::Rename(new_name) => {
11377 self.write_keyword("RENAME TO");
11378 self.write_space();
11379 self.generate_table(new_name)?;
11380 }
11381 AlterViewAction::OwnerTo(owner) => {
11382 self.write_keyword("OWNER TO");
11383 self.write_space();
11384 self.generate_identifier(owner)?;
11385 }
11386 AlterViewAction::SetSchema(schema) => {
11387 self.write_keyword("SET SCHEMA");
11388 self.write_space();
11389 self.generate_identifier(schema)?;
11390 }
11391 AlterViewAction::SetAuthorization(auth) => {
11392 self.write_keyword("SET AUTHORIZATION");
11393 self.write_space();
11394 self.write(auth);
11395 }
11396 AlterViewAction::AlterColumn { name, action } => {
11397 self.write_keyword("ALTER COLUMN");
11398 self.write_space();
11399 self.generate_identifier(name)?;
11400 self.write_space();
11401 self.generate_alter_column_action(action)?;
11402 }
11403 AlterViewAction::AsSelect(query) => {
11404 self.write_keyword("AS");
11405 self.write_space();
11406 self.generate_expression(query)?;
11407 }
11408 AlterViewAction::SetTblproperties(props) => {
11409 self.write_keyword("SET TBLPROPERTIES");
11410 self.write(" (");
11411 for (i, (key, value)) in props.iter().enumerate() {
11412 if i > 0 {
11413 self.write(", ");
11414 }
11415 self.generate_string_literal(key)?;
11416 self.write("=");
11417 self.generate_string_literal(value)?;
11418 }
11419 self.write(")");
11420 }
11421 AlterViewAction::UnsetTblproperties(keys) => {
11422 self.write_keyword("UNSET TBLPROPERTIES");
11423 self.write(" (");
11424 for (i, key) in keys.iter().enumerate() {
11425 if i > 0 {
11426 self.write(", ");
11427 }
11428 self.generate_string_literal(key)?;
11429 }
11430 self.write(")");
11431 }
11432 }
11433 }
11434
11435 Ok(())
11436 }
11437
11438 fn generate_alter_index(&mut self, ai: &AlterIndex) -> Result<()> {
11439 self.write_keyword("ALTER INDEX");
11440 self.write_space();
11441 self.generate_identifier(&ai.name)?;
11442
11443 if let Some(table) = &ai.table {
11444 self.write_space();
11445 self.write_keyword("ON");
11446 self.write_space();
11447 self.generate_table(table)?;
11448 }
11449
11450 for action in &ai.actions {
11451 self.write_space();
11452 match action {
11453 AlterIndexAction::Rename(new_name) => {
11454 self.write_keyword("RENAME TO");
11455 self.write_space();
11456 self.generate_identifier(new_name)?;
11457 }
11458 AlterIndexAction::SetTablespace(tablespace) => {
11459 self.write_keyword("SET TABLESPACE");
11460 self.write_space();
11461 self.generate_identifier(tablespace)?;
11462 }
11463 AlterIndexAction::Visible(visible) => {
11464 if *visible {
11465 self.write_keyword("VISIBLE");
11466 } else {
11467 self.write_keyword("INVISIBLE");
11468 }
11469 }
11470 }
11471 }
11472
11473 Ok(())
11474 }
11475
11476 fn generate_create_schema(&mut self, cs: &CreateSchema) -> Result<()> {
11477 for comment in &cs.leading_comments {
11479 self.write_formatted_comment(comment);
11480 self.write_space();
11481 }
11482
11483 let saved_athena_hive_context = self.athena_hive_context;
11485 if matches!(
11486 self.config.dialect,
11487 Some(crate::dialects::DialectType::Athena)
11488 ) {
11489 self.athena_hive_context = true;
11490 }
11491
11492 self.write_keyword("CREATE SCHEMA");
11493
11494 if cs.if_not_exists {
11495 self.write_space();
11496 self.write_keyword("IF NOT EXISTS");
11497 }
11498
11499 self.write_space();
11500 self.generate_identifier(&cs.name)?;
11501
11502 if let Some(ref clone_src) = cs.clone_from {
11503 self.write_keyword(" CLONE ");
11504 self.generate_identifier(clone_src)?;
11505 }
11506
11507 if let Some(ref at_clause) = cs.at_clause {
11508 self.write_space();
11509 self.generate_expression(at_clause)?;
11510 }
11511
11512 if let Some(auth) = &cs.authorization {
11513 self.write_space();
11514 self.write_keyword("AUTHORIZATION");
11515 self.write_space();
11516 self.generate_identifier(auth)?;
11517 }
11518
11519 let with_properties: Vec<_> = cs
11522 .properties
11523 .iter()
11524 .filter(|p| matches!(p, Expression::Property(_)))
11525 .collect();
11526 let other_properties: Vec<_> = cs
11527 .properties
11528 .iter()
11529 .filter(|p| !matches!(p, Expression::Property(_)))
11530 .collect();
11531
11532 if !with_properties.is_empty() {
11534 self.write_space();
11535 self.write_keyword("WITH");
11536 self.write(" (");
11537 for (i, prop) in with_properties.iter().enumerate() {
11538 if i > 0 {
11539 self.write(", ");
11540 }
11541 self.generate_expression(prop)?;
11542 }
11543 self.write(")");
11544 }
11545
11546 for prop in other_properties {
11548 self.write_space();
11549 self.generate_expression(prop)?;
11550 }
11551
11552 self.athena_hive_context = saved_athena_hive_context;
11554
11555 Ok(())
11556 }
11557
11558 fn generate_drop_schema(&mut self, ds: &DropSchema) -> Result<()> {
11559 self.write_keyword("DROP SCHEMA");
11560
11561 if ds.if_exists {
11562 self.write_space();
11563 self.write_keyword("IF EXISTS");
11564 }
11565
11566 self.write_space();
11567 self.generate_identifier(&ds.name)?;
11568
11569 if ds.cascade {
11570 self.write_space();
11571 self.write_keyword("CASCADE");
11572 }
11573
11574 Ok(())
11575 }
11576
11577 fn generate_drop_namespace(&mut self, dn: &DropNamespace) -> Result<()> {
11578 self.write_keyword("DROP NAMESPACE");
11579
11580 if dn.if_exists {
11581 self.write_space();
11582 self.write_keyword("IF EXISTS");
11583 }
11584
11585 self.write_space();
11586 self.generate_identifier(&dn.name)?;
11587
11588 if dn.cascade {
11589 self.write_space();
11590 self.write_keyword("CASCADE");
11591 }
11592
11593 Ok(())
11594 }
11595
11596 fn generate_create_database(&mut self, cd: &CreateDatabase) -> Result<()> {
11597 self.write_keyword("CREATE DATABASE");
11598
11599 if cd.if_not_exists {
11600 self.write_space();
11601 self.write_keyword("IF NOT EXISTS");
11602 }
11603
11604 self.write_space();
11605 self.generate_identifier(&cd.name)?;
11606
11607 if let Some(ref clone_src) = cd.clone_from {
11608 self.write_keyword(" CLONE ");
11609 self.generate_identifier(clone_src)?;
11610 }
11611
11612 if let Some(ref at_clause) = cd.at_clause {
11614 self.write_space();
11615 self.generate_expression(at_clause)?;
11616 }
11617
11618 for option in &cd.options {
11619 self.write_space();
11620 match option {
11621 DatabaseOption::CharacterSet(charset) => {
11622 self.write_keyword("CHARACTER SET");
11623 self.write(" = ");
11624 self.write(&format!("'{}'", charset));
11625 }
11626 DatabaseOption::Collate(collate) => {
11627 self.write_keyword("COLLATE");
11628 self.write(" = ");
11629 self.write(&format!("'{}'", collate));
11630 }
11631 DatabaseOption::Owner(owner) => {
11632 self.write_keyword("OWNER");
11633 self.write(" = ");
11634 self.generate_identifier(owner)?;
11635 }
11636 DatabaseOption::Template(template) => {
11637 self.write_keyword("TEMPLATE");
11638 self.write(" = ");
11639 self.generate_identifier(template)?;
11640 }
11641 DatabaseOption::Encoding(encoding) => {
11642 self.write_keyword("ENCODING");
11643 self.write(" = ");
11644 self.write(&format!("'{}'", encoding));
11645 }
11646 DatabaseOption::Location(location) => {
11647 self.write_keyword("LOCATION");
11648 self.write(" = ");
11649 self.write(&format!("'{}'", location));
11650 }
11651 }
11652 }
11653
11654 Ok(())
11655 }
11656
11657 fn generate_drop_database(&mut self, dd: &DropDatabase) -> Result<()> {
11658 self.write_keyword("DROP DATABASE");
11659
11660 if dd.if_exists {
11661 self.write_space();
11662 self.write_keyword("IF EXISTS");
11663 }
11664
11665 self.write_space();
11666 self.generate_identifier(&dd.name)?;
11667
11668 Ok(())
11669 }
11670
11671 fn generate_create_function(&mut self, cf: &CreateFunction) -> Result<()> {
11672 self.write_keyword("CREATE");
11673
11674 if cf.or_replace {
11675 self.write_space();
11676 self.write_keyword("OR REPLACE");
11677 }
11678
11679 if cf.temporary {
11680 self.write_space();
11681 self.write_keyword("TEMPORARY");
11682 }
11683
11684 self.write_space();
11685 if cf.is_table_function {
11686 self.write_keyword("TABLE FUNCTION");
11687 } else {
11688 self.write_keyword("FUNCTION");
11689 }
11690
11691 if cf.if_not_exists {
11692 self.write_space();
11693 self.write_keyword("IF NOT EXISTS");
11694 }
11695
11696 self.write_space();
11697 self.generate_table(&cf.name)?;
11698 if cf.has_parens {
11699 let func_multiline = self.config.pretty
11700 && matches!(
11701 self.config.dialect,
11702 Some(crate::dialects::DialectType::TSQL)
11703 | Some(crate::dialects::DialectType::Fabric)
11704 )
11705 && !cf.parameters.is_empty();
11706 if func_multiline {
11707 self.write("(\n");
11708 self.indent_level += 2;
11709 self.write_indent();
11710 self.generate_function_parameters(&cf.parameters)?;
11711 self.write("\n");
11712 self.indent_level -= 2;
11713 self.write(")");
11714 } else {
11715 self.write("(");
11716 self.generate_function_parameters(&cf.parameters)?;
11717 self.write(")");
11718 }
11719 }
11720
11721 let use_multiline = self.config.pretty
11724 && matches!(
11725 self.config.dialect,
11726 Some(crate::dialects::DialectType::BigQuery)
11727 | Some(crate::dialects::DialectType::TSQL)
11728 | Some(crate::dialects::DialectType::Fabric)
11729 );
11730
11731 if cf.language_first {
11732 if let Some(lang) = &cf.language {
11734 if use_multiline {
11735 self.write_newline();
11736 } else {
11737 self.write_space();
11738 }
11739 self.write_keyword("LANGUAGE");
11740 self.write_space();
11741 self.write(lang);
11742 }
11743
11744 if let Some(sql_data) = &cf.sql_data_access {
11746 self.write_space();
11747 match sql_data {
11748 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
11749 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
11750 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
11751 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
11752 }
11753 }
11754
11755 if let Some(ref rtb) = cf.returns_table_body {
11756 if use_multiline {
11757 self.write_newline();
11758 } else {
11759 self.write_space();
11760 }
11761 self.write_keyword("RETURNS");
11762 self.write_space();
11763 self.write(rtb);
11764 } else if let Some(return_type) = &cf.return_type {
11765 if use_multiline {
11766 self.write_newline();
11767 } else {
11768 self.write_space();
11769 }
11770 self.write_keyword("RETURNS");
11771 self.write_space();
11772 self.generate_data_type(return_type)?;
11773 }
11774 } else {
11775 let is_duckdb = matches!(
11778 self.config.dialect,
11779 Some(crate::dialects::DialectType::DuckDB)
11780 );
11781 if let Some(ref rtb) = cf.returns_table_body {
11782 if !(is_duckdb && rtb.is_empty()) {
11783 if use_multiline {
11784 self.write_newline();
11785 } else {
11786 self.write_space();
11787 }
11788 self.write_keyword("RETURNS");
11789 self.write_space();
11790 self.write(rtb);
11791 }
11792 } else if let Some(return_type) = &cf.return_type {
11793 if use_multiline {
11794 self.write_newline();
11795 } else {
11796 self.write_space();
11797 }
11798 self.write_keyword("RETURNS");
11799 self.write_space();
11800 self.generate_data_type(return_type)?;
11801 }
11802 }
11803
11804 if !cf.property_order.is_empty() {
11806 let is_bigquery = matches!(
11808 self.config.dialect,
11809 Some(crate::dialects::DialectType::BigQuery)
11810 );
11811 let property_order = if is_bigquery {
11812 let mut reordered = Vec::new();
11814 let mut has_as = false;
11815 let mut has_options = false;
11816 for prop in &cf.property_order {
11817 match prop {
11818 FunctionPropertyKind::As => has_as = true,
11819 FunctionPropertyKind::Options => has_options = true,
11820 _ => {}
11821 }
11822 }
11823 if has_as && has_options {
11824 for prop in &cf.property_order {
11826 if *prop != FunctionPropertyKind::As
11827 && *prop != FunctionPropertyKind::Options
11828 {
11829 reordered.push(*prop);
11830 }
11831 }
11832 reordered.push(FunctionPropertyKind::Options);
11833 reordered.push(FunctionPropertyKind::As);
11834 reordered
11835 } else {
11836 cf.property_order.clone()
11837 }
11838 } else {
11839 cf.property_order.clone()
11840 };
11841
11842 for prop in &property_order {
11843 match prop {
11844 FunctionPropertyKind::Set => {
11845 self.generate_function_set_options(cf)?;
11846 }
11847 FunctionPropertyKind::As => {
11848 self.generate_function_body(cf)?;
11849 }
11850 FunctionPropertyKind::Language => {
11851 if !cf.language_first {
11852 if let Some(lang) = &cf.language {
11854 let use_multiline = self.config.pretty
11856 && matches!(
11857 self.config.dialect,
11858 Some(crate::dialects::DialectType::BigQuery)
11859 );
11860 if use_multiline {
11861 self.write_newline();
11862 } else {
11863 self.write_space();
11864 }
11865 self.write_keyword("LANGUAGE");
11866 self.write_space();
11867 self.write(lang);
11868 }
11869 }
11870 }
11871 FunctionPropertyKind::Determinism => {
11872 self.generate_function_determinism(cf)?;
11873 }
11874 FunctionPropertyKind::NullInput => {
11875 self.generate_function_null_input(cf)?;
11876 }
11877 FunctionPropertyKind::Security => {
11878 self.generate_function_security(cf)?;
11879 }
11880 FunctionPropertyKind::SqlDataAccess => {
11881 if !cf.language_first {
11882 self.generate_function_sql_data_access(cf)?;
11884 }
11885 }
11886 FunctionPropertyKind::Options => {
11887 if !cf.options.is_empty() {
11888 self.write_space();
11889 self.generate_options_clause(&cf.options)?;
11890 }
11891 }
11892 FunctionPropertyKind::Environment => {
11893 if !cf.environment.is_empty() {
11894 self.write_space();
11895 self.generate_environment_clause(&cf.environment)?;
11896 }
11897 }
11898 }
11899 }
11900
11901 if !cf.options.is_empty() && !cf.property_order.contains(&FunctionPropertyKind::Options)
11903 {
11904 self.write_space();
11905 self.generate_options_clause(&cf.options)?;
11906 }
11907
11908 if !cf.environment.is_empty()
11910 && !cf
11911 .property_order
11912 .contains(&FunctionPropertyKind::Environment)
11913 {
11914 self.write_space();
11915 self.generate_environment_clause(&cf.environment)?;
11916 }
11917 } else {
11918 if matches!(
11921 self.config.dialect,
11922 Some(crate::dialects::DialectType::BigQuery)
11923 ) {
11924 self.generate_function_determinism(cf)?;
11925 }
11926
11927 let use_multiline = self.config.pretty
11929 && matches!(
11930 self.config.dialect,
11931 Some(crate::dialects::DialectType::BigQuery)
11932 );
11933
11934 if !cf.language_first {
11935 if let Some(lang) = &cf.language {
11936 if use_multiline {
11937 self.write_newline();
11938 } else {
11939 self.write_space();
11940 }
11941 self.write_keyword("LANGUAGE");
11942 self.write_space();
11943 self.write(lang);
11944 }
11945
11946 self.generate_function_sql_data_access(cf)?;
11948 }
11949
11950 if !matches!(
11952 self.config.dialect,
11953 Some(crate::dialects::DialectType::BigQuery)
11954 ) {
11955 self.generate_function_determinism(cf)?;
11956 }
11957
11958 self.generate_function_null_input(cf)?;
11959 self.generate_function_security(cf)?;
11960 self.generate_function_set_options(cf)?;
11961
11962 if !cf.options.is_empty() {
11964 self.write_space();
11965 self.generate_options_clause(&cf.options)?;
11966 }
11967
11968 if !cf.environment.is_empty() {
11970 self.write_space();
11971 self.generate_environment_clause(&cf.environment)?;
11972 }
11973
11974 self.generate_function_body(cf)?;
11975 }
11976
11977 Ok(())
11978 }
11979
11980 fn generate_function_set_options(&mut self, cf: &CreateFunction) -> Result<()> {
11982 for opt in &cf.set_options {
11983 self.write_space();
11984 self.write_keyword("SET");
11985 self.write_space();
11986 self.write(&opt.name);
11987 match &opt.value {
11988 FunctionSetValue::Value { value, use_to } => {
11989 if *use_to {
11990 self.write(" TO ");
11991 } else {
11992 self.write(" = ");
11993 }
11994 self.write(value);
11995 }
11996 FunctionSetValue::FromCurrent => {
11997 self.write_space();
11998 self.write_keyword("FROM CURRENT");
11999 }
12000 }
12001 }
12002 Ok(())
12003 }
12004
12005 fn generate_function_body(&mut self, cf: &CreateFunction) -> Result<()> {
12007 if let Some(body) = &cf.body {
12008 self.write_space();
12010 let use_multiline = self.config.pretty
12012 && matches!(
12013 self.config.dialect,
12014 Some(crate::dialects::DialectType::BigQuery)
12015 );
12016 match body {
12017 FunctionBody::Block(block) => {
12018 self.write_keyword("AS");
12019 if matches!(
12020 self.config.dialect,
12021 Some(crate::dialects::DialectType::TSQL)
12022 ) {
12023 self.write(" BEGIN ");
12024 self.write(block);
12025 self.write(" END");
12026 } else if matches!(
12027 self.config.dialect,
12028 Some(crate::dialects::DialectType::PostgreSQL)
12029 ) {
12030 self.write(" $$");
12031 self.write(block);
12032 self.write("$$");
12033 } else {
12034 let escaped = self.escape_block_for_single_quote(block);
12036 if use_multiline {
12038 self.write_newline();
12039 } else {
12040 self.write(" ");
12041 }
12042 self.write("'");
12043 self.write(&escaped);
12044 self.write("'");
12045 }
12046 }
12047 FunctionBody::StringLiteral(s) => {
12048 self.write_keyword("AS");
12049 if use_multiline {
12051 self.write_newline();
12052 } else {
12053 self.write(" ");
12054 }
12055 self.write("'");
12056 self.write(s);
12057 self.write("'");
12058 }
12059 FunctionBody::Expression(expr) => {
12060 self.write_keyword("AS");
12061 self.write_space();
12062 self.generate_expression(expr)?;
12063 }
12064 FunctionBody::External(name) => {
12065 self.write_keyword("EXTERNAL NAME");
12066 self.write(" '");
12067 self.write(name);
12068 self.write("'");
12069 }
12070 FunctionBody::Return(expr) => {
12071 if matches!(
12072 self.config.dialect,
12073 Some(crate::dialects::DialectType::DuckDB)
12074 ) {
12075 self.write_keyword("AS");
12077 self.write_space();
12078 if cf.returns_table_body.is_some() {
12080 self.write_keyword("TABLE");
12081 self.write_space();
12082 }
12083 self.generate_expression(expr)?;
12084 } else {
12085 if self.config.create_function_return_as {
12086 self.write_keyword("AS");
12087 if self.config.pretty
12089 && matches!(
12090 self.config.dialect,
12091 Some(crate::dialects::DialectType::TSQL)
12092 | Some(crate::dialects::DialectType::Fabric)
12093 )
12094 {
12095 self.write_newline();
12096 } else {
12097 self.write_space();
12098 }
12099 }
12100 self.write_keyword("RETURN");
12101 self.write_space();
12102 self.generate_expression(expr)?;
12103 }
12104 }
12105 FunctionBody::Statements(stmts) => {
12106 self.write_keyword("AS");
12107 self.write(" BEGIN ");
12108 for (i, stmt) in stmts.iter().enumerate() {
12109 if i > 0 {
12110 self.write(" ");
12111 }
12112 self.generate_expression(stmt)?;
12113 }
12114 self.write(" END");
12115 }
12116 FunctionBody::DollarQuoted { content, tag } => {
12117 self.write_keyword("AS");
12118 self.write(" ");
12119 let supports_dollar_quoting = matches!(
12121 self.config.dialect,
12122 Some(crate::dialects::DialectType::PostgreSQL)
12123 | Some(crate::dialects::DialectType::Databricks)
12124 | Some(crate::dialects::DialectType::Redshift)
12125 | Some(crate::dialects::DialectType::DuckDB)
12126 );
12127 if supports_dollar_quoting {
12128 self.write("$");
12130 if let Some(t) = tag {
12131 self.write(t);
12132 }
12133 self.write("$");
12134 self.write(content);
12135 self.write("$");
12136 if let Some(t) = tag {
12137 self.write(t);
12138 }
12139 self.write("$");
12140 } else {
12141 let escaped = self.escape_block_for_single_quote(content);
12143 self.write("'");
12144 self.write(&escaped);
12145 self.write("'");
12146 }
12147 }
12148 }
12149 }
12150 Ok(())
12151 }
12152
12153 fn generate_function_determinism(&mut self, cf: &CreateFunction) -> Result<()> {
12155 if let Some(det) = cf.deterministic {
12156 self.write_space();
12157 if matches!(
12158 self.config.dialect,
12159 Some(crate::dialects::DialectType::BigQuery)
12160 ) {
12161 if det {
12163 self.write_keyword("DETERMINISTIC");
12164 } else {
12165 self.write_keyword("NOT DETERMINISTIC");
12166 }
12167 } else {
12168 if det {
12170 self.write_keyword("IMMUTABLE");
12171 } else {
12172 self.write_keyword("VOLATILE");
12173 }
12174 }
12175 }
12176 Ok(())
12177 }
12178
12179 fn generate_function_null_input(&mut self, cf: &CreateFunction) -> Result<()> {
12181 if let Some(returns_null) = cf.returns_null_on_null_input {
12182 self.write_space();
12183 if returns_null {
12184 if cf.strict {
12185 self.write_keyword("STRICT");
12186 } else {
12187 self.write_keyword("RETURNS NULL ON NULL INPUT");
12188 }
12189 } else {
12190 self.write_keyword("CALLED ON NULL INPUT");
12191 }
12192 }
12193 Ok(())
12194 }
12195
12196 fn generate_function_security(&mut self, cf: &CreateFunction) -> Result<()> {
12198 if let Some(security) = &cf.security {
12199 self.write_space();
12200 self.write_keyword("SECURITY");
12201 self.write_space();
12202 match security {
12203 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
12204 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
12205 FunctionSecurity::None => self.write_keyword("NONE"),
12206 }
12207 }
12208 Ok(())
12209 }
12210
12211 fn generate_function_sql_data_access(&mut self, cf: &CreateFunction) -> Result<()> {
12213 if let Some(sql_data) = &cf.sql_data_access {
12214 self.write_space();
12215 match sql_data {
12216 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
12217 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
12218 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
12219 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
12220 }
12221 }
12222 Ok(())
12223 }
12224
12225 fn generate_function_parameters(&mut self, params: &[FunctionParameter]) -> Result<()> {
12226 for (i, param) in params.iter().enumerate() {
12227 if i > 0 {
12228 self.write(", ");
12229 }
12230
12231 if let Some(mode) = ¶m.mode {
12232 if let Some(text) = ¶m.mode_text {
12233 self.write(text);
12234 } else {
12235 match mode {
12236 ParameterMode::In => self.write_keyword("IN"),
12237 ParameterMode::Out => self.write_keyword("OUT"),
12238 ParameterMode::InOut => self.write_keyword("INOUT"),
12239 ParameterMode::Variadic => self.write_keyword("VARIADIC"),
12240 }
12241 }
12242 self.write_space();
12243 }
12244
12245 if let Some(name) = ¶m.name {
12246 self.generate_identifier(name)?;
12247 let skip_type =
12249 matches!(¶m.data_type, DataType::Custom { name } if name.is_empty());
12250 if !skip_type {
12251 self.write_space();
12252 self.generate_data_type(¶m.data_type)?;
12253 }
12254 } else {
12255 self.generate_data_type(¶m.data_type)?;
12256 }
12257
12258 if let Some(default) = ¶m.default {
12259 if self.config.parameter_default_equals {
12260 self.write(" = ");
12261 } else {
12262 self.write(" DEFAULT ");
12263 }
12264 self.generate_expression(default)?;
12265 }
12266 }
12267
12268 Ok(())
12269 }
12270
12271 fn generate_drop_function(&mut self, df: &DropFunction) -> Result<()> {
12272 self.write_keyword("DROP FUNCTION");
12273
12274 if df.if_exists {
12275 self.write_space();
12276 self.write_keyword("IF EXISTS");
12277 }
12278
12279 self.write_space();
12280 self.generate_table(&df.name)?;
12281
12282 if let Some(params) = &df.parameters {
12283 self.write(" (");
12284 for (i, dt) in params.iter().enumerate() {
12285 if i > 0 {
12286 self.write(", ");
12287 }
12288 self.generate_data_type(dt)?;
12289 }
12290 self.write(")");
12291 }
12292
12293 if df.cascade {
12294 self.write_space();
12295 self.write_keyword("CASCADE");
12296 }
12297
12298 Ok(())
12299 }
12300
12301 fn generate_create_procedure(&mut self, cp: &CreateProcedure) -> Result<()> {
12302 self.write_keyword("CREATE");
12303
12304 if cp.or_replace {
12305 self.write_space();
12306 self.write_keyword("OR REPLACE");
12307 }
12308
12309 self.write_space();
12310 if cp.use_proc_keyword {
12311 self.write_keyword("PROC");
12312 } else {
12313 self.write_keyword("PROCEDURE");
12314 }
12315
12316 if cp.if_not_exists {
12317 self.write_space();
12318 self.write_keyword("IF NOT EXISTS");
12319 }
12320
12321 self.write_space();
12322 self.generate_table(&cp.name)?;
12323 if cp.has_parens {
12324 self.write("(");
12325 self.generate_function_parameters(&cp.parameters)?;
12326 self.write(")");
12327 } else if !cp.parameters.is_empty() {
12328 self.write_space();
12330 self.generate_function_parameters(&cp.parameters)?;
12331 }
12332
12333 if let Some(return_type) = &cp.return_type {
12335 self.write_space();
12336 self.write_keyword("RETURNS");
12337 self.write_space();
12338 self.generate_data_type(return_type)?;
12339 }
12340
12341 if let Some(execute_as) = &cp.execute_as {
12343 self.write_space();
12344 self.write_keyword("EXECUTE AS");
12345 self.write_space();
12346 self.write_keyword(execute_as);
12347 }
12348
12349 if let Some(lang) = &cp.language {
12350 self.write_space();
12351 self.write_keyword("LANGUAGE");
12352 self.write_space();
12353 self.write(lang);
12354 }
12355
12356 if let Some(security) = &cp.security {
12357 self.write_space();
12358 self.write_keyword("SECURITY");
12359 self.write_space();
12360 match security {
12361 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
12362 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
12363 FunctionSecurity::None => self.write_keyword("NONE"),
12364 }
12365 }
12366
12367 if !cp.with_options.is_empty() {
12369 self.write_space();
12370 self.write_keyword("WITH");
12371 self.write_space();
12372 for (i, opt) in cp.with_options.iter().enumerate() {
12373 if i > 0 {
12374 self.write(", ");
12375 }
12376 self.write(opt);
12377 }
12378 }
12379
12380 if let Some(body) = &cp.body {
12381 self.write_space();
12382 match body {
12383 FunctionBody::Block(block) => {
12384 self.write_keyword("AS");
12385 if matches!(
12386 self.config.dialect,
12387 Some(crate::dialects::DialectType::TSQL)
12388 ) {
12389 self.write(" BEGIN ");
12390 self.write(block);
12391 self.write(" END");
12392 } else if matches!(
12393 self.config.dialect,
12394 Some(crate::dialects::DialectType::PostgreSQL)
12395 ) {
12396 self.write(" $$");
12397 self.write(block);
12398 self.write("$$");
12399 } else {
12400 let escaped = self.escape_block_for_single_quote(block);
12402 self.write(" '");
12403 self.write(&escaped);
12404 self.write("'");
12405 }
12406 }
12407 FunctionBody::StringLiteral(s) => {
12408 self.write_keyword("AS");
12409 self.write(" '");
12410 self.write(s);
12411 self.write("'");
12412 }
12413 FunctionBody::Expression(expr) => {
12414 self.write_keyword("AS");
12415 self.write_space();
12416 self.generate_expression(expr)?;
12417 }
12418 FunctionBody::External(name) => {
12419 self.write_keyword("EXTERNAL NAME");
12420 self.write(" '");
12421 self.write(name);
12422 self.write("'");
12423 }
12424 FunctionBody::Return(expr) => {
12425 self.write_keyword("RETURN");
12426 self.write_space();
12427 self.generate_expression(expr)?;
12428 }
12429 FunctionBody::Statements(stmts) => {
12430 self.write_keyword("AS");
12431 self.write(" BEGIN ");
12432 for (i, stmt) in stmts.iter().enumerate() {
12433 if i > 0 {
12434 self.write(" ");
12435 }
12436 self.generate_expression(stmt)?;
12437 }
12438 self.write(" END");
12439 }
12440 FunctionBody::DollarQuoted { content, tag } => {
12441 self.write_keyword("AS");
12442 self.write(" ");
12443 let supports_dollar_quoting = matches!(
12445 self.config.dialect,
12446 Some(crate::dialects::DialectType::PostgreSQL)
12447 | Some(crate::dialects::DialectType::Databricks)
12448 | Some(crate::dialects::DialectType::Redshift)
12449 | Some(crate::dialects::DialectType::DuckDB)
12450 );
12451 if supports_dollar_quoting {
12452 self.write("$");
12454 if let Some(t) = tag {
12455 self.write(t);
12456 }
12457 self.write("$");
12458 self.write(content);
12459 self.write("$");
12460 if let Some(t) = tag {
12461 self.write(t);
12462 }
12463 self.write("$");
12464 } else {
12465 let escaped = self.escape_block_for_single_quote(content);
12467 self.write("'");
12468 self.write(&escaped);
12469 self.write("'");
12470 }
12471 }
12472 }
12473 }
12474
12475 Ok(())
12476 }
12477
12478 fn generate_drop_procedure(&mut self, dp: &DropProcedure) -> Result<()> {
12479 self.write_keyword("DROP PROCEDURE");
12480
12481 if dp.if_exists {
12482 self.write_space();
12483 self.write_keyword("IF EXISTS");
12484 }
12485
12486 self.write_space();
12487 self.generate_table(&dp.name)?;
12488
12489 if let Some(params) = &dp.parameters {
12490 self.write(" (");
12491 for (i, dt) in params.iter().enumerate() {
12492 if i > 0 {
12493 self.write(", ");
12494 }
12495 self.generate_data_type(dt)?;
12496 }
12497 self.write(")");
12498 }
12499
12500 if dp.cascade {
12501 self.write_space();
12502 self.write_keyword("CASCADE");
12503 }
12504
12505 Ok(())
12506 }
12507
12508 fn generate_create_sequence(&mut self, cs: &CreateSequence) -> Result<()> {
12509 self.write_keyword("CREATE");
12510
12511 if cs.or_replace {
12512 self.write_space();
12513 self.write_keyword("OR REPLACE");
12514 }
12515
12516 if cs.temporary {
12517 self.write_space();
12518 self.write_keyword("TEMPORARY");
12519 }
12520
12521 self.write_space();
12522 self.write_keyword("SEQUENCE");
12523
12524 if cs.if_not_exists {
12525 self.write_space();
12526 self.write_keyword("IF NOT EXISTS");
12527 }
12528
12529 self.write_space();
12530 self.generate_table(&cs.name)?;
12531
12532 if let Some(as_type) = &cs.as_type {
12534 self.write_space();
12535 self.write_keyword("AS");
12536 self.write_space();
12537 self.generate_data_type(as_type)?;
12538 }
12539
12540 if let Some(comment) = &cs.comment {
12542 self.write_space();
12543 self.write_keyword("COMMENT");
12544 self.write("=");
12545 self.generate_string_literal(comment)?;
12546 }
12547
12548 if !cs.property_order.is_empty() {
12550 for prop in &cs.property_order {
12551 match prop {
12552 SeqPropKind::Start => {
12553 if let Some(start) = cs.start {
12554 self.write_space();
12555 self.write_keyword("START WITH");
12556 self.write(&format!(" {}", start));
12557 }
12558 }
12559 SeqPropKind::Increment => {
12560 if let Some(inc) = cs.increment {
12561 self.write_space();
12562 self.write_keyword("INCREMENT BY");
12563 self.write(&format!(" {}", inc));
12564 }
12565 }
12566 SeqPropKind::Minvalue => {
12567 if let Some(min) = &cs.minvalue {
12568 self.write_space();
12569 match min {
12570 SequenceBound::Value(v) => {
12571 self.write_keyword("MINVALUE");
12572 self.write(&format!(" {}", v));
12573 }
12574 SequenceBound::None => {
12575 self.write_keyword("NO MINVALUE");
12576 }
12577 }
12578 }
12579 }
12580 SeqPropKind::Maxvalue => {
12581 if let Some(max) = &cs.maxvalue {
12582 self.write_space();
12583 match max {
12584 SequenceBound::Value(v) => {
12585 self.write_keyword("MAXVALUE");
12586 self.write(&format!(" {}", v));
12587 }
12588 SequenceBound::None => {
12589 self.write_keyword("NO MAXVALUE");
12590 }
12591 }
12592 }
12593 }
12594 SeqPropKind::Cache => {
12595 if let Some(cache) = cs.cache {
12596 self.write_space();
12597 self.write_keyword("CACHE");
12598 self.write(&format!(" {}", cache));
12599 }
12600 }
12601 SeqPropKind::NoCache => {
12602 self.write_space();
12603 self.write_keyword("NO CACHE");
12604 }
12605 SeqPropKind::NoCacheWord => {
12606 self.write_space();
12607 self.write_keyword("NOCACHE");
12608 }
12609 SeqPropKind::Cycle => {
12610 self.write_space();
12611 self.write_keyword("CYCLE");
12612 }
12613 SeqPropKind::NoCycle => {
12614 self.write_space();
12615 self.write_keyword("NO CYCLE");
12616 }
12617 SeqPropKind::NoCycleWord => {
12618 self.write_space();
12619 self.write_keyword("NOCYCLE");
12620 }
12621 SeqPropKind::OwnedBy => {
12622 if !cs.owned_by_none {
12624 if let Some(owned) = &cs.owned_by {
12625 self.write_space();
12626 self.write_keyword("OWNED BY");
12627 self.write_space();
12628 self.generate_table(owned)?;
12629 }
12630 }
12631 }
12632 SeqPropKind::Order => {
12633 self.write_space();
12634 self.write_keyword("ORDER");
12635 }
12636 SeqPropKind::NoOrder => {
12637 self.write_space();
12638 self.write_keyword("NOORDER");
12639 }
12640 SeqPropKind::Comment => {
12641 }
12643 SeqPropKind::Sharing => {
12644 if let Some(val) = &cs.sharing {
12645 self.write_space();
12646 self.write(&format!("SHARING={}", val));
12647 }
12648 }
12649 SeqPropKind::Keep => {
12650 self.write_space();
12651 self.write_keyword("KEEP");
12652 }
12653 SeqPropKind::NoKeep => {
12654 self.write_space();
12655 self.write_keyword("NOKEEP");
12656 }
12657 SeqPropKind::Scale => {
12658 self.write_space();
12659 self.write_keyword("SCALE");
12660 if let Some(modifier) = &cs.scale_modifier {
12661 if !modifier.is_empty() {
12662 self.write_space();
12663 self.write_keyword(modifier);
12664 }
12665 }
12666 }
12667 SeqPropKind::NoScale => {
12668 self.write_space();
12669 self.write_keyword("NOSCALE");
12670 }
12671 SeqPropKind::Shard => {
12672 self.write_space();
12673 self.write_keyword("SHARD");
12674 if let Some(modifier) = &cs.shard_modifier {
12675 if !modifier.is_empty() {
12676 self.write_space();
12677 self.write_keyword(modifier);
12678 }
12679 }
12680 }
12681 SeqPropKind::NoShard => {
12682 self.write_space();
12683 self.write_keyword("NOSHARD");
12684 }
12685 SeqPropKind::Session => {
12686 self.write_space();
12687 self.write_keyword("SESSION");
12688 }
12689 SeqPropKind::Global => {
12690 self.write_space();
12691 self.write_keyword("GLOBAL");
12692 }
12693 SeqPropKind::NoMinvalueWord => {
12694 self.write_space();
12695 self.write_keyword("NOMINVALUE");
12696 }
12697 SeqPropKind::NoMaxvalueWord => {
12698 self.write_space();
12699 self.write_keyword("NOMAXVALUE");
12700 }
12701 }
12702 }
12703 } else {
12704 if let Some(inc) = cs.increment {
12706 self.write_space();
12707 self.write_keyword("INCREMENT BY");
12708 self.write(&format!(" {}", inc));
12709 }
12710
12711 if let Some(min) = &cs.minvalue {
12712 self.write_space();
12713 match min {
12714 SequenceBound::Value(v) => {
12715 self.write_keyword("MINVALUE");
12716 self.write(&format!(" {}", v));
12717 }
12718 SequenceBound::None => {
12719 self.write_keyword("NO MINVALUE");
12720 }
12721 }
12722 }
12723
12724 if let Some(max) = &cs.maxvalue {
12725 self.write_space();
12726 match max {
12727 SequenceBound::Value(v) => {
12728 self.write_keyword("MAXVALUE");
12729 self.write(&format!(" {}", v));
12730 }
12731 SequenceBound::None => {
12732 self.write_keyword("NO MAXVALUE");
12733 }
12734 }
12735 }
12736
12737 if let Some(start) = cs.start {
12738 self.write_space();
12739 self.write_keyword("START WITH");
12740 self.write(&format!(" {}", start));
12741 }
12742
12743 if let Some(cache) = cs.cache {
12744 self.write_space();
12745 self.write_keyword("CACHE");
12746 self.write(&format!(" {}", cache));
12747 }
12748
12749 if cs.cycle {
12750 self.write_space();
12751 self.write_keyword("CYCLE");
12752 }
12753
12754 if let Some(owned) = &cs.owned_by {
12755 self.write_space();
12756 self.write_keyword("OWNED BY");
12757 self.write_space();
12758 self.generate_table(owned)?;
12759 }
12760 }
12761
12762 Ok(())
12763 }
12764
12765 fn generate_drop_sequence(&mut self, ds: &DropSequence) -> Result<()> {
12766 self.write_keyword("DROP SEQUENCE");
12767
12768 if ds.if_exists {
12769 self.write_space();
12770 self.write_keyword("IF EXISTS");
12771 }
12772
12773 self.write_space();
12774 self.generate_table(&ds.name)?;
12775
12776 if ds.cascade {
12777 self.write_space();
12778 self.write_keyword("CASCADE");
12779 }
12780
12781 Ok(())
12782 }
12783
12784 fn generate_alter_sequence(&mut self, als: &AlterSequence) -> Result<()> {
12785 self.write_keyword("ALTER SEQUENCE");
12786
12787 if als.if_exists {
12788 self.write_space();
12789 self.write_keyword("IF EXISTS");
12790 }
12791
12792 self.write_space();
12793 self.generate_table(&als.name)?;
12794
12795 if let Some(inc) = als.increment {
12796 self.write_space();
12797 self.write_keyword("INCREMENT BY");
12798 self.write(&format!(" {}", inc));
12799 }
12800
12801 if let Some(min) = &als.minvalue {
12802 self.write_space();
12803 match min {
12804 SequenceBound::Value(v) => {
12805 self.write_keyword("MINVALUE");
12806 self.write(&format!(" {}", v));
12807 }
12808 SequenceBound::None => {
12809 self.write_keyword("NO MINVALUE");
12810 }
12811 }
12812 }
12813
12814 if let Some(max) = &als.maxvalue {
12815 self.write_space();
12816 match max {
12817 SequenceBound::Value(v) => {
12818 self.write_keyword("MAXVALUE");
12819 self.write(&format!(" {}", v));
12820 }
12821 SequenceBound::None => {
12822 self.write_keyword("NO MAXVALUE");
12823 }
12824 }
12825 }
12826
12827 if let Some(start) = als.start {
12828 self.write_space();
12829 self.write_keyword("START WITH");
12830 self.write(&format!(" {}", start));
12831 }
12832
12833 if let Some(restart) = &als.restart {
12834 self.write_space();
12835 self.write_keyword("RESTART");
12836 if let Some(val) = restart {
12837 self.write_keyword(" WITH");
12838 self.write(&format!(" {}", val));
12839 }
12840 }
12841
12842 if let Some(cache) = als.cache {
12843 self.write_space();
12844 self.write_keyword("CACHE");
12845 self.write(&format!(" {}", cache));
12846 }
12847
12848 if let Some(cycle) = als.cycle {
12849 self.write_space();
12850 if cycle {
12851 self.write_keyword("CYCLE");
12852 } else {
12853 self.write_keyword("NO CYCLE");
12854 }
12855 }
12856
12857 if let Some(owned) = &als.owned_by {
12858 self.write_space();
12859 self.write_keyword("OWNED BY");
12860 self.write_space();
12861 if let Some(table) = owned {
12862 self.generate_table(table)?;
12863 } else {
12864 self.write_keyword("NONE");
12865 }
12866 }
12867
12868 Ok(())
12869 }
12870
12871 fn generate_create_trigger(&mut self, ct: &CreateTrigger) -> Result<()> {
12872 self.write_keyword("CREATE");
12873
12874 if ct.or_replace {
12875 self.write_space();
12876 self.write_keyword("OR REPLACE");
12877 }
12878
12879 if ct.constraint {
12880 self.write_space();
12881 self.write_keyword("CONSTRAINT");
12882 }
12883
12884 self.write_space();
12885 self.write_keyword("TRIGGER");
12886 self.write_space();
12887 self.generate_identifier(&ct.name)?;
12888
12889 self.write_space();
12890 match ct.timing {
12891 TriggerTiming::Before => self.write_keyword("BEFORE"),
12892 TriggerTiming::After => self.write_keyword("AFTER"),
12893 TriggerTiming::InsteadOf => self.write_keyword("INSTEAD OF"),
12894 }
12895
12896 for (i, event) in ct.events.iter().enumerate() {
12898 if i > 0 {
12899 self.write_keyword(" OR");
12900 }
12901 self.write_space();
12902 match event {
12903 TriggerEvent::Insert => self.write_keyword("INSERT"),
12904 TriggerEvent::Update(cols) => {
12905 self.write_keyword("UPDATE");
12906 if let Some(cols) = cols {
12907 self.write_space();
12908 self.write_keyword("OF");
12909 for (j, col) in cols.iter().enumerate() {
12910 if j > 0 {
12911 self.write(",");
12912 }
12913 self.write_space();
12914 self.generate_identifier(col)?;
12915 }
12916 }
12917 }
12918 TriggerEvent::Delete => self.write_keyword("DELETE"),
12919 TriggerEvent::Truncate => self.write_keyword("TRUNCATE"),
12920 }
12921 }
12922
12923 self.write_space();
12924 self.write_keyword("ON");
12925 self.write_space();
12926 self.generate_table(&ct.table)?;
12927
12928 if let Some(ref_clause) = &ct.referencing {
12930 self.write_space();
12931 self.write_keyword("REFERENCING");
12932 if let Some(old_table) = &ref_clause.old_table {
12933 self.write_space();
12934 self.write_keyword("OLD TABLE AS");
12935 self.write_space();
12936 self.generate_identifier(old_table)?;
12937 }
12938 if let Some(new_table) = &ref_clause.new_table {
12939 self.write_space();
12940 self.write_keyword("NEW TABLE AS");
12941 self.write_space();
12942 self.generate_identifier(new_table)?;
12943 }
12944 if let Some(old_row) = &ref_clause.old_row {
12945 self.write_space();
12946 self.write_keyword("OLD ROW AS");
12947 self.write_space();
12948 self.generate_identifier(old_row)?;
12949 }
12950 if let Some(new_row) = &ref_clause.new_row {
12951 self.write_space();
12952 self.write_keyword("NEW ROW AS");
12953 self.write_space();
12954 self.generate_identifier(new_row)?;
12955 }
12956 }
12957
12958 if let Some(deferrable) = ct.deferrable {
12960 self.write_space();
12961 if deferrable {
12962 self.write_keyword("DEFERRABLE");
12963 } else {
12964 self.write_keyword("NOT DEFERRABLE");
12965 }
12966 }
12967
12968 if let Some(initially) = ct.initially_deferred {
12969 self.write_space();
12970 self.write_keyword("INITIALLY");
12971 self.write_space();
12972 if initially {
12973 self.write_keyword("DEFERRED");
12974 } else {
12975 self.write_keyword("IMMEDIATE");
12976 }
12977 }
12978
12979 self.write_space();
12980 self.write_keyword("FOR EACH");
12981 self.write_space();
12982 match ct.for_each {
12983 TriggerForEach::Row => self.write_keyword("ROW"),
12984 TriggerForEach::Statement => self.write_keyword("STATEMENT"),
12985 }
12986
12987 if let Some(when) = &ct.when {
12989 self.write_space();
12990 self.write_keyword("WHEN");
12991 self.write(" (");
12992 self.generate_expression(when)?;
12993 self.write(")");
12994 }
12995
12996 self.write_space();
12998 match &ct.body {
12999 TriggerBody::Execute { function, args } => {
13000 self.write_keyword("EXECUTE FUNCTION");
13001 self.write_space();
13002 self.generate_table(function)?;
13003 self.write("(");
13004 for (i, arg) in args.iter().enumerate() {
13005 if i > 0 {
13006 self.write(", ");
13007 }
13008 self.generate_expression(arg)?;
13009 }
13010 self.write(")");
13011 }
13012 TriggerBody::Block(block) => {
13013 self.write_keyword("BEGIN");
13014 self.write_space();
13015 self.write(block);
13016 self.write_space();
13017 self.write_keyword("END");
13018 }
13019 }
13020
13021 Ok(())
13022 }
13023
13024 fn generate_drop_trigger(&mut self, dt: &DropTrigger) -> Result<()> {
13025 self.write_keyword("DROP TRIGGER");
13026
13027 if dt.if_exists {
13028 self.write_space();
13029 self.write_keyword("IF EXISTS");
13030 }
13031
13032 self.write_space();
13033 self.generate_identifier(&dt.name)?;
13034
13035 if let Some(table) = &dt.table {
13036 self.write_space();
13037 self.write_keyword("ON");
13038 self.write_space();
13039 self.generate_table(table)?;
13040 }
13041
13042 if dt.cascade {
13043 self.write_space();
13044 self.write_keyword("CASCADE");
13045 }
13046
13047 Ok(())
13048 }
13049
13050 fn generate_create_type(&mut self, ct: &CreateType) -> Result<()> {
13051 self.write_keyword("CREATE TYPE");
13052
13053 if ct.if_not_exists {
13054 self.write_space();
13055 self.write_keyword("IF NOT EXISTS");
13056 }
13057
13058 self.write_space();
13059 self.generate_table(&ct.name)?;
13060
13061 self.write_space();
13062 self.write_keyword("AS");
13063 self.write_space();
13064
13065 match &ct.definition {
13066 TypeDefinition::Enum(values) => {
13067 self.write_keyword("ENUM");
13068 self.write(" (");
13069 for (i, val) in values.iter().enumerate() {
13070 if i > 0 {
13071 self.write(", ");
13072 }
13073 self.write(&format!("'{}'", val));
13074 }
13075 self.write(")");
13076 }
13077 TypeDefinition::Composite(attrs) => {
13078 self.write("(");
13079 for (i, attr) in attrs.iter().enumerate() {
13080 if i > 0 {
13081 self.write(", ");
13082 }
13083 self.generate_identifier(&attr.name)?;
13084 self.write_space();
13085 self.generate_data_type(&attr.data_type)?;
13086 if let Some(collate) = &attr.collate {
13087 self.write_space();
13088 self.write_keyword("COLLATE");
13089 self.write_space();
13090 self.generate_identifier(collate)?;
13091 }
13092 }
13093 self.write(")");
13094 }
13095 TypeDefinition::Range {
13096 subtype,
13097 subtype_diff,
13098 canonical,
13099 } => {
13100 self.write_keyword("RANGE");
13101 self.write(" (");
13102 self.write_keyword("SUBTYPE");
13103 self.write(" = ");
13104 self.generate_data_type(subtype)?;
13105 if let Some(diff) = subtype_diff {
13106 self.write(", ");
13107 self.write_keyword("SUBTYPE_DIFF");
13108 self.write(" = ");
13109 self.write(diff);
13110 }
13111 if let Some(canon) = canonical {
13112 self.write(", ");
13113 self.write_keyword("CANONICAL");
13114 self.write(" = ");
13115 self.write(canon);
13116 }
13117 self.write(")");
13118 }
13119 TypeDefinition::Base {
13120 input,
13121 output,
13122 internallength,
13123 } => {
13124 self.write("(");
13125 self.write_keyword("INPUT");
13126 self.write(" = ");
13127 self.write(input);
13128 self.write(", ");
13129 self.write_keyword("OUTPUT");
13130 self.write(" = ");
13131 self.write(output);
13132 if let Some(len) = internallength {
13133 self.write(", ");
13134 self.write_keyword("INTERNALLENGTH");
13135 self.write(" = ");
13136 self.write(&len.to_string());
13137 }
13138 self.write(")");
13139 }
13140 TypeDefinition::Domain {
13141 base_type,
13142 default,
13143 constraints,
13144 } => {
13145 self.generate_data_type(base_type)?;
13146 if let Some(def) = default {
13147 self.write_space();
13148 self.write_keyword("DEFAULT");
13149 self.write_space();
13150 self.generate_expression(def)?;
13151 }
13152 for constr in constraints {
13153 self.write_space();
13154 if let Some(name) = &constr.name {
13155 self.write_keyword("CONSTRAINT");
13156 self.write_space();
13157 self.generate_identifier(name)?;
13158 self.write_space();
13159 }
13160 self.write_keyword("CHECK");
13161 self.write(" (");
13162 self.generate_expression(&constr.check)?;
13163 self.write(")");
13164 }
13165 }
13166 }
13167
13168 Ok(())
13169 }
13170
13171 fn generate_drop_type(&mut self, dt: &DropType) -> Result<()> {
13172 self.write_keyword("DROP TYPE");
13173
13174 if dt.if_exists {
13175 self.write_space();
13176 self.write_keyword("IF EXISTS");
13177 }
13178
13179 self.write_space();
13180 self.generate_table(&dt.name)?;
13181
13182 if dt.cascade {
13183 self.write_space();
13184 self.write_keyword("CASCADE");
13185 }
13186
13187 Ok(())
13188 }
13189
13190 fn generate_describe(&mut self, d: &Describe) -> Result<()> {
13191 let saved_athena_hive_context = self.athena_hive_context;
13193 if matches!(
13194 self.config.dialect,
13195 Some(crate::dialects::DialectType::Athena)
13196 ) {
13197 self.athena_hive_context = true;
13198 }
13199
13200 for comment in &d.leading_comments {
13202 self.write_formatted_comment(comment);
13203 self.write(" ");
13204 }
13205
13206 self.write_keyword("DESCRIBE");
13207
13208 if d.extended {
13209 self.write_space();
13210 self.write_keyword("EXTENDED");
13211 } else if d.formatted {
13212 self.write_space();
13213 self.write_keyword("FORMATTED");
13214 }
13215
13216 if let Some(ref style) = d.style {
13218 self.write_space();
13219 self.write_keyword(style);
13220 }
13221
13222 let should_output_kind = match self.config.dialect {
13224 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
13226 false
13227 }
13228 Some(DialectType::Snowflake) => true,
13230 _ => d.kind.is_some(),
13231 };
13232 if should_output_kind {
13233 if let Some(ref kind) = d.kind {
13234 self.write_space();
13235 self.write_keyword(kind);
13236 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
13237 self.write_space();
13238 self.write_keyword("TABLE");
13239 }
13240 }
13241
13242 self.write_space();
13243 self.generate_expression(&d.target)?;
13244
13245 if let Some(ref partition) = d.partition {
13247 self.write_space();
13248 self.generate_expression(partition)?;
13249 }
13250
13251 if d.as_json {
13253 self.write_space();
13254 self.write_keyword("AS JSON");
13255 }
13256
13257 for (name, value) in &d.properties {
13259 self.write_space();
13260 self.write(name);
13261 self.write("=");
13262 self.write(value);
13263 }
13264
13265 self.athena_hive_context = saved_athena_hive_context;
13267
13268 Ok(())
13269 }
13270
13271 fn generate_show(&mut self, s: &Show) -> Result<()> {
13274 self.write_keyword("SHOW");
13275 self.write_space();
13276
13277 let show_terse = s.terse
13280 && !matches!(
13281 s.this.as_str(),
13282 "PRIMARY KEYS" | "UNIQUE KEYS" | "IMPORTED KEYS"
13283 );
13284 if show_terse {
13285 self.write_keyword("TERSE");
13286 self.write_space();
13287 }
13288
13289 self.write_keyword(&s.this);
13291
13292 if let Some(ref target_expr) = s.target {
13294 self.write_space();
13295 self.generate_expression(target_expr)?;
13296 }
13297
13298 if s.history {
13300 self.write_space();
13301 self.write_keyword("HISTORY");
13302 }
13303
13304 if let Some(ref for_target) = s.for_target {
13306 self.write_space();
13307 self.write_keyword("FOR");
13308 self.write_space();
13309 self.generate_expression(for_target)?;
13310 }
13311
13312 use crate::dialects::DialectType;
13316 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
13317
13318 if !is_snowflake && s.from.is_some() {
13319 if let Some(ref scope_kind) = s.scope_kind {
13323 self.write_space();
13324 self.write_keyword("IN");
13325 self.write_space();
13326 self.write_keyword(scope_kind);
13327 if let Some(ref scope) = s.scope {
13328 self.write_space();
13329 self.generate_expression(scope)?;
13330 }
13331 } else if let Some(ref scope) = s.scope {
13332 self.write_space();
13333 self.write_keyword("IN");
13334 self.write_space();
13335 self.generate_expression(scope)?;
13336 }
13337
13338 if let Some(ref from) = s.from {
13340 self.write_space();
13341 self.write_keyword("FROM");
13342 self.write_space();
13343 self.generate_expression(from)?;
13344 }
13345
13346 if let Some(ref db) = s.db {
13348 self.write_space();
13349 self.write_keyword("FROM");
13350 self.write_space();
13351 self.generate_expression(db)?;
13352 }
13353
13354 if let Some(ref like) = s.like {
13356 self.write_space();
13357 self.write_keyword("LIKE");
13358 self.write_space();
13359 self.generate_expression(like)?;
13360 }
13361 } else {
13362 if let Some(ref like) = s.like {
13366 self.write_space();
13367 self.write_keyword("LIKE");
13368 self.write_space();
13369 self.generate_expression(like)?;
13370 }
13371
13372 if let Some(ref scope_kind) = s.scope_kind {
13374 self.write_space();
13375 self.write_keyword("IN");
13376 self.write_space();
13377 self.write_keyword(scope_kind);
13378 if let Some(ref scope) = s.scope {
13379 self.write_space();
13380 self.generate_expression(scope)?;
13381 }
13382 } else if let Some(ref scope) = s.scope {
13383 self.write_space();
13384 self.write_keyword("IN");
13385 self.write_space();
13386 self.generate_expression(scope)?;
13387 }
13388 }
13389
13390 if let Some(ref starts_with) = s.starts_with {
13392 self.write_space();
13393 self.write_keyword("STARTS WITH");
13394 self.write_space();
13395 self.generate_expression(starts_with)?;
13396 }
13397
13398 if let Some(ref limit) = s.limit {
13400 self.write_space();
13401 self.generate_limit(limit)?;
13402 }
13403
13404 if is_snowflake {
13406 if let Some(ref from) = s.from {
13407 self.write_space();
13408 self.write_keyword("FROM");
13409 self.write_space();
13410 self.generate_expression(from)?;
13411 }
13412 }
13413
13414 if let Some(ref where_clause) = s.where_clause {
13416 self.write_space();
13417 self.write_keyword("WHERE");
13418 self.write_space();
13419 self.generate_expression(where_clause)?;
13420 }
13421
13422 if let Some(is_mutex) = s.mutex {
13424 self.write_space();
13425 if is_mutex {
13426 self.write_keyword("MUTEX");
13427 } else {
13428 self.write_keyword("STATUS");
13429 }
13430 }
13431
13432 if !s.privileges.is_empty() {
13434 self.write_space();
13435 self.write_keyword("WITH PRIVILEGES");
13436 self.write_space();
13437 for (i, priv_name) in s.privileges.iter().enumerate() {
13438 if i > 0 {
13439 self.write(", ");
13440 }
13441 self.write_keyword(priv_name);
13442 }
13443 }
13444
13445 Ok(())
13446 }
13447
13448 fn generate_literal(&mut self, lit: &Literal) -> Result<()> {
13451 use crate::dialects::DialectType;
13452 match lit {
13453 Literal::String(s) => {
13454 self.generate_string_literal(s)?;
13455 }
13456 Literal::Number(n) => {
13457 if matches!(self.config.dialect, Some(DialectType::MySQL))
13458 && n.len() > 2
13459 && (n.starts_with("0x") || n.starts_with("0X"))
13460 && !n[2..].chars().all(|c| c.is_ascii_hexdigit())
13461 {
13462 return self.generate_identifier(&Identifier {
13463 name: n.clone(),
13464 quoted: true,
13465 trailing_comments: Vec::new(),
13466 span: None,
13467 });
13468 }
13469 let n = if n.contains('_')
13473 && !matches!(
13474 self.config.dialect,
13475 Some(DialectType::ClickHouse)
13476 | Some(DialectType::DuckDB)
13477 | Some(DialectType::PostgreSQL)
13478 | Some(DialectType::Hive)
13479 | Some(DialectType::Spark)
13480 | Some(DialectType::Databricks)
13481 ) {
13482 std::borrow::Cow::Owned(n.replace('_', ""))
13483 } else {
13484 std::borrow::Cow::Borrowed(n.as_str())
13485 };
13486 if n.starts_with('.') {
13489 self.write("0");
13490 self.write(&n);
13491 } else if n.starts_with("-.") {
13492 self.write("-0");
13494 self.write(&n[1..]);
13495 } else {
13496 self.write(&n);
13497 }
13498 }
13499 Literal::HexString(h) => {
13500 match self.config.dialect {
13502 Some(DialectType::Spark)
13503 | Some(DialectType::Databricks)
13504 | Some(DialectType::Teradata) => self.write("X'"),
13505 _ => self.write("x'"),
13506 }
13507 self.write(h);
13508 self.write("'");
13509 }
13510 Literal::HexNumber(h) => {
13511 match self.config.dialect {
13515 Some(DialectType::BigQuery)
13516 | Some(DialectType::TSQL)
13517 | Some(DialectType::Fabric) => {
13518 self.write("0x");
13519 self.write(h);
13520 }
13521 _ => {
13522 if let Ok(val) = u64::from_str_radix(h, 16) {
13524 self.write(&val.to_string());
13525 } else {
13526 self.write("0x");
13528 self.write(h);
13529 }
13530 }
13531 }
13532 }
13533 Literal::BitString(b) => {
13534 self.write("B'");
13536 self.write(b);
13537 self.write("'");
13538 }
13539 Literal::ByteString(b) => {
13540 self.write("b'");
13542 self.write_escaped_byte_string(b);
13544 self.write("'");
13545 }
13546 Literal::NationalString(s) => {
13547 let keep_n_prefix = matches!(
13550 self.config.dialect,
13551 Some(DialectType::TSQL)
13552 | Some(DialectType::Oracle)
13553 | Some(DialectType::MySQL)
13554 | None
13555 );
13556 if keep_n_prefix {
13557 self.write("N'");
13558 } else {
13559 self.write("'");
13560 }
13561 self.write(s);
13562 self.write("'");
13563 }
13564 Literal::Date(d) => {
13565 self.generate_date_literal(d)?;
13566 }
13567 Literal::Time(t) => {
13568 self.generate_time_literal(t)?;
13569 }
13570 Literal::Timestamp(ts) => {
13571 self.generate_timestamp_literal(ts)?;
13572 }
13573 Literal::Datetime(dt) => {
13574 self.generate_datetime_literal(dt)?;
13575 }
13576 Literal::TripleQuotedString(s, _quote_char) => {
13577 if matches!(
13579 self.config.dialect,
13580 Some(crate::dialects::DialectType::BigQuery)
13581 | Some(crate::dialects::DialectType::DuckDB)
13582 | Some(crate::dialects::DialectType::Snowflake)
13583 | Some(crate::dialects::DialectType::Spark)
13584 | Some(crate::dialects::DialectType::Hive)
13585 | Some(crate::dialects::DialectType::Presto)
13586 | Some(crate::dialects::DialectType::Trino)
13587 | Some(crate::dialects::DialectType::PostgreSQL)
13588 | Some(crate::dialects::DialectType::MySQL)
13589 | Some(crate::dialects::DialectType::Redshift)
13590 | Some(crate::dialects::DialectType::TSQL)
13591 | Some(crate::dialects::DialectType::Oracle)
13592 | Some(crate::dialects::DialectType::ClickHouse)
13593 | Some(crate::dialects::DialectType::Databricks)
13594 | Some(crate::dialects::DialectType::SQLite)
13595 ) {
13596 self.generate_string_literal(s)?;
13597 } else {
13598 let quotes = format!("{0}{0}{0}", _quote_char);
13600 self.write("es);
13601 self.write(s);
13602 self.write("es);
13603 }
13604 }
13605 Literal::EscapeString(s) => {
13606 use crate::dialects::DialectType;
13610 let content = if let Some(c) = s.strip_prefix("e:") {
13611 c
13612 } else if let Some(c) = s.strip_prefix("E:") {
13613 c
13614 } else {
13615 s.as_str()
13616 };
13617
13618 if matches!(
13620 self.config.dialect,
13621 Some(DialectType::MySQL) | Some(DialectType::TiDB)
13622 ) {
13623 self.write(content);
13624 } else {
13625 let prefix = if matches!(
13627 self.config.dialect,
13628 Some(DialectType::SingleStore)
13629 | Some(DialectType::DuckDB)
13630 | Some(DialectType::PostgreSQL)
13631 | Some(DialectType::CockroachDB)
13632 | Some(DialectType::Materialize)
13633 | Some(DialectType::RisingWave)
13634 ) {
13635 "e'"
13636 } else {
13637 "E'"
13638 };
13639
13640 let normalized = content.replace("\\'", "''");
13642 self.write(prefix);
13643 self.write(&normalized);
13644 self.write("'");
13645 }
13646 }
13647 Literal::DollarString(s) => {
13648 use crate::dialects::DialectType;
13651 let (_tag, content) = crate::tokens::parse_dollar_string_token(s);
13653 let escape_backslash = matches!(self.config.dialect, Some(DialectType::Snowflake));
13655 let use_backslash_quote =
13659 matches!(self.config.dialect, Some(DialectType::Snowflake));
13660
13661 let mut escaped = String::with_capacity(content.len() + 4);
13662 for ch in content.chars() {
13663 if escape_backslash && ch == '\\' {
13664 escaped.push('\\');
13666 escaped.push('\\');
13667 } else if ch == '\'' {
13668 if use_backslash_quote {
13669 escaped.push('\\');
13670 escaped.push('\'');
13671 } else {
13672 escaped.push('\'');
13673 escaped.push('\'');
13674 }
13675 } else {
13676 escaped.push(ch);
13677 }
13678 }
13679 self.write("'");
13680 self.write(&escaped);
13681 self.write("'");
13682 }
13683 Literal::RawString(s) => {
13684 use crate::dialects::DialectType;
13690
13691 let escape_backslash = matches!(
13693 self.config.dialect,
13694 Some(DialectType::BigQuery)
13695 | Some(DialectType::MySQL)
13696 | Some(DialectType::SingleStore)
13697 | Some(DialectType::TiDB)
13698 | Some(DialectType::Hive)
13699 | Some(DialectType::Spark)
13700 | Some(DialectType::Databricks)
13701 | Some(DialectType::Drill)
13702 | Some(DialectType::Snowflake)
13703 | Some(DialectType::Redshift)
13704 | Some(DialectType::ClickHouse)
13705 );
13706
13707 let backslash_escapes_quote = matches!(
13710 self.config.dialect,
13711 Some(DialectType::BigQuery)
13712 | Some(DialectType::Hive)
13713 | Some(DialectType::Spark)
13714 | Some(DialectType::Databricks)
13715 | Some(DialectType::Drill)
13716 | Some(DialectType::Snowflake)
13717 | Some(DialectType::Redshift)
13718 );
13719
13720 let supports_escape_sequences = escape_backslash;
13723
13724 let mut escaped = String::with_capacity(s.len() + 4);
13725 for ch in s.chars() {
13726 if escape_backslash && ch == '\\' {
13727 escaped.push('\\');
13729 escaped.push('\\');
13730 } else if ch == '\'' {
13731 if backslash_escapes_quote {
13732 escaped.push('\\');
13734 escaped.push('\'');
13735 } else {
13736 escaped.push('\'');
13738 escaped.push('\'');
13739 }
13740 } else if supports_escape_sequences {
13741 match ch {
13744 '\n' => {
13745 escaped.push('\\');
13746 escaped.push('n');
13747 }
13748 '\r' => {
13749 escaped.push('\\');
13750 escaped.push('r');
13751 }
13752 '\t' => {
13753 escaped.push('\\');
13754 escaped.push('t');
13755 }
13756 '\x07' => {
13757 escaped.push('\\');
13758 escaped.push('a');
13759 }
13760 '\x08' => {
13761 escaped.push('\\');
13762 escaped.push('b');
13763 }
13764 '\x0C' => {
13765 escaped.push('\\');
13766 escaped.push('f');
13767 }
13768 '\x0B' => {
13769 escaped.push('\\');
13770 escaped.push('v');
13771 }
13772 _ => escaped.push(ch),
13773 }
13774 } else {
13775 escaped.push(ch);
13776 }
13777 }
13778 self.write("'");
13779 self.write(&escaped);
13780 self.write("'");
13781 }
13782 }
13783 Ok(())
13784 }
13785
13786 fn generate_date_literal(&mut self, d: &str) -> Result<()> {
13788 use crate::dialects::DialectType;
13789
13790 match self.config.dialect {
13791 Some(DialectType::TSQL) => {
13793 self.write("CAST('");
13794 self.write(d);
13795 self.write("' AS DATE)");
13796 }
13797 Some(DialectType::BigQuery) => {
13800 self.write("CAST('");
13801 self.write(d);
13802 self.write("' AS DATE)");
13803 }
13804 Some(DialectType::Exasol) => {
13807 self.write("CAST('");
13808 self.write(d);
13809 self.write("' AS DATE)");
13810 }
13811 Some(DialectType::Snowflake) => {
13814 self.write("CAST('");
13815 self.write(d);
13816 self.write("' AS DATE)");
13817 }
13818 Some(DialectType::PostgreSQL)
13820 | Some(DialectType::MySQL)
13821 | Some(DialectType::SingleStore)
13822 | Some(DialectType::TiDB)
13823 | Some(DialectType::Redshift) => {
13824 self.write("CAST('");
13825 self.write(d);
13826 self.write("' AS DATE)");
13827 }
13828 Some(DialectType::DuckDB)
13830 | Some(DialectType::Presto)
13831 | Some(DialectType::Trino)
13832 | Some(DialectType::Athena)
13833 | Some(DialectType::Spark)
13834 | Some(DialectType::Databricks)
13835 | Some(DialectType::Hive) => {
13836 self.write("CAST('");
13837 self.write(d);
13838 self.write("' AS DATE)");
13839 }
13840 Some(DialectType::Oracle) => {
13842 self.write("TO_DATE('");
13843 self.write(d);
13844 self.write("', 'YYYY-MM-DD')");
13845 }
13846 _ => {
13848 self.write_keyword("DATE");
13849 self.write(" '");
13850 self.write(d);
13851 self.write("'");
13852 }
13853 }
13854 Ok(())
13855 }
13856
13857 fn generate_time_literal(&mut self, t: &str) -> Result<()> {
13859 use crate::dialects::DialectType;
13860
13861 match self.config.dialect {
13862 Some(DialectType::TSQL) => {
13864 self.write("CAST('");
13865 self.write(t);
13866 self.write("' AS TIME)");
13867 }
13868 _ => {
13870 self.write_keyword("TIME");
13871 self.write(" '");
13872 self.write(t);
13873 self.write("'");
13874 }
13875 }
13876 Ok(())
13877 }
13878
13879 fn generate_dremio_date_expression(&mut self, expr: &Expression) -> Result<()> {
13881 use crate::expressions::Literal;
13882
13883 match expr {
13884 Expression::Literal(Literal::Date(d)) => {
13885 self.write("CAST('");
13887 self.write(d);
13888 self.write("' AS DATE)");
13889 }
13890 _ => {
13891 self.generate_expression(expr)?;
13893 }
13894 }
13895 Ok(())
13896 }
13897
13898 fn generate_timestamp_literal(&mut self, ts: &str) -> Result<()> {
13900 use crate::dialects::DialectType;
13901
13902 match self.config.dialect {
13903 Some(DialectType::TSQL) => {
13905 self.write("CAST('");
13906 self.write(ts);
13907 self.write("' AS DATETIME2)");
13908 }
13909 Some(DialectType::BigQuery) => {
13912 self.write("CAST('");
13913 self.write(ts);
13914 self.write("' AS TIMESTAMP)");
13915 }
13916 Some(DialectType::Snowflake) => {
13919 self.write("CAST('");
13920 self.write(ts);
13921 self.write("' AS TIMESTAMP)");
13922 }
13923 Some(DialectType::Dremio) => {
13926 self.write("CAST('");
13927 self.write(ts);
13928 self.write("' AS TIMESTAMP)");
13929 }
13930 Some(DialectType::Exasol) => {
13933 self.write("CAST('");
13934 self.write(ts);
13935 self.write("' AS TIMESTAMP)");
13936 }
13937 Some(DialectType::Oracle) => {
13940 self.write("TO_TIMESTAMP('");
13941 self.write(ts);
13942 self.write("', 'YYYY-MM-DD HH24:MI:SS.FF6')");
13943 }
13944 Some(DialectType::Presto) | Some(DialectType::Trino) => {
13946 if Self::timestamp_has_timezone(ts) {
13947 self.write("CAST('");
13948 self.write(ts);
13949 self.write("' AS TIMESTAMP WITH TIME ZONE)");
13950 } else {
13951 self.write("CAST('");
13952 self.write(ts);
13953 self.write("' AS TIMESTAMP)");
13954 }
13955 }
13956 Some(DialectType::ClickHouse) => {
13958 self.write("CAST('");
13959 self.write(ts);
13960 self.write("' AS Nullable(DateTime))");
13961 }
13962 Some(DialectType::Spark) => {
13964 self.write("CAST('");
13965 self.write(ts);
13966 self.write("' AS TIMESTAMP)");
13967 }
13968 Some(DialectType::Redshift) => {
13971 if ts == "epoch" {
13972 self.write_keyword("TIMESTAMP");
13973 self.write(" '");
13974 self.write(ts);
13975 self.write("'");
13976 } else {
13977 self.write("CAST('");
13978 self.write(ts);
13979 self.write("' AS TIMESTAMP)");
13980 }
13981 }
13982 Some(DialectType::PostgreSQL)
13984 | Some(DialectType::Hive)
13985 | Some(DialectType::SQLite)
13986 | Some(DialectType::DuckDB)
13987 | Some(DialectType::Athena)
13988 | Some(DialectType::Drill)
13989 | Some(DialectType::Teradata) => {
13990 self.write("CAST('");
13991 self.write(ts);
13992 self.write("' AS TIMESTAMP)");
13993 }
13994 Some(DialectType::MySQL) | Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
13996 self.write("CAST('");
13997 self.write(ts);
13998 self.write("' AS DATETIME)");
13999 }
14000 Some(DialectType::Databricks) => {
14002 self.write("CAST('");
14003 self.write(ts);
14004 self.write("' AS TIMESTAMP_NTZ)");
14005 }
14006 _ => {
14008 self.write_keyword("TIMESTAMP");
14009 self.write(" '");
14010 self.write(ts);
14011 self.write("'");
14012 }
14013 }
14014 Ok(())
14015 }
14016
14017 fn timestamp_has_timezone(ts: &str) -> bool {
14020 let ts_lower = ts.to_lowercase();
14024
14025 let continent_prefixes = [
14027 "africa/",
14028 "america/",
14029 "antarctica/",
14030 "arctic/",
14031 "asia/",
14032 "atlantic/",
14033 "australia/",
14034 "europe/",
14035 "indian/",
14036 "pacific/",
14037 "etc/",
14038 "brazil/",
14039 "canada/",
14040 "chile/",
14041 "mexico/",
14042 "us/",
14043 ];
14044
14045 for prefix in &continent_prefixes {
14046 if ts_lower.contains(prefix) {
14047 return true;
14048 }
14049 }
14050
14051 let tz_abbrevs = [
14054 " utc", " gmt", " cet", " cest", " eet", " eest", " wet", " west", " est", " edt",
14055 " cst", " cdt", " mst", " mdt", " pst", " pdt", " ist", " bst", " jst", " kst", " hkt",
14056 " sgt", " aest", " aedt", " acst", " acdt", " awst",
14057 ];
14058
14059 for abbrev in &tz_abbrevs {
14060 if ts_lower.ends_with(abbrev) {
14061 return true;
14062 }
14063 }
14064
14065 let trimmed = ts.trim();
14069 if let Some(last_space) = trimmed.rfind(' ') {
14070 let suffix = &trimmed[last_space + 1..];
14071 if (suffix.starts_with('+') || suffix.starts_with('-')) && suffix.len() > 1 {
14072 let rest = &suffix[1..];
14074 if rest.chars().all(|c| c.is_ascii_digit() || c == ':') {
14075 return true;
14076 }
14077 }
14078 }
14079
14080 false
14081 }
14082
14083 fn generate_datetime_literal(&mut self, dt: &str) -> Result<()> {
14085 use crate::dialects::DialectType;
14086
14087 match self.config.dialect {
14088 Some(DialectType::BigQuery) => {
14091 self.write("CAST('");
14092 self.write(dt);
14093 self.write("' AS DATETIME)");
14094 }
14095 Some(DialectType::DuckDB) => {
14097 self.write("CAST('");
14098 self.write(dt);
14099 self.write("' AS TIMESTAMP)");
14100 }
14101 _ => {
14104 self.write_keyword("DATETIME");
14105 self.write(" '");
14106 self.write(dt);
14107 self.write("'");
14108 }
14109 }
14110 Ok(())
14111 }
14112
14113 fn generate_string_literal(&mut self, s: &str) -> Result<()> {
14115 use crate::dialects::DialectType;
14116
14117 match self.config.dialect {
14118 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
14122 self.write("'");
14124 for c in s.chars() {
14125 match c {
14126 '\'' => self.write("\\'"),
14127 '\\' => self.write("\\\\"),
14128 '\n' => self.write("\\n"),
14129 '\r' => self.write("\\r"),
14130 '\t' => self.write("\\t"),
14131 '\0' => self.write("\\0"),
14132 _ => self.output.push(c),
14133 }
14134 }
14135 self.write("'");
14136 }
14137 Some(DialectType::Drill) => {
14138 self.write("'");
14141 for c in s.chars() {
14142 match c {
14143 '\'' => self.write("''"),
14144 '\\' => self.write("\\\\"),
14145 '\n' => self.write("\\n"),
14146 '\r' => self.write("\\r"),
14147 '\t' => self.write("\\t"),
14148 '\0' => self.write("\\0"),
14149 _ => self.output.push(c),
14150 }
14151 }
14152 self.write("'");
14153 }
14154 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB) => {
14155 self.write("'");
14156 for c in s.chars() {
14157 match c {
14158 '\'' => self.write("''"),
14160 '\\' => self.write("\\\\"),
14161 '\n' => self.write("\\n"),
14162 '\r' => self.write("\\r"),
14163 '\t' => self.write("\\t"),
14164 '\0' => self.output.push('\0'),
14166 _ => self.output.push(c),
14167 }
14168 }
14169 self.write("'");
14170 }
14171 Some(DialectType::BigQuery) => {
14173 self.write("'");
14174 for c in s.chars() {
14175 match c {
14176 '\'' => self.write("\\'"),
14177 '\\' => self.write("\\\\"),
14178 '\n' => self.write("\\n"),
14179 '\r' => self.write("\\r"),
14180 '\t' => self.write("\\t"),
14181 '\0' => self.write("\\0"),
14182 '\x07' => self.write("\\a"),
14183 '\x08' => self.write("\\b"),
14184 '\x0C' => self.write("\\f"),
14185 '\x0B' => self.write("\\v"),
14186 _ => self.output.push(c),
14187 }
14188 }
14189 self.write("'");
14190 }
14191 Some(DialectType::Athena) => {
14195 if self.athena_hive_context {
14196 self.write("'");
14198 for c in s.chars() {
14199 match c {
14200 '\'' => self.write("\\'"),
14201 '\\' => self.write("\\\\"),
14202 '\n' => self.write("\\n"),
14203 '\r' => self.write("\\r"),
14204 '\t' => self.write("\\t"),
14205 '\0' => self.write("\\0"),
14206 _ => self.output.push(c),
14207 }
14208 }
14209 self.write("'");
14210 } else {
14211 self.write("'");
14213 for c in s.chars() {
14214 match c {
14215 '\'' => self.write("''"),
14216 _ => self.output.push(c),
14218 }
14219 }
14220 self.write("'");
14221 }
14222 }
14223 Some(DialectType::Snowflake) => {
14228 self.write("'");
14229 for c in s.chars() {
14230 match c {
14231 '\'' => self.write("\\'"),
14232 '\n' => self.write("\\n"),
14235 '\r' => self.write("\\r"),
14236 '\t' => self.write("\\t"),
14237 _ => self.output.push(c),
14238 }
14239 }
14240 self.write("'");
14241 }
14242 Some(DialectType::PostgreSQL) => {
14244 self.write("'");
14245 for c in s.chars() {
14246 match c {
14247 '\'' => self.write("''"),
14248 _ => self.output.push(c),
14249 }
14250 }
14251 self.write("'");
14252 }
14253 Some(DialectType::Redshift) => {
14255 self.write("'");
14256 for c in s.chars() {
14257 match c {
14258 '\'' => self.write("\\'"),
14259 _ => self.output.push(c),
14260 }
14261 }
14262 self.write("'");
14263 }
14264 Some(DialectType::Oracle) => {
14266 self.write("'");
14267 self.write(&s.replace('\'', "''"));
14268 self.write("'");
14269 }
14270 Some(DialectType::ClickHouse) => {
14273 self.write("'");
14274 for c in s.chars() {
14275 match c {
14276 '\'' => self.write("''"),
14277 '\\' => self.write("\\\\"),
14278 '\n' => self.write("\\n"),
14279 '\r' => self.write("\\r"),
14280 '\t' => self.write("\\t"),
14281 '\0' => self.write("\\0"),
14282 '\x07' => self.write("\\a"),
14283 '\x08' => self.write("\\b"),
14284 '\x0C' => self.write("\\f"),
14285 '\x0B' => self.write("\\v"),
14286 c if c.is_control() || (c as u32) < 0x20 => {
14288 let byte = c as u32;
14289 if byte < 256 {
14290 self.write(&format!("\\x{:02X}", byte));
14291 } else {
14292 self.output.push(c);
14293 }
14294 }
14295 _ => self.output.push(c),
14296 }
14297 }
14298 self.write("'");
14299 }
14300 _ => {
14303 self.write("'");
14304 self.write(&s.replace('\'', "''"));
14305 self.write("'");
14306 }
14307 }
14308 Ok(())
14309 }
14310
14311 fn write_escaped_byte_string(&mut self, s: &str) {
14314 for c in s.chars() {
14315 match c {
14316 '\'' => self.write("\\'"),
14318 '\\' => self.write("\\\\"),
14320 _ if !c.is_control() => self.output.push(c),
14322 _ => {
14324 let byte = c as u32;
14325 if byte < 256 {
14326 self.write(&format!("\\x{:02x}", byte));
14327 } else {
14328 for b in c.to_string().as_bytes() {
14330 self.write(&format!("\\x{:02x}", b));
14331 }
14332 }
14333 }
14334 }
14335 }
14336 }
14337
14338 fn generate_boolean(&mut self, b: &BooleanLiteral) -> Result<()> {
14339 use crate::dialects::DialectType;
14340
14341 match self.config.dialect {
14343 Some(DialectType::TSQL) => {
14346 self.write(if b.value { "1" } else { "0" });
14347 }
14348 Some(DialectType::Oracle) => {
14350 self.write(if b.value { "1" } else { "0" });
14351 }
14352 Some(DialectType::MySQL) => {
14354 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
14355 }
14356 _ => {
14358 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
14359 }
14360 }
14361 Ok(())
14362 }
14363
14364 fn generate_alias_identifier(&mut self, id: &Identifier) -> Result<()> {
14367 let name = &id.name;
14368 let quote_style = &self.config.identifier_quote_style;
14369
14370 let needs_quoting = id.quoted || self.is_reserved_keyword(name);
14374
14375 let output_name = if self.config.normalize_identifiers && !id.quoted {
14377 name.to_lowercase()
14378 } else {
14379 name.to_string()
14380 };
14381
14382 if needs_quoting {
14383 let escaped_name = if quote_style.start == quote_style.end {
14385 output_name.replace(
14386 quote_style.end,
14387 &format!("{}{}", quote_style.end, quote_style.end),
14388 )
14389 } else {
14390 output_name.replace(
14391 quote_style.end,
14392 &format!("{}{}", quote_style.end, quote_style.end),
14393 )
14394 };
14395 self.write(&format!(
14396 "{}{}{}",
14397 quote_style.start, escaped_name, quote_style.end
14398 ));
14399 } else {
14400 self.write(&output_name);
14401 }
14402
14403 for comment in &id.trailing_comments {
14405 self.write(" ");
14406 self.write_formatted_comment(comment);
14407 }
14408 Ok(())
14409 }
14410
14411 fn generate_identifier(&mut self, id: &Identifier) -> Result<()> {
14412 use crate::dialects::DialectType;
14413
14414 let name = &id.name;
14415
14416 let quote_style = if matches!(self.config.dialect, Some(DialectType::Athena))
14418 && self.athena_hive_context
14419 {
14420 &IdentifierQuoteStyle::BACKTICK
14421 } else {
14422 &self.config.identifier_quote_style
14423 };
14424
14425 let starts_with_digit = name.chars().next().map_or(false, |c| c.is_ascii_digit());
14432 let needs_digit_quoting = starts_with_digit
14433 && !self.config.identifiers_can_start_with_digit
14434 && self.config.dialect.is_some();
14435 let mysql_invalid_hex_identifier = matches!(self.config.dialect, Some(DialectType::MySQL))
14436 && name.len() > 2
14437 && (name.starts_with("0x") || name.starts_with("0X"))
14438 && !name[2..].chars().all(|c| c.is_ascii_hexdigit());
14439 let needs_quoting = id.quoted
14440 || self.is_reserved_keyword(name)
14441 || self.config.always_quote_identifiers
14442 || needs_digit_quoting
14443 || mysql_invalid_hex_identifier;
14444
14445 let (base_name, suffix) = if needs_quoting {
14448 if let Some(paren_pos) = name.find('(') {
14450 let base = &name[..paren_pos];
14451 let rest = &name[paren_pos..];
14452 if rest.starts_with('(')
14454 && (rest.ends_with(')') || rest.ends_with(") ASC") || rest.ends_with(") DESC"))
14455 {
14456 let close_paren = rest.find(')').unwrap_or(rest.len());
14458 let inside = &rest[1..close_paren];
14459 if inside.chars().all(|c| c.is_ascii_digit()) {
14460 (base.to_string(), rest.to_string())
14461 } else {
14462 (name.to_string(), String::new())
14463 }
14464 } else {
14465 (name.to_string(), String::new())
14466 }
14467 } else if name.ends_with(" ASC") {
14468 let base = &name[..name.len() - 4];
14469 (base.to_string(), " ASC".to_string())
14470 } else if name.ends_with(" DESC") {
14471 let base = &name[..name.len() - 5];
14472 (base.to_string(), " DESC".to_string())
14473 } else {
14474 (name.to_string(), String::new())
14475 }
14476 } else {
14477 (name.to_string(), String::new())
14478 };
14479
14480 let output_name = if self.config.normalize_identifiers && !id.quoted {
14484 base_name.to_lowercase()
14485 } else if matches!(self.config.dialect, Some(DialectType::Exasol))
14486 && !id.quoted
14487 && self.is_reserved_keyword(name)
14488 {
14489 base_name.to_uppercase()
14492 } else {
14493 base_name
14494 };
14495
14496 if needs_quoting {
14497 let escaped_name = if quote_style.start == quote_style.end {
14499 output_name.replace(
14501 quote_style.end,
14502 &format!("{}{}", quote_style.end, quote_style.end),
14503 )
14504 } else {
14505 output_name.replace(
14507 quote_style.end,
14508 &format!("{}{}", quote_style.end, quote_style.end),
14509 )
14510 };
14511 self.write(&format!(
14512 "{}{}{}{}",
14513 quote_style.start, escaped_name, quote_style.end, suffix
14514 ));
14515 } else {
14516 self.write(&output_name);
14517 }
14518
14519 for comment in &id.trailing_comments {
14521 self.write(" ");
14522 self.write_formatted_comment(comment);
14523 }
14524 Ok(())
14525 }
14526
14527 fn generate_column(&mut self, col: &Column) -> Result<()> {
14528 use crate::dialects::DialectType;
14529
14530 if let Some(table) = &col.table {
14531 let is_exasol_local_prefix = matches!(self.config.dialect, Some(DialectType::Exasol))
14535 && !table.quoted
14536 && table.name.eq_ignore_ascii_case("LOCAL");
14537
14538 if is_exasol_local_prefix {
14539 self.write("LOCAL");
14541 } else {
14542 self.generate_identifier(table)?;
14543 }
14544 self.write(".");
14545 }
14546 self.generate_identifier(&col.name)?;
14547 if col.join_mark && self.config.supports_column_join_marks {
14550 self.write(" (+)");
14551 }
14552 for comment in &col.trailing_comments {
14554 self.write_space();
14555 self.write_formatted_comment(comment);
14556 }
14557 Ok(())
14558 }
14559
14560 fn generate_pseudocolumn(&mut self, pc: &Pseudocolumn) -> Result<()> {
14563 use crate::dialects::DialectType;
14564 use crate::expressions::PseudocolumnType;
14565
14566 if pc.kind == PseudocolumnType::Sysdate
14568 && !matches!(
14569 self.config.dialect,
14570 Some(DialectType::Oracle) | Some(DialectType::Redshift) | None
14571 )
14572 {
14573 self.write_keyword("CURRENT_TIMESTAMP");
14574 if matches!(
14576 self.config.dialect,
14577 Some(DialectType::MySQL)
14578 | Some(DialectType::ClickHouse)
14579 | Some(DialectType::Spark)
14580 | Some(DialectType::Databricks)
14581 | Some(DialectType::Hive)
14582 ) {
14583 self.write("()");
14584 }
14585 } else {
14586 self.write(pc.kind.as_str());
14587 }
14588 Ok(())
14589 }
14590
14591 fn generate_connect(&mut self, connect: &Connect) -> Result<()> {
14593 use crate::dialects::DialectType;
14594
14595 let supports_connect_by = matches!(
14598 self.config.dialect,
14599 Some(DialectType::Oracle) | Some(DialectType::Snowflake)
14600 );
14601
14602 if !supports_connect_by && self.config.dialect.is_some() {
14603 if self.config.pretty {
14605 self.write_newline();
14606 } else {
14607 self.write_space();
14608 }
14609 self.write_unsupported_comment(
14610 "CONNECT BY requires manual conversion to recursive CTE",
14611 )?;
14612 }
14613
14614 if let Some(start) = &connect.start {
14616 if self.config.pretty {
14617 self.write_newline();
14618 } else {
14619 self.write_space();
14620 }
14621 self.write_keyword("START WITH");
14622 self.write_space();
14623 self.generate_expression(start)?;
14624 }
14625
14626 if self.config.pretty {
14628 self.write_newline();
14629 } else {
14630 self.write_space();
14631 }
14632 self.write_keyword("CONNECT BY");
14633 if connect.nocycle {
14634 self.write_space();
14635 self.write_keyword("NOCYCLE");
14636 }
14637 self.write_space();
14638 self.generate_expression(&connect.connect)?;
14639
14640 Ok(())
14641 }
14642
14643 fn generate_connect_expr(&mut self, connect: &Connect) -> Result<()> {
14645 self.generate_connect(connect)
14646 }
14647
14648 fn generate_prior(&mut self, prior: &Prior) -> Result<()> {
14650 self.write_keyword("PRIOR");
14651 self.write_space();
14652 self.generate_expression(&prior.this)?;
14653 Ok(())
14654 }
14655
14656 fn generate_connect_by_root(&mut self, cbr: &ConnectByRoot) -> Result<()> {
14659 self.write_keyword("CONNECT_BY_ROOT");
14660 self.write_space();
14661 self.generate_expression(&cbr.this)?;
14662 Ok(())
14663 }
14664
14665 fn generate_match_recognize(&mut self, mr: &MatchRecognize) -> Result<()> {
14667 use crate::dialects::DialectType;
14668
14669 let supports_match_recognize = matches!(
14671 self.config.dialect,
14672 Some(DialectType::Oracle)
14673 | Some(DialectType::Snowflake)
14674 | Some(DialectType::Presto)
14675 | Some(DialectType::Trino)
14676 );
14677
14678 if let Some(source) = &mr.this {
14680 self.generate_expression(source)?;
14681 }
14682
14683 if !supports_match_recognize {
14684 self.write_unsupported_comment("MATCH_RECOGNIZE not supported in this dialect")?;
14685 return Ok(());
14686 }
14687
14688 if self.config.pretty {
14690 self.write_newline();
14691 } else {
14692 self.write_space();
14693 }
14694
14695 self.write_keyword("MATCH_RECOGNIZE");
14696 self.write(" (");
14697
14698 if self.config.pretty {
14699 self.indent_level += 1;
14700 }
14701
14702 let mut needs_separator = false;
14703
14704 if let Some(partition_by) = &mr.partition_by {
14706 if !partition_by.is_empty() {
14707 if self.config.pretty {
14708 self.write_newline();
14709 self.write_indent();
14710 }
14711 self.write_keyword("PARTITION BY");
14712 self.write_space();
14713 for (i, expr) in partition_by.iter().enumerate() {
14714 if i > 0 {
14715 self.write(", ");
14716 }
14717 self.generate_expression(expr)?;
14718 }
14719 needs_separator = true;
14720 }
14721 }
14722
14723 if let Some(order_by) = &mr.order_by {
14725 if !order_by.is_empty() {
14726 if needs_separator {
14727 if self.config.pretty {
14728 self.write_newline();
14729 self.write_indent();
14730 } else {
14731 self.write_space();
14732 }
14733 } else if self.config.pretty {
14734 self.write_newline();
14735 self.write_indent();
14736 }
14737 self.write_keyword("ORDER BY");
14738 if self.config.pretty {
14740 self.indent_level += 1;
14741 for (i, ordered) in order_by.iter().enumerate() {
14742 if i > 0 {
14743 self.write(",");
14744 }
14745 self.write_newline();
14746 self.write_indent();
14747 self.generate_ordered(ordered)?;
14748 }
14749 self.indent_level -= 1;
14750 } else {
14751 self.write_space();
14752 for (i, ordered) in order_by.iter().enumerate() {
14753 if i > 0 {
14754 self.write(", ");
14755 }
14756 self.generate_ordered(ordered)?;
14757 }
14758 }
14759 needs_separator = true;
14760 }
14761 }
14762
14763 if let Some(measures) = &mr.measures {
14765 if !measures.is_empty() {
14766 if needs_separator {
14767 if self.config.pretty {
14768 self.write_newline();
14769 self.write_indent();
14770 } else {
14771 self.write_space();
14772 }
14773 } else if self.config.pretty {
14774 self.write_newline();
14775 self.write_indent();
14776 }
14777 self.write_keyword("MEASURES");
14778 if self.config.pretty {
14780 self.indent_level += 1;
14781 for (i, measure) in measures.iter().enumerate() {
14782 if i > 0 {
14783 self.write(",");
14784 }
14785 self.write_newline();
14786 self.write_indent();
14787 if let Some(semantics) = &measure.window_frame {
14789 match semantics {
14790 MatchRecognizeSemantics::Running => {
14791 self.write_keyword("RUNNING");
14792 self.write_space();
14793 }
14794 MatchRecognizeSemantics::Final => {
14795 self.write_keyword("FINAL");
14796 self.write_space();
14797 }
14798 }
14799 }
14800 self.generate_expression(&measure.this)?;
14801 }
14802 self.indent_level -= 1;
14803 } else {
14804 self.write_space();
14805 for (i, measure) in measures.iter().enumerate() {
14806 if i > 0 {
14807 self.write(", ");
14808 }
14809 if let Some(semantics) = &measure.window_frame {
14811 match semantics {
14812 MatchRecognizeSemantics::Running => {
14813 self.write_keyword("RUNNING");
14814 self.write_space();
14815 }
14816 MatchRecognizeSemantics::Final => {
14817 self.write_keyword("FINAL");
14818 self.write_space();
14819 }
14820 }
14821 }
14822 self.generate_expression(&measure.this)?;
14823 }
14824 }
14825 needs_separator = true;
14826 }
14827 }
14828
14829 if let Some(rows) = &mr.rows {
14831 if needs_separator {
14832 if self.config.pretty {
14833 self.write_newline();
14834 self.write_indent();
14835 } else {
14836 self.write_space();
14837 }
14838 } else if self.config.pretty {
14839 self.write_newline();
14840 self.write_indent();
14841 }
14842 match rows {
14843 MatchRecognizeRows::OneRowPerMatch => {
14844 self.write_keyword("ONE ROW PER MATCH");
14845 }
14846 MatchRecognizeRows::AllRowsPerMatch => {
14847 self.write_keyword("ALL ROWS PER MATCH");
14848 }
14849 MatchRecognizeRows::AllRowsPerMatchShowEmptyMatches => {
14850 self.write_keyword("ALL ROWS PER MATCH SHOW EMPTY MATCHES");
14851 }
14852 MatchRecognizeRows::AllRowsPerMatchOmitEmptyMatches => {
14853 self.write_keyword("ALL ROWS PER MATCH OMIT EMPTY MATCHES");
14854 }
14855 MatchRecognizeRows::AllRowsPerMatchWithUnmatchedRows => {
14856 self.write_keyword("ALL ROWS PER MATCH WITH UNMATCHED ROWS");
14857 }
14858 }
14859 needs_separator = true;
14860 }
14861
14862 if let Some(after) = &mr.after {
14864 if needs_separator {
14865 if self.config.pretty {
14866 self.write_newline();
14867 self.write_indent();
14868 } else {
14869 self.write_space();
14870 }
14871 } else if self.config.pretty {
14872 self.write_newline();
14873 self.write_indent();
14874 }
14875 match after {
14876 MatchRecognizeAfter::PastLastRow => {
14877 self.write_keyword("AFTER MATCH SKIP PAST LAST ROW");
14878 }
14879 MatchRecognizeAfter::ToNextRow => {
14880 self.write_keyword("AFTER MATCH SKIP TO NEXT ROW");
14881 }
14882 MatchRecognizeAfter::ToFirst(ident) => {
14883 self.write_keyword("AFTER MATCH SKIP TO FIRST");
14884 self.write_space();
14885 self.generate_identifier(ident)?;
14886 }
14887 MatchRecognizeAfter::ToLast(ident) => {
14888 self.write_keyword("AFTER MATCH SKIP TO LAST");
14889 self.write_space();
14890 self.generate_identifier(ident)?;
14891 }
14892 }
14893 needs_separator = true;
14894 }
14895
14896 if let Some(pattern) = &mr.pattern {
14898 if needs_separator {
14899 if self.config.pretty {
14900 self.write_newline();
14901 self.write_indent();
14902 } else {
14903 self.write_space();
14904 }
14905 } else if self.config.pretty {
14906 self.write_newline();
14907 self.write_indent();
14908 }
14909 self.write_keyword("PATTERN");
14910 self.write_space();
14911 self.write("(");
14912 self.write(pattern);
14913 self.write(")");
14914 needs_separator = true;
14915 }
14916
14917 if let Some(define) = &mr.define {
14919 if !define.is_empty() {
14920 if needs_separator {
14921 if self.config.pretty {
14922 self.write_newline();
14923 self.write_indent();
14924 } else {
14925 self.write_space();
14926 }
14927 } else if self.config.pretty {
14928 self.write_newline();
14929 self.write_indent();
14930 }
14931 self.write_keyword("DEFINE");
14932 if self.config.pretty {
14934 self.indent_level += 1;
14935 for (i, (name, expr)) in define.iter().enumerate() {
14936 if i > 0 {
14937 self.write(",");
14938 }
14939 self.write_newline();
14940 self.write_indent();
14941 self.generate_identifier(name)?;
14942 self.write(" AS ");
14943 self.generate_expression(expr)?;
14944 }
14945 self.indent_level -= 1;
14946 } else {
14947 self.write_space();
14948 for (i, (name, expr)) in define.iter().enumerate() {
14949 if i > 0 {
14950 self.write(", ");
14951 }
14952 self.generate_identifier(name)?;
14953 self.write(" AS ");
14954 self.generate_expression(expr)?;
14955 }
14956 }
14957 }
14958 }
14959
14960 if self.config.pretty {
14961 self.indent_level -= 1;
14962 self.write_newline();
14963 }
14964 self.write(")");
14965
14966 if let Some(alias) = &mr.alias {
14968 self.write(" ");
14969 if mr.alias_explicit_as {
14970 self.write_keyword("AS");
14971 self.write(" ");
14972 }
14973 self.generate_identifier(alias)?;
14974 }
14975
14976 Ok(())
14977 }
14978
14979 fn generate_hint(&mut self, hint: &Hint) -> Result<()> {
14981 use crate::dialects::DialectType;
14982
14983 let supports_hints = matches!(
14985 self.config.dialect,
14986 None | Some(DialectType::Oracle) | Some(DialectType::MySQL) |
14988 Some(DialectType::Spark) | Some(DialectType::Hive) |
14989 Some(DialectType::Databricks) | Some(DialectType::PostgreSQL)
14990 );
14991
14992 if !supports_hints || hint.expressions.is_empty() {
14993 return Ok(());
14994 }
14995
14996 let mut hint_strings: Vec<String> = Vec::new();
14999 for expr in &hint.expressions {
15000 match expr {
15001 HintExpression::Raw(text) => {
15002 let parsed = self.parse_raw_hint_text(text);
15004 hint_strings.extend(parsed);
15005 }
15006 _ => {
15007 hint_strings.push(self.hint_expression_to_string(expr)?);
15008 }
15009 }
15010 }
15011
15012 let use_multiline = self.config.pretty && hint_strings.len() > 1;
15016
15017 if use_multiline {
15018 self.write(" /*+ ");
15020 for (i, hint_str) in hint_strings.iter().enumerate() {
15021 if i > 0 {
15022 self.write_newline();
15023 self.write(" "); }
15025 self.write(hint_str);
15026 }
15027 self.write(" */");
15028 } else {
15029 self.write(" /*+ ");
15031 let sep = match self.config.dialect {
15032 Some(DialectType::Spark) | Some(DialectType::Databricks) => ", ",
15033 _ => " ",
15034 };
15035 for (i, hint_str) in hint_strings.iter().enumerate() {
15036 if i > 0 {
15037 self.write(sep);
15038 }
15039 self.write(hint_str);
15040 }
15041 self.write(" */");
15042 }
15043
15044 Ok(())
15045 }
15046
15047 fn parse_raw_hint_text(&self, text: &str) -> Vec<String> {
15051 let mut results = Vec::new();
15052 let mut chars = text.chars().peekable();
15053 let mut current = String::new();
15054 let mut paren_depth = 0;
15055 let mut has_unparseable_content = false;
15056 let mut position_after_last_function = 0;
15057 let mut char_position = 0;
15058
15059 while let Some(c) = chars.next() {
15060 char_position += c.len_utf8();
15061 match c {
15062 '(' => {
15063 paren_depth += 1;
15064 current.push(c);
15065 }
15066 ')' => {
15067 paren_depth -= 1;
15068 current.push(c);
15069 if paren_depth == 0 {
15071 let trimmed = current.trim().to_string();
15072 if !trimmed.is_empty() {
15073 let formatted = self.format_hint_function(&trimmed);
15075 results.push(formatted);
15076 }
15077 current.clear();
15078 position_after_last_function = char_position;
15079 }
15080 }
15081 ' ' | '\t' | '\n' | ',' if paren_depth == 0 => {
15082 }
15084 _ if paren_depth == 0 => {
15085 current.push(c);
15087 }
15088 _ => {
15089 current.push(c);
15090 }
15091 }
15092 }
15093
15094 let remaining_text = text[position_after_last_function..].trim();
15096 if !remaining_text.is_empty() {
15097 let words: Vec<&str> = remaining_text.split_whitespace().collect();
15101 let looks_like_hint_functions = words.iter().all(|word| {
15102 word.contains('(') || (word.chars().all(|c| c.is_ascii_uppercase() || c == '_'))
15104 });
15105
15106 if !looks_like_hint_functions && words.len() > 1 {
15107 has_unparseable_content = true;
15108 }
15109 }
15110
15111 if has_unparseable_content {
15113 return vec![text.trim().to_string()];
15114 }
15115
15116 if results.is_empty() {
15118 results.push(text.trim().to_string());
15119 }
15120
15121 results
15122 }
15123
15124 fn format_hint_function(&self, hint: &str) -> String {
15127 if !self.config.pretty {
15128 return hint.to_string();
15129 }
15130
15131 if let Some(paren_pos) = hint.find('(') {
15133 if hint.ends_with(')') {
15134 let name = &hint[..paren_pos];
15135 let args_str = &hint[paren_pos + 1..hint.len() - 1];
15136
15137 let args: Vec<&str> = args_str.split_whitespace().collect();
15139
15140 let total_args_width: usize =
15142 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() {
15146 let mut result = format!("{}(\n", name);
15147 for arg in &args {
15148 result.push_str(" "); result.push_str(arg);
15150 result.push('\n');
15151 }
15152 result.push_str(" )"); return result;
15154 }
15155 }
15156 }
15157
15158 hint.to_string()
15159 }
15160
15161 fn hint_expression_to_string(&mut self, expr: &HintExpression) -> Result<String> {
15163 match expr {
15164 HintExpression::Function { name, args } => {
15165 let arg_strings: Vec<String> = args
15167 .iter()
15168 .map(|arg| {
15169 let mut gen = Generator::with_config(self.config.clone());
15170 gen.generate_expression(arg)?;
15171 Ok(gen.output)
15172 })
15173 .collect::<Result<Vec<_>>>()?;
15174
15175 let total_args_width: usize = arg_strings.iter().map(|s| s.len()).sum::<usize>()
15177 + arg_strings.len().saturating_sub(1); let args_multiline =
15182 self.config.pretty && total_args_width > self.config.max_text_width;
15183
15184 if args_multiline && !arg_strings.is_empty() {
15185 let mut result = format!("{}(\n", name);
15187 for arg_str in &arg_strings {
15188 result.push_str(" "); result.push_str(arg_str);
15190 result.push('\n');
15191 }
15192 result.push_str(" )"); Ok(result)
15194 } else {
15195 let args_str = arg_strings.join(" ");
15197 Ok(format!("{}({})", name, args_str))
15198 }
15199 }
15200 HintExpression::Identifier(name) => Ok(name.clone()),
15201 HintExpression::Raw(text) => {
15202 if self.config.pretty {
15204 Ok(self.format_hint_function(text))
15205 } else {
15206 Ok(text.clone())
15207 }
15208 }
15209 }
15210 }
15211
15212 fn generate_table(&mut self, table: &TableRef) -> Result<()> {
15213 if table.only {
15215 self.write_keyword("ONLY");
15216 self.write_space();
15217 }
15218
15219 if let Some(ref identifier_func) = table.identifier_func {
15221 self.generate_expression(identifier_func)?;
15222 } else {
15223 if let Some(catalog) = &table.catalog {
15224 self.generate_identifier(catalog)?;
15225 self.write(".");
15226 }
15227 if let Some(schema) = &table.schema {
15228 self.generate_identifier(schema)?;
15229 self.write(".");
15230 }
15231 self.generate_identifier(&table.name)?;
15232 }
15233
15234 if let Some(changes) = &table.changes {
15236 self.write(" ");
15237 self.generate_changes(changes)?;
15238 }
15239
15240 if !table.partitions.is_empty() {
15242 self.write_space();
15243 self.write_keyword("PARTITION");
15244 self.write("(");
15245 for (i, partition) in table.partitions.iter().enumerate() {
15246 if i > 0 {
15247 self.write(", ");
15248 }
15249 self.generate_identifier(partition)?;
15250 }
15251 self.write(")");
15252 }
15253
15254 if table.changes.is_none() {
15257 if let Some(when) = &table.when {
15258 self.write_space();
15259 self.generate_historical_data(when)?;
15260 }
15261 }
15262
15263 if let Some(ref system_time) = table.system_time {
15265 self.write_space();
15266 self.write(system_time);
15267 }
15268
15269 if let Some(ref version) = table.version {
15271 self.write_space();
15272 self.generate_version(version)?;
15273 }
15274
15275 let alias_post_tablesample = self.config.alias_post_tablesample;
15279
15280 if alias_post_tablesample {
15281 self.generate_table_sample_clause(table)?;
15283 }
15284
15285 let is_sqlite_hint = matches!(self.config.dialect, Some(DialectType::SQLite))
15288 && table.hints.iter().any(|h| {
15289 if let Expression::Identifier(id) = h {
15290 id.name.starts_with("INDEXED BY") || id.name == "NOT INDEXED"
15291 } else {
15292 false
15293 }
15294 });
15295 if !table.hints.is_empty() && !is_sqlite_hint {
15296 for hint in &table.hints {
15297 self.write_space();
15298 self.generate_expression(hint)?;
15299 }
15300 }
15301
15302 if let Some(alias) = &table.alias {
15303 self.write_space();
15304 let always_use_as = self.config.dialect.is_none()
15307 || matches!(
15308 self.config.dialect,
15309 Some(DialectType::Generic)
15310 | Some(DialectType::PostgreSQL)
15311 | Some(DialectType::Redshift)
15312 | Some(DialectType::Snowflake)
15313 | Some(DialectType::BigQuery)
15314 | Some(DialectType::Presto)
15315 | Some(DialectType::Trino)
15316 | Some(DialectType::TSQL)
15317 | Some(DialectType::Fabric)
15318 | Some(DialectType::MySQL)
15319 | Some(DialectType::Spark)
15320 | Some(DialectType::Hive)
15321 | Some(DialectType::SQLite)
15322 | Some(DialectType::Drill)
15323 );
15324 let is_stage_ref = table.name.name.starts_with('@');
15325 let suppress_as = matches!(self.config.dialect, Some(DialectType::Oracle));
15327 if !suppress_as && (table.alias_explicit_as || always_use_as || is_stage_ref) {
15328 self.write_keyword("AS");
15329 self.write_space();
15330 }
15331 self.generate_identifier(alias)?;
15332
15333 if !table.column_aliases.is_empty() && self.config.supports_table_alias_columns {
15336 self.write("(");
15337 for (i, col_alias) in table.column_aliases.iter().enumerate() {
15338 if i > 0 {
15339 self.write(", ");
15340 }
15341 self.generate_identifier(col_alias)?;
15342 }
15343 self.write(")");
15344 }
15345 }
15346
15347 if !alias_post_tablesample {
15349 self.generate_table_sample_clause(table)?;
15350 }
15351
15352 if is_sqlite_hint {
15354 for hint in &table.hints {
15355 self.write_space();
15356 self.generate_expression(hint)?;
15357 }
15358 }
15359
15360 if table.final_ && matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
15362 self.write_space();
15363 self.write_keyword("FINAL");
15364 }
15365
15366 for comment in &table.trailing_comments {
15368 self.write_space();
15369 self.write_formatted_comment(comment);
15370 }
15371
15372 Ok(())
15373 }
15374
15375 fn generate_table_sample_clause(&mut self, table: &TableRef) -> Result<()> {
15377 if let Some(ref ts) = table.table_sample {
15378 self.write_space();
15379 if ts.is_using_sample {
15380 self.write_keyword("USING SAMPLE");
15381 } else {
15382 self.write_keyword(self.config.tablesample_keywords);
15384 }
15385 self.generate_sample_body(ts)?;
15386 if let Some(ref seed) = ts.seed {
15388 self.write_space();
15389 self.write_keyword(self.config.tablesample_seed_keyword);
15390 self.write(" (");
15391 self.generate_expression(seed)?;
15392 self.write(")");
15393 }
15394 }
15395 Ok(())
15396 }
15397
15398 fn generate_stage_reference(&mut self, sr: &StageReference) -> Result<()> {
15399 if sr.quoted {
15403 self.write("'");
15404 }
15405
15406 self.write(&sr.name);
15407 if let Some(path) = &sr.path {
15408 self.write(path);
15409 }
15410
15411 if sr.quoted {
15412 self.write("'");
15413 }
15414
15415 let has_options = sr.file_format.is_some() || sr.pattern.is_some();
15417 if has_options {
15418 self.write(" (");
15419 let mut first = true;
15420
15421 if let Some(file_format) = &sr.file_format {
15422 if !first {
15423 self.write(", ");
15424 }
15425 self.write_keyword("FILE_FORMAT");
15426 self.write(" => ");
15427 self.generate_expression(file_format)?;
15428 first = false;
15429 }
15430
15431 if let Some(pattern) = &sr.pattern {
15432 if !first {
15433 self.write(", ");
15434 }
15435 self.write_keyword("PATTERN");
15436 self.write(" => '");
15437 self.write(pattern);
15438 self.write("'");
15439 }
15440
15441 self.write(")");
15442 }
15443 Ok(())
15444 }
15445
15446 fn generate_star(&mut self, star: &Star) -> Result<()> {
15447 use crate::dialects::DialectType;
15448
15449 if let Some(table) = &star.table {
15450 self.generate_identifier(table)?;
15451 self.write(".");
15452 }
15453 self.write("*");
15454
15455 if let Some(except) = &star.except {
15457 if !except.is_empty() {
15458 self.write_space();
15459 match self.config.dialect {
15461 Some(DialectType::BigQuery) => self.write_keyword("EXCEPT"),
15462 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => {
15463 self.write_keyword("EXCLUDE")
15464 }
15465 _ => self.write_keyword("EXCEPT"), }
15467 self.write(" (");
15468 for (i, col) in except.iter().enumerate() {
15469 if i > 0 {
15470 self.write(", ");
15471 }
15472 self.generate_identifier(col)?;
15473 }
15474 self.write(")");
15475 }
15476 }
15477
15478 if let Some(replace) = &star.replace {
15480 if !replace.is_empty() {
15481 self.write_space();
15482 self.write_keyword("REPLACE");
15483 self.write(" (");
15484 for (i, alias) in replace.iter().enumerate() {
15485 if i > 0 {
15486 self.write(", ");
15487 }
15488 self.generate_expression(&alias.this)?;
15489 self.write_space();
15490 self.write_keyword("AS");
15491 self.write_space();
15492 self.generate_identifier(&alias.alias)?;
15493 }
15494 self.write(")");
15495 }
15496 }
15497
15498 if let Some(rename) = &star.rename {
15500 if !rename.is_empty() {
15501 self.write_space();
15502 self.write_keyword("RENAME");
15503 self.write(" (");
15504 for (i, (old_name, new_name)) in rename.iter().enumerate() {
15505 if i > 0 {
15506 self.write(", ");
15507 }
15508 self.generate_identifier(old_name)?;
15509 self.write_space();
15510 self.write_keyword("AS");
15511 self.write_space();
15512 self.generate_identifier(new_name)?;
15513 }
15514 self.write(")");
15515 }
15516 }
15517
15518 for comment in &star.trailing_comments {
15520 self.write_space();
15521 self.write_formatted_comment(comment);
15522 }
15523
15524 Ok(())
15525 }
15526
15527 fn generate_braced_wildcard(&mut self, expr: &Expression) -> Result<()> {
15529 self.write("{");
15530 match expr {
15531 Expression::Star(star) => {
15532 self.generate_star(star)?;
15534 }
15535 Expression::ILike(ilike) => {
15536 self.generate_expression(&ilike.left)?;
15538 self.write_space();
15539 self.write_keyword("ILIKE");
15540 self.write_space();
15541 self.generate_expression(&ilike.right)?;
15542 }
15543 _ => {
15544 self.generate_expression(expr)?;
15545 }
15546 }
15547 self.write("}");
15548 Ok(())
15549 }
15550
15551 fn generate_alias(&mut self, alias: &Alias) -> Result<()> {
15552 match &alias.this {
15556 Expression::Column(col) => {
15557 if let Some(table) = &col.table {
15559 self.generate_identifier(table)?;
15560 self.write(".");
15561 }
15562 self.generate_identifier(&col.name)?;
15563 }
15564 _ => {
15565 self.generate_expression(&alias.this)?;
15566 }
15567 }
15568
15569 if !alias.pre_alias_comments.is_empty() && !alias.trailing_comments.is_empty() {
15573 for comment in &alias.pre_alias_comments {
15574 self.write_space();
15575 self.write_formatted_comment(comment);
15576 }
15577 }
15578
15579 use crate::dialects::DialectType;
15580
15581 let is_table_source = matches!(
15587 &alias.this,
15588 Expression::JSONTable(_)
15589 | Expression::XMLTable(_)
15590 | Expression::TableFromRows(_)
15591 | Expression::Unnest(_)
15592 | Expression::MatchRecognize(_)
15593 | Expression::Select(_)
15594 | Expression::Subquery(_)
15595 | Expression::Paren(_)
15596 );
15597 let dialect_skips_table_alias_as = matches!(self.config.dialect, Some(DialectType::Oracle));
15598 let skip_as = is_table_source && dialect_skips_table_alias_as;
15599
15600 self.write_space();
15601 if !skip_as {
15602 self.write_keyword("AS");
15603 self.write_space();
15604 }
15605
15606 let skip_column_aliases = matches!(self.config.dialect, Some(DialectType::BigQuery));
15608
15609 if alias.alias.is_empty() && !alias.column_aliases.is_empty() && !skip_column_aliases {
15611 self.write("(");
15613 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
15614 if i > 0 {
15615 self.write(", ");
15616 }
15617 self.generate_alias_identifier(col_alias)?;
15618 }
15619 self.write(")");
15620 } else if !alias.column_aliases.is_empty() && !skip_column_aliases {
15621 self.generate_alias_identifier(&alias.alias)?;
15623 self.write("(");
15624 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
15625 if i > 0 {
15626 self.write(", ");
15627 }
15628 self.generate_alias_identifier(col_alias)?;
15629 }
15630 self.write(")");
15631 } else {
15632 self.generate_alias_identifier(&alias.alias)?;
15634 }
15635
15636 for comment in &alias.trailing_comments {
15638 self.write_space();
15639 self.write_formatted_comment(comment);
15640 }
15641
15642 if alias.trailing_comments.is_empty() {
15647 for comment in &alias.pre_alias_comments {
15648 self.write_space();
15649 self.write_formatted_comment(comment);
15650 }
15651 }
15652
15653 Ok(())
15654 }
15655
15656 fn generate_cast(&mut self, cast: &Cast) -> Result<()> {
15657 use crate::dialects::DialectType;
15658
15659 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
15661 self.generate_expression(&cast.this)?;
15662 self.write(" :> ");
15663 self.generate_data_type(&cast.to)?;
15664 return Ok(());
15665 }
15666
15667 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
15669 let is_unknown_type = matches!(cast.to, DataType::Unknown)
15670 || matches!(cast.to, DataType::Custom { ref name } if name.is_empty());
15671 if is_unknown_type {
15672 if let Some(format) = &cast.format {
15673 self.write_keyword("CAST");
15674 self.write("(");
15675 self.generate_expression(&cast.this)?;
15676 self.write_space();
15677 self.write_keyword("AS");
15678 self.write_space();
15679 self.write_keyword("FORMAT");
15680 self.write_space();
15681 self.generate_expression(format)?;
15682 self.write(")");
15683 return Ok(());
15684 }
15685 }
15686 }
15687
15688 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
15691 if let Some(format) = &cast.format {
15692 let is_date = matches!(cast.to, DataType::Date);
15694 let is_timestamp = matches!(cast.to, DataType::Timestamp { .. });
15695
15696 if is_date || is_timestamp {
15697 let func_name = if is_date { "TO_DATE" } else { "TO_TIMESTAMP" };
15698 self.write_keyword(func_name);
15699 self.write("(");
15700 self.generate_expression(&cast.this)?;
15701 self.write(", ");
15702
15703 if let Expression::Literal(Literal::String(fmt_str)) = format.as_ref() {
15706 let normalized = self.normalize_oracle_format(fmt_str);
15707 self.write("'");
15708 self.write(&normalized);
15709 self.write("'");
15710 } else {
15711 self.generate_expression(format)?;
15712 }
15713
15714 self.write(")");
15715 return Ok(());
15716 }
15717 }
15718 }
15719
15720 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
15723 if let Expression::Array(arr) = &cast.this {
15724 self.generate_data_type(&cast.to)?;
15725 self.write("[");
15727 for (i, expr) in arr.expressions.iter().enumerate() {
15728 if i > 0 {
15729 self.write(", ");
15730 }
15731 self.generate_expression(expr)?;
15732 }
15733 self.write("]");
15734 return Ok(());
15735 }
15736 if matches!(&cast.this, Expression::ArrayFunc(_)) {
15737 self.generate_data_type(&cast.to)?;
15738 self.generate_expression(&cast.this)?;
15739 return Ok(());
15740 }
15741 }
15742
15743 if matches!(
15746 self.config.dialect,
15747 Some(DialectType::DuckDB) | Some(DialectType::Presto) | Some(DialectType::Trino)
15748 ) {
15749 if let Expression::Struct(ref s) = cast.this {
15750 let all_unnamed = s.fields.iter().all(|(name, _)| name.is_none());
15751 if all_unnamed && matches!(cast.to, DataType::Struct { .. }) {
15752 self.write_keyword("CAST");
15753 self.write("(");
15754 self.generate_struct_as_row(s)?;
15755 self.write_space();
15756 self.write_keyword("AS");
15757 self.write_space();
15758 self.generate_data_type(&cast.to)?;
15759 self.write(")");
15760 return Ok(());
15761 }
15762 }
15763 }
15764
15765 let use_double_colon = cast.double_colon_syntax && self.dialect_prefers_double_colon();
15768
15769 if use_double_colon {
15770 self.generate_expression(&cast.this)?;
15772 self.write("::");
15773 self.generate_data_type(&cast.to)?;
15774 } else {
15775 self.write_keyword("CAST");
15777 self.write("(");
15778 self.generate_expression(&cast.this)?;
15779 self.write_space();
15780 self.write_keyword("AS");
15781 self.write_space();
15782 if matches!(
15785 self.config.dialect,
15786 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB)
15787 ) {
15788 match &cast.to {
15789 DataType::Custom { ref name } => {
15790 let upper = name.to_uppercase();
15791 match upper.as_str() {
15792 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" | "LONGBLOB" | "MEDIUMBLOB"
15793 | "TINYBLOB" => {
15794 self.write_keyword("CHAR");
15795 }
15796 _ => {
15797 self.generate_data_type(&cast.to)?;
15798 }
15799 }
15800 }
15801 DataType::VarChar { length, .. } => {
15802 self.write_keyword("CHAR");
15804 if let Some(n) = length {
15805 self.write(&format!("({})", n));
15806 }
15807 }
15808 DataType::Text => {
15809 self.write_keyword("CHAR");
15811 }
15812 DataType::Timestamp {
15813 precision,
15814 timezone: false,
15815 } => {
15816 self.write_keyword("DATETIME");
15818 if let Some(p) = precision {
15819 self.write(&format!("({})", p));
15820 }
15821 }
15822 _ => {
15823 self.generate_data_type(&cast.to)?;
15824 }
15825 }
15826 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
15827 match &cast.to {
15829 DataType::String { length } => {
15830 self.write_keyword("VARCHAR");
15831 if let Some(n) = length {
15832 self.write(&format!("({})", n));
15833 }
15834 }
15835 _ => {
15836 self.generate_data_type(&cast.to)?;
15837 }
15838 }
15839 } else {
15840 self.generate_data_type(&cast.to)?;
15841 }
15842
15843 if let Some(default) = &cast.default {
15845 self.write_space();
15846 self.write_keyword("DEFAULT");
15847 self.write_space();
15848 self.generate_expression(default)?;
15849 self.write_space();
15850 self.write_keyword("ON");
15851 self.write_space();
15852 self.write_keyword("CONVERSION");
15853 self.write_space();
15854 self.write_keyword("ERROR");
15855 }
15856
15857 if let Some(format) = &cast.format {
15860 if matches!(
15862 self.config.dialect,
15863 Some(crate::dialects::DialectType::Oracle)
15864 ) {
15865 self.write(", ");
15866 } else {
15867 self.write_space();
15868 self.write_keyword("FORMAT");
15869 self.write_space();
15870 }
15871 self.generate_expression(format)?;
15872 }
15873
15874 self.write(")");
15875 for comment in &cast.trailing_comments {
15877 self.write_space();
15878 self.write_formatted_comment(comment);
15879 }
15880 }
15881 Ok(())
15882 }
15883
15884 fn generate_struct_as_row(&mut self, s: &crate::expressions::Struct) -> Result<()> {
15887 self.write_keyword("ROW");
15888 self.write("(");
15889 for (i, (_, expr)) in s.fields.iter().enumerate() {
15890 if i > 0 {
15891 self.write(", ");
15892 }
15893 if let Expression::Struct(ref inner_s) = expr {
15895 self.generate_struct_as_row(inner_s)?;
15896 } else {
15897 self.generate_expression(expr)?;
15898 }
15899 }
15900 self.write(")");
15901 Ok(())
15902 }
15903
15904 fn normalize_oracle_format(&self, format: &str) -> String {
15907 let mut result = String::new();
15910 let chars: Vec<char> = format.chars().collect();
15911 let mut i = 0;
15912
15913 while i < chars.len() {
15914 if i + 1 < chars.len() && chars[i] == 'H' && chars[i + 1] == 'H' {
15915 if i + 2 < chars.len() {
15917 let next = chars[i + 2];
15918 if next == '1' || next == '2' {
15919 result.push('H');
15921 result.push('H');
15922 i += 2;
15923 continue;
15924 }
15925 }
15926 result.push_str("HH12");
15928 i += 2;
15929 } else {
15930 result.push(chars[i]);
15931 i += 1;
15932 }
15933 }
15934
15935 result
15936 }
15937
15938 fn dialect_prefers_double_colon(&self) -> bool {
15942 false
15945 }
15946
15947 fn generate_mod_func(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
15949 use crate::dialects::DialectType;
15950
15951 let use_percent_operator = matches!(
15953 self.config.dialect,
15954 Some(DialectType::Snowflake)
15955 | Some(DialectType::MySQL)
15956 | Some(DialectType::Presto)
15957 | Some(DialectType::Trino)
15958 | Some(DialectType::PostgreSQL)
15959 | Some(DialectType::DuckDB)
15960 | Some(DialectType::Hive)
15961 | Some(DialectType::Spark)
15962 | Some(DialectType::Databricks)
15963 | Some(DialectType::Athena)
15964 );
15965
15966 if use_percent_operator {
15967 let needs_paren = |e: &Expression| matches!(e, Expression::Add(_) | Expression::Sub(_));
15970 if needs_paren(&f.this) {
15971 self.write("(");
15972 self.generate_expression(&f.this)?;
15973 self.write(")");
15974 } else {
15975 self.generate_expression(&f.this)?;
15976 }
15977 self.write(" % ");
15978 if needs_paren(&f.expression) {
15979 self.write("(");
15980 self.generate_expression(&f.expression)?;
15981 self.write(")");
15982 } else {
15983 self.generate_expression(&f.expression)?;
15984 }
15985 Ok(())
15986 } else {
15987 self.generate_binary_func("MOD", &f.this, &f.expression)
15988 }
15989 }
15990
15991 fn generate_ifnull(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
15993 use crate::dialects::DialectType;
15994
15995 let func_name = match self.config.dialect {
15997 Some(DialectType::Snowflake) => "COALESCE",
15998 _ => "IFNULL",
15999 };
16000
16001 self.generate_binary_func(func_name, &f.this, &f.expression)
16002 }
16003
16004 fn generate_nvl(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
16006 if let Some(ref original_name) = f.original_name {
16008 return self.generate_binary_func(original_name, &f.this, &f.expression);
16009 }
16010
16011 use crate::dialects::DialectType;
16013 let func_name = match self.config.dialect {
16014 Some(DialectType::Snowflake)
16015 | Some(DialectType::ClickHouse)
16016 | Some(DialectType::PostgreSQL)
16017 | Some(DialectType::Presto)
16018 | Some(DialectType::Trino)
16019 | Some(DialectType::Athena)
16020 | Some(DialectType::DuckDB)
16021 | Some(DialectType::BigQuery)
16022 | Some(DialectType::Spark)
16023 | Some(DialectType::Databricks)
16024 | Some(DialectType::Hive) => "COALESCE",
16025 Some(DialectType::MySQL)
16026 | Some(DialectType::Doris)
16027 | Some(DialectType::StarRocks)
16028 | Some(DialectType::SingleStore)
16029 | Some(DialectType::TiDB) => "IFNULL",
16030 _ => "NVL",
16031 };
16032
16033 self.generate_binary_func(func_name, &f.this, &f.expression)
16034 }
16035
16036 fn generate_stddev_samp(&mut self, f: &crate::expressions::AggFunc) -> Result<()> {
16038 use crate::dialects::DialectType;
16039
16040 let func_name = match self.config.dialect {
16042 Some(DialectType::Snowflake) => "STDDEV",
16043 _ => "STDDEV_SAMP",
16044 };
16045
16046 self.generate_agg_func(func_name, f)
16047 }
16048
16049 fn generate_collation(&mut self, coll: &CollationExpr) -> Result<()> {
16050 self.generate_expression(&coll.this)?;
16051 self.write_space();
16052 self.write_keyword("COLLATE");
16053 self.write_space();
16054 if coll.quoted {
16055 self.write("'");
16057 self.write(&coll.collation);
16058 self.write("'");
16059 } else if coll.double_quoted {
16060 self.write("\"");
16062 self.write(&coll.collation);
16063 self.write("\"");
16064 } else {
16065 self.write(&coll.collation);
16067 }
16068 Ok(())
16069 }
16070
16071 fn generate_case(&mut self, case: &Case) -> Result<()> {
16072 let multiline_case = if self.config.pretty {
16074 let mut statements: Vec<String> = Vec::new();
16076 let operand_str = if let Some(operand) = &case.operand {
16077 let s = self.generate_to_string(operand)?;
16078 statements.push(format!("CASE {}", s));
16079 s
16080 } else {
16081 statements.push("CASE".to_string());
16082 String::new()
16083 };
16084 let _ = operand_str;
16085 for (condition, result) in &case.whens {
16086 statements.push(format!("WHEN {}", self.generate_to_string(condition)?));
16087 statements.push(format!("THEN {}", self.generate_to_string(result)?));
16088 }
16089 if let Some(else_) = &case.else_ {
16090 statements.push(format!("ELSE {}", self.generate_to_string(else_)?));
16091 }
16092 statements.push("END".to_string());
16093 self.too_wide(&statements)
16094 } else {
16095 false
16096 };
16097
16098 self.write_keyword("CASE");
16099 if let Some(operand) = &case.operand {
16100 self.write_space();
16101 self.generate_expression(operand)?;
16102 }
16103 if multiline_case {
16104 self.indent_level += 1;
16105 }
16106 for (condition, result) in &case.whens {
16107 if multiline_case {
16108 self.write_newline();
16109 self.write_indent();
16110 } else {
16111 self.write_space();
16112 }
16113 self.write_keyword("WHEN");
16114 self.write_space();
16115 self.generate_expression(condition)?;
16116 if multiline_case {
16117 self.write_newline();
16118 self.write_indent();
16119 } else {
16120 self.write_space();
16121 }
16122 self.write_keyword("THEN");
16123 self.write_space();
16124 self.generate_expression(result)?;
16125 }
16126 if let Some(else_) = &case.else_ {
16127 if multiline_case {
16128 self.write_newline();
16129 self.write_indent();
16130 } else {
16131 self.write_space();
16132 }
16133 self.write_keyword("ELSE");
16134 self.write_space();
16135 self.generate_expression(else_)?;
16136 }
16137 if multiline_case {
16138 self.indent_level -= 1;
16139 self.write_newline();
16140 self.write_indent();
16141 } else {
16142 self.write_space();
16143 }
16144 self.write_keyword("END");
16145 for comment in &case.comments {
16147 self.write(" ");
16148 self.write_formatted_comment(comment);
16149 }
16150 Ok(())
16151 }
16152
16153 fn generate_function(&mut self, func: &Function) -> Result<()> {
16154 let normalized_name = self.normalize_func_name(&func.name);
16156 let upper_name = func.name.to_uppercase();
16157
16158 if matches!(self.config.dialect, Some(DialectType::DuckDB))
16160 && upper_name == "ARRAY_CONSTRUCT_COMPACT"
16161 {
16162 self.write("LIST_FILTER(");
16163 self.write("[");
16164 for (i, arg) in func.args.iter().enumerate() {
16165 if i > 0 {
16166 self.write(", ");
16167 }
16168 self.generate_expression(arg)?;
16169 }
16170 self.write("], _u -> NOT _u IS NULL)");
16171 return Ok(());
16172 }
16173
16174 if upper_name == "STRUCT"
16176 && !matches!(
16177 self.config.dialect,
16178 Some(DialectType::BigQuery)
16179 | Some(DialectType::Spark)
16180 | Some(DialectType::Databricks)
16181 | Some(DialectType::Hive)
16182 | None
16183 )
16184 {
16185 return self.generate_struct_function_cross_dialect(func);
16186 }
16187
16188 if upper_name == "__SS_JSON_PATH_QMARK__" && func.args.len() == 2 {
16191 self.generate_expression(&func.args[0])?;
16192 self.write("::?");
16193 if let Expression::Literal(crate::expressions::Literal::String(key)) = &func.args[1] {
16195 self.write(key);
16196 } else {
16197 self.generate_expression(&func.args[1])?;
16198 }
16199 return Ok(());
16200 }
16201
16202 if upper_name == "__PG_BITWISE_XOR__" && func.args.len() == 2 {
16204 self.generate_expression(&func.args[0])?;
16205 self.write(" # ");
16206 self.generate_expression(&func.args[1])?;
16207 return Ok(());
16208 }
16209
16210 if matches!(
16212 self.config.dialect,
16213 Some(DialectType::Spark | DialectType::Databricks | DialectType::Hive)
16214 ) && upper_name == "TRY"
16215 && func.args.len() == 1
16216 {
16217 self.generate_expression(&func.args[0])?;
16218 return Ok(());
16219 }
16220
16221 if self.config.dialect == Some(DialectType::ClickHouse)
16223 && upper_name == "TOSTARTOFDAY"
16224 && func.args.len() == 1
16225 {
16226 self.write("dateTrunc('DAY', ");
16227 self.generate_expression(&func.args[0])?;
16228 self.write(")");
16229 return Ok(());
16230 }
16231
16232 if self.config.dialect == Some(DialectType::Redshift)
16234 && upper_name == "CONCAT"
16235 && func.args.len() >= 2
16236 {
16237 for (i, arg) in func.args.iter().enumerate() {
16238 if i > 0 {
16239 self.write(" || ");
16240 }
16241 self.generate_expression(arg)?;
16242 }
16243 return Ok(());
16244 }
16245
16246 if self.config.dialect == Some(DialectType::Redshift)
16248 && upper_name == "CONCAT_WS"
16249 && func.args.len() >= 2
16250 {
16251 let sep = &func.args[0];
16252 for (i, arg) in func.args.iter().skip(1).enumerate() {
16253 if i > 0 {
16254 self.write(" || ");
16255 self.generate_expression(sep)?;
16256 self.write(" || ");
16257 }
16258 self.generate_expression(arg)?;
16259 }
16260 return Ok(());
16261 }
16262
16263 if self.config.dialect == Some(DialectType::Redshift)
16266 && (upper_name == "DATEDIFF" || upper_name == "DATE_DIFF")
16267 && func.args.len() == 3
16268 {
16269 self.write_keyword("DATEDIFF");
16270 self.write("(");
16271 self.write_redshift_date_part(&func.args[0]);
16273 self.write(", ");
16274 self.generate_expression(&func.args[1])?;
16275 self.write(", ");
16276 self.generate_expression(&func.args[2])?;
16277 self.write(")");
16278 return Ok(());
16279 }
16280
16281 if self.config.dialect == Some(DialectType::Redshift)
16284 && (upper_name == "DATEADD" || upper_name == "DATE_ADD")
16285 && func.args.len() == 3
16286 {
16287 self.write_keyword("DATEADD");
16288 self.write("(");
16289 self.write_redshift_date_part(&func.args[0]);
16291 self.write(", ");
16292 self.generate_expression(&func.args[1])?;
16293 self.write(", ");
16294 self.generate_expression(&func.args[2])?;
16295 self.write(")");
16296 return Ok(());
16297 }
16298
16299 if upper_name == "UUID_STRING"
16301 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None)
16302 {
16303 let func_name = match self.config.dialect {
16304 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
16305 Some(DialectType::BigQuery) => "GENERATE_UUID",
16306 _ => "UUID",
16307 };
16308 self.write_keyword(func_name);
16309 self.write("()");
16310 return Ok(());
16311 }
16312
16313 if self.config.dialect == Some(DialectType::Redshift)
16316 && upper_name == "DATE_TRUNC"
16317 && func.args.len() == 2
16318 {
16319 self.write_keyword("DATE_TRUNC");
16320 self.write("(");
16321 self.write_redshift_date_part_quoted(&func.args[0]);
16323 self.write(", ");
16324 self.generate_expression(&func.args[1])?;
16325 self.write(")");
16326 return Ok(());
16327 }
16328
16329 if matches!(
16331 self.config.dialect,
16332 Some(DialectType::TSQL) | Some(DialectType::Fabric)
16333 ) && (upper_name == "DATE_PART" || upper_name == "DATEPART")
16334 && func.args.len() == 2
16335 {
16336 self.write_keyword("DATEPART");
16337 self.write("(");
16338 self.generate_expression(&func.args[0])?;
16339 self.write(", ");
16340 self.generate_expression(&func.args[1])?;
16341 self.write(")");
16342 return Ok(());
16343 }
16344
16345 if matches!(
16347 self.config.dialect,
16348 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
16349 ) && (upper_name == "DATE_PART" || upper_name == "DATEPART")
16350 && func.args.len() == 2
16351 {
16352 self.write_keyword("EXTRACT");
16353 self.write("(");
16354 match &func.args[0] {
16356 Expression::Literal(crate::expressions::Literal::String(s)) => {
16357 self.write(&s.to_lowercase());
16358 }
16359 _ => self.generate_expression(&func.args[0])?,
16360 }
16361 self.write_space();
16362 self.write_keyword("FROM");
16363 self.write_space();
16364 self.generate_expression(&func.args[1])?;
16365 self.write(")");
16366 return Ok(());
16367 }
16368
16369 if self.config.dialect == Some(DialectType::Dremio)
16372 && (upper_name == "DATE_PART" || upper_name == "DATEPART")
16373 && func.args.len() == 2
16374 {
16375 self.write_keyword("EXTRACT");
16376 self.write("(");
16377 self.generate_expression(&func.args[0])?;
16378 self.write_space();
16379 self.write_keyword("FROM");
16380 self.write_space();
16381 self.generate_dremio_date_expression(&func.args[1])?;
16383 self.write(")");
16384 return Ok(());
16385 }
16386
16387 if self.config.dialect == Some(DialectType::Dremio)
16389 && upper_name == "CURRENT_DATE_UTC"
16390 && func.args.is_empty()
16391 {
16392 self.write_keyword("CURRENT_DATE_UTC");
16393 return Ok(());
16394 }
16395
16396 if self.config.dialect == Some(DialectType::Dremio)
16400 && upper_name == "DATETYPE"
16401 && func.args.len() == 3
16402 {
16403 fn get_int_literal(expr: &Expression) -> Option<i64> {
16405 if let Expression::Literal(crate::expressions::Literal::Number(s)) = expr {
16406 s.parse::<i64>().ok()
16407 } else {
16408 None
16409 }
16410 }
16411
16412 if let (Some(year), Some(month), Some(day)) = (
16414 get_int_literal(&func.args[0]),
16415 get_int_literal(&func.args[1]),
16416 get_int_literal(&func.args[2]),
16417 ) {
16418 self.write_keyword("DATE");
16420 self.write(&format!("('{:04}-{:02}-{:02}')", year, month, day));
16421 return Ok(());
16422 }
16423
16424 self.write_keyword("CAST");
16426 self.write("(");
16427 self.write_keyword("CONCAT");
16428 self.write("(");
16429 self.generate_expression(&func.args[0])?;
16430 self.write(", '-', ");
16431 self.generate_expression(&func.args[1])?;
16432 self.write(", '-', ");
16433 self.generate_expression(&func.args[2])?;
16434 self.write(")");
16435 self.write_space();
16436 self.write_keyword("AS");
16437 self.write_space();
16438 self.write_keyword("DATE");
16439 self.write(")");
16440 return Ok(());
16441 }
16442
16443 let is_presto_like = matches!(
16446 self.config.dialect,
16447 Some(DialectType::Presto) | Some(DialectType::Trino)
16448 );
16449 if is_presto_like && upper_name == "DATE_ADD" && func.args.len() == 3 {
16450 self.write_keyword("DATE_ADD");
16451 self.write("(");
16452 self.generate_expression(&func.args[0])?;
16454 self.write(", ");
16455 let interval = &func.args[1];
16457 let needs_cast = !self.returns_integer_type(interval);
16458 if needs_cast {
16459 self.write_keyword("CAST");
16460 self.write("(");
16461 }
16462 self.generate_expression(interval)?;
16463 if needs_cast {
16464 self.write_space();
16465 self.write_keyword("AS");
16466 self.write_space();
16467 self.write_keyword("BIGINT");
16468 self.write(")");
16469 }
16470 self.write(", ");
16471 self.generate_expression(&func.args[2])?;
16473 self.write(")");
16474 return Ok(());
16475 }
16476
16477 let use_brackets = func.use_bracket_syntax;
16479
16480 let has_ordinality = upper_name.ends_with(" WITH ORDINALITY");
16485 let output_name = if has_ordinality {
16486 let base_name = &func.name[..func.name.len() - " WITH ORDINALITY".len()];
16487 self.normalize_func_name(base_name)
16488 } else {
16489 normalized_name.clone()
16490 };
16491
16492 if func.name.contains('.') && !has_ordinality {
16495 if func.quoted {
16498 self.write("`");
16499 self.write(&func.name);
16500 self.write("`");
16501 } else {
16502 self.write(&func.name);
16503 }
16504 } else {
16505 self.write(&output_name);
16506 }
16507
16508 let force_parens = func.no_parens && func.args.is_empty() && !func.distinct && {
16511 let needs_parens = match upper_name.as_str() {
16512 "CURRENT_USER" | "SESSION_USER" | "SYSTEM_USER" => matches!(
16513 self.config.dialect,
16514 Some(DialectType::Snowflake)
16515 | Some(DialectType::Spark)
16516 | Some(DialectType::Databricks)
16517 | Some(DialectType::Hive)
16518 ),
16519 _ => false,
16520 };
16521 !needs_parens
16522 };
16523 if force_parens {
16524 for comment in &func.trailing_comments {
16526 self.write_space();
16527 self.write_formatted_comment(comment);
16528 }
16529 return Ok(());
16530 }
16531
16532 if upper_name == "CUBE" || upper_name == "ROLLUP" || upper_name == "GROUPING SETS" {
16534 self.write(" (");
16535 } else if use_brackets {
16536 self.write("[");
16537 } else {
16538 self.write("(");
16539 }
16540 if func.distinct {
16541 self.write_keyword("DISTINCT");
16542 self.write_space();
16543 }
16544
16545 let compact_pretty_func = matches!(self.config.dialect, Some(DialectType::Snowflake))
16547 && (upper_name == "TABLE" || upper_name == "FLATTEN");
16548 let is_grouping_func =
16550 upper_name == "GROUPING SETS" || upper_name == "CUBE" || upper_name == "ROLLUP";
16551 let should_split = if self.config.pretty && !func.args.is_empty() && !compact_pretty_func {
16552 if is_grouping_func {
16553 true
16554 } else {
16555 let mut expr_strings: Vec<String> = Vec::with_capacity(func.args.len());
16557 for arg in &func.args {
16558 let mut temp_gen = Generator::with_config(self.config.clone());
16559 temp_gen.config.pretty = false; temp_gen.generate_expression(arg)?;
16561 expr_strings.push(temp_gen.output);
16562 }
16563 self.too_wide(&expr_strings)
16564 }
16565 } else {
16566 false
16567 };
16568
16569 if should_split {
16570 self.write_newline();
16572 self.indent_level += 1;
16573 for (i, arg) in func.args.iter().enumerate() {
16574 self.write_indent();
16575 self.generate_expression(arg)?;
16576 if i + 1 < func.args.len() {
16577 self.write(",");
16578 }
16579 self.write_newline();
16580 }
16581 self.indent_level -= 1;
16582 self.write_indent();
16583 } else {
16584 for (i, arg) in func.args.iter().enumerate() {
16586 if i > 0 {
16587 self.write(", ");
16588 }
16589 self.generate_expression(arg)?;
16590 }
16591 }
16592
16593 if use_brackets {
16594 self.write("]");
16595 } else {
16596 self.write(")");
16597 }
16598 if has_ordinality {
16600 self.write_space();
16601 self.write_keyword("WITH ORDINALITY");
16602 }
16603 for comment in &func.trailing_comments {
16605 self.write_space();
16606 self.write_formatted_comment(comment);
16607 }
16608 Ok(())
16609 }
16610
16611 fn generate_aggregate_function(&mut self, func: &AggregateFunction) -> Result<()> {
16612 let mut normalized_name = self.normalize_func_name(&func.name);
16614
16615 let upper = normalized_name.to_uppercase();
16617 if upper == "MAX_BY" || upper == "MIN_BY" {
16618 let is_max = upper == "MAX_BY";
16619 match self.config.dialect {
16620 Some(DialectType::ClickHouse) => {
16621 normalized_name = if is_max {
16622 "argMax".to_string()
16623 } else {
16624 "argMin".to_string()
16625 };
16626 }
16627 Some(DialectType::DuckDB) => {
16628 normalized_name = if is_max {
16629 "ARG_MAX".to_string()
16630 } else {
16631 "ARG_MIN".to_string()
16632 };
16633 }
16634 _ => {}
16635 }
16636 }
16637 self.write(&normalized_name);
16638 self.write("(");
16639 if func.distinct {
16640 self.write_keyword("DISTINCT");
16641 self.write_space();
16642 }
16643
16644 let is_count = normalized_name.eq_ignore_ascii_case("COUNT");
16648 let needs_multi_arg_transform =
16649 func.distinct && is_count && func.args.len() > 1 && !self.config.multi_arg_distinct;
16650
16651 if needs_multi_arg_transform {
16652 self.write_keyword("CASE");
16654 for arg in &func.args {
16655 self.write_space();
16656 self.write_keyword("WHEN");
16657 self.write_space();
16658 self.generate_expression(arg)?;
16659 self.write_space();
16660 self.write_keyword("IS NULL THEN NULL");
16661 }
16662 self.write_space();
16663 self.write_keyword("ELSE");
16664 self.write(" (");
16665 for (i, arg) in func.args.iter().enumerate() {
16666 if i > 0 {
16667 self.write(", ");
16668 }
16669 self.generate_expression(arg)?;
16670 }
16671 self.write(")");
16672 self.write_space();
16673 self.write_keyword("END");
16674 } else {
16675 for (i, arg) in func.args.iter().enumerate() {
16676 if i > 0 {
16677 self.write(", ");
16678 }
16679 self.generate_expression(arg)?;
16680 }
16681 }
16682
16683 if self.config.ignore_nulls_in_func
16685 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
16686 {
16687 if let Some(ignore) = func.ignore_nulls {
16688 self.write_space();
16689 if ignore {
16690 self.write_keyword("IGNORE NULLS");
16691 } else {
16692 self.write_keyword("RESPECT NULLS");
16693 }
16694 }
16695 }
16696
16697 if !func.order_by.is_empty() {
16699 self.write_space();
16700 self.write_keyword("ORDER BY");
16701 self.write_space();
16702 for (i, ord) in func.order_by.iter().enumerate() {
16703 if i > 0 {
16704 self.write(", ");
16705 }
16706 self.generate_ordered(ord)?;
16707 }
16708 }
16709
16710 if let Some(limit) = &func.limit {
16712 self.write_space();
16713 self.write_keyword("LIMIT");
16714 self.write_space();
16715 if let Expression::Tuple(t) = limit.as_ref() {
16717 if t.expressions.len() == 2 {
16718 self.generate_expression(&t.expressions[0])?;
16719 self.write(", ");
16720 self.generate_expression(&t.expressions[1])?;
16721 } else {
16722 self.generate_expression(limit)?;
16723 }
16724 } else {
16725 self.generate_expression(limit)?;
16726 }
16727 }
16728
16729 self.write(")");
16730
16731 if !self.config.ignore_nulls_in_func
16733 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
16734 {
16735 if let Some(ignore) = func.ignore_nulls {
16736 self.write_space();
16737 if ignore {
16738 self.write_keyword("IGNORE NULLS");
16739 } else {
16740 self.write_keyword("RESPECT NULLS");
16741 }
16742 }
16743 }
16744
16745 if let Some(filter) = &func.filter {
16746 self.write_space();
16747 self.write_keyword("FILTER");
16748 self.write("(");
16749 self.write_keyword("WHERE");
16750 self.write_space();
16751 self.generate_expression(filter)?;
16752 self.write(")");
16753 }
16754
16755 Ok(())
16756 }
16757
16758 fn generate_window_function(&mut self, wf: &WindowFunction) -> Result<()> {
16759 self.generate_expression(&wf.this)?;
16760
16761 if let Some(keep) = &wf.keep {
16763 self.write_space();
16764 self.write_keyword("KEEP");
16765 self.write(" (");
16766 self.write_keyword("DENSE_RANK");
16767 self.write_space();
16768 if keep.first {
16769 self.write_keyword("FIRST");
16770 } else {
16771 self.write_keyword("LAST");
16772 }
16773 self.write_space();
16774 self.write_keyword("ORDER BY");
16775 self.write_space();
16776 for (i, ord) in keep.order_by.iter().enumerate() {
16777 if i > 0 {
16778 self.write(", ");
16779 }
16780 self.generate_ordered(ord)?;
16781 }
16782 self.write(")");
16783 }
16784
16785 let has_over = !wf.over.partition_by.is_empty()
16787 || !wf.over.order_by.is_empty()
16788 || wf.over.frame.is_some()
16789 || wf.over.window_name.is_some();
16790
16791 if has_over {
16793 self.write_space();
16794 self.write_keyword("OVER");
16795
16796 let has_specs = !wf.over.partition_by.is_empty()
16798 || !wf.over.order_by.is_empty()
16799 || wf.over.frame.is_some();
16800
16801 if wf.over.window_name.is_some() && !has_specs {
16802 self.write_space();
16804 self.write(&wf.over.window_name.as_ref().unwrap().name);
16805 } else {
16806 self.write(" (");
16808 self.generate_over(&wf.over)?;
16809 self.write(")");
16810 }
16811 } else if wf.keep.is_none() {
16812 self.write_space();
16814 self.write_keyword("OVER");
16815 self.write(" ()");
16816 }
16817
16818 Ok(())
16819 }
16820
16821 fn generate_within_group(&mut self, wg: &WithinGroup) -> Result<()> {
16823 self.generate_expression(&wg.this)?;
16824 self.write_space();
16825 self.write_keyword("WITHIN GROUP");
16826 self.write(" (");
16827 self.write_keyword("ORDER BY");
16828 self.write_space();
16829 for (i, ord) in wg.order_by.iter().enumerate() {
16830 if i > 0 {
16831 self.write(", ");
16832 }
16833 self.generate_ordered(ord)?;
16834 }
16835 self.write(")");
16836 Ok(())
16837 }
16838
16839 fn generate_over(&mut self, over: &Over) -> Result<()> {
16841 let mut has_content = false;
16842
16843 if let Some(name) = &over.window_name {
16845 self.write(&name.name);
16846 has_content = true;
16847 }
16848
16849 if !over.partition_by.is_empty() {
16851 if has_content {
16852 self.write_space();
16853 }
16854 self.write_keyword("PARTITION BY");
16855 self.write_space();
16856 for (i, expr) in over.partition_by.iter().enumerate() {
16857 if i > 0 {
16858 self.write(", ");
16859 }
16860 self.generate_expression(expr)?;
16861 }
16862 has_content = true;
16863 }
16864
16865 if !over.order_by.is_empty() {
16867 if has_content {
16868 self.write_space();
16869 }
16870 self.write_keyword("ORDER BY");
16871 self.write_space();
16872 for (i, ordered) in over.order_by.iter().enumerate() {
16873 if i > 0 {
16874 self.write(", ");
16875 }
16876 self.generate_ordered(ordered)?;
16877 }
16878 has_content = true;
16879 }
16880
16881 if let Some(frame) = &over.frame {
16883 if has_content {
16884 self.write_space();
16885 }
16886 self.generate_window_frame(frame)?;
16887 }
16888
16889 Ok(())
16890 }
16891
16892 fn generate_window_frame(&mut self, frame: &WindowFrame) -> Result<()> {
16893 let lowercase_frame = self.config.lowercase_window_frame_keywords;
16895
16896 if !lowercase_frame {
16898 if let Some(kind_text) = &frame.kind_text {
16899 self.write(kind_text);
16900 } else {
16901 match frame.kind {
16902 WindowFrameKind::Rows => self.write_keyword("ROWS"),
16903 WindowFrameKind::Range => self.write_keyword("RANGE"),
16904 WindowFrameKind::Groups => self.write_keyword("GROUPS"),
16905 }
16906 }
16907 } else {
16908 match frame.kind {
16909 WindowFrameKind::Rows => self.write("rows"),
16910 WindowFrameKind::Range => self.write("range"),
16911 WindowFrameKind::Groups => self.write("groups"),
16912 }
16913 }
16914
16915 self.write_space();
16918 let should_normalize = self.config.normalize_window_frame_between
16919 && frame.end.is_none()
16920 && matches!(
16921 frame.start,
16922 WindowFrameBound::Preceding(_)
16923 | WindowFrameBound::Following(_)
16924 | WindowFrameBound::UnboundedPreceding
16925 | WindowFrameBound::UnboundedFollowing
16926 );
16927
16928 if let Some(end) = &frame.end {
16929 self.write_keyword("BETWEEN");
16931 self.write_space();
16932 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
16933 self.write_space();
16934 self.write_keyword("AND");
16935 self.write_space();
16936 self.generate_window_frame_bound(end, frame.end_side_text.as_deref())?;
16937 } else if should_normalize {
16938 self.write_keyword("BETWEEN");
16940 self.write_space();
16941 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
16942 self.write_space();
16943 self.write_keyword("AND");
16944 self.write_space();
16945 self.write_keyword("CURRENT ROW");
16946 } else {
16947 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
16949 }
16950
16951 if let Some(exclude) = &frame.exclude {
16953 self.write_space();
16954 self.write_keyword("EXCLUDE");
16955 self.write_space();
16956 match exclude {
16957 WindowFrameExclude::CurrentRow => self.write_keyword("CURRENT ROW"),
16958 WindowFrameExclude::Group => self.write_keyword("GROUP"),
16959 WindowFrameExclude::Ties => self.write_keyword("TIES"),
16960 WindowFrameExclude::NoOthers => self.write_keyword("NO OTHERS"),
16961 }
16962 }
16963
16964 Ok(())
16965 }
16966
16967 fn generate_window_frame_bound(
16968 &mut self,
16969 bound: &WindowFrameBound,
16970 side_text: Option<&str>,
16971 ) -> Result<()> {
16972 let lowercase_frame = self.config.lowercase_window_frame_keywords;
16974
16975 match bound {
16976 WindowFrameBound::CurrentRow => {
16977 self.write_keyword("CURRENT ROW");
16978 }
16979 WindowFrameBound::UnboundedPreceding => {
16980 self.write_keyword("UNBOUNDED");
16981 self.write_space();
16982 if lowercase_frame {
16983 self.write("preceding");
16984 } else if let Some(text) = side_text {
16985 self.write(text);
16986 } else {
16987 self.write_keyword("PRECEDING");
16988 }
16989 }
16990 WindowFrameBound::UnboundedFollowing => {
16991 self.write_keyword("UNBOUNDED");
16992 self.write_space();
16993 if lowercase_frame {
16994 self.write("following");
16995 } else if let Some(text) = side_text {
16996 self.write(text);
16997 } else {
16998 self.write_keyword("FOLLOWING");
16999 }
17000 }
17001 WindowFrameBound::Preceding(expr) => {
17002 self.generate_expression(expr)?;
17003 self.write_space();
17004 if lowercase_frame {
17005 self.write("preceding");
17006 } else if let Some(text) = side_text {
17007 self.write(text);
17008 } else {
17009 self.write_keyword("PRECEDING");
17010 }
17011 }
17012 WindowFrameBound::Following(expr) => {
17013 self.generate_expression(expr)?;
17014 self.write_space();
17015 if lowercase_frame {
17016 self.write("following");
17017 } else if let Some(text) = side_text {
17018 self.write(text);
17019 } else {
17020 self.write_keyword("FOLLOWING");
17021 }
17022 }
17023 WindowFrameBound::BarePreceding => {
17024 if lowercase_frame {
17025 self.write("preceding");
17026 } else if let Some(text) = side_text {
17027 self.write(text);
17028 } else {
17029 self.write_keyword("PRECEDING");
17030 }
17031 }
17032 WindowFrameBound::BareFollowing => {
17033 if lowercase_frame {
17034 self.write("following");
17035 } else if let Some(text) = side_text {
17036 self.write(text);
17037 } else {
17038 self.write_keyword("FOLLOWING");
17039 }
17040 }
17041 WindowFrameBound::Value(expr) => {
17042 self.generate_expression(expr)?;
17044 }
17045 }
17046 Ok(())
17047 }
17048
17049 fn generate_interval(&mut self, interval: &Interval) -> Result<()> {
17050 let skip_interval_keyword = matches!(self.config.dialect, Some(DialectType::Oracle))
17053 && matches!(&interval.unit, Some(IntervalUnitSpec::ExprSpan(_)))
17054 && !matches!(&interval.this, Some(Expression::Literal(_)));
17055
17056 if self.config.single_string_interval {
17059 if let (
17060 Some(Expression::Literal(Literal::String(ref val))),
17061 Some(IntervalUnitSpec::Simple {
17062 ref unit,
17063 ref use_plural,
17064 }),
17065 ) = (&interval.this, &interval.unit)
17066 {
17067 self.write_keyword("INTERVAL");
17068 self.write_space();
17069 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
17070 let unit_str = self.interval_unit_str(unit, effective_plural);
17071 self.write("'");
17072 self.write(val);
17073 self.write(" ");
17074 self.write(&unit_str);
17075 self.write("'");
17076 return Ok(());
17077 }
17078 }
17079
17080 if !skip_interval_keyword {
17081 self.write_keyword("INTERVAL");
17082 }
17083
17084 if let Some(ref value) = interval.this {
17086 if !skip_interval_keyword {
17087 self.write_space();
17088 }
17089 let needs_parens = interval.unit.is_some()
17093 && matches!(
17094 value,
17095 Expression::Add(_)
17096 | Expression::Sub(_)
17097 | Expression::Mul(_)
17098 | Expression::Div(_)
17099 | Expression::Mod(_)
17100 | Expression::BitwiseAnd(_)
17101 | Expression::BitwiseOr(_)
17102 | Expression::BitwiseXor(_)
17103 );
17104 if needs_parens {
17105 self.write("(");
17106 }
17107 self.generate_expression(value)?;
17108 if needs_parens {
17109 self.write(")");
17110 }
17111 }
17112
17113 if let Some(ref unit_spec) = interval.unit {
17115 self.write_space();
17116 self.write_interval_unit_spec(unit_spec)?;
17117 }
17118
17119 Ok(())
17120 }
17121
17122 fn interval_unit_str(&self, unit: &IntervalUnit, use_plural: bool) -> &'static str {
17124 match (unit, use_plural) {
17125 (IntervalUnit::Year, false) => "YEAR",
17126 (IntervalUnit::Year, true) => "YEARS",
17127 (IntervalUnit::Quarter, false) => "QUARTER",
17128 (IntervalUnit::Quarter, true) => "QUARTERS",
17129 (IntervalUnit::Month, false) => "MONTH",
17130 (IntervalUnit::Month, true) => "MONTHS",
17131 (IntervalUnit::Week, false) => "WEEK",
17132 (IntervalUnit::Week, true) => "WEEKS",
17133 (IntervalUnit::Day, false) => "DAY",
17134 (IntervalUnit::Day, true) => "DAYS",
17135 (IntervalUnit::Hour, false) => "HOUR",
17136 (IntervalUnit::Hour, true) => "HOURS",
17137 (IntervalUnit::Minute, false) => "MINUTE",
17138 (IntervalUnit::Minute, true) => "MINUTES",
17139 (IntervalUnit::Second, false) => "SECOND",
17140 (IntervalUnit::Second, true) => "SECONDS",
17141 (IntervalUnit::Millisecond, false) => "MILLISECOND",
17142 (IntervalUnit::Millisecond, true) => "MILLISECONDS",
17143 (IntervalUnit::Microsecond, false) => "MICROSECOND",
17144 (IntervalUnit::Microsecond, true) => "MICROSECONDS",
17145 (IntervalUnit::Nanosecond, false) => "NANOSECOND",
17146 (IntervalUnit::Nanosecond, true) => "NANOSECONDS",
17147 }
17148 }
17149
17150 fn write_interval_unit_spec(&mut self, unit_spec: &IntervalUnitSpec) -> Result<()> {
17151 match unit_spec {
17152 IntervalUnitSpec::Simple { unit, use_plural } => {
17153 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
17155 self.write_simple_interval_unit(unit, effective_plural);
17156 }
17157 IntervalUnitSpec::Span(span) => {
17158 self.write_simple_interval_unit(&span.this, false);
17159 self.write_space();
17160 self.write_keyword("TO");
17161 self.write_space();
17162 self.write_simple_interval_unit(&span.expression, false);
17163 }
17164 IntervalUnitSpec::ExprSpan(span) => {
17165 self.generate_expression(&span.this)?;
17167 self.write_space();
17168 self.write_keyword("TO");
17169 self.write_space();
17170 self.generate_expression(&span.expression)?;
17171 }
17172 IntervalUnitSpec::Expr(expr) => {
17173 self.generate_expression(expr)?;
17174 }
17175 }
17176 Ok(())
17177 }
17178
17179 fn write_simple_interval_unit(&mut self, unit: &IntervalUnit, use_plural: bool) {
17180 match (unit, use_plural) {
17182 (IntervalUnit::Year, false) => self.write_keyword("YEAR"),
17183 (IntervalUnit::Year, true) => self.write_keyword("YEARS"),
17184 (IntervalUnit::Quarter, false) => self.write_keyword("QUARTER"),
17185 (IntervalUnit::Quarter, true) => self.write_keyword("QUARTERS"),
17186 (IntervalUnit::Month, false) => self.write_keyword("MONTH"),
17187 (IntervalUnit::Month, true) => self.write_keyword("MONTHS"),
17188 (IntervalUnit::Week, false) => self.write_keyword("WEEK"),
17189 (IntervalUnit::Week, true) => self.write_keyword("WEEKS"),
17190 (IntervalUnit::Day, false) => self.write_keyword("DAY"),
17191 (IntervalUnit::Day, true) => self.write_keyword("DAYS"),
17192 (IntervalUnit::Hour, false) => self.write_keyword("HOUR"),
17193 (IntervalUnit::Hour, true) => self.write_keyword("HOURS"),
17194 (IntervalUnit::Minute, false) => self.write_keyword("MINUTE"),
17195 (IntervalUnit::Minute, true) => self.write_keyword("MINUTES"),
17196 (IntervalUnit::Second, false) => self.write_keyword("SECOND"),
17197 (IntervalUnit::Second, true) => self.write_keyword("SECONDS"),
17198 (IntervalUnit::Millisecond, false) => self.write_keyword("MILLISECOND"),
17199 (IntervalUnit::Millisecond, true) => self.write_keyword("MILLISECONDS"),
17200 (IntervalUnit::Microsecond, false) => self.write_keyword("MICROSECOND"),
17201 (IntervalUnit::Microsecond, true) => self.write_keyword("MICROSECONDS"),
17202 (IntervalUnit::Nanosecond, false) => self.write_keyword("NANOSECOND"),
17203 (IntervalUnit::Nanosecond, true) => self.write_keyword("NANOSECONDS"),
17204 }
17205 }
17206
17207 fn write_redshift_date_part(&mut self, expr: &Expression) {
17210 let part_str = self.extract_date_part_string(expr);
17211 if let Some(part) = part_str {
17212 let normalized = self.normalize_date_part(&part);
17213 self.write_keyword(&normalized);
17214 } else {
17215 let _ = self.generate_expression(expr);
17217 }
17218 }
17219
17220 fn write_redshift_date_part_quoted(&mut self, expr: &Expression) {
17223 let part_str = self.extract_date_part_string(expr);
17224 if let Some(part) = part_str {
17225 let normalized = self.normalize_date_part(&part);
17226 self.write("'");
17227 self.write(&normalized);
17228 self.write("'");
17229 } else {
17230 let _ = self.generate_expression(expr);
17232 }
17233 }
17234
17235 fn extract_date_part_string(&self, expr: &Expression) -> Option<String> {
17237 match expr {
17238 Expression::Literal(crate::expressions::Literal::String(s)) => Some(s.clone()),
17239 Expression::Identifier(id) => Some(id.name.clone()),
17240 Expression::Column(col) if col.table.is_none() => {
17241 Some(col.name.name.clone())
17243 }
17244 _ => None,
17245 }
17246 }
17247
17248 fn normalize_date_part(&self, part: &str) -> String {
17251 let lower = part.to_lowercase();
17252 match lower.as_str() {
17253 "day" | "days" | "d" => "DAY".to_string(),
17254 "month" | "months" | "mon" | "mm" => "MONTH".to_string(),
17255 "year" | "years" | "y" | "yy" | "yyyy" => "YEAR".to_string(),
17256 "week" | "weeks" | "w" | "wk" => "WEEK".to_string(),
17257 "hour" | "hours" | "h" | "hh" => "HOUR".to_string(),
17258 "minute" | "minutes" | "m" | "mi" | "n" => "MINUTE".to_string(),
17259 "second" | "seconds" | "s" | "ss" => "SECOND".to_string(),
17260 "millisecond" | "milliseconds" | "ms" => "MILLISECOND".to_string(),
17261 "microsecond" | "microseconds" | "us" => "MICROSECOND".to_string(),
17262 "quarter" | "quarters" | "q" | "qq" => "QUARTER".to_string(),
17263 _ => part.to_uppercase(),
17264 }
17265 }
17266
17267 fn write_datetime_field(&mut self, field: &DateTimeField) {
17268 match field {
17269 DateTimeField::Year => self.write_keyword("YEAR"),
17270 DateTimeField::Month => self.write_keyword("MONTH"),
17271 DateTimeField::Day => self.write_keyword("DAY"),
17272 DateTimeField::Hour => self.write_keyword("HOUR"),
17273 DateTimeField::Minute => self.write_keyword("MINUTE"),
17274 DateTimeField::Second => self.write_keyword("SECOND"),
17275 DateTimeField::Millisecond => self.write_keyword("MILLISECOND"),
17276 DateTimeField::Microsecond => self.write_keyword("MICROSECOND"),
17277 DateTimeField::DayOfWeek => {
17278 let name = match self.config.dialect {
17279 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFWEEK",
17280 _ => "DOW",
17281 };
17282 self.write_keyword(name);
17283 }
17284 DateTimeField::DayOfYear => {
17285 let name = match self.config.dialect {
17286 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFYEAR",
17287 _ => "DOY",
17288 };
17289 self.write_keyword(name);
17290 }
17291 DateTimeField::Week => self.write_keyword("WEEK"),
17292 DateTimeField::WeekWithModifier(modifier) => {
17293 self.write_keyword("WEEK");
17294 self.write("(");
17295 self.write(modifier);
17296 self.write(")");
17297 }
17298 DateTimeField::Quarter => self.write_keyword("QUARTER"),
17299 DateTimeField::Epoch => self.write_keyword("EPOCH"),
17300 DateTimeField::Timezone => self.write_keyword("TIMEZONE"),
17301 DateTimeField::TimezoneHour => self.write_keyword("TIMEZONE_HOUR"),
17302 DateTimeField::TimezoneMinute => self.write_keyword("TIMEZONE_MINUTE"),
17303 DateTimeField::Date => self.write_keyword("DATE"),
17304 DateTimeField::Time => self.write_keyword("TIME"),
17305 DateTimeField::Custom(name) => self.write(name),
17306 }
17307 }
17308
17309 fn write_datetime_field_lower(&mut self, field: &DateTimeField) {
17311 match field {
17312 DateTimeField::Year => self.write("year"),
17313 DateTimeField::Month => self.write("month"),
17314 DateTimeField::Day => self.write("day"),
17315 DateTimeField::Hour => self.write("hour"),
17316 DateTimeField::Minute => self.write("minute"),
17317 DateTimeField::Second => self.write("second"),
17318 DateTimeField::Millisecond => self.write("millisecond"),
17319 DateTimeField::Microsecond => self.write("microsecond"),
17320 DateTimeField::DayOfWeek => self.write("dow"),
17321 DateTimeField::DayOfYear => self.write("doy"),
17322 DateTimeField::Week => self.write("week"),
17323 DateTimeField::WeekWithModifier(modifier) => {
17324 self.write("week(");
17325 self.write(modifier);
17326 self.write(")");
17327 }
17328 DateTimeField::Quarter => self.write("quarter"),
17329 DateTimeField::Epoch => self.write("epoch"),
17330 DateTimeField::Timezone => self.write("timezone"),
17331 DateTimeField::TimezoneHour => self.write("timezone_hour"),
17332 DateTimeField::TimezoneMinute => self.write("timezone_minute"),
17333 DateTimeField::Date => self.write("date"),
17334 DateTimeField::Time => self.write("time"),
17335 DateTimeField::Custom(name) => self.write(name),
17336 }
17337 }
17338
17339 fn generate_simple_func(&mut self, name: &str, arg: &Expression) -> Result<()> {
17342 self.write_keyword(name);
17343 self.write("(");
17344 self.generate_expression(arg)?;
17345 self.write(")");
17346 Ok(())
17347 }
17348
17349 fn generate_unary_func(
17351 &mut self,
17352 default_name: &str,
17353 f: &crate::expressions::UnaryFunc,
17354 ) -> Result<()> {
17355 let name = f.original_name.as_deref().unwrap_or(default_name);
17356 self.write_keyword(name);
17357 self.write("(");
17358 self.generate_expression(&f.this)?;
17359 self.write(")");
17360 Ok(())
17361 }
17362
17363 fn generate_sqrt_cbrt(
17365 &mut self,
17366 f: &crate::expressions::UnaryFunc,
17367 func_name: &str,
17368 _op: &str,
17369 ) -> Result<()> {
17370 self.write_keyword(func_name);
17373 self.write("(");
17374 self.generate_expression(&f.this)?;
17375 self.write(")");
17376 Ok(())
17377 }
17378
17379 fn generate_binary_func(
17380 &mut self,
17381 name: &str,
17382 arg1: &Expression,
17383 arg2: &Expression,
17384 ) -> Result<()> {
17385 self.write_keyword(name);
17386 self.write("(");
17387 self.generate_expression(arg1)?;
17388 self.write(", ");
17389 self.generate_expression(arg2)?;
17390 self.write(")");
17391 Ok(())
17392 }
17393
17394 fn generate_char_func(&mut self, f: &crate::expressions::CharFunc) -> Result<()> {
17398 let func_name = f.name.as_deref().unwrap_or("CHAR");
17400 self.write_keyword(func_name);
17401 self.write("(");
17402 for (i, arg) in f.args.iter().enumerate() {
17403 if i > 0 {
17404 self.write(", ");
17405 }
17406 self.generate_expression(arg)?;
17407 }
17408 if let Some(ref charset) = f.charset {
17409 self.write(" ");
17410 self.write_keyword("USING");
17411 self.write(" ");
17412 self.write(charset);
17413 }
17414 self.write(")");
17415 Ok(())
17416 }
17417
17418 fn generate_power(&mut self, f: &BinaryFunc) -> Result<()> {
17419 use crate::dialects::DialectType;
17420
17421 match self.config.dialect {
17422 Some(DialectType::Teradata) => {
17423 self.generate_expression(&f.this)?;
17425 self.write(" ** ");
17426 self.generate_expression(&f.expression)?;
17427 Ok(())
17428 }
17429 _ => {
17430 self.generate_binary_func("POWER", &f.this, &f.expression)
17432 }
17433 }
17434 }
17435
17436 fn generate_vararg_func(&mut self, name: &str, args: &[Expression]) -> Result<()> {
17437 self.write_func_name(name);
17438 self.write("(");
17439 for (i, arg) in args.iter().enumerate() {
17440 if i > 0 {
17441 self.write(", ");
17442 }
17443 self.generate_expression(arg)?;
17444 }
17445 self.write(")");
17446 Ok(())
17447 }
17448
17449 fn generate_concat_ws(&mut self, f: &ConcatWs) -> Result<()> {
17452 self.write_keyword("CONCAT_WS");
17453 self.write("(");
17454 self.generate_expression(&f.separator)?;
17455 for expr in &f.expressions {
17456 self.write(", ");
17457 self.generate_expression(expr)?;
17458 }
17459 self.write(")");
17460 Ok(())
17461 }
17462
17463 fn collect_concat_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
17464 if let Expression::Concat(op) = expr {
17465 Self::collect_concat_operands(&op.left, out);
17466 Self::collect_concat_operands(&op.right, out);
17467 } else {
17468 out.push(expr);
17469 }
17470 }
17471
17472 fn generate_mysql_concat_from_concat(&mut self, op: &BinaryOp) -> Result<()> {
17473 let mut operands = Vec::new();
17474 Self::collect_concat_operands(&op.left, &mut operands);
17475 Self::collect_concat_operands(&op.right, &mut operands);
17476
17477 self.write_keyword("CONCAT");
17478 self.write("(");
17479 for (i, operand) in operands.iter().enumerate() {
17480 if i > 0 {
17481 self.write(", ");
17482 }
17483 self.generate_expression(operand)?;
17484 }
17485 self.write(")");
17486 Ok(())
17487 }
17488
17489 fn collect_dpipe_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
17490 if let Expression::DPipe(dpipe) = expr {
17491 Self::collect_dpipe_operands(&dpipe.this, out);
17492 Self::collect_dpipe_operands(&dpipe.expression, out);
17493 } else {
17494 out.push(expr);
17495 }
17496 }
17497
17498 fn generate_mysql_concat_from_dpipe(&mut self, e: &DPipe) -> Result<()> {
17499 let mut operands = Vec::new();
17500 Self::collect_dpipe_operands(&e.this, &mut operands);
17501 Self::collect_dpipe_operands(&e.expression, &mut operands);
17502
17503 self.write_keyword("CONCAT");
17504 self.write("(");
17505 for (i, operand) in operands.iter().enumerate() {
17506 if i > 0 {
17507 self.write(", ");
17508 }
17509 self.generate_expression(operand)?;
17510 }
17511 self.write(")");
17512 Ok(())
17513 }
17514
17515 fn generate_substring(&mut self, f: &SubstringFunc) -> Result<()> {
17516 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
17518 if is_oracle {
17519 self.write_keyword("SUBSTR");
17520 } else {
17521 self.write_keyword("SUBSTRING");
17522 }
17523 self.write("(");
17524 self.generate_expression(&f.this)?;
17525 let force_from_for = matches!(self.config.dialect, Some(DialectType::PostgreSQL));
17527 let use_comma_syntax = matches!(
17529 self.config.dialect,
17530 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
17531 );
17532 if (f.from_for_syntax || force_from_for) && !use_comma_syntax {
17533 self.write_space();
17535 self.write_keyword("FROM");
17536 self.write_space();
17537 self.generate_expression(&f.start)?;
17538 if let Some(length) = &f.length {
17539 self.write_space();
17540 self.write_keyword("FOR");
17541 self.write_space();
17542 self.generate_expression(length)?;
17543 }
17544 } else {
17545 self.write(", ");
17547 self.generate_expression(&f.start)?;
17548 if let Some(length) = &f.length {
17549 self.write(", ");
17550 self.generate_expression(length)?;
17551 }
17552 }
17553 self.write(")");
17554 Ok(())
17555 }
17556
17557 fn generate_overlay(&mut self, f: &OverlayFunc) -> Result<()> {
17558 self.write_keyword("OVERLAY");
17559 self.write("(");
17560 self.generate_expression(&f.this)?;
17561 self.write_space();
17562 self.write_keyword("PLACING");
17563 self.write_space();
17564 self.generate_expression(&f.replacement)?;
17565 self.write_space();
17566 self.write_keyword("FROM");
17567 self.write_space();
17568 self.generate_expression(&f.from)?;
17569 if let Some(length) = &f.length {
17570 self.write_space();
17571 self.write_keyword("FOR");
17572 self.write_space();
17573 self.generate_expression(length)?;
17574 }
17575 self.write(")");
17576 Ok(())
17577 }
17578
17579 fn generate_trim(&mut self, f: &TrimFunc) -> Result<()> {
17580 if f.position_explicit && f.characters.is_none() {
17583 match f.position {
17584 TrimPosition::Leading => {
17585 self.write_keyword("LTRIM");
17586 self.write("(");
17587 self.generate_expression(&f.this)?;
17588 self.write(")");
17589 return Ok(());
17590 }
17591 TrimPosition::Trailing => {
17592 self.write_keyword("RTRIM");
17593 self.write("(");
17594 self.generate_expression(&f.this)?;
17595 self.write(")");
17596 return Ok(());
17597 }
17598 TrimPosition::Both => {
17599 }
17602 }
17603 }
17604
17605 self.write_keyword("TRIM");
17606 self.write("(");
17607 let force_standard = f.characters.is_some()
17610 && !f.sql_standard_syntax
17611 && matches!(
17612 self.config.dialect,
17613 Some(DialectType::Hive)
17614 | Some(DialectType::Spark)
17615 | Some(DialectType::Databricks)
17616 | Some(DialectType::ClickHouse)
17617 );
17618 let use_standard = (f.sql_standard_syntax || force_standard)
17619 && !(f.position_explicit
17620 && f.characters.is_none()
17621 && matches!(f.position, TrimPosition::Both));
17622 if use_standard {
17623 if f.position_explicit {
17626 match f.position {
17627 TrimPosition::Both => self.write_keyword("BOTH"),
17628 TrimPosition::Leading => self.write_keyword("LEADING"),
17629 TrimPosition::Trailing => self.write_keyword("TRAILING"),
17630 }
17631 self.write_space();
17632 }
17633 if let Some(chars) = &f.characters {
17634 self.generate_expression(chars)?;
17635 self.write_space();
17636 }
17637 self.write_keyword("FROM");
17638 self.write_space();
17639 self.generate_expression(&f.this)?;
17640 } else {
17641 self.generate_expression(&f.this)?;
17643 if let Some(chars) = &f.characters {
17644 self.write(", ");
17645 self.generate_expression(chars)?;
17646 }
17647 }
17648 self.write(")");
17649 Ok(())
17650 }
17651
17652 fn generate_replace(&mut self, f: &ReplaceFunc) -> Result<()> {
17653 self.write_keyword("REPLACE");
17654 self.write("(");
17655 self.generate_expression(&f.this)?;
17656 self.write(", ");
17657 self.generate_expression(&f.old)?;
17658 self.write(", ");
17659 self.generate_expression(&f.new)?;
17660 self.write(")");
17661 Ok(())
17662 }
17663
17664 fn generate_left_right(&mut self, name: &str, f: &LeftRightFunc) -> Result<()> {
17665 self.write_keyword(name);
17666 self.write("(");
17667 self.generate_expression(&f.this)?;
17668 self.write(", ");
17669 self.generate_expression(&f.length)?;
17670 self.write(")");
17671 Ok(())
17672 }
17673
17674 fn generate_repeat(&mut self, f: &RepeatFunc) -> Result<()> {
17675 self.write_keyword("REPEAT");
17676 self.write("(");
17677 self.generate_expression(&f.this)?;
17678 self.write(", ");
17679 self.generate_expression(&f.times)?;
17680 self.write(")");
17681 Ok(())
17682 }
17683
17684 fn generate_pad(&mut self, name: &str, f: &PadFunc) -> Result<()> {
17685 self.write_keyword(name);
17686 self.write("(");
17687 self.generate_expression(&f.this)?;
17688 self.write(", ");
17689 self.generate_expression(&f.length)?;
17690 if let Some(fill) = &f.fill {
17691 self.write(", ");
17692 self.generate_expression(fill)?;
17693 }
17694 self.write(")");
17695 Ok(())
17696 }
17697
17698 fn generate_split(&mut self, f: &SplitFunc) -> Result<()> {
17699 self.write_keyword("SPLIT");
17700 self.write("(");
17701 self.generate_expression(&f.this)?;
17702 self.write(", ");
17703 self.generate_expression(&f.delimiter)?;
17704 self.write(")");
17705 Ok(())
17706 }
17707
17708 fn generate_regexp_like(&mut self, f: &RegexpFunc) -> Result<()> {
17709 use crate::dialects::DialectType;
17710 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) && f.flags.is_none() {
17712 self.generate_expression(&f.this)?;
17713 self.write(" ~ ");
17714 self.generate_expression(&f.pattern)?;
17715 } else if matches!(
17716 self.config.dialect,
17717 Some(DialectType::SingleStore)
17718 | Some(DialectType::Spark)
17719 | Some(DialectType::Hive)
17720 | Some(DialectType::Databricks)
17721 ) && f.flags.is_none()
17722 {
17723 self.generate_expression(&f.this)?;
17725 self.write_keyword(" RLIKE ");
17726 self.generate_expression(&f.pattern)?;
17727 } else if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
17728 self.write_keyword("REGEXP");
17730 self.write("(");
17731 self.generate_expression(&f.this)?;
17732 self.write(", ");
17733 self.generate_expression(&f.pattern)?;
17734 if let Some(flags) = &f.flags {
17735 self.write(", ");
17736 self.generate_expression(flags)?;
17737 }
17738 self.write(")");
17739 } else {
17740 self.write_keyword("REGEXP_LIKE");
17741 self.write("(");
17742 self.generate_expression(&f.this)?;
17743 self.write(", ");
17744 self.generate_expression(&f.pattern)?;
17745 if let Some(flags) = &f.flags {
17746 self.write(", ");
17747 self.generate_expression(flags)?;
17748 }
17749 self.write(")");
17750 }
17751 Ok(())
17752 }
17753
17754 fn generate_regexp_replace(&mut self, f: &RegexpReplaceFunc) -> Result<()> {
17755 self.write_keyword("REGEXP_REPLACE");
17756 self.write("(");
17757 self.generate_expression(&f.this)?;
17758 self.write(", ");
17759 self.generate_expression(&f.pattern)?;
17760 self.write(", ");
17761 self.generate_expression(&f.replacement)?;
17762 if let Some(flags) = &f.flags {
17763 self.write(", ");
17764 self.generate_expression(flags)?;
17765 }
17766 self.write(")");
17767 Ok(())
17768 }
17769
17770 fn generate_regexp_extract(&mut self, f: &RegexpExtractFunc) -> Result<()> {
17771 self.write_keyword("REGEXP_EXTRACT");
17772 self.write("(");
17773 self.generate_expression(&f.this)?;
17774 self.write(", ");
17775 self.generate_expression(&f.pattern)?;
17776 if let Some(group) = &f.group {
17777 self.write(", ");
17778 self.generate_expression(group)?;
17779 }
17780 self.write(")");
17781 Ok(())
17782 }
17783
17784 fn generate_round(&mut self, f: &RoundFunc) -> Result<()> {
17787 self.write_keyword("ROUND");
17788 self.write("(");
17789 self.generate_expression(&f.this)?;
17790 if let Some(decimals) = &f.decimals {
17791 self.write(", ");
17792 self.generate_expression(decimals)?;
17793 }
17794 self.write(")");
17795 Ok(())
17796 }
17797
17798 fn generate_floor(&mut self, f: &FloorFunc) -> Result<()> {
17799 self.write_keyword("FLOOR");
17800 self.write("(");
17801 self.generate_expression(&f.this)?;
17802 if let Some(to) = &f.to {
17804 self.write(" ");
17805 self.write_keyword("TO");
17806 self.write(" ");
17807 self.generate_expression(to)?;
17808 } else if let Some(scale) = &f.scale {
17809 self.write(", ");
17810 self.generate_expression(scale)?;
17811 }
17812 self.write(")");
17813 Ok(())
17814 }
17815
17816 fn generate_ceil(&mut self, f: &CeilFunc) -> Result<()> {
17817 self.write_keyword("CEIL");
17818 self.write("(");
17819 self.generate_expression(&f.this)?;
17820 if let Some(to) = &f.to {
17822 self.write(" ");
17823 self.write_keyword("TO");
17824 self.write(" ");
17825 self.generate_expression(to)?;
17826 } else if let Some(decimals) = &f.decimals {
17827 self.write(", ");
17828 self.generate_expression(decimals)?;
17829 }
17830 self.write(")");
17831 Ok(())
17832 }
17833
17834 fn generate_log(&mut self, f: &LogFunc) -> Result<()> {
17835 use crate::expressions::Literal;
17836
17837 if let Some(base) = &f.base {
17838 if self.is_log_base_none() {
17841 if matches!(base, Expression::Literal(Literal::Number(s)) if s == "2") {
17842 self.write_func_name("LOG2");
17843 self.write("(");
17844 self.generate_expression(&f.this)?;
17845 self.write(")");
17846 return Ok(());
17847 } else if matches!(base, Expression::Literal(Literal::Number(s)) if s == "10") {
17848 self.write_func_name("LOG10");
17849 self.write("(");
17850 self.generate_expression(&f.this)?;
17851 self.write(")");
17852 return Ok(());
17853 }
17854 }
17856
17857 self.write_func_name("LOG");
17858 self.write("(");
17859 if self.is_log_value_first() {
17860 self.generate_expression(&f.this)?;
17862 self.write(", ");
17863 self.generate_expression(base)?;
17864 } else {
17865 self.generate_expression(base)?;
17867 self.write(", ");
17868 self.generate_expression(&f.this)?;
17869 }
17870 self.write(")");
17871 } else {
17872 self.write_func_name("LOG");
17874 self.write("(");
17875 self.generate_expression(&f.this)?;
17876 self.write(")");
17877 }
17878 Ok(())
17879 }
17880
17881 fn is_log_value_first(&self) -> bool {
17884 use crate::dialects::DialectType;
17885 matches!(
17886 self.config.dialect,
17887 Some(DialectType::BigQuery)
17888 | Some(DialectType::TSQL)
17889 | Some(DialectType::Tableau)
17890 | Some(DialectType::Fabric)
17891 )
17892 }
17893
17894 fn is_log_base_none(&self) -> bool {
17897 use crate::dialects::DialectType;
17898 matches!(
17899 self.config.dialect,
17900 Some(DialectType::Presto)
17901 | Some(DialectType::Trino)
17902 | Some(DialectType::ClickHouse)
17903 | Some(DialectType::Athena)
17904 )
17905 }
17906
17907 fn generate_current_time(&mut self, f: &CurrentTime) -> Result<()> {
17910 self.write_keyword("CURRENT_TIME");
17911 if let Some(precision) = f.precision {
17912 self.write(&format!("({})", precision));
17913 }
17914 Ok(())
17915 }
17916
17917 fn generate_current_timestamp(&mut self, f: &CurrentTimestamp) -> Result<()> {
17918 use crate::dialects::DialectType;
17919
17920 if f.sysdate {
17922 match self.config.dialect {
17923 Some(DialectType::Oracle) | Some(DialectType::Redshift) => {
17924 self.write_keyword("SYSDATE");
17925 return Ok(());
17926 }
17927 Some(DialectType::Snowflake) => {
17928 self.write_keyword("SYSDATE");
17930 self.write("()");
17931 return Ok(());
17932 }
17933 _ => {
17934 }
17936 }
17937 }
17938
17939 self.write_keyword("CURRENT_TIMESTAMP");
17940 if let Some(precision) = f.precision {
17942 self.write(&format!("({})", precision));
17943 } else if matches!(
17944 self.config.dialect,
17945 Some(crate::dialects::DialectType::MySQL)
17946 | Some(crate::dialects::DialectType::SingleStore)
17947 | Some(crate::dialects::DialectType::TiDB)
17948 | Some(crate::dialects::DialectType::Spark)
17949 | Some(crate::dialects::DialectType::Hive)
17950 | Some(crate::dialects::DialectType::Databricks)
17951 | Some(crate::dialects::DialectType::ClickHouse)
17952 | Some(crate::dialects::DialectType::BigQuery)
17953 | Some(crate::dialects::DialectType::Snowflake)
17954 ) {
17955 self.write("()");
17956 }
17957 Ok(())
17958 }
17959
17960 fn generate_at_time_zone(&mut self, f: &AtTimeZone) -> Result<()> {
17961 if self.config.dialect == Some(DialectType::Exasol) {
17963 self.write_keyword("CONVERT_TZ");
17964 self.write("(");
17965 self.generate_expression(&f.this)?;
17966 self.write(", 'UTC', ");
17967 self.generate_expression(&f.zone)?;
17968 self.write(")");
17969 return Ok(());
17970 }
17971
17972 self.generate_expression(&f.this)?;
17973 self.write_space();
17974 self.write_keyword("AT TIME ZONE");
17975 self.write_space();
17976 self.generate_expression(&f.zone)?;
17977 Ok(())
17978 }
17979
17980 fn generate_date_add(&mut self, f: &DateAddFunc, name: &str) -> Result<()> {
17981 use crate::dialects::DialectType;
17982
17983 let is_presto_like = matches!(
17986 self.config.dialect,
17987 Some(DialectType::Presto) | Some(DialectType::Trino)
17988 );
17989
17990 if is_presto_like {
17991 self.write_keyword(name);
17992 self.write("(");
17993 self.write("'");
17995 self.write_simple_interval_unit(&f.unit, false);
17996 self.write("'");
17997 self.write(", ");
17998 let needs_cast = !self.returns_integer_type(&f.interval);
18000 if needs_cast {
18001 self.write_keyword("CAST");
18002 self.write("(");
18003 }
18004 self.generate_expression(&f.interval)?;
18005 if needs_cast {
18006 self.write_space();
18007 self.write_keyword("AS");
18008 self.write_space();
18009 self.write_keyword("BIGINT");
18010 self.write(")");
18011 }
18012 self.write(", ");
18013 self.generate_expression(&f.this)?;
18014 self.write(")");
18015 } else {
18016 self.write_keyword(name);
18017 self.write("(");
18018 self.generate_expression(&f.this)?;
18019 self.write(", ");
18020 self.write_keyword("INTERVAL");
18021 self.write_space();
18022 self.generate_expression(&f.interval)?;
18023 self.write_space();
18024 self.write_simple_interval_unit(&f.unit, false); self.write(")");
18026 }
18027 Ok(())
18028 }
18029
18030 fn returns_integer_type(&self, expr: &Expression) -> bool {
18033 use crate::expressions::{DataType, Literal};
18034 match expr {
18035 Expression::Literal(Literal::Number(n)) => !n.contains('.'),
18037
18038 Expression::Floor(f) => self.returns_integer_type(&f.this),
18040
18041 Expression::Round(f) => {
18043 f.decimals.is_none() && self.returns_integer_type(&f.this)
18045 }
18046
18047 Expression::Sign(f) => self.returns_integer_type(&f.this),
18049
18050 Expression::Abs(f) => self.returns_integer_type(&f.this),
18052
18053 Expression::Mul(op) => {
18055 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
18056 }
18057 Expression::Add(op) => {
18058 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
18059 }
18060 Expression::Sub(op) => {
18061 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
18062 }
18063 Expression::Mod(op) => self.returns_integer_type(&op.left),
18064
18065 Expression::Cast(c) => matches!(
18067 &c.to,
18068 DataType::BigInt { .. }
18069 | DataType::Int { .. }
18070 | DataType::SmallInt { .. }
18071 | DataType::TinyInt { .. }
18072 ),
18073
18074 Expression::Neg(op) => self.returns_integer_type(&op.this),
18076
18077 Expression::Paren(p) => self.returns_integer_type(&p.this),
18079
18080 _ => false,
18083 }
18084 }
18085
18086 fn generate_datediff(&mut self, f: &DateDiffFunc) -> Result<()> {
18087 self.write_keyword("DATEDIFF");
18088 self.write("(");
18089 if let Some(unit) = &f.unit {
18090 self.write_simple_interval_unit(unit, false); self.write(", ");
18092 }
18093 self.generate_expression(&f.this)?;
18094 self.write(", ");
18095 self.generate_expression(&f.expression)?;
18096 self.write(")");
18097 Ok(())
18098 }
18099
18100 fn generate_date_trunc(&mut self, f: &DateTruncFunc) -> Result<()> {
18101 self.write_keyword("DATE_TRUNC");
18102 self.write("('");
18103 self.write_datetime_field(&f.unit);
18104 self.write("', ");
18105 self.generate_expression(&f.this)?;
18106 self.write(")");
18107 Ok(())
18108 }
18109
18110 fn generate_last_day(&mut self, f: &LastDayFunc) -> Result<()> {
18111 use crate::dialects::DialectType;
18112 use crate::expressions::DateTimeField;
18113
18114 self.write_keyword("LAST_DAY");
18115 self.write("(");
18116 self.generate_expression(&f.this)?;
18117 if let Some(unit) = &f.unit {
18118 self.write(", ");
18119 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
18122 if let DateTimeField::WeekWithModifier(_) = unit {
18123 self.write_keyword("WEEK");
18124 } else {
18125 self.write_datetime_field(unit);
18126 }
18127 } else {
18128 self.write_datetime_field(unit);
18129 }
18130 }
18131 self.write(")");
18132 Ok(())
18133 }
18134
18135 fn generate_extract(&mut self, f: &ExtractFunc) -> Result<()> {
18136 if matches!(
18138 self.config.dialect,
18139 Some(DialectType::TSQL) | Some(DialectType::Fabric)
18140 ) {
18141 self.write_keyword("DATEPART");
18142 self.write("(");
18143 self.write_datetime_field(&f.field);
18144 self.write(", ");
18145 self.generate_expression(&f.this)?;
18146 self.write(")");
18147 return Ok(());
18148 }
18149 self.write_keyword("EXTRACT");
18150 self.write("(");
18151 if matches!(
18153 self.config.dialect,
18154 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
18155 ) {
18156 self.write_datetime_field_lower(&f.field);
18157 } else {
18158 self.write_datetime_field(&f.field);
18159 }
18160 self.write_space();
18161 self.write_keyword("FROM");
18162 self.write_space();
18163 self.generate_expression(&f.this)?;
18164 self.write(")");
18165 Ok(())
18166 }
18167
18168 fn generate_to_date(&mut self, f: &ToDateFunc) -> Result<()> {
18169 self.write_keyword("TO_DATE");
18170 self.write("(");
18171 self.generate_expression(&f.this)?;
18172 if let Some(format) = &f.format {
18173 self.write(", ");
18174 self.generate_expression(format)?;
18175 }
18176 self.write(")");
18177 Ok(())
18178 }
18179
18180 fn generate_to_timestamp(&mut self, f: &ToTimestampFunc) -> Result<()> {
18181 self.write_keyword("TO_TIMESTAMP");
18182 self.write("(");
18183 self.generate_expression(&f.this)?;
18184 if let Some(format) = &f.format {
18185 self.write(", ");
18186 self.generate_expression(format)?;
18187 }
18188 self.write(")");
18189 Ok(())
18190 }
18191
18192 fn generate_if_func(&mut self, f: &IfFunc) -> Result<()> {
18195 use crate::dialects::DialectType;
18196
18197 if self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic) {
18199 self.write_keyword("CASE WHEN");
18200 self.write_space();
18201 self.generate_expression(&f.condition)?;
18202 self.write_space();
18203 self.write_keyword("THEN");
18204 self.write_space();
18205 self.generate_expression(&f.true_value)?;
18206 if let Some(false_val) = &f.false_value {
18207 self.write_space();
18208 self.write_keyword("ELSE");
18209 self.write_space();
18210 self.generate_expression(false_val)?;
18211 }
18212 self.write_space();
18213 self.write_keyword("END");
18214 return Ok(());
18215 }
18216
18217 if self.config.dialect == Some(DialectType::Exasol) {
18219 self.write_keyword("IF");
18220 self.write_space();
18221 self.generate_expression(&f.condition)?;
18222 self.write_space();
18223 self.write_keyword("THEN");
18224 self.write_space();
18225 self.generate_expression(&f.true_value)?;
18226 if let Some(false_val) = &f.false_value {
18227 self.write_space();
18228 self.write_keyword("ELSE");
18229 self.write_space();
18230 self.generate_expression(false_val)?;
18231 }
18232 self.write_space();
18233 self.write_keyword("ENDIF");
18234 return Ok(());
18235 }
18236
18237 let func_name = match self.config.dialect {
18239 Some(DialectType::Snowflake) => "IFF",
18240 Some(DialectType::SQLite) | Some(DialectType::TSQL) => "IIF",
18241 Some(DialectType::Drill) => "`IF`",
18242 _ => "IF",
18243 };
18244 self.write(func_name);
18245 self.write("(");
18246 self.generate_expression(&f.condition)?;
18247 self.write(", ");
18248 self.generate_expression(&f.true_value)?;
18249 if let Some(false_val) = &f.false_value {
18250 self.write(", ");
18251 self.generate_expression(false_val)?;
18252 }
18253 self.write(")");
18254 Ok(())
18255 }
18256
18257 fn generate_nvl2(&mut self, f: &Nvl2Func) -> Result<()> {
18258 self.write_keyword("NVL2");
18259 self.write("(");
18260 self.generate_expression(&f.this)?;
18261 self.write(", ");
18262 self.generate_expression(&f.true_value)?;
18263 self.write(", ");
18264 self.generate_expression(&f.false_value)?;
18265 self.write(")");
18266 Ok(())
18267 }
18268
18269 fn generate_count(&mut self, f: &CountFunc) -> Result<()> {
18272 let count_name = match self.config.normalize_functions {
18274 NormalizeFunctions::Upper => "COUNT".to_string(),
18275 NormalizeFunctions::Lower => "count".to_string(),
18276 NormalizeFunctions::None => f
18277 .original_name
18278 .clone()
18279 .unwrap_or_else(|| "COUNT".to_string()),
18280 };
18281 self.write(&count_name);
18282 self.write("(");
18283 if f.distinct {
18284 self.write_keyword("DISTINCT");
18285 self.write_space();
18286 }
18287 if f.star {
18288 self.write("*");
18289 } else if let Some(ref expr) = f.this {
18290 if let Expression::Tuple(tuple) = expr {
18292 let needs_transform =
18296 f.distinct && tuple.expressions.len() > 1 && !self.config.multi_arg_distinct;
18297
18298 if needs_transform {
18299 self.write_keyword("CASE");
18301 for e in &tuple.expressions {
18302 self.write_space();
18303 self.write_keyword("WHEN");
18304 self.write_space();
18305 self.generate_expression(e)?;
18306 self.write_space();
18307 self.write_keyword("IS NULL THEN NULL");
18308 }
18309 self.write_space();
18310 self.write_keyword("ELSE");
18311 self.write(" (");
18312 for (i, e) in tuple.expressions.iter().enumerate() {
18313 if i > 0 {
18314 self.write(", ");
18315 }
18316 self.generate_expression(e)?;
18317 }
18318 self.write(")");
18319 self.write_space();
18320 self.write_keyword("END");
18321 } else {
18322 for (i, e) in tuple.expressions.iter().enumerate() {
18323 if i > 0 {
18324 self.write(", ");
18325 }
18326 self.generate_expression(e)?;
18327 }
18328 }
18329 } else {
18330 self.generate_expression(expr)?;
18331 }
18332 }
18333 if let Some(ignore) = f.ignore_nulls {
18335 self.write_space();
18336 if ignore {
18337 self.write_keyword("IGNORE NULLS");
18338 } else {
18339 self.write_keyword("RESPECT NULLS");
18340 }
18341 }
18342 self.write(")");
18343 if let Some(ref filter) = f.filter {
18344 self.write_space();
18345 self.write_keyword("FILTER");
18346 self.write("(");
18347 self.write_keyword("WHERE");
18348 self.write_space();
18349 self.generate_expression(filter)?;
18350 self.write(")");
18351 }
18352 Ok(())
18353 }
18354
18355 fn generate_agg_func(&mut self, name: &str, f: &AggFunc) -> Result<()> {
18356 let func_name = match self.config.normalize_functions {
18358 NormalizeFunctions::Upper => name.to_uppercase(),
18359 NormalizeFunctions::Lower => name.to_lowercase(),
18360 NormalizeFunctions::None => {
18361 if let Some(ref original) = f.name {
18364 original.clone()
18365 } else {
18366 name.to_lowercase()
18367 }
18368 }
18369 };
18370 self.write(&func_name);
18371 self.write("(");
18372 if f.distinct {
18373 self.write_keyword("DISTINCT");
18374 self.write_space();
18375 }
18376 if !matches!(f.this, Expression::Null(_)) {
18378 self.generate_expression(&f.this)?;
18379 }
18380 if self.config.ignore_nulls_in_func
18383 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
18384 {
18385 match f.ignore_nulls {
18386 Some(true) => {
18387 self.write_space();
18388 self.write_keyword("IGNORE NULLS");
18389 }
18390 Some(false) => {
18391 self.write_space();
18392 self.write_keyword("RESPECT NULLS");
18393 }
18394 None => {}
18395 }
18396 }
18397 if let Some((ref expr, is_max)) = f.having_max {
18400 self.write_space();
18401 self.write_keyword("HAVING");
18402 self.write_space();
18403 if is_max {
18404 self.write_keyword("MAX");
18405 } else {
18406 self.write_keyword("MIN");
18407 }
18408 self.write_space();
18409 self.generate_expression(expr)?;
18410 }
18411 if !f.order_by.is_empty() {
18413 self.write_space();
18414 self.write_keyword("ORDER BY");
18415 self.write_space();
18416 for (i, ord) in f.order_by.iter().enumerate() {
18417 if i > 0 {
18418 self.write(", ");
18419 }
18420 self.generate_ordered(ord)?;
18421 }
18422 }
18423 if let Some(ref limit) = f.limit {
18425 self.write_space();
18426 self.write_keyword("LIMIT");
18427 self.write_space();
18428 if let Expression::Tuple(t) = limit.as_ref() {
18430 if t.expressions.len() == 2 {
18431 self.generate_expression(&t.expressions[0])?;
18432 self.write(", ");
18433 self.generate_expression(&t.expressions[1])?;
18434 } else {
18435 self.generate_expression(limit)?;
18436 }
18437 } else {
18438 self.generate_expression(limit)?;
18439 }
18440 }
18441 self.write(")");
18442 if !self.config.ignore_nulls_in_func
18445 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
18446 {
18447 match f.ignore_nulls {
18448 Some(true) => {
18449 self.write_space();
18450 self.write_keyword("IGNORE NULLS");
18451 }
18452 Some(false) => {
18453 self.write_space();
18454 self.write_keyword("RESPECT NULLS");
18455 }
18456 None => {}
18457 }
18458 }
18459 if let Some(ref filter) = f.filter {
18460 self.write_space();
18461 self.write_keyword("FILTER");
18462 self.write("(");
18463 self.write_keyword("WHERE");
18464 self.write_space();
18465 self.generate_expression(filter)?;
18466 self.write(")");
18467 }
18468 Ok(())
18469 }
18470
18471 fn generate_group_concat(&mut self, f: &GroupConcatFunc) -> Result<()> {
18472 self.write_keyword("GROUP_CONCAT");
18473 self.write("(");
18474 if f.distinct {
18475 self.write_keyword("DISTINCT");
18476 self.write_space();
18477 }
18478 self.generate_expression(&f.this)?;
18479 if let Some(ref order_by) = f.order_by {
18480 self.write_space();
18481 self.write_keyword("ORDER BY");
18482 self.write_space();
18483 for (i, ord) in order_by.iter().enumerate() {
18484 if i > 0 {
18485 self.write(", ");
18486 }
18487 self.generate_ordered(ord)?;
18488 }
18489 }
18490 if let Some(ref sep) = f.separator {
18491 if matches!(
18494 self.config.dialect,
18495 Some(crate::dialects::DialectType::SQLite)
18496 ) {
18497 self.write(", ");
18498 self.generate_expression(sep)?;
18499 } else {
18500 self.write_space();
18501 self.write_keyword("SEPARATOR");
18502 self.write_space();
18503 self.generate_expression(sep)?;
18504 }
18505 }
18506 self.write(")");
18507 if let Some(ref filter) = f.filter {
18508 self.write_space();
18509 self.write_keyword("FILTER");
18510 self.write("(");
18511 self.write_keyword("WHERE");
18512 self.write_space();
18513 self.generate_expression(filter)?;
18514 self.write(")");
18515 }
18516 Ok(())
18517 }
18518
18519 fn generate_string_agg(&mut self, f: &StringAggFunc) -> Result<()> {
18520 let is_tsql = matches!(
18521 self.config.dialect,
18522 Some(crate::dialects::DialectType::TSQL)
18523 );
18524 self.write_keyword("STRING_AGG");
18525 self.write("(");
18526 if f.distinct {
18527 self.write_keyword("DISTINCT");
18528 self.write_space();
18529 }
18530 self.generate_expression(&f.this)?;
18531 if let Some(ref separator) = f.separator {
18532 self.write(", ");
18533 self.generate_expression(separator)?;
18534 }
18535 if !is_tsql {
18537 if let Some(ref order_by) = f.order_by {
18538 self.write_space();
18539 self.write_keyword("ORDER BY");
18540 self.write_space();
18541 for (i, ord) in order_by.iter().enumerate() {
18542 if i > 0 {
18543 self.write(", ");
18544 }
18545 self.generate_ordered(ord)?;
18546 }
18547 }
18548 }
18549 if let Some(ref limit) = f.limit {
18550 self.write_space();
18551 self.write_keyword("LIMIT");
18552 self.write_space();
18553 self.generate_expression(limit)?;
18554 }
18555 self.write(")");
18556 if is_tsql {
18558 if let Some(ref order_by) = f.order_by {
18559 self.write_space();
18560 self.write_keyword("WITHIN GROUP");
18561 self.write(" (");
18562 self.write_keyword("ORDER BY");
18563 self.write_space();
18564 for (i, ord) in order_by.iter().enumerate() {
18565 if i > 0 {
18566 self.write(", ");
18567 }
18568 self.generate_ordered(ord)?;
18569 }
18570 self.write(")");
18571 }
18572 }
18573 if let Some(ref filter) = f.filter {
18574 self.write_space();
18575 self.write_keyword("FILTER");
18576 self.write("(");
18577 self.write_keyword("WHERE");
18578 self.write_space();
18579 self.generate_expression(filter)?;
18580 self.write(")");
18581 }
18582 Ok(())
18583 }
18584
18585 fn generate_listagg(&mut self, f: &ListAggFunc) -> Result<()> {
18586 use crate::dialects::DialectType;
18587 self.write_keyword("LISTAGG");
18588 self.write("(");
18589 if f.distinct {
18590 self.write_keyword("DISTINCT");
18591 self.write_space();
18592 }
18593 self.generate_expression(&f.this)?;
18594 if let Some(ref sep) = f.separator {
18595 self.write(", ");
18596 self.generate_expression(sep)?;
18597 } else if matches!(
18598 self.config.dialect,
18599 Some(DialectType::Trino) | Some(DialectType::Presto)
18600 ) {
18601 self.write(", ','");
18603 }
18604 if let Some(ref overflow) = f.on_overflow {
18605 self.write_space();
18606 self.write_keyword("ON OVERFLOW");
18607 self.write_space();
18608 match overflow {
18609 ListAggOverflow::Error => self.write_keyword("ERROR"),
18610 ListAggOverflow::Truncate { filler, with_count } => {
18611 self.write_keyword("TRUNCATE");
18612 if let Some(ref fill) = filler {
18613 self.write_space();
18614 self.generate_expression(fill)?;
18615 }
18616 if *with_count {
18617 self.write_space();
18618 self.write_keyword("WITH COUNT");
18619 } else {
18620 self.write_space();
18621 self.write_keyword("WITHOUT COUNT");
18622 }
18623 }
18624 }
18625 }
18626 self.write(")");
18627 if let Some(ref order_by) = f.order_by {
18628 self.write_space();
18629 self.write_keyword("WITHIN GROUP");
18630 self.write(" (");
18631 self.write_keyword("ORDER BY");
18632 self.write_space();
18633 for (i, ord) in order_by.iter().enumerate() {
18634 if i > 0 {
18635 self.write(", ");
18636 }
18637 self.generate_ordered(ord)?;
18638 }
18639 self.write(")");
18640 }
18641 if let Some(ref filter) = f.filter {
18642 self.write_space();
18643 self.write_keyword("FILTER");
18644 self.write("(");
18645 self.write_keyword("WHERE");
18646 self.write_space();
18647 self.generate_expression(filter)?;
18648 self.write(")");
18649 }
18650 Ok(())
18651 }
18652
18653 fn generate_sum_if(&mut self, f: &SumIfFunc) -> Result<()> {
18654 self.write_keyword("SUM_IF");
18655 self.write("(");
18656 self.generate_expression(&f.this)?;
18657 self.write(", ");
18658 self.generate_expression(&f.condition)?;
18659 self.write(")");
18660 if let Some(ref filter) = f.filter {
18661 self.write_space();
18662 self.write_keyword("FILTER");
18663 self.write("(");
18664 self.write_keyword("WHERE");
18665 self.write_space();
18666 self.generate_expression(filter)?;
18667 self.write(")");
18668 }
18669 Ok(())
18670 }
18671
18672 fn generate_approx_percentile(&mut self, f: &ApproxPercentileFunc) -> Result<()> {
18673 self.write_keyword("APPROX_PERCENTILE");
18674 self.write("(");
18675 self.generate_expression(&f.this)?;
18676 self.write(", ");
18677 self.generate_expression(&f.percentile)?;
18678 if let Some(ref acc) = f.accuracy {
18679 self.write(", ");
18680 self.generate_expression(acc)?;
18681 }
18682 self.write(")");
18683 if let Some(ref filter) = f.filter {
18684 self.write_space();
18685 self.write_keyword("FILTER");
18686 self.write("(");
18687 self.write_keyword("WHERE");
18688 self.write_space();
18689 self.generate_expression(filter)?;
18690 self.write(")");
18691 }
18692 Ok(())
18693 }
18694
18695 fn generate_percentile(&mut self, name: &str, f: &PercentileFunc) -> Result<()> {
18696 self.write_keyword(name);
18697 self.write("(");
18698 self.generate_expression(&f.percentile)?;
18699 self.write(")");
18700 if let Some(ref order_by) = f.order_by {
18701 self.write_space();
18702 self.write_keyword("WITHIN GROUP");
18703 self.write(" (");
18704 self.write_keyword("ORDER BY");
18705 self.write_space();
18706 self.generate_expression(&f.this)?;
18707 for ord in order_by.iter() {
18708 if ord.desc {
18709 self.write_space();
18710 self.write_keyword("DESC");
18711 }
18712 }
18713 self.write(")");
18714 }
18715 if let Some(ref filter) = f.filter {
18716 self.write_space();
18717 self.write_keyword("FILTER");
18718 self.write("(");
18719 self.write_keyword("WHERE");
18720 self.write_space();
18721 self.generate_expression(filter)?;
18722 self.write(")");
18723 }
18724 Ok(())
18725 }
18726
18727 fn generate_ntile(&mut self, f: &NTileFunc) -> Result<()> {
18730 self.write_keyword("NTILE");
18731 self.write("(");
18732 if let Some(num_buckets) = &f.num_buckets {
18733 self.generate_expression(num_buckets)?;
18734 }
18735 if let Some(order_by) = &f.order_by {
18736 self.write_keyword(" ORDER BY ");
18737 for (i, ob) in order_by.iter().enumerate() {
18738 if i > 0 {
18739 self.write(", ");
18740 }
18741 self.generate_ordered(ob)?;
18742 }
18743 }
18744 self.write(")");
18745 Ok(())
18746 }
18747
18748 fn generate_lead_lag(&mut self, name: &str, f: &LeadLagFunc) -> Result<()> {
18749 self.write_keyword(name);
18750 self.write("(");
18751 self.generate_expression(&f.this)?;
18752 if let Some(ref offset) = f.offset {
18753 self.write(", ");
18754 self.generate_expression(offset)?;
18755 if let Some(ref default) = f.default {
18756 self.write(", ");
18757 self.generate_expression(default)?;
18758 }
18759 }
18760 if f.ignore_nulls && self.config.ignore_nulls_in_func {
18762 self.write_space();
18763 self.write_keyword("IGNORE NULLS");
18764 }
18765 self.write(")");
18766 if f.ignore_nulls && !self.config.ignore_nulls_in_func {
18768 self.write_space();
18769 self.write_keyword("IGNORE NULLS");
18770 }
18771 Ok(())
18772 }
18773
18774 fn generate_value_func(&mut self, name: &str, f: &ValueFunc) -> Result<()> {
18775 self.write_keyword(name);
18776 self.write("(");
18777 self.generate_expression(&f.this)?;
18778 if self.config.ignore_nulls_in_func {
18780 match f.ignore_nulls {
18781 Some(true) => {
18782 self.write_space();
18783 self.write_keyword("IGNORE NULLS");
18784 }
18785 Some(false) => {
18786 self.write_space();
18787 self.write_keyword("RESPECT NULLS");
18788 }
18789 None => {}
18790 }
18791 }
18792 self.write(")");
18793 if !self.config.ignore_nulls_in_func {
18795 match f.ignore_nulls {
18796 Some(true) => {
18797 self.write_space();
18798 self.write_keyword("IGNORE NULLS");
18799 }
18800 Some(false) => {
18801 self.write_space();
18802 self.write_keyword("RESPECT NULLS");
18803 }
18804 None => {}
18805 }
18806 }
18807 Ok(())
18808 }
18809
18810 fn generate_nth_value(&mut self, f: &NthValueFunc) -> Result<()> {
18811 self.write_keyword("NTH_VALUE");
18812 self.write("(");
18813 self.generate_expression(&f.this)?;
18814 self.write(", ");
18815 self.generate_expression(&f.offset)?;
18816 if self.config.ignore_nulls_in_func {
18818 match f.ignore_nulls {
18819 Some(true) => {
18820 self.write_space();
18821 self.write_keyword("IGNORE NULLS");
18822 }
18823 Some(false) => {
18824 self.write_space();
18825 self.write_keyword("RESPECT NULLS");
18826 }
18827 None => {}
18828 }
18829 }
18830 self.write(")");
18831 if matches!(
18833 self.config.dialect,
18834 Some(crate::dialects::DialectType::Snowflake)
18835 ) {
18836 match f.from_first {
18837 Some(true) => {
18838 self.write_space();
18839 self.write_keyword("FROM FIRST");
18840 }
18841 Some(false) => {
18842 self.write_space();
18843 self.write_keyword("FROM LAST");
18844 }
18845 None => {}
18846 }
18847 }
18848 if !self.config.ignore_nulls_in_func {
18850 match f.ignore_nulls {
18851 Some(true) => {
18852 self.write_space();
18853 self.write_keyword("IGNORE NULLS");
18854 }
18855 Some(false) => {
18856 self.write_space();
18857 self.write_keyword("RESPECT NULLS");
18858 }
18859 None => {}
18860 }
18861 }
18862 Ok(())
18863 }
18864
18865 fn generate_position(&mut self, f: &PositionFunc) -> Result<()> {
18868 if matches!(
18871 self.config.dialect,
18872 Some(crate::dialects::DialectType::ClickHouse)
18873 ) {
18874 self.write_keyword("POSITION");
18875 self.write("(");
18876 self.generate_expression(&f.string)?;
18877 self.write(", ");
18878 self.generate_expression(&f.substring)?;
18879 if let Some(ref start) = f.start {
18880 self.write(", ");
18881 self.generate_expression(start)?;
18882 }
18883 self.write(")");
18884 return Ok(());
18885 }
18886
18887 self.write_keyword("POSITION");
18888 self.write("(");
18889 self.generate_expression(&f.substring)?;
18890 self.write_space();
18891 self.write_keyword("IN");
18892 self.write_space();
18893 self.generate_expression(&f.string)?;
18894 if let Some(ref start) = f.start {
18895 self.write(", ");
18896 self.generate_expression(start)?;
18897 }
18898 self.write(")");
18899 Ok(())
18900 }
18901
18902 fn generate_rand(&mut self, f: &Rand) -> Result<()> {
18905 if f.lower.is_some() || f.upper.is_some() {
18907 self.write_keyword("RANDOM");
18908 self.write("(");
18909 if let Some(ref lower) = f.lower {
18910 self.generate_expression(lower)?;
18911 }
18912 if let Some(ref upper) = f.upper {
18913 self.write(", ");
18914 self.generate_expression(upper)?;
18915 }
18916 self.write(")");
18917 return Ok(());
18918 }
18919 let func_name = match self.config.dialect {
18921 Some(crate::dialects::DialectType::Snowflake)
18922 | Some(crate::dialects::DialectType::DuckDB) => "RANDOM",
18923 _ => "RAND",
18924 };
18925 self.write_keyword(func_name);
18926 self.write("(");
18927 if !matches!(
18929 self.config.dialect,
18930 Some(crate::dialects::DialectType::DuckDB)
18931 ) {
18932 if let Some(ref seed) = f.seed {
18933 self.generate_expression(seed)?;
18934 }
18935 }
18936 self.write(")");
18937 Ok(())
18938 }
18939
18940 fn generate_truncate_func(&mut self, f: &TruncateFunc) -> Result<()> {
18941 self.write_keyword("TRUNCATE");
18942 self.write("(");
18943 self.generate_expression(&f.this)?;
18944 if let Some(ref decimals) = f.decimals {
18945 self.write(", ");
18946 self.generate_expression(decimals)?;
18947 }
18948 self.write(")");
18949 Ok(())
18950 }
18951
18952 fn generate_decode(&mut self, f: &DecodeFunc) -> Result<()> {
18955 self.write_keyword("DECODE");
18956 self.write("(");
18957 self.generate_expression(&f.this)?;
18958 for (search, result) in &f.search_results {
18959 self.write(", ");
18960 self.generate_expression(search)?;
18961 self.write(", ");
18962 self.generate_expression(result)?;
18963 }
18964 if let Some(ref default) = f.default {
18965 self.write(", ");
18966 self.generate_expression(default)?;
18967 }
18968 self.write(")");
18969 Ok(())
18970 }
18971
18972 fn generate_date_format(&mut self, name: &str, f: &DateFormatFunc) -> Result<()> {
18975 self.write_keyword(name);
18976 self.write("(");
18977 self.generate_expression(&f.this)?;
18978 self.write(", ");
18979 self.generate_expression(&f.format)?;
18980 self.write(")");
18981 Ok(())
18982 }
18983
18984 fn generate_from_unixtime(&mut self, f: &FromUnixtimeFunc) -> Result<()> {
18985 self.write_keyword("FROM_UNIXTIME");
18986 self.write("(");
18987 self.generate_expression(&f.this)?;
18988 if let Some(ref format) = f.format {
18989 self.write(", ");
18990 self.generate_expression(format)?;
18991 }
18992 self.write(")");
18993 Ok(())
18994 }
18995
18996 fn generate_unix_timestamp(&mut self, f: &UnixTimestampFunc) -> Result<()> {
18997 self.write_keyword("UNIX_TIMESTAMP");
18998 self.write("(");
18999 if let Some(ref expr) = f.this {
19000 self.generate_expression(expr)?;
19001 if let Some(ref format) = f.format {
19002 self.write(", ");
19003 self.generate_expression(format)?;
19004 }
19005 } else if matches!(
19006 self.config.dialect,
19007 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
19008 ) {
19009 self.write_keyword("CURRENT_TIMESTAMP");
19011 self.write("()");
19012 }
19013 self.write(")");
19014 Ok(())
19015 }
19016
19017 fn generate_make_date(&mut self, f: &MakeDateFunc) -> Result<()> {
19018 self.write_keyword("MAKE_DATE");
19019 self.write("(");
19020 self.generate_expression(&f.year)?;
19021 self.write(", ");
19022 self.generate_expression(&f.month)?;
19023 self.write(", ");
19024 self.generate_expression(&f.day)?;
19025 self.write(")");
19026 Ok(())
19027 }
19028
19029 fn generate_make_timestamp(&mut self, f: &MakeTimestampFunc) -> Result<()> {
19030 self.write_keyword("MAKE_TIMESTAMP");
19031 self.write("(");
19032 self.generate_expression(&f.year)?;
19033 self.write(", ");
19034 self.generate_expression(&f.month)?;
19035 self.write(", ");
19036 self.generate_expression(&f.day)?;
19037 self.write(", ");
19038 self.generate_expression(&f.hour)?;
19039 self.write(", ");
19040 self.generate_expression(&f.minute)?;
19041 self.write(", ");
19042 self.generate_expression(&f.second)?;
19043 if let Some(ref tz) = f.timezone {
19044 self.write(", ");
19045 self.generate_expression(tz)?;
19046 }
19047 self.write(")");
19048 Ok(())
19049 }
19050
19051 fn extract_struct_field_names(expr: &Expression) -> Option<Vec<String>> {
19053 match expr {
19054 Expression::Struct(s) => {
19055 if s.fields.iter().all(|(name, _)| name.is_some()) {
19056 Some(
19057 s.fields
19058 .iter()
19059 .map(|(name, _)| name.as_deref().unwrap_or("").to_string())
19060 .collect(),
19061 )
19062 } else {
19063 None
19064 }
19065 }
19066 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => {
19067 if f.args.iter().all(|a| matches!(a, Expression::Alias(_))) {
19069 Some(
19070 f.args
19071 .iter()
19072 .filter_map(|a| {
19073 if let Expression::Alias(alias) = a {
19074 Some(alias.alias.name.clone())
19075 } else {
19076 None
19077 }
19078 })
19079 .collect(),
19080 )
19081 } else {
19082 None
19083 }
19084 }
19085 _ => None,
19086 }
19087 }
19088
19089 fn struct_has_unnamed_fields(expr: &Expression) -> bool {
19091 match expr {
19092 Expression::Struct(s) => s.fields.iter().any(|(name, _)| name.is_none()),
19093 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => {
19094 f.args.iter().any(|a| !matches!(a, Expression::Alias(_)))
19095 }
19096 _ => false,
19097 }
19098 }
19099
19100 fn struct_field_count(expr: &Expression) -> usize {
19102 match expr {
19103 Expression::Struct(s) => s.fields.len(),
19104 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => f.args.len(),
19105 _ => 0,
19106 }
19107 }
19108
19109 fn apply_struct_field_names(expr: &Expression, field_names: &[String]) -> Expression {
19111 match expr {
19112 Expression::Struct(s) => {
19113 let mut new_fields = Vec::with_capacity(s.fields.len());
19114 for (i, (name, value)) in s.fields.iter().enumerate() {
19115 if name.is_none() && i < field_names.len() {
19116 new_fields.push((Some(field_names[i].clone()), value.clone()));
19117 } else {
19118 new_fields.push((name.clone(), value.clone()));
19119 }
19120 }
19121 Expression::Struct(Box::new(crate::expressions::Struct { fields: new_fields }))
19122 }
19123 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => {
19124 let mut new_args = Vec::with_capacity(f.args.len());
19125 for (i, arg) in f.args.iter().enumerate() {
19126 if !matches!(arg, Expression::Alias(_)) && i < field_names.len() {
19127 new_args.push(Expression::Alias(Box::new(crate::expressions::Alias {
19129 this: arg.clone(),
19130 alias: crate::expressions::Identifier::new(field_names[i].clone()),
19131 column_aliases: Vec::new(),
19132 pre_alias_comments: Vec::new(),
19133 trailing_comments: Vec::new(),
19134 inferred_type: None,
19135 })));
19136 } else {
19137 new_args.push(arg.clone());
19138 }
19139 }
19140 Expression::Function(Box::new(crate::expressions::Function {
19141 name: f.name.clone(),
19142 args: new_args,
19143 distinct: f.distinct,
19144 trailing_comments: f.trailing_comments.clone(),
19145 use_bracket_syntax: f.use_bracket_syntax,
19146 no_parens: f.no_parens,
19147 quoted: f.quoted,
19148 span: None,
19149 inferred_type: None,
19150 }))
19151 }
19152 _ => expr.clone(),
19153 }
19154 }
19155
19156 fn inherit_struct_field_names(expressions: &[Expression]) -> Vec<Expression> {
19160 let first = match expressions.first() {
19161 Some(e) => e,
19162 None => return expressions.to_vec(),
19163 };
19164
19165 let field_names = match Self::extract_struct_field_names(first) {
19166 Some(names) if !names.is_empty() => names,
19167 _ => return expressions.to_vec(),
19168 };
19169
19170 let mut result = Vec::with_capacity(expressions.len());
19171 for (idx, expr) in expressions.iter().enumerate() {
19172 if idx == 0 {
19173 result.push(expr.clone());
19174 continue;
19175 }
19176 if Self::struct_field_count(expr) == field_names.len()
19178 && Self::struct_has_unnamed_fields(expr)
19179 {
19180 result.push(Self::apply_struct_field_names(expr, &field_names));
19181 } else {
19182 result.push(expr.clone());
19183 }
19184 }
19185 result
19186 }
19187
19188 fn generate_array_constructor(&mut self, f: &ArrayConstructor) -> Result<()> {
19191 let needs_inheritance = matches!(
19194 self.config.dialect,
19195 Some(DialectType::DuckDB)
19196 | Some(DialectType::Spark)
19197 | Some(DialectType::Databricks)
19198 | Some(DialectType::Hive)
19199 | Some(DialectType::Snowflake)
19200 | Some(DialectType::Presto)
19201 | Some(DialectType::Trino)
19202 );
19203 let propagated: Vec<Expression>;
19204 let expressions = if needs_inheritance && f.expressions.len() > 1 {
19205 propagated = Self::inherit_struct_field_names(&f.expressions);
19206 &propagated
19207 } else {
19208 &f.expressions
19209 };
19210
19211 let should_split = if self.config.pretty && !expressions.is_empty() {
19213 let mut expr_strings: Vec<String> = Vec::with_capacity(expressions.len());
19214 for expr in expressions {
19215 let mut temp_gen = Generator::with_config(self.config.clone());
19216 temp_gen.config.pretty = false;
19217 temp_gen.generate_expression(expr)?;
19218 expr_strings.push(temp_gen.output);
19219 }
19220 self.too_wide(&expr_strings)
19221 } else {
19222 false
19223 };
19224
19225 if f.bracket_notation {
19226 let (open, close) = match self.config.dialect {
19230 None
19231 | Some(DialectType::Generic)
19232 | Some(DialectType::Spark)
19233 | Some(DialectType::Databricks)
19234 | Some(DialectType::Hive) => {
19235 self.write_keyword("ARRAY");
19236 ("(", ")")
19237 }
19238 Some(DialectType::Presto)
19239 | Some(DialectType::Trino)
19240 | Some(DialectType::PostgreSQL)
19241 | Some(DialectType::Redshift)
19242 | Some(DialectType::Materialize)
19243 | Some(DialectType::RisingWave)
19244 | Some(DialectType::CockroachDB) => {
19245 self.write_keyword("ARRAY");
19246 ("[", "]")
19247 }
19248 _ => ("[", "]"),
19249 };
19250 self.write(open);
19251 if should_split {
19252 self.write_newline();
19253 self.indent_level += 1;
19254 for (i, expr) in expressions.iter().enumerate() {
19255 self.write_indent();
19256 self.generate_expression(expr)?;
19257 if i + 1 < expressions.len() {
19258 self.write(",");
19259 }
19260 self.write_newline();
19261 }
19262 self.indent_level -= 1;
19263 self.write_indent();
19264 } else {
19265 for (i, expr) in expressions.iter().enumerate() {
19266 if i > 0 {
19267 self.write(", ");
19268 }
19269 self.generate_expression(expr)?;
19270 }
19271 }
19272 self.write(close);
19273 } else {
19274 if f.use_list_keyword {
19276 self.write_keyword("LIST");
19277 } else {
19278 self.write_keyword("ARRAY");
19279 }
19280 let has_subquery = expressions
19283 .iter()
19284 .any(|e| matches!(e, Expression::Select(_)));
19285 let (open, close) = if matches!(
19286 self.config.dialect,
19287 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive)
19288 ) || (matches!(self.config.dialect, Some(DialectType::BigQuery))
19289 && has_subquery)
19290 {
19291 ("(", ")")
19292 } else {
19293 ("[", "]")
19294 };
19295 self.write(open);
19296 if should_split {
19297 self.write_newline();
19298 self.indent_level += 1;
19299 for (i, expr) in expressions.iter().enumerate() {
19300 self.write_indent();
19301 self.generate_expression(expr)?;
19302 if i + 1 < expressions.len() {
19303 self.write(",");
19304 }
19305 self.write_newline();
19306 }
19307 self.indent_level -= 1;
19308 self.write_indent();
19309 } else {
19310 for (i, expr) in expressions.iter().enumerate() {
19311 if i > 0 {
19312 self.write(", ");
19313 }
19314 self.generate_expression(expr)?;
19315 }
19316 }
19317 self.write(close);
19318 }
19319 Ok(())
19320 }
19321
19322 fn generate_array_sort(&mut self, f: &ArraySortFunc) -> Result<()> {
19323 self.write_keyword("ARRAY_SORT");
19324 self.write("(");
19325 self.generate_expression(&f.this)?;
19326 if let Some(ref comp) = f.comparator {
19327 self.write(", ");
19328 self.generate_expression(comp)?;
19329 }
19330 self.write(")");
19331 Ok(())
19332 }
19333
19334 fn generate_array_join(&mut self, name: &str, f: &ArrayJoinFunc) -> Result<()> {
19335 self.write_keyword(name);
19336 self.write("(");
19337 self.generate_expression(&f.this)?;
19338 self.write(", ");
19339 self.generate_expression(&f.separator)?;
19340 if let Some(ref null_rep) = f.null_replacement {
19341 self.write(", ");
19342 self.generate_expression(null_rep)?;
19343 }
19344 self.write(")");
19345 Ok(())
19346 }
19347
19348 fn generate_unnest(&mut self, f: &UnnestFunc) -> Result<()> {
19349 self.write_keyword("UNNEST");
19350 self.write("(");
19351 self.generate_expression(&f.this)?;
19352 for extra in &f.expressions {
19353 self.write(", ");
19354 self.generate_expression(extra)?;
19355 }
19356 self.write(")");
19357 if f.with_ordinality {
19358 self.write_space();
19359 if self.config.unnest_with_ordinality {
19360 self.write_keyword("WITH ORDINALITY");
19362 } else if f.offset_alias.is_some() {
19363 if let Some(ref alias) = f.alias {
19366 self.write_keyword("AS");
19367 self.write_space();
19368 self.generate_identifier(alias)?;
19369 self.write_space();
19370 }
19371 self.write_keyword("WITH OFFSET");
19372 if let Some(ref offset_alias) = f.offset_alias {
19373 self.write_space();
19374 self.write_keyword("AS");
19375 self.write_space();
19376 self.generate_identifier(offset_alias)?;
19377 }
19378 } else {
19379 self.write_keyword("WITH OFFSET");
19381 if f.alias.is_none() {
19382 self.write(" AS offset");
19383 }
19384 }
19385 }
19386 if let Some(ref alias) = f.alias {
19387 let should_add_alias = if !f.with_ordinality {
19389 true
19390 } else if self.config.unnest_with_ordinality {
19391 true
19393 } else if f.offset_alias.is_some() {
19394 false
19396 } else {
19397 true
19399 };
19400 if should_add_alias {
19401 self.write_space();
19402 self.write_keyword("AS");
19403 self.write_space();
19404 self.generate_identifier(alias)?;
19405 }
19406 }
19407 Ok(())
19408 }
19409
19410 fn generate_array_filter(&mut self, f: &ArrayFilterFunc) -> Result<()> {
19411 self.write_keyword("FILTER");
19412 self.write("(");
19413 self.generate_expression(&f.this)?;
19414 self.write(", ");
19415 self.generate_expression(&f.filter)?;
19416 self.write(")");
19417 Ok(())
19418 }
19419
19420 fn generate_array_transform(&mut self, f: &ArrayTransformFunc) -> Result<()> {
19421 self.write_keyword("TRANSFORM");
19422 self.write("(");
19423 self.generate_expression(&f.this)?;
19424 self.write(", ");
19425 self.generate_expression(&f.transform)?;
19426 self.write(")");
19427 Ok(())
19428 }
19429
19430 fn generate_sequence(&mut self, name: &str, f: &SequenceFunc) -> Result<()> {
19431 self.write_keyword(name);
19432 self.write("(");
19433 self.generate_expression(&f.start)?;
19434 self.write(", ");
19435 self.generate_expression(&f.stop)?;
19436 if let Some(ref step) = f.step {
19437 self.write(", ");
19438 self.generate_expression(step)?;
19439 }
19440 self.write(")");
19441 Ok(())
19442 }
19443
19444 fn generate_struct_constructor(&mut self, f: &StructConstructor) -> Result<()> {
19447 self.write_keyword("STRUCT");
19448 self.write("(");
19449 for (i, (name, expr)) in f.fields.iter().enumerate() {
19450 if i > 0 {
19451 self.write(", ");
19452 }
19453 if let Some(ref id) = name {
19454 self.generate_identifier(id)?;
19455 self.write(" ");
19456 self.write_keyword("AS");
19457 self.write(" ");
19458 }
19459 self.generate_expression(expr)?;
19460 }
19461 self.write(")");
19462 Ok(())
19463 }
19464
19465 fn generate_struct_function_cross_dialect(&mut self, func: &Function) -> Result<()> {
19467 let mut names: Vec<Option<String>> = Vec::new();
19470 let mut values: Vec<&Expression> = Vec::new();
19471 let mut all_named = true;
19472
19473 for arg in &func.args {
19474 match arg {
19475 Expression::Alias(a) => {
19476 names.push(Some(a.alias.name.clone()));
19477 values.push(&a.this);
19478 }
19479 _ => {
19480 names.push(None);
19481 values.push(arg);
19482 all_named = false;
19483 }
19484 }
19485 }
19486
19487 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
19488 self.write("{");
19490 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
19491 if i > 0 {
19492 self.write(", ");
19493 }
19494 if let Some(n) = name {
19495 self.write("'");
19496 self.write(n);
19497 self.write("'");
19498 } else {
19499 self.write("'_");
19500 self.write(&i.to_string());
19501 self.write("'");
19502 }
19503 self.write(": ");
19504 self.generate_expression(value)?;
19505 }
19506 self.write("}");
19507 return Ok(());
19508 }
19509
19510 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
19511 self.write_keyword("OBJECT_CONSTRUCT");
19513 self.write("(");
19514 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
19515 if i > 0 {
19516 self.write(", ");
19517 }
19518 if let Some(n) = name {
19519 self.write("'");
19520 self.write(n);
19521 self.write("'");
19522 } else {
19523 self.write("'_");
19524 self.write(&i.to_string());
19525 self.write("'");
19526 }
19527 self.write(", ");
19528 self.generate_expression(value)?;
19529 }
19530 self.write(")");
19531 return Ok(());
19532 }
19533
19534 if matches!(
19535 self.config.dialect,
19536 Some(DialectType::Presto) | Some(DialectType::Trino)
19537 ) {
19538 if all_named && !names.is_empty() {
19539 self.write_keyword("CAST");
19542 self.write("(");
19543 self.write_keyword("ROW");
19544 self.write("(");
19545 for (i, value) in values.iter().enumerate() {
19546 if i > 0 {
19547 self.write(", ");
19548 }
19549 self.generate_expression(value)?;
19550 }
19551 self.write(")");
19552 self.write(" ");
19553 self.write_keyword("AS");
19554 self.write(" ");
19555 self.write_keyword("ROW");
19556 self.write("(");
19557 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
19558 if i > 0 {
19559 self.write(", ");
19560 }
19561 if let Some(n) = name {
19562 self.write(n);
19563 }
19564 self.write(" ");
19565 let type_str = Self::infer_sql_type_for_presto(value);
19566 self.write_keyword(&type_str);
19567 }
19568 self.write(")");
19569 self.write(")");
19570 } else {
19571 self.write_keyword("ROW");
19573 self.write("(");
19574 for (i, value) in values.iter().enumerate() {
19575 if i > 0 {
19576 self.write(", ");
19577 }
19578 self.generate_expression(value)?;
19579 }
19580 self.write(")");
19581 }
19582 return Ok(());
19583 }
19584
19585 self.write_keyword("ROW");
19587 self.write("(");
19588 for (i, value) in values.iter().enumerate() {
19589 if i > 0 {
19590 self.write(", ");
19591 }
19592 self.generate_expression(value)?;
19593 }
19594 self.write(")");
19595 Ok(())
19596 }
19597
19598 fn infer_sql_type_for_presto(expr: &Expression) -> String {
19600 match expr {
19601 Expression::Literal(crate::expressions::Literal::String(_)) => "VARCHAR".to_string(),
19602 Expression::Literal(crate::expressions::Literal::Number(n)) => {
19603 if n.contains('.') {
19604 "DOUBLE".to_string()
19605 } else {
19606 "INTEGER".to_string()
19607 }
19608 }
19609 Expression::Boolean(_) => "BOOLEAN".to_string(),
19610 Expression::Literal(crate::expressions::Literal::Date(_)) => "DATE".to_string(),
19611 Expression::Literal(crate::expressions::Literal::Timestamp(_)) => {
19612 "TIMESTAMP".to_string()
19613 }
19614 Expression::Literal(crate::expressions::Literal::Datetime(_)) => {
19615 "TIMESTAMP".to_string()
19616 }
19617 Expression::Array(_) | Expression::ArrayFunc(_) => {
19618 "ARRAY(VARCHAR)".to_string()
19620 }
19621 Expression::Struct(_) | Expression::StructFunc(_) => "ROW".to_string(),
19623 Expression::Function(f) => {
19624 let up = f.name.to_uppercase();
19625 if up == "STRUCT" {
19626 "ROW".to_string()
19627 } else if up == "CURRENT_DATE" {
19628 "DATE".to_string()
19629 } else if up == "CURRENT_TIMESTAMP" || up == "NOW" {
19630 "TIMESTAMP".to_string()
19631 } else {
19632 "VARCHAR".to_string()
19633 }
19634 }
19635 _ => "VARCHAR".to_string(),
19636 }
19637 }
19638
19639 fn generate_struct_extract(&mut self, f: &StructExtractFunc) -> Result<()> {
19640 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
19642 self.write_keyword("STRUCT_EXTRACT");
19643 self.write("(");
19644 self.generate_expression(&f.this)?;
19645 self.write(", ");
19646 self.write("'");
19648 self.write(&f.field.name);
19649 self.write("'");
19650 self.write(")");
19651 return Ok(());
19652 }
19653 self.generate_expression(&f.this)?;
19654 self.write(".");
19655 self.generate_identifier(&f.field)
19656 }
19657
19658 fn generate_named_struct(&mut self, f: &NamedStructFunc) -> Result<()> {
19659 self.write_keyword("NAMED_STRUCT");
19660 self.write("(");
19661 for (i, (name, value)) in f.pairs.iter().enumerate() {
19662 if i > 0 {
19663 self.write(", ");
19664 }
19665 self.generate_expression(name)?;
19666 self.write(", ");
19667 self.generate_expression(value)?;
19668 }
19669 self.write(")");
19670 Ok(())
19671 }
19672
19673 fn generate_map_constructor(&mut self, f: &MapConstructor) -> Result<()> {
19676 if f.curly_brace_syntax {
19677 if f.with_map_keyword {
19679 self.write_keyword("MAP");
19680 self.write(" ");
19681 }
19682 self.write("{");
19683 for (i, (key, val)) in f.keys.iter().zip(f.values.iter()).enumerate() {
19684 if i > 0 {
19685 self.write(", ");
19686 }
19687 self.generate_expression(key)?;
19688 self.write(": ");
19689 self.generate_expression(val)?;
19690 }
19691 self.write("}");
19692 } else {
19693 self.write_keyword("MAP");
19695 self.write("(");
19696 self.write_keyword("ARRAY");
19697 self.write("[");
19698 for (i, key) in f.keys.iter().enumerate() {
19699 if i > 0 {
19700 self.write(", ");
19701 }
19702 self.generate_expression(key)?;
19703 }
19704 self.write("], ");
19705 self.write_keyword("ARRAY");
19706 self.write("[");
19707 for (i, val) in f.values.iter().enumerate() {
19708 if i > 0 {
19709 self.write(", ");
19710 }
19711 self.generate_expression(val)?;
19712 }
19713 self.write("])");
19714 }
19715 Ok(())
19716 }
19717
19718 fn generate_transform_func(&mut self, name: &str, f: &TransformFunc) -> Result<()> {
19719 self.write_keyword(name);
19720 self.write("(");
19721 self.generate_expression(&f.this)?;
19722 self.write(", ");
19723 self.generate_expression(&f.transform)?;
19724 self.write(")");
19725 Ok(())
19726 }
19727
19728 fn generate_json_extract(&mut self, name: &str, f: &JsonExtractFunc) -> Result<()> {
19731 use crate::dialects::DialectType;
19732
19733 let use_arrow = f.arrow_syntax && self.dialect_supports_json_arrow();
19735
19736 if use_arrow {
19737 self.generate_expression(&f.this)?;
19739 if name == "JSON_EXTRACT_SCALAR" || name == "JSON_EXTRACT_PATH_TEXT" {
19740 self.write(" ->> ");
19741 } else {
19742 self.write(" -> ");
19743 }
19744 self.generate_expression(&f.path)?;
19745 return Ok(());
19746 }
19747
19748 if f.hash_arrow_syntax
19750 && matches!(
19751 self.config.dialect,
19752 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
19753 )
19754 {
19755 self.generate_expression(&f.this)?;
19756 self.write(" #>> ");
19757 self.generate_expression(&f.path)?;
19758 return Ok(());
19759 }
19760
19761 let func_name = if matches!(self.config.dialect, Some(DialectType::Redshift)) {
19764 match name {
19765 "JSON_EXTRACT_SCALAR"
19766 | "JSON_EXTRACT_PATH_TEXT"
19767 | "JSON_EXTRACT"
19768 | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH_TEXT",
19769 _ => name,
19770 }
19771 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
19772 match name {
19773 "JSON_EXTRACT_SCALAR" | "JSON_EXTRACT_PATH_TEXT" => "JSON_EXTRACT_PATH_TEXT",
19774 "JSON_EXTRACT" | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH",
19775 _ => name,
19776 }
19777 } else {
19778 name
19779 };
19780
19781 self.write_keyword(func_name);
19782 self.write("(");
19783 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
19785 if let Expression::Cast(ref cast) = f.this {
19786 if matches!(cast.to, crate::expressions::DataType::Json) {
19787 self.generate_expression(&cast.this)?;
19788 } else {
19789 self.generate_expression(&f.this)?;
19790 }
19791 } else {
19792 self.generate_expression(&f.this)?;
19793 }
19794 } else {
19795 self.generate_expression(&f.this)?;
19796 }
19797 if matches!(
19800 self.config.dialect,
19801 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
19802 ) && (func_name == "JSON_EXTRACT_PATH" || func_name == "JSON_EXTRACT_PATH_TEXT")
19803 {
19804 if let Expression::Literal(Literal::String(ref s)) = f.path {
19805 let parts = Self::decompose_json_path(s);
19806 for part in &parts {
19807 self.write(", '");
19808 self.write(part);
19809 self.write("'");
19810 }
19811 } else {
19812 self.write(", ");
19813 self.generate_expression(&f.path)?;
19814 }
19815 } else {
19816 self.write(", ");
19817 self.generate_expression(&f.path)?;
19818 }
19819
19820 if let Some(ref wrapper) = f.wrapper_option {
19823 self.write_space();
19824 self.write_keyword(wrapper);
19825 }
19826 if let Some(ref quotes) = f.quotes_option {
19827 self.write_space();
19828 self.write_keyword(quotes);
19829 if f.on_scalar_string {
19830 self.write_space();
19831 self.write_keyword("ON SCALAR STRING");
19832 }
19833 }
19834 if let Some(ref on_err) = f.on_error {
19835 self.write_space();
19836 self.write_keyword(on_err);
19837 }
19838 if let Some(ref ret_type) = f.returning {
19839 self.write_space();
19840 self.write_keyword("RETURNING");
19841 self.write_space();
19842 self.generate_data_type(ret_type)?;
19843 }
19844
19845 self.write(")");
19846 Ok(())
19847 }
19848
19849 fn dialect_supports_json_arrow(&self) -> bool {
19851 use crate::dialects::DialectType;
19852 match self.config.dialect {
19853 Some(DialectType::PostgreSQL) => true,
19855 Some(DialectType::MySQL) => true,
19856 Some(DialectType::DuckDB) => true,
19857 Some(DialectType::CockroachDB) => true,
19858 Some(DialectType::StarRocks) => true,
19859 Some(DialectType::SQLite) => true,
19860 _ => false,
19862 }
19863 }
19864
19865 fn generate_json_path(&mut self, name: &str, f: &JsonPathFunc) -> Result<()> {
19866 use crate::dialects::DialectType;
19867
19868 if matches!(
19870 self.config.dialect,
19871 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
19872 ) && name == "JSON_EXTRACT_PATH"
19873 {
19874 self.generate_expression(&f.this)?;
19875 self.write(" #> ");
19876 if f.paths.len() == 1 {
19877 self.generate_expression(&f.paths[0])?;
19878 } else {
19879 self.write_keyword("ARRAY");
19881 self.write("[");
19882 for (i, path) in f.paths.iter().enumerate() {
19883 if i > 0 {
19884 self.write(", ");
19885 }
19886 self.generate_expression(path)?;
19887 }
19888 self.write("]");
19889 }
19890 return Ok(());
19891 }
19892
19893 self.write_keyword(name);
19894 self.write("(");
19895 self.generate_expression(&f.this)?;
19896 for path in &f.paths {
19897 self.write(", ");
19898 self.generate_expression(path)?;
19899 }
19900 self.write(")");
19901 Ok(())
19902 }
19903
19904 fn generate_json_object(&mut self, f: &JsonObjectFunc) -> Result<()> {
19905 use crate::dialects::DialectType;
19906
19907 self.write_keyword("JSON_OBJECT");
19908 self.write("(");
19909 if f.star {
19910 self.write("*");
19911 } else {
19912 let use_comma_syntax = self.config.json_key_value_pair_sep == ","
19916 || matches!(
19917 self.config.dialect,
19918 Some(DialectType::BigQuery)
19919 | Some(DialectType::MySQL)
19920 | Some(DialectType::SQLite)
19921 );
19922
19923 for (i, (key, value)) in f.pairs.iter().enumerate() {
19924 if i > 0 {
19925 self.write(", ");
19926 }
19927 self.generate_expression(key)?;
19928 if use_comma_syntax {
19929 self.write(", ");
19930 } else {
19931 self.write(": ");
19932 }
19933 self.generate_expression(value)?;
19934 }
19935 }
19936 if let Some(null_handling) = f.null_handling {
19937 self.write_space();
19938 match null_handling {
19939 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
19940 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
19941 }
19942 }
19943 if f.with_unique_keys {
19944 self.write_space();
19945 self.write_keyword("WITH UNIQUE KEYS");
19946 }
19947 if let Some(ref ret_type) = f.returning_type {
19948 self.write_space();
19949 self.write_keyword("RETURNING");
19950 self.write_space();
19951 self.generate_data_type(ret_type)?;
19952 if f.format_json {
19953 self.write_space();
19954 self.write_keyword("FORMAT JSON");
19955 }
19956 if let Some(ref enc) = f.encoding {
19957 self.write_space();
19958 self.write_keyword("ENCODING");
19959 self.write_space();
19960 self.write(enc);
19961 }
19962 }
19963 self.write(")");
19964 Ok(())
19965 }
19966
19967 fn generate_json_modify(&mut self, name: &str, f: &JsonModifyFunc) -> Result<()> {
19968 self.write_keyword(name);
19969 self.write("(");
19970 self.generate_expression(&f.this)?;
19971 for (path, value) in &f.path_values {
19972 self.write(", ");
19973 self.generate_expression(path)?;
19974 self.write(", ");
19975 self.generate_expression(value)?;
19976 }
19977 self.write(")");
19978 Ok(())
19979 }
19980
19981 fn generate_json_array_agg(&mut self, f: &JsonArrayAggFunc) -> Result<()> {
19982 self.write_keyword("JSON_ARRAYAGG");
19983 self.write("(");
19984 self.generate_expression(&f.this)?;
19985 if let Some(ref order_by) = f.order_by {
19986 self.write_space();
19987 self.write_keyword("ORDER BY");
19988 self.write_space();
19989 for (i, ord) in order_by.iter().enumerate() {
19990 if i > 0 {
19991 self.write(", ");
19992 }
19993 self.generate_ordered(ord)?;
19994 }
19995 }
19996 if let Some(null_handling) = f.null_handling {
19997 self.write_space();
19998 match null_handling {
19999 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
20000 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
20001 }
20002 }
20003 self.write(")");
20004 if let Some(ref filter) = f.filter {
20005 self.write_space();
20006 self.write_keyword("FILTER");
20007 self.write("(");
20008 self.write_keyword("WHERE");
20009 self.write_space();
20010 self.generate_expression(filter)?;
20011 self.write(")");
20012 }
20013 Ok(())
20014 }
20015
20016 fn generate_json_object_agg(&mut self, f: &JsonObjectAggFunc) -> Result<()> {
20017 self.write_keyword("JSON_OBJECTAGG");
20018 self.write("(");
20019 self.generate_expression(&f.key)?;
20020 self.write(": ");
20021 self.generate_expression(&f.value)?;
20022 if let Some(null_handling) = f.null_handling {
20023 self.write_space();
20024 match null_handling {
20025 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
20026 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
20027 }
20028 }
20029 self.write(")");
20030 if let Some(ref filter) = f.filter {
20031 self.write_space();
20032 self.write_keyword("FILTER");
20033 self.write("(");
20034 self.write_keyword("WHERE");
20035 self.write_space();
20036 self.generate_expression(filter)?;
20037 self.write(")");
20038 }
20039 Ok(())
20040 }
20041
20042 fn generate_convert(&mut self, f: &ConvertFunc) -> Result<()> {
20045 use crate::dialects::DialectType;
20046
20047 if self.config.dialect == Some(DialectType::Redshift) {
20049 self.write_keyword("CAST");
20050 self.write("(");
20051 self.generate_expression(&f.this)?;
20052 self.write_space();
20053 self.write_keyword("AS");
20054 self.write_space();
20055 self.generate_data_type(&f.to)?;
20056 self.write(")");
20057 return Ok(());
20058 }
20059
20060 self.write_keyword("CONVERT");
20061 self.write("(");
20062 self.generate_data_type(&f.to)?;
20063 self.write(", ");
20064 self.generate_expression(&f.this)?;
20065 if let Some(ref style) = f.style {
20066 self.write(", ");
20067 self.generate_expression(style)?;
20068 }
20069 self.write(")");
20070 Ok(())
20071 }
20072
20073 fn generate_lambda(&mut self, f: &LambdaExpr) -> Result<()> {
20076 if f.colon {
20077 self.write_keyword("LAMBDA");
20079 self.write_space();
20080 for (i, param) in f.parameters.iter().enumerate() {
20081 if i > 0 {
20082 self.write(", ");
20083 }
20084 self.generate_identifier(param)?;
20085 }
20086 self.write(" : ");
20087 } else {
20088 if f.parameters.len() == 1 {
20090 self.generate_identifier(&f.parameters[0])?;
20091 } else {
20092 self.write("(");
20093 for (i, param) in f.parameters.iter().enumerate() {
20094 if i > 0 {
20095 self.write(", ");
20096 }
20097 self.generate_identifier(param)?;
20098 }
20099 self.write(")");
20100 }
20101 self.write(" -> ");
20102 }
20103 self.generate_expression(&f.body)
20104 }
20105
20106 fn generate_named_argument(&mut self, f: &NamedArgument) -> Result<()> {
20107 self.generate_identifier(&f.name)?;
20108 match f.separator {
20109 NamedArgSeparator::DArrow => self.write(" => "),
20110 NamedArgSeparator::ColonEq => self.write(" := "),
20111 NamedArgSeparator::Eq => self.write(" = "),
20112 }
20113 self.generate_expression(&f.value)
20114 }
20115
20116 fn generate_table_argument(&mut self, f: &TableArgument) -> Result<()> {
20117 self.write_keyword(&f.prefix);
20118 self.write(" ");
20119 self.generate_expression(&f.this)
20120 }
20121
20122 fn generate_parameter(&mut self, f: &Parameter) -> Result<()> {
20123 match f.style {
20124 ParameterStyle::Question => self.write("?"),
20125 ParameterStyle::Dollar => {
20126 self.write("$");
20127 if let Some(idx) = f.index {
20128 self.write(&idx.to_string());
20129 } else if let Some(ref name) = f.name {
20130 self.write(name);
20132 }
20133 }
20134 ParameterStyle::DollarBrace => {
20135 self.write("${");
20137 if let Some(ref name) = f.name {
20138 self.write(name);
20139 }
20140 if let Some(ref expr) = f.expression {
20141 self.write(":");
20142 self.write(expr);
20143 }
20144 self.write("}");
20145 }
20146 ParameterStyle::Colon => {
20147 self.write(":");
20148 if let Some(idx) = f.index {
20149 self.write(&idx.to_string());
20150 } else if let Some(ref name) = f.name {
20151 self.write(name);
20152 }
20153 }
20154 ParameterStyle::At => {
20155 self.write("@");
20156 if let Some(ref name) = f.name {
20157 if f.string_quoted {
20158 self.write("'");
20159 self.write(name);
20160 self.write("'");
20161 } else if f.quoted {
20162 self.write("\"");
20163 self.write(name);
20164 self.write("\"");
20165 } else {
20166 self.write(name);
20167 }
20168 }
20169 }
20170 ParameterStyle::DoubleAt => {
20171 self.write("@@");
20172 if let Some(ref name) = f.name {
20173 self.write(name);
20174 }
20175 }
20176 ParameterStyle::DoubleDollar => {
20177 self.write("$$");
20178 if let Some(ref name) = f.name {
20179 self.write(name);
20180 }
20181 }
20182 ParameterStyle::Percent => {
20183 if let Some(ref name) = f.name {
20184 self.write("%(");
20186 self.write(name);
20187 self.write(")s");
20188 } else {
20189 self.write("%s");
20191 }
20192 }
20193 ParameterStyle::Brace => {
20194 self.write("{");
20197 if let Some(ref name) = f.name {
20198 self.write(name);
20199 }
20200 if let Some(ref expr) = f.expression {
20201 self.write(": ");
20202 self.write(expr);
20203 }
20204 self.write("}");
20205 }
20206 }
20207 Ok(())
20208 }
20209
20210 fn generate_placeholder(&mut self, f: &Placeholder) -> Result<()> {
20211 self.write("?");
20212 if let Some(idx) = f.index {
20213 self.write(&idx.to_string());
20214 }
20215 Ok(())
20216 }
20217
20218 fn generate_sql_comment(&mut self, f: &SqlComment) -> Result<()> {
20219 if f.is_block {
20220 self.write("/*");
20221 self.write(&f.text);
20222 self.write("*/");
20223 } else {
20224 self.write("--");
20225 self.write(&f.text);
20226 }
20227 Ok(())
20228 }
20229
20230 fn generate_similar_to(&mut self, f: &SimilarToExpr) -> Result<()> {
20233 self.generate_expression(&f.this)?;
20234 if f.not {
20235 self.write_space();
20236 self.write_keyword("NOT");
20237 }
20238 self.write_space();
20239 self.write_keyword("SIMILAR TO");
20240 self.write_space();
20241 self.generate_expression(&f.pattern)?;
20242 if let Some(ref escape) = f.escape {
20243 self.write_space();
20244 self.write_keyword("ESCAPE");
20245 self.write_space();
20246 self.generate_expression(escape)?;
20247 }
20248 Ok(())
20249 }
20250
20251 fn generate_quantified(&mut self, name: &str, f: &QuantifiedExpr) -> Result<()> {
20252 self.generate_expression(&f.this)?;
20253 self.write_space();
20254 if let Some(op) = &f.op {
20256 match op {
20257 QuantifiedOp::Eq => self.write("="),
20258 QuantifiedOp::Neq => self.write("<>"),
20259 QuantifiedOp::Lt => self.write("<"),
20260 QuantifiedOp::Lte => self.write("<="),
20261 QuantifiedOp::Gt => self.write(">"),
20262 QuantifiedOp::Gte => self.write(">="),
20263 }
20264 self.write_space();
20265 }
20266 self.write_keyword(name);
20267
20268 if matches!(&f.subquery, Expression::Subquery(_)) {
20270 self.write_space();
20271 self.generate_expression(&f.subquery)?;
20272 } else {
20273 self.write("(");
20274
20275 let is_statement = matches!(
20276 &f.subquery,
20277 Expression::Select(_)
20278 | Expression::Union(_)
20279 | Expression::Intersect(_)
20280 | Expression::Except(_)
20281 );
20282
20283 if self.config.pretty && is_statement {
20284 self.write_newline();
20285 self.indent_level += 1;
20286 self.write_indent();
20287 }
20288 self.generate_expression(&f.subquery)?;
20289 if self.config.pretty && is_statement {
20290 self.write_newline();
20291 self.indent_level -= 1;
20292 self.write_indent();
20293 }
20294 self.write(")");
20295 }
20296 Ok(())
20297 }
20298
20299 fn generate_overlaps(&mut self, f: &OverlapsExpr) -> Result<()> {
20300 if let (Some(this), Some(expr)) = (&f.this, &f.expression) {
20302 self.generate_expression(this)?;
20303 self.write_space();
20304 self.write_keyword("OVERLAPS");
20305 self.write_space();
20306 self.generate_expression(expr)?;
20307 } else if let (Some(ls), Some(le), Some(rs), Some(re)) =
20308 (&f.left_start, &f.left_end, &f.right_start, &f.right_end)
20309 {
20310 self.write("(");
20312 self.generate_expression(ls)?;
20313 self.write(", ");
20314 self.generate_expression(le)?;
20315 self.write(")");
20316 self.write_space();
20317 self.write_keyword("OVERLAPS");
20318 self.write_space();
20319 self.write("(");
20320 self.generate_expression(rs)?;
20321 self.write(", ");
20322 self.generate_expression(re)?;
20323 self.write(")");
20324 }
20325 Ok(())
20326 }
20327
20328 fn generate_try_cast(&mut self, cast: &Cast) -> Result<()> {
20331 use crate::dialects::DialectType;
20332
20333 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
20335 self.generate_expression(&cast.this)?;
20336 self.write(" !:> ");
20337 self.generate_data_type(&cast.to)?;
20338 return Ok(());
20339 }
20340
20341 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
20343 self.write_keyword("TRYCAST");
20344 self.write("(");
20345 self.generate_expression(&cast.this)?;
20346 self.write_space();
20347 self.write_keyword("AS");
20348 self.write_space();
20349 self.generate_data_type(&cast.to)?;
20350 self.write(")");
20351 return Ok(());
20352 }
20353
20354 let keyword = if matches!(
20356 self.config.dialect,
20357 Some(DialectType::Hive)
20358 | Some(DialectType::MySQL)
20359 | Some(DialectType::SQLite)
20360 | Some(DialectType::Oracle)
20361 | Some(DialectType::ClickHouse)
20362 | Some(DialectType::Redshift)
20363 | Some(DialectType::PostgreSQL)
20364 | Some(DialectType::StarRocks)
20365 | Some(DialectType::Doris)
20366 ) {
20367 "CAST"
20368 } else {
20369 "TRY_CAST"
20370 };
20371
20372 self.write_keyword(keyword);
20373 self.write("(");
20374 self.generate_expression(&cast.this)?;
20375 self.write_space();
20376 self.write_keyword("AS");
20377 self.write_space();
20378 self.generate_data_type(&cast.to)?;
20379
20380 if let Some(format) = &cast.format {
20382 self.write_space();
20383 self.write_keyword("FORMAT");
20384 self.write_space();
20385 self.generate_expression(format)?;
20386 }
20387
20388 self.write(")");
20389 Ok(())
20390 }
20391
20392 fn generate_safe_cast(&mut self, cast: &Cast) -> Result<()> {
20393 self.write_keyword("SAFE_CAST");
20394 self.write("(");
20395 self.generate_expression(&cast.this)?;
20396 self.write_space();
20397 self.write_keyword("AS");
20398 self.write_space();
20399 self.generate_data_type(&cast.to)?;
20400
20401 if let Some(format) = &cast.format {
20403 self.write_space();
20404 self.write_keyword("FORMAT");
20405 self.write_space();
20406 self.generate_expression(format)?;
20407 }
20408
20409 self.write(")");
20410 Ok(())
20411 }
20412
20413 fn generate_subscript(&mut self, s: &Subscript) -> Result<()> {
20416 self.generate_expression(&s.this)?;
20417 self.write("[");
20418 self.generate_expression(&s.index)?;
20419 self.write("]");
20420 Ok(())
20421 }
20422
20423 fn generate_dot_access(&mut self, d: &DotAccess) -> Result<()> {
20424 self.generate_expression(&d.this)?;
20425 let use_colon = matches!(self.config.dialect, Some(DialectType::Snowflake))
20428 && matches!(
20429 &d.this,
20430 Expression::Cast(_) | Expression::SafeCast(_) | Expression::TryCast(_)
20431 );
20432 if use_colon {
20433 self.write(":");
20434 } else {
20435 self.write(".");
20436 }
20437 self.generate_identifier(&d.field)
20438 }
20439
20440 fn generate_method_call(&mut self, m: &MethodCall) -> Result<()> {
20441 self.generate_expression(&m.this)?;
20442 self.write(".");
20443 if m.method.quoted {
20446 let q = self.config.identifier_quote;
20447 self.write(&format!("{}{}{}", q, m.method.name, q));
20448 } else {
20449 self.write(&m.method.name);
20450 }
20451 self.write("(");
20452 for (i, arg) in m.args.iter().enumerate() {
20453 if i > 0 {
20454 self.write(", ");
20455 }
20456 self.generate_expression(arg)?;
20457 }
20458 self.write(")");
20459 Ok(())
20460 }
20461
20462 fn generate_array_slice(&mut self, s: &ArraySlice) -> Result<()> {
20463 let needs_parens = matches!(
20466 &s.this,
20467 Expression::JsonExtract(f) if f.arrow_syntax
20468 ) || matches!(
20469 &s.this,
20470 Expression::JsonExtractScalar(f) if f.arrow_syntax
20471 );
20472
20473 if needs_parens {
20474 self.write("(");
20475 }
20476 self.generate_expression(&s.this)?;
20477 if needs_parens {
20478 self.write(")");
20479 }
20480 self.write("[");
20481 if let Some(start) = &s.start {
20482 self.generate_expression(start)?;
20483 }
20484 self.write(":");
20485 if let Some(end) = &s.end {
20486 self.generate_expression(end)?;
20487 }
20488 self.write("]");
20489 Ok(())
20490 }
20491
20492 fn generate_binary_op(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
20493 match &op.left {
20497 Expression::Column(col) => {
20498 if let Some(table) = &col.table {
20501 self.generate_identifier(table)?;
20502 self.write(".");
20503 }
20504 self.generate_identifier(&col.name)?;
20505 if col.join_mark && self.config.supports_column_join_marks {
20507 self.write(" (+)");
20508 }
20509 if op.left_comments.is_empty() {
20511 for comment in &col.trailing_comments {
20512 self.write_space();
20513 self.write_formatted_comment(comment);
20514 }
20515 }
20516 }
20517 Expression::Add(inner_op)
20518 | Expression::Sub(inner_op)
20519 | Expression::Mul(inner_op)
20520 | Expression::Div(inner_op)
20521 | Expression::Concat(inner_op) => {
20522 self.generate_binary_op_no_trailing(inner_op, match &op.left {
20524 Expression::Add(_) => "+",
20525 Expression::Sub(_) => "-",
20526 Expression::Mul(_) => "*",
20527 Expression::Div(_) => "/",
20528 Expression::Concat(_) => "||",
20529 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
20530 })?;
20531 }
20532 _ => {
20533 self.generate_expression(&op.left)?;
20534 }
20535 }
20536 for comment in &op.left_comments {
20538 self.write_space();
20539 self.write_formatted_comment(comment);
20540 }
20541 if self.config.pretty
20542 && matches!(self.config.dialect, Some(DialectType::Snowflake))
20543 && (operator == "AND" || operator == "OR")
20544 {
20545 self.write_newline();
20546 self.write_indent();
20547 self.write_keyword(operator);
20548 } else {
20549 self.write_space();
20550 if operator.chars().all(|c| c.is_alphabetic()) {
20551 self.write_keyword(operator);
20552 } else {
20553 self.write(operator);
20554 }
20555 }
20556 for comment in &op.operator_comments {
20558 self.write_space();
20559 self.write_formatted_comment(comment);
20560 }
20561 self.write_space();
20562 self.generate_expression(&op.right)?;
20563 for comment in &op.trailing_comments {
20565 self.write_space();
20566 self.write_formatted_comment(comment);
20567 }
20568 Ok(())
20569 }
20570
20571 fn generate_connector_op(&mut self, op: &BinaryOp, connector: ConnectorOperator) -> Result<()> {
20572 let keyword = connector.keyword();
20573 let Some(terms) = self.flatten_connector_terms(op, connector) else {
20574 return self.generate_binary_op(op, keyword);
20575 };
20576
20577 self.generate_expression(terms[0])?;
20578 for term in terms.iter().skip(1) {
20579 if self.config.pretty && matches!(self.config.dialect, Some(DialectType::Snowflake)) {
20580 self.write_newline();
20581 self.write_indent();
20582 self.write_keyword(keyword);
20583 } else {
20584 self.write_space();
20585 self.write_keyword(keyword);
20586 }
20587 self.write_space();
20588 self.generate_expression(term)?;
20589 }
20590
20591 Ok(())
20592 }
20593
20594 fn flatten_connector_terms<'a>(
20595 &self,
20596 root: &'a BinaryOp,
20597 connector: ConnectorOperator,
20598 ) -> Option<Vec<&'a Expression>> {
20599 if !root.left_comments.is_empty()
20600 || !root.operator_comments.is_empty()
20601 || !root.trailing_comments.is_empty()
20602 {
20603 return None;
20604 }
20605
20606 let mut terms = Vec::new();
20607 let mut stack: Vec<&Expression> = vec![&root.right, &root.left];
20608
20609 while let Some(expr) = stack.pop() {
20610 match (connector, expr) {
20611 (ConnectorOperator::And, Expression::And(inner))
20612 if inner.left_comments.is_empty()
20613 && inner.operator_comments.is_empty()
20614 && inner.trailing_comments.is_empty() =>
20615 {
20616 stack.push(&inner.right);
20617 stack.push(&inner.left);
20618 }
20619 (ConnectorOperator::Or, Expression::Or(inner))
20620 if inner.left_comments.is_empty()
20621 && inner.operator_comments.is_empty()
20622 && inner.trailing_comments.is_empty() =>
20623 {
20624 stack.push(&inner.right);
20625 stack.push(&inner.left);
20626 }
20627 _ => terms.push(expr),
20628 }
20629 }
20630
20631 if terms.len() > 1 {
20632 Some(terms)
20633 } else {
20634 None
20635 }
20636 }
20637
20638 fn generate_like_op(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
20640 self.generate_expression(&op.left)?;
20641 self.write_space();
20642 if operator == "ILIKE" && matches!(self.config.dialect, Some(DialectType::Drill)) {
20644 self.write("`ILIKE`");
20645 } else {
20646 self.write_keyword(operator);
20647 }
20648 if let Some(quantifier) = &op.quantifier {
20649 self.write_space();
20650 self.write_keyword(quantifier);
20651 }
20652 self.write_space();
20653 self.generate_expression(&op.right)?;
20654 if let Some(escape) = &op.escape {
20655 self.write_space();
20656 self.write_keyword("ESCAPE");
20657 self.write_space();
20658 self.generate_expression(escape)?;
20659 }
20660 Ok(())
20661 }
20662
20663 fn generate_null_safe_eq(&mut self, op: &BinaryOp) -> Result<()> {
20666 use crate::dialects::DialectType;
20667 self.generate_expression(&op.left)?;
20668 self.write_space();
20669 if matches!(self.config.dialect, Some(DialectType::MySQL)) {
20670 self.write("<=>");
20671 } else {
20672 self.write_keyword("IS NOT DISTINCT FROM");
20673 }
20674 self.write_space();
20675 self.generate_expression(&op.right)?;
20676 Ok(())
20677 }
20678
20679 fn generate_null_safe_neq(&mut self, op: &BinaryOp) -> Result<()> {
20681 self.generate_expression(&op.left)?;
20682 self.write_space();
20683 self.write_keyword("IS DISTINCT FROM");
20684 self.write_space();
20685 self.generate_expression(&op.right)?;
20686 Ok(())
20687 }
20688
20689 fn generate_binary_op_no_trailing(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
20691 match &op.left {
20693 Expression::Column(col) => {
20694 if let Some(table) = &col.table {
20695 self.generate_identifier(table)?;
20696 self.write(".");
20697 }
20698 self.generate_identifier(&col.name)?;
20699 if col.join_mark && self.config.supports_column_join_marks {
20701 self.write(" (+)");
20702 }
20703 }
20704 Expression::Add(inner_op)
20705 | Expression::Sub(inner_op)
20706 | Expression::Mul(inner_op)
20707 | Expression::Div(inner_op)
20708 | Expression::Concat(inner_op) => {
20709 self.generate_binary_op_no_trailing(inner_op, match &op.left {
20710 Expression::Add(_) => "+",
20711 Expression::Sub(_) => "-",
20712 Expression::Mul(_) => "*",
20713 Expression::Div(_) => "/",
20714 Expression::Concat(_) => "||",
20715 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
20716 })?;
20717 }
20718 _ => {
20719 self.generate_expression(&op.left)?;
20720 }
20721 }
20722 for comment in &op.left_comments {
20724 self.write_space();
20725 self.write_formatted_comment(comment);
20726 }
20727 self.write_space();
20728 if operator.chars().all(|c| c.is_alphabetic()) {
20729 self.write_keyword(operator);
20730 } else {
20731 self.write(operator);
20732 }
20733 for comment in &op.operator_comments {
20735 self.write_space();
20736 self.write_formatted_comment(comment);
20737 }
20738 self.write_space();
20739 match &op.right {
20742 Expression::Column(col) => {
20743 if let Some(table) = &col.table {
20744 self.generate_identifier(table)?;
20745 self.write(".");
20746 }
20747 self.generate_identifier(&col.name)?;
20748 if col.join_mark && self.config.supports_column_join_marks {
20750 self.write(" (+)");
20751 }
20752 }
20753 _ => {
20754 self.generate_expression(&op.right)?;
20755 }
20756 }
20757 Ok(())
20759 }
20760
20761 fn generate_unary_op(&mut self, op: &UnaryOp, operator: &str) -> Result<()> {
20762 if operator.chars().all(|c| c.is_alphabetic()) {
20763 self.write_keyword(operator);
20764 self.write_space();
20765 } else {
20766 self.write(operator);
20767 if matches!(&op.this, Expression::Neg(_) | Expression::BitwiseNot(_)) {
20769 self.write_space();
20770 }
20771 }
20772 self.generate_expression(&op.this)
20773 }
20774
20775 fn generate_in(&mut self, in_expr: &In) -> Result<()> {
20776 let is_generic =
20780 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
20781 let use_prefix_not =
20782 in_expr.not && is_generic && self.config.not_in_style == NotInStyle::Prefix;
20783 if use_prefix_not {
20784 self.write_keyword("NOT");
20785 self.write_space();
20786 }
20787 self.generate_expression(&in_expr.this)?;
20788 if in_expr.global {
20789 self.write_space();
20790 self.write_keyword("GLOBAL");
20791 }
20792 if in_expr.not && !use_prefix_not {
20793 self.write_space();
20794 self.write_keyword("NOT");
20795 }
20796 self.write_space();
20797 self.write_keyword("IN");
20798
20799 if let Some(unnest_expr) = &in_expr.unnest {
20801 self.write_space();
20802 self.write_keyword("UNNEST");
20803 self.write("(");
20804 self.generate_expression(unnest_expr)?;
20805 self.write(")");
20806 return Ok(());
20807 }
20808
20809 if let Some(query) = &in_expr.query {
20810 let is_bare = in_expr.expressions.is_empty()
20813 && !matches!(
20814 query,
20815 Expression::Select(_)
20816 | Expression::Union(_)
20817 | Expression::Intersect(_)
20818 | Expression::Except(_)
20819 | Expression::Subquery(_)
20820 );
20821 if is_bare {
20822 self.write_space();
20824 self.generate_expression(query)?;
20825 } else {
20826 self.write(" (");
20828 let is_statement = matches!(
20829 query,
20830 Expression::Select(_)
20831 | Expression::Union(_)
20832 | Expression::Intersect(_)
20833 | Expression::Except(_)
20834 | Expression::Subquery(_)
20835 );
20836 if self.config.pretty && is_statement {
20837 self.write_newline();
20838 self.indent_level += 1;
20839 self.write_indent();
20840 }
20841 self.generate_expression(query)?;
20842 if self.config.pretty && is_statement {
20843 self.write_newline();
20844 self.indent_level -= 1;
20845 self.write_indent();
20846 }
20847 self.write(")");
20848 }
20849 } else {
20850 let is_duckdb = matches!(
20854 self.config.dialect,
20855 Some(crate::dialects::DialectType::DuckDB)
20856 );
20857 let is_clickhouse = matches!(
20858 self.config.dialect,
20859 Some(crate::dialects::DialectType::ClickHouse)
20860 );
20861 let single_expr = in_expr.expressions.len() == 1;
20862 if is_clickhouse && single_expr {
20863 if let Expression::Array(arr) = &in_expr.expressions[0] {
20864 self.write(" (");
20866 for (i, expr) in arr.expressions.iter().enumerate() {
20867 if i > 0 {
20868 self.write(", ");
20869 }
20870 self.generate_expression(expr)?;
20871 }
20872 self.write(")");
20873 } else {
20874 self.write_space();
20875 self.generate_expression(&in_expr.expressions[0])?;
20876 }
20877 } else {
20878 let is_bare_ref = single_expr
20879 && matches!(
20880 &in_expr.expressions[0],
20881 Expression::Column(_) | Expression::Identifier(_) | Expression::Dot(_)
20882 );
20883 if (is_duckdb && is_bare_ref) || (in_expr.is_field && single_expr) {
20884 self.write_space();
20887 self.generate_expression(&in_expr.expressions[0])?;
20888 } else {
20889 self.write(" (");
20891 for (i, expr) in in_expr.expressions.iter().enumerate() {
20892 if i > 0 {
20893 self.write(", ");
20894 }
20895 self.generate_expression(expr)?;
20896 }
20897 self.write(")");
20898 }
20899 }
20900 }
20901
20902 Ok(())
20903 }
20904
20905 fn generate_between(&mut self, between: &Between) -> Result<()> {
20906 let use_prefix_not = between.not
20908 && (self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic));
20909 if use_prefix_not {
20910 self.write_keyword("NOT");
20911 self.write_space();
20912 }
20913 self.generate_expression(&between.this)?;
20914 if between.not && !use_prefix_not {
20915 self.write_space();
20916 self.write_keyword("NOT");
20917 }
20918 self.write_space();
20919 self.write_keyword("BETWEEN");
20920 if let Some(sym) = between.symmetric {
20922 if sym {
20923 self.write(" SYMMETRIC");
20924 } else {
20925 self.write(" ASYMMETRIC");
20926 }
20927 }
20928 self.write_space();
20929 self.generate_expression(&between.low)?;
20930 self.write_space();
20931 self.write_keyword("AND");
20932 self.write_space();
20933 self.generate_expression(&between.high)
20934 }
20935
20936 fn generate_is_null(&mut self, is_null: &IsNull) -> Result<()> {
20937 let use_prefix_not = is_null.not
20939 && (self.config.dialect.is_none()
20940 || self.config.dialect == Some(DialectType::Generic)
20941 || is_null.postfix_form);
20942 if use_prefix_not {
20943 self.write_keyword("NOT");
20945 self.write_space();
20946 self.generate_expression(&is_null.this)?;
20947 self.write_space();
20948 self.write_keyword("IS");
20949 self.write_space();
20950 self.write_keyword("NULL");
20951 } else {
20952 self.generate_expression(&is_null.this)?;
20953 self.write_space();
20954 self.write_keyword("IS");
20955 if is_null.not {
20956 self.write_space();
20957 self.write_keyword("NOT");
20958 }
20959 self.write_space();
20960 self.write_keyword("NULL");
20961 }
20962 Ok(())
20963 }
20964
20965 fn generate_is_true(&mut self, is_true: &IsTrueFalse) -> Result<()> {
20966 self.generate_expression(&is_true.this)?;
20967 self.write_space();
20968 self.write_keyword("IS");
20969 if is_true.not {
20970 self.write_space();
20971 self.write_keyword("NOT");
20972 }
20973 self.write_space();
20974 self.write_keyword("TRUE");
20975 Ok(())
20976 }
20977
20978 fn generate_is_false(&mut self, is_false: &IsTrueFalse) -> Result<()> {
20979 self.generate_expression(&is_false.this)?;
20980 self.write_space();
20981 self.write_keyword("IS");
20982 if is_false.not {
20983 self.write_space();
20984 self.write_keyword("NOT");
20985 }
20986 self.write_space();
20987 self.write_keyword("FALSE");
20988 Ok(())
20989 }
20990
20991 fn generate_is_json(&mut self, is_json: &IsJson) -> Result<()> {
20992 self.generate_expression(&is_json.this)?;
20993 self.write_space();
20994 self.write_keyword("IS");
20995 if is_json.negated {
20996 self.write_space();
20997 self.write_keyword("NOT");
20998 }
20999 self.write_space();
21000 self.write_keyword("JSON");
21001
21002 if let Some(ref json_type) = is_json.json_type {
21004 self.write_space();
21005 self.write_keyword(json_type);
21006 }
21007
21008 match &is_json.unique_keys {
21010 Some(JsonUniqueKeys::With) => {
21011 self.write_space();
21012 self.write_keyword("WITH UNIQUE KEYS");
21013 }
21014 Some(JsonUniqueKeys::Without) => {
21015 self.write_space();
21016 self.write_keyword("WITHOUT UNIQUE KEYS");
21017 }
21018 Some(JsonUniqueKeys::Shorthand) => {
21019 self.write_space();
21020 self.write_keyword("UNIQUE KEYS");
21021 }
21022 None => {}
21023 }
21024
21025 Ok(())
21026 }
21027
21028 fn generate_is(&mut self, is_expr: &BinaryOp) -> Result<()> {
21029 self.generate_expression(&is_expr.left)?;
21030 self.write_space();
21031 self.write_keyword("IS");
21032 self.write_space();
21033 self.generate_expression(&is_expr.right)
21034 }
21035
21036 fn generate_exists(&mut self, exists: &Exists) -> Result<()> {
21037 if exists.not {
21038 self.write_keyword("NOT");
21039 self.write_space();
21040 }
21041 self.write_keyword("EXISTS");
21042 self.write("(");
21043 let is_statement = matches!(
21044 &exists.this,
21045 Expression::Select(_)
21046 | Expression::Union(_)
21047 | Expression::Intersect(_)
21048 | Expression::Except(_)
21049 );
21050 if self.config.pretty && is_statement {
21051 self.write_newline();
21052 self.indent_level += 1;
21053 self.write_indent();
21054 self.generate_expression(&exists.this)?;
21055 self.write_newline();
21056 self.indent_level -= 1;
21057 self.write_indent();
21058 self.write(")");
21059 } else {
21060 self.generate_expression(&exists.this)?;
21061 self.write(")");
21062 }
21063 Ok(())
21064 }
21065
21066 fn generate_member_of(&mut self, op: &BinaryOp) -> Result<()> {
21067 self.generate_expression(&op.left)?;
21068 self.write_space();
21069 self.write_keyword("MEMBER OF");
21070 self.write("(");
21071 self.generate_expression(&op.right)?;
21072 self.write(")");
21073 Ok(())
21074 }
21075
21076 fn generate_subquery(&mut self, subquery: &Subquery) -> Result<()> {
21077 if subquery.lateral {
21078 self.write_keyword("LATERAL");
21079 self.write_space();
21080 }
21081
21082 let skip_outer_parens = if let Expression::Paren(ref p) = &subquery.this {
21086 matches!(
21087 &p.this,
21088 Expression::Select(_)
21089 | Expression::Union(_)
21090 | Expression::Intersect(_)
21091 | Expression::Except(_)
21092 | Expression::Subquery(_)
21093 )
21094 } else {
21095 false
21096 };
21097
21098 let is_statement = matches!(
21100 &subquery.this,
21101 Expression::Select(_)
21102 | Expression::Union(_)
21103 | Expression::Intersect(_)
21104 | Expression::Except(_)
21105 | Expression::Merge(_)
21106 );
21107
21108 if !skip_outer_parens {
21109 self.write("(");
21110 if self.config.pretty && is_statement {
21111 self.write_newline();
21112 self.indent_level += 1;
21113 self.write_indent();
21114 }
21115 }
21116 self.generate_expression(&subquery.this)?;
21117
21118 if subquery.modifiers_inside {
21120 if let Some(order_by) = &subquery.order_by {
21122 self.write_space();
21123 self.write_keyword("ORDER BY");
21124 self.write_space();
21125 for (i, ord) in order_by.expressions.iter().enumerate() {
21126 if i > 0 {
21127 self.write(", ");
21128 }
21129 self.generate_ordered(ord)?;
21130 }
21131 }
21132
21133 if let Some(limit) = &subquery.limit {
21134 self.write_space();
21135 self.write_keyword("LIMIT");
21136 self.write_space();
21137 self.generate_expression(&limit.this)?;
21138 if limit.percent {
21139 self.write_space();
21140 self.write_keyword("PERCENT");
21141 }
21142 }
21143
21144 if let Some(offset) = &subquery.offset {
21145 self.write_space();
21146 self.write_keyword("OFFSET");
21147 self.write_space();
21148 self.generate_expression(&offset.this)?;
21149 }
21150 }
21151
21152 if !skip_outer_parens {
21153 if self.config.pretty && is_statement {
21154 self.write_newline();
21155 self.indent_level -= 1;
21156 self.write_indent();
21157 }
21158 self.write(")");
21159 }
21160
21161 if !subquery.modifiers_inside {
21163 if let Some(order_by) = &subquery.order_by {
21164 self.write_space();
21165 self.write_keyword("ORDER BY");
21166 self.write_space();
21167 for (i, ord) in order_by.expressions.iter().enumerate() {
21168 if i > 0 {
21169 self.write(", ");
21170 }
21171 self.generate_ordered(ord)?;
21172 }
21173 }
21174
21175 if let Some(limit) = &subquery.limit {
21176 self.write_space();
21177 self.write_keyword("LIMIT");
21178 self.write_space();
21179 self.generate_expression(&limit.this)?;
21180 if limit.percent {
21181 self.write_space();
21182 self.write_keyword("PERCENT");
21183 }
21184 }
21185
21186 if let Some(offset) = &subquery.offset {
21187 self.write_space();
21188 self.write_keyword("OFFSET");
21189 self.write_space();
21190 self.generate_expression(&offset.this)?;
21191 }
21192
21193 if let Some(distribute_by) = &subquery.distribute_by {
21195 self.write_space();
21196 self.write_keyword("DISTRIBUTE BY");
21197 self.write_space();
21198 for (i, expr) in distribute_by.expressions.iter().enumerate() {
21199 if i > 0 {
21200 self.write(", ");
21201 }
21202 self.generate_expression(expr)?;
21203 }
21204 }
21205
21206 if let Some(sort_by) = &subquery.sort_by {
21208 self.write_space();
21209 self.write_keyword("SORT BY");
21210 self.write_space();
21211 for (i, ord) in sort_by.expressions.iter().enumerate() {
21212 if i > 0 {
21213 self.write(", ");
21214 }
21215 self.generate_ordered(ord)?;
21216 }
21217 }
21218
21219 if let Some(cluster_by) = &subquery.cluster_by {
21221 self.write_space();
21222 self.write_keyword("CLUSTER BY");
21223 self.write_space();
21224 for (i, ord) in cluster_by.expressions.iter().enumerate() {
21225 if i > 0 {
21226 self.write(", ");
21227 }
21228 self.generate_ordered(ord)?;
21229 }
21230 }
21231 }
21232
21233 if let Some(alias) = &subquery.alias {
21234 self.write_space();
21235 let skip_as = matches!(
21237 self.config.dialect,
21238 Some(crate::dialects::DialectType::Oracle)
21239 );
21240 if !skip_as {
21241 self.write_keyword("AS");
21242 self.write_space();
21243 }
21244 self.generate_identifier(alias)?;
21245 if !subquery.column_aliases.is_empty() {
21246 self.write("(");
21247 for (i, col) in subquery.column_aliases.iter().enumerate() {
21248 if i > 0 {
21249 self.write(", ");
21250 }
21251 self.generate_identifier(col)?;
21252 }
21253 self.write(")");
21254 }
21255 }
21256 for comment in &subquery.trailing_comments {
21258 self.write(" ");
21259 self.write_formatted_comment(comment);
21260 }
21261 Ok(())
21262 }
21263
21264 fn generate_pivot(&mut self, pivot: &Pivot) -> Result<()> {
21265 if let Some(ref with) = pivot.with {
21267 self.generate_with(with)?;
21268 self.write_space();
21269 }
21270
21271 let direction = if pivot.unpivot { "UNPIVOT" } else { "PIVOT" };
21272
21273 let is_redshift_unpivot = pivot.unpivot
21277 && pivot.expressions.is_empty()
21278 && pivot.fields.is_empty()
21279 && pivot.using.is_empty()
21280 && pivot.into.is_none()
21281 && !matches!(&pivot.this, Expression::Null(_));
21282
21283 if is_redshift_unpivot {
21284 self.write_keyword("UNPIVOT");
21286 self.write_space();
21287 self.generate_expression(&pivot.this)?;
21288 if let Some(alias) = &pivot.alias {
21290 self.write_space();
21291 self.write_keyword("AS");
21292 self.write_space();
21293 self.write(&alias.name);
21295 }
21296 return Ok(());
21297 }
21298
21299 let is_simplified = !pivot.using.is_empty()
21301 || pivot.into.is_some()
21302 || (pivot.fields.is_empty()
21303 && !pivot.expressions.is_empty()
21304 && !matches!(&pivot.this, Expression::Null(_)));
21305
21306 if is_simplified {
21307 self.write_keyword(direction);
21311 self.write_space();
21312 self.generate_expression(&pivot.this)?;
21313
21314 if !pivot.expressions.is_empty() {
21315 self.write_space();
21316 self.write_keyword("ON");
21317 self.write_space();
21318 for (i, expr) in pivot.expressions.iter().enumerate() {
21319 if i > 0 {
21320 self.write(", ");
21321 }
21322 self.generate_expression(expr)?;
21323 }
21324 }
21325
21326 if let Some(into) = &pivot.into {
21328 self.write_space();
21329 self.write_keyword("INTO");
21330 self.write_space();
21331 self.generate_expression(into)?;
21332 }
21333
21334 if !pivot.using.is_empty() {
21336 self.write_space();
21337 self.write_keyword("USING");
21338 self.write_space();
21339 for (i, expr) in pivot.using.iter().enumerate() {
21340 if i > 0 {
21341 self.write(", ");
21342 }
21343 self.generate_expression(expr)?;
21344 }
21345 }
21346
21347 if let Some(group) = &pivot.group {
21349 self.write_space();
21350 self.generate_expression(group)?;
21351 }
21352 } else {
21353 if !matches!(&pivot.this, Expression::Null(_)) {
21358 self.generate_expression(&pivot.this)?;
21359 self.write_space();
21360 }
21361 self.write_keyword(direction);
21362 self.write("(");
21363
21364 for (i, expr) in pivot.expressions.iter().enumerate() {
21366 if i > 0 {
21367 self.write(", ");
21368 }
21369 self.generate_expression(expr)?;
21370 }
21371
21372 if !pivot.fields.is_empty() {
21374 if !pivot.expressions.is_empty() {
21375 self.write_space();
21376 }
21377 self.write_keyword("FOR");
21378 self.write_space();
21379 for (i, field) in pivot.fields.iter().enumerate() {
21380 if i > 0 {
21381 self.write_space();
21382 }
21383 self.generate_expression(field)?;
21385 }
21386 }
21387
21388 if let Some(default_val) = &pivot.default_on_null {
21390 self.write_space();
21391 self.write_keyword("DEFAULT ON NULL");
21392 self.write(" (");
21393 self.generate_expression(default_val)?;
21394 self.write(")");
21395 }
21396
21397 if let Some(group) = &pivot.group {
21399 self.write_space();
21400 self.generate_expression(group)?;
21401 }
21402
21403 self.write(")");
21404 }
21405
21406 if let Some(alias) = &pivot.alias {
21408 self.write_space();
21409 self.write_keyword("AS");
21410 self.write_space();
21411 self.generate_identifier(alias)?;
21412 }
21413
21414 Ok(())
21415 }
21416
21417 fn generate_unpivot(&mut self, unpivot: &Unpivot) -> Result<()> {
21418 self.generate_expression(&unpivot.this)?;
21419 self.write_space();
21420 self.write_keyword("UNPIVOT");
21421 if let Some(include) = unpivot.include_nulls {
21423 self.write_space();
21424 if include {
21425 self.write_keyword("INCLUDE NULLS");
21426 } else {
21427 self.write_keyword("EXCLUDE NULLS");
21428 }
21429 self.write_space();
21430 }
21431 self.write("(");
21432 if unpivot.value_column_parenthesized {
21433 self.write("(");
21434 }
21435 self.generate_identifier(&unpivot.value_column)?;
21436 for extra_col in &unpivot.extra_value_columns {
21438 self.write(", ");
21439 self.generate_identifier(extra_col)?;
21440 }
21441 if unpivot.value_column_parenthesized {
21442 self.write(")");
21443 }
21444 self.write_space();
21445 self.write_keyword("FOR");
21446 self.write_space();
21447 self.generate_identifier(&unpivot.name_column)?;
21448 self.write_space();
21449 self.write_keyword("IN");
21450 self.write(" (");
21451 for (i, col) in unpivot.columns.iter().enumerate() {
21452 if i > 0 {
21453 self.write(", ");
21454 }
21455 self.generate_expression(col)?;
21456 }
21457 self.write("))");
21458 if let Some(alias) = &unpivot.alias {
21459 self.write_space();
21460 self.write_keyword("AS");
21461 self.write_space();
21462 self.generate_identifier(alias)?;
21463 }
21464 Ok(())
21465 }
21466
21467 fn generate_values(&mut self, values: &Values) -> Result<()> {
21468 self.write_keyword("VALUES");
21469 for (i, row) in values.expressions.iter().enumerate() {
21470 if i > 0 {
21471 self.write(",");
21472 }
21473 self.write(" (");
21474 for (j, expr) in row.expressions.iter().enumerate() {
21475 if j > 0 {
21476 self.write(", ");
21477 }
21478 self.generate_expression(expr)?;
21479 }
21480 self.write(")");
21481 }
21482 if let Some(alias) = &values.alias {
21483 self.write_space();
21484 self.write_keyword("AS");
21485 self.write_space();
21486 self.generate_identifier(alias)?;
21487 if !values.column_aliases.is_empty() {
21488 self.write("(");
21489 for (i, col) in values.column_aliases.iter().enumerate() {
21490 if i > 0 {
21491 self.write(", ");
21492 }
21493 self.generate_identifier(col)?;
21494 }
21495 self.write(")");
21496 }
21497 }
21498 Ok(())
21499 }
21500
21501 fn generate_array(&mut self, arr: &Array) -> Result<()> {
21502 let needs_inheritance = matches!(
21504 self.config.dialect,
21505 Some(DialectType::DuckDB)
21506 | Some(DialectType::Spark)
21507 | Some(DialectType::Databricks)
21508 | Some(DialectType::Hive)
21509 | Some(DialectType::Snowflake)
21510 | Some(DialectType::Presto)
21511 | Some(DialectType::Trino)
21512 );
21513 let propagated: Vec<Expression>;
21514 let expressions = if needs_inheritance && arr.expressions.len() > 1 {
21515 propagated = Self::inherit_struct_field_names(&arr.expressions);
21516 &propagated
21517 } else {
21518 &arr.expressions
21519 };
21520
21521 let use_parens =
21524 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
21525 if !self.config.array_bracket_only {
21526 self.write_keyword("ARRAY");
21527 }
21528 if use_parens {
21529 self.write("(");
21530 } else {
21531 self.write("[");
21532 }
21533 for (i, expr) in expressions.iter().enumerate() {
21534 if i > 0 {
21535 self.write(", ");
21536 }
21537 self.generate_expression(expr)?;
21538 }
21539 if use_parens {
21540 self.write(")");
21541 } else {
21542 self.write("]");
21543 }
21544 Ok(())
21545 }
21546
21547 fn generate_tuple(&mut self, tuple: &Tuple) -> Result<()> {
21548 if tuple.expressions.len() == 2 {
21551 if let Expression::TableAlias(_) = &tuple.expressions[1] {
21552 self.generate_expression(&tuple.expressions[0])?;
21554 self.write_space();
21555 self.write_keyword("AS");
21556 self.write_space();
21557 self.generate_expression(&tuple.expressions[1])?;
21558 return Ok(());
21559 }
21560 }
21561
21562 let expand_tuple = if self.config.pretty && tuple.expressions.len() > 1 {
21565 let mut expr_strings: Vec<String> = Vec::with_capacity(tuple.expressions.len());
21566 for expr in &tuple.expressions {
21567 expr_strings.push(self.generate_to_string(expr)?);
21568 }
21569 self.too_wide(&expr_strings)
21570 } else {
21571 false
21572 };
21573
21574 if expand_tuple {
21575 self.write("(");
21576 self.write_newline();
21577 self.indent_level += 1;
21578 for (i, expr) in tuple.expressions.iter().enumerate() {
21579 if i > 0 {
21580 self.write(",");
21581 self.write_newline();
21582 }
21583 self.write_indent();
21584 self.generate_expression(expr)?;
21585 }
21586 self.indent_level -= 1;
21587 self.write_newline();
21588 self.write_indent();
21589 self.write(")");
21590 } else {
21591 self.write("(");
21592 for (i, expr) in tuple.expressions.iter().enumerate() {
21593 if i > 0 {
21594 self.write(", ");
21595 }
21596 self.generate_expression(expr)?;
21597 }
21598 self.write(")");
21599 }
21600 Ok(())
21601 }
21602
21603 fn generate_pipe_operator(&mut self, pipe: &PipeOperator) -> Result<()> {
21604 self.generate_expression(&pipe.this)?;
21605 self.write(" |> ");
21606 self.generate_expression(&pipe.expression)?;
21607 Ok(())
21608 }
21609
21610 fn generate_ordered(&mut self, ordered: &Ordered) -> Result<()> {
21611 self.generate_expression(&ordered.this)?;
21612 if ordered.desc {
21613 self.write_space();
21614 self.write_keyword("DESC");
21615 } else if ordered.explicit_asc {
21616 self.write_space();
21617 self.write_keyword("ASC");
21618 }
21619 if let Some(nulls_first) = ordered.nulls_first {
21620 let is_asc = !ordered.desc;
21634 let is_nulls_are_large = matches!(
21635 self.config.dialect,
21636 Some(DialectType::Oracle)
21637 | Some(DialectType::PostgreSQL)
21638 | Some(DialectType::Redshift)
21639 | Some(DialectType::Snowflake)
21640 );
21641 let is_nulls_are_last = matches!(
21642 self.config.dialect,
21643 Some(DialectType::Dremio)
21644 | Some(DialectType::DuckDB)
21645 | Some(DialectType::Presto)
21646 | Some(DialectType::Trino)
21647 | Some(DialectType::Athena)
21648 | Some(DialectType::ClickHouse)
21649 | Some(DialectType::Drill)
21650 | Some(DialectType::Exasol)
21651 );
21652
21653 let is_default_nulls = if is_nulls_are_large {
21655 (is_asc && !nulls_first) || (!is_asc && nulls_first)
21657 } else if is_nulls_are_last {
21658 !nulls_first
21660 } else {
21661 false
21662 };
21663
21664 if !is_default_nulls {
21665 self.write_space();
21666 self.write_keyword("NULLS");
21667 self.write_space();
21668 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
21669 }
21670 }
21671 if let Some(ref with_fill) = ordered.with_fill {
21673 self.write_space();
21674 self.generate_with_fill(with_fill)?;
21675 }
21676 Ok(())
21677 }
21678
21679 fn write_clickhouse_type(&mut self, type_str: &str) {
21681 if self.clickhouse_nullable_depth < 0 {
21682 self.write(type_str);
21684 } else {
21685 self.write(&format!("Nullable({})", type_str));
21686 }
21687 }
21688
21689 fn generate_data_type(&mut self, dt: &DataType) -> Result<()> {
21690 use crate::dialects::DialectType;
21691
21692 match dt {
21693 DataType::Boolean => {
21694 match self.config.dialect {
21696 Some(DialectType::TSQL) => self.write_keyword("BIT"),
21697 Some(DialectType::MySQL) => self.write_keyword("BOOLEAN"), Some(DialectType::Oracle) => {
21699 self.write_keyword("NUMBER(1)")
21701 }
21702 Some(DialectType::ClickHouse) => self.write("Bool"), _ => self.write_keyword("BOOLEAN"),
21704 }
21705 }
21706 DataType::TinyInt { length } => {
21707 match self.config.dialect {
21711 Some(DialectType::PostgreSQL)
21712 | Some(DialectType::Redshift)
21713 | Some(DialectType::Oracle)
21714 | Some(DialectType::Exasol) => {
21715 self.write_keyword("SMALLINT");
21716 }
21717 Some(DialectType::Teradata) => {
21718 self.write_keyword("BYTEINT");
21720 }
21721 Some(DialectType::Dremio) => {
21722 self.write_keyword("INT");
21724 }
21725 Some(DialectType::ClickHouse) => {
21726 self.write_clickhouse_type("Int8");
21727 }
21728 _ => {
21729 self.write_keyword("TINYINT");
21730 }
21731 }
21732 if let Some(n) = length {
21733 if !matches!(
21734 self.config.dialect,
21735 Some(DialectType::Dremio) | Some(DialectType::ClickHouse)
21736 ) {
21737 self.write(&format!("({})", n));
21738 }
21739 }
21740 }
21741 DataType::SmallInt { length } => {
21742 match self.config.dialect {
21744 Some(DialectType::Dremio) => {
21745 self.write_keyword("INT");
21746 }
21747 Some(DialectType::SQLite) | Some(DialectType::Drill) => {
21748 self.write_keyword("INTEGER");
21749 }
21750 Some(DialectType::BigQuery) => {
21751 self.write_keyword("INT64");
21752 }
21753 Some(DialectType::ClickHouse) => {
21754 self.write_clickhouse_type("Int16");
21755 }
21756 _ => {
21757 self.write_keyword("SMALLINT");
21758 if let Some(n) = length {
21759 self.write(&format!("({})", n));
21760 }
21761 }
21762 }
21763 }
21764 DataType::Int {
21765 length,
21766 integer_spelling,
21767 } => {
21768 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
21770 self.write_keyword("INT64");
21771 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
21772 self.write_clickhouse_type("Int32");
21773 } else {
21774 let use_integer = match self.config.dialect {
21776 Some(DialectType::TSQL)
21777 | Some(DialectType::Fabric)
21778 | Some(DialectType::Presto)
21779 | Some(DialectType::Trino)
21780 | Some(DialectType::SQLite)
21781 | Some(DialectType::Redshift) => true,
21782 Some(DialectType::Databricks) => *integer_spelling,
21784 _ => false,
21785 };
21786 if use_integer {
21787 self.write_keyword("INTEGER");
21788 } else {
21789 self.write_keyword("INT");
21790 }
21791 if let Some(n) = length {
21792 self.write(&format!("({})", n));
21793 }
21794 }
21795 }
21796 DataType::BigInt { length } => {
21797 match self.config.dialect {
21799 Some(DialectType::Oracle) => {
21800 self.write_keyword("INT");
21802 }
21803 Some(DialectType::ClickHouse) => {
21804 self.write_clickhouse_type("Int64");
21805 }
21806 _ => {
21807 self.write_keyword("BIGINT");
21808 if let Some(n) = length {
21809 self.write(&format!("({})", n));
21810 }
21811 }
21812 }
21813 }
21814 DataType::Float {
21815 precision,
21816 scale,
21817 real_spelling,
21818 } => {
21819 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
21823 self.write_clickhouse_type("Float32");
21824 } else if *real_spelling
21825 && !matches!(
21826 self.config.dialect,
21827 Some(DialectType::Spark)
21828 | Some(DialectType::Databricks)
21829 | Some(DialectType::Hive)
21830 | Some(DialectType::Snowflake)
21831 | Some(DialectType::MySQL)
21832 | Some(DialectType::BigQuery)
21833 )
21834 {
21835 self.write_keyword("REAL")
21836 } else {
21837 match self.config.dialect {
21838 Some(DialectType::PostgreSQL) => self.write_keyword("REAL"),
21839 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
21840 _ => self.write_keyword("FLOAT"),
21841 }
21842 }
21843 if !matches!(
21846 self.config.dialect,
21847 Some(DialectType::Spark)
21848 | Some(DialectType::Databricks)
21849 | Some(DialectType::Hive)
21850 | Some(DialectType::Presto)
21851 | Some(DialectType::Trino)
21852 ) {
21853 if let Some(p) = precision {
21854 self.write(&format!("({}", p));
21855 if let Some(s) = scale {
21856 self.write(&format!(", {})", s));
21857 } else {
21858 self.write(")");
21859 }
21860 }
21861 }
21862 }
21863 DataType::Double { precision, scale } => {
21864 match self.config.dialect {
21866 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
21867 self.write_keyword("FLOAT")
21868 } Some(DialectType::Oracle) => self.write_keyword("DOUBLE PRECISION"),
21870 Some(DialectType::ClickHouse) => self.write_clickhouse_type("Float64"),
21871 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
21872 Some(DialectType::SQLite) => self.write_keyword("REAL"),
21873 Some(DialectType::PostgreSQL)
21874 | Some(DialectType::Redshift)
21875 | Some(DialectType::Teradata)
21876 | Some(DialectType::Materialize) => self.write_keyword("DOUBLE PRECISION"),
21877 _ => self.write_keyword("DOUBLE"),
21878 }
21879 if let Some(p) = precision {
21881 self.write(&format!("({}", p));
21882 if let Some(s) = scale {
21883 self.write(&format!(", {})", s));
21884 } else {
21885 self.write(")");
21886 }
21887 }
21888 }
21889 DataType::Decimal { precision, scale } => {
21890 match self.config.dialect {
21892 Some(DialectType::ClickHouse) => {
21893 self.write("Decimal");
21894 if let Some(p) = precision {
21895 self.write(&format!("({}", p));
21896 if let Some(s) = scale {
21897 self.write(&format!(", {}", s));
21898 }
21899 self.write(")");
21900 }
21901 }
21902 Some(DialectType::Oracle) => {
21903 self.write_keyword("NUMBER");
21905 if let Some(p) = precision {
21906 self.write(&format!("({}", p));
21907 if let Some(s) = scale {
21908 self.write(&format!(", {}", s));
21909 }
21910 self.write(")");
21911 }
21912 }
21913 Some(DialectType::BigQuery) => {
21914 self.write_keyword("NUMERIC");
21916 if let Some(p) = precision {
21917 self.write(&format!("({}", p));
21918 if let Some(s) = scale {
21919 self.write(&format!(", {}", s));
21920 }
21921 self.write(")");
21922 }
21923 }
21924 _ => {
21925 self.write_keyword("DECIMAL");
21926 if let Some(p) = precision {
21927 self.write(&format!("({}", p));
21928 if let Some(s) = scale {
21929 self.write(&format!(", {}", s));
21930 }
21931 self.write(")");
21932 }
21933 }
21934 }
21935 }
21936 DataType::Char { length } => {
21937 match self.config.dialect {
21939 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
21940 self.write_keyword("TEXT");
21942 }
21943 Some(DialectType::Hive)
21944 | Some(DialectType::Spark)
21945 | Some(DialectType::Databricks) => {
21946 if length.is_some()
21949 && !matches!(self.config.dialect, Some(DialectType::Hive))
21950 {
21951 self.write_keyword("CHAR");
21952 if let Some(n) = length {
21953 self.write(&format!("({})", n));
21954 }
21955 } else {
21956 self.write_keyword("STRING");
21957 }
21958 }
21959 Some(DialectType::Dremio) => {
21960 self.write_keyword("VARCHAR");
21962 if let Some(n) = length {
21963 self.write(&format!("({})", n));
21964 }
21965 }
21966 _ => {
21967 self.write_keyword("CHAR");
21968 if let Some(n) = length {
21969 self.write(&format!("({})", n));
21970 }
21971 }
21972 }
21973 }
21974 DataType::VarChar {
21975 length,
21976 parenthesized_length,
21977 } => {
21978 match self.config.dialect {
21980 Some(DialectType::Oracle) => {
21981 self.write_keyword("VARCHAR2");
21982 if let Some(n) = length {
21983 self.write(&format!("({})", n));
21984 }
21985 }
21986 Some(DialectType::DuckDB) => {
21987 self.write_keyword("TEXT");
21989 if let Some(n) = length {
21990 self.write(&format!("({})", n));
21991 }
21992 }
21993 Some(DialectType::SQLite) => {
21994 self.write_keyword("TEXT");
21996 if let Some(n) = length {
21997 self.write(&format!("({})", n));
21998 }
21999 }
22000 Some(DialectType::MySQL) if length.is_none() => {
22001 self.write_keyword("TEXT");
22003 }
22004 Some(DialectType::Hive)
22005 | Some(DialectType::Spark)
22006 | Some(DialectType::Databricks)
22007 if length.is_none() =>
22008 {
22009 self.write_keyword("STRING");
22011 }
22012 _ => {
22013 self.write_keyword("VARCHAR");
22014 if let Some(n) = length {
22015 if *parenthesized_length {
22017 self.write(&format!("(({}))", n));
22018 } else {
22019 self.write(&format!("({})", n));
22020 }
22021 }
22022 }
22023 }
22024 }
22025 DataType::Text => {
22026 match self.config.dialect {
22028 Some(DialectType::Oracle) => self.write_keyword("CLOB"),
22029 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
22030 self.write_keyword("VARCHAR(MAX)")
22031 }
22032 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
22033 Some(DialectType::Snowflake)
22034 | Some(DialectType::Dremio)
22035 | Some(DialectType::Drill) => self.write_keyword("VARCHAR"),
22036 Some(DialectType::Exasol) => self.write_keyword("LONG VARCHAR"),
22037 Some(DialectType::Presto)
22038 | Some(DialectType::Trino)
22039 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
22040 Some(DialectType::Spark)
22041 | Some(DialectType::Databricks)
22042 | Some(DialectType::Hive) => self.write_keyword("STRING"),
22043 Some(DialectType::Redshift) => self.write_keyword("VARCHAR(MAX)"),
22044 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
22045 self.write_keyword("STRING")
22046 }
22047 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
22048 _ => self.write_keyword("TEXT"),
22049 }
22050 }
22051 DataType::TextWithLength { length } => {
22052 match self.config.dialect {
22054 Some(DialectType::Oracle) => self.write(&format!("CLOB({})", length)),
22055 Some(DialectType::Hive)
22056 | Some(DialectType::Spark)
22057 | Some(DialectType::Databricks) => {
22058 self.write(&format!("VARCHAR({})", length));
22059 }
22060 Some(DialectType::Redshift) => self.write(&format!("VARCHAR({})", length)),
22061 Some(DialectType::BigQuery) => self.write(&format!("STRING({})", length)),
22062 Some(DialectType::Snowflake)
22063 | Some(DialectType::Presto)
22064 | Some(DialectType::Trino)
22065 | Some(DialectType::Athena)
22066 | Some(DialectType::Drill)
22067 | Some(DialectType::Dremio) => {
22068 self.write(&format!("VARCHAR({})", length));
22069 }
22070 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
22071 self.write(&format!("VARCHAR({})", length))
22072 }
22073 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
22074 self.write(&format!("STRING({})", length))
22075 }
22076 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
22077 _ => self.write(&format!("TEXT({})", length)),
22078 }
22079 }
22080 DataType::String { length } => {
22081 match self.config.dialect {
22083 Some(DialectType::ClickHouse) => {
22084 self.write("String");
22086 if let Some(n) = length {
22087 self.write(&format!("({})", n));
22088 }
22089 }
22090 Some(DialectType::BigQuery)
22091 | Some(DialectType::Hive)
22092 | Some(DialectType::Spark)
22093 | Some(DialectType::Databricks)
22094 | Some(DialectType::StarRocks)
22095 | Some(DialectType::Doris) => {
22096 self.write_keyword("STRING");
22097 if let Some(n) = length {
22098 self.write(&format!("({})", n));
22099 }
22100 }
22101 Some(DialectType::PostgreSQL) => {
22102 if let Some(n) = length {
22104 self.write_keyword("VARCHAR");
22105 self.write(&format!("({})", n));
22106 } else {
22107 self.write_keyword("TEXT");
22108 }
22109 }
22110 Some(DialectType::Redshift) => {
22111 if let Some(n) = length {
22113 self.write_keyword("VARCHAR");
22114 self.write(&format!("({})", n));
22115 } else {
22116 self.write_keyword("VARCHAR(MAX)");
22117 }
22118 }
22119 Some(DialectType::MySQL) => {
22120 if let Some(n) = length {
22122 self.write_keyword("VARCHAR");
22123 self.write(&format!("({})", n));
22124 } else {
22125 self.write_keyword("TEXT");
22126 }
22127 }
22128 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
22129 if let Some(n) = length {
22131 self.write_keyword("VARCHAR");
22132 self.write(&format!("({})", n));
22133 } else {
22134 self.write_keyword("VARCHAR(MAX)");
22135 }
22136 }
22137 Some(DialectType::Oracle) => {
22138 self.write_keyword("CLOB");
22140 }
22141 Some(DialectType::DuckDB) | Some(DialectType::Materialize) => {
22142 self.write_keyword("TEXT");
22144 if let Some(n) = length {
22145 self.write(&format!("({})", n));
22146 }
22147 }
22148 Some(DialectType::Presto)
22149 | Some(DialectType::Trino)
22150 | Some(DialectType::Drill)
22151 | Some(DialectType::Dremio) => {
22152 self.write_keyword("VARCHAR");
22154 if let Some(n) = length {
22155 self.write(&format!("({})", n));
22156 }
22157 }
22158 Some(DialectType::Snowflake) => {
22159 self.write_keyword("STRING");
22162 if let Some(n) = length {
22163 self.write(&format!("({})", n));
22164 }
22165 }
22166 _ => {
22167 self.write_keyword("STRING");
22169 if let Some(n) = length {
22170 self.write(&format!("({})", n));
22171 }
22172 }
22173 }
22174 }
22175 DataType::Binary { length } => {
22176 match self.config.dialect {
22178 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
22179 self.write_keyword("BYTEA");
22180 if let Some(n) = length {
22181 self.write(&format!("({})", n));
22182 }
22183 }
22184 Some(DialectType::Redshift) => {
22185 self.write_keyword("VARBYTE");
22186 if let Some(n) = length {
22187 self.write(&format!("({})", n));
22188 }
22189 }
22190 Some(DialectType::DuckDB)
22191 | Some(DialectType::SQLite)
22192 | Some(DialectType::Oracle) => {
22193 self.write_keyword("BLOB");
22195 if let Some(n) = length {
22196 self.write(&format!("({})", n));
22197 }
22198 }
22199 Some(DialectType::Presto)
22200 | Some(DialectType::Trino)
22201 | Some(DialectType::Athena)
22202 | Some(DialectType::Drill)
22203 | Some(DialectType::Dremio) => {
22204 self.write_keyword("VARBINARY");
22206 if let Some(n) = length {
22207 self.write(&format!("({})", n));
22208 }
22209 }
22210 Some(DialectType::ClickHouse) => {
22211 if self.clickhouse_nullable_depth < 0 {
22213 self.write("BINARY");
22214 } else {
22215 self.write("Nullable(BINARY");
22216 }
22217 if let Some(n) = length {
22218 self.write(&format!("({})", n));
22219 }
22220 if self.clickhouse_nullable_depth >= 0 {
22221 self.write(")");
22222 }
22223 }
22224 _ => {
22225 self.write_keyword("BINARY");
22226 if let Some(n) = length {
22227 self.write(&format!("({})", n));
22228 }
22229 }
22230 }
22231 }
22232 DataType::VarBinary { length } => {
22233 match self.config.dialect {
22235 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
22236 self.write_keyword("BYTEA");
22237 if let Some(n) = length {
22238 self.write(&format!("({})", n));
22239 }
22240 }
22241 Some(DialectType::Redshift) => {
22242 self.write_keyword("VARBYTE");
22243 if let Some(n) = length {
22244 self.write(&format!("({})", n));
22245 }
22246 }
22247 Some(DialectType::DuckDB)
22248 | Some(DialectType::SQLite)
22249 | Some(DialectType::Oracle) => {
22250 self.write_keyword("BLOB");
22252 if let Some(n) = length {
22253 self.write(&format!("({})", n));
22254 }
22255 }
22256 Some(DialectType::Exasol) => {
22257 self.write_keyword("VARCHAR");
22259 }
22260 Some(DialectType::Spark)
22261 | Some(DialectType::Hive)
22262 | Some(DialectType::Databricks) => {
22263 self.write_keyword("BINARY");
22265 if let Some(n) = length {
22266 self.write(&format!("({})", n));
22267 }
22268 }
22269 Some(DialectType::ClickHouse) => {
22270 self.write_clickhouse_type("String");
22272 }
22273 _ => {
22274 self.write_keyword("VARBINARY");
22275 if let Some(n) = length {
22276 self.write(&format!("({})", n));
22277 }
22278 }
22279 }
22280 }
22281 DataType::Blob => {
22282 match self.config.dialect {
22284 Some(DialectType::PostgreSQL) => self.write_keyword("BYTEA"),
22285 Some(DialectType::Redshift) => self.write_keyword("VARBYTE"),
22286 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
22287 self.write_keyword("VARBINARY")
22288 }
22289 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
22290 Some(DialectType::Exasol) => self.write_keyword("VARCHAR"),
22291 Some(DialectType::Presto)
22292 | Some(DialectType::Trino)
22293 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
22294 Some(DialectType::DuckDB) => {
22295 self.write_keyword("VARBINARY");
22298 }
22299 Some(DialectType::Spark)
22300 | Some(DialectType::Databricks)
22301 | Some(DialectType::Hive) => self.write_keyword("BINARY"),
22302 Some(DialectType::ClickHouse) => {
22303 self.write("Nullable(String)");
22307 }
22308 _ => self.write_keyword("BLOB"),
22309 }
22310 }
22311 DataType::Bit { length } => {
22312 match self.config.dialect {
22314 Some(DialectType::Dremio)
22315 | Some(DialectType::Spark)
22316 | Some(DialectType::Databricks)
22317 | Some(DialectType::Hive)
22318 | Some(DialectType::Snowflake)
22319 | Some(DialectType::BigQuery)
22320 | Some(DialectType::Presto)
22321 | Some(DialectType::Trino)
22322 | Some(DialectType::ClickHouse)
22323 | Some(DialectType::Redshift) => {
22324 self.write_keyword("BOOLEAN");
22326 }
22327 _ => {
22328 self.write_keyword("BIT");
22329 if let Some(n) = length {
22330 self.write(&format!("({})", n));
22331 }
22332 }
22333 }
22334 }
22335 DataType::VarBit { length } => {
22336 self.write_keyword("VARBIT");
22337 if let Some(n) = length {
22338 self.write(&format!("({})", n));
22339 }
22340 }
22341 DataType::Date => self.write_keyword("DATE"),
22342 DataType::Time {
22343 precision,
22344 timezone,
22345 } => {
22346 if *timezone {
22347 match self.config.dialect {
22349 Some(DialectType::DuckDB) => {
22350 self.write_keyword("TIMETZ");
22352 }
22353 Some(DialectType::PostgreSQL) => {
22354 self.write_keyword("TIMETZ");
22356 if let Some(p) = precision {
22357 self.write(&format!("({})", p));
22358 }
22359 }
22360 _ => {
22361 self.write_keyword("TIME");
22363 if let Some(p) = precision {
22364 self.write(&format!("({})", p));
22365 }
22366 self.write_keyword(" WITH TIME ZONE");
22367 }
22368 }
22369 } else {
22370 if matches!(
22372 self.config.dialect,
22373 Some(DialectType::Spark)
22374 | Some(DialectType::Databricks)
22375 | Some(DialectType::Hive)
22376 ) {
22377 self.write_keyword("TIMESTAMP");
22378 } else {
22379 self.write_keyword("TIME");
22380 if let Some(p) = precision {
22381 self.write(&format!("({})", p));
22382 }
22383 }
22384 }
22385 }
22386 DataType::Timestamp {
22387 precision,
22388 timezone,
22389 } => {
22390 match self.config.dialect {
22392 Some(DialectType::ClickHouse) => {
22393 self.write("DateTime");
22394 if let Some(p) = precision {
22395 self.write(&format!("({})", p));
22396 }
22397 }
22398 Some(DialectType::TSQL) => {
22399 if *timezone {
22400 self.write_keyword("DATETIMEOFFSET");
22401 } else {
22402 self.write_keyword("DATETIME2");
22403 }
22404 if let Some(p) = precision {
22405 self.write(&format!("({})", p));
22406 }
22407 }
22408 Some(DialectType::MySQL) => {
22409 self.write_keyword("TIMESTAMP");
22411 if let Some(p) = precision {
22412 self.write(&format!("({})", p));
22413 }
22414 }
22415 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
22416 self.write_keyword("DATETIME");
22418 if let Some(p) = precision {
22419 self.write(&format!("({})", p));
22420 }
22421 }
22422 Some(DialectType::BigQuery) => {
22423 if *timezone {
22425 self.write_keyword("TIMESTAMP");
22426 } else {
22427 self.write_keyword("DATETIME");
22428 }
22429 }
22430 Some(DialectType::DuckDB) => {
22431 if *timezone {
22433 self.write_keyword("TIMESTAMPTZ");
22434 } else {
22435 self.write_keyword("TIMESTAMP");
22436 if let Some(p) = precision {
22437 self.write(&format!("({})", p));
22438 }
22439 }
22440 }
22441 _ => {
22442 if *timezone && !self.config.tz_to_with_time_zone {
22443 self.write_keyword("TIMESTAMPTZ");
22445 if let Some(p) = precision {
22446 self.write(&format!("({})", p));
22447 }
22448 } else {
22449 self.write_keyword("TIMESTAMP");
22450 if let Some(p) = precision {
22451 self.write(&format!("({})", p));
22452 }
22453 if *timezone {
22454 self.write_space();
22455 self.write_keyword("WITH TIME ZONE");
22456 }
22457 }
22458 }
22459 }
22460 }
22461 DataType::Interval { unit, to } => {
22462 self.write_keyword("INTERVAL");
22463 if let Some(u) = unit {
22464 self.write_space();
22465 self.write_keyword(u);
22466 }
22467 if let Some(t) = to {
22469 self.write_space();
22470 self.write_keyword("TO");
22471 self.write_space();
22472 self.write_keyword(t);
22473 }
22474 }
22475 DataType::Json => {
22476 match self.config.dialect {
22478 Some(DialectType::Oracle) => self.write_keyword("JSON"), Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"), Some(DialectType::MySQL) => self.write_keyword("JSON"),
22481 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
22482 _ => self.write_keyword("JSON"),
22483 }
22484 }
22485 DataType::JsonB => {
22486 match self.config.dialect {
22488 Some(DialectType::PostgreSQL) => self.write_keyword("JSONB"),
22489 Some(DialectType::Doris) => self.write_keyword("JSONB"),
22490 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
22491 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
22492 Some(DialectType::DuckDB) => self.write_keyword("JSON"), _ => self.write_keyword("JSON"), }
22495 }
22496 DataType::Uuid => {
22497 match self.config.dialect {
22499 Some(DialectType::TSQL) => self.write_keyword("UNIQUEIDENTIFIER"),
22500 Some(DialectType::MySQL) => self.write_keyword("CHAR(36)"),
22501 Some(DialectType::Oracle) => self.write_keyword("RAW(16)"),
22502 Some(DialectType::BigQuery)
22503 | Some(DialectType::Spark)
22504 | Some(DialectType::Databricks) => self.write_keyword("STRING"),
22505 _ => self.write_keyword("UUID"),
22506 }
22507 }
22508 DataType::Array {
22509 element_type,
22510 dimension,
22511 } => {
22512 match self.config.dialect {
22514 Some(DialectType::PostgreSQL)
22515 | Some(DialectType::Redshift)
22516 | Some(DialectType::DuckDB) => {
22517 self.generate_data_type(element_type)?;
22519 if let Some(dim) = dimension {
22520 self.write(&format!("[{}]", dim));
22521 } else {
22522 self.write("[]");
22523 }
22524 }
22525 Some(DialectType::BigQuery) => {
22526 self.write_keyword("ARRAY<");
22527 self.generate_data_type(element_type)?;
22528 self.write(">");
22529 }
22530 Some(DialectType::Snowflake)
22531 | Some(DialectType::Presto)
22532 | Some(DialectType::Trino)
22533 | Some(DialectType::ClickHouse) => {
22534 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
22536 self.write("Array(");
22537 } else {
22538 self.write_keyword("ARRAY(");
22539 }
22540 self.generate_data_type(element_type)?;
22541 self.write(")");
22542 }
22543 Some(DialectType::TSQL)
22544 | Some(DialectType::MySQL)
22545 | Some(DialectType::Oracle) => {
22546 match self.config.dialect {
22549 Some(DialectType::MySQL) => self.write_keyword("JSON"),
22550 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
22551 _ => self.write_keyword("JSON"),
22552 }
22553 }
22554 _ => {
22555 self.write_keyword("ARRAY<");
22557 self.generate_data_type(element_type)?;
22558 self.write(">");
22559 }
22560 }
22561 }
22562 DataType::List { element_type } => {
22563 self.generate_data_type(element_type)?;
22565 self.write_keyword(" LIST");
22566 }
22567 DataType::Map {
22568 key_type,
22569 value_type,
22570 } => {
22571 match self.config.dialect {
22573 Some(DialectType::Materialize) => {
22574 self.write_keyword("MAP[");
22576 self.generate_data_type(key_type)?;
22577 self.write(" => ");
22578 self.generate_data_type(value_type)?;
22579 self.write("]");
22580 }
22581 Some(DialectType::Snowflake)
22582 | Some(DialectType::RisingWave)
22583 | Some(DialectType::DuckDB)
22584 | Some(DialectType::Presto)
22585 | Some(DialectType::Trino)
22586 | Some(DialectType::Athena) => {
22587 self.write_keyword("MAP(");
22588 self.generate_data_type(key_type)?;
22589 self.write(", ");
22590 self.generate_data_type(value_type)?;
22591 self.write(")");
22592 }
22593 Some(DialectType::ClickHouse) => {
22594 self.write("Map(");
22597 self.clickhouse_nullable_depth = -1; self.generate_data_type(key_type)?;
22599 self.clickhouse_nullable_depth = 0;
22600 self.write(", ");
22601 self.generate_data_type(value_type)?;
22602 self.write(")");
22603 }
22604 _ => {
22605 self.write_keyword("MAP<");
22606 self.generate_data_type(key_type)?;
22607 self.write(", ");
22608 self.generate_data_type(value_type)?;
22609 self.write(">");
22610 }
22611 }
22612 }
22613 DataType::Vector {
22614 element_type,
22615 dimension,
22616 } => {
22617 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
22618 self.write_keyword("VECTOR(");
22620 if let Some(dim) = dimension {
22621 self.write(&dim.to_string());
22622 }
22623 let type_alias = element_type.as_ref().and_then(|et| match et.as_ref() {
22625 DataType::TinyInt { .. } => Some("I8"),
22626 DataType::SmallInt { .. } => Some("I16"),
22627 DataType::Int { .. } => Some("I32"),
22628 DataType::BigInt { .. } => Some("I64"),
22629 DataType::Float { .. } => Some("F32"),
22630 DataType::Double { .. } => Some("F64"),
22631 _ => None,
22632 });
22633 if let Some(alias) = type_alias {
22634 if dimension.is_some() {
22635 self.write(", ");
22636 }
22637 self.write(alias);
22638 }
22639 self.write(")");
22640 } else {
22641 self.write_keyword("VECTOR(");
22643 if let Some(ref et) = element_type {
22644 self.generate_data_type(et)?;
22645 if dimension.is_some() {
22646 self.write(", ");
22647 }
22648 }
22649 if let Some(dim) = dimension {
22650 self.write(&dim.to_string());
22651 }
22652 self.write(")");
22653 }
22654 }
22655 DataType::Object { fields, modifier } => {
22656 self.write_keyword("OBJECT(");
22657 for (i, (name, dt, not_null)) in fields.iter().enumerate() {
22658 if i > 0 {
22659 self.write(", ");
22660 }
22661 self.write(name);
22662 self.write(" ");
22663 self.generate_data_type(dt)?;
22664 if *not_null {
22665 self.write_keyword(" NOT NULL");
22666 }
22667 }
22668 self.write(")");
22669 if let Some(mod_str) = modifier {
22670 self.write(" ");
22671 self.write_keyword(mod_str);
22672 }
22673 }
22674 DataType::Struct { fields, nested } => {
22675 match self.config.dialect {
22677 Some(DialectType::Snowflake) => {
22678 self.write_keyword("OBJECT(");
22680 for (i, field) in fields.iter().enumerate() {
22681 if i > 0 {
22682 self.write(", ");
22683 }
22684 if !field.name.is_empty() {
22685 self.write(&field.name);
22686 self.write(" ");
22687 }
22688 self.generate_data_type(&field.data_type)?;
22689 }
22690 self.write(")");
22691 }
22692 Some(DialectType::Presto) | Some(DialectType::Trino) => {
22693 self.write_keyword("ROW(");
22695 for (i, field) in fields.iter().enumerate() {
22696 if i > 0 {
22697 self.write(", ");
22698 }
22699 if !field.name.is_empty() {
22700 self.write(&field.name);
22701 self.write(" ");
22702 }
22703 self.generate_data_type(&field.data_type)?;
22704 }
22705 self.write(")");
22706 }
22707 Some(DialectType::DuckDB) => {
22708 self.write_keyword("STRUCT(");
22710 for (i, field) in fields.iter().enumerate() {
22711 if i > 0 {
22712 self.write(", ");
22713 }
22714 if !field.name.is_empty() {
22715 self.write(&field.name);
22716 self.write(" ");
22717 }
22718 self.generate_data_type(&field.data_type)?;
22719 }
22720 self.write(")");
22721 }
22722 Some(DialectType::ClickHouse) => {
22723 self.write("Tuple(");
22725 for (i, field) in fields.iter().enumerate() {
22726 if i > 0 {
22727 self.write(", ");
22728 }
22729 if !field.name.is_empty() {
22730 self.write(&field.name);
22731 self.write(" ");
22732 }
22733 self.generate_data_type(&field.data_type)?;
22734 }
22735 self.write(")");
22736 }
22737 Some(DialectType::SingleStore) => {
22738 self.write_keyword("RECORD(");
22740 for (i, field) in fields.iter().enumerate() {
22741 if i > 0 {
22742 self.write(", ");
22743 }
22744 if !field.name.is_empty() {
22745 self.write(&field.name);
22746 self.write(" ");
22747 }
22748 self.generate_data_type(&field.data_type)?;
22749 }
22750 self.write(")");
22751 }
22752 _ => {
22753 let force_angle_brackets = matches!(
22755 self.config.dialect,
22756 Some(DialectType::Hive)
22757 | Some(DialectType::Spark)
22758 | Some(DialectType::Databricks)
22759 );
22760 if *nested && !force_angle_brackets {
22761 self.write_keyword("STRUCT(");
22762 for (i, field) in fields.iter().enumerate() {
22763 if i > 0 {
22764 self.write(", ");
22765 }
22766 if !field.name.is_empty() {
22767 self.write(&field.name);
22768 self.write(" ");
22769 }
22770 self.generate_data_type(&field.data_type)?;
22771 }
22772 self.write(")");
22773 } else {
22774 self.write_keyword("STRUCT<");
22775 for (i, field) in fields.iter().enumerate() {
22776 if i > 0 {
22777 self.write(", ");
22778 }
22779 if !field.name.is_empty() {
22780 self.write(&field.name);
22782 self.write(self.config.struct_field_sep);
22783 }
22784 self.generate_data_type(&field.data_type)?;
22786 if let Some(comment) = &field.comment {
22788 self.write(" COMMENT '");
22789 self.write(comment);
22790 self.write("'");
22791 }
22792 if !field.options.is_empty() {
22794 self.write(" ");
22795 self.generate_options_clause(&field.options)?;
22796 }
22797 }
22798 self.write(">");
22799 }
22800 }
22801 }
22802 }
22803 DataType::Enum {
22804 values,
22805 assignments,
22806 } => {
22807 if self.config.dialect == Some(DialectType::ClickHouse) {
22810 self.write("Enum(");
22811 } else {
22812 self.write_keyword("ENUM(");
22813 }
22814 for (i, val) in values.iter().enumerate() {
22815 if i > 0 {
22816 self.write(", ");
22817 }
22818 self.write("'");
22819 self.write(val);
22820 self.write("'");
22821 if let Some(Some(assignment)) = assignments.get(i) {
22822 self.write(" = ");
22823 self.write(assignment);
22824 }
22825 }
22826 self.write(")");
22827 }
22828 DataType::Set { values } => {
22829 self.write_keyword("SET(");
22831 for (i, val) in values.iter().enumerate() {
22832 if i > 0 {
22833 self.write(", ");
22834 }
22835 self.write("'");
22836 self.write(val);
22837 self.write("'");
22838 }
22839 self.write(")");
22840 }
22841 DataType::Union { fields } => {
22842 self.write_keyword("UNION(");
22844 for (i, (name, dt)) in fields.iter().enumerate() {
22845 if i > 0 {
22846 self.write(", ");
22847 }
22848 if !name.is_empty() {
22849 self.write(name);
22850 self.write(" ");
22851 }
22852 self.generate_data_type(dt)?;
22853 }
22854 self.write(")");
22855 }
22856 DataType::Nullable { inner } => {
22857 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
22859 self.write("Nullable(");
22860 let saved_depth = self.clickhouse_nullable_depth;
22862 self.clickhouse_nullable_depth = -1;
22863 self.generate_data_type(inner)?;
22864 self.clickhouse_nullable_depth = saved_depth;
22865 self.write(")");
22866 } else {
22867 match inner.as_ref() {
22869 DataType::Custom { name } if name.to_uppercase() == "DATETIME" => {
22870 self.generate_data_type(&DataType::Timestamp {
22871 precision: None,
22872 timezone: false,
22873 })?;
22874 }
22875 _ => {
22876 self.generate_data_type(inner)?;
22877 }
22878 }
22879 }
22880 }
22881 DataType::Custom { name } => {
22882 let name_upper = name.to_uppercase();
22884 match self.config.dialect {
22885 Some(DialectType::ClickHouse) => {
22886 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
22887 (name_upper[..idx].to_string(), &name[idx..])
22888 } else {
22889 (name_upper.clone(), "")
22890 };
22891 let mapped = match base_upper.as_str() {
22892 "DATETIME" | "TIMESTAMPTZ" | "TIMESTAMP" | "TIMESTAMPNTZ"
22893 | "SMALLDATETIME" | "DATETIME2" => "DateTime",
22894 "DATETIME64" => "DateTime64",
22895 "DATE32" => "Date32",
22896 "INT" => "Int32",
22897 "MEDIUMINT" => "Int32",
22898 "INT8" => "Int8",
22899 "INT16" => "Int16",
22900 "INT32" => "Int32",
22901 "INT64" => "Int64",
22902 "INT128" => "Int128",
22903 "INT256" => "Int256",
22904 "UINT8" => "UInt8",
22905 "UINT16" => "UInt16",
22906 "UINT32" => "UInt32",
22907 "UINT64" => "UInt64",
22908 "UINT128" => "UInt128",
22909 "UINT256" => "UInt256",
22910 "FLOAT32" => "Float32",
22911 "FLOAT64" => "Float64",
22912 "DECIMAL32" => "Decimal32",
22913 "DECIMAL64" => "Decimal64",
22914 "DECIMAL128" => "Decimal128",
22915 "DECIMAL256" => "Decimal256",
22916 "ENUM" => "Enum",
22917 "ENUM8" => "Enum8",
22918 "ENUM16" => "Enum16",
22919 "FIXEDSTRING" => "FixedString",
22920 "NESTED" => "Nested",
22921 "LOWCARDINALITY" => "LowCardinality",
22922 "NULLABLE" => "Nullable",
22923 "IPV4" => "IPv4",
22924 "IPV6" => "IPv6",
22925 "POINT" => "Point",
22926 "RING" => "Ring",
22927 "LINESTRING" => "LineString",
22928 "MULTILINESTRING" => "MultiLineString",
22929 "POLYGON" => "Polygon",
22930 "MULTIPOLYGON" => "MultiPolygon",
22931 "AGGREGATEFUNCTION" => "AggregateFunction",
22932 "SIMPLEAGGREGATEFUNCTION" => "SimpleAggregateFunction",
22933 "DYNAMIC" => "Dynamic",
22934 _ => "",
22935 };
22936 if mapped.is_empty() {
22937 self.write(name);
22938 } else {
22939 self.write(mapped);
22940 self.write(suffix);
22941 }
22942 }
22943 Some(DialectType::MySQL)
22944 if name_upper == "TIMESTAMPTZ" || name_upper == "TIMESTAMPLTZ" =>
22945 {
22946 self.write_keyword("TIMESTAMP");
22948 }
22949 Some(DialectType::TSQL) if name_upper == "VARIANT" => {
22950 self.write_keyword("SQL_VARIANT");
22951 }
22952 Some(DialectType::DuckDB) if name_upper == "DECFLOAT" => {
22953 self.write_keyword("DECIMAL(38, 5)");
22954 }
22955 Some(DialectType::Exasol) => {
22956 match name_upper.as_str() {
22958 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => self.write_keyword("VARCHAR"),
22960 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => self.write_keyword("VARCHAR"),
22962 "MEDIUMINT" => self.write_keyword("INT"),
22964 "DECIMAL32" | "DECIMAL64" | "DECIMAL128" | "DECIMAL256" => {
22966 self.write_keyword("DECIMAL")
22967 }
22968 "DATETIME" => self.write_keyword("TIMESTAMP"),
22970 "TIMESTAMPLTZ" => self.write_keyword("TIMESTAMP WITH LOCAL TIME ZONE"),
22971 _ => self.write(name),
22972 }
22973 }
22974 Some(DialectType::Dremio) => {
22975 match name_upper.as_str() {
22977 "TIMESTAMPNTZ" | "DATETIME" => self.write_keyword("TIMESTAMP"),
22978 "ARRAY" => self.write_keyword("LIST"),
22979 "NCHAR" => self.write_keyword("VARCHAR"),
22980 _ => self.write(name),
22981 }
22982 }
22983 _ => {
22985 let (base_upper, _args_str) = if let Some(idx) = name_upper.find('(') {
22987 (name_upper[..idx].to_string(), Some(&name[idx..]))
22988 } else {
22989 (name_upper.clone(), None)
22990 };
22991
22992 match base_upper.as_str() {
22993 "INT64"
22994 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
22995 {
22996 self.write_keyword("BIGINT");
22997 }
22998 "FLOAT64"
22999 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
23000 {
23001 self.write_keyword("DOUBLE");
23002 }
23003 "BOOL"
23004 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
23005 {
23006 self.write_keyword("BOOLEAN");
23007 }
23008 "BYTES"
23009 if matches!(
23010 self.config.dialect,
23011 Some(DialectType::Spark)
23012 | Some(DialectType::Hive)
23013 | Some(DialectType::Databricks)
23014 ) =>
23015 {
23016 self.write_keyword("BINARY");
23017 }
23018 "BYTES"
23019 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
23020 {
23021 self.write_keyword("VARBINARY");
23022 }
23023 "DATETIME2" | "SMALLDATETIME"
23025 if !matches!(
23026 self.config.dialect,
23027 Some(DialectType::TSQL) | Some(DialectType::Fabric)
23028 ) =>
23029 {
23030 if matches!(
23032 self.config.dialect,
23033 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
23034 ) {
23035 self.write_keyword("TIMESTAMP");
23036 if let Some(args) = _args_str {
23037 self.write(args);
23038 }
23039 } else {
23040 self.write_keyword("TIMESTAMP");
23041 }
23042 }
23043 "DATETIMEOFFSET"
23045 if !matches!(
23046 self.config.dialect,
23047 Some(DialectType::TSQL) | Some(DialectType::Fabric)
23048 ) =>
23049 {
23050 if matches!(
23051 self.config.dialect,
23052 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
23053 ) {
23054 self.write_keyword("TIMESTAMPTZ");
23055 if let Some(args) = _args_str {
23056 self.write(args);
23057 }
23058 } else {
23059 self.write_keyword("TIMESTAMPTZ");
23060 }
23061 }
23062 "UNIQUEIDENTIFIER"
23064 if !matches!(
23065 self.config.dialect,
23066 Some(DialectType::TSQL) | Some(DialectType::Fabric)
23067 ) =>
23068 {
23069 match self.config.dialect {
23070 Some(DialectType::Spark)
23071 | Some(DialectType::Databricks)
23072 | Some(DialectType::Hive) => self.write_keyword("STRING"),
23073 _ => self.write_keyword("UUID"),
23074 }
23075 }
23076 "BIT"
23078 if !matches!(
23079 self.config.dialect,
23080 Some(DialectType::TSQL)
23081 | Some(DialectType::Fabric)
23082 | Some(DialectType::PostgreSQL)
23083 | Some(DialectType::MySQL)
23084 | Some(DialectType::DuckDB)
23085 ) =>
23086 {
23087 self.write_keyword("BOOLEAN");
23088 }
23089 "NVARCHAR"
23091 if !matches!(
23092 self.config.dialect,
23093 Some(DialectType::TSQL) | Some(DialectType::Fabric)
23094 ) =>
23095 {
23096 match self.config.dialect {
23097 Some(DialectType::Oracle) => {
23098 self.write_keyword("NVARCHAR2");
23100 if let Some(args) = _args_str {
23101 self.write(args);
23102 }
23103 }
23104 Some(DialectType::BigQuery) => {
23105 self.write_keyword("STRING");
23107 }
23108 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
23109 self.write_keyword("TEXT");
23110 if let Some(args) = _args_str {
23111 self.write(args);
23112 }
23113 }
23114 Some(DialectType::Hive) => {
23115 self.write_keyword("STRING");
23117 }
23118 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
23119 if _args_str.is_some() {
23120 self.write_keyword("VARCHAR");
23121 self.write(_args_str.unwrap());
23122 } else {
23123 self.write_keyword("STRING");
23124 }
23125 }
23126 _ => {
23127 self.write_keyword("VARCHAR");
23128 if let Some(args) = _args_str {
23129 self.write(args);
23130 }
23131 }
23132 }
23133 }
23134 "NCHAR"
23136 if !matches!(
23137 self.config.dialect,
23138 Some(DialectType::TSQL) | Some(DialectType::Fabric)
23139 ) =>
23140 {
23141 match self.config.dialect {
23142 Some(DialectType::Oracle) => {
23143 self.write_keyword("NCHAR");
23145 if let Some(args) = _args_str {
23146 self.write(args);
23147 }
23148 }
23149 Some(DialectType::BigQuery) => {
23150 self.write_keyword("STRING");
23152 }
23153 Some(DialectType::Hive) => {
23154 self.write_keyword("STRING");
23156 }
23157 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
23158 self.write_keyword("TEXT");
23159 if let Some(args) = _args_str {
23160 self.write(args);
23161 }
23162 }
23163 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
23164 if _args_str.is_some() {
23165 self.write_keyword("CHAR");
23166 self.write(_args_str.unwrap());
23167 } else {
23168 self.write_keyword("STRING");
23169 }
23170 }
23171 _ => {
23172 self.write_keyword("CHAR");
23173 if let Some(args) = _args_str {
23174 self.write(args);
23175 }
23176 }
23177 }
23178 }
23179 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => match self.config.dialect {
23182 Some(DialectType::MySQL)
23183 | Some(DialectType::SingleStore)
23184 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
23185 Some(DialectType::Spark)
23186 | Some(DialectType::Databricks)
23187 | Some(DialectType::Hive) => self.write_keyword("TEXT"),
23188 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
23189 Some(DialectType::Presto)
23190 | Some(DialectType::Trino)
23191 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
23192 Some(DialectType::Snowflake)
23193 | Some(DialectType::Redshift)
23194 | Some(DialectType::Dremio) => self.write_keyword("VARCHAR"),
23195 _ => self.write_keyword("TEXT"),
23196 },
23197 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => match self.config.dialect {
23200 Some(DialectType::MySQL)
23201 | Some(DialectType::SingleStore)
23202 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
23203 Some(DialectType::Spark)
23204 | Some(DialectType::Databricks)
23205 | Some(DialectType::Hive) => self.write_keyword("BLOB"),
23206 Some(DialectType::DuckDB) => self.write_keyword("VARBINARY"),
23207 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
23208 Some(DialectType::Presto)
23209 | Some(DialectType::Trino)
23210 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
23211 Some(DialectType::Snowflake)
23212 | Some(DialectType::Redshift)
23213 | Some(DialectType::Dremio) => self.write_keyword("VARBINARY"),
23214 _ => self.write_keyword("BLOB"),
23215 },
23216 "LONGVARCHAR" => match self.config.dialect {
23218 Some(DialectType::SQLite) => self.write_keyword("TEXT"),
23219 _ => self.write_keyword("VARCHAR"),
23220 },
23221 "DATETIME" => {
23223 match self.config.dialect {
23224 Some(DialectType::MySQL)
23225 | Some(DialectType::Doris)
23226 | Some(DialectType::StarRocks)
23227 | Some(DialectType::TSQL)
23228 | Some(DialectType::Fabric)
23229 | Some(DialectType::BigQuery)
23230 | Some(DialectType::SQLite)
23231 | Some(DialectType::Snowflake) => {
23232 self.write_keyword("DATETIME");
23233 if let Some(args) = _args_str {
23234 self.write(args);
23235 }
23236 }
23237 Some(_) => {
23238 self.write_keyword("TIMESTAMP");
23240 if let Some(args) = _args_str {
23241 self.write(args);
23242 }
23243 }
23244 None => {
23245 self.write(name);
23247 }
23248 }
23249 }
23250 "VARCHAR2"
23252 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
23253 {
23254 match self.config.dialect {
23255 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
23256 self.write_keyword("TEXT");
23257 }
23258 Some(DialectType::Hive)
23259 | Some(DialectType::Spark)
23260 | Some(DialectType::Databricks)
23261 | Some(DialectType::BigQuery)
23262 | Some(DialectType::ClickHouse)
23263 | Some(DialectType::StarRocks)
23264 | Some(DialectType::Doris) => {
23265 self.write_keyword("STRING");
23266 }
23267 _ => {
23268 self.write_keyword("VARCHAR");
23269 if let Some(args) = _args_str {
23270 self.write(args);
23271 }
23272 }
23273 }
23274 }
23275 "NVARCHAR2"
23276 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
23277 {
23278 match self.config.dialect {
23279 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
23280 self.write_keyword("TEXT");
23281 }
23282 Some(DialectType::Hive)
23283 | Some(DialectType::Spark)
23284 | Some(DialectType::Databricks)
23285 | Some(DialectType::BigQuery)
23286 | Some(DialectType::ClickHouse)
23287 | Some(DialectType::StarRocks)
23288 | Some(DialectType::Doris) => {
23289 self.write_keyword("STRING");
23290 }
23291 _ => {
23292 self.write_keyword("VARCHAR");
23293 if let Some(args) = _args_str {
23294 self.write(args);
23295 }
23296 }
23297 }
23298 }
23299 _ => self.write(name),
23300 }
23301 }
23302 }
23303 }
23304 DataType::Geometry { subtype, srid } => {
23305 match self.config.dialect {
23307 Some(DialectType::MySQL) => {
23308 if let Some(sub) = subtype {
23310 self.write_keyword(sub);
23311 if let Some(s) = srid {
23312 self.write(" SRID ");
23313 self.write(&s.to_string());
23314 }
23315 } else {
23316 self.write_keyword("GEOMETRY");
23317 }
23318 }
23319 Some(DialectType::BigQuery) => {
23320 self.write_keyword("GEOGRAPHY");
23322 }
23323 Some(DialectType::Teradata) => {
23324 self.write_keyword("ST_GEOMETRY");
23326 if subtype.is_some() || srid.is_some() {
23327 self.write("(");
23328 if let Some(sub) = subtype {
23329 self.write_keyword(sub);
23330 }
23331 if let Some(s) = srid {
23332 if subtype.is_some() {
23333 self.write(", ");
23334 }
23335 self.write(&s.to_string());
23336 }
23337 self.write(")");
23338 }
23339 }
23340 _ => {
23341 self.write_keyword("GEOMETRY");
23343 if subtype.is_some() || srid.is_some() {
23344 self.write("(");
23345 if let Some(sub) = subtype {
23346 self.write_keyword(sub);
23347 }
23348 if let Some(s) = srid {
23349 if subtype.is_some() {
23350 self.write(", ");
23351 }
23352 self.write(&s.to_string());
23353 }
23354 self.write(")");
23355 }
23356 }
23357 }
23358 }
23359 DataType::Geography { subtype, srid } => {
23360 match self.config.dialect {
23362 Some(DialectType::MySQL) => {
23363 if let Some(sub) = subtype {
23365 self.write_keyword(sub);
23366 } else {
23367 self.write_keyword("GEOMETRY");
23368 }
23369 let effective_srid = srid.unwrap_or(4326);
23371 self.write(" SRID ");
23372 self.write(&effective_srid.to_string());
23373 }
23374 Some(DialectType::BigQuery) => {
23375 self.write_keyword("GEOGRAPHY");
23377 }
23378 Some(DialectType::Snowflake) => {
23379 self.write_keyword("GEOGRAPHY");
23381 }
23382 _ => {
23383 self.write_keyword("GEOGRAPHY");
23385 if subtype.is_some() || srid.is_some() {
23386 self.write("(");
23387 if let Some(sub) = subtype {
23388 self.write_keyword(sub);
23389 }
23390 if let Some(s) = srid {
23391 if subtype.is_some() {
23392 self.write(", ");
23393 }
23394 self.write(&s.to_string());
23395 }
23396 self.write(")");
23397 }
23398 }
23399 }
23400 }
23401 DataType::CharacterSet { name } => {
23402 self.write_keyword("CHAR CHARACTER SET ");
23404 self.write(name);
23405 }
23406 _ => self.write("UNKNOWN"),
23407 }
23408 Ok(())
23409 }
23410
23411 fn write(&mut self, s: &str) {
23414 self.output.push_str(s);
23415 }
23416
23417 fn write_space(&mut self) {
23418 self.output.push(' ');
23419 }
23420
23421 fn write_keyword(&mut self, keyword: &str) {
23422 if self.config.uppercase_keywords {
23423 self.output.push_str(keyword);
23424 } else {
23425 self.output.push_str(&keyword.to_lowercase());
23426 }
23427 }
23428
23429 fn write_func_name(&mut self, name: &str) {
23431 let normalized = self.normalize_func_name(name);
23432 self.output.push_str(&normalized);
23433 }
23434
23435 fn convert_strptime_to_exasol_format(format: &str) -> String {
23439 let mut result = String::new();
23440 let chars: Vec<char> = format.chars().collect();
23441 let mut i = 0;
23442 while i < chars.len() {
23443 if chars[i] == '%' && i + 1 < chars.len() {
23444 let spec = chars[i + 1];
23445 let exasol_spec = match spec {
23446 'Y' => "YYYY",
23447 'y' => "YY",
23448 'm' => "MM",
23449 'd' => "DD",
23450 'H' => "HH",
23451 'M' => "MI",
23452 'S' => "SS",
23453 'a' => "DY", 'A' => "DAY", 'b' => "MON", 'B' => "MONTH", 'I' => "H12", 'u' => "ID", 'V' => "IW", 'G' => "IYYY", 'W' => "UW", 'U' => "UW", 'z' => "Z", _ => {
23465 result.push('%');
23467 result.push(spec);
23468 i += 2;
23469 continue;
23470 }
23471 };
23472 result.push_str(exasol_spec);
23473 i += 2;
23474 } else {
23475 result.push(chars[i]);
23476 i += 1;
23477 }
23478 }
23479 result
23480 }
23481
23482 fn convert_strptime_to_postgres_format(format: &str) -> String {
23486 let mut result = String::new();
23487 let chars: Vec<char> = format.chars().collect();
23488 let mut i = 0;
23489 while i < chars.len() {
23490 if chars[i] == '%' && i + 1 < chars.len() {
23491 if chars[i + 1] == '-' && i + 2 < chars.len() {
23493 let spec = chars[i + 2];
23494 let pg_spec = match spec {
23495 'd' => "FMDD",
23496 'm' => "FMMM",
23497 'H' => "FMHH24",
23498 'M' => "FMMI",
23499 'S' => "FMSS",
23500 _ => {
23501 result.push('%');
23502 result.push('-');
23503 result.push(spec);
23504 i += 3;
23505 continue;
23506 }
23507 };
23508 result.push_str(pg_spec);
23509 i += 3;
23510 continue;
23511 }
23512 let spec = chars[i + 1];
23513 let pg_spec = match spec {
23514 'Y' => "YYYY",
23515 'y' => "YY",
23516 'm' => "MM",
23517 'd' => "DD",
23518 'H' => "HH24",
23519 'I' => "HH12",
23520 'M' => "MI",
23521 'S' => "SS",
23522 'f' => "US", 'u' => "D", 'j' => "DDD", 'z' => "OF", 'Z' => "TZ", 'A' => "TMDay", 'a' => "TMDy", 'b' => "TMMon", 'B' => "TMMonth", 'U' => "WW", _ => {
23533 result.push('%');
23535 result.push(spec);
23536 i += 2;
23537 continue;
23538 }
23539 };
23540 result.push_str(pg_spec);
23541 i += 2;
23542 } else {
23543 result.push(chars[i]);
23544 i += 1;
23545 }
23546 }
23547 result
23548 }
23549
23550 fn write_limit_expr(&mut self, expr: &Expression) -> Result<()> {
23552 if self.config.limit_only_literals {
23553 if let Some(value) = Self::try_evaluate_constant(expr) {
23554 self.write(&value.to_string());
23555 return Ok(());
23556 }
23557 }
23558 self.generate_expression(expr)
23559 }
23560
23561 fn write_formatted_comment(&mut self, comment: &str) {
23565 let content = if comment.starts_with("/*") && comment.ends_with("*/") {
23568 &comment[2..comment.len() - 2]
23571 } else if comment.starts_with("--") {
23572 &comment[2..]
23575 } else {
23576 comment
23578 };
23579 if content.trim().is_empty() {
23581 return;
23582 }
23583 self.output.push_str("/*");
23585 if !content.starts_with(' ') {
23586 self.output.push(' ');
23587 }
23588 self.output.push_str(content);
23589 if !content.ends_with(' ') {
23590 self.output.push(' ');
23591 }
23592 self.output.push_str("*/");
23593 }
23594
23595 fn escape_block_for_single_quote(&self, block: &str) -> String {
23598 let escape_backslash = matches!(
23599 self.config.dialect,
23600 Some(crate::dialects::DialectType::Snowflake)
23601 );
23602 let mut escaped = String::with_capacity(block.len() + 4);
23603 for ch in block.chars() {
23604 if ch == '\'' {
23605 escaped.push('\\');
23606 escaped.push('\'');
23607 } else if escape_backslash && ch == '\\' {
23608 escaped.push('\\');
23609 escaped.push('\\');
23610 } else {
23611 escaped.push(ch);
23612 }
23613 }
23614 escaped
23615 }
23616
23617 fn write_newline(&mut self) {
23618 self.output.push('\n');
23619 }
23620
23621 fn write_indent(&mut self) {
23622 for _ in 0..self.indent_level {
23623 self.output.push_str(&self.config.indent);
23624 }
23625 }
23626
23627 fn too_wide(&self, args: &[String]) -> bool {
23633 args.iter().map(|s| s.len()).sum::<usize>() > self.config.max_text_width
23634 }
23635
23636 fn generate_to_string(&self, expr: &Expression) -> Result<String> {
23639 let config = GeneratorConfig {
23640 pretty: false,
23641 dialect: self.config.dialect,
23642 ..Default::default()
23643 };
23644 let mut gen = Generator::with_config(config);
23645 gen.generate_expression(expr)?;
23646 Ok(gen.output)
23647 }
23648
23649 fn write_clause_condition(&mut self, keyword: &str, condition: &Expression) -> Result<()> {
23652 if self.config.pretty {
23653 self.write_newline();
23654 self.write_indent();
23655 self.write_keyword(keyword);
23656 self.write_newline();
23657 self.indent_level += 1;
23658 self.write_indent();
23659 self.generate_expression(condition)?;
23660 self.indent_level -= 1;
23661 } else {
23662 self.write_space();
23663 self.write_keyword(keyword);
23664 self.write_space();
23665 self.generate_expression(condition)?;
23666 }
23667 Ok(())
23668 }
23669
23670 fn write_clause_expressions(&mut self, keyword: &str, exprs: &[Expression]) -> Result<()> {
23673 if exprs.is_empty() {
23674 return Ok(());
23675 }
23676
23677 if self.config.pretty {
23678 self.write_newline();
23679 self.write_indent();
23680 self.write_keyword(keyword);
23681 self.write_newline();
23682 self.indent_level += 1;
23683 for (i, expr) in exprs.iter().enumerate() {
23684 if i > 0 {
23685 self.write(",");
23686 self.write_newline();
23687 }
23688 self.write_indent();
23689 self.generate_expression(expr)?;
23690 }
23691 self.indent_level -= 1;
23692 } else {
23693 self.write_space();
23694 self.write_keyword(keyword);
23695 self.write_space();
23696 for (i, expr) in exprs.iter().enumerate() {
23697 if i > 0 {
23698 self.write(", ");
23699 }
23700 self.generate_expression(expr)?;
23701 }
23702 }
23703 Ok(())
23704 }
23705
23706 fn write_order_clause(&mut self, keyword: &str, orderings: &[Ordered]) -> Result<()> {
23708 if orderings.is_empty() {
23709 return Ok(());
23710 }
23711
23712 if self.config.pretty {
23713 self.write_newline();
23714 self.write_indent();
23715 self.write_keyword(keyword);
23716 self.write_newline();
23717 self.indent_level += 1;
23718 for (i, ordered) in orderings.iter().enumerate() {
23719 if i > 0 {
23720 self.write(",");
23721 self.write_newline();
23722 }
23723 self.write_indent();
23724 self.generate_ordered(ordered)?;
23725 }
23726 self.indent_level -= 1;
23727 } else {
23728 self.write_space();
23729 self.write_keyword(keyword);
23730 self.write_space();
23731 for (i, ordered) in orderings.iter().enumerate() {
23732 if i > 0 {
23733 self.write(", ");
23734 }
23735 self.generate_ordered(ordered)?;
23736 }
23737 }
23738 Ok(())
23739 }
23740
23741 fn write_window_clause(&mut self, windows: &[NamedWindow]) -> Result<()> {
23743 if windows.is_empty() {
23744 return Ok(());
23745 }
23746
23747 if self.config.pretty {
23748 self.write_newline();
23749 self.write_indent();
23750 self.write_keyword("WINDOW");
23751 self.write_newline();
23752 self.indent_level += 1;
23753 for (i, named_window) in windows.iter().enumerate() {
23754 if i > 0 {
23755 self.write(",");
23756 self.write_newline();
23757 }
23758 self.write_indent();
23759 self.generate_identifier(&named_window.name)?;
23760 self.write_space();
23761 self.write_keyword("AS");
23762 self.write(" (");
23763 self.generate_over(&named_window.spec)?;
23764 self.write(")");
23765 }
23766 self.indent_level -= 1;
23767 } else {
23768 self.write_space();
23769 self.write_keyword("WINDOW");
23770 self.write_space();
23771 for (i, named_window) in windows.iter().enumerate() {
23772 if i > 0 {
23773 self.write(", ");
23774 }
23775 self.generate_identifier(&named_window.name)?;
23776 self.write_space();
23777 self.write_keyword("AS");
23778 self.write(" (");
23779 self.generate_over(&named_window.spec)?;
23780 self.write(")");
23781 }
23782 }
23783 Ok(())
23784 }
23785
23786 fn generate_ai_agg(&mut self, e: &AIAgg) -> Result<()> {
23788 self.write_keyword("AI_AGG");
23790 self.write("(");
23791 self.generate_expression(&e.this)?;
23792 self.write(", ");
23793 self.generate_expression(&e.expression)?;
23794 self.write(")");
23795 Ok(())
23796 }
23797
23798 fn generate_ai_classify(&mut self, e: &AIClassify) -> Result<()> {
23799 self.write_keyword("AI_CLASSIFY");
23801 self.write("(");
23802 self.generate_expression(&e.this)?;
23803 if let Some(categories) = &e.categories {
23804 self.write(", ");
23805 self.generate_expression(categories)?;
23806 }
23807 if let Some(config) = &e.config {
23808 self.write(", ");
23809 self.generate_expression(config)?;
23810 }
23811 self.write(")");
23812 Ok(())
23813 }
23814
23815 fn generate_add_partition(&mut self, e: &AddPartition) -> Result<()> {
23816 self.write_keyword("ADD");
23818 self.write_space();
23819 if e.exists {
23820 self.write_keyword("IF NOT EXISTS");
23821 self.write_space();
23822 }
23823 self.generate_expression(&e.this)?;
23824 if let Some(location) = &e.location {
23825 self.write_space();
23826 self.generate_expression(location)?;
23827 }
23828 Ok(())
23829 }
23830
23831 fn generate_algorithm_property(&mut self, e: &AlgorithmProperty) -> Result<()> {
23832 self.write_keyword("ALGORITHM");
23834 self.write("=");
23835 self.generate_expression(&e.this)?;
23836 Ok(())
23837 }
23838
23839 fn generate_aliases(&mut self, e: &Aliases) -> Result<()> {
23840 self.generate_expression(&e.this)?;
23842 self.write_space();
23843 self.write_keyword("AS");
23844 self.write(" (");
23845 for (i, expr) in e.expressions.iter().enumerate() {
23846 if i > 0 {
23847 self.write(", ");
23848 }
23849 self.generate_expression(expr)?;
23850 }
23851 self.write(")");
23852 Ok(())
23853 }
23854
23855 fn generate_allowed_values_property(&mut self, e: &AllowedValuesProperty) -> Result<()> {
23856 self.write_keyword("ALLOWED_VALUES");
23858 self.write_space();
23859 for (i, expr) in e.expressions.iter().enumerate() {
23860 if i > 0 {
23861 self.write(", ");
23862 }
23863 self.generate_expression(expr)?;
23864 }
23865 Ok(())
23866 }
23867
23868 fn generate_alter_column(&mut self, e: &AlterColumn) -> Result<()> {
23869 self.write_keyword("ALTER COLUMN");
23871 self.write_space();
23872 self.generate_expression(&e.this)?;
23873
23874 if let Some(dtype) = &e.dtype {
23875 self.write_space();
23876 self.write_keyword("SET DATA TYPE");
23877 self.write_space();
23878 self.generate_expression(dtype)?;
23879 if let Some(collate) = &e.collate {
23880 self.write_space();
23881 self.write_keyword("COLLATE");
23882 self.write_space();
23883 self.generate_expression(collate)?;
23884 }
23885 if let Some(using) = &e.using {
23886 self.write_space();
23887 self.write_keyword("USING");
23888 self.write_space();
23889 self.generate_expression(using)?;
23890 }
23891 } else if let Some(default) = &e.default {
23892 self.write_space();
23893 self.write_keyword("SET DEFAULT");
23894 self.write_space();
23895 self.generate_expression(default)?;
23896 } else if let Some(comment) = &e.comment {
23897 self.write_space();
23898 self.write_keyword("COMMENT");
23899 self.write_space();
23900 self.generate_expression(comment)?;
23901 } else if let Some(drop) = &e.drop {
23902 self.write_space();
23903 self.write_keyword("DROP");
23904 self.write_space();
23905 self.generate_expression(drop)?;
23906 } else if let Some(visible) = &e.visible {
23907 self.write_space();
23908 self.generate_expression(visible)?;
23909 } else if let Some(rename_to) = &e.rename_to {
23910 self.write_space();
23911 self.write_keyword("RENAME TO");
23912 self.write_space();
23913 self.generate_expression(rename_to)?;
23914 } else if let Some(allow_null) = &e.allow_null {
23915 self.write_space();
23916 self.generate_expression(allow_null)?;
23917 }
23918 Ok(())
23919 }
23920
23921 fn generate_alter_session(&mut self, e: &AlterSession) -> Result<()> {
23922 self.write_keyword("ALTER SESSION");
23924 self.write_space();
23925 if e.unset.is_some() {
23926 self.write_keyword("UNSET");
23927 } else {
23928 self.write_keyword("SET");
23929 }
23930 self.write_space();
23931 for (i, expr) in e.expressions.iter().enumerate() {
23932 if i > 0 {
23933 self.write(", ");
23934 }
23935 self.generate_expression(expr)?;
23936 }
23937 Ok(())
23938 }
23939
23940 fn generate_alter_set(&mut self, e: &AlterSet) -> Result<()> {
23941 self.write_keyword("SET");
23943
23944 if let Some(opt) = &e.option {
23946 self.write_space();
23947 self.generate_expression(opt)?;
23948 }
23949
23950 if !e.expressions.is_empty() {
23953 let is_properties = e
23955 .expressions
23956 .iter()
23957 .any(|expr| matches!(expr, Expression::Eq(_)));
23958 if is_properties && e.option.is_none() {
23959 self.write_space();
23960 self.write_keyword("PROPERTIES");
23961 }
23962 self.write_space();
23963 for (i, expr) in e.expressions.iter().enumerate() {
23964 if i > 0 {
23965 self.write(", ");
23966 }
23967 self.generate_expression(expr)?;
23968 }
23969 }
23970
23971 if let Some(file_format) = &e.file_format {
23973 self.write(" ");
23974 self.write_keyword("STAGE_FILE_FORMAT");
23975 self.write(" = (");
23976 self.generate_space_separated_properties(file_format)?;
23977 self.write(")");
23978 }
23979
23980 if let Some(copy_options) = &e.copy_options {
23982 self.write(" ");
23983 self.write_keyword("STAGE_COPY_OPTIONS");
23984 self.write(" = (");
23985 self.generate_space_separated_properties(copy_options)?;
23986 self.write(")");
23987 }
23988
23989 if let Some(tag) = &e.tag {
23991 self.write(" ");
23992 self.write_keyword("TAG");
23993 self.write(" ");
23994 self.generate_expression(tag)?;
23995 }
23996
23997 Ok(())
23998 }
23999
24000 fn generate_space_separated_properties(&mut self, expr: &Expression) -> Result<()> {
24002 match expr {
24003 Expression::Tuple(t) => {
24004 for (i, prop) in t.expressions.iter().enumerate() {
24005 if i > 0 {
24006 self.write(" ");
24007 }
24008 self.generate_expression(prop)?;
24009 }
24010 }
24011 _ => {
24012 self.generate_expression(expr)?;
24013 }
24014 }
24015 Ok(())
24016 }
24017
24018 fn generate_alter_sort_key(&mut self, e: &AlterSortKey) -> Result<()> {
24019 self.write_keyword("ALTER");
24021 if e.compound.is_some() {
24022 self.write_space();
24023 self.write_keyword("COMPOUND");
24024 }
24025 self.write_space();
24026 self.write_keyword("SORTKEY");
24027 self.write_space();
24028 if let Some(this) = &e.this {
24029 self.generate_expression(this)?;
24030 } else if !e.expressions.is_empty() {
24031 self.write("(");
24032 for (i, expr) in e.expressions.iter().enumerate() {
24033 if i > 0 {
24034 self.write(", ");
24035 }
24036 self.generate_expression(expr)?;
24037 }
24038 self.write(")");
24039 }
24040 Ok(())
24041 }
24042
24043 fn generate_analyze(&mut self, e: &Analyze) -> Result<()> {
24044 self.write_keyword("ANALYZE");
24046 if !e.options.is_empty() {
24047 self.write_space();
24048 for (i, opt) in e.options.iter().enumerate() {
24049 if i > 0 {
24050 self.write_space();
24051 }
24052 if let Expression::Identifier(id) = opt {
24054 self.write_keyword(&id.name);
24055 } else {
24056 self.generate_expression(opt)?;
24057 }
24058 }
24059 }
24060 if let Some(kind) = &e.kind {
24061 self.write_space();
24062 self.write_keyword(kind);
24063 }
24064 if let Some(this) = &e.this {
24065 self.write_space();
24066 self.generate_expression(this)?;
24067 }
24068 if !e.columns.is_empty() {
24070 self.write("(");
24071 for (i, col) in e.columns.iter().enumerate() {
24072 if i > 0 {
24073 self.write(", ");
24074 }
24075 self.write(col);
24076 }
24077 self.write(")");
24078 }
24079 if let Some(partition) = &e.partition {
24080 self.write_space();
24081 self.generate_expression(partition)?;
24082 }
24083 if let Some(mode) = &e.mode {
24084 self.write_space();
24085 self.generate_expression(mode)?;
24086 }
24087 if let Some(expression) = &e.expression {
24088 self.write_space();
24089 self.generate_expression(expression)?;
24090 }
24091 if !e.properties.is_empty() {
24092 self.write_space();
24093 self.write_keyword(self.config.with_properties_prefix);
24094 self.write(" (");
24095 for (i, prop) in e.properties.iter().enumerate() {
24096 if i > 0 {
24097 self.write(", ");
24098 }
24099 self.generate_expression(prop)?;
24100 }
24101 self.write(")");
24102 }
24103 Ok(())
24104 }
24105
24106 fn generate_analyze_delete(&mut self, e: &AnalyzeDelete) -> Result<()> {
24107 self.write_keyword("DELETE");
24109 if let Some(kind) = &e.kind {
24110 self.write_space();
24111 self.write_keyword(kind);
24112 }
24113 self.write_space();
24114 self.write_keyword("STATISTICS");
24115 Ok(())
24116 }
24117
24118 fn generate_analyze_histogram(&mut self, e: &AnalyzeHistogram) -> Result<()> {
24119 if let Expression::Identifier(id) = e.this.as_ref() {
24122 self.write_keyword(&id.name);
24123 } else {
24124 self.generate_expression(&e.this)?;
24125 }
24126 self.write_space();
24127 self.write_keyword("HISTOGRAM ON");
24128 self.write_space();
24129 for (i, expr) in e.expressions.iter().enumerate() {
24130 if i > 0 {
24131 self.write(", ");
24132 }
24133 self.generate_expression(expr)?;
24134 }
24135 if let Some(expression) = &e.expression {
24136 self.write_space();
24137 self.generate_expression(expression)?;
24138 }
24139 if let Some(update_options) = &e.update_options {
24140 self.write_space();
24141 self.generate_expression(update_options)?;
24142 self.write_space();
24143 self.write_keyword("UPDATE");
24144 }
24145 Ok(())
24146 }
24147
24148 fn generate_analyze_list_chained_rows(&mut self, e: &AnalyzeListChainedRows) -> Result<()> {
24149 self.write_keyword("LIST CHAINED ROWS");
24151 if let Some(expression) = &e.expression {
24152 self.write_space();
24153 self.write_keyword("INTO");
24154 self.write_space();
24155 self.generate_expression(expression)?;
24156 }
24157 Ok(())
24158 }
24159
24160 fn generate_analyze_sample(&mut self, e: &AnalyzeSample) -> Result<()> {
24161 self.write_keyword("SAMPLE");
24163 self.write_space();
24164 if let Some(sample) = &e.sample {
24165 self.generate_expression(sample)?;
24166 self.write_space();
24167 }
24168 self.write_keyword(&e.kind);
24169 Ok(())
24170 }
24171
24172 fn generate_analyze_statistics(&mut self, e: &AnalyzeStatistics) -> Result<()> {
24173 self.write_keyword(&e.kind);
24175 if let Some(option) = &e.option {
24176 self.write_space();
24177 self.generate_expression(option)?;
24178 }
24179 self.write_space();
24180 self.write_keyword("STATISTICS");
24181 if let Some(this) = &e.this {
24182 self.write_space();
24183 self.generate_expression(this)?;
24184 }
24185 if !e.expressions.is_empty() {
24186 self.write_space();
24187 for (i, expr) in e.expressions.iter().enumerate() {
24188 if i > 0 {
24189 self.write(", ");
24190 }
24191 self.generate_expression(expr)?;
24192 }
24193 }
24194 Ok(())
24195 }
24196
24197 fn generate_analyze_validate(&mut self, e: &AnalyzeValidate) -> Result<()> {
24198 self.write_keyword("VALIDATE");
24200 self.write_space();
24201 self.write_keyword(&e.kind);
24202 if let Some(this) = &e.this {
24203 self.write_space();
24204 if let Expression::Identifier(id) = this.as_ref() {
24206 self.write_keyword(&id.name);
24207 } else {
24208 self.generate_expression(this)?;
24209 }
24210 }
24211 if let Some(expression) = &e.expression {
24212 self.write_space();
24213 self.write_keyword("INTO");
24214 self.write_space();
24215 self.generate_expression(expression)?;
24216 }
24217 Ok(())
24218 }
24219
24220 fn generate_analyze_with(&mut self, e: &AnalyzeWith) -> Result<()> {
24221 self.write_keyword("WITH");
24223 self.write_space();
24224 for (i, expr) in e.expressions.iter().enumerate() {
24225 if i > 0 {
24226 self.write(", ");
24227 }
24228 self.generate_expression(expr)?;
24229 }
24230 Ok(())
24231 }
24232
24233 fn generate_anonymous(&mut self, e: &Anonymous) -> Result<()> {
24234 self.generate_expression(&e.this)?;
24237 self.write("(");
24238 for (i, arg) in e.expressions.iter().enumerate() {
24239 if i > 0 {
24240 self.write(", ");
24241 }
24242 self.generate_expression(arg)?;
24243 }
24244 self.write(")");
24245 Ok(())
24246 }
24247
24248 fn generate_anonymous_agg_func(&mut self, e: &AnonymousAggFunc) -> Result<()> {
24249 self.generate_expression(&e.this)?;
24251 self.write("(");
24252 for (i, arg) in e.expressions.iter().enumerate() {
24253 if i > 0 {
24254 self.write(", ");
24255 }
24256 self.generate_expression(arg)?;
24257 }
24258 self.write(")");
24259 Ok(())
24260 }
24261
24262 fn generate_apply(&mut self, e: &Apply) -> Result<()> {
24263 self.generate_expression(&e.this)?;
24265 self.write_space();
24266 self.write_keyword("APPLY");
24267 self.write("(");
24268 self.generate_expression(&e.expression)?;
24269 self.write(")");
24270 Ok(())
24271 }
24272
24273 fn generate_approx_percentile_estimate(&mut self, e: &ApproxPercentileEstimate) -> Result<()> {
24274 self.write_keyword("APPROX_PERCENTILE_ESTIMATE");
24276 self.write("(");
24277 self.generate_expression(&e.this)?;
24278 if let Some(percentile) = &e.percentile {
24279 self.write(", ");
24280 self.generate_expression(percentile)?;
24281 }
24282 self.write(")");
24283 Ok(())
24284 }
24285
24286 fn generate_approx_quantile(&mut self, e: &ApproxQuantile) -> Result<()> {
24287 self.write_keyword("APPROX_QUANTILE");
24289 self.write("(");
24290 self.generate_expression(&e.this)?;
24291 if let Some(quantile) = &e.quantile {
24292 self.write(", ");
24293 self.generate_expression(quantile)?;
24294 }
24295 if let Some(accuracy) = &e.accuracy {
24296 self.write(", ");
24297 self.generate_expression(accuracy)?;
24298 }
24299 if let Some(weight) = &e.weight {
24300 self.write(", ");
24301 self.generate_expression(weight)?;
24302 }
24303 self.write(")");
24304 Ok(())
24305 }
24306
24307 fn generate_approx_quantiles(&mut self, e: &ApproxQuantiles) -> Result<()> {
24308 self.write_keyword("APPROX_QUANTILES");
24310 self.write("(");
24311 self.generate_expression(&e.this)?;
24312 if let Some(expression) = &e.expression {
24313 self.write(", ");
24314 self.generate_expression(expression)?;
24315 }
24316 self.write(")");
24317 Ok(())
24318 }
24319
24320 fn generate_approx_top_k(&mut self, e: &ApproxTopK) -> Result<()> {
24321 self.write_keyword("APPROX_TOP_K");
24323 self.write("(");
24324 self.generate_expression(&e.this)?;
24325 if let Some(expression) = &e.expression {
24326 self.write(", ");
24327 self.generate_expression(expression)?;
24328 }
24329 if let Some(counters) = &e.counters {
24330 self.write(", ");
24331 self.generate_expression(counters)?;
24332 }
24333 self.write(")");
24334 Ok(())
24335 }
24336
24337 fn generate_approx_top_k_accumulate(&mut self, e: &ApproxTopKAccumulate) -> Result<()> {
24338 self.write_keyword("APPROX_TOP_K_ACCUMULATE");
24340 self.write("(");
24341 self.generate_expression(&e.this)?;
24342 if let Some(expression) = &e.expression {
24343 self.write(", ");
24344 self.generate_expression(expression)?;
24345 }
24346 self.write(")");
24347 Ok(())
24348 }
24349
24350 fn generate_approx_top_k_combine(&mut self, e: &ApproxTopKCombine) -> Result<()> {
24351 self.write_keyword("APPROX_TOP_K_COMBINE");
24353 self.write("(");
24354 self.generate_expression(&e.this)?;
24355 if let Some(expression) = &e.expression {
24356 self.write(", ");
24357 self.generate_expression(expression)?;
24358 }
24359 self.write(")");
24360 Ok(())
24361 }
24362
24363 fn generate_approx_top_k_estimate(&mut self, e: &ApproxTopKEstimate) -> Result<()> {
24364 self.write_keyword("APPROX_TOP_K_ESTIMATE");
24366 self.write("(");
24367 self.generate_expression(&e.this)?;
24368 if let Some(expression) = &e.expression {
24369 self.write(", ");
24370 self.generate_expression(expression)?;
24371 }
24372 self.write(")");
24373 Ok(())
24374 }
24375
24376 fn generate_approx_top_sum(&mut self, e: &ApproxTopSum) -> Result<()> {
24377 self.write_keyword("APPROX_TOP_SUM");
24379 self.write("(");
24380 self.generate_expression(&e.this)?;
24381 self.write(", ");
24382 self.generate_expression(&e.expression)?;
24383 if let Some(count) = &e.count {
24384 self.write(", ");
24385 self.generate_expression(count)?;
24386 }
24387 self.write(")");
24388 Ok(())
24389 }
24390
24391 fn generate_arg_max(&mut self, e: &ArgMax) -> Result<()> {
24392 self.write_keyword("ARG_MAX");
24394 self.write("(");
24395 self.generate_expression(&e.this)?;
24396 self.write(", ");
24397 self.generate_expression(&e.expression)?;
24398 if let Some(count) = &e.count {
24399 self.write(", ");
24400 self.generate_expression(count)?;
24401 }
24402 self.write(")");
24403 Ok(())
24404 }
24405
24406 fn generate_arg_min(&mut self, e: &ArgMin) -> Result<()> {
24407 self.write_keyword("ARG_MIN");
24409 self.write("(");
24410 self.generate_expression(&e.this)?;
24411 self.write(", ");
24412 self.generate_expression(&e.expression)?;
24413 if let Some(count) = &e.count {
24414 self.write(", ");
24415 self.generate_expression(count)?;
24416 }
24417 self.write(")");
24418 Ok(())
24419 }
24420
24421 fn generate_array_all(&mut self, e: &ArrayAll) -> Result<()> {
24422 self.write_keyword("ARRAY_ALL");
24424 self.write("(");
24425 self.generate_expression(&e.this)?;
24426 self.write(", ");
24427 self.generate_expression(&e.expression)?;
24428 self.write(")");
24429 Ok(())
24430 }
24431
24432 fn generate_array_any(&mut self, e: &ArrayAny) -> Result<()> {
24433 self.write_keyword("ARRAY_ANY");
24435 self.write("(");
24436 self.generate_expression(&e.this)?;
24437 self.write(", ");
24438 self.generate_expression(&e.expression)?;
24439 self.write(")");
24440 Ok(())
24441 }
24442
24443 fn generate_array_construct_compact(&mut self, e: &ArrayConstructCompact) -> Result<()> {
24444 self.write_keyword("ARRAY_CONSTRUCT_COMPACT");
24446 self.write("(");
24447 for (i, expr) in e.expressions.iter().enumerate() {
24448 if i > 0 {
24449 self.write(", ");
24450 }
24451 self.generate_expression(expr)?;
24452 }
24453 self.write(")");
24454 Ok(())
24455 }
24456
24457 fn generate_array_sum(&mut self, e: &ArraySum) -> Result<()> {
24458 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
24460 self.write("arraySum");
24461 } else {
24462 self.write_keyword("ARRAY_SUM");
24463 }
24464 self.write("(");
24465 self.generate_expression(&e.this)?;
24466 if let Some(expression) = &e.expression {
24467 self.write(", ");
24468 self.generate_expression(expression)?;
24469 }
24470 self.write(")");
24471 Ok(())
24472 }
24473
24474 fn generate_at_index(&mut self, e: &AtIndex) -> Result<()> {
24475 self.generate_expression(&e.this)?;
24477 self.write_space();
24478 self.write_keyword("AT");
24479 self.write_space();
24480 self.generate_expression(&e.expression)?;
24481 Ok(())
24482 }
24483
24484 fn generate_attach(&mut self, e: &Attach) -> Result<()> {
24485 self.write_keyword("ATTACH");
24487 if e.exists {
24488 self.write_space();
24489 self.write_keyword("IF NOT EXISTS");
24490 }
24491 self.write_space();
24492 self.generate_expression(&e.this)?;
24493 if !e.expressions.is_empty() {
24494 self.write(" (");
24495 for (i, expr) in e.expressions.iter().enumerate() {
24496 if i > 0 {
24497 self.write(", ");
24498 }
24499 self.generate_expression(expr)?;
24500 }
24501 self.write(")");
24502 }
24503 Ok(())
24504 }
24505
24506 fn generate_attach_option(&mut self, e: &AttachOption) -> Result<()> {
24507 self.generate_expression(&e.this)?;
24510 if let Some(expression) = &e.expression {
24511 self.write_space();
24512 self.generate_expression(expression)?;
24513 }
24514 Ok(())
24515 }
24516
24517 fn generate_auto_increment_keyword(
24521 &mut self,
24522 col: &crate::expressions::ColumnDef,
24523 ) -> Result<()> {
24524 use crate::dialects::DialectType;
24525 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
24526 self.write_keyword("IDENTITY");
24527 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
24528 self.write("(");
24529 if let Some(ref start) = col.auto_increment_start {
24530 self.generate_expression(start)?;
24531 } else {
24532 self.write("0");
24533 }
24534 self.write(", ");
24535 if let Some(ref inc) = col.auto_increment_increment {
24536 self.generate_expression(inc)?;
24537 } else {
24538 self.write("1");
24539 }
24540 self.write(")");
24541 }
24542 } else if matches!(
24543 self.config.dialect,
24544 Some(DialectType::Snowflake) | Some(DialectType::SQLite)
24545 ) {
24546 self.write_keyword("AUTOINCREMENT");
24547 if let Some(ref start) = col.auto_increment_start {
24548 self.write_space();
24549 self.write_keyword("START");
24550 self.write_space();
24551 self.generate_expression(start)?;
24552 }
24553 if let Some(ref inc) = col.auto_increment_increment {
24554 self.write_space();
24555 self.write_keyword("INCREMENT");
24556 self.write_space();
24557 self.generate_expression(inc)?;
24558 }
24559 if let Some(order) = col.auto_increment_order {
24560 self.write_space();
24561 if order {
24562 self.write_keyword("ORDER");
24563 } else {
24564 self.write_keyword("NOORDER");
24565 }
24566 }
24567 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
24568 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
24569 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
24570 self.write(" (");
24571 let mut first = true;
24572 if let Some(ref start) = col.auto_increment_start {
24573 self.write_keyword("START WITH");
24574 self.write_space();
24575 self.generate_expression(start)?;
24576 first = false;
24577 }
24578 if let Some(ref inc) = col.auto_increment_increment {
24579 if !first {
24580 self.write_space();
24581 }
24582 self.write_keyword("INCREMENT BY");
24583 self.write_space();
24584 self.generate_expression(inc)?;
24585 }
24586 self.write(")");
24587 }
24588 } else if matches!(self.config.dialect, Some(DialectType::Databricks)) {
24589 self.write_keyword("GENERATED ALWAYS AS IDENTITY");
24590 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
24591 self.write(" (");
24592 let mut first = true;
24593 if let Some(ref start) = col.auto_increment_start {
24594 self.write_keyword("START WITH");
24595 self.write_space();
24596 self.generate_expression(start)?;
24597 first = false;
24598 }
24599 if let Some(ref inc) = col.auto_increment_increment {
24600 if !first {
24601 self.write_space();
24602 }
24603 self.write_keyword("INCREMENT BY");
24604 self.write_space();
24605 self.generate_expression(inc)?;
24606 }
24607 self.write(")");
24608 }
24609 } else if matches!(
24610 self.config.dialect,
24611 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24612 ) {
24613 self.write_keyword("IDENTITY");
24614 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
24615 self.write("(");
24616 if let Some(ref start) = col.auto_increment_start {
24617 self.generate_expression(start)?;
24618 } else {
24619 self.write("0");
24620 }
24621 self.write(", ");
24622 if let Some(ref inc) = col.auto_increment_increment {
24623 self.generate_expression(inc)?;
24624 } else {
24625 self.write("1");
24626 }
24627 self.write(")");
24628 }
24629 } else {
24630 self.write_keyword("AUTO_INCREMENT");
24631 if let Some(ref start) = col.auto_increment_start {
24632 self.write_space();
24633 self.write_keyword("START");
24634 self.write_space();
24635 self.generate_expression(start)?;
24636 }
24637 if let Some(ref inc) = col.auto_increment_increment {
24638 self.write_space();
24639 self.write_keyword("INCREMENT");
24640 self.write_space();
24641 self.generate_expression(inc)?;
24642 }
24643 if let Some(order) = col.auto_increment_order {
24644 self.write_space();
24645 if order {
24646 self.write_keyword("ORDER");
24647 } else {
24648 self.write_keyword("NOORDER");
24649 }
24650 }
24651 }
24652 Ok(())
24653 }
24654
24655 fn generate_auto_increment_property(&mut self, e: &AutoIncrementProperty) -> Result<()> {
24656 self.write_keyword("AUTO_INCREMENT");
24658 self.write("=");
24659 self.generate_expression(&e.this)?;
24660 Ok(())
24661 }
24662
24663 fn generate_auto_refresh_property(&mut self, e: &AutoRefreshProperty) -> Result<()> {
24664 self.write_keyword("AUTO_REFRESH");
24666 self.write("=");
24667 self.generate_expression(&e.this)?;
24668 Ok(())
24669 }
24670
24671 fn generate_backup_property(&mut self, e: &BackupProperty) -> Result<()> {
24672 self.write_keyword("BACKUP");
24674 self.write_space();
24675 self.generate_expression(&e.this)?;
24676 Ok(())
24677 }
24678
24679 fn generate_base64_decode_binary(&mut self, e: &Base64DecodeBinary) -> Result<()> {
24680 self.write_keyword("BASE64_DECODE_BINARY");
24682 self.write("(");
24683 self.generate_expression(&e.this)?;
24684 if let Some(alphabet) = &e.alphabet {
24685 self.write(", ");
24686 self.generate_expression(alphabet)?;
24687 }
24688 self.write(")");
24689 Ok(())
24690 }
24691
24692 fn generate_base64_decode_string(&mut self, e: &Base64DecodeString) -> Result<()> {
24693 self.write_keyword("BASE64_DECODE_STRING");
24695 self.write("(");
24696 self.generate_expression(&e.this)?;
24697 if let Some(alphabet) = &e.alphabet {
24698 self.write(", ");
24699 self.generate_expression(alphabet)?;
24700 }
24701 self.write(")");
24702 Ok(())
24703 }
24704
24705 fn generate_base64_encode(&mut self, e: &Base64Encode) -> Result<()> {
24706 self.write_keyword("BASE64_ENCODE");
24708 self.write("(");
24709 self.generate_expression(&e.this)?;
24710 if let Some(max_line_length) = &e.max_line_length {
24711 self.write(", ");
24712 self.generate_expression(max_line_length)?;
24713 }
24714 if let Some(alphabet) = &e.alphabet {
24715 self.write(", ");
24716 self.generate_expression(alphabet)?;
24717 }
24718 self.write(")");
24719 Ok(())
24720 }
24721
24722 fn generate_block_compression_property(&mut self, e: &BlockCompressionProperty) -> Result<()> {
24723 self.write_keyword("BLOCKCOMPRESSION");
24725 self.write("=");
24726 if let Some(autotemp) = &e.autotemp {
24727 self.write_keyword("AUTOTEMP");
24728 self.write("(");
24729 self.generate_expression(autotemp)?;
24730 self.write(")");
24731 }
24732 if let Some(always) = &e.always {
24733 self.generate_expression(always)?;
24734 }
24735 if let Some(default) = &e.default {
24736 self.generate_expression(default)?;
24737 }
24738 if let Some(manual) = &e.manual {
24739 self.generate_expression(manual)?;
24740 }
24741 if let Some(never) = &e.never {
24742 self.generate_expression(never)?;
24743 }
24744 Ok(())
24745 }
24746
24747 fn generate_booland(&mut self, e: &Booland) -> Result<()> {
24748 self.write("((");
24750 self.generate_expression(&e.this)?;
24751 self.write(") ");
24752 self.write_keyword("AND");
24753 self.write(" (");
24754 self.generate_expression(&e.expression)?;
24755 self.write("))");
24756 Ok(())
24757 }
24758
24759 fn generate_boolor(&mut self, e: &Boolor) -> Result<()> {
24760 self.write("((");
24762 self.generate_expression(&e.this)?;
24763 self.write(") ");
24764 self.write_keyword("OR");
24765 self.write(" (");
24766 self.generate_expression(&e.expression)?;
24767 self.write("))");
24768 Ok(())
24769 }
24770
24771 fn generate_build_property(&mut self, e: &BuildProperty) -> Result<()> {
24772 self.write_keyword("BUILD");
24774 self.write_space();
24775 self.generate_expression(&e.this)?;
24776 Ok(())
24777 }
24778
24779 fn generate_byte_string(&mut self, e: &ByteString) -> Result<()> {
24780 self.generate_expression(&e.this)?;
24782 Ok(())
24783 }
24784
24785 fn generate_case_specific_column_constraint(
24786 &mut self,
24787 e: &CaseSpecificColumnConstraint,
24788 ) -> Result<()> {
24789 if e.not_.is_some() {
24791 self.write_keyword("NOT");
24792 self.write_space();
24793 }
24794 self.write_keyword("CASESPECIFIC");
24795 Ok(())
24796 }
24797
24798 fn generate_cast_to_str_type(&mut self, e: &CastToStrType) -> Result<()> {
24799 self.write_keyword("CAST");
24801 self.write("(");
24802 self.generate_expression(&e.this)?;
24803 if self.config.dialect == Some(DialectType::ClickHouse) {
24804 self.write(", ");
24806 } else {
24807 self.write_space();
24808 self.write_keyword("AS");
24809 self.write_space();
24810 }
24811 if let Some(to) = &e.to {
24812 self.generate_expression(to)?;
24813 }
24814 self.write(")");
24815 Ok(())
24816 }
24817
24818 fn generate_changes(&mut self, e: &Changes) -> Result<()> {
24819 self.write_keyword("CHANGES");
24822 self.write(" (");
24823 if let Some(information) = &e.information {
24824 self.write_keyword("INFORMATION");
24825 self.write(" => ");
24826 self.generate_expression(information)?;
24827 }
24828 self.write(")");
24829 if let Some(at_before) = &e.at_before {
24831 self.write(" ");
24832 self.generate_expression(at_before)?;
24833 }
24834 if let Some(end) = &e.end {
24835 self.write(" ");
24836 self.generate_expression(end)?;
24837 }
24838 Ok(())
24839 }
24840
24841 fn generate_character_set_column_constraint(
24842 &mut self,
24843 e: &CharacterSetColumnConstraint,
24844 ) -> Result<()> {
24845 self.write_keyword("CHARACTER SET");
24847 self.write_space();
24848 self.generate_expression(&e.this)?;
24849 Ok(())
24850 }
24851
24852 fn generate_character_set_property(&mut self, e: &CharacterSetProperty) -> Result<()> {
24853 if e.default.is_some() {
24855 self.write_keyword("DEFAULT");
24856 self.write_space();
24857 }
24858 self.write_keyword("CHARACTER SET");
24859 self.write("=");
24860 self.generate_expression(&e.this)?;
24861 Ok(())
24862 }
24863
24864 fn generate_check_column_constraint(&mut self, e: &CheckColumnConstraint) -> Result<()> {
24865 self.write_keyword("CHECK");
24867 self.write(" (");
24868 self.generate_expression(&e.this)?;
24869 self.write(")");
24870 if e.enforced.is_some() {
24871 self.write_space();
24872 self.write_keyword("ENFORCED");
24873 }
24874 Ok(())
24875 }
24876
24877 fn generate_check_json(&mut self, e: &CheckJson) -> Result<()> {
24878 self.write_keyword("CHECK_JSON");
24880 self.write("(");
24881 self.generate_expression(&e.this)?;
24882 self.write(")");
24883 Ok(())
24884 }
24885
24886 fn generate_check_xml(&mut self, e: &CheckXml) -> Result<()> {
24887 self.write_keyword("CHECK_XML");
24889 self.write("(");
24890 self.generate_expression(&e.this)?;
24891 self.write(")");
24892 Ok(())
24893 }
24894
24895 fn generate_checksum_property(&mut self, e: &ChecksumProperty) -> Result<()> {
24896 self.write_keyword("CHECKSUM");
24898 self.write("=");
24899 if e.on.is_some() {
24900 self.write_keyword("ON");
24901 } else if e.default.is_some() {
24902 self.write_keyword("DEFAULT");
24903 } else {
24904 self.write_keyword("OFF");
24905 }
24906 Ok(())
24907 }
24908
24909 fn generate_clone(&mut self, e: &Clone) -> Result<()> {
24910 if e.shallow.is_some() {
24912 self.write_keyword("SHALLOW");
24913 self.write_space();
24914 }
24915 if e.copy.is_some() {
24916 self.write_keyword("COPY");
24917 } else {
24918 self.write_keyword("CLONE");
24919 }
24920 self.write_space();
24921 self.generate_expression(&e.this)?;
24922 Ok(())
24923 }
24924
24925 fn generate_cluster_by(&mut self, e: &ClusterBy) -> Result<()> {
24926 self.write_keyword("CLUSTER BY");
24928 self.write(" (");
24929 for (i, ord) in e.expressions.iter().enumerate() {
24930 if i > 0 {
24931 self.write(", ");
24932 }
24933 self.generate_ordered(ord)?;
24934 }
24935 self.write(")");
24936 Ok(())
24937 }
24938
24939 fn generate_cluster_by_columns_property(&mut self, e: &ClusterByColumnsProperty) -> Result<()> {
24940 self.write_keyword("CLUSTER BY");
24942 self.write_space();
24943 for (i, col) in e.columns.iter().enumerate() {
24944 if i > 0 {
24945 self.write(", ");
24946 }
24947 self.generate_identifier(col)?;
24948 }
24949 Ok(())
24950 }
24951
24952 fn generate_clustered_by_property(&mut self, e: &ClusteredByProperty) -> Result<()> {
24953 self.write_keyword("CLUSTERED BY");
24955 self.write(" (");
24956 for (i, expr) in e.expressions.iter().enumerate() {
24957 if i > 0 {
24958 self.write(", ");
24959 }
24960 self.generate_expression(expr)?;
24961 }
24962 self.write(")");
24963 if let Some(sorted_by) = &e.sorted_by {
24964 self.write_space();
24965 self.write_keyword("SORTED BY");
24966 self.write(" (");
24967 if let Expression::Tuple(t) = sorted_by.as_ref() {
24969 for (i, expr) in t.expressions.iter().enumerate() {
24970 if i > 0 {
24971 self.write(", ");
24972 }
24973 self.generate_expression(expr)?;
24974 }
24975 } else {
24976 self.generate_expression(sorted_by)?;
24977 }
24978 self.write(")");
24979 }
24980 if let Some(buckets) = &e.buckets {
24981 self.write_space();
24982 self.write_keyword("INTO");
24983 self.write_space();
24984 self.generate_expression(buckets)?;
24985 self.write_space();
24986 self.write_keyword("BUCKETS");
24987 }
24988 Ok(())
24989 }
24990
24991 fn generate_collate_property(&mut self, e: &CollateProperty) -> Result<()> {
24992 if e.default.is_some() {
24996 self.write_keyword("DEFAULT");
24997 self.write_space();
24998 }
24999 self.write_keyword("COLLATE");
25000 match self.config.dialect {
25002 Some(DialectType::BigQuery) => self.write_space(),
25003 _ => self.write("="),
25004 }
25005 self.generate_expression(&e.this)?;
25006 Ok(())
25007 }
25008
25009 fn generate_column_constraint(&mut self, e: &ColumnConstraint) -> Result<()> {
25010 match e {
25012 ColumnConstraint::NotNull => {
25013 self.write_keyword("NOT NULL");
25014 }
25015 ColumnConstraint::Null => {
25016 self.write_keyword("NULL");
25017 }
25018 ColumnConstraint::Unique => {
25019 self.write_keyword("UNIQUE");
25020 }
25021 ColumnConstraint::PrimaryKey => {
25022 self.write_keyword("PRIMARY KEY");
25023 }
25024 ColumnConstraint::Default(expr) => {
25025 self.write_keyword("DEFAULT");
25026 self.write_space();
25027 self.generate_expression(expr)?;
25028 }
25029 ColumnConstraint::Check(expr) => {
25030 self.write_keyword("CHECK");
25031 self.write(" (");
25032 self.generate_expression(expr)?;
25033 self.write(")");
25034 }
25035 ColumnConstraint::References(fk_ref) => {
25036 if fk_ref.has_foreign_key_keywords {
25037 self.write_keyword("FOREIGN KEY");
25038 self.write_space();
25039 }
25040 self.write_keyword("REFERENCES");
25041 self.write_space();
25042 self.generate_table(&fk_ref.table)?;
25043 if !fk_ref.columns.is_empty() {
25044 self.write(" (");
25045 for (i, col) in fk_ref.columns.iter().enumerate() {
25046 if i > 0 {
25047 self.write(", ");
25048 }
25049 self.generate_identifier(col)?;
25050 }
25051 self.write(")");
25052 }
25053 }
25054 ColumnConstraint::GeneratedAsIdentity(gen) => {
25055 self.write_keyword("GENERATED");
25056 self.write_space();
25057 if gen.always {
25058 self.write_keyword("ALWAYS");
25059 } else {
25060 self.write_keyword("BY DEFAULT");
25061 if gen.on_null {
25062 self.write_space();
25063 self.write_keyword("ON NULL");
25064 }
25065 }
25066 self.write_space();
25067 self.write_keyword("AS IDENTITY");
25068 }
25069 ColumnConstraint::Collate(collation) => {
25070 self.write_keyword("COLLATE");
25071 self.write_space();
25072 self.generate_identifier(collation)?;
25073 }
25074 ColumnConstraint::Comment(comment) => {
25075 self.write_keyword("COMMENT");
25076 self.write(" '");
25077 self.write(comment);
25078 self.write("'");
25079 }
25080 ColumnConstraint::ComputedColumn(cc) => {
25081 self.generate_computed_column_inline(cc)?;
25082 }
25083 ColumnConstraint::GeneratedAsRow(gar) => {
25084 self.generate_generated_as_row_inline(gar)?;
25085 }
25086 ColumnConstraint::Tags(tags) => {
25087 self.write_keyword("TAG");
25088 self.write(" (");
25089 for (i, expr) in tags.expressions.iter().enumerate() {
25090 if i > 0 {
25091 self.write(", ");
25092 }
25093 self.generate_expression(expr)?;
25094 }
25095 self.write(")");
25096 }
25097 ColumnConstraint::Path(path_expr) => {
25098 self.write_keyword("PATH");
25099 self.write_space();
25100 self.generate_expression(path_expr)?;
25101 }
25102 }
25103 Ok(())
25104 }
25105
25106 fn generate_column_position(&mut self, e: &ColumnPosition) -> Result<()> {
25107 match e {
25109 ColumnPosition::First => {
25110 self.write_keyword("FIRST");
25111 }
25112 ColumnPosition::After(ident) => {
25113 self.write_keyword("AFTER");
25114 self.write_space();
25115 self.generate_identifier(ident)?;
25116 }
25117 }
25118 Ok(())
25119 }
25120
25121 fn generate_column_prefix(&mut self, e: &ColumnPrefix) -> Result<()> {
25122 self.generate_expression(&e.this)?;
25124 self.write("(");
25125 self.generate_expression(&e.expression)?;
25126 self.write(")");
25127 Ok(())
25128 }
25129
25130 fn generate_columns(&mut self, e: &Columns) -> Result<()> {
25131 if let Some(ref unpack) = e.unpack {
25134 if let Expression::Boolean(b) = unpack.as_ref() {
25135 if b.value {
25136 self.write("*");
25137 }
25138 }
25139 }
25140 self.write_keyword("COLUMNS");
25141 self.write("(");
25142 self.generate_expression(&e.this)?;
25143 self.write(")");
25144 Ok(())
25145 }
25146
25147 fn generate_combined_agg_func(&mut self, e: &CombinedAggFunc) -> Result<()> {
25148 self.generate_expression(&e.this)?;
25150 self.write("(");
25151 for (i, expr) in e.expressions.iter().enumerate() {
25152 if i > 0 {
25153 self.write(", ");
25154 }
25155 self.generate_expression(expr)?;
25156 }
25157 self.write(")");
25158 Ok(())
25159 }
25160
25161 fn generate_combined_parameterized_agg(&mut self, e: &CombinedParameterizedAgg) -> Result<()> {
25162 self.generate_expression(&e.this)?;
25164 self.write("(");
25165 for (i, param) in e.params.iter().enumerate() {
25166 if i > 0 {
25167 self.write(", ");
25168 }
25169 self.generate_expression(param)?;
25170 }
25171 self.write(")(");
25172 for (i, expr) in e.expressions.iter().enumerate() {
25173 if i > 0 {
25174 self.write(", ");
25175 }
25176 self.generate_expression(expr)?;
25177 }
25178 self.write(")");
25179 Ok(())
25180 }
25181
25182 fn generate_commit(&mut self, e: &Commit) -> Result<()> {
25183 self.write_keyword("COMMIT");
25185
25186 if e.this.is_none()
25188 && matches!(
25189 self.config.dialect,
25190 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25191 )
25192 {
25193 self.write_space();
25194 self.write_keyword("TRANSACTION");
25195 }
25196
25197 if let Some(this) = &e.this {
25199 let is_transaction_marker = matches!(
25201 this.as_ref(),
25202 Expression::Identifier(id) if id.name == "TRANSACTION"
25203 );
25204
25205 self.write_space();
25206 self.write_keyword("TRANSACTION");
25207
25208 if !is_transaction_marker {
25210 self.write_space();
25211 self.generate_expression(this)?;
25212 }
25213 }
25214
25215 if let Some(durability) = &e.durability {
25217 self.write_space();
25218 self.write_keyword("WITH");
25219 self.write(" (");
25220 self.write_keyword("DELAYED_DURABILITY");
25221 self.write(" = ");
25222 if let Expression::Boolean(BooleanLiteral { value: true }) = durability.as_ref() {
25223 self.write_keyword("ON");
25224 } else {
25225 self.write_keyword("OFF");
25226 }
25227 self.write(")");
25228 }
25229
25230 if let Some(chain) = &e.chain {
25232 self.write_space();
25233 if let Expression::Boolean(BooleanLiteral { value: false }) = chain.as_ref() {
25234 self.write_keyword("AND NO CHAIN");
25235 } else {
25236 self.write_keyword("AND CHAIN");
25237 }
25238 }
25239 Ok(())
25240 }
25241
25242 fn generate_comprehension(&mut self, e: &Comprehension) -> Result<()> {
25243 self.write("[");
25245 self.generate_expression(&e.this)?;
25246 self.write_space();
25247 self.write_keyword("FOR");
25248 self.write_space();
25249 self.generate_expression(&e.expression)?;
25250 if let Some(pos) = &e.position {
25252 self.write(", ");
25253 self.generate_expression(pos)?;
25254 }
25255 if let Some(iterator) = &e.iterator {
25256 self.write_space();
25257 self.write_keyword("IN");
25258 self.write_space();
25259 self.generate_expression(iterator)?;
25260 }
25261 if let Some(condition) = &e.condition {
25262 self.write_space();
25263 self.write_keyword("IF");
25264 self.write_space();
25265 self.generate_expression(condition)?;
25266 }
25267 self.write("]");
25268 Ok(())
25269 }
25270
25271 fn generate_compress(&mut self, e: &Compress) -> Result<()> {
25272 self.write_keyword("COMPRESS");
25274 self.write("(");
25275 self.generate_expression(&e.this)?;
25276 if let Some(method) = &e.method {
25277 self.write(", '");
25278 self.write(method);
25279 self.write("'");
25280 }
25281 self.write(")");
25282 Ok(())
25283 }
25284
25285 fn generate_compress_column_constraint(&mut self, e: &CompressColumnConstraint) -> Result<()> {
25286 self.write_keyword("COMPRESS");
25288 if let Some(this) = &e.this {
25289 self.write_space();
25290 self.generate_expression(this)?;
25291 }
25292 Ok(())
25293 }
25294
25295 fn generate_computed_column_constraint(&mut self, e: &ComputedColumnConstraint) -> Result<()> {
25296 self.write_keyword("AS");
25298 self.write_space();
25299 self.generate_expression(&e.this)?;
25300 if e.not_null.is_some() {
25301 self.write_space();
25302 self.write_keyword("PERSISTED NOT NULL");
25303 } else if e.persisted.is_some() {
25304 self.write_space();
25305 self.write_keyword("PERSISTED");
25306 }
25307 Ok(())
25308 }
25309
25310 fn generate_computed_column_inline(&mut self, cc: &ComputedColumn) -> Result<()> {
25314 let computed_expr = if matches!(
25315 self.config.dialect,
25316 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25317 ) {
25318 match &*cc.expression {
25319 Expression::Year(y) if !matches!(&y.this, Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
25320 {
25321 let wrapped = Expression::Cast(Box::new(Cast {
25322 this: y.this.clone(),
25323 to: DataType::Date,
25324 trailing_comments: Vec::new(),
25325 double_colon_syntax: false,
25326 format: None,
25327 default: None,
25328 inferred_type: None,
25329 }));
25330 Expression::Year(Box::new(UnaryFunc::new(wrapped)))
25331 }
25332 Expression::Function(f)
25333 if f.name.eq_ignore_ascii_case("YEAR")
25334 && f.args.len() == 1
25335 && !matches!(&f.args[0], Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
25336 {
25337 let wrapped = Expression::Cast(Box::new(Cast {
25338 this: f.args[0].clone(),
25339 to: DataType::Date,
25340 trailing_comments: Vec::new(),
25341 double_colon_syntax: false,
25342 format: None,
25343 default: None,
25344 inferred_type: None,
25345 }));
25346 Expression::Function(Box::new(Function::new("YEAR".to_string(), vec![wrapped])))
25347 }
25348 _ => *cc.expression.clone(),
25349 }
25350 } else {
25351 *cc.expression.clone()
25352 };
25353
25354 match cc.persistence_kind.as_deref() {
25355 Some("STORED") | Some("VIRTUAL") => {
25356 self.write_keyword("GENERATED ALWAYS AS");
25358 self.write(" (");
25359 self.generate_expression(&computed_expr)?;
25360 self.write(")");
25361 self.write_space();
25362 if cc.persisted {
25363 self.write_keyword("STORED");
25364 } else {
25365 self.write_keyword("VIRTUAL");
25366 }
25367 }
25368 Some("PERSISTED") => {
25369 self.write_keyword("AS");
25371 self.write(" (");
25372 self.generate_expression(&computed_expr)?;
25373 self.write(")");
25374 self.write_space();
25375 self.write_keyword("PERSISTED");
25376 if let Some(ref dt) = cc.data_type {
25378 self.write_space();
25379 self.generate_data_type(dt)?;
25380 }
25381 if cc.not_null {
25382 self.write_space();
25383 self.write_keyword("NOT NULL");
25384 }
25385 }
25386 _ => {
25387 if matches!(
25390 self.config.dialect,
25391 Some(DialectType::Spark)
25392 | Some(DialectType::Databricks)
25393 | Some(DialectType::Hive)
25394 ) {
25395 self.write_keyword("GENERATED ALWAYS AS");
25396 self.write(" (");
25397 self.generate_expression(&computed_expr)?;
25398 self.write(")");
25399 } else if matches!(
25400 self.config.dialect,
25401 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25402 ) {
25403 self.write_keyword("AS");
25404 let omit_parens = matches!(computed_expr, Expression::Year(_))
25405 || matches!(&computed_expr, Expression::Function(f) if f.name.eq_ignore_ascii_case("YEAR"));
25406 if omit_parens {
25407 self.write_space();
25408 self.generate_expression(&computed_expr)?;
25409 } else {
25410 self.write(" (");
25411 self.generate_expression(&computed_expr)?;
25412 self.write(")");
25413 }
25414 } else {
25415 self.write_keyword("AS");
25416 self.write(" (");
25417 self.generate_expression(&computed_expr)?;
25418 self.write(")");
25419 }
25420 }
25421 }
25422 Ok(())
25423 }
25424
25425 fn generate_generated_as_row_inline(&mut self, gar: &GeneratedAsRow) -> Result<()> {
25428 self.write_keyword("GENERATED ALWAYS AS ROW ");
25429 if gar.start {
25430 self.write_keyword("START");
25431 } else {
25432 self.write_keyword("END");
25433 }
25434 if gar.hidden {
25435 self.write_space();
25436 self.write_keyword("HIDDEN");
25437 }
25438 Ok(())
25439 }
25440
25441 fn generate_system_versioning_content(
25443 &mut self,
25444 e: &WithSystemVersioningProperty,
25445 ) -> Result<()> {
25446 let mut parts = Vec::new();
25447
25448 if let Some(this) = &e.this {
25449 let mut s = String::from("HISTORY_TABLE=");
25450 let mut gen = Generator::new();
25451 gen.config = self.config.clone();
25452 gen.generate_expression(this)?;
25453 s.push_str(&gen.output);
25454 parts.push(s);
25455 }
25456
25457 if let Some(data_consistency) = &e.data_consistency {
25458 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
25459 let mut gen = Generator::new();
25460 gen.config = self.config.clone();
25461 gen.generate_expression(data_consistency)?;
25462 s.push_str(&gen.output);
25463 parts.push(s);
25464 }
25465
25466 if let Some(retention_period) = &e.retention_period {
25467 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
25468 let mut gen = Generator::new();
25469 gen.config = self.config.clone();
25470 gen.generate_expression(retention_period)?;
25471 s.push_str(&gen.output);
25472 parts.push(s);
25473 }
25474
25475 self.write_keyword("SYSTEM_VERSIONING");
25476 self.write("=");
25477
25478 if !parts.is_empty() {
25479 self.write_keyword("ON");
25480 self.write("(");
25481 self.write(&parts.join(", "));
25482 self.write(")");
25483 } else if e.on.is_some() {
25484 self.write_keyword("ON");
25485 } else {
25486 self.write_keyword("OFF");
25487 }
25488
25489 Ok(())
25490 }
25491
25492 fn generate_conditional_insert(&mut self, e: &ConditionalInsert) -> Result<()> {
25493 if e.else_.is_some() {
25496 self.write_keyword("ELSE");
25497 self.write_space();
25498 } else if let Some(expression) = &e.expression {
25499 self.write_keyword("WHEN");
25500 self.write_space();
25501 self.generate_expression(expression)?;
25502 self.write_space();
25503 self.write_keyword("THEN");
25504 self.write_space();
25505 }
25506
25507 if let Expression::Insert(insert) = e.this.as_ref() {
25510 self.write_keyword("INTO");
25511 self.write_space();
25512 self.generate_table(&insert.table)?;
25513
25514 if !insert.columns.is_empty() {
25516 self.write(" (");
25517 for (i, col) in insert.columns.iter().enumerate() {
25518 if i > 0 {
25519 self.write(", ");
25520 }
25521 self.generate_identifier(col)?;
25522 }
25523 self.write(")");
25524 }
25525
25526 if !insert.values.is_empty() {
25528 self.write_space();
25529 self.write_keyword("VALUES");
25530 for (row_idx, row) in insert.values.iter().enumerate() {
25531 if row_idx > 0 {
25532 self.write(", ");
25533 }
25534 self.write(" (");
25535 for (i, val) in row.iter().enumerate() {
25536 if i > 0 {
25537 self.write(", ");
25538 }
25539 self.generate_expression(val)?;
25540 }
25541 self.write(")");
25542 }
25543 }
25544 } else {
25545 self.generate_expression(&e.this)?;
25547 }
25548 Ok(())
25549 }
25550
25551 fn generate_constraint(&mut self, e: &Constraint) -> Result<()> {
25552 self.write_keyword("CONSTRAINT");
25554 self.write_space();
25555 self.generate_expression(&e.this)?;
25556 if !e.expressions.is_empty() {
25557 self.write_space();
25558 for (i, expr) in e.expressions.iter().enumerate() {
25559 if i > 0 {
25560 self.write_space();
25561 }
25562 self.generate_expression(expr)?;
25563 }
25564 }
25565 Ok(())
25566 }
25567
25568 fn generate_convert_timezone(&mut self, e: &ConvertTimezone) -> Result<()> {
25569 self.write_keyword("CONVERT_TIMEZONE");
25571 self.write("(");
25572 let mut first = true;
25573 if let Some(source_tz) = &e.source_tz {
25574 self.generate_expression(source_tz)?;
25575 first = false;
25576 }
25577 if let Some(target_tz) = &e.target_tz {
25578 if !first {
25579 self.write(", ");
25580 }
25581 self.generate_expression(target_tz)?;
25582 first = false;
25583 }
25584 if let Some(timestamp) = &e.timestamp {
25585 if !first {
25586 self.write(", ");
25587 }
25588 self.generate_expression(timestamp)?;
25589 }
25590 self.write(")");
25591 Ok(())
25592 }
25593
25594 fn generate_convert_to_charset(&mut self, e: &ConvertToCharset) -> Result<()> {
25595 self.write_keyword("CONVERT");
25597 self.write("(");
25598 self.generate_expression(&e.this)?;
25599 if let Some(dest) = &e.dest {
25600 self.write_space();
25601 self.write_keyword("USING");
25602 self.write_space();
25603 self.generate_expression(dest)?;
25604 }
25605 self.write(")");
25606 Ok(())
25607 }
25608
25609 fn generate_copy(&mut self, e: &CopyStmt) -> Result<()> {
25610 self.write_keyword("COPY");
25611 if e.is_into {
25612 self.write_space();
25613 self.write_keyword("INTO");
25614 }
25615 self.write_space();
25616
25617 if let Expression::Literal(Literal::String(s)) = &e.this {
25619 if s.starts_with('@') {
25620 self.write(s);
25621 } else {
25622 self.generate_expression(&e.this)?;
25623 }
25624 } else {
25625 self.generate_expression(&e.this)?;
25626 }
25627
25628 if e.kind {
25630 if self.config.pretty {
25632 self.write_newline();
25633 } else {
25634 self.write_space();
25635 }
25636 self.write_keyword("FROM");
25637 self.write_space();
25638 } else if !e.files.is_empty() {
25639 if self.config.pretty {
25641 self.write_newline();
25642 } else {
25643 self.write_space();
25644 }
25645 self.write_keyword("TO");
25646 self.write_space();
25647 }
25648
25649 for (i, file) in e.files.iter().enumerate() {
25651 if i > 0 {
25652 self.write_space();
25653 }
25654 if let Expression::Literal(Literal::String(s)) = file {
25656 if s.starts_with('@') {
25657 self.write(s);
25658 } else {
25659 self.generate_expression(file)?;
25660 }
25661 } else if let Expression::Identifier(id) = file {
25662 if id.quoted {
25664 self.write("`");
25665 self.write(&id.name);
25666 self.write("`");
25667 } else {
25668 self.generate_expression(file)?;
25669 }
25670 } else {
25671 self.generate_expression(file)?;
25672 }
25673 }
25674
25675 if !e.with_wrapped {
25677 if let Some(ref creds) = e.credentials {
25678 if let Some(ref storage) = creds.storage {
25679 if self.config.pretty {
25680 self.write_newline();
25681 } else {
25682 self.write_space();
25683 }
25684 self.write_keyword("STORAGE_INTEGRATION");
25685 self.write(" = ");
25686 self.write(storage);
25687 }
25688 if creds.credentials.is_empty() {
25689 if self.config.pretty {
25691 self.write_newline();
25692 } else {
25693 self.write_space();
25694 }
25695 self.write_keyword("CREDENTIALS");
25696 self.write(" = ()");
25697 } else {
25698 if self.config.pretty {
25699 self.write_newline();
25700 } else {
25701 self.write_space();
25702 }
25703 self.write_keyword("CREDENTIALS");
25704 if creds.credentials.len() == 1 && creds.credentials[0].0.is_empty() {
25707 self.write(" '");
25709 self.write(&creds.credentials[0].1);
25710 self.write("'");
25711 } else {
25712 self.write(" = (");
25714 for (i, (k, v)) in creds.credentials.iter().enumerate() {
25715 if i > 0 {
25716 self.write_space();
25717 }
25718 self.write(k);
25719 self.write("='");
25720 self.write(v);
25721 self.write("'");
25722 }
25723 self.write(")");
25724 }
25725 }
25726 if let Some(ref encryption) = creds.encryption {
25727 self.write_space();
25728 self.write_keyword("ENCRYPTION");
25729 self.write(" = ");
25730 self.write(encryption);
25731 }
25732 }
25733 }
25734
25735 if !e.params.is_empty() {
25737 if e.with_wrapped {
25738 self.write_space();
25740 self.write_keyword("WITH");
25741 self.write(" (");
25742 for (i, param) in e.params.iter().enumerate() {
25743 if i > 0 {
25744 self.write(", ");
25745 }
25746 self.generate_copy_param_with_format(param)?;
25747 }
25748 self.write(")");
25749 } else {
25750 for param in &e.params {
25754 if self.config.pretty {
25755 self.write_newline();
25756 } else {
25757 self.write_space();
25758 }
25759 self.write(¶m.name);
25761 if let Some(ref value) = param.value {
25762 if param.eq {
25764 self.write(" = ");
25765 } else {
25766 self.write(" ");
25767 }
25768 if !param.values.is_empty() {
25769 self.write("(");
25770 for (i, v) in param.values.iter().enumerate() {
25771 if i > 0 {
25772 self.write_space();
25773 }
25774 self.generate_copy_nested_param(v)?;
25775 }
25776 self.write(")");
25777 } else {
25778 self.generate_copy_param_value(value)?;
25780 }
25781 } else if !param.values.is_empty() {
25782 if param.eq {
25784 self.write(" = (");
25785 } else {
25786 self.write(" (");
25787 }
25788 let is_key_value_pairs = param
25793 .values
25794 .first()
25795 .map_or(false, |v| matches!(v, Expression::Eq(_)));
25796 let sep = if is_key_value_pairs && param.eq {
25797 " "
25798 } else {
25799 ", "
25800 };
25801 for (i, v) in param.values.iter().enumerate() {
25802 if i > 0 {
25803 self.write(sep);
25804 }
25805 self.generate_copy_nested_param(v)?;
25806 }
25807 self.write(")");
25808 }
25809 }
25810 }
25811 }
25812
25813 Ok(())
25814 }
25815
25816 fn generate_copy_param_with_format(&mut self, param: &CopyParameter) -> Result<()> {
25819 self.write_keyword(¶m.name);
25820 if !param.values.is_empty() {
25821 self.write(" = (");
25823 for (i, v) in param.values.iter().enumerate() {
25824 if i > 0 {
25825 self.write(", ");
25826 }
25827 self.generate_copy_nested_param(v)?;
25828 }
25829 self.write(")");
25830 } else if let Some(ref value) = param.value {
25831 if param.eq {
25832 self.write(" = ");
25833 } else {
25834 self.write(" ");
25835 }
25836 self.generate_expression(value)?;
25837 }
25838 Ok(())
25839 }
25840
25841 fn generate_copy_nested_param(&mut self, expr: &Expression) -> Result<()> {
25843 match expr {
25844 Expression::Eq(eq) => {
25845 match &eq.left {
25847 Expression::Column(c) => self.write(&c.name.name),
25848 _ => self.generate_expression(&eq.left)?,
25849 }
25850 self.write("=");
25851 match &eq.right {
25853 Expression::Literal(Literal::String(s)) => {
25854 self.write("'");
25855 self.write(s);
25856 self.write("'");
25857 }
25858 Expression::Tuple(t) => {
25859 self.write("(");
25861 if self.config.pretty {
25862 self.write_newline();
25863 self.indent_level += 1;
25864 for (i, item) in t.expressions.iter().enumerate() {
25865 if i > 0 {
25866 self.write(", ");
25867 }
25868 self.write_indent();
25869 self.generate_expression(item)?;
25870 }
25871 self.write_newline();
25872 self.indent_level -= 1;
25873 } else {
25874 for (i, item) in t.expressions.iter().enumerate() {
25875 if i > 0 {
25876 self.write(", ");
25877 }
25878 self.generate_expression(item)?;
25879 }
25880 }
25881 self.write(")");
25882 }
25883 _ => self.generate_expression(&eq.right)?,
25884 }
25885 Ok(())
25886 }
25887 Expression::Column(c) => {
25888 self.write(&c.name.name);
25890 Ok(())
25891 }
25892 _ => self.generate_expression(expr),
25893 }
25894 }
25895
25896 fn generate_copy_param_value(&mut self, expr: &Expression) -> Result<()> {
25899 match expr {
25900 Expression::Column(c) => {
25901 if c.name.quoted {
25903 self.write("\"");
25904 self.write(&c.name.name);
25905 self.write("\"");
25906 } else {
25907 self.write(&c.name.name);
25908 }
25909 Ok(())
25910 }
25911 Expression::Identifier(id) => {
25912 if id.quoted {
25914 self.write("\"");
25915 self.write(&id.name);
25916 self.write("\"");
25917 } else {
25918 self.write(&id.name);
25919 }
25920 Ok(())
25921 }
25922 Expression::Literal(Literal::String(s)) => {
25923 self.write("'");
25925 self.write(s);
25926 self.write("'");
25927 Ok(())
25928 }
25929 _ => self.generate_expression(expr),
25930 }
25931 }
25932
25933 fn generate_copy_parameter(&mut self, e: &CopyParameter) -> Result<()> {
25934 self.write_keyword(&e.name);
25935 if let Some(ref value) = e.value {
25936 if e.eq {
25937 self.write(" = ");
25938 } else {
25939 self.write(" ");
25940 }
25941 self.generate_expression(value)?;
25942 }
25943 if !e.values.is_empty() {
25944 if e.eq {
25945 self.write(" = ");
25946 } else {
25947 self.write(" ");
25948 }
25949 self.write("(");
25950 for (i, v) in e.values.iter().enumerate() {
25951 if i > 0 {
25952 self.write(", ");
25953 }
25954 self.generate_expression(v)?;
25955 }
25956 self.write(")");
25957 }
25958 Ok(())
25959 }
25960
25961 fn generate_corr(&mut self, e: &Corr) -> Result<()> {
25962 self.write_keyword("CORR");
25964 self.write("(");
25965 self.generate_expression(&e.this)?;
25966 self.write(", ");
25967 self.generate_expression(&e.expression)?;
25968 self.write(")");
25969 Ok(())
25970 }
25971
25972 fn generate_cosine_distance(&mut self, e: &CosineDistance) -> Result<()> {
25973 self.write_keyword("COSINE_DISTANCE");
25975 self.write("(");
25976 self.generate_expression(&e.this)?;
25977 self.write(", ");
25978 self.generate_expression(&e.expression)?;
25979 self.write(")");
25980 Ok(())
25981 }
25982
25983 fn generate_covar_pop(&mut self, e: &CovarPop) -> Result<()> {
25984 self.write_keyword("COVAR_POP");
25986 self.write("(");
25987 self.generate_expression(&e.this)?;
25988 self.write(", ");
25989 self.generate_expression(&e.expression)?;
25990 self.write(")");
25991 Ok(())
25992 }
25993
25994 fn generate_covar_samp(&mut self, e: &CovarSamp) -> Result<()> {
25995 self.write_keyword("COVAR_SAMP");
25997 self.write("(");
25998 self.generate_expression(&e.this)?;
25999 self.write(", ");
26000 self.generate_expression(&e.expression)?;
26001 self.write(")");
26002 Ok(())
26003 }
26004
26005 fn generate_credentials(&mut self, e: &Credentials) -> Result<()> {
26006 self.write_keyword("CREDENTIALS");
26008 self.write(" (");
26009 for (i, (key, value)) in e.credentials.iter().enumerate() {
26010 if i > 0 {
26011 self.write(", ");
26012 }
26013 self.write(key);
26014 self.write("='");
26015 self.write(value);
26016 self.write("'");
26017 }
26018 self.write(")");
26019 Ok(())
26020 }
26021
26022 fn generate_credentials_property(&mut self, e: &CredentialsProperty) -> Result<()> {
26023 self.write_keyword("CREDENTIALS");
26025 self.write("=(");
26026 for (i, expr) in e.expressions.iter().enumerate() {
26027 if i > 0 {
26028 self.write(", ");
26029 }
26030 self.generate_expression(expr)?;
26031 }
26032 self.write(")");
26033 Ok(())
26034 }
26035
26036 fn generate_cte(&mut self, e: &Cte) -> Result<()> {
26037 use crate::dialects::DialectType;
26038
26039 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !e.alias_first {
26042 self.generate_expression(&e.this)?;
26043 self.write_space();
26044 self.write_keyword("AS");
26045 self.write_space();
26046 self.generate_identifier(&e.alias)?;
26047 return Ok(());
26048 }
26049 self.write(&e.alias.name);
26050
26051 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
26053
26054 if !e.columns.is_empty() && !skip_cte_columns {
26055 self.write("(");
26056 for (i, col) in e.columns.iter().enumerate() {
26057 if i > 0 {
26058 self.write(", ");
26059 }
26060 self.write(&col.name);
26061 }
26062 self.write(")");
26063 }
26064 if !e.key_expressions.is_empty() {
26066 self.write_space();
26067 self.write_keyword("USING KEY");
26068 self.write(" (");
26069 for (i, key) in e.key_expressions.iter().enumerate() {
26070 if i > 0 {
26071 self.write(", ");
26072 }
26073 self.write(&key.name);
26074 }
26075 self.write(")");
26076 }
26077 self.write_space();
26078 self.write_keyword("AS");
26079 self.write_space();
26080 if let Some(materialized) = e.materialized {
26081 if materialized {
26082 self.write_keyword("MATERIALIZED");
26083 } else {
26084 self.write_keyword("NOT MATERIALIZED");
26085 }
26086 self.write_space();
26087 }
26088 self.write("(");
26089 self.generate_expression(&e.this)?;
26090 self.write(")");
26091 Ok(())
26092 }
26093
26094 fn generate_cube(&mut self, e: &Cube) -> Result<()> {
26095 if e.expressions.is_empty() {
26097 self.write_keyword("WITH CUBE");
26098 } else {
26099 self.write_keyword("CUBE");
26100 self.write("(");
26101 for (i, expr) in e.expressions.iter().enumerate() {
26102 if i > 0 {
26103 self.write(", ");
26104 }
26105 self.generate_expression(expr)?;
26106 }
26107 self.write(")");
26108 }
26109 Ok(())
26110 }
26111
26112 fn generate_current_datetime(&mut self, e: &CurrentDatetime) -> Result<()> {
26113 self.write_keyword("CURRENT_DATETIME");
26115 if let Some(this) = &e.this {
26116 self.write("(");
26117 self.generate_expression(this)?;
26118 self.write(")");
26119 }
26120 Ok(())
26121 }
26122
26123 fn generate_current_schema(&mut self, _e: &CurrentSchema) -> Result<()> {
26124 self.write_keyword("CURRENT_SCHEMA");
26126 Ok(())
26127 }
26128
26129 fn generate_current_schemas(&mut self, e: &CurrentSchemas) -> Result<()> {
26130 self.write_keyword("CURRENT_SCHEMAS");
26132 self.write("(");
26133 if let Some(this) = &e.this {
26134 self.generate_expression(this)?;
26135 }
26136 self.write(")");
26137 Ok(())
26138 }
26139
26140 fn generate_current_user(&mut self, e: &CurrentUser) -> Result<()> {
26141 self.write_keyword("CURRENT_USER");
26143 let needs_parens = e.this.is_some()
26145 || matches!(
26146 self.config.dialect,
26147 Some(DialectType::Snowflake)
26148 | Some(DialectType::Spark)
26149 | Some(DialectType::Hive)
26150 | Some(DialectType::DuckDB)
26151 | Some(DialectType::BigQuery)
26152 | Some(DialectType::MySQL)
26153 | Some(DialectType::Databricks)
26154 );
26155 if needs_parens {
26156 self.write("()");
26157 }
26158 Ok(())
26159 }
26160
26161 fn generate_d_pipe(&mut self, e: &DPipe) -> Result<()> {
26162 if self.config.dialect == Some(DialectType::Solr) {
26164 self.generate_expression(&e.this)?;
26165 self.write(" ");
26166 self.write_keyword("OR");
26167 self.write(" ");
26168 self.generate_expression(&e.expression)?;
26169 } else if self.config.dialect == Some(DialectType::MySQL) {
26170 self.generate_mysql_concat_from_dpipe(e)?;
26171 } else {
26172 self.generate_expression(&e.this)?;
26174 self.write(" || ");
26175 self.generate_expression(&e.expression)?;
26176 }
26177 Ok(())
26178 }
26179
26180 fn generate_data_blocksize_property(&mut self, e: &DataBlocksizeProperty) -> Result<()> {
26181 self.write_keyword("DATABLOCKSIZE");
26183 self.write("=");
26184 if let Some(size) = e.size {
26185 self.write(&size.to_string());
26186 if let Some(units) = &e.units {
26187 self.write_space();
26188 self.generate_expression(units)?;
26189 }
26190 } else if e.minimum.is_some() {
26191 self.write_keyword("MINIMUM");
26192 } else if e.maximum.is_some() {
26193 self.write_keyword("MAXIMUM");
26194 } else if e.default.is_some() {
26195 self.write_keyword("DEFAULT");
26196 }
26197 Ok(())
26198 }
26199
26200 fn generate_data_deletion_property(&mut self, e: &DataDeletionProperty) -> Result<()> {
26201 self.write_keyword("DATA_DELETION");
26203 self.write("=");
26204
26205 let is_on = matches!(&*e.on, Expression::Boolean(BooleanLiteral { value: true }));
26206 let has_options = e.filter_column.is_some() || e.retention_period.is_some();
26207
26208 if is_on {
26209 self.write_keyword("ON");
26210 if has_options {
26211 self.write("(");
26212 let mut first = true;
26213 if let Some(filter_column) = &e.filter_column {
26214 self.write_keyword("FILTER_COLUMN");
26215 self.write("=");
26216 self.generate_expression(filter_column)?;
26217 first = false;
26218 }
26219 if let Some(retention_period) = &e.retention_period {
26220 if !first {
26221 self.write(", ");
26222 }
26223 self.write_keyword("RETENTION_PERIOD");
26224 self.write("=");
26225 self.generate_expression(retention_period)?;
26226 }
26227 self.write(")");
26228 }
26229 } else {
26230 self.write_keyword("OFF");
26231 }
26232 Ok(())
26233 }
26234
26235 fn generate_date_func(&mut self, e: &UnaryFunc) -> Result<()> {
26239 use crate::dialects::DialectType;
26240 use crate::expressions::Literal;
26241
26242 match self.config.dialect {
26243 Some(DialectType::Exasol) => {
26245 self.write_keyword("TO_DATE");
26246 self.write("(");
26247 match &e.this {
26249 Expression::Literal(Literal::String(s)) => {
26250 self.write("'");
26251 self.write(s);
26252 self.write("'");
26253 }
26254 _ => {
26255 self.generate_expression(&e.this)?;
26256 }
26257 }
26258 self.write(")");
26259 }
26260 _ => {
26262 self.write_keyword("DATE");
26263 self.write("(");
26264 self.generate_expression(&e.this)?;
26265 self.write(")");
26266 }
26267 }
26268 Ok(())
26269 }
26270
26271 fn generate_date_bin(&mut self, e: &DateBin) -> Result<()> {
26272 self.write_keyword("DATE_BIN");
26274 self.write("(");
26275 self.generate_expression(&e.this)?;
26276 self.write(", ");
26277 self.generate_expression(&e.expression)?;
26278 if let Some(origin) = &e.origin {
26279 self.write(", ");
26280 self.generate_expression(origin)?;
26281 }
26282 self.write(")");
26283 Ok(())
26284 }
26285
26286 fn generate_date_format_column_constraint(
26287 &mut self,
26288 e: &DateFormatColumnConstraint,
26289 ) -> Result<()> {
26290 self.write_keyword("FORMAT");
26292 self.write_space();
26293 self.generate_expression(&e.this)?;
26294 Ok(())
26295 }
26296
26297 fn generate_date_from_parts(&mut self, e: &DateFromParts) -> Result<()> {
26298 self.write_keyword("DATE_FROM_PARTS");
26300 self.write("(");
26301 let mut first = true;
26302 if let Some(year) = &e.year {
26303 self.generate_expression(year)?;
26304 first = false;
26305 }
26306 if let Some(month) = &e.month {
26307 if !first {
26308 self.write(", ");
26309 }
26310 self.generate_expression(month)?;
26311 first = false;
26312 }
26313 if let Some(day) = &e.day {
26314 if !first {
26315 self.write(", ");
26316 }
26317 self.generate_expression(day)?;
26318 }
26319 self.write(")");
26320 Ok(())
26321 }
26322
26323 fn generate_datetime(&mut self, e: &Datetime) -> Result<()> {
26324 self.write_keyword("DATETIME");
26326 self.write("(");
26327 self.generate_expression(&e.this)?;
26328 if let Some(expr) = &e.expression {
26329 self.write(", ");
26330 self.generate_expression(expr)?;
26331 }
26332 self.write(")");
26333 Ok(())
26334 }
26335
26336 fn generate_datetime_add(&mut self, e: &DatetimeAdd) -> Result<()> {
26337 self.write_keyword("DATETIME_ADD");
26339 self.write("(");
26340 self.generate_expression(&e.this)?;
26341 self.write(", ");
26342 self.generate_expression(&e.expression)?;
26343 if let Some(unit) = &e.unit {
26344 self.write(", ");
26345 self.write_keyword(unit);
26346 }
26347 self.write(")");
26348 Ok(())
26349 }
26350
26351 fn generate_datetime_diff(&mut self, e: &DatetimeDiff) -> Result<()> {
26352 self.write_keyword("DATETIME_DIFF");
26354 self.write("(");
26355 self.generate_expression(&e.this)?;
26356 self.write(", ");
26357 self.generate_expression(&e.expression)?;
26358 if let Some(unit) = &e.unit {
26359 self.write(", ");
26360 self.write_keyword(unit);
26361 }
26362 self.write(")");
26363 Ok(())
26364 }
26365
26366 fn generate_datetime_sub(&mut self, e: &DatetimeSub) -> Result<()> {
26367 self.write_keyword("DATETIME_SUB");
26369 self.write("(");
26370 self.generate_expression(&e.this)?;
26371 self.write(", ");
26372 self.generate_expression(&e.expression)?;
26373 if let Some(unit) = &e.unit {
26374 self.write(", ");
26375 self.write_keyword(unit);
26376 }
26377 self.write(")");
26378 Ok(())
26379 }
26380
26381 fn generate_datetime_trunc(&mut self, e: &DatetimeTrunc) -> Result<()> {
26382 self.write_keyword("DATETIME_TRUNC");
26384 self.write("(");
26385 self.generate_expression(&e.this)?;
26386 self.write(", ");
26387 self.write_keyword(&e.unit);
26388 if let Some(zone) = &e.zone {
26389 self.write(", ");
26390 self.generate_expression(zone)?;
26391 }
26392 self.write(")");
26393 Ok(())
26394 }
26395
26396 fn generate_dayname(&mut self, e: &Dayname) -> Result<()> {
26397 self.write_keyword("DAYNAME");
26399 self.write("(");
26400 self.generate_expression(&e.this)?;
26401 self.write(")");
26402 Ok(())
26403 }
26404
26405 fn generate_declare(&mut self, e: &Declare) -> Result<()> {
26406 self.write_keyword("DECLARE");
26408 self.write_space();
26409 for (i, expr) in e.expressions.iter().enumerate() {
26410 if i > 0 {
26411 self.write(", ");
26412 }
26413 self.generate_expression(expr)?;
26414 }
26415 Ok(())
26416 }
26417
26418 fn generate_declare_item(&mut self, e: &DeclareItem) -> Result<()> {
26419 use crate::dialects::DialectType;
26420
26421 self.generate_expression(&e.this)?;
26423 for name in &e.additional_names {
26425 self.write(", ");
26426 self.generate_expression(name)?;
26427 }
26428 if let Some(kind) = &e.kind {
26429 self.write_space();
26430 match self.config.dialect {
26434 Some(DialectType::BigQuery) => {
26435 self.write(kind);
26436 }
26437 Some(DialectType::TSQL) => {
26438 let is_complex_table = kind.starts_with("TABLE")
26442 && (kind.contains("CLUSTERED") || kind.contains("INDEX"));
26443
26444 if is_complex_table {
26445 self.write(kind);
26447 } else {
26448 if !kind.starts_with("CURSOR") {
26450 self.write_keyword("AS");
26451 self.write_space();
26452 }
26453 if kind == "INT" {
26455 self.write("INTEGER");
26456 } else if kind.starts_with("TABLE") {
26457 let normalized = kind
26459 .replace(" INT ", " INTEGER ")
26460 .replace(" INT,", " INTEGER,")
26461 .replace(" INT)", " INTEGER)")
26462 .replace("(INT ", "(INTEGER ");
26463 self.write(&normalized);
26464 } else {
26465 self.write(kind);
26466 }
26467 }
26468 }
26469 _ => {
26470 if e.has_as {
26471 self.write_keyword("AS");
26472 self.write_space();
26473 }
26474 self.write(kind);
26475 }
26476 }
26477 }
26478 if let Some(default) = &e.default {
26479 match self.config.dialect {
26481 Some(DialectType::BigQuery) => {
26482 self.write_space();
26483 self.write_keyword("DEFAULT");
26484 self.write_space();
26485 }
26486 _ => {
26487 self.write(" = ");
26488 }
26489 }
26490 self.generate_expression(default)?;
26491 }
26492 Ok(())
26493 }
26494
26495 fn generate_decode_case(&mut self, e: &DecodeCase) -> Result<()> {
26496 self.write_keyword("DECODE");
26498 self.write("(");
26499 for (i, expr) in e.expressions.iter().enumerate() {
26500 if i > 0 {
26501 self.write(", ");
26502 }
26503 self.generate_expression(expr)?;
26504 }
26505 self.write(")");
26506 Ok(())
26507 }
26508
26509 fn generate_decompress_binary(&mut self, e: &DecompressBinary) -> Result<()> {
26510 self.write_keyword("DECOMPRESS");
26512 self.write("(");
26513 self.generate_expression(&e.this)?;
26514 self.write(", '");
26515 self.write(&e.method);
26516 self.write("')");
26517 Ok(())
26518 }
26519
26520 fn generate_decompress_string(&mut self, e: &DecompressString) -> Result<()> {
26521 self.write_keyword("DECOMPRESS");
26523 self.write("(");
26524 self.generate_expression(&e.this)?;
26525 self.write(", '");
26526 self.write(&e.method);
26527 self.write("')");
26528 Ok(())
26529 }
26530
26531 fn generate_decrypt(&mut self, e: &Decrypt) -> Result<()> {
26532 self.write_keyword("DECRYPT");
26534 self.write("(");
26535 self.generate_expression(&e.this)?;
26536 if let Some(passphrase) = &e.passphrase {
26537 self.write(", ");
26538 self.generate_expression(passphrase)?;
26539 }
26540 if let Some(aad) = &e.aad {
26541 self.write(", ");
26542 self.generate_expression(aad)?;
26543 }
26544 if let Some(method) = &e.encryption_method {
26545 self.write(", ");
26546 self.generate_expression(method)?;
26547 }
26548 self.write(")");
26549 Ok(())
26550 }
26551
26552 fn generate_decrypt_raw(&mut self, e: &DecryptRaw) -> Result<()> {
26553 self.write_keyword("DECRYPT_RAW");
26555 self.write("(");
26556 self.generate_expression(&e.this)?;
26557 if let Some(key) = &e.key {
26558 self.write(", ");
26559 self.generate_expression(key)?;
26560 }
26561 if let Some(iv) = &e.iv {
26562 self.write(", ");
26563 self.generate_expression(iv)?;
26564 }
26565 if let Some(aad) = &e.aad {
26566 self.write(", ");
26567 self.generate_expression(aad)?;
26568 }
26569 if let Some(method) = &e.encryption_method {
26570 self.write(", ");
26571 self.generate_expression(method)?;
26572 }
26573 self.write(")");
26574 Ok(())
26575 }
26576
26577 fn generate_definer_property(&mut self, e: &DefinerProperty) -> Result<()> {
26578 self.write_keyword("DEFINER");
26580 self.write(" = ");
26581 self.generate_expression(&e.this)?;
26582 Ok(())
26583 }
26584
26585 fn generate_detach(&mut self, e: &Detach) -> Result<()> {
26586 self.write_keyword("DETACH");
26588 if e.exists {
26589 self.write_keyword(" DATABASE IF EXISTS");
26590 }
26591 self.write_space();
26592 self.generate_expression(&e.this)?;
26593 Ok(())
26594 }
26595
26596 fn generate_dict_property(&mut self, e: &DictProperty) -> Result<()> {
26597 let property_name = match e.this.as_ref() {
26598 Expression::Identifier(id) => id.name.as_str(),
26599 Expression::Var(v) => v.this.as_str(),
26600 _ => "DICTIONARY",
26601 };
26602 self.write_keyword(property_name);
26603 self.write("(");
26604 self.write(&e.kind);
26605 if let Some(settings) = &e.settings {
26606 self.write("(");
26607 if let Expression::Tuple(t) = settings.as_ref() {
26608 if self.config.pretty && !t.expressions.is_empty() {
26609 self.write_newline();
26610 self.indent_level += 1;
26611 for (i, pair) in t.expressions.iter().enumerate() {
26612 if i > 0 {
26613 self.write(",");
26614 self.write_newline();
26615 }
26616 self.write_indent();
26617 if let Expression::Tuple(pair_tuple) = pair {
26618 if let Some(k) = pair_tuple.expressions.first() {
26619 self.generate_expression(k)?;
26620 }
26621 if let Some(v) = pair_tuple.expressions.get(1) {
26622 self.write(" ");
26623 self.generate_expression(v)?;
26624 }
26625 } else {
26626 self.generate_expression(pair)?;
26627 }
26628 }
26629 self.indent_level -= 1;
26630 self.write_newline();
26631 self.write_indent();
26632 } else {
26633 for (i, pair) in t.expressions.iter().enumerate() {
26634 if i > 0 {
26635 self.write(", ");
26636 }
26637 if let Expression::Tuple(pair_tuple) = pair {
26638 if let Some(k) = pair_tuple.expressions.first() {
26639 self.generate_expression(k)?;
26640 }
26641 if let Some(v) = pair_tuple.expressions.get(1) {
26642 self.write(" ");
26643 self.generate_expression(v)?;
26644 }
26645 } else {
26646 self.generate_expression(pair)?;
26647 }
26648 }
26649 }
26650 } else {
26651 self.generate_expression(settings)?;
26652 }
26653 self.write(")");
26654 } else if property_name.eq_ignore_ascii_case("LAYOUT") {
26655 self.write("()");
26656 }
26657 self.write(")");
26658 Ok(())
26659 }
26660
26661 fn generate_dict_range(&mut self, e: &DictRange) -> Result<()> {
26662 let property_name = match e.this.as_ref() {
26663 Expression::Identifier(id) => id.name.as_str(),
26664 Expression::Var(v) => v.this.as_str(),
26665 _ => "RANGE",
26666 };
26667 self.write_keyword(property_name);
26668 self.write("(");
26669 if let Some(min) = &e.min {
26670 self.write_keyword("MIN");
26671 self.write_space();
26672 self.generate_expression(min)?;
26673 }
26674 if let Some(max) = &e.max {
26675 self.write_space();
26676 self.write_keyword("MAX");
26677 self.write_space();
26678 self.generate_expression(max)?;
26679 }
26680 self.write(")");
26681 Ok(())
26682 }
26683
26684 fn generate_directory(&mut self, e: &Directory) -> Result<()> {
26685 if e.local.is_some() {
26687 self.write_keyword("LOCAL ");
26688 }
26689 self.write_keyword("DIRECTORY");
26690 self.write_space();
26691 self.generate_expression(&e.this)?;
26692 if let Some(row_format) = &e.row_format {
26693 self.write_space();
26694 self.generate_expression(row_format)?;
26695 }
26696 Ok(())
26697 }
26698
26699 fn generate_dist_key_property(&mut self, e: &DistKeyProperty) -> Result<()> {
26700 self.write_keyword("DISTKEY");
26702 self.write("(");
26703 self.generate_expression(&e.this)?;
26704 self.write(")");
26705 Ok(())
26706 }
26707
26708 fn generate_dist_style_property(&mut self, e: &DistStyleProperty) -> Result<()> {
26709 self.write_keyword("DISTSTYLE");
26711 self.write_space();
26712 self.generate_expression(&e.this)?;
26713 Ok(())
26714 }
26715
26716 fn generate_distribute_by(&mut self, e: &DistributeBy) -> Result<()> {
26717 self.write_keyword("DISTRIBUTE BY");
26719 self.write_space();
26720 for (i, expr) in e.expressions.iter().enumerate() {
26721 if i > 0 {
26722 self.write(", ");
26723 }
26724 self.generate_expression(expr)?;
26725 }
26726 Ok(())
26727 }
26728
26729 fn generate_distributed_by_property(&mut self, e: &DistributedByProperty) -> Result<()> {
26730 self.write_keyword("DISTRIBUTED BY");
26732 self.write_space();
26733 self.write(&e.kind);
26734 if !e.expressions.is_empty() {
26735 self.write(" (");
26736 for (i, expr) in e.expressions.iter().enumerate() {
26737 if i > 0 {
26738 self.write(", ");
26739 }
26740 self.generate_expression(expr)?;
26741 }
26742 self.write(")");
26743 }
26744 if let Some(buckets) = &e.buckets {
26745 self.write_space();
26746 self.write_keyword("BUCKETS");
26747 self.write_space();
26748 self.generate_expression(buckets)?;
26749 }
26750 if let Some(order) = &e.order {
26751 self.write_space();
26752 self.generate_expression(order)?;
26753 }
26754 Ok(())
26755 }
26756
26757 fn generate_dot_product(&mut self, e: &DotProduct) -> Result<()> {
26758 self.write_keyword("DOT_PRODUCT");
26760 self.write("(");
26761 self.generate_expression(&e.this)?;
26762 self.write(", ");
26763 self.generate_expression(&e.expression)?;
26764 self.write(")");
26765 Ok(())
26766 }
26767
26768 fn generate_drop_partition(&mut self, e: &DropPartition) -> Result<()> {
26769 self.write_keyword("DROP");
26771 if e.exists {
26772 self.write_keyword(" IF EXISTS ");
26773 } else {
26774 self.write_space();
26775 }
26776 for (i, expr) in e.expressions.iter().enumerate() {
26777 if i > 0 {
26778 self.write(", ");
26779 }
26780 self.generate_expression(expr)?;
26781 }
26782 Ok(())
26783 }
26784
26785 fn generate_duplicate_key_property(&mut self, e: &DuplicateKeyProperty) -> Result<()> {
26786 self.write_keyword("DUPLICATE KEY");
26788 self.write(" (");
26789 for (i, expr) in e.expressions.iter().enumerate() {
26790 if i > 0 {
26791 self.write(", ");
26792 }
26793 self.generate_expression(expr)?;
26794 }
26795 self.write(")");
26796 Ok(())
26797 }
26798
26799 fn generate_elt(&mut self, e: &Elt) -> Result<()> {
26800 self.write_keyword("ELT");
26802 self.write("(");
26803 self.generate_expression(&e.this)?;
26804 for expr in &e.expressions {
26805 self.write(", ");
26806 self.generate_expression(expr)?;
26807 }
26808 self.write(")");
26809 Ok(())
26810 }
26811
26812 fn generate_encode(&mut self, e: &Encode) -> Result<()> {
26813 self.write_keyword("ENCODE");
26815 self.write("(");
26816 self.generate_expression(&e.this)?;
26817 if let Some(charset) = &e.charset {
26818 self.write(", ");
26819 self.generate_expression(charset)?;
26820 }
26821 self.write(")");
26822 Ok(())
26823 }
26824
26825 fn generate_encode_property(&mut self, e: &EncodeProperty) -> Result<()> {
26826 if e.key.is_some() {
26828 self.write_keyword("KEY ");
26829 }
26830 self.write_keyword("ENCODE");
26831 self.write_space();
26832 self.generate_expression(&e.this)?;
26833 if !e.properties.is_empty() {
26834 self.write(" (");
26835 for (i, prop) in e.properties.iter().enumerate() {
26836 if i > 0 {
26837 self.write(", ");
26838 }
26839 self.generate_expression(prop)?;
26840 }
26841 self.write(")");
26842 }
26843 Ok(())
26844 }
26845
26846 fn generate_encrypt(&mut self, e: &Encrypt) -> Result<()> {
26847 self.write_keyword("ENCRYPT");
26849 self.write("(");
26850 self.generate_expression(&e.this)?;
26851 if let Some(passphrase) = &e.passphrase {
26852 self.write(", ");
26853 self.generate_expression(passphrase)?;
26854 }
26855 if let Some(aad) = &e.aad {
26856 self.write(", ");
26857 self.generate_expression(aad)?;
26858 }
26859 if let Some(method) = &e.encryption_method {
26860 self.write(", ");
26861 self.generate_expression(method)?;
26862 }
26863 self.write(")");
26864 Ok(())
26865 }
26866
26867 fn generate_encrypt_raw(&mut self, e: &EncryptRaw) -> Result<()> {
26868 self.write_keyword("ENCRYPT_RAW");
26870 self.write("(");
26871 self.generate_expression(&e.this)?;
26872 if let Some(key) = &e.key {
26873 self.write(", ");
26874 self.generate_expression(key)?;
26875 }
26876 if let Some(iv) = &e.iv {
26877 self.write(", ");
26878 self.generate_expression(iv)?;
26879 }
26880 if let Some(aad) = &e.aad {
26881 self.write(", ");
26882 self.generate_expression(aad)?;
26883 }
26884 if let Some(method) = &e.encryption_method {
26885 self.write(", ");
26886 self.generate_expression(method)?;
26887 }
26888 self.write(")");
26889 Ok(())
26890 }
26891
26892 fn generate_engine_property(&mut self, e: &EngineProperty) -> Result<()> {
26893 self.write_keyword("ENGINE");
26895 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
26896 self.write("=");
26897 } else {
26898 self.write(" = ");
26899 }
26900 self.generate_expression(&e.this)?;
26901 Ok(())
26902 }
26903
26904 fn generate_enviroment_property(&mut self, e: &EnviromentProperty) -> Result<()> {
26905 self.write_keyword("ENVIRONMENT");
26907 self.write(" (");
26908 for (i, expr) in e.expressions.iter().enumerate() {
26909 if i > 0 {
26910 self.write(", ");
26911 }
26912 self.generate_expression(expr)?;
26913 }
26914 self.write(")");
26915 Ok(())
26916 }
26917
26918 fn generate_ephemeral_column_constraint(
26919 &mut self,
26920 e: &EphemeralColumnConstraint,
26921 ) -> Result<()> {
26922 self.write_keyword("EPHEMERAL");
26924 if let Some(this) = &e.this {
26925 self.write_space();
26926 self.generate_expression(this)?;
26927 }
26928 Ok(())
26929 }
26930
26931 fn generate_equal_null(&mut self, e: &EqualNull) -> Result<()> {
26932 self.write_keyword("EQUAL_NULL");
26934 self.write("(");
26935 self.generate_expression(&e.this)?;
26936 self.write(", ");
26937 self.generate_expression(&e.expression)?;
26938 self.write(")");
26939 Ok(())
26940 }
26941
26942 fn generate_euclidean_distance(&mut self, e: &EuclideanDistance) -> Result<()> {
26943 use crate::dialects::DialectType;
26944
26945 match self.config.dialect {
26947 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
26948 self.generate_expression(&e.this)?;
26949 self.write(" <-> ");
26950 self.generate_expression(&e.expression)?;
26951 }
26952 _ => {
26953 self.write_keyword("EUCLIDEAN_DISTANCE");
26955 self.write("(");
26956 self.generate_expression(&e.this)?;
26957 self.write(", ");
26958 self.generate_expression(&e.expression)?;
26959 self.write(")");
26960 }
26961 }
26962 Ok(())
26963 }
26964
26965 fn generate_execute_as_property(&mut self, e: &ExecuteAsProperty) -> Result<()> {
26966 self.write_keyword("EXECUTE AS");
26968 self.write_space();
26969 self.generate_expression(&e.this)?;
26970 Ok(())
26971 }
26972
26973 fn generate_export(&mut self, e: &Export) -> Result<()> {
26974 self.write_keyword("EXPORT DATA");
26976 if let Some(connection) = &e.connection {
26977 self.write_space();
26978 self.write_keyword("WITH CONNECTION");
26979 self.write_space();
26980 self.generate_expression(connection)?;
26981 }
26982 if !e.options.is_empty() {
26983 self.write_space();
26984 self.generate_options_clause(&e.options)?;
26985 }
26986 self.write_space();
26987 self.write_keyword("AS");
26988 self.write_space();
26989 self.generate_expression(&e.this)?;
26990 Ok(())
26991 }
26992
26993 fn generate_external_property(&mut self, e: &ExternalProperty) -> Result<()> {
26994 self.write_keyword("EXTERNAL");
26996 if let Some(this) = &e.this {
26997 self.write_space();
26998 self.generate_expression(this)?;
26999 }
27000 Ok(())
27001 }
27002
27003 fn generate_fallback_property(&mut self, e: &FallbackProperty) -> Result<()> {
27004 if e.no.is_some() {
27006 self.write_keyword("NO ");
27007 }
27008 self.write_keyword("FALLBACK");
27009 if e.protection.is_some() {
27010 self.write_keyword(" PROTECTION");
27011 }
27012 Ok(())
27013 }
27014
27015 fn generate_farm_fingerprint(&mut self, e: &FarmFingerprint) -> Result<()> {
27016 self.write_keyword("FARM_FINGERPRINT");
27018 self.write("(");
27019 for (i, expr) in e.expressions.iter().enumerate() {
27020 if i > 0 {
27021 self.write(", ");
27022 }
27023 self.generate_expression(expr)?;
27024 }
27025 self.write(")");
27026 Ok(())
27027 }
27028
27029 fn generate_features_at_time(&mut self, e: &FeaturesAtTime) -> Result<()> {
27030 self.write_keyword("FEATURES_AT_TIME");
27032 self.write("(");
27033 self.generate_expression(&e.this)?;
27034 if let Some(time) = &e.time {
27035 self.write(", ");
27036 self.generate_expression(time)?;
27037 }
27038 if let Some(num_rows) = &e.num_rows {
27039 self.write(", ");
27040 self.generate_expression(num_rows)?;
27041 }
27042 if let Some(ignore_nulls) = &e.ignore_feature_nulls {
27043 self.write(", ");
27044 self.generate_expression(ignore_nulls)?;
27045 }
27046 self.write(")");
27047 Ok(())
27048 }
27049
27050 fn generate_fetch(&mut self, e: &Fetch) -> Result<()> {
27051 let use_limit = !e.percent
27053 && !e.with_ties
27054 && e.count.is_some()
27055 && matches!(
27056 self.config.dialect,
27057 Some(DialectType::Spark)
27058 | Some(DialectType::Hive)
27059 | Some(DialectType::DuckDB)
27060 | Some(DialectType::SQLite)
27061 | Some(DialectType::MySQL)
27062 | Some(DialectType::BigQuery)
27063 | Some(DialectType::Databricks)
27064 | Some(DialectType::StarRocks)
27065 | Some(DialectType::Doris)
27066 | Some(DialectType::Athena)
27067 | Some(DialectType::ClickHouse)
27068 );
27069
27070 if use_limit {
27071 self.write_keyword("LIMIT");
27072 self.write_space();
27073 self.generate_expression(e.count.as_ref().unwrap())?;
27074 return Ok(());
27075 }
27076
27077 self.write_keyword("FETCH");
27079 if !e.direction.is_empty() {
27080 self.write_space();
27081 self.write_keyword(&e.direction);
27082 }
27083 if let Some(count) = &e.count {
27084 self.write_space();
27085 self.generate_expression(count)?;
27086 }
27087 if e.percent {
27089 self.write_keyword(" PERCENT");
27090 }
27091 if e.rows {
27092 self.write_keyword(" ROWS");
27093 }
27094 if e.with_ties {
27095 self.write_keyword(" WITH TIES");
27096 } else if e.rows {
27097 self.write_keyword(" ONLY");
27098 } else {
27099 self.write_keyword(" ROWS ONLY");
27100 }
27101 Ok(())
27102 }
27103
27104 fn generate_file_format_property(&mut self, e: &FileFormatProperty) -> Result<()> {
27105 if e.hive_format.is_some() {
27109 self.write_keyword("STORED AS");
27111 self.write_space();
27112 if let Some(this) = &e.this {
27113 if let Expression::Identifier(id) = this.as_ref() {
27115 self.write_keyword(&id.name.to_uppercase());
27116 } else {
27117 self.generate_expression(this)?;
27118 }
27119 }
27120 } else if matches!(self.config.dialect, Some(DialectType::Hive)) {
27121 self.write_keyword("STORED AS");
27123 self.write_space();
27124 if let Some(this) = &e.this {
27125 if let Expression::Identifier(id) = this.as_ref() {
27126 self.write_keyword(&id.name.to_uppercase());
27127 } else {
27128 self.generate_expression(this)?;
27129 }
27130 }
27131 } else if matches!(
27132 self.config.dialect,
27133 Some(DialectType::Spark) | Some(DialectType::Databricks)
27134 ) {
27135 self.write_keyword("USING");
27137 self.write_space();
27138 if let Some(this) = &e.this {
27139 self.generate_expression(this)?;
27140 }
27141 } else {
27142 self.write_keyword("FILE_FORMAT");
27144 self.write(" = ");
27145 if let Some(this) = &e.this {
27146 self.generate_expression(this)?;
27147 } else if !e.expressions.is_empty() {
27148 self.write("(");
27149 for (i, expr) in e.expressions.iter().enumerate() {
27150 if i > 0 {
27151 self.write(", ");
27152 }
27153 self.generate_expression(expr)?;
27154 }
27155 self.write(")");
27156 }
27157 }
27158 Ok(())
27159 }
27160
27161 fn generate_filter(&mut self, e: &Filter) -> Result<()> {
27162 self.generate_expression(&e.this)?;
27164 self.write_space();
27165 self.write_keyword("FILTER");
27166 self.write("(");
27167 self.write_keyword("WHERE");
27168 self.write_space();
27169 self.generate_expression(&e.expression)?;
27170 self.write(")");
27171 Ok(())
27172 }
27173
27174 fn generate_float64(&mut self, e: &Float64) -> Result<()> {
27175 self.write_keyword("FLOAT64");
27177 self.write("(");
27178 self.generate_expression(&e.this)?;
27179 if let Some(expr) = &e.expression {
27180 self.write(", ");
27181 self.generate_expression(expr)?;
27182 }
27183 self.write(")");
27184 Ok(())
27185 }
27186
27187 fn generate_for_in(&mut self, e: &ForIn) -> Result<()> {
27188 self.write_keyword("FOR");
27190 self.write_space();
27191 self.generate_expression(&e.this)?;
27192 self.write_space();
27193 self.write_keyword("DO");
27194 self.write_space();
27195 self.generate_expression(&e.expression)?;
27196 Ok(())
27197 }
27198
27199 fn generate_foreign_key(&mut self, e: &ForeignKey) -> Result<()> {
27200 self.write_keyword("FOREIGN KEY");
27202 if !e.expressions.is_empty() {
27203 self.write(" (");
27204 for (i, expr) in e.expressions.iter().enumerate() {
27205 if i > 0 {
27206 self.write(", ");
27207 }
27208 self.generate_expression(expr)?;
27209 }
27210 self.write(")");
27211 }
27212 if let Some(reference) = &e.reference {
27213 self.write_space();
27214 self.generate_expression(reference)?;
27215 }
27216 if let Some(delete) = &e.delete {
27217 self.write_space();
27218 self.write_keyword("ON DELETE");
27219 self.write_space();
27220 self.generate_expression(delete)?;
27221 }
27222 if let Some(update) = &e.update {
27223 self.write_space();
27224 self.write_keyword("ON UPDATE");
27225 self.write_space();
27226 self.generate_expression(update)?;
27227 }
27228 if !e.options.is_empty() {
27229 self.write_space();
27230 for (i, opt) in e.options.iter().enumerate() {
27231 if i > 0 {
27232 self.write_space();
27233 }
27234 self.generate_expression(opt)?;
27235 }
27236 }
27237 Ok(())
27238 }
27239
27240 fn generate_format(&mut self, e: &Format) -> Result<()> {
27241 self.write_keyword("FORMAT");
27243 self.write("(");
27244 self.generate_expression(&e.this)?;
27245 for expr in &e.expressions {
27246 self.write(", ");
27247 self.generate_expression(expr)?;
27248 }
27249 self.write(")");
27250 Ok(())
27251 }
27252
27253 fn generate_format_phrase(&mut self, e: &FormatPhrase) -> Result<()> {
27254 self.generate_expression(&e.this)?;
27256 self.write(" (");
27257 self.write_keyword("FORMAT");
27258 self.write(" '");
27259 self.write(&e.format);
27260 self.write("')");
27261 Ok(())
27262 }
27263
27264 fn generate_freespace_property(&mut self, e: &FreespaceProperty) -> Result<()> {
27265 self.write_keyword("FREESPACE");
27267 self.write("=");
27268 self.generate_expression(&e.this)?;
27269 if e.percent.is_some() {
27270 self.write_keyword(" PERCENT");
27271 }
27272 Ok(())
27273 }
27274
27275 fn generate_from(&mut self, e: &From) -> Result<()> {
27276 self.write_keyword("FROM");
27278 self.write_space();
27279
27280 use crate::dialects::DialectType;
27284 let has_tablesample = e
27285 .expressions
27286 .iter()
27287 .any(|expr| matches!(expr, Expression::TableSample(_)));
27288 let is_cross_join_dialect = matches!(
27289 self.config.dialect,
27290 Some(DialectType::BigQuery)
27291 | Some(DialectType::Hive)
27292 | Some(DialectType::Spark)
27293 | Some(DialectType::Databricks)
27294 | Some(DialectType::SQLite)
27295 | Some(DialectType::ClickHouse)
27296 );
27297 let source_is_same_as_target2 = self.config.source_dialect.is_some()
27298 && self.config.source_dialect == self.config.dialect;
27299 let source_is_cross_join_dialect2 = matches!(
27300 self.config.source_dialect,
27301 Some(DialectType::BigQuery)
27302 | Some(DialectType::Hive)
27303 | Some(DialectType::Spark)
27304 | Some(DialectType::Databricks)
27305 | Some(DialectType::SQLite)
27306 | Some(DialectType::ClickHouse)
27307 );
27308 let use_cross_join = !has_tablesample
27309 && is_cross_join_dialect
27310 && (source_is_same_as_target2
27311 || source_is_cross_join_dialect2
27312 || self.config.source_dialect.is_none());
27313
27314 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
27316
27317 for (i, expr) in e.expressions.iter().enumerate() {
27318 if i > 0 {
27319 if use_cross_join {
27320 self.write(" CROSS JOIN ");
27321 } else {
27322 self.write(", ");
27323 }
27324 }
27325 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
27326 self.write("(");
27327 self.generate_expression(expr)?;
27328 self.write(")");
27329 } else {
27330 self.generate_expression(expr)?;
27331 }
27332 }
27333 Ok(())
27334 }
27335
27336 fn generate_from_base(&mut self, e: &FromBase) -> Result<()> {
27337 self.write_keyword("FROM_BASE");
27339 self.write("(");
27340 self.generate_expression(&e.this)?;
27341 self.write(", ");
27342 self.generate_expression(&e.expression)?;
27343 self.write(")");
27344 Ok(())
27345 }
27346
27347 fn generate_from_time_zone(&mut self, e: &FromTimeZone) -> Result<()> {
27348 self.generate_expression(&e.this)?;
27350 if let Some(zone) = &e.zone {
27351 self.write_space();
27352 self.write_keyword("AT TIME ZONE");
27353 self.write_space();
27354 self.generate_expression(zone)?;
27355 self.write_space();
27356 self.write_keyword("AT TIME ZONE");
27357 self.write(" 'UTC'");
27358 }
27359 Ok(())
27360 }
27361
27362 fn generate_gap_fill(&mut self, e: &GapFill) -> Result<()> {
27363 self.write_keyword("GAP_FILL");
27365 self.write("(");
27366 self.generate_expression(&e.this)?;
27367 if let Some(ts_column) = &e.ts_column {
27368 self.write(", ");
27369 self.generate_expression(ts_column)?;
27370 }
27371 if let Some(bucket_width) = &e.bucket_width {
27372 self.write(", ");
27373 self.generate_expression(bucket_width)?;
27374 }
27375 if let Some(partitioning_columns) = &e.partitioning_columns {
27376 self.write(", ");
27377 self.generate_expression(partitioning_columns)?;
27378 }
27379 if let Some(value_columns) = &e.value_columns {
27380 self.write(", ");
27381 self.generate_expression(value_columns)?;
27382 }
27383 self.write(")");
27384 Ok(())
27385 }
27386
27387 fn generate_generate_date_array(&mut self, e: &GenerateDateArray) -> Result<()> {
27388 self.write_keyword("GENERATE_DATE_ARRAY");
27390 self.write("(");
27391 let mut first = true;
27392 if let Some(start) = &e.start {
27393 self.generate_expression(start)?;
27394 first = false;
27395 }
27396 if let Some(end) = &e.end {
27397 if !first {
27398 self.write(", ");
27399 }
27400 self.generate_expression(end)?;
27401 first = false;
27402 }
27403 if let Some(step) = &e.step {
27404 if !first {
27405 self.write(", ");
27406 }
27407 self.generate_expression(step)?;
27408 }
27409 self.write(")");
27410 Ok(())
27411 }
27412
27413 fn generate_generate_embedding(&mut self, e: &GenerateEmbedding) -> Result<()> {
27414 self.write_keyword("ML.GENERATE_EMBEDDING");
27416 self.write("(");
27417 self.generate_expression(&e.this)?;
27418 self.write(", ");
27419 self.generate_expression(&e.expression)?;
27420 if let Some(params) = &e.params_struct {
27421 self.write(", ");
27422 self.generate_expression(params)?;
27423 }
27424 self.write(")");
27425 Ok(())
27426 }
27427
27428 fn generate_generate_series(&mut self, e: &GenerateSeries) -> Result<()> {
27429 let fn_name = match self.config.dialect {
27431 Some(DialectType::Presto)
27432 | Some(DialectType::Trino)
27433 | Some(DialectType::Athena)
27434 | Some(DialectType::Spark)
27435 | Some(DialectType::Databricks)
27436 | Some(DialectType::Hive) => "SEQUENCE",
27437 _ => "GENERATE_SERIES",
27438 };
27439 self.write_keyword(fn_name);
27440 self.write("(");
27441 let mut first = true;
27442 if let Some(start) = &e.start {
27443 self.generate_expression(start)?;
27444 first = false;
27445 }
27446 if let Some(end) = &e.end {
27447 if !first {
27448 self.write(", ");
27449 }
27450 self.generate_expression(end)?;
27451 first = false;
27452 }
27453 if let Some(step) = &e.step {
27454 if !first {
27455 self.write(", ");
27456 }
27457 if matches!(
27460 self.config.dialect,
27461 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
27462 ) {
27463 if let Some(converted) = self.convert_week_interval_to_day(step) {
27464 self.generate_expression(&converted)?;
27465 } else {
27466 self.generate_expression(step)?;
27467 }
27468 } else {
27469 self.generate_expression(step)?;
27470 }
27471 }
27472 self.write(")");
27473 Ok(())
27474 }
27475
27476 fn convert_week_interval_to_day(&self, expr: &Expression) -> Option<Expression> {
27479 use crate::expressions::*;
27480 if let Expression::Interval(ref iv) = expr {
27481 let (is_week, count_str) = if let Some(IntervalUnitSpec::Simple {
27483 unit: IntervalUnit::Week,
27484 ..
27485 }) = &iv.unit
27486 {
27487 let count = match &iv.this {
27489 Some(Expression::Literal(Literal::String(s))) => s.clone(),
27490 Some(Expression::Literal(Literal::Number(s))) => s.clone(),
27491 _ => return None,
27492 };
27493 (true, count)
27494 } else if iv.unit.is_none() {
27495 if let Some(Expression::Literal(Literal::String(s))) = &iv.this {
27497 let parts: Vec<&str> = s.trim().splitn(2, char::is_whitespace).collect();
27498 if parts.len() == 2 && parts[1].eq_ignore_ascii_case("WEEK") {
27499 (true, parts[0].to_string())
27500 } else {
27501 (false, String::new())
27502 }
27503 } else {
27504 (false, String::new())
27505 }
27506 } else {
27507 (false, String::new())
27508 };
27509
27510 if is_week {
27511 let count_expr = Expression::Literal(Literal::Number(count_str));
27513 let day_interval = Expression::Interval(Box::new(Interval {
27514 this: Some(Expression::Literal(Literal::String("7".to_string()))),
27515 unit: Some(IntervalUnitSpec::Simple {
27516 unit: IntervalUnit::Day,
27517 use_plural: false,
27518 }),
27519 }));
27520 let mul = Expression::Mul(Box::new(BinaryOp {
27521 left: count_expr,
27522 right: day_interval,
27523 left_comments: vec![],
27524 operator_comments: vec![],
27525 trailing_comments: vec![],
27526 inferred_type: None,
27527 }));
27528 return Some(Expression::Paren(Box::new(Paren {
27529 this: mul,
27530 trailing_comments: vec![],
27531 })));
27532 }
27533 }
27534 None
27535 }
27536
27537 fn generate_generate_timestamp_array(&mut self, e: &GenerateTimestampArray) -> Result<()> {
27538 self.write_keyword("GENERATE_TIMESTAMP_ARRAY");
27540 self.write("(");
27541 let mut first = true;
27542 if let Some(start) = &e.start {
27543 self.generate_expression(start)?;
27544 first = false;
27545 }
27546 if let Some(end) = &e.end {
27547 if !first {
27548 self.write(", ");
27549 }
27550 self.generate_expression(end)?;
27551 first = false;
27552 }
27553 if let Some(step) = &e.step {
27554 if !first {
27555 self.write(", ");
27556 }
27557 self.generate_expression(step)?;
27558 }
27559 self.write(")");
27560 Ok(())
27561 }
27562
27563 fn generate_generated_as_identity_column_constraint(
27564 &mut self,
27565 e: &GeneratedAsIdentityColumnConstraint,
27566 ) -> Result<()> {
27567 use crate::dialects::DialectType;
27568
27569 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
27571 self.write_keyword("AUTOINCREMENT");
27572 if let Some(start) = &e.start {
27573 self.write_keyword(" START ");
27574 self.generate_expression(start)?;
27575 }
27576 if let Some(increment) = &e.increment {
27577 self.write_keyword(" INCREMENT ");
27578 self.generate_expression(increment)?;
27579 }
27580 return Ok(());
27581 }
27582
27583 self.write_keyword("GENERATED");
27585 if let Some(this) = &e.this {
27586 if let Expression::Boolean(b) = this.as_ref() {
27588 if b.value {
27589 self.write_keyword(" ALWAYS");
27590 } else {
27591 self.write_keyword(" BY DEFAULT");
27592 if e.on_null.is_some() {
27593 self.write_keyword(" ON NULL");
27594 }
27595 }
27596 } else {
27597 self.write_keyword(" ALWAYS");
27598 }
27599 }
27600 self.write_keyword(" AS IDENTITY");
27601 let has_options = e.start.is_some()
27603 || e.increment.is_some()
27604 || e.minvalue.is_some()
27605 || e.maxvalue.is_some();
27606 if has_options {
27607 self.write(" (");
27608 let mut first = true;
27609 if let Some(start) = &e.start {
27610 self.write_keyword("START WITH ");
27611 self.generate_expression(start)?;
27612 first = false;
27613 }
27614 if let Some(increment) = &e.increment {
27615 if !first {
27616 self.write(" ");
27617 }
27618 self.write_keyword("INCREMENT BY ");
27619 self.generate_expression(increment)?;
27620 first = false;
27621 }
27622 if let Some(minvalue) = &e.minvalue {
27623 if !first {
27624 self.write(" ");
27625 }
27626 self.write_keyword("MINVALUE ");
27627 self.generate_expression(minvalue)?;
27628 first = false;
27629 }
27630 if let Some(maxvalue) = &e.maxvalue {
27631 if !first {
27632 self.write(" ");
27633 }
27634 self.write_keyword("MAXVALUE ");
27635 self.generate_expression(maxvalue)?;
27636 }
27637 self.write(")");
27638 }
27639 Ok(())
27640 }
27641
27642 fn generate_generated_as_row_column_constraint(
27643 &mut self,
27644 e: &GeneratedAsRowColumnConstraint,
27645 ) -> Result<()> {
27646 self.write_keyword("GENERATED ALWAYS AS ROW ");
27648 if e.start.is_some() {
27649 self.write_keyword("START");
27650 } else {
27651 self.write_keyword("END");
27652 }
27653 if e.hidden.is_some() {
27654 self.write_keyword(" HIDDEN");
27655 }
27656 Ok(())
27657 }
27658
27659 fn generate_get(&mut self, e: &Get) -> Result<()> {
27660 self.write_keyword("GET");
27662 self.write_space();
27663 self.generate_expression(&e.this)?;
27664 if let Some(target) = &e.target {
27665 self.write_space();
27666 self.generate_expression(target)?;
27667 }
27668 for prop in &e.properties {
27669 self.write_space();
27670 self.generate_expression(prop)?;
27671 }
27672 Ok(())
27673 }
27674
27675 fn generate_get_extract(&mut self, e: &GetExtract) -> Result<()> {
27676 self.generate_expression(&e.this)?;
27678 self.write("[");
27679 self.generate_expression(&e.expression)?;
27680 self.write("]");
27681 Ok(())
27682 }
27683
27684 fn generate_getbit(&mut self, e: &Getbit) -> Result<()> {
27685 self.write_keyword("GETBIT");
27687 self.write("(");
27688 self.generate_expression(&e.this)?;
27689 self.write(", ");
27690 self.generate_expression(&e.expression)?;
27691 self.write(")");
27692 Ok(())
27693 }
27694
27695 fn generate_grant_principal(&mut self, e: &GrantPrincipal) -> Result<()> {
27696 if e.is_role {
27698 self.write_keyword("ROLE");
27699 self.write_space();
27700 } else if e.is_group {
27701 self.write_keyword("GROUP");
27702 self.write_space();
27703 }
27704 self.write(&e.name.name);
27705 Ok(())
27706 }
27707
27708 fn generate_grant_privilege(&mut self, e: &GrantPrivilege) -> Result<()> {
27709 self.generate_expression(&e.this)?;
27711 if !e.expressions.is_empty() {
27712 self.write("(");
27713 for (i, expr) in e.expressions.iter().enumerate() {
27714 if i > 0 {
27715 self.write(", ");
27716 }
27717 self.generate_expression(expr)?;
27718 }
27719 self.write(")");
27720 }
27721 Ok(())
27722 }
27723
27724 fn generate_group(&mut self, e: &Group) -> Result<()> {
27725 self.write_keyword("GROUP BY");
27727 match e.all {
27729 Some(true) => {
27730 self.write_space();
27731 self.write_keyword("ALL");
27732 }
27733 Some(false) => {
27734 self.write_space();
27735 self.write_keyword("DISTINCT");
27736 }
27737 None => {}
27738 }
27739 if !e.expressions.is_empty() {
27740 self.write_space();
27741 for (i, expr) in e.expressions.iter().enumerate() {
27742 if i > 0 {
27743 self.write(", ");
27744 }
27745 self.generate_expression(expr)?;
27746 }
27747 }
27748 if let Some(cube) = &e.cube {
27750 if !e.expressions.is_empty() {
27751 self.write(", ");
27752 } else {
27753 self.write_space();
27754 }
27755 self.generate_expression(cube)?;
27756 }
27757 if let Some(rollup) = &e.rollup {
27758 if !e.expressions.is_empty() || e.cube.is_some() {
27759 self.write(", ");
27760 } else {
27761 self.write_space();
27762 }
27763 self.generate_expression(rollup)?;
27764 }
27765 if let Some(grouping_sets) = &e.grouping_sets {
27766 if !e.expressions.is_empty() || e.cube.is_some() || e.rollup.is_some() {
27767 self.write(", ");
27768 } else {
27769 self.write_space();
27770 }
27771 self.generate_expression(grouping_sets)?;
27772 }
27773 if let Some(totals) = &e.totals {
27774 self.write_space();
27775 self.write_keyword("WITH TOTALS");
27776 self.generate_expression(totals)?;
27777 }
27778 Ok(())
27779 }
27780
27781 fn generate_group_by(&mut self, e: &GroupBy) -> Result<()> {
27782 self.write_keyword("GROUP BY");
27784 match e.all {
27786 Some(true) => {
27787 self.write_space();
27788 self.write_keyword("ALL");
27789 }
27790 Some(false) => {
27791 self.write_space();
27792 self.write_keyword("DISTINCT");
27793 }
27794 None => {}
27795 }
27796
27797 let mut trailing_cube = false;
27800 let mut trailing_rollup = false;
27801 let mut regular_expressions: Vec<&Expression> = Vec::new();
27802
27803 for expr in &e.expressions {
27804 match expr {
27805 Expression::Cube(c) if c.expressions.is_empty() => {
27806 trailing_cube = true;
27807 }
27808 Expression::Rollup(r) if r.expressions.is_empty() => {
27809 trailing_rollup = true;
27810 }
27811 _ => {
27812 regular_expressions.push(expr);
27813 }
27814 }
27815 }
27816
27817 if self.config.pretty {
27819 self.write_newline();
27820 self.indent_level += 1;
27821 for (i, expr) in regular_expressions.iter().enumerate() {
27822 if i > 0 {
27823 self.write(",");
27824 self.write_newline();
27825 }
27826 self.write_indent();
27827 self.generate_expression(expr)?;
27828 }
27829 self.indent_level -= 1;
27830 } else {
27831 self.write_space();
27832 for (i, expr) in regular_expressions.iter().enumerate() {
27833 if i > 0 {
27834 self.write(", ");
27835 }
27836 self.generate_expression(expr)?;
27837 }
27838 }
27839
27840 if trailing_cube {
27842 self.write_space();
27843 self.write_keyword("WITH CUBE");
27844 } else if trailing_rollup {
27845 self.write_space();
27846 self.write_keyword("WITH ROLLUP");
27847 }
27848
27849 if e.totals {
27851 self.write_space();
27852 self.write_keyword("WITH TOTALS");
27853 }
27854
27855 Ok(())
27856 }
27857
27858 fn generate_grouping(&mut self, e: &Grouping) -> Result<()> {
27859 self.write_keyword("GROUPING");
27861 self.write("(");
27862 for (i, expr) in e.expressions.iter().enumerate() {
27863 if i > 0 {
27864 self.write(", ");
27865 }
27866 self.generate_expression(expr)?;
27867 }
27868 self.write(")");
27869 Ok(())
27870 }
27871
27872 fn generate_grouping_id(&mut self, e: &GroupingId) -> Result<()> {
27873 self.write_keyword("GROUPING_ID");
27875 self.write("(");
27876 for (i, expr) in e.expressions.iter().enumerate() {
27877 if i > 0 {
27878 self.write(", ");
27879 }
27880 self.generate_expression(expr)?;
27881 }
27882 self.write(")");
27883 Ok(())
27884 }
27885
27886 fn generate_grouping_sets(&mut self, e: &GroupingSets) -> Result<()> {
27887 self.write_keyword("GROUPING SETS");
27889 self.write(" (");
27890 for (i, expr) in e.expressions.iter().enumerate() {
27891 if i > 0 {
27892 self.write(", ");
27893 }
27894 self.generate_expression(expr)?;
27895 }
27896 self.write(")");
27897 Ok(())
27898 }
27899
27900 fn generate_hash_agg(&mut self, e: &HashAgg) -> Result<()> {
27901 self.write_keyword("HASH_AGG");
27903 self.write("(");
27904 self.generate_expression(&e.this)?;
27905 for expr in &e.expressions {
27906 self.write(", ");
27907 self.generate_expression(expr)?;
27908 }
27909 self.write(")");
27910 Ok(())
27911 }
27912
27913 fn generate_having(&mut self, e: &Having) -> Result<()> {
27914 self.write_keyword("HAVING");
27916 self.write_space();
27917 self.generate_expression(&e.this)?;
27918 Ok(())
27919 }
27920
27921 fn generate_having_max(&mut self, e: &HavingMax) -> Result<()> {
27922 self.generate_expression(&e.this)?;
27924 self.write_space();
27925 self.write_keyword("HAVING");
27926 self.write_space();
27927 if e.max.is_some() {
27928 self.write_keyword("MAX");
27929 } else {
27930 self.write_keyword("MIN");
27931 }
27932 self.write_space();
27933 self.generate_expression(&e.expression)?;
27934 Ok(())
27935 }
27936
27937 fn generate_heredoc(&mut self, e: &Heredoc) -> Result<()> {
27938 use crate::dialects::DialectType;
27939 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
27941 if let Expression::Literal(Literal::String(ref s)) = *e.this {
27943 return self.generate_string_literal(s);
27944 }
27945 }
27946 if matches!(
27948 self.config.dialect,
27949 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
27950 ) {
27951 self.write("$");
27952 if let Some(tag) = &e.tag {
27953 self.generate_expression(tag)?;
27954 }
27955 self.write("$");
27956 self.generate_expression(&e.this)?;
27957 self.write("$");
27958 if let Some(tag) = &e.tag {
27959 self.generate_expression(tag)?;
27960 }
27961 self.write("$");
27962 return Ok(());
27963 }
27964 self.write("$");
27966 if let Some(tag) = &e.tag {
27967 self.generate_expression(tag)?;
27968 }
27969 self.write("$");
27970 self.generate_expression(&e.this)?;
27971 self.write("$");
27972 if let Some(tag) = &e.tag {
27973 self.generate_expression(tag)?;
27974 }
27975 self.write("$");
27976 Ok(())
27977 }
27978
27979 fn generate_hex_encode(&mut self, e: &HexEncode) -> Result<()> {
27980 self.write_keyword("HEX_ENCODE");
27982 self.write("(");
27983 self.generate_expression(&e.this)?;
27984 self.write(")");
27985 Ok(())
27986 }
27987
27988 fn generate_historical_data(&mut self, e: &HistoricalData) -> Result<()> {
27989 match e.this.as_ref() {
27992 Expression::Identifier(id) => self.write(&id.name),
27993 other => self.generate_expression(other)?,
27994 }
27995 self.write(" (");
27996 self.write(&e.kind);
27997 self.write(" => ");
27998 self.generate_expression(&e.expression)?;
27999 self.write(")");
28000 Ok(())
28001 }
28002
28003 fn generate_hll(&mut self, e: &Hll) -> Result<()> {
28004 self.write_keyword("HLL");
28006 self.write("(");
28007 self.generate_expression(&e.this)?;
28008 for expr in &e.expressions {
28009 self.write(", ");
28010 self.generate_expression(expr)?;
28011 }
28012 self.write(")");
28013 Ok(())
28014 }
28015
28016 fn generate_in_out_column_constraint(&mut self, e: &InOutColumnConstraint) -> Result<()> {
28017 if e.input_.is_some() && e.output.is_some() {
28019 self.write_keyword("IN OUT");
28020 } else if e.input_.is_some() {
28021 self.write_keyword("IN");
28022 } else if e.output.is_some() {
28023 self.write_keyword("OUT");
28024 }
28025 Ok(())
28026 }
28027
28028 fn generate_include_property(&mut self, e: &IncludeProperty) -> Result<()> {
28029 self.write_keyword("INCLUDE");
28031 self.write_space();
28032 self.generate_expression(&e.this)?;
28033 if let Some(column_def) = &e.column_def {
28034 self.write_space();
28035 self.generate_expression(column_def)?;
28036 }
28037 if let Some(alias) = &e.alias {
28038 self.write_space();
28039 self.write_keyword("AS");
28040 self.write_space();
28041 self.write(alias);
28042 }
28043 Ok(())
28044 }
28045
28046 fn generate_index(&mut self, e: &Index) -> Result<()> {
28047 if e.unique {
28049 self.write_keyword("UNIQUE");
28050 self.write_space();
28051 }
28052 if e.primary.is_some() {
28053 self.write_keyword("PRIMARY");
28054 self.write_space();
28055 }
28056 if e.amp.is_some() {
28057 self.write_keyword("AMP");
28058 self.write_space();
28059 }
28060 if e.table.is_none() {
28061 self.write_keyword("INDEX");
28062 self.write_space();
28063 }
28064 if let Some(name) = &e.this {
28065 self.generate_expression(name)?;
28066 self.write_space();
28067 }
28068 if let Some(table) = &e.table {
28069 self.write_keyword("ON");
28070 self.write_space();
28071 self.generate_expression(table)?;
28072 }
28073 if !e.params.is_empty() {
28074 self.write("(");
28075 for (i, param) in e.params.iter().enumerate() {
28076 if i > 0 {
28077 self.write(", ");
28078 }
28079 self.generate_expression(param)?;
28080 }
28081 self.write(")");
28082 }
28083 Ok(())
28084 }
28085
28086 fn generate_index_column_constraint(&mut self, e: &IndexColumnConstraint) -> Result<()> {
28087 if let Some(kind) = &e.kind {
28089 self.write(kind);
28090 self.write_space();
28091 }
28092 self.write_keyword("INDEX");
28093 if let Some(this) = &e.this {
28094 self.write_space();
28095 self.generate_expression(this)?;
28096 }
28097 if let Some(index_type) = &e.index_type {
28098 self.write_space();
28099 self.write_keyword("USING");
28100 self.write_space();
28101 self.generate_expression(index_type)?;
28102 }
28103 if !e.expressions.is_empty() {
28104 self.write(" (");
28105 for (i, expr) in e.expressions.iter().enumerate() {
28106 if i > 0 {
28107 self.write(", ");
28108 }
28109 self.generate_expression(expr)?;
28110 }
28111 self.write(")");
28112 }
28113 for opt in &e.options {
28114 self.write_space();
28115 self.generate_expression(opt)?;
28116 }
28117 Ok(())
28118 }
28119
28120 fn generate_index_constraint_option(&mut self, e: &IndexConstraintOption) -> Result<()> {
28121 if let Some(key_block_size) = &e.key_block_size {
28123 self.write_keyword("KEY_BLOCK_SIZE");
28124 self.write(" = ");
28125 self.generate_expression(key_block_size)?;
28126 } else if let Some(using) = &e.using {
28127 self.write_keyword("USING");
28128 self.write_space();
28129 self.generate_expression(using)?;
28130 } else if let Some(parser) = &e.parser {
28131 self.write_keyword("WITH PARSER");
28132 self.write_space();
28133 self.generate_expression(parser)?;
28134 } else if let Some(comment) = &e.comment {
28135 self.write_keyword("COMMENT");
28136 self.write_space();
28137 self.generate_expression(comment)?;
28138 } else if let Some(visible) = &e.visible {
28139 self.generate_expression(visible)?;
28140 } else if let Some(engine_attr) = &e.engine_attr {
28141 self.write_keyword("ENGINE_ATTRIBUTE");
28142 self.write(" = ");
28143 self.generate_expression(engine_attr)?;
28144 } else if let Some(secondary_engine_attr) = &e.secondary_engine_attr {
28145 self.write_keyword("SECONDARY_ENGINE_ATTRIBUTE");
28146 self.write(" = ");
28147 self.generate_expression(secondary_engine_attr)?;
28148 }
28149 Ok(())
28150 }
28151
28152 fn generate_index_parameters(&mut self, e: &IndexParameters) -> Result<()> {
28153 if let Some(using) = &e.using {
28155 self.write_keyword("USING");
28156 self.write_space();
28157 self.generate_expression(using)?;
28158 }
28159 if !e.columns.is_empty() {
28160 self.write("(");
28161 for (i, col) in e.columns.iter().enumerate() {
28162 if i > 0 {
28163 self.write(", ");
28164 }
28165 self.generate_expression(col)?;
28166 }
28167 self.write(")");
28168 }
28169 if let Some(partition_by) = &e.partition_by {
28170 self.write_space();
28171 self.write_keyword("PARTITION BY");
28172 self.write_space();
28173 self.generate_expression(partition_by)?;
28174 }
28175 if let Some(where_) = &e.where_ {
28176 self.write_space();
28177 self.generate_expression(where_)?;
28178 }
28179 if let Some(include) = &e.include {
28180 self.write_space();
28181 self.write_keyword("INCLUDE");
28182 self.write(" (");
28183 self.generate_expression(include)?;
28184 self.write(")");
28185 }
28186 if let Some(with_storage) = &e.with_storage {
28187 self.write_space();
28188 self.write_keyword("WITH");
28189 self.write(" (");
28190 self.generate_expression(with_storage)?;
28191 self.write(")");
28192 }
28193 if let Some(tablespace) = &e.tablespace {
28194 self.write_space();
28195 self.write_keyword("USING INDEX TABLESPACE");
28196 self.write_space();
28197 self.generate_expression(tablespace)?;
28198 }
28199 Ok(())
28200 }
28201
28202 fn generate_index_table_hint(&mut self, e: &IndexTableHint) -> Result<()> {
28203 if let Expression::Identifier(id) = &*e.this {
28207 self.write_keyword(&id.name);
28208 } else {
28209 self.generate_expression(&e.this)?;
28210 }
28211 self.write_space();
28212 self.write_keyword("INDEX");
28213 if let Some(target) = &e.target {
28214 self.write_space();
28215 self.write_keyword("FOR");
28216 self.write_space();
28217 if let Expression::Identifier(id) = &**target {
28218 self.write_keyword(&id.name);
28219 } else {
28220 self.generate_expression(target)?;
28221 }
28222 }
28223 self.write(" (");
28225 for (i, expr) in e.expressions.iter().enumerate() {
28226 if i > 0 {
28227 self.write(", ");
28228 }
28229 self.generate_expression(expr)?;
28230 }
28231 self.write(")");
28232 Ok(())
28233 }
28234
28235 fn generate_inherits_property(&mut self, e: &InheritsProperty) -> Result<()> {
28236 self.write_keyword("INHERITS");
28238 self.write(" (");
28239 for (i, expr) in e.expressions.iter().enumerate() {
28240 if i > 0 {
28241 self.write(", ");
28242 }
28243 self.generate_expression(expr)?;
28244 }
28245 self.write(")");
28246 Ok(())
28247 }
28248
28249 fn generate_input_model_property(&mut self, e: &InputModelProperty) -> Result<()> {
28250 self.write_keyword("INPUT");
28252 self.write("(");
28253 self.generate_expression(&e.this)?;
28254 self.write(")");
28255 Ok(())
28256 }
28257
28258 fn generate_input_output_format(&mut self, e: &InputOutputFormat) -> Result<()> {
28259 if let Some(input_format) = &e.input_format {
28261 self.write_keyword("INPUTFORMAT");
28262 self.write_space();
28263 self.generate_expression(input_format)?;
28264 }
28265 if let Some(output_format) = &e.output_format {
28266 if e.input_format.is_some() {
28267 self.write(" ");
28268 }
28269 self.write_keyword("OUTPUTFORMAT");
28270 self.write_space();
28271 self.generate_expression(output_format)?;
28272 }
28273 Ok(())
28274 }
28275
28276 fn generate_install(&mut self, e: &Install) -> Result<()> {
28277 if e.force.is_some() {
28279 self.write_keyword("FORCE");
28280 self.write_space();
28281 }
28282 self.write_keyword("INSTALL");
28283 self.write_space();
28284 self.generate_expression(&e.this)?;
28285 if let Some(from) = &e.from_ {
28286 self.write_space();
28287 self.write_keyword("FROM");
28288 self.write_space();
28289 self.generate_expression(from)?;
28290 }
28291 Ok(())
28292 }
28293
28294 fn generate_interval_op(&mut self, e: &IntervalOp) -> Result<()> {
28295 self.write_keyword("INTERVAL");
28297 self.write_space();
28298 self.generate_expression(&e.expression)?;
28300 if let Some(unit) = &e.unit {
28301 self.write_space();
28302 self.write(unit);
28303 }
28304 Ok(())
28305 }
28306
28307 fn generate_interval_span(&mut self, e: &IntervalSpan) -> Result<()> {
28308 self.write(&format!("{:?}", e.this).to_uppercase());
28310 self.write_space();
28311 self.write_keyword("TO");
28312 self.write_space();
28313 self.write(&format!("{:?}", e.expression).to_uppercase());
28314 Ok(())
28315 }
28316
28317 fn generate_into_clause(&mut self, e: &IntoClause) -> Result<()> {
28318 self.write_keyword("INTO");
28320 if e.temporary {
28321 self.write_keyword(" TEMPORARY");
28322 }
28323 if e.unlogged.is_some() {
28324 self.write_keyword(" UNLOGGED");
28325 }
28326 if let Some(this) = &e.this {
28327 self.write_space();
28328 self.generate_expression(this)?;
28329 }
28330 if !e.expressions.is_empty() {
28331 self.write(" (");
28332 for (i, expr) in e.expressions.iter().enumerate() {
28333 if i > 0 {
28334 self.write(", ");
28335 }
28336 self.generate_expression(expr)?;
28337 }
28338 self.write(")");
28339 }
28340 Ok(())
28341 }
28342
28343 fn generate_introducer(&mut self, e: &Introducer) -> Result<()> {
28344 self.generate_expression(&e.this)?;
28346 self.write_space();
28347 self.generate_expression(&e.expression)?;
28348 Ok(())
28349 }
28350
28351 fn generate_isolated_loading_property(&mut self, e: &IsolatedLoadingProperty) -> Result<()> {
28352 self.write_keyword("WITH");
28354 if e.no.is_some() {
28355 self.write_keyword(" NO");
28356 }
28357 if e.concurrent.is_some() {
28358 self.write_keyword(" CONCURRENT");
28359 }
28360 self.write_keyword(" ISOLATED LOADING");
28361 if let Some(target) = &e.target {
28362 self.write_space();
28363 self.generate_expression(target)?;
28364 }
28365 Ok(())
28366 }
28367
28368 fn generate_json(&mut self, e: &JSON) -> Result<()> {
28369 self.write_keyword("JSON");
28371 if let Some(this) = &e.this {
28372 self.write_space();
28373 self.generate_expression(this)?;
28374 }
28375 if let Some(with_) = &e.with_ {
28376 if let Expression::Boolean(b) = with_.as_ref() {
28378 if b.value {
28379 self.write_keyword(" WITH");
28380 } else {
28381 self.write_keyword(" WITHOUT");
28382 }
28383 }
28384 }
28385 if e.unique {
28386 self.write_keyword(" UNIQUE KEYS");
28387 }
28388 Ok(())
28389 }
28390
28391 fn generate_json_array(&mut self, e: &JSONArray) -> Result<()> {
28392 self.write_keyword("JSON_ARRAY");
28394 self.write("(");
28395 for (i, expr) in e.expressions.iter().enumerate() {
28396 if i > 0 {
28397 self.write(", ");
28398 }
28399 self.generate_expression(expr)?;
28400 }
28401 if let Some(null_handling) = &e.null_handling {
28402 self.write_space();
28403 self.generate_expression(null_handling)?;
28404 }
28405 if let Some(return_type) = &e.return_type {
28406 self.write_space();
28407 self.write_keyword("RETURNING");
28408 self.write_space();
28409 self.generate_expression(return_type)?;
28410 }
28411 if e.strict.is_some() {
28412 self.write_space();
28413 self.write_keyword("STRICT");
28414 }
28415 self.write(")");
28416 Ok(())
28417 }
28418
28419 fn generate_json_array_agg_struct(&mut self, e: &JSONArrayAgg) -> Result<()> {
28420 self.write_keyword("JSON_ARRAYAGG");
28422 self.write("(");
28423 self.generate_expression(&e.this)?;
28424 if let Some(order) = &e.order {
28425 self.write_space();
28426 if let Expression::OrderBy(ob) = order.as_ref() {
28428 self.write_keyword("ORDER BY");
28429 self.write_space();
28430 for (i, ord) in ob.expressions.iter().enumerate() {
28431 if i > 0 {
28432 self.write(", ");
28433 }
28434 self.generate_ordered(ord)?;
28435 }
28436 } else {
28437 self.generate_expression(order)?;
28439 }
28440 }
28441 if let Some(null_handling) = &e.null_handling {
28442 self.write_space();
28443 self.generate_expression(null_handling)?;
28444 }
28445 if let Some(return_type) = &e.return_type {
28446 self.write_space();
28447 self.write_keyword("RETURNING");
28448 self.write_space();
28449 self.generate_expression(return_type)?;
28450 }
28451 if e.strict.is_some() {
28452 self.write_space();
28453 self.write_keyword("STRICT");
28454 }
28455 self.write(")");
28456 Ok(())
28457 }
28458
28459 fn generate_json_object_agg_struct(&mut self, e: &JSONObjectAgg) -> Result<()> {
28460 self.write_keyword("JSON_OBJECTAGG");
28462 self.write("(");
28463 for (i, expr) in e.expressions.iter().enumerate() {
28464 if i > 0 {
28465 self.write(", ");
28466 }
28467 self.generate_expression(expr)?;
28468 }
28469 if let Some(null_handling) = &e.null_handling {
28470 self.write_space();
28471 self.generate_expression(null_handling)?;
28472 }
28473 if let Some(unique_keys) = &e.unique_keys {
28474 self.write_space();
28475 if let Expression::Boolean(b) = unique_keys.as_ref() {
28476 if b.value {
28477 self.write_keyword("WITH UNIQUE KEYS");
28478 } else {
28479 self.write_keyword("WITHOUT UNIQUE KEYS");
28480 }
28481 }
28482 }
28483 if let Some(return_type) = &e.return_type {
28484 self.write_space();
28485 self.write_keyword("RETURNING");
28486 self.write_space();
28487 self.generate_expression(return_type)?;
28488 }
28489 self.write(")");
28490 Ok(())
28491 }
28492
28493 fn generate_json_array_append(&mut self, e: &JSONArrayAppend) -> Result<()> {
28494 self.write_keyword("JSON_ARRAY_APPEND");
28496 self.write("(");
28497 self.generate_expression(&e.this)?;
28498 for expr in &e.expressions {
28499 self.write(", ");
28500 self.generate_expression(expr)?;
28501 }
28502 self.write(")");
28503 Ok(())
28504 }
28505
28506 fn generate_json_array_contains(&mut self, e: &JSONArrayContains) -> Result<()> {
28507 self.write_keyword("JSON_ARRAY_CONTAINS");
28509 self.write("(");
28510 self.generate_expression(&e.this)?;
28511 self.write(", ");
28512 self.generate_expression(&e.expression)?;
28513 self.write(")");
28514 Ok(())
28515 }
28516
28517 fn generate_json_array_insert(&mut self, e: &JSONArrayInsert) -> Result<()> {
28518 self.write_keyword("JSON_ARRAY_INSERT");
28520 self.write("(");
28521 self.generate_expression(&e.this)?;
28522 for expr in &e.expressions {
28523 self.write(", ");
28524 self.generate_expression(expr)?;
28525 }
28526 self.write(")");
28527 Ok(())
28528 }
28529
28530 fn generate_jsonb_exists(&mut self, e: &JSONBExists) -> Result<()> {
28531 self.write_keyword("JSONB_EXISTS");
28533 self.write("(");
28534 self.generate_expression(&e.this)?;
28535 if let Some(path) = &e.path {
28536 self.write(", ");
28537 self.generate_expression(path)?;
28538 }
28539 self.write(")");
28540 Ok(())
28541 }
28542
28543 fn generate_jsonb_extract_scalar(&mut self, e: &JSONBExtractScalar) -> Result<()> {
28544 self.write_keyword("JSONB_EXTRACT_SCALAR");
28546 self.write("(");
28547 self.generate_expression(&e.this)?;
28548 self.write(", ");
28549 self.generate_expression(&e.expression)?;
28550 self.write(")");
28551 Ok(())
28552 }
28553
28554 fn generate_jsonb_object_agg(&mut self, e: &JSONBObjectAgg) -> Result<()> {
28555 self.write_keyword("JSONB_OBJECT_AGG");
28557 self.write("(");
28558 self.generate_expression(&e.this)?;
28559 self.write(", ");
28560 self.generate_expression(&e.expression)?;
28561 self.write(")");
28562 Ok(())
28563 }
28564
28565 fn generate_json_column_def(&mut self, e: &JSONColumnDef) -> Result<()> {
28566 if let Some(nested_schema) = &e.nested_schema {
28568 self.write_keyword("NESTED");
28569 if let Some(path) = &e.path {
28570 self.write_space();
28571 self.write_keyword("PATH");
28572 self.write_space();
28573 self.generate_expression(path)?;
28574 }
28575 self.write_space();
28576 self.generate_expression(nested_schema)?;
28577 } else {
28578 if let Some(this) = &e.this {
28579 self.generate_expression(this)?;
28580 }
28581 if let Some(kind) = &e.kind {
28582 self.write_space();
28583 self.write(kind);
28584 }
28585 if let Some(path) = &e.path {
28586 self.write_space();
28587 self.write_keyword("PATH");
28588 self.write_space();
28589 self.generate_expression(path)?;
28590 }
28591 if e.ordinality.is_some() {
28592 self.write_keyword(" FOR ORDINALITY");
28593 }
28594 }
28595 Ok(())
28596 }
28597
28598 fn generate_json_exists(&mut self, e: &JSONExists) -> Result<()> {
28599 self.write_keyword("JSON_EXISTS");
28601 self.write("(");
28602 self.generate_expression(&e.this)?;
28603 if let Some(path) = &e.path {
28604 self.write(", ");
28605 self.generate_expression(path)?;
28606 }
28607 if let Some(passing) = &e.passing {
28608 self.write_space();
28609 self.write_keyword("PASSING");
28610 self.write_space();
28611 self.generate_expression(passing)?;
28612 }
28613 if let Some(on_condition) = &e.on_condition {
28614 self.write_space();
28615 self.generate_expression(on_condition)?;
28616 }
28617 self.write(")");
28618 Ok(())
28619 }
28620
28621 fn generate_json_cast(&mut self, e: &JSONCast) -> Result<()> {
28622 self.generate_expression(&e.this)?;
28623 self.write(".:");
28624 self.generate_data_type(&e.to)?;
28625 Ok(())
28626 }
28627
28628 fn generate_json_extract_array(&mut self, e: &JSONExtractArray) -> Result<()> {
28629 self.write_keyword("JSON_EXTRACT_ARRAY");
28631 self.write("(");
28632 self.generate_expression(&e.this)?;
28633 if let Some(expr) = &e.expression {
28634 self.write(", ");
28635 self.generate_expression(expr)?;
28636 }
28637 self.write(")");
28638 Ok(())
28639 }
28640
28641 fn generate_json_extract_quote(&mut self, e: &JSONExtractQuote) -> Result<()> {
28642 if let Some(option) = &e.option {
28644 self.generate_expression(option)?;
28645 self.write_space();
28646 }
28647 self.write_keyword("QUOTES");
28648 if e.scalar.is_some() {
28649 self.write_keyword(" SCALAR_ONLY");
28650 }
28651 Ok(())
28652 }
28653
28654 fn generate_json_extract_scalar(&mut self, e: &JSONExtractScalar) -> Result<()> {
28655 self.write_keyword("JSON_EXTRACT_SCALAR");
28657 self.write("(");
28658 self.generate_expression(&e.this)?;
28659 self.write(", ");
28660 self.generate_expression(&e.expression)?;
28661 self.write(")");
28662 Ok(())
28663 }
28664
28665 fn generate_json_extract_path(&mut self, e: &JSONExtract) -> Result<()> {
28666 if e.variant_extract.is_some() {
28670 use crate::dialects::DialectType;
28671 if matches!(self.config.dialect, Some(DialectType::Databricks)) {
28672 self.generate_expression(&e.this)?;
28674 self.write(":");
28675 match e.expression.as_ref() {
28678 Expression::Literal(Literal::String(s)) => {
28679 self.write(s);
28680 }
28681 _ => {
28682 self.generate_expression(&e.expression)?;
28684 }
28685 }
28686 } else {
28687 self.write_keyword("GET_PATH");
28689 self.write("(");
28690 self.generate_expression(&e.this)?;
28691 self.write(", ");
28692 self.generate_expression(&e.expression)?;
28693 self.write(")");
28694 }
28695 } else {
28696 self.write_keyword("JSON_EXTRACT");
28697 self.write("(");
28698 self.generate_expression(&e.this)?;
28699 self.write(", ");
28700 self.generate_expression(&e.expression)?;
28701 for expr in &e.expressions {
28702 self.write(", ");
28703 self.generate_expression(expr)?;
28704 }
28705 self.write(")");
28706 }
28707 Ok(())
28708 }
28709
28710 fn generate_json_format(&mut self, e: &JSONFormat) -> Result<()> {
28711 if let Some(this) = &e.this {
28714 self.generate_expression(this)?;
28715 self.write_space();
28716 }
28717 self.write_keyword("FORMAT JSON");
28718 Ok(())
28719 }
28720
28721 fn generate_json_key_value(&mut self, e: &JSONKeyValue) -> Result<()> {
28722 self.generate_expression(&e.this)?;
28724 self.write(": ");
28725 self.generate_expression(&e.expression)?;
28726 Ok(())
28727 }
28728
28729 fn generate_json_keys(&mut self, e: &JSONKeys) -> Result<()> {
28730 self.write_keyword("JSON_KEYS");
28732 self.write("(");
28733 self.generate_expression(&e.this)?;
28734 if let Some(expr) = &e.expression {
28735 self.write(", ");
28736 self.generate_expression(expr)?;
28737 }
28738 for expr in &e.expressions {
28739 self.write(", ");
28740 self.generate_expression(expr)?;
28741 }
28742 self.write(")");
28743 Ok(())
28744 }
28745
28746 fn generate_json_keys_at_depth(&mut self, e: &JSONKeysAtDepth) -> Result<()> {
28747 self.write_keyword("JSON_KEYS");
28749 self.write("(");
28750 self.generate_expression(&e.this)?;
28751 if let Some(expr) = &e.expression {
28752 self.write(", ");
28753 self.generate_expression(expr)?;
28754 }
28755 self.write(")");
28756 Ok(())
28757 }
28758
28759 fn generate_json_path_expr(&mut self, e: &JSONPath) -> Result<()> {
28760 let mut path_str = String::new();
28763 for expr in &e.expressions {
28764 match expr {
28765 Expression::JSONPathRoot(_) => {
28766 path_str.push('$');
28767 }
28768 Expression::JSONPathKey(k) => {
28769 if let Expression::Literal(crate::expressions::Literal::String(s)) =
28771 k.this.as_ref()
28772 {
28773 path_str.push('.');
28774 let needs_quoting = s.chars().any(|c| !c.is_alphanumeric() && c != '_');
28776 if needs_quoting {
28777 path_str.push('"');
28778 path_str.push_str(s);
28779 path_str.push('"');
28780 } else {
28781 path_str.push_str(s);
28782 }
28783 }
28784 }
28785 Expression::JSONPathSubscript(s) => {
28786 if let Expression::Literal(crate::expressions::Literal::Number(n)) =
28788 s.this.as_ref()
28789 {
28790 path_str.push('[');
28791 path_str.push_str(n);
28792 path_str.push(']');
28793 }
28794 }
28795 _ => {
28796 let mut temp_gen = Self::with_config(self.config.clone());
28798 temp_gen.generate_expression(expr)?;
28799 path_str.push_str(&temp_gen.output);
28800 }
28801 }
28802 }
28803 self.write("'");
28805 self.write(&path_str);
28806 self.write("'");
28807 Ok(())
28808 }
28809
28810 fn generate_json_path_filter(&mut self, e: &JSONPathFilter) -> Result<()> {
28811 self.write("?(");
28813 self.generate_expression(&e.this)?;
28814 self.write(")");
28815 Ok(())
28816 }
28817
28818 fn generate_json_path_key(&mut self, e: &JSONPathKey) -> Result<()> {
28819 self.write(".");
28821 self.generate_expression(&e.this)?;
28822 Ok(())
28823 }
28824
28825 fn generate_json_path_recursive(&mut self, e: &JSONPathRecursive) -> Result<()> {
28826 self.write("..");
28828 if let Some(this) = &e.this {
28829 self.generate_expression(this)?;
28830 }
28831 Ok(())
28832 }
28833
28834 fn generate_json_path_root(&mut self) -> Result<()> {
28835 self.write("$");
28837 Ok(())
28838 }
28839
28840 fn generate_json_path_script(&mut self, e: &JSONPathScript) -> Result<()> {
28841 self.write("(");
28843 self.generate_expression(&e.this)?;
28844 self.write(")");
28845 Ok(())
28846 }
28847
28848 fn generate_json_path_selector(&mut self, e: &JSONPathSelector) -> Result<()> {
28849 self.generate_expression(&e.this)?;
28851 Ok(())
28852 }
28853
28854 fn generate_json_path_slice(&mut self, e: &JSONPathSlice) -> Result<()> {
28855 self.write("[");
28857 if let Some(start) = &e.start {
28858 self.generate_expression(start)?;
28859 }
28860 self.write(":");
28861 if let Some(end) = &e.end {
28862 self.generate_expression(end)?;
28863 }
28864 if let Some(step) = &e.step {
28865 self.write(":");
28866 self.generate_expression(step)?;
28867 }
28868 self.write("]");
28869 Ok(())
28870 }
28871
28872 fn generate_json_path_subscript(&mut self, e: &JSONPathSubscript) -> Result<()> {
28873 self.write("[");
28875 self.generate_expression(&e.this)?;
28876 self.write("]");
28877 Ok(())
28878 }
28879
28880 fn generate_json_path_union(&mut self, e: &JSONPathUnion) -> Result<()> {
28881 self.write("[");
28883 for (i, expr) in e.expressions.iter().enumerate() {
28884 if i > 0 {
28885 self.write(", ");
28886 }
28887 self.generate_expression(expr)?;
28888 }
28889 self.write("]");
28890 Ok(())
28891 }
28892
28893 fn generate_json_remove(&mut self, e: &JSONRemove) -> Result<()> {
28894 self.write_keyword("JSON_REMOVE");
28896 self.write("(");
28897 self.generate_expression(&e.this)?;
28898 for expr in &e.expressions {
28899 self.write(", ");
28900 self.generate_expression(expr)?;
28901 }
28902 self.write(")");
28903 Ok(())
28904 }
28905
28906 fn generate_json_schema(&mut self, e: &JSONSchema) -> Result<()> {
28907 self.write_keyword("COLUMNS");
28910 self.write("(");
28911
28912 if self.config.pretty && !e.expressions.is_empty() {
28913 let mut expr_strings: Vec<String> = Vec::with_capacity(e.expressions.len());
28915 for expr in &e.expressions {
28916 let mut temp_gen = Generator::with_config(self.config.clone());
28917 temp_gen.generate_expression(expr)?;
28918 expr_strings.push(temp_gen.output);
28919 }
28920
28921 if self.too_wide(&expr_strings) {
28923 self.write_newline();
28925 self.indent_level += 1;
28926 for (i, expr_str) in expr_strings.iter().enumerate() {
28927 if i > 0 {
28928 self.write(",");
28929 self.write_newline();
28930 }
28931 self.write_indent();
28932 self.write(expr_str);
28933 }
28934 self.write_newline();
28935 self.indent_level -= 1;
28936 self.write_indent();
28937 } else {
28938 for (i, expr_str) in expr_strings.iter().enumerate() {
28940 if i > 0 {
28941 self.write(", ");
28942 }
28943 self.write(expr_str);
28944 }
28945 }
28946 } else {
28947 for (i, expr) in e.expressions.iter().enumerate() {
28949 if i > 0 {
28950 self.write(", ");
28951 }
28952 self.generate_expression(expr)?;
28953 }
28954 }
28955 self.write(")");
28956 Ok(())
28957 }
28958
28959 fn generate_json_set(&mut self, e: &JSONSet) -> Result<()> {
28960 self.write_keyword("JSON_SET");
28962 self.write("(");
28963 self.generate_expression(&e.this)?;
28964 for expr in &e.expressions {
28965 self.write(", ");
28966 self.generate_expression(expr)?;
28967 }
28968 self.write(")");
28969 Ok(())
28970 }
28971
28972 fn generate_json_strip_nulls(&mut self, e: &JSONStripNulls) -> Result<()> {
28973 self.write_keyword("JSON_STRIP_NULLS");
28975 self.write("(");
28976 self.generate_expression(&e.this)?;
28977 if let Some(expr) = &e.expression {
28978 self.write(", ");
28979 self.generate_expression(expr)?;
28980 }
28981 self.write(")");
28982 Ok(())
28983 }
28984
28985 fn generate_json_table(&mut self, e: &JSONTable) -> Result<()> {
28986 self.write_keyword("JSON_TABLE");
28988 self.write("(");
28989 self.generate_expression(&e.this)?;
28990 if let Some(path) = &e.path {
28991 self.write(", ");
28992 self.generate_expression(path)?;
28993 }
28994 if let Some(error_handling) = &e.error_handling {
28995 self.write_space();
28996 self.generate_expression(error_handling)?;
28997 }
28998 if let Some(empty_handling) = &e.empty_handling {
28999 self.write_space();
29000 self.generate_expression(empty_handling)?;
29001 }
29002 if let Some(schema) = &e.schema {
29003 self.write_space();
29004 self.generate_expression(schema)?;
29005 }
29006 self.write(")");
29007 Ok(())
29008 }
29009
29010 fn generate_json_type(&mut self, e: &JSONType) -> Result<()> {
29011 self.write_keyword("JSON_TYPE");
29013 self.write("(");
29014 self.generate_expression(&e.this)?;
29015 self.write(")");
29016 Ok(())
29017 }
29018
29019 fn generate_json_value(&mut self, e: &JSONValue) -> Result<()> {
29020 self.write_keyword("JSON_VALUE");
29022 self.write("(");
29023 self.generate_expression(&e.this)?;
29024 if let Some(path) = &e.path {
29025 self.write(", ");
29026 self.generate_expression(path)?;
29027 }
29028 if let Some(returning) = &e.returning {
29029 self.write_space();
29030 self.write_keyword("RETURNING");
29031 self.write_space();
29032 self.generate_expression(returning)?;
29033 }
29034 if let Some(on_condition) = &e.on_condition {
29035 self.write_space();
29036 self.generate_expression(on_condition)?;
29037 }
29038 self.write(")");
29039 Ok(())
29040 }
29041
29042 fn generate_json_value_array(&mut self, e: &JSONValueArray) -> Result<()> {
29043 self.write_keyword("JSON_VALUE_ARRAY");
29045 self.write("(");
29046 self.generate_expression(&e.this)?;
29047 self.write(")");
29048 Ok(())
29049 }
29050
29051 fn generate_jarowinkler_similarity(&mut self, e: &JarowinklerSimilarity) -> Result<()> {
29052 self.write_keyword("JAROWINKLER_SIMILARITY");
29054 self.write("(");
29055 self.generate_expression(&e.this)?;
29056 self.write(", ");
29057 self.generate_expression(&e.expression)?;
29058 self.write(")");
29059 Ok(())
29060 }
29061
29062 fn generate_join_hint(&mut self, e: &JoinHint) -> Result<()> {
29063 self.generate_expression(&e.this)?;
29065 self.write("(");
29066 for (i, expr) in e.expressions.iter().enumerate() {
29067 if i > 0 {
29068 self.write(", ");
29069 }
29070 self.generate_expression(expr)?;
29071 }
29072 self.write(")");
29073 Ok(())
29074 }
29075
29076 fn generate_journal_property(&mut self, e: &JournalProperty) -> Result<()> {
29077 if e.no.is_some() {
29079 self.write_keyword("NO ");
29080 }
29081 if let Some(local) = &e.local {
29082 self.generate_expression(local)?;
29083 self.write_space();
29084 }
29085 if e.dual.is_some() {
29086 self.write_keyword("DUAL ");
29087 }
29088 if e.before.is_some() {
29089 self.write_keyword("BEFORE ");
29090 }
29091 if e.after.is_some() {
29092 self.write_keyword("AFTER ");
29093 }
29094 self.write_keyword("JOURNAL");
29095 Ok(())
29096 }
29097
29098 fn generate_language_property(&mut self, e: &LanguageProperty) -> Result<()> {
29099 self.write_keyword("LANGUAGE");
29101 self.write_space();
29102 self.generate_expression(&e.this)?;
29103 Ok(())
29104 }
29105
29106 fn generate_lateral(&mut self, e: &Lateral) -> Result<()> {
29107 if e.view.is_some() {
29109 self.write_keyword("LATERAL VIEW");
29111 if e.outer.is_some() {
29112 self.write_space();
29113 self.write_keyword("OUTER");
29114 }
29115 self.write_space();
29116 self.generate_expression(&e.this)?;
29117 if let Some(alias) = &e.alias {
29118 self.write_space();
29119 self.write(alias);
29120 }
29121 } else {
29122 self.write_keyword("LATERAL");
29124 self.write_space();
29125 self.generate_expression(&e.this)?;
29126 if e.ordinality.is_some() {
29127 self.write_space();
29128 self.write_keyword("WITH ORDINALITY");
29129 }
29130 if let Some(alias) = &e.alias {
29131 self.write_space();
29132 self.write_keyword("AS");
29133 self.write_space();
29134 self.write(alias);
29135 if !e.column_aliases.is_empty() {
29136 self.write("(");
29137 for (i, col) in e.column_aliases.iter().enumerate() {
29138 if i > 0 {
29139 self.write(", ");
29140 }
29141 self.write(col);
29142 }
29143 self.write(")");
29144 }
29145 }
29146 }
29147 Ok(())
29148 }
29149
29150 fn generate_like_property(&mut self, e: &LikeProperty) -> Result<()> {
29151 self.write_keyword("LIKE");
29153 self.write_space();
29154 self.generate_expression(&e.this)?;
29155 for expr in &e.expressions {
29156 self.write_space();
29157 self.generate_expression(expr)?;
29158 }
29159 Ok(())
29160 }
29161
29162 fn generate_limit(&mut self, e: &Limit) -> Result<()> {
29163 self.write_keyword("LIMIT");
29164 self.write_space();
29165 self.write_limit_expr(&e.this)?;
29166 if e.percent {
29167 self.write_space();
29168 self.write_keyword("PERCENT");
29169 }
29170 for comment in &e.comments {
29172 self.write(" ");
29173 self.write_formatted_comment(comment);
29174 }
29175 Ok(())
29176 }
29177
29178 fn generate_limit_options(&mut self, e: &LimitOptions) -> Result<()> {
29179 if e.percent.is_some() {
29181 self.write_keyword(" PERCENT");
29182 }
29183 if e.rows.is_some() {
29184 self.write_keyword(" ROWS");
29185 }
29186 if e.with_ties.is_some() {
29187 self.write_keyword(" WITH TIES");
29188 } else if e.rows.is_some() {
29189 self.write_keyword(" ONLY");
29190 }
29191 Ok(())
29192 }
29193
29194 fn generate_list(&mut self, e: &List) -> Result<()> {
29195 use crate::dialects::DialectType;
29196 let is_materialize = matches!(self.config.dialect, Some(DialectType::Materialize));
29197
29198 if e.expressions.len() == 1 {
29200 if let Expression::Select(_) = &e.expressions[0] {
29201 self.write_keyword("LIST");
29202 self.write("(");
29203 self.generate_expression(&e.expressions[0])?;
29204 self.write(")");
29205 return Ok(());
29206 }
29207 }
29208
29209 if is_materialize {
29211 self.write_keyword("LIST");
29212 self.write("[");
29213 for (i, expr) in e.expressions.iter().enumerate() {
29214 if i > 0 {
29215 self.write(", ");
29216 }
29217 self.generate_expression(expr)?;
29218 }
29219 self.write("]");
29220 } else {
29221 self.write_keyword("LIST");
29223 self.write("(");
29224 for (i, expr) in e.expressions.iter().enumerate() {
29225 if i > 0 {
29226 self.write(", ");
29227 }
29228 self.generate_expression(expr)?;
29229 }
29230 self.write(")");
29231 }
29232 Ok(())
29233 }
29234
29235 fn generate_tomap(&mut self, e: &ToMap) -> Result<()> {
29236 if let Expression::Select(_) = &*e.this {
29238 self.write_keyword("MAP");
29239 self.write("(");
29240 self.generate_expression(&e.this)?;
29241 self.write(")");
29242 return Ok(());
29243 }
29244
29245 let is_duckdb = matches!(self.config.dialect, Some(DialectType::DuckDB));
29246
29247 self.write_keyword("MAP");
29249 if is_duckdb {
29250 self.write(" {");
29251 } else {
29252 self.write("[");
29253 }
29254 if let Expression::Struct(s) = &*e.this {
29255 for (i, (_, expr)) in s.fields.iter().enumerate() {
29256 if i > 0 {
29257 self.write(", ");
29258 }
29259 if let Expression::PropertyEQ(op) = expr {
29260 self.generate_expression(&op.left)?;
29261 if is_duckdb {
29262 self.write(": ");
29263 } else {
29264 self.write(" => ");
29265 }
29266 self.generate_expression(&op.right)?;
29267 } else {
29268 self.generate_expression(expr)?;
29269 }
29270 }
29271 }
29272 if is_duckdb {
29273 self.write("}");
29274 } else {
29275 self.write("]");
29276 }
29277 Ok(())
29278 }
29279
29280 fn generate_localtime(&mut self, e: &Localtime) -> Result<()> {
29281 self.write_keyword("LOCALTIME");
29283 if let Some(precision) = &e.this {
29284 self.write("(");
29285 self.generate_expression(precision)?;
29286 self.write(")");
29287 }
29288 Ok(())
29289 }
29290
29291 fn generate_localtimestamp(&mut self, e: &Localtimestamp) -> Result<()> {
29292 self.write_keyword("LOCALTIMESTAMP");
29294 if let Some(precision) = &e.this {
29295 self.write("(");
29296 self.generate_expression(precision)?;
29297 self.write(")");
29298 }
29299 Ok(())
29300 }
29301
29302 fn generate_location_property(&mut self, e: &LocationProperty) -> Result<()> {
29303 self.write_keyword("LOCATION");
29305 self.write_space();
29306 self.generate_expression(&e.this)?;
29307 Ok(())
29308 }
29309
29310 fn generate_lock(&mut self, e: &Lock) -> Result<()> {
29311 if e.update.is_some() {
29313 if e.key.is_some() {
29314 self.write_keyword("FOR NO KEY UPDATE");
29315 } else {
29316 self.write_keyword("FOR UPDATE");
29317 }
29318 } else {
29319 if e.key.is_some() {
29320 self.write_keyword("FOR KEY SHARE");
29321 } else {
29322 self.write_keyword("FOR SHARE");
29323 }
29324 }
29325 if !e.expressions.is_empty() {
29326 self.write_keyword(" OF ");
29327 for (i, expr) in e.expressions.iter().enumerate() {
29328 if i > 0 {
29329 self.write(", ");
29330 }
29331 self.generate_expression(expr)?;
29332 }
29333 }
29334 if let Some(wait) = &e.wait {
29339 match wait.as_ref() {
29340 Expression::Boolean(b) => {
29341 if b.value {
29342 self.write_keyword(" NOWAIT");
29343 } else {
29344 self.write_keyword(" SKIP LOCKED");
29345 }
29346 }
29347 _ => {
29348 self.write_keyword(" WAIT ");
29350 self.generate_expression(wait)?;
29351 }
29352 }
29353 }
29354 Ok(())
29355 }
29356
29357 fn generate_lock_property(&mut self, e: &LockProperty) -> Result<()> {
29358 self.write_keyword("LOCK");
29360 self.write_space();
29361 self.generate_expression(&e.this)?;
29362 Ok(())
29363 }
29364
29365 fn generate_locking_property(&mut self, e: &LockingProperty) -> Result<()> {
29366 self.write_keyword("LOCKING");
29368 self.write_space();
29369 self.write(&e.kind);
29370 if let Some(this) = &e.this {
29371 self.write_space();
29372 self.generate_expression(this)?;
29373 }
29374 if let Some(for_or_in) = &e.for_or_in {
29375 self.write_space();
29376 self.generate_expression(for_or_in)?;
29377 }
29378 if let Some(lock_type) = &e.lock_type {
29379 self.write_space();
29380 self.generate_expression(lock_type)?;
29381 }
29382 if e.override_.is_some() {
29383 self.write_keyword(" OVERRIDE");
29384 }
29385 Ok(())
29386 }
29387
29388 fn generate_locking_statement(&mut self, e: &LockingStatement) -> Result<()> {
29389 self.generate_expression(&e.this)?;
29391 self.write_space();
29392 self.generate_expression(&e.expression)?;
29393 Ok(())
29394 }
29395
29396 fn generate_log_property(&mut self, e: &LogProperty) -> Result<()> {
29397 if e.no.is_some() {
29399 self.write_keyword("NO ");
29400 }
29401 self.write_keyword("LOG");
29402 Ok(())
29403 }
29404
29405 fn generate_md5_digest(&mut self, e: &MD5Digest) -> Result<()> {
29406 self.write_keyword("MD5");
29408 self.write("(");
29409 self.generate_expression(&e.this)?;
29410 for expr in &e.expressions {
29411 self.write(", ");
29412 self.generate_expression(expr)?;
29413 }
29414 self.write(")");
29415 Ok(())
29416 }
29417
29418 fn generate_ml_forecast(&mut self, e: &MLForecast) -> Result<()> {
29419 self.write_keyword("ML.FORECAST");
29421 self.write("(");
29422 self.generate_expression(&e.this)?;
29423 if let Some(expression) = &e.expression {
29424 self.write(", ");
29425 self.generate_expression(expression)?;
29426 }
29427 if let Some(params) = &e.params_struct {
29428 self.write(", ");
29429 self.generate_expression(params)?;
29430 }
29431 self.write(")");
29432 Ok(())
29433 }
29434
29435 fn generate_ml_translate(&mut self, e: &MLTranslate) -> Result<()> {
29436 self.write_keyword("ML.TRANSLATE");
29438 self.write("(");
29439 self.generate_expression(&e.this)?;
29440 self.write(", ");
29441 self.generate_expression(&e.expression)?;
29442 if let Some(params) = &e.params_struct {
29443 self.write(", ");
29444 self.generate_expression(params)?;
29445 }
29446 self.write(")");
29447 Ok(())
29448 }
29449
29450 fn generate_make_interval(&mut self, e: &MakeInterval) -> Result<()> {
29451 self.write_keyword("MAKE_INTERVAL");
29453 self.write("(");
29454 let mut first = true;
29455 if let Some(year) = &e.year {
29456 self.write("years => ");
29457 self.generate_expression(year)?;
29458 first = false;
29459 }
29460 if let Some(month) = &e.month {
29461 if !first {
29462 self.write(", ");
29463 }
29464 self.write("months => ");
29465 self.generate_expression(month)?;
29466 first = false;
29467 }
29468 if let Some(week) = &e.week {
29469 if !first {
29470 self.write(", ");
29471 }
29472 self.write("weeks => ");
29473 self.generate_expression(week)?;
29474 first = false;
29475 }
29476 if let Some(day) = &e.day {
29477 if !first {
29478 self.write(", ");
29479 }
29480 self.write("days => ");
29481 self.generate_expression(day)?;
29482 first = false;
29483 }
29484 if let Some(hour) = &e.hour {
29485 if !first {
29486 self.write(", ");
29487 }
29488 self.write("hours => ");
29489 self.generate_expression(hour)?;
29490 first = false;
29491 }
29492 if let Some(minute) = &e.minute {
29493 if !first {
29494 self.write(", ");
29495 }
29496 self.write("mins => ");
29497 self.generate_expression(minute)?;
29498 first = false;
29499 }
29500 if let Some(second) = &e.second {
29501 if !first {
29502 self.write(", ");
29503 }
29504 self.write("secs => ");
29505 self.generate_expression(second)?;
29506 }
29507 self.write(")");
29508 Ok(())
29509 }
29510
29511 fn generate_manhattan_distance(&mut self, e: &ManhattanDistance) -> Result<()> {
29512 self.write_keyword("MANHATTAN_DISTANCE");
29514 self.write("(");
29515 self.generate_expression(&e.this)?;
29516 self.write(", ");
29517 self.generate_expression(&e.expression)?;
29518 self.write(")");
29519 Ok(())
29520 }
29521
29522 fn generate_map(&mut self, e: &Map) -> Result<()> {
29523 self.write_keyword("MAP");
29525 self.write("(");
29526 for (i, (key, value)) in e.keys.iter().zip(e.values.iter()).enumerate() {
29527 if i > 0 {
29528 self.write(", ");
29529 }
29530 self.generate_expression(key)?;
29531 self.write(", ");
29532 self.generate_expression(value)?;
29533 }
29534 self.write(")");
29535 Ok(())
29536 }
29537
29538 fn generate_map_cat(&mut self, e: &MapCat) -> Result<()> {
29539 self.write_keyword("MAP_CAT");
29541 self.write("(");
29542 self.generate_expression(&e.this)?;
29543 self.write(", ");
29544 self.generate_expression(&e.expression)?;
29545 self.write(")");
29546 Ok(())
29547 }
29548
29549 fn generate_map_delete(&mut self, e: &MapDelete) -> Result<()> {
29550 self.write_keyword("MAP_DELETE");
29552 self.write("(");
29553 self.generate_expression(&e.this)?;
29554 for expr in &e.expressions {
29555 self.write(", ");
29556 self.generate_expression(expr)?;
29557 }
29558 self.write(")");
29559 Ok(())
29560 }
29561
29562 fn generate_map_insert(&mut self, e: &MapInsert) -> Result<()> {
29563 self.write_keyword("MAP_INSERT");
29565 self.write("(");
29566 self.generate_expression(&e.this)?;
29567 if let Some(key) = &e.key {
29568 self.write(", ");
29569 self.generate_expression(key)?;
29570 }
29571 if let Some(value) = &e.value {
29572 self.write(", ");
29573 self.generate_expression(value)?;
29574 }
29575 if let Some(update_flag) = &e.update_flag {
29576 self.write(", ");
29577 self.generate_expression(update_flag)?;
29578 }
29579 self.write(")");
29580 Ok(())
29581 }
29582
29583 fn generate_map_pick(&mut self, e: &MapPick) -> Result<()> {
29584 self.write_keyword("MAP_PICK");
29586 self.write("(");
29587 self.generate_expression(&e.this)?;
29588 for expr in &e.expressions {
29589 self.write(", ");
29590 self.generate_expression(expr)?;
29591 }
29592 self.write(")");
29593 Ok(())
29594 }
29595
29596 fn generate_masking_policy_column_constraint(
29597 &mut self,
29598 e: &MaskingPolicyColumnConstraint,
29599 ) -> Result<()> {
29600 self.write_keyword("MASKING POLICY");
29602 self.write_space();
29603 self.generate_expression(&e.this)?;
29604 if !e.expressions.is_empty() {
29605 self.write_keyword(" USING");
29606 self.write(" (");
29607 for (i, expr) in e.expressions.iter().enumerate() {
29608 if i > 0 {
29609 self.write(", ");
29610 }
29611 self.generate_expression(expr)?;
29612 }
29613 self.write(")");
29614 }
29615 Ok(())
29616 }
29617
29618 fn generate_match_against(&mut self, e: &MatchAgainst) -> Result<()> {
29619 if matches!(
29620 self.config.dialect,
29621 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
29622 ) {
29623 if e.expressions.len() > 1 {
29624 self.write("(");
29625 }
29626 for (i, expr) in e.expressions.iter().enumerate() {
29627 if i > 0 {
29628 self.write_keyword(" OR ");
29629 }
29630 self.generate_expression(expr)?;
29631 self.write_space();
29632 self.write("@@");
29633 self.write_space();
29634 self.generate_expression(&e.this)?;
29635 }
29636 if e.expressions.len() > 1 {
29637 self.write(")");
29638 }
29639 return Ok(());
29640 }
29641
29642 self.write_keyword("MATCH");
29644 self.write("(");
29645 for (i, expr) in e.expressions.iter().enumerate() {
29646 if i > 0 {
29647 self.write(", ");
29648 }
29649 self.generate_expression(expr)?;
29650 }
29651 self.write(")");
29652 self.write_keyword(" AGAINST");
29653 self.write("(");
29654 self.generate_expression(&e.this)?;
29655 if let Some(modifier) = &e.modifier {
29656 self.write_space();
29657 self.generate_expression(modifier)?;
29658 }
29659 self.write(")");
29660 Ok(())
29661 }
29662
29663 fn generate_match_recognize_measure(&mut self, e: &MatchRecognizeMeasure) -> Result<()> {
29664 if let Some(window_frame) = &e.window_frame {
29666 self.write(&format!("{:?}", window_frame).to_uppercase());
29667 self.write_space();
29668 }
29669 self.generate_expression(&e.this)?;
29670 Ok(())
29671 }
29672
29673 fn generate_materialized_property(&mut self, e: &MaterializedProperty) -> Result<()> {
29674 self.write_keyword("MATERIALIZED");
29676 if let Some(this) = &e.this {
29677 self.write_space();
29678 self.generate_expression(this)?;
29679 }
29680 Ok(())
29681 }
29682
29683 fn generate_merge(&mut self, e: &Merge) -> Result<()> {
29684 if let Some(with_) = &e.with_ {
29687 self.generate_expression(with_)?;
29688 self.write_space();
29689 }
29690 self.write_keyword("MERGE INTO");
29691 self.write_space();
29692 self.generate_expression(&e.this)?;
29693
29694 if self.config.pretty {
29696 self.write_newline();
29697 self.write_indent();
29698 } else {
29699 self.write_space();
29700 }
29701 self.write_keyword("USING");
29702 self.write_space();
29703 self.generate_expression(&e.using)?;
29704
29705 if let Some(on) = &e.on {
29707 if self.config.pretty {
29708 self.write_newline();
29709 self.write_indent();
29710 } else {
29711 self.write_space();
29712 }
29713 self.write_keyword("ON");
29714 self.write_space();
29715 self.generate_expression(on)?;
29716 }
29717 if let Some(using_cond) = &e.using_cond {
29719 self.write_space();
29720 self.write_keyword("USING");
29721 self.write_space();
29722 self.write("(");
29723 if let Expression::Tuple(tuple) = using_cond.as_ref() {
29725 for (i, col) in tuple.expressions.iter().enumerate() {
29726 if i > 0 {
29727 self.write(", ");
29728 }
29729 self.generate_expression(col)?;
29730 }
29731 } else {
29732 self.generate_expression(using_cond)?;
29733 }
29734 self.write(")");
29735 }
29736 let saved_merge_strip = std::mem::take(&mut self.merge_strip_qualifiers);
29738 if matches!(
29739 self.config.dialect,
29740 Some(crate::DialectType::PostgreSQL)
29741 | Some(crate::DialectType::Redshift)
29742 | Some(crate::DialectType::Trino)
29743 | Some(crate::DialectType::Presto)
29744 | Some(crate::DialectType::Athena)
29745 ) {
29746 let mut names = Vec::new();
29747 match e.this.as_ref() {
29748 Expression::Alias(a) => {
29749 if let Expression::Table(t) = &a.this {
29751 names.push(t.name.name.clone());
29752 } else if let Expression::Identifier(id) = &a.this {
29753 names.push(id.name.clone());
29754 }
29755 names.push(a.alias.name.clone());
29756 }
29757 Expression::Table(t) => {
29758 names.push(t.name.name.clone());
29759 }
29760 Expression::Identifier(id) => {
29761 names.push(id.name.clone());
29762 }
29763 _ => {}
29764 }
29765 self.merge_strip_qualifiers = names;
29766 }
29767
29768 if let Some(whens) = &e.whens {
29770 if self.config.pretty {
29771 self.write_newline();
29772 self.write_indent();
29773 } else {
29774 self.write_space();
29775 }
29776 self.generate_expression(whens)?;
29777 }
29778
29779 self.merge_strip_qualifiers = saved_merge_strip;
29781
29782 if let Some(returning) = &e.returning {
29784 if self.config.pretty {
29785 self.write_newline();
29786 self.write_indent();
29787 } else {
29788 self.write_space();
29789 }
29790 self.generate_expression(returning)?;
29791 }
29792 Ok(())
29793 }
29794
29795 fn generate_merge_block_ratio_property(&mut self, e: &MergeBlockRatioProperty) -> Result<()> {
29796 if e.no.is_some() {
29798 self.write_keyword("NO MERGEBLOCKRATIO");
29799 } else if e.default.is_some() {
29800 self.write_keyword("DEFAULT MERGEBLOCKRATIO");
29801 } else {
29802 self.write_keyword("MERGEBLOCKRATIO");
29803 self.write("=");
29804 if let Some(this) = &e.this {
29805 self.generate_expression(this)?;
29806 }
29807 if e.percent.is_some() {
29808 self.write_keyword(" PERCENT");
29809 }
29810 }
29811 Ok(())
29812 }
29813
29814 fn generate_merge_tree_ttl(&mut self, e: &MergeTreeTTL) -> Result<()> {
29815 self.write_keyword("TTL");
29817 let pretty_clickhouse = self.config.pretty
29818 && matches!(
29819 self.config.dialect,
29820 Some(crate::dialects::DialectType::ClickHouse)
29821 );
29822
29823 if pretty_clickhouse {
29824 self.write_newline();
29825 self.indent_level += 1;
29826 for (i, expr) in e.expressions.iter().enumerate() {
29827 if i > 0 {
29828 self.write(",");
29829 self.write_newline();
29830 }
29831 self.write_indent();
29832 self.generate_expression(expr)?;
29833 }
29834 self.indent_level -= 1;
29835 } else {
29836 self.write_space();
29837 for (i, expr) in e.expressions.iter().enumerate() {
29838 if i > 0 {
29839 self.write(", ");
29840 }
29841 self.generate_expression(expr)?;
29842 }
29843 }
29844
29845 if let Some(where_) = &e.where_ {
29846 if pretty_clickhouse {
29847 self.write_newline();
29848 if let Expression::Where(w) = where_.as_ref() {
29849 self.write_indent();
29850 self.write_keyword("WHERE");
29851 self.write_newline();
29852 self.indent_level += 1;
29853 self.write_indent();
29854 self.generate_expression(&w.this)?;
29855 self.indent_level -= 1;
29856 } else {
29857 self.write_indent();
29858 self.generate_expression(where_)?;
29859 }
29860 } else {
29861 self.write_space();
29862 self.generate_expression(where_)?;
29863 }
29864 }
29865 if let Some(group) = &e.group {
29866 if pretty_clickhouse {
29867 self.write_newline();
29868 if let Expression::Group(g) = group.as_ref() {
29869 self.write_indent();
29870 self.write_keyword("GROUP BY");
29871 self.write_newline();
29872 self.indent_level += 1;
29873 for (i, expr) in g.expressions.iter().enumerate() {
29874 if i > 0 {
29875 self.write(",");
29876 self.write_newline();
29877 }
29878 self.write_indent();
29879 self.generate_expression(expr)?;
29880 }
29881 self.indent_level -= 1;
29882 } else {
29883 self.write_indent();
29884 self.generate_expression(group)?;
29885 }
29886 } else {
29887 self.write_space();
29888 self.generate_expression(group)?;
29889 }
29890 }
29891 if let Some(aggregates) = &e.aggregates {
29892 if pretty_clickhouse {
29893 self.write_newline();
29894 self.write_indent();
29895 self.write_keyword("SET");
29896 self.write_newline();
29897 self.indent_level += 1;
29898 if let Expression::Tuple(t) = aggregates.as_ref() {
29899 for (i, agg) in t.expressions.iter().enumerate() {
29900 if i > 0 {
29901 self.write(",");
29902 self.write_newline();
29903 }
29904 self.write_indent();
29905 self.generate_expression(agg)?;
29906 }
29907 } else {
29908 self.write_indent();
29909 self.generate_expression(aggregates)?;
29910 }
29911 self.indent_level -= 1;
29912 } else {
29913 self.write_space();
29914 self.write_keyword("SET");
29915 self.write_space();
29916 self.generate_expression(aggregates)?;
29917 }
29918 }
29919 Ok(())
29920 }
29921
29922 fn generate_merge_tree_ttl_action(&mut self, e: &MergeTreeTTLAction) -> Result<()> {
29923 self.generate_expression(&e.this)?;
29925 if e.delete.is_some() {
29926 self.write_keyword(" DELETE");
29927 }
29928 if let Some(recompress) = &e.recompress {
29929 self.write_keyword(" RECOMPRESS ");
29930 self.generate_expression(recompress)?;
29931 }
29932 if let Some(to_disk) = &e.to_disk {
29933 self.write_keyword(" TO DISK ");
29934 self.generate_expression(to_disk)?;
29935 }
29936 if let Some(to_volume) = &e.to_volume {
29937 self.write_keyword(" TO VOLUME ");
29938 self.generate_expression(to_volume)?;
29939 }
29940 Ok(())
29941 }
29942
29943 fn generate_minhash(&mut self, e: &Minhash) -> Result<()> {
29944 self.write_keyword("MINHASH");
29946 self.write("(");
29947 self.generate_expression(&e.this)?;
29948 for expr in &e.expressions {
29949 self.write(", ");
29950 self.generate_expression(expr)?;
29951 }
29952 self.write(")");
29953 Ok(())
29954 }
29955
29956 fn generate_model_attribute(&mut self, e: &ModelAttribute) -> Result<()> {
29957 self.generate_expression(&e.this)?;
29959 self.write("!");
29960 self.generate_expression(&e.expression)?;
29961 Ok(())
29962 }
29963
29964 fn generate_monthname(&mut self, e: &Monthname) -> Result<()> {
29965 self.write_keyword("MONTHNAME");
29967 self.write("(");
29968 self.generate_expression(&e.this)?;
29969 self.write(")");
29970 Ok(())
29971 }
29972
29973 fn generate_multitable_inserts(&mut self, e: &MultitableInserts) -> Result<()> {
29974 for comment in &e.leading_comments {
29976 self.write_formatted_comment(comment);
29977 if self.config.pretty {
29978 self.write_newline();
29979 self.write_indent();
29980 } else {
29981 self.write_space();
29982 }
29983 }
29984 self.write_keyword("INSERT");
29986 self.write_space();
29987 self.write(&e.kind);
29988 if self.config.pretty {
29989 self.indent_level += 1;
29990 for expr in &e.expressions {
29991 self.write_newline();
29992 self.write_indent();
29993 self.generate_expression(expr)?;
29994 }
29995 self.indent_level -= 1;
29996 } else {
29997 for expr in &e.expressions {
29998 self.write_space();
29999 self.generate_expression(expr)?;
30000 }
30001 }
30002 if let Some(source) = &e.source {
30003 if self.config.pretty {
30004 self.write_newline();
30005 self.write_indent();
30006 } else {
30007 self.write_space();
30008 }
30009 self.generate_expression(source)?;
30010 }
30011 Ok(())
30012 }
30013
30014 fn generate_next_value_for(&mut self, e: &NextValueFor) -> Result<()> {
30015 self.write_keyword("NEXT VALUE FOR");
30017 self.write_space();
30018 self.generate_expression(&e.this)?;
30019 if let Some(order) = &e.order {
30020 self.write_space();
30021 self.write_keyword("OVER");
30022 self.write(" (");
30023 self.generate_expression(order)?;
30024 self.write(")");
30025 }
30026 Ok(())
30027 }
30028
30029 fn generate_normal(&mut self, e: &Normal) -> Result<()> {
30030 self.write_keyword("NORMAL");
30032 self.write("(");
30033 self.generate_expression(&e.this)?;
30034 if let Some(stddev) = &e.stddev {
30035 self.write(", ");
30036 self.generate_expression(stddev)?;
30037 }
30038 if let Some(gen) = &e.gen {
30039 self.write(", ");
30040 self.generate_expression(gen)?;
30041 }
30042 self.write(")");
30043 Ok(())
30044 }
30045
30046 fn generate_normalize(&mut self, e: &Normalize) -> Result<()> {
30047 if e.is_casefold.is_some() {
30049 self.write_keyword("NORMALIZE_AND_CASEFOLD");
30050 } else {
30051 self.write_keyword("NORMALIZE");
30052 }
30053 self.write("(");
30054 self.generate_expression(&e.this)?;
30055 if let Some(form) = &e.form {
30056 self.write(", ");
30057 self.generate_expression(form)?;
30058 }
30059 self.write(")");
30060 Ok(())
30061 }
30062
30063 fn generate_not_null_column_constraint(&mut self, e: &NotNullColumnConstraint) -> Result<()> {
30064 if e.allow_null.is_none() {
30066 self.write_keyword("NOT ");
30067 }
30068 self.write_keyword("NULL");
30069 Ok(())
30070 }
30071
30072 fn generate_nullif(&mut self, e: &Nullif) -> Result<()> {
30073 self.write_keyword("NULLIF");
30075 self.write("(");
30076 self.generate_expression(&e.this)?;
30077 self.write(", ");
30078 self.generate_expression(&e.expression)?;
30079 self.write(")");
30080 Ok(())
30081 }
30082
30083 fn generate_number_to_str(&mut self, e: &NumberToStr) -> Result<()> {
30084 self.write_keyword("FORMAT");
30086 self.write("(");
30087 self.generate_expression(&e.this)?;
30088 self.write(", '");
30089 self.write(&e.format);
30090 self.write("'");
30091 if let Some(culture) = &e.culture {
30092 self.write(", ");
30093 self.generate_expression(culture)?;
30094 }
30095 self.write(")");
30096 Ok(())
30097 }
30098
30099 fn generate_object_agg(&mut self, e: &ObjectAgg) -> Result<()> {
30100 self.write_keyword("OBJECT_AGG");
30102 self.write("(");
30103 self.generate_expression(&e.this)?;
30104 self.write(", ");
30105 self.generate_expression(&e.expression)?;
30106 self.write(")");
30107 Ok(())
30108 }
30109
30110 fn generate_object_identifier(&mut self, e: &ObjectIdentifier) -> Result<()> {
30111 self.generate_expression(&e.this)?;
30113 Ok(())
30114 }
30115
30116 fn generate_object_insert(&mut self, e: &ObjectInsert) -> Result<()> {
30117 self.write_keyword("OBJECT_INSERT");
30119 self.write("(");
30120 self.generate_expression(&e.this)?;
30121 if let Some(key) = &e.key {
30122 self.write(", ");
30123 self.generate_expression(key)?;
30124 }
30125 if let Some(value) = &e.value {
30126 self.write(", ");
30127 self.generate_expression(value)?;
30128 }
30129 if let Some(update_flag) = &e.update_flag {
30130 self.write(", ");
30131 self.generate_expression(update_flag)?;
30132 }
30133 self.write(")");
30134 Ok(())
30135 }
30136
30137 fn generate_offset(&mut self, e: &Offset) -> Result<()> {
30138 self.write_keyword("OFFSET");
30140 self.write_space();
30141 self.generate_expression(&e.this)?;
30142 if e.rows == Some(true)
30144 && matches!(
30145 self.config.dialect,
30146 Some(crate::dialects::DialectType::TSQL)
30147 | Some(crate::dialects::DialectType::Oracle)
30148 )
30149 {
30150 self.write_space();
30151 self.write_keyword("ROWS");
30152 }
30153 Ok(())
30154 }
30155
30156 fn generate_qualify(&mut self, e: &Qualify) -> Result<()> {
30157 self.write_keyword("QUALIFY");
30159 self.write_space();
30160 self.generate_expression(&e.this)?;
30161 Ok(())
30162 }
30163
30164 fn generate_on_cluster(&mut self, e: &OnCluster) -> Result<()> {
30165 self.write_keyword("ON CLUSTER");
30167 self.write_space();
30168 self.generate_expression(&e.this)?;
30169 Ok(())
30170 }
30171
30172 fn generate_on_commit_property(&mut self, e: &OnCommitProperty) -> Result<()> {
30173 self.write_keyword("ON COMMIT");
30175 if e.delete.is_some() {
30176 self.write_keyword(" DELETE ROWS");
30177 } else {
30178 self.write_keyword(" PRESERVE ROWS");
30179 }
30180 Ok(())
30181 }
30182
30183 fn generate_on_condition(&mut self, e: &OnCondition) -> Result<()> {
30184 if let Some(empty) = &e.empty {
30186 self.generate_expression(empty)?;
30187 self.write_keyword(" ON EMPTY");
30188 }
30189 if let Some(error) = &e.error {
30190 if e.empty.is_some() {
30191 self.write_space();
30192 }
30193 self.generate_expression(error)?;
30194 self.write_keyword(" ON ERROR");
30195 }
30196 if let Some(null) = &e.null {
30197 if e.empty.is_some() || e.error.is_some() {
30198 self.write_space();
30199 }
30200 self.generate_expression(null)?;
30201 self.write_keyword(" ON NULL");
30202 }
30203 Ok(())
30204 }
30205
30206 fn generate_on_conflict(&mut self, e: &OnConflict) -> Result<()> {
30207 if matches!(self.config.dialect, Some(DialectType::Materialize)) {
30209 return Ok(());
30210 }
30211 if e.duplicate.is_some() {
30213 self.write_keyword("ON DUPLICATE KEY UPDATE");
30215 for (i, expr) in e.expressions.iter().enumerate() {
30216 if i > 0 {
30217 self.write(",");
30218 }
30219 self.write_space();
30220 self.generate_expression(expr)?;
30221 }
30222 return Ok(());
30223 } else {
30224 self.write_keyword("ON CONFLICT");
30225 }
30226 if let Some(constraint) = &e.constraint {
30227 self.write_keyword(" ON CONSTRAINT ");
30228 self.generate_expression(constraint)?;
30229 }
30230 if let Some(conflict_keys) = &e.conflict_keys {
30231 if let Expression::Tuple(t) = conflict_keys.as_ref() {
30233 self.write("(");
30234 for (i, expr) in t.expressions.iter().enumerate() {
30235 if i > 0 {
30236 self.write(", ");
30237 }
30238 self.generate_expression(expr)?;
30239 }
30240 self.write(")");
30241 } else {
30242 self.write("(");
30243 self.generate_expression(conflict_keys)?;
30244 self.write(")");
30245 }
30246 }
30247 if let Some(index_predicate) = &e.index_predicate {
30248 self.write_keyword(" WHERE ");
30249 self.generate_expression(index_predicate)?;
30250 }
30251 if let Some(action) = &e.action {
30252 if let Expression::Identifier(id) = action.as_ref() {
30254 if id.name == "NOTHING" || id.name.to_uppercase() == "NOTHING" {
30255 self.write_keyword(" DO NOTHING");
30256 } else {
30257 self.write_keyword(" DO ");
30258 self.generate_expression(action)?;
30259 }
30260 } else if let Expression::Tuple(t) = action.as_ref() {
30261 self.write_keyword(" DO UPDATE SET ");
30263 for (i, expr) in t.expressions.iter().enumerate() {
30264 if i > 0 {
30265 self.write(", ");
30266 }
30267 self.generate_expression(expr)?;
30268 }
30269 } else {
30270 self.write_keyword(" DO ");
30271 self.generate_expression(action)?;
30272 }
30273 }
30274 if let Some(where_) = &e.where_ {
30276 self.write_keyword(" WHERE ");
30277 self.generate_expression(where_)?;
30278 }
30279 Ok(())
30280 }
30281
30282 fn generate_on_property(&mut self, e: &OnProperty) -> Result<()> {
30283 self.write_keyword("ON");
30285 self.write_space();
30286 self.generate_expression(&e.this)?;
30287 Ok(())
30288 }
30289
30290 fn generate_opclass(&mut self, e: &Opclass) -> Result<()> {
30291 self.generate_expression(&e.this)?;
30293 self.write_space();
30294 self.generate_expression(&e.expression)?;
30295 Ok(())
30296 }
30297
30298 fn generate_open_json(&mut self, e: &OpenJSON) -> Result<()> {
30299 self.write_keyword("OPENJSON");
30301 self.write("(");
30302 self.generate_expression(&e.this)?;
30303 if let Some(path) = &e.path {
30304 self.write(", ");
30305 self.generate_expression(path)?;
30306 }
30307 self.write(")");
30308 if !e.expressions.is_empty() {
30309 self.write_keyword(" WITH");
30310 if self.config.pretty {
30311 self.write(" (\n");
30312 self.indent_level += 2;
30313 for (i, expr) in e.expressions.iter().enumerate() {
30314 if i > 0 {
30315 self.write(",\n");
30316 }
30317 self.write_indent();
30318 self.generate_expression(expr)?;
30319 }
30320 self.write("\n");
30321 self.indent_level -= 2;
30322 self.write(")");
30323 } else {
30324 self.write(" (");
30325 for (i, expr) in e.expressions.iter().enumerate() {
30326 if i > 0 {
30327 self.write(", ");
30328 }
30329 self.generate_expression(expr)?;
30330 }
30331 self.write(")");
30332 }
30333 }
30334 Ok(())
30335 }
30336
30337 fn generate_open_json_column_def(&mut self, e: &OpenJSONColumnDef) -> Result<()> {
30338 self.generate_expression(&e.this)?;
30340 self.write_space();
30341 if let Some(ref dt) = e.data_type {
30343 self.generate_data_type(dt)?;
30344 } else if !e.kind.is_empty() {
30345 self.write(&e.kind);
30346 }
30347 if let Some(path) = &e.path {
30348 self.write_space();
30349 self.generate_expression(path)?;
30350 }
30351 if e.as_json.is_some() {
30352 self.write_keyword(" AS JSON");
30353 }
30354 Ok(())
30355 }
30356
30357 fn generate_operator(&mut self, e: &Operator) -> Result<()> {
30358 self.generate_expression(&e.this)?;
30360 self.write_space();
30361 if let Some(op) = &e.operator {
30362 self.write_keyword("OPERATOR");
30363 self.write("(");
30364 self.generate_expression(op)?;
30365 self.write(")");
30366 }
30367 for comment in &e.comments {
30369 self.write_space();
30370 self.write_formatted_comment(comment);
30371 }
30372 self.write_space();
30373 self.generate_expression(&e.expression)?;
30374 Ok(())
30375 }
30376
30377 fn generate_order_by(&mut self, e: &OrderBy) -> Result<()> {
30378 self.write_keyword("ORDER BY");
30380 let pretty_clickhouse_single_paren = self.config.pretty
30381 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
30382 && e.expressions.len() == 1
30383 && matches!(e.expressions[0].this, Expression::Paren(ref p) if !matches!(p.this, Expression::Tuple(_)));
30384 let clickhouse_single_tuple = matches!(self.config.dialect, Some(DialectType::ClickHouse))
30385 && e.expressions.len() == 1
30386 && matches!(e.expressions[0].this, Expression::Tuple(_))
30387 && !e.expressions[0].desc
30388 && e.expressions[0].nulls_first.is_none();
30389
30390 if pretty_clickhouse_single_paren {
30391 self.write_space();
30392 if let Expression::Paren(p) = &e.expressions[0].this {
30393 self.write("(");
30394 self.write_newline();
30395 self.indent_level += 1;
30396 self.write_indent();
30397 self.generate_expression(&p.this)?;
30398 self.indent_level -= 1;
30399 self.write_newline();
30400 self.write(")");
30401 }
30402 return Ok(());
30403 }
30404
30405 if clickhouse_single_tuple {
30406 self.write_space();
30407 if let Expression::Tuple(t) = &e.expressions[0].this {
30408 self.write("(");
30409 for (i, expr) in t.expressions.iter().enumerate() {
30410 if i > 0 {
30411 self.write(", ");
30412 }
30413 self.generate_expression(expr)?;
30414 }
30415 self.write(")");
30416 }
30417 return Ok(());
30418 }
30419
30420 self.write_space();
30421 for (i, ordered) in e.expressions.iter().enumerate() {
30422 if i > 0 {
30423 self.write(", ");
30424 }
30425 self.generate_expression(&ordered.this)?;
30426 if ordered.desc {
30427 self.write_space();
30428 self.write_keyword("DESC");
30429 } else if ordered.explicit_asc {
30430 self.write_space();
30431 self.write_keyword("ASC");
30432 }
30433 if let Some(nulls_first) = ordered.nulls_first {
30434 let skip_nulls_last =
30436 !nulls_first && matches!(self.config.dialect, Some(DialectType::Dremio));
30437 if !skip_nulls_last {
30438 self.write_space();
30439 self.write_keyword("NULLS");
30440 self.write_space();
30441 if nulls_first {
30442 self.write_keyword("FIRST");
30443 } else {
30444 self.write_keyword("LAST");
30445 }
30446 }
30447 }
30448 }
30449 Ok(())
30450 }
30451
30452 fn generate_output_model_property(&mut self, e: &OutputModelProperty) -> Result<()> {
30453 self.write_keyword("OUTPUT");
30455 self.write("(");
30456 if self.config.pretty {
30457 self.indent_level += 1;
30458 self.write_newline();
30459 self.write_indent();
30460 self.generate_expression(&e.this)?;
30461 self.indent_level -= 1;
30462 self.write_newline();
30463 } else {
30464 self.generate_expression(&e.this)?;
30465 }
30466 self.write(")");
30467 Ok(())
30468 }
30469
30470 fn generate_overflow_truncate_behavior(&mut self, e: &OverflowTruncateBehavior) -> Result<()> {
30471 self.write_keyword("TRUNCATE");
30473 if let Some(this) = &e.this {
30474 self.write_space();
30475 self.generate_expression(this)?;
30476 }
30477 if e.with_count.is_some() {
30478 self.write_keyword(" WITH COUNT");
30479 } else {
30480 self.write_keyword(" WITHOUT COUNT");
30481 }
30482 Ok(())
30483 }
30484
30485 fn generate_parameterized_agg(&mut self, e: &ParameterizedAgg) -> Result<()> {
30486 self.generate_expression(&e.this)?;
30488 self.write("(");
30489 for (i, expr) in e.expressions.iter().enumerate() {
30490 if i > 0 {
30491 self.write(", ");
30492 }
30493 self.generate_expression(expr)?;
30494 }
30495 self.write(")(");
30496 for (i, param) in e.params.iter().enumerate() {
30497 if i > 0 {
30498 self.write(", ");
30499 }
30500 self.generate_expression(param)?;
30501 }
30502 self.write(")");
30503 Ok(())
30504 }
30505
30506 fn generate_parse_datetime(&mut self, e: &ParseDatetime) -> Result<()> {
30507 self.write_keyword("PARSE_DATETIME");
30509 self.write("(");
30510 if let Some(format) = &e.format {
30511 self.write("'");
30512 self.write(format);
30513 self.write("', ");
30514 }
30515 self.generate_expression(&e.this)?;
30516 if let Some(zone) = &e.zone {
30517 self.write(", ");
30518 self.generate_expression(zone)?;
30519 }
30520 self.write(")");
30521 Ok(())
30522 }
30523
30524 fn generate_parse_ip(&mut self, e: &ParseIp) -> Result<()> {
30525 self.write_keyword("PARSE_IP");
30527 self.write("(");
30528 self.generate_expression(&e.this)?;
30529 if let Some(type_) = &e.type_ {
30530 self.write(", ");
30531 self.generate_expression(type_)?;
30532 }
30533 if let Some(permissive) = &e.permissive {
30534 self.write(", ");
30535 self.generate_expression(permissive)?;
30536 }
30537 self.write(")");
30538 Ok(())
30539 }
30540
30541 fn generate_parse_json(&mut self, e: &ParseJSON) -> Result<()> {
30542 self.write_keyword("PARSE_JSON");
30544 self.write("(");
30545 self.generate_expression(&e.this)?;
30546 if let Some(expression) = &e.expression {
30547 self.write(", ");
30548 self.generate_expression(expression)?;
30549 }
30550 self.write(")");
30551 Ok(())
30552 }
30553
30554 fn generate_parse_time(&mut self, e: &ParseTime) -> Result<()> {
30555 self.write_keyword("PARSE_TIME");
30557 self.write("(");
30558 self.write(&format!("'{}'", e.format));
30559 self.write(", ");
30560 self.generate_expression(&e.this)?;
30561 self.write(")");
30562 Ok(())
30563 }
30564
30565 fn generate_parse_url(&mut self, e: &ParseUrl) -> Result<()> {
30566 self.write_keyword("PARSE_URL");
30568 self.write("(");
30569 self.generate_expression(&e.this)?;
30570 if let Some(part) = &e.part_to_extract {
30571 self.write(", ");
30572 self.generate_expression(part)?;
30573 }
30574 if let Some(key) = &e.key {
30575 self.write(", ");
30576 self.generate_expression(key)?;
30577 }
30578 if let Some(permissive) = &e.permissive {
30579 self.write(", ");
30580 self.generate_expression(permissive)?;
30581 }
30582 self.write(")");
30583 Ok(())
30584 }
30585
30586 fn generate_partition_expr(&mut self, e: &Partition) -> Result<()> {
30587 if e.subpartition {
30589 self.write_keyword("SUBPARTITION");
30590 } else {
30591 self.write_keyword("PARTITION");
30592 }
30593 self.write("(");
30594 for (i, expr) in e.expressions.iter().enumerate() {
30595 if i > 0 {
30596 self.write(", ");
30597 }
30598 self.generate_expression(expr)?;
30599 }
30600 self.write(")");
30601 Ok(())
30602 }
30603
30604 fn generate_partition_bound_spec(&mut self, e: &PartitionBoundSpec) -> Result<()> {
30605 if let Some(this) = &e.this {
30607 if let Some(expression) = &e.expression {
30608 self.write_keyword("WITH");
30610 self.write(" (");
30611 self.write_keyword("MODULUS");
30612 self.write_space();
30613 self.generate_expression(this)?;
30614 self.write(", ");
30615 self.write_keyword("REMAINDER");
30616 self.write_space();
30617 self.generate_expression(expression)?;
30618 self.write(")");
30619 } else {
30620 self.write_keyword("IN");
30622 self.write(" (");
30623 self.generate_partition_bound_values(this)?;
30624 self.write(")");
30625 }
30626 } else if let (Some(from), Some(to)) = (&e.from_expressions, &e.to_expressions) {
30627 self.write_keyword("FROM");
30629 self.write(" (");
30630 self.generate_partition_bound_values(from)?;
30631 self.write(") ");
30632 self.write_keyword("TO");
30633 self.write(" (");
30634 self.generate_partition_bound_values(to)?;
30635 self.write(")");
30636 }
30637 Ok(())
30638 }
30639
30640 fn generate_partition_bound_values(&mut self, expr: &Expression) -> Result<()> {
30643 if let Expression::Tuple(t) = expr {
30644 for (i, e) in t.expressions.iter().enumerate() {
30645 if i > 0 {
30646 self.write(", ");
30647 }
30648 self.generate_expression(e)?;
30649 }
30650 Ok(())
30651 } else {
30652 self.generate_expression(expr)
30653 }
30654 }
30655
30656 fn generate_partition_by_list_property(&mut self, e: &PartitionByListProperty) -> Result<()> {
30657 self.write_keyword("PARTITION BY LIST");
30659 if let Some(partition_exprs) = &e.partition_expressions {
30660 self.write(" (");
30661 self.generate_doris_partition_expressions(partition_exprs)?;
30663 self.write(")");
30664 }
30665 if let Some(create_exprs) = &e.create_expressions {
30666 self.write(" (");
30667 self.generate_doris_partition_definitions(create_exprs)?;
30669 self.write(")");
30670 }
30671 Ok(())
30672 }
30673
30674 fn generate_partition_by_range_property(&mut self, e: &PartitionByRangeProperty) -> Result<()> {
30675 self.write_keyword("PARTITION BY RANGE");
30677 if let Some(partition_exprs) = &e.partition_expressions {
30678 self.write(" (");
30679 self.generate_doris_partition_expressions(partition_exprs)?;
30681 self.write(")");
30682 }
30683 if let Some(create_exprs) = &e.create_expressions {
30684 self.write(" (");
30685 self.generate_doris_partition_definitions(create_exprs)?;
30687 self.write(")");
30688 }
30689 Ok(())
30690 }
30691
30692 fn generate_doris_partition_expressions(&mut self, expr: &Expression) -> Result<()> {
30694 if let Expression::Tuple(t) = expr {
30695 for (i, e) in t.expressions.iter().enumerate() {
30696 if i > 0 {
30697 self.write(", ");
30698 }
30699 self.generate_expression(e)?;
30700 }
30701 } else {
30702 self.generate_expression(expr)?;
30703 }
30704 Ok(())
30705 }
30706
30707 fn generate_doris_partition_definitions(&mut self, expr: &Expression) -> Result<()> {
30709 match expr {
30710 Expression::Tuple(t) => {
30711 for (i, part) in t.expressions.iter().enumerate() {
30713 if i > 0 {
30714 self.write(", ");
30715 }
30716 if let Expression::Partition(p) = part {
30718 for (j, inner) in p.expressions.iter().enumerate() {
30719 if j > 0 {
30720 self.write(", ");
30721 }
30722 self.generate_expression(inner)?;
30723 }
30724 } else {
30725 self.generate_expression(part)?;
30726 }
30727 }
30728 }
30729 Expression::PartitionByRangePropertyDynamic(_) => {
30730 self.generate_expression(expr)?;
30732 }
30733 _ => {
30734 self.generate_expression(expr)?;
30735 }
30736 }
30737 Ok(())
30738 }
30739
30740 fn generate_partition_by_range_property_dynamic(
30741 &mut self,
30742 e: &PartitionByRangePropertyDynamic,
30743 ) -> Result<()> {
30744 if e.use_start_end {
30745 if let Some(start) = &e.start {
30747 self.write_keyword("START");
30748 self.write(" (");
30749 self.generate_expression(start)?;
30750 self.write(")");
30751 }
30752 if let Some(end) = &e.end {
30753 self.write_space();
30754 self.write_keyword("END");
30755 self.write(" (");
30756 self.generate_expression(end)?;
30757 self.write(")");
30758 }
30759 if let Some(every) = &e.every {
30760 self.write_space();
30761 self.write_keyword("EVERY");
30762 self.write(" (");
30763 self.generate_doris_interval(every)?;
30765 self.write(")");
30766 }
30767 } else {
30768 if let Some(start) = &e.start {
30770 self.write_keyword("FROM");
30771 self.write(" (");
30772 self.generate_expression(start)?;
30773 self.write(")");
30774 }
30775 if let Some(end) = &e.end {
30776 self.write_space();
30777 self.write_keyword("TO");
30778 self.write(" (");
30779 self.generate_expression(end)?;
30780 self.write(")");
30781 }
30782 if let Some(every) = &e.every {
30783 self.write_space();
30784 self.generate_doris_interval(every)?;
30786 }
30787 }
30788 Ok(())
30789 }
30790
30791 fn generate_doris_interval(&mut self, expr: &Expression) -> Result<()> {
30793 if let Expression::Interval(interval) = expr {
30794 self.write_keyword("INTERVAL");
30795 if let Some(ref value) = interval.this {
30796 self.write_space();
30797 match value {
30801 Expression::Literal(Literal::String(s))
30802 if s.chars()
30803 .all(|c| c.is_ascii_digit() || c == '.' || c == '-')
30804 && !s.is_empty() =>
30805 {
30806 self.write(s);
30807 }
30808 _ => {
30809 self.generate_expression(value)?;
30810 }
30811 }
30812 }
30813 if let Some(ref unit_spec) = interval.unit {
30814 self.write_space();
30815 self.write_interval_unit_spec(unit_spec)?;
30816 }
30817 Ok(())
30818 } else {
30819 self.generate_expression(expr)
30820 }
30821 }
30822
30823 fn generate_partition_by_truncate(&mut self, e: &PartitionByTruncate) -> Result<()> {
30824 self.write_keyword("TRUNCATE");
30826 self.write("(");
30827 self.generate_expression(&e.expression)?;
30828 self.write(", ");
30829 self.generate_expression(&e.this)?;
30830 self.write(")");
30831 Ok(())
30832 }
30833
30834 fn generate_partition_list(&mut self, e: &PartitionList) -> Result<()> {
30835 self.write_keyword("PARTITION");
30837 self.write_space();
30838 self.generate_expression(&e.this)?;
30839 self.write_space();
30840 self.write_keyword("VALUES IN");
30841 self.write(" (");
30842 for (i, expr) in e.expressions.iter().enumerate() {
30843 if i > 0 {
30844 self.write(", ");
30845 }
30846 self.generate_expression(expr)?;
30847 }
30848 self.write(")");
30849 Ok(())
30850 }
30851
30852 fn generate_partition_range(&mut self, e: &PartitionRange) -> Result<()> {
30853 if e.expressions.is_empty() && e.expression.is_some() {
30856 self.generate_expression(&e.this)?;
30858 self.write_space();
30859 self.write_keyword("TO");
30860 self.write_space();
30861 self.generate_expression(e.expression.as_ref().unwrap())?;
30862 return Ok(());
30863 }
30864
30865 self.write_keyword("PARTITION");
30867 self.write_space();
30868 self.generate_expression(&e.this)?;
30869 self.write_space();
30870
30871 if e.expressions.len() == 1 {
30873 self.write_keyword("VALUES LESS THAN");
30875 self.write(" (");
30876 self.generate_expression(&e.expressions[0])?;
30877 self.write(")");
30878 } else if !e.expressions.is_empty() {
30879 self.write_keyword("VALUES");
30881 self.write(" [");
30882 for (i, expr) in e.expressions.iter().enumerate() {
30883 if i > 0 {
30884 self.write(", ");
30885 }
30886 if let Expression::Tuple(t) = expr {
30888 self.write("(");
30889 for (j, inner) in t.expressions.iter().enumerate() {
30890 if j > 0 {
30891 self.write(", ");
30892 }
30893 self.generate_expression(inner)?;
30894 }
30895 self.write(")");
30896 } else {
30897 self.write("(");
30898 self.generate_expression(expr)?;
30899 self.write(")");
30900 }
30901 }
30902 self.write(")");
30903 }
30904 Ok(())
30905 }
30906
30907 fn generate_partitioned_by_bucket(&mut self, e: &PartitionedByBucket) -> Result<()> {
30908 self.write_keyword("BUCKET");
30910 self.write("(");
30911 self.generate_expression(&e.this)?;
30912 self.write(", ");
30913 self.generate_expression(&e.expression)?;
30914 self.write(")");
30915 Ok(())
30916 }
30917
30918 fn generate_partition_by_property(&mut self, e: &PartitionByProperty) -> Result<()> {
30919 self.write_keyword("PARTITION BY");
30921 self.write_space();
30922 for (i, expr) in e.expressions.iter().enumerate() {
30923 if i > 0 {
30924 self.write(", ");
30925 }
30926 self.generate_expression(expr)?;
30927 }
30928 Ok(())
30929 }
30930
30931 fn generate_partitioned_by_property(&mut self, e: &PartitionedByProperty) -> Result<()> {
30932 if matches!(
30934 self.config.dialect,
30935 Some(crate::dialects::DialectType::Teradata)
30936 | Some(crate::dialects::DialectType::ClickHouse)
30937 ) {
30938 self.write_keyword("PARTITION BY");
30939 } else {
30940 self.write_keyword("PARTITIONED BY");
30941 }
30942 self.write_space();
30943 if self.config.pretty {
30945 if let Expression::Tuple(ref tuple) = *e.this {
30946 self.write("(");
30947 self.write_newline();
30948 self.indent_level += 1;
30949 for (i, expr) in tuple.expressions.iter().enumerate() {
30950 if i > 0 {
30951 self.write(",");
30952 self.write_newline();
30953 }
30954 self.write_indent();
30955 self.generate_expression(expr)?;
30956 }
30957 self.indent_level -= 1;
30958 self.write_newline();
30959 self.write(")");
30960 } else {
30961 self.generate_expression(&e.this)?;
30962 }
30963 } else {
30964 self.generate_expression(&e.this)?;
30965 }
30966 Ok(())
30967 }
30968
30969 fn generate_partitioned_of_property(&mut self, e: &PartitionedOfProperty) -> Result<()> {
30970 self.write_keyword("PARTITION OF");
30972 self.write_space();
30973 self.generate_expression(&e.this)?;
30974 if let Expression::PartitionBoundSpec(_) = e.expression.as_ref() {
30976 self.write_space();
30977 self.write_keyword("FOR VALUES");
30978 self.write_space();
30979 self.generate_expression(&e.expression)?;
30980 } else {
30981 self.write_space();
30982 self.write_keyword("DEFAULT");
30983 }
30984 Ok(())
30985 }
30986
30987 fn generate_period_for_system_time_constraint(
30988 &mut self,
30989 e: &PeriodForSystemTimeConstraint,
30990 ) -> Result<()> {
30991 self.write_keyword("PERIOD FOR SYSTEM_TIME");
30993 self.write(" (");
30994 self.generate_expression(&e.this)?;
30995 self.write(", ");
30996 self.generate_expression(&e.expression)?;
30997 self.write(")");
30998 Ok(())
30999 }
31000
31001 fn generate_pivot_alias(&mut self, e: &PivotAlias) -> Result<()> {
31002 self.generate_expression(&e.this)?;
31005 self.write_space();
31006 self.write_keyword("AS");
31007 self.write_space();
31008 if self.config.unpivot_aliases_are_identifiers {
31010 match &e.alias {
31011 Expression::Literal(Literal::String(s)) => {
31012 self.generate_identifier(&Identifier::new(s.clone()))?;
31014 }
31015 Expression::Literal(Literal::Number(n)) => {
31016 let mut id = Identifier::new(n.clone());
31018 id.quoted = true;
31019 self.generate_identifier(&id)?;
31020 }
31021 other => {
31022 self.generate_expression(other)?;
31023 }
31024 }
31025 } else {
31026 self.generate_expression(&e.alias)?;
31027 }
31028 Ok(())
31029 }
31030
31031 fn generate_pivot_any(&mut self, e: &PivotAny) -> Result<()> {
31032 self.write_keyword("ANY");
31034 if let Some(this) = &e.this {
31035 self.write_space();
31036 self.generate_expression(this)?;
31037 }
31038 Ok(())
31039 }
31040
31041 fn generate_predict(&mut self, e: &Predict) -> Result<()> {
31042 self.write_keyword("ML.PREDICT");
31044 self.write("(");
31045 self.write_keyword("MODEL");
31046 self.write_space();
31047 self.generate_expression(&e.this)?;
31048 self.write(", ");
31049 self.generate_expression(&e.expression)?;
31050 if let Some(params) = &e.params_struct {
31051 self.write(", ");
31052 self.generate_expression(params)?;
31053 }
31054 self.write(")");
31055 Ok(())
31056 }
31057
31058 fn generate_previous_day(&mut self, e: &PreviousDay) -> Result<()> {
31059 self.write_keyword("PREVIOUS_DAY");
31061 self.write("(");
31062 self.generate_expression(&e.this)?;
31063 self.write(", ");
31064 self.generate_expression(&e.expression)?;
31065 self.write(")");
31066 Ok(())
31067 }
31068
31069 fn generate_primary_key(&mut self, e: &PrimaryKey) -> Result<()> {
31070 self.write_keyword("PRIMARY KEY");
31072 if let Some(name) = &e.this {
31073 self.write_space();
31074 self.generate_expression(name)?;
31075 }
31076 if !e.expressions.is_empty() {
31077 self.write(" (");
31078 for (i, expr) in e.expressions.iter().enumerate() {
31079 if i > 0 {
31080 self.write(", ");
31081 }
31082 self.generate_expression(expr)?;
31083 }
31084 self.write(")");
31085 }
31086 if let Some(include) = &e.include {
31087 self.write_space();
31088 self.generate_expression(include)?;
31089 }
31090 if !e.options.is_empty() {
31091 self.write_space();
31092 for (i, opt) in e.options.iter().enumerate() {
31093 if i > 0 {
31094 self.write_space();
31095 }
31096 self.generate_expression(opt)?;
31097 }
31098 }
31099 Ok(())
31100 }
31101
31102 fn generate_primary_key_column_constraint(
31103 &mut self,
31104 _e: &PrimaryKeyColumnConstraint,
31105 ) -> Result<()> {
31106 self.write_keyword("PRIMARY KEY");
31108 Ok(())
31109 }
31110
31111 fn generate_path_column_constraint(&mut self, e: &PathColumnConstraint) -> Result<()> {
31112 self.write_keyword("PATH");
31114 self.write_space();
31115 self.generate_expression(&e.this)?;
31116 Ok(())
31117 }
31118
31119 fn generate_projection_def(&mut self, e: &ProjectionDef) -> Result<()> {
31120 self.write_keyword("PROJECTION");
31122 self.write_space();
31123 self.generate_expression(&e.this)?;
31124 self.write(" (");
31125 self.generate_expression(&e.expression)?;
31126 self.write(")");
31127 Ok(())
31128 }
31129
31130 fn generate_properties(&mut self, e: &Properties) -> Result<()> {
31131 for (i, prop) in e.expressions.iter().enumerate() {
31133 if i > 0 {
31134 self.write(", ");
31135 }
31136 self.generate_expression(prop)?;
31137 }
31138 Ok(())
31139 }
31140
31141 fn generate_property(&mut self, e: &Property) -> Result<()> {
31142 self.generate_expression(&e.this)?;
31144 if let Some(value) = &e.value {
31145 self.write("=");
31146 self.generate_expression(value)?;
31147 }
31148 Ok(())
31149 }
31150
31151 fn generate_options_property(&mut self, e: &OptionsProperty) -> Result<()> {
31152 self.write_keyword("OPTIONS");
31153 if e.entries.is_empty() {
31154 self.write(" ()");
31155 return Ok(());
31156 }
31157
31158 if self.config.pretty {
31159 self.write(" (");
31160 self.write_newline();
31161 self.indent_level += 1;
31162 for (i, entry) in e.entries.iter().enumerate() {
31163 if i > 0 {
31164 self.write(",");
31165 self.write_newline();
31166 }
31167 self.write_indent();
31168 self.generate_identifier(&entry.key)?;
31169 self.write("=");
31170 self.generate_expression(&entry.value)?;
31171 }
31172 self.indent_level -= 1;
31173 self.write_newline();
31174 self.write(")");
31175 } else {
31176 self.write(" (");
31177 for (i, entry) in e.entries.iter().enumerate() {
31178 if i > 0 {
31179 self.write(", ");
31180 }
31181 self.generate_identifier(&entry.key)?;
31182 self.write("=");
31183 self.generate_expression(&entry.value)?;
31184 }
31185 self.write(")");
31186 }
31187 Ok(())
31188 }
31189
31190 fn generate_options_clause(&mut self, options: &[Expression]) -> Result<()> {
31192 self.write_keyword("OPTIONS");
31193 self.write(" (");
31194 for (i, opt) in options.iter().enumerate() {
31195 if i > 0 {
31196 self.write(", ");
31197 }
31198 self.generate_option_expression(opt)?;
31199 }
31200 self.write(")");
31201 Ok(())
31202 }
31203
31204 fn generate_properties_clause(&mut self, properties: &[Expression]) -> Result<()> {
31206 self.write_keyword("PROPERTIES");
31207 self.write(" (");
31208 for (i, prop) in properties.iter().enumerate() {
31209 if i > 0 {
31210 self.write(", ");
31211 }
31212 self.generate_option_expression(prop)?;
31213 }
31214 self.write(")");
31215 Ok(())
31216 }
31217
31218 fn generate_environment_clause(&mut self, environment: &[Expression]) -> Result<()> {
31220 self.write_keyword("ENVIRONMENT");
31221 self.write(" (");
31222 for (i, env_item) in environment.iter().enumerate() {
31223 if i > 0 {
31224 self.write(", ");
31225 }
31226 self.generate_environment_expression(env_item)?;
31227 }
31228 self.write(")");
31229 Ok(())
31230 }
31231
31232 fn generate_environment_expression(&mut self, expr: &Expression) -> Result<()> {
31234 match expr {
31235 Expression::Eq(eq) => {
31236 self.generate_expression(&eq.left)?;
31238 self.write(" = ");
31239 self.generate_expression(&eq.right)?;
31240 Ok(())
31241 }
31242 _ => self.generate_expression(expr),
31243 }
31244 }
31245
31246 fn generate_tblproperties_clause(&mut self, options: &[Expression]) -> Result<()> {
31248 self.write_keyword("TBLPROPERTIES");
31249 if self.config.pretty {
31250 self.write(" (");
31251 self.write_newline();
31252 self.indent_level += 1;
31253 for (i, opt) in options.iter().enumerate() {
31254 if i > 0 {
31255 self.write(",");
31256 self.write_newline();
31257 }
31258 self.write_indent();
31259 self.generate_option_expression(opt)?;
31260 }
31261 self.indent_level -= 1;
31262 self.write_newline();
31263 self.write(")");
31264 } else {
31265 self.write(" (");
31266 for (i, opt) in options.iter().enumerate() {
31267 if i > 0 {
31268 self.write(", ");
31269 }
31270 self.generate_option_expression(opt)?;
31271 }
31272 self.write(")");
31273 }
31274 Ok(())
31275 }
31276
31277 fn generate_option_expression(&mut self, expr: &Expression) -> Result<()> {
31279 match expr {
31280 Expression::Eq(eq) => {
31281 self.generate_expression(&eq.left)?;
31283 self.write("=");
31284 self.generate_expression(&eq.right)?;
31285 Ok(())
31286 }
31287 _ => self.generate_expression(expr),
31288 }
31289 }
31290
31291 fn generate_pseudo_type(&mut self, e: &PseudoType) -> Result<()> {
31292 self.generate_expression(&e.this)?;
31294 Ok(())
31295 }
31296
31297 fn generate_put(&mut self, e: &PutStmt) -> Result<()> {
31298 self.write_keyword("PUT");
31300 self.write_space();
31301
31302 if e.source_quoted {
31304 self.write("'");
31305 self.write(&e.source);
31306 self.write("'");
31307 } else {
31308 self.write(&e.source);
31309 }
31310
31311 self.write_space();
31312
31313 if let Expression::Literal(Literal::String(s)) = &e.target {
31315 self.write(s);
31316 } else {
31317 self.generate_expression(&e.target)?;
31318 }
31319
31320 for param in &e.params {
31322 self.write_space();
31323 self.write(¶m.name);
31324 if let Some(ref value) = param.value {
31325 self.write("=");
31326 self.generate_expression(value)?;
31327 }
31328 }
31329
31330 Ok(())
31331 }
31332
31333 fn generate_quantile(&mut self, e: &Quantile) -> Result<()> {
31334 self.write_keyword("QUANTILE");
31336 self.write("(");
31337 self.generate_expression(&e.this)?;
31338 if let Some(quantile) = &e.quantile {
31339 self.write(", ");
31340 self.generate_expression(quantile)?;
31341 }
31342 self.write(")");
31343 Ok(())
31344 }
31345
31346 fn generate_query_band(&mut self, e: &QueryBand) -> Result<()> {
31347 if matches!(
31349 self.config.dialect,
31350 Some(crate::dialects::DialectType::Teradata)
31351 ) {
31352 self.write_keyword("SET");
31353 self.write_space();
31354 }
31355 self.write_keyword("QUERY_BAND");
31356 self.write(" = ");
31357 self.generate_expression(&e.this)?;
31358 if e.update.is_some() {
31359 self.write_space();
31360 self.write_keyword("UPDATE");
31361 }
31362 if let Some(scope) = &e.scope {
31363 self.write_space();
31364 self.write_keyword("FOR");
31365 self.write_space();
31366 self.generate_expression(scope)?;
31367 }
31368 Ok(())
31369 }
31370
31371 fn generate_query_option(&mut self, e: &QueryOption) -> Result<()> {
31372 self.generate_expression(&e.this)?;
31374 if let Some(expression) = &e.expression {
31375 self.write(" = ");
31376 self.generate_expression(expression)?;
31377 }
31378 Ok(())
31379 }
31380
31381 fn generate_query_transform(&mut self, e: &QueryTransform) -> Result<()> {
31382 self.write_keyword("TRANSFORM");
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 if let Some(row_format_before) = &e.row_format_before {
31393 self.write_space();
31394 self.generate_expression(row_format_before)?;
31395 }
31396 if let Some(record_writer) = &e.record_writer {
31397 self.write_space();
31398 self.write_keyword("RECORDWRITER");
31399 self.write_space();
31400 self.generate_expression(record_writer)?;
31401 }
31402 if let Some(command_script) = &e.command_script {
31403 self.write_space();
31404 self.write_keyword("USING");
31405 self.write_space();
31406 self.generate_expression(command_script)?;
31407 }
31408 if let Some(schema) = &e.schema {
31409 self.write_space();
31410 self.write_keyword("AS");
31411 self.write_space();
31412 self.generate_expression(schema)?;
31413 }
31414 if let Some(row_format_after) = &e.row_format_after {
31415 self.write_space();
31416 self.generate_expression(row_format_after)?;
31417 }
31418 if let Some(record_reader) = &e.record_reader {
31419 self.write_space();
31420 self.write_keyword("RECORDREADER");
31421 self.write_space();
31422 self.generate_expression(record_reader)?;
31423 }
31424 Ok(())
31425 }
31426
31427 fn generate_randn(&mut self, e: &Randn) -> Result<()> {
31428 self.write_keyword("RANDN");
31430 self.write("(");
31431 if let Some(this) = &e.this {
31432 self.generate_expression(this)?;
31433 }
31434 self.write(")");
31435 Ok(())
31436 }
31437
31438 fn generate_randstr(&mut self, e: &Randstr) -> Result<()> {
31439 self.write_keyword("RANDSTR");
31441 self.write("(");
31442 self.generate_expression(&e.this)?;
31443 if let Some(generator) = &e.generator {
31444 self.write(", ");
31445 self.generate_expression(generator)?;
31446 }
31447 self.write(")");
31448 Ok(())
31449 }
31450
31451 fn generate_range_bucket(&mut self, e: &RangeBucket) -> Result<()> {
31452 self.write_keyword("RANGE_BUCKET");
31454 self.write("(");
31455 self.generate_expression(&e.this)?;
31456 self.write(", ");
31457 self.generate_expression(&e.expression)?;
31458 self.write(")");
31459 Ok(())
31460 }
31461
31462 fn generate_range_n(&mut self, e: &RangeN) -> Result<()> {
31463 self.write_keyword("RANGE_N");
31465 self.write("(");
31466 self.generate_expression(&e.this)?;
31467 self.write_space();
31468 self.write_keyword("BETWEEN");
31469 self.write_space();
31470 for (i, expr) in e.expressions.iter().enumerate() {
31471 if i > 0 {
31472 self.write(", ");
31473 }
31474 self.generate_expression(expr)?;
31475 }
31476 if let Some(each) = &e.each {
31477 self.write_space();
31478 self.write_keyword("EACH");
31479 self.write_space();
31480 self.generate_expression(each)?;
31481 }
31482 self.write(")");
31483 Ok(())
31484 }
31485
31486 fn generate_read_csv(&mut self, e: &ReadCSV) -> Result<()> {
31487 self.write_keyword("READ_CSV");
31489 self.write("(");
31490 self.generate_expression(&e.this)?;
31491 for expr in &e.expressions {
31492 self.write(", ");
31493 self.generate_expression(expr)?;
31494 }
31495 self.write(")");
31496 Ok(())
31497 }
31498
31499 fn generate_read_parquet(&mut self, e: &ReadParquet) -> Result<()> {
31500 self.write_keyword("READ_PARQUET");
31502 self.write("(");
31503 for (i, expr) in e.expressions.iter().enumerate() {
31504 if i > 0 {
31505 self.write(", ");
31506 }
31507 self.generate_expression(expr)?;
31508 }
31509 self.write(")");
31510 Ok(())
31511 }
31512
31513 fn generate_recursive_with_search(&mut self, e: &RecursiveWithSearch) -> Result<()> {
31514 if e.kind == "CYCLE" {
31517 self.write_keyword("CYCLE");
31518 } else {
31519 self.write_keyword("SEARCH");
31520 self.write_space();
31521 self.write(&e.kind);
31522 self.write_space();
31523 self.write_keyword("FIRST BY");
31524 }
31525 self.write_space();
31526 self.generate_expression(&e.this)?;
31527 self.write_space();
31528 self.write_keyword("SET");
31529 self.write_space();
31530 self.generate_expression(&e.expression)?;
31531 if let Some(using) = &e.using {
31532 self.write_space();
31533 self.write_keyword("USING");
31534 self.write_space();
31535 self.generate_expression(using)?;
31536 }
31537 Ok(())
31538 }
31539
31540 fn generate_reduce(&mut self, e: &Reduce) -> Result<()> {
31541 self.write_keyword("REDUCE");
31543 self.write("(");
31544 self.generate_expression(&e.this)?;
31545 if let Some(initial) = &e.initial {
31546 self.write(", ");
31547 self.generate_expression(initial)?;
31548 }
31549 if let Some(merge) = &e.merge {
31550 self.write(", ");
31551 self.generate_expression(merge)?;
31552 }
31553 if let Some(finish) = &e.finish {
31554 self.write(", ");
31555 self.generate_expression(finish)?;
31556 }
31557 self.write(")");
31558 Ok(())
31559 }
31560
31561 fn generate_reference(&mut self, e: &Reference) -> Result<()> {
31562 self.write_keyword("REFERENCES");
31564 self.write_space();
31565 self.generate_expression(&e.this)?;
31566 if !e.expressions.is_empty() {
31567 self.write(" (");
31568 for (i, expr) in e.expressions.iter().enumerate() {
31569 if i > 0 {
31570 self.write(", ");
31571 }
31572 self.generate_expression(expr)?;
31573 }
31574 self.write(")");
31575 }
31576 for opt in &e.options {
31577 self.write_space();
31578 self.generate_expression(opt)?;
31579 }
31580 Ok(())
31581 }
31582
31583 fn generate_refresh(&mut self, e: &Refresh) -> Result<()> {
31584 self.write_keyword("REFRESH");
31586 if !e.kind.is_empty() {
31587 self.write_space();
31588 self.write_keyword(&e.kind);
31589 }
31590 self.write_space();
31591 self.generate_expression(&e.this)?;
31592 Ok(())
31593 }
31594
31595 fn generate_refresh_trigger_property(&mut self, e: &RefreshTriggerProperty) -> Result<()> {
31596 self.write_keyword("REFRESH");
31598 self.write_space();
31599 self.write_keyword(&e.method);
31600
31601 if let Some(ref kind) = e.kind {
31602 self.write_space();
31603 self.write_keyword("ON");
31604 self.write_space();
31605 self.write_keyword(kind);
31606
31607 if let Some(ref every) = e.every {
31609 self.write_space();
31610 self.write_keyword("EVERY");
31611 self.write_space();
31612 self.generate_expression(every)?;
31613 if let Some(ref unit) = e.unit {
31614 self.write_space();
31615 self.write_keyword(unit);
31616 }
31617 }
31618
31619 if let Some(ref starts) = e.starts {
31621 self.write_space();
31622 self.write_keyword("STARTS");
31623 self.write_space();
31624 self.generate_expression(starts)?;
31625 }
31626 }
31627 Ok(())
31628 }
31629
31630 fn generate_regexp_count(&mut self, e: &RegexpCount) -> Result<()> {
31631 self.write_keyword("REGEXP_COUNT");
31633 self.write("(");
31634 self.generate_expression(&e.this)?;
31635 self.write(", ");
31636 self.generate_expression(&e.expression)?;
31637 if let Some(position) = &e.position {
31638 self.write(", ");
31639 self.generate_expression(position)?;
31640 }
31641 if let Some(parameters) = &e.parameters {
31642 self.write(", ");
31643 self.generate_expression(parameters)?;
31644 }
31645 self.write(")");
31646 Ok(())
31647 }
31648
31649 fn generate_regexp_extract_all(&mut self, e: &RegexpExtractAll) -> Result<()> {
31650 self.write_keyword("REGEXP_EXTRACT_ALL");
31652 self.write("(");
31653 self.generate_expression(&e.this)?;
31654 self.write(", ");
31655 self.generate_expression(&e.expression)?;
31656 if let Some(group) = &e.group {
31657 self.write(", ");
31658 self.generate_expression(group)?;
31659 }
31660 self.write(")");
31661 Ok(())
31662 }
31663
31664 fn generate_regexp_full_match(&mut self, e: &RegexpFullMatch) -> Result<()> {
31665 self.write_keyword("REGEXP_FULL_MATCH");
31667 self.write("(");
31668 self.generate_expression(&e.this)?;
31669 self.write(", ");
31670 self.generate_expression(&e.expression)?;
31671 self.write(")");
31672 Ok(())
31673 }
31674
31675 fn generate_regexp_i_like(&mut self, e: &RegexpILike) -> Result<()> {
31676 use crate::dialects::DialectType;
31677 if matches!(
31679 self.config.dialect,
31680 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
31681 ) && e.flag.is_none()
31682 {
31683 self.generate_expression(&e.this)?;
31684 self.write(" ~* ");
31685 self.generate_expression(&e.expression)?;
31686 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
31687 self.write_keyword("REGEXP_LIKE");
31689 self.write("(");
31690 self.generate_expression(&e.this)?;
31691 self.write(", ");
31692 self.generate_expression(&e.expression)?;
31693 self.write(", ");
31694 if let Some(flag) = &e.flag {
31695 self.generate_expression(flag)?;
31696 } else {
31697 self.write("'i'");
31698 }
31699 self.write(")");
31700 } else {
31701 self.generate_expression(&e.this)?;
31703 self.write_space();
31704 self.write_keyword("REGEXP_ILIKE");
31705 self.write_space();
31706 self.generate_expression(&e.expression)?;
31707 if let Some(flag) = &e.flag {
31708 self.write(", ");
31709 self.generate_expression(flag)?;
31710 }
31711 }
31712 Ok(())
31713 }
31714
31715 fn generate_regexp_instr(&mut self, e: &RegexpInstr) -> Result<()> {
31716 self.write_keyword("REGEXP_INSTR");
31718 self.write("(");
31719 self.generate_expression(&e.this)?;
31720 self.write(", ");
31721 self.generate_expression(&e.expression)?;
31722 if let Some(position) = &e.position {
31723 self.write(", ");
31724 self.generate_expression(position)?;
31725 }
31726 if let Some(occurrence) = &e.occurrence {
31727 self.write(", ");
31728 self.generate_expression(occurrence)?;
31729 }
31730 if let Some(option) = &e.option {
31731 self.write(", ");
31732 self.generate_expression(option)?;
31733 }
31734 if let Some(parameters) = &e.parameters {
31735 self.write(", ");
31736 self.generate_expression(parameters)?;
31737 }
31738 if let Some(group) = &e.group {
31739 self.write(", ");
31740 self.generate_expression(group)?;
31741 }
31742 self.write(")");
31743 Ok(())
31744 }
31745
31746 fn generate_regexp_split(&mut self, e: &RegexpSplit) -> Result<()> {
31747 self.write_keyword("REGEXP_SPLIT");
31749 self.write("(");
31750 self.generate_expression(&e.this)?;
31751 self.write(", ");
31752 self.generate_expression(&e.expression)?;
31753 if let Some(limit) = &e.limit {
31754 self.write(", ");
31755 self.generate_expression(limit)?;
31756 }
31757 self.write(")");
31758 Ok(())
31759 }
31760
31761 fn generate_regr_avgx(&mut self, e: &RegrAvgx) -> Result<()> {
31762 self.write_keyword("REGR_AVGX");
31764 self.write("(");
31765 self.generate_expression(&e.this)?;
31766 self.write(", ");
31767 self.generate_expression(&e.expression)?;
31768 self.write(")");
31769 Ok(())
31770 }
31771
31772 fn generate_regr_avgy(&mut self, e: &RegrAvgy) -> Result<()> {
31773 self.write_keyword("REGR_AVGY");
31775 self.write("(");
31776 self.generate_expression(&e.this)?;
31777 self.write(", ");
31778 self.generate_expression(&e.expression)?;
31779 self.write(")");
31780 Ok(())
31781 }
31782
31783 fn generate_regr_count(&mut self, e: &RegrCount) -> Result<()> {
31784 self.write_keyword("REGR_COUNT");
31786 self.write("(");
31787 self.generate_expression(&e.this)?;
31788 self.write(", ");
31789 self.generate_expression(&e.expression)?;
31790 self.write(")");
31791 Ok(())
31792 }
31793
31794 fn generate_regr_intercept(&mut self, e: &RegrIntercept) -> Result<()> {
31795 self.write_keyword("REGR_INTERCEPT");
31797 self.write("(");
31798 self.generate_expression(&e.this)?;
31799 self.write(", ");
31800 self.generate_expression(&e.expression)?;
31801 self.write(")");
31802 Ok(())
31803 }
31804
31805 fn generate_regr_r2(&mut self, e: &RegrR2) -> Result<()> {
31806 self.write_keyword("REGR_R2");
31808 self.write("(");
31809 self.generate_expression(&e.this)?;
31810 self.write(", ");
31811 self.generate_expression(&e.expression)?;
31812 self.write(")");
31813 Ok(())
31814 }
31815
31816 fn generate_regr_slope(&mut self, e: &RegrSlope) -> Result<()> {
31817 self.write_keyword("REGR_SLOPE");
31819 self.write("(");
31820 self.generate_expression(&e.this)?;
31821 self.write(", ");
31822 self.generate_expression(&e.expression)?;
31823 self.write(")");
31824 Ok(())
31825 }
31826
31827 fn generate_regr_sxx(&mut self, e: &RegrSxx) -> Result<()> {
31828 self.write_keyword("REGR_SXX");
31830 self.write("(");
31831 self.generate_expression(&e.this)?;
31832 self.write(", ");
31833 self.generate_expression(&e.expression)?;
31834 self.write(")");
31835 Ok(())
31836 }
31837
31838 fn generate_regr_sxy(&mut self, e: &RegrSxy) -> Result<()> {
31839 self.write_keyword("REGR_SXY");
31841 self.write("(");
31842 self.generate_expression(&e.this)?;
31843 self.write(", ");
31844 self.generate_expression(&e.expression)?;
31845 self.write(")");
31846 Ok(())
31847 }
31848
31849 fn generate_regr_syy(&mut self, e: &RegrSyy) -> Result<()> {
31850 self.write_keyword("REGR_SYY");
31852 self.write("(");
31853 self.generate_expression(&e.this)?;
31854 self.write(", ");
31855 self.generate_expression(&e.expression)?;
31856 self.write(")");
31857 Ok(())
31858 }
31859
31860 fn generate_regr_valx(&mut self, e: &RegrValx) -> Result<()> {
31861 self.write_keyword("REGR_VALX");
31863 self.write("(");
31864 self.generate_expression(&e.this)?;
31865 self.write(", ");
31866 self.generate_expression(&e.expression)?;
31867 self.write(")");
31868 Ok(())
31869 }
31870
31871 fn generate_regr_valy(&mut self, e: &RegrValy) -> Result<()> {
31872 self.write_keyword("REGR_VALY");
31874 self.write("(");
31875 self.generate_expression(&e.this)?;
31876 self.write(", ");
31877 self.generate_expression(&e.expression)?;
31878 self.write(")");
31879 Ok(())
31880 }
31881
31882 fn generate_remote_with_connection_model_property(
31883 &mut self,
31884 e: &RemoteWithConnectionModelProperty,
31885 ) -> Result<()> {
31886 self.write_keyword("REMOTE WITH CONNECTION");
31888 self.write_space();
31889 self.generate_expression(&e.this)?;
31890 Ok(())
31891 }
31892
31893 fn generate_rename_column(&mut self, e: &RenameColumn) -> Result<()> {
31894 self.write_keyword("RENAME COLUMN");
31896 if e.exists {
31897 self.write_space();
31898 self.write_keyword("IF EXISTS");
31899 }
31900 self.write_space();
31901 self.generate_expression(&e.this)?;
31902 if let Some(to) = &e.to {
31903 self.write_space();
31904 self.write_keyword("TO");
31905 self.write_space();
31906 self.generate_expression(to)?;
31907 }
31908 Ok(())
31909 }
31910
31911 fn generate_replace_partition(&mut self, e: &ReplacePartition) -> Result<()> {
31912 self.write_keyword("REPLACE PARTITION");
31914 self.write_space();
31915 self.generate_expression(&e.expression)?;
31916 if let Some(source) = &e.source {
31917 self.write_space();
31918 self.write_keyword("FROM");
31919 self.write_space();
31920 self.generate_expression(source)?;
31921 }
31922 Ok(())
31923 }
31924
31925 fn generate_returning(&mut self, e: &Returning) -> Result<()> {
31926 let keyword = match self.config.dialect {
31929 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "OUTPUT",
31930 _ => "RETURNING",
31931 };
31932 self.write_keyword(keyword);
31933 self.write_space();
31934 for (i, expr) in e.expressions.iter().enumerate() {
31935 if i > 0 {
31936 self.write(", ");
31937 }
31938 self.generate_expression(expr)?;
31939 }
31940 if let Some(into) = &e.into {
31941 self.write_space();
31942 self.write_keyword("INTO");
31943 self.write_space();
31944 self.generate_expression(into)?;
31945 }
31946 Ok(())
31947 }
31948
31949 fn generate_output_clause(&mut self, output: &OutputClause) -> Result<()> {
31950 self.write_space();
31952 self.write_keyword("OUTPUT");
31953 self.write_space();
31954 for (i, expr) in output.columns.iter().enumerate() {
31955 if i > 0 {
31956 self.write(", ");
31957 }
31958 self.generate_expression(expr)?;
31959 }
31960 if let Some(into_table) = &output.into_table {
31961 self.write_space();
31962 self.write_keyword("INTO");
31963 self.write_space();
31964 self.generate_expression(into_table)?;
31965 }
31966 Ok(())
31967 }
31968
31969 fn generate_returns_property(&mut self, e: &ReturnsProperty) -> Result<()> {
31970 self.write_keyword("RETURNS");
31972 if e.is_table.is_some() {
31973 self.write_space();
31974 self.write_keyword("TABLE");
31975 }
31976 if let Some(table) = &e.table {
31977 self.write_space();
31978 self.generate_expression(table)?;
31979 } else if let Some(this) = &e.this {
31980 self.write_space();
31981 self.generate_expression(this)?;
31982 }
31983 if e.null.is_some() {
31984 self.write_space();
31985 self.write_keyword("NULL ON NULL INPUT");
31986 }
31987 Ok(())
31988 }
31989
31990 fn generate_rollback(&mut self, e: &Rollback) -> Result<()> {
31991 self.write_keyword("ROLLBACK");
31993
31994 if e.this.is_none()
31996 && matches!(
31997 self.config.dialect,
31998 Some(DialectType::TSQL) | Some(DialectType::Fabric)
31999 )
32000 {
32001 self.write_space();
32002 self.write_keyword("TRANSACTION");
32003 }
32004
32005 if let Some(this) = &e.this {
32007 let is_transaction_marker = matches!(
32009 this.as_ref(),
32010 Expression::Identifier(id) if id.name == "TRANSACTION"
32011 );
32012
32013 self.write_space();
32014 self.write_keyword("TRANSACTION");
32015
32016 if !is_transaction_marker {
32018 self.write_space();
32019 self.generate_expression(this)?;
32020 }
32021 }
32022
32023 if let Some(savepoint) = &e.savepoint {
32025 self.write_space();
32026 self.write_keyword("TO");
32027 self.write_space();
32028 self.generate_expression(savepoint)?;
32029 }
32030 Ok(())
32031 }
32032
32033 fn generate_rollup(&mut self, e: &Rollup) -> Result<()> {
32034 if e.expressions.is_empty() {
32036 self.write_keyword("WITH ROLLUP");
32037 } else {
32038 self.write_keyword("ROLLUP");
32039 self.write("(");
32040 for (i, expr) in e.expressions.iter().enumerate() {
32041 if i > 0 {
32042 self.write(", ");
32043 }
32044 self.generate_expression(expr)?;
32045 }
32046 self.write(")");
32047 }
32048 Ok(())
32049 }
32050
32051 fn generate_row_format_delimited_property(
32052 &mut self,
32053 e: &RowFormatDelimitedProperty,
32054 ) -> Result<()> {
32055 self.write_keyword("ROW FORMAT DELIMITED");
32057 if let Some(fields) = &e.fields {
32058 self.write_space();
32059 self.write_keyword("FIELDS TERMINATED BY");
32060 self.write_space();
32061 self.generate_expression(fields)?;
32062 }
32063 if let Some(escaped) = &e.escaped {
32064 self.write_space();
32065 self.write_keyword("ESCAPED BY");
32066 self.write_space();
32067 self.generate_expression(escaped)?;
32068 }
32069 if let Some(items) = &e.collection_items {
32070 self.write_space();
32071 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
32072 self.write_space();
32073 self.generate_expression(items)?;
32074 }
32075 if let Some(keys) = &e.map_keys {
32076 self.write_space();
32077 self.write_keyword("MAP KEYS TERMINATED BY");
32078 self.write_space();
32079 self.generate_expression(keys)?;
32080 }
32081 if let Some(lines) = &e.lines {
32082 self.write_space();
32083 self.write_keyword("LINES TERMINATED BY");
32084 self.write_space();
32085 self.generate_expression(lines)?;
32086 }
32087 if let Some(null) = &e.null {
32088 self.write_space();
32089 self.write_keyword("NULL DEFINED AS");
32090 self.write_space();
32091 self.generate_expression(null)?;
32092 }
32093 if let Some(serde) = &e.serde {
32094 self.write_space();
32095 self.generate_expression(serde)?;
32096 }
32097 Ok(())
32098 }
32099
32100 fn generate_row_format_property(&mut self, e: &RowFormatProperty) -> Result<()> {
32101 self.write_keyword("ROW FORMAT");
32103 self.write_space();
32104 self.generate_expression(&e.this)?;
32105 Ok(())
32106 }
32107
32108 fn generate_row_format_serde_property(&mut self, e: &RowFormatSerdeProperty) -> Result<()> {
32109 self.write_keyword("ROW FORMAT SERDE");
32111 self.write_space();
32112 self.generate_expression(&e.this)?;
32113 if let Some(props) = &e.serde_properties {
32114 self.write_space();
32115 self.generate_expression(props)?;
32117 }
32118 Ok(())
32119 }
32120
32121 fn generate_sha2(&mut self, e: &SHA2) -> Result<()> {
32122 self.write_keyword("SHA2");
32124 self.write("(");
32125 self.generate_expression(&e.this)?;
32126 if let Some(length) = e.length {
32127 self.write(", ");
32128 self.write(&length.to_string());
32129 }
32130 self.write(")");
32131 Ok(())
32132 }
32133
32134 fn generate_sha2_digest(&mut self, e: &SHA2Digest) -> Result<()> {
32135 self.write_keyword("SHA2_DIGEST");
32137 self.write("(");
32138 self.generate_expression(&e.this)?;
32139 if let Some(length) = e.length {
32140 self.write(", ");
32141 self.write(&length.to_string());
32142 }
32143 self.write(")");
32144 Ok(())
32145 }
32146
32147 fn generate_safe_add(&mut self, e: &SafeAdd) -> Result<()> {
32148 let name = if matches!(
32149 self.config.dialect,
32150 Some(crate::dialects::DialectType::Spark)
32151 | Some(crate::dialects::DialectType::Databricks)
32152 ) {
32153 "TRY_ADD"
32154 } else {
32155 "SAFE_ADD"
32156 };
32157 self.write_keyword(name);
32158 self.write("(");
32159 self.generate_expression(&e.this)?;
32160 self.write(", ");
32161 self.generate_expression(&e.expression)?;
32162 self.write(")");
32163 Ok(())
32164 }
32165
32166 fn generate_safe_divide(&mut self, e: &SafeDivide) -> Result<()> {
32167 self.write_keyword("SAFE_DIVIDE");
32169 self.write("(");
32170 self.generate_expression(&e.this)?;
32171 self.write(", ");
32172 self.generate_expression(&e.expression)?;
32173 self.write(")");
32174 Ok(())
32175 }
32176
32177 fn generate_safe_multiply(&mut self, e: &SafeMultiply) -> Result<()> {
32178 let name = if matches!(
32179 self.config.dialect,
32180 Some(crate::dialects::DialectType::Spark)
32181 | Some(crate::dialects::DialectType::Databricks)
32182 ) {
32183 "TRY_MULTIPLY"
32184 } else {
32185 "SAFE_MULTIPLY"
32186 };
32187 self.write_keyword(name);
32188 self.write("(");
32189 self.generate_expression(&e.this)?;
32190 self.write(", ");
32191 self.generate_expression(&e.expression)?;
32192 self.write(")");
32193 Ok(())
32194 }
32195
32196 fn generate_safe_subtract(&mut self, e: &SafeSubtract) -> Result<()> {
32197 let name = if matches!(
32198 self.config.dialect,
32199 Some(crate::dialects::DialectType::Spark)
32200 | Some(crate::dialects::DialectType::Databricks)
32201 ) {
32202 "TRY_SUBTRACT"
32203 } else {
32204 "SAFE_SUBTRACT"
32205 };
32206 self.write_keyword(name);
32207 self.write("(");
32208 self.generate_expression(&e.this)?;
32209 self.write(", ");
32210 self.generate_expression(&e.expression)?;
32211 self.write(")");
32212 Ok(())
32213 }
32214
32215 fn generate_sample_body(&mut self, sample: &Sample) -> Result<()> {
32218 if matches!(sample.method, SampleMethod::Bucket) {
32220 self.write(" (");
32221 self.write_keyword("BUCKET");
32222 self.write_space();
32223 if let Some(ref num) = sample.bucket_numerator {
32224 self.generate_expression(num)?;
32225 }
32226 self.write_space();
32227 self.write_keyword("OUT OF");
32228 self.write_space();
32229 if let Some(ref denom) = sample.bucket_denominator {
32230 self.generate_expression(denom)?;
32231 }
32232 if let Some(ref field) = sample.bucket_field {
32233 self.write_space();
32234 self.write_keyword("ON");
32235 self.write_space();
32236 self.generate_expression(field)?;
32237 }
32238 self.write(")");
32239 return Ok(());
32240 }
32241
32242 let is_snowflake = matches!(
32244 self.config.dialect,
32245 Some(crate::dialects::DialectType::Snowflake)
32246 );
32247 let is_postgres = matches!(
32248 self.config.dialect,
32249 Some(crate::dialects::DialectType::PostgreSQL)
32250 | Some(crate::dialects::DialectType::Redshift)
32251 );
32252 let is_databricks = matches!(
32254 self.config.dialect,
32255 Some(crate::dialects::DialectType::Databricks)
32256 );
32257 let is_spark = matches!(
32258 self.config.dialect,
32259 Some(crate::dialects::DialectType::Spark)
32260 );
32261 let suppress_method = is_databricks || is_spark || sample.suppress_method_output;
32262 let force_method = is_postgres && matches!(sample.method, SampleMethod::Bernoulli);
32264 if !suppress_method && (sample.explicit_method || is_snowflake || force_method) {
32265 self.write_space();
32266 if !sample.explicit_method && (is_snowflake || force_method) {
32267 self.write_keyword("BERNOULLI");
32269 } else {
32270 match sample.method {
32271 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
32272 SampleMethod::System => self.write_keyword("SYSTEM"),
32273 SampleMethod::Block => self.write_keyword("BLOCK"),
32274 SampleMethod::Row => self.write_keyword("ROW"),
32275 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
32276 SampleMethod::Percent => self.write_keyword("SYSTEM"),
32277 SampleMethod::Bucket => {} }
32279 }
32280 }
32281
32282 let emit_size_no_parens = !self.config.tablesample_requires_parens;
32284 if emit_size_no_parens {
32285 self.write_space();
32286 match &sample.size {
32287 Expression::Tuple(tuple) => {
32288 for (i, expr) in tuple.expressions.iter().enumerate() {
32289 if i > 0 {
32290 self.write(", ");
32291 }
32292 self.generate_expression(expr)?;
32293 }
32294 }
32295 expr => self.generate_expression(expr)?,
32296 }
32297 } else {
32298 self.write(" (");
32299 self.generate_expression(&sample.size)?;
32300 }
32301
32302 let is_rows_method = matches!(
32304 sample.method,
32305 SampleMethod::Reservoir | SampleMethod::Row | SampleMethod::Bucket
32306 );
32307 let is_percent = matches!(
32308 sample.method,
32309 SampleMethod::Percent
32310 | SampleMethod::System
32311 | SampleMethod::Bernoulli
32312 | SampleMethod::Block
32313 );
32314
32315 let is_presto = matches!(
32319 self.config.dialect,
32320 Some(crate::dialects::DialectType::Presto)
32321 | Some(crate::dialects::DialectType::Trino)
32322 | Some(crate::dialects::DialectType::Athena)
32323 );
32324 let should_output_unit = if is_databricks || is_spark {
32325 is_percent || is_rows_method || sample.unit_after_size
32327 } else if is_snowflake || is_postgres || is_presto {
32328 sample.unit_after_size
32329 } else {
32330 sample.unit_after_size || (sample.explicit_method && (is_rows_method || is_percent))
32331 };
32332
32333 if should_output_unit {
32334 self.write_space();
32335 if sample.is_percent {
32336 self.write_keyword("PERCENT");
32337 } else if is_rows_method && !sample.unit_after_size {
32338 self.write_keyword("ROWS");
32339 } else if sample.unit_after_size {
32340 match sample.method {
32341 SampleMethod::Percent
32342 | SampleMethod::System
32343 | SampleMethod::Bernoulli
32344 | SampleMethod::Block => {
32345 self.write_keyword("PERCENT");
32346 }
32347 SampleMethod::Row | SampleMethod::Reservoir => {
32348 self.write_keyword("ROWS");
32349 }
32350 _ => self.write_keyword("ROWS"),
32351 }
32352 } else {
32353 self.write_keyword("PERCENT");
32354 }
32355 }
32356
32357 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
32358 if let Some(ref offset) = sample.offset {
32359 self.write_space();
32360 self.write_keyword("OFFSET");
32361 self.write_space();
32362 self.generate_expression(offset)?;
32363 }
32364 }
32365 if !emit_size_no_parens {
32366 self.write(")");
32367 }
32368
32369 Ok(())
32370 }
32371
32372 fn generate_sample_property(&mut self, e: &SampleProperty) -> Result<()> {
32373 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
32375 self.write_keyword("SAMPLE BY");
32376 } else {
32377 self.write_keyword("SAMPLE");
32378 }
32379 self.write_space();
32380 self.generate_expression(&e.this)?;
32381 Ok(())
32382 }
32383
32384 fn generate_schema(&mut self, e: &Schema) -> Result<()> {
32385 if let Some(this) = &e.this {
32387 self.generate_expression(this)?;
32388 }
32389 if !e.expressions.is_empty() {
32390 if e.this.is_some() {
32392 self.write_space();
32393 }
32394 self.write("(");
32395 for (i, expr) in e.expressions.iter().enumerate() {
32396 if i > 0 {
32397 self.write(", ");
32398 }
32399 self.generate_expression(expr)?;
32400 }
32401 self.write(")");
32402 }
32403 Ok(())
32404 }
32405
32406 fn generate_schema_comment_property(&mut self, e: &SchemaCommentProperty) -> Result<()> {
32407 self.write_keyword("COMMENT");
32409 self.write_space();
32410 self.generate_expression(&e.this)?;
32411 Ok(())
32412 }
32413
32414 fn generate_scope_resolution(&mut self, e: &ScopeResolution) -> Result<()> {
32415 if let Some(this) = &e.this {
32417 self.generate_expression(this)?;
32418 self.write("::");
32419 }
32420 self.generate_expression(&e.expression)?;
32421 Ok(())
32422 }
32423
32424 fn generate_search(&mut self, e: &Search) -> Result<()> {
32425 self.write_keyword("SEARCH");
32427 self.write("(");
32428 self.generate_expression(&e.this)?;
32429 self.write(", ");
32430 self.generate_expression(&e.expression)?;
32431 if let Some(json_scope) = &e.json_scope {
32432 self.write(", ");
32433 self.generate_expression(json_scope)?;
32434 }
32435 if let Some(analyzer) = &e.analyzer {
32436 self.write(", ");
32437 self.generate_expression(analyzer)?;
32438 }
32439 if let Some(analyzer_options) = &e.analyzer_options {
32440 self.write(", ");
32441 self.generate_expression(analyzer_options)?;
32442 }
32443 if let Some(search_mode) = &e.search_mode {
32444 self.write(", ");
32445 self.generate_expression(search_mode)?;
32446 }
32447 self.write(")");
32448 Ok(())
32449 }
32450
32451 fn generate_search_ip(&mut self, e: &SearchIp) -> Result<()> {
32452 self.write_keyword("SEARCH_IP");
32454 self.write("(");
32455 self.generate_expression(&e.this)?;
32456 self.write(", ");
32457 self.generate_expression(&e.expression)?;
32458 self.write(")");
32459 Ok(())
32460 }
32461
32462 fn generate_security_property(&mut self, e: &SecurityProperty) -> Result<()> {
32463 self.write_keyword("SECURITY");
32465 self.write_space();
32466 self.generate_expression(&e.this)?;
32467 Ok(())
32468 }
32469
32470 fn generate_semantic_view(&mut self, e: &SemanticView) -> Result<()> {
32471 self.write("SEMANTIC_VIEW(");
32473
32474 if self.config.pretty {
32475 self.write_newline();
32477 self.indent_level += 1;
32478 self.write_indent();
32479 self.generate_expression(&e.this)?;
32480
32481 if let Some(metrics) = &e.metrics {
32482 self.write_newline();
32483 self.write_indent();
32484 self.write_keyword("METRICS");
32485 self.write_space();
32486 self.generate_semantic_view_tuple(metrics)?;
32487 }
32488 if let Some(dimensions) = &e.dimensions {
32489 self.write_newline();
32490 self.write_indent();
32491 self.write_keyword("DIMENSIONS");
32492 self.write_space();
32493 self.generate_semantic_view_tuple(dimensions)?;
32494 }
32495 if let Some(facts) = &e.facts {
32496 self.write_newline();
32497 self.write_indent();
32498 self.write_keyword("FACTS");
32499 self.write_space();
32500 self.generate_semantic_view_tuple(facts)?;
32501 }
32502 if let Some(where_) = &e.where_ {
32503 self.write_newline();
32504 self.write_indent();
32505 self.write_keyword("WHERE");
32506 self.write_space();
32507 self.generate_expression(where_)?;
32508 }
32509 self.write_newline();
32510 self.indent_level -= 1;
32511 self.write_indent();
32512 } else {
32513 self.generate_expression(&e.this)?;
32515 if let Some(metrics) = &e.metrics {
32516 self.write_space();
32517 self.write_keyword("METRICS");
32518 self.write_space();
32519 self.generate_semantic_view_tuple(metrics)?;
32520 }
32521 if let Some(dimensions) = &e.dimensions {
32522 self.write_space();
32523 self.write_keyword("DIMENSIONS");
32524 self.write_space();
32525 self.generate_semantic_view_tuple(dimensions)?;
32526 }
32527 if let Some(facts) = &e.facts {
32528 self.write_space();
32529 self.write_keyword("FACTS");
32530 self.write_space();
32531 self.generate_semantic_view_tuple(facts)?;
32532 }
32533 if let Some(where_) = &e.where_ {
32534 self.write_space();
32535 self.write_keyword("WHERE");
32536 self.write_space();
32537 self.generate_expression(where_)?;
32538 }
32539 }
32540 self.write(")");
32541 Ok(())
32542 }
32543
32544 fn generate_semantic_view_tuple(&mut self, expr: &Expression) -> Result<()> {
32546 if let Expression::Tuple(t) = expr {
32547 for (i, e) in t.expressions.iter().enumerate() {
32548 if i > 0 {
32549 self.write(", ");
32550 }
32551 self.generate_expression(e)?;
32552 }
32553 } else {
32554 self.generate_expression(expr)?;
32555 }
32556 Ok(())
32557 }
32558
32559 fn generate_sequence_properties(&mut self, e: &SequenceProperties) -> Result<()> {
32560 if let Some(start) = &e.start {
32562 self.write_keyword("START WITH");
32563 self.write_space();
32564 self.generate_expression(start)?;
32565 }
32566 if let Some(increment) = &e.increment {
32567 self.write_space();
32568 self.write_keyword("INCREMENT BY");
32569 self.write_space();
32570 self.generate_expression(increment)?;
32571 }
32572 if let Some(minvalue) = &e.minvalue {
32573 self.write_space();
32574 self.write_keyword("MINVALUE");
32575 self.write_space();
32576 self.generate_expression(minvalue)?;
32577 }
32578 if let Some(maxvalue) = &e.maxvalue {
32579 self.write_space();
32580 self.write_keyword("MAXVALUE");
32581 self.write_space();
32582 self.generate_expression(maxvalue)?;
32583 }
32584 if let Some(cache) = &e.cache {
32585 self.write_space();
32586 self.write_keyword("CACHE");
32587 self.write_space();
32588 self.generate_expression(cache)?;
32589 }
32590 if let Some(owned) = &e.owned {
32591 self.write_space();
32592 self.write_keyword("OWNED BY");
32593 self.write_space();
32594 self.generate_expression(owned)?;
32595 }
32596 for opt in &e.options {
32597 self.write_space();
32598 self.generate_expression(opt)?;
32599 }
32600 Ok(())
32601 }
32602
32603 fn generate_serde_properties(&mut self, e: &SerdeProperties) -> Result<()> {
32604 if e.with_.is_some() {
32606 self.write_keyword("WITH");
32607 self.write_space();
32608 }
32609 self.write_keyword("SERDEPROPERTIES");
32610 self.write(" (");
32611 for (i, expr) in e.expressions.iter().enumerate() {
32612 if i > 0 {
32613 self.write(", ");
32614 }
32615 match expr {
32617 Expression::Eq(eq) => {
32618 self.generate_expression(&eq.left)?;
32619 self.write("=");
32620 self.generate_expression(&eq.right)?;
32621 }
32622 _ => self.generate_expression(expr)?,
32623 }
32624 }
32625 self.write(")");
32626 Ok(())
32627 }
32628
32629 fn generate_session_parameter(&mut self, e: &SessionParameter) -> Result<()> {
32630 self.write("@@");
32632 if let Some(kind) = &e.kind {
32633 self.write(kind);
32634 self.write(".");
32635 }
32636 self.generate_expression(&e.this)?;
32637 Ok(())
32638 }
32639
32640 fn generate_set(&mut self, e: &Set) -> Result<()> {
32641 if e.unset.is_some() {
32643 self.write_keyword("UNSET");
32644 } else {
32645 self.write_keyword("SET");
32646 }
32647 if e.tag.is_some() {
32648 self.write_space();
32649 self.write_keyword("TAG");
32650 }
32651 if !e.expressions.is_empty() {
32652 self.write_space();
32653 for (i, expr) in e.expressions.iter().enumerate() {
32654 if i > 0 {
32655 self.write(", ");
32656 }
32657 self.generate_expression(expr)?;
32658 }
32659 }
32660 Ok(())
32661 }
32662
32663 fn generate_set_config_property(&mut self, e: &SetConfigProperty) -> Result<()> {
32664 self.write_keyword("SET");
32666 self.write_space();
32667 self.generate_expression(&e.this)?;
32668 Ok(())
32669 }
32670
32671 fn generate_set_item(&mut self, e: &SetItem) -> Result<()> {
32672 if let Some(kind) = &e.kind {
32674 self.write_keyword(kind);
32675 self.write_space();
32676 }
32677 self.generate_expression(&e.name)?;
32678 self.write(" = ");
32679 self.generate_expression(&e.value)?;
32680 Ok(())
32681 }
32682
32683 fn generate_set_operation(&mut self, e: &SetOperation) -> Result<()> {
32684 if let Some(with_) = &e.with_ {
32686 self.generate_expression(with_)?;
32687 self.write_space();
32688 }
32689 self.generate_expression(&e.this)?;
32690 self.write_space();
32691 if let Some(kind) = &e.kind {
32693 self.write_keyword(kind);
32694 }
32695 if e.distinct {
32696 self.write_space();
32697 self.write_keyword("DISTINCT");
32698 } else {
32699 self.write_space();
32700 self.write_keyword("ALL");
32701 }
32702 if e.by_name.is_some() {
32703 self.write_space();
32704 self.write_keyword("BY NAME");
32705 }
32706 self.write_space();
32707 self.generate_expression(&e.expression)?;
32708 Ok(())
32709 }
32710
32711 fn generate_set_property(&mut self, e: &SetProperty) -> Result<()> {
32712 if e.multi.is_some() {
32714 self.write_keyword("MULTISET");
32715 } else {
32716 self.write_keyword("SET");
32717 }
32718 Ok(())
32719 }
32720
32721 fn generate_settings_property(&mut self, e: &SettingsProperty) -> Result<()> {
32722 self.write_keyword("SETTINGS");
32724 if self.config.pretty && e.expressions.len() > 1 {
32725 self.indent_level += 1;
32727 for (i, expr) in e.expressions.iter().enumerate() {
32728 if i > 0 {
32729 self.write(",");
32730 }
32731 self.write_newline();
32732 self.write_indent();
32733 self.generate_expression(expr)?;
32734 }
32735 self.indent_level -= 1;
32736 } else {
32737 self.write_space();
32738 for (i, expr) in e.expressions.iter().enumerate() {
32739 if i > 0 {
32740 self.write(", ");
32741 }
32742 self.generate_expression(expr)?;
32743 }
32744 }
32745 Ok(())
32746 }
32747
32748 fn generate_sharing_property(&mut self, e: &SharingProperty) -> Result<()> {
32749 self.write_keyword("SHARING");
32751 if let Some(this) = &e.this {
32752 self.write(" = ");
32753 self.generate_expression(this)?;
32754 }
32755 Ok(())
32756 }
32757
32758 fn generate_slice(&mut self, e: &Slice) -> Result<()> {
32759 if let Some(begin) = &e.this {
32761 self.generate_expression(begin)?;
32762 }
32763 self.write(":");
32764 if let Some(end) = &e.expression {
32765 self.generate_expression(end)?;
32766 }
32767 if let Some(step) = &e.step {
32768 self.write(":");
32769 self.generate_expression(step)?;
32770 }
32771 Ok(())
32772 }
32773
32774 fn generate_sort_array(&mut self, e: &SortArray) -> Result<()> {
32775 self.write_keyword("SORT_ARRAY");
32777 self.write("(");
32778 self.generate_expression(&e.this)?;
32779 if let Some(asc) = &e.asc {
32780 self.write(", ");
32781 self.generate_expression(asc)?;
32782 }
32783 self.write(")");
32784 Ok(())
32785 }
32786
32787 fn generate_sort_by(&mut self, e: &SortBy) -> Result<()> {
32788 self.write_keyword("SORT BY");
32790 self.write_space();
32791 for (i, expr) in e.expressions.iter().enumerate() {
32792 if i > 0 {
32793 self.write(", ");
32794 }
32795 self.generate_ordered(expr)?;
32796 }
32797 Ok(())
32798 }
32799
32800 fn generate_sort_key_property(&mut self, e: &SortKeyProperty) -> Result<()> {
32801 if e.compound.is_some() {
32803 self.write_keyword("COMPOUND");
32804 self.write_space();
32805 }
32806 self.write_keyword("SORTKEY");
32807 self.write("(");
32808 if let Expression::Tuple(t) = e.this.as_ref() {
32810 for (i, expr) in t.expressions.iter().enumerate() {
32811 if i > 0 {
32812 self.write(", ");
32813 }
32814 self.generate_expression(expr)?;
32815 }
32816 } else {
32817 self.generate_expression(&e.this)?;
32818 }
32819 self.write(")");
32820 Ok(())
32821 }
32822
32823 fn generate_split_part(&mut self, e: &SplitPart) -> Result<()> {
32824 self.write_keyword("SPLIT_PART");
32826 self.write("(");
32827 self.generate_expression(&e.this)?;
32828 if let Some(delimiter) = &e.delimiter {
32829 self.write(", ");
32830 self.generate_expression(delimiter)?;
32831 }
32832 if let Some(part_index) = &e.part_index {
32833 self.write(", ");
32834 self.generate_expression(part_index)?;
32835 }
32836 self.write(")");
32837 Ok(())
32838 }
32839
32840 fn generate_sql_read_write_property(&mut self, e: &SqlReadWriteProperty) -> Result<()> {
32841 self.generate_expression(&e.this)?;
32843 Ok(())
32844 }
32845
32846 fn generate_sql_security_property(&mut self, e: &SqlSecurityProperty) -> Result<()> {
32847 self.write_keyword("SQL SECURITY");
32849 self.write_space();
32850 self.generate_expression(&e.this)?;
32851 Ok(())
32852 }
32853
32854 fn generate_st_distance(&mut self, e: &StDistance) -> Result<()> {
32855 self.write_keyword("ST_DISTANCE");
32857 self.write("(");
32858 self.generate_expression(&e.this)?;
32859 self.write(", ");
32860 self.generate_expression(&e.expression)?;
32861 if let Some(use_spheroid) = &e.use_spheroid {
32862 self.write(", ");
32863 self.generate_expression(use_spheroid)?;
32864 }
32865 self.write(")");
32866 Ok(())
32867 }
32868
32869 fn generate_st_point(&mut self, e: &StPoint) -> Result<()> {
32870 self.write_keyword("ST_POINT");
32872 self.write("(");
32873 self.generate_expression(&e.this)?;
32874 self.write(", ");
32875 self.generate_expression(&e.expression)?;
32876 self.write(")");
32877 Ok(())
32878 }
32879
32880 fn generate_stability_property(&mut self, e: &StabilityProperty) -> Result<()> {
32881 self.generate_expression(&e.this)?;
32883 Ok(())
32884 }
32885
32886 fn generate_standard_hash(&mut self, e: &StandardHash) -> Result<()> {
32887 self.write_keyword("STANDARD_HASH");
32889 self.write("(");
32890 self.generate_expression(&e.this)?;
32891 if let Some(expression) = &e.expression {
32892 self.write(", ");
32893 self.generate_expression(expression)?;
32894 }
32895 self.write(")");
32896 Ok(())
32897 }
32898
32899 fn generate_storage_handler_property(&mut self, e: &StorageHandlerProperty) -> Result<()> {
32900 self.write_keyword("STORED BY");
32902 self.write_space();
32903 self.generate_expression(&e.this)?;
32904 Ok(())
32905 }
32906
32907 fn generate_str_position(&mut self, e: &StrPosition) -> Result<()> {
32908 use crate::dialects::DialectType;
32911 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
32912 self.write_keyword("CHARINDEX");
32914 self.write("(");
32915 if let Some(substr) = &e.substr {
32916 self.generate_expression(substr)?;
32917 self.write(", ");
32918 }
32919 self.generate_expression(&e.this)?;
32920 if let Some(position) = &e.position {
32921 self.write(", ");
32922 self.generate_expression(position)?;
32923 }
32924 self.write(")");
32925 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
32926 self.write_keyword("POSITION");
32927 self.write("(");
32928 self.generate_expression(&e.this)?;
32929 if let Some(substr) = &e.substr {
32930 self.write(", ");
32931 self.generate_expression(substr)?;
32932 }
32933 if let Some(position) = &e.position {
32934 self.write(", ");
32935 self.generate_expression(position)?;
32936 }
32937 if let Some(occurrence) = &e.occurrence {
32938 self.write(", ");
32939 self.generate_expression(occurrence)?;
32940 }
32941 self.write(")");
32942 } else if matches!(
32943 self.config.dialect,
32944 Some(DialectType::SQLite)
32945 | Some(DialectType::Oracle)
32946 | Some(DialectType::BigQuery)
32947 | Some(DialectType::Teradata)
32948 ) {
32949 self.write_keyword("INSTR");
32950 self.write("(");
32951 self.generate_expression(&e.this)?;
32952 if let Some(substr) = &e.substr {
32953 self.write(", ");
32954 self.generate_expression(substr)?;
32955 }
32956 if let Some(position) = &e.position {
32957 self.write(", ");
32958 self.generate_expression(position)?;
32959 } else if e.occurrence.is_some() {
32960 self.write(", 1");
32963 }
32964 if let Some(occurrence) = &e.occurrence {
32965 self.write(", ");
32966 self.generate_expression(occurrence)?;
32967 }
32968 self.write(")");
32969 } else if matches!(
32970 self.config.dialect,
32971 Some(DialectType::MySQL)
32972 | Some(DialectType::SingleStore)
32973 | Some(DialectType::Doris)
32974 | Some(DialectType::StarRocks)
32975 | Some(DialectType::Hive)
32976 | Some(DialectType::Spark)
32977 | Some(DialectType::Databricks)
32978 ) {
32979 self.write_keyword("LOCATE");
32981 self.write("(");
32982 if let Some(substr) = &e.substr {
32983 self.generate_expression(substr)?;
32984 self.write(", ");
32985 }
32986 self.generate_expression(&e.this)?;
32987 if let Some(position) = &e.position {
32988 self.write(", ");
32989 self.generate_expression(position)?;
32990 }
32991 self.write(")");
32992 } else if matches!(self.config.dialect, Some(DialectType::TSQL)) {
32993 self.write_keyword("CHARINDEX");
32995 self.write("(");
32996 if let Some(substr) = &e.substr {
32997 self.generate_expression(substr)?;
32998 self.write(", ");
32999 }
33000 self.generate_expression(&e.this)?;
33001 if let Some(position) = &e.position {
33002 self.write(", ");
33003 self.generate_expression(position)?;
33004 }
33005 self.write(")");
33006 } else if matches!(
33007 self.config.dialect,
33008 Some(DialectType::PostgreSQL)
33009 | Some(DialectType::Materialize)
33010 | Some(DialectType::RisingWave)
33011 | Some(DialectType::Redshift)
33012 ) {
33013 self.write_keyword("POSITION");
33015 self.write("(");
33016 if let Some(substr) = &e.substr {
33017 self.generate_expression(substr)?;
33018 self.write(" IN ");
33019 }
33020 self.generate_expression(&e.this)?;
33021 self.write(")");
33022 } else {
33023 self.write_keyword("STRPOS");
33024 self.write("(");
33025 self.generate_expression(&e.this)?;
33026 if let Some(substr) = &e.substr {
33027 self.write(", ");
33028 self.generate_expression(substr)?;
33029 }
33030 if let Some(position) = &e.position {
33031 self.write(", ");
33032 self.generate_expression(position)?;
33033 }
33034 if let Some(occurrence) = &e.occurrence {
33035 self.write(", ");
33036 self.generate_expression(occurrence)?;
33037 }
33038 self.write(")");
33039 }
33040 Ok(())
33041 }
33042
33043 fn generate_str_to_date(&mut self, e: &StrToDate) -> Result<()> {
33044 match self.config.dialect {
33045 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
33046 self.write_keyword("TO_DATE");
33048 self.write("(");
33049 self.generate_expression(&e.this)?;
33050 if let Some(format) = &e.format {
33051 self.write(", '");
33052 self.write(&Self::strftime_to_java_format(format));
33053 self.write("'");
33054 }
33055 self.write(")");
33056 }
33057 Some(DialectType::DuckDB) => {
33058 self.write_keyword("CAST");
33060 self.write("(");
33061 self.write_keyword("STRPTIME");
33062 self.write("(");
33063 self.generate_expression(&e.this)?;
33064 if let Some(format) = &e.format {
33065 self.write(", '");
33066 self.write(format);
33067 self.write("'");
33068 }
33069 self.write(")");
33070 self.write_keyword(" AS ");
33071 self.write_keyword("DATE");
33072 self.write(")");
33073 }
33074 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
33075 self.write_keyword("TO_DATE");
33077 self.write("(");
33078 self.generate_expression(&e.this)?;
33079 if let Some(format) = &e.format {
33080 self.write(", '");
33081 self.write(&Self::strftime_to_postgres_format(format));
33082 self.write("'");
33083 }
33084 self.write(")");
33085 }
33086 Some(DialectType::BigQuery) => {
33087 self.write_keyword("PARSE_DATE");
33089 self.write("(");
33090 if let Some(format) = &e.format {
33091 self.write("'");
33092 self.write(format);
33093 self.write("'");
33094 self.write(", ");
33095 }
33096 self.generate_expression(&e.this)?;
33097 self.write(")");
33098 }
33099 Some(DialectType::Teradata) => {
33100 self.write_keyword("CAST");
33102 self.write("(");
33103 self.generate_expression(&e.this)?;
33104 self.write_keyword(" AS ");
33105 self.write_keyword("DATE");
33106 if let Some(format) = &e.format {
33107 self.write_keyword(" FORMAT ");
33108 self.write("'");
33109 self.write(&Self::strftime_to_teradata_format(format));
33110 self.write("'");
33111 }
33112 self.write(")");
33113 }
33114 _ => {
33115 self.write_keyword("STR_TO_DATE");
33117 self.write("(");
33118 self.generate_expression(&e.this)?;
33119 if let Some(format) = &e.format {
33120 self.write(", '");
33121 self.write(format);
33122 self.write("'");
33123 }
33124 self.write(")");
33125 }
33126 }
33127 Ok(())
33128 }
33129
33130 fn strftime_to_teradata_format(fmt: &str) -> String {
33132 let mut result = fmt.to_string();
33133 result = result.replace("%Y", "YYYY");
33134 result = result.replace("%y", "YY");
33135 result = result.replace("%m", "MM");
33136 result = result.replace("%B", "MMMM");
33137 result = result.replace("%b", "MMM");
33138 result = result.replace("%d", "DD");
33139 result = result.replace("%j", "DDD");
33140 result = result.replace("%H", "HH");
33141 result = result.replace("%M", "MI");
33142 result = result.replace("%S", "SS");
33143 result = result.replace("%f", "SSSSSS");
33144 result = result.replace("%A", "EEEE");
33145 result = result.replace("%a", "EEE");
33146 result
33147 }
33148
33149 pub fn strftime_to_java_format_static(fmt: &str) -> String {
33152 Self::strftime_to_java_format(fmt)
33153 }
33154
33155 fn strftime_to_java_format(fmt: &str) -> String {
33157 let mut result = fmt.to_string();
33158 result = result.replace("%-d", "d");
33160 result = result.replace("%-m", "M");
33161 result = result.replace("%-H", "H");
33162 result = result.replace("%-M", "m");
33163 result = result.replace("%-S", "s");
33164 result = result.replace("%Y", "yyyy");
33165 result = result.replace("%y", "yy");
33166 result = result.replace("%m", "MM");
33167 result = result.replace("%B", "MMMM");
33168 result = result.replace("%b", "MMM");
33169 result = result.replace("%d", "dd");
33170 result = result.replace("%j", "DDD");
33171 result = result.replace("%H", "HH");
33172 result = result.replace("%M", "mm");
33173 result = result.replace("%S", "ss");
33174 result = result.replace("%f", "SSSSSS");
33175 result = result.replace("%A", "EEEE");
33176 result = result.replace("%a", "EEE");
33177 result
33178 }
33179
33180 fn strftime_to_tsql_format(fmt: &str) -> String {
33183 let mut result = fmt.to_string();
33184 result = result.replace("%-d", "d");
33186 result = result.replace("%-m", "M");
33187 result = result.replace("%-H", "H");
33188 result = result.replace("%-M", "m");
33189 result = result.replace("%-S", "s");
33190 result = result.replace("%Y", "yyyy");
33191 result = result.replace("%y", "yy");
33192 result = result.replace("%m", "MM");
33193 result = result.replace("%B", "MMMM");
33194 result = result.replace("%b", "MMM");
33195 result = result.replace("%d", "dd");
33196 result = result.replace("%j", "DDD");
33197 result = result.replace("%H", "HH");
33198 result = result.replace("%M", "mm");
33199 result = result.replace("%S", "ss");
33200 result = result.replace("%f", "ffffff");
33201 result = result.replace("%A", "dddd");
33202 result = result.replace("%a", "ddd");
33203 result
33204 }
33205
33206 fn decompose_json_path(path: &str) -> Vec<String> {
33209 let mut parts = Vec::new();
33210 let path = if path.starts_with("$.") {
33212 &path[2..]
33213 } else if path.starts_with('$') {
33214 &path[1..]
33215 } else {
33216 path
33217 };
33218 if path.is_empty() {
33219 return parts;
33220 }
33221 let mut current = String::new();
33222 let chars: Vec<char> = path.chars().collect();
33223 let mut i = 0;
33224 while i < chars.len() {
33225 match chars[i] {
33226 '.' => {
33227 if !current.is_empty() {
33228 parts.push(current.clone());
33229 current.clear();
33230 }
33231 i += 1;
33232 }
33233 '[' => {
33234 if !current.is_empty() {
33235 parts.push(current.clone());
33236 current.clear();
33237 }
33238 i += 1;
33239 let mut bracket_content = String::new();
33241 while i < chars.len() && chars[i] != ']' {
33242 if chars[i] == '"' || chars[i] == '\'' {
33244 let quote = chars[i];
33245 i += 1;
33246 while i < chars.len() && chars[i] != quote {
33247 bracket_content.push(chars[i]);
33248 i += 1;
33249 }
33250 if i < chars.len() {
33251 i += 1;
33252 } } else {
33254 bracket_content.push(chars[i]);
33255 i += 1;
33256 }
33257 }
33258 if i < chars.len() {
33259 i += 1;
33260 } if bracket_content != "*" {
33263 parts.push(bracket_content);
33264 }
33265 }
33266 _ => {
33267 current.push(chars[i]);
33268 i += 1;
33269 }
33270 }
33271 }
33272 if !current.is_empty() {
33273 parts.push(current);
33274 }
33275 parts
33276 }
33277
33278 fn strftime_to_postgres_format(fmt: &str) -> String {
33280 let mut result = fmt.to_string();
33281 result = result.replace("%-d", "FMDD");
33283 result = result.replace("%-m", "FMMM");
33284 result = result.replace("%-H", "FMHH24");
33285 result = result.replace("%-M", "FMMI");
33286 result = result.replace("%-S", "FMSS");
33287 result = result.replace("%Y", "YYYY");
33288 result = result.replace("%y", "YY");
33289 result = result.replace("%m", "MM");
33290 result = result.replace("%B", "Month");
33291 result = result.replace("%b", "Mon");
33292 result = result.replace("%d", "DD");
33293 result = result.replace("%j", "DDD");
33294 result = result.replace("%H", "HH24");
33295 result = result.replace("%M", "MI");
33296 result = result.replace("%S", "SS");
33297 result = result.replace("%f", "US");
33298 result = result.replace("%A", "Day");
33299 result = result.replace("%a", "Dy");
33300 result
33301 }
33302
33303 fn strftime_to_snowflake_format(fmt: &str) -> String {
33305 let mut result = fmt.to_string();
33306 result = result.replace("%-d", "dd");
33308 result = result.replace("%-m", "mm"); result = result.replace("%Y", "yyyy");
33310 result = result.replace("%y", "yy");
33311 result = result.replace("%m", "mm");
33312 result = result.replace("%d", "DD");
33313 result = result.replace("%H", "hh24");
33314 result = result.replace("%M", "mi");
33315 result = result.replace("%S", "ss");
33316 result = result.replace("%f", "ff");
33317 result
33318 }
33319
33320 fn generate_str_to_map(&mut self, e: &StrToMap) -> Result<()> {
33321 self.write_keyword("STR_TO_MAP");
33323 self.write("(");
33324 self.generate_expression(&e.this)?;
33325 let needs_defaults = matches!(
33327 self.config.dialect,
33328 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
33329 );
33330 if let Some(pair_delim) = &e.pair_delim {
33331 self.write(", ");
33332 self.generate_expression(pair_delim)?;
33333 } else if needs_defaults {
33334 self.write(", ','");
33335 }
33336 if let Some(key_value_delim) = &e.key_value_delim {
33337 self.write(", ");
33338 self.generate_expression(key_value_delim)?;
33339 } else if needs_defaults {
33340 self.write(", ':'");
33341 }
33342 self.write(")");
33343 Ok(())
33344 }
33345
33346 fn generate_str_to_time(&mut self, e: &StrToTime) -> Result<()> {
33347 let is_strftime = e.format.contains('%');
33349 let to_strftime = |f: &str| -> String {
33351 if is_strftime {
33352 f.to_string()
33353 } else {
33354 Self::snowflake_format_to_strftime(f)
33355 }
33356 };
33357 let to_java = |f: &str| -> String {
33359 if is_strftime {
33360 Self::strftime_to_java_format(f)
33361 } else {
33362 Self::snowflake_format_to_spark(f)
33363 }
33364 };
33365 let to_pg = |f: &str| -> String {
33367 if is_strftime {
33368 Self::strftime_to_postgres_format(f)
33369 } else {
33370 Self::convert_strptime_to_postgres_format(f)
33371 }
33372 };
33373
33374 match self.config.dialect {
33375 Some(DialectType::Exasol) => {
33376 self.write_keyword("TO_DATE");
33377 self.write("(");
33378 self.generate_expression(&e.this)?;
33379 self.write(", '");
33380 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
33381 self.write("'");
33382 self.write(")");
33383 }
33384 Some(DialectType::BigQuery) => {
33385 let fmt = to_strftime(&e.format);
33387 let fmt = fmt.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
33389 self.write_keyword("PARSE_TIMESTAMP");
33390 self.write("('");
33391 self.write(&fmt);
33392 self.write("', ");
33393 self.generate_expression(&e.this)?;
33394 self.write(")");
33395 }
33396 Some(DialectType::Hive) => {
33397 let java_fmt = to_java(&e.format);
33400 if java_fmt == "yyyy-MM-dd HH:mm:ss"
33401 || java_fmt == "yyyy-MM-dd"
33402 || e.format == "yyyy-MM-dd HH:mm:ss"
33403 || e.format == "yyyy-MM-dd"
33404 {
33405 self.write_keyword("CAST");
33406 self.write("(");
33407 self.generate_expression(&e.this)?;
33408 self.write(" ");
33409 self.write_keyword("AS TIMESTAMP");
33410 self.write(")");
33411 } else {
33412 self.write_keyword("CAST");
33414 self.write("(");
33415 self.write_keyword("FROM_UNIXTIME");
33416 self.write("(");
33417 self.write_keyword("UNIX_TIMESTAMP");
33418 self.write("(");
33419 self.generate_expression(&e.this)?;
33420 self.write(", '");
33421 self.write(&java_fmt);
33422 self.write("')");
33423 self.write(") ");
33424 self.write_keyword("AS TIMESTAMP");
33425 self.write(")");
33426 }
33427 }
33428 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
33429 let java_fmt = to_java(&e.format);
33431 self.write_keyword("TO_TIMESTAMP");
33432 self.write("(");
33433 self.generate_expression(&e.this)?;
33434 self.write(", '");
33435 self.write(&java_fmt);
33436 self.write("')");
33437 }
33438 Some(DialectType::MySQL) => {
33439 let mut fmt = to_strftime(&e.format);
33441 fmt = fmt.replace("%-d", "%e");
33443 fmt = fmt.replace("%-m", "%c");
33444 fmt = fmt.replace("%H:%M:%S", "%T");
33445 self.write_keyword("STR_TO_DATE");
33446 self.write("(");
33447 self.generate_expression(&e.this)?;
33448 self.write(", '");
33449 self.write(&fmt);
33450 self.write("')");
33451 }
33452 Some(DialectType::Drill) => {
33453 let java_fmt = to_java(&e.format);
33455 let java_fmt = java_fmt.replace('T', "''T''");
33457 self.write_keyword("TO_TIMESTAMP");
33458 self.write("(");
33459 self.generate_expression(&e.this)?;
33460 self.write(", '");
33461 self.write(&java_fmt);
33462 self.write("')");
33463 }
33464 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
33465 let mut fmt = to_strftime(&e.format);
33467 fmt = fmt.replace("%-d", "%e");
33469 fmt = fmt.replace("%-m", "%c");
33470 fmt = fmt.replace("%H:%M:%S", "%T");
33471 self.write_keyword("DATE_PARSE");
33472 self.write("(");
33473 self.generate_expression(&e.this)?;
33474 self.write(", '");
33475 self.write(&fmt);
33476 self.write("')");
33477 }
33478 Some(DialectType::DuckDB) => {
33479 let fmt = to_strftime(&e.format);
33481 self.write_keyword("STRPTIME");
33482 self.write("(");
33483 self.generate_expression(&e.this)?;
33484 self.write(", '");
33485 self.write(&fmt);
33486 self.write("')");
33487 }
33488 Some(DialectType::PostgreSQL)
33489 | Some(DialectType::Redshift)
33490 | Some(DialectType::Materialize) => {
33491 let pg_fmt = to_pg(&e.format);
33493 self.write_keyword("TO_TIMESTAMP");
33494 self.write("(");
33495 self.generate_expression(&e.this)?;
33496 self.write(", '");
33497 self.write(&pg_fmt);
33498 self.write("')");
33499 }
33500 Some(DialectType::Oracle) => {
33501 let pg_fmt = to_pg(&e.format);
33503 self.write_keyword("TO_TIMESTAMP");
33504 self.write("(");
33505 self.generate_expression(&e.this)?;
33506 self.write(", '");
33507 self.write(&pg_fmt);
33508 self.write("')");
33509 }
33510 Some(DialectType::Snowflake) => {
33511 self.write_keyword("TO_TIMESTAMP");
33513 self.write("(");
33514 self.generate_expression(&e.this)?;
33515 self.write(", '");
33516 self.write(&e.format);
33517 self.write("')");
33518 }
33519 _ => {
33520 self.write_keyword("STR_TO_TIME");
33522 self.write("(");
33523 self.generate_expression(&e.this)?;
33524 self.write(", '");
33525 self.write(&e.format);
33526 self.write("'");
33527 self.write(")");
33528 }
33529 }
33530 Ok(())
33531 }
33532
33533 fn snowflake_format_to_strftime(format: &str) -> String {
33535 let mut result = String::new();
33536 let chars: Vec<char> = format.chars().collect();
33537 let mut i = 0;
33538 while i < chars.len() {
33539 let remaining = &format[i..];
33540 if remaining.starts_with("yyyy") {
33541 result.push_str("%Y");
33542 i += 4;
33543 } else if remaining.starts_with("yy") {
33544 result.push_str("%y");
33545 i += 2;
33546 } else if remaining.starts_with("mmmm") {
33547 result.push_str("%B"); i += 4;
33549 } else if remaining.starts_with("mon") {
33550 result.push_str("%b"); i += 3;
33552 } else if remaining.starts_with("mm") {
33553 result.push_str("%m");
33554 i += 2;
33555 } else if remaining.starts_with("DD") {
33556 result.push_str("%d");
33557 i += 2;
33558 } else if remaining.starts_with("dy") {
33559 result.push_str("%a"); i += 2;
33561 } else if remaining.starts_with("hh24") {
33562 result.push_str("%H");
33563 i += 4;
33564 } else if remaining.starts_with("hh12") {
33565 result.push_str("%I");
33566 i += 4;
33567 } else if remaining.starts_with("hh") {
33568 result.push_str("%H");
33569 i += 2;
33570 } else if remaining.starts_with("mi") {
33571 result.push_str("%M");
33572 i += 2;
33573 } else if remaining.starts_with("ss") {
33574 result.push_str("%S");
33575 i += 2;
33576 } else if remaining.starts_with("ff") {
33577 result.push_str("%f");
33579 i += 2;
33580 while i < chars.len() && chars[i].is_ascii_digit() {
33582 i += 1;
33583 }
33584 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
33585 result.push_str("%p");
33586 i += 2;
33587 } else if remaining.starts_with("tz") {
33588 result.push_str("%Z");
33589 i += 2;
33590 } else {
33591 result.push(chars[i]);
33592 i += 1;
33593 }
33594 }
33595 result
33596 }
33597
33598 fn snowflake_format_to_spark(format: &str) -> String {
33600 let mut result = String::new();
33601 let chars: Vec<char> = format.chars().collect();
33602 let mut i = 0;
33603 while i < chars.len() {
33604 let remaining = &format[i..];
33605 if remaining.starts_with("yyyy") {
33606 result.push_str("yyyy");
33607 i += 4;
33608 } else if remaining.starts_with("yy") {
33609 result.push_str("yy");
33610 i += 2;
33611 } else if remaining.starts_with("mmmm") {
33612 result.push_str("MMMM"); i += 4;
33614 } else if remaining.starts_with("mon") {
33615 result.push_str("MMM"); i += 3;
33617 } else if remaining.starts_with("mm") {
33618 result.push_str("MM");
33619 i += 2;
33620 } else if remaining.starts_with("DD") {
33621 result.push_str("dd");
33622 i += 2;
33623 } else if remaining.starts_with("dy") {
33624 result.push_str("EEE"); i += 2;
33626 } else if remaining.starts_with("hh24") {
33627 result.push_str("HH");
33628 i += 4;
33629 } else if remaining.starts_with("hh12") {
33630 result.push_str("hh");
33631 i += 4;
33632 } else if remaining.starts_with("hh") {
33633 result.push_str("HH");
33634 i += 2;
33635 } else if remaining.starts_with("mi") {
33636 result.push_str("mm");
33637 i += 2;
33638 } else if remaining.starts_with("ss") {
33639 result.push_str("ss");
33640 i += 2;
33641 } else if remaining.starts_with("ff") {
33642 result.push_str("SSS"); i += 2;
33644 while i < chars.len() && chars[i].is_ascii_digit() {
33646 i += 1;
33647 }
33648 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
33649 result.push_str("a");
33650 i += 2;
33651 } else if remaining.starts_with("tz") {
33652 result.push_str("z");
33653 i += 2;
33654 } else {
33655 result.push(chars[i]);
33656 i += 1;
33657 }
33658 }
33659 result
33660 }
33661
33662 fn generate_str_to_unix(&mut self, e: &StrToUnix) -> Result<()> {
33663 match self.config.dialect {
33664 Some(DialectType::DuckDB) => {
33665 self.write_keyword("EPOCH");
33667 self.write("(");
33668 self.write_keyword("STRPTIME");
33669 self.write("(");
33670 if let Some(this) = &e.this {
33671 self.generate_expression(this)?;
33672 }
33673 if let Some(format) = &e.format {
33674 self.write(", '");
33675 self.write(format);
33676 self.write("'");
33677 }
33678 self.write("))");
33679 }
33680 Some(DialectType::Hive) => {
33681 self.write_keyword("UNIX_TIMESTAMP");
33683 self.write("(");
33684 if let Some(this) = &e.this {
33685 self.generate_expression(this)?;
33686 }
33687 if let Some(format) = &e.format {
33688 let java_fmt = Self::strftime_to_java_format(format);
33689 if java_fmt != "yyyy-MM-dd HH:mm:ss" {
33690 self.write(", '");
33691 self.write(&java_fmt);
33692 self.write("'");
33693 }
33694 }
33695 self.write(")");
33696 }
33697 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
33698 self.write_keyword("UNIX_TIMESTAMP");
33700 self.write("(");
33701 if let Some(this) = &e.this {
33702 self.generate_expression(this)?;
33703 }
33704 if let Some(format) = &e.format {
33705 self.write(", '");
33706 self.write(format);
33707 self.write("'");
33708 }
33709 self.write(")");
33710 }
33711 Some(DialectType::Presto) | Some(DialectType::Trino) => {
33712 let c_fmt = e.format.as_deref().unwrap_or("%Y-%m-%d %T");
33715 let java_fmt = Self::strftime_to_java_format(c_fmt);
33716 self.write_keyword("TO_UNIXTIME");
33717 self.write("(");
33718 self.write_keyword("COALESCE");
33719 self.write("(");
33720 self.write_keyword("TRY");
33721 self.write("(");
33722 self.write_keyword("DATE_PARSE");
33723 self.write("(");
33724 self.write_keyword("CAST");
33725 self.write("(");
33726 if let Some(this) = &e.this {
33727 self.generate_expression(this)?;
33728 }
33729 self.write(" ");
33730 self.write_keyword("AS VARCHAR");
33731 self.write("), '");
33732 self.write(c_fmt);
33733 self.write("')), ");
33734 self.write_keyword("PARSE_DATETIME");
33735 self.write("(");
33736 self.write_keyword("DATE_FORMAT");
33737 self.write("(");
33738 self.write_keyword("CAST");
33739 self.write("(");
33740 if let Some(this) = &e.this {
33741 self.generate_expression(this)?;
33742 }
33743 self.write(" ");
33744 self.write_keyword("AS TIMESTAMP");
33745 self.write("), '");
33746 self.write(c_fmt);
33747 self.write("'), '");
33748 self.write(&java_fmt);
33749 self.write("')))");
33750 }
33751 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
33752 self.write_keyword("UNIX_TIMESTAMP");
33754 self.write("(");
33755 if let Some(this) = &e.this {
33756 self.generate_expression(this)?;
33757 }
33758 if let Some(format) = &e.format {
33759 let java_fmt = Self::strftime_to_java_format(format);
33760 self.write(", '");
33761 self.write(&java_fmt);
33762 self.write("'");
33763 }
33764 self.write(")");
33765 }
33766 _ => {
33767 self.write_keyword("STR_TO_UNIX");
33769 self.write("(");
33770 if let Some(this) = &e.this {
33771 self.generate_expression(this)?;
33772 }
33773 if let Some(format) = &e.format {
33774 self.write(", '");
33775 self.write(format);
33776 self.write("'");
33777 }
33778 self.write(")");
33779 }
33780 }
33781 Ok(())
33782 }
33783
33784 fn generate_string_to_array(&mut self, e: &StringToArray) -> Result<()> {
33785 self.write_keyword("STRING_TO_ARRAY");
33787 self.write("(");
33788 self.generate_expression(&e.this)?;
33789 if let Some(expression) = &e.expression {
33790 self.write(", ");
33791 self.generate_expression(expression)?;
33792 }
33793 if let Some(null_val) = &e.null {
33794 self.write(", ");
33795 self.generate_expression(null_val)?;
33796 }
33797 self.write(")");
33798 Ok(())
33799 }
33800
33801 fn generate_struct(&mut self, e: &Struct) -> Result<()> {
33802 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
33803 self.write_keyword("OBJECT_CONSTRUCT");
33805 self.write("(");
33806 for (i, (name, expr)) in e.fields.iter().enumerate() {
33807 if i > 0 {
33808 self.write(", ");
33809 }
33810 if let Some(name) = name {
33811 self.write("'");
33812 self.write(name);
33813 self.write("'");
33814 self.write(", ");
33815 } else {
33816 self.write("'_");
33817 self.write(&i.to_string());
33818 self.write("'");
33819 self.write(", ");
33820 }
33821 self.generate_expression(expr)?;
33822 }
33823 self.write(")");
33824 } else if self.config.struct_curly_brace_notation {
33825 self.write("{");
33827 for (i, (name, expr)) in e.fields.iter().enumerate() {
33828 if i > 0 {
33829 self.write(", ");
33830 }
33831 if let Some(name) = name {
33832 self.write("'");
33834 self.write(name);
33835 self.write("'");
33836 self.write(": ");
33837 } else {
33838 self.write("'_");
33840 self.write(&i.to_string());
33841 self.write("'");
33842 self.write(": ");
33843 }
33844 self.generate_expression(expr)?;
33845 }
33846 self.write("}");
33847 } else {
33848 let value_as_name = matches!(
33852 self.config.dialect,
33853 Some(DialectType::BigQuery)
33854 | Some(DialectType::Spark)
33855 | Some(DialectType::Databricks)
33856 | Some(DialectType::Hive)
33857 );
33858 self.write_keyword("STRUCT");
33859 self.write("(");
33860 for (i, (name, expr)) in e.fields.iter().enumerate() {
33861 if i > 0 {
33862 self.write(", ");
33863 }
33864 if let Some(name) = name {
33865 if value_as_name {
33866 self.generate_expression(expr)?;
33868 self.write_space();
33869 self.write_keyword("AS");
33870 self.write_space();
33871 let needs_quoting = name.contains(' ') || name.contains('-');
33873 if needs_quoting {
33874 if matches!(
33875 self.config.dialect,
33876 Some(DialectType::Spark)
33877 | Some(DialectType::Databricks)
33878 | Some(DialectType::Hive)
33879 ) {
33880 self.write("`");
33881 self.write(name);
33882 self.write("`");
33883 } else {
33884 self.write(name);
33885 }
33886 } else {
33887 self.write(name);
33888 }
33889 } else {
33890 self.write(name);
33892 self.write_space();
33893 self.write_keyword("AS");
33894 self.write_space();
33895 self.generate_expression(expr)?;
33896 }
33897 } else {
33898 self.generate_expression(expr)?;
33899 }
33900 }
33901 self.write(")");
33902 }
33903 Ok(())
33904 }
33905
33906 fn generate_stuff(&mut self, e: &Stuff) -> Result<()> {
33907 self.write_keyword("STUFF");
33909 self.write("(");
33910 self.generate_expression(&e.this)?;
33911 if let Some(start) = &e.start {
33912 self.write(", ");
33913 self.generate_expression(start)?;
33914 }
33915 if let Some(length) = e.length {
33916 self.write(", ");
33917 self.write(&length.to_string());
33918 }
33919 self.write(", ");
33920 self.generate_expression(&e.expression)?;
33921 self.write(")");
33922 Ok(())
33923 }
33924
33925 fn generate_substring_index(&mut self, e: &SubstringIndex) -> Result<()> {
33926 self.write_keyword("SUBSTRING_INDEX");
33928 self.write("(");
33929 self.generate_expression(&e.this)?;
33930 if let Some(delimiter) = &e.delimiter {
33931 self.write(", ");
33932 self.generate_expression(delimiter)?;
33933 }
33934 if let Some(count) = &e.count {
33935 self.write(", ");
33936 self.generate_expression(count)?;
33937 }
33938 self.write(")");
33939 Ok(())
33940 }
33941
33942 fn generate_summarize(&mut self, e: &Summarize) -> Result<()> {
33943 self.write_keyword("SUMMARIZE");
33945 if e.table.is_some() {
33946 self.write_space();
33947 self.write_keyword("TABLE");
33948 }
33949 self.write_space();
33950 self.generate_expression(&e.this)?;
33951 Ok(())
33952 }
33953
33954 fn generate_systimestamp(&mut self, _e: &Systimestamp) -> Result<()> {
33955 self.write_keyword("SYSTIMESTAMP");
33957 Ok(())
33958 }
33959
33960 fn generate_table_alias(&mut self, e: &TableAlias) -> Result<()> {
33961 if let Some(this) = &e.this {
33963 self.generate_expression(this)?;
33964 }
33965 if !e.columns.is_empty() {
33966 self.write("(");
33967 for (i, col) in e.columns.iter().enumerate() {
33968 if i > 0 {
33969 self.write(", ");
33970 }
33971 self.generate_expression(col)?;
33972 }
33973 self.write(")");
33974 }
33975 Ok(())
33976 }
33977
33978 fn generate_table_from_rows(&mut self, e: &TableFromRows) -> Result<()> {
33979 self.write_keyword("TABLE");
33981 self.write("(");
33982 self.generate_expression(&e.this)?;
33983 self.write(")");
33984 if let Some(alias) = &e.alias {
33985 self.write_space();
33986 self.write_keyword("AS");
33987 self.write_space();
33988 self.write(alias);
33989 }
33990 Ok(())
33991 }
33992
33993 fn generate_rows_from(&mut self, e: &RowsFrom) -> Result<()> {
33994 self.write_keyword("ROWS FROM");
33996 self.write(" (");
33997 for (i, expr) in e.expressions.iter().enumerate() {
33998 if i > 0 {
33999 self.write(", ");
34000 }
34001 match expr {
34005 Expression::Tuple(tuple) if tuple.expressions.len() == 2 => {
34006 self.generate_expression(&tuple.expressions[0])?;
34008 self.write_space();
34009 self.write_keyword("AS");
34010 self.write_space();
34011 self.generate_expression(&tuple.expressions[1])?;
34012 }
34013 _ => {
34014 self.generate_expression(expr)?;
34015 }
34016 }
34017 }
34018 self.write(")");
34019 if e.ordinality {
34020 self.write_space();
34021 self.write_keyword("WITH ORDINALITY");
34022 }
34023 if let Some(alias) = &e.alias {
34024 self.write_space();
34025 self.write_keyword("AS");
34026 self.write_space();
34027 self.generate_expression(alias)?;
34028 }
34029 Ok(())
34030 }
34031
34032 fn generate_table_sample(&mut self, e: &TableSample) -> Result<()> {
34033 use crate::dialects::DialectType;
34034
34035 if let (Some(this), Some(sample)) = (&e.this, &e.sample) {
34037 if self.config.alias_post_tablesample {
34039 if let Expression::Subquery(ref s) = **this {
34041 if let Some(ref alias) = s.alias {
34042 let mut subquery_no_alias = (**s).clone();
34044 subquery_no_alias.alias = None;
34045 subquery_no_alias.column_aliases = Vec::new();
34046 self.generate_expression(&Expression::Subquery(Box::new(
34047 subquery_no_alias,
34048 )))?;
34049 self.write_space();
34050 self.write_keyword("TABLESAMPLE");
34051 self.generate_sample_body(sample)?;
34052 if let Some(ref seed) = sample.seed {
34053 self.write_space();
34054 let use_seed = sample.use_seed_keyword
34055 && !matches!(
34056 self.config.dialect,
34057 Some(crate::dialects::DialectType::Databricks)
34058 | Some(crate::dialects::DialectType::Spark)
34059 );
34060 if use_seed {
34061 self.write_keyword("SEED");
34062 } else {
34063 self.write_keyword("REPEATABLE");
34064 }
34065 self.write(" (");
34066 self.generate_expression(seed)?;
34067 self.write(")");
34068 }
34069 self.write_space();
34070 self.write_keyword("AS");
34071 self.write_space();
34072 self.generate_identifier(alias)?;
34073 return Ok(());
34074 }
34075 } else if let Expression::Alias(ref a) = **this {
34076 self.generate_expression(&a.this)?;
34078 self.write_space();
34079 self.write_keyword("TABLESAMPLE");
34080 self.generate_sample_body(sample)?;
34081 if let Some(ref seed) = sample.seed {
34082 self.write_space();
34083 let use_seed = sample.use_seed_keyword
34084 && !matches!(
34085 self.config.dialect,
34086 Some(crate::dialects::DialectType::Databricks)
34087 | Some(crate::dialects::DialectType::Spark)
34088 );
34089 if use_seed {
34090 self.write_keyword("SEED");
34091 } else {
34092 self.write_keyword("REPEATABLE");
34093 }
34094 self.write(" (");
34095 self.generate_expression(seed)?;
34096 self.write(")");
34097 }
34098 self.write_space();
34100 self.write_keyword("AS");
34101 self.write_space();
34102 self.generate_identifier(&a.alias)?;
34103 return Ok(());
34104 }
34105 }
34106 self.generate_expression(this)?;
34108 self.write_space();
34109 self.write_keyword("TABLESAMPLE");
34110 self.generate_sample_body(sample)?;
34111 if let Some(ref seed) = sample.seed {
34113 self.write_space();
34114 let use_seed = sample.use_seed_keyword
34116 && !matches!(
34117 self.config.dialect,
34118 Some(crate::dialects::DialectType::Databricks)
34119 | Some(crate::dialects::DialectType::Spark)
34120 );
34121 if use_seed {
34122 self.write_keyword("SEED");
34123 } else {
34124 self.write_keyword("REPEATABLE");
34125 }
34126 self.write(" (");
34127 self.generate_expression(seed)?;
34128 self.write(")");
34129 }
34130 return Ok(());
34131 }
34132
34133 self.write_keyword("TABLESAMPLE");
34135 if let Some(method) = &e.method {
34136 self.write_space();
34137 self.write_keyword(method);
34138 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
34139 self.write_space();
34141 self.write_keyword("BERNOULLI");
34142 }
34143 if let (Some(numerator), Some(denominator)) = (&e.bucket_numerator, &e.bucket_denominator) {
34144 self.write_space();
34145 self.write_keyword("BUCKET");
34146 self.write_space();
34147 self.generate_expression(numerator)?;
34148 self.write_space();
34149 self.write_keyword("OUT OF");
34150 self.write_space();
34151 self.generate_expression(denominator)?;
34152 if let Some(field) = &e.bucket_field {
34153 self.write_space();
34154 self.write_keyword("ON");
34155 self.write_space();
34156 self.generate_expression(field)?;
34157 }
34158 } else if !e.expressions.is_empty() {
34159 self.write(" (");
34160 for (i, expr) in e.expressions.iter().enumerate() {
34161 if i > 0 {
34162 self.write(", ");
34163 }
34164 self.generate_expression(expr)?;
34165 }
34166 self.write(")");
34167 } else if let Some(percent) = &e.percent {
34168 self.write(" (");
34169 self.generate_expression(percent)?;
34170 self.write_space();
34171 self.write_keyword("PERCENT");
34172 self.write(")");
34173 }
34174 Ok(())
34175 }
34176
34177 fn generate_tag(&mut self, e: &Tag) -> Result<()> {
34178 if let Some(prefix) = &e.prefix {
34180 self.generate_expression(prefix)?;
34181 }
34182 if let Some(this) = &e.this {
34183 self.generate_expression(this)?;
34184 }
34185 if let Some(postfix) = &e.postfix {
34186 self.generate_expression(postfix)?;
34187 }
34188 Ok(())
34189 }
34190
34191 fn generate_tags(&mut self, e: &Tags) -> Result<()> {
34192 self.write_keyword("TAG");
34194 self.write(" (");
34195 for (i, expr) in e.expressions.iter().enumerate() {
34196 if i > 0 {
34197 self.write(", ");
34198 }
34199 self.generate_expression(expr)?;
34200 }
34201 self.write(")");
34202 Ok(())
34203 }
34204
34205 fn generate_temporary_property(&mut self, e: &TemporaryProperty) -> Result<()> {
34206 if let Some(this) = &e.this {
34208 self.generate_expression(this)?;
34209 self.write_space();
34210 }
34211 self.write_keyword("TEMPORARY");
34212 Ok(())
34213 }
34214
34215 fn generate_time_func(&mut self, e: &UnaryFunc) -> Result<()> {
34218 self.write_keyword("TIME");
34220 self.write("(");
34221 self.generate_expression(&e.this)?;
34222 self.write(")");
34223 Ok(())
34224 }
34225
34226 fn generate_time_add(&mut self, e: &TimeAdd) -> Result<()> {
34227 self.write_keyword("TIME_ADD");
34229 self.write("(");
34230 self.generate_expression(&e.this)?;
34231 self.write(", ");
34232 self.generate_expression(&e.expression)?;
34233 if let Some(unit) = &e.unit {
34234 self.write(", ");
34235 self.write_keyword(unit);
34236 }
34237 self.write(")");
34238 Ok(())
34239 }
34240
34241 fn generate_time_diff(&mut self, e: &TimeDiff) -> Result<()> {
34242 self.write_keyword("TIME_DIFF");
34244 self.write("(");
34245 self.generate_expression(&e.this)?;
34246 self.write(", ");
34247 self.generate_expression(&e.expression)?;
34248 if let Some(unit) = &e.unit {
34249 self.write(", ");
34250 self.write_keyword(unit);
34251 }
34252 self.write(")");
34253 Ok(())
34254 }
34255
34256 fn generate_time_from_parts(&mut self, e: &TimeFromParts) -> Result<()> {
34257 self.write_keyword("TIME_FROM_PARTS");
34259 self.write("(");
34260 let mut first = true;
34261 if let Some(hour) = &e.hour {
34262 self.generate_expression(hour)?;
34263 first = false;
34264 }
34265 if let Some(minute) = &e.min {
34266 if !first {
34267 self.write(", ");
34268 }
34269 self.generate_expression(minute)?;
34270 first = false;
34271 }
34272 if let Some(second) = &e.sec {
34273 if !first {
34274 self.write(", ");
34275 }
34276 self.generate_expression(second)?;
34277 first = false;
34278 }
34279 if let Some(ns) = &e.nano {
34280 if !first {
34281 self.write(", ");
34282 }
34283 self.generate_expression(ns)?;
34284 }
34285 self.write(")");
34286 Ok(())
34287 }
34288
34289 fn generate_time_slice(&mut self, e: &TimeSlice) -> Result<()> {
34290 self.write_keyword("TIME_SLICE");
34292 self.write("(");
34293 self.generate_expression(&e.this)?;
34294 self.write(", ");
34295 self.generate_expression(&e.expression)?;
34296 self.write(", ");
34297 self.write_keyword(&e.unit);
34298 self.write(")");
34299 Ok(())
34300 }
34301
34302 fn generate_time_str_to_time(&mut self, e: &TimeStrToTime) -> Result<()> {
34303 self.write_keyword("TIME_STR_TO_TIME");
34305 self.write("(");
34306 self.generate_expression(&e.this)?;
34307 self.write(")");
34308 Ok(())
34309 }
34310
34311 fn generate_time_sub(&mut self, e: &TimeSub) -> Result<()> {
34312 self.write_keyword("TIME_SUB");
34314 self.write("(");
34315 self.generate_expression(&e.this)?;
34316 self.write(", ");
34317 self.generate_expression(&e.expression)?;
34318 if let Some(unit) = &e.unit {
34319 self.write(", ");
34320 self.write_keyword(unit);
34321 }
34322 self.write(")");
34323 Ok(())
34324 }
34325
34326 fn generate_time_to_str(&mut self, e: &TimeToStr) -> Result<()> {
34327 match self.config.dialect {
34328 Some(DialectType::Exasol) => {
34329 self.write_keyword("TO_CHAR");
34331 self.write("(");
34332 self.generate_expression(&e.this)?;
34333 self.write(", '");
34334 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
34335 self.write("'");
34336 self.write(")");
34337 }
34338 Some(DialectType::PostgreSQL)
34339 | Some(DialectType::Redshift)
34340 | Some(DialectType::Materialize) => {
34341 self.write_keyword("TO_CHAR");
34343 self.write("(");
34344 self.generate_expression(&e.this)?;
34345 self.write(", '");
34346 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
34347 self.write("'");
34348 self.write(")");
34349 }
34350 Some(DialectType::Oracle) => {
34351 self.write_keyword("TO_CHAR");
34353 self.write("(");
34354 self.generate_expression(&e.this)?;
34355 self.write(", '");
34356 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
34357 self.write("'");
34358 self.write(")");
34359 }
34360 Some(DialectType::Drill) => {
34361 self.write_keyword("TO_CHAR");
34363 self.write("(");
34364 self.generate_expression(&e.this)?;
34365 self.write(", '");
34366 self.write(&Self::strftime_to_java_format(&e.format));
34367 self.write("'");
34368 self.write(")");
34369 }
34370 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
34371 self.write_keyword("FORMAT");
34373 self.write("(");
34374 self.generate_expression(&e.this)?;
34375 self.write(", '");
34376 self.write(&Self::strftime_to_tsql_format(&e.format));
34377 self.write("'");
34378 self.write(")");
34379 }
34380 Some(DialectType::DuckDB) => {
34381 self.write_keyword("STRFTIME");
34383 self.write("(");
34384 self.generate_expression(&e.this)?;
34385 self.write(", '");
34386 self.write(&e.format);
34387 self.write("'");
34388 self.write(")");
34389 }
34390 Some(DialectType::BigQuery) => {
34391 let fmt = e.format.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
34394 self.write_keyword("FORMAT_DATE");
34395 self.write("('");
34396 self.write(&fmt);
34397 self.write("', ");
34398 self.generate_expression(&e.this)?;
34399 self.write(")");
34400 }
34401 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
34402 self.write_keyword("DATE_FORMAT");
34404 self.write("(");
34405 self.generate_expression(&e.this)?;
34406 self.write(", '");
34407 self.write(&Self::strftime_to_java_format(&e.format));
34408 self.write("'");
34409 self.write(")");
34410 }
34411 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
34412 self.write_keyword("DATE_FORMAT");
34414 self.write("(");
34415 self.generate_expression(&e.this)?;
34416 self.write(", '");
34417 self.write(&e.format);
34418 self.write("'");
34419 self.write(")");
34420 }
34421 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
34422 self.write_keyword("DATE_FORMAT");
34424 self.write("(");
34425 self.generate_expression(&e.this)?;
34426 self.write(", '");
34427 self.write(&e.format);
34428 self.write("'");
34429 self.write(")");
34430 }
34431 _ => {
34432 self.write_keyword("TIME_TO_STR");
34434 self.write("(");
34435 self.generate_expression(&e.this)?;
34436 self.write(", '");
34437 self.write(&e.format);
34438 self.write("'");
34439 self.write(")");
34440 }
34441 }
34442 Ok(())
34443 }
34444
34445 fn generate_time_to_unix(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
34446 match self.config.dialect {
34447 Some(DialectType::DuckDB) => {
34448 self.write_keyword("EPOCH");
34450 self.write("(");
34451 self.generate_expression(&e.this)?;
34452 self.write(")");
34453 }
34454 Some(DialectType::Hive)
34455 | Some(DialectType::Spark)
34456 | Some(DialectType::Databricks)
34457 | Some(DialectType::Doris)
34458 | Some(DialectType::StarRocks)
34459 | Some(DialectType::Drill) => {
34460 self.write_keyword("UNIX_TIMESTAMP");
34462 self.write("(");
34463 self.generate_expression(&e.this)?;
34464 self.write(")");
34465 }
34466 Some(DialectType::Presto) | Some(DialectType::Trino) => {
34467 self.write_keyword("TO_UNIXTIME");
34469 self.write("(");
34470 self.generate_expression(&e.this)?;
34471 self.write(")");
34472 }
34473 _ => {
34474 self.write_keyword("TIME_TO_UNIX");
34476 self.write("(");
34477 self.generate_expression(&e.this)?;
34478 self.write(")");
34479 }
34480 }
34481 Ok(())
34482 }
34483
34484 fn generate_time_str_to_date(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
34485 match self.config.dialect {
34486 Some(DialectType::Hive) => {
34487 self.write_keyword("TO_DATE");
34489 self.write("(");
34490 self.generate_expression(&e.this)?;
34491 self.write(")");
34492 }
34493 _ => {
34494 self.write_keyword("TIME_STR_TO_DATE");
34496 self.write("(");
34497 self.generate_expression(&e.this)?;
34498 self.write(")");
34499 }
34500 }
34501 Ok(())
34502 }
34503
34504 fn generate_time_trunc(&mut self, e: &TimeTrunc) -> Result<()> {
34505 self.write_keyword("TIME_TRUNC");
34507 self.write("(");
34508 self.generate_expression(&e.this)?;
34509 self.write(", ");
34510 self.write_keyword(&e.unit);
34511 self.write(")");
34512 Ok(())
34513 }
34514
34515 fn generate_time_unit(&mut self, e: &TimeUnit) -> Result<()> {
34516 if let Some(unit) = &e.unit {
34518 self.write_keyword(unit);
34519 }
34520 Ok(())
34521 }
34522
34523 fn generate_timestamp_func(&mut self, e: &TimestampFunc) -> Result<()> {
34527 use crate::dialects::DialectType;
34528 use crate::expressions::Literal;
34529
34530 match self.config.dialect {
34531 Some(DialectType::Exasol) => {
34533 self.write_keyword("TO_TIMESTAMP");
34534 self.write("(");
34535 if let Some(this) = &e.this {
34537 match this.as_ref() {
34538 Expression::Literal(Literal::String(s)) => {
34539 self.write("'");
34540 self.write(s);
34541 self.write("'");
34542 }
34543 _ => {
34544 self.generate_expression(this)?;
34545 }
34546 }
34547 }
34548 self.write(")");
34549 }
34550 _ => {
34552 self.write_keyword("TIMESTAMP");
34553 self.write("(");
34554 if let Some(this) = &e.this {
34555 self.generate_expression(this)?;
34556 }
34557 if let Some(zone) = &e.zone {
34558 self.write(", ");
34559 self.generate_expression(zone)?;
34560 }
34561 self.write(")");
34562 }
34563 }
34564 Ok(())
34565 }
34566
34567 fn generate_timestamp_add(&mut self, e: &TimestampAdd) -> Result<()> {
34568 self.write_keyword("TIMESTAMP_ADD");
34570 self.write("(");
34571 self.generate_expression(&e.this)?;
34572 self.write(", ");
34573 self.generate_expression(&e.expression)?;
34574 if let Some(unit) = &e.unit {
34575 self.write(", ");
34576 self.write_keyword(unit);
34577 }
34578 self.write(")");
34579 Ok(())
34580 }
34581
34582 fn generate_timestamp_diff(&mut self, e: &TimestampDiff) -> Result<()> {
34583 self.write_keyword("TIMESTAMP_DIFF");
34585 self.write("(");
34586 self.generate_expression(&e.this)?;
34587 self.write(", ");
34588 self.generate_expression(&e.expression)?;
34589 if let Some(unit) = &e.unit {
34590 self.write(", ");
34591 self.write_keyword(unit);
34592 }
34593 self.write(")");
34594 Ok(())
34595 }
34596
34597 fn generate_timestamp_from_parts(&mut self, e: &TimestampFromParts) -> Result<()> {
34598 self.write_keyword("TIMESTAMP_FROM_PARTS");
34600 self.write("(");
34601 if let Some(this) = &e.this {
34602 self.generate_expression(this)?;
34603 }
34604 if let Some(expression) = &e.expression {
34605 self.write(", ");
34606 self.generate_expression(expression)?;
34607 }
34608 if let Some(zone) = &e.zone {
34609 self.write(", ");
34610 self.generate_expression(zone)?;
34611 }
34612 if let Some(milli) = &e.milli {
34613 self.write(", ");
34614 self.generate_expression(milli)?;
34615 }
34616 self.write(")");
34617 Ok(())
34618 }
34619
34620 fn generate_timestamp_sub(&mut self, e: &TimestampSub) -> Result<()> {
34621 self.write_keyword("TIMESTAMP_SUB");
34623 self.write("(");
34624 self.generate_expression(&e.this)?;
34625 self.write(", ");
34626 self.write_keyword("INTERVAL");
34627 self.write_space();
34628 self.generate_expression(&e.expression)?;
34629 if let Some(unit) = &e.unit {
34630 self.write_space();
34631 self.write_keyword(unit);
34632 }
34633 self.write(")");
34634 Ok(())
34635 }
34636
34637 fn generate_timestamp_tz_from_parts(&mut self, e: &TimestampTzFromParts) -> Result<()> {
34638 self.write_keyword("TIMESTAMP_TZ_FROM_PARTS");
34640 self.write("(");
34641 if let Some(zone) = &e.zone {
34642 self.generate_expression(zone)?;
34643 }
34644 self.write(")");
34645 Ok(())
34646 }
34647
34648 fn generate_to_binary(&mut self, e: &ToBinary) -> Result<()> {
34649 self.write_keyword("TO_BINARY");
34651 self.write("(");
34652 self.generate_expression(&e.this)?;
34653 if let Some(format) = &e.format {
34654 self.write(", '");
34655 self.write(format);
34656 self.write("'");
34657 }
34658 self.write(")");
34659 Ok(())
34660 }
34661
34662 fn generate_to_boolean(&mut self, e: &ToBoolean) -> Result<()> {
34663 self.write_keyword("TO_BOOLEAN");
34665 self.write("(");
34666 self.generate_expression(&e.this)?;
34667 self.write(")");
34668 Ok(())
34669 }
34670
34671 fn generate_to_char(&mut self, e: &ToChar) -> Result<()> {
34672 self.write_keyword("TO_CHAR");
34674 self.write("(");
34675 self.generate_expression(&e.this)?;
34676 if let Some(format) = &e.format {
34677 self.write(", '");
34678 self.write(format);
34679 self.write("'");
34680 }
34681 if let Some(nlsparam) = &e.nlsparam {
34682 self.write(", ");
34683 self.generate_expression(nlsparam)?;
34684 }
34685 self.write(")");
34686 Ok(())
34687 }
34688
34689 fn generate_to_decfloat(&mut self, e: &ToDecfloat) -> Result<()> {
34690 self.write_keyword("TO_DECFLOAT");
34692 self.write("(");
34693 self.generate_expression(&e.this)?;
34694 if let Some(format) = &e.format {
34695 self.write(", '");
34696 self.write(format);
34697 self.write("'");
34698 }
34699 self.write(")");
34700 Ok(())
34701 }
34702
34703 fn generate_to_double(&mut self, e: &ToDouble) -> Result<()> {
34704 self.write_keyword("TO_DOUBLE");
34706 self.write("(");
34707 self.generate_expression(&e.this)?;
34708 if let Some(format) = &e.format {
34709 self.write(", '");
34710 self.write(format);
34711 self.write("'");
34712 }
34713 self.write(")");
34714 Ok(())
34715 }
34716
34717 fn generate_to_file(&mut self, e: &ToFile) -> Result<()> {
34718 self.write_keyword("TO_FILE");
34720 self.write("(");
34721 self.generate_expression(&e.this)?;
34722 if let Some(path) = &e.path {
34723 self.write(", ");
34724 self.generate_expression(path)?;
34725 }
34726 self.write(")");
34727 Ok(())
34728 }
34729
34730 fn generate_to_number(&mut self, e: &ToNumber) -> Result<()> {
34731 let is_safe = e.safe.is_some();
34734 if is_safe {
34735 self.write_keyword("TRY_TO_NUMBER");
34736 } else {
34737 self.write_keyword("TO_NUMBER");
34738 }
34739 self.write("(");
34740 self.generate_expression(&e.this)?;
34741 if let Some(format) = &e.format {
34742 self.write(", ");
34743 self.generate_expression(format)?;
34744 }
34745 if let Some(nlsparam) = &e.nlsparam {
34746 self.write(", ");
34747 self.generate_expression(nlsparam)?;
34748 }
34749 if let Some(precision) = &e.precision {
34750 self.write(", ");
34751 self.generate_expression(precision)?;
34752 }
34753 if let Some(scale) = &e.scale {
34754 self.write(", ");
34755 self.generate_expression(scale)?;
34756 }
34757 self.write(")");
34758 Ok(())
34759 }
34760
34761 fn generate_to_table_property(&mut self, e: &ToTableProperty) -> Result<()> {
34762 self.write_keyword("TO_TABLE");
34764 self.write_space();
34765 self.generate_expression(&e.this)?;
34766 Ok(())
34767 }
34768
34769 fn generate_transaction(&mut self, e: &Transaction) -> Result<()> {
34770 let mark_text = e.mark.as_ref().map(|m| match m.as_ref() {
34772 Expression::Identifier(id) => id.name.clone(),
34773 Expression::Literal(Literal::String(s)) => s.clone(),
34774 _ => String::new(),
34775 });
34776
34777 let is_start = mark_text.as_ref().map_or(false, |s| s == "START");
34778 let has_transaction_keyword = mark_text.as_ref().map_or(false, |s| s == "TRANSACTION");
34779 let has_with_mark = e.mark.as_ref().map_or(false, |m| {
34780 matches!(m.as_ref(), Expression::Literal(Literal::String(_)))
34781 });
34782
34783 let use_start_transaction = matches!(
34785 self.config.dialect,
34786 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
34787 );
34788 let strip_transaction = matches!(
34790 self.config.dialect,
34791 Some(DialectType::Snowflake)
34792 | Some(DialectType::PostgreSQL)
34793 | Some(DialectType::Redshift)
34794 | Some(DialectType::MySQL)
34795 | Some(DialectType::Hive)
34796 | Some(DialectType::Spark)
34797 | Some(DialectType::Databricks)
34798 | Some(DialectType::DuckDB)
34799 | Some(DialectType::Oracle)
34800 | Some(DialectType::Doris)
34801 | Some(DialectType::StarRocks)
34802 | Some(DialectType::Materialize)
34803 | Some(DialectType::ClickHouse)
34804 );
34805
34806 if is_start || use_start_transaction {
34807 self.write_keyword("START TRANSACTION");
34809 if let Some(modes) = &e.modes {
34810 self.write_space();
34811 self.generate_expression(modes)?;
34812 }
34813 } else {
34814 self.write_keyword("BEGIN");
34816
34817 let is_kind = e.this.as_ref().map_or(false, |t| {
34819 if let Expression::Identifier(id) = t.as_ref() {
34820 matches!(
34821 id.name.to_uppercase().as_str(),
34822 "DEFERRED" | "IMMEDIATE" | "EXCLUSIVE"
34823 )
34824 } else {
34825 false
34826 }
34827 });
34828
34829 if is_kind {
34831 if let Some(this) = &e.this {
34832 self.write_space();
34833 if let Expression::Identifier(id) = this.as_ref() {
34834 self.write_keyword(&id.name);
34835 }
34836 }
34837 }
34838
34839 if (has_transaction_keyword || has_with_mark) && !strip_transaction {
34841 self.write_space();
34842 self.write_keyword("TRANSACTION");
34843 }
34844
34845 if !is_kind {
34847 if let Some(this) = &e.this {
34848 self.write_space();
34849 self.generate_expression(this)?;
34850 }
34851 }
34852
34853 if has_with_mark {
34855 self.write_space();
34856 self.write_keyword("WITH MARK");
34857 if let Some(Expression::Literal(Literal::String(desc))) = e.mark.as_deref() {
34858 if !desc.is_empty() {
34859 self.write_space();
34860 self.write(&format!("'{}'", desc));
34861 }
34862 }
34863 }
34864
34865 if let Some(modes) = &e.modes {
34867 self.write_space();
34868 self.generate_expression(modes)?;
34869 }
34870 }
34871 Ok(())
34872 }
34873
34874 fn generate_transform(&mut self, e: &Transform) -> Result<()> {
34875 self.write_keyword("TRANSFORM");
34877 self.write("(");
34878 self.generate_expression(&e.this)?;
34879 self.write(", ");
34880 self.generate_expression(&e.expression)?;
34881 self.write(")");
34882 Ok(())
34883 }
34884
34885 fn generate_transform_model_property(&mut self, e: &TransformModelProperty) -> Result<()> {
34886 self.write_keyword("TRANSFORM");
34888 self.write("(");
34889 if self.config.pretty && !e.expressions.is_empty() {
34890 self.indent_level += 1;
34891 for (i, expr) in e.expressions.iter().enumerate() {
34892 if i > 0 {
34893 self.write(",");
34894 }
34895 self.write_newline();
34896 self.write_indent();
34897 self.generate_expression(expr)?;
34898 }
34899 self.indent_level -= 1;
34900 self.write_newline();
34901 self.write(")");
34902 } else {
34903 for (i, expr) in e.expressions.iter().enumerate() {
34904 if i > 0 {
34905 self.write(", ");
34906 }
34907 self.generate_expression(expr)?;
34908 }
34909 self.write(")");
34910 }
34911 Ok(())
34912 }
34913
34914 fn generate_transient_property(&mut self, e: &TransientProperty) -> Result<()> {
34915 use crate::dialects::DialectType;
34916 if let Some(this) = &e.this {
34918 self.generate_expression(this)?;
34919 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
34920 self.write_space();
34921 }
34922 }
34923 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
34924 self.write_keyword("TRANSIENT");
34925 }
34926 Ok(())
34927 }
34928
34929 fn generate_translate(&mut self, e: &Translate) -> Result<()> {
34930 self.write_keyword("TRANSLATE");
34932 self.write("(");
34933 self.generate_expression(&e.this)?;
34934 if let Some(from) = &e.from_ {
34935 self.write(", ");
34936 self.generate_expression(from)?;
34937 }
34938 if let Some(to) = &e.to {
34939 self.write(", ");
34940 self.generate_expression(to)?;
34941 }
34942 self.write(")");
34943 Ok(())
34944 }
34945
34946 fn generate_translate_characters(&mut self, e: &TranslateCharacters) -> Result<()> {
34947 self.write_keyword("TRANSLATE");
34949 self.write("(");
34950 self.generate_expression(&e.this)?;
34951 self.write_space();
34952 self.write_keyword("USING");
34953 self.write_space();
34954 self.generate_expression(&e.expression)?;
34955 if e.with_error.is_some() {
34956 self.write_space();
34957 self.write_keyword("WITH ERROR");
34958 }
34959 self.write(")");
34960 Ok(())
34961 }
34962
34963 fn generate_truncate_table(&mut self, e: &TruncateTable) -> Result<()> {
34964 self.write_keyword("TRUNCATE TABLE");
34966 self.write_space();
34967 for (i, expr) in e.expressions.iter().enumerate() {
34968 if i > 0 {
34969 self.write(", ");
34970 }
34971 self.generate_expression(expr)?;
34972 }
34973 Ok(())
34974 }
34975
34976 fn generate_try_base64_decode_binary(&mut self, e: &TryBase64DecodeBinary) -> Result<()> {
34977 self.write_keyword("TRY_BASE64_DECODE_BINARY");
34979 self.write("(");
34980 self.generate_expression(&e.this)?;
34981 if let Some(alphabet) = &e.alphabet {
34982 self.write(", ");
34983 self.generate_expression(alphabet)?;
34984 }
34985 self.write(")");
34986 Ok(())
34987 }
34988
34989 fn generate_try_base64_decode_string(&mut self, e: &TryBase64DecodeString) -> Result<()> {
34990 self.write_keyword("TRY_BASE64_DECODE_STRING");
34992 self.write("(");
34993 self.generate_expression(&e.this)?;
34994 if let Some(alphabet) = &e.alphabet {
34995 self.write(", ");
34996 self.generate_expression(alphabet)?;
34997 }
34998 self.write(")");
34999 Ok(())
35000 }
35001
35002 fn generate_try_to_decfloat(&mut self, e: &TryToDecfloat) -> Result<()> {
35003 self.write_keyword("TRY_TO_DECFLOAT");
35005 self.write("(");
35006 self.generate_expression(&e.this)?;
35007 if let Some(format) = &e.format {
35008 self.write(", '");
35009 self.write(format);
35010 self.write("'");
35011 }
35012 self.write(")");
35013 Ok(())
35014 }
35015
35016 fn generate_ts_or_ds_add(&mut self, e: &TsOrDsAdd) -> Result<()> {
35017 self.write_keyword("TS_OR_DS_ADD");
35019 self.write("(");
35020 self.generate_expression(&e.this)?;
35021 self.write(", ");
35022 self.generate_expression(&e.expression)?;
35023 if let Some(unit) = &e.unit {
35024 self.write(", ");
35025 self.write_keyword(unit);
35026 }
35027 if let Some(return_type) = &e.return_type {
35028 self.write(", ");
35029 self.generate_expression(return_type)?;
35030 }
35031 self.write(")");
35032 Ok(())
35033 }
35034
35035 fn generate_ts_or_ds_diff(&mut self, e: &TsOrDsDiff) -> Result<()> {
35036 self.write_keyword("TS_OR_DS_DIFF");
35038 self.write("(");
35039 self.generate_expression(&e.this)?;
35040 self.write(", ");
35041 self.generate_expression(&e.expression)?;
35042 if let Some(unit) = &e.unit {
35043 self.write(", ");
35044 self.write_keyword(unit);
35045 }
35046 self.write(")");
35047 Ok(())
35048 }
35049
35050 fn generate_ts_or_ds_to_date(&mut self, e: &TsOrDsToDate) -> Result<()> {
35051 let default_time_format = "%Y-%m-%d %H:%M:%S";
35052 let default_date_format = "%Y-%m-%d";
35053 let has_non_default_format = e.format.as_ref().map_or(false, |f| {
35054 f != default_time_format && f != default_date_format
35055 });
35056
35057 if has_non_default_format {
35058 let fmt = e.format.as_ref().unwrap();
35060 match self.config.dialect {
35061 Some(DialectType::MySQL) | Some(DialectType::StarRocks) => {
35062 let str_to_time = crate::expressions::StrToTime {
35065 this: Box::new((*e.this).clone()),
35066 format: fmt.clone(),
35067 zone: None,
35068 safe: None,
35069 target_type: None,
35070 };
35071 self.generate_str_to_time(&str_to_time)?;
35072 }
35073 Some(DialectType::Hive)
35074 | Some(DialectType::Spark)
35075 | Some(DialectType::Databricks) => {
35076 self.write_keyword("TO_DATE");
35078 self.write("(");
35079 self.generate_expression(&e.this)?;
35080 self.write(", '");
35081 self.write(&Self::strftime_to_java_format(fmt));
35082 self.write("')");
35083 }
35084 Some(DialectType::Snowflake) => {
35085 self.write_keyword("TO_DATE");
35087 self.write("(");
35088 self.generate_expression(&e.this)?;
35089 self.write(", '");
35090 self.write(&Self::strftime_to_snowflake_format(fmt));
35091 self.write("')");
35092 }
35093 Some(DialectType::Doris) => {
35094 self.write_keyword("TO_DATE");
35096 self.write("(");
35097 self.generate_expression(&e.this)?;
35098 self.write(")");
35099 }
35100 _ => {
35101 self.write_keyword("CAST");
35103 self.write("(");
35104 let str_to_time = crate::expressions::StrToTime {
35105 this: Box::new((*e.this).clone()),
35106 format: fmt.clone(),
35107 zone: None,
35108 safe: None,
35109 target_type: None,
35110 };
35111 self.generate_str_to_time(&str_to_time)?;
35112 self.write_keyword(" AS ");
35113 self.write_keyword("DATE");
35114 self.write(")");
35115 }
35116 }
35117 } else {
35118 match self.config.dialect {
35120 Some(DialectType::MySQL)
35121 | Some(DialectType::SQLite)
35122 | Some(DialectType::StarRocks) => {
35123 self.write_keyword("DATE");
35125 self.write("(");
35126 self.generate_expression(&e.this)?;
35127 self.write(")");
35128 }
35129 Some(DialectType::Hive)
35130 | Some(DialectType::Spark)
35131 | Some(DialectType::Databricks)
35132 | Some(DialectType::Snowflake)
35133 | Some(DialectType::Doris) => {
35134 self.write_keyword("TO_DATE");
35136 self.write("(");
35137 self.generate_expression(&e.this)?;
35138 self.write(")");
35139 }
35140 Some(DialectType::Presto)
35141 | Some(DialectType::Trino)
35142 | Some(DialectType::Athena) => {
35143 self.write_keyword("CAST");
35145 self.write("(");
35146 self.write_keyword("CAST");
35147 self.write("(");
35148 self.generate_expression(&e.this)?;
35149 self.write_keyword(" AS ");
35150 self.write_keyword("TIMESTAMP");
35151 self.write(")");
35152 self.write_keyword(" AS ");
35153 self.write_keyword("DATE");
35154 self.write(")");
35155 }
35156 Some(DialectType::ClickHouse) => {
35157 self.write_keyword("CAST");
35159 self.write("(");
35160 self.generate_expression(&e.this)?;
35161 self.write_keyword(" AS ");
35162 self.write("Nullable(DATE)");
35163 self.write(")");
35164 }
35165 _ => {
35166 self.write_keyword("CAST");
35168 self.write("(");
35169 self.generate_expression(&e.this)?;
35170 self.write_keyword(" AS ");
35171 self.write_keyword("DATE");
35172 self.write(")");
35173 }
35174 }
35175 }
35176 Ok(())
35177 }
35178
35179 fn generate_ts_or_ds_to_time(&mut self, e: &TsOrDsToTime) -> Result<()> {
35180 self.write_keyword("TS_OR_DS_TO_TIME");
35182 self.write("(");
35183 self.generate_expression(&e.this)?;
35184 if let Some(format) = &e.format {
35185 self.write(", '");
35186 self.write(format);
35187 self.write("'");
35188 }
35189 self.write(")");
35190 Ok(())
35191 }
35192
35193 fn generate_unhex(&mut self, e: &Unhex) -> Result<()> {
35194 self.write_keyword("UNHEX");
35196 self.write("(");
35197 self.generate_expression(&e.this)?;
35198 if let Some(expression) = &e.expression {
35199 self.write(", ");
35200 self.generate_expression(expression)?;
35201 }
35202 self.write(")");
35203 Ok(())
35204 }
35205
35206 fn generate_unicode_string(&mut self, e: &UnicodeString) -> Result<()> {
35207 self.write("U&");
35209 self.generate_expression(&e.this)?;
35210 if let Some(escape) = &e.escape {
35211 self.write_space();
35212 self.write_keyword("UESCAPE");
35213 self.write_space();
35214 self.generate_expression(escape)?;
35215 }
35216 Ok(())
35217 }
35218
35219 fn generate_uniform(&mut self, e: &Uniform) -> Result<()> {
35220 self.write_keyword("UNIFORM");
35222 self.write("(");
35223 self.generate_expression(&e.this)?;
35224 self.write(", ");
35225 self.generate_expression(&e.expression)?;
35226 if let Some(gen) = &e.gen {
35227 self.write(", ");
35228 self.generate_expression(gen)?;
35229 }
35230 if let Some(seed) = &e.seed {
35231 self.write(", ");
35232 self.generate_expression(seed)?;
35233 }
35234 self.write(")");
35235 Ok(())
35236 }
35237
35238 fn generate_unique_column_constraint(&mut self, e: &UniqueColumnConstraint) -> Result<()> {
35239 self.write_keyword("UNIQUE");
35241 if e.nulls.is_some() {
35243 self.write(" NULLS NOT DISTINCT");
35244 }
35245 if let Some(this) = &e.this {
35246 self.write_space();
35247 self.generate_expression(this)?;
35248 }
35249 if let Some(index_type) = &e.index_type {
35250 self.write(" USING ");
35251 self.generate_expression(index_type)?;
35252 }
35253 if let Some(on_conflict) = &e.on_conflict {
35254 self.write_space();
35255 self.generate_expression(on_conflict)?;
35256 }
35257 for opt in &e.options {
35258 self.write_space();
35259 self.generate_expression(opt)?;
35260 }
35261 Ok(())
35262 }
35263
35264 fn generate_unique_key_property(&mut self, e: &UniqueKeyProperty) -> Result<()> {
35265 self.write_keyword("UNIQUE KEY");
35267 self.write(" (");
35268 for (i, expr) in e.expressions.iter().enumerate() {
35269 if i > 0 {
35270 self.write(", ");
35271 }
35272 self.generate_expression(expr)?;
35273 }
35274 self.write(")");
35275 Ok(())
35276 }
35277
35278 fn generate_rollup_property(&mut self, e: &RollupProperty) -> Result<()> {
35279 self.write_keyword("ROLLUP");
35281 self.write(" (");
35282 for (i, index) in e.expressions.iter().enumerate() {
35283 if i > 0 {
35284 self.write(", ");
35285 }
35286 self.generate_identifier(&index.name)?;
35287 self.write("(");
35288 for (j, col) in index.expressions.iter().enumerate() {
35289 if j > 0 {
35290 self.write(", ");
35291 }
35292 self.generate_identifier(col)?;
35293 }
35294 self.write(")");
35295 }
35296 self.write(")");
35297 Ok(())
35298 }
35299
35300 fn generate_unix_to_str(&mut self, e: &UnixToStr) -> Result<()> {
35301 match self.config.dialect {
35302 Some(DialectType::DuckDB) => {
35303 self.write_keyword("STRFTIME");
35305 self.write("(");
35306 self.write_keyword("TO_TIMESTAMP");
35307 self.write("(");
35308 self.generate_expression(&e.this)?;
35309 self.write("), '");
35310 if let Some(format) = &e.format {
35311 self.write(format);
35312 }
35313 self.write("')");
35314 }
35315 Some(DialectType::Hive) => {
35316 self.write_keyword("FROM_UNIXTIME");
35318 self.write("(");
35319 self.generate_expression(&e.this)?;
35320 if let Some(format) = &e.format {
35321 if format != "yyyy-MM-dd HH:mm:ss" {
35322 self.write(", '");
35323 self.write(format);
35324 self.write("'");
35325 }
35326 }
35327 self.write(")");
35328 }
35329 Some(DialectType::Presto) | Some(DialectType::Trino) => {
35330 self.write_keyword("DATE_FORMAT");
35332 self.write("(");
35333 self.write_keyword("FROM_UNIXTIME");
35334 self.write("(");
35335 self.generate_expression(&e.this)?;
35336 self.write("), '");
35337 if let Some(format) = &e.format {
35338 self.write(format);
35339 }
35340 self.write("')");
35341 }
35342 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
35343 self.write_keyword("FROM_UNIXTIME");
35345 self.write("(");
35346 self.generate_expression(&e.this)?;
35347 if let Some(format) = &e.format {
35348 self.write(", '");
35349 self.write(format);
35350 self.write("'");
35351 }
35352 self.write(")");
35353 }
35354 _ => {
35355 self.write_keyword("UNIX_TO_STR");
35357 self.write("(");
35358 self.generate_expression(&e.this)?;
35359 if let Some(format) = &e.format {
35360 self.write(", '");
35361 self.write(format);
35362 self.write("'");
35363 }
35364 self.write(")");
35365 }
35366 }
35367 Ok(())
35368 }
35369
35370 fn generate_unix_to_time(&mut self, e: &UnixToTime) -> Result<()> {
35371 use crate::dialects::DialectType;
35372 let scale = e.scale.unwrap_or(0); match self.config.dialect {
35375 Some(DialectType::Snowflake) => {
35376 self.write_keyword("TO_TIMESTAMP");
35378 self.write("(");
35379 self.generate_expression(&e.this)?;
35380 if let Some(s) = e.scale {
35381 if s > 0 {
35382 self.write(", ");
35383 self.write(&s.to_string());
35384 }
35385 }
35386 self.write(")");
35387 }
35388 Some(DialectType::BigQuery) => {
35389 match scale {
35392 0 => {
35393 self.write_keyword("TIMESTAMP_SECONDS");
35394 self.write("(");
35395 self.generate_expression(&e.this)?;
35396 self.write(")");
35397 }
35398 3 => {
35399 self.write_keyword("TIMESTAMP_MILLIS");
35400 self.write("(");
35401 self.generate_expression(&e.this)?;
35402 self.write(")");
35403 }
35404 6 => {
35405 self.write_keyword("TIMESTAMP_MICROS");
35406 self.write("(");
35407 self.generate_expression(&e.this)?;
35408 self.write(")");
35409 }
35410 _ => {
35411 self.write_keyword("TIMESTAMP_SECONDS");
35413 self.write("(CAST(");
35414 self.generate_expression(&e.this)?;
35415 self.write(&format!(" / POWER(10, {}) AS INT64))", scale));
35416 }
35417 }
35418 }
35419 Some(DialectType::Spark) => {
35420 match scale {
35425 0 => {
35426 self.write_keyword("CAST");
35427 self.write("(");
35428 self.write_keyword("FROM_UNIXTIME");
35429 self.write("(");
35430 self.generate_expression(&e.this)?;
35431 self.write(") ");
35432 self.write_keyword("AS TIMESTAMP");
35433 self.write(")");
35434 }
35435 3 => {
35436 self.write_keyword("TIMESTAMP_MILLIS");
35437 self.write("(");
35438 self.generate_expression(&e.this)?;
35439 self.write(")");
35440 }
35441 6 => {
35442 self.write_keyword("TIMESTAMP_MICROS");
35443 self.write("(");
35444 self.generate_expression(&e.this)?;
35445 self.write(")");
35446 }
35447 _ => {
35448 self.write_keyword("TIMESTAMP_SECONDS");
35449 self.write("(");
35450 self.generate_expression(&e.this)?;
35451 self.write(&format!(" / POWER(10, {}))", scale));
35452 }
35453 }
35454 }
35455 Some(DialectType::Databricks) => {
35456 match scale {
35460 0 => {
35461 self.write_keyword("CAST");
35462 self.write("(");
35463 self.write_keyword("FROM_UNIXTIME");
35464 self.write("(");
35465 self.generate_expression(&e.this)?;
35466 self.write(") ");
35467 self.write_keyword("AS TIMESTAMP");
35468 self.write(")");
35469 }
35470 3 => {
35471 self.write_keyword("TIMESTAMP_MILLIS");
35472 self.write("(");
35473 self.generate_expression(&e.this)?;
35474 self.write(")");
35475 }
35476 6 => {
35477 self.write_keyword("TIMESTAMP_MICROS");
35478 self.write("(");
35479 self.generate_expression(&e.this)?;
35480 self.write(")");
35481 }
35482 _ => {
35483 self.write_keyword("TIMESTAMP_SECONDS");
35484 self.write("(");
35485 self.generate_expression(&e.this)?;
35486 self.write(&format!(" / POWER(10, {}))", scale));
35487 }
35488 }
35489 }
35490 Some(DialectType::Hive) => {
35491 if scale == 0 {
35493 self.write_keyword("FROM_UNIXTIME");
35494 self.write("(");
35495 self.generate_expression(&e.this)?;
35496 self.write(")");
35497 } else {
35498 self.write_keyword("FROM_UNIXTIME");
35499 self.write("(");
35500 self.generate_expression(&e.this)?;
35501 self.write(&format!(" / POWER(10, {})", scale));
35502 self.write(")");
35503 }
35504 }
35505 Some(DialectType::Presto) | Some(DialectType::Trino) => {
35506 if scale == 0 {
35509 self.write_keyword("FROM_UNIXTIME");
35510 self.write("(");
35511 self.generate_expression(&e.this)?;
35512 self.write(")");
35513 } else {
35514 self.write_keyword("FROM_UNIXTIME");
35515 self.write("(CAST(");
35516 self.generate_expression(&e.this)?;
35517 self.write(&format!(" AS DOUBLE) / POW(10, {}))", scale));
35518 }
35519 }
35520 Some(DialectType::DuckDB) => {
35521 match scale {
35525 0 => {
35526 self.write_keyword("TO_TIMESTAMP");
35527 self.write("(");
35528 self.generate_expression(&e.this)?;
35529 self.write(")");
35530 }
35531 3 => {
35532 self.write_keyword("EPOCH_MS");
35533 self.write("(");
35534 self.generate_expression(&e.this)?;
35535 self.write(")");
35536 }
35537 6 => {
35538 self.write_keyword("MAKE_TIMESTAMP");
35539 self.write("(");
35540 self.generate_expression(&e.this)?;
35541 self.write(")");
35542 }
35543 _ => {
35544 self.write_keyword("TO_TIMESTAMP");
35545 self.write("(");
35546 self.generate_expression(&e.this)?;
35547 self.write(&format!(" / POWER(10, {}))", scale));
35548 self.write_keyword(" AT TIME ZONE");
35549 self.write(" 'UTC'");
35550 }
35551 }
35552 }
35553 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
35554 self.write_keyword("FROM_UNIXTIME");
35556 self.write("(");
35557 self.generate_expression(&e.this)?;
35558 self.write(")");
35559 }
35560 Some(DialectType::Oracle) => {
35561 self.write("TO_DATE('1970-01-01', 'YYYY-MM-DD') + (");
35563 self.generate_expression(&e.this)?;
35564 self.write(" / 86400)");
35565 }
35566 Some(DialectType::Redshift) => {
35567 self.write("(TIMESTAMP 'epoch' + ");
35570 if scale == 0 {
35571 self.generate_expression(&e.this)?;
35572 } else {
35573 self.write("(");
35574 self.generate_expression(&e.this)?;
35575 self.write(&format!(" / POWER(10, {}))", scale));
35576 }
35577 self.write(" * INTERVAL '1 SECOND')");
35578 }
35579 _ => {
35580 self.write_keyword("TO_TIMESTAMP");
35582 self.write("(");
35583 self.generate_expression(&e.this)?;
35584 if let Some(s) = e.scale {
35585 self.write(", ");
35586 self.write(&s.to_string());
35587 }
35588 self.write(")");
35589 }
35590 }
35591 Ok(())
35592 }
35593
35594 fn generate_unpivot_columns(&mut self, e: &UnpivotColumns) -> Result<()> {
35595 if !matches!(&*e.this, Expression::Null(_)) {
35597 self.write_keyword("NAME");
35598 self.write_space();
35599 self.generate_expression(&e.this)?;
35600 }
35601 if !e.expressions.is_empty() {
35602 self.write_space();
35603 self.write_keyword("VALUE");
35604 self.write_space();
35605 for (i, expr) in e.expressions.iter().enumerate() {
35606 if i > 0 {
35607 self.write(", ");
35608 }
35609 self.generate_expression(expr)?;
35610 }
35611 }
35612 Ok(())
35613 }
35614
35615 fn generate_user_defined_function(&mut self, e: &UserDefinedFunction) -> Result<()> {
35616 if e.wrapped.is_some() {
35618 self.write("(");
35619 }
35620 self.generate_expression(&e.this)?;
35621 if e.wrapped.is_some() {
35622 self.write(")");
35623 }
35624 self.write("(");
35625 for (i, expr) in e.expressions.iter().enumerate() {
35626 if i > 0 {
35627 self.write(", ");
35628 }
35629 self.generate_expression(expr)?;
35630 }
35631 self.write(")");
35632 Ok(())
35633 }
35634
35635 fn generate_using_template_property(&mut self, e: &UsingTemplateProperty) -> Result<()> {
35636 self.write_keyword("USING TEMPLATE");
35638 self.write_space();
35639 self.generate_expression(&e.this)?;
35640 Ok(())
35641 }
35642
35643 fn generate_utc_time(&mut self, _e: &UtcTime) -> Result<()> {
35644 self.write_keyword("UTC_TIME");
35646 Ok(())
35647 }
35648
35649 fn generate_utc_timestamp(&mut self, _e: &UtcTimestamp) -> Result<()> {
35650 self.write_keyword("UTC_TIMESTAMP");
35652 Ok(())
35653 }
35654
35655 fn generate_uuid(&mut self, e: &Uuid) -> Result<()> {
35656 use crate::dialects::DialectType;
35657 let func_name = match self.config.dialect {
35659 Some(DialectType::Snowflake) => "UUID_STRING",
35660 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
35661 Some(DialectType::BigQuery) => "GENERATE_UUID",
35662 _ => {
35663 if let Some(name) = &e.name {
35664 name.as_str()
35665 } else {
35666 "UUID"
35667 }
35668 }
35669 };
35670 self.write_keyword(func_name);
35671 self.write("(");
35672 if let Some(this) = &e.this {
35673 self.generate_expression(this)?;
35674 }
35675 self.write(")");
35676 Ok(())
35677 }
35678
35679 fn generate_var_map(&mut self, e: &VarMap) -> Result<()> {
35680 self.write_keyword("MAP");
35682 self.write("(");
35683 let mut first = true;
35684 for (k, v) in e.keys.iter().zip(e.values.iter()) {
35685 if !first {
35686 self.write(", ");
35687 }
35688 self.generate_expression(k)?;
35689 self.write(", ");
35690 self.generate_expression(v)?;
35691 first = false;
35692 }
35693 self.write(")");
35694 Ok(())
35695 }
35696
35697 fn generate_vector_search(&mut self, e: &VectorSearch) -> Result<()> {
35698 self.write_keyword("VECTOR_SEARCH");
35700 self.write("(");
35701 self.generate_expression(&e.this)?;
35702 if let Some(col) = &e.column_to_search {
35703 self.write(", ");
35704 self.generate_expression(col)?;
35705 }
35706 if let Some(query_table) = &e.query_table {
35707 self.write(", ");
35708 self.generate_expression(query_table)?;
35709 }
35710 if let Some(query_col) = &e.query_column_to_search {
35711 self.write(", ");
35712 self.generate_expression(query_col)?;
35713 }
35714 if let Some(top_k) = &e.top_k {
35715 self.write(", ");
35716 self.generate_expression(top_k)?;
35717 }
35718 if let Some(dist_type) = &e.distance_type {
35719 self.write(", ");
35720 self.generate_expression(dist_type)?;
35721 }
35722 self.write(")");
35723 Ok(())
35724 }
35725
35726 fn generate_version(&mut self, e: &Version) -> Result<()> {
35727 use crate::dialects::DialectType;
35733 let skip_for = matches!(
35734 self.config.dialect,
35735 Some(DialectType::Hive) | Some(DialectType::Spark)
35736 );
35737 if !skip_for {
35738 self.write_keyword("FOR");
35739 self.write_space();
35740 }
35741 match e.this.as_ref() {
35743 Expression::Identifier(ident) => {
35744 self.write_keyword(&ident.name);
35745 }
35746 _ => {
35747 self.generate_expression(&e.this)?;
35748 }
35749 }
35750 self.write_space();
35751 self.write_keyword(&e.kind);
35752 if let Some(expression) = &e.expression {
35753 self.write_space();
35754 self.generate_expression(expression)?;
35755 }
35756 Ok(())
35757 }
35758
35759 fn generate_view_attribute_property(&mut self, e: &ViewAttributeProperty) -> Result<()> {
35760 self.generate_expression(&e.this)?;
35762 Ok(())
35763 }
35764
35765 fn generate_volatile_property(&mut self, e: &VolatileProperty) -> Result<()> {
35766 if e.this.is_some() {
35768 self.write_keyword("NOT VOLATILE");
35769 } else {
35770 self.write_keyword("VOLATILE");
35771 }
35772 Ok(())
35773 }
35774
35775 fn generate_watermark_column_constraint(
35776 &mut self,
35777 e: &WatermarkColumnConstraint,
35778 ) -> Result<()> {
35779 self.write_keyword("WATERMARK FOR");
35781 self.write_space();
35782 self.generate_expression(&e.this)?;
35783 self.write_space();
35784 self.write_keyword("AS");
35785 self.write_space();
35786 self.generate_expression(&e.expression)?;
35787 Ok(())
35788 }
35789
35790 fn generate_week(&mut self, e: &Week) -> Result<()> {
35791 self.write_keyword("WEEK");
35793 self.write("(");
35794 self.generate_expression(&e.this)?;
35795 if let Some(mode) = &e.mode {
35796 self.write(", ");
35797 self.generate_expression(mode)?;
35798 }
35799 self.write(")");
35800 Ok(())
35801 }
35802
35803 fn generate_when(&mut self, e: &When) -> Result<()> {
35804 self.write_keyword("WHEN");
35808 self.write_space();
35809
35810 if let Some(matched) = &e.matched {
35812 match matched.as_ref() {
35814 Expression::Boolean(b) if b.value => {
35815 self.write_keyword("MATCHED");
35816 }
35817 _ => {
35818 self.write_keyword("NOT MATCHED");
35819 }
35820 }
35821 } else {
35822 self.write_keyword("NOT MATCHED");
35823 }
35824
35825 if self.config.matched_by_source {
35830 if let Some(source) = &e.source {
35831 if let Expression::Boolean(b) = source.as_ref() {
35832 if b.value {
35833 self.write_space();
35835 self.write_keyword("BY SOURCE");
35836 }
35837 } else {
35839 self.write_space();
35841 self.write_keyword("BY SOURCE");
35842 }
35843 }
35844 }
35845
35846 if let Some(condition) = &e.condition {
35848 self.write_space();
35849 self.write_keyword("AND");
35850 self.write_space();
35851 self.generate_expression(condition)?;
35852 }
35853
35854 self.write_space();
35855 self.write_keyword("THEN");
35856 self.write_space();
35857
35858 self.generate_merge_action(&e.then)?;
35861
35862 Ok(())
35863 }
35864
35865 fn generate_merge_action(&mut self, action: &Expression) -> Result<()> {
35866 match action {
35867 Expression::Tuple(tuple) => {
35868 let elements = &tuple.expressions;
35869 if elements.is_empty() {
35870 return self.generate_expression(action);
35871 }
35872 match &elements[0] {
35874 Expression::Var(v) if v.this == "INSERT" => {
35875 self.write_keyword("INSERT");
35876 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
35878 self.write(" *");
35879 } else {
35880 let mut values_idx = 1;
35881 if elements.len() > 1 {
35883 if let Expression::Tuple(cols) = &elements[1] {
35884 if elements.len() > 2 {
35886 self.write(" (");
35888 for (i, col) in cols.expressions.iter().enumerate() {
35889 if i > 0 {
35890 self.write(", ");
35891 }
35892 if !self.merge_strip_qualifiers.is_empty() {
35894 let stripped = self.strip_merge_qualifier(col);
35895 self.generate_expression(&stripped)?;
35896 } else {
35897 self.generate_expression(col)?;
35898 }
35899 }
35900 self.write(")");
35901 values_idx = 2;
35902 } else {
35903 values_idx = 1;
35905 }
35906 }
35907 }
35908 if values_idx < elements.len() {
35910 let is_row = matches!(&elements[values_idx], Expression::Var(v) if v.this == "ROW");
35912 if !is_row {
35913 self.write_space();
35914 self.write_keyword("VALUES");
35915 }
35916 self.write(" ");
35917 if let Expression::Tuple(vals) = &elements[values_idx] {
35918 self.write("(");
35919 for (i, val) in vals.expressions.iter().enumerate() {
35920 if i > 0 {
35921 self.write(", ");
35922 }
35923 self.generate_expression(val)?;
35924 }
35925 self.write(")");
35926 } else {
35927 self.generate_expression(&elements[values_idx])?;
35928 }
35929 }
35930 } }
35932 Expression::Var(v) if v.this == "UPDATE" => {
35933 self.write_keyword("UPDATE");
35934 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
35936 self.write(" *");
35937 } else if elements.len() > 1 {
35938 self.write_space();
35939 self.write_keyword("SET");
35940 if self.config.pretty {
35942 self.write_newline();
35943 self.indent_level += 1;
35944 self.write_indent();
35945 } else {
35946 self.write_space();
35947 }
35948 if let Expression::Tuple(assignments) = &elements[1] {
35949 for (i, assignment) in assignments.expressions.iter().enumerate() {
35950 if i > 0 {
35951 if self.config.pretty {
35952 self.write(",");
35953 self.write_newline();
35954 self.write_indent();
35955 } else {
35956 self.write(", ");
35957 }
35958 }
35959 if !self.merge_strip_qualifiers.is_empty() {
35961 self.generate_merge_set_assignment(assignment)?;
35962 } else {
35963 self.generate_expression(assignment)?;
35964 }
35965 }
35966 } else {
35967 self.generate_expression(&elements[1])?;
35968 }
35969 if self.config.pretty {
35970 self.indent_level -= 1;
35971 }
35972 }
35973 }
35974 _ => {
35975 self.generate_expression(action)?;
35977 }
35978 }
35979 }
35980 Expression::Var(v)
35981 if v.this == "INSERT"
35982 || v.this == "UPDATE"
35983 || v.this == "DELETE"
35984 || v.this == "DO NOTHING" =>
35985 {
35986 self.write_keyword(&v.this);
35987 }
35988 _ => {
35989 self.generate_expression(action)?;
35990 }
35991 }
35992 Ok(())
35993 }
35994
35995 fn generate_merge_set_assignment(&mut self, assignment: &Expression) -> Result<()> {
35997 match assignment {
35998 Expression::Eq(eq) => {
35999 let stripped_left = self.strip_merge_qualifier(&eq.left);
36001 self.generate_expression(&stripped_left)?;
36002 self.write(" = ");
36003 self.generate_expression(&eq.right)?;
36004 Ok(())
36005 }
36006 other => self.generate_expression(other),
36007 }
36008 }
36009
36010 fn strip_merge_qualifier(&self, expr: &Expression) -> Expression {
36012 match expr {
36013 Expression::Column(col) => {
36014 if let Some(ref table_ident) = col.table {
36015 if self
36016 .merge_strip_qualifiers
36017 .iter()
36018 .any(|n| n.eq_ignore_ascii_case(&table_ident.name))
36019 {
36020 let mut col = col.clone();
36022 col.table = None;
36023 return Expression::Column(col);
36024 }
36025 }
36026 expr.clone()
36027 }
36028 Expression::Dot(dot) => {
36029 if let Expression::Identifier(id) = &dot.this {
36031 if self
36032 .merge_strip_qualifiers
36033 .iter()
36034 .any(|n| n.eq_ignore_ascii_case(&id.name))
36035 {
36036 return Expression::Identifier(dot.field.clone());
36037 }
36038 }
36039 expr.clone()
36040 }
36041 _ => expr.clone(),
36042 }
36043 }
36044
36045 fn generate_whens(&mut self, e: &Whens) -> Result<()> {
36046 for (i, expr) in e.expressions.iter().enumerate() {
36048 if i > 0 {
36049 if self.config.pretty {
36051 self.write_newline();
36052 self.write_indent();
36053 } else {
36054 self.write_space();
36055 }
36056 }
36057 self.generate_expression(expr)?;
36058 }
36059 Ok(())
36060 }
36061
36062 fn generate_where(&mut self, e: &Where) -> Result<()> {
36063 self.write_keyword("WHERE");
36065 self.write_space();
36066 self.generate_expression(&e.this)?;
36067 Ok(())
36068 }
36069
36070 fn generate_width_bucket(&mut self, e: &WidthBucket) -> Result<()> {
36071 self.write_keyword("WIDTH_BUCKET");
36073 self.write("(");
36074 self.generate_expression(&e.this)?;
36075 if let Some(min_value) = &e.min_value {
36076 self.write(", ");
36077 self.generate_expression(min_value)?;
36078 }
36079 if let Some(max_value) = &e.max_value {
36080 self.write(", ");
36081 self.generate_expression(max_value)?;
36082 }
36083 if let Some(num_buckets) = &e.num_buckets {
36084 self.write(", ");
36085 self.generate_expression(num_buckets)?;
36086 }
36087 self.write(")");
36088 Ok(())
36089 }
36090
36091 fn generate_window(&mut self, e: &WindowSpec) -> Result<()> {
36092 self.generate_window_spec(e)
36094 }
36095
36096 fn generate_window_spec(&mut self, e: &WindowSpec) -> Result<()> {
36097 let mut has_content = false;
36099
36100 if !e.partition_by.is_empty() {
36102 self.write_keyword("PARTITION BY");
36103 self.write_space();
36104 for (i, expr) in e.partition_by.iter().enumerate() {
36105 if i > 0 {
36106 self.write(", ");
36107 }
36108 self.generate_expression(expr)?;
36109 }
36110 has_content = true;
36111 }
36112
36113 if !e.order_by.is_empty() {
36115 if has_content {
36116 self.write_space();
36117 }
36118 self.write_keyword("ORDER BY");
36119 self.write_space();
36120 for (i, ordered) in e.order_by.iter().enumerate() {
36121 if i > 0 {
36122 self.write(", ");
36123 }
36124 self.generate_expression(&ordered.this)?;
36125 if ordered.desc {
36126 self.write_space();
36127 self.write_keyword("DESC");
36128 } else if ordered.explicit_asc {
36129 self.write_space();
36130 self.write_keyword("ASC");
36131 }
36132 if let Some(nulls_first) = ordered.nulls_first {
36133 self.write_space();
36134 self.write_keyword("NULLS");
36135 self.write_space();
36136 if nulls_first {
36137 self.write_keyword("FIRST");
36138 } else {
36139 self.write_keyword("LAST");
36140 }
36141 }
36142 }
36143 has_content = true;
36144 }
36145
36146 if let Some(frame) = &e.frame {
36148 if has_content {
36149 self.write_space();
36150 }
36151 self.generate_window_frame(frame)?;
36152 }
36153
36154 Ok(())
36155 }
36156
36157 fn generate_with_data_property(&mut self, e: &WithDataProperty) -> Result<()> {
36158 self.write_keyword("WITH");
36160 self.write_space();
36161 if e.no.is_some() {
36162 self.write_keyword("NO");
36163 self.write_space();
36164 }
36165 self.write_keyword("DATA");
36166
36167 if let Some(statistics) = &e.statistics {
36169 self.write_space();
36170 self.write_keyword("AND");
36171 self.write_space();
36172 match statistics.as_ref() {
36174 Expression::Boolean(b) if !b.value => {
36175 self.write_keyword("NO");
36176 self.write_space();
36177 }
36178 _ => {}
36179 }
36180 self.write_keyword("STATISTICS");
36181 }
36182 Ok(())
36183 }
36184
36185 fn generate_with_fill(&mut self, e: &WithFill) -> Result<()> {
36186 self.write_keyword("WITH FILL");
36188
36189 if let Some(from_) = &e.from_ {
36190 self.write_space();
36191 self.write_keyword("FROM");
36192 self.write_space();
36193 self.generate_expression(from_)?;
36194 }
36195
36196 if let Some(to) = &e.to {
36197 self.write_space();
36198 self.write_keyword("TO");
36199 self.write_space();
36200 self.generate_expression(to)?;
36201 }
36202
36203 if let Some(step) = &e.step {
36204 self.write_space();
36205 self.write_keyword("STEP");
36206 self.write_space();
36207 self.generate_expression(step)?;
36208 }
36209
36210 if let Some(staleness) = &e.staleness {
36211 self.write_space();
36212 self.write_keyword("STALENESS");
36213 self.write_space();
36214 self.generate_expression(staleness)?;
36215 }
36216
36217 if let Some(interpolate) = &e.interpolate {
36218 self.write_space();
36219 self.write_keyword("INTERPOLATE");
36220 self.write(" (");
36221 self.generate_interpolate_item(interpolate)?;
36223 self.write(")");
36224 }
36225
36226 Ok(())
36227 }
36228
36229 fn generate_interpolate_item(&mut self, expr: &Expression) -> Result<()> {
36231 match expr {
36232 Expression::Alias(alias) => {
36233 self.generate_identifier(&alias.alias)?;
36235 self.write_space();
36236 self.write_keyword("AS");
36237 self.write_space();
36238 self.generate_expression(&alias.this)?;
36239 }
36240 Expression::Tuple(tuple) => {
36241 for (i, item) in tuple.expressions.iter().enumerate() {
36242 if i > 0 {
36243 self.write(", ");
36244 }
36245 self.generate_interpolate_item(item)?;
36246 }
36247 }
36248 other => {
36249 self.generate_expression(other)?;
36250 }
36251 }
36252 Ok(())
36253 }
36254
36255 fn generate_with_journal_table_property(&mut self, e: &WithJournalTableProperty) -> Result<()> {
36256 self.write_keyword("WITH JOURNAL TABLE");
36258 self.write("=");
36259 self.generate_expression(&e.this)?;
36260 Ok(())
36261 }
36262
36263 fn generate_with_operator(&mut self, e: &WithOperator) -> Result<()> {
36264 self.generate_expression(&e.this)?;
36266 self.write_space();
36267 self.write_keyword("WITH");
36268 self.write_space();
36269 self.write_keyword(&e.op);
36270 Ok(())
36271 }
36272
36273 fn generate_with_procedure_options(&mut self, e: &WithProcedureOptions) -> Result<()> {
36274 self.write_keyword("WITH");
36276 self.write_space();
36277 for (i, expr) in e.expressions.iter().enumerate() {
36278 if i > 0 {
36279 self.write(", ");
36280 }
36281 self.generate_expression(expr)?;
36282 }
36283 Ok(())
36284 }
36285
36286 fn generate_with_schema_binding_property(
36287 &mut self,
36288 e: &WithSchemaBindingProperty,
36289 ) -> Result<()> {
36290 self.write_keyword("WITH");
36292 self.write_space();
36293 self.generate_expression(&e.this)?;
36294 Ok(())
36295 }
36296
36297 fn generate_with_system_versioning_property(
36298 &mut self,
36299 e: &WithSystemVersioningProperty,
36300 ) -> Result<()> {
36301 let mut parts = Vec::new();
36307
36308 if let Some(this) = &e.this {
36309 let mut s = String::from("HISTORY_TABLE=");
36311 let mut gen = Generator::new();
36312 gen.generate_expression(this)?;
36313 s.push_str(&gen.output);
36314 parts.push(s);
36315 }
36316
36317 if let Some(data_consistency) = &e.data_consistency {
36318 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
36319 let mut gen = Generator::new();
36320 gen.generate_expression(data_consistency)?;
36321 s.push_str(&gen.output);
36322 parts.push(s);
36323 }
36324
36325 if let Some(retention_period) = &e.retention_period {
36326 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
36327 let mut gen = Generator::new();
36328 gen.generate_expression(retention_period)?;
36329 s.push_str(&gen.output);
36330 parts.push(s);
36331 }
36332
36333 self.write_keyword("SYSTEM_VERSIONING");
36334 self.write("=");
36335
36336 if !parts.is_empty() {
36337 self.write_keyword("ON");
36338 self.write("(");
36339 self.write(&parts.join(", "));
36340 self.write(")");
36341 } else if e.on.is_some() {
36342 self.write_keyword("ON");
36343 } else {
36344 self.write_keyword("OFF");
36345 }
36346
36347 if e.with_.is_some() {
36349 let inner = self.output.clone();
36350 self.output.clear();
36351 self.write("WITH(");
36352 self.write(&inner);
36353 self.write(")");
36354 }
36355
36356 Ok(())
36357 }
36358
36359 fn generate_with_table_hint(&mut self, e: &WithTableHint) -> Result<()> {
36360 self.write_keyword("WITH");
36362 self.write(" (");
36363 for (i, expr) in e.expressions.iter().enumerate() {
36364 if i > 0 {
36365 self.write(", ");
36366 }
36367 self.generate_expression(expr)?;
36368 }
36369 self.write(")");
36370 Ok(())
36371 }
36372
36373 fn generate_xml_element(&mut self, e: &XMLElement) -> Result<()> {
36374 self.write_keyword("XMLELEMENT");
36377 self.write("(");
36378
36379 if e.evalname.is_some() {
36380 self.write_keyword("EVALNAME");
36381 } else {
36382 self.write_keyword("NAME");
36383 }
36384 self.write_space();
36385 self.generate_expression(&e.this)?;
36386
36387 for expr in &e.expressions {
36388 self.write(", ");
36389 self.generate_expression(expr)?;
36390 }
36391 self.write(")");
36392 Ok(())
36393 }
36394
36395 fn generate_xml_get(&mut self, e: &XMLGet) -> Result<()> {
36396 self.write_keyword("XMLGET");
36398 self.write("(");
36399 self.generate_expression(&e.this)?;
36400 self.write(", ");
36401 self.generate_expression(&e.expression)?;
36402 if let Some(instance) = &e.instance {
36403 self.write(", ");
36404 self.generate_expression(instance)?;
36405 }
36406 self.write(")");
36407 Ok(())
36408 }
36409
36410 fn generate_xml_key_value_option(&mut self, e: &XMLKeyValueOption) -> Result<()> {
36411 self.generate_expression(&e.this)?;
36413 if let Some(expression) = &e.expression {
36414 self.write("(");
36415 self.generate_expression(expression)?;
36416 self.write(")");
36417 }
36418 Ok(())
36419 }
36420
36421 fn generate_xml_table(&mut self, e: &XMLTable) -> Result<()> {
36422 self.write_keyword("XMLTABLE");
36424 self.write("(");
36425
36426 if self.config.pretty {
36427 self.indent_level += 1;
36428 self.write_newline();
36429 self.write_indent();
36430 self.generate_expression(&e.this)?;
36431
36432 if let Some(passing) = &e.passing {
36433 self.write_newline();
36434 self.write_indent();
36435 self.write_keyword("PASSING");
36436 if let Expression::Tuple(tuple) = passing.as_ref() {
36437 for expr in &tuple.expressions {
36438 self.write_newline();
36439 self.indent_level += 1;
36440 self.write_indent();
36441 self.generate_expression(expr)?;
36442 self.indent_level -= 1;
36443 }
36444 } else {
36445 self.write_newline();
36446 self.indent_level += 1;
36447 self.write_indent();
36448 self.generate_expression(passing)?;
36449 self.indent_level -= 1;
36450 }
36451 }
36452
36453 if e.by_ref.is_some() {
36454 self.write_newline();
36455 self.write_indent();
36456 self.write_keyword("RETURNING SEQUENCE BY REF");
36457 }
36458
36459 if !e.columns.is_empty() {
36460 self.write_newline();
36461 self.write_indent();
36462 self.write_keyword("COLUMNS");
36463 for (i, col) in e.columns.iter().enumerate() {
36464 self.write_newline();
36465 self.indent_level += 1;
36466 self.write_indent();
36467 self.generate_expression(col)?;
36468 self.indent_level -= 1;
36469 if i < e.columns.len() - 1 {
36470 self.write(",");
36471 }
36472 }
36473 }
36474
36475 self.indent_level -= 1;
36476 self.write_newline();
36477 self.write_indent();
36478 self.write(")");
36479 return Ok(());
36480 }
36481
36482 if let Some(namespaces) = &e.namespaces {
36484 self.write_keyword("XMLNAMESPACES");
36485 self.write("(");
36486 if let Expression::Tuple(tuple) = namespaces.as_ref() {
36488 for (i, expr) in tuple.expressions.iter().enumerate() {
36489 if i > 0 {
36490 self.write(", ");
36491 }
36492 if !matches!(expr, Expression::Alias(_)) {
36495 self.write_keyword("DEFAULT");
36496 self.write_space();
36497 }
36498 self.generate_expression(expr)?;
36499 }
36500 } else {
36501 if !matches!(namespaces.as_ref(), Expression::Alias(_)) {
36503 self.write_keyword("DEFAULT");
36504 self.write_space();
36505 }
36506 self.generate_expression(namespaces)?;
36507 }
36508 self.write("), ");
36509 }
36510
36511 self.generate_expression(&e.this)?;
36513
36514 if let Some(passing) = &e.passing {
36516 self.write_space();
36517 self.write_keyword("PASSING");
36518 self.write_space();
36519 if let Expression::Tuple(tuple) = passing.as_ref() {
36521 for (i, expr) in tuple.expressions.iter().enumerate() {
36522 if i > 0 {
36523 self.write(", ");
36524 }
36525 self.generate_expression(expr)?;
36526 }
36527 } else {
36528 self.generate_expression(passing)?;
36529 }
36530 }
36531
36532 if e.by_ref.is_some() {
36534 self.write_space();
36535 self.write_keyword("RETURNING SEQUENCE BY REF");
36536 }
36537
36538 if !e.columns.is_empty() {
36540 self.write_space();
36541 self.write_keyword("COLUMNS");
36542 self.write_space();
36543 for (i, col) in e.columns.iter().enumerate() {
36544 if i > 0 {
36545 self.write(", ");
36546 }
36547 self.generate_expression(col)?;
36548 }
36549 }
36550
36551 self.write(")");
36552 Ok(())
36553 }
36554
36555 fn generate_xor(&mut self, e: &Xor) -> Result<()> {
36556 if let Some(this) = &e.this {
36559 self.generate_expression(this)?;
36560 if let Some(expression) = &e.expression {
36561 self.write_space();
36562 self.write_keyword("XOR");
36563 self.write_space();
36564 self.generate_expression(expression)?;
36565 }
36566 }
36567
36568 for (i, expr) in e.expressions.iter().enumerate() {
36570 if i > 0 || e.this.is_some() {
36571 self.write_space();
36572 self.write_keyword("XOR");
36573 self.write_space();
36574 }
36575 self.generate_expression(expr)?;
36576 }
36577 Ok(())
36578 }
36579
36580 fn generate_zipf(&mut self, e: &Zipf) -> Result<()> {
36581 self.write_keyword("ZIPF");
36583 self.write("(");
36584 self.generate_expression(&e.this)?;
36585 if let Some(elementcount) = &e.elementcount {
36586 self.write(", ");
36587 self.generate_expression(elementcount)?;
36588 }
36589 if let Some(gen) = &e.gen {
36590 self.write(", ");
36591 self.generate_expression(gen)?;
36592 }
36593 self.write(")");
36594 Ok(())
36595 }
36596}
36597
36598impl Default for Generator {
36599 fn default() -> Self {
36600 Self::new()
36601 }
36602}
36603
36604#[cfg(test)]
36605mod tests {
36606 use super::*;
36607 use crate::parser::Parser;
36608
36609 fn roundtrip(sql: &str) -> String {
36610 let ast = Parser::parse_sql(sql).unwrap();
36611 Generator::sql(&ast[0]).unwrap()
36612 }
36613
36614 #[test]
36615 fn test_simple_select() {
36616 let result = roundtrip("SELECT 1");
36617 assert_eq!(result, "SELECT 1");
36618 }
36619
36620 #[test]
36621 fn test_select_from() {
36622 let result = roundtrip("SELECT a, b FROM t");
36623 assert_eq!(result, "SELECT a, b FROM t");
36624 }
36625
36626 #[test]
36627 fn test_select_where() {
36628 let result = roundtrip("SELECT * FROM t WHERE x = 1");
36629 assert_eq!(result, "SELECT * FROM t WHERE x = 1");
36630 }
36631
36632 #[test]
36633 fn test_select_join() {
36634 let result = roundtrip("SELECT * FROM a JOIN b ON a.id = b.id");
36635 assert_eq!(result, "SELECT * FROM a JOIN b ON a.id = b.id");
36636 }
36637
36638 #[test]
36639 fn test_insert() {
36640 let result = roundtrip("INSERT INTO t (a, b) VALUES (1, 2)");
36641 assert_eq!(result, "INSERT INTO t (a, b) VALUES (1, 2)");
36642 }
36643
36644 #[test]
36645 fn test_pretty_print() {
36646 let ast = Parser::parse_sql("SELECT a, b FROM t WHERE x = 1").unwrap();
36647 let result = Generator::pretty_sql(&ast[0]).unwrap();
36648 assert!(result.contains('\n'));
36649 }
36650
36651 #[test]
36652 fn test_window_function() {
36653 let result = roundtrip("SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)");
36654 assert_eq!(
36655 result,
36656 "SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)"
36657 );
36658 }
36659
36660 #[test]
36661 fn test_window_function_with_frame() {
36662 let result = roundtrip("SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
36663 assert_eq!(result, "SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
36664 }
36665
36666 #[test]
36667 fn test_aggregate_with_filter() {
36668 let result = roundtrip("SELECT COUNT(*) FILTER (WHERE status = 1) FROM orders");
36669 assert_eq!(
36670 result,
36671 "SELECT COUNT(*) FILTER(WHERE status = 1) FROM orders"
36672 );
36673 }
36674
36675 #[test]
36676 fn test_subscript() {
36677 let result = roundtrip("SELECT arr[0]");
36678 assert_eq!(result, "SELECT arr[0]");
36679 }
36680
36681 #[test]
36683 fn test_create_table() {
36684 let result = roundtrip("CREATE TABLE users (id INT, name VARCHAR(100))");
36685 assert_eq!(result, "CREATE TABLE users (id INT, name VARCHAR(100))");
36686 }
36687
36688 #[test]
36689 fn test_create_table_with_constraints() {
36690 let result = roundtrip(
36691 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)",
36692 );
36693 assert_eq!(
36694 result,
36695 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)"
36696 );
36697 }
36698
36699 #[test]
36700 fn test_create_table_if_not_exists() {
36701 let result = roundtrip("CREATE TABLE IF NOT EXISTS t (id INT)");
36702 assert_eq!(result, "CREATE TABLE IF NOT EXISTS t (id INT)");
36703 }
36704
36705 #[test]
36706 fn test_drop_table() {
36707 let result = roundtrip("DROP TABLE users");
36708 assert_eq!(result, "DROP TABLE users");
36709 }
36710
36711 #[test]
36712 fn test_drop_table_if_exists_cascade() {
36713 let result = roundtrip("DROP TABLE IF EXISTS users CASCADE");
36714 assert_eq!(result, "DROP TABLE IF EXISTS users CASCADE");
36715 }
36716
36717 #[test]
36718 fn test_alter_table_add_column() {
36719 let result = roundtrip("ALTER TABLE users ADD COLUMN email VARCHAR(255)");
36720 assert_eq!(result, "ALTER TABLE users ADD COLUMN email VARCHAR(255)");
36721 }
36722
36723 #[test]
36724 fn test_alter_table_drop_column() {
36725 let result = roundtrip("ALTER TABLE users DROP COLUMN email");
36726 assert_eq!(result, "ALTER TABLE users DROP COLUMN email");
36727 }
36728
36729 #[test]
36730 fn test_create_index() {
36731 let result = roundtrip("CREATE INDEX idx_name ON users(name)");
36732 assert_eq!(result, "CREATE INDEX idx_name ON users(name)");
36733 }
36734
36735 #[test]
36736 fn test_create_unique_index() {
36737 let result = roundtrip("CREATE UNIQUE INDEX idx_email ON users(email)");
36738 assert_eq!(result, "CREATE UNIQUE INDEX idx_email ON users(email)");
36739 }
36740
36741 #[test]
36742 fn test_drop_index() {
36743 let result = roundtrip("DROP INDEX idx_name");
36744 assert_eq!(result, "DROP INDEX idx_name");
36745 }
36746
36747 #[test]
36748 fn test_create_view() {
36749 let result = roundtrip("CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1");
36750 assert_eq!(
36751 result,
36752 "CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1"
36753 );
36754 }
36755
36756 #[test]
36757 fn test_drop_view() {
36758 let result = roundtrip("DROP VIEW active_users");
36759 assert_eq!(result, "DROP VIEW active_users");
36760 }
36761
36762 #[test]
36763 fn test_truncate() {
36764 let result = roundtrip("TRUNCATE TABLE users");
36765 assert_eq!(result, "TRUNCATE TABLE users");
36766 }
36767
36768 #[test]
36769 fn test_string_literal_escaping_default() {
36770 let result = roundtrip("SELECT 'hello'");
36772 assert_eq!(result, "SELECT 'hello'");
36773
36774 let result = roundtrip("SELECT 'it''s a test'");
36776 assert_eq!(result, "SELECT 'it''s a test'");
36777 }
36778
36779 #[test]
36780 fn test_not_in_style_prefix_default_generic() {
36781 let result = roundtrip("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')");
36782 assert_eq!(
36783 result,
36784 "SELECT id FROM users WHERE NOT status IN ('deleted', 'banned')"
36785 );
36786 }
36787
36788 #[test]
36789 fn test_not_in_style_infix_generic_override() {
36790 let ast =
36791 Parser::parse_sql("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')")
36792 .unwrap();
36793 let config = GeneratorConfig {
36794 not_in_style: NotInStyle::Infix,
36795 ..Default::default()
36796 };
36797 let mut gen = Generator::with_config(config);
36798 let result = gen.generate(&ast[0]).unwrap();
36799 assert_eq!(
36800 result,
36801 "SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')"
36802 );
36803 }
36804
36805 #[test]
36806 fn test_string_literal_escaping_mysql() {
36807 use crate::dialects::DialectType;
36808
36809 let config = GeneratorConfig {
36810 dialect: Some(DialectType::MySQL),
36811 ..Default::default()
36812 };
36813
36814 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
36815 let mut gen = Generator::with_config(config.clone());
36816 let result = gen.generate(&ast[0]).unwrap();
36817 assert_eq!(result, "SELECT 'hello'");
36818
36819 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
36821 let mut gen = Generator::with_config(config.clone());
36822 let result = gen.generate(&ast[0]).unwrap();
36823 assert_eq!(result, "SELECT 'it''s'");
36824 }
36825
36826 #[test]
36827 fn test_string_literal_escaping_postgres() {
36828 use crate::dialects::DialectType;
36829
36830 let config = GeneratorConfig {
36831 dialect: Some(DialectType::PostgreSQL),
36832 ..Default::default()
36833 };
36834
36835 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
36836 let mut gen = Generator::with_config(config.clone());
36837 let result = gen.generate(&ast[0]).unwrap();
36838 assert_eq!(result, "SELECT 'hello'");
36839
36840 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
36842 let mut gen = Generator::with_config(config.clone());
36843 let result = gen.generate(&ast[0]).unwrap();
36844 assert_eq!(result, "SELECT 'it''s'");
36845 }
36846
36847 #[test]
36848 fn test_string_literal_escaping_bigquery() {
36849 use crate::dialects::DialectType;
36850
36851 let config = GeneratorConfig {
36852 dialect: Some(DialectType::BigQuery),
36853 ..Default::default()
36854 };
36855
36856 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
36857 let mut gen = Generator::with_config(config.clone());
36858 let result = gen.generate(&ast[0]).unwrap();
36859 assert_eq!(result, "SELECT 'hello'");
36860
36861 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
36863 let mut gen = Generator::with_config(config.clone());
36864 let result = gen.generate(&ast[0]).unwrap();
36865 assert_eq!(result, "SELECT 'it\\'s'");
36866 }
36867
36868 #[test]
36869 fn test_generate_deep_and_chain_without_stack_growth() {
36870 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
36871 Expression::column("c0"),
36872 Expression::number(0),
36873 )));
36874
36875 for i in 1..2500 {
36876 let predicate = Expression::Eq(Box::new(BinaryOp::new(
36877 Expression::column(format!("c{i}")),
36878 Expression::number(i as i64),
36879 )));
36880 expr = Expression::And(Box::new(BinaryOp::new(expr, predicate)));
36881 }
36882
36883 let sql = Generator::sql(&expr).expect("deep AND chain should generate");
36884 assert!(sql.contains("c2499 = 2499"), "{}", sql);
36885 }
36886
36887 #[test]
36888 fn test_generate_deep_or_chain_without_stack_growth() {
36889 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
36890 Expression::column("c0"),
36891 Expression::number(0),
36892 )));
36893
36894 for i in 1..2500 {
36895 let predicate = Expression::Eq(Box::new(BinaryOp::new(
36896 Expression::column(format!("c{i}")),
36897 Expression::number(i as i64),
36898 )));
36899 expr = Expression::Or(Box::new(BinaryOp::new(expr, predicate)));
36900 }
36901
36902 let sql = Generator::sql(&expr).expect("deep OR chain should generate");
36903 assert!(sql.contains("c2499 = 2499"), "{}", sql);
36904 }
36905}