1use crate::error::Result;
14use crate::expressions::*;
15use crate::DialectType;
16
17pub struct Generator {
42 config: GeneratorConfig,
43 output: String,
44 indent_level: usize,
45 athena_hive_context: bool,
48 sqlite_inline_pk_columns: std::collections::HashSet<String>,
50 merge_strip_qualifiers: Vec<String>,
52 clickhouse_nullable_depth: i32,
57}
58
59#[derive(Debug, Clone, Copy, PartialEq, Default)]
65pub enum NormalizeFunctions {
66 #[default]
68 Upper,
69 Lower,
71 None,
73}
74
75#[derive(Debug, Clone, Copy, PartialEq, Default)]
77pub enum LimitFetchStyle {
78 #[default]
80 Limit,
81 Top,
83 FetchFirst,
85}
86
87#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
89pub enum NotInStyle {
90 #[default]
92 Prefix,
93 Infix,
95}
96
97#[derive(Debug, Clone, Copy, PartialEq, Eq)]
98enum ConnectorOperator {
99 And,
100 Or,
101}
102
103impl ConnectorOperator {
104 fn keyword(self) -> &'static str {
105 match self {
106 Self::And => "AND",
107 Self::Or => "OR",
108 }
109 }
110}
111
112#[derive(Debug, Clone, Copy, PartialEq)]
114pub struct IdentifierQuoteStyle {
115 pub start: char,
117 pub end: char,
119}
120
121impl Default for IdentifierQuoteStyle {
122 fn default() -> Self {
123 Self {
124 start: '"',
125 end: '"',
126 }
127 }
128}
129
130impl IdentifierQuoteStyle {
131 pub const DOUBLE_QUOTE: Self = Self {
133 start: '"',
134 end: '"',
135 };
136 pub const BACKTICK: Self = Self {
138 start: '`',
139 end: '`',
140 };
141 pub const BRACKET: Self = Self {
143 start: '[',
144 end: ']',
145 };
146}
147
148#[derive(Debug, Clone)]
170pub struct GeneratorConfig {
171 pub pretty: bool,
174 pub indent: String,
176 pub max_text_width: usize,
178 pub identifier_quote: char,
180 pub identifier_quote_style: IdentifierQuoteStyle,
182 pub uppercase_keywords: bool,
184 pub normalize_identifiers: bool,
186 pub dialect: Option<crate::dialects::DialectType>,
188 pub source_dialect: Option<crate::dialects::DialectType>,
190 pub normalize_functions: NormalizeFunctions,
192 pub string_escape: char,
194 pub case_sensitive_identifiers: bool,
196 pub identifiers_can_start_with_digit: bool,
198 pub always_quote_identifiers: bool,
201 pub not_in_style: NotInStyle,
203
204 pub null_ordering_supported: bool,
208 pub ignore_nulls_in_func: bool,
211 pub nvl2_supported: bool,
213
214 pub limit_fetch_style: LimitFetchStyle,
217 pub limit_is_top: bool,
219 pub limit_only_literals: bool,
221
222 pub single_string_interval: bool,
225 pub interval_allows_plural_form: bool,
227
228 pub cte_recursive_keyword_required: bool,
231
232 pub values_as_table: bool,
235 pub wrap_derived_values: bool,
237
238 pub tablesample_seed_keyword: &'static str,
241 pub tablesample_requires_parens: bool,
243 pub tablesample_size_is_rows: bool,
245 pub tablesample_keywords: &'static str,
247 pub tablesample_with_method: bool,
249 pub alias_post_tablesample: bool,
251
252 pub aggregate_filter_supported: bool,
255 pub multi_arg_distinct: bool,
257 pub quantified_no_paren_space: bool,
259 pub supports_median: bool,
261
262 pub supports_select_into: bool,
265 pub locking_reads_supported: bool,
267
268 pub rename_table_with_db: bool,
271 pub semi_anti_join_with_side: bool,
273 pub supports_table_alias_columns: bool,
275 pub join_hints: bool,
277 pub table_hints: bool,
279 pub query_hints: bool,
281 pub query_hint_sep: &'static str,
283 pub supports_column_join_marks: bool,
285
286 pub index_using_no_space: bool,
290 pub supports_unlogged_tables: bool,
292 pub supports_create_table_like: bool,
294 pub like_property_inside_schema: bool,
296 pub alter_table_include_column_keyword: bool,
298 pub supports_table_copy: bool,
300 pub alter_set_type: &'static str,
302 pub alter_set_wrapped: bool,
304
305 pub tz_to_with_time_zone: bool,
308 pub supports_convert_timezone: bool,
310
311 pub json_type_required_for_extraction: bool,
314 pub json_path_bracketed_key_supported: bool,
316 pub json_path_single_quote_escape: bool,
318 pub quote_json_path: bool,
320 pub json_key_value_pair_sep: &'static str,
322
323 pub copy_params_are_wrapped: bool,
326 pub copy_params_eq_required: bool,
328 pub copy_has_into_keyword: bool,
330
331 pub supports_window_exclude: bool,
334 pub unnest_with_ordinality: bool,
336 pub lowercase_window_frame_keywords: bool,
339 pub normalize_window_frame_between: bool,
342
343 pub array_concat_is_var_len: bool,
346 pub array_size_dim_required: Option<bool>,
349 pub can_implement_array_any: bool,
351 pub array_size_name: &'static str,
353
354 pub supports_between_flags: bool,
357
358 pub is_bool_allowed: bool,
361 pub ensure_bools: bool,
363
364 pub extract_allows_quotes: bool,
367 pub normalize_extract_date_parts: bool,
369
370 pub try_supported: bool,
373 pub supports_uescape: bool,
375 pub supports_to_number: bool,
377 pub supports_single_arg_concat: bool,
379 pub last_day_supports_date_part: bool,
381 pub supports_exploding_projections: bool,
383 pub supports_unix_seconds: bool,
385 pub supports_like_quantifiers: bool,
387 pub supports_decode_case: bool,
389 pub set_op_modifiers: bool,
391 pub update_statement_supports_from: bool,
393
394 pub collate_is_func: bool,
397
398 pub duplicate_key_update_with_set: bool,
401 pub insert_overwrite: &'static str,
403
404 pub returning_end: bool,
407
408 pub matched_by_source: bool,
411
412 pub create_function_return_as: bool,
415 pub parameter_default_equals: bool,
417
418 pub computed_column_with_type: bool,
421
422 pub unpivot_aliases_are_identifiers: bool,
425
426 pub star_except: &'static str,
429
430 pub hex_func: &'static str,
433
434 pub with_properties_prefix: &'static str,
437
438 pub pad_fill_pattern_is_required: bool,
441
442 pub index_on: &'static str,
445
446 pub groupings_sep: &'static str,
449
450 pub struct_delimiter: (&'static str, &'static str),
453 pub struct_curly_brace_notation: bool,
455 pub array_bracket_only: bool,
457 pub struct_field_sep: &'static str,
459
460 pub except_intersect_support_all_clause: bool,
463
464 pub parameter_token: &'static str,
467 pub named_placeholder_token: &'static str,
469
470 pub data_type_specifiers_allowed: bool,
473
474 pub schema_comment_with_eq: bool,
478}
479
480impl Default for GeneratorConfig {
481 fn default() -> Self {
482 Self {
483 pretty: false,
485 indent: " ".to_string(),
486 max_text_width: 80,
487 identifier_quote: '"',
488 identifier_quote_style: IdentifierQuoteStyle::DOUBLE_QUOTE,
489 uppercase_keywords: true,
490 normalize_identifiers: false,
491 dialect: None,
492 source_dialect: None,
493 normalize_functions: NormalizeFunctions::Upper,
494 string_escape: '\'',
495 case_sensitive_identifiers: false,
496 identifiers_can_start_with_digit: false,
497 always_quote_identifiers: false,
498 not_in_style: NotInStyle::Prefix,
499
500 null_ordering_supported: true,
502 ignore_nulls_in_func: false,
503 nvl2_supported: true,
504
505 limit_fetch_style: LimitFetchStyle::Limit,
507 limit_is_top: false,
508 limit_only_literals: false,
509
510 single_string_interval: false,
512 interval_allows_plural_form: true,
513
514 cte_recursive_keyword_required: true,
516
517 values_as_table: true,
519 wrap_derived_values: true,
520
521 tablesample_seed_keyword: "SEED",
523 tablesample_requires_parens: true,
524 tablesample_size_is_rows: true,
525 tablesample_keywords: "TABLESAMPLE",
526 tablesample_with_method: true,
527 alias_post_tablesample: false,
528
529 aggregate_filter_supported: true,
531 multi_arg_distinct: true,
532 quantified_no_paren_space: false,
533 supports_median: true,
534
535 supports_select_into: false,
537 locking_reads_supported: true,
538
539 rename_table_with_db: true,
541 semi_anti_join_with_side: true,
542 supports_table_alias_columns: true,
543 join_hints: true,
544 table_hints: true,
545 query_hints: true,
546 query_hint_sep: ", ",
547 supports_column_join_marks: false,
548
549 index_using_no_space: false,
551 supports_unlogged_tables: false,
552 supports_create_table_like: true,
553 like_property_inside_schema: false,
554 alter_table_include_column_keyword: true,
555 supports_table_copy: true,
556 alter_set_type: "SET DATA TYPE",
557 alter_set_wrapped: false,
558
559 tz_to_with_time_zone: false,
561 supports_convert_timezone: false,
562
563 json_type_required_for_extraction: false,
565 json_path_bracketed_key_supported: true,
566 json_path_single_quote_escape: false,
567 quote_json_path: true,
568 json_key_value_pair_sep: ":",
569
570 copy_params_are_wrapped: true,
572 copy_params_eq_required: false,
573 copy_has_into_keyword: true,
574
575 supports_window_exclude: false,
577 unnest_with_ordinality: true,
578 lowercase_window_frame_keywords: false,
579 normalize_window_frame_between: false,
580
581 array_concat_is_var_len: true,
583 array_size_dim_required: None,
584 can_implement_array_any: false,
585 array_size_name: "ARRAY_LENGTH",
586
587 supports_between_flags: false,
589
590 is_bool_allowed: true,
592 ensure_bools: false,
593
594 extract_allows_quotes: true,
596 normalize_extract_date_parts: false,
597
598 try_supported: true,
600 supports_uescape: true,
601 supports_to_number: true,
602 supports_single_arg_concat: true,
603 last_day_supports_date_part: true,
604 supports_exploding_projections: true,
605 supports_unix_seconds: false,
606 supports_like_quantifiers: true,
607 supports_decode_case: true,
608 set_op_modifiers: true,
609 update_statement_supports_from: true,
610
611 collate_is_func: false,
613
614 duplicate_key_update_with_set: true,
616 insert_overwrite: " OVERWRITE TABLE",
617
618 returning_end: true,
620
621 matched_by_source: true,
623
624 create_function_return_as: true,
626 parameter_default_equals: false,
627
628 computed_column_with_type: true,
630
631 unpivot_aliases_are_identifiers: true,
633
634 star_except: "EXCEPT",
636
637 hex_func: "HEX",
639
640 with_properties_prefix: "WITH",
642
643 pad_fill_pattern_is_required: false,
645
646 index_on: "ON",
648
649 groupings_sep: ",",
651
652 struct_delimiter: ("<", ">"),
654 struct_curly_brace_notation: false,
655 array_bracket_only: false,
656 struct_field_sep: " ",
657
658 except_intersect_support_all_clause: true,
660
661 parameter_token: "@",
663 named_placeholder_token: ":",
664
665 data_type_specifiers_allowed: false,
667
668 schema_comment_with_eq: true,
670 }
671 }
672}
673
674mod reserved_keywords {
677 use std::collections::HashSet;
678 use std::sync::LazyLock;
679
680 pub static SQL_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
682 [
683 "all",
684 "alter",
685 "and",
686 "any",
687 "array",
688 "as",
689 "asc",
690 "at",
691 "authorization",
692 "begin",
693 "between",
694 "both",
695 "by",
696 "case",
697 "cast",
698 "check",
699 "collate",
700 "column",
701 "commit",
702 "constraint",
703 "create",
704 "cross",
705 "cube",
706 "current",
707 "current_date",
708 "current_time",
709 "current_timestamp",
710 "current_user",
711 "default",
712 "delete",
713 "desc",
714 "distinct",
715 "drop",
716 "else",
717 "end",
718 "escape",
719 "except",
720 "execute",
721 "exists",
722 "external",
723 "false",
724 "fetch",
725 "filter",
726 "for",
727 "foreign",
728 "from",
729 "full",
730 "function",
731 "grant",
732 "group",
733 "grouping",
734 "having",
735 "if",
736 "in",
737 "index",
738 "inner",
739 "insert",
740 "intersect",
741 "interval",
742 "into",
743 "is",
744 "join",
745 "key",
746 "leading",
747 "left",
748 "like",
749 "limit",
750 "local",
751 "localtime",
752 "localtimestamp",
753 "match",
754 "merge",
755 "natural",
756 "no",
757 "not",
758 "null",
759 "of",
760 "offset",
761 "on",
762 "only",
763 "or",
764 "order",
765 "outer",
766 "over",
767 "partition",
768 "primary",
769 "procedure",
770 "range",
771 "references",
772 "right",
773 "rollback",
774 "rollup",
775 "row",
776 "rows",
777 "select",
778 "session_user",
779 "set",
780 "some",
781 "table",
782 "tablesample",
783 "then",
784 "to",
785 "trailing",
786 "true",
787 "truncate",
788 "union",
789 "unique",
790 "unknown",
791 "update",
792 "user",
793 "using",
794 "values",
795 "view",
796 "when",
797 "where",
798 "window",
799 "with",
800 ]
801 .into_iter()
802 .collect()
803 });
804
805 pub static BIGQUERY_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
808 let mut set = SQL_RESERVED.clone();
809 set.extend([
810 "assert_rows_modified",
811 "at",
812 "contains",
813 "cube",
814 "current",
815 "define",
816 "enum",
817 "escape",
818 "exclude",
819 "following",
820 "for",
821 "groups",
822 "hash",
823 "ignore",
824 "lateral",
825 "lookup",
826 "new",
827 "no",
828 "nulls",
829 "of",
830 "over",
831 "preceding",
832 "proto",
833 "qualify",
834 "recursive",
835 "respect",
836 "struct",
837 "tablesample",
838 "treat",
839 "unbounded",
840 "unnest",
841 "window",
842 "within",
843 ]);
844 set.remove("grant");
846 set.remove("key");
847 set.remove("index");
848 set.remove("values");
849 set.remove("table");
850 set
851 });
852
853 pub static MYSQL_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
855 let mut set = SQL_RESERVED.clone();
856 set.extend([
857 "accessible",
858 "add",
859 "analyze",
860 "asensitive",
861 "before",
862 "bigint",
863 "binary",
864 "blob",
865 "call",
866 "cascade",
867 "change",
868 "char",
869 "character",
870 "condition",
871 "continue",
872 "convert",
873 "current_date",
874 "current_time",
875 "current_timestamp",
876 "current_user",
877 "cursor",
878 "database",
879 "databases",
880 "day_hour",
881 "day_microsecond",
882 "day_minute",
883 "day_second",
884 "dec",
885 "decimal",
886 "declare",
887 "delayed",
888 "describe",
889 "deterministic",
890 "distinctrow",
891 "div",
892 "double",
893 "dual",
894 "each",
895 "elseif",
896 "enclosed",
897 "escaped",
898 "exit",
899 "explain",
900 "float",
901 "float4",
902 "float8",
903 "force",
904 "get",
905 "high_priority",
906 "hour_microsecond",
907 "hour_minute",
908 "hour_second",
909 "ignore",
910 "infile",
911 "inout",
912 "insensitive",
913 "int",
914 "int1",
915 "int2",
916 "int3",
917 "int4",
918 "int8",
919 "integer",
920 "iterate",
921 "keys",
922 "kill",
923 "leave",
924 "linear",
925 "lines",
926 "load",
927 "lock",
928 "long",
929 "longblob",
930 "longtext",
931 "loop",
932 "low_priority",
933 "master_ssl_verify_server_cert",
934 "maxvalue",
935 "mediumblob",
936 "mediumint",
937 "mediumtext",
938 "middleint",
939 "minute_microsecond",
940 "minute_second",
941 "mod",
942 "modifies",
943 "no_write_to_binlog",
944 "numeric",
945 "optimize",
946 "option",
947 "optionally",
948 "out",
949 "outfile",
950 "precision",
951 "purge",
952 "read",
953 "reads",
954 "real",
955 "regexp",
956 "release",
957 "rename",
958 "repeat",
959 "replace",
960 "require",
961 "resignal",
962 "restrict",
963 "return",
964 "revoke",
965 "rlike",
966 "schema",
967 "schemas",
968 "second_microsecond",
969 "sensitive",
970 "separator",
971 "show",
972 "signal",
973 "smallint",
974 "spatial",
975 "specific",
976 "sql",
977 "sql_big_result",
978 "sql_calc_found_rows",
979 "sql_small_result",
980 "sqlexception",
981 "sqlstate",
982 "sqlwarning",
983 "ssl",
984 "starting",
985 "straight_join",
986 "terminated",
987 "text",
988 "tinyblob",
989 "tinyint",
990 "tinytext",
991 "trigger",
992 "undo",
993 "unlock",
994 "unsigned",
995 "usage",
996 "utc_date",
997 "utc_time",
998 "utc_timestamp",
999 "varbinary",
1000 "varchar",
1001 "varcharacter",
1002 "varying",
1003 "while",
1004 "write",
1005 "xor",
1006 "year_month",
1007 "zerofill",
1008 ]);
1009 set.remove("table");
1010 set
1011 });
1012
1013 pub static DORIS_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1016 let mut set = MYSQL_RESERVED.clone();
1017 set.extend([
1018 "aggregate",
1019 "anti",
1020 "array",
1021 "backend",
1022 "backup",
1023 "begin",
1024 "bitmap",
1025 "boolean",
1026 "broker",
1027 "buckets",
1028 "cached",
1029 "cancel",
1030 "cast",
1031 "catalog",
1032 "charset",
1033 "cluster",
1034 "collation",
1035 "columns",
1036 "comment",
1037 "commit",
1038 "config",
1039 "connection",
1040 "count",
1041 "current",
1042 "data",
1043 "date",
1044 "datetime",
1045 "day",
1046 "deferred",
1047 "distributed",
1048 "dynamic",
1049 "enable",
1050 "end",
1051 "events",
1052 "export",
1053 "external",
1054 "fields",
1055 "first",
1056 "follower",
1057 "format",
1058 "free",
1059 "frontend",
1060 "full",
1061 "functions",
1062 "global",
1063 "grants",
1064 "hash",
1065 "help",
1066 "hour",
1067 "install",
1068 "intermediate",
1069 "json",
1070 "label",
1071 "last",
1072 "less",
1073 "level",
1074 "link",
1075 "local",
1076 "location",
1077 "max",
1078 "merge",
1079 "min",
1080 "minute",
1081 "modify",
1082 "month",
1083 "name",
1084 "names",
1085 "negative",
1086 "nulls",
1087 "observer",
1088 "offset",
1089 "only",
1090 "open",
1091 "overwrite",
1092 "password",
1093 "path",
1094 "plan",
1095 "plugin",
1096 "plugins",
1097 "policy",
1098 "process",
1099 "properties",
1100 "property",
1101 "query",
1102 "quota",
1103 "recover",
1104 "refresh",
1105 "repair",
1106 "replica",
1107 "repository",
1108 "resource",
1109 "restore",
1110 "resume",
1111 "role",
1112 "roles",
1113 "rollback",
1114 "rollup",
1115 "routine",
1116 "sample",
1117 "second",
1118 "semi",
1119 "session",
1120 "signed",
1121 "snapshot",
1122 "start",
1123 "stats",
1124 "status",
1125 "stop",
1126 "stream",
1127 "string",
1128 "sum",
1129 "tables",
1130 "tablet",
1131 "temporary",
1132 "text",
1133 "timestamp",
1134 "transaction",
1135 "trash",
1136 "trim",
1137 "truncate",
1138 "type",
1139 "user",
1140 "value",
1141 "variables",
1142 "verbose",
1143 "version",
1144 "view",
1145 "warnings",
1146 "week",
1147 "work",
1148 "year",
1149 ]);
1150 set
1151 });
1152
1153 pub static POSTGRES_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1155 let mut set = SQL_RESERVED.clone();
1156 set.extend([
1157 "analyse",
1158 "analyze",
1159 "asymmetric",
1160 "binary",
1161 "collation",
1162 "concurrently",
1163 "current_catalog",
1164 "current_role",
1165 "current_schema",
1166 "deferrable",
1167 "do",
1168 "freeze",
1169 "ilike",
1170 "initially",
1171 "isnull",
1172 "lateral",
1173 "notnull",
1174 "placing",
1175 "returning",
1176 "similar",
1177 "symmetric",
1178 "variadic",
1179 "verbose",
1180 ]);
1181 set.remove("default");
1183 set.remove("interval");
1184 set.remove("match");
1185 set.remove("offset");
1186 set.remove("table");
1187 set
1188 });
1189
1190 pub static REDSHIFT_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1194 [
1195 "aes128",
1196 "aes256",
1197 "all",
1198 "allowoverwrite",
1199 "analyse",
1200 "analyze",
1201 "and",
1202 "any",
1203 "array",
1204 "as",
1205 "asc",
1206 "authorization",
1207 "az64",
1208 "backup",
1209 "between",
1210 "binary",
1211 "blanksasnull",
1212 "both",
1213 "bytedict",
1214 "bzip2",
1215 "case",
1216 "cast",
1217 "check",
1218 "collate",
1219 "column",
1220 "constraint",
1221 "create",
1222 "credentials",
1223 "cross",
1224 "current_date",
1225 "current_time",
1226 "current_timestamp",
1227 "current_user",
1228 "current_user_id",
1229 "default",
1230 "deferrable",
1231 "deflate",
1232 "defrag",
1233 "delta",
1234 "delta32k",
1235 "desc",
1236 "disable",
1237 "distinct",
1238 "do",
1239 "else",
1240 "emptyasnull",
1241 "enable",
1242 "encode",
1243 "encrypt",
1244 "encryption",
1245 "end",
1246 "except",
1247 "explicit",
1248 "false",
1249 "for",
1250 "foreign",
1251 "freeze",
1252 "from",
1253 "full",
1254 "globaldict256",
1255 "globaldict64k",
1256 "grant",
1257 "group",
1258 "gzip",
1259 "having",
1260 "identity",
1261 "ignore",
1262 "ilike",
1263 "in",
1264 "initially",
1265 "inner",
1266 "intersect",
1267 "interval",
1268 "into",
1269 "is",
1270 "isnull",
1271 "join",
1272 "leading",
1273 "left",
1274 "like",
1275 "limit",
1276 "localtime",
1277 "localtimestamp",
1278 "lun",
1279 "luns",
1280 "lzo",
1281 "lzop",
1282 "minus",
1283 "mostly16",
1284 "mostly32",
1285 "mostly8",
1286 "natural",
1287 "new",
1288 "not",
1289 "notnull",
1290 "null",
1291 "nulls",
1292 "off",
1293 "offline",
1294 "offset",
1295 "oid",
1296 "old",
1297 "on",
1298 "only",
1299 "open",
1300 "or",
1301 "order",
1302 "outer",
1303 "overlaps",
1304 "parallel",
1305 "partition",
1306 "percent",
1307 "permissions",
1308 "pivot",
1309 "placing",
1310 "primary",
1311 "raw",
1312 "readratio",
1313 "recover",
1314 "references",
1315 "rejectlog",
1316 "resort",
1317 "respect",
1318 "restore",
1319 "right",
1320 "select",
1321 "session_user",
1322 "similar",
1323 "snapshot",
1324 "some",
1325 "sysdate",
1326 "system",
1327 "table",
1328 "tag",
1329 "tdes",
1330 "text255",
1331 "text32k",
1332 "then",
1333 "timestamp",
1334 "to",
1335 "top",
1336 "trailing",
1337 "true",
1338 "truncatecolumns",
1339 "type",
1340 "union",
1341 "unique",
1342 "unnest",
1343 "unpivot",
1344 "user",
1345 "using",
1346 "verbose",
1347 "wallet",
1348 "when",
1349 "where",
1350 "with",
1351 "without",
1352 ]
1353 .into_iter()
1354 .collect()
1355 });
1356
1357 pub static DUCKDB_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1359 let mut set = POSTGRES_RESERVED.clone();
1360 set.extend([
1361 "anti",
1362 "asof",
1363 "columns",
1364 "describe",
1365 "groups",
1366 "macro",
1367 "pivot",
1368 "pivot_longer",
1369 "pivot_wider",
1370 "qualify",
1371 "replace",
1372 "respect",
1373 "semi",
1374 "show",
1375 "table",
1376 "unpivot",
1377 ]);
1378 set.remove("at");
1379 set.remove("key");
1380 set.remove("row");
1381 set
1382 });
1383
1384 pub static PRESTO_TRINO_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1386 let mut set = SQL_RESERVED.clone();
1387 set.extend([
1388 "alter",
1389 "and",
1390 "as",
1391 "between",
1392 "by",
1393 "case",
1394 "cast",
1395 "constraint",
1396 "create",
1397 "cross",
1398 "cube",
1399 "current_catalog",
1400 "current_date",
1401 "current_path",
1402 "current_role",
1403 "current_schema",
1404 "current_time",
1405 "current_timestamp",
1406 "current_user",
1407 "deallocate",
1408 "delete",
1409 "describe",
1410 "distinct",
1411 "drop",
1412 "else",
1413 "end",
1414 "escape",
1415 "except",
1416 "execute",
1417 "exists",
1418 "extract",
1419 "false",
1420 "for",
1421 "from",
1422 "full",
1423 "group",
1424 "grouping",
1425 "having",
1426 "in",
1427 "inner",
1428 "insert",
1429 "intersect",
1430 "into",
1431 "is",
1432 "join",
1433 "json_array",
1434 "json_exists",
1435 "json_object",
1436 "json_query",
1437 "json_table",
1438 "json_value",
1439 "left",
1440 "like",
1441 "listagg",
1442 "localtime",
1443 "localtimestamp",
1444 "natural",
1445 "normalize",
1446 "not",
1447 "null",
1448 "on",
1449 "or",
1450 "order",
1451 "outer",
1452 "prepare",
1453 "recursive",
1454 "right",
1455 "rollup",
1456 "select",
1457 "skip",
1458 "table",
1459 "then",
1460 "trim",
1461 "true",
1462 "uescape",
1463 "union",
1464 "unnest",
1465 "using",
1466 "values",
1467 "when",
1468 "where",
1469 "with",
1470 ]);
1471 set.remove("key");
1473 set
1474 });
1475
1476 pub static STARROCKS_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1479 [
1480 "add",
1481 "all",
1482 "alter",
1483 "analyze",
1484 "and",
1485 "array",
1486 "as",
1487 "asc",
1488 "between",
1489 "bigint",
1490 "bitmap",
1491 "both",
1492 "by",
1493 "case",
1494 "char",
1495 "character",
1496 "check",
1497 "collate",
1498 "column",
1499 "compaction",
1500 "convert",
1501 "create",
1502 "cross",
1503 "cube",
1504 "current_date",
1505 "current_role",
1506 "current_time",
1507 "current_timestamp",
1508 "current_user",
1509 "database",
1510 "databases",
1511 "decimal",
1512 "decimalv2",
1513 "decimal32",
1514 "decimal64",
1515 "decimal128",
1516 "default",
1517 "deferred",
1518 "delete",
1519 "dense_rank",
1520 "desc",
1521 "describe",
1522 "distinct",
1523 "double",
1524 "drop",
1525 "dual",
1526 "else",
1527 "except",
1528 "exists",
1529 "explain",
1530 "false",
1531 "first_value",
1532 "float",
1533 "for",
1534 "force",
1535 "from",
1536 "full",
1537 "function",
1538 "grant",
1539 "group",
1540 "grouping",
1541 "grouping_id",
1542 "groups",
1543 "having",
1544 "hll",
1545 "host",
1546 "if",
1547 "ignore",
1548 "immediate",
1549 "in",
1550 "index",
1551 "infile",
1552 "inner",
1553 "insert",
1554 "int",
1555 "integer",
1556 "intersect",
1557 "into",
1558 "is",
1559 "join",
1560 "json",
1561 "key",
1562 "keys",
1563 "kill",
1564 "lag",
1565 "largeint",
1566 "last_value",
1567 "lateral",
1568 "lead",
1569 "left",
1570 "like",
1571 "limit",
1572 "load",
1573 "localtime",
1574 "localtimestamp",
1575 "maxvalue",
1576 "minus",
1577 "mod",
1578 "not",
1579 "ntile",
1580 "null",
1581 "on",
1582 "or",
1583 "order",
1584 "outer",
1585 "outfile",
1586 "over",
1587 "partition",
1588 "percentile",
1589 "primary",
1590 "procedure",
1591 "qualify",
1592 "range",
1593 "rank",
1594 "read",
1595 "regexp",
1596 "release",
1597 "rename",
1598 "replace",
1599 "revoke",
1600 "right",
1601 "rlike",
1602 "row",
1603 "row_number",
1604 "rows",
1605 "schema",
1606 "schemas",
1607 "select",
1608 "set",
1609 "set_var",
1610 "show",
1611 "smallint",
1612 "system",
1613 "table",
1614 "terminated",
1615 "text",
1616 "then",
1617 "tinyint",
1618 "to",
1619 "true",
1620 "union",
1621 "unique",
1622 "unsigned",
1623 "update",
1624 "use",
1625 "using",
1626 "values",
1627 "varchar",
1628 "when",
1629 "where",
1630 "with",
1631 ]
1632 .into_iter()
1633 .collect()
1634 });
1635
1636 pub static SINGLESTORE_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1639 let mut set = MYSQL_RESERVED.clone();
1640 set.extend([
1641 "abs",
1644 "account",
1645 "acos",
1646 "adddate",
1647 "addtime",
1648 "admin",
1649 "aes_decrypt",
1650 "aes_encrypt",
1651 "aggregate",
1652 "aggregates",
1653 "aggregator",
1654 "anti_join",
1655 "any_value",
1656 "approx_count_distinct",
1657 "approx_percentile",
1658 "arrange",
1659 "arrangement",
1660 "asin",
1661 "atan",
1662 "atan2",
1663 "attach",
1664 "autostats",
1665 "avro",
1666 "background",
1667 "backup",
1668 "batch",
1669 "batches",
1670 "boot_strapping",
1671 "ceil",
1672 "ceiling",
1673 "coercibility",
1674 "columnar",
1675 "columnstore",
1676 "compile",
1677 "concurrent",
1678 "connection_id",
1679 "cos",
1680 "cot",
1681 "current_security_groups",
1682 "current_security_roles",
1683 "dayname",
1684 "dayofmonth",
1685 "dayofweek",
1686 "dayofyear",
1687 "degrees",
1688 "dot_product",
1689 "dump",
1690 "durability",
1691 "earliest",
1692 "echo",
1693 "election",
1694 "euclidean_distance",
1695 "exp",
1696 "extractor",
1697 "extractors",
1698 "floor",
1699 "foreground",
1700 "found_rows",
1701 "from_base64",
1702 "from_days",
1703 "from_unixtime",
1704 "fs",
1705 "fulltext",
1706 "gc",
1707 "gcs",
1708 "geography",
1709 "geography_area",
1710 "geography_contains",
1711 "geography_distance",
1712 "geography_intersects",
1713 "geography_latitude",
1714 "geography_length",
1715 "geography_longitude",
1716 "geographypoint",
1717 "geography_point",
1718 "geography_within_distance",
1719 "geometry",
1720 "geometry_area",
1721 "geometry_contains",
1722 "geometry_distance",
1723 "geometry_filter",
1724 "geometry_intersects",
1725 "geometry_length",
1726 "geometrypoint",
1727 "geometry_point",
1728 "geometry_within_distance",
1729 "geometry_x",
1730 "geometry_y",
1731 "greatest",
1732 "groups",
1733 "group_concat",
1734 "gzip",
1735 "hdfs",
1736 "hex",
1737 "highlight",
1738 "ifnull",
1739 "ilike",
1740 "inet_aton",
1741 "inet_ntoa",
1742 "inet6_aton",
1743 "inet6_ntoa",
1744 "initcap",
1745 "instr",
1746 "interpreter_mode",
1747 "isnull",
1748 "json",
1749 "json_agg",
1750 "json_array_contains_double",
1751 "json_array_contains_json",
1752 "json_array_contains_string",
1753 "json_delete_key",
1754 "json_extract_double",
1755 "json_extract_json",
1756 "json_extract_string",
1757 "json_extract_bigint",
1758 "json_get_type",
1759 "json_length",
1760 "json_set_double",
1761 "json_set_json",
1762 "json_set_string",
1763 "kafka",
1764 "lag",
1765 "last_day",
1766 "last_insert_id",
1767 "latest",
1768 "lcase",
1769 "lead",
1770 "leaf",
1771 "least",
1772 "leaves",
1773 "length",
1774 "license",
1775 "links",
1776 "llvm",
1777 "ln",
1778 "load",
1779 "locate",
1780 "log",
1781 "log10",
1782 "log2",
1783 "lpad",
1784 "lz4",
1785 "management",
1786 "match",
1787 "mbc",
1788 "md5",
1789 "median",
1790 "memsql",
1791 "memsql_deserialize",
1792 "memsql_serialize",
1793 "metadata",
1794 "microsecond",
1795 "minute",
1796 "model",
1797 "monthname",
1798 "months_between",
1799 "mpl",
1800 "namespace",
1801 "node",
1802 "noparam",
1803 "now",
1804 "nth_value",
1805 "ntile",
1806 "nullcols",
1807 "nullif",
1808 "object",
1809 "octet_length",
1810 "offsets",
1811 "online",
1812 "optimizer",
1813 "orphan",
1814 "parquet",
1815 "partitions",
1816 "pause",
1817 "percentile_cont",
1818 "percentile_disc",
1819 "periodic",
1820 "persisted",
1821 "pi",
1822 "pipeline",
1823 "pipelines",
1824 "plancache",
1825 "plugins",
1826 "pool",
1827 "pools",
1828 "pow",
1829 "power",
1830 "process",
1831 "processlist",
1832 "profile",
1833 "profiles",
1834 "quarter",
1835 "queries",
1836 "query",
1837 "radians",
1838 "rand",
1839 "record",
1840 "reduce",
1841 "redundancy",
1842 "regexp_match",
1843 "regexp_substr",
1844 "remote",
1845 "replication",
1846 "resource",
1847 "resource_pool",
1848 "restore",
1849 "retry",
1850 "role",
1851 "roles",
1852 "round",
1853 "rpad",
1854 "rtrim",
1855 "running",
1856 "s3",
1857 "scalar",
1858 "sec_to_time",
1859 "second",
1860 "security_lists_intersect",
1861 "semi_join",
1862 "sha",
1863 "sha1",
1864 "sha2",
1865 "shard",
1866 "sharded",
1867 "sharded_id",
1868 "sigmoid",
1869 "sign",
1870 "sin",
1871 "skip",
1872 "sleep",
1873 "snapshot",
1874 "soname",
1875 "sparse",
1876 "spatial_check_index",
1877 "split",
1878 "sqrt",
1879 "standalone",
1880 "std",
1881 "stddev",
1882 "stddev_pop",
1883 "stddev_samp",
1884 "stop",
1885 "str_to_date",
1886 "subdate",
1887 "substr",
1888 "substring_index",
1889 "success",
1890 "synchronize",
1891 "table_checksum",
1892 "tan",
1893 "task",
1894 "timediff",
1895 "time_bucket",
1896 "time_format",
1897 "time_to_sec",
1898 "timestampadd",
1899 "timestampdiff",
1900 "to_base64",
1901 "to_char",
1902 "to_date",
1903 "to_days",
1904 "to_json",
1905 "to_number",
1906 "to_seconds",
1907 "to_timestamp",
1908 "tracelogs",
1909 "transform",
1910 "trim",
1911 "trunc",
1912 "truncate",
1913 "ucase",
1914 "unhex",
1915 "unix_timestamp",
1916 "utc_date",
1917 "utc_time",
1918 "utc_timestamp",
1919 "vacuum",
1920 "variance",
1921 "var_pop",
1922 "var_samp",
1923 "vector_sub",
1924 "voting",
1925 "week",
1926 "weekday",
1927 "weekofyear",
1928 "workload",
1929 "year",
1930 ]);
1931 set.remove("all");
1933 set
1934 });
1935
1936 pub static SQLITE_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1940 [
1942 "abort",
1943 "action",
1944 "add",
1945 "after",
1946 "all",
1947 "alter",
1948 "always",
1949 "analyze",
1950 "and",
1951 "as",
1952 "asc",
1953 "attach",
1954 "autoincrement",
1955 "before",
1956 "begin",
1957 "between",
1958 "by",
1959 "cascade",
1960 "case",
1961 "cast",
1962 "check",
1963 "collate",
1964 "column",
1965 "commit",
1966 "conflict",
1967 "constraint",
1968 "create",
1969 "cross",
1970 "current",
1971 "current_date",
1972 "current_time",
1973 "current_timestamp",
1974 "database",
1975 "default",
1976 "deferrable",
1977 "deferred",
1978 "delete",
1979 "desc",
1980 "detach",
1981 "distinct",
1982 "do",
1983 "drop",
1984 "each",
1985 "else",
1986 "end",
1987 "escape",
1988 "except",
1989 "exclude",
1990 "exclusive",
1991 "exists",
1992 "explain",
1993 "fail",
1994 "filter",
1995 "first",
1996 "following",
1997 "for",
1998 "foreign",
1999 "from",
2000 "full",
2001 "generated",
2002 "glob",
2003 "group",
2004 "groups",
2005 "having",
2006 "if",
2007 "ignore",
2008 "immediate",
2009 "in",
2010 "index",
2011 "indexed",
2012 "initially",
2013 "inner",
2014 "insert",
2015 "instead",
2016 "intersect",
2017 "into",
2018 "is",
2019 "isnull",
2020 "join",
2021 "key",
2022 "last",
2023 "left",
2024 "like",
2025 "limit",
2026 "natural",
2027 "no",
2028 "not",
2029 "nothing",
2030 "notnull",
2031 "null",
2032 "nulls",
2033 "of",
2034 "offset",
2035 "on",
2036 "or",
2037 "order",
2038 "others",
2039 "outer",
2040 "partition",
2041 "plan",
2042 "pragma",
2043 "preceding",
2044 "primary",
2045 "query",
2046 "raise",
2047 "range",
2048 "recursive",
2049 "references",
2050 "regexp",
2051 "reindex",
2052 "release",
2053 "rename",
2054 "replace",
2055 "restrict",
2056 "returning",
2057 "right",
2058 "rollback",
2059 "row",
2060 "rows",
2061 "savepoint",
2062 "select",
2063 "set",
2064 "table",
2065 "temp",
2066 "temporary",
2067 "then",
2068 "ties",
2069 "to",
2070 "transaction",
2071 "trigger",
2072 "unbounded",
2073 "union",
2074 "unique",
2075 "update",
2076 "using",
2077 "vacuum",
2078 "values",
2079 "view",
2080 "virtual",
2081 "when",
2082 "where",
2083 "window",
2084 "with",
2085 "without",
2086 ]
2087 .into_iter()
2088 .collect()
2089 });
2090}
2091
2092impl Generator {
2093 pub fn new() -> Self {
2099 Self::with_config(GeneratorConfig::default())
2100 }
2101
2102 pub fn with_config(config: GeneratorConfig) -> Self {
2107 Self {
2108 config,
2109 output: String::new(),
2110 indent_level: 0,
2111 athena_hive_context: false,
2112 sqlite_inline_pk_columns: std::collections::HashSet::new(),
2113 merge_strip_qualifiers: Vec::new(),
2114 clickhouse_nullable_depth: 0,
2115 }
2116 }
2117
2118 fn add_column_aliases_to_query(expr: Expression) -> Expression {
2122 match expr {
2123 Expression::Select(mut select) => {
2124 select.expressions = select
2126 .expressions
2127 .into_iter()
2128 .map(|e| Self::add_alias_to_expression(e))
2129 .collect();
2130
2131 if let Some(ref mut from) = select.from {
2133 from.expressions = from
2134 .expressions
2135 .iter()
2136 .cloned()
2137 .map(|e| Self::add_column_aliases_to_query(e))
2138 .collect();
2139 }
2140
2141 Expression::Select(select)
2142 }
2143 Expression::Subquery(mut sq) => {
2144 sq.this = Self::add_column_aliases_to_query(sq.this);
2145 Expression::Subquery(sq)
2146 }
2147 Expression::Paren(mut p) => {
2148 p.this = Self::add_column_aliases_to_query(p.this);
2149 Expression::Paren(p)
2150 }
2151 other => other,
2153 }
2154 }
2155
2156 fn add_alias_to_expression(expr: Expression) -> Expression {
2159 use crate::expressions::Alias;
2160
2161 match &expr {
2162 Expression::Alias(_) => expr,
2164
2165 Expression::Column(col) => Expression::Alias(Box::new(Alias {
2167 this: expr.clone(),
2168 alias: col.name.clone(),
2169 column_aliases: Vec::new(),
2170 pre_alias_comments: Vec::new(),
2171 trailing_comments: Vec::new(),
2172 })),
2173
2174 Expression::Identifier(ident) => Expression::Alias(Box::new(Alias {
2176 this: expr.clone(),
2177 alias: ident.clone(),
2178 column_aliases: Vec::new(),
2179 pre_alias_comments: Vec::new(),
2180 trailing_comments: Vec::new(),
2181 })),
2182
2183 Expression::Subquery(sq) => {
2185 let processed = Self::add_column_aliases_to_query(Expression::Subquery(sq.clone()));
2186 if sq.alias.is_some() {
2188 processed
2189 } else {
2190 processed
2192 }
2193 }
2194
2195 Expression::Star(_) => expr,
2197
2198 _ => expr,
2201 }
2202 }
2203
2204 fn try_evaluate_constant(expr: &Expression) -> Option<i64> {
2208 match expr {
2209 Expression::Literal(Literal::Number(n)) => n.parse::<i64>().ok(),
2210 Expression::Add(op) => {
2211 let left = Self::try_evaluate_constant(&op.left)?;
2212 let right = Self::try_evaluate_constant(&op.right)?;
2213 Some(left + right)
2214 }
2215 Expression::Sub(op) => {
2216 let left = Self::try_evaluate_constant(&op.left)?;
2217 let right = Self::try_evaluate_constant(&op.right)?;
2218 Some(left - right)
2219 }
2220 Expression::Mul(op) => {
2221 let left = Self::try_evaluate_constant(&op.left)?;
2222 let right = Self::try_evaluate_constant(&op.right)?;
2223 Some(left * right)
2224 }
2225 Expression::Div(op) => {
2226 let left = Self::try_evaluate_constant(&op.left)?;
2227 let right = Self::try_evaluate_constant(&op.right)?;
2228 if right != 0 {
2229 Some(left / right)
2230 } else {
2231 None
2232 }
2233 }
2234 Expression::Paren(p) => Self::try_evaluate_constant(&p.this),
2235 _ => None,
2236 }
2237 }
2238
2239 fn is_reserved_keyword(&self, name: &str) -> bool {
2241 use crate::dialects::DialectType;
2242 let lower = name.to_lowercase();
2243 let lower_ref = lower.as_str();
2244
2245 match self.config.dialect {
2246 Some(DialectType::BigQuery) => reserved_keywords::BIGQUERY_RESERVED.contains(lower_ref),
2247 Some(DialectType::MySQL) | Some(DialectType::TiDB) => {
2248 reserved_keywords::MYSQL_RESERVED.contains(lower_ref)
2249 }
2250 Some(DialectType::Doris) => reserved_keywords::DORIS_RESERVED.contains(lower_ref),
2251 Some(DialectType::SingleStore) => {
2252 reserved_keywords::SINGLESTORE_RESERVED.contains(lower_ref)
2253 }
2254 Some(DialectType::StarRocks) => {
2255 reserved_keywords::STARROCKS_RESERVED.contains(lower_ref)
2256 }
2257 Some(DialectType::PostgreSQL)
2258 | Some(DialectType::CockroachDB)
2259 | Some(DialectType::Materialize)
2260 | Some(DialectType::RisingWave) => {
2261 reserved_keywords::POSTGRES_RESERVED.contains(lower_ref)
2262 }
2263 Some(DialectType::Redshift) => reserved_keywords::REDSHIFT_RESERVED.contains(lower_ref),
2264 Some(DialectType::Snowflake) => false,
2267 Some(DialectType::ClickHouse) => false,
2269 Some(DialectType::DuckDB) => reserved_keywords::DUCKDB_RESERVED.contains(lower_ref),
2270 Some(DialectType::Teradata) => false,
2272 Some(DialectType::TSQL)
2274 | Some(DialectType::Fabric)
2275 | Some(DialectType::Oracle)
2276 | Some(DialectType::Spark)
2277 | Some(DialectType::Databricks)
2278 | Some(DialectType::Hive)
2279 | Some(DialectType::Solr) => false,
2280 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
2281 reserved_keywords::PRESTO_TRINO_RESERVED.contains(lower_ref)
2282 }
2283 Some(DialectType::SQLite) => reserved_keywords::SQLITE_RESERVED.contains(lower_ref),
2284 Some(DialectType::Generic) | None => false,
2286 _ => reserved_keywords::SQL_RESERVED.contains(lower_ref),
2288 }
2289 }
2290
2291 fn normalize_func_name(&self, name: &str) -> String {
2293 match self.config.normalize_functions {
2294 NormalizeFunctions::Upper => name.to_uppercase(),
2295 NormalizeFunctions::Lower => name.to_lowercase(),
2296 NormalizeFunctions::None => name.to_string(),
2297 }
2298 }
2299
2300 pub fn generate(&mut self, expr: &Expression) -> Result<String> {
2309 self.output.clear();
2310 self.generate_expression(expr)?;
2311 Ok(std::mem::take(&mut self.output))
2312 }
2313
2314 pub fn sql(expr: &Expression) -> Result<String> {
2320 let mut gen = Generator::new();
2321 gen.generate(expr)
2322 }
2323
2324 pub fn pretty_sql(expr: &Expression) -> Result<String> {
2329 let config = GeneratorConfig {
2330 pretty: true,
2331 ..Default::default()
2332 };
2333 let mut gen = Generator::with_config(config);
2334 let mut sql = gen.generate(expr)?;
2335 if !sql.ends_with(';') {
2337 sql.push(';');
2338 }
2339 Ok(sql)
2340 }
2341
2342 fn generate_expression(&mut self, expr: &Expression) -> Result<()> {
2343 match expr {
2344 Expression::Select(select) => self.generate_select(select),
2345 Expression::Union(union) => self.generate_union(union),
2346 Expression::Intersect(intersect) => self.generate_intersect(intersect),
2347 Expression::Except(except) => self.generate_except(except),
2348 Expression::Insert(insert) => self.generate_insert(insert),
2349 Expression::Update(update) => self.generate_update(update),
2350 Expression::Delete(delete) => self.generate_delete(delete),
2351 Expression::Literal(lit) => self.generate_literal(lit),
2352 Expression::Boolean(b) => self.generate_boolean(b),
2353 Expression::Null(_) => {
2354 self.write_keyword("NULL");
2355 Ok(())
2356 }
2357 Expression::Identifier(id) => self.generate_identifier(id),
2358 Expression::Column(col) => self.generate_column(col),
2359 Expression::Pseudocolumn(pc) => self.generate_pseudocolumn(pc),
2360 Expression::Connect(c) => self.generate_connect_expr(c),
2361 Expression::Prior(p) => self.generate_prior(p),
2362 Expression::ConnectByRoot(cbr) => self.generate_connect_by_root(cbr),
2363 Expression::MatchRecognize(mr) => self.generate_match_recognize(mr),
2364 Expression::Table(table) => self.generate_table(table),
2365 Expression::StageReference(sr) => self.generate_stage_reference(sr),
2366 Expression::HistoricalData(hd) => self.generate_historical_data(hd),
2367 Expression::JoinedTable(jt) => self.generate_joined_table(jt),
2368 Expression::Star(star) => self.generate_star(star),
2369 Expression::BracedWildcard(expr) => self.generate_braced_wildcard(expr),
2370 Expression::Alias(alias) => self.generate_alias(alias),
2371 Expression::Cast(cast) => self.generate_cast(cast),
2372 Expression::Collation(coll) => self.generate_collation(coll),
2373 Expression::Case(case) => self.generate_case(case),
2374 Expression::Function(func) => self.generate_function(func),
2375 Expression::AggregateFunction(func) => self.generate_aggregate_function(func),
2376 Expression::WindowFunction(wf) => self.generate_window_function(wf),
2377 Expression::WithinGroup(wg) => self.generate_within_group(wg),
2378 Expression::Interval(interval) => self.generate_interval(interval),
2379
2380 Expression::ConcatWs(f) => self.generate_concat_ws(f),
2382 Expression::Substring(f) => self.generate_substring(f),
2383 Expression::Upper(f) => self.generate_unary_func("UPPER", f),
2384 Expression::Lower(f) => self.generate_unary_func("LOWER", f),
2385 Expression::Length(f) => self.generate_unary_func("LENGTH", f),
2386 Expression::Trim(f) => self.generate_trim(f),
2387 Expression::LTrim(f) => self.generate_simple_func("LTRIM", &f.this),
2388 Expression::RTrim(f) => self.generate_simple_func("RTRIM", &f.this),
2389 Expression::Replace(f) => self.generate_replace(f),
2390 Expression::Reverse(f) => self.generate_simple_func("REVERSE", &f.this),
2391 Expression::Left(f) => self.generate_left_right("LEFT", f),
2392 Expression::Right(f) => self.generate_left_right("RIGHT", f),
2393 Expression::Repeat(f) => self.generate_repeat(f),
2394 Expression::Lpad(f) => self.generate_pad("LPAD", f),
2395 Expression::Rpad(f) => self.generate_pad("RPAD", f),
2396 Expression::Split(f) => self.generate_split(f),
2397 Expression::RegexpLike(f) => self.generate_regexp_like(f),
2398 Expression::RegexpReplace(f) => self.generate_regexp_replace(f),
2399 Expression::RegexpExtract(f) => self.generate_regexp_extract(f),
2400 Expression::Overlay(f) => self.generate_overlay(f),
2401
2402 Expression::Abs(f) => self.generate_simple_func("ABS", &f.this),
2404 Expression::Round(f) => self.generate_round(f),
2405 Expression::Floor(f) => self.generate_floor(f),
2406 Expression::Ceil(f) => self.generate_ceil(f),
2407 Expression::Power(f) => self.generate_power(f),
2408 Expression::Sqrt(f) => self.generate_sqrt_cbrt(f, "SQRT", "|/"),
2409 Expression::Cbrt(f) => self.generate_sqrt_cbrt(f, "CBRT", "||/"),
2410 Expression::Ln(f) => self.generate_simple_func("LN", &f.this),
2411 Expression::Log(f) => self.generate_log(f),
2412 Expression::Exp(f) => self.generate_simple_func("EXP", &f.this),
2413 Expression::Sign(f) => self.generate_simple_func("SIGN", &f.this),
2414 Expression::Greatest(f) => self.generate_vararg_func("GREATEST", &f.expressions),
2415 Expression::Least(f) => self.generate_vararg_func("LEAST", &f.expressions),
2416
2417 Expression::CurrentDate(_) => {
2419 self.write_keyword("CURRENT_DATE");
2420 Ok(())
2421 }
2422 Expression::CurrentTime(f) => self.generate_current_time(f),
2423 Expression::CurrentTimestamp(f) => self.generate_current_timestamp(f),
2424 Expression::AtTimeZone(f) => self.generate_at_time_zone(f),
2425 Expression::DateAdd(f) => self.generate_date_add(f, "DATE_ADD"),
2426 Expression::DateSub(f) => self.generate_date_add(f, "DATE_SUB"),
2427 Expression::DateDiff(f) => self.generate_datediff(f),
2428 Expression::DateTrunc(f) => self.generate_date_trunc(f),
2429 Expression::Extract(f) => self.generate_extract(f),
2430 Expression::ToDate(f) => self.generate_to_date(f),
2431 Expression::ToTimestamp(f) => self.generate_to_timestamp(f),
2432
2433 Expression::Coalesce(f) => {
2435 let func_name = f.original_name.as_deref().unwrap_or("COALESCE");
2437 self.generate_vararg_func(func_name, &f.expressions)
2438 }
2439 Expression::NullIf(f) => self.generate_binary_func("NULLIF", &f.this, &f.expression),
2440 Expression::IfFunc(f) => self.generate_if_func(f),
2441 Expression::IfNull(f) => self.generate_ifnull(f),
2442 Expression::Nvl(f) => self.generate_nvl(f),
2443 Expression::Nvl2(f) => self.generate_nvl2(f),
2444
2445 Expression::TryCast(cast) => self.generate_try_cast(cast),
2447 Expression::SafeCast(cast) => self.generate_safe_cast(cast),
2448
2449 Expression::Count(f) => self.generate_count(f),
2451 Expression::Sum(f) => self.generate_agg_func("SUM", f),
2452 Expression::Avg(f) => self.generate_agg_func("AVG", f),
2453 Expression::Min(f) => self.generate_agg_func("MIN", f),
2454 Expression::Max(f) => self.generate_agg_func("MAX", f),
2455 Expression::GroupConcat(f) => self.generate_group_concat(f),
2456 Expression::StringAgg(f) => self.generate_string_agg(f),
2457 Expression::ListAgg(f) => self.generate_listagg(f),
2458 Expression::ArrayAgg(f) => {
2459 let override_name = f
2462 .name
2463 .as_ref()
2464 .filter(|n| n.to_uppercase() != "ARRAY_AGG")
2465 .map(|n| n.to_uppercase());
2466 match override_name {
2467 Some(name) => self.generate_agg_func(&name, f),
2468 None => self.generate_agg_func("ARRAY_AGG", f),
2469 }
2470 }
2471 Expression::ArrayConcatAgg(f) => self.generate_agg_func("ARRAY_CONCAT_AGG", f),
2472 Expression::CountIf(f) => self.generate_agg_func("COUNT_IF", f),
2473 Expression::SumIf(f) => self.generate_sum_if(f),
2474 Expression::Stddev(f) => self.generate_agg_func("STDDEV", f),
2475 Expression::StddevPop(f) => self.generate_agg_func("STDDEV_POP", f),
2476 Expression::StddevSamp(f) => self.generate_stddev_samp(f),
2477 Expression::Variance(f) => self.generate_agg_func("VARIANCE", f),
2478 Expression::VarPop(f) => {
2479 let name = if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
2480 "VARIANCE_POP"
2481 } else {
2482 "VAR_POP"
2483 };
2484 self.generate_agg_func(name, f)
2485 }
2486 Expression::VarSamp(f) => self.generate_agg_func("VAR_SAMP", f),
2487 Expression::Skewness(f) => {
2488 let name = match self.config.dialect {
2489 Some(DialectType::Snowflake) => "SKEW",
2490 _ => "SKEWNESS",
2491 };
2492 self.generate_agg_func(name, f)
2493 }
2494 Expression::Median(f) => self.generate_agg_func("MEDIAN", f),
2495 Expression::Mode(f) => self.generate_agg_func("MODE", f),
2496 Expression::First(f) => self.generate_agg_func("FIRST", f),
2497 Expression::Last(f) => self.generate_agg_func("LAST", f),
2498 Expression::AnyValue(f) => self.generate_agg_func("ANY_VALUE", f),
2499 Expression::ApproxDistinct(f) => {
2500 match self.config.dialect {
2501 Some(DialectType::Hive)
2502 | Some(DialectType::Spark)
2503 | Some(DialectType::Databricks)
2504 | Some(DialectType::BigQuery) => {
2505 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2507 }
2508 Some(DialectType::Redshift) => {
2509 self.write_keyword("APPROXIMATE COUNT");
2511 self.write("(");
2512 self.write_keyword("DISTINCT");
2513 self.write(" ");
2514 self.generate_expression(&f.this)?;
2515 self.write(")");
2516 Ok(())
2517 }
2518 _ => self.generate_agg_func("APPROX_DISTINCT", f),
2519 }
2520 }
2521 Expression::ApproxCountDistinct(f) => {
2522 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2523 }
2524 Expression::ApproxPercentile(f) => self.generate_approx_percentile(f),
2525 Expression::Percentile(f) => self.generate_percentile("PERCENTILE", f),
2526 Expression::LogicalAnd(f) => {
2527 let name = match self.config.dialect {
2528 Some(DialectType::Snowflake) => "BOOLAND_AGG",
2529 Some(DialectType::Spark)
2530 | Some(DialectType::Databricks)
2531 | Some(DialectType::PostgreSQL)
2532 | Some(DialectType::DuckDB)
2533 | Some(DialectType::Redshift) => "BOOL_AND",
2534 Some(DialectType::Oracle)
2535 | Some(DialectType::SQLite)
2536 | Some(DialectType::MySQL) => "MIN",
2537 _ => "BOOL_AND",
2538 };
2539 self.generate_agg_func(name, f)
2540 }
2541 Expression::LogicalOr(f) => {
2542 let name = match self.config.dialect {
2543 Some(DialectType::Snowflake) => "BOOLOR_AGG",
2544 Some(DialectType::Spark)
2545 | Some(DialectType::Databricks)
2546 | Some(DialectType::PostgreSQL)
2547 | Some(DialectType::DuckDB)
2548 | Some(DialectType::Redshift) => "BOOL_OR",
2549 Some(DialectType::Oracle)
2550 | Some(DialectType::SQLite)
2551 | Some(DialectType::MySQL) => "MAX",
2552 _ => "BOOL_OR",
2553 };
2554 self.generate_agg_func(name, f)
2555 }
2556
2557 Expression::RowNumber(_) => {
2559 if self.config.dialect == Some(DialectType::ClickHouse) {
2560 self.write("row_number");
2561 } else {
2562 self.write_keyword("ROW_NUMBER");
2563 }
2564 self.write("()");
2565 Ok(())
2566 }
2567 Expression::Rank(r) => {
2568 self.write_keyword("RANK");
2569 self.write("(");
2570 if !r.args.is_empty() {
2572 for (i, arg) in r.args.iter().enumerate() {
2573 if i > 0 {
2574 self.write(", ");
2575 }
2576 self.generate_expression(arg)?;
2577 }
2578 } else if let Some(order_by) = &r.order_by {
2579 self.write_keyword(" ORDER BY ");
2581 for (i, ob) in order_by.iter().enumerate() {
2582 if i > 0 {
2583 self.write(", ");
2584 }
2585 self.generate_ordered(ob)?;
2586 }
2587 }
2588 self.write(")");
2589 Ok(())
2590 }
2591 Expression::DenseRank(dr) => {
2592 self.write_keyword("DENSE_RANK");
2593 self.write("(");
2594 for (i, arg) in dr.args.iter().enumerate() {
2596 if i > 0 {
2597 self.write(", ");
2598 }
2599 self.generate_expression(arg)?;
2600 }
2601 self.write(")");
2602 Ok(())
2603 }
2604 Expression::NTile(f) => self.generate_ntile(f),
2605 Expression::Lead(f) => self.generate_lead_lag("LEAD", f),
2606 Expression::Lag(f) => self.generate_lead_lag("LAG", f),
2607 Expression::FirstValue(f) => self.generate_value_func("FIRST_VALUE", f),
2608 Expression::LastValue(f) => self.generate_value_func("LAST_VALUE", f),
2609 Expression::NthValue(f) => self.generate_nth_value(f),
2610 Expression::PercentRank(pr) => {
2611 self.write_keyword("PERCENT_RANK");
2612 self.write("(");
2613 if !pr.args.is_empty() {
2615 for (i, arg) in pr.args.iter().enumerate() {
2616 if i > 0 {
2617 self.write(", ");
2618 }
2619 self.generate_expression(arg)?;
2620 }
2621 } else if let Some(order_by) = &pr.order_by {
2622 self.write_keyword(" ORDER BY ");
2624 for (i, ob) in order_by.iter().enumerate() {
2625 if i > 0 {
2626 self.write(", ");
2627 }
2628 self.generate_ordered(ob)?;
2629 }
2630 }
2631 self.write(")");
2632 Ok(())
2633 }
2634 Expression::CumeDist(cd) => {
2635 self.write_keyword("CUME_DIST");
2636 self.write("(");
2637 if !cd.args.is_empty() {
2639 for (i, arg) in cd.args.iter().enumerate() {
2640 if i > 0 {
2641 self.write(", ");
2642 }
2643 self.generate_expression(arg)?;
2644 }
2645 } else if let Some(order_by) = &cd.order_by {
2646 self.write_keyword(" ORDER BY ");
2648 for (i, ob) in order_by.iter().enumerate() {
2649 if i > 0 {
2650 self.write(", ");
2651 }
2652 self.generate_ordered(ob)?;
2653 }
2654 }
2655 self.write(")");
2656 Ok(())
2657 }
2658 Expression::PercentileCont(f) => self.generate_percentile("PERCENTILE_CONT", f),
2659 Expression::PercentileDisc(f) => self.generate_percentile("PERCENTILE_DISC", f),
2660
2661 Expression::Contains(f) => {
2663 self.generate_binary_func("CONTAINS", &f.this, &f.expression)
2664 }
2665 Expression::StartsWith(f) => {
2666 let name = match self.config.dialect {
2667 Some(DialectType::Spark) | Some(DialectType::Databricks) => "STARTSWITH",
2668 _ => "STARTS_WITH",
2669 };
2670 self.generate_binary_func(name, &f.this, &f.expression)
2671 }
2672 Expression::EndsWith(f) => {
2673 let name = match self.config.dialect {
2674 Some(DialectType::Snowflake) => "ENDSWITH",
2675 Some(DialectType::Spark) | Some(DialectType::Databricks) => "ENDSWITH",
2676 Some(DialectType::ClickHouse) => "endsWith",
2677 _ => "ENDS_WITH",
2678 };
2679 self.generate_binary_func(name, &f.this, &f.expression)
2680 }
2681 Expression::Position(f) => self.generate_position(f),
2682 Expression::Initcap(f) => match self.config.dialect {
2683 Some(DialectType::Presto)
2684 | Some(DialectType::Trino)
2685 | Some(DialectType::Athena) => {
2686 self.write_keyword("REGEXP_REPLACE");
2687 self.write("(");
2688 self.generate_expression(&f.this)?;
2689 self.write(", '(\\w)(\\w*)', x -> UPPER(x[1]) || LOWER(x[2]))");
2690 Ok(())
2691 }
2692 _ => self.generate_simple_func("INITCAP", &f.this),
2693 },
2694 Expression::Ascii(f) => self.generate_simple_func("ASCII", &f.this),
2695 Expression::Chr(f) => self.generate_simple_func("CHR", &f.this),
2696 Expression::CharFunc(f) => self.generate_char_func(f),
2697 Expression::Soundex(f) => self.generate_simple_func("SOUNDEX", &f.this),
2698 Expression::Levenshtein(f) => {
2699 self.generate_binary_func("LEVENSHTEIN", &f.this, &f.expression)
2700 }
2701
2702 Expression::ModFunc(f) => self.generate_mod_func(f),
2704 Expression::Random(_) => {
2705 self.write_keyword("RANDOM");
2706 self.write("()");
2707 Ok(())
2708 }
2709 Expression::Rand(f) => self.generate_rand(f),
2710 Expression::TruncFunc(f) => self.generate_truncate_func(f),
2711 Expression::Pi(_) => {
2712 self.write_keyword("PI");
2713 self.write("()");
2714 Ok(())
2715 }
2716 Expression::Radians(f) => self.generate_simple_func("RADIANS", &f.this),
2717 Expression::Degrees(f) => self.generate_simple_func("DEGREES", &f.this),
2718 Expression::Sin(f) => self.generate_simple_func("SIN", &f.this),
2719 Expression::Cos(f) => self.generate_simple_func("COS", &f.this),
2720 Expression::Tan(f) => self.generate_simple_func("TAN", &f.this),
2721 Expression::Asin(f) => self.generate_simple_func("ASIN", &f.this),
2722 Expression::Acos(f) => self.generate_simple_func("ACOS", &f.this),
2723 Expression::Atan(f) => self.generate_simple_func("ATAN", &f.this),
2724 Expression::Atan2(f) => {
2725 let name = f.original_name.as_deref().unwrap_or("ATAN2");
2726 self.generate_binary_func(name, &f.this, &f.expression)
2727 }
2728
2729 Expression::Decode(f) => self.generate_decode(f),
2731
2732 Expression::DateFormat(f) => self.generate_date_format("DATE_FORMAT", f),
2734 Expression::FormatDate(f) => self.generate_date_format("FORMAT_DATE", f),
2735 Expression::Year(f) => self.generate_simple_func("YEAR", &f.this),
2736 Expression::Month(f) => self.generate_simple_func("MONTH", &f.this),
2737 Expression::Day(f) => self.generate_simple_func("DAY", &f.this),
2738 Expression::Hour(f) => self.generate_simple_func("HOUR", &f.this),
2739 Expression::Minute(f) => self.generate_simple_func("MINUTE", &f.this),
2740 Expression::Second(f) => self.generate_simple_func("SECOND", &f.this),
2741 Expression::DayOfWeek(f) => {
2742 let name = match self.config.dialect {
2743 Some(DialectType::Presto)
2744 | Some(DialectType::Trino)
2745 | Some(DialectType::Athena) => "DAY_OF_WEEK",
2746 Some(DialectType::DuckDB) => "ISODOW",
2747 _ => "DAYOFWEEK",
2748 };
2749 self.generate_simple_func(name, &f.this)
2750 }
2751 Expression::DayOfMonth(f) => {
2752 let name = match self.config.dialect {
2753 Some(DialectType::Presto)
2754 | Some(DialectType::Trino)
2755 | Some(DialectType::Athena) => "DAY_OF_MONTH",
2756 _ => "DAYOFMONTH",
2757 };
2758 self.generate_simple_func(name, &f.this)
2759 }
2760 Expression::DayOfYear(f) => {
2761 let name = match self.config.dialect {
2762 Some(DialectType::Presto)
2763 | Some(DialectType::Trino)
2764 | Some(DialectType::Athena) => "DAY_OF_YEAR",
2765 _ => "DAYOFYEAR",
2766 };
2767 self.generate_simple_func(name, &f.this)
2768 }
2769 Expression::WeekOfYear(f) => {
2770 let name = match self.config.dialect {
2772 Some(DialectType::Hive)
2773 | Some(DialectType::DuckDB)
2774 | Some(DialectType::Spark)
2775 | Some(DialectType::Databricks)
2776 | Some(DialectType::MySQL) => "WEEKOFYEAR",
2777 _ => "WEEK_OF_YEAR",
2778 };
2779 self.generate_simple_func(name, &f.this)
2780 }
2781 Expression::Quarter(f) => self.generate_simple_func("QUARTER", &f.this),
2782 Expression::AddMonths(f) => {
2783 self.generate_binary_func("ADD_MONTHS", &f.this, &f.expression)
2784 }
2785 Expression::MonthsBetween(f) => {
2786 self.generate_binary_func("MONTHS_BETWEEN", &f.this, &f.expression)
2787 }
2788 Expression::LastDay(f) => self.generate_last_day(f),
2789 Expression::NextDay(f) => self.generate_binary_func("NEXT_DAY", &f.this, &f.expression),
2790 Expression::Epoch(f) => self.generate_simple_func("EPOCH", &f.this),
2791 Expression::EpochMs(f) => self.generate_simple_func("EPOCH_MS", &f.this),
2792 Expression::FromUnixtime(f) => self.generate_from_unixtime(f),
2793 Expression::UnixTimestamp(f) => self.generate_unix_timestamp(f),
2794 Expression::MakeDate(f) => self.generate_make_date(f),
2795 Expression::MakeTimestamp(f) => self.generate_make_timestamp(f),
2796 Expression::TimestampTrunc(f) => self.generate_date_trunc(f),
2797
2798 Expression::ArrayFunc(f) => self.generate_array_constructor(f),
2800 Expression::ArrayLength(f) => self.generate_simple_func("ARRAY_LENGTH", &f.this),
2801 Expression::ArraySize(f) => self.generate_simple_func("ARRAY_SIZE", &f.this),
2802 Expression::Cardinality(f) => self.generate_simple_func("CARDINALITY", &f.this),
2803 Expression::ArrayContains(f) => {
2804 self.generate_binary_func("ARRAY_CONTAINS", &f.this, &f.expression)
2805 }
2806 Expression::ArrayPosition(f) => {
2807 self.generate_binary_func("ARRAY_POSITION", &f.this, &f.expression)
2808 }
2809 Expression::ArrayAppend(f) => {
2810 self.generate_binary_func("ARRAY_APPEND", &f.this, &f.expression)
2811 }
2812 Expression::ArrayPrepend(f) => {
2813 self.generate_binary_func("ARRAY_PREPEND", &f.this, &f.expression)
2814 }
2815 Expression::ArrayConcat(f) => self.generate_vararg_func("ARRAY_CONCAT", &f.expressions),
2816 Expression::ArraySort(f) => self.generate_array_sort(f),
2817 Expression::ArrayReverse(f) => self.generate_simple_func("ARRAY_REVERSE", &f.this),
2818 Expression::ArrayDistinct(f) => self.generate_simple_func("ARRAY_DISTINCT", &f.this),
2819 Expression::ArrayJoin(f) => self.generate_array_join("ARRAY_JOIN", f),
2820 Expression::ArrayToString(f) => self.generate_array_join("ARRAY_TO_STRING", f),
2821 Expression::Unnest(f) => self.generate_unnest(f),
2822 Expression::Explode(f) => self.generate_simple_func("EXPLODE", &f.this),
2823 Expression::ExplodeOuter(f) => self.generate_simple_func("EXPLODE_OUTER", &f.this),
2824 Expression::ArrayFilter(f) => self.generate_array_filter(f),
2825 Expression::ArrayTransform(f) => self.generate_array_transform(f),
2826 Expression::ArrayFlatten(f) => self.generate_simple_func("FLATTEN", &f.this),
2827 Expression::ArrayCompact(f) => {
2828 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
2829 self.write("LIST_FILTER(");
2831 self.generate_expression(&f.this)?;
2832 self.write(", _u -> NOT _u IS NULL)");
2833 Ok(())
2834 } else {
2835 self.generate_simple_func("ARRAY_COMPACT", &f.this)
2836 }
2837 }
2838 Expression::ArrayIntersect(f) => {
2839 let func_name = f.original_name.as_deref().unwrap_or("ARRAY_INTERSECT");
2840 self.generate_vararg_func(func_name, &f.expressions)
2841 }
2842 Expression::ArrayUnion(f) => {
2843 self.generate_binary_func("ARRAY_UNION", &f.this, &f.expression)
2844 }
2845 Expression::ArrayExcept(f) => {
2846 self.generate_binary_func("ARRAY_EXCEPT", &f.this, &f.expression)
2847 }
2848 Expression::ArrayRemove(f) => {
2849 self.generate_binary_func("ARRAY_REMOVE", &f.this, &f.expression)
2850 }
2851 Expression::ArrayZip(f) => self.generate_vararg_func("ARRAYS_ZIP", &f.expressions),
2852 Expression::Sequence(f) => self.generate_sequence("SEQUENCE", f),
2853 Expression::Generate(f) => self.generate_sequence("GENERATE_SERIES", f),
2854
2855 Expression::StructFunc(f) => self.generate_struct_constructor(f),
2857 Expression::StructExtract(f) => self.generate_struct_extract(f),
2858 Expression::NamedStruct(f) => self.generate_named_struct(f),
2859
2860 Expression::MapFunc(f) => self.generate_map_constructor(f),
2862 Expression::MapFromEntries(f) => self.generate_simple_func("MAP_FROM_ENTRIES", &f.this),
2863 Expression::MapFromArrays(f) => {
2864 self.generate_binary_func("MAP_FROM_ARRAYS", &f.this, &f.expression)
2865 }
2866 Expression::MapKeys(f) => self.generate_simple_func("MAP_KEYS", &f.this),
2867 Expression::MapValues(f) => self.generate_simple_func("MAP_VALUES", &f.this),
2868 Expression::MapContainsKey(f) => {
2869 self.generate_binary_func("MAP_CONTAINS_KEY", &f.this, &f.expression)
2870 }
2871 Expression::MapConcat(f) => self.generate_vararg_func("MAP_CONCAT", &f.expressions),
2872 Expression::ElementAt(f) => {
2873 self.generate_binary_func("ELEMENT_AT", &f.this, &f.expression)
2874 }
2875 Expression::TransformKeys(f) => self.generate_transform_func("TRANSFORM_KEYS", f),
2876 Expression::TransformValues(f) => self.generate_transform_func("TRANSFORM_VALUES", f),
2877
2878 Expression::JsonExtract(f) => self.generate_json_extract("JSON_EXTRACT", f),
2880 Expression::JsonExtractScalar(f) => {
2881 self.generate_json_extract("JSON_EXTRACT_SCALAR", f)
2882 }
2883 Expression::JsonExtractPath(f) => self.generate_json_path("JSON_EXTRACT_PATH", f),
2884 Expression::JsonArray(f) => self.generate_vararg_func("JSON_ARRAY", &f.expressions),
2885 Expression::JsonObject(f) => self.generate_json_object(f),
2886 Expression::JsonQuery(f) => self.generate_json_extract("JSON_QUERY", f),
2887 Expression::JsonValue(f) => self.generate_json_extract("JSON_VALUE", f),
2888 Expression::JsonArrayLength(f) => {
2889 self.generate_simple_func("JSON_ARRAY_LENGTH", &f.this)
2890 }
2891 Expression::JsonKeys(f) => self.generate_simple_func("JSON_KEYS", &f.this),
2892 Expression::JsonType(f) => self.generate_simple_func("JSON_TYPE", &f.this),
2893 Expression::ParseJson(f) => {
2894 let name = match self.config.dialect {
2895 Some(DialectType::Presto)
2896 | Some(DialectType::Trino)
2897 | Some(DialectType::Athena) => "JSON_PARSE",
2898 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
2899 self.write_keyword("CAST");
2901 self.write("(");
2902 self.generate_expression(&f.this)?;
2903 self.write_keyword(" AS ");
2904 self.write_keyword("JSON");
2905 self.write(")");
2906 return Ok(());
2907 }
2908 Some(DialectType::Hive)
2909 | Some(DialectType::Spark)
2910 | Some(DialectType::MySQL)
2911 | Some(DialectType::SingleStore)
2912 | Some(DialectType::TiDB)
2913 | Some(DialectType::TSQL) => {
2914 self.generate_expression(&f.this)?;
2916 return Ok(());
2917 }
2918 Some(DialectType::DuckDB) => "JSON",
2919 _ => "PARSE_JSON",
2920 };
2921 self.generate_simple_func(name, &f.this)
2922 }
2923 Expression::ToJson(f) => self.generate_simple_func("TO_JSON", &f.this),
2924 Expression::JsonSet(f) => self.generate_json_modify("JSON_SET", f),
2925 Expression::JsonInsert(f) => self.generate_json_modify("JSON_INSERT", f),
2926 Expression::JsonRemove(f) => self.generate_json_path("JSON_REMOVE", f),
2927 Expression::JsonMergePatch(f) => {
2928 self.generate_binary_func("JSON_MERGE_PATCH", &f.this, &f.expression)
2929 }
2930 Expression::JsonArrayAgg(f) => self.generate_json_array_agg(f),
2931 Expression::JsonObjectAgg(f) => self.generate_json_object_agg(f),
2932
2933 Expression::Convert(f) => self.generate_convert(f),
2935 Expression::Typeof(f) => self.generate_simple_func("TYPEOF", &f.this),
2936
2937 Expression::Lambda(f) => self.generate_lambda(f),
2939 Expression::Parameter(f) => self.generate_parameter(f),
2940 Expression::Placeholder(f) => self.generate_placeholder(f),
2941 Expression::NamedArgument(f) => self.generate_named_argument(f),
2942 Expression::TableArgument(f) => self.generate_table_argument(f),
2943 Expression::SqlComment(f) => self.generate_sql_comment(f),
2944
2945 Expression::NullSafeEq(op) => self.generate_null_safe_eq(op),
2947 Expression::NullSafeNeq(op) => self.generate_null_safe_neq(op),
2948 Expression::Glob(op) => self.generate_binary_op(op, "GLOB"),
2949 Expression::SimilarTo(f) => self.generate_similar_to(f),
2950 Expression::Any(f) => self.generate_quantified("ANY", f),
2951 Expression::All(f) => self.generate_quantified("ALL", f),
2952 Expression::Overlaps(f) => self.generate_overlaps(f),
2953
2954 Expression::BitwiseLeftShift(op) => {
2956 if matches!(
2957 self.config.dialect,
2958 Some(DialectType::Presto) | Some(DialectType::Trino)
2959 ) {
2960 self.write_keyword("BITWISE_ARITHMETIC_SHIFT_LEFT");
2961 self.write("(");
2962 self.generate_expression(&op.left)?;
2963 self.write(", ");
2964 self.generate_expression(&op.right)?;
2965 self.write(")");
2966 Ok(())
2967 } else if matches!(
2968 self.config.dialect,
2969 Some(DialectType::Spark) | Some(DialectType::Databricks)
2970 ) {
2971 self.write_keyword("SHIFTLEFT");
2972 self.write("(");
2973 self.generate_expression(&op.left)?;
2974 self.write(", ");
2975 self.generate_expression(&op.right)?;
2976 self.write(")");
2977 Ok(())
2978 } else {
2979 self.generate_binary_op(op, "<<")
2980 }
2981 }
2982 Expression::BitwiseRightShift(op) => {
2983 if matches!(
2984 self.config.dialect,
2985 Some(DialectType::Presto) | Some(DialectType::Trino)
2986 ) {
2987 self.write_keyword("BITWISE_ARITHMETIC_SHIFT_RIGHT");
2988 self.write("(");
2989 self.generate_expression(&op.left)?;
2990 self.write(", ");
2991 self.generate_expression(&op.right)?;
2992 self.write(")");
2993 Ok(())
2994 } else if matches!(
2995 self.config.dialect,
2996 Some(DialectType::Spark) | Some(DialectType::Databricks)
2997 ) {
2998 self.write_keyword("SHIFTRIGHT");
2999 self.write("(");
3000 self.generate_expression(&op.left)?;
3001 self.write(", ");
3002 self.generate_expression(&op.right)?;
3003 self.write(")");
3004 Ok(())
3005 } else {
3006 self.generate_binary_op(op, ">>")
3007 }
3008 }
3009 Expression::BitwiseAndAgg(f) => self.generate_agg_func("BIT_AND", f),
3010 Expression::BitwiseOrAgg(f) => self.generate_agg_func("BIT_OR", f),
3011 Expression::BitwiseXorAgg(f) => self.generate_agg_func("BIT_XOR", f),
3012
3013 Expression::Subscript(s) => self.generate_subscript(s),
3015 Expression::Dot(d) => self.generate_dot_access(d),
3016 Expression::MethodCall(m) => self.generate_method_call(m),
3017 Expression::ArraySlice(s) => self.generate_array_slice(s),
3018
3019 Expression::And(op) => self.generate_connector_op(op, ConnectorOperator::And),
3020 Expression::Or(op) => self.generate_connector_op(op, ConnectorOperator::Or),
3021 Expression::Add(op) => self.generate_binary_op(op, "+"),
3022 Expression::Sub(op) => self.generate_binary_op(op, "-"),
3023 Expression::Mul(op) => self.generate_binary_op(op, "*"),
3024 Expression::Div(op) => self.generate_binary_op(op, "/"),
3025 Expression::IntDiv(f) => {
3026 use crate::dialects::DialectType;
3027 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
3028 self.generate_expression(&f.this)?;
3030 self.write(" // ");
3031 self.generate_expression(&f.expression)?;
3032 Ok(())
3033 } else if matches!(
3034 self.config.dialect,
3035 Some(DialectType::Hive | DialectType::Spark | DialectType::Databricks)
3036 ) {
3037 self.generate_expression(&f.this)?;
3039 self.write(" ");
3040 self.write_keyword("DIV");
3041 self.write(" ");
3042 self.generate_expression(&f.expression)?;
3043 Ok(())
3044 } else {
3045 self.write_keyword("DIV");
3047 self.write("(");
3048 self.generate_expression(&f.this)?;
3049 self.write(", ");
3050 self.generate_expression(&f.expression)?;
3051 self.write(")");
3052 Ok(())
3053 }
3054 }
3055 Expression::Mod(op) => {
3056 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
3057 self.generate_binary_op(op, "MOD")
3058 } else {
3059 self.generate_binary_op(op, "%")
3060 }
3061 }
3062 Expression::Eq(op) => self.generate_binary_op(op, "="),
3063 Expression::Neq(op) => self.generate_binary_op(op, "<>"),
3064 Expression::Lt(op) => self.generate_binary_op(op, "<"),
3065 Expression::Lte(op) => self.generate_binary_op(op, "<="),
3066 Expression::Gt(op) => self.generate_binary_op(op, ">"),
3067 Expression::Gte(op) => self.generate_binary_op(op, ">="),
3068 Expression::Like(op) => self.generate_like_op(op, "LIKE"),
3069 Expression::ILike(op) => self.generate_like_op(op, "ILIKE"),
3070 Expression::Match(op) => self.generate_binary_op(op, "MATCH"),
3071 Expression::Concat(op) => {
3072 if self.config.dialect == Some(DialectType::Solr) {
3074 self.generate_binary_op(op, "OR")
3075 } else {
3076 self.generate_binary_op(op, "||")
3077 }
3078 }
3079 Expression::BitwiseAnd(op) => {
3080 if matches!(
3082 self.config.dialect,
3083 Some(DialectType::Presto) | Some(DialectType::Trino)
3084 ) {
3085 self.write_keyword("BITWISE_AND");
3086 self.write("(");
3087 self.generate_expression(&op.left)?;
3088 self.write(", ");
3089 self.generate_expression(&op.right)?;
3090 self.write(")");
3091 Ok(())
3092 } else {
3093 self.generate_binary_op(op, "&")
3094 }
3095 }
3096 Expression::BitwiseOr(op) => {
3097 if matches!(
3099 self.config.dialect,
3100 Some(DialectType::Presto) | Some(DialectType::Trino)
3101 ) {
3102 self.write_keyword("BITWISE_OR");
3103 self.write("(");
3104 self.generate_expression(&op.left)?;
3105 self.write(", ");
3106 self.generate_expression(&op.right)?;
3107 self.write(")");
3108 Ok(())
3109 } else {
3110 self.generate_binary_op(op, "|")
3111 }
3112 }
3113 Expression::BitwiseXor(op) => {
3114 if matches!(
3116 self.config.dialect,
3117 Some(DialectType::Presto) | Some(DialectType::Trino)
3118 ) {
3119 self.write_keyword("BITWISE_XOR");
3120 self.write("(");
3121 self.generate_expression(&op.left)?;
3122 self.write(", ");
3123 self.generate_expression(&op.right)?;
3124 self.write(")");
3125 Ok(())
3126 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
3127 self.generate_binary_op(op, "#")
3128 } else {
3129 self.generate_binary_op(op, "^")
3130 }
3131 }
3132 Expression::Adjacent(op) => self.generate_binary_op(op, "-|-"),
3133 Expression::TsMatch(op) => self.generate_binary_op(op, "@@"),
3134 Expression::PropertyEQ(op) => self.generate_binary_op(op, ":="),
3135 Expression::ArrayContainsAll(op) => self.generate_binary_op(op, "@>"),
3136 Expression::ArrayContainedBy(op) => self.generate_binary_op(op, "<@"),
3137 Expression::ArrayOverlaps(op) => self.generate_binary_op(op, "&&"),
3138 Expression::JSONBContainsAllTopKeys(op) => self.generate_binary_op(op, "?&"),
3139 Expression::JSONBContainsAnyTopKeys(op) => self.generate_binary_op(op, "?|"),
3140 Expression::JSONBContains(f) => {
3141 self.generate_expression(&f.this)?;
3143 self.write_space();
3144 self.write("?");
3145 self.write_space();
3146 self.generate_expression(&f.expression)
3147 }
3148 Expression::JSONBDeleteAtPath(op) => self.generate_binary_op(op, "#-"),
3149 Expression::ExtendsLeft(op) => self.generate_binary_op(op, "&<"),
3150 Expression::ExtendsRight(op) => self.generate_binary_op(op, "&>"),
3151 Expression::Not(op) => self.generate_unary_op(op, "NOT"),
3152 Expression::Neg(op) => self.generate_unary_op(op, "-"),
3153 Expression::BitwiseNot(op) => {
3154 if matches!(
3156 self.config.dialect,
3157 Some(DialectType::Presto) | Some(DialectType::Trino)
3158 ) {
3159 self.write_keyword("BITWISE_NOT");
3160 self.write("(");
3161 self.generate_expression(&op.this)?;
3162 self.write(")");
3163 Ok(())
3164 } else {
3165 self.generate_unary_op(op, "~")
3166 }
3167 }
3168 Expression::In(in_expr) => self.generate_in(in_expr),
3169 Expression::Between(between) => self.generate_between(between),
3170 Expression::IsNull(is_null) => self.generate_is_null(is_null),
3171 Expression::IsTrue(is_true) => self.generate_is_true(is_true),
3172 Expression::IsFalse(is_false) => self.generate_is_false(is_false),
3173 Expression::IsJson(is_json) => self.generate_is_json(is_json),
3174 Expression::Is(is_expr) => self.generate_is(is_expr),
3175 Expression::Exists(exists) => self.generate_exists(exists),
3176 Expression::MemberOf(member_of) => self.generate_member_of(member_of),
3177 Expression::Subquery(subquery) => self.generate_subquery(subquery),
3178 Expression::Paren(paren) => {
3179 let skip_parens = matches!(&paren.this, Expression::JoinedTable(_));
3181
3182 if !skip_parens {
3183 self.write("(");
3184 if self.config.pretty {
3185 self.write_newline();
3186 self.indent_level += 1;
3187 self.write_indent();
3188 }
3189 }
3190 self.generate_expression(&paren.this)?;
3191 if !skip_parens {
3192 if self.config.pretty {
3193 self.write_newline();
3194 self.indent_level -= 1;
3195 self.write_indent();
3196 }
3197 self.write(")");
3198 }
3199 for comment in &paren.trailing_comments {
3201 self.write(" ");
3202 self.write_formatted_comment(comment);
3203 }
3204 Ok(())
3205 }
3206 Expression::Array(arr) => self.generate_array(arr),
3207 Expression::Tuple(tuple) => self.generate_tuple(tuple),
3208 Expression::PipeOperator(pipe) => self.generate_pipe_operator(pipe),
3209 Expression::Ordered(ordered) => self.generate_ordered(ordered),
3210 Expression::DataType(dt) => self.generate_data_type(dt),
3211 Expression::Raw(raw) => {
3212 self.write(&raw.sql);
3213 Ok(())
3214 }
3215 Expression::Command(cmd) => {
3216 self.write(&cmd.this);
3217 Ok(())
3218 }
3219 Expression::Kill(kill) => {
3220 self.write_keyword("KILL");
3221 if let Some(kind) = &kill.kind {
3222 self.write_space();
3223 self.write_keyword(kind);
3224 }
3225 self.write_space();
3226 self.generate_expression(&kill.this)?;
3227 Ok(())
3228 }
3229 Expression::Execute(exec) => {
3230 self.write_keyword("EXEC");
3231 self.write_space();
3232 self.generate_expression(&exec.this)?;
3233 for (i, param) in exec.parameters.iter().enumerate() {
3234 if i == 0 {
3235 self.write_space();
3236 } else {
3237 self.write(", ");
3238 }
3239 self.write(¶m.name);
3240 self.write("=");
3241 self.generate_expression(¶m.value)?;
3242 }
3243 Ok(())
3244 }
3245 Expression::Annotated(annotated) => {
3246 self.generate_expression(&annotated.this)?;
3247 for comment in &annotated.trailing_comments {
3248 self.write(" ");
3249 self.write_formatted_comment(comment);
3250 }
3251 Ok(())
3252 }
3253
3254 Expression::CreateTable(ct) => self.generate_create_table(ct),
3256 Expression::DropTable(dt) => self.generate_drop_table(dt),
3257 Expression::AlterTable(at) => self.generate_alter_table(at),
3258 Expression::CreateIndex(ci) => self.generate_create_index(ci),
3259 Expression::DropIndex(di) => self.generate_drop_index(di),
3260 Expression::CreateView(cv) => self.generate_create_view(cv),
3261 Expression::DropView(dv) => self.generate_drop_view(dv),
3262 Expression::AlterView(av) => self.generate_alter_view(av),
3263 Expression::AlterIndex(ai) => self.generate_alter_index(ai),
3264 Expression::Truncate(tr) => self.generate_truncate(tr),
3265 Expression::Use(u) => self.generate_use(u),
3266 Expression::CreateSchema(cs) => self.generate_create_schema(cs),
3268 Expression::DropSchema(ds) => self.generate_drop_schema(ds),
3269 Expression::DropNamespace(dn) => self.generate_drop_namespace(dn),
3270 Expression::CreateDatabase(cd) => self.generate_create_database(cd),
3271 Expression::DropDatabase(dd) => self.generate_drop_database(dd),
3272 Expression::CreateFunction(cf) => self.generate_create_function(cf),
3273 Expression::DropFunction(df) => self.generate_drop_function(df),
3274 Expression::CreateProcedure(cp) => self.generate_create_procedure(cp),
3275 Expression::DropProcedure(dp) => self.generate_drop_procedure(dp),
3276 Expression::CreateSequence(cs) => self.generate_create_sequence(cs),
3277 Expression::DropSequence(ds) => self.generate_drop_sequence(ds),
3278 Expression::AlterSequence(als) => self.generate_alter_sequence(als),
3279 Expression::CreateTrigger(ct) => self.generate_create_trigger(ct),
3280 Expression::DropTrigger(dt) => self.generate_drop_trigger(dt),
3281 Expression::CreateType(ct) => self.generate_create_type(ct),
3282 Expression::DropType(dt) => self.generate_drop_type(dt),
3283 Expression::Describe(d) => self.generate_describe(d),
3284 Expression::Show(s) => self.generate_show(s),
3285
3286 Expression::Cache(c) => self.generate_cache(c),
3288 Expression::Uncache(u) => self.generate_uncache(u),
3289 Expression::LoadData(l) => self.generate_load_data(l),
3290 Expression::Pragma(p) => self.generate_pragma(p),
3291 Expression::Grant(g) => self.generate_grant(g),
3292 Expression::Revoke(r) => self.generate_revoke(r),
3293 Expression::Comment(c) => self.generate_comment(c),
3294 Expression::SetStatement(s) => self.generate_set_statement(s),
3295
3296 Expression::Pivot(pivot) => self.generate_pivot(pivot),
3298 Expression::Unpivot(unpivot) => self.generate_unpivot(unpivot),
3299
3300 Expression::Values(values) => self.generate_values(values),
3302
3303 Expression::AIAgg(e) => self.generate_ai_agg(e),
3305 Expression::AIClassify(e) => self.generate_ai_classify(e),
3306 Expression::AddPartition(e) => self.generate_add_partition(e),
3307 Expression::AlgorithmProperty(e) => self.generate_algorithm_property(e),
3308 Expression::Aliases(e) => self.generate_aliases(e),
3309 Expression::AllowedValuesProperty(e) => self.generate_allowed_values_property(e),
3310 Expression::AlterColumn(e) => self.generate_alter_column(e),
3311 Expression::AlterSession(e) => self.generate_alter_session(e),
3312 Expression::AlterSet(e) => self.generate_alter_set(e),
3313 Expression::AlterSortKey(e) => self.generate_alter_sort_key(e),
3314 Expression::Analyze(e) => self.generate_analyze(e),
3315 Expression::AnalyzeDelete(e) => self.generate_analyze_delete(e),
3316 Expression::AnalyzeHistogram(e) => self.generate_analyze_histogram(e),
3317 Expression::AnalyzeListChainedRows(e) => self.generate_analyze_list_chained_rows(e),
3318 Expression::AnalyzeSample(e) => self.generate_analyze_sample(e),
3319 Expression::AnalyzeStatistics(e) => self.generate_analyze_statistics(e),
3320 Expression::AnalyzeValidate(e) => self.generate_analyze_validate(e),
3321 Expression::AnalyzeWith(e) => self.generate_analyze_with(e),
3322 Expression::Anonymous(e) => self.generate_anonymous(e),
3323 Expression::AnonymousAggFunc(e) => self.generate_anonymous_agg_func(e),
3324 Expression::Apply(e) => self.generate_apply(e),
3325 Expression::ApproxPercentileEstimate(e) => self.generate_approx_percentile_estimate(e),
3326 Expression::ApproxQuantile(e) => self.generate_approx_quantile(e),
3327 Expression::ApproxQuantiles(e) => self.generate_approx_quantiles(e),
3328 Expression::ApproxTopK(e) => self.generate_approx_top_k(e),
3329 Expression::ApproxTopKAccumulate(e) => self.generate_approx_top_k_accumulate(e),
3330 Expression::ApproxTopKCombine(e) => self.generate_approx_top_k_combine(e),
3331 Expression::ApproxTopKEstimate(e) => self.generate_approx_top_k_estimate(e),
3332 Expression::ApproxTopSum(e) => self.generate_approx_top_sum(e),
3333 Expression::ArgMax(e) => self.generate_arg_max(e),
3334 Expression::ArgMin(e) => self.generate_arg_min(e),
3335 Expression::ArrayAll(e) => self.generate_array_all(e),
3336 Expression::ArrayAny(e) => self.generate_array_any(e),
3337 Expression::ArrayConstructCompact(e) => self.generate_array_construct_compact(e),
3338 Expression::ArraySum(e) => self.generate_array_sum(e),
3339 Expression::AtIndex(e) => self.generate_at_index(e),
3340 Expression::Attach(e) => self.generate_attach(e),
3341 Expression::AttachOption(e) => self.generate_attach_option(e),
3342 Expression::AutoIncrementProperty(e) => self.generate_auto_increment_property(e),
3343 Expression::AutoRefreshProperty(e) => self.generate_auto_refresh_property(e),
3344 Expression::BackupProperty(e) => self.generate_backup_property(e),
3345 Expression::Base64DecodeBinary(e) => self.generate_base64_decode_binary(e),
3346 Expression::Base64DecodeString(e) => self.generate_base64_decode_string(e),
3347 Expression::Base64Encode(e) => self.generate_base64_encode(e),
3348 Expression::BlockCompressionProperty(e) => self.generate_block_compression_property(e),
3349 Expression::Booland(e) => self.generate_booland(e),
3350 Expression::Boolor(e) => self.generate_boolor(e),
3351 Expression::BuildProperty(e) => self.generate_build_property(e),
3352 Expression::ByteString(e) => self.generate_byte_string(e),
3353 Expression::CaseSpecificColumnConstraint(e) => {
3354 self.generate_case_specific_column_constraint(e)
3355 }
3356 Expression::CastToStrType(e) => self.generate_cast_to_str_type(e),
3357 Expression::Changes(e) => self.generate_changes(e),
3358 Expression::CharacterSetColumnConstraint(e) => {
3359 self.generate_character_set_column_constraint(e)
3360 }
3361 Expression::CharacterSetProperty(e) => self.generate_character_set_property(e),
3362 Expression::CheckColumnConstraint(e) => self.generate_check_column_constraint(e),
3363 Expression::CheckJson(e) => self.generate_check_json(e),
3364 Expression::CheckXml(e) => self.generate_check_xml(e),
3365 Expression::ChecksumProperty(e) => self.generate_checksum_property(e),
3366 Expression::Clone(e) => self.generate_clone(e),
3367 Expression::ClusterBy(e) => self.generate_cluster_by(e),
3368 Expression::ClusteredByProperty(e) => self.generate_clustered_by_property(e),
3369 Expression::CollateProperty(e) => self.generate_collate_property(e),
3370 Expression::ColumnConstraint(e) => self.generate_column_constraint(e),
3371 Expression::ColumnDef(e) => self.generate_column_def_expr(e),
3372 Expression::ColumnPosition(e) => self.generate_column_position(e),
3373 Expression::ColumnPrefix(e) => self.generate_column_prefix(e),
3374 Expression::Columns(e) => self.generate_columns(e),
3375 Expression::CombinedAggFunc(e) => self.generate_combined_agg_func(e),
3376 Expression::CombinedParameterizedAgg(e) => self.generate_combined_parameterized_agg(e),
3377 Expression::Commit(e) => self.generate_commit(e),
3378 Expression::Comprehension(e) => self.generate_comprehension(e),
3379 Expression::Compress(e) => self.generate_compress(e),
3380 Expression::CompressColumnConstraint(e) => self.generate_compress_column_constraint(e),
3381 Expression::ComputedColumnConstraint(e) => self.generate_computed_column_constraint(e),
3382 Expression::ConditionalInsert(e) => self.generate_conditional_insert(e),
3383 Expression::Constraint(e) => self.generate_constraint(e),
3384 Expression::ConvertTimezone(e) => self.generate_convert_timezone(e),
3385 Expression::ConvertToCharset(e) => self.generate_convert_to_charset(e),
3386 Expression::Copy(e) => self.generate_copy(e),
3387 Expression::CopyParameter(e) => self.generate_copy_parameter(e),
3388 Expression::Corr(e) => self.generate_corr(e),
3389 Expression::CosineDistance(e) => self.generate_cosine_distance(e),
3390 Expression::CovarPop(e) => self.generate_covar_pop(e),
3391 Expression::CovarSamp(e) => self.generate_covar_samp(e),
3392 Expression::Credentials(e) => self.generate_credentials(e),
3393 Expression::CredentialsProperty(e) => self.generate_credentials_property(e),
3394 Expression::Cte(e) => self.generate_cte(e),
3395 Expression::Cube(e) => self.generate_cube(e),
3396 Expression::CurrentDatetime(e) => self.generate_current_datetime(e),
3397 Expression::CurrentSchema(e) => self.generate_current_schema(e),
3398 Expression::CurrentSchemas(e) => self.generate_current_schemas(e),
3399 Expression::CurrentUser(e) => self.generate_current_user(e),
3400 Expression::DPipe(e) => self.generate_d_pipe(e),
3401 Expression::DataBlocksizeProperty(e) => self.generate_data_blocksize_property(e),
3402 Expression::DataDeletionProperty(e) => self.generate_data_deletion_property(e),
3403 Expression::Date(e) => self.generate_date_func(e),
3404 Expression::DateBin(e) => self.generate_date_bin(e),
3405 Expression::DateFormatColumnConstraint(e) => {
3406 self.generate_date_format_column_constraint(e)
3407 }
3408 Expression::DateFromParts(e) => self.generate_date_from_parts(e),
3409 Expression::Datetime(e) => self.generate_datetime(e),
3410 Expression::DatetimeAdd(e) => self.generate_datetime_add(e),
3411 Expression::DatetimeDiff(e) => self.generate_datetime_diff(e),
3412 Expression::DatetimeSub(e) => self.generate_datetime_sub(e),
3413 Expression::DatetimeTrunc(e) => self.generate_datetime_trunc(e),
3414 Expression::Dayname(e) => self.generate_dayname(e),
3415 Expression::Declare(e) => self.generate_declare(e),
3416 Expression::DeclareItem(e) => self.generate_declare_item(e),
3417 Expression::DecodeCase(e) => self.generate_decode_case(e),
3418 Expression::DecompressBinary(e) => self.generate_decompress_binary(e),
3419 Expression::DecompressString(e) => self.generate_decompress_string(e),
3420 Expression::Decrypt(e) => self.generate_decrypt(e),
3421 Expression::DecryptRaw(e) => self.generate_decrypt_raw(e),
3422 Expression::DefinerProperty(e) => self.generate_definer_property(e),
3423 Expression::Detach(e) => self.generate_detach(e),
3424 Expression::DictProperty(e) => self.generate_dict_property(e),
3425 Expression::DictRange(e) => self.generate_dict_range(e),
3426 Expression::Directory(e) => self.generate_directory(e),
3427 Expression::DistKeyProperty(e) => self.generate_dist_key_property(e),
3428 Expression::DistStyleProperty(e) => self.generate_dist_style_property(e),
3429 Expression::DistributeBy(e) => self.generate_distribute_by(e),
3430 Expression::DistributedByProperty(e) => self.generate_distributed_by_property(e),
3431 Expression::DotProduct(e) => self.generate_dot_product(e),
3432 Expression::DropPartition(e) => self.generate_drop_partition(e),
3433 Expression::DuplicateKeyProperty(e) => self.generate_duplicate_key_property(e),
3434 Expression::Elt(e) => self.generate_elt(e),
3435 Expression::Encode(e) => self.generate_encode(e),
3436 Expression::EncodeProperty(e) => self.generate_encode_property(e),
3437 Expression::Encrypt(e) => self.generate_encrypt(e),
3438 Expression::EncryptRaw(e) => self.generate_encrypt_raw(e),
3439 Expression::EngineProperty(e) => self.generate_engine_property(e),
3440 Expression::EnviromentProperty(e) => self.generate_enviroment_property(e),
3441 Expression::EphemeralColumnConstraint(e) => {
3442 self.generate_ephemeral_column_constraint(e)
3443 }
3444 Expression::EqualNull(e) => self.generate_equal_null(e),
3445 Expression::EuclideanDistance(e) => self.generate_euclidean_distance(e),
3446 Expression::ExecuteAsProperty(e) => self.generate_execute_as_property(e),
3447 Expression::Export(e) => self.generate_export(e),
3448 Expression::ExternalProperty(e) => self.generate_external_property(e),
3449 Expression::FallbackProperty(e) => self.generate_fallback_property(e),
3450 Expression::FarmFingerprint(e) => self.generate_farm_fingerprint(e),
3451 Expression::FeaturesAtTime(e) => self.generate_features_at_time(e),
3452 Expression::Fetch(e) => self.generate_fetch(e),
3453 Expression::FileFormatProperty(e) => self.generate_file_format_property(e),
3454 Expression::Filter(e) => self.generate_filter(e),
3455 Expression::Float64(e) => self.generate_float64(e),
3456 Expression::ForIn(e) => self.generate_for_in(e),
3457 Expression::ForeignKey(e) => self.generate_foreign_key(e),
3458 Expression::Format(e) => self.generate_format(e),
3459 Expression::FormatPhrase(e) => self.generate_format_phrase(e),
3460 Expression::FreespaceProperty(e) => self.generate_freespace_property(e),
3461 Expression::From(e) => self.generate_from(e),
3462 Expression::FromBase(e) => self.generate_from_base(e),
3463 Expression::FromTimeZone(e) => self.generate_from_time_zone(e),
3464 Expression::GapFill(e) => self.generate_gap_fill(e),
3465 Expression::GenerateDateArray(e) => self.generate_generate_date_array(e),
3466 Expression::GenerateEmbedding(e) => self.generate_generate_embedding(e),
3467 Expression::GenerateSeries(e) => self.generate_generate_series(e),
3468 Expression::GenerateTimestampArray(e) => self.generate_generate_timestamp_array(e),
3469 Expression::GeneratedAsIdentityColumnConstraint(e) => {
3470 self.generate_generated_as_identity_column_constraint(e)
3471 }
3472 Expression::GeneratedAsRowColumnConstraint(e) => {
3473 self.generate_generated_as_row_column_constraint(e)
3474 }
3475 Expression::Get(e) => self.generate_get(e),
3476 Expression::GetExtract(e) => self.generate_get_extract(e),
3477 Expression::Getbit(e) => self.generate_getbit(e),
3478 Expression::GrantPrincipal(e) => self.generate_grant_principal(e),
3479 Expression::GrantPrivilege(e) => self.generate_grant_privilege(e),
3480 Expression::Group(e) => self.generate_group(e),
3481 Expression::GroupBy(e) => self.generate_group_by(e),
3482 Expression::Grouping(e) => self.generate_grouping(e),
3483 Expression::GroupingId(e) => self.generate_grouping_id(e),
3484 Expression::GroupingSets(e) => self.generate_grouping_sets(e),
3485 Expression::HashAgg(e) => self.generate_hash_agg(e),
3486 Expression::Having(e) => self.generate_having(e),
3487 Expression::HavingMax(e) => self.generate_having_max(e),
3488 Expression::Heredoc(e) => self.generate_heredoc(e),
3489 Expression::HexEncode(e) => self.generate_hex_encode(e),
3490 Expression::Hll(e) => self.generate_hll(e),
3491 Expression::InOutColumnConstraint(e) => self.generate_in_out_column_constraint(e),
3492 Expression::IncludeProperty(e) => self.generate_include_property(e),
3493 Expression::Index(e) => self.generate_index(e),
3494 Expression::IndexColumnConstraint(e) => self.generate_index_column_constraint(e),
3495 Expression::IndexConstraintOption(e) => self.generate_index_constraint_option(e),
3496 Expression::IndexParameters(e) => self.generate_index_parameters(e),
3497 Expression::IndexTableHint(e) => self.generate_index_table_hint(e),
3498 Expression::InheritsProperty(e) => self.generate_inherits_property(e),
3499 Expression::InputModelProperty(e) => self.generate_input_model_property(e),
3500 Expression::InputOutputFormat(e) => self.generate_input_output_format(e),
3501 Expression::Install(e) => self.generate_install(e),
3502 Expression::IntervalOp(e) => self.generate_interval_op(e),
3503 Expression::IntervalSpan(e) => self.generate_interval_span(e),
3504 Expression::IntoClause(e) => self.generate_into_clause(e),
3505 Expression::Introducer(e) => self.generate_introducer(e),
3506 Expression::IsolatedLoadingProperty(e) => self.generate_isolated_loading_property(e),
3507 Expression::JSON(e) => self.generate_json(e),
3508 Expression::JSONArray(e) => self.generate_json_array(e),
3509 Expression::JSONArrayAgg(e) => self.generate_json_array_agg_struct(e),
3510 Expression::JSONArrayAppend(e) => self.generate_json_array_append(e),
3511 Expression::JSONArrayContains(e) => self.generate_json_array_contains(e),
3512 Expression::JSONArrayInsert(e) => self.generate_json_array_insert(e),
3513 Expression::JSONBExists(e) => self.generate_jsonb_exists(e),
3514 Expression::JSONBExtractScalar(e) => self.generate_jsonb_extract_scalar(e),
3515 Expression::JSONBObjectAgg(e) => self.generate_jsonb_object_agg(e),
3516 Expression::JSONObjectAgg(e) => self.generate_json_object_agg_struct(e),
3517 Expression::JSONColumnDef(e) => self.generate_json_column_def(e),
3518 Expression::JSONExists(e) => self.generate_json_exists(e),
3519 Expression::JSONCast(e) => self.generate_json_cast(e),
3520 Expression::JSONExtract(e) => self.generate_json_extract_path(e),
3521 Expression::JSONExtractArray(e) => self.generate_json_extract_array(e),
3522 Expression::JSONExtractQuote(e) => self.generate_json_extract_quote(e),
3523 Expression::JSONExtractScalar(e) => self.generate_json_extract_scalar(e),
3524 Expression::JSONFormat(e) => self.generate_json_format(e),
3525 Expression::JSONKeyValue(e) => self.generate_json_key_value(e),
3526 Expression::JSONKeys(e) => self.generate_json_keys(e),
3527 Expression::JSONKeysAtDepth(e) => self.generate_json_keys_at_depth(e),
3528 Expression::JSONPath(e) => self.generate_json_path_expr(e),
3529 Expression::JSONPathFilter(e) => self.generate_json_path_filter(e),
3530 Expression::JSONPathKey(e) => self.generate_json_path_key(e),
3531 Expression::JSONPathRecursive(e) => self.generate_json_path_recursive(e),
3532 Expression::JSONPathRoot(_) => self.generate_json_path_root(),
3533 Expression::JSONPathScript(e) => self.generate_json_path_script(e),
3534 Expression::JSONPathSelector(e) => self.generate_json_path_selector(e),
3535 Expression::JSONPathSlice(e) => self.generate_json_path_slice(e),
3536 Expression::JSONPathSubscript(e) => self.generate_json_path_subscript(e),
3537 Expression::JSONPathUnion(e) => self.generate_json_path_union(e),
3538 Expression::JSONRemove(e) => self.generate_json_remove(e),
3539 Expression::JSONSchema(e) => self.generate_json_schema(e),
3540 Expression::JSONSet(e) => self.generate_json_set(e),
3541 Expression::JSONStripNulls(e) => self.generate_json_strip_nulls(e),
3542 Expression::JSONTable(e) => self.generate_json_table(e),
3543 Expression::JSONType(e) => self.generate_json_type(e),
3544 Expression::JSONValue(e) => self.generate_json_value(e),
3545 Expression::JSONValueArray(e) => self.generate_json_value_array(e),
3546 Expression::JarowinklerSimilarity(e) => self.generate_jarowinkler_similarity(e),
3547 Expression::JoinHint(e) => self.generate_join_hint(e),
3548 Expression::JournalProperty(e) => self.generate_journal_property(e),
3549 Expression::LanguageProperty(e) => self.generate_language_property(e),
3550 Expression::Lateral(e) => self.generate_lateral(e),
3551 Expression::LikeProperty(e) => self.generate_like_property(e),
3552 Expression::Limit(e) => self.generate_limit(e),
3553 Expression::LimitOptions(e) => self.generate_limit_options(e),
3554 Expression::List(e) => self.generate_list(e),
3555 Expression::ToMap(e) => self.generate_tomap(e),
3556 Expression::Localtime(e) => self.generate_localtime(e),
3557 Expression::Localtimestamp(e) => self.generate_localtimestamp(e),
3558 Expression::LocationProperty(e) => self.generate_location_property(e),
3559 Expression::Lock(e) => self.generate_lock(e),
3560 Expression::LockProperty(e) => self.generate_lock_property(e),
3561 Expression::LockingProperty(e) => self.generate_locking_property(e),
3562 Expression::LockingStatement(e) => self.generate_locking_statement(e),
3563 Expression::LogProperty(e) => self.generate_log_property(e),
3564 Expression::MD5Digest(e) => self.generate_md5_digest(e),
3565 Expression::MLForecast(e) => self.generate_ml_forecast(e),
3566 Expression::MLTranslate(e) => self.generate_ml_translate(e),
3567 Expression::MakeInterval(e) => self.generate_make_interval(e),
3568 Expression::ManhattanDistance(e) => self.generate_manhattan_distance(e),
3569 Expression::Map(e) => self.generate_map(e),
3570 Expression::MapCat(e) => self.generate_map_cat(e),
3571 Expression::MapDelete(e) => self.generate_map_delete(e),
3572 Expression::MapInsert(e) => self.generate_map_insert(e),
3573 Expression::MapPick(e) => self.generate_map_pick(e),
3574 Expression::MaskingPolicyColumnConstraint(e) => {
3575 self.generate_masking_policy_column_constraint(e)
3576 }
3577 Expression::MatchAgainst(e) => self.generate_match_against(e),
3578 Expression::MatchRecognizeMeasure(e) => self.generate_match_recognize_measure(e),
3579 Expression::MaterializedProperty(e) => self.generate_materialized_property(e),
3580 Expression::Merge(e) => self.generate_merge(e),
3581 Expression::MergeBlockRatioProperty(e) => self.generate_merge_block_ratio_property(e),
3582 Expression::MergeTreeTTL(e) => self.generate_merge_tree_ttl(e),
3583 Expression::MergeTreeTTLAction(e) => self.generate_merge_tree_ttl_action(e),
3584 Expression::Minhash(e) => self.generate_minhash(e),
3585 Expression::ModelAttribute(e) => self.generate_model_attribute(e),
3586 Expression::Monthname(e) => self.generate_monthname(e),
3587 Expression::MultitableInserts(e) => self.generate_multitable_inserts(e),
3588 Expression::NextValueFor(e) => self.generate_next_value_for(e),
3589 Expression::Normal(e) => self.generate_normal(e),
3590 Expression::Normalize(e) => self.generate_normalize(e),
3591 Expression::NotNullColumnConstraint(e) => self.generate_not_null_column_constraint(e),
3592 Expression::Nullif(e) => self.generate_nullif(e),
3593 Expression::NumberToStr(e) => self.generate_number_to_str(e),
3594 Expression::ObjectAgg(e) => self.generate_object_agg(e),
3595 Expression::ObjectIdentifier(e) => self.generate_object_identifier(e),
3596 Expression::ObjectInsert(e) => self.generate_object_insert(e),
3597 Expression::Offset(e) => self.generate_offset(e),
3598 Expression::Qualify(e) => self.generate_qualify(e),
3599 Expression::OnCluster(e) => self.generate_on_cluster(e),
3600 Expression::OnCommitProperty(e) => self.generate_on_commit_property(e),
3601 Expression::OnCondition(e) => self.generate_on_condition(e),
3602 Expression::OnConflict(e) => self.generate_on_conflict(e),
3603 Expression::OnProperty(e) => self.generate_on_property(e),
3604 Expression::Opclass(e) => self.generate_opclass(e),
3605 Expression::OpenJSON(e) => self.generate_open_json(e),
3606 Expression::OpenJSONColumnDef(e) => self.generate_open_json_column_def(e),
3607 Expression::Operator(e) => self.generate_operator(e),
3608 Expression::OrderBy(e) => self.generate_order_by(e),
3609 Expression::OutputModelProperty(e) => self.generate_output_model_property(e),
3610 Expression::OverflowTruncateBehavior(e) => self.generate_overflow_truncate_behavior(e),
3611 Expression::ParameterizedAgg(e) => self.generate_parameterized_agg(e),
3612 Expression::ParseDatetime(e) => self.generate_parse_datetime(e),
3613 Expression::ParseIp(e) => self.generate_parse_ip(e),
3614 Expression::ParseJSON(e) => self.generate_parse_json(e),
3615 Expression::ParseTime(e) => self.generate_parse_time(e),
3616 Expression::ParseUrl(e) => self.generate_parse_url(e),
3617 Expression::Partition(e) => self.generate_partition_expr(e),
3618 Expression::PartitionBoundSpec(e) => self.generate_partition_bound_spec(e),
3619 Expression::PartitionByListProperty(e) => self.generate_partition_by_list_property(e),
3620 Expression::PartitionByRangeProperty(e) => self.generate_partition_by_range_property(e),
3621 Expression::PartitionByRangePropertyDynamic(e) => {
3622 self.generate_partition_by_range_property_dynamic(e)
3623 }
3624 Expression::PartitionByTruncate(e) => self.generate_partition_by_truncate(e),
3625 Expression::PartitionList(e) => self.generate_partition_list(e),
3626 Expression::PartitionRange(e) => self.generate_partition_range(e),
3627 Expression::PartitionedByBucket(e) => self.generate_partitioned_by_bucket(e),
3628 Expression::PartitionedByProperty(e) => self.generate_partitioned_by_property(e),
3629 Expression::PartitionedOfProperty(e) => self.generate_partitioned_of_property(e),
3630 Expression::PeriodForSystemTimeConstraint(e) => {
3631 self.generate_period_for_system_time_constraint(e)
3632 }
3633 Expression::PivotAlias(e) => self.generate_pivot_alias(e),
3634 Expression::PivotAny(e) => self.generate_pivot_any(e),
3635 Expression::Predict(e) => self.generate_predict(e),
3636 Expression::PreviousDay(e) => self.generate_previous_day(e),
3637 Expression::PrimaryKey(e) => self.generate_primary_key(e),
3638 Expression::PrimaryKeyColumnConstraint(e) => {
3639 self.generate_primary_key_column_constraint(e)
3640 }
3641 Expression::PathColumnConstraint(e) => self.generate_path_column_constraint(e),
3642 Expression::ProjectionDef(e) => self.generate_projection_def(e),
3643 Expression::Properties(e) => self.generate_properties(e),
3644 Expression::Property(e) => self.generate_property(e),
3645 Expression::PseudoType(e) => self.generate_pseudo_type(e),
3646 Expression::Put(e) => self.generate_put(e),
3647 Expression::Quantile(e) => self.generate_quantile(e),
3648 Expression::QueryBand(e) => self.generate_query_band(e),
3649 Expression::QueryOption(e) => self.generate_query_option(e),
3650 Expression::QueryTransform(e) => self.generate_query_transform(e),
3651 Expression::Randn(e) => self.generate_randn(e),
3652 Expression::Randstr(e) => self.generate_randstr(e),
3653 Expression::RangeBucket(e) => self.generate_range_bucket(e),
3654 Expression::RangeN(e) => self.generate_range_n(e),
3655 Expression::ReadCSV(e) => self.generate_read_csv(e),
3656 Expression::ReadParquet(e) => self.generate_read_parquet(e),
3657 Expression::RecursiveWithSearch(e) => self.generate_recursive_with_search(e),
3658 Expression::Reduce(e) => self.generate_reduce(e),
3659 Expression::Reference(e) => self.generate_reference(e),
3660 Expression::Refresh(e) => self.generate_refresh(e),
3661 Expression::RefreshTriggerProperty(e) => self.generate_refresh_trigger_property(e),
3662 Expression::RegexpCount(e) => self.generate_regexp_count(e),
3663 Expression::RegexpExtractAll(e) => self.generate_regexp_extract_all(e),
3664 Expression::RegexpFullMatch(e) => self.generate_regexp_full_match(e),
3665 Expression::RegexpILike(e) => self.generate_regexp_i_like(e),
3666 Expression::RegexpInstr(e) => self.generate_regexp_instr(e),
3667 Expression::RegexpSplit(e) => self.generate_regexp_split(e),
3668 Expression::RegrAvgx(e) => self.generate_regr_avgx(e),
3669 Expression::RegrAvgy(e) => self.generate_regr_avgy(e),
3670 Expression::RegrCount(e) => self.generate_regr_count(e),
3671 Expression::RegrIntercept(e) => self.generate_regr_intercept(e),
3672 Expression::RegrR2(e) => self.generate_regr_r2(e),
3673 Expression::RegrSlope(e) => self.generate_regr_slope(e),
3674 Expression::RegrSxx(e) => self.generate_regr_sxx(e),
3675 Expression::RegrSxy(e) => self.generate_regr_sxy(e),
3676 Expression::RegrSyy(e) => self.generate_regr_syy(e),
3677 Expression::RegrValx(e) => self.generate_regr_valx(e),
3678 Expression::RegrValy(e) => self.generate_regr_valy(e),
3679 Expression::RemoteWithConnectionModelProperty(e) => {
3680 self.generate_remote_with_connection_model_property(e)
3681 }
3682 Expression::RenameColumn(e) => self.generate_rename_column(e),
3683 Expression::ReplacePartition(e) => self.generate_replace_partition(e),
3684 Expression::Returning(e) => self.generate_returning(e),
3685 Expression::ReturnsProperty(e) => self.generate_returns_property(e),
3686 Expression::Rollback(e) => self.generate_rollback(e),
3687 Expression::Rollup(e) => self.generate_rollup(e),
3688 Expression::RowFormatDelimitedProperty(e) => {
3689 self.generate_row_format_delimited_property(e)
3690 }
3691 Expression::RowFormatProperty(e) => self.generate_row_format_property(e),
3692 Expression::RowFormatSerdeProperty(e) => self.generate_row_format_serde_property(e),
3693 Expression::SHA2(e) => self.generate_sha2(e),
3694 Expression::SHA2Digest(e) => self.generate_sha2_digest(e),
3695 Expression::SafeAdd(e) => self.generate_safe_add(e),
3696 Expression::SafeDivide(e) => self.generate_safe_divide(e),
3697 Expression::SafeMultiply(e) => self.generate_safe_multiply(e),
3698 Expression::SafeSubtract(e) => self.generate_safe_subtract(e),
3699 Expression::SampleProperty(e) => self.generate_sample_property(e),
3700 Expression::Schema(e) => self.generate_schema(e),
3701 Expression::SchemaCommentProperty(e) => self.generate_schema_comment_property(e),
3702 Expression::ScopeResolution(e) => self.generate_scope_resolution(e),
3703 Expression::Search(e) => self.generate_search(e),
3704 Expression::SearchIp(e) => self.generate_search_ip(e),
3705 Expression::SecurityProperty(e) => self.generate_security_property(e),
3706 Expression::SemanticView(e) => self.generate_semantic_view(e),
3707 Expression::SequenceProperties(e) => self.generate_sequence_properties(e),
3708 Expression::SerdeProperties(e) => self.generate_serde_properties(e),
3709 Expression::SessionParameter(e) => self.generate_session_parameter(e),
3710 Expression::Set(e) => self.generate_set(e),
3711 Expression::SetConfigProperty(e) => self.generate_set_config_property(e),
3712 Expression::SetItem(e) => self.generate_set_item(e),
3713 Expression::SetOperation(e) => self.generate_set_operation(e),
3714 Expression::SetProperty(e) => self.generate_set_property(e),
3715 Expression::SettingsProperty(e) => self.generate_settings_property(e),
3716 Expression::SharingProperty(e) => self.generate_sharing_property(e),
3717 Expression::Slice(e) => self.generate_slice(e),
3718 Expression::SortArray(e) => self.generate_sort_array(e),
3719 Expression::SortBy(e) => self.generate_sort_by(e),
3720 Expression::SortKeyProperty(e) => self.generate_sort_key_property(e),
3721 Expression::SplitPart(e) => self.generate_split_part(e),
3722 Expression::SqlReadWriteProperty(e) => self.generate_sql_read_write_property(e),
3723 Expression::SqlSecurityProperty(e) => self.generate_sql_security_property(e),
3724 Expression::StDistance(e) => self.generate_st_distance(e),
3725 Expression::StPoint(e) => self.generate_st_point(e),
3726 Expression::StabilityProperty(e) => self.generate_stability_property(e),
3727 Expression::StandardHash(e) => self.generate_standard_hash(e),
3728 Expression::StorageHandlerProperty(e) => self.generate_storage_handler_property(e),
3729 Expression::StrPosition(e) => self.generate_str_position(e),
3730 Expression::StrToDate(e) => self.generate_str_to_date(e),
3731 Expression::DateStrToDate(f) => self.generate_simple_func("DATE_STR_TO_DATE", &f.this),
3732 Expression::DateToDateStr(f) => self.generate_simple_func("DATE_TO_DATE_STR", &f.this),
3733 Expression::StrToMap(e) => self.generate_str_to_map(e),
3734 Expression::StrToTime(e) => self.generate_str_to_time(e),
3735 Expression::StrToUnix(e) => self.generate_str_to_unix(e),
3736 Expression::StringToArray(e) => self.generate_string_to_array(e),
3737 Expression::Struct(e) => self.generate_struct(e),
3738 Expression::Stuff(e) => self.generate_stuff(e),
3739 Expression::SubstringIndex(e) => self.generate_substring_index(e),
3740 Expression::Summarize(e) => self.generate_summarize(e),
3741 Expression::Systimestamp(e) => self.generate_systimestamp(e),
3742 Expression::TableAlias(e) => self.generate_table_alias(e),
3743 Expression::TableFromRows(e) => self.generate_table_from_rows(e),
3744 Expression::RowsFrom(e) => self.generate_rows_from(e),
3745 Expression::TableSample(e) => self.generate_table_sample(e),
3746 Expression::Tag(e) => self.generate_tag(e),
3747 Expression::Tags(e) => self.generate_tags(e),
3748 Expression::TemporaryProperty(e) => self.generate_temporary_property(e),
3749 Expression::Time(e) => self.generate_time_func(e),
3750 Expression::TimeAdd(e) => self.generate_time_add(e),
3751 Expression::TimeDiff(e) => self.generate_time_diff(e),
3752 Expression::TimeFromParts(e) => self.generate_time_from_parts(e),
3753 Expression::TimeSlice(e) => self.generate_time_slice(e),
3754 Expression::TimeStrToDate(e) => self.generate_time_str_to_date(e),
3755 Expression::TimeStrToTime(e) => self.generate_time_str_to_time(e),
3756 Expression::TimeSub(e) => self.generate_time_sub(e),
3757 Expression::TimeToStr(e) => self.generate_time_to_str(e),
3758 Expression::TimeToUnix(e) => self.generate_time_to_unix(e),
3759 Expression::TimeTrunc(e) => self.generate_time_trunc(e),
3760 Expression::TimeUnit(e) => self.generate_time_unit(e),
3761 Expression::Timestamp(e) => self.generate_timestamp_func(e),
3762 Expression::TimestampAdd(e) => self.generate_timestamp_add(e),
3763 Expression::TimestampDiff(e) => self.generate_timestamp_diff(e),
3764 Expression::TimestampFromParts(e) => self.generate_timestamp_from_parts(e),
3765 Expression::TimestampSub(e) => self.generate_timestamp_sub(e),
3766 Expression::TimestampTzFromParts(e) => self.generate_timestamp_tz_from_parts(e),
3767 Expression::ToBinary(e) => self.generate_to_binary(e),
3768 Expression::ToBoolean(e) => self.generate_to_boolean(e),
3769 Expression::ToChar(e) => self.generate_to_char(e),
3770 Expression::ToDecfloat(e) => self.generate_to_decfloat(e),
3771 Expression::ToDouble(e) => self.generate_to_double(e),
3772 Expression::ToFile(e) => self.generate_to_file(e),
3773 Expression::ToNumber(e) => self.generate_to_number(e),
3774 Expression::ToTableProperty(e) => self.generate_to_table_property(e),
3775 Expression::Transaction(e) => self.generate_transaction(e),
3776 Expression::Transform(e) => self.generate_transform(e),
3777 Expression::TransformModelProperty(e) => self.generate_transform_model_property(e),
3778 Expression::TransientProperty(e) => self.generate_transient_property(e),
3779 Expression::Translate(e) => self.generate_translate(e),
3780 Expression::TranslateCharacters(e) => self.generate_translate_characters(e),
3781 Expression::TruncateTable(e) => self.generate_truncate_table(e),
3782 Expression::TryBase64DecodeBinary(e) => self.generate_try_base64_decode_binary(e),
3783 Expression::TryBase64DecodeString(e) => self.generate_try_base64_decode_string(e),
3784 Expression::TryToDecfloat(e) => self.generate_try_to_decfloat(e),
3785 Expression::TsOrDsAdd(e) => self.generate_ts_or_ds_add(e),
3786 Expression::TsOrDsDiff(e) => self.generate_ts_or_ds_diff(e),
3787 Expression::TsOrDsToDate(e) => self.generate_ts_or_ds_to_date(e),
3788 Expression::TsOrDsToTime(e) => self.generate_ts_or_ds_to_time(e),
3789 Expression::Unhex(e) => self.generate_unhex(e),
3790 Expression::UnicodeString(e) => self.generate_unicode_string(e),
3791 Expression::Uniform(e) => self.generate_uniform(e),
3792 Expression::UniqueColumnConstraint(e) => self.generate_unique_column_constraint(e),
3793 Expression::UniqueKeyProperty(e) => self.generate_unique_key_property(e),
3794 Expression::RollupProperty(e) => self.generate_rollup_property(e),
3795 Expression::UnixToStr(e) => self.generate_unix_to_str(e),
3796 Expression::UnixToTime(e) => self.generate_unix_to_time(e),
3797 Expression::UnpivotColumns(e) => self.generate_unpivot_columns(e),
3798 Expression::UserDefinedFunction(e) => self.generate_user_defined_function(e),
3799 Expression::UsingTemplateProperty(e) => self.generate_using_template_property(e),
3800 Expression::UtcTime(e) => self.generate_utc_time(e),
3801 Expression::UtcTimestamp(e) => self.generate_utc_timestamp(e),
3802 Expression::Uuid(e) => self.generate_uuid(e),
3803 Expression::Var(v) => {
3804 if matches!(self.config.dialect, Some(DialectType::MySQL))
3805 && v.this.len() > 2
3806 && (v.this.starts_with("0x") || v.this.starts_with("0X"))
3807 && !v.this[2..].chars().all(|c| c.is_ascii_hexdigit())
3808 {
3809 return self.generate_identifier(&Identifier {
3810 name: v.this.clone(),
3811 quoted: true,
3812 trailing_comments: Vec::new(),
3813 span: None,
3814 });
3815 }
3816 self.write(&v.this);
3817 Ok(())
3818 }
3819 Expression::Variadic(e) => {
3820 self.write_keyword("VARIADIC");
3821 self.write_space();
3822 self.generate_expression(&e.this)?;
3823 Ok(())
3824 }
3825 Expression::VarMap(e) => self.generate_var_map(e),
3826 Expression::VectorSearch(e) => self.generate_vector_search(e),
3827 Expression::Version(e) => self.generate_version(e),
3828 Expression::ViewAttributeProperty(e) => self.generate_view_attribute_property(e),
3829 Expression::VolatileProperty(e) => self.generate_volatile_property(e),
3830 Expression::WatermarkColumnConstraint(e) => {
3831 self.generate_watermark_column_constraint(e)
3832 }
3833 Expression::Week(e) => self.generate_week(e),
3834 Expression::When(e) => self.generate_when(e),
3835 Expression::Whens(e) => self.generate_whens(e),
3836 Expression::Where(e) => self.generate_where(e),
3837 Expression::WidthBucket(e) => self.generate_width_bucket(e),
3838 Expression::Window(e) => self.generate_window(e),
3839 Expression::WindowSpec(e) => self.generate_window_spec(e),
3840 Expression::WithDataProperty(e) => self.generate_with_data_property(e),
3841 Expression::WithFill(e) => self.generate_with_fill(e),
3842 Expression::WithJournalTableProperty(e) => self.generate_with_journal_table_property(e),
3843 Expression::WithOperator(e) => self.generate_with_operator(e),
3844 Expression::WithProcedureOptions(e) => self.generate_with_procedure_options(e),
3845 Expression::WithSchemaBindingProperty(e) => {
3846 self.generate_with_schema_binding_property(e)
3847 }
3848 Expression::WithSystemVersioningProperty(e) => {
3849 self.generate_with_system_versioning_property(e)
3850 }
3851 Expression::WithTableHint(e) => self.generate_with_table_hint(e),
3852 Expression::XMLElement(e) => self.generate_xml_element(e),
3853 Expression::XMLGet(e) => self.generate_xml_get(e),
3854 Expression::XMLKeyValueOption(e) => self.generate_xml_key_value_option(e),
3855 Expression::XMLTable(e) => self.generate_xml_table(e),
3856 Expression::Xor(e) => self.generate_xor(e),
3857 Expression::Zipf(e) => self.generate_zipf(e),
3858 _ => {
3859 self.write(&format!("/* unimplemented: {:?} */", expr));
3861 Ok(())
3862 }
3863 }
3864 }
3865
3866 fn generate_select(&mut self, select: &Select) -> Result<()> {
3867 use crate::dialects::DialectType;
3868
3869 for comment in &select.leading_comments {
3871 self.write_formatted_comment(comment);
3872 self.write(" ");
3873 }
3874
3875 if let Some(with) = &select.with {
3877 self.generate_with(with)?;
3878 if self.config.pretty {
3879 self.write_newline();
3880 self.write_indent();
3881 } else {
3882 self.write_space();
3883 }
3884 }
3885
3886 for comment in &select.post_select_comments {
3889 self.write_formatted_comment(comment);
3890 self.write(" ");
3891 }
3892
3893 self.write_keyword("SELECT");
3894
3895 if let Some(hint) = &select.hint {
3897 self.generate_hint(hint)?;
3898 }
3899
3900 let use_top_from_limit = matches!(self.config.dialect, Some(DialectType::TSQL))
3904 && select.top.is_none()
3905 && select.limit.is_some()
3906 && select.offset.is_none(); let is_top_dialect = matches!(
3911 self.config.dialect,
3912 Some(DialectType::TSQL) | Some(DialectType::Teradata) | Some(DialectType::Fabric)
3913 );
3914 let keep_top_verbatim = !is_top_dialect
3915 && select.limit.is_none()
3916 && select
3917 .top
3918 .as_ref()
3919 .map_or(false, |top| top.percent || top.with_ties);
3920
3921 if select.distinct && (is_top_dialect || select.top.is_some()) {
3922 self.write_space();
3923 self.write_keyword("DISTINCT");
3924 }
3925
3926 if is_top_dialect || keep_top_verbatim {
3927 if let Some(top) = &select.top {
3928 self.write_space();
3929 self.write_keyword("TOP");
3930 if top.parenthesized {
3931 self.write(" (");
3932 self.generate_expression(&top.this)?;
3933 self.write(")");
3934 } else {
3935 self.write_space();
3936 self.generate_expression(&top.this)?;
3937 }
3938 if top.percent {
3939 self.write_space();
3940 self.write_keyword("PERCENT");
3941 }
3942 if top.with_ties {
3943 self.write_space();
3944 self.write_keyword("WITH TIES");
3945 }
3946 } else if use_top_from_limit {
3947 if let Some(limit) = &select.limit {
3949 self.write_space();
3950 self.write_keyword("TOP");
3951 let is_simple_literal =
3953 matches!(&limit.this, Expression::Literal(Literal::Number(_)));
3954 if is_simple_literal {
3955 self.write_space();
3956 self.generate_expression(&limit.this)?;
3957 } else {
3958 self.write(" (");
3959 self.generate_expression(&limit.this)?;
3960 self.write(")");
3961 }
3962 }
3963 }
3964 }
3965
3966 if select.distinct && !is_top_dialect && select.top.is_none() {
3967 self.write_space();
3968 self.write_keyword("DISTINCT");
3969 }
3970
3971 if let Some(distinct_on) = &select.distinct_on {
3973 self.write_space();
3974 self.write_keyword("ON");
3975 self.write(" (");
3976 for (i, expr) in distinct_on.iter().enumerate() {
3977 if i > 0 {
3978 self.write(", ");
3979 }
3980 self.generate_expression(expr)?;
3981 }
3982 self.write(")");
3983 }
3984
3985 for modifier in &select.operation_modifiers {
3987 self.write_space();
3988 self.write_keyword(modifier);
3989 }
3990
3991 if let Some(kind) = &select.kind {
3993 self.write_space();
3994 self.write_keyword("AS");
3995 self.write_space();
3996 self.write_keyword(kind);
3997 }
3998
3999 if !select.expressions.is_empty() {
4001 if self.config.pretty {
4002 self.write_newline();
4003 self.indent_level += 1;
4004 } else {
4005 self.write_space();
4006 }
4007 }
4008
4009 for (i, expr) in select.expressions.iter().enumerate() {
4010 if i > 0 {
4011 self.write(",");
4012 if self.config.pretty {
4013 self.write_newline();
4014 } else {
4015 self.write_space();
4016 }
4017 }
4018 if self.config.pretty {
4019 self.write_indent();
4020 }
4021 self.generate_expression(expr)?;
4022 }
4023
4024 if self.config.pretty && !select.expressions.is_empty() {
4025 self.indent_level -= 1;
4026 }
4027
4028 if let Some(into) = &select.into {
4031 if self.config.pretty {
4032 self.write_newline();
4033 self.write_indent();
4034 } else {
4035 self.write_space();
4036 }
4037 if into.bulk_collect {
4038 self.write_keyword("BULK COLLECT INTO");
4039 } else {
4040 self.write_keyword("INTO");
4041 }
4042 if into.temporary {
4043 self.write_space();
4044 self.write_keyword("TEMPORARY");
4045 }
4046 if into.unlogged {
4047 self.write_space();
4048 self.write_keyword("UNLOGGED");
4049 }
4050 self.write_space();
4051 if !into.expressions.is_empty() {
4053 for (i, expr) in into.expressions.iter().enumerate() {
4054 if i > 0 {
4055 self.write(", ");
4056 }
4057 self.generate_expression(expr)?;
4058 }
4059 } else {
4060 self.generate_expression(&into.this)?;
4061 }
4062 }
4063
4064 if let Some(from) = &select.from {
4066 if self.config.pretty {
4067 self.write_newline();
4068 self.write_indent();
4069 } else {
4070 self.write_space();
4071 }
4072 self.write_keyword("FROM");
4073 self.write_space();
4074
4075 let has_tablesample = from
4080 .expressions
4081 .iter()
4082 .any(|e| matches!(e, Expression::TableSample(_)));
4083 let is_cross_join_dialect = matches!(
4084 self.config.dialect,
4085 Some(DialectType::BigQuery)
4086 | Some(DialectType::Hive)
4087 | Some(DialectType::Spark)
4088 | Some(DialectType::Databricks)
4089 | Some(DialectType::SQLite)
4090 | Some(DialectType::ClickHouse)
4091 );
4092 let source_is_same_as_target = self.config.source_dialect.is_some()
4095 && self.config.source_dialect == self.config.dialect;
4096 let source_is_cross_join_dialect = matches!(
4097 self.config.source_dialect,
4098 Some(DialectType::BigQuery)
4099 | Some(DialectType::Hive)
4100 | Some(DialectType::Spark)
4101 | Some(DialectType::Databricks)
4102 | Some(DialectType::SQLite)
4103 | Some(DialectType::ClickHouse)
4104 );
4105 let use_cross_join = !has_tablesample
4106 && is_cross_join_dialect
4107 && (source_is_same_as_target
4108 || source_is_cross_join_dialect
4109 || self.config.source_dialect.is_none());
4110
4111 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
4113
4114 for (i, expr) in from.expressions.iter().enumerate() {
4115 if i > 0 {
4116 if use_cross_join {
4117 self.write(" CROSS JOIN ");
4118 } else {
4119 self.write(", ");
4120 }
4121 }
4122 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
4123 self.write("(");
4124 self.generate_expression(expr)?;
4125 self.write(")");
4126 } else {
4127 self.generate_expression(expr)?;
4128 }
4129 }
4130 }
4131
4132 if self.config.pretty {
4136 self.generate_joins_with_nesting(&select.joins)?;
4137 } else {
4138 for join in &select.joins {
4139 self.generate_join(join)?;
4140 }
4141 for join in select.joins.iter().rev() {
4143 if join.deferred_condition {
4144 self.generate_join_condition(join)?;
4145 }
4146 }
4147 }
4148
4149 for lateral_view in &select.lateral_views {
4151 self.generate_lateral_view(lateral_view)?;
4152 }
4153
4154 if let Some(prewhere) = &select.prewhere {
4156 self.write_clause_condition("PREWHERE", prewhere)?;
4157 }
4158
4159 if let Some(where_clause) = &select.where_clause {
4161 self.write_clause_condition("WHERE", &where_clause.this)?;
4162 }
4163
4164 if let Some(connect) = &select.connect {
4166 self.generate_connect(connect)?;
4167 }
4168
4169 if let Some(group_by) = &select.group_by {
4171 if self.config.pretty {
4172 for comment in &group_by.comments {
4174 self.write_newline();
4175 self.write_indent();
4176 self.write_formatted_comment(comment);
4177 }
4178 self.write_newline();
4179 self.write_indent();
4180 } else {
4181 self.write_space();
4182 for comment in &group_by.comments {
4184 self.write_formatted_comment(comment);
4185 self.write_space();
4186 }
4187 }
4188 self.write_keyword("GROUP BY");
4189 match group_by.all {
4191 Some(true) => {
4192 self.write_space();
4193 self.write_keyword("ALL");
4194 }
4195 Some(false) => {
4196 self.write_space();
4197 self.write_keyword("DISTINCT");
4198 }
4199 None => {}
4200 }
4201 if !group_by.expressions.is_empty() {
4202 let mut trailing_cube = false;
4205 let mut trailing_rollup = false;
4206 let mut plain_expressions: Vec<&Expression> = Vec::new();
4207 let mut grouping_sets_expressions: Vec<&Expression> = Vec::new();
4208 let mut cube_expressions: Vec<&Expression> = Vec::new();
4209 let mut rollup_expressions: Vec<&Expression> = Vec::new();
4210
4211 for expr in &group_by.expressions {
4212 match expr {
4213 Expression::Cube(c) if c.expressions.is_empty() => {
4214 trailing_cube = true;
4215 }
4216 Expression::Rollup(r) if r.expressions.is_empty() => {
4217 trailing_rollup = true;
4218 }
4219 Expression::Function(f) if f.name == "CUBE" => {
4220 cube_expressions.push(expr);
4221 }
4222 Expression::Function(f) if f.name == "ROLLUP" => {
4223 rollup_expressions.push(expr);
4224 }
4225 Expression::Function(f) if f.name == "GROUPING SETS" => {
4226 grouping_sets_expressions.push(expr);
4227 }
4228 _ => {
4229 plain_expressions.push(expr);
4230 }
4231 }
4232 }
4233
4234 let mut regular_expressions: Vec<&Expression> = Vec::new();
4236 regular_expressions.extend(plain_expressions);
4237 regular_expressions.extend(grouping_sets_expressions);
4238 regular_expressions.extend(cube_expressions);
4239 regular_expressions.extend(rollup_expressions);
4240
4241 if self.config.pretty {
4242 self.write_newline();
4243 self.indent_level += 1;
4244 self.write_indent();
4245 } else {
4246 self.write_space();
4247 }
4248
4249 for (i, expr) in regular_expressions.iter().enumerate() {
4250 if i > 0 {
4251 if self.config.pretty {
4252 self.write(",");
4253 self.write_newline();
4254 self.write_indent();
4255 } else {
4256 self.write(", ");
4257 }
4258 }
4259 self.generate_expression(expr)?;
4260 }
4261
4262 if self.config.pretty {
4263 self.indent_level -= 1;
4264 }
4265
4266 if trailing_cube {
4268 self.write_space();
4269 self.write_keyword("WITH CUBE");
4270 } else if trailing_rollup {
4271 self.write_space();
4272 self.write_keyword("WITH ROLLUP");
4273 }
4274 }
4275
4276 if group_by.totals {
4278 self.write_space();
4279 self.write_keyword("WITH TOTALS");
4280 }
4281 }
4282
4283 if let Some(having) = &select.having {
4285 if self.config.pretty {
4286 for comment in &having.comments {
4288 self.write_newline();
4289 self.write_indent();
4290 self.write_formatted_comment(comment);
4291 }
4292 } else {
4293 for comment in &having.comments {
4294 self.write_space();
4295 self.write_formatted_comment(comment);
4296 }
4297 }
4298 self.write_clause_condition("HAVING", &having.this)?;
4299 }
4300
4301 if select.qualify_after_window {
4303 if let Some(windows) = &select.windows {
4305 self.write_window_clause(windows)?;
4306 }
4307 if let Some(qualify) = &select.qualify {
4308 self.write_clause_condition("QUALIFY", &qualify.this)?;
4309 }
4310 } else {
4311 if let Some(qualify) = &select.qualify {
4313 self.write_clause_condition("QUALIFY", &qualify.this)?;
4314 }
4315 if let Some(windows) = &select.windows {
4316 self.write_window_clause(windows)?;
4317 }
4318 }
4319
4320 if let Some(distribute_by) = &select.distribute_by {
4322 self.write_clause_expressions("DISTRIBUTE BY", &distribute_by.expressions)?;
4323 }
4324
4325 if let Some(cluster_by) = &select.cluster_by {
4327 self.write_order_clause("CLUSTER BY", &cluster_by.expressions)?;
4328 }
4329
4330 if let Some(sort_by) = &select.sort_by {
4332 self.write_order_clause("SORT BY", &sort_by.expressions)?;
4333 }
4334
4335 if let Some(order_by) = &select.order_by {
4337 if self.config.pretty {
4338 for comment in &order_by.comments {
4340 self.write_newline();
4341 self.write_indent();
4342 self.write_formatted_comment(comment);
4343 }
4344 } else {
4345 for comment in &order_by.comments {
4346 self.write_space();
4347 self.write_formatted_comment(comment);
4348 }
4349 }
4350 let keyword = if order_by.siblings {
4351 "ORDER SIBLINGS BY"
4352 } else {
4353 "ORDER BY"
4354 };
4355 self.write_order_clause(keyword, &order_by.expressions)?;
4356 }
4357
4358 if select.order_by.is_none()
4360 && select.fetch.is_some()
4361 && matches!(
4362 self.config.dialect,
4363 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4364 )
4365 {
4366 if self.config.pretty {
4367 self.write_newline();
4368 self.write_indent();
4369 } else {
4370 self.write_space();
4371 }
4372 self.write_keyword("ORDER BY (SELECT NULL) OFFSET 0 ROWS");
4373 }
4374
4375 let is_presto_like = matches!(
4380 self.config.dialect,
4381 Some(DialectType::Presto) | Some(DialectType::Trino)
4382 );
4383
4384 if is_presto_like && select.offset.is_some() {
4385 if let Some(offset) = &select.offset {
4387 if self.config.pretty {
4388 self.write_newline();
4389 self.write_indent();
4390 } else {
4391 self.write_space();
4392 }
4393 self.write_keyword("OFFSET");
4394 self.write_space();
4395 self.write_limit_expr(&offset.this)?;
4396 if offset.rows == Some(true) {
4397 self.write_space();
4398 self.write_keyword("ROWS");
4399 }
4400 }
4401 if let Some(limit) = &select.limit {
4402 if self.config.pretty {
4403 self.write_newline();
4404 self.write_indent();
4405 } else {
4406 self.write_space();
4407 }
4408 self.write_keyword("LIMIT");
4409 self.write_space();
4410 self.write_limit_expr(&limit.this)?;
4411 if limit.percent {
4412 self.write_space();
4413 self.write_keyword("PERCENT");
4414 }
4415 for comment in &limit.comments {
4417 self.write(" ");
4418 self.write_formatted_comment(comment);
4419 }
4420 }
4421 } else {
4422 let fetch_as_limit = select.fetch.as_ref().map_or(false, |fetch| {
4424 !fetch.percent
4425 && !fetch.with_ties
4426 && fetch.count.is_some()
4427 && matches!(
4428 self.config.dialect,
4429 Some(DialectType::Spark)
4430 | Some(DialectType::Hive)
4431 | Some(DialectType::DuckDB)
4432 | Some(DialectType::SQLite)
4433 | Some(DialectType::MySQL)
4434 | Some(DialectType::BigQuery)
4435 | Some(DialectType::Databricks)
4436 | Some(DialectType::StarRocks)
4437 | Some(DialectType::Doris)
4438 | Some(DialectType::Athena)
4439 | Some(DialectType::ClickHouse)
4440 | Some(DialectType::Redshift)
4441 )
4442 });
4443
4444 if let Some(limit) = &select.limit {
4446 if !matches!(self.config.dialect, Some(DialectType::TSQL)) {
4448 if self.config.pretty {
4449 self.write_newline();
4450 self.write_indent();
4451 } else {
4452 self.write_space();
4453 }
4454 self.write_keyword("LIMIT");
4455 self.write_space();
4456 self.write_limit_expr(&limit.this)?;
4457 if limit.percent {
4458 self.write_space();
4459 self.write_keyword("PERCENT");
4460 }
4461 for comment in &limit.comments {
4463 self.write(" ");
4464 self.write_formatted_comment(comment);
4465 }
4466 }
4467 }
4468
4469 if select.top.is_some() && !is_top_dialect && select.limit.is_none() {
4471 if let Some(top) = &select.top {
4472 if !top.percent && !top.with_ties {
4473 if self.config.pretty {
4474 self.write_newline();
4475 self.write_indent();
4476 } else {
4477 self.write_space();
4478 }
4479 self.write_keyword("LIMIT");
4480 self.write_space();
4481 self.generate_expression(&top.this)?;
4482 }
4483 }
4484 }
4485
4486 if fetch_as_limit && select.offset.is_some() {
4489 if let Some(fetch) = &select.fetch {
4490 if self.config.pretty {
4491 self.write_newline();
4492 self.write_indent();
4493 } else {
4494 self.write_space();
4495 }
4496 self.write_keyword("LIMIT");
4497 self.write_space();
4498 self.generate_expression(fetch.count.as_ref().unwrap())?;
4499 }
4500 }
4501
4502 if let Some(offset) = &select.offset {
4506 if self.config.pretty {
4507 self.write_newline();
4508 self.write_indent();
4509 } else {
4510 self.write_space();
4511 }
4512 if matches!(self.config.dialect, Some(DialectType::TSQL)) {
4513 self.write_keyword("OFFSET");
4515 self.write_space();
4516 self.write_limit_expr(&offset.this)?;
4517 self.write_space();
4518 self.write_keyword("ROWS");
4519 if let Some(limit) = &select.limit {
4521 self.write_space();
4522 self.write_keyword("FETCH NEXT");
4523 self.write_space();
4524 self.write_limit_expr(&limit.this)?;
4525 self.write_space();
4526 self.write_keyword("ROWS ONLY");
4527 }
4528 } else {
4529 self.write_keyword("OFFSET");
4530 self.write_space();
4531 self.write_limit_expr(&offset.this)?;
4532 if offset.rows == Some(true) {
4534 self.write_space();
4535 self.write_keyword("ROWS");
4536 }
4537 }
4538 }
4539 }
4540
4541 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4543 if let Some(limit_by) = &select.limit_by {
4544 if !limit_by.is_empty() {
4545 self.write_space();
4546 self.write_keyword("BY");
4547 self.write_space();
4548 for (i, expr) in limit_by.iter().enumerate() {
4549 if i > 0 {
4550 self.write(", ");
4551 }
4552 self.generate_expression(expr)?;
4553 }
4554 }
4555 }
4556 }
4557
4558 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4560 if let Some(settings) = &select.settings {
4561 if self.config.pretty {
4562 self.write_newline();
4563 self.write_indent();
4564 } else {
4565 self.write_space();
4566 }
4567 self.write_keyword("SETTINGS");
4568 self.write_space();
4569 for (i, expr) in settings.iter().enumerate() {
4570 if i > 0 {
4571 self.write(", ");
4572 }
4573 self.generate_expression(expr)?;
4574 }
4575 }
4576
4577 if let Some(format_expr) = &select.format {
4578 if self.config.pretty {
4579 self.write_newline();
4580 self.write_indent();
4581 } else {
4582 self.write_space();
4583 }
4584 self.write_keyword("FORMAT");
4585 self.write_space();
4586 self.generate_expression(format_expr)?;
4587 }
4588 }
4589
4590 if let Some(fetch) = &select.fetch {
4592 let fetch_already_as_limit = select.offset.is_some()
4594 && !fetch.percent
4595 && !fetch.with_ties
4596 && fetch.count.is_some()
4597 && matches!(
4598 self.config.dialect,
4599 Some(DialectType::Spark)
4600 | Some(DialectType::Hive)
4601 | Some(DialectType::DuckDB)
4602 | Some(DialectType::SQLite)
4603 | Some(DialectType::MySQL)
4604 | Some(DialectType::BigQuery)
4605 | Some(DialectType::Databricks)
4606 | Some(DialectType::StarRocks)
4607 | Some(DialectType::Doris)
4608 | Some(DialectType::Athena)
4609 | Some(DialectType::ClickHouse)
4610 | Some(DialectType::Redshift)
4611 );
4612
4613 if fetch_already_as_limit {
4614 } else {
4616 if self.config.pretty {
4617 self.write_newline();
4618 self.write_indent();
4619 } else {
4620 self.write_space();
4621 }
4622
4623 let use_limit = !fetch.percent
4625 && !fetch.with_ties
4626 && fetch.count.is_some()
4627 && matches!(
4628 self.config.dialect,
4629 Some(DialectType::Spark)
4630 | Some(DialectType::Hive)
4631 | Some(DialectType::DuckDB)
4632 | Some(DialectType::SQLite)
4633 | Some(DialectType::MySQL)
4634 | Some(DialectType::BigQuery)
4635 | Some(DialectType::Databricks)
4636 | Some(DialectType::StarRocks)
4637 | Some(DialectType::Doris)
4638 | Some(DialectType::Athena)
4639 | Some(DialectType::ClickHouse)
4640 | Some(DialectType::Redshift)
4641 );
4642
4643 if use_limit {
4644 self.write_keyword("LIMIT");
4645 self.write_space();
4646 self.generate_expression(fetch.count.as_ref().unwrap())?;
4647 } else {
4648 self.write_keyword("FETCH");
4649 self.write_space();
4650 self.write_keyword(&fetch.direction);
4651 if let Some(ref count) = fetch.count {
4652 self.write_space();
4653 self.generate_expression(count)?;
4654 }
4655 if fetch.percent {
4656 self.write_space();
4657 self.write_keyword("PERCENT");
4658 }
4659 if fetch.rows {
4660 self.write_space();
4661 self.write_keyword("ROWS");
4662 }
4663 if fetch.with_ties {
4664 self.write_space();
4665 self.write_keyword("WITH TIES");
4666 } else {
4667 self.write_space();
4668 self.write_keyword("ONLY");
4669 }
4670 }
4671 } }
4673
4674 if let Some(sample) = &select.sample {
4676 use crate::dialects::DialectType;
4677 if self.config.pretty {
4678 self.write_newline();
4679 } else {
4680 self.write_space();
4681 }
4682
4683 if sample.is_using_sample {
4684 self.write_keyword("USING SAMPLE");
4686 self.generate_sample_body(sample)?;
4687 } else {
4688 self.write_keyword("TABLESAMPLE");
4689
4690 let snowflake_bernoulli =
4692 matches!(self.config.dialect, Some(DialectType::Snowflake))
4693 && !sample.explicit_method;
4694 if snowflake_bernoulli {
4695 self.write_space();
4696 self.write_keyword("BERNOULLI");
4697 }
4698
4699 if matches!(sample.method, SampleMethod::Bucket) {
4701 self.write_space();
4702 self.write("(");
4703 self.write_keyword("BUCKET");
4704 self.write_space();
4705 if let Some(ref num) = sample.bucket_numerator {
4706 self.generate_expression(num)?;
4707 }
4708 self.write_space();
4709 self.write_keyword("OUT OF");
4710 self.write_space();
4711 if let Some(ref denom) = sample.bucket_denominator {
4712 self.generate_expression(denom)?;
4713 }
4714 if let Some(ref field) = sample.bucket_field {
4715 self.write_space();
4716 self.write_keyword("ON");
4717 self.write_space();
4718 self.generate_expression(field)?;
4719 }
4720 self.write(")");
4721 } else if sample.unit_after_size {
4722 if sample.explicit_method && sample.method_before_size {
4724 self.write_space();
4725 match sample.method {
4726 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
4727 SampleMethod::System => self.write_keyword("SYSTEM"),
4728 SampleMethod::Block => self.write_keyword("BLOCK"),
4729 SampleMethod::Row => self.write_keyword("ROW"),
4730 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
4731 _ => {}
4732 }
4733 }
4734 self.write(" (");
4735 self.generate_expression(&sample.size)?;
4736 self.write_space();
4737 match sample.method {
4738 SampleMethod::Percent => self.write_keyword("PERCENT"),
4739 SampleMethod::Row => self.write_keyword("ROWS"),
4740 SampleMethod::Reservoir => self.write_keyword("ROWS"),
4741 _ => {
4742 self.write_keyword("PERCENT");
4743 }
4744 }
4745 self.write(")");
4746 } else {
4747 self.write_space();
4749 match sample.method {
4750 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
4751 SampleMethod::System => self.write_keyword("SYSTEM"),
4752 SampleMethod::Block => self.write_keyword("BLOCK"),
4753 SampleMethod::Row => self.write_keyword("ROW"),
4754 SampleMethod::Percent => self.write_keyword("BERNOULLI"),
4755 SampleMethod::Bucket => {}
4756 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
4757 }
4758 self.write(" (");
4759 self.generate_expression(&sample.size)?;
4760 if matches!(sample.method, SampleMethod::Percent) {
4761 self.write_space();
4762 self.write_keyword("PERCENT");
4763 }
4764 self.write(")");
4765 }
4766 }
4767
4768 if let Some(seed) = &sample.seed {
4769 self.write_space();
4770 let use_seed = sample.use_seed_keyword
4772 && !matches!(
4773 self.config.dialect,
4774 Some(crate::dialects::DialectType::Databricks)
4775 | Some(crate::dialects::DialectType::Spark)
4776 );
4777 if use_seed {
4778 self.write_keyword("SEED");
4779 } else {
4780 self.write_keyword("REPEATABLE");
4781 }
4782 self.write(" (");
4783 self.generate_expression(seed)?;
4784 self.write(")");
4785 }
4786 }
4787
4788 if self.config.locking_reads_supported {
4791 for lock in &select.locks {
4792 if self.config.pretty {
4793 self.write_newline();
4794 self.write_indent();
4795 } else {
4796 self.write_space();
4797 }
4798 self.generate_lock(lock)?;
4799 }
4800 }
4801
4802 if !select.for_xml.is_empty() {
4804 if self.config.pretty {
4805 self.write_newline();
4806 self.write_indent();
4807 } else {
4808 self.write_space();
4809 }
4810 self.write_keyword("FOR XML");
4811 for (i, opt) in select.for_xml.iter().enumerate() {
4812 if self.config.pretty {
4813 if i > 0 {
4814 self.write(",");
4815 }
4816 self.write_newline();
4817 self.write_indent();
4818 self.write(" "); } else {
4820 if i > 0 {
4821 self.write(",");
4822 }
4823 self.write_space();
4824 }
4825 self.generate_for_xml_option(opt)?;
4826 }
4827 }
4828
4829 if let Some(ref option) = select.option {
4831 if matches!(
4832 self.config.dialect,
4833 Some(crate::dialects::DialectType::TSQL)
4834 | Some(crate::dialects::DialectType::Fabric)
4835 ) {
4836 self.write_space();
4837 self.write(option);
4838 }
4839 }
4840
4841 Ok(())
4842 }
4843
4844 fn generate_for_xml_option(&mut self, opt: &Expression) -> Result<()> {
4846 match opt {
4847 Expression::QueryOption(qo) => {
4848 if let Expression::Var(var) = &*qo.this {
4850 self.write(&var.this);
4851 } else {
4852 self.generate_expression(&qo.this)?;
4853 }
4854 if let Some(expr) = &qo.expression {
4856 self.write("(");
4857 self.generate_expression(expr)?;
4858 self.write(")");
4859 }
4860 }
4861 _ => {
4862 self.generate_expression(opt)?;
4863 }
4864 }
4865 Ok(())
4866 }
4867
4868 fn generate_with(&mut self, with: &With) -> Result<()> {
4869 use crate::dialects::DialectType;
4870
4871 for comment in &with.leading_comments {
4873 self.write_formatted_comment(comment);
4874 self.write(" ");
4875 }
4876 self.write_keyword("WITH");
4877 if with.recursive && self.config.cte_recursive_keyword_required {
4878 self.write_space();
4879 self.write_keyword("RECURSIVE");
4880 }
4881 self.write_space();
4882
4883 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
4885
4886 for (i, cte) in with.ctes.iter().enumerate() {
4887 if i > 0 {
4888 self.write(",");
4889 if self.config.pretty {
4890 self.write_space();
4891 } else {
4892 self.write(" ");
4893 }
4894 }
4895 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !cte.alias_first {
4896 self.generate_expression(&cte.this)?;
4897 self.write_space();
4898 self.write_keyword("AS");
4899 self.write_space();
4900 self.generate_identifier(&cte.alias)?;
4901 continue;
4902 }
4903 self.generate_identifier(&cte.alias)?;
4904 for comment in &cte.comments {
4906 self.write_space();
4907 self.write_formatted_comment(comment);
4908 }
4909 if !cte.columns.is_empty() && !skip_cte_columns {
4910 self.write("(");
4911 for (j, col) in cte.columns.iter().enumerate() {
4912 if j > 0 {
4913 self.write(", ");
4914 }
4915 self.generate_identifier(col)?;
4916 }
4917 self.write(")");
4918 }
4919 if !cte.key_expressions.is_empty() {
4921 self.write_space();
4922 self.write_keyword("USING KEY");
4923 self.write(" (");
4924 for (i, key) in cte.key_expressions.iter().enumerate() {
4925 if i > 0 {
4926 self.write(", ");
4927 }
4928 self.generate_identifier(key)?;
4929 }
4930 self.write(")");
4931 }
4932 self.write_space();
4933 self.write_keyword("AS");
4934 if let Some(materialized) = cte.materialized {
4936 self.write_space();
4937 if materialized {
4938 self.write_keyword("MATERIALIZED");
4939 } else {
4940 self.write_keyword("NOT MATERIALIZED");
4941 }
4942 }
4943 self.write(" (");
4944 if self.config.pretty {
4945 self.write_newline();
4946 self.indent_level += 1;
4947 self.write_indent();
4948 }
4949 let wrap_values_in_select = matches!(
4952 self.config.dialect,
4953 Some(DialectType::Spark) | Some(DialectType::Databricks)
4954 ) && matches!(&cte.this, Expression::Values(_));
4955
4956 if wrap_values_in_select {
4957 self.write_keyword("SELECT");
4958 self.write(" * ");
4959 self.write_keyword("FROM");
4960 self.write_space();
4961 }
4962 self.generate_expression(&cte.this)?;
4963 if self.config.pretty {
4964 self.write_newline();
4965 self.indent_level -= 1;
4966 self.write_indent();
4967 }
4968 self.write(")");
4969 }
4970
4971 if let Some(search) = &with.search {
4973 self.write_space();
4974 self.generate_expression(search)?;
4975 }
4976
4977 Ok(())
4978 }
4979
4980 fn generate_joins_with_nesting(&mut self, joins: &[Join]) -> Result<()> {
4984 let mut i = 0;
4985 while i < joins.len() {
4986 if joins[i].deferred_condition {
4987 let parent_group = joins[i].nesting_group;
4988
4989 self.generate_join_without_condition(&joins[i])?;
4992
4993 let child_start = i + 1;
4995 let mut child_end = child_start;
4996 while child_end < joins.len()
4997 && !joins[child_end].deferred_condition
4998 && joins[child_end].nesting_group == parent_group
4999 {
5000 child_end += 1;
5001 }
5002
5003 if child_start < child_end {
5005 self.indent_level += 1;
5006 for j in child_start..child_end {
5007 self.generate_join(&joins[j])?;
5008 }
5009 self.indent_level -= 1;
5010 }
5011
5012 self.generate_join_condition(&joins[i])?;
5014
5015 i = child_end;
5016 } else {
5017 self.generate_join(&joins[i])?;
5019 i += 1;
5020 }
5021 }
5022 Ok(())
5023 }
5024
5025 fn generate_join_without_condition(&mut self, join: &Join) -> Result<()> {
5028 let mut join_copy = join.clone();
5031 join_copy.on = None;
5032 join_copy.using = Vec::new();
5033 join_copy.deferred_condition = false;
5034 self.generate_join(&join_copy)
5035 }
5036
5037 fn generate_join(&mut self, join: &Join) -> Result<()> {
5038 if join.kind == JoinKind::Implicit {
5040 self.write(",");
5041 if self.config.pretty {
5042 self.write_newline();
5043 self.write_indent();
5044 } else {
5045 self.write_space();
5046 }
5047 self.generate_expression(&join.this)?;
5048 return Ok(());
5049 }
5050
5051 if self.config.pretty {
5052 self.write_newline();
5053 self.write_indent();
5054 } else {
5055 self.write_space();
5056 }
5057
5058 let hint_str = if self.config.join_hints {
5061 join.join_hint
5062 .as_ref()
5063 .map(|h| format!(" {}", h))
5064 .unwrap_or_default()
5065 } else {
5066 String::new()
5067 };
5068
5069 let clickhouse_join_keyword =
5070 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
5071 if let Some(hint) = &join.join_hint {
5072 let mut global = false;
5073 let mut strictness: Option<&'static str> = None;
5074 for part in hint.split_whitespace() {
5075 match part.to_uppercase().as_str() {
5076 "GLOBAL" => global = true,
5077 "ANY" => strictness = Some("ANY"),
5078 "ASOF" => strictness = Some("ASOF"),
5079 "SEMI" => strictness = Some("SEMI"),
5080 "ANTI" => strictness = Some("ANTI"),
5081 _ => {}
5082 }
5083 }
5084
5085 if global || strictness.is_some() {
5086 let join_type = match join.kind {
5087 JoinKind::Left => {
5088 if join.use_outer_keyword {
5089 "LEFT OUTER"
5090 } else if join.use_inner_keyword {
5091 "LEFT INNER"
5092 } else {
5093 "LEFT"
5094 }
5095 }
5096 JoinKind::Right => {
5097 if join.use_outer_keyword {
5098 "RIGHT OUTER"
5099 } else if join.use_inner_keyword {
5100 "RIGHT INNER"
5101 } else {
5102 "RIGHT"
5103 }
5104 }
5105 JoinKind::Full => {
5106 if join.use_outer_keyword {
5107 "FULL OUTER"
5108 } else {
5109 "FULL"
5110 }
5111 }
5112 JoinKind::Inner => {
5113 if join.use_inner_keyword {
5114 "INNER"
5115 } else {
5116 ""
5117 }
5118 }
5119 _ => "",
5120 };
5121
5122 let mut parts = Vec::new();
5123 if global {
5124 parts.push("GLOBAL");
5125 }
5126 if !join_type.is_empty() {
5127 parts.push(join_type);
5128 }
5129 if let Some(strict) = strictness {
5130 parts.push(strict);
5131 }
5132 parts.push("JOIN");
5133 Some(parts.join(" "))
5134 } else {
5135 None
5136 }
5137 } else {
5138 None
5139 }
5140 } else {
5141 None
5142 };
5143
5144 if !join.comments.is_empty() {
5148 if self.config.pretty {
5149 let trimmed = self.output.trim_end().len();
5154 self.output.truncate(trimmed);
5155 for comment in &join.comments {
5156 self.write_newline();
5157 self.write_indent();
5158 self.write_formatted_comment(comment);
5159 }
5160 self.write_newline();
5161 self.write_indent();
5162 } else {
5163 for comment in &join.comments {
5164 self.write_formatted_comment(comment);
5165 self.write_space();
5166 }
5167 }
5168 }
5169
5170 let directed_str = if join.directed { " DIRECTED" } else { "" };
5171
5172 if let Some(keyword) = clickhouse_join_keyword {
5173 self.write_keyword(&keyword);
5174 } else {
5175 match join.kind {
5176 JoinKind::Inner => {
5177 if join.use_inner_keyword {
5178 self.write_keyword(&format!("INNER{}{} JOIN", hint_str, directed_str));
5179 } else {
5180 self.write_keyword(&format!(
5181 "{}{}JOIN",
5182 if hint_str.is_empty() {
5183 String::new()
5184 } else {
5185 format!("{} ", hint_str.trim())
5186 },
5187 if directed_str.is_empty() {
5188 ""
5189 } else {
5190 "DIRECTED "
5191 }
5192 ));
5193 }
5194 }
5195 JoinKind::Left => {
5196 if join.use_outer_keyword {
5197 self.write_keyword(&format!("LEFT OUTER{}{} JOIN", hint_str, directed_str));
5198 } else if join.use_inner_keyword {
5199 self.write_keyword(&format!("LEFT INNER{}{} JOIN", hint_str, directed_str));
5200 } else {
5201 self.write_keyword(&format!("LEFT{}{} JOIN", hint_str, directed_str));
5202 }
5203 }
5204 JoinKind::Right => {
5205 if join.use_outer_keyword {
5206 self.write_keyword(&format!(
5207 "RIGHT OUTER{}{} JOIN",
5208 hint_str, directed_str
5209 ));
5210 } else if join.use_inner_keyword {
5211 self.write_keyword(&format!(
5212 "RIGHT INNER{}{} JOIN",
5213 hint_str, directed_str
5214 ));
5215 } else {
5216 self.write_keyword(&format!("RIGHT{}{} JOIN", hint_str, directed_str));
5217 }
5218 }
5219 JoinKind::Full => {
5220 if join.use_outer_keyword {
5221 self.write_keyword(&format!("FULL OUTER{}{} JOIN", hint_str, directed_str));
5222 } else {
5223 self.write_keyword(&format!("FULL{}{} JOIN", hint_str, directed_str));
5224 }
5225 }
5226 JoinKind::Outer => self.write_keyword(&format!("OUTER{} JOIN", directed_str)),
5227 JoinKind::Cross => self.write_keyword(&format!("CROSS{} JOIN", directed_str)),
5228 JoinKind::Natural => {
5229 if join.use_inner_keyword {
5230 self.write_keyword(&format!("NATURAL INNER{} JOIN", directed_str));
5231 } else {
5232 self.write_keyword(&format!("NATURAL{} JOIN", directed_str));
5233 }
5234 }
5235 JoinKind::NaturalLeft => {
5236 if join.use_outer_keyword {
5237 self.write_keyword(&format!("NATURAL LEFT OUTER{} JOIN", directed_str));
5238 } else {
5239 self.write_keyword(&format!("NATURAL LEFT{} JOIN", directed_str));
5240 }
5241 }
5242 JoinKind::NaturalRight => {
5243 if join.use_outer_keyword {
5244 self.write_keyword(&format!("NATURAL RIGHT OUTER{} JOIN", directed_str));
5245 } else {
5246 self.write_keyword(&format!("NATURAL RIGHT{} JOIN", directed_str));
5247 }
5248 }
5249 JoinKind::NaturalFull => {
5250 if join.use_outer_keyword {
5251 self.write_keyword(&format!("NATURAL FULL OUTER{} JOIN", directed_str));
5252 } else {
5253 self.write_keyword(&format!("NATURAL FULL{} JOIN", directed_str));
5254 }
5255 }
5256 JoinKind::Semi => self.write_keyword("SEMI JOIN"),
5257 JoinKind::Anti => self.write_keyword("ANTI JOIN"),
5258 JoinKind::LeftSemi => self.write_keyword("LEFT SEMI JOIN"),
5259 JoinKind::LeftAnti => self.write_keyword("LEFT ANTI JOIN"),
5260 JoinKind::RightSemi => self.write_keyword("RIGHT SEMI JOIN"),
5261 JoinKind::RightAnti => self.write_keyword("RIGHT ANTI JOIN"),
5262 JoinKind::CrossApply => {
5263 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
5265 self.write_keyword("CROSS APPLY");
5266 } else {
5267 self.write_keyword("INNER JOIN LATERAL");
5268 }
5269 }
5270 JoinKind::OuterApply => {
5271 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
5273 self.write_keyword("OUTER APPLY");
5274 } else {
5275 self.write_keyword("LEFT JOIN LATERAL");
5276 }
5277 }
5278 JoinKind::AsOf => self.write_keyword("ASOF JOIN"),
5279 JoinKind::AsOfLeft => {
5280 if join.use_outer_keyword {
5281 self.write_keyword("ASOF LEFT OUTER JOIN");
5282 } else {
5283 self.write_keyword("ASOF LEFT JOIN");
5284 }
5285 }
5286 JoinKind::AsOfRight => {
5287 if join.use_outer_keyword {
5288 self.write_keyword("ASOF RIGHT OUTER JOIN");
5289 } else {
5290 self.write_keyword("ASOF RIGHT JOIN");
5291 }
5292 }
5293 JoinKind::Lateral => self.write_keyword("LATERAL JOIN"),
5294 JoinKind::LeftLateral => {
5295 if join.use_outer_keyword {
5296 self.write_keyword("LEFT OUTER LATERAL JOIN");
5297 } else {
5298 self.write_keyword("LEFT LATERAL JOIN");
5299 }
5300 }
5301 JoinKind::Straight => self.write_keyword("STRAIGHT_JOIN"),
5302 JoinKind::Implicit => {
5303 use crate::dialects::DialectType;
5307 let is_cj_dialect = matches!(
5308 self.config.dialect,
5309 Some(DialectType::BigQuery)
5310 | Some(DialectType::Hive)
5311 | Some(DialectType::Spark)
5312 | Some(DialectType::Databricks)
5313 );
5314 let source_is_same = self.config.source_dialect.is_some()
5315 && self.config.source_dialect == self.config.dialect;
5316 let source_is_cj = matches!(
5317 self.config.source_dialect,
5318 Some(DialectType::BigQuery)
5319 | Some(DialectType::Hive)
5320 | Some(DialectType::Spark)
5321 | Some(DialectType::Databricks)
5322 );
5323 if is_cj_dialect
5324 && (source_is_same || source_is_cj || self.config.source_dialect.is_none())
5325 {
5326 self.write_keyword("CROSS JOIN");
5327 } else {
5328 self.output.truncate(self.output.trim_end().len());
5332 self.write(",");
5333 }
5334 }
5335 JoinKind::Array => self.write_keyword("ARRAY JOIN"),
5336 JoinKind::LeftArray => self.write_keyword("LEFT ARRAY JOIN"),
5337 JoinKind::Paste => self.write_keyword("PASTE JOIN"),
5338 }
5339 }
5340
5341 if matches!(join.kind, JoinKind::Array | JoinKind::LeftArray) {
5343 self.write_space();
5344 match &join.this {
5345 Expression::Tuple(t) => {
5346 for (i, item) in t.expressions.iter().enumerate() {
5347 if i > 0 {
5348 self.write(", ");
5349 }
5350 self.generate_expression(item)?;
5351 }
5352 }
5353 other => {
5354 self.generate_expression(other)?;
5355 }
5356 }
5357 } else {
5358 self.write_space();
5359 self.generate_expression(&join.this)?;
5360 }
5361
5362 if !join.deferred_condition {
5364 if let Some(match_cond) = &join.match_condition {
5366 self.write_space();
5367 self.write_keyword("MATCH_CONDITION");
5368 self.write(" (");
5369 self.generate_expression(match_cond)?;
5370 self.write(")");
5371 }
5372
5373 if let Some(on) = &join.on {
5374 if self.config.pretty {
5375 self.write_newline();
5376 self.indent_level += 1;
5377 self.write_indent();
5378 self.write_keyword("ON");
5379 self.write_space();
5380 self.generate_join_on_condition(on)?;
5381 self.indent_level -= 1;
5382 } else {
5383 self.write_space();
5384 self.write_keyword("ON");
5385 self.write_space();
5386 self.generate_expression(on)?;
5387 }
5388 }
5389
5390 if !join.using.is_empty() {
5391 if self.config.pretty {
5392 self.write_newline();
5393 self.indent_level += 1;
5394 self.write_indent();
5395 self.write_keyword("USING");
5396 self.write(" (");
5397 for (i, col) in join.using.iter().enumerate() {
5398 if i > 0 {
5399 self.write(", ");
5400 }
5401 self.generate_identifier(col)?;
5402 }
5403 self.write(")");
5404 self.indent_level -= 1;
5405 } else {
5406 self.write_space();
5407 self.write_keyword("USING");
5408 self.write(" (");
5409 for (i, col) in join.using.iter().enumerate() {
5410 if i > 0 {
5411 self.write(", ");
5412 }
5413 self.generate_identifier(col)?;
5414 }
5415 self.write(")");
5416 }
5417 }
5418 }
5419
5420 for pivot in &join.pivots {
5422 self.write_space();
5423 self.generate_expression(pivot)?;
5424 }
5425
5426 Ok(())
5427 }
5428
5429 fn generate_join_condition(&mut self, join: &Join) -> Result<()> {
5431 if let Some(match_cond) = &join.match_condition {
5433 self.write_space();
5434 self.write_keyword("MATCH_CONDITION");
5435 self.write(" (");
5436 self.generate_expression(match_cond)?;
5437 self.write(")");
5438 }
5439
5440 if let Some(on) = &join.on {
5441 if self.config.pretty {
5442 self.write_newline();
5443 self.indent_level += 1;
5444 self.write_indent();
5445 self.write_keyword("ON");
5446 self.write_space();
5447 self.generate_join_on_condition(on)?;
5449 self.indent_level -= 1;
5450 } else {
5451 self.write_space();
5452 self.write_keyword("ON");
5453 self.write_space();
5454 self.generate_expression(on)?;
5455 }
5456 }
5457
5458 if !join.using.is_empty() {
5459 if self.config.pretty {
5460 self.write_newline();
5461 self.indent_level += 1;
5462 self.write_indent();
5463 self.write_keyword("USING");
5464 self.write(" (");
5465 for (i, col) in join.using.iter().enumerate() {
5466 if i > 0 {
5467 self.write(", ");
5468 }
5469 self.generate_identifier(col)?;
5470 }
5471 self.write(")");
5472 self.indent_level -= 1;
5473 } else {
5474 self.write_space();
5475 self.write_keyword("USING");
5476 self.write(" (");
5477 for (i, col) in join.using.iter().enumerate() {
5478 if i > 0 {
5479 self.write(", ");
5480 }
5481 self.generate_identifier(col)?;
5482 }
5483 self.write(")");
5484 }
5485 }
5486
5487 for pivot in &join.pivots {
5489 self.write_space();
5490 self.generate_expression(pivot)?;
5491 }
5492
5493 Ok(())
5494 }
5495
5496 fn generate_join_on_condition(&mut self, expr: &Expression) -> Result<()> {
5498 if let Expression::And(and_op) = expr {
5499 if let Some(conditions) = self.flatten_connector_terms(and_op, ConnectorOperator::And) {
5500 self.generate_expression(conditions[0])?;
5501 for condition in conditions.iter().skip(1) {
5502 self.write_newline();
5503 self.write_indent();
5504 self.write_keyword("AND");
5505 self.write_space();
5506 self.generate_expression(condition)?;
5507 }
5508 return Ok(());
5509 }
5510 }
5511
5512 self.generate_expression(expr)
5513 }
5514
5515 fn generate_joined_table(&mut self, jt: &JoinedTable) -> Result<()> {
5516 self.write("(");
5518 self.generate_expression(&jt.left)?;
5519
5520 for join in &jt.joins {
5522 self.generate_join(join)?;
5523 }
5524
5525 for lv in &jt.lateral_views {
5527 self.generate_lateral_view(lv)?;
5528 }
5529
5530 self.write(")");
5531
5532 if let Some(alias) = &jt.alias {
5534 self.write_space();
5535 self.write_keyword("AS");
5536 self.write_space();
5537 self.generate_identifier(alias)?;
5538 }
5539
5540 Ok(())
5541 }
5542
5543 fn generate_lateral_view(&mut self, lv: &LateralView) -> Result<()> {
5544 use crate::dialects::DialectType;
5545
5546 if self.config.pretty {
5547 self.write_newline();
5548 self.write_indent();
5549 } else {
5550 self.write_space();
5551 }
5552
5553 let use_lateral_join = matches!(
5556 self.config.dialect,
5557 Some(DialectType::PostgreSQL)
5558 | Some(DialectType::DuckDB)
5559 | Some(DialectType::Snowflake)
5560 | Some(DialectType::TSQL)
5561 | Some(DialectType::Presto)
5562 | Some(DialectType::Trino)
5563 | Some(DialectType::Athena)
5564 );
5565
5566 let use_unnest = matches!(
5568 self.config.dialect,
5569 Some(DialectType::DuckDB)
5570 | Some(DialectType::Presto)
5571 | Some(DialectType::Trino)
5572 | Some(DialectType::Athena)
5573 );
5574
5575 let (is_posexplode, func_args) = match &lv.this {
5577 Expression::Explode(uf) => {
5578 (false, vec![uf.this.clone()])
5580 }
5581 Expression::Unnest(uf) => {
5582 let mut args = vec![uf.this.clone()];
5583 args.extend(uf.expressions.clone());
5584 (false, args)
5585 }
5586 Expression::Function(func) => {
5587 let name = func.name.to_uppercase();
5588 if name == "POSEXPLODE" || name == "POSEXPLODE_OUTER" {
5589 (true, func.args.clone())
5590 } else if name == "EXPLODE" || name == "EXPLODE_OUTER" || name == "INLINE" {
5591 (false, func.args.clone())
5592 } else {
5593 (false, vec![])
5594 }
5595 }
5596 _ => (false, vec![]),
5597 };
5598
5599 if use_lateral_join {
5600 if lv.outer {
5602 self.write_keyword("LEFT JOIN LATERAL");
5603 } else {
5604 self.write_keyword("CROSS JOIN");
5605 }
5606 self.write_space();
5607
5608 if use_unnest && !func_args.is_empty() {
5609 let unnest_args = if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
5612 func_args
5614 .iter()
5615 .map(|a| {
5616 if let Expression::Function(ref f) = a {
5617 if f.name.to_uppercase() == "ARRAY" && f.args.len() == 1 {
5618 return Expression::ArrayFunc(Box::new(
5619 crate::expressions::ArrayConstructor {
5620 expressions: f.args.clone(),
5621 bracket_notation: true,
5622 use_list_keyword: false,
5623 },
5624 ));
5625 }
5626 }
5627 a.clone()
5628 })
5629 .collect::<Vec<_>>()
5630 } else if matches!(
5631 self.config.dialect,
5632 Some(DialectType::Presto)
5633 | Some(DialectType::Trino)
5634 | Some(DialectType::Athena)
5635 ) {
5636 func_args
5638 .iter()
5639 .map(|a| {
5640 if let Expression::Function(ref f) = a {
5641 if f.name.to_uppercase() == "ARRAY" && f.args.len() >= 1 {
5642 return Expression::ArrayFunc(Box::new(
5643 crate::expressions::ArrayConstructor {
5644 expressions: f.args.clone(),
5645 bracket_notation: true,
5646 use_list_keyword: false,
5647 },
5648 ));
5649 }
5650 }
5651 a.clone()
5652 })
5653 .collect::<Vec<_>>()
5654 } else {
5655 func_args
5656 };
5657
5658 if is_posexplode {
5660 self.write_keyword("LATERAL");
5661 self.write(" (");
5662 self.write_keyword("SELECT");
5663 self.write_space();
5664
5665 let pos_alias = if !lv.column_aliases.is_empty() {
5668 lv.column_aliases[0].clone()
5669 } else {
5670 Identifier::new("pos")
5671 };
5672 let data_aliases: Vec<Identifier> = if lv.column_aliases.len() > 1 {
5673 lv.column_aliases[1..].to_vec()
5674 } else {
5675 vec![Identifier::new("col")]
5676 };
5677
5678 self.generate_identifier(&pos_alias)?;
5680 self.write(" - 1");
5681 self.write_space();
5682 self.write_keyword("AS");
5683 self.write_space();
5684 self.generate_identifier(&pos_alias)?;
5685
5686 for data_col in &data_aliases {
5688 self.write(", ");
5689 self.generate_identifier(data_col)?;
5690 }
5691
5692 self.write_space();
5693 self.write_keyword("FROM");
5694 self.write_space();
5695 self.write_keyword("UNNEST");
5696 self.write("(");
5697 for (i, arg) in unnest_args.iter().enumerate() {
5698 if i > 0 {
5699 self.write(", ");
5700 }
5701 self.generate_expression(arg)?;
5702 }
5703 self.write(")");
5704 self.write_space();
5705 self.write_keyword("WITH ORDINALITY");
5706 self.write_space();
5707 self.write_keyword("AS");
5708 self.write_space();
5709
5710 let table_alias_ident = lv
5712 .table_alias
5713 .clone()
5714 .unwrap_or_else(|| Identifier::new("t"));
5715 self.generate_identifier(&table_alias_ident)?;
5716 self.write("(");
5717 for (i, data_col) in data_aliases.iter().enumerate() {
5718 if i > 0 {
5719 self.write(", ");
5720 }
5721 self.generate_identifier(data_col)?;
5722 }
5723 self.write(", ");
5724 self.generate_identifier(&pos_alias)?;
5725 self.write("))");
5726 } else {
5727 self.write_keyword("UNNEST");
5728 self.write("(");
5729 for (i, arg) in unnest_args.iter().enumerate() {
5730 if i > 0 {
5731 self.write(", ");
5732 }
5733 self.generate_expression(arg)?;
5734 }
5735 self.write(")");
5736
5737 if let Some(alias) = &lv.table_alias {
5739 self.write_space();
5740 self.write_keyword("AS");
5741 self.write_space();
5742 self.generate_identifier(alias)?;
5743 if !lv.column_aliases.is_empty() {
5744 self.write("(");
5745 for (i, col) in lv.column_aliases.iter().enumerate() {
5746 if i > 0 {
5747 self.write(", ");
5748 }
5749 self.generate_identifier(col)?;
5750 }
5751 self.write(")");
5752 }
5753 } else if !lv.column_aliases.is_empty() {
5754 self.write_space();
5755 self.write_keyword("AS");
5756 self.write(" t(");
5757 for (i, col) in lv.column_aliases.iter().enumerate() {
5758 if i > 0 {
5759 self.write(", ");
5760 }
5761 self.generate_identifier(col)?;
5762 }
5763 self.write(")");
5764 }
5765 }
5766 } else {
5767 if !lv.outer {
5769 self.write_keyword("LATERAL");
5770 self.write_space();
5771 }
5772 self.generate_expression(&lv.this)?;
5773
5774 if let Some(alias) = &lv.table_alias {
5776 self.write_space();
5777 self.write_keyword("AS");
5778 self.write_space();
5779 self.generate_identifier(alias)?;
5780 if !lv.column_aliases.is_empty() {
5781 self.write("(");
5782 for (i, col) in lv.column_aliases.iter().enumerate() {
5783 if i > 0 {
5784 self.write(", ");
5785 }
5786 self.generate_identifier(col)?;
5787 }
5788 self.write(")");
5789 }
5790 } else if !lv.column_aliases.is_empty() {
5791 self.write_space();
5792 self.write_keyword("AS");
5793 self.write(" t(");
5794 for (i, col) in lv.column_aliases.iter().enumerate() {
5795 if i > 0 {
5796 self.write(", ");
5797 }
5798 self.generate_identifier(col)?;
5799 }
5800 self.write(")");
5801 }
5802 }
5803
5804 if lv.outer {
5806 self.write_space();
5807 self.write_keyword("ON TRUE");
5808 }
5809 } else {
5810 self.write_keyword("LATERAL VIEW");
5812 if lv.outer {
5813 self.write_space();
5814 self.write_keyword("OUTER");
5815 }
5816 if self.config.pretty {
5817 self.write_newline();
5818 self.write_indent();
5819 } else {
5820 self.write_space();
5821 }
5822 self.generate_expression(&lv.this)?;
5823
5824 if let Some(alias) = &lv.table_alias {
5826 self.write_space();
5827 self.generate_identifier(alias)?;
5828 }
5829
5830 if !lv.column_aliases.is_empty() {
5832 self.write_space();
5833 self.write_keyword("AS");
5834 self.write_space();
5835 for (i, col) in lv.column_aliases.iter().enumerate() {
5836 if i > 0 {
5837 self.write(", ");
5838 }
5839 self.generate_identifier(col)?;
5840 }
5841 }
5842 }
5843
5844 Ok(())
5845 }
5846
5847 fn generate_union(&mut self, union: &Union) -> Result<()> {
5848 if let Some(with) = &union.with {
5850 self.generate_with(with)?;
5851 self.write_space();
5852 }
5853 self.generate_expression(&union.left)?;
5854 if self.config.pretty {
5855 self.write_newline();
5856 self.write_indent();
5857 } else {
5858 self.write_space();
5859 }
5860
5861 if let Some(side) = &union.side {
5863 self.write_keyword(side);
5864 self.write_space();
5865 }
5866 if let Some(kind) = &union.kind {
5867 self.write_keyword(kind);
5868 self.write_space();
5869 }
5870
5871 self.write_keyword("UNION");
5872 if union.all {
5873 self.write_space();
5874 self.write_keyword("ALL");
5875 } else if union.distinct {
5876 self.write_space();
5877 self.write_keyword("DISTINCT");
5878 }
5879
5880 if union.corresponding || union.by_name {
5883 self.write_space();
5884 self.write_keyword("BY NAME");
5885 }
5886 if !union.on_columns.is_empty() {
5887 self.write_space();
5888 self.write_keyword("ON");
5889 self.write(" (");
5890 for (i, col) in union.on_columns.iter().enumerate() {
5891 if i > 0 {
5892 self.write(", ");
5893 }
5894 self.generate_expression(col)?;
5895 }
5896 self.write(")");
5897 }
5898
5899 if self.config.pretty {
5900 self.write_newline();
5901 self.write_indent();
5902 } else {
5903 self.write_space();
5904 }
5905 self.generate_expression(&union.right)?;
5906 if let Some(order_by) = &union.order_by {
5908 if self.config.pretty {
5909 self.write_newline();
5910 } else {
5911 self.write_space();
5912 }
5913 self.write_keyword("ORDER BY");
5914 self.write_space();
5915 for (i, ordered) in order_by.expressions.iter().enumerate() {
5916 if i > 0 {
5917 self.write(", ");
5918 }
5919 self.generate_ordered(ordered)?;
5920 }
5921 }
5922 if let Some(limit) = &union.limit {
5923 if self.config.pretty {
5924 self.write_newline();
5925 } else {
5926 self.write_space();
5927 }
5928 self.write_keyword("LIMIT");
5929 self.write_space();
5930 self.generate_expression(limit)?;
5931 }
5932 if let Some(offset) = &union.offset {
5933 if self.config.pretty {
5934 self.write_newline();
5935 } else {
5936 self.write_space();
5937 }
5938 self.write_keyword("OFFSET");
5939 self.write_space();
5940 self.generate_expression(offset)?;
5941 }
5942 if let Some(distribute_by) = &union.distribute_by {
5944 self.write_space();
5945 self.write_keyword("DISTRIBUTE BY");
5946 self.write_space();
5947 for (i, expr) in distribute_by.expressions.iter().enumerate() {
5948 if i > 0 {
5949 self.write(", ");
5950 }
5951 self.generate_expression(expr)?;
5952 }
5953 }
5954 if let Some(sort_by) = &union.sort_by {
5956 self.write_space();
5957 self.write_keyword("SORT BY");
5958 self.write_space();
5959 for (i, ord) in sort_by.expressions.iter().enumerate() {
5960 if i > 0 {
5961 self.write(", ");
5962 }
5963 self.generate_ordered(ord)?;
5964 }
5965 }
5966 if let Some(cluster_by) = &union.cluster_by {
5968 self.write_space();
5969 self.write_keyword("CLUSTER BY");
5970 self.write_space();
5971 for (i, ord) in cluster_by.expressions.iter().enumerate() {
5972 if i > 0 {
5973 self.write(", ");
5974 }
5975 self.generate_ordered(ord)?;
5976 }
5977 }
5978 Ok(())
5979 }
5980
5981 fn generate_intersect(&mut self, intersect: &Intersect) -> Result<()> {
5982 if let Some(with) = &intersect.with {
5984 self.generate_with(with)?;
5985 self.write_space();
5986 }
5987 self.generate_expression(&intersect.left)?;
5988 if self.config.pretty {
5989 self.write_newline();
5990 self.write_indent();
5991 } else {
5992 self.write_space();
5993 }
5994
5995 if let Some(side) = &intersect.side {
5997 self.write_keyword(side);
5998 self.write_space();
5999 }
6000 if let Some(kind) = &intersect.kind {
6001 self.write_keyword(kind);
6002 self.write_space();
6003 }
6004
6005 self.write_keyword("INTERSECT");
6006 if intersect.all {
6007 self.write_space();
6008 self.write_keyword("ALL");
6009 } else if intersect.distinct {
6010 self.write_space();
6011 self.write_keyword("DISTINCT");
6012 }
6013
6014 if intersect.corresponding || intersect.by_name {
6017 self.write_space();
6018 self.write_keyword("BY NAME");
6019 }
6020 if !intersect.on_columns.is_empty() {
6021 self.write_space();
6022 self.write_keyword("ON");
6023 self.write(" (");
6024 for (i, col) in intersect.on_columns.iter().enumerate() {
6025 if i > 0 {
6026 self.write(", ");
6027 }
6028 self.generate_expression(col)?;
6029 }
6030 self.write(")");
6031 }
6032
6033 if self.config.pretty {
6034 self.write_newline();
6035 self.write_indent();
6036 } else {
6037 self.write_space();
6038 }
6039 self.generate_expression(&intersect.right)?;
6040 if let Some(order_by) = &intersect.order_by {
6042 if self.config.pretty {
6043 self.write_newline();
6044 } else {
6045 self.write_space();
6046 }
6047 self.write_keyword("ORDER BY");
6048 self.write_space();
6049 for (i, ordered) in order_by.expressions.iter().enumerate() {
6050 if i > 0 {
6051 self.write(", ");
6052 }
6053 self.generate_ordered(ordered)?;
6054 }
6055 }
6056 if let Some(limit) = &intersect.limit {
6057 if self.config.pretty {
6058 self.write_newline();
6059 } else {
6060 self.write_space();
6061 }
6062 self.write_keyword("LIMIT");
6063 self.write_space();
6064 self.generate_expression(limit)?;
6065 }
6066 if let Some(offset) = &intersect.offset {
6067 if self.config.pretty {
6068 self.write_newline();
6069 } else {
6070 self.write_space();
6071 }
6072 self.write_keyword("OFFSET");
6073 self.write_space();
6074 self.generate_expression(offset)?;
6075 }
6076 if let Some(distribute_by) = &intersect.distribute_by {
6078 self.write_space();
6079 self.write_keyword("DISTRIBUTE BY");
6080 self.write_space();
6081 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6082 if i > 0 {
6083 self.write(", ");
6084 }
6085 self.generate_expression(expr)?;
6086 }
6087 }
6088 if let Some(sort_by) = &intersect.sort_by {
6090 self.write_space();
6091 self.write_keyword("SORT BY");
6092 self.write_space();
6093 for (i, ord) in sort_by.expressions.iter().enumerate() {
6094 if i > 0 {
6095 self.write(", ");
6096 }
6097 self.generate_ordered(ord)?;
6098 }
6099 }
6100 if let Some(cluster_by) = &intersect.cluster_by {
6102 self.write_space();
6103 self.write_keyword("CLUSTER BY");
6104 self.write_space();
6105 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6106 if i > 0 {
6107 self.write(", ");
6108 }
6109 self.generate_ordered(ord)?;
6110 }
6111 }
6112 Ok(())
6113 }
6114
6115 fn generate_except(&mut self, except: &Except) -> Result<()> {
6116 use crate::dialects::DialectType;
6117
6118 if let Some(with) = &except.with {
6120 self.generate_with(with)?;
6121 self.write_space();
6122 }
6123
6124 self.generate_expression(&except.left)?;
6125 if self.config.pretty {
6126 self.write_newline();
6127 self.write_indent();
6128 } else {
6129 self.write_space();
6130 }
6131
6132 if let Some(side) = &except.side {
6134 self.write_keyword(side);
6135 self.write_space();
6136 }
6137 if let Some(kind) = &except.kind {
6138 self.write_keyword(kind);
6139 self.write_space();
6140 }
6141
6142 match self.config.dialect {
6144 Some(DialectType::Oracle) if !except.all => {
6145 self.write_keyword("MINUS");
6146 }
6147 Some(DialectType::ClickHouse) => {
6148 self.write_keyword("EXCEPT");
6150 if except.distinct {
6151 self.write_space();
6152 self.write_keyword("DISTINCT");
6153 }
6154 }
6155 Some(DialectType::BigQuery) => {
6156 self.write_keyword("EXCEPT");
6158 if except.all {
6159 self.write_space();
6160 self.write_keyword("ALL");
6161 } else {
6162 self.write_space();
6163 self.write_keyword("DISTINCT");
6164 }
6165 }
6166 _ => {
6167 self.write_keyword("EXCEPT");
6168 if except.all {
6169 self.write_space();
6170 self.write_keyword("ALL");
6171 } else if except.distinct {
6172 self.write_space();
6173 self.write_keyword("DISTINCT");
6174 }
6175 }
6176 }
6177
6178 if except.corresponding || except.by_name {
6181 self.write_space();
6182 self.write_keyword("BY NAME");
6183 }
6184 if !except.on_columns.is_empty() {
6185 self.write_space();
6186 self.write_keyword("ON");
6187 self.write(" (");
6188 for (i, col) in except.on_columns.iter().enumerate() {
6189 if i > 0 {
6190 self.write(", ");
6191 }
6192 self.generate_expression(col)?;
6193 }
6194 self.write(")");
6195 }
6196
6197 if self.config.pretty {
6198 self.write_newline();
6199 self.write_indent();
6200 } else {
6201 self.write_space();
6202 }
6203 self.generate_expression(&except.right)?;
6204 if let Some(order_by) = &except.order_by {
6206 if self.config.pretty {
6207 self.write_newline();
6208 } else {
6209 self.write_space();
6210 }
6211 self.write_keyword("ORDER BY");
6212 self.write_space();
6213 for (i, ordered) in order_by.expressions.iter().enumerate() {
6214 if i > 0 {
6215 self.write(", ");
6216 }
6217 self.generate_ordered(ordered)?;
6218 }
6219 }
6220 if let Some(limit) = &except.limit {
6221 if self.config.pretty {
6222 self.write_newline();
6223 } else {
6224 self.write_space();
6225 }
6226 self.write_keyword("LIMIT");
6227 self.write_space();
6228 self.generate_expression(limit)?;
6229 }
6230 if let Some(offset) = &except.offset {
6231 if self.config.pretty {
6232 self.write_newline();
6233 } else {
6234 self.write_space();
6235 }
6236 self.write_keyword("OFFSET");
6237 self.write_space();
6238 self.generate_expression(offset)?;
6239 }
6240 if let Some(distribute_by) = &except.distribute_by {
6242 self.write_space();
6243 self.write_keyword("DISTRIBUTE BY");
6244 self.write_space();
6245 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6246 if i > 0 {
6247 self.write(", ");
6248 }
6249 self.generate_expression(expr)?;
6250 }
6251 }
6252 if let Some(sort_by) = &except.sort_by {
6254 self.write_space();
6255 self.write_keyword("SORT BY");
6256 self.write_space();
6257 for (i, ord) in sort_by.expressions.iter().enumerate() {
6258 if i > 0 {
6259 self.write(", ");
6260 }
6261 self.generate_ordered(ord)?;
6262 }
6263 }
6264 if let Some(cluster_by) = &except.cluster_by {
6266 self.write_space();
6267 self.write_keyword("CLUSTER BY");
6268 self.write_space();
6269 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6270 if i > 0 {
6271 self.write(", ");
6272 }
6273 self.generate_ordered(ord)?;
6274 }
6275 }
6276 Ok(())
6277 }
6278
6279 fn generate_insert(&mut self, insert: &Insert) -> Result<()> {
6280 let prepend_query_cte = if insert.with.is_none() {
6282 use crate::dialects::DialectType;
6283 let should_prepend = matches!(
6284 self.config.dialect,
6285 Some(DialectType::TSQL)
6286 | Some(DialectType::Fabric)
6287 | Some(DialectType::Spark)
6288 | Some(DialectType::Databricks)
6289 | Some(DialectType::Hive)
6290 );
6291 if should_prepend {
6292 if let Some(Expression::Select(select)) = &insert.query {
6293 select.with.clone()
6294 } else {
6295 None
6296 }
6297 } else {
6298 None
6299 }
6300 } else {
6301 None
6302 };
6303
6304 if let Some(with) = &insert.with {
6306 self.generate_with(with)?;
6307 self.write_space();
6308 } else if let Some(with) = &prepend_query_cte {
6309 self.generate_with(with)?;
6310 self.write_space();
6311 }
6312
6313 for comment in &insert.leading_comments {
6315 self.write_formatted_comment(comment);
6316 self.write(" ");
6317 }
6318
6319 if let Some(dir) = &insert.directory {
6321 self.write_keyword("INSERT OVERWRITE");
6322 if dir.local {
6323 self.write_space();
6324 self.write_keyword("LOCAL");
6325 }
6326 self.write_space();
6327 self.write_keyword("DIRECTORY");
6328 self.write_space();
6329 self.write("'");
6330 self.write(&dir.path);
6331 self.write("'");
6332
6333 if let Some(row_format) = &dir.row_format {
6335 self.write_space();
6336 self.write_keyword("ROW FORMAT");
6337 if row_format.delimited {
6338 self.write_space();
6339 self.write_keyword("DELIMITED");
6340 }
6341 if let Some(val) = &row_format.fields_terminated_by {
6342 self.write_space();
6343 self.write_keyword("FIELDS TERMINATED BY");
6344 self.write_space();
6345 self.write("'");
6346 self.write(val);
6347 self.write("'");
6348 }
6349 if let Some(val) = &row_format.collection_items_terminated_by {
6350 self.write_space();
6351 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
6352 self.write_space();
6353 self.write("'");
6354 self.write(val);
6355 self.write("'");
6356 }
6357 if let Some(val) = &row_format.map_keys_terminated_by {
6358 self.write_space();
6359 self.write_keyword("MAP KEYS TERMINATED BY");
6360 self.write_space();
6361 self.write("'");
6362 self.write(val);
6363 self.write("'");
6364 }
6365 if let Some(val) = &row_format.lines_terminated_by {
6366 self.write_space();
6367 self.write_keyword("LINES TERMINATED BY");
6368 self.write_space();
6369 self.write("'");
6370 self.write(val);
6371 self.write("'");
6372 }
6373 if let Some(val) = &row_format.null_defined_as {
6374 self.write_space();
6375 self.write_keyword("NULL DEFINED AS");
6376 self.write_space();
6377 self.write("'");
6378 self.write(val);
6379 self.write("'");
6380 }
6381 }
6382
6383 if let Some(format) = &dir.stored_as {
6385 self.write_space();
6386 self.write_keyword("STORED AS");
6387 self.write_space();
6388 self.write_keyword(format);
6389 }
6390
6391 if let Some(query) = &insert.query {
6393 self.write_space();
6394 self.generate_expression(query)?;
6395 }
6396
6397 return Ok(());
6398 }
6399
6400 if insert.is_replace {
6401 self.write_keyword("REPLACE INTO");
6403 } else if insert.overwrite {
6404 self.write_keyword("INSERT");
6406 if let Some(ref hint) = insert.hint {
6408 self.generate_hint(hint)?;
6409 }
6410 self.write(&self.config.insert_overwrite.to_uppercase());
6411 } else if let Some(ref action) = insert.conflict_action {
6412 self.write_keyword("INSERT OR");
6414 self.write_space();
6415 self.write_keyword(action);
6416 self.write_space();
6417 self.write_keyword("INTO");
6418 } else if insert.ignore {
6419 self.write_keyword("INSERT IGNORE INTO");
6421 } else {
6422 self.write_keyword("INSERT");
6423 if let Some(ref hint) = insert.hint {
6425 self.generate_hint(hint)?;
6426 }
6427 self.write_space();
6428 self.write_keyword("INTO");
6429 }
6430 if let Some(ref func) = insert.function_target {
6432 self.write_space();
6433 self.write_keyword("FUNCTION");
6434 self.write_space();
6435 self.generate_expression(func)?;
6436 } else {
6437 self.write_space();
6438 self.generate_table(&insert.table)?;
6439 }
6440
6441 if let Some(ref alias) = insert.alias {
6443 self.write_space();
6444 if insert.alias_explicit_as {
6445 self.write_keyword("AS");
6446 self.write_space();
6447 }
6448 self.generate_identifier(alias)?;
6449 }
6450
6451 if insert.if_exists {
6453 self.write_space();
6454 self.write_keyword("IF EXISTS");
6455 }
6456
6457 if let Some(ref replace_where) = insert.replace_where {
6459 if self.config.pretty {
6460 self.write_newline();
6461 self.write_indent();
6462 } else {
6463 self.write_space();
6464 }
6465 self.write_keyword("REPLACE WHERE");
6466 self.write_space();
6467 self.generate_expression(replace_where)?;
6468 }
6469
6470 if !insert.partition.is_empty() {
6472 self.write_space();
6473 self.write_keyword("PARTITION");
6474 self.write("(");
6475 for (i, (col, val)) in insert.partition.iter().enumerate() {
6476 if i > 0 {
6477 self.write(", ");
6478 }
6479 self.generate_identifier(col)?;
6480 if let Some(v) = val {
6481 self.write(" = ");
6482 self.generate_expression(v)?;
6483 }
6484 }
6485 self.write(")");
6486 }
6487
6488 if let Some(ref partition_by) = insert.partition_by {
6490 self.write_space();
6491 self.write_keyword("PARTITION BY");
6492 self.write_space();
6493 self.generate_expression(partition_by)?;
6494 }
6495
6496 if !insert.settings.is_empty() {
6498 self.write_space();
6499 self.write_keyword("SETTINGS");
6500 self.write_space();
6501 for (i, setting) in insert.settings.iter().enumerate() {
6502 if i > 0 {
6503 self.write(", ");
6504 }
6505 self.generate_expression(setting)?;
6506 }
6507 }
6508
6509 if !insert.columns.is_empty() {
6510 if insert.alias.is_some() && insert.alias_explicit_as {
6511 self.write("(");
6513 } else {
6514 self.write(" (");
6516 }
6517 for (i, col) in insert.columns.iter().enumerate() {
6518 if i > 0 {
6519 self.write(", ");
6520 }
6521 self.generate_identifier(col)?;
6522 }
6523 self.write(")");
6524 }
6525
6526 if let Some(ref output) = insert.output {
6528 self.generate_output_clause(output)?;
6529 }
6530
6531 if insert.by_name {
6533 self.write_space();
6534 self.write_keyword("BY NAME");
6535 }
6536
6537 if insert.default_values {
6538 self.write_space();
6539 self.write_keyword("DEFAULT VALUES");
6540 } else if let Some(query) = &insert.query {
6541 if self.config.pretty {
6542 self.write_newline();
6543 } else {
6544 self.write_space();
6545 }
6546 if prepend_query_cte.is_some() {
6548 if let Expression::Select(select) = query {
6549 let mut select_no_with = select.clone();
6550 select_no_with.with = None;
6551 self.generate_select(&select_no_with)?;
6552 } else {
6553 self.generate_expression(query)?;
6554 }
6555 } else {
6556 self.generate_expression(query)?;
6557 }
6558 } else if !insert.values.is_empty() {
6559 if self.config.pretty {
6560 self.write_newline();
6562 self.write_keyword("VALUES");
6563 self.write_newline();
6564 self.indent_level += 1;
6565 for (i, row) in insert.values.iter().enumerate() {
6566 if i > 0 {
6567 self.write(",");
6568 self.write_newline();
6569 }
6570 self.write_indent();
6571 self.write("(");
6572 for (j, val) in row.iter().enumerate() {
6573 if j > 0 {
6574 self.write(", ");
6575 }
6576 self.generate_expression(val)?;
6577 }
6578 self.write(")");
6579 }
6580 self.indent_level -= 1;
6581 } else {
6582 self.write_space();
6584 self.write_keyword("VALUES");
6585 for (i, row) in insert.values.iter().enumerate() {
6586 if i > 0 {
6587 self.write(",");
6588 }
6589 self.write(" (");
6590 for (j, val) in row.iter().enumerate() {
6591 if j > 0 {
6592 self.write(", ");
6593 }
6594 self.generate_expression(val)?;
6595 }
6596 self.write(")");
6597 }
6598 }
6599 }
6600
6601 if let Some(ref source) = insert.source {
6603 self.write_space();
6604 self.write_keyword("TABLE");
6605 self.write_space();
6606 self.generate_expression(source)?;
6607 }
6608
6609 if let Some(alias) = &insert.source_alias {
6611 self.write_space();
6612 self.write_keyword("AS");
6613 self.write_space();
6614 self.generate_identifier(alias)?;
6615 }
6616
6617 if let Some(on_conflict) = &insert.on_conflict {
6619 if !matches!(self.config.dialect, Some(DialectType::Materialize)) {
6620 self.write_space();
6621 self.generate_expression(on_conflict)?;
6622 }
6623 }
6624
6625 if !insert.returning.is_empty() {
6627 self.write_space();
6628 self.write_keyword("RETURNING");
6629 self.write_space();
6630 for (i, expr) in insert.returning.iter().enumerate() {
6631 if i > 0 {
6632 self.write(", ");
6633 }
6634 self.generate_expression(expr)?;
6635 }
6636 }
6637
6638 Ok(())
6639 }
6640
6641 fn generate_update(&mut self, update: &Update) -> Result<()> {
6642 for comment in &update.leading_comments {
6644 self.write_formatted_comment(comment);
6645 self.write(" ");
6646 }
6647
6648 if let Some(ref with) = update.with {
6650 self.generate_with(with)?;
6651 self.write_space();
6652 }
6653
6654 self.write_keyword("UPDATE");
6655 self.write_space();
6656 self.generate_table(&update.table)?;
6657
6658 let mysql_like_update_from = matches!(
6659 self.config.dialect,
6660 Some(DialectType::MySQL) | Some(DialectType::SingleStore)
6661 ) && update.from_clause.is_some();
6662
6663 let mut set_pairs = update.set.clone();
6664
6665 let mut pre_set_joins = update.table_joins.clone();
6667 if mysql_like_update_from {
6668 let target_name = update
6669 .table
6670 .alias
6671 .as_ref()
6672 .map(|a| a.name.clone())
6673 .unwrap_or_else(|| update.table.name.name.clone());
6674
6675 for (col, _) in &mut set_pairs {
6676 if !col.name.contains('.') {
6677 col.name = format!("{}.{}", target_name, col.name);
6678 }
6679 }
6680
6681 if let Some(from_clause) = &update.from_clause {
6682 for table_expr in &from_clause.expressions {
6683 pre_set_joins.push(crate::expressions::Join {
6684 this: table_expr.clone(),
6685 on: Some(Expression::Boolean(crate::expressions::BooleanLiteral {
6686 value: true,
6687 })),
6688 using: Vec::new(),
6689 kind: crate::expressions::JoinKind::Inner,
6690 use_inner_keyword: false,
6691 use_outer_keyword: false,
6692 deferred_condition: false,
6693 join_hint: None,
6694 match_condition: None,
6695 pivots: Vec::new(),
6696 comments: Vec::new(),
6697 nesting_group: 0,
6698 directed: false,
6699 });
6700 }
6701 }
6702 for join in &update.from_joins {
6703 let mut join = join.clone();
6704 if join.on.is_none() && join.using.is_empty() {
6705 join.on = Some(Expression::Boolean(crate::expressions::BooleanLiteral {
6706 value: true,
6707 }));
6708 }
6709 pre_set_joins.push(join);
6710 }
6711 }
6712
6713 for extra_table in &update.extra_tables {
6715 self.write(", ");
6716 self.generate_table(extra_table)?;
6717 }
6718
6719 for join in &pre_set_joins {
6721 self.generate_join(join)?;
6723 }
6724
6725 let teradata_from_before_set = matches!(self.config.dialect, Some(DialectType::Teradata));
6727 if teradata_from_before_set && !mysql_like_update_from {
6728 if let Some(ref from_clause) = update.from_clause {
6729 self.write_space();
6730 self.write_keyword("FROM");
6731 self.write_space();
6732 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
6733 if i > 0 {
6734 self.write(", ");
6735 }
6736 self.generate_expression(table_expr)?;
6737 }
6738 }
6739 for join in &update.from_joins {
6740 self.generate_join(join)?;
6741 }
6742 }
6743
6744 self.write_space();
6745 self.write_keyword("SET");
6746 self.write_space();
6747
6748 for (i, (col, val)) in set_pairs.iter().enumerate() {
6749 if i > 0 {
6750 self.write(", ");
6751 }
6752 self.generate_identifier(col)?;
6753 self.write(" = ");
6754 self.generate_expression(val)?;
6755 }
6756
6757 if let Some(ref output) = update.output {
6759 self.generate_output_clause(output)?;
6760 }
6761
6762 if !mysql_like_update_from && !teradata_from_before_set {
6764 if let Some(ref from_clause) = update.from_clause {
6765 self.write_space();
6766 self.write_keyword("FROM");
6767 self.write_space();
6768 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
6770 if i > 0 {
6771 self.write(", ");
6772 }
6773 self.generate_expression(table_expr)?;
6774 }
6775 }
6776 }
6777
6778 if !mysql_like_update_from && !teradata_from_before_set {
6779 for join in &update.from_joins {
6781 self.generate_join(join)?;
6782 }
6783 }
6784
6785 if let Some(where_clause) = &update.where_clause {
6786 self.write_space();
6787 self.write_keyword("WHERE");
6788 self.write_space();
6789 self.generate_expression(&where_clause.this)?;
6790 }
6791
6792 if !update.returning.is_empty() {
6794 self.write_space();
6795 self.write_keyword("RETURNING");
6796 self.write_space();
6797 for (i, expr) in update.returning.iter().enumerate() {
6798 if i > 0 {
6799 self.write(", ");
6800 }
6801 self.generate_expression(expr)?;
6802 }
6803 }
6804
6805 if let Some(ref order_by) = update.order_by {
6807 self.write_space();
6808 self.generate_order_by(order_by)?;
6809 }
6810
6811 if let Some(ref limit) = update.limit {
6813 self.write_space();
6814 self.write_keyword("LIMIT");
6815 self.write_space();
6816 self.generate_expression(limit)?;
6817 }
6818
6819 Ok(())
6820 }
6821
6822 fn generate_delete(&mut self, delete: &Delete) -> Result<()> {
6823 if let Some(with) = &delete.with {
6825 self.generate_with(with)?;
6826 self.write_space();
6827 }
6828
6829 for comment in &delete.leading_comments {
6831 self.write_formatted_comment(comment);
6832 self.write(" ");
6833 }
6834
6835 if !delete.tables.is_empty() && !delete.tables_from_using {
6837 self.write_keyword("DELETE");
6839 self.write_space();
6840 for (i, tbl) in delete.tables.iter().enumerate() {
6841 if i > 0 {
6842 self.write(", ");
6843 }
6844 self.generate_table(tbl)?;
6845 }
6846 if let Some(ref output) = delete.output {
6848 self.generate_output_clause(output)?;
6849 }
6850 self.write_space();
6851 self.write_keyword("FROM");
6852 self.write_space();
6853 self.generate_table(&delete.table)?;
6854 } else if !delete.tables.is_empty() && delete.tables_from_using {
6855 self.write_keyword("DELETE FROM");
6857 self.write_space();
6858 for (i, tbl) in delete.tables.iter().enumerate() {
6859 if i > 0 {
6860 self.write(", ");
6861 }
6862 self.generate_table(tbl)?;
6863 }
6864 } else if delete.no_from && matches!(self.config.dialect, Some(DialectType::BigQuery)) {
6865 self.write_keyword("DELETE");
6867 self.write_space();
6868 self.generate_table(&delete.table)?;
6869 } else {
6870 self.write_keyword("DELETE FROM");
6871 self.write_space();
6872 self.generate_table(&delete.table)?;
6873 }
6874
6875 if let Some(ref on_cluster) = delete.on_cluster {
6877 self.write_space();
6878 self.generate_on_cluster(on_cluster)?;
6879 }
6880
6881 if let Some(ref idx) = delete.force_index {
6883 self.write_space();
6884 self.write_keyword("FORCE INDEX");
6885 self.write(" (");
6886 self.write(idx);
6887 self.write(")");
6888 }
6889
6890 if let Some(ref alias) = delete.alias {
6892 self.write_space();
6893 if delete.alias_explicit_as
6894 || matches!(self.config.dialect, Some(DialectType::BigQuery))
6895 {
6896 self.write_keyword("AS");
6897 self.write_space();
6898 }
6899 self.generate_identifier(alias)?;
6900 }
6901
6902 if !delete.tables_from_using {
6904 for join in &delete.joins {
6905 self.generate_join(join)?;
6906 }
6907 }
6908
6909 if !delete.using.is_empty() {
6911 self.write_space();
6912 self.write_keyword("USING");
6913 for (i, table) in delete.using.iter().enumerate() {
6914 if i > 0 {
6915 self.write(",");
6916 }
6917 self.write_space();
6918 if !table.hints.is_empty() && table.name.is_empty() {
6920 self.generate_expression(&table.hints[0])?;
6922 if let Some(ref alias) = table.alias {
6923 self.write_space();
6924 if table.alias_explicit_as {
6925 self.write_keyword("AS");
6926 self.write_space();
6927 }
6928 self.generate_identifier(alias)?;
6929 if !table.column_aliases.is_empty() {
6930 self.write("(");
6931 for (j, col_alias) in table.column_aliases.iter().enumerate() {
6932 if j > 0 {
6933 self.write(", ");
6934 }
6935 self.generate_identifier(col_alias)?;
6936 }
6937 self.write(")");
6938 }
6939 }
6940 } else {
6941 self.generate_table(table)?;
6942 }
6943 }
6944 }
6945
6946 if delete.tables_from_using {
6948 for join in &delete.joins {
6949 self.generate_join(join)?;
6950 }
6951 }
6952
6953 let output_already_emitted =
6955 !delete.tables.is_empty() && !delete.tables_from_using && delete.output.is_some();
6956 if !output_already_emitted {
6957 if let Some(ref output) = delete.output {
6958 self.generate_output_clause(output)?;
6959 }
6960 }
6961
6962 if let Some(where_clause) = &delete.where_clause {
6963 self.write_space();
6964 self.write_keyword("WHERE");
6965 self.write_space();
6966 self.generate_expression(&where_clause.this)?;
6967 }
6968
6969 if let Some(ref order_by) = delete.order_by {
6971 self.write_space();
6972 self.generate_order_by(order_by)?;
6973 }
6974
6975 if let Some(ref limit) = delete.limit {
6977 self.write_space();
6978 self.write_keyword("LIMIT");
6979 self.write_space();
6980 self.generate_expression(limit)?;
6981 }
6982
6983 if !delete.returning.is_empty() {
6985 self.write_space();
6986 self.write_keyword("RETURNING");
6987 self.write_space();
6988 for (i, expr) in delete.returning.iter().enumerate() {
6989 if i > 0 {
6990 self.write(", ");
6991 }
6992 self.generate_expression(expr)?;
6993 }
6994 }
6995
6996 Ok(())
6997 }
6998
6999 fn generate_create_table(&mut self, ct: &CreateTable) -> Result<()> {
7002 let saved_athena_hive_context = self.athena_hive_context;
7006 let is_clickhouse = matches!(self.config.dialect, Some(DialectType::ClickHouse));
7007 if matches!(
7008 self.config.dialect,
7009 Some(crate::dialects::DialectType::Athena)
7010 ) {
7011 let is_external = ct
7015 .table_modifier
7016 .as_ref()
7017 .map(|m| m.eq_ignore_ascii_case("EXTERNAL"))
7018 .unwrap_or(false);
7019 let has_as_select = ct.as_select.is_some();
7020 self.athena_hive_context = is_external || !has_as_select;
7021 }
7022
7023 if matches!(
7025 self.config.dialect,
7026 Some(crate::dialects::DialectType::TSQL)
7027 ) {
7028 if let Some(ref query) = ct.as_select {
7029 if let Some(with_cte) = &ct.with_cte {
7031 self.generate_with(with_cte)?;
7032 self.write_space();
7033 }
7034
7035 self.write_keyword("SELECT");
7037 self.write(" * ");
7038 self.write_keyword("INTO");
7039 self.write_space();
7040
7041 if ct.temporary {
7043 self.write("#");
7044 }
7045 self.generate_table(&ct.name)?;
7046
7047 self.write_space();
7048 self.write_keyword("FROM");
7049 self.write(" (");
7050 let aliased_query = Self::add_column_aliases_to_query(query.clone());
7052 self.generate_expression(&aliased_query)?;
7053 self.write(") ");
7054 self.write_keyword("AS");
7055 self.write(" temp");
7056 return Ok(());
7057 }
7058 }
7059
7060 if let Some(with_cte) = &ct.with_cte {
7062 self.generate_with(with_cte)?;
7063 self.write_space();
7064 }
7065
7066 for comment in &ct.leading_comments {
7068 self.write_formatted_comment(comment);
7069 self.write(" ");
7070 }
7071 self.write_keyword("CREATE");
7072
7073 if ct.or_replace {
7074 self.write_space();
7075 self.write_keyword("OR REPLACE");
7076 }
7077
7078 if ct.temporary {
7079 self.write_space();
7080 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
7082 self.write_keyword("GLOBAL TEMPORARY");
7083 } else {
7084 self.write_keyword("TEMPORARY");
7085 }
7086 }
7087
7088 let is_dictionary = ct
7090 .table_modifier
7091 .as_ref()
7092 .map(|m| m.eq_ignore_ascii_case("DICTIONARY"))
7093 .unwrap_or(false);
7094 if let Some(ref modifier) = ct.table_modifier {
7095 let skip_transient = modifier.eq_ignore_ascii_case("TRANSIENT")
7097 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None);
7098 let is_teradata_modifier = modifier.eq_ignore_ascii_case("VOLATILE")
7100 || modifier.eq_ignore_ascii_case("SET")
7101 || modifier.eq_ignore_ascii_case("MULTISET")
7102 || modifier.to_uppercase().contains("VOLATILE")
7103 || modifier.to_uppercase().starts_with("SET ")
7104 || modifier.to_uppercase().starts_with("MULTISET ");
7105 let skip_teradata =
7106 is_teradata_modifier && !matches!(self.config.dialect, Some(DialectType::Teradata));
7107 if !skip_transient && !skip_teradata {
7108 self.write_space();
7109 self.write_keyword(modifier);
7110 }
7111 }
7112
7113 if !is_dictionary {
7114 self.write_space();
7115 self.write_keyword("TABLE");
7116 }
7117
7118 if ct.if_not_exists {
7119 self.write_space();
7120 self.write_keyword("IF NOT EXISTS");
7121 }
7122
7123 self.write_space();
7124 self.generate_table(&ct.name)?;
7125
7126 if let Some(ref on_cluster) = ct.on_cluster {
7128 self.write_space();
7129 self.generate_on_cluster(on_cluster)?;
7130 }
7131
7132 if matches!(
7134 self.config.dialect,
7135 Some(crate::dialects::DialectType::Teradata)
7136 ) && !ct.teradata_post_name_options.is_empty()
7137 {
7138 for opt in &ct.teradata_post_name_options {
7139 self.write(", ");
7140 self.write(opt);
7141 }
7142 }
7143
7144 if ct.copy_grants {
7146 self.write_space();
7147 self.write_keyword("COPY GRANTS");
7148 }
7149
7150 if let Some(ref using_template) = ct.using_template {
7152 self.write_space();
7153 self.write_keyword("USING TEMPLATE");
7154 self.write_space();
7155 self.generate_expression(using_template)?;
7156 return Ok(());
7157 }
7158
7159 if let Some(ref clone_source) = ct.clone_source {
7161 self.write_space();
7162 if ct.is_copy && self.config.supports_table_copy {
7163 self.write_keyword("COPY");
7165 } else if ct.shallow_clone {
7166 self.write_keyword("SHALLOW CLONE");
7167 } else {
7168 self.write_keyword("CLONE");
7169 }
7170 self.write_space();
7171 self.generate_table(clone_source)?;
7172 if let Some(ref at_clause) = ct.clone_at_clause {
7174 self.write_space();
7175 self.generate_expression(at_clause)?;
7176 }
7177 return Ok(());
7178 }
7179
7180 if let Some(ref partition_of) = ct.partition_of {
7184 self.write_space();
7185
7186 if let Expression::PartitionedOfProperty(ref pop) = partition_of {
7188 self.write_keyword("PARTITION OF");
7190 self.write_space();
7191 self.generate_expression(&pop.this)?;
7192
7193 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
7195 self.write(" (");
7196 let mut first = true;
7197 for col in &ct.columns {
7198 if !first {
7199 self.write(", ");
7200 }
7201 first = false;
7202 self.generate_column_def(col)?;
7203 }
7204 for constraint in &ct.constraints {
7205 if !first {
7206 self.write(", ");
7207 }
7208 first = false;
7209 self.generate_table_constraint(constraint)?;
7210 }
7211 self.write(")");
7212 }
7213
7214 if let Expression::PartitionBoundSpec(_) = pop.expression.as_ref() {
7216 self.write_space();
7217 self.write_keyword("FOR VALUES");
7218 self.write_space();
7219 self.generate_expression(&pop.expression)?;
7220 } else {
7221 self.write_space();
7222 self.write_keyword("DEFAULT");
7223 }
7224 } else {
7225 self.generate_expression(partition_of)?;
7227
7228 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
7230 self.write(" (");
7231 let mut first = true;
7232 for col in &ct.columns {
7233 if !first {
7234 self.write(", ");
7235 }
7236 first = false;
7237 self.generate_column_def(col)?;
7238 }
7239 for constraint in &ct.constraints {
7240 if !first {
7241 self.write(", ");
7242 }
7243 first = false;
7244 self.generate_table_constraint(constraint)?;
7245 }
7246 self.write(")");
7247 }
7248 }
7249
7250 for prop in &ct.properties {
7252 self.write_space();
7253 self.generate_expression(prop)?;
7254 }
7255
7256 return Ok(());
7257 }
7258
7259 self.sqlite_inline_pk_columns.clear();
7262 if matches!(
7263 self.config.dialect,
7264 Some(crate::dialects::DialectType::SQLite)
7265 ) {
7266 for constraint in &ct.constraints {
7267 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7268 if columns.len() == 1 && name.is_none() {
7270 let pk_col_name = columns[0].name.to_lowercase();
7271 if ct
7273 .columns
7274 .iter()
7275 .any(|c| c.name.name.to_lowercase() == pk_col_name)
7276 {
7277 self.sqlite_inline_pk_columns.insert(pk_col_name);
7278 }
7279 }
7280 }
7281 }
7282 }
7283
7284 if !ct.columns.is_empty() {
7286 if self.config.pretty {
7287 self.write(" (");
7289 self.write_newline();
7290 self.indent_level += 1;
7291 for (i, col) in ct.columns.iter().enumerate() {
7292 if i > 0 {
7293 self.write(",");
7294 self.write_newline();
7295 }
7296 self.write_indent();
7297 self.generate_column_def(col)?;
7298 }
7299 for constraint in &ct.constraints {
7301 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7303 if columns.len() == 1
7304 && name.is_none()
7305 && self
7306 .sqlite_inline_pk_columns
7307 .contains(&columns[0].name.to_lowercase())
7308 {
7309 continue;
7310 }
7311 }
7312 self.write(",");
7313 self.write_newline();
7314 self.write_indent();
7315 self.generate_table_constraint(constraint)?;
7316 }
7317 self.indent_level -= 1;
7318 self.write_newline();
7319 self.write(")");
7320 } else {
7321 self.write(" (");
7322 for (i, col) in ct.columns.iter().enumerate() {
7323 if i > 0 {
7324 self.write(", ");
7325 }
7326 self.generate_column_def(col)?;
7327 }
7328 let mut first_constraint = true;
7330 for constraint in &ct.constraints {
7331 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7333 if columns.len() == 1
7334 && name.is_none()
7335 && self
7336 .sqlite_inline_pk_columns
7337 .contains(&columns[0].name.to_lowercase())
7338 {
7339 continue;
7340 }
7341 }
7342 if first_constraint {
7343 self.write(", ");
7344 first_constraint = false;
7345 } else {
7346 self.write(", ");
7347 }
7348 self.generate_table_constraint(constraint)?;
7349 }
7350 self.write(")");
7351 }
7352 } else if !ct.constraints.is_empty() {
7353 let has_like_only = ct
7355 .constraints
7356 .iter()
7357 .all(|c| matches!(c, TableConstraint::Like { .. }));
7358 let has_tags_only = ct
7359 .constraints
7360 .iter()
7361 .all(|c| matches!(c, TableConstraint::Tags(_)));
7362 let is_pg_like = matches!(
7366 self.config.dialect,
7367 Some(crate::dialects::DialectType::PostgreSQL)
7368 | Some(crate::dialects::DialectType::CockroachDB)
7369 | Some(crate::dialects::DialectType::Materialize)
7370 | Some(crate::dialects::DialectType::RisingWave)
7371 | Some(crate::dialects::DialectType::Redshift)
7372 | Some(crate::dialects::DialectType::Presto)
7373 | Some(crate::dialects::DialectType::Trino)
7374 | Some(crate::dialects::DialectType::Athena)
7375 );
7376 let use_parens = if has_like_only {
7377 is_pg_like
7378 } else {
7379 !has_tags_only
7380 };
7381 if self.config.pretty && use_parens {
7382 self.write(" (");
7383 self.write_newline();
7384 self.indent_level += 1;
7385 for (i, constraint) in ct.constraints.iter().enumerate() {
7386 if i > 0 {
7387 self.write(",");
7388 self.write_newline();
7389 }
7390 self.write_indent();
7391 self.generate_table_constraint(constraint)?;
7392 }
7393 self.indent_level -= 1;
7394 self.write_newline();
7395 self.write(")");
7396 } else {
7397 if use_parens {
7398 self.write(" (");
7399 } else {
7400 self.write_space();
7401 }
7402 for (i, constraint) in ct.constraints.iter().enumerate() {
7403 if i > 0 {
7404 self.write(", ");
7405 }
7406 self.generate_table_constraint(constraint)?;
7407 }
7408 if use_parens {
7409 self.write(")");
7410 }
7411 }
7412 }
7413
7414 if let Some(ref on_prop) = ct.on_property {
7416 self.write(" ");
7417 self.write_keyword("ON");
7418 self.write(" ");
7419 self.generate_expression(&on_prop.this)?;
7420 }
7421
7422 if !is_clickhouse {
7425 for prop in &ct.properties {
7426 if let Expression::SchemaCommentProperty(_) = prop {
7427 if self.config.pretty {
7428 self.write_newline();
7429 } else {
7430 self.write_space();
7431 }
7432 self.generate_expression(prop)?;
7433 }
7434 }
7435 }
7436
7437 if !ct.with_properties.is_empty() {
7439 let is_snowflake_special_table = matches!(
7441 self.config.dialect,
7442 Some(crate::dialects::DialectType::Snowflake)
7443 ) && (ct.table_modifier.as_deref() == Some("ICEBERG")
7444 || ct.table_modifier.as_deref() == Some("DYNAMIC"));
7445 if is_snowflake_special_table {
7446 for (key, value) in &ct.with_properties {
7447 self.write_space();
7448 self.write(key);
7449 self.write("=");
7450 self.write(value);
7451 }
7452 } else if self.config.pretty {
7453 self.write_newline();
7454 self.write_keyword("WITH");
7455 self.write(" (");
7456 self.write_newline();
7457 self.indent_level += 1;
7458 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
7459 if i > 0 {
7460 self.write(",");
7461 self.write_newline();
7462 }
7463 self.write_indent();
7464 self.write(key);
7465 self.write("=");
7466 self.write(value);
7467 }
7468 self.indent_level -= 1;
7469 self.write_newline();
7470 self.write(")");
7471 } else {
7472 self.write_space();
7473 self.write_keyword("WITH");
7474 self.write(" (");
7475 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
7476 if i > 0 {
7477 self.write(", ");
7478 }
7479 self.write(key);
7480 self.write("=");
7481 self.write(value);
7482 }
7483 self.write(")");
7484 }
7485 }
7486
7487 let (pre_as_properties, post_as_properties): (Vec<&Expression>, Vec<&Expression>) =
7488 if is_clickhouse && ct.as_select.is_some() {
7489 let mut pre = Vec::new();
7490 let mut post = Vec::new();
7491 for prop in &ct.properties {
7492 if matches!(prop, Expression::SchemaCommentProperty(_)) {
7493 post.push(prop);
7494 } else {
7495 pre.push(prop);
7496 }
7497 }
7498 (pre, post)
7499 } else {
7500 (ct.properties.iter().collect(), Vec::new())
7501 };
7502
7503 for prop in pre_as_properties {
7505 if !is_clickhouse && matches!(prop, Expression::SchemaCommentProperty(_)) {
7507 continue;
7508 }
7509 if self.config.pretty {
7510 self.write_newline();
7511 } else {
7512 self.write_space();
7513 }
7514 if let Expression::Properties(props) = prop {
7518 let is_hive_dialect = matches!(
7519 self.config.dialect,
7520 Some(crate::dialects::DialectType::Hive)
7521 | Some(crate::dialects::DialectType::Spark)
7522 | Some(crate::dialects::DialectType::Databricks)
7523 | Some(crate::dialects::DialectType::Athena)
7524 );
7525 let is_doris_starrocks = matches!(
7526 self.config.dialect,
7527 Some(crate::dialects::DialectType::Doris)
7528 | Some(crate::dialects::DialectType::StarRocks)
7529 );
7530 if is_hive_dialect {
7531 self.generate_tblproperties_clause(&props.expressions)?;
7532 } else if is_doris_starrocks {
7533 self.generate_properties_clause(&props.expressions)?;
7534 } else {
7535 self.generate_options_clause(&props.expressions)?;
7536 }
7537 } else {
7538 self.generate_expression(prop)?;
7539 }
7540 }
7541
7542 for prop in &ct.post_table_properties {
7544 if let Expression::WithSystemVersioningProperty(ref svp) = prop {
7545 self.write(" WITH(");
7546 self.generate_system_versioning_content(svp)?;
7547 self.write(")");
7548 } else if let Expression::Properties(props) = prop {
7549 let is_doris_starrocks = matches!(
7551 self.config.dialect,
7552 Some(crate::dialects::DialectType::Doris)
7553 | Some(crate::dialects::DialectType::StarRocks)
7554 );
7555 self.write_space();
7556 if is_doris_starrocks {
7557 self.generate_properties_clause(&props.expressions)?;
7558 } else {
7559 self.generate_options_clause(&props.expressions)?;
7560 }
7561 } else {
7562 self.write_space();
7563 self.generate_expression(prop)?;
7564 }
7565 }
7566
7567 if let Some(ref rollup) = ct.rollup {
7570 if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
7571 self.write_space();
7572 self.generate_rollup_property(rollup)?;
7573 }
7574 }
7575
7576 let is_mysql_compatible = matches!(
7580 self.config.dialect,
7581 Some(DialectType::MySQL)
7582 | Some(DialectType::SingleStore)
7583 | Some(DialectType::Doris)
7584 | Some(DialectType::StarRocks)
7585 | None
7586 );
7587 let is_hive_compatible = matches!(
7588 self.config.dialect,
7589 Some(DialectType::Hive)
7590 | Some(DialectType::Spark)
7591 | Some(DialectType::Databricks)
7592 | Some(DialectType::Athena)
7593 );
7594 let mysql_pretty_options =
7595 self.config.pretty && matches!(self.config.dialect, Some(DialectType::MySQL));
7596 for (key, value) in &ct.mysql_table_options {
7597 let should_output = if is_mysql_compatible {
7599 true
7600 } else if is_hive_compatible && key == "COMMENT" {
7601 true } else {
7603 false
7604 };
7605 if should_output {
7606 if mysql_pretty_options {
7607 self.write_newline();
7608 self.write_indent();
7609 } else {
7610 self.write_space();
7611 }
7612 self.write_keyword(key);
7613 if key == "COMMENT" && !self.config.schema_comment_with_eq {
7615 self.write_space();
7616 } else {
7617 self.write("=");
7618 }
7619 self.write(value);
7620 }
7621 }
7622
7623 if ct.temporary
7625 && matches!(
7626 self.config.dialect,
7627 Some(DialectType::Spark) | Some(DialectType::Databricks)
7628 )
7629 && ct.as_select.is_none()
7630 {
7631 self.write_space();
7632 self.write_keyword("USING PARQUET");
7633 }
7634
7635 if !ct.inherits.is_empty() {
7637 self.write_space();
7638 self.write_keyword("INHERITS");
7639 self.write(" (");
7640 for (i, parent) in ct.inherits.iter().enumerate() {
7641 if i > 0 {
7642 self.write(", ");
7643 }
7644 self.generate_table(parent)?;
7645 }
7646 self.write(")");
7647 }
7648
7649 if let Some(ref query) = ct.as_select {
7651 self.write_space();
7652 self.write_keyword("AS");
7653 self.write_space();
7654 if ct.as_select_parenthesized {
7655 self.write("(");
7656 }
7657 self.generate_expression(query)?;
7658 if ct.as_select_parenthesized {
7659 self.write(")");
7660 }
7661
7662 if let Some(with_data) = ct.with_data {
7664 self.write_space();
7665 self.write_keyword("WITH");
7666 if !with_data {
7667 self.write_space();
7668 self.write_keyword("NO");
7669 }
7670 self.write_space();
7671 self.write_keyword("DATA");
7672 }
7673
7674 if let Some(with_statistics) = ct.with_statistics {
7676 self.write_space();
7677 self.write_keyword("AND");
7678 if !with_statistics {
7679 self.write_space();
7680 self.write_keyword("NO");
7681 }
7682 self.write_space();
7683 self.write_keyword("STATISTICS");
7684 }
7685
7686 for index in &ct.teradata_indexes {
7688 self.write_space();
7689 match index.kind {
7690 TeradataIndexKind::NoPrimary => {
7691 self.write_keyword("NO PRIMARY INDEX");
7692 }
7693 TeradataIndexKind::Primary => {
7694 self.write_keyword("PRIMARY INDEX");
7695 }
7696 TeradataIndexKind::PrimaryAmp => {
7697 self.write_keyword("PRIMARY AMP INDEX");
7698 }
7699 TeradataIndexKind::Unique => {
7700 self.write_keyword("UNIQUE INDEX");
7701 }
7702 TeradataIndexKind::UniquePrimary => {
7703 self.write_keyword("UNIQUE PRIMARY INDEX");
7704 }
7705 TeradataIndexKind::Secondary => {
7706 self.write_keyword("INDEX");
7707 }
7708 }
7709 if let Some(ref name) = index.name {
7711 self.write_space();
7712 self.write(name);
7713 }
7714 if !index.columns.is_empty() {
7716 self.write(" (");
7717 for (i, col) in index.columns.iter().enumerate() {
7718 if i > 0 {
7719 self.write(", ");
7720 }
7721 self.write(col);
7722 }
7723 self.write(")");
7724 }
7725 }
7726
7727 if let Some(ref on_commit) = ct.on_commit {
7729 self.write_space();
7730 self.write_keyword("ON COMMIT");
7731 self.write_space();
7732 match on_commit {
7733 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
7734 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
7735 }
7736 }
7737
7738 if !post_as_properties.is_empty() {
7739 for prop in post_as_properties {
7740 self.write_space();
7741 self.generate_expression(prop)?;
7742 }
7743 }
7744
7745 self.athena_hive_context = saved_athena_hive_context;
7747 return Ok(());
7748 }
7749
7750 if let Some(ref on_commit) = ct.on_commit {
7752 self.write_space();
7753 self.write_keyword("ON COMMIT");
7754 self.write_space();
7755 match on_commit {
7756 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
7757 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
7758 }
7759 }
7760
7761 self.athena_hive_context = saved_athena_hive_context;
7763
7764 Ok(())
7765 }
7766
7767 fn generate_column_def_expr(&mut self, col: &ColumnDef) -> Result<()> {
7770 self.generate_identifier(&col.name)?;
7772 if !matches!(col.data_type, DataType::Unknown) {
7774 self.write_space();
7775 self.generate_data_type(&col.data_type)?;
7776 }
7777 for constraint in &col.constraints {
7779 if let ColumnConstraint::Path(path_expr) = constraint {
7780 self.write_space();
7781 self.write_keyword("PATH");
7782 self.write_space();
7783 self.generate_expression(path_expr)?;
7784 }
7785 }
7786 Ok(())
7787 }
7788
7789 fn generate_column_def(&mut self, col: &ColumnDef) -> Result<()> {
7790 let has_computed_no_type = matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
7792 && col
7793 .constraints
7794 .iter()
7795 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
7796 let omit_computed_type = !self.config.computed_column_with_type
7798 && col
7799 .constraints
7800 .iter()
7801 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
7802
7803 let is_partition_column_spec = matches!(col.data_type, DataType::Unknown);
7806
7807 let has_no_type = col.no_type
7810 || (matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
7811 && col.constraints.is_empty());
7812
7813 self.generate_identifier(&col.name)?;
7814
7815 let serial_expansion = if matches!(
7817 self.config.dialect,
7818 Some(DialectType::Materialize) | Some(DialectType::PostgreSQL)
7819 ) {
7820 if let DataType::Custom { ref name } = col.data_type {
7821 match name.to_uppercase().as_str() {
7822 "SERIAL" => Some("INT"),
7823 "BIGSERIAL" => Some("BIGINT"),
7824 "SMALLSERIAL" => Some("SMALLINT"),
7825 _ => None,
7826 }
7827 } else {
7828 None
7829 }
7830 } else {
7831 None
7832 };
7833
7834 if !has_computed_no_type && !omit_computed_type && !is_partition_column_spec && !has_no_type
7835 {
7836 self.write_space();
7837 let saved_nullable_depth = self.clickhouse_nullable_depth;
7840 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
7841 self.clickhouse_nullable_depth = -1;
7842 }
7843 if let Some(int_type) = serial_expansion {
7844 self.write_keyword(int_type);
7846 } else if col.unsigned && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
7847 let unsigned_type = match &col.data_type {
7849 DataType::Int { .. } => Some("UINTEGER"),
7850 DataType::BigInt { .. } => Some("UBIGINT"),
7851 DataType::SmallInt { .. } => Some("USMALLINT"),
7852 DataType::TinyInt { .. } => Some("UTINYINT"),
7853 _ => None,
7854 };
7855 if let Some(utype) = unsigned_type {
7856 self.write_keyword(utype);
7857 } else {
7858 self.generate_data_type(&col.data_type)?;
7859 }
7860 } else {
7861 self.generate_data_type(&col.data_type)?;
7862 }
7863 self.clickhouse_nullable_depth = saved_nullable_depth;
7864 }
7865
7866 if col.unsigned && !matches!(self.config.dialect, Some(DialectType::DuckDB)) {
7869 self.write_space();
7870 self.write_keyword("UNSIGNED");
7871 }
7872 if col.zerofill {
7873 self.write_space();
7874 self.write_keyword("ZEROFILL");
7875 }
7876
7877 if let Some(ref charset) = col.character_set {
7881 self.write_space();
7882 self.write_keyword("CHARACTER SET");
7883 self.write_space();
7884 self.write(charset);
7885 }
7886
7887 if col.uppercase {
7888 self.write_space();
7889 self.write_keyword("UPPERCASE");
7890 }
7891
7892 if let Some(casespecific) = col.casespecific {
7893 self.write_space();
7894 if casespecific {
7895 self.write_keyword("CASESPECIFIC");
7896 } else {
7897 self.write_keyword("NOT CASESPECIFIC");
7898 }
7899 }
7900
7901 if let Some(ref format) = col.format {
7902 self.write_space();
7903 self.write_keyword("FORMAT");
7904 self.write(" '");
7905 self.write(format);
7906 self.write("'");
7907 }
7908
7909 if let Some(ref title) = col.title {
7910 self.write_space();
7911 self.write_keyword("TITLE");
7912 self.write(" '");
7913 self.write(title);
7914 self.write("'");
7915 }
7916
7917 if let Some(length) = col.inline_length {
7918 self.write_space();
7919 self.write_keyword("INLINE LENGTH");
7920 self.write(" ");
7921 self.write(&length.to_string());
7922 }
7923
7924 if let Some(ref compress) = col.compress {
7925 self.write_space();
7926 self.write_keyword("COMPRESS");
7927 if !compress.is_empty() {
7928 if compress.len() == 1 {
7930 if let Expression::Literal(Literal::String(_)) = &compress[0] {
7931 self.write_space();
7932 self.generate_expression(&compress[0])?;
7933 } else {
7934 self.write(" (");
7935 self.generate_expression(&compress[0])?;
7936 self.write(")");
7937 }
7938 } else {
7939 self.write(" (");
7940 for (i, val) in compress.iter().enumerate() {
7941 if i > 0 {
7942 self.write(", ");
7943 }
7944 self.generate_expression(val)?;
7945 }
7946 self.write(")");
7947 }
7948 }
7949 }
7950
7951 if !col.constraint_order.is_empty() {
7954 let mut references_idx = 0;
7957 let mut check_idx = 0;
7958 let mut generated_idx = 0;
7959 let mut collate_idx = 0;
7960 let mut comment_idx = 0;
7961 let defer_not_null_after_identity = false;
7964 let mut pending_not_null_after_identity = false;
7965
7966 for constraint_type in &col.constraint_order {
7967 match constraint_type {
7968 ConstraintType::PrimaryKey => {
7969 if col.primary_key
7971 && !matches!(self.config.dialect, Some(DialectType::Materialize))
7972 {
7973 if let Some(ref cname) = col.primary_key_constraint_name {
7974 self.write_space();
7975 self.write_keyword("CONSTRAINT");
7976 self.write_space();
7977 self.write(cname);
7978 }
7979 self.write_space();
7980 self.write_keyword("PRIMARY KEY");
7981 if let Some(ref order) = col.primary_key_order {
7982 self.write_space();
7983 match order {
7984 SortOrder::Asc => self.write_keyword("ASC"),
7985 SortOrder::Desc => self.write_keyword("DESC"),
7986 }
7987 }
7988 }
7989 }
7990 ConstraintType::Unique => {
7991 if col.unique {
7992 if let Some(ref cname) = col.unique_constraint_name {
7993 self.write_space();
7994 self.write_keyword("CONSTRAINT");
7995 self.write_space();
7996 self.write(cname);
7997 }
7998 self.write_space();
7999 self.write_keyword("UNIQUE");
8000 if col.unique_nulls_not_distinct {
8002 self.write(" NULLS NOT DISTINCT");
8003 }
8004 }
8005 }
8006 ConstraintType::NotNull => {
8007 if col.nullable == Some(false) {
8008 if defer_not_null_after_identity {
8009 pending_not_null_after_identity = true;
8010 continue;
8011 }
8012 if let Some(ref cname) = col.not_null_constraint_name {
8013 self.write_space();
8014 self.write_keyword("CONSTRAINT");
8015 self.write_space();
8016 self.write(cname);
8017 }
8018 self.write_space();
8019 self.write_keyword("NOT NULL");
8020 }
8021 }
8022 ConstraintType::Null => {
8023 if col.nullable == Some(true) {
8024 self.write_space();
8025 self.write_keyword("NULL");
8026 }
8027 }
8028 ConstraintType::Default => {
8029 if let Some(ref default) = col.default {
8030 self.write_space();
8031 self.write_keyword("DEFAULT");
8032 self.write_space();
8033 self.generate_expression(default)?;
8034 }
8035 }
8036 ConstraintType::AutoIncrement => {
8037 if col.auto_increment {
8038 if matches!(
8040 self.config.dialect,
8041 Some(crate::dialects::DialectType::DuckDB)
8042 ) {
8043 } else if matches!(
8045 self.config.dialect,
8046 Some(crate::dialects::DialectType::Materialize)
8047 ) {
8048 if !matches!(col.nullable, Some(false)) {
8050 self.write_space();
8051 self.write_keyword("NOT NULL");
8052 }
8053 } else if matches!(
8054 self.config.dialect,
8055 Some(crate::dialects::DialectType::PostgreSQL)
8056 ) {
8057 self.write_space();
8059 self.generate_auto_increment_keyword(col)?;
8060 } else {
8061 self.write_space();
8062 self.generate_auto_increment_keyword(col)?;
8063 if pending_not_null_after_identity {
8064 self.write_space();
8065 self.write_keyword("NOT NULL");
8066 pending_not_null_after_identity = false;
8067 }
8068 }
8069 } }
8071 ConstraintType::References => {
8072 while references_idx < col.constraints.len() {
8074 if let ColumnConstraint::References(fk_ref) =
8075 &col.constraints[references_idx]
8076 {
8077 if let Some(ref name) = fk_ref.constraint_name {
8079 self.write_space();
8080 self.write_keyword("CONSTRAINT");
8081 self.write_space();
8082 self.write(name);
8083 }
8084 self.write_space();
8085 if fk_ref.has_foreign_key_keywords {
8086 self.write_keyword("FOREIGN KEY");
8087 self.write_space();
8088 }
8089 self.write_keyword("REFERENCES");
8090 self.write_space();
8091 self.generate_table(&fk_ref.table)?;
8092 if !fk_ref.columns.is_empty() {
8093 self.write(" (");
8094 for (i, c) in fk_ref.columns.iter().enumerate() {
8095 if i > 0 {
8096 self.write(", ");
8097 }
8098 self.generate_identifier(c)?;
8099 }
8100 self.write(")");
8101 }
8102 self.generate_referential_actions(fk_ref)?;
8103 references_idx += 1;
8104 break;
8105 }
8106 references_idx += 1;
8107 }
8108 }
8109 ConstraintType::Check => {
8110 while check_idx < col.constraints.len() {
8112 if let ColumnConstraint::Check(expr) = &col.constraints[check_idx] {
8113 if check_idx == 0 {
8115 if let Some(ref cname) = col.check_constraint_name {
8116 self.write_space();
8117 self.write_keyword("CONSTRAINT");
8118 self.write_space();
8119 self.write(cname);
8120 }
8121 }
8122 self.write_space();
8123 self.write_keyword("CHECK");
8124 self.write(" (");
8125 self.generate_expression(expr)?;
8126 self.write(")");
8127 check_idx += 1;
8128 break;
8129 }
8130 check_idx += 1;
8131 }
8132 }
8133 ConstraintType::GeneratedAsIdentity => {
8134 while generated_idx < col.constraints.len() {
8136 if let ColumnConstraint::GeneratedAsIdentity(gen) =
8137 &col.constraints[generated_idx]
8138 {
8139 self.write_space();
8140 if matches!(
8142 self.config.dialect,
8143 Some(crate::dialects::DialectType::Redshift)
8144 ) {
8145 self.write_keyword("IDENTITY");
8146 self.write("(");
8147 if let Some(ref start) = gen.start {
8148 self.generate_expression(start)?;
8149 } else {
8150 self.write("0");
8151 }
8152 self.write(", ");
8153 if let Some(ref incr) = gen.increment {
8154 self.generate_expression(incr)?;
8155 } else {
8156 self.write("1");
8157 }
8158 self.write(")");
8159 } else {
8160 self.write_keyword("GENERATED");
8161 if gen.always {
8162 self.write_space();
8163 self.write_keyword("ALWAYS");
8164 } else {
8165 self.write_space();
8166 self.write_keyword("BY DEFAULT");
8167 if gen.on_null {
8168 self.write_space();
8169 self.write_keyword("ON NULL");
8170 }
8171 }
8172 self.write_space();
8173 self.write_keyword("AS IDENTITY");
8174
8175 let has_options = gen.start.is_some()
8176 || gen.increment.is_some()
8177 || gen.minvalue.is_some()
8178 || gen.maxvalue.is_some()
8179 || gen.cycle.is_some();
8180 if has_options {
8181 self.write(" (");
8182 let mut first = true;
8183 if let Some(ref start) = gen.start {
8184 if !first {
8185 self.write(" ");
8186 }
8187 first = false;
8188 self.write_keyword("START WITH");
8189 self.write_space();
8190 self.generate_expression(start)?;
8191 }
8192 if let Some(ref incr) = gen.increment {
8193 if !first {
8194 self.write(" ");
8195 }
8196 first = false;
8197 self.write_keyword("INCREMENT BY");
8198 self.write_space();
8199 self.generate_expression(incr)?;
8200 }
8201 if let Some(ref minv) = gen.minvalue {
8202 if !first {
8203 self.write(" ");
8204 }
8205 first = false;
8206 self.write_keyword("MINVALUE");
8207 self.write_space();
8208 self.generate_expression(minv)?;
8209 }
8210 if let Some(ref maxv) = gen.maxvalue {
8211 if !first {
8212 self.write(" ");
8213 }
8214 first = false;
8215 self.write_keyword("MAXVALUE");
8216 self.write_space();
8217 self.generate_expression(maxv)?;
8218 }
8219 if let Some(cycle) = gen.cycle {
8220 if !first {
8221 self.write(" ");
8222 }
8223 if cycle {
8224 self.write_keyword("CYCLE");
8225 } else {
8226 self.write_keyword("NO CYCLE");
8227 }
8228 }
8229 self.write(")");
8230 }
8231 }
8232 generated_idx += 1;
8233 break;
8234 }
8235 generated_idx += 1;
8236 }
8237 }
8238 ConstraintType::Collate => {
8239 while collate_idx < col.constraints.len() {
8241 if let ColumnConstraint::Collate(collation) =
8242 &col.constraints[collate_idx]
8243 {
8244 self.write_space();
8245 self.write_keyword("COLLATE");
8246 self.write_space();
8247 self.generate_identifier(collation)?;
8248 collate_idx += 1;
8249 break;
8250 }
8251 collate_idx += 1;
8252 }
8253 }
8254 ConstraintType::Comment => {
8255 while comment_idx < col.constraints.len() {
8257 if let ColumnConstraint::Comment(comment) =
8258 &col.constraints[comment_idx]
8259 {
8260 self.write_space();
8261 self.write_keyword("COMMENT");
8262 self.write_space();
8263 self.generate_string_literal(comment)?;
8264 comment_idx += 1;
8265 break;
8266 }
8267 comment_idx += 1;
8268 }
8269 }
8270 ConstraintType::Tags => {
8271 for constraint in &col.constraints {
8273 if let ColumnConstraint::Tags(tags) = constraint {
8274 self.write_space();
8275 self.write_keyword("TAG");
8276 self.write(" (");
8277 for (i, expr) in tags.expressions.iter().enumerate() {
8278 if i > 0 {
8279 self.write(", ");
8280 }
8281 self.generate_expression(expr)?;
8282 }
8283 self.write(")");
8284 break;
8285 }
8286 }
8287 }
8288 ConstraintType::ComputedColumn => {
8289 for constraint in &col.constraints {
8291 if let ColumnConstraint::ComputedColumn(cc) = constraint {
8292 self.write_space();
8293 self.generate_computed_column_inline(cc)?;
8294 break;
8295 }
8296 }
8297 }
8298 ConstraintType::GeneratedAsRow => {
8299 for constraint in &col.constraints {
8301 if let ColumnConstraint::GeneratedAsRow(gar) = constraint {
8302 self.write_space();
8303 self.generate_generated_as_row_inline(gar)?;
8304 break;
8305 }
8306 }
8307 }
8308 ConstraintType::OnUpdate => {
8309 if let Some(ref expr) = col.on_update {
8310 self.write_space();
8311 self.write_keyword("ON UPDATE");
8312 self.write_space();
8313 self.generate_expression(expr)?;
8314 }
8315 }
8316 ConstraintType::Encode => {
8317 if let Some(ref encoding) = col.encoding {
8318 self.write_space();
8319 self.write_keyword("ENCODE");
8320 self.write_space();
8321 self.write(encoding);
8322 }
8323 }
8324 ConstraintType::Path => {
8325 for constraint in &col.constraints {
8327 if let ColumnConstraint::Path(path_expr) = constraint {
8328 self.write_space();
8329 self.write_keyword("PATH");
8330 self.write_space();
8331 self.generate_expression(path_expr)?;
8332 break;
8333 }
8334 }
8335 }
8336 }
8337 }
8338 if pending_not_null_after_identity {
8339 self.write_space();
8340 self.write_keyword("NOT NULL");
8341 }
8342 } else {
8343 if col.primary_key {
8345 self.write_space();
8346 self.write_keyword("PRIMARY KEY");
8347 if let Some(ref order) = col.primary_key_order {
8348 self.write_space();
8349 match order {
8350 SortOrder::Asc => self.write_keyword("ASC"),
8351 SortOrder::Desc => self.write_keyword("DESC"),
8352 }
8353 }
8354 }
8355
8356 if col.unique {
8357 self.write_space();
8358 self.write_keyword("UNIQUE");
8359 if col.unique_nulls_not_distinct {
8361 self.write(" NULLS NOT DISTINCT");
8362 }
8363 }
8364
8365 match col.nullable {
8366 Some(false) => {
8367 self.write_space();
8368 self.write_keyword("NOT NULL");
8369 }
8370 Some(true) => {
8371 self.write_space();
8372 self.write_keyword("NULL");
8373 }
8374 None => {}
8375 }
8376
8377 if let Some(ref default) = col.default {
8378 self.write_space();
8379 self.write_keyword("DEFAULT");
8380 self.write_space();
8381 self.generate_expression(default)?;
8382 }
8383
8384 if col.auto_increment {
8385 self.write_space();
8386 self.generate_auto_increment_keyword(col)?;
8387 }
8388
8389 for constraint in &col.constraints {
8391 match constraint {
8392 ColumnConstraint::References(fk_ref) => {
8393 self.write_space();
8394 if fk_ref.has_foreign_key_keywords {
8395 self.write_keyword("FOREIGN KEY");
8396 self.write_space();
8397 }
8398 self.write_keyword("REFERENCES");
8399 self.write_space();
8400 self.generate_table(&fk_ref.table)?;
8401 if !fk_ref.columns.is_empty() {
8402 self.write(" (");
8403 for (i, c) in fk_ref.columns.iter().enumerate() {
8404 if i > 0 {
8405 self.write(", ");
8406 }
8407 self.generate_identifier(c)?;
8408 }
8409 self.write(")");
8410 }
8411 self.generate_referential_actions(fk_ref)?;
8412 }
8413 ColumnConstraint::Check(expr) => {
8414 self.write_space();
8415 self.write_keyword("CHECK");
8416 self.write(" (");
8417 self.generate_expression(expr)?;
8418 self.write(")");
8419 }
8420 ColumnConstraint::GeneratedAsIdentity(gen) => {
8421 self.write_space();
8422 if matches!(
8424 self.config.dialect,
8425 Some(crate::dialects::DialectType::Redshift)
8426 ) {
8427 self.write_keyword("IDENTITY");
8428 self.write("(");
8429 if let Some(ref start) = gen.start {
8430 self.generate_expression(start)?;
8431 } else {
8432 self.write("0");
8433 }
8434 self.write(", ");
8435 if let Some(ref incr) = gen.increment {
8436 self.generate_expression(incr)?;
8437 } else {
8438 self.write("1");
8439 }
8440 self.write(")");
8441 } else {
8442 self.write_keyword("GENERATED");
8443 if gen.always {
8444 self.write_space();
8445 self.write_keyword("ALWAYS");
8446 } else {
8447 self.write_space();
8448 self.write_keyword("BY DEFAULT");
8449 if gen.on_null {
8450 self.write_space();
8451 self.write_keyword("ON NULL");
8452 }
8453 }
8454 self.write_space();
8455 self.write_keyword("AS IDENTITY");
8456
8457 let has_options = gen.start.is_some()
8458 || gen.increment.is_some()
8459 || gen.minvalue.is_some()
8460 || gen.maxvalue.is_some()
8461 || gen.cycle.is_some();
8462 if has_options {
8463 self.write(" (");
8464 let mut first = true;
8465 if let Some(ref start) = gen.start {
8466 if !first {
8467 self.write(" ");
8468 }
8469 first = false;
8470 self.write_keyword("START WITH");
8471 self.write_space();
8472 self.generate_expression(start)?;
8473 }
8474 if let Some(ref incr) = gen.increment {
8475 if !first {
8476 self.write(" ");
8477 }
8478 first = false;
8479 self.write_keyword("INCREMENT BY");
8480 self.write_space();
8481 self.generate_expression(incr)?;
8482 }
8483 if let Some(ref minv) = gen.minvalue {
8484 if !first {
8485 self.write(" ");
8486 }
8487 first = false;
8488 self.write_keyword("MINVALUE");
8489 self.write_space();
8490 self.generate_expression(minv)?;
8491 }
8492 if let Some(ref maxv) = gen.maxvalue {
8493 if !first {
8494 self.write(" ");
8495 }
8496 first = false;
8497 self.write_keyword("MAXVALUE");
8498 self.write_space();
8499 self.generate_expression(maxv)?;
8500 }
8501 if let Some(cycle) = gen.cycle {
8502 if !first {
8503 self.write(" ");
8504 }
8505 if cycle {
8506 self.write_keyword("CYCLE");
8507 } else {
8508 self.write_keyword("NO CYCLE");
8509 }
8510 }
8511 self.write(")");
8512 }
8513 }
8514 }
8515 ColumnConstraint::Collate(collation) => {
8516 self.write_space();
8517 self.write_keyword("COLLATE");
8518 self.write_space();
8519 self.generate_identifier(collation)?;
8520 }
8521 ColumnConstraint::Comment(comment) => {
8522 self.write_space();
8523 self.write_keyword("COMMENT");
8524 self.write_space();
8525 self.generate_string_literal(comment)?;
8526 }
8527 ColumnConstraint::Path(path_expr) => {
8528 self.write_space();
8529 self.write_keyword("PATH");
8530 self.write_space();
8531 self.generate_expression(path_expr)?;
8532 }
8533 _ => {} }
8535 }
8536
8537 if let Some(ref encoding) = col.encoding {
8539 self.write_space();
8540 self.write_keyword("ENCODE");
8541 self.write_space();
8542 self.write(encoding);
8543 }
8544 }
8545
8546 if let Some(ref codec) = col.codec {
8548 self.write_space();
8549 self.write_keyword("CODEC");
8550 self.write("(");
8551 self.write(codec);
8552 self.write(")");
8553 }
8554
8555 if let Some(ref ephemeral) = col.ephemeral {
8557 self.write_space();
8558 self.write_keyword("EPHEMERAL");
8559 if let Some(ref expr) = ephemeral {
8560 self.write_space();
8561 self.generate_expression(expr)?;
8562 }
8563 }
8564
8565 if let Some(ref mat_expr) = col.materialized_expr {
8567 self.write_space();
8568 self.write_keyword("MATERIALIZED");
8569 self.write_space();
8570 self.generate_expression(mat_expr)?;
8571 }
8572
8573 if let Some(ref alias_expr) = col.alias_expr {
8575 self.write_space();
8576 self.write_keyword("ALIAS");
8577 self.write_space();
8578 self.generate_expression(alias_expr)?;
8579 }
8580
8581 if let Some(ref ttl_expr) = col.ttl_expr {
8583 self.write_space();
8584 self.write_keyword("TTL");
8585 self.write_space();
8586 self.generate_expression(ttl_expr)?;
8587 }
8588
8589 if col.not_for_replication
8591 && matches!(
8592 self.config.dialect,
8593 Some(crate::dialects::DialectType::TSQL)
8594 | Some(crate::dialects::DialectType::Fabric)
8595 )
8596 {
8597 self.write_space();
8598 self.write_keyword("NOT FOR REPLICATION");
8599 }
8600
8601 if !col.options.is_empty() {
8603 self.write_space();
8604 self.generate_options_clause(&col.options)?;
8605 }
8606
8607 if !col.primary_key
8610 && self
8611 .sqlite_inline_pk_columns
8612 .contains(&col.name.name.to_lowercase())
8613 {
8614 self.write_space();
8615 self.write_keyword("PRIMARY KEY");
8616 }
8617
8618 if serial_expansion.is_some() {
8621 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
8622 self.write_space();
8623 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY NOT NULL");
8624 } else if matches!(self.config.dialect, Some(DialectType::Materialize)) {
8625 self.write_space();
8626 self.write_keyword("NOT NULL");
8627 }
8628 }
8629
8630 Ok(())
8631 }
8632
8633 fn generate_table_constraint(&mut self, constraint: &TableConstraint) -> Result<()> {
8634 match constraint {
8635 TableConstraint::PrimaryKey {
8636 name,
8637 columns,
8638 include_columns,
8639 modifiers,
8640 has_constraint_keyword,
8641 } => {
8642 if let Some(ref n) = name {
8643 if *has_constraint_keyword {
8644 self.write_keyword("CONSTRAINT");
8645 self.write_space();
8646 self.generate_identifier(n)?;
8647 self.write_space();
8648 }
8649 }
8650 self.write_keyword("PRIMARY KEY");
8651 if let Some(ref clustered) = modifiers.clustered {
8653 self.write_space();
8654 self.write_keyword(clustered);
8655 }
8656 if let Some(ref n) = name {
8658 if !*has_constraint_keyword {
8659 self.write_space();
8660 self.generate_identifier(n)?;
8661 }
8662 }
8663 self.write(" (");
8664 for (i, col) in columns.iter().enumerate() {
8665 if i > 0 {
8666 self.write(", ");
8667 }
8668 self.generate_identifier(col)?;
8669 }
8670 self.write(")");
8671 if !include_columns.is_empty() {
8672 self.write_space();
8673 self.write_keyword("INCLUDE");
8674 self.write(" (");
8675 for (i, col) in include_columns.iter().enumerate() {
8676 if i > 0 {
8677 self.write(", ");
8678 }
8679 self.generate_identifier(col)?;
8680 }
8681 self.write(")");
8682 }
8683 self.generate_constraint_modifiers(modifiers);
8684 }
8685 TableConstraint::Unique {
8686 name,
8687 columns,
8688 columns_parenthesized,
8689 modifiers,
8690 has_constraint_keyword,
8691 nulls_not_distinct,
8692 } => {
8693 if let Some(ref n) = name {
8694 if *has_constraint_keyword {
8695 self.write_keyword("CONSTRAINT");
8696 self.write_space();
8697 self.generate_identifier(n)?;
8698 self.write_space();
8699 }
8700 }
8701 self.write_keyword("UNIQUE");
8702 if let Some(ref clustered) = modifiers.clustered {
8704 self.write_space();
8705 self.write_keyword(clustered);
8706 }
8707 if *nulls_not_distinct {
8709 self.write(" NULLS NOT DISTINCT");
8710 }
8711 if let Some(ref n) = name {
8713 if !*has_constraint_keyword {
8714 self.write_space();
8715 self.generate_identifier(n)?;
8716 }
8717 }
8718 if *columns_parenthesized {
8719 self.write(" (");
8720 for (i, col) in columns.iter().enumerate() {
8721 if i > 0 {
8722 self.write(", ");
8723 }
8724 self.generate_identifier(col)?;
8725 }
8726 self.write(")");
8727 } else {
8728 for col in columns.iter() {
8730 self.write_space();
8731 self.generate_identifier(col)?;
8732 }
8733 }
8734 self.generate_constraint_modifiers(modifiers);
8735 }
8736 TableConstraint::ForeignKey {
8737 name,
8738 columns,
8739 references,
8740 on_delete,
8741 on_update,
8742 modifiers,
8743 } => {
8744 if let Some(ref n) = name {
8745 self.write_keyword("CONSTRAINT");
8746 self.write_space();
8747 self.generate_identifier(n)?;
8748 self.write_space();
8749 }
8750 self.write_keyword("FOREIGN KEY");
8751 self.write(" (");
8752 for (i, col) in columns.iter().enumerate() {
8753 if i > 0 {
8754 self.write(", ");
8755 }
8756 self.generate_identifier(col)?;
8757 }
8758 self.write(")");
8759 if let Some(ref refs) = references {
8760 self.write(" ");
8761 self.write_keyword("REFERENCES");
8762 self.write_space();
8763 self.generate_table(&refs.table)?;
8764 if !refs.columns.is_empty() {
8765 if self.config.pretty {
8766 self.write(" (");
8767 self.write_newline();
8768 self.indent_level += 1;
8769 for (i, col) in refs.columns.iter().enumerate() {
8770 if i > 0 {
8771 self.write(",");
8772 self.write_newline();
8773 }
8774 self.write_indent();
8775 self.generate_identifier(col)?;
8776 }
8777 self.indent_level -= 1;
8778 self.write_newline();
8779 self.write_indent();
8780 self.write(")");
8781 } else {
8782 self.write(" (");
8783 for (i, col) in refs.columns.iter().enumerate() {
8784 if i > 0 {
8785 self.write(", ");
8786 }
8787 self.generate_identifier(col)?;
8788 }
8789 self.write(")");
8790 }
8791 }
8792 self.generate_referential_actions(refs)?;
8793 } else {
8794 if let Some(ref action) = on_delete {
8796 self.write_space();
8797 self.write_keyword("ON DELETE");
8798 self.write_space();
8799 self.generate_referential_action(action);
8800 }
8801 if let Some(ref action) = on_update {
8802 self.write_space();
8803 self.write_keyword("ON UPDATE");
8804 self.write_space();
8805 self.generate_referential_action(action);
8806 }
8807 }
8808 self.generate_constraint_modifiers(modifiers);
8809 }
8810 TableConstraint::Check {
8811 name,
8812 expression,
8813 modifiers,
8814 } => {
8815 if let Some(ref n) = name {
8816 self.write_keyword("CONSTRAINT");
8817 self.write_space();
8818 self.generate_identifier(n)?;
8819 self.write_space();
8820 }
8821 self.write_keyword("CHECK");
8822 self.write(" (");
8823 self.generate_expression(expression)?;
8824 self.write(")");
8825 self.generate_constraint_modifiers(modifiers);
8826 }
8827 TableConstraint::Index {
8828 name,
8829 columns,
8830 kind,
8831 modifiers,
8832 use_key_keyword,
8833 expression,
8834 index_type,
8835 granularity,
8836 } => {
8837 if expression.is_some() {
8839 self.write_keyword("INDEX");
8840 if let Some(ref n) = name {
8841 self.write_space();
8842 self.generate_identifier(n)?;
8843 }
8844 if let Some(ref expr) = expression {
8845 self.write_space();
8846 self.generate_expression(expr)?;
8847 }
8848 if let Some(ref idx_type) = index_type {
8849 self.write_space();
8850 self.write_keyword("TYPE");
8851 self.write_space();
8852 self.generate_expression(idx_type)?;
8853 }
8854 if let Some(ref gran) = granularity {
8855 self.write_space();
8856 self.write_keyword("GRANULARITY");
8857 self.write_space();
8858 self.generate_expression(gran)?;
8859 }
8860 } else {
8861 use crate::dialects::DialectType;
8865 let index_keyword = if *use_key_keyword
8866 && !matches!(self.config.dialect, Some(DialectType::MySQL))
8867 {
8868 "KEY"
8869 } else {
8870 "INDEX"
8871 };
8872
8873 if let Some(ref k) = kind {
8875 self.write_keyword(k);
8876 if k != "UNIQUE" {
8878 self.write_space();
8879 self.write_keyword(index_keyword);
8880 }
8881 } else {
8882 self.write_keyword(index_keyword);
8883 }
8884
8885 if modifiers.using_before_columns && name.is_none() {
8887 if let Some(ref using) = modifiers.using {
8888 self.write_space();
8889 self.write_keyword("USING");
8890 self.write_space();
8891 self.write_keyword(using);
8892 }
8893 }
8894
8895 if let Some(ref n) = name {
8897 self.write_space();
8898 self.generate_identifier(n)?;
8899 }
8900
8901 if modifiers.using_before_columns && name.is_some() {
8903 if let Some(ref using) = modifiers.using {
8904 self.write_space();
8905 self.write_keyword("USING");
8906 self.write_space();
8907 self.write_keyword(using);
8908 }
8909 }
8910
8911 self.write(" (");
8913 for (i, col) in columns.iter().enumerate() {
8914 if i > 0 {
8915 self.write(", ");
8916 }
8917 self.generate_identifier(col)?;
8918 }
8919 self.write(")");
8920
8921 if !modifiers.using_before_columns {
8923 if let Some(ref using) = modifiers.using {
8924 self.write_space();
8925 self.write_keyword("USING");
8926 self.write_space();
8927 self.write_keyword(using);
8928 }
8929 }
8930
8931 self.generate_constraint_modifiers_without_using(modifiers);
8933 }
8934 }
8935 TableConstraint::Projection { name, expression } => {
8936 self.write_keyword("PROJECTION");
8938 self.write_space();
8939 self.generate_identifier(name)?;
8940 self.write(" (");
8941 self.generate_expression(expression)?;
8942 self.write(")");
8943 }
8944 TableConstraint::Like { source, options } => {
8945 self.write_keyword("LIKE");
8946 self.write_space();
8947 self.generate_table(source)?;
8948 for (action, prop) in options {
8949 self.write_space();
8950 match action {
8951 LikeOptionAction::Including => self.write_keyword("INCLUDING"),
8952 LikeOptionAction::Excluding => self.write_keyword("EXCLUDING"),
8953 }
8954 self.write_space();
8955 self.write_keyword(prop);
8956 }
8957 }
8958 TableConstraint::PeriodForSystemTime { start_col, end_col } => {
8959 self.write_keyword("PERIOD FOR SYSTEM_TIME");
8960 self.write(" (");
8961 self.generate_identifier(start_col)?;
8962 self.write(", ");
8963 self.generate_identifier(end_col)?;
8964 self.write(")");
8965 }
8966 TableConstraint::Exclude {
8967 name,
8968 using,
8969 elements,
8970 include_columns,
8971 where_clause,
8972 with_params,
8973 using_index_tablespace,
8974 modifiers: _,
8975 } => {
8976 if let Some(ref n) = name {
8977 self.write_keyword("CONSTRAINT");
8978 self.write_space();
8979 self.generate_identifier(n)?;
8980 self.write_space();
8981 }
8982 self.write_keyword("EXCLUDE");
8983 if let Some(ref method) = using {
8984 self.write_space();
8985 self.write_keyword("USING");
8986 self.write_space();
8987 self.write(method);
8988 self.write("(");
8989 } else {
8990 self.write(" (");
8991 }
8992 for (i, elem) in elements.iter().enumerate() {
8993 if i > 0 {
8994 self.write(", ");
8995 }
8996 self.write(&elem.expression);
8997 self.write_space();
8998 self.write_keyword("WITH");
8999 self.write_space();
9000 self.write(&elem.operator);
9001 }
9002 self.write(")");
9003 if !include_columns.is_empty() {
9004 self.write_space();
9005 self.write_keyword("INCLUDE");
9006 self.write(" (");
9007 for (i, col) in include_columns.iter().enumerate() {
9008 if i > 0 {
9009 self.write(", ");
9010 }
9011 self.generate_identifier(col)?;
9012 }
9013 self.write(")");
9014 }
9015 if !with_params.is_empty() {
9016 self.write_space();
9017 self.write_keyword("WITH");
9018 self.write(" (");
9019 for (i, (key, val)) in with_params.iter().enumerate() {
9020 if i > 0 {
9021 self.write(", ");
9022 }
9023 self.write(key);
9024 self.write("=");
9025 self.write(val);
9026 }
9027 self.write(")");
9028 }
9029 if let Some(ref tablespace) = using_index_tablespace {
9030 self.write_space();
9031 self.write_keyword("USING INDEX TABLESPACE");
9032 self.write_space();
9033 self.write(tablespace);
9034 }
9035 if let Some(ref where_expr) = where_clause {
9036 self.write_space();
9037 self.write_keyword("WHERE");
9038 self.write(" (");
9039 self.generate_expression(where_expr)?;
9040 self.write(")");
9041 }
9042 }
9043 TableConstraint::Tags(tags) => {
9044 self.write_keyword("TAG");
9045 self.write(" (");
9046 for (i, expr) in tags.expressions.iter().enumerate() {
9047 if i > 0 {
9048 self.write(", ");
9049 }
9050 self.generate_expression(expr)?;
9051 }
9052 self.write(")");
9053 }
9054 TableConstraint::InitiallyDeferred { deferred } => {
9055 self.write_keyword("INITIALLY");
9056 self.write_space();
9057 if *deferred {
9058 self.write_keyword("DEFERRED");
9059 } else {
9060 self.write_keyword("IMMEDIATE");
9061 }
9062 }
9063 }
9064 Ok(())
9065 }
9066
9067 fn generate_constraint_modifiers(&mut self, modifiers: &ConstraintModifiers) {
9068 if let Some(using) = &modifiers.using {
9070 self.write_space();
9071 self.write_keyword("USING");
9072 self.write_space();
9073 self.write_keyword(using);
9074 }
9075 if let Some(enforced) = modifiers.enforced {
9077 self.write_space();
9078 if enforced {
9079 self.write_keyword("ENFORCED");
9080 } else {
9081 self.write_keyword("NOT ENFORCED");
9082 }
9083 }
9084 if let Some(deferrable) = modifiers.deferrable {
9086 self.write_space();
9087 if deferrable {
9088 self.write_keyword("DEFERRABLE");
9089 } else {
9090 self.write_keyword("NOT DEFERRABLE");
9091 }
9092 }
9093 if let Some(initially_deferred) = modifiers.initially_deferred {
9095 self.write_space();
9096 if initially_deferred {
9097 self.write_keyword("INITIALLY DEFERRED");
9098 } else {
9099 self.write_keyword("INITIALLY IMMEDIATE");
9100 }
9101 }
9102 if modifiers.norely {
9104 self.write_space();
9105 self.write_keyword("NORELY");
9106 }
9107 if modifiers.rely {
9109 self.write_space();
9110 self.write_keyword("RELY");
9111 }
9112 if modifiers.not_valid {
9114 self.write_space();
9115 self.write_keyword("NOT VALID");
9116 }
9117 if let Some(on_conflict) = &modifiers.on_conflict {
9119 self.write_space();
9120 self.write_keyword("ON CONFLICT");
9121 self.write_space();
9122 self.write_keyword(on_conflict);
9123 }
9124 if !modifiers.with_options.is_empty() {
9126 self.write_space();
9127 self.write_keyword("WITH");
9128 self.write(" (");
9129 for (i, (key, value)) in modifiers.with_options.iter().enumerate() {
9130 if i > 0 {
9131 self.write(", ");
9132 }
9133 self.write(key);
9134 self.write("=");
9135 self.write(value);
9136 }
9137 self.write(")");
9138 }
9139 if let Some(ref fg) = modifiers.on_filegroup {
9141 self.write_space();
9142 self.write_keyword("ON");
9143 self.write_space();
9144 let _ = self.generate_identifier(fg);
9145 }
9146 }
9147
9148 fn generate_constraint_modifiers_without_using(&mut self, modifiers: &ConstraintModifiers) {
9150 if let Some(enforced) = modifiers.enforced {
9152 self.write_space();
9153 if enforced {
9154 self.write_keyword("ENFORCED");
9155 } else {
9156 self.write_keyword("NOT ENFORCED");
9157 }
9158 }
9159 if let Some(deferrable) = modifiers.deferrable {
9161 self.write_space();
9162 if deferrable {
9163 self.write_keyword("DEFERRABLE");
9164 } else {
9165 self.write_keyword("NOT DEFERRABLE");
9166 }
9167 }
9168 if let Some(initially_deferred) = modifiers.initially_deferred {
9170 self.write_space();
9171 if initially_deferred {
9172 self.write_keyword("INITIALLY DEFERRED");
9173 } else {
9174 self.write_keyword("INITIALLY IMMEDIATE");
9175 }
9176 }
9177 if modifiers.norely {
9179 self.write_space();
9180 self.write_keyword("NORELY");
9181 }
9182 if modifiers.rely {
9184 self.write_space();
9185 self.write_keyword("RELY");
9186 }
9187 if modifiers.not_valid {
9189 self.write_space();
9190 self.write_keyword("NOT VALID");
9191 }
9192 if let Some(on_conflict) = &modifiers.on_conflict {
9194 self.write_space();
9195 self.write_keyword("ON CONFLICT");
9196 self.write_space();
9197 self.write_keyword(on_conflict);
9198 }
9199 self.generate_index_specific_modifiers(modifiers);
9201 }
9202
9203 fn generate_index_specific_modifiers(&mut self, modifiers: &ConstraintModifiers) {
9205 if let Some(ref comment) = modifiers.comment {
9206 self.write_space();
9207 self.write_keyword("COMMENT");
9208 self.write(" '");
9209 self.write(comment);
9210 self.write("'");
9211 }
9212 if let Some(visible) = modifiers.visible {
9213 self.write_space();
9214 if visible {
9215 self.write_keyword("VISIBLE");
9216 } else {
9217 self.write_keyword("INVISIBLE");
9218 }
9219 }
9220 if let Some(ref attr) = modifiers.engine_attribute {
9221 self.write_space();
9222 self.write_keyword("ENGINE_ATTRIBUTE");
9223 self.write(" = '");
9224 self.write(attr);
9225 self.write("'");
9226 }
9227 if let Some(ref parser) = modifiers.with_parser {
9228 self.write_space();
9229 self.write_keyword("WITH PARSER");
9230 self.write_space();
9231 self.write(parser);
9232 }
9233 }
9234
9235 fn generate_referential_actions(&mut self, fk_ref: &ForeignKeyRef) -> Result<()> {
9236 if !fk_ref.match_after_actions {
9238 if let Some(ref match_type) = fk_ref.match_type {
9239 self.write_space();
9240 self.write_keyword("MATCH");
9241 self.write_space();
9242 match match_type {
9243 MatchType::Full => self.write_keyword("FULL"),
9244 MatchType::Partial => self.write_keyword("PARTIAL"),
9245 MatchType::Simple => self.write_keyword("SIMPLE"),
9246 }
9247 }
9248 }
9249
9250 if fk_ref.on_update_first {
9252 if let Some(ref action) = fk_ref.on_update {
9253 self.write_space();
9254 self.write_keyword("ON UPDATE");
9255 self.write_space();
9256 self.generate_referential_action(action);
9257 }
9258 if let Some(ref action) = fk_ref.on_delete {
9259 self.write_space();
9260 self.write_keyword("ON DELETE");
9261 self.write_space();
9262 self.generate_referential_action(action);
9263 }
9264 } else {
9265 if let Some(ref action) = fk_ref.on_delete {
9266 self.write_space();
9267 self.write_keyword("ON DELETE");
9268 self.write_space();
9269 self.generate_referential_action(action);
9270 }
9271 if let Some(ref action) = fk_ref.on_update {
9272 self.write_space();
9273 self.write_keyword("ON UPDATE");
9274 self.write_space();
9275 self.generate_referential_action(action);
9276 }
9277 }
9278
9279 if fk_ref.match_after_actions {
9281 if let Some(ref match_type) = fk_ref.match_type {
9282 self.write_space();
9283 self.write_keyword("MATCH");
9284 self.write_space();
9285 match match_type {
9286 MatchType::Full => self.write_keyword("FULL"),
9287 MatchType::Partial => self.write_keyword("PARTIAL"),
9288 MatchType::Simple => self.write_keyword("SIMPLE"),
9289 }
9290 }
9291 }
9292
9293 if let Some(deferrable) = fk_ref.deferrable {
9295 self.write_space();
9296 if deferrable {
9297 self.write_keyword("DEFERRABLE");
9298 } else {
9299 self.write_keyword("NOT DEFERRABLE");
9300 }
9301 }
9302
9303 Ok(())
9304 }
9305
9306 fn generate_referential_action(&mut self, action: &ReferentialAction) {
9307 match action {
9308 ReferentialAction::Cascade => self.write_keyword("CASCADE"),
9309 ReferentialAction::SetNull => self.write_keyword("SET NULL"),
9310 ReferentialAction::SetDefault => self.write_keyword("SET DEFAULT"),
9311 ReferentialAction::Restrict => self.write_keyword("RESTRICT"),
9312 ReferentialAction::NoAction => self.write_keyword("NO ACTION"),
9313 }
9314 }
9315
9316 fn generate_drop_table(&mut self, dt: &DropTable) -> Result<()> {
9317 let saved_athena_hive_context = self.athena_hive_context;
9319 if matches!(
9320 self.config.dialect,
9321 Some(crate::dialects::DialectType::Athena)
9322 ) {
9323 self.athena_hive_context = true;
9324 }
9325
9326 for comment in &dt.leading_comments {
9328 self.write_formatted_comment(comment);
9329 self.write_space();
9330 }
9331 self.write_keyword("DROP TABLE");
9332
9333 if dt.if_exists {
9334 self.write_space();
9335 self.write_keyword("IF EXISTS");
9336 }
9337
9338 self.write_space();
9339 for (i, table) in dt.names.iter().enumerate() {
9340 if i > 0 {
9341 self.write(", ");
9342 }
9343 self.generate_table(table)?;
9344 }
9345
9346 if dt.cascade_constraints {
9347 self.write_space();
9348 self.write_keyword("CASCADE CONSTRAINTS");
9349 } else if dt.cascade {
9350 self.write_space();
9351 self.write_keyword("CASCADE");
9352 }
9353
9354 if dt.purge {
9355 self.write_space();
9356 self.write_keyword("PURGE");
9357 }
9358
9359 self.athena_hive_context = saved_athena_hive_context;
9361
9362 Ok(())
9363 }
9364
9365 fn generate_alter_table(&mut self, at: &AlterTable) -> Result<()> {
9366 let saved_athena_hive_context = self.athena_hive_context;
9368 if matches!(
9369 self.config.dialect,
9370 Some(crate::dialects::DialectType::Athena)
9371 ) {
9372 self.athena_hive_context = true;
9373 }
9374
9375 self.write_keyword("ALTER TABLE");
9376 if at.if_exists {
9377 self.write_space();
9378 self.write_keyword("IF EXISTS");
9379 }
9380 self.write_space();
9381 self.generate_table(&at.name)?;
9382
9383 if let Some(ref on_cluster) = at.on_cluster {
9385 self.write_space();
9386 self.generate_on_cluster(on_cluster)?;
9387 }
9388
9389 if let Some(ref partition) = at.partition {
9391 self.write_space();
9392 self.write_keyword("PARTITION");
9393 self.write("(");
9394 for (i, (key, value)) in partition.iter().enumerate() {
9395 if i > 0 {
9396 self.write(", ");
9397 }
9398 self.generate_identifier(key)?;
9399 self.write(" = ");
9400 self.generate_expression(value)?;
9401 }
9402 self.write(")");
9403 }
9404
9405 if let Some(ref with_check) = at.with_check {
9407 self.write_space();
9408 self.write_keyword(with_check);
9409 }
9410
9411 if self.config.pretty {
9412 self.write_newline();
9414 self.indent_level += 1;
9415 for (i, action) in at.actions.iter().enumerate() {
9416 let is_continuation = i > 0
9418 && matches!(
9419 (&at.actions[i - 1], action),
9420 (
9421 AlterTableAction::AddColumn { .. },
9422 AlterTableAction::AddColumn { .. }
9423 ) | (
9424 AlterTableAction::AddConstraint(_),
9425 AlterTableAction::AddConstraint(_)
9426 )
9427 );
9428 if i > 0 {
9429 self.write(",");
9430 self.write_newline();
9431 }
9432 self.write_indent();
9433 self.generate_alter_action_with_continuation(action, is_continuation)?;
9434 }
9435 self.indent_level -= 1;
9436 } else {
9437 for (i, action) in at.actions.iter().enumerate() {
9438 let is_continuation = i > 0
9440 && matches!(
9441 (&at.actions[i - 1], action),
9442 (
9443 AlterTableAction::AddColumn { .. },
9444 AlterTableAction::AddColumn { .. }
9445 ) | (
9446 AlterTableAction::AddConstraint(_),
9447 AlterTableAction::AddConstraint(_)
9448 )
9449 );
9450 if i > 0 {
9451 self.write(",");
9452 }
9453 self.write_space();
9454 self.generate_alter_action_with_continuation(action, is_continuation)?;
9455 }
9456 }
9457
9458 if let Some(ref algorithm) = at.algorithm {
9460 self.write(", ");
9461 self.write_keyword("ALGORITHM");
9462 self.write("=");
9463 self.write_keyword(algorithm);
9464 }
9465 if let Some(ref lock) = at.lock {
9466 self.write(", ");
9467 self.write_keyword("LOCK");
9468 self.write("=");
9469 self.write_keyword(lock);
9470 }
9471
9472 self.athena_hive_context = saved_athena_hive_context;
9474
9475 Ok(())
9476 }
9477
9478 fn generate_alter_action_with_continuation(
9479 &mut self,
9480 action: &AlterTableAction,
9481 is_continuation: bool,
9482 ) -> Result<()> {
9483 match action {
9484 AlterTableAction::AddColumn {
9485 column,
9486 if_not_exists,
9487 position,
9488 } => {
9489 use crate::dialects::DialectType;
9490 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
9494 let is_tsql_like = matches!(
9495 self.config.dialect,
9496 Some(DialectType::TSQL) | Some(DialectType::Fabric)
9497 );
9498 let is_athena = matches!(self.config.dialect, Some(DialectType::Athena));
9500
9501 if is_continuation && (is_snowflake || is_tsql_like) {
9502 } else if is_snowflake {
9504 self.write_keyword("ADD");
9505 self.write_space();
9506 } else if is_athena {
9507 self.write_keyword("ADD COLUMNS");
9509 self.write(" (");
9510 } else if self.config.alter_table_include_column_keyword {
9511 self.write_keyword("ADD COLUMN");
9512 self.write_space();
9513 } else {
9514 self.write_keyword("ADD");
9516 self.write_space();
9517 }
9518
9519 if *if_not_exists {
9520 self.write_keyword("IF NOT EXISTS");
9521 self.write_space();
9522 }
9523 self.generate_column_def(column)?;
9524
9525 if is_athena {
9527 self.write(")");
9528 }
9529
9530 if let Some(pos) = position {
9532 self.write_space();
9533 match pos {
9534 ColumnPosition::First => self.write_keyword("FIRST"),
9535 ColumnPosition::After(col_name) => {
9536 self.write_keyword("AFTER");
9537 self.write_space();
9538 self.generate_identifier(col_name)?;
9539 }
9540 }
9541 }
9542 }
9543 AlterTableAction::DropColumn {
9544 name,
9545 if_exists,
9546 cascade,
9547 } => {
9548 self.write_keyword("DROP COLUMN");
9549 if *if_exists {
9550 self.write_space();
9551 self.write_keyword("IF EXISTS");
9552 }
9553 self.write_space();
9554 self.generate_identifier(name)?;
9555 if *cascade {
9556 self.write_space();
9557 self.write_keyword("CASCADE");
9558 }
9559 }
9560 AlterTableAction::DropColumns { names } => {
9561 self.write_keyword("DROP COLUMNS");
9562 self.write(" (");
9563 for (i, name) in names.iter().enumerate() {
9564 if i > 0 {
9565 self.write(", ");
9566 }
9567 self.generate_identifier(name)?;
9568 }
9569 self.write(")");
9570 }
9571 AlterTableAction::RenameColumn {
9572 old_name,
9573 new_name,
9574 if_exists,
9575 } => {
9576 self.write_keyword("RENAME COLUMN");
9577 if *if_exists {
9578 self.write_space();
9579 self.write_keyword("IF EXISTS");
9580 }
9581 self.write_space();
9582 self.generate_identifier(old_name)?;
9583 self.write_space();
9584 self.write_keyword("TO");
9585 self.write_space();
9586 self.generate_identifier(new_name)?;
9587 }
9588 AlterTableAction::AlterColumn {
9589 name,
9590 action,
9591 use_modify_keyword,
9592 } => {
9593 use crate::dialects::DialectType;
9594 let use_modify = *use_modify_keyword
9597 || (matches!(self.config.dialect, Some(DialectType::MySQL))
9598 && matches!(action, AlterColumnAction::SetDataType { .. }));
9599 if use_modify {
9600 self.write_keyword("MODIFY COLUMN");
9601 self.write_space();
9602 self.generate_identifier(name)?;
9603 if let AlterColumnAction::SetDataType {
9605 data_type,
9606 using: _,
9607 collate,
9608 } = action
9609 {
9610 self.write_space();
9611 self.generate_data_type(data_type)?;
9612 if let Some(collate_name) = collate {
9614 self.write_space();
9615 self.write_keyword("COLLATE");
9616 self.write_space();
9617 self.write(&format!("'{}'", collate_name));
9619 }
9620 } else {
9621 self.write_space();
9622 self.generate_alter_column_action(action)?;
9623 }
9624 } else if matches!(self.config.dialect, Some(DialectType::Hive))
9625 && matches!(action, AlterColumnAction::SetDataType { .. })
9626 {
9627 self.write_keyword("CHANGE COLUMN");
9629 self.write_space();
9630 self.generate_identifier(name)?;
9631 self.write_space();
9632 self.generate_identifier(name)?;
9633 if let AlterColumnAction::SetDataType { data_type, .. } = action {
9634 self.write_space();
9635 self.generate_data_type(data_type)?;
9636 }
9637 } else {
9638 self.write_keyword("ALTER COLUMN");
9639 self.write_space();
9640 self.generate_identifier(name)?;
9641 self.write_space();
9642 self.generate_alter_column_action(action)?;
9643 }
9644 }
9645 AlterTableAction::RenameTable(new_name) => {
9646 let mysql_like = matches!(
9648 self.config.dialect,
9649 Some(DialectType::MySQL)
9650 | Some(DialectType::Doris)
9651 | Some(DialectType::StarRocks)
9652 | Some(DialectType::SingleStore)
9653 );
9654 if mysql_like {
9655 self.write_keyword("RENAME");
9656 } else {
9657 self.write_keyword("RENAME TO");
9658 }
9659 self.write_space();
9660 let rename_table_with_db = !matches!(
9662 self.config.dialect,
9663 Some(DialectType::Doris)
9664 | Some(DialectType::DuckDB)
9665 | Some(DialectType::BigQuery)
9666 | Some(DialectType::PostgreSQL)
9667 );
9668 if !rename_table_with_db {
9669 let mut stripped = new_name.clone();
9670 stripped.schema = None;
9671 stripped.catalog = None;
9672 self.generate_table(&stripped)?;
9673 } else {
9674 self.generate_table(new_name)?;
9675 }
9676 }
9677 AlterTableAction::AddConstraint(constraint) => {
9678 if !is_continuation {
9681 self.write_keyword("ADD");
9682 self.write_space();
9683 }
9684 self.generate_table_constraint(constraint)?;
9685 }
9686 AlterTableAction::DropConstraint { name, if_exists } => {
9687 self.write_keyword("DROP CONSTRAINT");
9688 if *if_exists {
9689 self.write_space();
9690 self.write_keyword("IF EXISTS");
9691 }
9692 self.write_space();
9693 self.generate_identifier(name)?;
9694 }
9695 AlterTableAction::DropForeignKey { name } => {
9696 self.write_keyword("DROP FOREIGN KEY");
9697 self.write_space();
9698 self.generate_identifier(name)?;
9699 }
9700 AlterTableAction::DropPartition {
9701 partitions,
9702 if_exists,
9703 } => {
9704 self.write_keyword("DROP");
9705 if *if_exists {
9706 self.write_space();
9707 self.write_keyword("IF EXISTS");
9708 }
9709 for (i, partition) in partitions.iter().enumerate() {
9710 if i > 0 {
9711 self.write(",");
9712 }
9713 self.write_space();
9714 self.write_keyword("PARTITION");
9715 if partition.len() == 1 && partition[0].0.name == "__expr__" {
9717 self.write_space();
9719 self.generate_expression(&partition[0].1)?;
9720 } else if partition.len() == 1 && partition[0].0.name == "ALL" {
9721 self.write_space();
9723 self.write_keyword("ALL");
9724 } else if partition.len() == 1 && partition[0].0.name == "ID" {
9725 self.write_space();
9727 self.write_keyword("ID");
9728 self.write_space();
9729 self.generate_expression(&partition[0].1)?;
9730 } else {
9731 self.write("(");
9733 for (j, (key, value)) in partition.iter().enumerate() {
9734 if j > 0 {
9735 self.write(", ");
9736 }
9737 self.generate_identifier(key)?;
9738 self.write(" = ");
9739 self.generate_expression(value)?;
9740 }
9741 self.write(")");
9742 }
9743 }
9744 }
9745 AlterTableAction::Delete { where_clause } => {
9746 self.write_keyword("DELETE");
9747 self.write_space();
9748 self.write_keyword("WHERE");
9749 self.write_space();
9750 self.generate_expression(where_clause)?;
9751 }
9752 AlterTableAction::SwapWith(target) => {
9753 self.write_keyword("SWAP WITH");
9754 self.write_space();
9755 self.generate_table(target)?;
9756 }
9757 AlterTableAction::SetProperty { properties } => {
9758 use crate::dialects::DialectType;
9759 self.write_keyword("SET");
9760 let is_trino_presto = matches!(
9762 self.config.dialect,
9763 Some(DialectType::Trino) | Some(DialectType::Presto)
9764 );
9765 if is_trino_presto {
9766 self.write_space();
9767 self.write_keyword("PROPERTIES");
9768 }
9769 let eq = if is_trino_presto { " = " } else { "=" };
9770 for (i, (key, value)) in properties.iter().enumerate() {
9771 if i > 0 {
9772 self.write(",");
9773 }
9774 self.write_space();
9775 if key.contains(' ') {
9777 self.generate_string_literal(key)?;
9778 } else {
9779 self.write(key);
9780 }
9781 self.write(eq);
9782 self.generate_expression(value)?;
9783 }
9784 }
9785 AlterTableAction::UnsetProperty { properties } => {
9786 self.write_keyword("UNSET");
9787 for (i, name) in properties.iter().enumerate() {
9788 if i > 0 {
9789 self.write(",");
9790 }
9791 self.write_space();
9792 self.write(name);
9793 }
9794 }
9795 AlterTableAction::ClusterBy { expressions } => {
9796 self.write_keyword("CLUSTER BY");
9797 self.write(" (");
9798 for (i, expr) in expressions.iter().enumerate() {
9799 if i > 0 {
9800 self.write(", ");
9801 }
9802 self.generate_expression(expr)?;
9803 }
9804 self.write(")");
9805 }
9806 AlterTableAction::SetTag { expressions } => {
9807 self.write_keyword("SET TAG");
9808 for (i, (key, value)) in expressions.iter().enumerate() {
9809 if i > 0 {
9810 self.write(",");
9811 }
9812 self.write_space();
9813 self.write(key);
9814 self.write(" = ");
9815 self.generate_expression(value)?;
9816 }
9817 }
9818 AlterTableAction::UnsetTag { names } => {
9819 self.write_keyword("UNSET TAG");
9820 for (i, name) in names.iter().enumerate() {
9821 if i > 0 {
9822 self.write(",");
9823 }
9824 self.write_space();
9825 self.write(name);
9826 }
9827 }
9828 AlterTableAction::SetOptions { expressions } => {
9829 self.write_keyword("SET");
9830 self.write(" (");
9831 for (i, expr) in expressions.iter().enumerate() {
9832 if i > 0 {
9833 self.write(", ");
9834 }
9835 self.generate_expression(expr)?;
9836 }
9837 self.write(")");
9838 }
9839 AlterTableAction::AlterIndex { name, visible } => {
9840 self.write_keyword("ALTER INDEX");
9841 self.write_space();
9842 self.generate_identifier(name)?;
9843 self.write_space();
9844 if *visible {
9845 self.write_keyword("VISIBLE");
9846 } else {
9847 self.write_keyword("INVISIBLE");
9848 }
9849 }
9850 AlterTableAction::SetAttribute { attribute } => {
9851 self.write_keyword("SET");
9852 self.write_space();
9853 self.write_keyword(attribute);
9854 }
9855 AlterTableAction::SetStageFileFormat { options } => {
9856 self.write_keyword("SET");
9857 self.write_space();
9858 self.write_keyword("STAGE_FILE_FORMAT");
9859 self.write(" = (");
9860 if let Some(opts) = options {
9861 self.generate_space_separated_properties(opts)?;
9862 }
9863 self.write(")");
9864 }
9865 AlterTableAction::SetStageCopyOptions { options } => {
9866 self.write_keyword("SET");
9867 self.write_space();
9868 self.write_keyword("STAGE_COPY_OPTIONS");
9869 self.write(" = (");
9870 if let Some(opts) = options {
9871 self.generate_space_separated_properties(opts)?;
9872 }
9873 self.write(")");
9874 }
9875 AlterTableAction::AddColumns { columns, cascade } => {
9876 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
9879 if is_oracle {
9880 self.write_keyword("ADD");
9881 } else {
9882 self.write_keyword("ADD COLUMNS");
9883 }
9884 self.write(" (");
9885 for (i, col) in columns.iter().enumerate() {
9886 if i > 0 {
9887 self.write(", ");
9888 }
9889 self.generate_column_def(col)?;
9890 }
9891 self.write(")");
9892 if *cascade {
9893 self.write_space();
9894 self.write_keyword("CASCADE");
9895 }
9896 }
9897 AlterTableAction::ChangeColumn {
9898 old_name,
9899 new_name,
9900 data_type,
9901 comment,
9902 cascade,
9903 } => {
9904 use crate::dialects::DialectType;
9905 let is_spark = matches!(
9906 self.config.dialect,
9907 Some(DialectType::Spark) | Some(DialectType::Databricks)
9908 );
9909 let is_rename = old_name.name != new_name.name;
9910
9911 if is_spark {
9912 if is_rename {
9913 self.write_keyword("RENAME COLUMN");
9915 self.write_space();
9916 self.generate_identifier(old_name)?;
9917 self.write_space();
9918 self.write_keyword("TO");
9919 self.write_space();
9920 self.generate_identifier(new_name)?;
9921 } else if comment.is_some() {
9922 self.write_keyword("ALTER COLUMN");
9924 self.write_space();
9925 self.generate_identifier(old_name)?;
9926 self.write_space();
9927 self.write_keyword("COMMENT");
9928 self.write_space();
9929 self.write("'");
9930 self.write(comment.as_ref().unwrap());
9931 self.write("'");
9932 } else if data_type.is_some() {
9933 self.write_keyword("ALTER COLUMN");
9935 self.write_space();
9936 self.generate_identifier(old_name)?;
9937 self.write_space();
9938 self.write_keyword("TYPE");
9939 self.write_space();
9940 self.generate_data_type(data_type.as_ref().unwrap())?;
9941 } else {
9942 self.write_keyword("CHANGE COLUMN");
9944 self.write_space();
9945 self.generate_identifier(old_name)?;
9946 self.write_space();
9947 self.generate_identifier(new_name)?;
9948 }
9949 } else {
9950 if data_type.is_some() {
9952 self.write_keyword("CHANGE COLUMN");
9953 } else {
9954 self.write_keyword("CHANGE");
9955 }
9956 self.write_space();
9957 self.generate_identifier(old_name)?;
9958 self.write_space();
9959 self.generate_identifier(new_name)?;
9960 if let Some(ref dt) = data_type {
9961 self.write_space();
9962 self.generate_data_type(dt)?;
9963 }
9964 if let Some(ref c) = comment {
9965 self.write_space();
9966 self.write_keyword("COMMENT");
9967 self.write_space();
9968 self.write("'");
9969 self.write(c);
9970 self.write("'");
9971 }
9972 if *cascade {
9973 self.write_space();
9974 self.write_keyword("CASCADE");
9975 }
9976 }
9977 }
9978 AlterTableAction::AddPartition {
9979 partition,
9980 if_not_exists,
9981 location,
9982 } => {
9983 self.write_keyword("ADD");
9984 self.write_space();
9985 if *if_not_exists {
9986 self.write_keyword("IF NOT EXISTS");
9987 self.write_space();
9988 }
9989 self.generate_expression(partition)?;
9990 if let Some(ref loc) = location {
9991 self.write_space();
9992 self.write_keyword("LOCATION");
9993 self.write_space();
9994 self.generate_expression(loc)?;
9995 }
9996 }
9997 AlterTableAction::AlterSortKey {
9998 this,
9999 expressions,
10000 compound,
10001 } => {
10002 self.write_keyword("ALTER");
10004 if *compound {
10005 self.write_space();
10006 self.write_keyword("COMPOUND");
10007 }
10008 self.write_space();
10009 self.write_keyword("SORTKEY");
10010 self.write_space();
10011 if let Some(style) = this {
10012 self.write_keyword(style);
10013 } else if !expressions.is_empty() {
10014 self.write("(");
10015 for (i, expr) in expressions.iter().enumerate() {
10016 if i > 0 {
10017 self.write(", ");
10018 }
10019 self.generate_expression(expr)?;
10020 }
10021 self.write(")");
10022 }
10023 }
10024 AlterTableAction::AlterDistStyle { style, distkey } => {
10025 self.write_keyword("ALTER");
10027 self.write_space();
10028 self.write_keyword("DISTSTYLE");
10029 self.write_space();
10030 self.write_keyword(style);
10031 if let Some(col) = distkey {
10032 self.write_space();
10033 self.write_keyword("DISTKEY");
10034 self.write_space();
10035 self.generate_identifier(col)?;
10036 }
10037 }
10038 AlterTableAction::SetTableProperties { properties } => {
10039 self.write_keyword("SET TABLE PROPERTIES");
10041 self.write(" (");
10042 for (i, (key, value)) in properties.iter().enumerate() {
10043 if i > 0 {
10044 self.write(", ");
10045 }
10046 self.generate_expression(key)?;
10047 self.write(" = ");
10048 self.generate_expression(value)?;
10049 }
10050 self.write(")");
10051 }
10052 AlterTableAction::SetLocation { location } => {
10053 self.write_keyword("SET LOCATION");
10055 self.write_space();
10056 self.write("'");
10057 self.write(location);
10058 self.write("'");
10059 }
10060 AlterTableAction::SetFileFormat { format } => {
10061 self.write_keyword("SET FILE FORMAT");
10063 self.write_space();
10064 self.write_keyword(format);
10065 }
10066 AlterTableAction::ReplacePartition { partition, source } => {
10067 self.write_keyword("REPLACE PARTITION");
10069 self.write_space();
10070 self.generate_expression(partition)?;
10071 if let Some(src) = source {
10072 self.write_space();
10073 self.write_keyword("FROM");
10074 self.write_space();
10075 self.generate_expression(src)?;
10076 }
10077 }
10078 AlterTableAction::Raw { sql } => {
10079 self.write(sql);
10080 }
10081 }
10082 Ok(())
10083 }
10084
10085 fn generate_alter_column_action(&mut self, action: &AlterColumnAction) -> Result<()> {
10086 match action {
10087 AlterColumnAction::SetDataType {
10088 data_type,
10089 using,
10090 collate,
10091 } => {
10092 use crate::dialects::DialectType;
10093 let is_no_prefix = matches!(
10098 self.config.dialect,
10099 Some(DialectType::TSQL) | Some(DialectType::Fabric) | Some(DialectType::Hive)
10100 );
10101 let is_type_only = matches!(
10102 self.config.dialect,
10103 Some(DialectType::Redshift)
10104 | Some(DialectType::Spark)
10105 | Some(DialectType::Databricks)
10106 );
10107 if is_type_only {
10108 self.write_keyword("TYPE");
10109 self.write_space();
10110 } else if !is_no_prefix {
10111 self.write_keyword("SET DATA TYPE");
10112 self.write_space();
10113 }
10114 self.generate_data_type(data_type)?;
10115 if let Some(ref collation) = collate {
10116 self.write_space();
10117 self.write_keyword("COLLATE");
10118 self.write_space();
10119 self.write(collation);
10120 }
10121 if let Some(ref using_expr) = using {
10122 self.write_space();
10123 self.write_keyword("USING");
10124 self.write_space();
10125 self.generate_expression(using_expr)?;
10126 }
10127 }
10128 AlterColumnAction::SetDefault(expr) => {
10129 self.write_keyword("SET DEFAULT");
10130 self.write_space();
10131 self.generate_expression(expr)?;
10132 }
10133 AlterColumnAction::DropDefault => {
10134 self.write_keyword("DROP DEFAULT");
10135 }
10136 AlterColumnAction::SetNotNull => {
10137 self.write_keyword("SET NOT NULL");
10138 }
10139 AlterColumnAction::DropNotNull => {
10140 self.write_keyword("DROP NOT NULL");
10141 }
10142 AlterColumnAction::Comment(comment) => {
10143 self.write_keyword("COMMENT");
10144 self.write_space();
10145 self.generate_string_literal(comment)?;
10146 }
10147 AlterColumnAction::SetVisible => {
10148 self.write_keyword("SET VISIBLE");
10149 }
10150 AlterColumnAction::SetInvisible => {
10151 self.write_keyword("SET INVISIBLE");
10152 }
10153 }
10154 Ok(())
10155 }
10156
10157 fn generate_create_index(&mut self, ci: &CreateIndex) -> Result<()> {
10158 self.write_keyword("CREATE");
10159
10160 if ci.unique {
10161 self.write_space();
10162 self.write_keyword("UNIQUE");
10163 }
10164
10165 if let Some(ref clustered) = ci.clustered {
10167 self.write_space();
10168 self.write_keyword(clustered);
10169 }
10170
10171 self.write_space();
10172 self.write_keyword("INDEX");
10173
10174 if ci.concurrently {
10176 self.write_space();
10177 self.write_keyword("CONCURRENTLY");
10178 }
10179
10180 if ci.if_not_exists {
10181 self.write_space();
10182 self.write_keyword("IF NOT EXISTS");
10183 }
10184
10185 if !ci.name.name.is_empty() {
10187 self.write_space();
10188 self.generate_identifier(&ci.name)?;
10189 }
10190 self.write_space();
10191 self.write_keyword("ON");
10192 if matches!(self.config.dialect, Some(DialectType::Hive)) {
10194 self.write_space();
10195 self.write_keyword("TABLE");
10196 }
10197 self.write_space();
10198 self.generate_table(&ci.table)?;
10199
10200 if !ci.columns.is_empty() || ci.using.is_some() {
10203 let space_before_paren = false;
10204
10205 if let Some(ref using) = ci.using {
10206 self.write_space();
10207 self.write_keyword("USING");
10208 self.write_space();
10209 self.write(using);
10210 if space_before_paren {
10211 self.write(" (");
10212 } else {
10213 self.write("(");
10214 }
10215 } else {
10216 if space_before_paren {
10217 self.write(" (");
10218 } else {
10219 self.write("(");
10220 }
10221 }
10222 for (i, col) in ci.columns.iter().enumerate() {
10223 if i > 0 {
10224 self.write(", ");
10225 }
10226 self.generate_identifier(&col.column)?;
10227 if let Some(ref opclass) = col.opclass {
10228 self.write_space();
10229 self.write(opclass);
10230 }
10231 if col.desc {
10232 self.write_space();
10233 self.write_keyword("DESC");
10234 } else if col.asc {
10235 self.write_space();
10236 self.write_keyword("ASC");
10237 }
10238 if let Some(nulls_first) = col.nulls_first {
10239 self.write_space();
10240 self.write_keyword("NULLS");
10241 self.write_space();
10242 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
10243 }
10244 }
10245 self.write(")");
10246 }
10247
10248 if !ci.include_columns.is_empty() {
10250 self.write_space();
10251 self.write_keyword("INCLUDE");
10252 self.write(" (");
10253 for (i, col) in ci.include_columns.iter().enumerate() {
10254 if i > 0 {
10255 self.write(", ");
10256 }
10257 self.generate_identifier(col)?;
10258 }
10259 self.write(")");
10260 }
10261
10262 if !ci.with_options.is_empty() {
10264 self.write_space();
10265 self.write_keyword("WITH");
10266 self.write(" (");
10267 for (i, (key, value)) in ci.with_options.iter().enumerate() {
10268 if i > 0 {
10269 self.write(", ");
10270 }
10271 self.write(key);
10272 self.write("=");
10273 self.write(value);
10274 }
10275 self.write(")");
10276 }
10277
10278 if let Some(ref where_clause) = ci.where_clause {
10280 self.write_space();
10281 self.write_keyword("WHERE");
10282 self.write_space();
10283 self.generate_expression(where_clause)?;
10284 }
10285
10286 if let Some(ref on_fg) = ci.on_filegroup {
10288 self.write_space();
10289 self.write_keyword("ON");
10290 self.write_space();
10291 self.write(on_fg);
10292 }
10293
10294 Ok(())
10295 }
10296
10297 fn generate_drop_index(&mut self, di: &DropIndex) -> Result<()> {
10298 self.write_keyword("DROP INDEX");
10299
10300 if di.concurrently {
10301 self.write_space();
10302 self.write_keyword("CONCURRENTLY");
10303 }
10304
10305 if di.if_exists {
10306 self.write_space();
10307 self.write_keyword("IF EXISTS");
10308 }
10309
10310 self.write_space();
10311 self.generate_identifier(&di.name)?;
10312
10313 if let Some(ref table) = di.table {
10314 self.write_space();
10315 self.write_keyword("ON");
10316 self.write_space();
10317 self.generate_table(table)?;
10318 }
10319
10320 Ok(())
10321 }
10322
10323 fn generate_create_view(&mut self, cv: &CreateView) -> Result<()> {
10324 self.write_keyword("CREATE");
10325
10326 if let Some(ref algorithm) = cv.algorithm {
10328 self.write_space();
10329 self.write_keyword("ALGORITHM");
10330 self.write("=");
10331 self.write_keyword(algorithm);
10332 }
10333
10334 if let Some(ref definer) = cv.definer {
10336 self.write_space();
10337 self.write_keyword("DEFINER");
10338 self.write("=");
10339 self.write(definer);
10340 }
10341
10342 if cv.security_sql_style {
10344 if let Some(ref security) = cv.security {
10345 self.write_space();
10346 self.write_keyword("SQL SECURITY");
10347 self.write_space();
10348 match security {
10349 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
10350 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
10351 FunctionSecurity::None => self.write_keyword("NONE"),
10352 }
10353 }
10354 }
10355
10356 if cv.or_replace {
10357 self.write_space();
10358 self.write_keyword("OR REPLACE");
10359 }
10360
10361 if cv.temporary {
10362 self.write_space();
10363 self.write_keyword("TEMPORARY");
10364 }
10365
10366 if cv.materialized {
10367 self.write_space();
10368 self.write_keyword("MATERIALIZED");
10369 }
10370
10371 if cv.secure {
10373 self.write_space();
10374 self.write_keyword("SECURE");
10375 }
10376
10377 self.write_space();
10378 self.write_keyword("VIEW");
10379
10380 if cv.if_not_exists {
10381 self.write_space();
10382 self.write_keyword("IF NOT EXISTS");
10383 }
10384
10385 self.write_space();
10386 self.generate_table(&cv.name)?;
10387
10388 if let Some(ref on_cluster) = cv.on_cluster {
10390 self.write_space();
10391 self.generate_on_cluster(on_cluster)?;
10392 }
10393
10394 if let Some(ref to_table) = cv.to_table {
10396 self.write_space();
10397 self.write_keyword("TO");
10398 self.write_space();
10399 self.generate_table(to_table)?;
10400 }
10401
10402 if !cv.materialized {
10405 if !cv.columns.is_empty() {
10407 self.write(" (");
10408 for (i, col) in cv.columns.iter().enumerate() {
10409 if i > 0 {
10410 self.write(", ");
10411 }
10412 self.generate_identifier(&col.name)?;
10413 if !col.options.is_empty() {
10415 self.write_space();
10416 self.generate_options_clause(&col.options)?;
10417 }
10418 if let Some(ref comment) = col.comment {
10419 self.write_space();
10420 self.write_keyword("COMMENT");
10421 self.write_space();
10422 self.generate_string_literal(comment)?;
10423 }
10424 }
10425 self.write(")");
10426 }
10427
10428 if !cv.security_sql_style {
10430 if let Some(ref security) = cv.security {
10431 self.write_space();
10432 self.write_keyword("SECURITY");
10433 self.write_space();
10434 match security {
10435 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
10436 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
10437 FunctionSecurity::None => self.write_keyword("NONE"),
10438 }
10439 }
10440 }
10441
10442 if cv.copy_grants {
10444 self.write_space();
10445 self.write_keyword("COPY GRANTS");
10446 }
10447 } else {
10448 if cv.copy_grants {
10450 self.write_space();
10451 self.write_keyword("COPY GRANTS");
10452 }
10453
10454 if let Some(ref schema) = cv.schema {
10456 self.write(" (");
10457 for (i, expr) in schema.expressions.iter().enumerate() {
10458 if i > 0 {
10459 self.write(", ");
10460 }
10461 self.generate_expression(expr)?;
10462 }
10463 self.write(")");
10464 } else if !cv.columns.is_empty() {
10465 self.write(" (");
10467 for (i, col) in cv.columns.iter().enumerate() {
10468 if i > 0 {
10469 self.write(", ");
10470 }
10471 self.generate_identifier(&col.name)?;
10472 if !col.options.is_empty() {
10474 self.write_space();
10475 self.generate_options_clause(&col.options)?;
10476 }
10477 if let Some(ref comment) = col.comment {
10478 self.write_space();
10479 self.write_keyword("COMMENT");
10480 self.write_space();
10481 self.generate_string_literal(comment)?;
10482 }
10483 }
10484 self.write(")");
10485 }
10486
10487 if let Some(ref unique_key) = cv.unique_key {
10489 self.write_space();
10490 self.write_keyword("KEY");
10491 self.write(" (");
10492 for (i, expr) in unique_key.expressions.iter().enumerate() {
10493 if i > 0 {
10494 self.write(", ");
10495 }
10496 self.generate_expression(expr)?;
10497 }
10498 self.write(")");
10499 }
10500 }
10501
10502 if let Some(ref comment) = cv.comment {
10504 self.write_space();
10505 self.write_keyword("COMMENT");
10506 self.write("=");
10507 self.generate_string_literal(comment)?;
10508 }
10509
10510 if !cv.tags.is_empty() {
10512 self.write_space();
10513 self.write_keyword("TAG");
10514 self.write(" (");
10515 for (i, (name, value)) in cv.tags.iter().enumerate() {
10516 if i > 0 {
10517 self.write(", ");
10518 }
10519 self.write(name);
10520 self.write("='");
10521 self.write(value);
10522 self.write("'");
10523 }
10524 self.write(")");
10525 }
10526
10527 if !cv.options.is_empty() {
10529 self.write_space();
10530 self.generate_options_clause(&cv.options)?;
10531 }
10532
10533 if let Some(ref build) = cv.build {
10535 self.write_space();
10536 self.write_keyword("BUILD");
10537 self.write_space();
10538 self.write_keyword(build);
10539 }
10540
10541 if let Some(ref refresh) = cv.refresh {
10543 self.write_space();
10544 self.generate_refresh_trigger_property(refresh)?;
10545 }
10546
10547 if let Some(auto_refresh) = cv.auto_refresh {
10549 self.write_space();
10550 self.write_keyword("AUTO REFRESH");
10551 self.write_space();
10552 if auto_refresh {
10553 self.write_keyword("YES");
10554 } else {
10555 self.write_keyword("NO");
10556 }
10557 }
10558
10559 for prop in &cv.table_properties {
10561 self.write_space();
10562 self.generate_expression(prop)?;
10563 }
10564
10565 if !matches!(&cv.query, Expression::Null(_)) {
10567 self.write_space();
10568 self.write_keyword("AS");
10569 self.write_space();
10570
10571 if let Some(ref mode) = cv.locking_mode {
10573 self.write_keyword("LOCKING");
10574 self.write_space();
10575 self.write_keyword(mode);
10576 if let Some(ref access) = cv.locking_access {
10577 self.write_space();
10578 self.write_keyword("FOR");
10579 self.write_space();
10580 self.write_keyword(access);
10581 }
10582 self.write_space();
10583 }
10584
10585 if cv.query_parenthesized {
10586 self.write("(");
10587 }
10588 self.generate_expression(&cv.query)?;
10589 if cv.query_parenthesized {
10590 self.write(")");
10591 }
10592 }
10593
10594 if cv.no_schema_binding {
10596 self.write_space();
10597 self.write_keyword("WITH NO SCHEMA BINDING");
10598 }
10599
10600 Ok(())
10601 }
10602
10603 fn generate_drop_view(&mut self, dv: &DropView) -> Result<()> {
10604 self.write_keyword("DROP");
10605
10606 if dv.materialized {
10607 self.write_space();
10608 self.write_keyword("MATERIALIZED");
10609 }
10610
10611 self.write_space();
10612 self.write_keyword("VIEW");
10613
10614 if dv.if_exists {
10615 self.write_space();
10616 self.write_keyword("IF EXISTS");
10617 }
10618
10619 self.write_space();
10620 self.generate_table(&dv.name)?;
10621
10622 Ok(())
10623 }
10624
10625 fn generate_truncate(&mut self, tr: &Truncate) -> Result<()> {
10626 match tr.target {
10627 TruncateTarget::Database => self.write_keyword("TRUNCATE DATABASE"),
10628 TruncateTarget::Table => self.write_keyword("TRUNCATE TABLE"),
10629 }
10630 if tr.if_exists {
10631 self.write_space();
10632 self.write_keyword("IF EXISTS");
10633 }
10634 self.write_space();
10635 self.generate_table(&tr.table)?;
10636
10637 if let Some(ref on_cluster) = tr.on_cluster {
10639 self.write_space();
10640 self.generate_on_cluster(on_cluster)?;
10641 }
10642
10643 if !tr.extra_tables.is_empty() {
10645 let skip_first = if let Some(first) = tr.extra_tables.first() {
10647 first.table.name == tr.table.name && first.star
10648 } else {
10649 false
10650 };
10651
10652 let strip_star = matches!(
10654 self.config.dialect,
10655 Some(crate::dialects::DialectType::PostgreSQL)
10656 | Some(crate::dialects::DialectType::Redshift)
10657 );
10658 if skip_first && !strip_star {
10659 self.write("*");
10660 }
10661
10662 for (i, entry) in tr.extra_tables.iter().enumerate() {
10664 if i == 0 && skip_first {
10665 continue; }
10667 self.write(", ");
10668 self.generate_table(&entry.table)?;
10669 if entry.star && !strip_star {
10670 self.write("*");
10671 }
10672 }
10673 }
10674
10675 if let Some(identity) = &tr.identity {
10677 self.write_space();
10678 match identity {
10679 TruncateIdentity::Restart => self.write_keyword("RESTART IDENTITY"),
10680 TruncateIdentity::Continue => self.write_keyword("CONTINUE IDENTITY"),
10681 }
10682 }
10683
10684 if tr.cascade {
10685 self.write_space();
10686 self.write_keyword("CASCADE");
10687 }
10688
10689 if tr.restrict {
10690 self.write_space();
10691 self.write_keyword("RESTRICT");
10692 }
10693
10694 if let Some(ref partition) = tr.partition {
10696 self.write_space();
10697 self.generate_expression(partition)?;
10698 }
10699
10700 Ok(())
10701 }
10702
10703 fn generate_use(&mut self, u: &Use) -> Result<()> {
10704 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
10706 self.write_keyword("DATABASE");
10707 self.write_space();
10708 self.generate_identifier(&u.this)?;
10709 return Ok(());
10710 }
10711
10712 self.write_keyword("USE");
10713
10714 if let Some(kind) = &u.kind {
10715 self.write_space();
10716 match kind {
10717 UseKind::Database => self.write_keyword("DATABASE"),
10718 UseKind::Schema => self.write_keyword("SCHEMA"),
10719 UseKind::Role => self.write_keyword("ROLE"),
10720 UseKind::Warehouse => self.write_keyword("WAREHOUSE"),
10721 UseKind::Catalog => self.write_keyword("CATALOG"),
10722 UseKind::SecondaryRoles => self.write_keyword("SECONDARY ROLES"),
10723 }
10724 }
10725
10726 self.write_space();
10727 if matches!(&u.kind, Some(UseKind::SecondaryRoles)) {
10730 self.write(&u.this.name);
10731 } else {
10732 self.generate_identifier(&u.this)?;
10733 }
10734 Ok(())
10735 }
10736
10737 fn generate_cache(&mut self, c: &Cache) -> Result<()> {
10738 self.write_keyword("CACHE");
10739 if c.lazy {
10740 self.write_space();
10741 self.write_keyword("LAZY");
10742 }
10743 self.write_space();
10744 self.write_keyword("TABLE");
10745 self.write_space();
10746 self.generate_identifier(&c.table)?;
10747
10748 if !c.options.is_empty() {
10750 self.write_space();
10751 self.write_keyword("OPTIONS");
10752 self.write("(");
10753 for (i, (key, value)) in c.options.iter().enumerate() {
10754 if i > 0 {
10755 self.write(", ");
10756 }
10757 self.generate_expression(key)?;
10758 self.write(" = ");
10759 self.generate_expression(value)?;
10760 }
10761 self.write(")");
10762 }
10763
10764 if let Some(query) = &c.query {
10766 self.write_space();
10767 self.write_keyword("AS");
10768 self.write_space();
10769 self.generate_expression(query)?;
10770 }
10771
10772 Ok(())
10773 }
10774
10775 fn generate_uncache(&mut self, u: &Uncache) -> Result<()> {
10776 self.write_keyword("UNCACHE TABLE");
10777 if u.if_exists {
10778 self.write_space();
10779 self.write_keyword("IF EXISTS");
10780 }
10781 self.write_space();
10782 self.generate_identifier(&u.table)?;
10783 Ok(())
10784 }
10785
10786 fn generate_load_data(&mut self, l: &LoadData) -> Result<()> {
10787 self.write_keyword("LOAD DATA");
10788 if l.local {
10789 self.write_space();
10790 self.write_keyword("LOCAL");
10791 }
10792 self.write_space();
10793 self.write_keyword("INPATH");
10794 self.write_space();
10795 self.write("'");
10796 self.write(&l.inpath);
10797 self.write("'");
10798
10799 if l.overwrite {
10800 self.write_space();
10801 self.write_keyword("OVERWRITE");
10802 }
10803
10804 self.write_space();
10805 self.write_keyword("INTO TABLE");
10806 self.write_space();
10807 self.generate_expression(&l.table)?;
10808
10809 if !l.partition.is_empty() {
10811 self.write_space();
10812 self.write_keyword("PARTITION");
10813 self.write("(");
10814 for (i, (col, val)) in l.partition.iter().enumerate() {
10815 if i > 0 {
10816 self.write(", ");
10817 }
10818 self.generate_identifier(col)?;
10819 self.write(" = ");
10820 self.generate_expression(val)?;
10821 }
10822 self.write(")");
10823 }
10824
10825 if let Some(fmt) = &l.input_format {
10827 self.write_space();
10828 self.write_keyword("INPUTFORMAT");
10829 self.write_space();
10830 self.write("'");
10831 self.write(fmt);
10832 self.write("'");
10833 }
10834
10835 if let Some(serde) = &l.serde {
10837 self.write_space();
10838 self.write_keyword("SERDE");
10839 self.write_space();
10840 self.write("'");
10841 self.write(serde);
10842 self.write("'");
10843 }
10844
10845 Ok(())
10846 }
10847
10848 fn generate_pragma(&mut self, p: &Pragma) -> Result<()> {
10849 self.write_keyword("PRAGMA");
10850 self.write_space();
10851
10852 if let Some(schema) = &p.schema {
10854 self.generate_identifier(schema)?;
10855 self.write(".");
10856 }
10857
10858 self.generate_identifier(&p.name)?;
10860
10861 if let Some(value) = &p.value {
10863 self.write(" = ");
10864 self.generate_expression(value)?;
10865 } else if !p.args.is_empty() {
10866 self.write("(");
10867 for (i, arg) in p.args.iter().enumerate() {
10868 if i > 0 {
10869 self.write(", ");
10870 }
10871 self.generate_expression(arg)?;
10872 }
10873 self.write(")");
10874 }
10875
10876 Ok(())
10877 }
10878
10879 fn generate_grant(&mut self, g: &Grant) -> Result<()> {
10880 self.write_keyword("GRANT");
10881 self.write_space();
10882
10883 for (i, privilege) in g.privileges.iter().enumerate() {
10885 if i > 0 {
10886 self.write(", ");
10887 }
10888 self.write_keyword(&privilege.name);
10889 if !privilege.columns.is_empty() {
10891 self.write("(");
10892 for (j, col) in privilege.columns.iter().enumerate() {
10893 if j > 0 {
10894 self.write(", ");
10895 }
10896 self.write(col);
10897 }
10898 self.write(")");
10899 }
10900 }
10901
10902 self.write_space();
10903 self.write_keyword("ON");
10904 self.write_space();
10905
10906 if let Some(kind) = &g.kind {
10908 self.write_keyword(kind);
10909 self.write_space();
10910 }
10911
10912 {
10914 use crate::dialects::DialectType;
10915 let should_upper = matches!(
10916 self.config.dialect,
10917 Some(DialectType::PostgreSQL)
10918 | Some(DialectType::CockroachDB)
10919 | Some(DialectType::Materialize)
10920 | Some(DialectType::RisingWave)
10921 ) && (g.kind.as_deref() == Some("FUNCTION")
10922 || g.kind.as_deref() == Some("PROCEDURE"));
10923 if should_upper {
10924 use crate::expressions::Identifier;
10925 let upper_id = Identifier {
10926 name: g.securable.name.to_uppercase(),
10927 quoted: g.securable.quoted,
10928 ..g.securable.clone()
10929 };
10930 self.generate_identifier(&upper_id)?;
10931 } else {
10932 self.generate_identifier(&g.securable)?;
10933 }
10934 }
10935
10936 if !g.function_params.is_empty() {
10938 self.write("(");
10939 for (i, param) in g.function_params.iter().enumerate() {
10940 if i > 0 {
10941 self.write(", ");
10942 }
10943 self.write(param);
10944 }
10945 self.write(")");
10946 }
10947
10948 self.write_space();
10949 self.write_keyword("TO");
10950 self.write_space();
10951
10952 for (i, principal) in g.principals.iter().enumerate() {
10954 if i > 0 {
10955 self.write(", ");
10956 }
10957 if principal.is_role {
10958 self.write_keyword("ROLE");
10959 self.write_space();
10960 } else if principal.is_group {
10961 self.write_keyword("GROUP");
10962 self.write_space();
10963 }
10964 self.generate_identifier(&principal.name)?;
10965 }
10966
10967 if g.grant_option {
10969 self.write_space();
10970 self.write_keyword("WITH GRANT OPTION");
10971 }
10972
10973 if let Some(ref principal) = g.as_principal {
10975 self.write_space();
10976 self.write_keyword("AS");
10977 self.write_space();
10978 self.generate_identifier(principal)?;
10979 }
10980
10981 Ok(())
10982 }
10983
10984 fn generate_revoke(&mut self, r: &Revoke) -> Result<()> {
10985 self.write_keyword("REVOKE");
10986 self.write_space();
10987
10988 if r.grant_option {
10990 self.write_keyword("GRANT OPTION FOR");
10991 self.write_space();
10992 }
10993
10994 for (i, privilege) in r.privileges.iter().enumerate() {
10996 if i > 0 {
10997 self.write(", ");
10998 }
10999 self.write_keyword(&privilege.name);
11000 if !privilege.columns.is_empty() {
11002 self.write("(");
11003 for (j, col) in privilege.columns.iter().enumerate() {
11004 if j > 0 {
11005 self.write(", ");
11006 }
11007 self.write(col);
11008 }
11009 self.write(")");
11010 }
11011 }
11012
11013 self.write_space();
11014 self.write_keyword("ON");
11015 self.write_space();
11016
11017 if let Some(kind) = &r.kind {
11019 self.write_keyword(kind);
11020 self.write_space();
11021 }
11022
11023 {
11025 use crate::dialects::DialectType;
11026 let should_upper = matches!(
11027 self.config.dialect,
11028 Some(DialectType::PostgreSQL)
11029 | Some(DialectType::CockroachDB)
11030 | Some(DialectType::Materialize)
11031 | Some(DialectType::RisingWave)
11032 ) && (r.kind.as_deref() == Some("FUNCTION")
11033 || r.kind.as_deref() == Some("PROCEDURE"));
11034 if should_upper {
11035 use crate::expressions::Identifier;
11036 let upper_id = Identifier {
11037 name: r.securable.name.to_uppercase(),
11038 quoted: r.securable.quoted,
11039 ..r.securable.clone()
11040 };
11041 self.generate_identifier(&upper_id)?;
11042 } else {
11043 self.generate_identifier(&r.securable)?;
11044 }
11045 }
11046
11047 if !r.function_params.is_empty() {
11049 self.write("(");
11050 for (i, param) in r.function_params.iter().enumerate() {
11051 if i > 0 {
11052 self.write(", ");
11053 }
11054 self.write(param);
11055 }
11056 self.write(")");
11057 }
11058
11059 self.write_space();
11060 self.write_keyword("FROM");
11061 self.write_space();
11062
11063 for (i, principal) in r.principals.iter().enumerate() {
11065 if i > 0 {
11066 self.write(", ");
11067 }
11068 if principal.is_role {
11069 self.write_keyword("ROLE");
11070 self.write_space();
11071 } else if principal.is_group {
11072 self.write_keyword("GROUP");
11073 self.write_space();
11074 }
11075 self.generate_identifier(&principal.name)?;
11076 }
11077
11078 if r.cascade {
11080 self.write_space();
11081 self.write_keyword("CASCADE");
11082 } else if r.restrict {
11083 self.write_space();
11084 self.write_keyword("RESTRICT");
11085 }
11086
11087 Ok(())
11088 }
11089
11090 fn generate_comment(&mut self, c: &Comment) -> Result<()> {
11091 self.write_keyword("COMMENT");
11092
11093 if c.exists {
11095 self.write_space();
11096 self.write_keyword("IF EXISTS");
11097 }
11098
11099 self.write_space();
11100 self.write_keyword("ON");
11101
11102 if c.materialized {
11104 self.write_space();
11105 self.write_keyword("MATERIALIZED");
11106 }
11107
11108 self.write_space();
11109 self.write_keyword(&c.kind);
11110 self.write_space();
11111
11112 self.generate_expression(&c.this)?;
11114
11115 self.write_space();
11116 self.write_keyword("IS");
11117 self.write_space();
11118
11119 self.generate_expression(&c.expression)?;
11121
11122 Ok(())
11123 }
11124
11125 fn generate_set_statement(&mut self, s: &SetStatement) -> Result<()> {
11126 self.write_keyword("SET");
11127
11128 for (i, item) in s.items.iter().enumerate() {
11129 if i > 0 {
11130 self.write(",");
11131 }
11132 self.write_space();
11133
11134 if let Some(ref kind) = item.kind {
11136 self.write_keyword(kind);
11137 self.write_space();
11138 }
11139
11140 let name_str = match &item.name {
11142 Expression::Identifier(id) => Some(id.name.as_str()),
11143 _ => None,
11144 };
11145
11146 let is_transaction = name_str == Some("TRANSACTION");
11147 let is_character_set = name_str == Some("CHARACTER SET");
11148 let is_names = name_str == Some("NAMES");
11149 let is_collate = name_str == Some("COLLATE");
11150 let has_variable_kind = item.kind.as_deref() == Some("VARIABLE");
11151 let name_has_variable_prefix = name_str.map_or(false, |n| n.starts_with("VARIABLE "));
11152 let is_variable = has_variable_kind || name_has_variable_prefix;
11153 let is_value_only =
11154 matches!(&item.value, Expression::Identifier(id) if id.name.is_empty());
11155
11156 if is_transaction {
11157 self.write_keyword("TRANSACTION");
11159 if let Expression::Identifier(id) = &item.value {
11160 if !id.name.is_empty() {
11161 self.write_space();
11162 self.write(&id.name);
11163 }
11164 }
11165 } else if is_character_set {
11166 self.write_keyword("CHARACTER SET");
11168 self.write_space();
11169 self.generate_set_value(&item.value)?;
11170 } else if is_names {
11171 self.write_keyword("NAMES");
11173 self.write_space();
11174 self.generate_set_value(&item.value)?;
11175 } else if is_collate {
11176 self.write_keyword("COLLATE");
11178 self.write_space();
11179 self.generate_set_value(&item.value)?;
11180 } else if is_variable {
11181 if name_has_variable_prefix && !has_variable_kind {
11185 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
11186 self.write_keyword("VARIABLE");
11187 self.write_space();
11188 }
11189 }
11190 if let Some(ns) = name_str {
11192 let var_name = if name_has_variable_prefix {
11193 &ns["VARIABLE ".len()..]
11194 } else {
11195 ns
11196 };
11197 self.write(var_name);
11198 } else {
11199 self.generate_expression(&item.name)?;
11200 }
11201 self.write(" = ");
11202 self.generate_set_value(&item.value)?;
11203 } else if is_value_only {
11204 self.generate_expression(&item.name)?;
11206 } else if item.no_equals && matches!(self.config.dialect, Some(DialectType::TSQL)) {
11207 self.generate_expression(&item.name)?;
11209 self.write_space();
11210 self.generate_set_value(&item.value)?;
11211 } else {
11212 match &item.name {
11215 Expression::Identifier(id) => {
11216 self.write(&id.name);
11217 }
11218 _ => {
11219 self.generate_expression(&item.name)?;
11220 }
11221 }
11222 self.write(" = ");
11223 self.generate_set_value(&item.value)?;
11224 }
11225 }
11226
11227 Ok(())
11228 }
11229
11230 fn generate_set_value(&mut self, value: &Expression) -> Result<()> {
11233 if let Expression::Identifier(id) = value {
11234 match id.name.as_str() {
11235 "DEFAULT" | "ON" | "OFF" => {
11236 self.write_keyword(&id.name);
11237 return Ok(());
11238 }
11239 _ => {}
11240 }
11241 }
11242 self.generate_expression(value)
11243 }
11244
11245 fn generate_alter_view(&mut self, av: &AlterView) -> Result<()> {
11248 self.write_keyword("ALTER");
11249 if let Some(ref algorithm) = av.algorithm {
11251 self.write_space();
11252 self.write_keyword("ALGORITHM");
11253 self.write(" = ");
11254 self.write_keyword(algorithm);
11255 }
11256 if let Some(ref definer) = av.definer {
11257 self.write_space();
11258 self.write_keyword("DEFINER");
11259 self.write(" = ");
11260 self.write(definer);
11261 }
11262 if let Some(ref sql_security) = av.sql_security {
11263 self.write_space();
11264 self.write_keyword("SQL SECURITY");
11265 self.write(" = ");
11266 self.write_keyword(sql_security);
11267 }
11268 self.write_space();
11269 self.write_keyword("VIEW");
11270 self.write_space();
11271 self.generate_table(&av.name)?;
11272
11273 if !av.columns.is_empty() {
11275 self.write(" (");
11276 for (i, col) in av.columns.iter().enumerate() {
11277 if i > 0 {
11278 self.write(", ");
11279 }
11280 self.generate_identifier(&col.name)?;
11281 if let Some(ref comment) = col.comment {
11282 self.write_space();
11283 self.write_keyword("COMMENT");
11284 self.write(" ");
11285 self.generate_string_literal(comment)?;
11286 }
11287 }
11288 self.write(")");
11289 }
11290
11291 if let Some(ref opt) = av.with_option {
11293 self.write_space();
11294 self.write_keyword("WITH");
11295 self.write_space();
11296 self.write_keyword(opt);
11297 }
11298
11299 for action in &av.actions {
11300 self.write_space();
11301 match action {
11302 AlterViewAction::Rename(new_name) => {
11303 self.write_keyword("RENAME TO");
11304 self.write_space();
11305 self.generate_table(new_name)?;
11306 }
11307 AlterViewAction::OwnerTo(owner) => {
11308 self.write_keyword("OWNER TO");
11309 self.write_space();
11310 self.generate_identifier(owner)?;
11311 }
11312 AlterViewAction::SetSchema(schema) => {
11313 self.write_keyword("SET SCHEMA");
11314 self.write_space();
11315 self.generate_identifier(schema)?;
11316 }
11317 AlterViewAction::SetAuthorization(auth) => {
11318 self.write_keyword("SET AUTHORIZATION");
11319 self.write_space();
11320 self.write(auth);
11321 }
11322 AlterViewAction::AlterColumn { name, action } => {
11323 self.write_keyword("ALTER COLUMN");
11324 self.write_space();
11325 self.generate_identifier(name)?;
11326 self.write_space();
11327 self.generate_alter_column_action(action)?;
11328 }
11329 AlterViewAction::AsSelect(query) => {
11330 self.write_keyword("AS");
11331 self.write_space();
11332 self.generate_expression(query)?;
11333 }
11334 AlterViewAction::SetTblproperties(props) => {
11335 self.write_keyword("SET TBLPROPERTIES");
11336 self.write(" (");
11337 for (i, (key, value)) in props.iter().enumerate() {
11338 if i > 0 {
11339 self.write(", ");
11340 }
11341 self.generate_string_literal(key)?;
11342 self.write("=");
11343 self.generate_string_literal(value)?;
11344 }
11345 self.write(")");
11346 }
11347 AlterViewAction::UnsetTblproperties(keys) => {
11348 self.write_keyword("UNSET TBLPROPERTIES");
11349 self.write(" (");
11350 for (i, key) in keys.iter().enumerate() {
11351 if i > 0 {
11352 self.write(", ");
11353 }
11354 self.generate_string_literal(key)?;
11355 }
11356 self.write(")");
11357 }
11358 }
11359 }
11360
11361 Ok(())
11362 }
11363
11364 fn generate_alter_index(&mut self, ai: &AlterIndex) -> Result<()> {
11365 self.write_keyword("ALTER INDEX");
11366 self.write_space();
11367 self.generate_identifier(&ai.name)?;
11368
11369 if let Some(table) = &ai.table {
11370 self.write_space();
11371 self.write_keyword("ON");
11372 self.write_space();
11373 self.generate_table(table)?;
11374 }
11375
11376 for action in &ai.actions {
11377 self.write_space();
11378 match action {
11379 AlterIndexAction::Rename(new_name) => {
11380 self.write_keyword("RENAME TO");
11381 self.write_space();
11382 self.generate_identifier(new_name)?;
11383 }
11384 AlterIndexAction::SetTablespace(tablespace) => {
11385 self.write_keyword("SET TABLESPACE");
11386 self.write_space();
11387 self.generate_identifier(tablespace)?;
11388 }
11389 AlterIndexAction::Visible(visible) => {
11390 if *visible {
11391 self.write_keyword("VISIBLE");
11392 } else {
11393 self.write_keyword("INVISIBLE");
11394 }
11395 }
11396 }
11397 }
11398
11399 Ok(())
11400 }
11401
11402 fn generate_create_schema(&mut self, cs: &CreateSchema) -> Result<()> {
11403 for comment in &cs.leading_comments {
11405 self.write_formatted_comment(comment);
11406 self.write_space();
11407 }
11408
11409 let saved_athena_hive_context = self.athena_hive_context;
11411 if matches!(
11412 self.config.dialect,
11413 Some(crate::dialects::DialectType::Athena)
11414 ) {
11415 self.athena_hive_context = true;
11416 }
11417
11418 self.write_keyword("CREATE SCHEMA");
11419
11420 if cs.if_not_exists {
11421 self.write_space();
11422 self.write_keyword("IF NOT EXISTS");
11423 }
11424
11425 self.write_space();
11426 self.generate_identifier(&cs.name)?;
11427
11428 if let Some(ref clone_src) = cs.clone_from {
11429 self.write_keyword(" CLONE ");
11430 self.generate_identifier(clone_src)?;
11431 }
11432
11433 if let Some(ref at_clause) = cs.at_clause {
11434 self.write_space();
11435 self.generate_expression(at_clause)?;
11436 }
11437
11438 if let Some(auth) = &cs.authorization {
11439 self.write_space();
11440 self.write_keyword("AUTHORIZATION");
11441 self.write_space();
11442 self.generate_identifier(auth)?;
11443 }
11444
11445 let with_properties: Vec<_> = cs
11448 .properties
11449 .iter()
11450 .filter(|p| matches!(p, Expression::Property(_)))
11451 .collect();
11452 let other_properties: Vec<_> = cs
11453 .properties
11454 .iter()
11455 .filter(|p| !matches!(p, Expression::Property(_)))
11456 .collect();
11457
11458 if !with_properties.is_empty() {
11460 self.write_space();
11461 self.write_keyword("WITH");
11462 self.write(" (");
11463 for (i, prop) in with_properties.iter().enumerate() {
11464 if i > 0 {
11465 self.write(", ");
11466 }
11467 self.generate_expression(prop)?;
11468 }
11469 self.write(")");
11470 }
11471
11472 for prop in other_properties {
11474 self.write_space();
11475 self.generate_expression(prop)?;
11476 }
11477
11478 self.athena_hive_context = saved_athena_hive_context;
11480
11481 Ok(())
11482 }
11483
11484 fn generate_drop_schema(&mut self, ds: &DropSchema) -> Result<()> {
11485 self.write_keyword("DROP SCHEMA");
11486
11487 if ds.if_exists {
11488 self.write_space();
11489 self.write_keyword("IF EXISTS");
11490 }
11491
11492 self.write_space();
11493 self.generate_identifier(&ds.name)?;
11494
11495 if ds.cascade {
11496 self.write_space();
11497 self.write_keyword("CASCADE");
11498 }
11499
11500 Ok(())
11501 }
11502
11503 fn generate_drop_namespace(&mut self, dn: &DropNamespace) -> Result<()> {
11504 self.write_keyword("DROP NAMESPACE");
11505
11506 if dn.if_exists {
11507 self.write_space();
11508 self.write_keyword("IF EXISTS");
11509 }
11510
11511 self.write_space();
11512 self.generate_identifier(&dn.name)?;
11513
11514 if dn.cascade {
11515 self.write_space();
11516 self.write_keyword("CASCADE");
11517 }
11518
11519 Ok(())
11520 }
11521
11522 fn generate_create_database(&mut self, cd: &CreateDatabase) -> Result<()> {
11523 self.write_keyword("CREATE DATABASE");
11524
11525 if cd.if_not_exists {
11526 self.write_space();
11527 self.write_keyword("IF NOT EXISTS");
11528 }
11529
11530 self.write_space();
11531 self.generate_identifier(&cd.name)?;
11532
11533 if let Some(ref clone_src) = cd.clone_from {
11534 self.write_keyword(" CLONE ");
11535 self.generate_identifier(clone_src)?;
11536 }
11537
11538 if let Some(ref at_clause) = cd.at_clause {
11540 self.write_space();
11541 self.generate_expression(at_clause)?;
11542 }
11543
11544 for option in &cd.options {
11545 self.write_space();
11546 match option {
11547 DatabaseOption::CharacterSet(charset) => {
11548 self.write_keyword("CHARACTER SET");
11549 self.write(" = ");
11550 self.write(&format!("'{}'", charset));
11551 }
11552 DatabaseOption::Collate(collate) => {
11553 self.write_keyword("COLLATE");
11554 self.write(" = ");
11555 self.write(&format!("'{}'", collate));
11556 }
11557 DatabaseOption::Owner(owner) => {
11558 self.write_keyword("OWNER");
11559 self.write(" = ");
11560 self.generate_identifier(owner)?;
11561 }
11562 DatabaseOption::Template(template) => {
11563 self.write_keyword("TEMPLATE");
11564 self.write(" = ");
11565 self.generate_identifier(template)?;
11566 }
11567 DatabaseOption::Encoding(encoding) => {
11568 self.write_keyword("ENCODING");
11569 self.write(" = ");
11570 self.write(&format!("'{}'", encoding));
11571 }
11572 DatabaseOption::Location(location) => {
11573 self.write_keyword("LOCATION");
11574 self.write(" = ");
11575 self.write(&format!("'{}'", location));
11576 }
11577 }
11578 }
11579
11580 Ok(())
11581 }
11582
11583 fn generate_drop_database(&mut self, dd: &DropDatabase) -> Result<()> {
11584 self.write_keyword("DROP DATABASE");
11585
11586 if dd.if_exists {
11587 self.write_space();
11588 self.write_keyword("IF EXISTS");
11589 }
11590
11591 self.write_space();
11592 self.generate_identifier(&dd.name)?;
11593
11594 Ok(())
11595 }
11596
11597 fn generate_create_function(&mut self, cf: &CreateFunction) -> Result<()> {
11598 self.write_keyword("CREATE");
11599
11600 if cf.or_replace {
11601 self.write_space();
11602 self.write_keyword("OR REPLACE");
11603 }
11604
11605 if cf.temporary {
11606 self.write_space();
11607 self.write_keyword("TEMPORARY");
11608 }
11609
11610 self.write_space();
11611 if cf.is_table_function {
11612 self.write_keyword("TABLE FUNCTION");
11613 } else {
11614 self.write_keyword("FUNCTION");
11615 }
11616
11617 if cf.if_not_exists {
11618 self.write_space();
11619 self.write_keyword("IF NOT EXISTS");
11620 }
11621
11622 self.write_space();
11623 self.generate_table(&cf.name)?;
11624 if cf.has_parens {
11625 let func_multiline = self.config.pretty
11626 && matches!(
11627 self.config.dialect,
11628 Some(crate::dialects::DialectType::TSQL)
11629 | Some(crate::dialects::DialectType::Fabric)
11630 )
11631 && !cf.parameters.is_empty();
11632 if func_multiline {
11633 self.write("(\n");
11634 self.indent_level += 2;
11635 self.write_indent();
11636 self.generate_function_parameters(&cf.parameters)?;
11637 self.write("\n");
11638 self.indent_level -= 2;
11639 self.write(")");
11640 } else {
11641 self.write("(");
11642 self.generate_function_parameters(&cf.parameters)?;
11643 self.write(")");
11644 }
11645 }
11646
11647 let use_multiline = self.config.pretty
11650 && matches!(
11651 self.config.dialect,
11652 Some(crate::dialects::DialectType::BigQuery)
11653 | Some(crate::dialects::DialectType::TSQL)
11654 | Some(crate::dialects::DialectType::Fabric)
11655 );
11656
11657 if cf.language_first {
11658 if let Some(lang) = &cf.language {
11660 if use_multiline {
11661 self.write_newline();
11662 } else {
11663 self.write_space();
11664 }
11665 self.write_keyword("LANGUAGE");
11666 self.write_space();
11667 self.write(lang);
11668 }
11669
11670 if let Some(sql_data) = &cf.sql_data_access {
11672 self.write_space();
11673 match sql_data {
11674 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
11675 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
11676 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
11677 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
11678 }
11679 }
11680
11681 if let Some(ref rtb) = cf.returns_table_body {
11682 if use_multiline {
11683 self.write_newline();
11684 } else {
11685 self.write_space();
11686 }
11687 self.write_keyword("RETURNS");
11688 self.write_space();
11689 self.write(rtb);
11690 } else if let Some(return_type) = &cf.return_type {
11691 if use_multiline {
11692 self.write_newline();
11693 } else {
11694 self.write_space();
11695 }
11696 self.write_keyword("RETURNS");
11697 self.write_space();
11698 self.generate_data_type(return_type)?;
11699 }
11700 } else {
11701 let is_duckdb = matches!(
11704 self.config.dialect,
11705 Some(crate::dialects::DialectType::DuckDB)
11706 );
11707 if let Some(ref rtb) = cf.returns_table_body {
11708 if !(is_duckdb && rtb.is_empty()) {
11709 if use_multiline {
11710 self.write_newline();
11711 } else {
11712 self.write_space();
11713 }
11714 self.write_keyword("RETURNS");
11715 self.write_space();
11716 self.write(rtb);
11717 }
11718 } else if let Some(return_type) = &cf.return_type {
11719 if use_multiline {
11720 self.write_newline();
11721 } else {
11722 self.write_space();
11723 }
11724 self.write_keyword("RETURNS");
11725 self.write_space();
11726 self.generate_data_type(return_type)?;
11727 }
11728 }
11729
11730 if !cf.property_order.is_empty() {
11732 let is_bigquery = matches!(
11734 self.config.dialect,
11735 Some(crate::dialects::DialectType::BigQuery)
11736 );
11737 let property_order = if is_bigquery {
11738 let mut reordered = Vec::new();
11740 let mut has_as = false;
11741 let mut has_options = false;
11742 for prop in &cf.property_order {
11743 match prop {
11744 FunctionPropertyKind::As => has_as = true,
11745 FunctionPropertyKind::Options => has_options = true,
11746 _ => {}
11747 }
11748 }
11749 if has_as && has_options {
11750 for prop in &cf.property_order {
11752 if *prop != FunctionPropertyKind::As
11753 && *prop != FunctionPropertyKind::Options
11754 {
11755 reordered.push(*prop);
11756 }
11757 }
11758 reordered.push(FunctionPropertyKind::Options);
11759 reordered.push(FunctionPropertyKind::As);
11760 reordered
11761 } else {
11762 cf.property_order.clone()
11763 }
11764 } else {
11765 cf.property_order.clone()
11766 };
11767
11768 for prop in &property_order {
11769 match prop {
11770 FunctionPropertyKind::Set => {
11771 self.generate_function_set_options(cf)?;
11772 }
11773 FunctionPropertyKind::As => {
11774 self.generate_function_body(cf)?;
11775 }
11776 FunctionPropertyKind::Language => {
11777 if !cf.language_first {
11778 if let Some(lang) = &cf.language {
11780 let use_multiline = self.config.pretty
11782 && matches!(
11783 self.config.dialect,
11784 Some(crate::dialects::DialectType::BigQuery)
11785 );
11786 if use_multiline {
11787 self.write_newline();
11788 } else {
11789 self.write_space();
11790 }
11791 self.write_keyword("LANGUAGE");
11792 self.write_space();
11793 self.write(lang);
11794 }
11795 }
11796 }
11797 FunctionPropertyKind::Determinism => {
11798 self.generate_function_determinism(cf)?;
11799 }
11800 FunctionPropertyKind::NullInput => {
11801 self.generate_function_null_input(cf)?;
11802 }
11803 FunctionPropertyKind::Security => {
11804 self.generate_function_security(cf)?;
11805 }
11806 FunctionPropertyKind::SqlDataAccess => {
11807 if !cf.language_first {
11808 self.generate_function_sql_data_access(cf)?;
11810 }
11811 }
11812 FunctionPropertyKind::Options => {
11813 if !cf.options.is_empty() {
11814 self.write_space();
11815 self.generate_options_clause(&cf.options)?;
11816 }
11817 }
11818 FunctionPropertyKind::Environment => {
11819 if !cf.environment.is_empty() {
11820 self.write_space();
11821 self.generate_environment_clause(&cf.environment)?;
11822 }
11823 }
11824 }
11825 }
11826
11827 if !cf.options.is_empty() && !cf.property_order.contains(&FunctionPropertyKind::Options)
11829 {
11830 self.write_space();
11831 self.generate_options_clause(&cf.options)?;
11832 }
11833
11834 if !cf.environment.is_empty()
11836 && !cf
11837 .property_order
11838 .contains(&FunctionPropertyKind::Environment)
11839 {
11840 self.write_space();
11841 self.generate_environment_clause(&cf.environment)?;
11842 }
11843 } else {
11844 if matches!(
11847 self.config.dialect,
11848 Some(crate::dialects::DialectType::BigQuery)
11849 ) {
11850 self.generate_function_determinism(cf)?;
11851 }
11852
11853 let use_multiline = self.config.pretty
11855 && matches!(
11856 self.config.dialect,
11857 Some(crate::dialects::DialectType::BigQuery)
11858 );
11859
11860 if !cf.language_first {
11861 if let Some(lang) = &cf.language {
11862 if use_multiline {
11863 self.write_newline();
11864 } else {
11865 self.write_space();
11866 }
11867 self.write_keyword("LANGUAGE");
11868 self.write_space();
11869 self.write(lang);
11870 }
11871
11872 self.generate_function_sql_data_access(cf)?;
11874 }
11875
11876 if !matches!(
11878 self.config.dialect,
11879 Some(crate::dialects::DialectType::BigQuery)
11880 ) {
11881 self.generate_function_determinism(cf)?;
11882 }
11883
11884 self.generate_function_null_input(cf)?;
11885 self.generate_function_security(cf)?;
11886 self.generate_function_set_options(cf)?;
11887
11888 if !cf.options.is_empty() {
11890 self.write_space();
11891 self.generate_options_clause(&cf.options)?;
11892 }
11893
11894 if !cf.environment.is_empty() {
11896 self.write_space();
11897 self.generate_environment_clause(&cf.environment)?;
11898 }
11899
11900 self.generate_function_body(cf)?;
11901 }
11902
11903 Ok(())
11904 }
11905
11906 fn generate_function_set_options(&mut self, cf: &CreateFunction) -> Result<()> {
11908 for opt in &cf.set_options {
11909 self.write_space();
11910 self.write_keyword("SET");
11911 self.write_space();
11912 self.write(&opt.name);
11913 match &opt.value {
11914 FunctionSetValue::Value { value, use_to } => {
11915 if *use_to {
11916 self.write(" TO ");
11917 } else {
11918 self.write(" = ");
11919 }
11920 self.write(value);
11921 }
11922 FunctionSetValue::FromCurrent => {
11923 self.write_space();
11924 self.write_keyword("FROM CURRENT");
11925 }
11926 }
11927 }
11928 Ok(())
11929 }
11930
11931 fn generate_function_body(&mut self, cf: &CreateFunction) -> Result<()> {
11933 if let Some(body) = &cf.body {
11934 self.write_space();
11936 let use_multiline = self.config.pretty
11938 && matches!(
11939 self.config.dialect,
11940 Some(crate::dialects::DialectType::BigQuery)
11941 );
11942 match body {
11943 FunctionBody::Block(block) => {
11944 self.write_keyword("AS");
11945 if matches!(
11946 self.config.dialect,
11947 Some(crate::dialects::DialectType::TSQL)
11948 ) {
11949 self.write(" BEGIN ");
11950 self.write(block);
11951 self.write(" END");
11952 } else if matches!(
11953 self.config.dialect,
11954 Some(crate::dialects::DialectType::PostgreSQL)
11955 ) {
11956 self.write(" $$");
11957 self.write(block);
11958 self.write("$$");
11959 } else {
11960 let escaped = self.escape_block_for_single_quote(block);
11962 if use_multiline {
11964 self.write_newline();
11965 } else {
11966 self.write(" ");
11967 }
11968 self.write("'");
11969 self.write(&escaped);
11970 self.write("'");
11971 }
11972 }
11973 FunctionBody::StringLiteral(s) => {
11974 self.write_keyword("AS");
11975 if use_multiline {
11977 self.write_newline();
11978 } else {
11979 self.write(" ");
11980 }
11981 self.write("'");
11982 self.write(s);
11983 self.write("'");
11984 }
11985 FunctionBody::Expression(expr) => {
11986 self.write_keyword("AS");
11987 self.write_space();
11988 self.generate_expression(expr)?;
11989 }
11990 FunctionBody::External(name) => {
11991 self.write_keyword("EXTERNAL NAME");
11992 self.write(" '");
11993 self.write(name);
11994 self.write("'");
11995 }
11996 FunctionBody::Return(expr) => {
11997 if matches!(
11998 self.config.dialect,
11999 Some(crate::dialects::DialectType::DuckDB)
12000 ) {
12001 self.write_keyword("AS");
12003 self.write_space();
12004 if cf.returns_table_body.is_some() {
12006 self.write_keyword("TABLE");
12007 self.write_space();
12008 }
12009 self.generate_expression(expr)?;
12010 } else {
12011 if self.config.create_function_return_as {
12012 self.write_keyword("AS");
12013 if self.config.pretty
12015 && matches!(
12016 self.config.dialect,
12017 Some(crate::dialects::DialectType::TSQL)
12018 | Some(crate::dialects::DialectType::Fabric)
12019 )
12020 {
12021 self.write_newline();
12022 } else {
12023 self.write_space();
12024 }
12025 }
12026 self.write_keyword("RETURN");
12027 self.write_space();
12028 self.generate_expression(expr)?;
12029 }
12030 }
12031 FunctionBody::Statements(stmts) => {
12032 self.write_keyword("AS");
12033 self.write(" BEGIN ");
12034 for (i, stmt) in stmts.iter().enumerate() {
12035 if i > 0 {
12036 self.write(" ");
12037 }
12038 self.generate_expression(stmt)?;
12039 }
12040 self.write(" END");
12041 }
12042 FunctionBody::DollarQuoted { content, tag } => {
12043 self.write_keyword("AS");
12044 self.write(" ");
12045 let supports_dollar_quoting = matches!(
12047 self.config.dialect,
12048 Some(crate::dialects::DialectType::PostgreSQL)
12049 | Some(crate::dialects::DialectType::Databricks)
12050 | Some(crate::dialects::DialectType::Redshift)
12051 | Some(crate::dialects::DialectType::DuckDB)
12052 );
12053 if supports_dollar_quoting {
12054 self.write("$");
12056 if let Some(t) = tag {
12057 self.write(t);
12058 }
12059 self.write("$");
12060 self.write(content);
12061 self.write("$");
12062 if let Some(t) = tag {
12063 self.write(t);
12064 }
12065 self.write("$");
12066 } else {
12067 let escaped = self.escape_block_for_single_quote(content);
12069 self.write("'");
12070 self.write(&escaped);
12071 self.write("'");
12072 }
12073 }
12074 }
12075 }
12076 Ok(())
12077 }
12078
12079 fn generate_function_determinism(&mut self, cf: &CreateFunction) -> Result<()> {
12081 if let Some(det) = cf.deterministic {
12082 self.write_space();
12083 if matches!(
12084 self.config.dialect,
12085 Some(crate::dialects::DialectType::BigQuery)
12086 ) {
12087 if det {
12089 self.write_keyword("DETERMINISTIC");
12090 } else {
12091 self.write_keyword("NOT DETERMINISTIC");
12092 }
12093 } else {
12094 if det {
12096 self.write_keyword("IMMUTABLE");
12097 } else {
12098 self.write_keyword("VOLATILE");
12099 }
12100 }
12101 }
12102 Ok(())
12103 }
12104
12105 fn generate_function_null_input(&mut self, cf: &CreateFunction) -> Result<()> {
12107 if let Some(returns_null) = cf.returns_null_on_null_input {
12108 self.write_space();
12109 if returns_null {
12110 if cf.strict {
12111 self.write_keyword("STRICT");
12112 } else {
12113 self.write_keyword("RETURNS NULL ON NULL INPUT");
12114 }
12115 } else {
12116 self.write_keyword("CALLED ON NULL INPUT");
12117 }
12118 }
12119 Ok(())
12120 }
12121
12122 fn generate_function_security(&mut self, cf: &CreateFunction) -> Result<()> {
12124 if let Some(security) = &cf.security {
12125 self.write_space();
12126 self.write_keyword("SECURITY");
12127 self.write_space();
12128 match security {
12129 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
12130 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
12131 FunctionSecurity::None => self.write_keyword("NONE"),
12132 }
12133 }
12134 Ok(())
12135 }
12136
12137 fn generate_function_sql_data_access(&mut self, cf: &CreateFunction) -> Result<()> {
12139 if let Some(sql_data) = &cf.sql_data_access {
12140 self.write_space();
12141 match sql_data {
12142 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
12143 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
12144 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
12145 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
12146 }
12147 }
12148 Ok(())
12149 }
12150
12151 fn generate_function_parameters(&mut self, params: &[FunctionParameter]) -> Result<()> {
12152 for (i, param) in params.iter().enumerate() {
12153 if i > 0 {
12154 self.write(", ");
12155 }
12156
12157 if let Some(mode) = ¶m.mode {
12158 if let Some(text) = ¶m.mode_text {
12159 self.write(text);
12160 } else {
12161 match mode {
12162 ParameterMode::In => self.write_keyword("IN"),
12163 ParameterMode::Out => self.write_keyword("OUT"),
12164 ParameterMode::InOut => self.write_keyword("INOUT"),
12165 ParameterMode::Variadic => self.write_keyword("VARIADIC"),
12166 }
12167 }
12168 self.write_space();
12169 }
12170
12171 if let Some(name) = ¶m.name {
12172 self.generate_identifier(name)?;
12173 let skip_type =
12175 matches!(¶m.data_type, DataType::Custom { name } if name.is_empty());
12176 if !skip_type {
12177 self.write_space();
12178 self.generate_data_type(¶m.data_type)?;
12179 }
12180 } else {
12181 self.generate_data_type(¶m.data_type)?;
12182 }
12183
12184 if let Some(default) = ¶m.default {
12185 if self.config.parameter_default_equals {
12186 self.write(" = ");
12187 } else {
12188 self.write(" DEFAULT ");
12189 }
12190 self.generate_expression(default)?;
12191 }
12192 }
12193
12194 Ok(())
12195 }
12196
12197 fn generate_drop_function(&mut self, df: &DropFunction) -> Result<()> {
12198 self.write_keyword("DROP FUNCTION");
12199
12200 if df.if_exists {
12201 self.write_space();
12202 self.write_keyword("IF EXISTS");
12203 }
12204
12205 self.write_space();
12206 self.generate_table(&df.name)?;
12207
12208 if let Some(params) = &df.parameters {
12209 self.write(" (");
12210 for (i, dt) in params.iter().enumerate() {
12211 if i > 0 {
12212 self.write(", ");
12213 }
12214 self.generate_data_type(dt)?;
12215 }
12216 self.write(")");
12217 }
12218
12219 if df.cascade {
12220 self.write_space();
12221 self.write_keyword("CASCADE");
12222 }
12223
12224 Ok(())
12225 }
12226
12227 fn generate_create_procedure(&mut self, cp: &CreateProcedure) -> Result<()> {
12228 self.write_keyword("CREATE");
12229
12230 if cp.or_replace {
12231 self.write_space();
12232 self.write_keyword("OR REPLACE");
12233 }
12234
12235 self.write_space();
12236 if cp.use_proc_keyword {
12237 self.write_keyword("PROC");
12238 } else {
12239 self.write_keyword("PROCEDURE");
12240 }
12241
12242 if cp.if_not_exists {
12243 self.write_space();
12244 self.write_keyword("IF NOT EXISTS");
12245 }
12246
12247 self.write_space();
12248 self.generate_table(&cp.name)?;
12249 if cp.has_parens {
12250 self.write("(");
12251 self.generate_function_parameters(&cp.parameters)?;
12252 self.write(")");
12253 } else if !cp.parameters.is_empty() {
12254 self.write_space();
12256 self.generate_function_parameters(&cp.parameters)?;
12257 }
12258
12259 if let Some(return_type) = &cp.return_type {
12261 self.write_space();
12262 self.write_keyword("RETURNS");
12263 self.write_space();
12264 self.generate_data_type(return_type)?;
12265 }
12266
12267 if let Some(execute_as) = &cp.execute_as {
12269 self.write_space();
12270 self.write_keyword("EXECUTE AS");
12271 self.write_space();
12272 self.write_keyword(execute_as);
12273 }
12274
12275 if let Some(lang) = &cp.language {
12276 self.write_space();
12277 self.write_keyword("LANGUAGE");
12278 self.write_space();
12279 self.write(lang);
12280 }
12281
12282 if let Some(security) = &cp.security {
12283 self.write_space();
12284 self.write_keyword("SECURITY");
12285 self.write_space();
12286 match security {
12287 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
12288 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
12289 FunctionSecurity::None => self.write_keyword("NONE"),
12290 }
12291 }
12292
12293 if !cp.with_options.is_empty() {
12295 self.write_space();
12296 self.write_keyword("WITH");
12297 self.write_space();
12298 for (i, opt) in cp.with_options.iter().enumerate() {
12299 if i > 0 {
12300 self.write(", ");
12301 }
12302 self.write(opt);
12303 }
12304 }
12305
12306 if let Some(body) = &cp.body {
12307 self.write_space();
12308 match body {
12309 FunctionBody::Block(block) => {
12310 self.write_keyword("AS");
12311 if matches!(
12312 self.config.dialect,
12313 Some(crate::dialects::DialectType::TSQL)
12314 ) {
12315 self.write(" BEGIN ");
12316 self.write(block);
12317 self.write(" END");
12318 } else if matches!(
12319 self.config.dialect,
12320 Some(crate::dialects::DialectType::PostgreSQL)
12321 ) {
12322 self.write(" $$");
12323 self.write(block);
12324 self.write("$$");
12325 } else {
12326 let escaped = self.escape_block_for_single_quote(block);
12328 self.write(" '");
12329 self.write(&escaped);
12330 self.write("'");
12331 }
12332 }
12333 FunctionBody::StringLiteral(s) => {
12334 self.write_keyword("AS");
12335 self.write(" '");
12336 self.write(s);
12337 self.write("'");
12338 }
12339 FunctionBody::Expression(expr) => {
12340 self.write_keyword("AS");
12341 self.write_space();
12342 self.generate_expression(expr)?;
12343 }
12344 FunctionBody::External(name) => {
12345 self.write_keyword("EXTERNAL NAME");
12346 self.write(" '");
12347 self.write(name);
12348 self.write("'");
12349 }
12350 FunctionBody::Return(expr) => {
12351 self.write_keyword("RETURN");
12352 self.write_space();
12353 self.generate_expression(expr)?;
12354 }
12355 FunctionBody::Statements(stmts) => {
12356 self.write_keyword("AS");
12357 self.write(" BEGIN ");
12358 for (i, stmt) in stmts.iter().enumerate() {
12359 if i > 0 {
12360 self.write(" ");
12361 }
12362 self.generate_expression(stmt)?;
12363 }
12364 self.write(" END");
12365 }
12366 FunctionBody::DollarQuoted { content, tag } => {
12367 self.write_keyword("AS");
12368 self.write(" ");
12369 let supports_dollar_quoting = matches!(
12371 self.config.dialect,
12372 Some(crate::dialects::DialectType::PostgreSQL)
12373 | Some(crate::dialects::DialectType::Databricks)
12374 | Some(crate::dialects::DialectType::Redshift)
12375 | Some(crate::dialects::DialectType::DuckDB)
12376 );
12377 if supports_dollar_quoting {
12378 self.write("$");
12380 if let Some(t) = tag {
12381 self.write(t);
12382 }
12383 self.write("$");
12384 self.write(content);
12385 self.write("$");
12386 if let Some(t) = tag {
12387 self.write(t);
12388 }
12389 self.write("$");
12390 } else {
12391 let escaped = self.escape_block_for_single_quote(content);
12393 self.write("'");
12394 self.write(&escaped);
12395 self.write("'");
12396 }
12397 }
12398 }
12399 }
12400
12401 Ok(())
12402 }
12403
12404 fn generate_drop_procedure(&mut self, dp: &DropProcedure) -> Result<()> {
12405 self.write_keyword("DROP PROCEDURE");
12406
12407 if dp.if_exists {
12408 self.write_space();
12409 self.write_keyword("IF EXISTS");
12410 }
12411
12412 self.write_space();
12413 self.generate_table(&dp.name)?;
12414
12415 if let Some(params) = &dp.parameters {
12416 self.write(" (");
12417 for (i, dt) in params.iter().enumerate() {
12418 if i > 0 {
12419 self.write(", ");
12420 }
12421 self.generate_data_type(dt)?;
12422 }
12423 self.write(")");
12424 }
12425
12426 if dp.cascade {
12427 self.write_space();
12428 self.write_keyword("CASCADE");
12429 }
12430
12431 Ok(())
12432 }
12433
12434 fn generate_create_sequence(&mut self, cs: &CreateSequence) -> Result<()> {
12435 self.write_keyword("CREATE");
12436
12437 if cs.or_replace {
12438 self.write_space();
12439 self.write_keyword("OR REPLACE");
12440 }
12441
12442 if cs.temporary {
12443 self.write_space();
12444 self.write_keyword("TEMPORARY");
12445 }
12446
12447 self.write_space();
12448 self.write_keyword("SEQUENCE");
12449
12450 if cs.if_not_exists {
12451 self.write_space();
12452 self.write_keyword("IF NOT EXISTS");
12453 }
12454
12455 self.write_space();
12456 self.generate_table(&cs.name)?;
12457
12458 if let Some(as_type) = &cs.as_type {
12460 self.write_space();
12461 self.write_keyword("AS");
12462 self.write_space();
12463 self.generate_data_type(as_type)?;
12464 }
12465
12466 if let Some(comment) = &cs.comment {
12468 self.write_space();
12469 self.write_keyword("COMMENT");
12470 self.write("=");
12471 self.generate_string_literal(comment)?;
12472 }
12473
12474 if !cs.property_order.is_empty() {
12476 for prop in &cs.property_order {
12477 match prop {
12478 SeqPropKind::Start => {
12479 if let Some(start) = cs.start {
12480 self.write_space();
12481 self.write_keyword("START WITH");
12482 self.write(&format!(" {}", start));
12483 }
12484 }
12485 SeqPropKind::Increment => {
12486 if let Some(inc) = cs.increment {
12487 self.write_space();
12488 self.write_keyword("INCREMENT BY");
12489 self.write(&format!(" {}", inc));
12490 }
12491 }
12492 SeqPropKind::Minvalue => {
12493 if let Some(min) = &cs.minvalue {
12494 self.write_space();
12495 match min {
12496 SequenceBound::Value(v) => {
12497 self.write_keyword("MINVALUE");
12498 self.write(&format!(" {}", v));
12499 }
12500 SequenceBound::None => {
12501 self.write_keyword("NO MINVALUE");
12502 }
12503 }
12504 }
12505 }
12506 SeqPropKind::Maxvalue => {
12507 if let Some(max) = &cs.maxvalue {
12508 self.write_space();
12509 match max {
12510 SequenceBound::Value(v) => {
12511 self.write_keyword("MAXVALUE");
12512 self.write(&format!(" {}", v));
12513 }
12514 SequenceBound::None => {
12515 self.write_keyword("NO MAXVALUE");
12516 }
12517 }
12518 }
12519 }
12520 SeqPropKind::Cache => {
12521 if let Some(cache) = cs.cache {
12522 self.write_space();
12523 self.write_keyword("CACHE");
12524 self.write(&format!(" {}", cache));
12525 }
12526 }
12527 SeqPropKind::NoCache => {
12528 self.write_space();
12529 self.write_keyword("NO CACHE");
12530 }
12531 SeqPropKind::NoCacheWord => {
12532 self.write_space();
12533 self.write_keyword("NOCACHE");
12534 }
12535 SeqPropKind::Cycle => {
12536 self.write_space();
12537 self.write_keyword("CYCLE");
12538 }
12539 SeqPropKind::NoCycle => {
12540 self.write_space();
12541 self.write_keyword("NO CYCLE");
12542 }
12543 SeqPropKind::NoCycleWord => {
12544 self.write_space();
12545 self.write_keyword("NOCYCLE");
12546 }
12547 SeqPropKind::OwnedBy => {
12548 if !cs.owned_by_none {
12550 if let Some(owned) = &cs.owned_by {
12551 self.write_space();
12552 self.write_keyword("OWNED BY");
12553 self.write_space();
12554 self.generate_table(owned)?;
12555 }
12556 }
12557 }
12558 SeqPropKind::Order => {
12559 self.write_space();
12560 self.write_keyword("ORDER");
12561 }
12562 SeqPropKind::NoOrder => {
12563 self.write_space();
12564 self.write_keyword("NOORDER");
12565 }
12566 SeqPropKind::Comment => {
12567 }
12569 SeqPropKind::Sharing => {
12570 if let Some(val) = &cs.sharing {
12571 self.write_space();
12572 self.write(&format!("SHARING={}", val));
12573 }
12574 }
12575 SeqPropKind::Keep => {
12576 self.write_space();
12577 self.write_keyword("KEEP");
12578 }
12579 SeqPropKind::NoKeep => {
12580 self.write_space();
12581 self.write_keyword("NOKEEP");
12582 }
12583 SeqPropKind::Scale => {
12584 self.write_space();
12585 self.write_keyword("SCALE");
12586 if let Some(modifier) = &cs.scale_modifier {
12587 if !modifier.is_empty() {
12588 self.write_space();
12589 self.write_keyword(modifier);
12590 }
12591 }
12592 }
12593 SeqPropKind::NoScale => {
12594 self.write_space();
12595 self.write_keyword("NOSCALE");
12596 }
12597 SeqPropKind::Shard => {
12598 self.write_space();
12599 self.write_keyword("SHARD");
12600 if let Some(modifier) = &cs.shard_modifier {
12601 if !modifier.is_empty() {
12602 self.write_space();
12603 self.write_keyword(modifier);
12604 }
12605 }
12606 }
12607 SeqPropKind::NoShard => {
12608 self.write_space();
12609 self.write_keyword("NOSHARD");
12610 }
12611 SeqPropKind::Session => {
12612 self.write_space();
12613 self.write_keyword("SESSION");
12614 }
12615 SeqPropKind::Global => {
12616 self.write_space();
12617 self.write_keyword("GLOBAL");
12618 }
12619 SeqPropKind::NoMinvalueWord => {
12620 self.write_space();
12621 self.write_keyword("NOMINVALUE");
12622 }
12623 SeqPropKind::NoMaxvalueWord => {
12624 self.write_space();
12625 self.write_keyword("NOMAXVALUE");
12626 }
12627 }
12628 }
12629 } else {
12630 if let Some(inc) = cs.increment {
12632 self.write_space();
12633 self.write_keyword("INCREMENT BY");
12634 self.write(&format!(" {}", inc));
12635 }
12636
12637 if let Some(min) = &cs.minvalue {
12638 self.write_space();
12639 match min {
12640 SequenceBound::Value(v) => {
12641 self.write_keyword("MINVALUE");
12642 self.write(&format!(" {}", v));
12643 }
12644 SequenceBound::None => {
12645 self.write_keyword("NO MINVALUE");
12646 }
12647 }
12648 }
12649
12650 if let Some(max) = &cs.maxvalue {
12651 self.write_space();
12652 match max {
12653 SequenceBound::Value(v) => {
12654 self.write_keyword("MAXVALUE");
12655 self.write(&format!(" {}", v));
12656 }
12657 SequenceBound::None => {
12658 self.write_keyword("NO MAXVALUE");
12659 }
12660 }
12661 }
12662
12663 if let Some(start) = cs.start {
12664 self.write_space();
12665 self.write_keyword("START WITH");
12666 self.write(&format!(" {}", start));
12667 }
12668
12669 if let Some(cache) = cs.cache {
12670 self.write_space();
12671 self.write_keyword("CACHE");
12672 self.write(&format!(" {}", cache));
12673 }
12674
12675 if cs.cycle {
12676 self.write_space();
12677 self.write_keyword("CYCLE");
12678 }
12679
12680 if let Some(owned) = &cs.owned_by {
12681 self.write_space();
12682 self.write_keyword("OWNED BY");
12683 self.write_space();
12684 self.generate_table(owned)?;
12685 }
12686 }
12687
12688 Ok(())
12689 }
12690
12691 fn generate_drop_sequence(&mut self, ds: &DropSequence) -> Result<()> {
12692 self.write_keyword("DROP SEQUENCE");
12693
12694 if ds.if_exists {
12695 self.write_space();
12696 self.write_keyword("IF EXISTS");
12697 }
12698
12699 self.write_space();
12700 self.generate_table(&ds.name)?;
12701
12702 if ds.cascade {
12703 self.write_space();
12704 self.write_keyword("CASCADE");
12705 }
12706
12707 Ok(())
12708 }
12709
12710 fn generate_alter_sequence(&mut self, als: &AlterSequence) -> Result<()> {
12711 self.write_keyword("ALTER SEQUENCE");
12712
12713 if als.if_exists {
12714 self.write_space();
12715 self.write_keyword("IF EXISTS");
12716 }
12717
12718 self.write_space();
12719 self.generate_table(&als.name)?;
12720
12721 if let Some(inc) = als.increment {
12722 self.write_space();
12723 self.write_keyword("INCREMENT BY");
12724 self.write(&format!(" {}", inc));
12725 }
12726
12727 if let Some(min) = &als.minvalue {
12728 self.write_space();
12729 match min {
12730 SequenceBound::Value(v) => {
12731 self.write_keyword("MINVALUE");
12732 self.write(&format!(" {}", v));
12733 }
12734 SequenceBound::None => {
12735 self.write_keyword("NO MINVALUE");
12736 }
12737 }
12738 }
12739
12740 if let Some(max) = &als.maxvalue {
12741 self.write_space();
12742 match max {
12743 SequenceBound::Value(v) => {
12744 self.write_keyword("MAXVALUE");
12745 self.write(&format!(" {}", v));
12746 }
12747 SequenceBound::None => {
12748 self.write_keyword("NO MAXVALUE");
12749 }
12750 }
12751 }
12752
12753 if let Some(start) = als.start {
12754 self.write_space();
12755 self.write_keyword("START WITH");
12756 self.write(&format!(" {}", start));
12757 }
12758
12759 if let Some(restart) = &als.restart {
12760 self.write_space();
12761 self.write_keyword("RESTART");
12762 if let Some(val) = restart {
12763 self.write_keyword(" WITH");
12764 self.write(&format!(" {}", val));
12765 }
12766 }
12767
12768 if let Some(cache) = als.cache {
12769 self.write_space();
12770 self.write_keyword("CACHE");
12771 self.write(&format!(" {}", cache));
12772 }
12773
12774 if let Some(cycle) = als.cycle {
12775 self.write_space();
12776 if cycle {
12777 self.write_keyword("CYCLE");
12778 } else {
12779 self.write_keyword("NO CYCLE");
12780 }
12781 }
12782
12783 if let Some(owned) = &als.owned_by {
12784 self.write_space();
12785 self.write_keyword("OWNED BY");
12786 self.write_space();
12787 if let Some(table) = owned {
12788 self.generate_table(table)?;
12789 } else {
12790 self.write_keyword("NONE");
12791 }
12792 }
12793
12794 Ok(())
12795 }
12796
12797 fn generate_create_trigger(&mut self, ct: &CreateTrigger) -> Result<()> {
12798 self.write_keyword("CREATE");
12799
12800 if ct.or_replace {
12801 self.write_space();
12802 self.write_keyword("OR REPLACE");
12803 }
12804
12805 if ct.constraint {
12806 self.write_space();
12807 self.write_keyword("CONSTRAINT");
12808 }
12809
12810 self.write_space();
12811 self.write_keyword("TRIGGER");
12812 self.write_space();
12813 self.generate_identifier(&ct.name)?;
12814
12815 self.write_space();
12816 match ct.timing {
12817 TriggerTiming::Before => self.write_keyword("BEFORE"),
12818 TriggerTiming::After => self.write_keyword("AFTER"),
12819 TriggerTiming::InsteadOf => self.write_keyword("INSTEAD OF"),
12820 }
12821
12822 for (i, event) in ct.events.iter().enumerate() {
12824 if i > 0 {
12825 self.write_keyword(" OR");
12826 }
12827 self.write_space();
12828 match event {
12829 TriggerEvent::Insert => self.write_keyword("INSERT"),
12830 TriggerEvent::Update(cols) => {
12831 self.write_keyword("UPDATE");
12832 if let Some(cols) = cols {
12833 self.write_space();
12834 self.write_keyword("OF");
12835 for (j, col) in cols.iter().enumerate() {
12836 if j > 0 {
12837 self.write(",");
12838 }
12839 self.write_space();
12840 self.generate_identifier(col)?;
12841 }
12842 }
12843 }
12844 TriggerEvent::Delete => self.write_keyword("DELETE"),
12845 TriggerEvent::Truncate => self.write_keyword("TRUNCATE"),
12846 }
12847 }
12848
12849 self.write_space();
12850 self.write_keyword("ON");
12851 self.write_space();
12852 self.generate_table(&ct.table)?;
12853
12854 if let Some(ref_clause) = &ct.referencing {
12856 self.write_space();
12857 self.write_keyword("REFERENCING");
12858 if let Some(old_table) = &ref_clause.old_table {
12859 self.write_space();
12860 self.write_keyword("OLD TABLE AS");
12861 self.write_space();
12862 self.generate_identifier(old_table)?;
12863 }
12864 if let Some(new_table) = &ref_clause.new_table {
12865 self.write_space();
12866 self.write_keyword("NEW TABLE AS");
12867 self.write_space();
12868 self.generate_identifier(new_table)?;
12869 }
12870 if let Some(old_row) = &ref_clause.old_row {
12871 self.write_space();
12872 self.write_keyword("OLD ROW AS");
12873 self.write_space();
12874 self.generate_identifier(old_row)?;
12875 }
12876 if let Some(new_row) = &ref_clause.new_row {
12877 self.write_space();
12878 self.write_keyword("NEW ROW AS");
12879 self.write_space();
12880 self.generate_identifier(new_row)?;
12881 }
12882 }
12883
12884 if let Some(deferrable) = ct.deferrable {
12886 self.write_space();
12887 if deferrable {
12888 self.write_keyword("DEFERRABLE");
12889 } else {
12890 self.write_keyword("NOT DEFERRABLE");
12891 }
12892 }
12893
12894 if let Some(initially) = ct.initially_deferred {
12895 self.write_space();
12896 self.write_keyword("INITIALLY");
12897 self.write_space();
12898 if initially {
12899 self.write_keyword("DEFERRED");
12900 } else {
12901 self.write_keyword("IMMEDIATE");
12902 }
12903 }
12904
12905 self.write_space();
12906 self.write_keyword("FOR EACH");
12907 self.write_space();
12908 match ct.for_each {
12909 TriggerForEach::Row => self.write_keyword("ROW"),
12910 TriggerForEach::Statement => self.write_keyword("STATEMENT"),
12911 }
12912
12913 if let Some(when) = &ct.when {
12915 self.write_space();
12916 self.write_keyword("WHEN");
12917 self.write(" (");
12918 self.generate_expression(when)?;
12919 self.write(")");
12920 }
12921
12922 self.write_space();
12924 match &ct.body {
12925 TriggerBody::Execute { function, args } => {
12926 self.write_keyword("EXECUTE FUNCTION");
12927 self.write_space();
12928 self.generate_table(function)?;
12929 self.write("(");
12930 for (i, arg) in args.iter().enumerate() {
12931 if i > 0 {
12932 self.write(", ");
12933 }
12934 self.generate_expression(arg)?;
12935 }
12936 self.write(")");
12937 }
12938 TriggerBody::Block(block) => {
12939 self.write_keyword("BEGIN");
12940 self.write_space();
12941 self.write(block);
12942 self.write_space();
12943 self.write_keyword("END");
12944 }
12945 }
12946
12947 Ok(())
12948 }
12949
12950 fn generate_drop_trigger(&mut self, dt: &DropTrigger) -> Result<()> {
12951 self.write_keyword("DROP TRIGGER");
12952
12953 if dt.if_exists {
12954 self.write_space();
12955 self.write_keyword("IF EXISTS");
12956 }
12957
12958 self.write_space();
12959 self.generate_identifier(&dt.name)?;
12960
12961 if let Some(table) = &dt.table {
12962 self.write_space();
12963 self.write_keyword("ON");
12964 self.write_space();
12965 self.generate_table(table)?;
12966 }
12967
12968 if dt.cascade {
12969 self.write_space();
12970 self.write_keyword("CASCADE");
12971 }
12972
12973 Ok(())
12974 }
12975
12976 fn generate_create_type(&mut self, ct: &CreateType) -> Result<()> {
12977 self.write_keyword("CREATE TYPE");
12978
12979 if ct.if_not_exists {
12980 self.write_space();
12981 self.write_keyword("IF NOT EXISTS");
12982 }
12983
12984 self.write_space();
12985 self.generate_table(&ct.name)?;
12986
12987 self.write_space();
12988 self.write_keyword("AS");
12989 self.write_space();
12990
12991 match &ct.definition {
12992 TypeDefinition::Enum(values) => {
12993 self.write_keyword("ENUM");
12994 self.write(" (");
12995 for (i, val) in values.iter().enumerate() {
12996 if i > 0 {
12997 self.write(", ");
12998 }
12999 self.write(&format!("'{}'", val));
13000 }
13001 self.write(")");
13002 }
13003 TypeDefinition::Composite(attrs) => {
13004 self.write("(");
13005 for (i, attr) in attrs.iter().enumerate() {
13006 if i > 0 {
13007 self.write(", ");
13008 }
13009 self.generate_identifier(&attr.name)?;
13010 self.write_space();
13011 self.generate_data_type(&attr.data_type)?;
13012 if let Some(collate) = &attr.collate {
13013 self.write_space();
13014 self.write_keyword("COLLATE");
13015 self.write_space();
13016 self.generate_identifier(collate)?;
13017 }
13018 }
13019 self.write(")");
13020 }
13021 TypeDefinition::Range {
13022 subtype,
13023 subtype_diff,
13024 canonical,
13025 } => {
13026 self.write_keyword("RANGE");
13027 self.write(" (");
13028 self.write_keyword("SUBTYPE");
13029 self.write(" = ");
13030 self.generate_data_type(subtype)?;
13031 if let Some(diff) = subtype_diff {
13032 self.write(", ");
13033 self.write_keyword("SUBTYPE_DIFF");
13034 self.write(" = ");
13035 self.write(diff);
13036 }
13037 if let Some(canon) = canonical {
13038 self.write(", ");
13039 self.write_keyword("CANONICAL");
13040 self.write(" = ");
13041 self.write(canon);
13042 }
13043 self.write(")");
13044 }
13045 TypeDefinition::Base {
13046 input,
13047 output,
13048 internallength,
13049 } => {
13050 self.write("(");
13051 self.write_keyword("INPUT");
13052 self.write(" = ");
13053 self.write(input);
13054 self.write(", ");
13055 self.write_keyword("OUTPUT");
13056 self.write(" = ");
13057 self.write(output);
13058 if let Some(len) = internallength {
13059 self.write(", ");
13060 self.write_keyword("INTERNALLENGTH");
13061 self.write(" = ");
13062 self.write(&len.to_string());
13063 }
13064 self.write(")");
13065 }
13066 TypeDefinition::Domain {
13067 base_type,
13068 default,
13069 constraints,
13070 } => {
13071 self.generate_data_type(base_type)?;
13072 if let Some(def) = default {
13073 self.write_space();
13074 self.write_keyword("DEFAULT");
13075 self.write_space();
13076 self.generate_expression(def)?;
13077 }
13078 for constr in constraints {
13079 self.write_space();
13080 if let Some(name) = &constr.name {
13081 self.write_keyword("CONSTRAINT");
13082 self.write_space();
13083 self.generate_identifier(name)?;
13084 self.write_space();
13085 }
13086 self.write_keyword("CHECK");
13087 self.write(" (");
13088 self.generate_expression(&constr.check)?;
13089 self.write(")");
13090 }
13091 }
13092 }
13093
13094 Ok(())
13095 }
13096
13097 fn generate_drop_type(&mut self, dt: &DropType) -> Result<()> {
13098 self.write_keyword("DROP TYPE");
13099
13100 if dt.if_exists {
13101 self.write_space();
13102 self.write_keyword("IF EXISTS");
13103 }
13104
13105 self.write_space();
13106 self.generate_table(&dt.name)?;
13107
13108 if dt.cascade {
13109 self.write_space();
13110 self.write_keyword("CASCADE");
13111 }
13112
13113 Ok(())
13114 }
13115
13116 fn generate_describe(&mut self, d: &Describe) -> Result<()> {
13117 let saved_athena_hive_context = self.athena_hive_context;
13119 if matches!(
13120 self.config.dialect,
13121 Some(crate::dialects::DialectType::Athena)
13122 ) {
13123 self.athena_hive_context = true;
13124 }
13125
13126 for comment in &d.leading_comments {
13128 self.write_formatted_comment(comment);
13129 self.write(" ");
13130 }
13131
13132 self.write_keyword("DESCRIBE");
13133
13134 if d.extended {
13135 self.write_space();
13136 self.write_keyword("EXTENDED");
13137 } else if d.formatted {
13138 self.write_space();
13139 self.write_keyword("FORMATTED");
13140 }
13141
13142 if let Some(ref style) = d.style {
13144 self.write_space();
13145 self.write_keyword(style);
13146 }
13147
13148 let should_output_kind = match self.config.dialect {
13150 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
13152 false
13153 }
13154 Some(DialectType::Snowflake) => true,
13156 _ => d.kind.is_some(),
13157 };
13158 if should_output_kind {
13159 if let Some(ref kind) = d.kind {
13160 self.write_space();
13161 self.write_keyword(kind);
13162 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
13163 self.write_space();
13164 self.write_keyword("TABLE");
13165 }
13166 }
13167
13168 self.write_space();
13169 self.generate_expression(&d.target)?;
13170
13171 if let Some(ref partition) = d.partition {
13173 self.write_space();
13174 self.generate_expression(partition)?;
13175 }
13176
13177 if d.as_json {
13179 self.write_space();
13180 self.write_keyword("AS JSON");
13181 }
13182
13183 for (name, value) in &d.properties {
13185 self.write_space();
13186 self.write(name);
13187 self.write("=");
13188 self.write(value);
13189 }
13190
13191 self.athena_hive_context = saved_athena_hive_context;
13193
13194 Ok(())
13195 }
13196
13197 fn generate_show(&mut self, s: &Show) -> Result<()> {
13200 self.write_keyword("SHOW");
13201 self.write_space();
13202
13203 let show_terse = s.terse
13206 && !matches!(
13207 s.this.as_str(),
13208 "PRIMARY KEYS" | "UNIQUE KEYS" | "IMPORTED KEYS"
13209 );
13210 if show_terse {
13211 self.write_keyword("TERSE");
13212 self.write_space();
13213 }
13214
13215 self.write_keyword(&s.this);
13217
13218 if let Some(ref target_expr) = s.target {
13220 self.write_space();
13221 self.generate_expression(target_expr)?;
13222 }
13223
13224 if s.history {
13226 self.write_space();
13227 self.write_keyword("HISTORY");
13228 }
13229
13230 if let Some(ref for_target) = s.for_target {
13232 self.write_space();
13233 self.write_keyword("FOR");
13234 self.write_space();
13235 self.generate_expression(for_target)?;
13236 }
13237
13238 use crate::dialects::DialectType;
13242 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
13243
13244 if !is_snowflake && s.from.is_some() {
13245 if let Some(ref scope_kind) = s.scope_kind {
13249 self.write_space();
13250 self.write_keyword("IN");
13251 self.write_space();
13252 self.write_keyword(scope_kind);
13253 if let Some(ref scope) = s.scope {
13254 self.write_space();
13255 self.generate_expression(scope)?;
13256 }
13257 } else if let Some(ref scope) = s.scope {
13258 self.write_space();
13259 self.write_keyword("IN");
13260 self.write_space();
13261 self.generate_expression(scope)?;
13262 }
13263
13264 if let Some(ref from) = s.from {
13266 self.write_space();
13267 self.write_keyword("FROM");
13268 self.write_space();
13269 self.generate_expression(from)?;
13270 }
13271
13272 if let Some(ref db) = s.db {
13274 self.write_space();
13275 self.write_keyword("FROM");
13276 self.write_space();
13277 self.generate_expression(db)?;
13278 }
13279
13280 if let Some(ref like) = s.like {
13282 self.write_space();
13283 self.write_keyword("LIKE");
13284 self.write_space();
13285 self.generate_expression(like)?;
13286 }
13287 } else {
13288 if let Some(ref like) = s.like {
13292 self.write_space();
13293 self.write_keyword("LIKE");
13294 self.write_space();
13295 self.generate_expression(like)?;
13296 }
13297
13298 if let Some(ref scope_kind) = s.scope_kind {
13300 self.write_space();
13301 self.write_keyword("IN");
13302 self.write_space();
13303 self.write_keyword(scope_kind);
13304 if let Some(ref scope) = s.scope {
13305 self.write_space();
13306 self.generate_expression(scope)?;
13307 }
13308 } else if let Some(ref scope) = s.scope {
13309 self.write_space();
13310 self.write_keyword("IN");
13311 self.write_space();
13312 self.generate_expression(scope)?;
13313 }
13314 }
13315
13316 if let Some(ref starts_with) = s.starts_with {
13318 self.write_space();
13319 self.write_keyword("STARTS WITH");
13320 self.write_space();
13321 self.generate_expression(starts_with)?;
13322 }
13323
13324 if let Some(ref limit) = s.limit {
13326 self.write_space();
13327 self.generate_limit(limit)?;
13328 }
13329
13330 if is_snowflake {
13332 if let Some(ref from) = s.from {
13333 self.write_space();
13334 self.write_keyword("FROM");
13335 self.write_space();
13336 self.generate_expression(from)?;
13337 }
13338 }
13339
13340 if let Some(ref where_clause) = s.where_clause {
13342 self.write_space();
13343 self.write_keyword("WHERE");
13344 self.write_space();
13345 self.generate_expression(where_clause)?;
13346 }
13347
13348 if let Some(is_mutex) = s.mutex {
13350 self.write_space();
13351 if is_mutex {
13352 self.write_keyword("MUTEX");
13353 } else {
13354 self.write_keyword("STATUS");
13355 }
13356 }
13357
13358 if !s.privileges.is_empty() {
13360 self.write_space();
13361 self.write_keyword("WITH PRIVILEGES");
13362 self.write_space();
13363 for (i, priv_name) in s.privileges.iter().enumerate() {
13364 if i > 0 {
13365 self.write(", ");
13366 }
13367 self.write_keyword(priv_name);
13368 }
13369 }
13370
13371 Ok(())
13372 }
13373
13374 fn generate_literal(&mut self, lit: &Literal) -> Result<()> {
13377 use crate::dialects::DialectType;
13378 match lit {
13379 Literal::String(s) => {
13380 self.generate_string_literal(s)?;
13381 }
13382 Literal::Number(n) => {
13383 if matches!(self.config.dialect, Some(DialectType::MySQL))
13384 && n.len() > 2
13385 && (n.starts_with("0x") || n.starts_with("0X"))
13386 && !n[2..].chars().all(|c| c.is_ascii_hexdigit())
13387 {
13388 return self.generate_identifier(&Identifier {
13389 name: n.clone(),
13390 quoted: true,
13391 trailing_comments: Vec::new(),
13392 span: None,
13393 });
13394 }
13395 let n = if n.contains('_')
13399 && !matches!(
13400 self.config.dialect,
13401 Some(DialectType::ClickHouse)
13402 | Some(DialectType::DuckDB)
13403 | Some(DialectType::PostgreSQL)
13404 | Some(DialectType::Hive)
13405 | Some(DialectType::Spark)
13406 | Some(DialectType::Databricks)
13407 ) {
13408 std::borrow::Cow::Owned(n.replace('_', ""))
13409 } else {
13410 std::borrow::Cow::Borrowed(n.as_str())
13411 };
13412 if n.starts_with('.') {
13415 self.write("0");
13416 self.write(&n);
13417 } else if n.starts_with("-.") {
13418 self.write("-0");
13420 self.write(&n[1..]);
13421 } else {
13422 self.write(&n);
13423 }
13424 }
13425 Literal::HexString(h) => {
13426 match self.config.dialect {
13428 Some(DialectType::Spark)
13429 | Some(DialectType::Databricks)
13430 | Some(DialectType::Teradata) => self.write("X'"),
13431 _ => self.write("x'"),
13432 }
13433 self.write(h);
13434 self.write("'");
13435 }
13436 Literal::HexNumber(h) => {
13437 match self.config.dialect {
13441 Some(DialectType::BigQuery)
13442 | Some(DialectType::TSQL)
13443 | Some(DialectType::Fabric) => {
13444 self.write("0x");
13445 self.write(h);
13446 }
13447 _ => {
13448 if let Ok(val) = u64::from_str_radix(h, 16) {
13450 self.write(&val.to_string());
13451 } else {
13452 self.write("0x");
13454 self.write(h);
13455 }
13456 }
13457 }
13458 }
13459 Literal::BitString(b) => {
13460 self.write("B'");
13462 self.write(b);
13463 self.write("'");
13464 }
13465 Literal::ByteString(b) => {
13466 self.write("b'");
13468 self.write_escaped_byte_string(b);
13470 self.write("'");
13471 }
13472 Literal::NationalString(s) => {
13473 let keep_n_prefix = matches!(
13476 self.config.dialect,
13477 Some(DialectType::TSQL)
13478 | Some(DialectType::Oracle)
13479 | Some(DialectType::MySQL)
13480 | None
13481 );
13482 if keep_n_prefix {
13483 self.write("N'");
13484 } else {
13485 self.write("'");
13486 }
13487 self.write(s);
13488 self.write("'");
13489 }
13490 Literal::Date(d) => {
13491 self.generate_date_literal(d)?;
13492 }
13493 Literal::Time(t) => {
13494 self.generate_time_literal(t)?;
13495 }
13496 Literal::Timestamp(ts) => {
13497 self.generate_timestamp_literal(ts)?;
13498 }
13499 Literal::Datetime(dt) => {
13500 self.generate_datetime_literal(dt)?;
13501 }
13502 Literal::TripleQuotedString(s, _quote_char) => {
13503 if matches!(
13505 self.config.dialect,
13506 Some(crate::dialects::DialectType::BigQuery)
13507 | Some(crate::dialects::DialectType::DuckDB)
13508 | Some(crate::dialects::DialectType::Snowflake)
13509 | Some(crate::dialects::DialectType::Spark)
13510 | Some(crate::dialects::DialectType::Hive)
13511 | Some(crate::dialects::DialectType::Presto)
13512 | Some(crate::dialects::DialectType::Trino)
13513 | Some(crate::dialects::DialectType::PostgreSQL)
13514 | Some(crate::dialects::DialectType::MySQL)
13515 | Some(crate::dialects::DialectType::Redshift)
13516 | Some(crate::dialects::DialectType::TSQL)
13517 | Some(crate::dialects::DialectType::Oracle)
13518 | Some(crate::dialects::DialectType::ClickHouse)
13519 | Some(crate::dialects::DialectType::Databricks)
13520 | Some(crate::dialects::DialectType::SQLite)
13521 ) {
13522 self.generate_string_literal(s)?;
13523 } else {
13524 let quotes = format!("{0}{0}{0}", _quote_char);
13526 self.write("es);
13527 self.write(s);
13528 self.write("es);
13529 }
13530 }
13531 Literal::EscapeString(s) => {
13532 use crate::dialects::DialectType;
13536 let content = if let Some(c) = s.strip_prefix("e:") {
13537 c
13538 } else if let Some(c) = s.strip_prefix("E:") {
13539 c
13540 } else {
13541 s.as_str()
13542 };
13543
13544 if matches!(
13546 self.config.dialect,
13547 Some(DialectType::MySQL) | Some(DialectType::TiDB)
13548 ) {
13549 self.write(content);
13550 } else {
13551 let prefix = if matches!(
13553 self.config.dialect,
13554 Some(DialectType::SingleStore)
13555 | Some(DialectType::DuckDB)
13556 | Some(DialectType::PostgreSQL)
13557 | Some(DialectType::CockroachDB)
13558 | Some(DialectType::Materialize)
13559 | Some(DialectType::RisingWave)
13560 ) {
13561 "e'"
13562 } else {
13563 "E'"
13564 };
13565
13566 let normalized = content.replace("\\'", "''");
13568 self.write(prefix);
13569 self.write(&normalized);
13570 self.write("'");
13571 }
13572 }
13573 Literal::DollarString(s) => {
13574 use crate::dialects::DialectType;
13577 let (_tag, content) = crate::tokens::parse_dollar_string_token(s);
13579 let escape_backslash = matches!(self.config.dialect, Some(DialectType::Snowflake));
13581 let use_backslash_quote =
13585 matches!(self.config.dialect, Some(DialectType::Snowflake));
13586
13587 let mut escaped = String::with_capacity(content.len() + 4);
13588 for ch in content.chars() {
13589 if escape_backslash && ch == '\\' {
13590 escaped.push('\\');
13592 escaped.push('\\');
13593 } else if ch == '\'' {
13594 if use_backslash_quote {
13595 escaped.push('\\');
13596 escaped.push('\'');
13597 } else {
13598 escaped.push('\'');
13599 escaped.push('\'');
13600 }
13601 } else {
13602 escaped.push(ch);
13603 }
13604 }
13605 self.write("'");
13606 self.write(&escaped);
13607 self.write("'");
13608 }
13609 Literal::RawString(s) => {
13610 use crate::dialects::DialectType;
13616
13617 let escape_backslash = matches!(
13619 self.config.dialect,
13620 Some(DialectType::BigQuery)
13621 | Some(DialectType::MySQL)
13622 | Some(DialectType::SingleStore)
13623 | Some(DialectType::TiDB)
13624 | Some(DialectType::Hive)
13625 | Some(DialectType::Spark)
13626 | Some(DialectType::Databricks)
13627 | Some(DialectType::Drill)
13628 | Some(DialectType::Snowflake)
13629 | Some(DialectType::Redshift)
13630 | Some(DialectType::ClickHouse)
13631 );
13632
13633 let backslash_escapes_quote = matches!(
13636 self.config.dialect,
13637 Some(DialectType::BigQuery)
13638 | Some(DialectType::Hive)
13639 | Some(DialectType::Spark)
13640 | Some(DialectType::Databricks)
13641 | Some(DialectType::Drill)
13642 | Some(DialectType::Snowflake)
13643 | Some(DialectType::Redshift)
13644 );
13645
13646 let supports_escape_sequences = escape_backslash;
13649
13650 let mut escaped = String::with_capacity(s.len() + 4);
13651 for ch in s.chars() {
13652 if escape_backslash && ch == '\\' {
13653 escaped.push('\\');
13655 escaped.push('\\');
13656 } else if ch == '\'' {
13657 if backslash_escapes_quote {
13658 escaped.push('\\');
13660 escaped.push('\'');
13661 } else {
13662 escaped.push('\'');
13664 escaped.push('\'');
13665 }
13666 } else if supports_escape_sequences {
13667 match ch {
13670 '\n' => {
13671 escaped.push('\\');
13672 escaped.push('n');
13673 }
13674 '\r' => {
13675 escaped.push('\\');
13676 escaped.push('r');
13677 }
13678 '\t' => {
13679 escaped.push('\\');
13680 escaped.push('t');
13681 }
13682 '\x07' => {
13683 escaped.push('\\');
13684 escaped.push('a');
13685 }
13686 '\x08' => {
13687 escaped.push('\\');
13688 escaped.push('b');
13689 }
13690 '\x0C' => {
13691 escaped.push('\\');
13692 escaped.push('f');
13693 }
13694 '\x0B' => {
13695 escaped.push('\\');
13696 escaped.push('v');
13697 }
13698 _ => escaped.push(ch),
13699 }
13700 } else {
13701 escaped.push(ch);
13702 }
13703 }
13704 self.write("'");
13705 self.write(&escaped);
13706 self.write("'");
13707 }
13708 }
13709 Ok(())
13710 }
13711
13712 fn generate_date_literal(&mut self, d: &str) -> Result<()> {
13714 use crate::dialects::DialectType;
13715
13716 match self.config.dialect {
13717 Some(DialectType::TSQL) => {
13719 self.write("CAST('");
13720 self.write(d);
13721 self.write("' AS DATE)");
13722 }
13723 Some(DialectType::BigQuery) => {
13726 self.write("CAST('");
13727 self.write(d);
13728 self.write("' AS DATE)");
13729 }
13730 Some(DialectType::Exasol) => {
13733 self.write("CAST('");
13734 self.write(d);
13735 self.write("' AS DATE)");
13736 }
13737 Some(DialectType::Snowflake) => {
13740 self.write("CAST('");
13741 self.write(d);
13742 self.write("' AS DATE)");
13743 }
13744 Some(DialectType::PostgreSQL)
13746 | Some(DialectType::MySQL)
13747 | Some(DialectType::SingleStore)
13748 | Some(DialectType::TiDB)
13749 | Some(DialectType::Redshift) => {
13750 self.write("CAST('");
13751 self.write(d);
13752 self.write("' AS DATE)");
13753 }
13754 Some(DialectType::DuckDB)
13756 | Some(DialectType::Presto)
13757 | Some(DialectType::Trino)
13758 | Some(DialectType::Athena)
13759 | Some(DialectType::Spark)
13760 | Some(DialectType::Databricks)
13761 | Some(DialectType::Hive) => {
13762 self.write("CAST('");
13763 self.write(d);
13764 self.write("' AS DATE)");
13765 }
13766 Some(DialectType::Oracle) => {
13768 self.write("TO_DATE('");
13769 self.write(d);
13770 self.write("', 'YYYY-MM-DD')");
13771 }
13772 _ => {
13774 self.write_keyword("DATE");
13775 self.write(" '");
13776 self.write(d);
13777 self.write("'");
13778 }
13779 }
13780 Ok(())
13781 }
13782
13783 fn generate_time_literal(&mut self, t: &str) -> Result<()> {
13785 use crate::dialects::DialectType;
13786
13787 match self.config.dialect {
13788 Some(DialectType::TSQL) => {
13790 self.write("CAST('");
13791 self.write(t);
13792 self.write("' AS TIME)");
13793 }
13794 _ => {
13796 self.write_keyword("TIME");
13797 self.write(" '");
13798 self.write(t);
13799 self.write("'");
13800 }
13801 }
13802 Ok(())
13803 }
13804
13805 fn generate_dremio_date_expression(&mut self, expr: &Expression) -> Result<()> {
13807 use crate::expressions::Literal;
13808
13809 match expr {
13810 Expression::Literal(Literal::Date(d)) => {
13811 self.write("CAST('");
13813 self.write(d);
13814 self.write("' AS DATE)");
13815 }
13816 _ => {
13817 self.generate_expression(expr)?;
13819 }
13820 }
13821 Ok(())
13822 }
13823
13824 fn generate_timestamp_literal(&mut self, ts: &str) -> Result<()> {
13826 use crate::dialects::DialectType;
13827
13828 match self.config.dialect {
13829 Some(DialectType::TSQL) => {
13831 self.write("CAST('");
13832 self.write(ts);
13833 self.write("' AS DATETIME2)");
13834 }
13835 Some(DialectType::BigQuery) => {
13838 self.write("CAST('");
13839 self.write(ts);
13840 self.write("' AS TIMESTAMP)");
13841 }
13842 Some(DialectType::Snowflake) => {
13845 self.write("CAST('");
13846 self.write(ts);
13847 self.write("' AS TIMESTAMP)");
13848 }
13849 Some(DialectType::Dremio) => {
13852 self.write("CAST('");
13853 self.write(ts);
13854 self.write("' AS TIMESTAMP)");
13855 }
13856 Some(DialectType::Exasol) => {
13859 self.write("CAST('");
13860 self.write(ts);
13861 self.write("' AS TIMESTAMP)");
13862 }
13863 Some(DialectType::Oracle) => {
13866 self.write("TO_TIMESTAMP('");
13867 self.write(ts);
13868 self.write("', 'YYYY-MM-DD HH24:MI:SS.FF6')");
13869 }
13870 Some(DialectType::Presto) | Some(DialectType::Trino) => {
13872 if Self::timestamp_has_timezone(ts) {
13873 self.write("CAST('");
13874 self.write(ts);
13875 self.write("' AS TIMESTAMP WITH TIME ZONE)");
13876 } else {
13877 self.write("CAST('");
13878 self.write(ts);
13879 self.write("' AS TIMESTAMP)");
13880 }
13881 }
13882 Some(DialectType::ClickHouse) => {
13884 self.write("CAST('");
13885 self.write(ts);
13886 self.write("' AS Nullable(DateTime))");
13887 }
13888 Some(DialectType::Spark) => {
13890 self.write("CAST('");
13891 self.write(ts);
13892 self.write("' AS TIMESTAMP)");
13893 }
13894 Some(DialectType::Redshift) => {
13897 if ts == "epoch" {
13898 self.write_keyword("TIMESTAMP");
13899 self.write(" '");
13900 self.write(ts);
13901 self.write("'");
13902 } else {
13903 self.write("CAST('");
13904 self.write(ts);
13905 self.write("' AS TIMESTAMP)");
13906 }
13907 }
13908 Some(DialectType::PostgreSQL)
13910 | Some(DialectType::Hive)
13911 | Some(DialectType::SQLite)
13912 | Some(DialectType::DuckDB)
13913 | Some(DialectType::Athena)
13914 | Some(DialectType::Drill)
13915 | Some(DialectType::Teradata) => {
13916 self.write("CAST('");
13917 self.write(ts);
13918 self.write("' AS TIMESTAMP)");
13919 }
13920 Some(DialectType::MySQL) | Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
13922 self.write("CAST('");
13923 self.write(ts);
13924 self.write("' AS DATETIME)");
13925 }
13926 Some(DialectType::Databricks) => {
13928 self.write("CAST('");
13929 self.write(ts);
13930 self.write("' AS TIMESTAMP_NTZ)");
13931 }
13932 _ => {
13934 self.write_keyword("TIMESTAMP");
13935 self.write(" '");
13936 self.write(ts);
13937 self.write("'");
13938 }
13939 }
13940 Ok(())
13941 }
13942
13943 fn timestamp_has_timezone(ts: &str) -> bool {
13946 let ts_lower = ts.to_lowercase();
13950
13951 let continent_prefixes = [
13953 "africa/",
13954 "america/",
13955 "antarctica/",
13956 "arctic/",
13957 "asia/",
13958 "atlantic/",
13959 "australia/",
13960 "europe/",
13961 "indian/",
13962 "pacific/",
13963 "etc/",
13964 "brazil/",
13965 "canada/",
13966 "chile/",
13967 "mexico/",
13968 "us/",
13969 ];
13970
13971 for prefix in &continent_prefixes {
13972 if ts_lower.contains(prefix) {
13973 return true;
13974 }
13975 }
13976
13977 let tz_abbrevs = [
13980 " utc", " gmt", " cet", " cest", " eet", " eest", " wet", " west", " est", " edt",
13981 " cst", " cdt", " mst", " mdt", " pst", " pdt", " ist", " bst", " jst", " kst", " hkt",
13982 " sgt", " aest", " aedt", " acst", " acdt", " awst",
13983 ];
13984
13985 for abbrev in &tz_abbrevs {
13986 if ts_lower.ends_with(abbrev) {
13987 return true;
13988 }
13989 }
13990
13991 let trimmed = ts.trim();
13995 if let Some(last_space) = trimmed.rfind(' ') {
13996 let suffix = &trimmed[last_space + 1..];
13997 if (suffix.starts_with('+') || suffix.starts_with('-')) && suffix.len() > 1 {
13998 let rest = &suffix[1..];
14000 if rest.chars().all(|c| c.is_ascii_digit() || c == ':') {
14001 return true;
14002 }
14003 }
14004 }
14005
14006 false
14007 }
14008
14009 fn generate_datetime_literal(&mut self, dt: &str) -> Result<()> {
14011 use crate::dialects::DialectType;
14012
14013 match self.config.dialect {
14014 Some(DialectType::BigQuery) => {
14017 self.write("CAST('");
14018 self.write(dt);
14019 self.write("' AS DATETIME)");
14020 }
14021 Some(DialectType::DuckDB) => {
14023 self.write("CAST('");
14024 self.write(dt);
14025 self.write("' AS TIMESTAMP)");
14026 }
14027 _ => {
14030 self.write_keyword("DATETIME");
14031 self.write(" '");
14032 self.write(dt);
14033 self.write("'");
14034 }
14035 }
14036 Ok(())
14037 }
14038
14039 fn generate_string_literal(&mut self, s: &str) -> Result<()> {
14041 use crate::dialects::DialectType;
14042
14043 match self.config.dialect {
14044 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
14048 self.write("'");
14050 for c in s.chars() {
14051 match c {
14052 '\'' => self.write("\\'"),
14053 '\\' => self.write("\\\\"),
14054 '\n' => self.write("\\n"),
14055 '\r' => self.write("\\r"),
14056 '\t' => self.write("\\t"),
14057 '\0' => self.write("\\0"),
14058 _ => self.output.push(c),
14059 }
14060 }
14061 self.write("'");
14062 }
14063 Some(DialectType::Drill) => {
14064 self.write("'");
14067 for c in s.chars() {
14068 match c {
14069 '\'' => self.write("''"),
14070 '\\' => self.write("\\\\"),
14071 '\n' => self.write("\\n"),
14072 '\r' => self.write("\\r"),
14073 '\t' => self.write("\\t"),
14074 '\0' => self.write("\\0"),
14075 _ => self.output.push(c),
14076 }
14077 }
14078 self.write("'");
14079 }
14080 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB) => {
14081 self.write("'");
14082 for c in s.chars() {
14083 match c {
14084 '\'' => self.write("''"),
14086 '\\' => self.write("\\\\"),
14087 '\n' => self.write("\\n"),
14088 '\r' => self.write("\\r"),
14089 '\t' => self.write("\\t"),
14090 '\0' => self.output.push('\0'),
14092 _ => self.output.push(c),
14093 }
14094 }
14095 self.write("'");
14096 }
14097 Some(DialectType::BigQuery) => {
14099 self.write("'");
14100 for c in s.chars() {
14101 match c {
14102 '\'' => self.write("\\'"),
14103 '\\' => self.write("\\\\"),
14104 '\n' => self.write("\\n"),
14105 '\r' => self.write("\\r"),
14106 '\t' => self.write("\\t"),
14107 '\0' => self.write("\\0"),
14108 '\x07' => self.write("\\a"),
14109 '\x08' => self.write("\\b"),
14110 '\x0C' => self.write("\\f"),
14111 '\x0B' => self.write("\\v"),
14112 _ => self.output.push(c),
14113 }
14114 }
14115 self.write("'");
14116 }
14117 Some(DialectType::Athena) => {
14121 if self.athena_hive_context {
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 } else {
14137 self.write("'");
14139 for c in s.chars() {
14140 match c {
14141 '\'' => self.write("''"),
14142 _ => self.output.push(c),
14144 }
14145 }
14146 self.write("'");
14147 }
14148 }
14149 Some(DialectType::Snowflake) => {
14154 self.write("'");
14155 for c in s.chars() {
14156 match c {
14157 '\'' => self.write("\\'"),
14158 '\n' => self.write("\\n"),
14161 '\r' => self.write("\\r"),
14162 '\t' => self.write("\\t"),
14163 _ => self.output.push(c),
14164 }
14165 }
14166 self.write("'");
14167 }
14168 Some(DialectType::PostgreSQL) => {
14170 self.write("'");
14171 for c in s.chars() {
14172 match c {
14173 '\'' => self.write("''"),
14174 _ => self.output.push(c),
14175 }
14176 }
14177 self.write("'");
14178 }
14179 Some(DialectType::Redshift) => {
14181 self.write("'");
14182 for c in s.chars() {
14183 match c {
14184 '\'' => self.write("\\'"),
14185 _ => self.output.push(c),
14186 }
14187 }
14188 self.write("'");
14189 }
14190 Some(DialectType::Oracle) => {
14192 self.write("'");
14193 self.write(&s.replace('\'', "''"));
14194 self.write("'");
14195 }
14196 Some(DialectType::ClickHouse) => {
14199 self.write("'");
14200 for c in s.chars() {
14201 match c {
14202 '\'' => self.write("''"),
14203 '\\' => self.write("\\\\"),
14204 '\n' => self.write("\\n"),
14205 '\r' => self.write("\\r"),
14206 '\t' => self.write("\\t"),
14207 '\0' => self.write("\\0"),
14208 '\x07' => self.write("\\a"),
14209 '\x08' => self.write("\\b"),
14210 '\x0C' => self.write("\\f"),
14211 '\x0B' => self.write("\\v"),
14212 c if c.is_control() || (c as u32) < 0x20 => {
14214 let byte = c as u32;
14215 if byte < 256 {
14216 self.write(&format!("\\x{:02X}", byte));
14217 } else {
14218 self.output.push(c);
14219 }
14220 }
14221 _ => self.output.push(c),
14222 }
14223 }
14224 self.write("'");
14225 }
14226 _ => {
14229 self.write("'");
14230 self.write(&s.replace('\'', "''"));
14231 self.write("'");
14232 }
14233 }
14234 Ok(())
14235 }
14236
14237 fn write_escaped_byte_string(&mut self, s: &str) {
14240 for c in s.chars() {
14241 match c {
14242 '\'' => self.write("\\'"),
14244 '\\' => self.write("\\\\"),
14246 _ if !c.is_control() => self.output.push(c),
14248 _ => {
14250 let byte = c as u32;
14251 if byte < 256 {
14252 self.write(&format!("\\x{:02x}", byte));
14253 } else {
14254 for b in c.to_string().as_bytes() {
14256 self.write(&format!("\\x{:02x}", b));
14257 }
14258 }
14259 }
14260 }
14261 }
14262 }
14263
14264 fn generate_boolean(&mut self, b: &BooleanLiteral) -> Result<()> {
14265 use crate::dialects::DialectType;
14266
14267 match self.config.dialect {
14269 Some(DialectType::TSQL) => {
14272 self.write(if b.value { "1" } else { "0" });
14273 }
14274 Some(DialectType::Oracle) => {
14276 self.write(if b.value { "1" } else { "0" });
14277 }
14278 Some(DialectType::MySQL) => {
14280 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
14281 }
14282 _ => {
14284 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
14285 }
14286 }
14287 Ok(())
14288 }
14289
14290 fn generate_alias_identifier(&mut self, id: &Identifier) -> Result<()> {
14293 let name = &id.name;
14294 let quote_style = &self.config.identifier_quote_style;
14295
14296 let needs_quoting = id.quoted || self.is_reserved_keyword(name);
14300
14301 let output_name = if self.config.normalize_identifiers && !id.quoted {
14303 name.to_lowercase()
14304 } else {
14305 name.to_string()
14306 };
14307
14308 if needs_quoting {
14309 let escaped_name = if quote_style.start == quote_style.end {
14311 output_name.replace(
14312 quote_style.end,
14313 &format!("{}{}", quote_style.end, quote_style.end),
14314 )
14315 } else {
14316 output_name.replace(
14317 quote_style.end,
14318 &format!("{}{}", quote_style.end, quote_style.end),
14319 )
14320 };
14321 self.write(&format!(
14322 "{}{}{}",
14323 quote_style.start, escaped_name, quote_style.end
14324 ));
14325 } else {
14326 self.write(&output_name);
14327 }
14328
14329 for comment in &id.trailing_comments {
14331 self.write(" ");
14332 self.write_formatted_comment(comment);
14333 }
14334 Ok(())
14335 }
14336
14337 fn generate_identifier(&mut self, id: &Identifier) -> Result<()> {
14338 use crate::dialects::DialectType;
14339
14340 let name = &id.name;
14341
14342 let quote_style = if matches!(self.config.dialect, Some(DialectType::Athena))
14344 && self.athena_hive_context
14345 {
14346 &IdentifierQuoteStyle::BACKTICK
14347 } else {
14348 &self.config.identifier_quote_style
14349 };
14350
14351 let starts_with_digit = name.chars().next().map_or(false, |c| c.is_ascii_digit());
14358 let needs_digit_quoting = starts_with_digit
14359 && !self.config.identifiers_can_start_with_digit
14360 && self.config.dialect.is_some();
14361 let mysql_invalid_hex_identifier = matches!(self.config.dialect, Some(DialectType::MySQL))
14362 && name.len() > 2
14363 && (name.starts_with("0x") || name.starts_with("0X"))
14364 && !name[2..].chars().all(|c| c.is_ascii_hexdigit());
14365 let needs_quoting = id.quoted
14366 || self.is_reserved_keyword(name)
14367 || self.config.always_quote_identifiers
14368 || needs_digit_quoting
14369 || mysql_invalid_hex_identifier;
14370
14371 let (base_name, suffix) = if needs_quoting {
14374 if let Some(paren_pos) = name.find('(') {
14376 let base = &name[..paren_pos];
14377 let rest = &name[paren_pos..];
14378 if rest.starts_with('(')
14380 && (rest.ends_with(')') || rest.ends_with(") ASC") || rest.ends_with(") DESC"))
14381 {
14382 let close_paren = rest.find(')').unwrap_or(rest.len());
14384 let inside = &rest[1..close_paren];
14385 if inside.chars().all(|c| c.is_ascii_digit()) {
14386 (base.to_string(), rest.to_string())
14387 } else {
14388 (name.to_string(), String::new())
14389 }
14390 } else {
14391 (name.to_string(), String::new())
14392 }
14393 } else if name.ends_with(" ASC") {
14394 let base = &name[..name.len() - 4];
14395 (base.to_string(), " ASC".to_string())
14396 } else if name.ends_with(" DESC") {
14397 let base = &name[..name.len() - 5];
14398 (base.to_string(), " DESC".to_string())
14399 } else {
14400 (name.to_string(), String::new())
14401 }
14402 } else {
14403 (name.to_string(), String::new())
14404 };
14405
14406 let output_name = if self.config.normalize_identifiers && !id.quoted {
14410 base_name.to_lowercase()
14411 } else if matches!(self.config.dialect, Some(DialectType::Exasol))
14412 && !id.quoted
14413 && self.is_reserved_keyword(name)
14414 {
14415 base_name.to_uppercase()
14418 } else {
14419 base_name
14420 };
14421
14422 if needs_quoting {
14423 let escaped_name = if quote_style.start == quote_style.end {
14425 output_name.replace(
14427 quote_style.end,
14428 &format!("{}{}", quote_style.end, quote_style.end),
14429 )
14430 } else {
14431 output_name.replace(
14433 quote_style.end,
14434 &format!("{}{}", quote_style.end, quote_style.end),
14435 )
14436 };
14437 self.write(&format!(
14438 "{}{}{}{}",
14439 quote_style.start, escaped_name, quote_style.end, suffix
14440 ));
14441 } else {
14442 self.write(&output_name);
14443 }
14444
14445 for comment in &id.trailing_comments {
14447 self.write(" ");
14448 self.write_formatted_comment(comment);
14449 }
14450 Ok(())
14451 }
14452
14453 fn generate_column(&mut self, col: &Column) -> Result<()> {
14454 use crate::dialects::DialectType;
14455
14456 if let Some(table) = &col.table {
14457 let is_exasol_local_prefix = matches!(self.config.dialect, Some(DialectType::Exasol))
14461 && !table.quoted
14462 && table.name.eq_ignore_ascii_case("LOCAL");
14463
14464 if is_exasol_local_prefix {
14465 self.write("LOCAL");
14467 } else {
14468 self.generate_identifier(table)?;
14469 }
14470 self.write(".");
14471 }
14472 self.generate_identifier(&col.name)?;
14473 if col.join_mark && self.config.supports_column_join_marks {
14476 self.write(" (+)");
14477 }
14478 for comment in &col.trailing_comments {
14480 self.write_space();
14481 self.write_formatted_comment(comment);
14482 }
14483 Ok(())
14484 }
14485
14486 fn generate_pseudocolumn(&mut self, pc: &Pseudocolumn) -> Result<()> {
14489 use crate::dialects::DialectType;
14490 use crate::expressions::PseudocolumnType;
14491
14492 if pc.kind == PseudocolumnType::Sysdate
14494 && !matches!(
14495 self.config.dialect,
14496 Some(DialectType::Oracle) | Some(DialectType::Redshift) | None
14497 )
14498 {
14499 self.write_keyword("CURRENT_TIMESTAMP");
14500 if matches!(
14502 self.config.dialect,
14503 Some(DialectType::MySQL)
14504 | Some(DialectType::ClickHouse)
14505 | Some(DialectType::Spark)
14506 | Some(DialectType::Databricks)
14507 | Some(DialectType::Hive)
14508 ) {
14509 self.write("()");
14510 }
14511 } else {
14512 self.write(pc.kind.as_str());
14513 }
14514 Ok(())
14515 }
14516
14517 fn generate_connect(&mut self, connect: &Connect) -> Result<()> {
14519 use crate::dialects::DialectType;
14520
14521 let supports_connect_by = matches!(
14524 self.config.dialect,
14525 Some(DialectType::Oracle) | Some(DialectType::Snowflake)
14526 );
14527
14528 if !supports_connect_by && self.config.dialect.is_some() {
14529 if self.config.pretty {
14531 self.write_newline();
14532 } else {
14533 self.write_space();
14534 }
14535 self.write("/* CONNECT BY requires manual conversion to recursive CTE */");
14536 }
14537
14538 if let Some(start) = &connect.start {
14540 if self.config.pretty {
14541 self.write_newline();
14542 } else {
14543 self.write_space();
14544 }
14545 self.write_keyword("START WITH");
14546 self.write_space();
14547 self.generate_expression(start)?;
14548 }
14549
14550 if self.config.pretty {
14552 self.write_newline();
14553 } else {
14554 self.write_space();
14555 }
14556 self.write_keyword("CONNECT BY");
14557 if connect.nocycle {
14558 self.write_space();
14559 self.write_keyword("NOCYCLE");
14560 }
14561 self.write_space();
14562 self.generate_expression(&connect.connect)?;
14563
14564 Ok(())
14565 }
14566
14567 fn generate_connect_expr(&mut self, connect: &Connect) -> Result<()> {
14569 self.generate_connect(connect)
14570 }
14571
14572 fn generate_prior(&mut self, prior: &Prior) -> Result<()> {
14574 self.write_keyword("PRIOR");
14575 self.write_space();
14576 self.generate_expression(&prior.this)?;
14577 Ok(())
14578 }
14579
14580 fn generate_connect_by_root(&mut self, cbr: &ConnectByRoot) -> Result<()> {
14583 self.write_keyword("CONNECT_BY_ROOT");
14584 self.write_space();
14585 self.generate_expression(&cbr.this)?;
14586 Ok(())
14587 }
14588
14589 fn generate_match_recognize(&mut self, mr: &MatchRecognize) -> Result<()> {
14591 use crate::dialects::DialectType;
14592
14593 let supports_match_recognize = matches!(
14595 self.config.dialect,
14596 Some(DialectType::Oracle)
14597 | Some(DialectType::Snowflake)
14598 | Some(DialectType::Presto)
14599 | Some(DialectType::Trino)
14600 );
14601
14602 if let Some(source) = &mr.this {
14604 self.generate_expression(source)?;
14605 }
14606
14607 if !supports_match_recognize {
14608 self.write("/* MATCH_RECOGNIZE not supported in this dialect */");
14609 return Ok(());
14610 }
14611
14612 if self.config.pretty {
14614 self.write_newline();
14615 } else {
14616 self.write_space();
14617 }
14618
14619 self.write_keyword("MATCH_RECOGNIZE");
14620 self.write(" (");
14621
14622 if self.config.pretty {
14623 self.indent_level += 1;
14624 }
14625
14626 let mut needs_separator = false;
14627
14628 if let Some(partition_by) = &mr.partition_by {
14630 if !partition_by.is_empty() {
14631 if self.config.pretty {
14632 self.write_newline();
14633 self.write_indent();
14634 }
14635 self.write_keyword("PARTITION BY");
14636 self.write_space();
14637 for (i, expr) in partition_by.iter().enumerate() {
14638 if i > 0 {
14639 self.write(", ");
14640 }
14641 self.generate_expression(expr)?;
14642 }
14643 needs_separator = true;
14644 }
14645 }
14646
14647 if let Some(order_by) = &mr.order_by {
14649 if !order_by.is_empty() {
14650 if needs_separator {
14651 if self.config.pretty {
14652 self.write_newline();
14653 self.write_indent();
14654 } else {
14655 self.write_space();
14656 }
14657 } else if self.config.pretty {
14658 self.write_newline();
14659 self.write_indent();
14660 }
14661 self.write_keyword("ORDER BY");
14662 if self.config.pretty {
14664 self.indent_level += 1;
14665 for (i, ordered) in order_by.iter().enumerate() {
14666 if i > 0 {
14667 self.write(",");
14668 }
14669 self.write_newline();
14670 self.write_indent();
14671 self.generate_ordered(ordered)?;
14672 }
14673 self.indent_level -= 1;
14674 } else {
14675 self.write_space();
14676 for (i, ordered) in order_by.iter().enumerate() {
14677 if i > 0 {
14678 self.write(", ");
14679 }
14680 self.generate_ordered(ordered)?;
14681 }
14682 }
14683 needs_separator = true;
14684 }
14685 }
14686
14687 if let Some(measures) = &mr.measures {
14689 if !measures.is_empty() {
14690 if needs_separator {
14691 if self.config.pretty {
14692 self.write_newline();
14693 self.write_indent();
14694 } else {
14695 self.write_space();
14696 }
14697 } else if self.config.pretty {
14698 self.write_newline();
14699 self.write_indent();
14700 }
14701 self.write_keyword("MEASURES");
14702 if self.config.pretty {
14704 self.indent_level += 1;
14705 for (i, measure) in measures.iter().enumerate() {
14706 if i > 0 {
14707 self.write(",");
14708 }
14709 self.write_newline();
14710 self.write_indent();
14711 if let Some(semantics) = &measure.window_frame {
14713 match semantics {
14714 MatchRecognizeSemantics::Running => {
14715 self.write_keyword("RUNNING");
14716 self.write_space();
14717 }
14718 MatchRecognizeSemantics::Final => {
14719 self.write_keyword("FINAL");
14720 self.write_space();
14721 }
14722 }
14723 }
14724 self.generate_expression(&measure.this)?;
14725 }
14726 self.indent_level -= 1;
14727 } else {
14728 self.write_space();
14729 for (i, measure) in measures.iter().enumerate() {
14730 if i > 0 {
14731 self.write(", ");
14732 }
14733 if let Some(semantics) = &measure.window_frame {
14735 match semantics {
14736 MatchRecognizeSemantics::Running => {
14737 self.write_keyword("RUNNING");
14738 self.write_space();
14739 }
14740 MatchRecognizeSemantics::Final => {
14741 self.write_keyword("FINAL");
14742 self.write_space();
14743 }
14744 }
14745 }
14746 self.generate_expression(&measure.this)?;
14747 }
14748 }
14749 needs_separator = true;
14750 }
14751 }
14752
14753 if let Some(rows) = &mr.rows {
14755 if needs_separator {
14756 if self.config.pretty {
14757 self.write_newline();
14758 self.write_indent();
14759 } else {
14760 self.write_space();
14761 }
14762 } else if self.config.pretty {
14763 self.write_newline();
14764 self.write_indent();
14765 }
14766 match rows {
14767 MatchRecognizeRows::OneRowPerMatch => {
14768 self.write_keyword("ONE ROW PER MATCH");
14769 }
14770 MatchRecognizeRows::AllRowsPerMatch => {
14771 self.write_keyword("ALL ROWS PER MATCH");
14772 }
14773 MatchRecognizeRows::AllRowsPerMatchShowEmptyMatches => {
14774 self.write_keyword("ALL ROWS PER MATCH SHOW EMPTY MATCHES");
14775 }
14776 MatchRecognizeRows::AllRowsPerMatchOmitEmptyMatches => {
14777 self.write_keyword("ALL ROWS PER MATCH OMIT EMPTY MATCHES");
14778 }
14779 MatchRecognizeRows::AllRowsPerMatchWithUnmatchedRows => {
14780 self.write_keyword("ALL ROWS PER MATCH WITH UNMATCHED ROWS");
14781 }
14782 }
14783 needs_separator = true;
14784 }
14785
14786 if let Some(after) = &mr.after {
14788 if needs_separator {
14789 if self.config.pretty {
14790 self.write_newline();
14791 self.write_indent();
14792 } else {
14793 self.write_space();
14794 }
14795 } else if self.config.pretty {
14796 self.write_newline();
14797 self.write_indent();
14798 }
14799 match after {
14800 MatchRecognizeAfter::PastLastRow => {
14801 self.write_keyword("AFTER MATCH SKIP PAST LAST ROW");
14802 }
14803 MatchRecognizeAfter::ToNextRow => {
14804 self.write_keyword("AFTER MATCH SKIP TO NEXT ROW");
14805 }
14806 MatchRecognizeAfter::ToFirst(ident) => {
14807 self.write_keyword("AFTER MATCH SKIP TO FIRST");
14808 self.write_space();
14809 self.generate_identifier(ident)?;
14810 }
14811 MatchRecognizeAfter::ToLast(ident) => {
14812 self.write_keyword("AFTER MATCH SKIP TO LAST");
14813 self.write_space();
14814 self.generate_identifier(ident)?;
14815 }
14816 }
14817 needs_separator = true;
14818 }
14819
14820 if let Some(pattern) = &mr.pattern {
14822 if needs_separator {
14823 if self.config.pretty {
14824 self.write_newline();
14825 self.write_indent();
14826 } else {
14827 self.write_space();
14828 }
14829 } else if self.config.pretty {
14830 self.write_newline();
14831 self.write_indent();
14832 }
14833 self.write_keyword("PATTERN");
14834 self.write_space();
14835 self.write("(");
14836 self.write(pattern);
14837 self.write(")");
14838 needs_separator = true;
14839 }
14840
14841 if let Some(define) = &mr.define {
14843 if !define.is_empty() {
14844 if needs_separator {
14845 if self.config.pretty {
14846 self.write_newline();
14847 self.write_indent();
14848 } else {
14849 self.write_space();
14850 }
14851 } else if self.config.pretty {
14852 self.write_newline();
14853 self.write_indent();
14854 }
14855 self.write_keyword("DEFINE");
14856 if self.config.pretty {
14858 self.indent_level += 1;
14859 for (i, (name, expr)) in define.iter().enumerate() {
14860 if i > 0 {
14861 self.write(",");
14862 }
14863 self.write_newline();
14864 self.write_indent();
14865 self.generate_identifier(name)?;
14866 self.write(" AS ");
14867 self.generate_expression(expr)?;
14868 }
14869 self.indent_level -= 1;
14870 } else {
14871 self.write_space();
14872 for (i, (name, expr)) in define.iter().enumerate() {
14873 if i > 0 {
14874 self.write(", ");
14875 }
14876 self.generate_identifier(name)?;
14877 self.write(" AS ");
14878 self.generate_expression(expr)?;
14879 }
14880 }
14881 }
14882 }
14883
14884 if self.config.pretty {
14885 self.indent_level -= 1;
14886 self.write_newline();
14887 }
14888 self.write(")");
14889
14890 if let Some(alias) = &mr.alias {
14892 self.write(" ");
14893 if mr.alias_explicit_as {
14894 self.write_keyword("AS");
14895 self.write(" ");
14896 }
14897 self.generate_identifier(alias)?;
14898 }
14899
14900 Ok(())
14901 }
14902
14903 fn generate_hint(&mut self, hint: &Hint) -> Result<()> {
14905 use crate::dialects::DialectType;
14906
14907 let supports_hints = matches!(
14909 self.config.dialect,
14910 None | Some(DialectType::Oracle) | Some(DialectType::MySQL) |
14912 Some(DialectType::Spark) | Some(DialectType::Hive) |
14913 Some(DialectType::Databricks) | Some(DialectType::PostgreSQL)
14914 );
14915
14916 if !supports_hints || hint.expressions.is_empty() {
14917 return Ok(());
14918 }
14919
14920 let mut hint_strings: Vec<String> = Vec::new();
14923 for expr in &hint.expressions {
14924 match expr {
14925 HintExpression::Raw(text) => {
14926 let parsed = self.parse_raw_hint_text(text);
14928 hint_strings.extend(parsed);
14929 }
14930 _ => {
14931 hint_strings.push(self.hint_expression_to_string(expr)?);
14932 }
14933 }
14934 }
14935
14936 let use_multiline = self.config.pretty && hint_strings.len() > 1;
14940
14941 if use_multiline {
14942 self.write(" /*+ ");
14944 for (i, hint_str) in hint_strings.iter().enumerate() {
14945 if i > 0 {
14946 self.write_newline();
14947 self.write(" "); }
14949 self.write(hint_str);
14950 }
14951 self.write(" */");
14952 } else {
14953 self.write(" /*+ ");
14955 let sep = match self.config.dialect {
14956 Some(DialectType::Spark) | Some(DialectType::Databricks) => ", ",
14957 _ => " ",
14958 };
14959 for (i, hint_str) in hint_strings.iter().enumerate() {
14960 if i > 0 {
14961 self.write(sep);
14962 }
14963 self.write(hint_str);
14964 }
14965 self.write(" */");
14966 }
14967
14968 Ok(())
14969 }
14970
14971 fn parse_raw_hint_text(&self, text: &str) -> Vec<String> {
14975 let mut results = Vec::new();
14976 let mut chars = text.chars().peekable();
14977 let mut current = String::new();
14978 let mut paren_depth = 0;
14979 let mut has_unparseable_content = false;
14980 let mut position_after_last_function = 0;
14981 let mut char_position = 0;
14982
14983 while let Some(c) = chars.next() {
14984 char_position += c.len_utf8();
14985 match c {
14986 '(' => {
14987 paren_depth += 1;
14988 current.push(c);
14989 }
14990 ')' => {
14991 paren_depth -= 1;
14992 current.push(c);
14993 if paren_depth == 0 {
14995 let trimmed = current.trim().to_string();
14996 if !trimmed.is_empty() {
14997 let formatted = self.format_hint_function(&trimmed);
14999 results.push(formatted);
15000 }
15001 current.clear();
15002 position_after_last_function = char_position;
15003 }
15004 }
15005 ' ' | '\t' | '\n' | ',' if paren_depth == 0 => {
15006 }
15008 _ if paren_depth == 0 => {
15009 current.push(c);
15011 }
15012 _ => {
15013 current.push(c);
15014 }
15015 }
15016 }
15017
15018 let remaining_text = text[position_after_last_function..].trim();
15020 if !remaining_text.is_empty() {
15021 let words: Vec<&str> = remaining_text.split_whitespace().collect();
15025 let looks_like_hint_functions = words.iter().all(|word| {
15026 word.contains('(') || (word.chars().all(|c| c.is_ascii_uppercase() || c == '_'))
15028 });
15029
15030 if !looks_like_hint_functions && words.len() > 1 {
15031 has_unparseable_content = true;
15032 }
15033 }
15034
15035 if has_unparseable_content {
15037 return vec![text.trim().to_string()];
15038 }
15039
15040 if results.is_empty() {
15042 results.push(text.trim().to_string());
15043 }
15044
15045 results
15046 }
15047
15048 fn format_hint_function(&self, hint: &str) -> String {
15051 if !self.config.pretty {
15052 return hint.to_string();
15053 }
15054
15055 if let Some(paren_pos) = hint.find('(') {
15057 if hint.ends_with(')') {
15058 let name = &hint[..paren_pos];
15059 let args_str = &hint[paren_pos + 1..hint.len() - 1];
15060
15061 let args: Vec<&str> = args_str.split_whitespace().collect();
15063
15064 let total_args_width: usize =
15066 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() {
15070 let mut result = format!("{}(\n", name);
15071 for arg in &args {
15072 result.push_str(" "); result.push_str(arg);
15074 result.push('\n');
15075 }
15076 result.push_str(" )"); return result;
15078 }
15079 }
15080 }
15081
15082 hint.to_string()
15083 }
15084
15085 fn hint_expression_to_string(&mut self, expr: &HintExpression) -> Result<String> {
15087 match expr {
15088 HintExpression::Function { name, args } => {
15089 let arg_strings: Vec<String> = args
15091 .iter()
15092 .map(|arg| {
15093 let mut gen = Generator::with_config(self.config.clone());
15094 gen.generate_expression(arg)?;
15095 Ok(gen.output)
15096 })
15097 .collect::<Result<Vec<_>>>()?;
15098
15099 let total_args_width: usize = arg_strings.iter().map(|s| s.len()).sum::<usize>()
15101 + arg_strings.len().saturating_sub(1); let args_multiline =
15106 self.config.pretty && total_args_width > self.config.max_text_width;
15107
15108 if args_multiline && !arg_strings.is_empty() {
15109 let mut result = format!("{}(\n", name);
15111 for arg_str in &arg_strings {
15112 result.push_str(" "); result.push_str(arg_str);
15114 result.push('\n');
15115 }
15116 result.push_str(" )"); Ok(result)
15118 } else {
15119 let args_str = arg_strings.join(" ");
15121 Ok(format!("{}({})", name, args_str))
15122 }
15123 }
15124 HintExpression::Identifier(name) => Ok(name.clone()),
15125 HintExpression::Raw(text) => {
15126 if self.config.pretty {
15128 Ok(self.format_hint_function(text))
15129 } else {
15130 Ok(text.clone())
15131 }
15132 }
15133 }
15134 }
15135
15136 fn generate_table(&mut self, table: &TableRef) -> Result<()> {
15137 if table.only {
15139 self.write_keyword("ONLY");
15140 self.write_space();
15141 }
15142
15143 if let Some(ref identifier_func) = table.identifier_func {
15145 self.generate_expression(identifier_func)?;
15146 } else {
15147 if let Some(catalog) = &table.catalog {
15148 self.generate_identifier(catalog)?;
15149 self.write(".");
15150 }
15151 if let Some(schema) = &table.schema {
15152 self.generate_identifier(schema)?;
15153 self.write(".");
15154 }
15155 self.generate_identifier(&table.name)?;
15156 }
15157
15158 if let Some(changes) = &table.changes {
15160 self.write(" ");
15161 self.generate_changes(changes)?;
15162 }
15163
15164 if !table.partitions.is_empty() {
15166 self.write_space();
15167 self.write_keyword("PARTITION");
15168 self.write("(");
15169 for (i, partition) in table.partitions.iter().enumerate() {
15170 if i > 0 {
15171 self.write(", ");
15172 }
15173 self.generate_identifier(partition)?;
15174 }
15175 self.write(")");
15176 }
15177
15178 if table.changes.is_none() {
15181 if let Some(when) = &table.when {
15182 self.write_space();
15183 self.generate_historical_data(when)?;
15184 }
15185 }
15186
15187 if let Some(ref system_time) = table.system_time {
15189 self.write_space();
15190 self.write(system_time);
15191 }
15192
15193 if let Some(ref version) = table.version {
15195 self.write_space();
15196 self.generate_version(version)?;
15197 }
15198
15199 let alias_post_tablesample = self.config.alias_post_tablesample;
15203
15204 if alias_post_tablesample {
15205 self.generate_table_sample_clause(table)?;
15207 }
15208
15209 let is_sqlite_hint = matches!(self.config.dialect, Some(DialectType::SQLite))
15212 && table.hints.iter().any(|h| {
15213 if let Expression::Identifier(id) = h {
15214 id.name.starts_with("INDEXED BY") || id.name == "NOT INDEXED"
15215 } else {
15216 false
15217 }
15218 });
15219 if !table.hints.is_empty() && !is_sqlite_hint {
15220 for hint in &table.hints {
15221 self.write_space();
15222 self.generate_expression(hint)?;
15223 }
15224 }
15225
15226 if let Some(alias) = &table.alias {
15227 self.write_space();
15228 let always_use_as = self.config.dialect.is_none()
15231 || matches!(
15232 self.config.dialect,
15233 Some(DialectType::Generic)
15234 | Some(DialectType::PostgreSQL)
15235 | Some(DialectType::Redshift)
15236 | Some(DialectType::Snowflake)
15237 | Some(DialectType::BigQuery)
15238 | Some(DialectType::Presto)
15239 | Some(DialectType::Trino)
15240 | Some(DialectType::TSQL)
15241 | Some(DialectType::Fabric)
15242 | Some(DialectType::MySQL)
15243 | Some(DialectType::Spark)
15244 | Some(DialectType::Hive)
15245 | Some(DialectType::SQLite)
15246 | Some(DialectType::Drill)
15247 );
15248 let is_stage_ref = table.name.name.starts_with('@');
15249 let suppress_as = matches!(self.config.dialect, Some(DialectType::Oracle));
15251 if !suppress_as && (table.alias_explicit_as || always_use_as || is_stage_ref) {
15252 self.write_keyword("AS");
15253 self.write_space();
15254 }
15255 self.generate_identifier(alias)?;
15256
15257 if !table.column_aliases.is_empty() && self.config.supports_table_alias_columns {
15260 self.write("(");
15261 for (i, col_alias) in table.column_aliases.iter().enumerate() {
15262 if i > 0 {
15263 self.write(", ");
15264 }
15265 self.generate_identifier(col_alias)?;
15266 }
15267 self.write(")");
15268 }
15269 }
15270
15271 if !alias_post_tablesample {
15273 self.generate_table_sample_clause(table)?;
15274 }
15275
15276 if is_sqlite_hint {
15278 for hint in &table.hints {
15279 self.write_space();
15280 self.generate_expression(hint)?;
15281 }
15282 }
15283
15284 if table.final_ && matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
15286 self.write_space();
15287 self.write_keyword("FINAL");
15288 }
15289
15290 for comment in &table.trailing_comments {
15292 self.write_space();
15293 self.write_formatted_comment(comment);
15294 }
15295
15296 Ok(())
15297 }
15298
15299 fn generate_table_sample_clause(&mut self, table: &TableRef) -> Result<()> {
15301 if let Some(ref ts) = table.table_sample {
15302 self.write_space();
15303 if ts.is_using_sample {
15304 self.write_keyword("USING SAMPLE");
15305 } else {
15306 self.write_keyword(self.config.tablesample_keywords);
15308 }
15309 self.generate_sample_body(ts)?;
15310 if let Some(ref seed) = ts.seed {
15312 self.write_space();
15313 self.write_keyword(self.config.tablesample_seed_keyword);
15314 self.write(" (");
15315 self.generate_expression(seed)?;
15316 self.write(")");
15317 }
15318 }
15319 Ok(())
15320 }
15321
15322 fn generate_stage_reference(&mut self, sr: &StageReference) -> Result<()> {
15323 if sr.quoted {
15327 self.write("'");
15328 }
15329
15330 self.write(&sr.name);
15331 if let Some(path) = &sr.path {
15332 self.write(path);
15333 }
15334
15335 if sr.quoted {
15336 self.write("'");
15337 }
15338
15339 let has_options = sr.file_format.is_some() || sr.pattern.is_some();
15341 if has_options {
15342 self.write(" (");
15343 let mut first = true;
15344
15345 if let Some(file_format) = &sr.file_format {
15346 if !first {
15347 self.write(", ");
15348 }
15349 self.write_keyword("FILE_FORMAT");
15350 self.write(" => ");
15351 self.generate_expression(file_format)?;
15352 first = false;
15353 }
15354
15355 if let Some(pattern) = &sr.pattern {
15356 if !first {
15357 self.write(", ");
15358 }
15359 self.write_keyword("PATTERN");
15360 self.write(" => '");
15361 self.write(pattern);
15362 self.write("'");
15363 }
15364
15365 self.write(")");
15366 }
15367 Ok(())
15368 }
15369
15370 fn generate_star(&mut self, star: &Star) -> Result<()> {
15371 use crate::dialects::DialectType;
15372
15373 if let Some(table) = &star.table {
15374 self.generate_identifier(table)?;
15375 self.write(".");
15376 }
15377 self.write("*");
15378
15379 if let Some(except) = &star.except {
15381 if !except.is_empty() {
15382 self.write_space();
15383 match self.config.dialect {
15385 Some(DialectType::BigQuery) => self.write_keyword("EXCEPT"),
15386 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => {
15387 self.write_keyword("EXCLUDE")
15388 }
15389 _ => self.write_keyword("EXCEPT"), }
15391 self.write(" (");
15392 for (i, col) in except.iter().enumerate() {
15393 if i > 0 {
15394 self.write(", ");
15395 }
15396 self.generate_identifier(col)?;
15397 }
15398 self.write(")");
15399 }
15400 }
15401
15402 if let Some(replace) = &star.replace {
15404 if !replace.is_empty() {
15405 self.write_space();
15406 self.write_keyword("REPLACE");
15407 self.write(" (");
15408 for (i, alias) in replace.iter().enumerate() {
15409 if i > 0 {
15410 self.write(", ");
15411 }
15412 self.generate_expression(&alias.this)?;
15413 self.write_space();
15414 self.write_keyword("AS");
15415 self.write_space();
15416 self.generate_identifier(&alias.alias)?;
15417 }
15418 self.write(")");
15419 }
15420 }
15421
15422 if let Some(rename) = &star.rename {
15424 if !rename.is_empty() {
15425 self.write_space();
15426 self.write_keyword("RENAME");
15427 self.write(" (");
15428 for (i, (old_name, new_name)) in rename.iter().enumerate() {
15429 if i > 0 {
15430 self.write(", ");
15431 }
15432 self.generate_identifier(old_name)?;
15433 self.write_space();
15434 self.write_keyword("AS");
15435 self.write_space();
15436 self.generate_identifier(new_name)?;
15437 }
15438 self.write(")");
15439 }
15440 }
15441
15442 for comment in &star.trailing_comments {
15444 self.write_space();
15445 self.write_formatted_comment(comment);
15446 }
15447
15448 Ok(())
15449 }
15450
15451 fn generate_braced_wildcard(&mut self, expr: &Expression) -> Result<()> {
15453 self.write("{");
15454 match expr {
15455 Expression::Star(star) => {
15456 self.generate_star(star)?;
15458 }
15459 Expression::ILike(ilike) => {
15460 self.generate_expression(&ilike.left)?;
15462 self.write_space();
15463 self.write_keyword("ILIKE");
15464 self.write_space();
15465 self.generate_expression(&ilike.right)?;
15466 }
15467 _ => {
15468 self.generate_expression(expr)?;
15469 }
15470 }
15471 self.write("}");
15472 Ok(())
15473 }
15474
15475 fn generate_alias(&mut self, alias: &Alias) -> Result<()> {
15476 match &alias.this {
15480 Expression::Column(col) => {
15481 if let Some(table) = &col.table {
15483 self.generate_identifier(table)?;
15484 self.write(".");
15485 }
15486 self.generate_identifier(&col.name)?;
15487 }
15488 _ => {
15489 self.generate_expression(&alias.this)?;
15490 }
15491 }
15492
15493 if !alias.pre_alias_comments.is_empty() && !alias.trailing_comments.is_empty() {
15497 for comment in &alias.pre_alias_comments {
15498 self.write_space();
15499 self.write_formatted_comment(comment);
15500 }
15501 }
15502
15503 use crate::dialects::DialectType;
15504
15505 let is_table_source = matches!(
15511 &alias.this,
15512 Expression::JSONTable(_)
15513 | Expression::XMLTable(_)
15514 | Expression::TableFromRows(_)
15515 | Expression::Unnest(_)
15516 | Expression::MatchRecognize(_)
15517 | Expression::Select(_)
15518 | Expression::Subquery(_)
15519 | Expression::Paren(_)
15520 );
15521 let dialect_skips_table_alias_as = matches!(self.config.dialect, Some(DialectType::Oracle));
15522 let skip_as = is_table_source && dialect_skips_table_alias_as;
15523
15524 self.write_space();
15525 if !skip_as {
15526 self.write_keyword("AS");
15527 self.write_space();
15528 }
15529
15530 let skip_column_aliases = matches!(self.config.dialect, Some(DialectType::BigQuery));
15532
15533 if alias.alias.is_empty() && !alias.column_aliases.is_empty() && !skip_column_aliases {
15535 self.write("(");
15537 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
15538 if i > 0 {
15539 self.write(", ");
15540 }
15541 self.generate_alias_identifier(col_alias)?;
15542 }
15543 self.write(")");
15544 } else if !alias.column_aliases.is_empty() && !skip_column_aliases {
15545 self.generate_alias_identifier(&alias.alias)?;
15547 self.write("(");
15548 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
15549 if i > 0 {
15550 self.write(", ");
15551 }
15552 self.generate_alias_identifier(col_alias)?;
15553 }
15554 self.write(")");
15555 } else {
15556 self.generate_alias_identifier(&alias.alias)?;
15558 }
15559
15560 for comment in &alias.trailing_comments {
15562 self.write_space();
15563 self.write_formatted_comment(comment);
15564 }
15565
15566 if alias.trailing_comments.is_empty() {
15571 for comment in &alias.pre_alias_comments {
15572 self.write_space();
15573 self.write_formatted_comment(comment);
15574 }
15575 }
15576
15577 Ok(())
15578 }
15579
15580 fn generate_cast(&mut self, cast: &Cast) -> Result<()> {
15581 use crate::dialects::DialectType;
15582
15583 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
15585 self.generate_expression(&cast.this)?;
15586 self.write(" :> ");
15587 self.generate_data_type(&cast.to)?;
15588 return Ok(());
15589 }
15590
15591 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
15593 let is_unknown_type = matches!(cast.to, DataType::Unknown)
15594 || matches!(cast.to, DataType::Custom { ref name } if name.is_empty());
15595 if is_unknown_type {
15596 if let Some(format) = &cast.format {
15597 self.write_keyword("CAST");
15598 self.write("(");
15599 self.generate_expression(&cast.this)?;
15600 self.write_space();
15601 self.write_keyword("AS");
15602 self.write_space();
15603 self.write_keyword("FORMAT");
15604 self.write_space();
15605 self.generate_expression(format)?;
15606 self.write(")");
15607 return Ok(());
15608 }
15609 }
15610 }
15611
15612 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
15615 if let Some(format) = &cast.format {
15616 let is_date = matches!(cast.to, DataType::Date);
15618 let is_timestamp = matches!(cast.to, DataType::Timestamp { .. });
15619
15620 if is_date || is_timestamp {
15621 let func_name = if is_date { "TO_DATE" } else { "TO_TIMESTAMP" };
15622 self.write_keyword(func_name);
15623 self.write("(");
15624 self.generate_expression(&cast.this)?;
15625 self.write(", ");
15626
15627 if let Expression::Literal(Literal::String(fmt_str)) = format.as_ref() {
15630 let normalized = self.normalize_oracle_format(fmt_str);
15631 self.write("'");
15632 self.write(&normalized);
15633 self.write("'");
15634 } else {
15635 self.generate_expression(format)?;
15636 }
15637
15638 self.write(")");
15639 return Ok(());
15640 }
15641 }
15642 }
15643
15644 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
15647 if let Expression::Array(arr) = &cast.this {
15648 self.generate_data_type(&cast.to)?;
15649 self.write("[");
15651 for (i, expr) in arr.expressions.iter().enumerate() {
15652 if i > 0 {
15653 self.write(", ");
15654 }
15655 self.generate_expression(expr)?;
15656 }
15657 self.write("]");
15658 return Ok(());
15659 }
15660 if matches!(&cast.this, Expression::ArrayFunc(_)) {
15661 self.generate_data_type(&cast.to)?;
15662 self.generate_expression(&cast.this)?;
15663 return Ok(());
15664 }
15665 }
15666
15667 if matches!(
15670 self.config.dialect,
15671 Some(DialectType::DuckDB) | Some(DialectType::Presto) | Some(DialectType::Trino)
15672 ) {
15673 if let Expression::Struct(ref s) = cast.this {
15674 let all_unnamed = s.fields.iter().all(|(name, _)| name.is_none());
15675 if all_unnamed && matches!(cast.to, DataType::Struct { .. }) {
15676 self.write_keyword("CAST");
15677 self.write("(");
15678 self.generate_struct_as_row(s)?;
15679 self.write_space();
15680 self.write_keyword("AS");
15681 self.write_space();
15682 self.generate_data_type(&cast.to)?;
15683 self.write(")");
15684 return Ok(());
15685 }
15686 }
15687 }
15688
15689 let use_double_colon = cast.double_colon_syntax && self.dialect_prefers_double_colon();
15692
15693 if use_double_colon {
15694 self.generate_expression(&cast.this)?;
15696 self.write("::");
15697 self.generate_data_type(&cast.to)?;
15698 } else {
15699 self.write_keyword("CAST");
15701 self.write("(");
15702 self.generate_expression(&cast.this)?;
15703 self.write_space();
15704 self.write_keyword("AS");
15705 self.write_space();
15706 if matches!(
15709 self.config.dialect,
15710 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB)
15711 ) {
15712 match &cast.to {
15713 DataType::Custom { ref name } => {
15714 let upper = name.to_uppercase();
15715 match upper.as_str() {
15716 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" | "LONGBLOB" | "MEDIUMBLOB"
15717 | "TINYBLOB" => {
15718 self.write_keyword("CHAR");
15719 }
15720 _ => {
15721 self.generate_data_type(&cast.to)?;
15722 }
15723 }
15724 }
15725 DataType::VarChar { length, .. } => {
15726 self.write_keyword("CHAR");
15728 if let Some(n) = length {
15729 self.write(&format!("({})", n));
15730 }
15731 }
15732 DataType::Text => {
15733 self.write_keyword("CHAR");
15735 }
15736 DataType::Timestamp {
15737 precision,
15738 timezone: false,
15739 } => {
15740 self.write_keyword("DATETIME");
15742 if let Some(p) = precision {
15743 self.write(&format!("({})", p));
15744 }
15745 }
15746 _ => {
15747 self.generate_data_type(&cast.to)?;
15748 }
15749 }
15750 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
15751 match &cast.to {
15753 DataType::String { length } => {
15754 self.write_keyword("VARCHAR");
15755 if let Some(n) = length {
15756 self.write(&format!("({})", n));
15757 }
15758 }
15759 _ => {
15760 self.generate_data_type(&cast.to)?;
15761 }
15762 }
15763 } else {
15764 self.generate_data_type(&cast.to)?;
15765 }
15766
15767 if let Some(default) = &cast.default {
15769 self.write_space();
15770 self.write_keyword("DEFAULT");
15771 self.write_space();
15772 self.generate_expression(default)?;
15773 self.write_space();
15774 self.write_keyword("ON");
15775 self.write_space();
15776 self.write_keyword("CONVERSION");
15777 self.write_space();
15778 self.write_keyword("ERROR");
15779 }
15780
15781 if let Some(format) = &cast.format {
15784 if matches!(
15786 self.config.dialect,
15787 Some(crate::dialects::DialectType::Oracle)
15788 ) {
15789 self.write(", ");
15790 } else {
15791 self.write_space();
15792 self.write_keyword("FORMAT");
15793 self.write_space();
15794 }
15795 self.generate_expression(format)?;
15796 }
15797
15798 self.write(")");
15799 for comment in &cast.trailing_comments {
15801 self.write_space();
15802 self.write_formatted_comment(comment);
15803 }
15804 }
15805 Ok(())
15806 }
15807
15808 fn generate_struct_as_row(&mut self, s: &crate::expressions::Struct) -> Result<()> {
15811 self.write_keyword("ROW");
15812 self.write("(");
15813 for (i, (_, expr)) in s.fields.iter().enumerate() {
15814 if i > 0 {
15815 self.write(", ");
15816 }
15817 if let Expression::Struct(ref inner_s) = expr {
15819 self.generate_struct_as_row(inner_s)?;
15820 } else {
15821 self.generate_expression(expr)?;
15822 }
15823 }
15824 self.write(")");
15825 Ok(())
15826 }
15827
15828 fn normalize_oracle_format(&self, format: &str) -> String {
15831 let mut result = String::new();
15834 let chars: Vec<char> = format.chars().collect();
15835 let mut i = 0;
15836
15837 while i < chars.len() {
15838 if i + 1 < chars.len() && chars[i] == 'H' && chars[i + 1] == 'H' {
15839 if i + 2 < chars.len() {
15841 let next = chars[i + 2];
15842 if next == '1' || next == '2' {
15843 result.push('H');
15845 result.push('H');
15846 i += 2;
15847 continue;
15848 }
15849 }
15850 result.push_str("HH12");
15852 i += 2;
15853 } else {
15854 result.push(chars[i]);
15855 i += 1;
15856 }
15857 }
15858
15859 result
15860 }
15861
15862 fn dialect_prefers_double_colon(&self) -> bool {
15866 false
15869 }
15870
15871 fn generate_mod_func(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
15873 use crate::dialects::DialectType;
15874
15875 let use_percent_operator = matches!(
15877 self.config.dialect,
15878 Some(DialectType::Snowflake)
15879 | Some(DialectType::MySQL)
15880 | Some(DialectType::Presto)
15881 | Some(DialectType::Trino)
15882 | Some(DialectType::PostgreSQL)
15883 | Some(DialectType::DuckDB)
15884 | Some(DialectType::Hive)
15885 | Some(DialectType::Spark)
15886 | Some(DialectType::Databricks)
15887 | Some(DialectType::Athena)
15888 );
15889
15890 if use_percent_operator {
15891 let needs_paren = |e: &Expression| matches!(e, Expression::Add(_) | Expression::Sub(_));
15894 if needs_paren(&f.this) {
15895 self.write("(");
15896 self.generate_expression(&f.this)?;
15897 self.write(")");
15898 } else {
15899 self.generate_expression(&f.this)?;
15900 }
15901 self.write(" % ");
15902 if needs_paren(&f.expression) {
15903 self.write("(");
15904 self.generate_expression(&f.expression)?;
15905 self.write(")");
15906 } else {
15907 self.generate_expression(&f.expression)?;
15908 }
15909 Ok(())
15910 } else {
15911 self.generate_binary_func("MOD", &f.this, &f.expression)
15912 }
15913 }
15914
15915 fn generate_ifnull(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
15917 use crate::dialects::DialectType;
15918
15919 let func_name = match self.config.dialect {
15921 Some(DialectType::Snowflake) => "COALESCE",
15922 _ => "IFNULL",
15923 };
15924
15925 self.generate_binary_func(func_name, &f.this, &f.expression)
15926 }
15927
15928 fn generate_nvl(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
15930 if let Some(ref original_name) = f.original_name {
15932 return self.generate_binary_func(original_name, &f.this, &f.expression);
15933 }
15934
15935 use crate::dialects::DialectType;
15937 let func_name = match self.config.dialect {
15938 Some(DialectType::Snowflake)
15939 | Some(DialectType::ClickHouse)
15940 | Some(DialectType::PostgreSQL)
15941 | Some(DialectType::Presto)
15942 | Some(DialectType::Trino)
15943 | Some(DialectType::Athena)
15944 | Some(DialectType::DuckDB)
15945 | Some(DialectType::BigQuery)
15946 | Some(DialectType::Spark)
15947 | Some(DialectType::Databricks)
15948 | Some(DialectType::Hive) => "COALESCE",
15949 Some(DialectType::MySQL)
15950 | Some(DialectType::Doris)
15951 | Some(DialectType::StarRocks)
15952 | Some(DialectType::SingleStore)
15953 | Some(DialectType::TiDB) => "IFNULL",
15954 _ => "NVL",
15955 };
15956
15957 self.generate_binary_func(func_name, &f.this, &f.expression)
15958 }
15959
15960 fn generate_stddev_samp(&mut self, f: &crate::expressions::AggFunc) -> Result<()> {
15962 use crate::dialects::DialectType;
15963
15964 let func_name = match self.config.dialect {
15966 Some(DialectType::Snowflake) => "STDDEV",
15967 _ => "STDDEV_SAMP",
15968 };
15969
15970 self.generate_agg_func(func_name, f)
15971 }
15972
15973 fn generate_collation(&mut self, coll: &CollationExpr) -> Result<()> {
15974 self.generate_expression(&coll.this)?;
15975 self.write_space();
15976 self.write_keyword("COLLATE");
15977 self.write_space();
15978 if coll.quoted {
15979 self.write("'");
15981 self.write(&coll.collation);
15982 self.write("'");
15983 } else if coll.double_quoted {
15984 self.write("\"");
15986 self.write(&coll.collation);
15987 self.write("\"");
15988 } else {
15989 self.write(&coll.collation);
15991 }
15992 Ok(())
15993 }
15994
15995 fn generate_case(&mut self, case: &Case) -> Result<()> {
15996 let multiline_case = if self.config.pretty {
15998 let mut statements: Vec<String> = Vec::new();
16000 let operand_str = if let Some(operand) = &case.operand {
16001 let s = self.generate_to_string(operand)?;
16002 statements.push(format!("CASE {}", s));
16003 s
16004 } else {
16005 statements.push("CASE".to_string());
16006 String::new()
16007 };
16008 let _ = operand_str;
16009 for (condition, result) in &case.whens {
16010 statements.push(format!("WHEN {}", self.generate_to_string(condition)?));
16011 statements.push(format!("THEN {}", self.generate_to_string(result)?));
16012 }
16013 if let Some(else_) = &case.else_ {
16014 statements.push(format!("ELSE {}", self.generate_to_string(else_)?));
16015 }
16016 statements.push("END".to_string());
16017 self.too_wide(&statements)
16018 } else {
16019 false
16020 };
16021
16022 self.write_keyword("CASE");
16023 if let Some(operand) = &case.operand {
16024 self.write_space();
16025 self.generate_expression(operand)?;
16026 }
16027 if multiline_case {
16028 self.indent_level += 1;
16029 }
16030 for (condition, result) in &case.whens {
16031 if multiline_case {
16032 self.write_newline();
16033 self.write_indent();
16034 } else {
16035 self.write_space();
16036 }
16037 self.write_keyword("WHEN");
16038 self.write_space();
16039 self.generate_expression(condition)?;
16040 if multiline_case {
16041 self.write_newline();
16042 self.write_indent();
16043 } else {
16044 self.write_space();
16045 }
16046 self.write_keyword("THEN");
16047 self.write_space();
16048 self.generate_expression(result)?;
16049 }
16050 if let Some(else_) = &case.else_ {
16051 if multiline_case {
16052 self.write_newline();
16053 self.write_indent();
16054 } else {
16055 self.write_space();
16056 }
16057 self.write_keyword("ELSE");
16058 self.write_space();
16059 self.generate_expression(else_)?;
16060 }
16061 if multiline_case {
16062 self.indent_level -= 1;
16063 self.write_newline();
16064 self.write_indent();
16065 } else {
16066 self.write_space();
16067 }
16068 self.write_keyword("END");
16069 for comment in &case.comments {
16071 self.write(" ");
16072 self.write_formatted_comment(comment);
16073 }
16074 Ok(())
16075 }
16076
16077 fn generate_function(&mut self, func: &Function) -> Result<()> {
16078 let normalized_name = self.normalize_func_name(&func.name);
16080 let upper_name = func.name.to_uppercase();
16081
16082 if matches!(self.config.dialect, Some(DialectType::DuckDB))
16084 && upper_name == "ARRAY_CONSTRUCT_COMPACT"
16085 {
16086 self.write("LIST_FILTER(");
16087 self.write("[");
16088 for (i, arg) in func.args.iter().enumerate() {
16089 if i > 0 {
16090 self.write(", ");
16091 }
16092 self.generate_expression(arg)?;
16093 }
16094 self.write("], _u -> NOT _u IS NULL)");
16095 return Ok(());
16096 }
16097
16098 if upper_name == "STRUCT"
16100 && !matches!(
16101 self.config.dialect,
16102 Some(DialectType::BigQuery)
16103 | Some(DialectType::Spark)
16104 | Some(DialectType::Databricks)
16105 | Some(DialectType::Hive)
16106 | None
16107 )
16108 {
16109 return self.generate_struct_function_cross_dialect(func);
16110 }
16111
16112 if upper_name == "__SS_JSON_PATH_QMARK__" && func.args.len() == 2 {
16115 self.generate_expression(&func.args[0])?;
16116 self.write("::?");
16117 if let Expression::Literal(crate::expressions::Literal::String(key)) = &func.args[1] {
16119 self.write(key);
16120 } else {
16121 self.generate_expression(&func.args[1])?;
16122 }
16123 return Ok(());
16124 }
16125
16126 if upper_name == "__PG_BITWISE_XOR__" && func.args.len() == 2 {
16128 self.generate_expression(&func.args[0])?;
16129 self.write(" # ");
16130 self.generate_expression(&func.args[1])?;
16131 return Ok(());
16132 }
16133
16134 if matches!(
16136 self.config.dialect,
16137 Some(DialectType::Spark | DialectType::Databricks | DialectType::Hive)
16138 ) && upper_name == "TRY"
16139 && func.args.len() == 1
16140 {
16141 self.generate_expression(&func.args[0])?;
16142 return Ok(());
16143 }
16144
16145 if self.config.dialect == Some(DialectType::ClickHouse)
16147 && upper_name == "TOSTARTOFDAY"
16148 && func.args.len() == 1
16149 {
16150 self.write("dateTrunc('DAY', ");
16151 self.generate_expression(&func.args[0])?;
16152 self.write(")");
16153 return Ok(());
16154 }
16155
16156 if self.config.dialect == Some(DialectType::Redshift)
16158 && upper_name == "CONCAT"
16159 && func.args.len() >= 2
16160 {
16161 for (i, arg) in func.args.iter().enumerate() {
16162 if i > 0 {
16163 self.write(" || ");
16164 }
16165 self.generate_expression(arg)?;
16166 }
16167 return Ok(());
16168 }
16169
16170 if self.config.dialect == Some(DialectType::Redshift)
16172 && upper_name == "CONCAT_WS"
16173 && func.args.len() >= 2
16174 {
16175 let sep = &func.args[0];
16176 for (i, arg) in func.args.iter().skip(1).enumerate() {
16177 if i > 0 {
16178 self.write(" || ");
16179 self.generate_expression(sep)?;
16180 self.write(" || ");
16181 }
16182 self.generate_expression(arg)?;
16183 }
16184 return Ok(());
16185 }
16186
16187 if self.config.dialect == Some(DialectType::Redshift)
16190 && (upper_name == "DATEDIFF" || upper_name == "DATE_DIFF")
16191 && func.args.len() == 3
16192 {
16193 self.write_keyword("DATEDIFF");
16194 self.write("(");
16195 self.write_redshift_date_part(&func.args[0]);
16197 self.write(", ");
16198 self.generate_expression(&func.args[1])?;
16199 self.write(", ");
16200 self.generate_expression(&func.args[2])?;
16201 self.write(")");
16202 return Ok(());
16203 }
16204
16205 if self.config.dialect == Some(DialectType::Redshift)
16208 && (upper_name == "DATEADD" || upper_name == "DATE_ADD")
16209 && func.args.len() == 3
16210 {
16211 self.write_keyword("DATEADD");
16212 self.write("(");
16213 self.write_redshift_date_part(&func.args[0]);
16215 self.write(", ");
16216 self.generate_expression(&func.args[1])?;
16217 self.write(", ");
16218 self.generate_expression(&func.args[2])?;
16219 self.write(")");
16220 return Ok(());
16221 }
16222
16223 if upper_name == "UUID_STRING"
16225 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None)
16226 {
16227 let func_name = match self.config.dialect {
16228 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
16229 Some(DialectType::BigQuery) => "GENERATE_UUID",
16230 _ => "UUID",
16231 };
16232 self.write_keyword(func_name);
16233 self.write("()");
16234 return Ok(());
16235 }
16236
16237 if self.config.dialect == Some(DialectType::Redshift)
16240 && upper_name == "DATE_TRUNC"
16241 && func.args.len() == 2
16242 {
16243 self.write_keyword("DATE_TRUNC");
16244 self.write("(");
16245 self.write_redshift_date_part_quoted(&func.args[0]);
16247 self.write(", ");
16248 self.generate_expression(&func.args[1])?;
16249 self.write(")");
16250 return Ok(());
16251 }
16252
16253 if matches!(
16255 self.config.dialect,
16256 Some(DialectType::TSQL) | Some(DialectType::Fabric)
16257 ) && (upper_name == "DATE_PART" || upper_name == "DATEPART")
16258 && func.args.len() == 2
16259 {
16260 self.write_keyword("DATEPART");
16261 self.write("(");
16262 self.generate_expression(&func.args[0])?;
16263 self.write(", ");
16264 self.generate_expression(&func.args[1])?;
16265 self.write(")");
16266 return Ok(());
16267 }
16268
16269 if matches!(
16271 self.config.dialect,
16272 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
16273 ) && (upper_name == "DATE_PART" || upper_name == "DATEPART")
16274 && func.args.len() == 2
16275 {
16276 self.write_keyword("EXTRACT");
16277 self.write("(");
16278 match &func.args[0] {
16280 Expression::Literal(crate::expressions::Literal::String(s)) => {
16281 self.write(&s.to_lowercase());
16282 }
16283 _ => self.generate_expression(&func.args[0])?,
16284 }
16285 self.write_space();
16286 self.write_keyword("FROM");
16287 self.write_space();
16288 self.generate_expression(&func.args[1])?;
16289 self.write(")");
16290 return Ok(());
16291 }
16292
16293 if self.config.dialect == Some(DialectType::Dremio)
16296 && (upper_name == "DATE_PART" || upper_name == "DATEPART")
16297 && func.args.len() == 2
16298 {
16299 self.write_keyword("EXTRACT");
16300 self.write("(");
16301 self.generate_expression(&func.args[0])?;
16302 self.write_space();
16303 self.write_keyword("FROM");
16304 self.write_space();
16305 self.generate_dremio_date_expression(&func.args[1])?;
16307 self.write(")");
16308 return Ok(());
16309 }
16310
16311 if self.config.dialect == Some(DialectType::Dremio)
16313 && upper_name == "CURRENT_DATE_UTC"
16314 && func.args.is_empty()
16315 {
16316 self.write_keyword("CURRENT_DATE_UTC");
16317 return Ok(());
16318 }
16319
16320 if self.config.dialect == Some(DialectType::Dremio)
16324 && upper_name == "DATETYPE"
16325 && func.args.len() == 3
16326 {
16327 fn get_int_literal(expr: &Expression) -> Option<i64> {
16329 if let Expression::Literal(crate::expressions::Literal::Number(s)) = expr {
16330 s.parse::<i64>().ok()
16331 } else {
16332 None
16333 }
16334 }
16335
16336 if let (Some(year), Some(month), Some(day)) = (
16338 get_int_literal(&func.args[0]),
16339 get_int_literal(&func.args[1]),
16340 get_int_literal(&func.args[2]),
16341 ) {
16342 self.write_keyword("DATE");
16344 self.write(&format!("('{:04}-{:02}-{:02}')", year, month, day));
16345 return Ok(());
16346 }
16347
16348 self.write_keyword("CAST");
16350 self.write("(");
16351 self.write_keyword("CONCAT");
16352 self.write("(");
16353 self.generate_expression(&func.args[0])?;
16354 self.write(", '-', ");
16355 self.generate_expression(&func.args[1])?;
16356 self.write(", '-', ");
16357 self.generate_expression(&func.args[2])?;
16358 self.write(")");
16359 self.write_space();
16360 self.write_keyword("AS");
16361 self.write_space();
16362 self.write_keyword("DATE");
16363 self.write(")");
16364 return Ok(());
16365 }
16366
16367 let is_presto_like = matches!(
16370 self.config.dialect,
16371 Some(DialectType::Presto) | Some(DialectType::Trino)
16372 );
16373 if is_presto_like && upper_name == "DATE_ADD" && func.args.len() == 3 {
16374 self.write_keyword("DATE_ADD");
16375 self.write("(");
16376 self.generate_expression(&func.args[0])?;
16378 self.write(", ");
16379 let interval = &func.args[1];
16381 let needs_cast = !self.returns_integer_type(interval);
16382 if needs_cast {
16383 self.write_keyword("CAST");
16384 self.write("(");
16385 }
16386 self.generate_expression(interval)?;
16387 if needs_cast {
16388 self.write_space();
16389 self.write_keyword("AS");
16390 self.write_space();
16391 self.write_keyword("BIGINT");
16392 self.write(")");
16393 }
16394 self.write(", ");
16395 self.generate_expression(&func.args[2])?;
16397 self.write(")");
16398 return Ok(());
16399 }
16400
16401 let use_brackets = func.use_bracket_syntax;
16403
16404 let has_ordinality = upper_name.ends_with(" WITH ORDINALITY");
16409 let output_name = if has_ordinality {
16410 let base_name = &func.name[..func.name.len() - " WITH ORDINALITY".len()];
16411 self.normalize_func_name(base_name)
16412 } else {
16413 normalized_name.clone()
16414 };
16415
16416 if func.name.contains('.') && !has_ordinality {
16419 if func.quoted {
16422 self.write("`");
16423 self.write(&func.name);
16424 self.write("`");
16425 } else {
16426 self.write(&func.name);
16427 }
16428 } else {
16429 self.write(&output_name);
16430 }
16431
16432 let force_parens = func.no_parens && func.args.is_empty() && !func.distinct && {
16435 let needs_parens = match upper_name.as_str() {
16436 "CURRENT_USER" | "SESSION_USER" | "SYSTEM_USER" => matches!(
16437 self.config.dialect,
16438 Some(DialectType::Snowflake)
16439 | Some(DialectType::Spark)
16440 | Some(DialectType::Databricks)
16441 | Some(DialectType::Hive)
16442 ),
16443 _ => false,
16444 };
16445 !needs_parens
16446 };
16447 if force_parens {
16448 for comment in &func.trailing_comments {
16450 self.write_space();
16451 self.write_formatted_comment(comment);
16452 }
16453 return Ok(());
16454 }
16455
16456 if upper_name == "CUBE" || upper_name == "ROLLUP" || upper_name == "GROUPING SETS" {
16458 self.write(" (");
16459 } else if use_brackets {
16460 self.write("[");
16461 } else {
16462 self.write("(");
16463 }
16464 if func.distinct {
16465 self.write_keyword("DISTINCT");
16466 self.write_space();
16467 }
16468
16469 let compact_pretty_func = matches!(self.config.dialect, Some(DialectType::Snowflake))
16471 && (upper_name == "TABLE" || upper_name == "FLATTEN");
16472 let is_grouping_func =
16474 upper_name == "GROUPING SETS" || upper_name == "CUBE" || upper_name == "ROLLUP";
16475 let should_split = if self.config.pretty && !func.args.is_empty() && !compact_pretty_func {
16476 if is_grouping_func {
16477 true
16478 } else {
16479 let mut expr_strings: Vec<String> = Vec::with_capacity(func.args.len());
16481 for arg in &func.args {
16482 let mut temp_gen = Generator::with_config(self.config.clone());
16483 temp_gen.config.pretty = false; temp_gen.generate_expression(arg)?;
16485 expr_strings.push(temp_gen.output);
16486 }
16487 self.too_wide(&expr_strings)
16488 }
16489 } else {
16490 false
16491 };
16492
16493 if should_split {
16494 self.write_newline();
16496 self.indent_level += 1;
16497 for (i, arg) in func.args.iter().enumerate() {
16498 self.write_indent();
16499 self.generate_expression(arg)?;
16500 if i + 1 < func.args.len() {
16501 self.write(",");
16502 }
16503 self.write_newline();
16504 }
16505 self.indent_level -= 1;
16506 self.write_indent();
16507 } else {
16508 for (i, arg) in func.args.iter().enumerate() {
16510 if i > 0 {
16511 self.write(", ");
16512 }
16513 self.generate_expression(arg)?;
16514 }
16515 }
16516
16517 if use_brackets {
16518 self.write("]");
16519 } else {
16520 self.write(")");
16521 }
16522 if has_ordinality {
16524 self.write_space();
16525 self.write_keyword("WITH ORDINALITY");
16526 }
16527 for comment in &func.trailing_comments {
16529 self.write_space();
16530 self.write_formatted_comment(comment);
16531 }
16532 Ok(())
16533 }
16534
16535 fn generate_aggregate_function(&mut self, func: &AggregateFunction) -> Result<()> {
16536 let mut normalized_name = self.normalize_func_name(&func.name);
16538
16539 let upper = normalized_name.to_uppercase();
16541 if upper == "MAX_BY" || upper == "MIN_BY" {
16542 let is_max = upper == "MAX_BY";
16543 match self.config.dialect {
16544 Some(DialectType::ClickHouse) => {
16545 normalized_name = if is_max {
16546 "argMax".to_string()
16547 } else {
16548 "argMin".to_string()
16549 };
16550 }
16551 Some(DialectType::DuckDB) => {
16552 normalized_name = if is_max {
16553 "ARG_MAX".to_string()
16554 } else {
16555 "ARG_MIN".to_string()
16556 };
16557 }
16558 _ => {}
16559 }
16560 }
16561 self.write(&normalized_name);
16562 self.write("(");
16563 if func.distinct {
16564 self.write_keyword("DISTINCT");
16565 self.write_space();
16566 }
16567
16568 let is_count = normalized_name.eq_ignore_ascii_case("COUNT");
16572 let needs_multi_arg_transform =
16573 func.distinct && is_count && func.args.len() > 1 && !self.config.multi_arg_distinct;
16574
16575 if needs_multi_arg_transform {
16576 self.write_keyword("CASE");
16578 for arg in &func.args {
16579 self.write_space();
16580 self.write_keyword("WHEN");
16581 self.write_space();
16582 self.generate_expression(arg)?;
16583 self.write_space();
16584 self.write_keyword("IS NULL THEN NULL");
16585 }
16586 self.write_space();
16587 self.write_keyword("ELSE");
16588 self.write(" (");
16589 for (i, arg) in func.args.iter().enumerate() {
16590 if i > 0 {
16591 self.write(", ");
16592 }
16593 self.generate_expression(arg)?;
16594 }
16595 self.write(")");
16596 self.write_space();
16597 self.write_keyword("END");
16598 } else {
16599 for (i, arg) in func.args.iter().enumerate() {
16600 if i > 0 {
16601 self.write(", ");
16602 }
16603 self.generate_expression(arg)?;
16604 }
16605 }
16606
16607 if self.config.ignore_nulls_in_func
16609 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
16610 {
16611 if let Some(ignore) = func.ignore_nulls {
16612 self.write_space();
16613 if ignore {
16614 self.write_keyword("IGNORE NULLS");
16615 } else {
16616 self.write_keyword("RESPECT NULLS");
16617 }
16618 }
16619 }
16620
16621 if !func.order_by.is_empty() {
16623 self.write_space();
16624 self.write_keyword("ORDER BY");
16625 self.write_space();
16626 for (i, ord) in func.order_by.iter().enumerate() {
16627 if i > 0 {
16628 self.write(", ");
16629 }
16630 self.generate_ordered(ord)?;
16631 }
16632 }
16633
16634 if let Some(limit) = &func.limit {
16636 self.write_space();
16637 self.write_keyword("LIMIT");
16638 self.write_space();
16639 if let Expression::Tuple(t) = limit.as_ref() {
16641 if t.expressions.len() == 2 {
16642 self.generate_expression(&t.expressions[0])?;
16643 self.write(", ");
16644 self.generate_expression(&t.expressions[1])?;
16645 } else {
16646 self.generate_expression(limit)?;
16647 }
16648 } else {
16649 self.generate_expression(limit)?;
16650 }
16651 }
16652
16653 self.write(")");
16654
16655 if !self.config.ignore_nulls_in_func
16657 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
16658 {
16659 if let Some(ignore) = func.ignore_nulls {
16660 self.write_space();
16661 if ignore {
16662 self.write_keyword("IGNORE NULLS");
16663 } else {
16664 self.write_keyword("RESPECT NULLS");
16665 }
16666 }
16667 }
16668
16669 if let Some(filter) = &func.filter {
16670 self.write_space();
16671 self.write_keyword("FILTER");
16672 self.write("(");
16673 self.write_keyword("WHERE");
16674 self.write_space();
16675 self.generate_expression(filter)?;
16676 self.write(")");
16677 }
16678
16679 Ok(())
16680 }
16681
16682 fn generate_window_function(&mut self, wf: &WindowFunction) -> Result<()> {
16683 self.generate_expression(&wf.this)?;
16684
16685 if let Some(keep) = &wf.keep {
16687 self.write_space();
16688 self.write_keyword("KEEP");
16689 self.write(" (");
16690 self.write_keyword("DENSE_RANK");
16691 self.write_space();
16692 if keep.first {
16693 self.write_keyword("FIRST");
16694 } else {
16695 self.write_keyword("LAST");
16696 }
16697 self.write_space();
16698 self.write_keyword("ORDER BY");
16699 self.write_space();
16700 for (i, ord) in keep.order_by.iter().enumerate() {
16701 if i > 0 {
16702 self.write(", ");
16703 }
16704 self.generate_ordered(ord)?;
16705 }
16706 self.write(")");
16707 }
16708
16709 let has_over = !wf.over.partition_by.is_empty()
16711 || !wf.over.order_by.is_empty()
16712 || wf.over.frame.is_some()
16713 || wf.over.window_name.is_some();
16714
16715 if has_over {
16717 self.write_space();
16718 self.write_keyword("OVER");
16719
16720 let has_specs = !wf.over.partition_by.is_empty()
16722 || !wf.over.order_by.is_empty()
16723 || wf.over.frame.is_some();
16724
16725 if wf.over.window_name.is_some() && !has_specs {
16726 self.write_space();
16728 self.write(&wf.over.window_name.as_ref().unwrap().name);
16729 } else {
16730 self.write(" (");
16732 self.generate_over(&wf.over)?;
16733 self.write(")");
16734 }
16735 } else if wf.keep.is_none() {
16736 self.write_space();
16738 self.write_keyword("OVER");
16739 self.write(" ()");
16740 }
16741
16742 Ok(())
16743 }
16744
16745 fn generate_within_group(&mut self, wg: &WithinGroup) -> Result<()> {
16747 self.generate_expression(&wg.this)?;
16748 self.write_space();
16749 self.write_keyword("WITHIN GROUP");
16750 self.write(" (");
16751 self.write_keyword("ORDER BY");
16752 self.write_space();
16753 for (i, ord) in wg.order_by.iter().enumerate() {
16754 if i > 0 {
16755 self.write(", ");
16756 }
16757 self.generate_ordered(ord)?;
16758 }
16759 self.write(")");
16760 Ok(())
16761 }
16762
16763 fn generate_over(&mut self, over: &Over) -> Result<()> {
16765 let mut has_content = false;
16766
16767 if let Some(name) = &over.window_name {
16769 self.write(&name.name);
16770 has_content = true;
16771 }
16772
16773 if !over.partition_by.is_empty() {
16775 if has_content {
16776 self.write_space();
16777 }
16778 self.write_keyword("PARTITION BY");
16779 self.write_space();
16780 for (i, expr) in over.partition_by.iter().enumerate() {
16781 if i > 0 {
16782 self.write(", ");
16783 }
16784 self.generate_expression(expr)?;
16785 }
16786 has_content = true;
16787 }
16788
16789 if !over.order_by.is_empty() {
16791 if has_content {
16792 self.write_space();
16793 }
16794 self.write_keyword("ORDER BY");
16795 self.write_space();
16796 for (i, ordered) in over.order_by.iter().enumerate() {
16797 if i > 0 {
16798 self.write(", ");
16799 }
16800 self.generate_ordered(ordered)?;
16801 }
16802 has_content = true;
16803 }
16804
16805 if let Some(frame) = &over.frame {
16807 if has_content {
16808 self.write_space();
16809 }
16810 self.generate_window_frame(frame)?;
16811 }
16812
16813 Ok(())
16814 }
16815
16816 fn generate_window_frame(&mut self, frame: &WindowFrame) -> Result<()> {
16817 let lowercase_frame = self.config.lowercase_window_frame_keywords;
16819
16820 if !lowercase_frame {
16822 if let Some(kind_text) = &frame.kind_text {
16823 self.write(kind_text);
16824 } else {
16825 match frame.kind {
16826 WindowFrameKind::Rows => self.write_keyword("ROWS"),
16827 WindowFrameKind::Range => self.write_keyword("RANGE"),
16828 WindowFrameKind::Groups => self.write_keyword("GROUPS"),
16829 }
16830 }
16831 } else {
16832 match frame.kind {
16833 WindowFrameKind::Rows => self.write("rows"),
16834 WindowFrameKind::Range => self.write("range"),
16835 WindowFrameKind::Groups => self.write("groups"),
16836 }
16837 }
16838
16839 self.write_space();
16842 let should_normalize = self.config.normalize_window_frame_between
16843 && frame.end.is_none()
16844 && matches!(
16845 frame.start,
16846 WindowFrameBound::Preceding(_)
16847 | WindowFrameBound::Following(_)
16848 | WindowFrameBound::UnboundedPreceding
16849 | WindowFrameBound::UnboundedFollowing
16850 );
16851
16852 if let Some(end) = &frame.end {
16853 self.write_keyword("BETWEEN");
16855 self.write_space();
16856 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
16857 self.write_space();
16858 self.write_keyword("AND");
16859 self.write_space();
16860 self.generate_window_frame_bound(end, frame.end_side_text.as_deref())?;
16861 } else if should_normalize {
16862 self.write_keyword("BETWEEN");
16864 self.write_space();
16865 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
16866 self.write_space();
16867 self.write_keyword("AND");
16868 self.write_space();
16869 self.write_keyword("CURRENT ROW");
16870 } else {
16871 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
16873 }
16874
16875 if let Some(exclude) = &frame.exclude {
16877 self.write_space();
16878 self.write_keyword("EXCLUDE");
16879 self.write_space();
16880 match exclude {
16881 WindowFrameExclude::CurrentRow => self.write_keyword("CURRENT ROW"),
16882 WindowFrameExclude::Group => self.write_keyword("GROUP"),
16883 WindowFrameExclude::Ties => self.write_keyword("TIES"),
16884 WindowFrameExclude::NoOthers => self.write_keyword("NO OTHERS"),
16885 }
16886 }
16887
16888 Ok(())
16889 }
16890
16891 fn generate_window_frame_bound(
16892 &mut self,
16893 bound: &WindowFrameBound,
16894 side_text: Option<&str>,
16895 ) -> Result<()> {
16896 let lowercase_frame = self.config.lowercase_window_frame_keywords;
16898
16899 match bound {
16900 WindowFrameBound::CurrentRow => {
16901 self.write_keyword("CURRENT ROW");
16902 }
16903 WindowFrameBound::UnboundedPreceding => {
16904 self.write_keyword("UNBOUNDED");
16905 self.write_space();
16906 if lowercase_frame {
16907 self.write("preceding");
16908 } else if let Some(text) = side_text {
16909 self.write(text);
16910 } else {
16911 self.write_keyword("PRECEDING");
16912 }
16913 }
16914 WindowFrameBound::UnboundedFollowing => {
16915 self.write_keyword("UNBOUNDED");
16916 self.write_space();
16917 if lowercase_frame {
16918 self.write("following");
16919 } else if let Some(text) = side_text {
16920 self.write(text);
16921 } else {
16922 self.write_keyword("FOLLOWING");
16923 }
16924 }
16925 WindowFrameBound::Preceding(expr) => {
16926 self.generate_expression(expr)?;
16927 self.write_space();
16928 if lowercase_frame {
16929 self.write("preceding");
16930 } else if let Some(text) = side_text {
16931 self.write(text);
16932 } else {
16933 self.write_keyword("PRECEDING");
16934 }
16935 }
16936 WindowFrameBound::Following(expr) => {
16937 self.generate_expression(expr)?;
16938 self.write_space();
16939 if lowercase_frame {
16940 self.write("following");
16941 } else if let Some(text) = side_text {
16942 self.write(text);
16943 } else {
16944 self.write_keyword("FOLLOWING");
16945 }
16946 }
16947 WindowFrameBound::BarePreceding => {
16948 if lowercase_frame {
16949 self.write("preceding");
16950 } else if let Some(text) = side_text {
16951 self.write(text);
16952 } else {
16953 self.write_keyword("PRECEDING");
16954 }
16955 }
16956 WindowFrameBound::BareFollowing => {
16957 if lowercase_frame {
16958 self.write("following");
16959 } else if let Some(text) = side_text {
16960 self.write(text);
16961 } else {
16962 self.write_keyword("FOLLOWING");
16963 }
16964 }
16965 WindowFrameBound::Value(expr) => {
16966 self.generate_expression(expr)?;
16968 }
16969 }
16970 Ok(())
16971 }
16972
16973 fn generate_interval(&mut self, interval: &Interval) -> Result<()> {
16974 let skip_interval_keyword = matches!(self.config.dialect, Some(DialectType::Oracle))
16977 && matches!(&interval.unit, Some(IntervalUnitSpec::ExprSpan(_)))
16978 && !matches!(&interval.this, Some(Expression::Literal(_)));
16979
16980 if self.config.single_string_interval {
16983 if let (
16984 Some(Expression::Literal(Literal::String(ref val))),
16985 Some(IntervalUnitSpec::Simple {
16986 ref unit,
16987 ref use_plural,
16988 }),
16989 ) = (&interval.this, &interval.unit)
16990 {
16991 self.write_keyword("INTERVAL");
16992 self.write_space();
16993 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
16994 let unit_str = self.interval_unit_str(unit, effective_plural);
16995 self.write("'");
16996 self.write(val);
16997 self.write(" ");
16998 self.write(&unit_str);
16999 self.write("'");
17000 return Ok(());
17001 }
17002 }
17003
17004 if !skip_interval_keyword {
17005 self.write_keyword("INTERVAL");
17006 }
17007
17008 if let Some(ref value) = interval.this {
17010 if !skip_interval_keyword {
17011 self.write_space();
17012 }
17013 let needs_parens = interval.unit.is_some()
17017 && matches!(
17018 value,
17019 Expression::Add(_)
17020 | Expression::Sub(_)
17021 | Expression::Mul(_)
17022 | Expression::Div(_)
17023 | Expression::Mod(_)
17024 | Expression::BitwiseAnd(_)
17025 | Expression::BitwiseOr(_)
17026 | Expression::BitwiseXor(_)
17027 );
17028 if needs_parens {
17029 self.write("(");
17030 }
17031 self.generate_expression(value)?;
17032 if needs_parens {
17033 self.write(")");
17034 }
17035 }
17036
17037 if let Some(ref unit_spec) = interval.unit {
17039 self.write_space();
17040 self.write_interval_unit_spec(unit_spec)?;
17041 }
17042
17043 Ok(())
17044 }
17045
17046 fn interval_unit_str(&self, unit: &IntervalUnit, use_plural: bool) -> &'static str {
17048 match (unit, use_plural) {
17049 (IntervalUnit::Year, false) => "YEAR",
17050 (IntervalUnit::Year, true) => "YEARS",
17051 (IntervalUnit::Quarter, false) => "QUARTER",
17052 (IntervalUnit::Quarter, true) => "QUARTERS",
17053 (IntervalUnit::Month, false) => "MONTH",
17054 (IntervalUnit::Month, true) => "MONTHS",
17055 (IntervalUnit::Week, false) => "WEEK",
17056 (IntervalUnit::Week, true) => "WEEKS",
17057 (IntervalUnit::Day, false) => "DAY",
17058 (IntervalUnit::Day, true) => "DAYS",
17059 (IntervalUnit::Hour, false) => "HOUR",
17060 (IntervalUnit::Hour, true) => "HOURS",
17061 (IntervalUnit::Minute, false) => "MINUTE",
17062 (IntervalUnit::Minute, true) => "MINUTES",
17063 (IntervalUnit::Second, false) => "SECOND",
17064 (IntervalUnit::Second, true) => "SECONDS",
17065 (IntervalUnit::Millisecond, false) => "MILLISECOND",
17066 (IntervalUnit::Millisecond, true) => "MILLISECONDS",
17067 (IntervalUnit::Microsecond, false) => "MICROSECOND",
17068 (IntervalUnit::Microsecond, true) => "MICROSECONDS",
17069 (IntervalUnit::Nanosecond, false) => "NANOSECOND",
17070 (IntervalUnit::Nanosecond, true) => "NANOSECONDS",
17071 }
17072 }
17073
17074 fn write_interval_unit_spec(&mut self, unit_spec: &IntervalUnitSpec) -> Result<()> {
17075 match unit_spec {
17076 IntervalUnitSpec::Simple { unit, use_plural } => {
17077 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
17079 self.write_simple_interval_unit(unit, effective_plural);
17080 }
17081 IntervalUnitSpec::Span(span) => {
17082 self.write_simple_interval_unit(&span.this, false);
17083 self.write_space();
17084 self.write_keyword("TO");
17085 self.write_space();
17086 self.write_simple_interval_unit(&span.expression, false);
17087 }
17088 IntervalUnitSpec::ExprSpan(span) => {
17089 self.generate_expression(&span.this)?;
17091 self.write_space();
17092 self.write_keyword("TO");
17093 self.write_space();
17094 self.generate_expression(&span.expression)?;
17095 }
17096 IntervalUnitSpec::Expr(expr) => {
17097 self.generate_expression(expr)?;
17098 }
17099 }
17100 Ok(())
17101 }
17102
17103 fn write_simple_interval_unit(&mut self, unit: &IntervalUnit, use_plural: bool) {
17104 match (unit, use_plural) {
17106 (IntervalUnit::Year, false) => self.write_keyword("YEAR"),
17107 (IntervalUnit::Year, true) => self.write_keyword("YEARS"),
17108 (IntervalUnit::Quarter, false) => self.write_keyword("QUARTER"),
17109 (IntervalUnit::Quarter, true) => self.write_keyword("QUARTERS"),
17110 (IntervalUnit::Month, false) => self.write_keyword("MONTH"),
17111 (IntervalUnit::Month, true) => self.write_keyword("MONTHS"),
17112 (IntervalUnit::Week, false) => self.write_keyword("WEEK"),
17113 (IntervalUnit::Week, true) => self.write_keyword("WEEKS"),
17114 (IntervalUnit::Day, false) => self.write_keyword("DAY"),
17115 (IntervalUnit::Day, true) => self.write_keyword("DAYS"),
17116 (IntervalUnit::Hour, false) => self.write_keyword("HOUR"),
17117 (IntervalUnit::Hour, true) => self.write_keyword("HOURS"),
17118 (IntervalUnit::Minute, false) => self.write_keyword("MINUTE"),
17119 (IntervalUnit::Minute, true) => self.write_keyword("MINUTES"),
17120 (IntervalUnit::Second, false) => self.write_keyword("SECOND"),
17121 (IntervalUnit::Second, true) => self.write_keyword("SECONDS"),
17122 (IntervalUnit::Millisecond, false) => self.write_keyword("MILLISECOND"),
17123 (IntervalUnit::Millisecond, true) => self.write_keyword("MILLISECONDS"),
17124 (IntervalUnit::Microsecond, false) => self.write_keyword("MICROSECOND"),
17125 (IntervalUnit::Microsecond, true) => self.write_keyword("MICROSECONDS"),
17126 (IntervalUnit::Nanosecond, false) => self.write_keyword("NANOSECOND"),
17127 (IntervalUnit::Nanosecond, true) => self.write_keyword("NANOSECONDS"),
17128 }
17129 }
17130
17131 fn write_redshift_date_part(&mut self, expr: &Expression) {
17134 let part_str = self.extract_date_part_string(expr);
17135 if let Some(part) = part_str {
17136 let normalized = self.normalize_date_part(&part);
17137 self.write_keyword(&normalized);
17138 } else {
17139 let _ = self.generate_expression(expr);
17141 }
17142 }
17143
17144 fn write_redshift_date_part_quoted(&mut self, expr: &Expression) {
17147 let part_str = self.extract_date_part_string(expr);
17148 if let Some(part) = part_str {
17149 let normalized = self.normalize_date_part(&part);
17150 self.write("'");
17151 self.write(&normalized);
17152 self.write("'");
17153 } else {
17154 let _ = self.generate_expression(expr);
17156 }
17157 }
17158
17159 fn extract_date_part_string(&self, expr: &Expression) -> Option<String> {
17161 match expr {
17162 Expression::Literal(crate::expressions::Literal::String(s)) => Some(s.clone()),
17163 Expression::Identifier(id) => Some(id.name.clone()),
17164 Expression::Column(col) if col.table.is_none() => {
17165 Some(col.name.name.clone())
17167 }
17168 _ => None,
17169 }
17170 }
17171
17172 fn normalize_date_part(&self, part: &str) -> String {
17175 let lower = part.to_lowercase();
17176 match lower.as_str() {
17177 "day" | "days" | "d" => "DAY".to_string(),
17178 "month" | "months" | "mon" | "mm" => "MONTH".to_string(),
17179 "year" | "years" | "y" | "yy" | "yyyy" => "YEAR".to_string(),
17180 "week" | "weeks" | "w" | "wk" => "WEEK".to_string(),
17181 "hour" | "hours" | "h" | "hh" => "HOUR".to_string(),
17182 "minute" | "minutes" | "m" | "mi" | "n" => "MINUTE".to_string(),
17183 "second" | "seconds" | "s" | "ss" => "SECOND".to_string(),
17184 "millisecond" | "milliseconds" | "ms" => "MILLISECOND".to_string(),
17185 "microsecond" | "microseconds" | "us" => "MICROSECOND".to_string(),
17186 "quarter" | "quarters" | "q" | "qq" => "QUARTER".to_string(),
17187 _ => part.to_uppercase(),
17188 }
17189 }
17190
17191 fn write_datetime_field(&mut self, field: &DateTimeField) {
17192 match field {
17193 DateTimeField::Year => self.write_keyword("YEAR"),
17194 DateTimeField::Month => self.write_keyword("MONTH"),
17195 DateTimeField::Day => self.write_keyword("DAY"),
17196 DateTimeField::Hour => self.write_keyword("HOUR"),
17197 DateTimeField::Minute => self.write_keyword("MINUTE"),
17198 DateTimeField::Second => self.write_keyword("SECOND"),
17199 DateTimeField::Millisecond => self.write_keyword("MILLISECOND"),
17200 DateTimeField::Microsecond => self.write_keyword("MICROSECOND"),
17201 DateTimeField::DayOfWeek => {
17202 let name = match self.config.dialect {
17203 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFWEEK",
17204 _ => "DOW",
17205 };
17206 self.write_keyword(name);
17207 }
17208 DateTimeField::DayOfYear => {
17209 let name = match self.config.dialect {
17210 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFYEAR",
17211 _ => "DOY",
17212 };
17213 self.write_keyword(name);
17214 }
17215 DateTimeField::Week => self.write_keyword("WEEK"),
17216 DateTimeField::WeekWithModifier(modifier) => {
17217 self.write_keyword("WEEK");
17218 self.write("(");
17219 self.write(modifier);
17220 self.write(")");
17221 }
17222 DateTimeField::Quarter => self.write_keyword("QUARTER"),
17223 DateTimeField::Epoch => self.write_keyword("EPOCH"),
17224 DateTimeField::Timezone => self.write_keyword("TIMEZONE"),
17225 DateTimeField::TimezoneHour => self.write_keyword("TIMEZONE_HOUR"),
17226 DateTimeField::TimezoneMinute => self.write_keyword("TIMEZONE_MINUTE"),
17227 DateTimeField::Date => self.write_keyword("DATE"),
17228 DateTimeField::Time => self.write_keyword("TIME"),
17229 DateTimeField::Custom(name) => self.write(name),
17230 }
17231 }
17232
17233 fn write_datetime_field_lower(&mut self, field: &DateTimeField) {
17235 match field {
17236 DateTimeField::Year => self.write("year"),
17237 DateTimeField::Month => self.write("month"),
17238 DateTimeField::Day => self.write("day"),
17239 DateTimeField::Hour => self.write("hour"),
17240 DateTimeField::Minute => self.write("minute"),
17241 DateTimeField::Second => self.write("second"),
17242 DateTimeField::Millisecond => self.write("millisecond"),
17243 DateTimeField::Microsecond => self.write("microsecond"),
17244 DateTimeField::DayOfWeek => self.write("dow"),
17245 DateTimeField::DayOfYear => self.write("doy"),
17246 DateTimeField::Week => self.write("week"),
17247 DateTimeField::WeekWithModifier(modifier) => {
17248 self.write("week(");
17249 self.write(modifier);
17250 self.write(")");
17251 }
17252 DateTimeField::Quarter => self.write("quarter"),
17253 DateTimeField::Epoch => self.write("epoch"),
17254 DateTimeField::Timezone => self.write("timezone"),
17255 DateTimeField::TimezoneHour => self.write("timezone_hour"),
17256 DateTimeField::TimezoneMinute => self.write("timezone_minute"),
17257 DateTimeField::Date => self.write("date"),
17258 DateTimeField::Time => self.write("time"),
17259 DateTimeField::Custom(name) => self.write(name),
17260 }
17261 }
17262
17263 fn generate_simple_func(&mut self, name: &str, arg: &Expression) -> Result<()> {
17266 self.write_keyword(name);
17267 self.write("(");
17268 self.generate_expression(arg)?;
17269 self.write(")");
17270 Ok(())
17271 }
17272
17273 fn generate_unary_func(
17275 &mut self,
17276 default_name: &str,
17277 f: &crate::expressions::UnaryFunc,
17278 ) -> Result<()> {
17279 let name = f.original_name.as_deref().unwrap_or(default_name);
17280 self.write_keyword(name);
17281 self.write("(");
17282 self.generate_expression(&f.this)?;
17283 self.write(")");
17284 Ok(())
17285 }
17286
17287 fn generate_sqrt_cbrt(
17289 &mut self,
17290 f: &crate::expressions::UnaryFunc,
17291 func_name: &str,
17292 _op: &str,
17293 ) -> Result<()> {
17294 self.write_keyword(func_name);
17297 self.write("(");
17298 self.generate_expression(&f.this)?;
17299 self.write(")");
17300 Ok(())
17301 }
17302
17303 fn generate_binary_func(
17304 &mut self,
17305 name: &str,
17306 arg1: &Expression,
17307 arg2: &Expression,
17308 ) -> Result<()> {
17309 self.write_keyword(name);
17310 self.write("(");
17311 self.generate_expression(arg1)?;
17312 self.write(", ");
17313 self.generate_expression(arg2)?;
17314 self.write(")");
17315 Ok(())
17316 }
17317
17318 fn generate_char_func(&mut self, f: &crate::expressions::CharFunc) -> Result<()> {
17322 let func_name = f.name.as_deref().unwrap_or("CHAR");
17324 self.write_keyword(func_name);
17325 self.write("(");
17326 for (i, arg) in f.args.iter().enumerate() {
17327 if i > 0 {
17328 self.write(", ");
17329 }
17330 self.generate_expression(arg)?;
17331 }
17332 if let Some(ref charset) = f.charset {
17333 self.write(" ");
17334 self.write_keyword("USING");
17335 self.write(" ");
17336 self.write(charset);
17337 }
17338 self.write(")");
17339 Ok(())
17340 }
17341
17342 fn generate_power(&mut self, f: &BinaryFunc) -> Result<()> {
17343 use crate::dialects::DialectType;
17344
17345 match self.config.dialect {
17346 Some(DialectType::Teradata) => {
17347 self.generate_expression(&f.this)?;
17349 self.write(" ** ");
17350 self.generate_expression(&f.expression)?;
17351 Ok(())
17352 }
17353 _ => {
17354 self.generate_binary_func("POWER", &f.this, &f.expression)
17356 }
17357 }
17358 }
17359
17360 fn generate_vararg_func(&mut self, name: &str, args: &[Expression]) -> Result<()> {
17361 self.write_func_name(name);
17362 self.write("(");
17363 for (i, arg) in args.iter().enumerate() {
17364 if i > 0 {
17365 self.write(", ");
17366 }
17367 self.generate_expression(arg)?;
17368 }
17369 self.write(")");
17370 Ok(())
17371 }
17372
17373 fn generate_concat_ws(&mut self, f: &ConcatWs) -> Result<()> {
17376 self.write_keyword("CONCAT_WS");
17377 self.write("(");
17378 self.generate_expression(&f.separator)?;
17379 for expr in &f.expressions {
17380 self.write(", ");
17381 self.generate_expression(expr)?;
17382 }
17383 self.write(")");
17384 Ok(())
17385 }
17386
17387 fn generate_substring(&mut self, f: &SubstringFunc) -> Result<()> {
17388 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
17390 if is_oracle {
17391 self.write_keyword("SUBSTR");
17392 } else {
17393 self.write_keyword("SUBSTRING");
17394 }
17395 self.write("(");
17396 self.generate_expression(&f.this)?;
17397 let force_from_for = matches!(self.config.dialect, Some(DialectType::PostgreSQL));
17399 let use_comma_syntax = matches!(
17401 self.config.dialect,
17402 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
17403 );
17404 if (f.from_for_syntax || force_from_for) && !use_comma_syntax {
17405 self.write_space();
17407 self.write_keyword("FROM");
17408 self.write_space();
17409 self.generate_expression(&f.start)?;
17410 if let Some(length) = &f.length {
17411 self.write_space();
17412 self.write_keyword("FOR");
17413 self.write_space();
17414 self.generate_expression(length)?;
17415 }
17416 } else {
17417 self.write(", ");
17419 self.generate_expression(&f.start)?;
17420 if let Some(length) = &f.length {
17421 self.write(", ");
17422 self.generate_expression(length)?;
17423 }
17424 }
17425 self.write(")");
17426 Ok(())
17427 }
17428
17429 fn generate_overlay(&mut self, f: &OverlayFunc) -> Result<()> {
17430 self.write_keyword("OVERLAY");
17431 self.write("(");
17432 self.generate_expression(&f.this)?;
17433 self.write_space();
17434 self.write_keyword("PLACING");
17435 self.write_space();
17436 self.generate_expression(&f.replacement)?;
17437 self.write_space();
17438 self.write_keyword("FROM");
17439 self.write_space();
17440 self.generate_expression(&f.from)?;
17441 if let Some(length) = &f.length {
17442 self.write_space();
17443 self.write_keyword("FOR");
17444 self.write_space();
17445 self.generate_expression(length)?;
17446 }
17447 self.write(")");
17448 Ok(())
17449 }
17450
17451 fn generate_trim(&mut self, f: &TrimFunc) -> Result<()> {
17452 if f.position_explicit && f.characters.is_none() {
17455 match f.position {
17456 TrimPosition::Leading => {
17457 self.write_keyword("LTRIM");
17458 self.write("(");
17459 self.generate_expression(&f.this)?;
17460 self.write(")");
17461 return Ok(());
17462 }
17463 TrimPosition::Trailing => {
17464 self.write_keyword("RTRIM");
17465 self.write("(");
17466 self.generate_expression(&f.this)?;
17467 self.write(")");
17468 return Ok(());
17469 }
17470 TrimPosition::Both => {
17471 }
17474 }
17475 }
17476
17477 self.write_keyword("TRIM");
17478 self.write("(");
17479 let force_standard = f.characters.is_some()
17482 && !f.sql_standard_syntax
17483 && matches!(
17484 self.config.dialect,
17485 Some(DialectType::Hive)
17486 | Some(DialectType::Spark)
17487 | Some(DialectType::Databricks)
17488 | Some(DialectType::ClickHouse)
17489 );
17490 let use_standard = (f.sql_standard_syntax || force_standard)
17491 && !(f.position_explicit
17492 && f.characters.is_none()
17493 && matches!(f.position, TrimPosition::Both));
17494 if use_standard {
17495 if f.position_explicit {
17498 match f.position {
17499 TrimPosition::Both => self.write_keyword("BOTH"),
17500 TrimPosition::Leading => self.write_keyword("LEADING"),
17501 TrimPosition::Trailing => self.write_keyword("TRAILING"),
17502 }
17503 self.write_space();
17504 }
17505 if let Some(chars) = &f.characters {
17506 self.generate_expression(chars)?;
17507 self.write_space();
17508 }
17509 self.write_keyword("FROM");
17510 self.write_space();
17511 self.generate_expression(&f.this)?;
17512 } else {
17513 self.generate_expression(&f.this)?;
17515 if let Some(chars) = &f.characters {
17516 self.write(", ");
17517 self.generate_expression(chars)?;
17518 }
17519 }
17520 self.write(")");
17521 Ok(())
17522 }
17523
17524 fn generate_replace(&mut self, f: &ReplaceFunc) -> Result<()> {
17525 self.write_keyword("REPLACE");
17526 self.write("(");
17527 self.generate_expression(&f.this)?;
17528 self.write(", ");
17529 self.generate_expression(&f.old)?;
17530 self.write(", ");
17531 self.generate_expression(&f.new)?;
17532 self.write(")");
17533 Ok(())
17534 }
17535
17536 fn generate_left_right(&mut self, name: &str, f: &LeftRightFunc) -> Result<()> {
17537 self.write_keyword(name);
17538 self.write("(");
17539 self.generate_expression(&f.this)?;
17540 self.write(", ");
17541 self.generate_expression(&f.length)?;
17542 self.write(")");
17543 Ok(())
17544 }
17545
17546 fn generate_repeat(&mut self, f: &RepeatFunc) -> Result<()> {
17547 self.write_keyword("REPEAT");
17548 self.write("(");
17549 self.generate_expression(&f.this)?;
17550 self.write(", ");
17551 self.generate_expression(&f.times)?;
17552 self.write(")");
17553 Ok(())
17554 }
17555
17556 fn generate_pad(&mut self, name: &str, f: &PadFunc) -> Result<()> {
17557 self.write_keyword(name);
17558 self.write("(");
17559 self.generate_expression(&f.this)?;
17560 self.write(", ");
17561 self.generate_expression(&f.length)?;
17562 if let Some(fill) = &f.fill {
17563 self.write(", ");
17564 self.generate_expression(fill)?;
17565 }
17566 self.write(")");
17567 Ok(())
17568 }
17569
17570 fn generate_split(&mut self, f: &SplitFunc) -> Result<()> {
17571 self.write_keyword("SPLIT");
17572 self.write("(");
17573 self.generate_expression(&f.this)?;
17574 self.write(", ");
17575 self.generate_expression(&f.delimiter)?;
17576 self.write(")");
17577 Ok(())
17578 }
17579
17580 fn generate_regexp_like(&mut self, f: &RegexpFunc) -> Result<()> {
17581 use crate::dialects::DialectType;
17582 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) && f.flags.is_none() {
17584 self.generate_expression(&f.this)?;
17585 self.write(" ~ ");
17586 self.generate_expression(&f.pattern)?;
17587 } else if matches!(
17588 self.config.dialect,
17589 Some(DialectType::SingleStore)
17590 | Some(DialectType::Spark)
17591 | Some(DialectType::Hive)
17592 | Some(DialectType::Databricks)
17593 ) && f.flags.is_none()
17594 {
17595 self.generate_expression(&f.this)?;
17597 self.write_keyword(" RLIKE ");
17598 self.generate_expression(&f.pattern)?;
17599 } else if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
17600 self.write_keyword("REGEXP");
17602 self.write("(");
17603 self.generate_expression(&f.this)?;
17604 self.write(", ");
17605 self.generate_expression(&f.pattern)?;
17606 if let Some(flags) = &f.flags {
17607 self.write(", ");
17608 self.generate_expression(flags)?;
17609 }
17610 self.write(")");
17611 } else {
17612 self.write_keyword("REGEXP_LIKE");
17613 self.write("(");
17614 self.generate_expression(&f.this)?;
17615 self.write(", ");
17616 self.generate_expression(&f.pattern)?;
17617 if let Some(flags) = &f.flags {
17618 self.write(", ");
17619 self.generate_expression(flags)?;
17620 }
17621 self.write(")");
17622 }
17623 Ok(())
17624 }
17625
17626 fn generate_regexp_replace(&mut self, f: &RegexpReplaceFunc) -> Result<()> {
17627 self.write_keyword("REGEXP_REPLACE");
17628 self.write("(");
17629 self.generate_expression(&f.this)?;
17630 self.write(", ");
17631 self.generate_expression(&f.pattern)?;
17632 self.write(", ");
17633 self.generate_expression(&f.replacement)?;
17634 if let Some(flags) = &f.flags {
17635 self.write(", ");
17636 self.generate_expression(flags)?;
17637 }
17638 self.write(")");
17639 Ok(())
17640 }
17641
17642 fn generate_regexp_extract(&mut self, f: &RegexpExtractFunc) -> Result<()> {
17643 self.write_keyword("REGEXP_EXTRACT");
17644 self.write("(");
17645 self.generate_expression(&f.this)?;
17646 self.write(", ");
17647 self.generate_expression(&f.pattern)?;
17648 if let Some(group) = &f.group {
17649 self.write(", ");
17650 self.generate_expression(group)?;
17651 }
17652 self.write(")");
17653 Ok(())
17654 }
17655
17656 fn generate_round(&mut self, f: &RoundFunc) -> Result<()> {
17659 self.write_keyword("ROUND");
17660 self.write("(");
17661 self.generate_expression(&f.this)?;
17662 if let Some(decimals) = &f.decimals {
17663 self.write(", ");
17664 self.generate_expression(decimals)?;
17665 }
17666 self.write(")");
17667 Ok(())
17668 }
17669
17670 fn generate_floor(&mut self, f: &FloorFunc) -> Result<()> {
17671 self.write_keyword("FLOOR");
17672 self.write("(");
17673 self.generate_expression(&f.this)?;
17674 if let Some(to) = &f.to {
17676 self.write(" ");
17677 self.write_keyword("TO");
17678 self.write(" ");
17679 self.generate_expression(to)?;
17680 } else if let Some(scale) = &f.scale {
17681 self.write(", ");
17682 self.generate_expression(scale)?;
17683 }
17684 self.write(")");
17685 Ok(())
17686 }
17687
17688 fn generate_ceil(&mut self, f: &CeilFunc) -> Result<()> {
17689 self.write_keyword("CEIL");
17690 self.write("(");
17691 self.generate_expression(&f.this)?;
17692 if let Some(to) = &f.to {
17694 self.write(" ");
17695 self.write_keyword("TO");
17696 self.write(" ");
17697 self.generate_expression(to)?;
17698 } else if let Some(decimals) = &f.decimals {
17699 self.write(", ");
17700 self.generate_expression(decimals)?;
17701 }
17702 self.write(")");
17703 Ok(())
17704 }
17705
17706 fn generate_log(&mut self, f: &LogFunc) -> Result<()> {
17707 use crate::expressions::Literal;
17708
17709 if let Some(base) = &f.base {
17710 if self.is_log_base_none() {
17713 if matches!(base, Expression::Literal(Literal::Number(s)) if s == "2") {
17714 self.write_func_name("LOG2");
17715 self.write("(");
17716 self.generate_expression(&f.this)?;
17717 self.write(")");
17718 return Ok(());
17719 } else if matches!(base, Expression::Literal(Literal::Number(s)) if s == "10") {
17720 self.write_func_name("LOG10");
17721 self.write("(");
17722 self.generate_expression(&f.this)?;
17723 self.write(")");
17724 return Ok(());
17725 }
17726 }
17728
17729 self.write_func_name("LOG");
17730 self.write("(");
17731 if self.is_log_value_first() {
17732 self.generate_expression(&f.this)?;
17734 self.write(", ");
17735 self.generate_expression(base)?;
17736 } else {
17737 self.generate_expression(base)?;
17739 self.write(", ");
17740 self.generate_expression(&f.this)?;
17741 }
17742 self.write(")");
17743 } else {
17744 self.write_func_name("LOG");
17746 self.write("(");
17747 self.generate_expression(&f.this)?;
17748 self.write(")");
17749 }
17750 Ok(())
17751 }
17752
17753 fn is_log_value_first(&self) -> bool {
17756 use crate::dialects::DialectType;
17757 matches!(
17758 self.config.dialect,
17759 Some(DialectType::BigQuery)
17760 | Some(DialectType::TSQL)
17761 | Some(DialectType::Tableau)
17762 | Some(DialectType::Fabric)
17763 )
17764 }
17765
17766 fn is_log_base_none(&self) -> bool {
17769 use crate::dialects::DialectType;
17770 matches!(
17771 self.config.dialect,
17772 Some(DialectType::Presto)
17773 | Some(DialectType::Trino)
17774 | Some(DialectType::ClickHouse)
17775 | Some(DialectType::Athena)
17776 )
17777 }
17778
17779 fn generate_current_time(&mut self, f: &CurrentTime) -> Result<()> {
17782 self.write_keyword("CURRENT_TIME");
17783 if let Some(precision) = f.precision {
17784 self.write(&format!("({})", precision));
17785 }
17786 Ok(())
17787 }
17788
17789 fn generate_current_timestamp(&mut self, f: &CurrentTimestamp) -> Result<()> {
17790 use crate::dialects::DialectType;
17791
17792 if f.sysdate {
17794 match self.config.dialect {
17795 Some(DialectType::Oracle) | Some(DialectType::Redshift) => {
17796 self.write_keyword("SYSDATE");
17797 return Ok(());
17798 }
17799 Some(DialectType::Snowflake) => {
17800 self.write_keyword("SYSDATE");
17802 self.write("()");
17803 return Ok(());
17804 }
17805 _ => {
17806 }
17808 }
17809 }
17810
17811 self.write_keyword("CURRENT_TIMESTAMP");
17812 if let Some(precision) = f.precision {
17814 self.write(&format!("({})", precision));
17815 } else if matches!(
17816 self.config.dialect,
17817 Some(crate::dialects::DialectType::MySQL)
17818 | Some(crate::dialects::DialectType::SingleStore)
17819 | Some(crate::dialects::DialectType::TiDB)
17820 | Some(crate::dialects::DialectType::Spark)
17821 | Some(crate::dialects::DialectType::Hive)
17822 | Some(crate::dialects::DialectType::Databricks)
17823 | Some(crate::dialects::DialectType::ClickHouse)
17824 | Some(crate::dialects::DialectType::BigQuery)
17825 | Some(crate::dialects::DialectType::Snowflake)
17826 ) {
17827 self.write("()");
17828 }
17829 Ok(())
17830 }
17831
17832 fn generate_at_time_zone(&mut self, f: &AtTimeZone) -> Result<()> {
17833 if self.config.dialect == Some(DialectType::Exasol) {
17835 self.write_keyword("CONVERT_TZ");
17836 self.write("(");
17837 self.generate_expression(&f.this)?;
17838 self.write(", 'UTC', ");
17839 self.generate_expression(&f.zone)?;
17840 self.write(")");
17841 return Ok(());
17842 }
17843
17844 self.generate_expression(&f.this)?;
17845 self.write_space();
17846 self.write_keyword("AT TIME ZONE");
17847 self.write_space();
17848 self.generate_expression(&f.zone)?;
17849 Ok(())
17850 }
17851
17852 fn generate_date_add(&mut self, f: &DateAddFunc, name: &str) -> Result<()> {
17853 use crate::dialects::DialectType;
17854
17855 let is_presto_like = matches!(
17858 self.config.dialect,
17859 Some(DialectType::Presto) | Some(DialectType::Trino)
17860 );
17861
17862 if is_presto_like {
17863 self.write_keyword(name);
17864 self.write("(");
17865 self.write("'");
17867 self.write_simple_interval_unit(&f.unit, false);
17868 self.write("'");
17869 self.write(", ");
17870 let needs_cast = !self.returns_integer_type(&f.interval);
17872 if needs_cast {
17873 self.write_keyword("CAST");
17874 self.write("(");
17875 }
17876 self.generate_expression(&f.interval)?;
17877 if needs_cast {
17878 self.write_space();
17879 self.write_keyword("AS");
17880 self.write_space();
17881 self.write_keyword("BIGINT");
17882 self.write(")");
17883 }
17884 self.write(", ");
17885 self.generate_expression(&f.this)?;
17886 self.write(")");
17887 } else {
17888 self.write_keyword(name);
17889 self.write("(");
17890 self.generate_expression(&f.this)?;
17891 self.write(", ");
17892 self.write_keyword("INTERVAL");
17893 self.write_space();
17894 self.generate_expression(&f.interval)?;
17895 self.write_space();
17896 self.write_simple_interval_unit(&f.unit, false); self.write(")");
17898 }
17899 Ok(())
17900 }
17901
17902 fn returns_integer_type(&self, expr: &Expression) -> bool {
17905 use crate::expressions::{DataType, Literal};
17906 match expr {
17907 Expression::Literal(Literal::Number(n)) => !n.contains('.'),
17909
17910 Expression::Floor(f) => self.returns_integer_type(&f.this),
17912
17913 Expression::Round(f) => {
17915 f.decimals.is_none() && self.returns_integer_type(&f.this)
17917 }
17918
17919 Expression::Sign(f) => self.returns_integer_type(&f.this),
17921
17922 Expression::Abs(f) => self.returns_integer_type(&f.this),
17924
17925 Expression::Mul(op) => {
17927 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
17928 }
17929 Expression::Add(op) => {
17930 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
17931 }
17932 Expression::Sub(op) => {
17933 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
17934 }
17935 Expression::Mod(op) => self.returns_integer_type(&op.left),
17936
17937 Expression::Cast(c) => matches!(
17939 &c.to,
17940 DataType::BigInt { .. }
17941 | DataType::Int { .. }
17942 | DataType::SmallInt { .. }
17943 | DataType::TinyInt { .. }
17944 ),
17945
17946 Expression::Neg(op) => self.returns_integer_type(&op.this),
17948
17949 Expression::Paren(p) => self.returns_integer_type(&p.this),
17951
17952 _ => false,
17955 }
17956 }
17957
17958 fn generate_datediff(&mut self, f: &DateDiffFunc) -> Result<()> {
17959 self.write_keyword("DATEDIFF");
17960 self.write("(");
17961 if let Some(unit) = &f.unit {
17962 self.write_simple_interval_unit(unit, false); self.write(", ");
17964 }
17965 self.generate_expression(&f.this)?;
17966 self.write(", ");
17967 self.generate_expression(&f.expression)?;
17968 self.write(")");
17969 Ok(())
17970 }
17971
17972 fn generate_date_trunc(&mut self, f: &DateTruncFunc) -> Result<()> {
17973 self.write_keyword("DATE_TRUNC");
17974 self.write("('");
17975 self.write_datetime_field(&f.unit);
17976 self.write("', ");
17977 self.generate_expression(&f.this)?;
17978 self.write(")");
17979 Ok(())
17980 }
17981
17982 fn generate_last_day(&mut self, f: &LastDayFunc) -> Result<()> {
17983 use crate::dialects::DialectType;
17984 use crate::expressions::DateTimeField;
17985
17986 self.write_keyword("LAST_DAY");
17987 self.write("(");
17988 self.generate_expression(&f.this)?;
17989 if let Some(unit) = &f.unit {
17990 self.write(", ");
17991 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
17994 if let DateTimeField::WeekWithModifier(_) = unit {
17995 self.write_keyword("WEEK");
17996 } else {
17997 self.write_datetime_field(unit);
17998 }
17999 } else {
18000 self.write_datetime_field(unit);
18001 }
18002 }
18003 self.write(")");
18004 Ok(())
18005 }
18006
18007 fn generate_extract(&mut self, f: &ExtractFunc) -> Result<()> {
18008 if matches!(
18010 self.config.dialect,
18011 Some(DialectType::TSQL) | Some(DialectType::Fabric)
18012 ) {
18013 self.write_keyword("DATEPART");
18014 self.write("(");
18015 self.write_datetime_field(&f.field);
18016 self.write(", ");
18017 self.generate_expression(&f.this)?;
18018 self.write(")");
18019 return Ok(());
18020 }
18021 self.write_keyword("EXTRACT");
18022 self.write("(");
18023 if matches!(
18025 self.config.dialect,
18026 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
18027 ) {
18028 self.write_datetime_field_lower(&f.field);
18029 } else {
18030 self.write_datetime_field(&f.field);
18031 }
18032 self.write_space();
18033 self.write_keyword("FROM");
18034 self.write_space();
18035 self.generate_expression(&f.this)?;
18036 self.write(")");
18037 Ok(())
18038 }
18039
18040 fn generate_to_date(&mut self, f: &ToDateFunc) -> Result<()> {
18041 self.write_keyword("TO_DATE");
18042 self.write("(");
18043 self.generate_expression(&f.this)?;
18044 if let Some(format) = &f.format {
18045 self.write(", ");
18046 self.generate_expression(format)?;
18047 }
18048 self.write(")");
18049 Ok(())
18050 }
18051
18052 fn generate_to_timestamp(&mut self, f: &ToTimestampFunc) -> Result<()> {
18053 self.write_keyword("TO_TIMESTAMP");
18054 self.write("(");
18055 self.generate_expression(&f.this)?;
18056 if let Some(format) = &f.format {
18057 self.write(", ");
18058 self.generate_expression(format)?;
18059 }
18060 self.write(")");
18061 Ok(())
18062 }
18063
18064 fn generate_if_func(&mut self, f: &IfFunc) -> Result<()> {
18067 use crate::dialects::DialectType;
18068
18069 if self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic) {
18071 self.write_keyword("CASE WHEN");
18072 self.write_space();
18073 self.generate_expression(&f.condition)?;
18074 self.write_space();
18075 self.write_keyword("THEN");
18076 self.write_space();
18077 self.generate_expression(&f.true_value)?;
18078 if let Some(false_val) = &f.false_value {
18079 self.write_space();
18080 self.write_keyword("ELSE");
18081 self.write_space();
18082 self.generate_expression(false_val)?;
18083 }
18084 self.write_space();
18085 self.write_keyword("END");
18086 return Ok(());
18087 }
18088
18089 if self.config.dialect == Some(DialectType::Exasol) {
18091 self.write_keyword("IF");
18092 self.write_space();
18093 self.generate_expression(&f.condition)?;
18094 self.write_space();
18095 self.write_keyword("THEN");
18096 self.write_space();
18097 self.generate_expression(&f.true_value)?;
18098 if let Some(false_val) = &f.false_value {
18099 self.write_space();
18100 self.write_keyword("ELSE");
18101 self.write_space();
18102 self.generate_expression(false_val)?;
18103 }
18104 self.write_space();
18105 self.write_keyword("ENDIF");
18106 return Ok(());
18107 }
18108
18109 let func_name = match self.config.dialect {
18111 Some(DialectType::Snowflake) => "IFF",
18112 Some(DialectType::SQLite) | Some(DialectType::TSQL) => "IIF",
18113 Some(DialectType::Drill) => "`IF`",
18114 _ => "IF",
18115 };
18116 self.write(func_name);
18117 self.write("(");
18118 self.generate_expression(&f.condition)?;
18119 self.write(", ");
18120 self.generate_expression(&f.true_value)?;
18121 if let Some(false_val) = &f.false_value {
18122 self.write(", ");
18123 self.generate_expression(false_val)?;
18124 }
18125 self.write(")");
18126 Ok(())
18127 }
18128
18129 fn generate_nvl2(&mut self, f: &Nvl2Func) -> Result<()> {
18130 self.write_keyword("NVL2");
18131 self.write("(");
18132 self.generate_expression(&f.this)?;
18133 self.write(", ");
18134 self.generate_expression(&f.true_value)?;
18135 self.write(", ");
18136 self.generate_expression(&f.false_value)?;
18137 self.write(")");
18138 Ok(())
18139 }
18140
18141 fn generate_count(&mut self, f: &CountFunc) -> Result<()> {
18144 let count_name = match self.config.normalize_functions {
18146 NormalizeFunctions::Upper => "COUNT".to_string(),
18147 NormalizeFunctions::Lower => "count".to_string(),
18148 NormalizeFunctions::None => f
18149 .original_name
18150 .clone()
18151 .unwrap_or_else(|| "COUNT".to_string()),
18152 };
18153 self.write(&count_name);
18154 self.write("(");
18155 if f.distinct {
18156 self.write_keyword("DISTINCT");
18157 self.write_space();
18158 }
18159 if f.star {
18160 self.write("*");
18161 } else if let Some(ref expr) = f.this {
18162 if let Expression::Tuple(tuple) = expr {
18164 let needs_transform =
18168 f.distinct && tuple.expressions.len() > 1 && !self.config.multi_arg_distinct;
18169
18170 if needs_transform {
18171 self.write_keyword("CASE");
18173 for e in &tuple.expressions {
18174 self.write_space();
18175 self.write_keyword("WHEN");
18176 self.write_space();
18177 self.generate_expression(e)?;
18178 self.write_space();
18179 self.write_keyword("IS NULL THEN NULL");
18180 }
18181 self.write_space();
18182 self.write_keyword("ELSE");
18183 self.write(" (");
18184 for (i, e) in tuple.expressions.iter().enumerate() {
18185 if i > 0 {
18186 self.write(", ");
18187 }
18188 self.generate_expression(e)?;
18189 }
18190 self.write(")");
18191 self.write_space();
18192 self.write_keyword("END");
18193 } else {
18194 for (i, e) in tuple.expressions.iter().enumerate() {
18195 if i > 0 {
18196 self.write(", ");
18197 }
18198 self.generate_expression(e)?;
18199 }
18200 }
18201 } else {
18202 self.generate_expression(expr)?;
18203 }
18204 }
18205 if let Some(ignore) = f.ignore_nulls {
18207 self.write_space();
18208 if ignore {
18209 self.write_keyword("IGNORE NULLS");
18210 } else {
18211 self.write_keyword("RESPECT NULLS");
18212 }
18213 }
18214 self.write(")");
18215 if let Some(ref filter) = f.filter {
18216 self.write_space();
18217 self.write_keyword("FILTER");
18218 self.write("(");
18219 self.write_keyword("WHERE");
18220 self.write_space();
18221 self.generate_expression(filter)?;
18222 self.write(")");
18223 }
18224 Ok(())
18225 }
18226
18227 fn generate_agg_func(&mut self, name: &str, f: &AggFunc) -> Result<()> {
18228 let func_name = match self.config.normalize_functions {
18230 NormalizeFunctions::Upper => name.to_uppercase(),
18231 NormalizeFunctions::Lower => name.to_lowercase(),
18232 NormalizeFunctions::None => {
18233 if let Some(ref original) = f.name {
18236 original.clone()
18237 } else {
18238 name.to_lowercase()
18239 }
18240 }
18241 };
18242 self.write(&func_name);
18243 self.write("(");
18244 if f.distinct {
18245 self.write_keyword("DISTINCT");
18246 self.write_space();
18247 }
18248 if !matches!(f.this, Expression::Null(_)) {
18250 self.generate_expression(&f.this)?;
18251 }
18252 if self.config.ignore_nulls_in_func
18255 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
18256 {
18257 match f.ignore_nulls {
18258 Some(true) => {
18259 self.write_space();
18260 self.write_keyword("IGNORE NULLS");
18261 }
18262 Some(false) => {
18263 self.write_space();
18264 self.write_keyword("RESPECT NULLS");
18265 }
18266 None => {}
18267 }
18268 }
18269 if let Some((ref expr, is_max)) = f.having_max {
18272 self.write_space();
18273 self.write_keyword("HAVING");
18274 self.write_space();
18275 if is_max {
18276 self.write_keyword("MAX");
18277 } else {
18278 self.write_keyword("MIN");
18279 }
18280 self.write_space();
18281 self.generate_expression(expr)?;
18282 }
18283 if !f.order_by.is_empty() {
18285 self.write_space();
18286 self.write_keyword("ORDER BY");
18287 self.write_space();
18288 for (i, ord) in f.order_by.iter().enumerate() {
18289 if i > 0 {
18290 self.write(", ");
18291 }
18292 self.generate_ordered(ord)?;
18293 }
18294 }
18295 if let Some(ref limit) = f.limit {
18297 self.write_space();
18298 self.write_keyword("LIMIT");
18299 self.write_space();
18300 if let Expression::Tuple(t) = limit.as_ref() {
18302 if t.expressions.len() == 2 {
18303 self.generate_expression(&t.expressions[0])?;
18304 self.write(", ");
18305 self.generate_expression(&t.expressions[1])?;
18306 } else {
18307 self.generate_expression(limit)?;
18308 }
18309 } else {
18310 self.generate_expression(limit)?;
18311 }
18312 }
18313 self.write(")");
18314 if !self.config.ignore_nulls_in_func
18317 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
18318 {
18319 match f.ignore_nulls {
18320 Some(true) => {
18321 self.write_space();
18322 self.write_keyword("IGNORE NULLS");
18323 }
18324 Some(false) => {
18325 self.write_space();
18326 self.write_keyword("RESPECT NULLS");
18327 }
18328 None => {}
18329 }
18330 }
18331 if let Some(ref filter) = f.filter {
18332 self.write_space();
18333 self.write_keyword("FILTER");
18334 self.write("(");
18335 self.write_keyword("WHERE");
18336 self.write_space();
18337 self.generate_expression(filter)?;
18338 self.write(")");
18339 }
18340 Ok(())
18341 }
18342
18343 fn generate_group_concat(&mut self, f: &GroupConcatFunc) -> Result<()> {
18344 self.write_keyword("GROUP_CONCAT");
18345 self.write("(");
18346 if f.distinct {
18347 self.write_keyword("DISTINCT");
18348 self.write_space();
18349 }
18350 self.generate_expression(&f.this)?;
18351 if let Some(ref order_by) = f.order_by {
18352 self.write_space();
18353 self.write_keyword("ORDER BY");
18354 self.write_space();
18355 for (i, ord) in order_by.iter().enumerate() {
18356 if i > 0 {
18357 self.write(", ");
18358 }
18359 self.generate_ordered(ord)?;
18360 }
18361 }
18362 if let Some(ref sep) = f.separator {
18363 if matches!(
18366 self.config.dialect,
18367 Some(crate::dialects::DialectType::SQLite)
18368 ) {
18369 self.write(", ");
18370 self.generate_expression(sep)?;
18371 } else {
18372 self.write_space();
18373 self.write_keyword("SEPARATOR");
18374 self.write_space();
18375 self.generate_expression(sep)?;
18376 }
18377 }
18378 self.write(")");
18379 if let Some(ref filter) = f.filter {
18380 self.write_space();
18381 self.write_keyword("FILTER");
18382 self.write("(");
18383 self.write_keyword("WHERE");
18384 self.write_space();
18385 self.generate_expression(filter)?;
18386 self.write(")");
18387 }
18388 Ok(())
18389 }
18390
18391 fn generate_string_agg(&mut self, f: &StringAggFunc) -> Result<()> {
18392 let is_tsql = matches!(
18393 self.config.dialect,
18394 Some(crate::dialects::DialectType::TSQL)
18395 );
18396 self.write_keyword("STRING_AGG");
18397 self.write("(");
18398 if f.distinct {
18399 self.write_keyword("DISTINCT");
18400 self.write_space();
18401 }
18402 self.generate_expression(&f.this)?;
18403 if let Some(ref separator) = f.separator {
18404 self.write(", ");
18405 self.generate_expression(separator)?;
18406 }
18407 if !is_tsql {
18409 if let Some(ref order_by) = f.order_by {
18410 self.write_space();
18411 self.write_keyword("ORDER BY");
18412 self.write_space();
18413 for (i, ord) in order_by.iter().enumerate() {
18414 if i > 0 {
18415 self.write(", ");
18416 }
18417 self.generate_ordered(ord)?;
18418 }
18419 }
18420 }
18421 if let Some(ref limit) = f.limit {
18422 self.write_space();
18423 self.write_keyword("LIMIT");
18424 self.write_space();
18425 self.generate_expression(limit)?;
18426 }
18427 self.write(")");
18428 if is_tsql {
18430 if let Some(ref order_by) = f.order_by {
18431 self.write_space();
18432 self.write_keyword("WITHIN GROUP");
18433 self.write(" (");
18434 self.write_keyword("ORDER BY");
18435 self.write_space();
18436 for (i, ord) in order_by.iter().enumerate() {
18437 if i > 0 {
18438 self.write(", ");
18439 }
18440 self.generate_ordered(ord)?;
18441 }
18442 self.write(")");
18443 }
18444 }
18445 if let Some(ref filter) = f.filter {
18446 self.write_space();
18447 self.write_keyword("FILTER");
18448 self.write("(");
18449 self.write_keyword("WHERE");
18450 self.write_space();
18451 self.generate_expression(filter)?;
18452 self.write(")");
18453 }
18454 Ok(())
18455 }
18456
18457 fn generate_listagg(&mut self, f: &ListAggFunc) -> Result<()> {
18458 use crate::dialects::DialectType;
18459 self.write_keyword("LISTAGG");
18460 self.write("(");
18461 if f.distinct {
18462 self.write_keyword("DISTINCT");
18463 self.write_space();
18464 }
18465 self.generate_expression(&f.this)?;
18466 if let Some(ref sep) = f.separator {
18467 self.write(", ");
18468 self.generate_expression(sep)?;
18469 } else if matches!(
18470 self.config.dialect,
18471 Some(DialectType::Trino) | Some(DialectType::Presto)
18472 ) {
18473 self.write(", ','");
18475 }
18476 if let Some(ref overflow) = f.on_overflow {
18477 self.write_space();
18478 self.write_keyword("ON OVERFLOW");
18479 self.write_space();
18480 match overflow {
18481 ListAggOverflow::Error => self.write_keyword("ERROR"),
18482 ListAggOverflow::Truncate { filler, with_count } => {
18483 self.write_keyword("TRUNCATE");
18484 if let Some(ref fill) = filler {
18485 self.write_space();
18486 self.generate_expression(fill)?;
18487 }
18488 if *with_count {
18489 self.write_space();
18490 self.write_keyword("WITH COUNT");
18491 } else {
18492 self.write_space();
18493 self.write_keyword("WITHOUT COUNT");
18494 }
18495 }
18496 }
18497 }
18498 self.write(")");
18499 if let Some(ref order_by) = f.order_by {
18500 self.write_space();
18501 self.write_keyword("WITHIN GROUP");
18502 self.write(" (");
18503 self.write_keyword("ORDER BY");
18504 self.write_space();
18505 for (i, ord) in order_by.iter().enumerate() {
18506 if i > 0 {
18507 self.write(", ");
18508 }
18509 self.generate_ordered(ord)?;
18510 }
18511 self.write(")");
18512 }
18513 if let Some(ref filter) = f.filter {
18514 self.write_space();
18515 self.write_keyword("FILTER");
18516 self.write("(");
18517 self.write_keyword("WHERE");
18518 self.write_space();
18519 self.generate_expression(filter)?;
18520 self.write(")");
18521 }
18522 Ok(())
18523 }
18524
18525 fn generate_sum_if(&mut self, f: &SumIfFunc) -> Result<()> {
18526 self.write_keyword("SUM_IF");
18527 self.write("(");
18528 self.generate_expression(&f.this)?;
18529 self.write(", ");
18530 self.generate_expression(&f.condition)?;
18531 self.write(")");
18532 if let Some(ref filter) = f.filter {
18533 self.write_space();
18534 self.write_keyword("FILTER");
18535 self.write("(");
18536 self.write_keyword("WHERE");
18537 self.write_space();
18538 self.generate_expression(filter)?;
18539 self.write(")");
18540 }
18541 Ok(())
18542 }
18543
18544 fn generate_approx_percentile(&mut self, f: &ApproxPercentileFunc) -> Result<()> {
18545 self.write_keyword("APPROX_PERCENTILE");
18546 self.write("(");
18547 self.generate_expression(&f.this)?;
18548 self.write(", ");
18549 self.generate_expression(&f.percentile)?;
18550 if let Some(ref acc) = f.accuracy {
18551 self.write(", ");
18552 self.generate_expression(acc)?;
18553 }
18554 self.write(")");
18555 if let Some(ref filter) = f.filter {
18556 self.write_space();
18557 self.write_keyword("FILTER");
18558 self.write("(");
18559 self.write_keyword("WHERE");
18560 self.write_space();
18561 self.generate_expression(filter)?;
18562 self.write(")");
18563 }
18564 Ok(())
18565 }
18566
18567 fn generate_percentile(&mut self, name: &str, f: &PercentileFunc) -> Result<()> {
18568 self.write_keyword(name);
18569 self.write("(");
18570 self.generate_expression(&f.percentile)?;
18571 self.write(")");
18572 if let Some(ref order_by) = f.order_by {
18573 self.write_space();
18574 self.write_keyword("WITHIN GROUP");
18575 self.write(" (");
18576 self.write_keyword("ORDER BY");
18577 self.write_space();
18578 self.generate_expression(&f.this)?;
18579 for ord in order_by.iter() {
18580 if ord.desc {
18581 self.write_space();
18582 self.write_keyword("DESC");
18583 }
18584 }
18585 self.write(")");
18586 }
18587 if let Some(ref filter) = f.filter {
18588 self.write_space();
18589 self.write_keyword("FILTER");
18590 self.write("(");
18591 self.write_keyword("WHERE");
18592 self.write_space();
18593 self.generate_expression(filter)?;
18594 self.write(")");
18595 }
18596 Ok(())
18597 }
18598
18599 fn generate_ntile(&mut self, f: &NTileFunc) -> Result<()> {
18602 self.write_keyword("NTILE");
18603 self.write("(");
18604 if let Some(num_buckets) = &f.num_buckets {
18605 self.generate_expression(num_buckets)?;
18606 }
18607 if let Some(order_by) = &f.order_by {
18608 self.write_keyword(" ORDER BY ");
18609 for (i, ob) in order_by.iter().enumerate() {
18610 if i > 0 {
18611 self.write(", ");
18612 }
18613 self.generate_ordered(ob)?;
18614 }
18615 }
18616 self.write(")");
18617 Ok(())
18618 }
18619
18620 fn generate_lead_lag(&mut self, name: &str, f: &LeadLagFunc) -> Result<()> {
18621 self.write_keyword(name);
18622 self.write("(");
18623 self.generate_expression(&f.this)?;
18624 if let Some(ref offset) = f.offset {
18625 self.write(", ");
18626 self.generate_expression(offset)?;
18627 if let Some(ref default) = f.default {
18628 self.write(", ");
18629 self.generate_expression(default)?;
18630 }
18631 }
18632 if f.ignore_nulls && self.config.ignore_nulls_in_func {
18634 self.write_space();
18635 self.write_keyword("IGNORE NULLS");
18636 }
18637 self.write(")");
18638 if f.ignore_nulls && !self.config.ignore_nulls_in_func {
18640 self.write_space();
18641 self.write_keyword("IGNORE NULLS");
18642 }
18643 Ok(())
18644 }
18645
18646 fn generate_value_func(&mut self, name: &str, f: &ValueFunc) -> Result<()> {
18647 self.write_keyword(name);
18648 self.write("(");
18649 self.generate_expression(&f.this)?;
18650 if self.config.ignore_nulls_in_func {
18652 match f.ignore_nulls {
18653 Some(true) => {
18654 self.write_space();
18655 self.write_keyword("IGNORE NULLS");
18656 }
18657 Some(false) => {
18658 self.write_space();
18659 self.write_keyword("RESPECT NULLS");
18660 }
18661 None => {}
18662 }
18663 }
18664 self.write(")");
18665 if !self.config.ignore_nulls_in_func {
18667 match f.ignore_nulls {
18668 Some(true) => {
18669 self.write_space();
18670 self.write_keyword("IGNORE NULLS");
18671 }
18672 Some(false) => {
18673 self.write_space();
18674 self.write_keyword("RESPECT NULLS");
18675 }
18676 None => {}
18677 }
18678 }
18679 Ok(())
18680 }
18681
18682 fn generate_nth_value(&mut self, f: &NthValueFunc) -> Result<()> {
18683 self.write_keyword("NTH_VALUE");
18684 self.write("(");
18685 self.generate_expression(&f.this)?;
18686 self.write(", ");
18687 self.generate_expression(&f.offset)?;
18688 if self.config.ignore_nulls_in_func {
18690 match f.ignore_nulls {
18691 Some(true) => {
18692 self.write_space();
18693 self.write_keyword("IGNORE NULLS");
18694 }
18695 Some(false) => {
18696 self.write_space();
18697 self.write_keyword("RESPECT NULLS");
18698 }
18699 None => {}
18700 }
18701 }
18702 self.write(")");
18703 if matches!(
18705 self.config.dialect,
18706 Some(crate::dialects::DialectType::Snowflake)
18707 ) {
18708 match f.from_first {
18709 Some(true) => {
18710 self.write_space();
18711 self.write_keyword("FROM FIRST");
18712 }
18713 Some(false) => {
18714 self.write_space();
18715 self.write_keyword("FROM LAST");
18716 }
18717 None => {}
18718 }
18719 }
18720 if !self.config.ignore_nulls_in_func {
18722 match f.ignore_nulls {
18723 Some(true) => {
18724 self.write_space();
18725 self.write_keyword("IGNORE NULLS");
18726 }
18727 Some(false) => {
18728 self.write_space();
18729 self.write_keyword("RESPECT NULLS");
18730 }
18731 None => {}
18732 }
18733 }
18734 Ok(())
18735 }
18736
18737 fn generate_position(&mut self, f: &PositionFunc) -> Result<()> {
18740 if matches!(
18743 self.config.dialect,
18744 Some(crate::dialects::DialectType::ClickHouse)
18745 ) {
18746 self.write_keyword("POSITION");
18747 self.write("(");
18748 self.generate_expression(&f.string)?;
18749 self.write(", ");
18750 self.generate_expression(&f.substring)?;
18751 if let Some(ref start) = f.start {
18752 self.write(", ");
18753 self.generate_expression(start)?;
18754 }
18755 self.write(")");
18756 return Ok(());
18757 }
18758
18759 self.write_keyword("POSITION");
18760 self.write("(");
18761 self.generate_expression(&f.substring)?;
18762 self.write_space();
18763 self.write_keyword("IN");
18764 self.write_space();
18765 self.generate_expression(&f.string)?;
18766 if let Some(ref start) = f.start {
18767 self.write(", ");
18768 self.generate_expression(start)?;
18769 }
18770 self.write(")");
18771 Ok(())
18772 }
18773
18774 fn generate_rand(&mut self, f: &Rand) -> Result<()> {
18777 if f.lower.is_some() || f.upper.is_some() {
18779 self.write_keyword("RANDOM");
18780 self.write("(");
18781 if let Some(ref lower) = f.lower {
18782 self.generate_expression(lower)?;
18783 }
18784 if let Some(ref upper) = f.upper {
18785 self.write(", ");
18786 self.generate_expression(upper)?;
18787 }
18788 self.write(")");
18789 return Ok(());
18790 }
18791 let func_name = match self.config.dialect {
18793 Some(crate::dialects::DialectType::Snowflake)
18794 | Some(crate::dialects::DialectType::DuckDB) => "RANDOM",
18795 _ => "RAND",
18796 };
18797 self.write_keyword(func_name);
18798 self.write("(");
18799 if !matches!(
18801 self.config.dialect,
18802 Some(crate::dialects::DialectType::DuckDB)
18803 ) {
18804 if let Some(ref seed) = f.seed {
18805 self.generate_expression(seed)?;
18806 }
18807 }
18808 self.write(")");
18809 Ok(())
18810 }
18811
18812 fn generate_truncate_func(&mut self, f: &TruncateFunc) -> Result<()> {
18813 self.write_keyword("TRUNCATE");
18814 self.write("(");
18815 self.generate_expression(&f.this)?;
18816 if let Some(ref decimals) = f.decimals {
18817 self.write(", ");
18818 self.generate_expression(decimals)?;
18819 }
18820 self.write(")");
18821 Ok(())
18822 }
18823
18824 fn generate_decode(&mut self, f: &DecodeFunc) -> Result<()> {
18827 self.write_keyword("DECODE");
18828 self.write("(");
18829 self.generate_expression(&f.this)?;
18830 for (search, result) in &f.search_results {
18831 self.write(", ");
18832 self.generate_expression(search)?;
18833 self.write(", ");
18834 self.generate_expression(result)?;
18835 }
18836 if let Some(ref default) = f.default {
18837 self.write(", ");
18838 self.generate_expression(default)?;
18839 }
18840 self.write(")");
18841 Ok(())
18842 }
18843
18844 fn generate_date_format(&mut self, name: &str, f: &DateFormatFunc) -> Result<()> {
18847 self.write_keyword(name);
18848 self.write("(");
18849 self.generate_expression(&f.this)?;
18850 self.write(", ");
18851 self.generate_expression(&f.format)?;
18852 self.write(")");
18853 Ok(())
18854 }
18855
18856 fn generate_from_unixtime(&mut self, f: &FromUnixtimeFunc) -> Result<()> {
18857 self.write_keyword("FROM_UNIXTIME");
18858 self.write("(");
18859 self.generate_expression(&f.this)?;
18860 if let Some(ref format) = f.format {
18861 self.write(", ");
18862 self.generate_expression(format)?;
18863 }
18864 self.write(")");
18865 Ok(())
18866 }
18867
18868 fn generate_unix_timestamp(&mut self, f: &UnixTimestampFunc) -> Result<()> {
18869 self.write_keyword("UNIX_TIMESTAMP");
18870 self.write("(");
18871 if let Some(ref expr) = f.this {
18872 self.generate_expression(expr)?;
18873 if let Some(ref format) = f.format {
18874 self.write(", ");
18875 self.generate_expression(format)?;
18876 }
18877 } else if matches!(
18878 self.config.dialect,
18879 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
18880 ) {
18881 self.write_keyword("CURRENT_TIMESTAMP");
18883 self.write("()");
18884 }
18885 self.write(")");
18886 Ok(())
18887 }
18888
18889 fn generate_make_date(&mut self, f: &MakeDateFunc) -> Result<()> {
18890 self.write_keyword("MAKE_DATE");
18891 self.write("(");
18892 self.generate_expression(&f.year)?;
18893 self.write(", ");
18894 self.generate_expression(&f.month)?;
18895 self.write(", ");
18896 self.generate_expression(&f.day)?;
18897 self.write(")");
18898 Ok(())
18899 }
18900
18901 fn generate_make_timestamp(&mut self, f: &MakeTimestampFunc) -> Result<()> {
18902 self.write_keyword("MAKE_TIMESTAMP");
18903 self.write("(");
18904 self.generate_expression(&f.year)?;
18905 self.write(", ");
18906 self.generate_expression(&f.month)?;
18907 self.write(", ");
18908 self.generate_expression(&f.day)?;
18909 self.write(", ");
18910 self.generate_expression(&f.hour)?;
18911 self.write(", ");
18912 self.generate_expression(&f.minute)?;
18913 self.write(", ");
18914 self.generate_expression(&f.second)?;
18915 if let Some(ref tz) = f.timezone {
18916 self.write(", ");
18917 self.generate_expression(tz)?;
18918 }
18919 self.write(")");
18920 Ok(())
18921 }
18922
18923 fn extract_struct_field_names(expr: &Expression) -> Option<Vec<String>> {
18925 match expr {
18926 Expression::Struct(s) => {
18927 if s.fields.iter().all(|(name, _)| name.is_some()) {
18928 Some(
18929 s.fields
18930 .iter()
18931 .map(|(name, _)| name.as_deref().unwrap_or("").to_string())
18932 .collect(),
18933 )
18934 } else {
18935 None
18936 }
18937 }
18938 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => {
18939 if f.args.iter().all(|a| matches!(a, Expression::Alias(_))) {
18941 Some(
18942 f.args
18943 .iter()
18944 .filter_map(|a| {
18945 if let Expression::Alias(alias) = a {
18946 Some(alias.alias.name.clone())
18947 } else {
18948 None
18949 }
18950 })
18951 .collect(),
18952 )
18953 } else {
18954 None
18955 }
18956 }
18957 _ => None,
18958 }
18959 }
18960
18961 fn struct_has_unnamed_fields(expr: &Expression) -> bool {
18963 match expr {
18964 Expression::Struct(s) => s.fields.iter().any(|(name, _)| name.is_none()),
18965 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => {
18966 f.args.iter().any(|a| !matches!(a, Expression::Alias(_)))
18967 }
18968 _ => false,
18969 }
18970 }
18971
18972 fn struct_field_count(expr: &Expression) -> usize {
18974 match expr {
18975 Expression::Struct(s) => s.fields.len(),
18976 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => f.args.len(),
18977 _ => 0,
18978 }
18979 }
18980
18981 fn apply_struct_field_names(expr: &Expression, field_names: &[String]) -> Expression {
18983 match expr {
18984 Expression::Struct(s) => {
18985 let mut new_fields = Vec::with_capacity(s.fields.len());
18986 for (i, (name, value)) in s.fields.iter().enumerate() {
18987 if name.is_none() && i < field_names.len() {
18988 new_fields.push((Some(field_names[i].clone()), value.clone()));
18989 } else {
18990 new_fields.push((name.clone(), value.clone()));
18991 }
18992 }
18993 Expression::Struct(Box::new(crate::expressions::Struct { fields: new_fields }))
18994 }
18995 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => {
18996 let mut new_args = Vec::with_capacity(f.args.len());
18997 for (i, arg) in f.args.iter().enumerate() {
18998 if !matches!(arg, Expression::Alias(_)) && i < field_names.len() {
18999 new_args.push(Expression::Alias(Box::new(crate::expressions::Alias {
19001 this: arg.clone(),
19002 alias: crate::expressions::Identifier::new(field_names[i].clone()),
19003 column_aliases: Vec::new(),
19004 pre_alias_comments: Vec::new(),
19005 trailing_comments: Vec::new(),
19006 })));
19007 } else {
19008 new_args.push(arg.clone());
19009 }
19010 }
19011 Expression::Function(Box::new(crate::expressions::Function {
19012 name: f.name.clone(),
19013 args: new_args,
19014 distinct: f.distinct,
19015 trailing_comments: f.trailing_comments.clone(),
19016 use_bracket_syntax: f.use_bracket_syntax,
19017 no_parens: f.no_parens,
19018 quoted: f.quoted,
19019 span: None,
19020 }))
19021 }
19022 _ => expr.clone(),
19023 }
19024 }
19025
19026 fn inherit_struct_field_names(expressions: &[Expression]) -> Vec<Expression> {
19030 let first = match expressions.first() {
19031 Some(e) => e,
19032 None => return expressions.to_vec(),
19033 };
19034
19035 let field_names = match Self::extract_struct_field_names(first) {
19036 Some(names) if !names.is_empty() => names,
19037 _ => return expressions.to_vec(),
19038 };
19039
19040 let mut result = Vec::with_capacity(expressions.len());
19041 for (idx, expr) in expressions.iter().enumerate() {
19042 if idx == 0 {
19043 result.push(expr.clone());
19044 continue;
19045 }
19046 if Self::struct_field_count(expr) == field_names.len()
19048 && Self::struct_has_unnamed_fields(expr)
19049 {
19050 result.push(Self::apply_struct_field_names(expr, &field_names));
19051 } else {
19052 result.push(expr.clone());
19053 }
19054 }
19055 result
19056 }
19057
19058 fn generate_array_constructor(&mut self, f: &ArrayConstructor) -> Result<()> {
19061 let needs_inheritance = matches!(
19064 self.config.dialect,
19065 Some(DialectType::DuckDB)
19066 | Some(DialectType::Spark)
19067 | Some(DialectType::Databricks)
19068 | Some(DialectType::Hive)
19069 | Some(DialectType::Snowflake)
19070 | Some(DialectType::Presto)
19071 | Some(DialectType::Trino)
19072 );
19073 let propagated: Vec<Expression>;
19074 let expressions = if needs_inheritance && f.expressions.len() > 1 {
19075 propagated = Self::inherit_struct_field_names(&f.expressions);
19076 &propagated
19077 } else {
19078 &f.expressions
19079 };
19080
19081 let should_split = if self.config.pretty && !expressions.is_empty() {
19083 let mut expr_strings: Vec<String> = Vec::with_capacity(expressions.len());
19084 for expr in expressions {
19085 let mut temp_gen = Generator::with_config(self.config.clone());
19086 temp_gen.config.pretty = false;
19087 temp_gen.generate_expression(expr)?;
19088 expr_strings.push(temp_gen.output);
19089 }
19090 self.too_wide(&expr_strings)
19091 } else {
19092 false
19093 };
19094
19095 if f.bracket_notation {
19096 let (open, close) = match self.config.dialect {
19100 None
19101 | Some(DialectType::Generic)
19102 | Some(DialectType::Spark)
19103 | Some(DialectType::Databricks)
19104 | Some(DialectType::Hive) => {
19105 self.write_keyword("ARRAY");
19106 ("(", ")")
19107 }
19108 Some(DialectType::Presto)
19109 | Some(DialectType::Trino)
19110 | Some(DialectType::PostgreSQL)
19111 | Some(DialectType::Redshift)
19112 | Some(DialectType::Materialize)
19113 | Some(DialectType::RisingWave)
19114 | Some(DialectType::CockroachDB) => {
19115 self.write_keyword("ARRAY");
19116 ("[", "]")
19117 }
19118 _ => ("[", "]"),
19119 };
19120 self.write(open);
19121 if should_split {
19122 self.write_newline();
19123 self.indent_level += 1;
19124 for (i, expr) in expressions.iter().enumerate() {
19125 self.write_indent();
19126 self.generate_expression(expr)?;
19127 if i + 1 < expressions.len() {
19128 self.write(",");
19129 }
19130 self.write_newline();
19131 }
19132 self.indent_level -= 1;
19133 self.write_indent();
19134 } else {
19135 for (i, expr) in expressions.iter().enumerate() {
19136 if i > 0 {
19137 self.write(", ");
19138 }
19139 self.generate_expression(expr)?;
19140 }
19141 }
19142 self.write(close);
19143 } else {
19144 if f.use_list_keyword {
19146 self.write_keyword("LIST");
19147 } else {
19148 self.write_keyword("ARRAY");
19149 }
19150 let has_subquery = expressions
19153 .iter()
19154 .any(|e| matches!(e, Expression::Select(_)));
19155 let (open, close) = if matches!(
19156 self.config.dialect,
19157 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive)
19158 ) || (matches!(self.config.dialect, Some(DialectType::BigQuery))
19159 && has_subquery)
19160 {
19161 ("(", ")")
19162 } else {
19163 ("[", "]")
19164 };
19165 self.write(open);
19166 if should_split {
19167 self.write_newline();
19168 self.indent_level += 1;
19169 for (i, expr) in expressions.iter().enumerate() {
19170 self.write_indent();
19171 self.generate_expression(expr)?;
19172 if i + 1 < expressions.len() {
19173 self.write(",");
19174 }
19175 self.write_newline();
19176 }
19177 self.indent_level -= 1;
19178 self.write_indent();
19179 } else {
19180 for (i, expr) in expressions.iter().enumerate() {
19181 if i > 0 {
19182 self.write(", ");
19183 }
19184 self.generate_expression(expr)?;
19185 }
19186 }
19187 self.write(close);
19188 }
19189 Ok(())
19190 }
19191
19192 fn generate_array_sort(&mut self, f: &ArraySortFunc) -> Result<()> {
19193 self.write_keyword("ARRAY_SORT");
19194 self.write("(");
19195 self.generate_expression(&f.this)?;
19196 if let Some(ref comp) = f.comparator {
19197 self.write(", ");
19198 self.generate_expression(comp)?;
19199 }
19200 self.write(")");
19201 Ok(())
19202 }
19203
19204 fn generate_array_join(&mut self, name: &str, f: &ArrayJoinFunc) -> Result<()> {
19205 self.write_keyword(name);
19206 self.write("(");
19207 self.generate_expression(&f.this)?;
19208 self.write(", ");
19209 self.generate_expression(&f.separator)?;
19210 if let Some(ref null_rep) = f.null_replacement {
19211 self.write(", ");
19212 self.generate_expression(null_rep)?;
19213 }
19214 self.write(")");
19215 Ok(())
19216 }
19217
19218 fn generate_unnest(&mut self, f: &UnnestFunc) -> Result<()> {
19219 self.write_keyword("UNNEST");
19220 self.write("(");
19221 self.generate_expression(&f.this)?;
19222 for extra in &f.expressions {
19223 self.write(", ");
19224 self.generate_expression(extra)?;
19225 }
19226 self.write(")");
19227 if f.with_ordinality {
19228 self.write_space();
19229 if self.config.unnest_with_ordinality {
19230 self.write_keyword("WITH ORDINALITY");
19232 } else if f.offset_alias.is_some() {
19233 if let Some(ref alias) = f.alias {
19236 self.write_keyword("AS");
19237 self.write_space();
19238 self.generate_identifier(alias)?;
19239 self.write_space();
19240 }
19241 self.write_keyword("WITH OFFSET");
19242 if let Some(ref offset_alias) = f.offset_alias {
19243 self.write_space();
19244 self.write_keyword("AS");
19245 self.write_space();
19246 self.generate_identifier(offset_alias)?;
19247 }
19248 } else {
19249 self.write_keyword("WITH OFFSET");
19251 if f.alias.is_none() {
19252 self.write(" AS offset");
19253 }
19254 }
19255 }
19256 if let Some(ref alias) = f.alias {
19257 let should_add_alias = if !f.with_ordinality {
19259 true
19260 } else if self.config.unnest_with_ordinality {
19261 true
19263 } else if f.offset_alias.is_some() {
19264 false
19266 } else {
19267 true
19269 };
19270 if should_add_alias {
19271 self.write_space();
19272 self.write_keyword("AS");
19273 self.write_space();
19274 self.generate_identifier(alias)?;
19275 }
19276 }
19277 Ok(())
19278 }
19279
19280 fn generate_array_filter(&mut self, f: &ArrayFilterFunc) -> Result<()> {
19281 self.write_keyword("FILTER");
19282 self.write("(");
19283 self.generate_expression(&f.this)?;
19284 self.write(", ");
19285 self.generate_expression(&f.filter)?;
19286 self.write(")");
19287 Ok(())
19288 }
19289
19290 fn generate_array_transform(&mut self, f: &ArrayTransformFunc) -> Result<()> {
19291 self.write_keyword("TRANSFORM");
19292 self.write("(");
19293 self.generate_expression(&f.this)?;
19294 self.write(", ");
19295 self.generate_expression(&f.transform)?;
19296 self.write(")");
19297 Ok(())
19298 }
19299
19300 fn generate_sequence(&mut self, name: &str, f: &SequenceFunc) -> Result<()> {
19301 self.write_keyword(name);
19302 self.write("(");
19303 self.generate_expression(&f.start)?;
19304 self.write(", ");
19305 self.generate_expression(&f.stop)?;
19306 if let Some(ref step) = f.step {
19307 self.write(", ");
19308 self.generate_expression(step)?;
19309 }
19310 self.write(")");
19311 Ok(())
19312 }
19313
19314 fn generate_struct_constructor(&mut self, f: &StructConstructor) -> Result<()> {
19317 self.write_keyword("STRUCT");
19318 self.write("(");
19319 for (i, (name, expr)) in f.fields.iter().enumerate() {
19320 if i > 0 {
19321 self.write(", ");
19322 }
19323 if let Some(ref id) = name {
19324 self.generate_identifier(id)?;
19325 self.write(" ");
19326 self.write_keyword("AS");
19327 self.write(" ");
19328 }
19329 self.generate_expression(expr)?;
19330 }
19331 self.write(")");
19332 Ok(())
19333 }
19334
19335 fn generate_struct_function_cross_dialect(&mut self, func: &Function) -> Result<()> {
19337 let mut names: Vec<Option<String>> = Vec::new();
19340 let mut values: Vec<&Expression> = Vec::new();
19341 let mut all_named = true;
19342
19343 for arg in &func.args {
19344 match arg {
19345 Expression::Alias(a) => {
19346 names.push(Some(a.alias.name.clone()));
19347 values.push(&a.this);
19348 }
19349 _ => {
19350 names.push(None);
19351 values.push(arg);
19352 all_named = false;
19353 }
19354 }
19355 }
19356
19357 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
19358 self.write("{");
19360 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
19361 if i > 0 {
19362 self.write(", ");
19363 }
19364 if let Some(n) = name {
19365 self.write("'");
19366 self.write(n);
19367 self.write("'");
19368 } else {
19369 self.write("'_");
19370 self.write(&i.to_string());
19371 self.write("'");
19372 }
19373 self.write(": ");
19374 self.generate_expression(value)?;
19375 }
19376 self.write("}");
19377 return Ok(());
19378 }
19379
19380 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
19381 self.write_keyword("OBJECT_CONSTRUCT");
19383 self.write("(");
19384 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
19385 if i > 0 {
19386 self.write(", ");
19387 }
19388 if let Some(n) = name {
19389 self.write("'");
19390 self.write(n);
19391 self.write("'");
19392 } else {
19393 self.write("'_");
19394 self.write(&i.to_string());
19395 self.write("'");
19396 }
19397 self.write(", ");
19398 self.generate_expression(value)?;
19399 }
19400 self.write(")");
19401 return Ok(());
19402 }
19403
19404 if matches!(
19405 self.config.dialect,
19406 Some(DialectType::Presto) | Some(DialectType::Trino)
19407 ) {
19408 if all_named && !names.is_empty() {
19409 self.write_keyword("CAST");
19412 self.write("(");
19413 self.write_keyword("ROW");
19414 self.write("(");
19415 for (i, value) in values.iter().enumerate() {
19416 if i > 0 {
19417 self.write(", ");
19418 }
19419 self.generate_expression(value)?;
19420 }
19421 self.write(")");
19422 self.write(" ");
19423 self.write_keyword("AS");
19424 self.write(" ");
19425 self.write_keyword("ROW");
19426 self.write("(");
19427 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
19428 if i > 0 {
19429 self.write(", ");
19430 }
19431 if let Some(n) = name {
19432 self.write(n);
19433 }
19434 self.write(" ");
19435 let type_str = Self::infer_sql_type_for_presto(value);
19436 self.write_keyword(&type_str);
19437 }
19438 self.write(")");
19439 self.write(")");
19440 } else {
19441 self.write_keyword("ROW");
19443 self.write("(");
19444 for (i, value) in values.iter().enumerate() {
19445 if i > 0 {
19446 self.write(", ");
19447 }
19448 self.generate_expression(value)?;
19449 }
19450 self.write(")");
19451 }
19452 return Ok(());
19453 }
19454
19455 self.write_keyword("ROW");
19457 self.write("(");
19458 for (i, value) in values.iter().enumerate() {
19459 if i > 0 {
19460 self.write(", ");
19461 }
19462 self.generate_expression(value)?;
19463 }
19464 self.write(")");
19465 Ok(())
19466 }
19467
19468 fn infer_sql_type_for_presto(expr: &Expression) -> String {
19470 match expr {
19471 Expression::Literal(crate::expressions::Literal::String(_)) => "VARCHAR".to_string(),
19472 Expression::Literal(crate::expressions::Literal::Number(n)) => {
19473 if n.contains('.') {
19474 "DOUBLE".to_string()
19475 } else {
19476 "INTEGER".to_string()
19477 }
19478 }
19479 Expression::Boolean(_) => "BOOLEAN".to_string(),
19480 Expression::Literal(crate::expressions::Literal::Date(_)) => "DATE".to_string(),
19481 Expression::Literal(crate::expressions::Literal::Timestamp(_)) => {
19482 "TIMESTAMP".to_string()
19483 }
19484 Expression::Literal(crate::expressions::Literal::Datetime(_)) => {
19485 "TIMESTAMP".to_string()
19486 }
19487 Expression::Array(_) | Expression::ArrayFunc(_) => {
19488 "ARRAY(VARCHAR)".to_string()
19490 }
19491 Expression::Struct(_) | Expression::StructFunc(_) => "ROW".to_string(),
19493 Expression::Function(f) => {
19494 let up = f.name.to_uppercase();
19495 if up == "STRUCT" {
19496 "ROW".to_string()
19497 } else if up == "CURRENT_DATE" {
19498 "DATE".to_string()
19499 } else if up == "CURRENT_TIMESTAMP" || up == "NOW" {
19500 "TIMESTAMP".to_string()
19501 } else {
19502 "VARCHAR".to_string()
19503 }
19504 }
19505 _ => "VARCHAR".to_string(),
19506 }
19507 }
19508
19509 fn generate_struct_extract(&mut self, f: &StructExtractFunc) -> Result<()> {
19510 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
19512 self.write_keyword("STRUCT_EXTRACT");
19513 self.write("(");
19514 self.generate_expression(&f.this)?;
19515 self.write(", ");
19516 self.write("'");
19518 self.write(&f.field.name);
19519 self.write("'");
19520 self.write(")");
19521 return Ok(());
19522 }
19523 self.generate_expression(&f.this)?;
19524 self.write(".");
19525 self.generate_identifier(&f.field)
19526 }
19527
19528 fn generate_named_struct(&mut self, f: &NamedStructFunc) -> Result<()> {
19529 self.write_keyword("NAMED_STRUCT");
19530 self.write("(");
19531 for (i, (name, value)) in f.pairs.iter().enumerate() {
19532 if i > 0 {
19533 self.write(", ");
19534 }
19535 self.generate_expression(name)?;
19536 self.write(", ");
19537 self.generate_expression(value)?;
19538 }
19539 self.write(")");
19540 Ok(())
19541 }
19542
19543 fn generate_map_constructor(&mut self, f: &MapConstructor) -> Result<()> {
19546 if f.curly_brace_syntax {
19547 if f.with_map_keyword {
19549 self.write_keyword("MAP");
19550 self.write(" ");
19551 }
19552 self.write("{");
19553 for (i, (key, val)) in f.keys.iter().zip(f.values.iter()).enumerate() {
19554 if i > 0 {
19555 self.write(", ");
19556 }
19557 self.generate_expression(key)?;
19558 self.write(": ");
19559 self.generate_expression(val)?;
19560 }
19561 self.write("}");
19562 } else {
19563 self.write_keyword("MAP");
19565 self.write("(");
19566 self.write_keyword("ARRAY");
19567 self.write("[");
19568 for (i, key) in f.keys.iter().enumerate() {
19569 if i > 0 {
19570 self.write(", ");
19571 }
19572 self.generate_expression(key)?;
19573 }
19574 self.write("], ");
19575 self.write_keyword("ARRAY");
19576 self.write("[");
19577 for (i, val) in f.values.iter().enumerate() {
19578 if i > 0 {
19579 self.write(", ");
19580 }
19581 self.generate_expression(val)?;
19582 }
19583 self.write("])");
19584 }
19585 Ok(())
19586 }
19587
19588 fn generate_transform_func(&mut self, name: &str, f: &TransformFunc) -> Result<()> {
19589 self.write_keyword(name);
19590 self.write("(");
19591 self.generate_expression(&f.this)?;
19592 self.write(", ");
19593 self.generate_expression(&f.transform)?;
19594 self.write(")");
19595 Ok(())
19596 }
19597
19598 fn generate_json_extract(&mut self, name: &str, f: &JsonExtractFunc) -> Result<()> {
19601 use crate::dialects::DialectType;
19602
19603 let use_arrow = f.arrow_syntax && self.dialect_supports_json_arrow();
19605
19606 if use_arrow {
19607 self.generate_expression(&f.this)?;
19609 if name == "JSON_EXTRACT_SCALAR" || name == "JSON_EXTRACT_PATH_TEXT" {
19610 self.write(" ->> ");
19611 } else {
19612 self.write(" -> ");
19613 }
19614 self.generate_expression(&f.path)?;
19615 return Ok(());
19616 }
19617
19618 if f.hash_arrow_syntax
19620 && matches!(
19621 self.config.dialect,
19622 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
19623 )
19624 {
19625 self.generate_expression(&f.this)?;
19626 self.write(" #>> ");
19627 self.generate_expression(&f.path)?;
19628 return Ok(());
19629 }
19630
19631 let func_name = if matches!(self.config.dialect, Some(DialectType::Redshift)) {
19634 match name {
19635 "JSON_EXTRACT_SCALAR"
19636 | "JSON_EXTRACT_PATH_TEXT"
19637 | "JSON_EXTRACT"
19638 | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH_TEXT",
19639 _ => name,
19640 }
19641 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
19642 match name {
19643 "JSON_EXTRACT_SCALAR" | "JSON_EXTRACT_PATH_TEXT" => "JSON_EXTRACT_PATH_TEXT",
19644 "JSON_EXTRACT" | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH",
19645 _ => name,
19646 }
19647 } else {
19648 name
19649 };
19650
19651 self.write_keyword(func_name);
19652 self.write("(");
19653 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
19655 if let Expression::Cast(ref cast) = f.this {
19656 if matches!(cast.to, crate::expressions::DataType::Json) {
19657 self.generate_expression(&cast.this)?;
19658 } else {
19659 self.generate_expression(&f.this)?;
19660 }
19661 } else {
19662 self.generate_expression(&f.this)?;
19663 }
19664 } else {
19665 self.generate_expression(&f.this)?;
19666 }
19667 if matches!(
19670 self.config.dialect,
19671 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
19672 ) && (func_name == "JSON_EXTRACT_PATH" || func_name == "JSON_EXTRACT_PATH_TEXT")
19673 {
19674 if let Expression::Literal(Literal::String(ref s)) = f.path {
19675 let parts = Self::decompose_json_path(s);
19676 for part in &parts {
19677 self.write(", '");
19678 self.write(part);
19679 self.write("'");
19680 }
19681 } else {
19682 self.write(", ");
19683 self.generate_expression(&f.path)?;
19684 }
19685 } else {
19686 self.write(", ");
19687 self.generate_expression(&f.path)?;
19688 }
19689
19690 if let Some(ref wrapper) = f.wrapper_option {
19693 self.write_space();
19694 self.write_keyword(wrapper);
19695 }
19696 if let Some(ref quotes) = f.quotes_option {
19697 self.write_space();
19698 self.write_keyword(quotes);
19699 if f.on_scalar_string {
19700 self.write_space();
19701 self.write_keyword("ON SCALAR STRING");
19702 }
19703 }
19704 if let Some(ref on_err) = f.on_error {
19705 self.write_space();
19706 self.write_keyword(on_err);
19707 }
19708 if let Some(ref ret_type) = f.returning {
19709 self.write_space();
19710 self.write_keyword("RETURNING");
19711 self.write_space();
19712 self.generate_data_type(ret_type)?;
19713 }
19714
19715 self.write(")");
19716 Ok(())
19717 }
19718
19719 fn dialect_supports_json_arrow(&self) -> bool {
19721 use crate::dialects::DialectType;
19722 match self.config.dialect {
19723 Some(DialectType::PostgreSQL) => true,
19725 Some(DialectType::MySQL) => true,
19726 Some(DialectType::DuckDB) => true,
19727 Some(DialectType::CockroachDB) => true,
19728 Some(DialectType::StarRocks) => true,
19729 Some(DialectType::SQLite) => true,
19730 _ => false,
19732 }
19733 }
19734
19735 fn generate_json_path(&mut self, name: &str, f: &JsonPathFunc) -> Result<()> {
19736 use crate::dialects::DialectType;
19737
19738 if matches!(
19740 self.config.dialect,
19741 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
19742 ) && name == "JSON_EXTRACT_PATH"
19743 {
19744 self.generate_expression(&f.this)?;
19745 self.write(" #> ");
19746 if f.paths.len() == 1 {
19747 self.generate_expression(&f.paths[0])?;
19748 } else {
19749 self.write_keyword("ARRAY");
19751 self.write("[");
19752 for (i, path) in f.paths.iter().enumerate() {
19753 if i > 0 {
19754 self.write(", ");
19755 }
19756 self.generate_expression(path)?;
19757 }
19758 self.write("]");
19759 }
19760 return Ok(());
19761 }
19762
19763 self.write_keyword(name);
19764 self.write("(");
19765 self.generate_expression(&f.this)?;
19766 for path in &f.paths {
19767 self.write(", ");
19768 self.generate_expression(path)?;
19769 }
19770 self.write(")");
19771 Ok(())
19772 }
19773
19774 fn generate_json_object(&mut self, f: &JsonObjectFunc) -> Result<()> {
19775 use crate::dialects::DialectType;
19776
19777 self.write_keyword("JSON_OBJECT");
19778 self.write("(");
19779 if f.star {
19780 self.write("*");
19781 } else {
19782 let use_comma_syntax = self.config.json_key_value_pair_sep == ","
19786 || matches!(
19787 self.config.dialect,
19788 Some(DialectType::BigQuery)
19789 | Some(DialectType::MySQL)
19790 | Some(DialectType::SQLite)
19791 );
19792
19793 for (i, (key, value)) in f.pairs.iter().enumerate() {
19794 if i > 0 {
19795 self.write(", ");
19796 }
19797 self.generate_expression(key)?;
19798 if use_comma_syntax {
19799 self.write(", ");
19800 } else {
19801 self.write(": ");
19802 }
19803 self.generate_expression(value)?;
19804 }
19805 }
19806 if let Some(null_handling) = f.null_handling {
19807 self.write_space();
19808 match null_handling {
19809 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
19810 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
19811 }
19812 }
19813 if f.with_unique_keys {
19814 self.write_space();
19815 self.write_keyword("WITH UNIQUE KEYS");
19816 }
19817 if let Some(ref ret_type) = f.returning_type {
19818 self.write_space();
19819 self.write_keyword("RETURNING");
19820 self.write_space();
19821 self.generate_data_type(ret_type)?;
19822 if f.format_json {
19823 self.write_space();
19824 self.write_keyword("FORMAT JSON");
19825 }
19826 if let Some(ref enc) = f.encoding {
19827 self.write_space();
19828 self.write_keyword("ENCODING");
19829 self.write_space();
19830 self.write(enc);
19831 }
19832 }
19833 self.write(")");
19834 Ok(())
19835 }
19836
19837 fn generate_json_modify(&mut self, name: &str, f: &JsonModifyFunc) -> Result<()> {
19838 self.write_keyword(name);
19839 self.write("(");
19840 self.generate_expression(&f.this)?;
19841 for (path, value) in &f.path_values {
19842 self.write(", ");
19843 self.generate_expression(path)?;
19844 self.write(", ");
19845 self.generate_expression(value)?;
19846 }
19847 self.write(")");
19848 Ok(())
19849 }
19850
19851 fn generate_json_array_agg(&mut self, f: &JsonArrayAggFunc) -> Result<()> {
19852 self.write_keyword("JSON_ARRAYAGG");
19853 self.write("(");
19854 self.generate_expression(&f.this)?;
19855 if let Some(ref order_by) = f.order_by {
19856 self.write_space();
19857 self.write_keyword("ORDER BY");
19858 self.write_space();
19859 for (i, ord) in order_by.iter().enumerate() {
19860 if i > 0 {
19861 self.write(", ");
19862 }
19863 self.generate_ordered(ord)?;
19864 }
19865 }
19866 if let Some(null_handling) = f.null_handling {
19867 self.write_space();
19868 match null_handling {
19869 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
19870 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
19871 }
19872 }
19873 self.write(")");
19874 if let Some(ref filter) = f.filter {
19875 self.write_space();
19876 self.write_keyword("FILTER");
19877 self.write("(");
19878 self.write_keyword("WHERE");
19879 self.write_space();
19880 self.generate_expression(filter)?;
19881 self.write(")");
19882 }
19883 Ok(())
19884 }
19885
19886 fn generate_json_object_agg(&mut self, f: &JsonObjectAggFunc) -> Result<()> {
19887 self.write_keyword("JSON_OBJECTAGG");
19888 self.write("(");
19889 self.generate_expression(&f.key)?;
19890 self.write(": ");
19891 self.generate_expression(&f.value)?;
19892 if let Some(null_handling) = f.null_handling {
19893 self.write_space();
19894 match null_handling {
19895 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
19896 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
19897 }
19898 }
19899 self.write(")");
19900 if let Some(ref filter) = f.filter {
19901 self.write_space();
19902 self.write_keyword("FILTER");
19903 self.write("(");
19904 self.write_keyword("WHERE");
19905 self.write_space();
19906 self.generate_expression(filter)?;
19907 self.write(")");
19908 }
19909 Ok(())
19910 }
19911
19912 fn generate_convert(&mut self, f: &ConvertFunc) -> Result<()> {
19915 use crate::dialects::DialectType;
19916
19917 if self.config.dialect == Some(DialectType::Redshift) {
19919 self.write_keyword("CAST");
19920 self.write("(");
19921 self.generate_expression(&f.this)?;
19922 self.write_space();
19923 self.write_keyword("AS");
19924 self.write_space();
19925 self.generate_data_type(&f.to)?;
19926 self.write(")");
19927 return Ok(());
19928 }
19929
19930 self.write_keyword("CONVERT");
19931 self.write("(");
19932 self.generate_data_type(&f.to)?;
19933 self.write(", ");
19934 self.generate_expression(&f.this)?;
19935 if let Some(ref style) = f.style {
19936 self.write(", ");
19937 self.generate_expression(style)?;
19938 }
19939 self.write(")");
19940 Ok(())
19941 }
19942
19943 fn generate_lambda(&mut self, f: &LambdaExpr) -> Result<()> {
19946 if f.colon {
19947 self.write_keyword("LAMBDA");
19949 self.write_space();
19950 for (i, param) in f.parameters.iter().enumerate() {
19951 if i > 0 {
19952 self.write(", ");
19953 }
19954 self.generate_identifier(param)?;
19955 }
19956 self.write(" : ");
19957 } else {
19958 if f.parameters.len() == 1 {
19960 self.generate_identifier(&f.parameters[0])?;
19961 } else {
19962 self.write("(");
19963 for (i, param) in f.parameters.iter().enumerate() {
19964 if i > 0 {
19965 self.write(", ");
19966 }
19967 self.generate_identifier(param)?;
19968 }
19969 self.write(")");
19970 }
19971 self.write(" -> ");
19972 }
19973 self.generate_expression(&f.body)
19974 }
19975
19976 fn generate_named_argument(&mut self, f: &NamedArgument) -> Result<()> {
19977 self.generate_identifier(&f.name)?;
19978 match f.separator {
19979 NamedArgSeparator::DArrow => self.write(" => "),
19980 NamedArgSeparator::ColonEq => self.write(" := "),
19981 NamedArgSeparator::Eq => self.write(" = "),
19982 }
19983 self.generate_expression(&f.value)
19984 }
19985
19986 fn generate_table_argument(&mut self, f: &TableArgument) -> Result<()> {
19987 self.write_keyword(&f.prefix);
19988 self.write(" ");
19989 self.generate_expression(&f.this)
19990 }
19991
19992 fn generate_parameter(&mut self, f: &Parameter) -> Result<()> {
19993 match f.style {
19994 ParameterStyle::Question => self.write("?"),
19995 ParameterStyle::Dollar => {
19996 self.write("$");
19997 if let Some(idx) = f.index {
19998 self.write(&idx.to_string());
19999 } else if let Some(ref name) = f.name {
20000 self.write(name);
20002 }
20003 }
20004 ParameterStyle::DollarBrace => {
20005 self.write("${");
20007 if let Some(ref name) = f.name {
20008 self.write(name);
20009 }
20010 if let Some(ref expr) = f.expression {
20011 self.write(":");
20012 self.write(expr);
20013 }
20014 self.write("}");
20015 }
20016 ParameterStyle::Colon => {
20017 self.write(":");
20018 if let Some(idx) = f.index {
20019 self.write(&idx.to_string());
20020 } else if let Some(ref name) = f.name {
20021 self.write(name);
20022 }
20023 }
20024 ParameterStyle::At => {
20025 self.write("@");
20026 if let Some(ref name) = f.name {
20027 if f.string_quoted {
20028 self.write("'");
20029 self.write(name);
20030 self.write("'");
20031 } else if f.quoted {
20032 self.write("\"");
20033 self.write(name);
20034 self.write("\"");
20035 } else {
20036 self.write(name);
20037 }
20038 }
20039 }
20040 ParameterStyle::DoubleAt => {
20041 self.write("@@");
20042 if let Some(ref name) = f.name {
20043 self.write(name);
20044 }
20045 }
20046 ParameterStyle::DoubleDollar => {
20047 self.write("$$");
20048 if let Some(ref name) = f.name {
20049 self.write(name);
20050 }
20051 }
20052 ParameterStyle::Percent => {
20053 if let Some(ref name) = f.name {
20054 self.write("%(");
20056 self.write(name);
20057 self.write(")s");
20058 } else {
20059 self.write("%s");
20061 }
20062 }
20063 ParameterStyle::Brace => {
20064 self.write("{");
20067 if let Some(ref name) = f.name {
20068 self.write(name);
20069 }
20070 if let Some(ref expr) = f.expression {
20071 self.write(": ");
20072 self.write(expr);
20073 }
20074 self.write("}");
20075 }
20076 }
20077 Ok(())
20078 }
20079
20080 fn generate_placeholder(&mut self, f: &Placeholder) -> Result<()> {
20081 self.write("?");
20082 if let Some(idx) = f.index {
20083 self.write(&idx.to_string());
20084 }
20085 Ok(())
20086 }
20087
20088 fn generate_sql_comment(&mut self, f: &SqlComment) -> Result<()> {
20089 if f.is_block {
20090 self.write("/*");
20091 self.write(&f.text);
20092 self.write("*/");
20093 } else {
20094 self.write("--");
20095 self.write(&f.text);
20096 }
20097 Ok(())
20098 }
20099
20100 fn generate_similar_to(&mut self, f: &SimilarToExpr) -> Result<()> {
20103 self.generate_expression(&f.this)?;
20104 if f.not {
20105 self.write_space();
20106 self.write_keyword("NOT");
20107 }
20108 self.write_space();
20109 self.write_keyword("SIMILAR TO");
20110 self.write_space();
20111 self.generate_expression(&f.pattern)?;
20112 if let Some(ref escape) = f.escape {
20113 self.write_space();
20114 self.write_keyword("ESCAPE");
20115 self.write_space();
20116 self.generate_expression(escape)?;
20117 }
20118 Ok(())
20119 }
20120
20121 fn generate_quantified(&mut self, name: &str, f: &QuantifiedExpr) -> Result<()> {
20122 self.generate_expression(&f.this)?;
20123 self.write_space();
20124 if let Some(op) = &f.op {
20126 match op {
20127 QuantifiedOp::Eq => self.write("="),
20128 QuantifiedOp::Neq => self.write("<>"),
20129 QuantifiedOp::Lt => self.write("<"),
20130 QuantifiedOp::Lte => self.write("<="),
20131 QuantifiedOp::Gt => self.write(">"),
20132 QuantifiedOp::Gte => self.write(">="),
20133 }
20134 self.write_space();
20135 }
20136 self.write_keyword(name);
20137
20138 if matches!(&f.subquery, Expression::Subquery(_)) {
20140 self.write_space();
20141 self.generate_expression(&f.subquery)?;
20142 } else {
20143 self.write("(");
20144
20145 let is_statement = matches!(
20146 &f.subquery,
20147 Expression::Select(_)
20148 | Expression::Union(_)
20149 | Expression::Intersect(_)
20150 | Expression::Except(_)
20151 );
20152
20153 if self.config.pretty && is_statement {
20154 self.write_newline();
20155 self.indent_level += 1;
20156 self.write_indent();
20157 }
20158 self.generate_expression(&f.subquery)?;
20159 if self.config.pretty && is_statement {
20160 self.write_newline();
20161 self.indent_level -= 1;
20162 self.write_indent();
20163 }
20164 self.write(")");
20165 }
20166 Ok(())
20167 }
20168
20169 fn generate_overlaps(&mut self, f: &OverlapsExpr) -> Result<()> {
20170 if let (Some(this), Some(expr)) = (&f.this, &f.expression) {
20172 self.generate_expression(this)?;
20173 self.write_space();
20174 self.write_keyword("OVERLAPS");
20175 self.write_space();
20176 self.generate_expression(expr)?;
20177 } else if let (Some(ls), Some(le), Some(rs), Some(re)) =
20178 (&f.left_start, &f.left_end, &f.right_start, &f.right_end)
20179 {
20180 self.write("(");
20182 self.generate_expression(ls)?;
20183 self.write(", ");
20184 self.generate_expression(le)?;
20185 self.write(")");
20186 self.write_space();
20187 self.write_keyword("OVERLAPS");
20188 self.write_space();
20189 self.write("(");
20190 self.generate_expression(rs)?;
20191 self.write(", ");
20192 self.generate_expression(re)?;
20193 self.write(")");
20194 }
20195 Ok(())
20196 }
20197
20198 fn generate_try_cast(&mut self, cast: &Cast) -> Result<()> {
20201 use crate::dialects::DialectType;
20202
20203 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
20205 self.generate_expression(&cast.this)?;
20206 self.write(" !:> ");
20207 self.generate_data_type(&cast.to)?;
20208 return Ok(());
20209 }
20210
20211 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
20213 self.write_keyword("TRYCAST");
20214 self.write("(");
20215 self.generate_expression(&cast.this)?;
20216 self.write_space();
20217 self.write_keyword("AS");
20218 self.write_space();
20219 self.generate_data_type(&cast.to)?;
20220 self.write(")");
20221 return Ok(());
20222 }
20223
20224 let keyword = if matches!(
20226 self.config.dialect,
20227 Some(DialectType::Hive)
20228 | Some(DialectType::MySQL)
20229 | Some(DialectType::SQLite)
20230 | Some(DialectType::Oracle)
20231 | Some(DialectType::ClickHouse)
20232 | Some(DialectType::Redshift)
20233 | Some(DialectType::PostgreSQL)
20234 | Some(DialectType::StarRocks)
20235 | Some(DialectType::Doris)
20236 ) {
20237 "CAST"
20238 } else {
20239 "TRY_CAST"
20240 };
20241
20242 self.write_keyword(keyword);
20243 self.write("(");
20244 self.generate_expression(&cast.this)?;
20245 self.write_space();
20246 self.write_keyword("AS");
20247 self.write_space();
20248 self.generate_data_type(&cast.to)?;
20249
20250 if let Some(format) = &cast.format {
20252 self.write_space();
20253 self.write_keyword("FORMAT");
20254 self.write_space();
20255 self.generate_expression(format)?;
20256 }
20257
20258 self.write(")");
20259 Ok(())
20260 }
20261
20262 fn generate_safe_cast(&mut self, cast: &Cast) -> Result<()> {
20263 self.write_keyword("SAFE_CAST");
20264 self.write("(");
20265 self.generate_expression(&cast.this)?;
20266 self.write_space();
20267 self.write_keyword("AS");
20268 self.write_space();
20269 self.generate_data_type(&cast.to)?;
20270
20271 if let Some(format) = &cast.format {
20273 self.write_space();
20274 self.write_keyword("FORMAT");
20275 self.write_space();
20276 self.generate_expression(format)?;
20277 }
20278
20279 self.write(")");
20280 Ok(())
20281 }
20282
20283 fn generate_subscript(&mut self, s: &Subscript) -> Result<()> {
20286 self.generate_expression(&s.this)?;
20287 self.write("[");
20288 self.generate_expression(&s.index)?;
20289 self.write("]");
20290 Ok(())
20291 }
20292
20293 fn generate_dot_access(&mut self, d: &DotAccess) -> Result<()> {
20294 self.generate_expression(&d.this)?;
20295 let use_colon = matches!(self.config.dialect, Some(DialectType::Snowflake))
20298 && matches!(
20299 &d.this,
20300 Expression::Cast(_) | Expression::SafeCast(_) | Expression::TryCast(_)
20301 );
20302 if use_colon {
20303 self.write(":");
20304 } else {
20305 self.write(".");
20306 }
20307 self.generate_identifier(&d.field)
20308 }
20309
20310 fn generate_method_call(&mut self, m: &MethodCall) -> Result<()> {
20311 self.generate_expression(&m.this)?;
20312 self.write(".");
20313 if m.method.quoted {
20316 let q = self.config.identifier_quote;
20317 self.write(&format!("{}{}{}", q, m.method.name, q));
20318 } else {
20319 self.write(&m.method.name);
20320 }
20321 self.write("(");
20322 for (i, arg) in m.args.iter().enumerate() {
20323 if i > 0 {
20324 self.write(", ");
20325 }
20326 self.generate_expression(arg)?;
20327 }
20328 self.write(")");
20329 Ok(())
20330 }
20331
20332 fn generate_array_slice(&mut self, s: &ArraySlice) -> Result<()> {
20333 let needs_parens = matches!(
20336 &s.this,
20337 Expression::JsonExtract(f) if f.arrow_syntax
20338 ) || matches!(
20339 &s.this,
20340 Expression::JsonExtractScalar(f) if f.arrow_syntax
20341 );
20342
20343 if needs_parens {
20344 self.write("(");
20345 }
20346 self.generate_expression(&s.this)?;
20347 if needs_parens {
20348 self.write(")");
20349 }
20350 self.write("[");
20351 if let Some(start) = &s.start {
20352 self.generate_expression(start)?;
20353 }
20354 self.write(":");
20355 if let Some(end) = &s.end {
20356 self.generate_expression(end)?;
20357 }
20358 self.write("]");
20359 Ok(())
20360 }
20361
20362 fn generate_binary_op(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
20363 match &op.left {
20367 Expression::Column(col) => {
20368 if let Some(table) = &col.table {
20371 self.generate_identifier(table)?;
20372 self.write(".");
20373 }
20374 self.generate_identifier(&col.name)?;
20375 if col.join_mark && self.config.supports_column_join_marks {
20377 self.write(" (+)");
20378 }
20379 if op.left_comments.is_empty() {
20381 for comment in &col.trailing_comments {
20382 self.write_space();
20383 self.write_formatted_comment(comment);
20384 }
20385 }
20386 }
20387 Expression::Add(inner_op)
20388 | Expression::Sub(inner_op)
20389 | Expression::Mul(inner_op)
20390 | Expression::Div(inner_op)
20391 | Expression::Concat(inner_op) => {
20392 self.generate_binary_op_no_trailing(inner_op, match &op.left {
20394 Expression::Add(_) => "+",
20395 Expression::Sub(_) => "-",
20396 Expression::Mul(_) => "*",
20397 Expression::Div(_) => "/",
20398 Expression::Concat(_) => "||",
20399 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
20400 })?;
20401 }
20402 _ => {
20403 self.generate_expression(&op.left)?;
20404 }
20405 }
20406 for comment in &op.left_comments {
20408 self.write_space();
20409 self.write_formatted_comment(comment);
20410 }
20411 if self.config.pretty
20412 && matches!(self.config.dialect, Some(DialectType::Snowflake))
20413 && (operator == "AND" || operator == "OR")
20414 {
20415 self.write_newline();
20416 self.write_indent();
20417 self.write_keyword(operator);
20418 } else {
20419 self.write_space();
20420 if operator.chars().all(|c| c.is_alphabetic()) {
20421 self.write_keyword(operator);
20422 } else {
20423 self.write(operator);
20424 }
20425 }
20426 for comment in &op.operator_comments {
20428 self.write_space();
20429 self.write_formatted_comment(comment);
20430 }
20431 self.write_space();
20432 self.generate_expression(&op.right)?;
20433 for comment in &op.trailing_comments {
20435 self.write_space();
20436 self.write_formatted_comment(comment);
20437 }
20438 Ok(())
20439 }
20440
20441 fn generate_connector_op(&mut self, op: &BinaryOp, connector: ConnectorOperator) -> Result<()> {
20442 let keyword = connector.keyword();
20443 let Some(terms) = self.flatten_connector_terms(op, connector) else {
20444 return self.generate_binary_op(op, keyword);
20445 };
20446
20447 self.generate_expression(terms[0])?;
20448 for term in terms.iter().skip(1) {
20449 if self.config.pretty && matches!(self.config.dialect, Some(DialectType::Snowflake)) {
20450 self.write_newline();
20451 self.write_indent();
20452 self.write_keyword(keyword);
20453 } else {
20454 self.write_space();
20455 self.write_keyword(keyword);
20456 }
20457 self.write_space();
20458 self.generate_expression(term)?;
20459 }
20460
20461 Ok(())
20462 }
20463
20464 fn flatten_connector_terms<'a>(
20465 &self,
20466 root: &'a BinaryOp,
20467 connector: ConnectorOperator,
20468 ) -> Option<Vec<&'a Expression>> {
20469 if !root.left_comments.is_empty()
20470 || !root.operator_comments.is_empty()
20471 || !root.trailing_comments.is_empty()
20472 {
20473 return None;
20474 }
20475
20476 let mut terms = Vec::new();
20477 let mut stack: Vec<&Expression> = vec![&root.right, &root.left];
20478
20479 while let Some(expr) = stack.pop() {
20480 match (connector, expr) {
20481 (ConnectorOperator::And, Expression::And(inner))
20482 if inner.left_comments.is_empty()
20483 && inner.operator_comments.is_empty()
20484 && inner.trailing_comments.is_empty() =>
20485 {
20486 stack.push(&inner.right);
20487 stack.push(&inner.left);
20488 }
20489 (ConnectorOperator::Or, Expression::Or(inner))
20490 if inner.left_comments.is_empty()
20491 && inner.operator_comments.is_empty()
20492 && inner.trailing_comments.is_empty() =>
20493 {
20494 stack.push(&inner.right);
20495 stack.push(&inner.left);
20496 }
20497 _ => terms.push(expr),
20498 }
20499 }
20500
20501 if terms.len() > 1 {
20502 Some(terms)
20503 } else {
20504 None
20505 }
20506 }
20507
20508 fn generate_like_op(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
20510 self.generate_expression(&op.left)?;
20511 self.write_space();
20512 if operator == "ILIKE" && matches!(self.config.dialect, Some(DialectType::Drill)) {
20514 self.write("`ILIKE`");
20515 } else {
20516 self.write_keyword(operator);
20517 }
20518 if let Some(quantifier) = &op.quantifier {
20519 self.write_space();
20520 self.write_keyword(quantifier);
20521 }
20522 self.write_space();
20523 self.generate_expression(&op.right)?;
20524 if let Some(escape) = &op.escape {
20525 self.write_space();
20526 self.write_keyword("ESCAPE");
20527 self.write_space();
20528 self.generate_expression(escape)?;
20529 }
20530 Ok(())
20531 }
20532
20533 fn generate_null_safe_eq(&mut self, op: &BinaryOp) -> Result<()> {
20536 use crate::dialects::DialectType;
20537 self.generate_expression(&op.left)?;
20538 self.write_space();
20539 if matches!(self.config.dialect, Some(DialectType::MySQL)) {
20540 self.write("<=>");
20541 } else {
20542 self.write_keyword("IS NOT DISTINCT FROM");
20543 }
20544 self.write_space();
20545 self.generate_expression(&op.right)?;
20546 Ok(())
20547 }
20548
20549 fn generate_null_safe_neq(&mut self, op: &BinaryOp) -> Result<()> {
20551 self.generate_expression(&op.left)?;
20552 self.write_space();
20553 self.write_keyword("IS DISTINCT FROM");
20554 self.write_space();
20555 self.generate_expression(&op.right)?;
20556 Ok(())
20557 }
20558
20559 fn generate_binary_op_no_trailing(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
20561 match &op.left {
20563 Expression::Column(col) => {
20564 if let Some(table) = &col.table {
20565 self.generate_identifier(table)?;
20566 self.write(".");
20567 }
20568 self.generate_identifier(&col.name)?;
20569 if col.join_mark && self.config.supports_column_join_marks {
20571 self.write(" (+)");
20572 }
20573 }
20574 Expression::Add(inner_op)
20575 | Expression::Sub(inner_op)
20576 | Expression::Mul(inner_op)
20577 | Expression::Div(inner_op)
20578 | Expression::Concat(inner_op) => {
20579 self.generate_binary_op_no_trailing(inner_op, match &op.left {
20580 Expression::Add(_) => "+",
20581 Expression::Sub(_) => "-",
20582 Expression::Mul(_) => "*",
20583 Expression::Div(_) => "/",
20584 Expression::Concat(_) => "||",
20585 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
20586 })?;
20587 }
20588 _ => {
20589 self.generate_expression(&op.left)?;
20590 }
20591 }
20592 for comment in &op.left_comments {
20594 self.write_space();
20595 self.write_formatted_comment(comment);
20596 }
20597 self.write_space();
20598 if operator.chars().all(|c| c.is_alphabetic()) {
20599 self.write_keyword(operator);
20600 } else {
20601 self.write(operator);
20602 }
20603 for comment in &op.operator_comments {
20605 self.write_space();
20606 self.write_formatted_comment(comment);
20607 }
20608 self.write_space();
20609 match &op.right {
20612 Expression::Column(col) => {
20613 if let Some(table) = &col.table {
20614 self.generate_identifier(table)?;
20615 self.write(".");
20616 }
20617 self.generate_identifier(&col.name)?;
20618 if col.join_mark && self.config.supports_column_join_marks {
20620 self.write(" (+)");
20621 }
20622 }
20623 _ => {
20624 self.generate_expression(&op.right)?;
20625 }
20626 }
20627 Ok(())
20629 }
20630
20631 fn generate_unary_op(&mut self, op: &UnaryOp, operator: &str) -> Result<()> {
20632 if operator.chars().all(|c| c.is_alphabetic()) {
20633 self.write_keyword(operator);
20634 self.write_space();
20635 } else {
20636 self.write(operator);
20637 if matches!(&op.this, Expression::Neg(_) | Expression::BitwiseNot(_)) {
20639 self.write_space();
20640 }
20641 }
20642 self.generate_expression(&op.this)
20643 }
20644
20645 fn generate_in(&mut self, in_expr: &In) -> Result<()> {
20646 let is_generic =
20650 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
20651 let use_prefix_not =
20652 in_expr.not && is_generic && self.config.not_in_style == NotInStyle::Prefix;
20653 if use_prefix_not {
20654 self.write_keyword("NOT");
20655 self.write_space();
20656 }
20657 self.generate_expression(&in_expr.this)?;
20658 if in_expr.global {
20659 self.write_space();
20660 self.write_keyword("GLOBAL");
20661 }
20662 if in_expr.not && !use_prefix_not {
20663 self.write_space();
20664 self.write_keyword("NOT");
20665 }
20666 self.write_space();
20667 self.write_keyword("IN");
20668
20669 if let Some(unnest_expr) = &in_expr.unnest {
20671 self.write_space();
20672 self.write_keyword("UNNEST");
20673 self.write("(");
20674 self.generate_expression(unnest_expr)?;
20675 self.write(")");
20676 return Ok(());
20677 }
20678
20679 if let Some(query) = &in_expr.query {
20680 let is_bare = in_expr.expressions.is_empty()
20683 && !matches!(
20684 query,
20685 Expression::Select(_)
20686 | Expression::Union(_)
20687 | Expression::Intersect(_)
20688 | Expression::Except(_)
20689 | Expression::Subquery(_)
20690 );
20691 if is_bare {
20692 self.write_space();
20694 self.generate_expression(query)?;
20695 } else {
20696 self.write(" (");
20698 let is_statement = matches!(
20699 query,
20700 Expression::Select(_)
20701 | Expression::Union(_)
20702 | Expression::Intersect(_)
20703 | Expression::Except(_)
20704 | Expression::Subquery(_)
20705 );
20706 if self.config.pretty && is_statement {
20707 self.write_newline();
20708 self.indent_level += 1;
20709 self.write_indent();
20710 }
20711 self.generate_expression(query)?;
20712 if self.config.pretty && is_statement {
20713 self.write_newline();
20714 self.indent_level -= 1;
20715 self.write_indent();
20716 }
20717 self.write(")");
20718 }
20719 } else {
20720 let is_duckdb = matches!(
20724 self.config.dialect,
20725 Some(crate::dialects::DialectType::DuckDB)
20726 );
20727 let is_clickhouse = matches!(
20728 self.config.dialect,
20729 Some(crate::dialects::DialectType::ClickHouse)
20730 );
20731 let single_expr = in_expr.expressions.len() == 1;
20732 if is_clickhouse && single_expr {
20733 if let Expression::Array(arr) = &in_expr.expressions[0] {
20734 self.write(" (");
20736 for (i, expr) in arr.expressions.iter().enumerate() {
20737 if i > 0 {
20738 self.write(", ");
20739 }
20740 self.generate_expression(expr)?;
20741 }
20742 self.write(")");
20743 } else {
20744 self.write_space();
20745 self.generate_expression(&in_expr.expressions[0])?;
20746 }
20747 } else {
20748 let is_bare_ref = single_expr
20749 && matches!(
20750 &in_expr.expressions[0],
20751 Expression::Column(_) | Expression::Identifier(_) | Expression::Dot(_)
20752 );
20753 if (is_duckdb && is_bare_ref) || (in_expr.is_field && single_expr) {
20754 self.write_space();
20757 self.generate_expression(&in_expr.expressions[0])?;
20758 } else {
20759 self.write(" (");
20761 for (i, expr) in in_expr.expressions.iter().enumerate() {
20762 if i > 0 {
20763 self.write(", ");
20764 }
20765 self.generate_expression(expr)?;
20766 }
20767 self.write(")");
20768 }
20769 }
20770 }
20771
20772 Ok(())
20773 }
20774
20775 fn generate_between(&mut self, between: &Between) -> Result<()> {
20776 let use_prefix_not = between.not
20778 && (self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic));
20779 if use_prefix_not {
20780 self.write_keyword("NOT");
20781 self.write_space();
20782 }
20783 self.generate_expression(&between.this)?;
20784 if between.not && !use_prefix_not {
20785 self.write_space();
20786 self.write_keyword("NOT");
20787 }
20788 self.write_space();
20789 self.write_keyword("BETWEEN");
20790 if let Some(sym) = between.symmetric {
20792 if sym {
20793 self.write(" SYMMETRIC");
20794 } else {
20795 self.write(" ASYMMETRIC");
20796 }
20797 }
20798 self.write_space();
20799 self.generate_expression(&between.low)?;
20800 self.write_space();
20801 self.write_keyword("AND");
20802 self.write_space();
20803 self.generate_expression(&between.high)
20804 }
20805
20806 fn generate_is_null(&mut self, is_null: &IsNull) -> Result<()> {
20807 let use_prefix_not = is_null.not
20809 && (self.config.dialect.is_none()
20810 || self.config.dialect == Some(DialectType::Generic)
20811 || is_null.postfix_form);
20812 if use_prefix_not {
20813 self.write_keyword("NOT");
20815 self.write_space();
20816 self.generate_expression(&is_null.this)?;
20817 self.write_space();
20818 self.write_keyword("IS");
20819 self.write_space();
20820 self.write_keyword("NULL");
20821 } else {
20822 self.generate_expression(&is_null.this)?;
20823 self.write_space();
20824 self.write_keyword("IS");
20825 if is_null.not {
20826 self.write_space();
20827 self.write_keyword("NOT");
20828 }
20829 self.write_space();
20830 self.write_keyword("NULL");
20831 }
20832 Ok(())
20833 }
20834
20835 fn generate_is_true(&mut self, is_true: &IsTrueFalse) -> Result<()> {
20836 self.generate_expression(&is_true.this)?;
20837 self.write_space();
20838 self.write_keyword("IS");
20839 if is_true.not {
20840 self.write_space();
20841 self.write_keyword("NOT");
20842 }
20843 self.write_space();
20844 self.write_keyword("TRUE");
20845 Ok(())
20846 }
20847
20848 fn generate_is_false(&mut self, is_false: &IsTrueFalse) -> Result<()> {
20849 self.generate_expression(&is_false.this)?;
20850 self.write_space();
20851 self.write_keyword("IS");
20852 if is_false.not {
20853 self.write_space();
20854 self.write_keyword("NOT");
20855 }
20856 self.write_space();
20857 self.write_keyword("FALSE");
20858 Ok(())
20859 }
20860
20861 fn generate_is_json(&mut self, is_json: &IsJson) -> Result<()> {
20862 self.generate_expression(&is_json.this)?;
20863 self.write_space();
20864 self.write_keyword("IS");
20865 if is_json.negated {
20866 self.write_space();
20867 self.write_keyword("NOT");
20868 }
20869 self.write_space();
20870 self.write_keyword("JSON");
20871
20872 if let Some(ref json_type) = is_json.json_type {
20874 self.write_space();
20875 self.write_keyword(json_type);
20876 }
20877
20878 match &is_json.unique_keys {
20880 Some(JsonUniqueKeys::With) => {
20881 self.write_space();
20882 self.write_keyword("WITH UNIQUE KEYS");
20883 }
20884 Some(JsonUniqueKeys::Without) => {
20885 self.write_space();
20886 self.write_keyword("WITHOUT UNIQUE KEYS");
20887 }
20888 Some(JsonUniqueKeys::Shorthand) => {
20889 self.write_space();
20890 self.write_keyword("UNIQUE KEYS");
20891 }
20892 None => {}
20893 }
20894
20895 Ok(())
20896 }
20897
20898 fn generate_is(&mut self, is_expr: &BinaryOp) -> Result<()> {
20899 self.generate_expression(&is_expr.left)?;
20900 self.write_space();
20901 self.write_keyword("IS");
20902 self.write_space();
20903 self.generate_expression(&is_expr.right)
20904 }
20905
20906 fn generate_exists(&mut self, exists: &Exists) -> Result<()> {
20907 if exists.not {
20908 self.write_keyword("NOT");
20909 self.write_space();
20910 }
20911 self.write_keyword("EXISTS");
20912 self.write("(");
20913 let is_statement = matches!(
20914 &exists.this,
20915 Expression::Select(_)
20916 | Expression::Union(_)
20917 | Expression::Intersect(_)
20918 | Expression::Except(_)
20919 );
20920 if self.config.pretty && is_statement {
20921 self.write_newline();
20922 self.indent_level += 1;
20923 self.write_indent();
20924 self.generate_expression(&exists.this)?;
20925 self.write_newline();
20926 self.indent_level -= 1;
20927 self.write_indent();
20928 self.write(")");
20929 } else {
20930 self.generate_expression(&exists.this)?;
20931 self.write(")");
20932 }
20933 Ok(())
20934 }
20935
20936 fn generate_member_of(&mut self, op: &BinaryOp) -> Result<()> {
20937 self.generate_expression(&op.left)?;
20938 self.write_space();
20939 self.write_keyword("MEMBER OF");
20940 self.write("(");
20941 self.generate_expression(&op.right)?;
20942 self.write(")");
20943 Ok(())
20944 }
20945
20946 fn generate_subquery(&mut self, subquery: &Subquery) -> Result<()> {
20947 if subquery.lateral {
20948 self.write_keyword("LATERAL");
20949 self.write_space();
20950 }
20951
20952 let skip_outer_parens = if let Expression::Paren(ref p) = &subquery.this {
20956 matches!(
20957 &p.this,
20958 Expression::Select(_)
20959 | Expression::Union(_)
20960 | Expression::Intersect(_)
20961 | Expression::Except(_)
20962 | Expression::Subquery(_)
20963 )
20964 } else {
20965 false
20966 };
20967
20968 let is_statement = matches!(
20970 &subquery.this,
20971 Expression::Select(_)
20972 | Expression::Union(_)
20973 | Expression::Intersect(_)
20974 | Expression::Except(_)
20975 | Expression::Merge(_)
20976 );
20977
20978 if !skip_outer_parens {
20979 self.write("(");
20980 if self.config.pretty && is_statement {
20981 self.write_newline();
20982 self.indent_level += 1;
20983 self.write_indent();
20984 }
20985 }
20986 self.generate_expression(&subquery.this)?;
20987
20988 if subquery.modifiers_inside {
20990 if let Some(order_by) = &subquery.order_by {
20992 self.write_space();
20993 self.write_keyword("ORDER BY");
20994 self.write_space();
20995 for (i, ord) in order_by.expressions.iter().enumerate() {
20996 if i > 0 {
20997 self.write(", ");
20998 }
20999 self.generate_ordered(ord)?;
21000 }
21001 }
21002
21003 if let Some(limit) = &subquery.limit {
21004 self.write_space();
21005 self.write_keyword("LIMIT");
21006 self.write_space();
21007 self.generate_expression(&limit.this)?;
21008 if limit.percent {
21009 self.write_space();
21010 self.write_keyword("PERCENT");
21011 }
21012 }
21013
21014 if let Some(offset) = &subquery.offset {
21015 self.write_space();
21016 self.write_keyword("OFFSET");
21017 self.write_space();
21018 self.generate_expression(&offset.this)?;
21019 }
21020 }
21021
21022 if !skip_outer_parens {
21023 if self.config.pretty && is_statement {
21024 self.write_newline();
21025 self.indent_level -= 1;
21026 self.write_indent();
21027 }
21028 self.write(")");
21029 }
21030
21031 if !subquery.modifiers_inside {
21033 if let Some(order_by) = &subquery.order_by {
21034 self.write_space();
21035 self.write_keyword("ORDER BY");
21036 self.write_space();
21037 for (i, ord) in order_by.expressions.iter().enumerate() {
21038 if i > 0 {
21039 self.write(", ");
21040 }
21041 self.generate_ordered(ord)?;
21042 }
21043 }
21044
21045 if let Some(limit) = &subquery.limit {
21046 self.write_space();
21047 self.write_keyword("LIMIT");
21048 self.write_space();
21049 self.generate_expression(&limit.this)?;
21050 if limit.percent {
21051 self.write_space();
21052 self.write_keyword("PERCENT");
21053 }
21054 }
21055
21056 if let Some(offset) = &subquery.offset {
21057 self.write_space();
21058 self.write_keyword("OFFSET");
21059 self.write_space();
21060 self.generate_expression(&offset.this)?;
21061 }
21062
21063 if let Some(distribute_by) = &subquery.distribute_by {
21065 self.write_space();
21066 self.write_keyword("DISTRIBUTE BY");
21067 self.write_space();
21068 for (i, expr) in distribute_by.expressions.iter().enumerate() {
21069 if i > 0 {
21070 self.write(", ");
21071 }
21072 self.generate_expression(expr)?;
21073 }
21074 }
21075
21076 if let Some(sort_by) = &subquery.sort_by {
21078 self.write_space();
21079 self.write_keyword("SORT BY");
21080 self.write_space();
21081 for (i, ord) in sort_by.expressions.iter().enumerate() {
21082 if i > 0 {
21083 self.write(", ");
21084 }
21085 self.generate_ordered(ord)?;
21086 }
21087 }
21088
21089 if let Some(cluster_by) = &subquery.cluster_by {
21091 self.write_space();
21092 self.write_keyword("CLUSTER BY");
21093 self.write_space();
21094 for (i, ord) in cluster_by.expressions.iter().enumerate() {
21095 if i > 0 {
21096 self.write(", ");
21097 }
21098 self.generate_ordered(ord)?;
21099 }
21100 }
21101 }
21102
21103 if let Some(alias) = &subquery.alias {
21104 self.write_space();
21105 let skip_as = matches!(
21107 self.config.dialect,
21108 Some(crate::dialects::DialectType::Oracle)
21109 );
21110 if !skip_as {
21111 self.write_keyword("AS");
21112 self.write_space();
21113 }
21114 self.generate_identifier(alias)?;
21115 if !subquery.column_aliases.is_empty() {
21116 self.write("(");
21117 for (i, col) in subquery.column_aliases.iter().enumerate() {
21118 if i > 0 {
21119 self.write(", ");
21120 }
21121 self.generate_identifier(col)?;
21122 }
21123 self.write(")");
21124 }
21125 }
21126 for comment in &subquery.trailing_comments {
21128 self.write(" ");
21129 self.write_formatted_comment(comment);
21130 }
21131 Ok(())
21132 }
21133
21134 fn generate_pivot(&mut self, pivot: &Pivot) -> Result<()> {
21135 if let Some(ref with) = pivot.with {
21137 self.generate_with(with)?;
21138 self.write_space();
21139 }
21140
21141 let direction = if pivot.unpivot { "UNPIVOT" } else { "PIVOT" };
21142
21143 let is_redshift_unpivot = pivot.unpivot
21147 && pivot.expressions.is_empty()
21148 && pivot.fields.is_empty()
21149 && pivot.using.is_empty()
21150 && pivot.into.is_none()
21151 && !matches!(&pivot.this, Expression::Null(_));
21152
21153 if is_redshift_unpivot {
21154 self.write_keyword("UNPIVOT");
21156 self.write_space();
21157 self.generate_expression(&pivot.this)?;
21158 if let Some(alias) = &pivot.alias {
21160 self.write_space();
21161 self.write_keyword("AS");
21162 self.write_space();
21163 self.write(&alias.name);
21165 }
21166 return Ok(());
21167 }
21168
21169 let is_simplified = !pivot.using.is_empty()
21171 || pivot.into.is_some()
21172 || (pivot.fields.is_empty()
21173 && !pivot.expressions.is_empty()
21174 && !matches!(&pivot.this, Expression::Null(_)));
21175
21176 if is_simplified {
21177 self.write_keyword(direction);
21181 self.write_space();
21182 self.generate_expression(&pivot.this)?;
21183
21184 if !pivot.expressions.is_empty() {
21185 self.write_space();
21186 self.write_keyword("ON");
21187 self.write_space();
21188 for (i, expr) in pivot.expressions.iter().enumerate() {
21189 if i > 0 {
21190 self.write(", ");
21191 }
21192 self.generate_expression(expr)?;
21193 }
21194 }
21195
21196 if let Some(into) = &pivot.into {
21198 self.write_space();
21199 self.write_keyword("INTO");
21200 self.write_space();
21201 self.generate_expression(into)?;
21202 }
21203
21204 if !pivot.using.is_empty() {
21206 self.write_space();
21207 self.write_keyword("USING");
21208 self.write_space();
21209 for (i, expr) in pivot.using.iter().enumerate() {
21210 if i > 0 {
21211 self.write(", ");
21212 }
21213 self.generate_expression(expr)?;
21214 }
21215 }
21216
21217 if let Some(group) = &pivot.group {
21219 self.write_space();
21220 self.generate_expression(group)?;
21221 }
21222 } else {
21223 if !matches!(&pivot.this, Expression::Null(_)) {
21228 self.generate_expression(&pivot.this)?;
21229 self.write_space();
21230 }
21231 self.write_keyword(direction);
21232 self.write("(");
21233
21234 for (i, expr) in pivot.expressions.iter().enumerate() {
21236 if i > 0 {
21237 self.write(", ");
21238 }
21239 self.generate_expression(expr)?;
21240 }
21241
21242 if !pivot.fields.is_empty() {
21244 if !pivot.expressions.is_empty() {
21245 self.write_space();
21246 }
21247 self.write_keyword("FOR");
21248 self.write_space();
21249 for (i, field) in pivot.fields.iter().enumerate() {
21250 if i > 0 {
21251 self.write_space();
21252 }
21253 self.generate_expression(field)?;
21255 }
21256 }
21257
21258 if let Some(default_val) = &pivot.default_on_null {
21260 self.write_space();
21261 self.write_keyword("DEFAULT ON NULL");
21262 self.write(" (");
21263 self.generate_expression(default_val)?;
21264 self.write(")");
21265 }
21266
21267 if let Some(group) = &pivot.group {
21269 self.write_space();
21270 self.generate_expression(group)?;
21271 }
21272
21273 self.write(")");
21274 }
21275
21276 if let Some(alias) = &pivot.alias {
21278 self.write_space();
21279 self.write_keyword("AS");
21280 self.write_space();
21281 self.generate_identifier(alias)?;
21282 }
21283
21284 Ok(())
21285 }
21286
21287 fn generate_unpivot(&mut self, unpivot: &Unpivot) -> Result<()> {
21288 self.generate_expression(&unpivot.this)?;
21289 self.write_space();
21290 self.write_keyword("UNPIVOT");
21291 if let Some(include) = unpivot.include_nulls {
21293 self.write_space();
21294 if include {
21295 self.write_keyword("INCLUDE NULLS");
21296 } else {
21297 self.write_keyword("EXCLUDE NULLS");
21298 }
21299 self.write_space();
21300 }
21301 self.write("(");
21302 if unpivot.value_column_parenthesized {
21303 self.write("(");
21304 }
21305 self.generate_identifier(&unpivot.value_column)?;
21306 for extra_col in &unpivot.extra_value_columns {
21308 self.write(", ");
21309 self.generate_identifier(extra_col)?;
21310 }
21311 if unpivot.value_column_parenthesized {
21312 self.write(")");
21313 }
21314 self.write_space();
21315 self.write_keyword("FOR");
21316 self.write_space();
21317 self.generate_identifier(&unpivot.name_column)?;
21318 self.write_space();
21319 self.write_keyword("IN");
21320 self.write(" (");
21321 for (i, col) in unpivot.columns.iter().enumerate() {
21322 if i > 0 {
21323 self.write(", ");
21324 }
21325 self.generate_expression(col)?;
21326 }
21327 self.write("))");
21328 if let Some(alias) = &unpivot.alias {
21329 self.write_space();
21330 self.write_keyword("AS");
21331 self.write_space();
21332 self.generate_identifier(alias)?;
21333 }
21334 Ok(())
21335 }
21336
21337 fn generate_values(&mut self, values: &Values) -> Result<()> {
21338 self.write_keyword("VALUES");
21339 for (i, row) in values.expressions.iter().enumerate() {
21340 if i > 0 {
21341 self.write(",");
21342 }
21343 self.write(" (");
21344 for (j, expr) in row.expressions.iter().enumerate() {
21345 if j > 0 {
21346 self.write(", ");
21347 }
21348 self.generate_expression(expr)?;
21349 }
21350 self.write(")");
21351 }
21352 if let Some(alias) = &values.alias {
21353 self.write_space();
21354 self.write_keyword("AS");
21355 self.write_space();
21356 self.generate_identifier(alias)?;
21357 if !values.column_aliases.is_empty() {
21358 self.write("(");
21359 for (i, col) in values.column_aliases.iter().enumerate() {
21360 if i > 0 {
21361 self.write(", ");
21362 }
21363 self.generate_identifier(col)?;
21364 }
21365 self.write(")");
21366 }
21367 }
21368 Ok(())
21369 }
21370
21371 fn generate_array(&mut self, arr: &Array) -> Result<()> {
21372 let needs_inheritance = matches!(
21374 self.config.dialect,
21375 Some(DialectType::DuckDB)
21376 | Some(DialectType::Spark)
21377 | Some(DialectType::Databricks)
21378 | Some(DialectType::Hive)
21379 | Some(DialectType::Snowflake)
21380 | Some(DialectType::Presto)
21381 | Some(DialectType::Trino)
21382 );
21383 let propagated: Vec<Expression>;
21384 let expressions = if needs_inheritance && arr.expressions.len() > 1 {
21385 propagated = Self::inherit_struct_field_names(&arr.expressions);
21386 &propagated
21387 } else {
21388 &arr.expressions
21389 };
21390
21391 let use_parens =
21394 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
21395 if !self.config.array_bracket_only {
21396 self.write_keyword("ARRAY");
21397 }
21398 if use_parens {
21399 self.write("(");
21400 } else {
21401 self.write("[");
21402 }
21403 for (i, expr) in expressions.iter().enumerate() {
21404 if i > 0 {
21405 self.write(", ");
21406 }
21407 self.generate_expression(expr)?;
21408 }
21409 if use_parens {
21410 self.write(")");
21411 } else {
21412 self.write("]");
21413 }
21414 Ok(())
21415 }
21416
21417 fn generate_tuple(&mut self, tuple: &Tuple) -> Result<()> {
21418 if tuple.expressions.len() == 2 {
21421 if let Expression::TableAlias(_) = &tuple.expressions[1] {
21422 self.generate_expression(&tuple.expressions[0])?;
21424 self.write_space();
21425 self.write_keyword("AS");
21426 self.write_space();
21427 self.generate_expression(&tuple.expressions[1])?;
21428 return Ok(());
21429 }
21430 }
21431
21432 let expand_tuple = if self.config.pretty && tuple.expressions.len() > 1 {
21435 let mut expr_strings: Vec<String> = Vec::with_capacity(tuple.expressions.len());
21436 for expr in &tuple.expressions {
21437 expr_strings.push(self.generate_to_string(expr)?);
21438 }
21439 self.too_wide(&expr_strings)
21440 } else {
21441 false
21442 };
21443
21444 if expand_tuple {
21445 self.write("(");
21446 self.write_newline();
21447 self.indent_level += 1;
21448 for (i, expr) in tuple.expressions.iter().enumerate() {
21449 if i > 0 {
21450 self.write(",");
21451 self.write_newline();
21452 }
21453 self.write_indent();
21454 self.generate_expression(expr)?;
21455 }
21456 self.indent_level -= 1;
21457 self.write_newline();
21458 self.write_indent();
21459 self.write(")");
21460 } else {
21461 self.write("(");
21462 for (i, expr) in tuple.expressions.iter().enumerate() {
21463 if i > 0 {
21464 self.write(", ");
21465 }
21466 self.generate_expression(expr)?;
21467 }
21468 self.write(")");
21469 }
21470 Ok(())
21471 }
21472
21473 fn generate_pipe_operator(&mut self, pipe: &PipeOperator) -> Result<()> {
21474 self.generate_expression(&pipe.this)?;
21475 self.write(" |> ");
21476 self.generate_expression(&pipe.expression)?;
21477 Ok(())
21478 }
21479
21480 fn generate_ordered(&mut self, ordered: &Ordered) -> Result<()> {
21481 self.generate_expression(&ordered.this)?;
21482 if ordered.desc {
21483 self.write_space();
21484 self.write_keyword("DESC");
21485 } else if ordered.explicit_asc {
21486 self.write_space();
21487 self.write_keyword("ASC");
21488 }
21489 if let Some(nulls_first) = ordered.nulls_first {
21490 let is_asc = !ordered.desc;
21504 let is_nulls_are_large = matches!(
21505 self.config.dialect,
21506 Some(DialectType::Oracle)
21507 | Some(DialectType::PostgreSQL)
21508 | Some(DialectType::Redshift)
21509 | Some(DialectType::Snowflake)
21510 );
21511 let is_nulls_are_last = matches!(
21512 self.config.dialect,
21513 Some(DialectType::Dremio)
21514 | Some(DialectType::DuckDB)
21515 | Some(DialectType::Presto)
21516 | Some(DialectType::Trino)
21517 | Some(DialectType::Athena)
21518 | Some(DialectType::ClickHouse)
21519 | Some(DialectType::Drill)
21520 | Some(DialectType::Exasol)
21521 );
21522
21523 let is_default_nulls = if is_nulls_are_large {
21525 (is_asc && !nulls_first) || (!is_asc && nulls_first)
21527 } else if is_nulls_are_last {
21528 !nulls_first
21530 } else {
21531 false
21532 };
21533
21534 if !is_default_nulls {
21535 self.write_space();
21536 self.write_keyword("NULLS");
21537 self.write_space();
21538 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
21539 }
21540 }
21541 if let Some(ref with_fill) = ordered.with_fill {
21543 self.write_space();
21544 self.generate_with_fill(with_fill)?;
21545 }
21546 Ok(())
21547 }
21548
21549 fn write_clickhouse_type(&mut self, type_str: &str) {
21551 if self.clickhouse_nullable_depth < 0 {
21552 self.write(type_str);
21554 } else {
21555 self.write(&format!("Nullable({})", type_str));
21556 }
21557 }
21558
21559 fn generate_data_type(&mut self, dt: &DataType) -> Result<()> {
21560 use crate::dialects::DialectType;
21561
21562 match dt {
21563 DataType::Boolean => {
21564 match self.config.dialect {
21566 Some(DialectType::TSQL) => self.write_keyword("BIT"),
21567 Some(DialectType::MySQL) => self.write_keyword("BOOLEAN"), Some(DialectType::Oracle) => {
21569 self.write_keyword("NUMBER(1)")
21571 }
21572 Some(DialectType::ClickHouse) => self.write("Bool"), _ => self.write_keyword("BOOLEAN"),
21574 }
21575 }
21576 DataType::TinyInt { length } => {
21577 match self.config.dialect {
21581 Some(DialectType::PostgreSQL)
21582 | Some(DialectType::Redshift)
21583 | Some(DialectType::Oracle)
21584 | Some(DialectType::Exasol) => {
21585 self.write_keyword("SMALLINT");
21586 }
21587 Some(DialectType::Teradata) => {
21588 self.write_keyword("BYTEINT");
21590 }
21591 Some(DialectType::Dremio) => {
21592 self.write_keyword("INT");
21594 }
21595 Some(DialectType::ClickHouse) => {
21596 self.write_clickhouse_type("Int8");
21597 }
21598 _ => {
21599 self.write_keyword("TINYINT");
21600 }
21601 }
21602 if let Some(n) = length {
21603 if !matches!(
21604 self.config.dialect,
21605 Some(DialectType::Dremio) | Some(DialectType::ClickHouse)
21606 ) {
21607 self.write(&format!("({})", n));
21608 }
21609 }
21610 }
21611 DataType::SmallInt { length } => {
21612 match self.config.dialect {
21614 Some(DialectType::Dremio) => {
21615 self.write_keyword("INT");
21616 }
21617 Some(DialectType::SQLite) | Some(DialectType::Drill) => {
21618 self.write_keyword("INTEGER");
21619 }
21620 Some(DialectType::BigQuery) => {
21621 self.write_keyword("INT64");
21622 }
21623 Some(DialectType::ClickHouse) => {
21624 self.write_clickhouse_type("Int16");
21625 }
21626 _ => {
21627 self.write_keyword("SMALLINT");
21628 if let Some(n) = length {
21629 self.write(&format!("({})", n));
21630 }
21631 }
21632 }
21633 }
21634 DataType::Int {
21635 length,
21636 integer_spelling,
21637 } => {
21638 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
21640 self.write_keyword("INT64");
21641 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
21642 self.write_clickhouse_type("Int32");
21643 } else {
21644 let use_integer = match self.config.dialect {
21646 Some(DialectType::TSQL)
21647 | Some(DialectType::Fabric)
21648 | Some(DialectType::Presto)
21649 | Some(DialectType::Trino)
21650 | Some(DialectType::SQLite)
21651 | Some(DialectType::Redshift) => true,
21652 Some(DialectType::Databricks) => *integer_spelling,
21654 _ => false,
21655 };
21656 if use_integer {
21657 self.write_keyword("INTEGER");
21658 } else {
21659 self.write_keyword("INT");
21660 }
21661 if let Some(n) = length {
21662 self.write(&format!("({})", n));
21663 }
21664 }
21665 }
21666 DataType::BigInt { length } => {
21667 match self.config.dialect {
21669 Some(DialectType::Oracle) => {
21670 self.write_keyword("INT");
21672 }
21673 Some(DialectType::ClickHouse) => {
21674 self.write_clickhouse_type("Int64");
21675 }
21676 _ => {
21677 self.write_keyword("BIGINT");
21678 if let Some(n) = length {
21679 self.write(&format!("({})", n));
21680 }
21681 }
21682 }
21683 }
21684 DataType::Float {
21685 precision,
21686 scale,
21687 real_spelling,
21688 } => {
21689 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
21693 self.write_clickhouse_type("Float32");
21694 } else if *real_spelling
21695 && !matches!(
21696 self.config.dialect,
21697 Some(DialectType::Spark)
21698 | Some(DialectType::Databricks)
21699 | Some(DialectType::Hive)
21700 | Some(DialectType::Snowflake)
21701 | Some(DialectType::MySQL)
21702 | Some(DialectType::BigQuery)
21703 )
21704 {
21705 self.write_keyword("REAL")
21706 } else {
21707 match self.config.dialect {
21708 Some(DialectType::PostgreSQL) => self.write_keyword("REAL"),
21709 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
21710 _ => self.write_keyword("FLOAT"),
21711 }
21712 }
21713 if !matches!(
21716 self.config.dialect,
21717 Some(DialectType::Spark)
21718 | Some(DialectType::Databricks)
21719 | Some(DialectType::Hive)
21720 | Some(DialectType::Presto)
21721 | Some(DialectType::Trino)
21722 ) {
21723 if let Some(p) = precision {
21724 self.write(&format!("({}", p));
21725 if let Some(s) = scale {
21726 self.write(&format!(", {})", s));
21727 } else {
21728 self.write(")");
21729 }
21730 }
21731 }
21732 }
21733 DataType::Double { precision, scale } => {
21734 match self.config.dialect {
21736 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
21737 self.write_keyword("FLOAT")
21738 } Some(DialectType::Oracle) => self.write_keyword("DOUBLE PRECISION"),
21740 Some(DialectType::ClickHouse) => self.write_clickhouse_type("Float64"),
21741 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
21742 Some(DialectType::SQLite) => self.write_keyword("REAL"),
21743 Some(DialectType::PostgreSQL)
21744 | Some(DialectType::Redshift)
21745 | Some(DialectType::Teradata)
21746 | Some(DialectType::Materialize) => self.write_keyword("DOUBLE PRECISION"),
21747 _ => self.write_keyword("DOUBLE"),
21748 }
21749 if let Some(p) = precision {
21751 self.write(&format!("({}", p));
21752 if let Some(s) = scale {
21753 self.write(&format!(", {})", s));
21754 } else {
21755 self.write(")");
21756 }
21757 }
21758 }
21759 DataType::Decimal { precision, scale } => {
21760 match self.config.dialect {
21762 Some(DialectType::ClickHouse) => {
21763 self.write("Decimal");
21764 if let Some(p) = precision {
21765 self.write(&format!("({}", p));
21766 if let Some(s) = scale {
21767 self.write(&format!(", {}", s));
21768 }
21769 self.write(")");
21770 }
21771 }
21772 Some(DialectType::Oracle) => {
21773 self.write_keyword("NUMBER");
21775 if let Some(p) = precision {
21776 self.write(&format!("({}", p));
21777 if let Some(s) = scale {
21778 self.write(&format!(", {}", s));
21779 }
21780 self.write(")");
21781 }
21782 }
21783 Some(DialectType::BigQuery) => {
21784 self.write_keyword("NUMERIC");
21786 if let Some(p) = precision {
21787 self.write(&format!("({}", p));
21788 if let Some(s) = scale {
21789 self.write(&format!(", {}", s));
21790 }
21791 self.write(")");
21792 }
21793 }
21794 _ => {
21795 self.write_keyword("DECIMAL");
21796 if let Some(p) = precision {
21797 self.write(&format!("({}", p));
21798 if let Some(s) = scale {
21799 self.write(&format!(", {}", s));
21800 }
21801 self.write(")");
21802 }
21803 }
21804 }
21805 }
21806 DataType::Char { length } => {
21807 match self.config.dialect {
21809 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
21810 self.write_keyword("TEXT");
21812 }
21813 Some(DialectType::Hive)
21814 | Some(DialectType::Spark)
21815 | Some(DialectType::Databricks) => {
21816 if length.is_some()
21819 && !matches!(self.config.dialect, Some(DialectType::Hive))
21820 {
21821 self.write_keyword("CHAR");
21822 if let Some(n) = length {
21823 self.write(&format!("({})", n));
21824 }
21825 } else {
21826 self.write_keyword("STRING");
21827 }
21828 }
21829 Some(DialectType::Dremio) => {
21830 self.write_keyword("VARCHAR");
21832 if let Some(n) = length {
21833 self.write(&format!("({})", n));
21834 }
21835 }
21836 _ => {
21837 self.write_keyword("CHAR");
21838 if let Some(n) = length {
21839 self.write(&format!("({})", n));
21840 }
21841 }
21842 }
21843 }
21844 DataType::VarChar {
21845 length,
21846 parenthesized_length,
21847 } => {
21848 match self.config.dialect {
21850 Some(DialectType::Oracle) => {
21851 self.write_keyword("VARCHAR2");
21852 if let Some(n) = length {
21853 self.write(&format!("({})", n));
21854 }
21855 }
21856 Some(DialectType::DuckDB) => {
21857 self.write_keyword("TEXT");
21859 if let Some(n) = length {
21860 self.write(&format!("({})", n));
21861 }
21862 }
21863 Some(DialectType::SQLite) => {
21864 self.write_keyword("TEXT");
21866 if let Some(n) = length {
21867 self.write(&format!("({})", n));
21868 }
21869 }
21870 Some(DialectType::MySQL) if length.is_none() => {
21871 self.write_keyword("TEXT");
21873 }
21874 Some(DialectType::Hive)
21875 | Some(DialectType::Spark)
21876 | Some(DialectType::Databricks)
21877 if length.is_none() =>
21878 {
21879 self.write_keyword("STRING");
21881 }
21882 _ => {
21883 self.write_keyword("VARCHAR");
21884 if let Some(n) = length {
21885 if *parenthesized_length {
21887 self.write(&format!("(({}))", n));
21888 } else {
21889 self.write(&format!("({})", n));
21890 }
21891 }
21892 }
21893 }
21894 }
21895 DataType::Text => {
21896 match self.config.dialect {
21898 Some(DialectType::Oracle) => self.write_keyword("CLOB"),
21899 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
21900 self.write_keyword("VARCHAR(MAX)")
21901 }
21902 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
21903 Some(DialectType::Snowflake)
21904 | Some(DialectType::Dremio)
21905 | Some(DialectType::Drill) => self.write_keyword("VARCHAR"),
21906 Some(DialectType::Exasol) => self.write_keyword("LONG VARCHAR"),
21907 Some(DialectType::Presto)
21908 | Some(DialectType::Trino)
21909 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
21910 Some(DialectType::Spark)
21911 | Some(DialectType::Databricks)
21912 | Some(DialectType::Hive) => self.write_keyword("STRING"),
21913 Some(DialectType::Redshift) => self.write_keyword("VARCHAR(MAX)"),
21914 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
21915 self.write_keyword("STRING")
21916 }
21917 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
21918 _ => self.write_keyword("TEXT"),
21919 }
21920 }
21921 DataType::TextWithLength { length } => {
21922 match self.config.dialect {
21924 Some(DialectType::Oracle) => self.write(&format!("CLOB({})", length)),
21925 Some(DialectType::Hive)
21926 | Some(DialectType::Spark)
21927 | Some(DialectType::Databricks) => {
21928 self.write(&format!("VARCHAR({})", length));
21929 }
21930 Some(DialectType::Redshift) => self.write(&format!("VARCHAR({})", length)),
21931 Some(DialectType::BigQuery) => self.write(&format!("STRING({})", length)),
21932 Some(DialectType::Snowflake)
21933 | Some(DialectType::Presto)
21934 | Some(DialectType::Trino)
21935 | Some(DialectType::Athena)
21936 | Some(DialectType::Drill)
21937 | Some(DialectType::Dremio) => {
21938 self.write(&format!("VARCHAR({})", length));
21939 }
21940 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
21941 self.write(&format!("VARCHAR({})", length))
21942 }
21943 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
21944 self.write(&format!("STRING({})", length))
21945 }
21946 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
21947 _ => self.write(&format!("TEXT({})", length)),
21948 }
21949 }
21950 DataType::String { length } => {
21951 match self.config.dialect {
21953 Some(DialectType::ClickHouse) => {
21954 self.write("String");
21956 if let Some(n) = length {
21957 self.write(&format!("({})", n));
21958 }
21959 }
21960 Some(DialectType::BigQuery)
21961 | Some(DialectType::Hive)
21962 | Some(DialectType::Spark)
21963 | Some(DialectType::Databricks)
21964 | Some(DialectType::StarRocks)
21965 | Some(DialectType::Doris) => {
21966 self.write_keyword("STRING");
21967 if let Some(n) = length {
21968 self.write(&format!("({})", n));
21969 }
21970 }
21971 Some(DialectType::PostgreSQL) => {
21972 if let Some(n) = length {
21974 self.write_keyword("VARCHAR");
21975 self.write(&format!("({})", n));
21976 } else {
21977 self.write_keyword("TEXT");
21978 }
21979 }
21980 Some(DialectType::Redshift) => {
21981 if let Some(n) = length {
21983 self.write_keyword("VARCHAR");
21984 self.write(&format!("({})", n));
21985 } else {
21986 self.write_keyword("VARCHAR(MAX)");
21987 }
21988 }
21989 Some(DialectType::MySQL) => {
21990 if let Some(n) = length {
21992 self.write_keyword("VARCHAR");
21993 self.write(&format!("({})", n));
21994 } else {
21995 self.write_keyword("TEXT");
21996 }
21997 }
21998 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
21999 if let Some(n) = length {
22001 self.write_keyword("VARCHAR");
22002 self.write(&format!("({})", n));
22003 } else {
22004 self.write_keyword("VARCHAR(MAX)");
22005 }
22006 }
22007 Some(DialectType::Oracle) => {
22008 self.write_keyword("CLOB");
22010 }
22011 Some(DialectType::DuckDB) | Some(DialectType::Materialize) => {
22012 self.write_keyword("TEXT");
22014 if let Some(n) = length {
22015 self.write(&format!("({})", n));
22016 }
22017 }
22018 Some(DialectType::Presto)
22019 | Some(DialectType::Trino)
22020 | Some(DialectType::Drill)
22021 | Some(DialectType::Dremio) => {
22022 self.write_keyword("VARCHAR");
22024 if let Some(n) = length {
22025 self.write(&format!("({})", n));
22026 }
22027 }
22028 Some(DialectType::Snowflake) => {
22029 self.write_keyword("STRING");
22032 if let Some(n) = length {
22033 self.write(&format!("({})", n));
22034 }
22035 }
22036 _ => {
22037 self.write_keyword("STRING");
22039 if let Some(n) = length {
22040 self.write(&format!("({})", n));
22041 }
22042 }
22043 }
22044 }
22045 DataType::Binary { length } => {
22046 match self.config.dialect {
22048 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
22049 self.write_keyword("BYTEA");
22050 if let Some(n) = length {
22051 self.write(&format!("({})", n));
22052 }
22053 }
22054 Some(DialectType::Redshift) => {
22055 self.write_keyword("VARBYTE");
22056 if let Some(n) = length {
22057 self.write(&format!("({})", n));
22058 }
22059 }
22060 Some(DialectType::DuckDB)
22061 | Some(DialectType::SQLite)
22062 | Some(DialectType::Oracle) => {
22063 self.write_keyword("BLOB");
22065 if let Some(n) = length {
22066 self.write(&format!("({})", n));
22067 }
22068 }
22069 Some(DialectType::Presto)
22070 | Some(DialectType::Trino)
22071 | Some(DialectType::Athena)
22072 | Some(DialectType::Drill)
22073 | Some(DialectType::Dremio) => {
22074 self.write_keyword("VARBINARY");
22076 if let Some(n) = length {
22077 self.write(&format!("({})", n));
22078 }
22079 }
22080 Some(DialectType::ClickHouse) => {
22081 if self.clickhouse_nullable_depth < 0 {
22083 self.write("BINARY");
22084 } else {
22085 self.write("Nullable(BINARY");
22086 }
22087 if let Some(n) = length {
22088 self.write(&format!("({})", n));
22089 }
22090 if self.clickhouse_nullable_depth >= 0 {
22091 self.write(")");
22092 }
22093 }
22094 _ => {
22095 self.write_keyword("BINARY");
22096 if let Some(n) = length {
22097 self.write(&format!("({})", n));
22098 }
22099 }
22100 }
22101 }
22102 DataType::VarBinary { length } => {
22103 match self.config.dialect {
22105 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
22106 self.write_keyword("BYTEA");
22107 if let Some(n) = length {
22108 self.write(&format!("({})", n));
22109 }
22110 }
22111 Some(DialectType::Redshift) => {
22112 self.write_keyword("VARBYTE");
22113 if let Some(n) = length {
22114 self.write(&format!("({})", n));
22115 }
22116 }
22117 Some(DialectType::DuckDB)
22118 | Some(DialectType::SQLite)
22119 | Some(DialectType::Oracle) => {
22120 self.write_keyword("BLOB");
22122 if let Some(n) = length {
22123 self.write(&format!("({})", n));
22124 }
22125 }
22126 Some(DialectType::Exasol) => {
22127 self.write_keyword("VARCHAR");
22129 }
22130 Some(DialectType::Spark)
22131 | Some(DialectType::Hive)
22132 | Some(DialectType::Databricks) => {
22133 self.write_keyword("BINARY");
22135 if let Some(n) = length {
22136 self.write(&format!("({})", n));
22137 }
22138 }
22139 Some(DialectType::ClickHouse) => {
22140 self.write_clickhouse_type("String");
22142 }
22143 _ => {
22144 self.write_keyword("VARBINARY");
22145 if let Some(n) = length {
22146 self.write(&format!("({})", n));
22147 }
22148 }
22149 }
22150 }
22151 DataType::Blob => {
22152 match self.config.dialect {
22154 Some(DialectType::PostgreSQL) => self.write_keyword("BYTEA"),
22155 Some(DialectType::Redshift) => self.write_keyword("VARBYTE"),
22156 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
22157 self.write_keyword("VARBINARY")
22158 }
22159 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
22160 Some(DialectType::Exasol) => self.write_keyword("VARCHAR"),
22161 Some(DialectType::Presto)
22162 | Some(DialectType::Trino)
22163 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
22164 Some(DialectType::DuckDB) => {
22165 self.write_keyword("VARBINARY");
22168 }
22169 Some(DialectType::Spark)
22170 | Some(DialectType::Databricks)
22171 | Some(DialectType::Hive) => self.write_keyword("BINARY"),
22172 Some(DialectType::ClickHouse) => {
22173 self.write("Nullable(String)");
22177 }
22178 _ => self.write_keyword("BLOB"),
22179 }
22180 }
22181 DataType::Bit { length } => {
22182 match self.config.dialect {
22184 Some(DialectType::Dremio)
22185 | Some(DialectType::Spark)
22186 | Some(DialectType::Databricks)
22187 | Some(DialectType::Hive)
22188 | Some(DialectType::Snowflake)
22189 | Some(DialectType::BigQuery)
22190 | Some(DialectType::Presto)
22191 | Some(DialectType::Trino)
22192 | Some(DialectType::ClickHouse)
22193 | Some(DialectType::Redshift) => {
22194 self.write_keyword("BOOLEAN");
22196 }
22197 _ => {
22198 self.write_keyword("BIT");
22199 if let Some(n) = length {
22200 self.write(&format!("({})", n));
22201 }
22202 }
22203 }
22204 }
22205 DataType::VarBit { length } => {
22206 self.write_keyword("VARBIT");
22207 if let Some(n) = length {
22208 self.write(&format!("({})", n));
22209 }
22210 }
22211 DataType::Date => self.write_keyword("DATE"),
22212 DataType::Time {
22213 precision,
22214 timezone,
22215 } => {
22216 if *timezone {
22217 match self.config.dialect {
22219 Some(DialectType::DuckDB) => {
22220 self.write_keyword("TIMETZ");
22222 }
22223 Some(DialectType::PostgreSQL) => {
22224 self.write_keyword("TIMETZ");
22226 if let Some(p) = precision {
22227 self.write(&format!("({})", p));
22228 }
22229 }
22230 _ => {
22231 self.write_keyword("TIME");
22233 if let Some(p) = precision {
22234 self.write(&format!("({})", p));
22235 }
22236 self.write_keyword(" WITH TIME ZONE");
22237 }
22238 }
22239 } else {
22240 if matches!(
22242 self.config.dialect,
22243 Some(DialectType::Spark)
22244 | Some(DialectType::Databricks)
22245 | Some(DialectType::Hive)
22246 ) {
22247 self.write_keyword("TIMESTAMP");
22248 } else {
22249 self.write_keyword("TIME");
22250 if let Some(p) = precision {
22251 self.write(&format!("({})", p));
22252 }
22253 }
22254 }
22255 }
22256 DataType::Timestamp {
22257 precision,
22258 timezone,
22259 } => {
22260 match self.config.dialect {
22262 Some(DialectType::ClickHouse) => {
22263 self.write("DateTime");
22264 if let Some(p) = precision {
22265 self.write(&format!("({})", p));
22266 }
22267 }
22268 Some(DialectType::TSQL) => {
22269 if *timezone {
22270 self.write_keyword("DATETIMEOFFSET");
22271 } else {
22272 self.write_keyword("DATETIME2");
22273 }
22274 if let Some(p) = precision {
22275 self.write(&format!("({})", p));
22276 }
22277 }
22278 Some(DialectType::MySQL) => {
22279 self.write_keyword("TIMESTAMP");
22281 if let Some(p) = precision {
22282 self.write(&format!("({})", p));
22283 }
22284 }
22285 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
22286 self.write_keyword("DATETIME");
22288 if let Some(p) = precision {
22289 self.write(&format!("({})", p));
22290 }
22291 }
22292 Some(DialectType::BigQuery) => {
22293 if *timezone {
22295 self.write_keyword("TIMESTAMP");
22296 } else {
22297 self.write_keyword("DATETIME");
22298 }
22299 }
22300 Some(DialectType::DuckDB) => {
22301 if *timezone {
22303 self.write_keyword("TIMESTAMPTZ");
22304 } else {
22305 self.write_keyword("TIMESTAMP");
22306 if let Some(p) = precision {
22307 self.write(&format!("({})", p));
22308 }
22309 }
22310 }
22311 _ => {
22312 if *timezone && !self.config.tz_to_with_time_zone {
22313 self.write_keyword("TIMESTAMPTZ");
22315 if let Some(p) = precision {
22316 self.write(&format!("({})", p));
22317 }
22318 } else {
22319 self.write_keyword("TIMESTAMP");
22320 if let Some(p) = precision {
22321 self.write(&format!("({})", p));
22322 }
22323 if *timezone {
22324 self.write_space();
22325 self.write_keyword("WITH TIME ZONE");
22326 }
22327 }
22328 }
22329 }
22330 }
22331 DataType::Interval { unit, to } => {
22332 self.write_keyword("INTERVAL");
22333 if let Some(u) = unit {
22334 self.write_space();
22335 self.write_keyword(u);
22336 }
22337 if let Some(t) = to {
22339 self.write_space();
22340 self.write_keyword("TO");
22341 self.write_space();
22342 self.write_keyword(t);
22343 }
22344 }
22345 DataType::Json => {
22346 match self.config.dialect {
22348 Some(DialectType::Oracle) => self.write_keyword("JSON"), Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"), Some(DialectType::MySQL) => self.write_keyword("JSON"),
22351 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
22352 _ => self.write_keyword("JSON"),
22353 }
22354 }
22355 DataType::JsonB => {
22356 match self.config.dialect {
22358 Some(DialectType::PostgreSQL) => self.write_keyword("JSONB"),
22359 Some(DialectType::Doris) => self.write_keyword("JSONB"),
22360 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
22361 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
22362 Some(DialectType::DuckDB) => self.write_keyword("JSON"), _ => self.write_keyword("JSON"), }
22365 }
22366 DataType::Uuid => {
22367 match self.config.dialect {
22369 Some(DialectType::TSQL) => self.write_keyword("UNIQUEIDENTIFIER"),
22370 Some(DialectType::MySQL) => self.write_keyword("CHAR(36)"),
22371 Some(DialectType::Oracle) => self.write_keyword("RAW(16)"),
22372 Some(DialectType::BigQuery)
22373 | Some(DialectType::Spark)
22374 | Some(DialectType::Databricks) => self.write_keyword("STRING"),
22375 _ => self.write_keyword("UUID"),
22376 }
22377 }
22378 DataType::Array {
22379 element_type,
22380 dimension,
22381 } => {
22382 match self.config.dialect {
22384 Some(DialectType::PostgreSQL)
22385 | Some(DialectType::Redshift)
22386 | Some(DialectType::DuckDB) => {
22387 self.generate_data_type(element_type)?;
22389 if let Some(dim) = dimension {
22390 self.write(&format!("[{}]", dim));
22391 } else {
22392 self.write("[]");
22393 }
22394 }
22395 Some(DialectType::BigQuery) => {
22396 self.write_keyword("ARRAY<");
22397 self.generate_data_type(element_type)?;
22398 self.write(">");
22399 }
22400 Some(DialectType::Snowflake)
22401 | Some(DialectType::Presto)
22402 | Some(DialectType::Trino)
22403 | Some(DialectType::ClickHouse) => {
22404 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
22406 self.write("Array(");
22407 } else {
22408 self.write_keyword("ARRAY(");
22409 }
22410 self.generate_data_type(element_type)?;
22411 self.write(")");
22412 }
22413 Some(DialectType::TSQL)
22414 | Some(DialectType::MySQL)
22415 | Some(DialectType::Oracle) => {
22416 match self.config.dialect {
22419 Some(DialectType::MySQL) => self.write_keyword("JSON"),
22420 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
22421 _ => self.write_keyword("JSON"),
22422 }
22423 }
22424 _ => {
22425 self.write_keyword("ARRAY<");
22427 self.generate_data_type(element_type)?;
22428 self.write(">");
22429 }
22430 }
22431 }
22432 DataType::List { element_type } => {
22433 self.generate_data_type(element_type)?;
22435 self.write_keyword(" LIST");
22436 }
22437 DataType::Map {
22438 key_type,
22439 value_type,
22440 } => {
22441 match self.config.dialect {
22443 Some(DialectType::Materialize) => {
22444 self.write_keyword("MAP[");
22446 self.generate_data_type(key_type)?;
22447 self.write(" => ");
22448 self.generate_data_type(value_type)?;
22449 self.write("]");
22450 }
22451 Some(DialectType::Snowflake)
22452 | Some(DialectType::RisingWave)
22453 | Some(DialectType::DuckDB)
22454 | Some(DialectType::Presto)
22455 | Some(DialectType::Trino)
22456 | Some(DialectType::Athena) => {
22457 self.write_keyword("MAP(");
22458 self.generate_data_type(key_type)?;
22459 self.write(", ");
22460 self.generate_data_type(value_type)?;
22461 self.write(")");
22462 }
22463 Some(DialectType::ClickHouse) => {
22464 self.write("Map(");
22467 self.clickhouse_nullable_depth = -1; self.generate_data_type(key_type)?;
22469 self.clickhouse_nullable_depth = 0;
22470 self.write(", ");
22471 self.generate_data_type(value_type)?;
22472 self.write(")");
22473 }
22474 _ => {
22475 self.write_keyword("MAP<");
22476 self.generate_data_type(key_type)?;
22477 self.write(", ");
22478 self.generate_data_type(value_type)?;
22479 self.write(">");
22480 }
22481 }
22482 }
22483 DataType::Vector {
22484 element_type,
22485 dimension,
22486 } => {
22487 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
22488 self.write_keyword("VECTOR(");
22490 if let Some(dim) = dimension {
22491 self.write(&dim.to_string());
22492 }
22493 let type_alias = element_type.as_ref().and_then(|et| match et.as_ref() {
22495 DataType::TinyInt { .. } => Some("I8"),
22496 DataType::SmallInt { .. } => Some("I16"),
22497 DataType::Int { .. } => Some("I32"),
22498 DataType::BigInt { .. } => Some("I64"),
22499 DataType::Float { .. } => Some("F32"),
22500 DataType::Double { .. } => Some("F64"),
22501 _ => None,
22502 });
22503 if let Some(alias) = type_alias {
22504 if dimension.is_some() {
22505 self.write(", ");
22506 }
22507 self.write(alias);
22508 }
22509 self.write(")");
22510 } else {
22511 self.write_keyword("VECTOR(");
22513 if let Some(ref et) = element_type {
22514 self.generate_data_type(et)?;
22515 if dimension.is_some() {
22516 self.write(", ");
22517 }
22518 }
22519 if let Some(dim) = dimension {
22520 self.write(&dim.to_string());
22521 }
22522 self.write(")");
22523 }
22524 }
22525 DataType::Object { fields, modifier } => {
22526 self.write_keyword("OBJECT(");
22527 for (i, (name, dt, not_null)) in fields.iter().enumerate() {
22528 if i > 0 {
22529 self.write(", ");
22530 }
22531 self.write(name);
22532 self.write(" ");
22533 self.generate_data_type(dt)?;
22534 if *not_null {
22535 self.write_keyword(" NOT NULL");
22536 }
22537 }
22538 self.write(")");
22539 if let Some(mod_str) = modifier {
22540 self.write(" ");
22541 self.write_keyword(mod_str);
22542 }
22543 }
22544 DataType::Struct { fields, nested } => {
22545 match self.config.dialect {
22547 Some(DialectType::Snowflake) => {
22548 self.write_keyword("OBJECT(");
22550 for (i, field) in fields.iter().enumerate() {
22551 if i > 0 {
22552 self.write(", ");
22553 }
22554 if !field.name.is_empty() {
22555 self.write(&field.name);
22556 self.write(" ");
22557 }
22558 self.generate_data_type(&field.data_type)?;
22559 }
22560 self.write(")");
22561 }
22562 Some(DialectType::Presto) | Some(DialectType::Trino) => {
22563 self.write_keyword("ROW(");
22565 for (i, field) in fields.iter().enumerate() {
22566 if i > 0 {
22567 self.write(", ");
22568 }
22569 if !field.name.is_empty() {
22570 self.write(&field.name);
22571 self.write(" ");
22572 }
22573 self.generate_data_type(&field.data_type)?;
22574 }
22575 self.write(")");
22576 }
22577 Some(DialectType::DuckDB) => {
22578 self.write_keyword("STRUCT(");
22580 for (i, field) in fields.iter().enumerate() {
22581 if i > 0 {
22582 self.write(", ");
22583 }
22584 if !field.name.is_empty() {
22585 self.write(&field.name);
22586 self.write(" ");
22587 }
22588 self.generate_data_type(&field.data_type)?;
22589 }
22590 self.write(")");
22591 }
22592 Some(DialectType::ClickHouse) => {
22593 self.write("Tuple(");
22595 for (i, field) in fields.iter().enumerate() {
22596 if i > 0 {
22597 self.write(", ");
22598 }
22599 if !field.name.is_empty() {
22600 self.write(&field.name);
22601 self.write(" ");
22602 }
22603 self.generate_data_type(&field.data_type)?;
22604 }
22605 self.write(")");
22606 }
22607 Some(DialectType::SingleStore) => {
22608 self.write_keyword("RECORD(");
22610 for (i, field) in fields.iter().enumerate() {
22611 if i > 0 {
22612 self.write(", ");
22613 }
22614 if !field.name.is_empty() {
22615 self.write(&field.name);
22616 self.write(" ");
22617 }
22618 self.generate_data_type(&field.data_type)?;
22619 }
22620 self.write(")");
22621 }
22622 _ => {
22623 let force_angle_brackets = matches!(
22625 self.config.dialect,
22626 Some(DialectType::Hive)
22627 | Some(DialectType::Spark)
22628 | Some(DialectType::Databricks)
22629 );
22630 if *nested && !force_angle_brackets {
22631 self.write_keyword("STRUCT(");
22632 for (i, field) in fields.iter().enumerate() {
22633 if i > 0 {
22634 self.write(", ");
22635 }
22636 if !field.name.is_empty() {
22637 self.write(&field.name);
22638 self.write(" ");
22639 }
22640 self.generate_data_type(&field.data_type)?;
22641 }
22642 self.write(")");
22643 } else {
22644 self.write_keyword("STRUCT<");
22645 for (i, field) in fields.iter().enumerate() {
22646 if i > 0 {
22647 self.write(", ");
22648 }
22649 if !field.name.is_empty() {
22650 self.write(&field.name);
22652 self.write(self.config.struct_field_sep);
22653 }
22654 self.generate_data_type(&field.data_type)?;
22656 if let Some(comment) = &field.comment {
22658 self.write(" COMMENT '");
22659 self.write(comment);
22660 self.write("'");
22661 }
22662 if !field.options.is_empty() {
22664 self.write(" ");
22665 self.generate_options_clause(&field.options)?;
22666 }
22667 }
22668 self.write(">");
22669 }
22670 }
22671 }
22672 }
22673 DataType::Enum {
22674 values,
22675 assignments,
22676 } => {
22677 if self.config.dialect == Some(DialectType::ClickHouse) {
22680 self.write("Enum(");
22681 } else {
22682 self.write_keyword("ENUM(");
22683 }
22684 for (i, val) in values.iter().enumerate() {
22685 if i > 0 {
22686 self.write(", ");
22687 }
22688 self.write("'");
22689 self.write(val);
22690 self.write("'");
22691 if let Some(Some(assignment)) = assignments.get(i) {
22692 self.write(" = ");
22693 self.write(assignment);
22694 }
22695 }
22696 self.write(")");
22697 }
22698 DataType::Set { values } => {
22699 self.write_keyword("SET(");
22701 for (i, val) in values.iter().enumerate() {
22702 if i > 0 {
22703 self.write(", ");
22704 }
22705 self.write("'");
22706 self.write(val);
22707 self.write("'");
22708 }
22709 self.write(")");
22710 }
22711 DataType::Union { fields } => {
22712 self.write_keyword("UNION(");
22714 for (i, (name, dt)) in fields.iter().enumerate() {
22715 if i > 0 {
22716 self.write(", ");
22717 }
22718 if !name.is_empty() {
22719 self.write(name);
22720 self.write(" ");
22721 }
22722 self.generate_data_type(dt)?;
22723 }
22724 self.write(")");
22725 }
22726 DataType::Nullable { inner } => {
22727 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
22729 self.write("Nullable(");
22730 let saved_depth = self.clickhouse_nullable_depth;
22732 self.clickhouse_nullable_depth = -1;
22733 self.generate_data_type(inner)?;
22734 self.clickhouse_nullable_depth = saved_depth;
22735 self.write(")");
22736 } else {
22737 match inner.as_ref() {
22739 DataType::Custom { name } if name.to_uppercase() == "DATETIME" => {
22740 self.generate_data_type(&DataType::Timestamp {
22741 precision: None,
22742 timezone: false,
22743 })?;
22744 }
22745 _ => {
22746 self.generate_data_type(inner)?;
22747 }
22748 }
22749 }
22750 }
22751 DataType::Custom { name } => {
22752 let name_upper = name.to_uppercase();
22754 match self.config.dialect {
22755 Some(DialectType::ClickHouse) => {
22756 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
22757 (name_upper[..idx].to_string(), &name[idx..])
22758 } else {
22759 (name_upper.clone(), "")
22760 };
22761 let mapped = match base_upper.as_str() {
22762 "DATETIME" | "TIMESTAMPTZ" | "TIMESTAMP" | "TIMESTAMPNTZ"
22763 | "SMALLDATETIME" | "DATETIME2" => "DateTime",
22764 "DATETIME64" => "DateTime64",
22765 "DATE32" => "Date32",
22766 "INT" => "Int32",
22767 "MEDIUMINT" => "Int32",
22768 "INT8" => "Int8",
22769 "INT16" => "Int16",
22770 "INT32" => "Int32",
22771 "INT64" => "Int64",
22772 "INT128" => "Int128",
22773 "INT256" => "Int256",
22774 "UINT8" => "UInt8",
22775 "UINT16" => "UInt16",
22776 "UINT32" => "UInt32",
22777 "UINT64" => "UInt64",
22778 "UINT128" => "UInt128",
22779 "UINT256" => "UInt256",
22780 "FLOAT32" => "Float32",
22781 "FLOAT64" => "Float64",
22782 "DECIMAL32" => "Decimal32",
22783 "DECIMAL64" => "Decimal64",
22784 "DECIMAL128" => "Decimal128",
22785 "DECIMAL256" => "Decimal256",
22786 "ENUM" => "Enum",
22787 "ENUM8" => "Enum8",
22788 "ENUM16" => "Enum16",
22789 "FIXEDSTRING" => "FixedString",
22790 "NESTED" => "Nested",
22791 "LOWCARDINALITY" => "LowCardinality",
22792 "NULLABLE" => "Nullable",
22793 "IPV4" => "IPv4",
22794 "IPV6" => "IPv6",
22795 "POINT" => "Point",
22796 "RING" => "Ring",
22797 "LINESTRING" => "LineString",
22798 "MULTILINESTRING" => "MultiLineString",
22799 "POLYGON" => "Polygon",
22800 "MULTIPOLYGON" => "MultiPolygon",
22801 "AGGREGATEFUNCTION" => "AggregateFunction",
22802 "SIMPLEAGGREGATEFUNCTION" => "SimpleAggregateFunction",
22803 "DYNAMIC" => "Dynamic",
22804 _ => "",
22805 };
22806 if mapped.is_empty() {
22807 self.write(name);
22808 } else {
22809 self.write(mapped);
22810 self.write(suffix);
22811 }
22812 }
22813 Some(DialectType::MySQL)
22814 if name_upper == "TIMESTAMPTZ" || name_upper == "TIMESTAMPLTZ" =>
22815 {
22816 self.write_keyword("TIMESTAMP");
22818 }
22819 Some(DialectType::TSQL) if name_upper == "VARIANT" => {
22820 self.write_keyword("SQL_VARIANT");
22821 }
22822 Some(DialectType::DuckDB) if name_upper == "DECFLOAT" => {
22823 self.write_keyword("DECIMAL(38, 5)");
22824 }
22825 Some(DialectType::Exasol) => {
22826 match name_upper.as_str() {
22828 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => self.write_keyword("VARCHAR"),
22830 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => self.write_keyword("VARCHAR"),
22832 "MEDIUMINT" => self.write_keyword("INT"),
22834 "DECIMAL32" | "DECIMAL64" | "DECIMAL128" | "DECIMAL256" => {
22836 self.write_keyword("DECIMAL")
22837 }
22838 "DATETIME" => self.write_keyword("TIMESTAMP"),
22840 "TIMESTAMPLTZ" => self.write_keyword("TIMESTAMP WITH LOCAL TIME ZONE"),
22841 _ => self.write(name),
22842 }
22843 }
22844 Some(DialectType::Dremio) => {
22845 match name_upper.as_str() {
22847 "TIMESTAMPNTZ" | "DATETIME" => self.write_keyword("TIMESTAMP"),
22848 "ARRAY" => self.write_keyword("LIST"),
22849 "NCHAR" => self.write_keyword("VARCHAR"),
22850 _ => self.write(name),
22851 }
22852 }
22853 _ => {
22855 let (base_upper, _args_str) = if let Some(idx) = name_upper.find('(') {
22857 (name_upper[..idx].to_string(), Some(&name[idx..]))
22858 } else {
22859 (name_upper.clone(), None)
22860 };
22861
22862 match base_upper.as_str() {
22863 "INT64"
22864 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
22865 {
22866 self.write_keyword("BIGINT");
22867 }
22868 "FLOAT64"
22869 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
22870 {
22871 self.write_keyword("DOUBLE");
22872 }
22873 "BOOL"
22874 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
22875 {
22876 self.write_keyword("BOOLEAN");
22877 }
22878 "BYTES"
22879 if matches!(
22880 self.config.dialect,
22881 Some(DialectType::Spark)
22882 | Some(DialectType::Hive)
22883 | Some(DialectType::Databricks)
22884 ) =>
22885 {
22886 self.write_keyword("BINARY");
22887 }
22888 "BYTES"
22889 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
22890 {
22891 self.write_keyword("VARBINARY");
22892 }
22893 "DATETIME2" | "SMALLDATETIME"
22895 if !matches!(
22896 self.config.dialect,
22897 Some(DialectType::TSQL) | Some(DialectType::Fabric)
22898 ) =>
22899 {
22900 if matches!(
22902 self.config.dialect,
22903 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
22904 ) {
22905 self.write_keyword("TIMESTAMP");
22906 if let Some(args) = _args_str {
22907 self.write(args);
22908 }
22909 } else {
22910 self.write_keyword("TIMESTAMP");
22911 }
22912 }
22913 "DATETIMEOFFSET"
22915 if !matches!(
22916 self.config.dialect,
22917 Some(DialectType::TSQL) | Some(DialectType::Fabric)
22918 ) =>
22919 {
22920 if matches!(
22921 self.config.dialect,
22922 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
22923 ) {
22924 self.write_keyword("TIMESTAMPTZ");
22925 if let Some(args) = _args_str {
22926 self.write(args);
22927 }
22928 } else {
22929 self.write_keyword("TIMESTAMPTZ");
22930 }
22931 }
22932 "UNIQUEIDENTIFIER"
22934 if !matches!(
22935 self.config.dialect,
22936 Some(DialectType::TSQL) | Some(DialectType::Fabric)
22937 ) =>
22938 {
22939 match self.config.dialect {
22940 Some(DialectType::Spark)
22941 | Some(DialectType::Databricks)
22942 | Some(DialectType::Hive) => self.write_keyword("STRING"),
22943 _ => self.write_keyword("UUID"),
22944 }
22945 }
22946 "BIT"
22948 if !matches!(
22949 self.config.dialect,
22950 Some(DialectType::TSQL)
22951 | Some(DialectType::Fabric)
22952 | Some(DialectType::PostgreSQL)
22953 | Some(DialectType::MySQL)
22954 | Some(DialectType::DuckDB)
22955 ) =>
22956 {
22957 self.write_keyword("BOOLEAN");
22958 }
22959 "NVARCHAR"
22961 if !matches!(
22962 self.config.dialect,
22963 Some(DialectType::TSQL) | Some(DialectType::Fabric)
22964 ) =>
22965 {
22966 match self.config.dialect {
22967 Some(DialectType::Oracle) => {
22968 self.write_keyword("NVARCHAR2");
22970 if let Some(args) = _args_str {
22971 self.write(args);
22972 }
22973 }
22974 Some(DialectType::BigQuery) => {
22975 self.write_keyword("STRING");
22977 }
22978 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
22979 self.write_keyword("TEXT");
22980 if let Some(args) = _args_str {
22981 self.write(args);
22982 }
22983 }
22984 Some(DialectType::Hive) => {
22985 self.write_keyword("STRING");
22987 }
22988 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
22989 if _args_str.is_some() {
22990 self.write_keyword("VARCHAR");
22991 self.write(_args_str.unwrap());
22992 } else {
22993 self.write_keyword("STRING");
22994 }
22995 }
22996 _ => {
22997 self.write_keyword("VARCHAR");
22998 if let Some(args) = _args_str {
22999 self.write(args);
23000 }
23001 }
23002 }
23003 }
23004 "NCHAR"
23006 if !matches!(
23007 self.config.dialect,
23008 Some(DialectType::TSQL) | Some(DialectType::Fabric)
23009 ) =>
23010 {
23011 match self.config.dialect {
23012 Some(DialectType::Oracle) => {
23013 self.write_keyword("NCHAR");
23015 if let Some(args) = _args_str {
23016 self.write(args);
23017 }
23018 }
23019 Some(DialectType::BigQuery) => {
23020 self.write_keyword("STRING");
23022 }
23023 Some(DialectType::Hive) => {
23024 self.write_keyword("STRING");
23026 }
23027 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
23028 self.write_keyword("TEXT");
23029 if let Some(args) = _args_str {
23030 self.write(args);
23031 }
23032 }
23033 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
23034 if _args_str.is_some() {
23035 self.write_keyword("CHAR");
23036 self.write(_args_str.unwrap());
23037 } else {
23038 self.write_keyword("STRING");
23039 }
23040 }
23041 _ => {
23042 self.write_keyword("CHAR");
23043 if let Some(args) = _args_str {
23044 self.write(args);
23045 }
23046 }
23047 }
23048 }
23049 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => match self.config.dialect {
23052 Some(DialectType::MySQL)
23053 | Some(DialectType::SingleStore)
23054 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
23055 Some(DialectType::Spark)
23056 | Some(DialectType::Databricks)
23057 | Some(DialectType::Hive) => self.write_keyword("TEXT"),
23058 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
23059 Some(DialectType::Presto)
23060 | Some(DialectType::Trino)
23061 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
23062 Some(DialectType::Snowflake)
23063 | Some(DialectType::Redshift)
23064 | Some(DialectType::Dremio) => self.write_keyword("VARCHAR"),
23065 _ => self.write_keyword("TEXT"),
23066 },
23067 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => match self.config.dialect {
23070 Some(DialectType::MySQL)
23071 | Some(DialectType::SingleStore)
23072 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
23073 Some(DialectType::Spark)
23074 | Some(DialectType::Databricks)
23075 | Some(DialectType::Hive) => self.write_keyword("BLOB"),
23076 Some(DialectType::DuckDB) => self.write_keyword("VARBINARY"),
23077 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
23078 Some(DialectType::Presto)
23079 | Some(DialectType::Trino)
23080 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
23081 Some(DialectType::Snowflake)
23082 | Some(DialectType::Redshift)
23083 | Some(DialectType::Dremio) => self.write_keyword("VARBINARY"),
23084 _ => self.write_keyword("BLOB"),
23085 },
23086 "LONGVARCHAR" => match self.config.dialect {
23088 Some(DialectType::SQLite) => self.write_keyword("TEXT"),
23089 _ => self.write_keyword("VARCHAR"),
23090 },
23091 "DATETIME" => {
23093 match self.config.dialect {
23094 Some(DialectType::MySQL)
23095 | Some(DialectType::Doris)
23096 | Some(DialectType::StarRocks)
23097 | Some(DialectType::TSQL)
23098 | Some(DialectType::Fabric)
23099 | Some(DialectType::BigQuery)
23100 | Some(DialectType::SQLite)
23101 | Some(DialectType::Snowflake) => {
23102 self.write_keyword("DATETIME");
23103 if let Some(args) = _args_str {
23104 self.write(args);
23105 }
23106 }
23107 Some(_) => {
23108 self.write_keyword("TIMESTAMP");
23110 if let Some(args) = _args_str {
23111 self.write(args);
23112 }
23113 }
23114 None => {
23115 self.write(name);
23117 }
23118 }
23119 }
23120 "VARCHAR2"
23122 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
23123 {
23124 match self.config.dialect {
23125 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
23126 self.write_keyword("TEXT");
23127 }
23128 Some(DialectType::Hive)
23129 | Some(DialectType::Spark)
23130 | Some(DialectType::Databricks)
23131 | Some(DialectType::BigQuery)
23132 | Some(DialectType::ClickHouse)
23133 | Some(DialectType::StarRocks)
23134 | Some(DialectType::Doris) => {
23135 self.write_keyword("STRING");
23136 }
23137 _ => {
23138 self.write_keyword("VARCHAR");
23139 if let Some(args) = _args_str {
23140 self.write(args);
23141 }
23142 }
23143 }
23144 }
23145 "NVARCHAR2"
23146 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
23147 {
23148 match self.config.dialect {
23149 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
23150 self.write_keyword("TEXT");
23151 }
23152 Some(DialectType::Hive)
23153 | Some(DialectType::Spark)
23154 | Some(DialectType::Databricks)
23155 | Some(DialectType::BigQuery)
23156 | Some(DialectType::ClickHouse)
23157 | Some(DialectType::StarRocks)
23158 | Some(DialectType::Doris) => {
23159 self.write_keyword("STRING");
23160 }
23161 _ => {
23162 self.write_keyword("VARCHAR");
23163 if let Some(args) = _args_str {
23164 self.write(args);
23165 }
23166 }
23167 }
23168 }
23169 _ => self.write(name),
23170 }
23171 }
23172 }
23173 }
23174 DataType::Geometry { subtype, srid } => {
23175 match self.config.dialect {
23177 Some(DialectType::MySQL) => {
23178 if let Some(sub) = subtype {
23180 self.write_keyword(sub);
23181 if let Some(s) = srid {
23182 self.write(" SRID ");
23183 self.write(&s.to_string());
23184 }
23185 } else {
23186 self.write_keyword("GEOMETRY");
23187 }
23188 }
23189 Some(DialectType::BigQuery) => {
23190 self.write_keyword("GEOGRAPHY");
23192 }
23193 Some(DialectType::Teradata) => {
23194 self.write_keyword("ST_GEOMETRY");
23196 if subtype.is_some() || srid.is_some() {
23197 self.write("(");
23198 if let Some(sub) = subtype {
23199 self.write_keyword(sub);
23200 }
23201 if let Some(s) = srid {
23202 if subtype.is_some() {
23203 self.write(", ");
23204 }
23205 self.write(&s.to_string());
23206 }
23207 self.write(")");
23208 }
23209 }
23210 _ => {
23211 self.write_keyword("GEOMETRY");
23213 if subtype.is_some() || srid.is_some() {
23214 self.write("(");
23215 if let Some(sub) = subtype {
23216 self.write_keyword(sub);
23217 }
23218 if let Some(s) = srid {
23219 if subtype.is_some() {
23220 self.write(", ");
23221 }
23222 self.write(&s.to_string());
23223 }
23224 self.write(")");
23225 }
23226 }
23227 }
23228 }
23229 DataType::Geography { subtype, srid } => {
23230 match self.config.dialect {
23232 Some(DialectType::MySQL) => {
23233 if let Some(sub) = subtype {
23235 self.write_keyword(sub);
23236 } else {
23237 self.write_keyword("GEOMETRY");
23238 }
23239 let effective_srid = srid.unwrap_or(4326);
23241 self.write(" SRID ");
23242 self.write(&effective_srid.to_string());
23243 }
23244 Some(DialectType::BigQuery) => {
23245 self.write_keyword("GEOGRAPHY");
23247 }
23248 Some(DialectType::Snowflake) => {
23249 self.write_keyword("GEOGRAPHY");
23251 }
23252 _ => {
23253 self.write_keyword("GEOGRAPHY");
23255 if subtype.is_some() || srid.is_some() {
23256 self.write("(");
23257 if let Some(sub) = subtype {
23258 self.write_keyword(sub);
23259 }
23260 if let Some(s) = srid {
23261 if subtype.is_some() {
23262 self.write(", ");
23263 }
23264 self.write(&s.to_string());
23265 }
23266 self.write(")");
23267 }
23268 }
23269 }
23270 }
23271 DataType::CharacterSet { name } => {
23272 self.write_keyword("CHAR CHARACTER SET ");
23274 self.write(name);
23275 }
23276 _ => self.write("UNKNOWN"),
23277 }
23278 Ok(())
23279 }
23280
23281 fn write(&mut self, s: &str) {
23284 self.output.push_str(s);
23285 }
23286
23287 fn write_space(&mut self) {
23288 self.output.push(' ');
23289 }
23290
23291 fn write_keyword(&mut self, keyword: &str) {
23292 if self.config.uppercase_keywords {
23293 self.output.push_str(keyword);
23294 } else {
23295 self.output.push_str(&keyword.to_lowercase());
23296 }
23297 }
23298
23299 fn write_func_name(&mut self, name: &str) {
23301 let normalized = self.normalize_func_name(name);
23302 self.output.push_str(&normalized);
23303 }
23304
23305 fn convert_strptime_to_exasol_format(format: &str) -> String {
23309 let mut result = String::new();
23310 let chars: Vec<char> = format.chars().collect();
23311 let mut i = 0;
23312 while i < chars.len() {
23313 if chars[i] == '%' && i + 1 < chars.len() {
23314 let spec = chars[i + 1];
23315 let exasol_spec = match spec {
23316 'Y' => "YYYY",
23317 'y' => "YY",
23318 'm' => "MM",
23319 'd' => "DD",
23320 'H' => "HH",
23321 'M' => "MI",
23322 'S' => "SS",
23323 'a' => "DY", 'A' => "DAY", 'b' => "MON", 'B' => "MONTH", 'I' => "H12", 'u' => "ID", 'V' => "IW", 'G' => "IYYY", 'W' => "UW", 'U' => "UW", 'z' => "Z", _ => {
23335 result.push('%');
23337 result.push(spec);
23338 i += 2;
23339 continue;
23340 }
23341 };
23342 result.push_str(exasol_spec);
23343 i += 2;
23344 } else {
23345 result.push(chars[i]);
23346 i += 1;
23347 }
23348 }
23349 result
23350 }
23351
23352 fn convert_strptime_to_postgres_format(format: &str) -> String {
23356 let mut result = String::new();
23357 let chars: Vec<char> = format.chars().collect();
23358 let mut i = 0;
23359 while i < chars.len() {
23360 if chars[i] == '%' && i + 1 < chars.len() {
23361 if chars[i + 1] == '-' && i + 2 < chars.len() {
23363 let spec = chars[i + 2];
23364 let pg_spec = match spec {
23365 'd' => "FMDD",
23366 'm' => "FMMM",
23367 'H' => "FMHH24",
23368 'M' => "FMMI",
23369 'S' => "FMSS",
23370 _ => {
23371 result.push('%');
23372 result.push('-');
23373 result.push(spec);
23374 i += 3;
23375 continue;
23376 }
23377 };
23378 result.push_str(pg_spec);
23379 i += 3;
23380 continue;
23381 }
23382 let spec = chars[i + 1];
23383 let pg_spec = match spec {
23384 'Y' => "YYYY",
23385 'y' => "YY",
23386 'm' => "MM",
23387 'd' => "DD",
23388 'H' => "HH24",
23389 'I' => "HH12",
23390 'M' => "MI",
23391 'S' => "SS",
23392 'f' => "US", 'u' => "D", 'j' => "DDD", 'z' => "OF", 'Z' => "TZ", 'A' => "TMDay", 'a' => "TMDy", 'b' => "TMMon", 'B' => "TMMonth", 'U' => "WW", _ => {
23403 result.push('%');
23405 result.push(spec);
23406 i += 2;
23407 continue;
23408 }
23409 };
23410 result.push_str(pg_spec);
23411 i += 2;
23412 } else {
23413 result.push(chars[i]);
23414 i += 1;
23415 }
23416 }
23417 result
23418 }
23419
23420 fn write_limit_expr(&mut self, expr: &Expression) -> Result<()> {
23422 if self.config.limit_only_literals {
23423 if let Some(value) = Self::try_evaluate_constant(expr) {
23424 self.write(&value.to_string());
23425 return Ok(());
23426 }
23427 }
23428 self.generate_expression(expr)
23429 }
23430
23431 fn write_formatted_comment(&mut self, comment: &str) {
23435 let content = if comment.starts_with("/*") && comment.ends_with("*/") {
23438 &comment[2..comment.len() - 2]
23441 } else if comment.starts_with("--") {
23442 &comment[2..]
23445 } else {
23446 comment
23448 };
23449 if content.trim().is_empty() {
23451 return;
23452 }
23453 self.output.push_str("/*");
23455 if !content.starts_with(' ') {
23456 self.output.push(' ');
23457 }
23458 self.output.push_str(content);
23459 if !content.ends_with(' ') {
23460 self.output.push(' ');
23461 }
23462 self.output.push_str("*/");
23463 }
23464
23465 fn escape_block_for_single_quote(&self, block: &str) -> String {
23468 let escape_backslash = matches!(
23469 self.config.dialect,
23470 Some(crate::dialects::DialectType::Snowflake)
23471 );
23472 let mut escaped = String::with_capacity(block.len() + 4);
23473 for ch in block.chars() {
23474 if ch == '\'' {
23475 escaped.push('\\');
23476 escaped.push('\'');
23477 } else if escape_backslash && ch == '\\' {
23478 escaped.push('\\');
23479 escaped.push('\\');
23480 } else {
23481 escaped.push(ch);
23482 }
23483 }
23484 escaped
23485 }
23486
23487 fn write_newline(&mut self) {
23488 self.output.push('\n');
23489 }
23490
23491 fn write_indent(&mut self) {
23492 for _ in 0..self.indent_level {
23493 self.output.push_str(&self.config.indent);
23494 }
23495 }
23496
23497 fn too_wide(&self, args: &[String]) -> bool {
23503 args.iter().map(|s| s.len()).sum::<usize>() > self.config.max_text_width
23504 }
23505
23506 fn generate_to_string(&self, expr: &Expression) -> Result<String> {
23509 let config = GeneratorConfig {
23510 pretty: false,
23511 dialect: self.config.dialect,
23512 ..Default::default()
23513 };
23514 let mut gen = Generator::with_config(config);
23515 gen.generate_expression(expr)?;
23516 Ok(gen.output)
23517 }
23518
23519 fn write_clause_condition(&mut self, keyword: &str, condition: &Expression) -> Result<()> {
23522 if self.config.pretty {
23523 self.write_newline();
23524 self.write_indent();
23525 self.write_keyword(keyword);
23526 self.write_newline();
23527 self.indent_level += 1;
23528 self.write_indent();
23529 self.generate_expression(condition)?;
23530 self.indent_level -= 1;
23531 } else {
23532 self.write_space();
23533 self.write_keyword(keyword);
23534 self.write_space();
23535 self.generate_expression(condition)?;
23536 }
23537 Ok(())
23538 }
23539
23540 fn write_clause_expressions(&mut self, keyword: &str, exprs: &[Expression]) -> Result<()> {
23543 if exprs.is_empty() {
23544 return Ok(());
23545 }
23546
23547 if self.config.pretty {
23548 self.write_newline();
23549 self.write_indent();
23550 self.write_keyword(keyword);
23551 self.write_newline();
23552 self.indent_level += 1;
23553 for (i, expr) in exprs.iter().enumerate() {
23554 if i > 0 {
23555 self.write(",");
23556 self.write_newline();
23557 }
23558 self.write_indent();
23559 self.generate_expression(expr)?;
23560 }
23561 self.indent_level -= 1;
23562 } else {
23563 self.write_space();
23564 self.write_keyword(keyword);
23565 self.write_space();
23566 for (i, expr) in exprs.iter().enumerate() {
23567 if i > 0 {
23568 self.write(", ");
23569 }
23570 self.generate_expression(expr)?;
23571 }
23572 }
23573 Ok(())
23574 }
23575
23576 fn write_order_clause(&mut self, keyword: &str, orderings: &[Ordered]) -> Result<()> {
23578 if orderings.is_empty() {
23579 return Ok(());
23580 }
23581
23582 if self.config.pretty {
23583 self.write_newline();
23584 self.write_indent();
23585 self.write_keyword(keyword);
23586 self.write_newline();
23587 self.indent_level += 1;
23588 for (i, ordered) in orderings.iter().enumerate() {
23589 if i > 0 {
23590 self.write(",");
23591 self.write_newline();
23592 }
23593 self.write_indent();
23594 self.generate_ordered(ordered)?;
23595 }
23596 self.indent_level -= 1;
23597 } else {
23598 self.write_space();
23599 self.write_keyword(keyword);
23600 self.write_space();
23601 for (i, ordered) in orderings.iter().enumerate() {
23602 if i > 0 {
23603 self.write(", ");
23604 }
23605 self.generate_ordered(ordered)?;
23606 }
23607 }
23608 Ok(())
23609 }
23610
23611 fn write_window_clause(&mut self, windows: &[NamedWindow]) -> Result<()> {
23613 if windows.is_empty() {
23614 return Ok(());
23615 }
23616
23617 if self.config.pretty {
23618 self.write_newline();
23619 self.write_indent();
23620 self.write_keyword("WINDOW");
23621 self.write_newline();
23622 self.indent_level += 1;
23623 for (i, named_window) in windows.iter().enumerate() {
23624 if i > 0 {
23625 self.write(",");
23626 self.write_newline();
23627 }
23628 self.write_indent();
23629 self.generate_identifier(&named_window.name)?;
23630 self.write_space();
23631 self.write_keyword("AS");
23632 self.write(" (");
23633 self.generate_over(&named_window.spec)?;
23634 self.write(")");
23635 }
23636 self.indent_level -= 1;
23637 } else {
23638 self.write_space();
23639 self.write_keyword("WINDOW");
23640 self.write_space();
23641 for (i, named_window) in windows.iter().enumerate() {
23642 if i > 0 {
23643 self.write(", ");
23644 }
23645 self.generate_identifier(&named_window.name)?;
23646 self.write_space();
23647 self.write_keyword("AS");
23648 self.write(" (");
23649 self.generate_over(&named_window.spec)?;
23650 self.write(")");
23651 }
23652 }
23653 Ok(())
23654 }
23655
23656 fn generate_ai_agg(&mut self, e: &AIAgg) -> Result<()> {
23658 self.write_keyword("AI_AGG");
23660 self.write("(");
23661 self.generate_expression(&e.this)?;
23662 self.write(", ");
23663 self.generate_expression(&e.expression)?;
23664 self.write(")");
23665 Ok(())
23666 }
23667
23668 fn generate_ai_classify(&mut self, e: &AIClassify) -> Result<()> {
23669 self.write_keyword("AI_CLASSIFY");
23671 self.write("(");
23672 self.generate_expression(&e.this)?;
23673 if let Some(categories) = &e.categories {
23674 self.write(", ");
23675 self.generate_expression(categories)?;
23676 }
23677 if let Some(config) = &e.config {
23678 self.write(", ");
23679 self.generate_expression(config)?;
23680 }
23681 self.write(")");
23682 Ok(())
23683 }
23684
23685 fn generate_add_partition(&mut self, e: &AddPartition) -> Result<()> {
23686 self.write_keyword("ADD");
23688 self.write_space();
23689 if e.exists {
23690 self.write_keyword("IF NOT EXISTS");
23691 self.write_space();
23692 }
23693 self.generate_expression(&e.this)?;
23694 if let Some(location) = &e.location {
23695 self.write_space();
23696 self.generate_expression(location)?;
23697 }
23698 Ok(())
23699 }
23700
23701 fn generate_algorithm_property(&mut self, e: &AlgorithmProperty) -> Result<()> {
23702 self.write_keyword("ALGORITHM");
23704 self.write("=");
23705 self.generate_expression(&e.this)?;
23706 Ok(())
23707 }
23708
23709 fn generate_aliases(&mut self, e: &Aliases) -> Result<()> {
23710 self.generate_expression(&e.this)?;
23712 self.write_space();
23713 self.write_keyword("AS");
23714 self.write(" (");
23715 for (i, expr) in e.expressions.iter().enumerate() {
23716 if i > 0 {
23717 self.write(", ");
23718 }
23719 self.generate_expression(expr)?;
23720 }
23721 self.write(")");
23722 Ok(())
23723 }
23724
23725 fn generate_allowed_values_property(&mut self, e: &AllowedValuesProperty) -> Result<()> {
23726 self.write_keyword("ALLOWED_VALUES");
23728 self.write_space();
23729 for (i, expr) in e.expressions.iter().enumerate() {
23730 if i > 0 {
23731 self.write(", ");
23732 }
23733 self.generate_expression(expr)?;
23734 }
23735 Ok(())
23736 }
23737
23738 fn generate_alter_column(&mut self, e: &AlterColumn) -> Result<()> {
23739 self.write_keyword("ALTER COLUMN");
23741 self.write_space();
23742 self.generate_expression(&e.this)?;
23743
23744 if let Some(dtype) = &e.dtype {
23745 self.write_space();
23746 self.write_keyword("SET DATA TYPE");
23747 self.write_space();
23748 self.generate_expression(dtype)?;
23749 if let Some(collate) = &e.collate {
23750 self.write_space();
23751 self.write_keyword("COLLATE");
23752 self.write_space();
23753 self.generate_expression(collate)?;
23754 }
23755 if let Some(using) = &e.using {
23756 self.write_space();
23757 self.write_keyword("USING");
23758 self.write_space();
23759 self.generate_expression(using)?;
23760 }
23761 } else if let Some(default) = &e.default {
23762 self.write_space();
23763 self.write_keyword("SET DEFAULT");
23764 self.write_space();
23765 self.generate_expression(default)?;
23766 } else if let Some(comment) = &e.comment {
23767 self.write_space();
23768 self.write_keyword("COMMENT");
23769 self.write_space();
23770 self.generate_expression(comment)?;
23771 } else if let Some(drop) = &e.drop {
23772 self.write_space();
23773 self.write_keyword("DROP");
23774 self.write_space();
23775 self.generate_expression(drop)?;
23776 } else if let Some(visible) = &e.visible {
23777 self.write_space();
23778 self.generate_expression(visible)?;
23779 } else if let Some(rename_to) = &e.rename_to {
23780 self.write_space();
23781 self.write_keyword("RENAME TO");
23782 self.write_space();
23783 self.generate_expression(rename_to)?;
23784 } else if let Some(allow_null) = &e.allow_null {
23785 self.write_space();
23786 self.generate_expression(allow_null)?;
23787 }
23788 Ok(())
23789 }
23790
23791 fn generate_alter_session(&mut self, e: &AlterSession) -> Result<()> {
23792 self.write_keyword("ALTER SESSION");
23794 self.write_space();
23795 if e.unset.is_some() {
23796 self.write_keyword("UNSET");
23797 } else {
23798 self.write_keyword("SET");
23799 }
23800 self.write_space();
23801 for (i, expr) in e.expressions.iter().enumerate() {
23802 if i > 0 {
23803 self.write(", ");
23804 }
23805 self.generate_expression(expr)?;
23806 }
23807 Ok(())
23808 }
23809
23810 fn generate_alter_set(&mut self, e: &AlterSet) -> Result<()> {
23811 self.write_keyword("SET");
23813
23814 if let Some(opt) = &e.option {
23816 self.write_space();
23817 self.generate_expression(opt)?;
23818 }
23819
23820 if !e.expressions.is_empty() {
23823 let is_properties = e
23825 .expressions
23826 .iter()
23827 .any(|expr| matches!(expr, Expression::Eq(_)));
23828 if is_properties && e.option.is_none() {
23829 self.write_space();
23830 self.write_keyword("PROPERTIES");
23831 }
23832 self.write_space();
23833 for (i, expr) in e.expressions.iter().enumerate() {
23834 if i > 0 {
23835 self.write(", ");
23836 }
23837 self.generate_expression(expr)?;
23838 }
23839 }
23840
23841 if let Some(file_format) = &e.file_format {
23843 self.write(" ");
23844 self.write_keyword("STAGE_FILE_FORMAT");
23845 self.write(" = (");
23846 self.generate_space_separated_properties(file_format)?;
23847 self.write(")");
23848 }
23849
23850 if let Some(copy_options) = &e.copy_options {
23852 self.write(" ");
23853 self.write_keyword("STAGE_COPY_OPTIONS");
23854 self.write(" = (");
23855 self.generate_space_separated_properties(copy_options)?;
23856 self.write(")");
23857 }
23858
23859 if let Some(tag) = &e.tag {
23861 self.write(" ");
23862 self.write_keyword("TAG");
23863 self.write(" ");
23864 self.generate_expression(tag)?;
23865 }
23866
23867 Ok(())
23868 }
23869
23870 fn generate_space_separated_properties(&mut self, expr: &Expression) -> Result<()> {
23872 match expr {
23873 Expression::Tuple(t) => {
23874 for (i, prop) in t.expressions.iter().enumerate() {
23875 if i > 0 {
23876 self.write(" ");
23877 }
23878 self.generate_expression(prop)?;
23879 }
23880 }
23881 _ => {
23882 self.generate_expression(expr)?;
23883 }
23884 }
23885 Ok(())
23886 }
23887
23888 fn generate_alter_sort_key(&mut self, e: &AlterSortKey) -> Result<()> {
23889 self.write_keyword("ALTER");
23891 if e.compound.is_some() {
23892 self.write_space();
23893 self.write_keyword("COMPOUND");
23894 }
23895 self.write_space();
23896 self.write_keyword("SORTKEY");
23897 self.write_space();
23898 if let Some(this) = &e.this {
23899 self.generate_expression(this)?;
23900 } else if !e.expressions.is_empty() {
23901 self.write("(");
23902 for (i, expr) in e.expressions.iter().enumerate() {
23903 if i > 0 {
23904 self.write(", ");
23905 }
23906 self.generate_expression(expr)?;
23907 }
23908 self.write(")");
23909 }
23910 Ok(())
23911 }
23912
23913 fn generate_analyze(&mut self, e: &Analyze) -> Result<()> {
23914 self.write_keyword("ANALYZE");
23916 if !e.options.is_empty() {
23917 self.write_space();
23918 for (i, opt) in e.options.iter().enumerate() {
23919 if i > 0 {
23920 self.write_space();
23921 }
23922 if let Expression::Identifier(id) = opt {
23924 self.write_keyword(&id.name);
23925 } else {
23926 self.generate_expression(opt)?;
23927 }
23928 }
23929 }
23930 if let Some(kind) = &e.kind {
23931 self.write_space();
23932 self.write_keyword(kind);
23933 }
23934 if let Some(this) = &e.this {
23935 self.write_space();
23936 self.generate_expression(this)?;
23937 }
23938 if !e.columns.is_empty() {
23940 self.write("(");
23941 for (i, col) in e.columns.iter().enumerate() {
23942 if i > 0 {
23943 self.write(", ");
23944 }
23945 self.write(col);
23946 }
23947 self.write(")");
23948 }
23949 if let Some(partition) = &e.partition {
23950 self.write_space();
23951 self.generate_expression(partition)?;
23952 }
23953 if let Some(mode) = &e.mode {
23954 self.write_space();
23955 self.generate_expression(mode)?;
23956 }
23957 if let Some(expression) = &e.expression {
23958 self.write_space();
23959 self.generate_expression(expression)?;
23960 }
23961 if !e.properties.is_empty() {
23962 self.write_space();
23963 self.write_keyword(self.config.with_properties_prefix);
23964 self.write(" (");
23965 for (i, prop) in e.properties.iter().enumerate() {
23966 if i > 0 {
23967 self.write(", ");
23968 }
23969 self.generate_expression(prop)?;
23970 }
23971 self.write(")");
23972 }
23973 Ok(())
23974 }
23975
23976 fn generate_analyze_delete(&mut self, e: &AnalyzeDelete) -> Result<()> {
23977 self.write_keyword("DELETE");
23979 if let Some(kind) = &e.kind {
23980 self.write_space();
23981 self.write_keyword(kind);
23982 }
23983 self.write_space();
23984 self.write_keyword("STATISTICS");
23985 Ok(())
23986 }
23987
23988 fn generate_analyze_histogram(&mut self, e: &AnalyzeHistogram) -> Result<()> {
23989 if let Expression::Identifier(id) = e.this.as_ref() {
23992 self.write_keyword(&id.name);
23993 } else {
23994 self.generate_expression(&e.this)?;
23995 }
23996 self.write_space();
23997 self.write_keyword("HISTOGRAM ON");
23998 self.write_space();
23999 for (i, expr) in e.expressions.iter().enumerate() {
24000 if i > 0 {
24001 self.write(", ");
24002 }
24003 self.generate_expression(expr)?;
24004 }
24005 if let Some(expression) = &e.expression {
24006 self.write_space();
24007 self.generate_expression(expression)?;
24008 }
24009 if let Some(update_options) = &e.update_options {
24010 self.write_space();
24011 self.generate_expression(update_options)?;
24012 self.write_space();
24013 self.write_keyword("UPDATE");
24014 }
24015 Ok(())
24016 }
24017
24018 fn generate_analyze_list_chained_rows(&mut self, e: &AnalyzeListChainedRows) -> Result<()> {
24019 self.write_keyword("LIST CHAINED ROWS");
24021 if let Some(expression) = &e.expression {
24022 self.write_space();
24023 self.write_keyword("INTO");
24024 self.write_space();
24025 self.generate_expression(expression)?;
24026 }
24027 Ok(())
24028 }
24029
24030 fn generate_analyze_sample(&mut self, e: &AnalyzeSample) -> Result<()> {
24031 self.write_keyword("SAMPLE");
24033 self.write_space();
24034 if let Some(sample) = &e.sample {
24035 self.generate_expression(sample)?;
24036 self.write_space();
24037 }
24038 self.write_keyword(&e.kind);
24039 Ok(())
24040 }
24041
24042 fn generate_analyze_statistics(&mut self, e: &AnalyzeStatistics) -> Result<()> {
24043 self.write_keyword(&e.kind);
24045 if let Some(option) = &e.option {
24046 self.write_space();
24047 self.generate_expression(option)?;
24048 }
24049 self.write_space();
24050 self.write_keyword("STATISTICS");
24051 if let Some(this) = &e.this {
24052 self.write_space();
24053 self.generate_expression(this)?;
24054 }
24055 if !e.expressions.is_empty() {
24056 self.write_space();
24057 for (i, expr) in e.expressions.iter().enumerate() {
24058 if i > 0 {
24059 self.write(", ");
24060 }
24061 self.generate_expression(expr)?;
24062 }
24063 }
24064 Ok(())
24065 }
24066
24067 fn generate_analyze_validate(&mut self, e: &AnalyzeValidate) -> Result<()> {
24068 self.write_keyword("VALIDATE");
24070 self.write_space();
24071 self.write_keyword(&e.kind);
24072 if let Some(this) = &e.this {
24073 self.write_space();
24074 if let Expression::Identifier(id) = this.as_ref() {
24076 self.write_keyword(&id.name);
24077 } else {
24078 self.generate_expression(this)?;
24079 }
24080 }
24081 if let Some(expression) = &e.expression {
24082 self.write_space();
24083 self.write_keyword("INTO");
24084 self.write_space();
24085 self.generate_expression(expression)?;
24086 }
24087 Ok(())
24088 }
24089
24090 fn generate_analyze_with(&mut self, e: &AnalyzeWith) -> Result<()> {
24091 self.write_keyword("WITH");
24093 self.write_space();
24094 for (i, expr) in e.expressions.iter().enumerate() {
24095 if i > 0 {
24096 self.write(", ");
24097 }
24098 self.generate_expression(expr)?;
24099 }
24100 Ok(())
24101 }
24102
24103 fn generate_anonymous(&mut self, e: &Anonymous) -> Result<()> {
24104 self.generate_expression(&e.this)?;
24107 self.write("(");
24108 for (i, arg) in e.expressions.iter().enumerate() {
24109 if i > 0 {
24110 self.write(", ");
24111 }
24112 self.generate_expression(arg)?;
24113 }
24114 self.write(")");
24115 Ok(())
24116 }
24117
24118 fn generate_anonymous_agg_func(&mut self, e: &AnonymousAggFunc) -> Result<()> {
24119 self.generate_expression(&e.this)?;
24121 self.write("(");
24122 for (i, arg) in e.expressions.iter().enumerate() {
24123 if i > 0 {
24124 self.write(", ");
24125 }
24126 self.generate_expression(arg)?;
24127 }
24128 self.write(")");
24129 Ok(())
24130 }
24131
24132 fn generate_apply(&mut self, e: &Apply) -> Result<()> {
24133 self.generate_expression(&e.this)?;
24135 self.write_space();
24136 self.write_keyword("APPLY");
24137 self.write("(");
24138 self.generate_expression(&e.expression)?;
24139 self.write(")");
24140 Ok(())
24141 }
24142
24143 fn generate_approx_percentile_estimate(&mut self, e: &ApproxPercentileEstimate) -> Result<()> {
24144 self.write_keyword("APPROX_PERCENTILE_ESTIMATE");
24146 self.write("(");
24147 self.generate_expression(&e.this)?;
24148 if let Some(percentile) = &e.percentile {
24149 self.write(", ");
24150 self.generate_expression(percentile)?;
24151 }
24152 self.write(")");
24153 Ok(())
24154 }
24155
24156 fn generate_approx_quantile(&mut self, e: &ApproxQuantile) -> Result<()> {
24157 self.write_keyword("APPROX_QUANTILE");
24159 self.write("(");
24160 self.generate_expression(&e.this)?;
24161 if let Some(quantile) = &e.quantile {
24162 self.write(", ");
24163 self.generate_expression(quantile)?;
24164 }
24165 if let Some(accuracy) = &e.accuracy {
24166 self.write(", ");
24167 self.generate_expression(accuracy)?;
24168 }
24169 if let Some(weight) = &e.weight {
24170 self.write(", ");
24171 self.generate_expression(weight)?;
24172 }
24173 self.write(")");
24174 Ok(())
24175 }
24176
24177 fn generate_approx_quantiles(&mut self, e: &ApproxQuantiles) -> Result<()> {
24178 self.write_keyword("APPROX_QUANTILES");
24180 self.write("(");
24181 self.generate_expression(&e.this)?;
24182 if let Some(expression) = &e.expression {
24183 self.write(", ");
24184 self.generate_expression(expression)?;
24185 }
24186 self.write(")");
24187 Ok(())
24188 }
24189
24190 fn generate_approx_top_k(&mut self, e: &ApproxTopK) -> Result<()> {
24191 self.write_keyword("APPROX_TOP_K");
24193 self.write("(");
24194 self.generate_expression(&e.this)?;
24195 if let Some(expression) = &e.expression {
24196 self.write(", ");
24197 self.generate_expression(expression)?;
24198 }
24199 if let Some(counters) = &e.counters {
24200 self.write(", ");
24201 self.generate_expression(counters)?;
24202 }
24203 self.write(")");
24204 Ok(())
24205 }
24206
24207 fn generate_approx_top_k_accumulate(&mut self, e: &ApproxTopKAccumulate) -> Result<()> {
24208 self.write_keyword("APPROX_TOP_K_ACCUMULATE");
24210 self.write("(");
24211 self.generate_expression(&e.this)?;
24212 if let Some(expression) = &e.expression {
24213 self.write(", ");
24214 self.generate_expression(expression)?;
24215 }
24216 self.write(")");
24217 Ok(())
24218 }
24219
24220 fn generate_approx_top_k_combine(&mut self, e: &ApproxTopKCombine) -> Result<()> {
24221 self.write_keyword("APPROX_TOP_K_COMBINE");
24223 self.write("(");
24224 self.generate_expression(&e.this)?;
24225 if let Some(expression) = &e.expression {
24226 self.write(", ");
24227 self.generate_expression(expression)?;
24228 }
24229 self.write(")");
24230 Ok(())
24231 }
24232
24233 fn generate_approx_top_k_estimate(&mut self, e: &ApproxTopKEstimate) -> Result<()> {
24234 self.write_keyword("APPROX_TOP_K_ESTIMATE");
24236 self.write("(");
24237 self.generate_expression(&e.this)?;
24238 if let Some(expression) = &e.expression {
24239 self.write(", ");
24240 self.generate_expression(expression)?;
24241 }
24242 self.write(")");
24243 Ok(())
24244 }
24245
24246 fn generate_approx_top_sum(&mut self, e: &ApproxTopSum) -> Result<()> {
24247 self.write_keyword("APPROX_TOP_SUM");
24249 self.write("(");
24250 self.generate_expression(&e.this)?;
24251 self.write(", ");
24252 self.generate_expression(&e.expression)?;
24253 if let Some(count) = &e.count {
24254 self.write(", ");
24255 self.generate_expression(count)?;
24256 }
24257 self.write(")");
24258 Ok(())
24259 }
24260
24261 fn generate_arg_max(&mut self, e: &ArgMax) -> Result<()> {
24262 self.write_keyword("ARG_MAX");
24264 self.write("(");
24265 self.generate_expression(&e.this)?;
24266 self.write(", ");
24267 self.generate_expression(&e.expression)?;
24268 if let Some(count) = &e.count {
24269 self.write(", ");
24270 self.generate_expression(count)?;
24271 }
24272 self.write(")");
24273 Ok(())
24274 }
24275
24276 fn generate_arg_min(&mut self, e: &ArgMin) -> Result<()> {
24277 self.write_keyword("ARG_MIN");
24279 self.write("(");
24280 self.generate_expression(&e.this)?;
24281 self.write(", ");
24282 self.generate_expression(&e.expression)?;
24283 if let Some(count) = &e.count {
24284 self.write(", ");
24285 self.generate_expression(count)?;
24286 }
24287 self.write(")");
24288 Ok(())
24289 }
24290
24291 fn generate_array_all(&mut self, e: &ArrayAll) -> Result<()> {
24292 self.write_keyword("ARRAY_ALL");
24294 self.write("(");
24295 self.generate_expression(&e.this)?;
24296 self.write(", ");
24297 self.generate_expression(&e.expression)?;
24298 self.write(")");
24299 Ok(())
24300 }
24301
24302 fn generate_array_any(&mut self, e: &ArrayAny) -> Result<()> {
24303 self.write_keyword("ARRAY_ANY");
24305 self.write("(");
24306 self.generate_expression(&e.this)?;
24307 self.write(", ");
24308 self.generate_expression(&e.expression)?;
24309 self.write(")");
24310 Ok(())
24311 }
24312
24313 fn generate_array_construct_compact(&mut self, e: &ArrayConstructCompact) -> Result<()> {
24314 self.write_keyword("ARRAY_CONSTRUCT_COMPACT");
24316 self.write("(");
24317 for (i, expr) in e.expressions.iter().enumerate() {
24318 if i > 0 {
24319 self.write(", ");
24320 }
24321 self.generate_expression(expr)?;
24322 }
24323 self.write(")");
24324 Ok(())
24325 }
24326
24327 fn generate_array_sum(&mut self, e: &ArraySum) -> Result<()> {
24328 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
24330 self.write("arraySum");
24331 } else {
24332 self.write_keyword("ARRAY_SUM");
24333 }
24334 self.write("(");
24335 self.generate_expression(&e.this)?;
24336 if let Some(expression) = &e.expression {
24337 self.write(", ");
24338 self.generate_expression(expression)?;
24339 }
24340 self.write(")");
24341 Ok(())
24342 }
24343
24344 fn generate_at_index(&mut self, e: &AtIndex) -> Result<()> {
24345 self.generate_expression(&e.this)?;
24347 self.write_space();
24348 self.write_keyword("AT");
24349 self.write_space();
24350 self.generate_expression(&e.expression)?;
24351 Ok(())
24352 }
24353
24354 fn generate_attach(&mut self, e: &Attach) -> Result<()> {
24355 self.write_keyword("ATTACH");
24357 if e.exists {
24358 self.write_space();
24359 self.write_keyword("IF NOT EXISTS");
24360 }
24361 self.write_space();
24362 self.generate_expression(&e.this)?;
24363 if !e.expressions.is_empty() {
24364 self.write(" (");
24365 for (i, expr) in e.expressions.iter().enumerate() {
24366 if i > 0 {
24367 self.write(", ");
24368 }
24369 self.generate_expression(expr)?;
24370 }
24371 self.write(")");
24372 }
24373 Ok(())
24374 }
24375
24376 fn generate_attach_option(&mut self, e: &AttachOption) -> Result<()> {
24377 self.generate_expression(&e.this)?;
24380 if let Some(expression) = &e.expression {
24381 self.write_space();
24382 self.generate_expression(expression)?;
24383 }
24384 Ok(())
24385 }
24386
24387 fn generate_auto_increment_keyword(
24391 &mut self,
24392 col: &crate::expressions::ColumnDef,
24393 ) -> Result<()> {
24394 use crate::dialects::DialectType;
24395 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
24396 self.write_keyword("IDENTITY");
24397 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
24398 self.write("(");
24399 if let Some(ref start) = col.auto_increment_start {
24400 self.generate_expression(start)?;
24401 } else {
24402 self.write("0");
24403 }
24404 self.write(", ");
24405 if let Some(ref inc) = col.auto_increment_increment {
24406 self.generate_expression(inc)?;
24407 } else {
24408 self.write("1");
24409 }
24410 self.write(")");
24411 }
24412 } else if matches!(
24413 self.config.dialect,
24414 Some(DialectType::Snowflake) | Some(DialectType::SQLite)
24415 ) {
24416 self.write_keyword("AUTOINCREMENT");
24417 if let Some(ref start) = col.auto_increment_start {
24418 self.write_space();
24419 self.write_keyword("START");
24420 self.write_space();
24421 self.generate_expression(start)?;
24422 }
24423 if let Some(ref inc) = col.auto_increment_increment {
24424 self.write_space();
24425 self.write_keyword("INCREMENT");
24426 self.write_space();
24427 self.generate_expression(inc)?;
24428 }
24429 if let Some(order) = col.auto_increment_order {
24430 self.write_space();
24431 if order {
24432 self.write_keyword("ORDER");
24433 } else {
24434 self.write_keyword("NOORDER");
24435 }
24436 }
24437 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
24438 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
24439 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
24440 self.write(" (");
24441 let mut first = true;
24442 if let Some(ref start) = col.auto_increment_start {
24443 self.write_keyword("START WITH");
24444 self.write_space();
24445 self.generate_expression(start)?;
24446 first = false;
24447 }
24448 if let Some(ref inc) = col.auto_increment_increment {
24449 if !first {
24450 self.write_space();
24451 }
24452 self.write_keyword("INCREMENT BY");
24453 self.write_space();
24454 self.generate_expression(inc)?;
24455 }
24456 self.write(")");
24457 }
24458 } else if matches!(self.config.dialect, Some(DialectType::Databricks)) {
24459 self.write_keyword("GENERATED ALWAYS AS IDENTITY");
24460 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
24461 self.write(" (");
24462 let mut first = true;
24463 if let Some(ref start) = col.auto_increment_start {
24464 self.write_keyword("START WITH");
24465 self.write_space();
24466 self.generate_expression(start)?;
24467 first = false;
24468 }
24469 if let Some(ref inc) = col.auto_increment_increment {
24470 if !first {
24471 self.write_space();
24472 }
24473 self.write_keyword("INCREMENT BY");
24474 self.write_space();
24475 self.generate_expression(inc)?;
24476 }
24477 self.write(")");
24478 }
24479 } else if matches!(
24480 self.config.dialect,
24481 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24482 ) {
24483 self.write_keyword("IDENTITY");
24484 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
24485 self.write("(");
24486 if let Some(ref start) = col.auto_increment_start {
24487 self.generate_expression(start)?;
24488 } else {
24489 self.write("0");
24490 }
24491 self.write(", ");
24492 if let Some(ref inc) = col.auto_increment_increment {
24493 self.generate_expression(inc)?;
24494 } else {
24495 self.write("1");
24496 }
24497 self.write(")");
24498 }
24499 } else {
24500 self.write_keyword("AUTO_INCREMENT");
24501 if let Some(ref start) = col.auto_increment_start {
24502 self.write_space();
24503 self.write_keyword("START");
24504 self.write_space();
24505 self.generate_expression(start)?;
24506 }
24507 if let Some(ref inc) = col.auto_increment_increment {
24508 self.write_space();
24509 self.write_keyword("INCREMENT");
24510 self.write_space();
24511 self.generate_expression(inc)?;
24512 }
24513 if let Some(order) = col.auto_increment_order {
24514 self.write_space();
24515 if order {
24516 self.write_keyword("ORDER");
24517 } else {
24518 self.write_keyword("NOORDER");
24519 }
24520 }
24521 }
24522 Ok(())
24523 }
24524
24525 fn generate_auto_increment_property(&mut self, e: &AutoIncrementProperty) -> Result<()> {
24526 self.write_keyword("AUTO_INCREMENT");
24528 self.write("=");
24529 self.generate_expression(&e.this)?;
24530 Ok(())
24531 }
24532
24533 fn generate_auto_refresh_property(&mut self, e: &AutoRefreshProperty) -> Result<()> {
24534 self.write_keyword("AUTO_REFRESH");
24536 self.write("=");
24537 self.generate_expression(&e.this)?;
24538 Ok(())
24539 }
24540
24541 fn generate_backup_property(&mut self, e: &BackupProperty) -> Result<()> {
24542 self.write_keyword("BACKUP");
24544 self.write_space();
24545 self.generate_expression(&e.this)?;
24546 Ok(())
24547 }
24548
24549 fn generate_base64_decode_binary(&mut self, e: &Base64DecodeBinary) -> Result<()> {
24550 self.write_keyword("BASE64_DECODE_BINARY");
24552 self.write("(");
24553 self.generate_expression(&e.this)?;
24554 if let Some(alphabet) = &e.alphabet {
24555 self.write(", ");
24556 self.generate_expression(alphabet)?;
24557 }
24558 self.write(")");
24559 Ok(())
24560 }
24561
24562 fn generate_base64_decode_string(&mut self, e: &Base64DecodeString) -> Result<()> {
24563 self.write_keyword("BASE64_DECODE_STRING");
24565 self.write("(");
24566 self.generate_expression(&e.this)?;
24567 if let Some(alphabet) = &e.alphabet {
24568 self.write(", ");
24569 self.generate_expression(alphabet)?;
24570 }
24571 self.write(")");
24572 Ok(())
24573 }
24574
24575 fn generate_base64_encode(&mut self, e: &Base64Encode) -> Result<()> {
24576 self.write_keyword("BASE64_ENCODE");
24578 self.write("(");
24579 self.generate_expression(&e.this)?;
24580 if let Some(max_line_length) = &e.max_line_length {
24581 self.write(", ");
24582 self.generate_expression(max_line_length)?;
24583 }
24584 if let Some(alphabet) = &e.alphabet {
24585 self.write(", ");
24586 self.generate_expression(alphabet)?;
24587 }
24588 self.write(")");
24589 Ok(())
24590 }
24591
24592 fn generate_block_compression_property(&mut self, e: &BlockCompressionProperty) -> Result<()> {
24593 self.write_keyword("BLOCKCOMPRESSION");
24595 self.write("=");
24596 if let Some(autotemp) = &e.autotemp {
24597 self.write_keyword("AUTOTEMP");
24598 self.write("(");
24599 self.generate_expression(autotemp)?;
24600 self.write(")");
24601 }
24602 if let Some(always) = &e.always {
24603 self.generate_expression(always)?;
24604 }
24605 if let Some(default) = &e.default {
24606 self.generate_expression(default)?;
24607 }
24608 if let Some(manual) = &e.manual {
24609 self.generate_expression(manual)?;
24610 }
24611 if let Some(never) = &e.never {
24612 self.generate_expression(never)?;
24613 }
24614 Ok(())
24615 }
24616
24617 fn generate_booland(&mut self, e: &Booland) -> Result<()> {
24618 self.write("((");
24620 self.generate_expression(&e.this)?;
24621 self.write(") ");
24622 self.write_keyword("AND");
24623 self.write(" (");
24624 self.generate_expression(&e.expression)?;
24625 self.write("))");
24626 Ok(())
24627 }
24628
24629 fn generate_boolor(&mut self, e: &Boolor) -> Result<()> {
24630 self.write("((");
24632 self.generate_expression(&e.this)?;
24633 self.write(") ");
24634 self.write_keyword("OR");
24635 self.write(" (");
24636 self.generate_expression(&e.expression)?;
24637 self.write("))");
24638 Ok(())
24639 }
24640
24641 fn generate_build_property(&mut self, e: &BuildProperty) -> Result<()> {
24642 self.write_keyword("BUILD");
24644 self.write_space();
24645 self.generate_expression(&e.this)?;
24646 Ok(())
24647 }
24648
24649 fn generate_byte_string(&mut self, e: &ByteString) -> Result<()> {
24650 self.generate_expression(&e.this)?;
24652 Ok(())
24653 }
24654
24655 fn generate_case_specific_column_constraint(
24656 &mut self,
24657 e: &CaseSpecificColumnConstraint,
24658 ) -> Result<()> {
24659 if e.not_.is_some() {
24661 self.write_keyword("NOT");
24662 self.write_space();
24663 }
24664 self.write_keyword("CASESPECIFIC");
24665 Ok(())
24666 }
24667
24668 fn generate_cast_to_str_type(&mut self, e: &CastToStrType) -> Result<()> {
24669 self.write_keyword("CAST");
24671 self.write("(");
24672 self.generate_expression(&e.this)?;
24673 if self.config.dialect == Some(DialectType::ClickHouse) {
24674 self.write(", ");
24676 } else {
24677 self.write_space();
24678 self.write_keyword("AS");
24679 self.write_space();
24680 }
24681 if let Some(to) = &e.to {
24682 self.generate_expression(to)?;
24683 }
24684 self.write(")");
24685 Ok(())
24686 }
24687
24688 fn generate_changes(&mut self, e: &Changes) -> Result<()> {
24689 self.write_keyword("CHANGES");
24692 self.write(" (");
24693 if let Some(information) = &e.information {
24694 self.write_keyword("INFORMATION");
24695 self.write(" => ");
24696 self.generate_expression(information)?;
24697 }
24698 self.write(")");
24699 if let Some(at_before) = &e.at_before {
24701 self.write(" ");
24702 self.generate_expression(at_before)?;
24703 }
24704 if let Some(end) = &e.end {
24705 self.write(" ");
24706 self.generate_expression(end)?;
24707 }
24708 Ok(())
24709 }
24710
24711 fn generate_character_set_column_constraint(
24712 &mut self,
24713 e: &CharacterSetColumnConstraint,
24714 ) -> Result<()> {
24715 self.write_keyword("CHARACTER SET");
24717 self.write_space();
24718 self.generate_expression(&e.this)?;
24719 Ok(())
24720 }
24721
24722 fn generate_character_set_property(&mut self, e: &CharacterSetProperty) -> Result<()> {
24723 if e.default.is_some() {
24725 self.write_keyword("DEFAULT");
24726 self.write_space();
24727 }
24728 self.write_keyword("CHARACTER SET");
24729 self.write("=");
24730 self.generate_expression(&e.this)?;
24731 Ok(())
24732 }
24733
24734 fn generate_check_column_constraint(&mut self, e: &CheckColumnConstraint) -> Result<()> {
24735 self.write_keyword("CHECK");
24737 self.write(" (");
24738 self.generate_expression(&e.this)?;
24739 self.write(")");
24740 if e.enforced.is_some() {
24741 self.write_space();
24742 self.write_keyword("ENFORCED");
24743 }
24744 Ok(())
24745 }
24746
24747 fn generate_check_json(&mut self, e: &CheckJson) -> Result<()> {
24748 self.write_keyword("CHECK_JSON");
24750 self.write("(");
24751 self.generate_expression(&e.this)?;
24752 self.write(")");
24753 Ok(())
24754 }
24755
24756 fn generate_check_xml(&mut self, e: &CheckXml) -> Result<()> {
24757 self.write_keyword("CHECK_XML");
24759 self.write("(");
24760 self.generate_expression(&e.this)?;
24761 self.write(")");
24762 Ok(())
24763 }
24764
24765 fn generate_checksum_property(&mut self, e: &ChecksumProperty) -> Result<()> {
24766 self.write_keyword("CHECKSUM");
24768 self.write("=");
24769 if e.on.is_some() {
24770 self.write_keyword("ON");
24771 } else if e.default.is_some() {
24772 self.write_keyword("DEFAULT");
24773 } else {
24774 self.write_keyword("OFF");
24775 }
24776 Ok(())
24777 }
24778
24779 fn generate_clone(&mut self, e: &Clone) -> Result<()> {
24780 if e.shallow.is_some() {
24782 self.write_keyword("SHALLOW");
24783 self.write_space();
24784 }
24785 if e.copy.is_some() {
24786 self.write_keyword("COPY");
24787 } else {
24788 self.write_keyword("CLONE");
24789 }
24790 self.write_space();
24791 self.generate_expression(&e.this)?;
24792 Ok(())
24793 }
24794
24795 fn generate_cluster_by(&mut self, e: &ClusterBy) -> Result<()> {
24796 self.write_keyword("CLUSTER BY");
24798 self.write(" (");
24799 for (i, ord) in e.expressions.iter().enumerate() {
24800 if i > 0 {
24801 self.write(", ");
24802 }
24803 self.generate_ordered(ord)?;
24804 }
24805 self.write(")");
24806 Ok(())
24807 }
24808
24809 fn generate_clustered_by_property(&mut self, e: &ClusteredByProperty) -> Result<()> {
24810 self.write_keyword("CLUSTERED BY");
24812 self.write(" (");
24813 for (i, expr) in e.expressions.iter().enumerate() {
24814 if i > 0 {
24815 self.write(", ");
24816 }
24817 self.generate_expression(expr)?;
24818 }
24819 self.write(")");
24820 if let Some(sorted_by) = &e.sorted_by {
24821 self.write_space();
24822 self.write_keyword("SORTED BY");
24823 self.write(" (");
24824 if let Expression::Tuple(t) = sorted_by.as_ref() {
24826 for (i, expr) in t.expressions.iter().enumerate() {
24827 if i > 0 {
24828 self.write(", ");
24829 }
24830 self.generate_expression(expr)?;
24831 }
24832 } else {
24833 self.generate_expression(sorted_by)?;
24834 }
24835 self.write(")");
24836 }
24837 if let Some(buckets) = &e.buckets {
24838 self.write_space();
24839 self.write_keyword("INTO");
24840 self.write_space();
24841 self.generate_expression(buckets)?;
24842 self.write_space();
24843 self.write_keyword("BUCKETS");
24844 }
24845 Ok(())
24846 }
24847
24848 fn generate_collate_property(&mut self, e: &CollateProperty) -> Result<()> {
24849 if e.default.is_some() {
24853 self.write_keyword("DEFAULT");
24854 self.write_space();
24855 }
24856 self.write_keyword("COLLATE");
24857 match self.config.dialect {
24859 Some(DialectType::BigQuery) => self.write_space(),
24860 _ => self.write("="),
24861 }
24862 self.generate_expression(&e.this)?;
24863 Ok(())
24864 }
24865
24866 fn generate_column_constraint(&mut self, e: &ColumnConstraint) -> Result<()> {
24867 match e {
24869 ColumnConstraint::NotNull => {
24870 self.write_keyword("NOT NULL");
24871 }
24872 ColumnConstraint::Null => {
24873 self.write_keyword("NULL");
24874 }
24875 ColumnConstraint::Unique => {
24876 self.write_keyword("UNIQUE");
24877 }
24878 ColumnConstraint::PrimaryKey => {
24879 self.write_keyword("PRIMARY KEY");
24880 }
24881 ColumnConstraint::Default(expr) => {
24882 self.write_keyword("DEFAULT");
24883 self.write_space();
24884 self.generate_expression(expr)?;
24885 }
24886 ColumnConstraint::Check(expr) => {
24887 self.write_keyword("CHECK");
24888 self.write(" (");
24889 self.generate_expression(expr)?;
24890 self.write(")");
24891 }
24892 ColumnConstraint::References(fk_ref) => {
24893 if fk_ref.has_foreign_key_keywords {
24894 self.write_keyword("FOREIGN KEY");
24895 self.write_space();
24896 }
24897 self.write_keyword("REFERENCES");
24898 self.write_space();
24899 self.generate_table(&fk_ref.table)?;
24900 if !fk_ref.columns.is_empty() {
24901 self.write(" (");
24902 for (i, col) in fk_ref.columns.iter().enumerate() {
24903 if i > 0 {
24904 self.write(", ");
24905 }
24906 self.generate_identifier(col)?;
24907 }
24908 self.write(")");
24909 }
24910 }
24911 ColumnConstraint::GeneratedAsIdentity(gen) => {
24912 self.write_keyword("GENERATED");
24913 self.write_space();
24914 if gen.always {
24915 self.write_keyword("ALWAYS");
24916 } else {
24917 self.write_keyword("BY DEFAULT");
24918 if gen.on_null {
24919 self.write_space();
24920 self.write_keyword("ON NULL");
24921 }
24922 }
24923 self.write_space();
24924 self.write_keyword("AS IDENTITY");
24925 }
24926 ColumnConstraint::Collate(collation) => {
24927 self.write_keyword("COLLATE");
24928 self.write_space();
24929 self.generate_identifier(collation)?;
24930 }
24931 ColumnConstraint::Comment(comment) => {
24932 self.write_keyword("COMMENT");
24933 self.write(" '");
24934 self.write(comment);
24935 self.write("'");
24936 }
24937 ColumnConstraint::ComputedColumn(cc) => {
24938 self.generate_computed_column_inline(cc)?;
24939 }
24940 ColumnConstraint::GeneratedAsRow(gar) => {
24941 self.generate_generated_as_row_inline(gar)?;
24942 }
24943 ColumnConstraint::Tags(tags) => {
24944 self.write_keyword("TAG");
24945 self.write(" (");
24946 for (i, expr) in tags.expressions.iter().enumerate() {
24947 if i > 0 {
24948 self.write(", ");
24949 }
24950 self.generate_expression(expr)?;
24951 }
24952 self.write(")");
24953 }
24954 ColumnConstraint::Path(path_expr) => {
24955 self.write_keyword("PATH");
24956 self.write_space();
24957 self.generate_expression(path_expr)?;
24958 }
24959 }
24960 Ok(())
24961 }
24962
24963 fn generate_column_position(&mut self, e: &ColumnPosition) -> Result<()> {
24964 match e {
24966 ColumnPosition::First => {
24967 self.write_keyword("FIRST");
24968 }
24969 ColumnPosition::After(ident) => {
24970 self.write_keyword("AFTER");
24971 self.write_space();
24972 self.generate_identifier(ident)?;
24973 }
24974 }
24975 Ok(())
24976 }
24977
24978 fn generate_column_prefix(&mut self, e: &ColumnPrefix) -> Result<()> {
24979 self.generate_expression(&e.this)?;
24981 self.write("(");
24982 self.generate_expression(&e.expression)?;
24983 self.write(")");
24984 Ok(())
24985 }
24986
24987 fn generate_columns(&mut self, e: &Columns) -> Result<()> {
24988 if let Some(ref unpack) = e.unpack {
24991 if let Expression::Boolean(b) = unpack.as_ref() {
24992 if b.value {
24993 self.write("*");
24994 }
24995 }
24996 }
24997 self.write_keyword("COLUMNS");
24998 self.write("(");
24999 self.generate_expression(&e.this)?;
25000 self.write(")");
25001 Ok(())
25002 }
25003
25004 fn generate_combined_agg_func(&mut self, e: &CombinedAggFunc) -> Result<()> {
25005 self.generate_expression(&e.this)?;
25007 self.write("(");
25008 for (i, expr) in e.expressions.iter().enumerate() {
25009 if i > 0 {
25010 self.write(", ");
25011 }
25012 self.generate_expression(expr)?;
25013 }
25014 self.write(")");
25015 Ok(())
25016 }
25017
25018 fn generate_combined_parameterized_agg(&mut self, e: &CombinedParameterizedAgg) -> Result<()> {
25019 self.generate_expression(&e.this)?;
25021 self.write("(");
25022 for (i, param) in e.params.iter().enumerate() {
25023 if i > 0 {
25024 self.write(", ");
25025 }
25026 self.generate_expression(param)?;
25027 }
25028 self.write(")(");
25029 for (i, expr) in e.expressions.iter().enumerate() {
25030 if i > 0 {
25031 self.write(", ");
25032 }
25033 self.generate_expression(expr)?;
25034 }
25035 self.write(")");
25036 Ok(())
25037 }
25038
25039 fn generate_commit(&mut self, e: &Commit) -> Result<()> {
25040 self.write_keyword("COMMIT");
25042
25043 if e.this.is_none()
25045 && matches!(
25046 self.config.dialect,
25047 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25048 )
25049 {
25050 self.write_space();
25051 self.write_keyword("TRANSACTION");
25052 }
25053
25054 if let Some(this) = &e.this {
25056 let is_transaction_marker = matches!(
25058 this.as_ref(),
25059 Expression::Identifier(id) if id.name == "TRANSACTION"
25060 );
25061
25062 self.write_space();
25063 self.write_keyword("TRANSACTION");
25064
25065 if !is_transaction_marker {
25067 self.write_space();
25068 self.generate_expression(this)?;
25069 }
25070 }
25071
25072 if let Some(durability) = &e.durability {
25074 self.write_space();
25075 self.write_keyword("WITH");
25076 self.write(" (");
25077 self.write_keyword("DELAYED_DURABILITY");
25078 self.write(" = ");
25079 if let Expression::Boolean(BooleanLiteral { value: true }) = durability.as_ref() {
25080 self.write_keyword("ON");
25081 } else {
25082 self.write_keyword("OFF");
25083 }
25084 self.write(")");
25085 }
25086
25087 if let Some(chain) = &e.chain {
25089 self.write_space();
25090 if let Expression::Boolean(BooleanLiteral { value: false }) = chain.as_ref() {
25091 self.write_keyword("AND NO CHAIN");
25092 } else {
25093 self.write_keyword("AND CHAIN");
25094 }
25095 }
25096 Ok(())
25097 }
25098
25099 fn generate_comprehension(&mut self, e: &Comprehension) -> Result<()> {
25100 self.write("[");
25102 self.generate_expression(&e.this)?;
25103 self.write_space();
25104 self.write_keyword("FOR");
25105 self.write_space();
25106 self.generate_expression(&e.expression)?;
25107 if let Some(pos) = &e.position {
25109 self.write(", ");
25110 self.generate_expression(pos)?;
25111 }
25112 if let Some(iterator) = &e.iterator {
25113 self.write_space();
25114 self.write_keyword("IN");
25115 self.write_space();
25116 self.generate_expression(iterator)?;
25117 }
25118 if let Some(condition) = &e.condition {
25119 self.write_space();
25120 self.write_keyword("IF");
25121 self.write_space();
25122 self.generate_expression(condition)?;
25123 }
25124 self.write("]");
25125 Ok(())
25126 }
25127
25128 fn generate_compress(&mut self, e: &Compress) -> Result<()> {
25129 self.write_keyword("COMPRESS");
25131 self.write("(");
25132 self.generate_expression(&e.this)?;
25133 if let Some(method) = &e.method {
25134 self.write(", '");
25135 self.write(method);
25136 self.write("'");
25137 }
25138 self.write(")");
25139 Ok(())
25140 }
25141
25142 fn generate_compress_column_constraint(&mut self, e: &CompressColumnConstraint) -> Result<()> {
25143 self.write_keyword("COMPRESS");
25145 if let Some(this) = &e.this {
25146 self.write_space();
25147 self.generate_expression(this)?;
25148 }
25149 Ok(())
25150 }
25151
25152 fn generate_computed_column_constraint(&mut self, e: &ComputedColumnConstraint) -> Result<()> {
25153 self.write_keyword("AS");
25155 self.write_space();
25156 self.generate_expression(&e.this)?;
25157 if e.not_null.is_some() {
25158 self.write_space();
25159 self.write_keyword("PERSISTED NOT NULL");
25160 } else if e.persisted.is_some() {
25161 self.write_space();
25162 self.write_keyword("PERSISTED");
25163 }
25164 Ok(())
25165 }
25166
25167 fn generate_computed_column_inline(&mut self, cc: &ComputedColumn) -> Result<()> {
25171 let computed_expr = if matches!(
25172 self.config.dialect,
25173 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25174 ) {
25175 match &*cc.expression {
25176 Expression::Year(y) if !matches!(&y.this, Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
25177 {
25178 let wrapped = Expression::Cast(Box::new(Cast {
25179 this: y.this.clone(),
25180 to: DataType::Date,
25181 trailing_comments: Vec::new(),
25182 double_colon_syntax: false,
25183 format: None,
25184 default: None,
25185 }));
25186 Expression::Year(Box::new(UnaryFunc::new(wrapped)))
25187 }
25188 Expression::Function(f)
25189 if f.name.eq_ignore_ascii_case("YEAR")
25190 && f.args.len() == 1
25191 && !matches!(&f.args[0], Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
25192 {
25193 let wrapped = Expression::Cast(Box::new(Cast {
25194 this: f.args[0].clone(),
25195 to: DataType::Date,
25196 trailing_comments: Vec::new(),
25197 double_colon_syntax: false,
25198 format: None,
25199 default: None,
25200 }));
25201 Expression::Function(Box::new(Function::new("YEAR".to_string(), vec![wrapped])))
25202 }
25203 _ => *cc.expression.clone(),
25204 }
25205 } else {
25206 *cc.expression.clone()
25207 };
25208
25209 match cc.persistence_kind.as_deref() {
25210 Some("STORED") | Some("VIRTUAL") => {
25211 self.write_keyword("GENERATED ALWAYS AS");
25213 self.write(" (");
25214 self.generate_expression(&computed_expr)?;
25215 self.write(")");
25216 self.write_space();
25217 if cc.persisted {
25218 self.write_keyword("STORED");
25219 } else {
25220 self.write_keyword("VIRTUAL");
25221 }
25222 }
25223 Some("PERSISTED") => {
25224 self.write_keyword("AS");
25226 self.write(" (");
25227 self.generate_expression(&computed_expr)?;
25228 self.write(")");
25229 self.write_space();
25230 self.write_keyword("PERSISTED");
25231 if let Some(ref dt) = cc.data_type {
25233 self.write_space();
25234 self.generate_data_type(dt)?;
25235 }
25236 if cc.not_null {
25237 self.write_space();
25238 self.write_keyword("NOT NULL");
25239 }
25240 }
25241 _ => {
25242 if matches!(
25245 self.config.dialect,
25246 Some(DialectType::Spark)
25247 | Some(DialectType::Databricks)
25248 | Some(DialectType::Hive)
25249 ) {
25250 self.write_keyword("GENERATED ALWAYS AS");
25251 self.write(" (");
25252 self.generate_expression(&computed_expr)?;
25253 self.write(")");
25254 } else if matches!(
25255 self.config.dialect,
25256 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25257 ) {
25258 self.write_keyword("AS");
25259 let omit_parens = matches!(computed_expr, Expression::Year(_))
25260 || matches!(&computed_expr, Expression::Function(f) if f.name.eq_ignore_ascii_case("YEAR"));
25261 if omit_parens {
25262 self.write_space();
25263 self.generate_expression(&computed_expr)?;
25264 } else {
25265 self.write(" (");
25266 self.generate_expression(&computed_expr)?;
25267 self.write(")");
25268 }
25269 } else {
25270 self.write_keyword("AS");
25271 self.write(" (");
25272 self.generate_expression(&computed_expr)?;
25273 self.write(")");
25274 }
25275 }
25276 }
25277 Ok(())
25278 }
25279
25280 fn generate_generated_as_row_inline(&mut self, gar: &GeneratedAsRow) -> Result<()> {
25283 self.write_keyword("GENERATED ALWAYS AS ROW ");
25284 if gar.start {
25285 self.write_keyword("START");
25286 } else {
25287 self.write_keyword("END");
25288 }
25289 if gar.hidden {
25290 self.write_space();
25291 self.write_keyword("HIDDEN");
25292 }
25293 Ok(())
25294 }
25295
25296 fn generate_system_versioning_content(
25298 &mut self,
25299 e: &WithSystemVersioningProperty,
25300 ) -> Result<()> {
25301 let mut parts = Vec::new();
25302
25303 if let Some(this) = &e.this {
25304 let mut s = String::from("HISTORY_TABLE=");
25305 let mut gen = Generator::new();
25306 gen.config = self.config.clone();
25307 gen.generate_expression(this)?;
25308 s.push_str(&gen.output);
25309 parts.push(s);
25310 }
25311
25312 if let Some(data_consistency) = &e.data_consistency {
25313 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
25314 let mut gen = Generator::new();
25315 gen.config = self.config.clone();
25316 gen.generate_expression(data_consistency)?;
25317 s.push_str(&gen.output);
25318 parts.push(s);
25319 }
25320
25321 if let Some(retention_period) = &e.retention_period {
25322 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
25323 let mut gen = Generator::new();
25324 gen.config = self.config.clone();
25325 gen.generate_expression(retention_period)?;
25326 s.push_str(&gen.output);
25327 parts.push(s);
25328 }
25329
25330 self.write_keyword("SYSTEM_VERSIONING");
25331 self.write("=");
25332
25333 if !parts.is_empty() {
25334 self.write_keyword("ON");
25335 self.write("(");
25336 self.write(&parts.join(", "));
25337 self.write(")");
25338 } else if e.on.is_some() {
25339 self.write_keyword("ON");
25340 } else {
25341 self.write_keyword("OFF");
25342 }
25343
25344 Ok(())
25345 }
25346
25347 fn generate_conditional_insert(&mut self, e: &ConditionalInsert) -> Result<()> {
25348 if e.else_.is_some() {
25351 self.write_keyword("ELSE");
25352 self.write_space();
25353 } else if let Some(expression) = &e.expression {
25354 self.write_keyword("WHEN");
25355 self.write_space();
25356 self.generate_expression(expression)?;
25357 self.write_space();
25358 self.write_keyword("THEN");
25359 self.write_space();
25360 }
25361
25362 if let Expression::Insert(insert) = e.this.as_ref() {
25365 self.write_keyword("INTO");
25366 self.write_space();
25367 self.generate_table(&insert.table)?;
25368
25369 if !insert.columns.is_empty() {
25371 self.write(" (");
25372 for (i, col) in insert.columns.iter().enumerate() {
25373 if i > 0 {
25374 self.write(", ");
25375 }
25376 self.generate_identifier(col)?;
25377 }
25378 self.write(")");
25379 }
25380
25381 if !insert.values.is_empty() {
25383 self.write_space();
25384 self.write_keyword("VALUES");
25385 for (row_idx, row) in insert.values.iter().enumerate() {
25386 if row_idx > 0 {
25387 self.write(", ");
25388 }
25389 self.write(" (");
25390 for (i, val) in row.iter().enumerate() {
25391 if i > 0 {
25392 self.write(", ");
25393 }
25394 self.generate_expression(val)?;
25395 }
25396 self.write(")");
25397 }
25398 }
25399 } else {
25400 self.generate_expression(&e.this)?;
25402 }
25403 Ok(())
25404 }
25405
25406 fn generate_constraint(&mut self, e: &Constraint) -> Result<()> {
25407 self.write_keyword("CONSTRAINT");
25409 self.write_space();
25410 self.generate_expression(&e.this)?;
25411 if !e.expressions.is_empty() {
25412 self.write_space();
25413 for (i, expr) in e.expressions.iter().enumerate() {
25414 if i > 0 {
25415 self.write_space();
25416 }
25417 self.generate_expression(expr)?;
25418 }
25419 }
25420 Ok(())
25421 }
25422
25423 fn generate_convert_timezone(&mut self, e: &ConvertTimezone) -> Result<()> {
25424 self.write_keyword("CONVERT_TIMEZONE");
25426 self.write("(");
25427 let mut first = true;
25428 if let Some(source_tz) = &e.source_tz {
25429 self.generate_expression(source_tz)?;
25430 first = false;
25431 }
25432 if let Some(target_tz) = &e.target_tz {
25433 if !first {
25434 self.write(", ");
25435 }
25436 self.generate_expression(target_tz)?;
25437 first = false;
25438 }
25439 if let Some(timestamp) = &e.timestamp {
25440 if !first {
25441 self.write(", ");
25442 }
25443 self.generate_expression(timestamp)?;
25444 }
25445 self.write(")");
25446 Ok(())
25447 }
25448
25449 fn generate_convert_to_charset(&mut self, e: &ConvertToCharset) -> Result<()> {
25450 self.write_keyword("CONVERT");
25452 self.write("(");
25453 self.generate_expression(&e.this)?;
25454 if let Some(dest) = &e.dest {
25455 self.write_space();
25456 self.write_keyword("USING");
25457 self.write_space();
25458 self.generate_expression(dest)?;
25459 }
25460 self.write(")");
25461 Ok(())
25462 }
25463
25464 fn generate_copy(&mut self, e: &CopyStmt) -> Result<()> {
25465 self.write_keyword("COPY");
25466 if e.is_into {
25467 self.write_space();
25468 self.write_keyword("INTO");
25469 }
25470 self.write_space();
25471
25472 if let Expression::Literal(Literal::String(s)) = &e.this {
25474 if s.starts_with('@') {
25475 self.write(s);
25476 } else {
25477 self.generate_expression(&e.this)?;
25478 }
25479 } else {
25480 self.generate_expression(&e.this)?;
25481 }
25482
25483 if e.kind {
25485 if self.config.pretty {
25487 self.write_newline();
25488 } else {
25489 self.write_space();
25490 }
25491 self.write_keyword("FROM");
25492 self.write_space();
25493 } else if !e.files.is_empty() {
25494 if self.config.pretty {
25496 self.write_newline();
25497 } else {
25498 self.write_space();
25499 }
25500 self.write_keyword("TO");
25501 self.write_space();
25502 }
25503
25504 for (i, file) in e.files.iter().enumerate() {
25506 if i > 0 {
25507 self.write_space();
25508 }
25509 if let Expression::Literal(Literal::String(s)) = file {
25511 if s.starts_with('@') {
25512 self.write(s);
25513 } else {
25514 self.generate_expression(file)?;
25515 }
25516 } else if let Expression::Identifier(id) = file {
25517 if id.quoted {
25519 self.write("`");
25520 self.write(&id.name);
25521 self.write("`");
25522 } else {
25523 self.generate_expression(file)?;
25524 }
25525 } else {
25526 self.generate_expression(file)?;
25527 }
25528 }
25529
25530 if !e.with_wrapped {
25532 if let Some(ref creds) = e.credentials {
25533 if let Some(ref storage) = creds.storage {
25534 if self.config.pretty {
25535 self.write_newline();
25536 } else {
25537 self.write_space();
25538 }
25539 self.write_keyword("STORAGE_INTEGRATION");
25540 self.write(" = ");
25541 self.write(storage);
25542 }
25543 if creds.credentials.is_empty() {
25544 if self.config.pretty {
25546 self.write_newline();
25547 } else {
25548 self.write_space();
25549 }
25550 self.write_keyword("CREDENTIALS");
25551 self.write(" = ()");
25552 } else {
25553 if self.config.pretty {
25554 self.write_newline();
25555 } else {
25556 self.write_space();
25557 }
25558 self.write_keyword("CREDENTIALS");
25559 if creds.credentials.len() == 1 && creds.credentials[0].0.is_empty() {
25562 self.write(" '");
25564 self.write(&creds.credentials[0].1);
25565 self.write("'");
25566 } else {
25567 self.write(" = (");
25569 for (i, (k, v)) in creds.credentials.iter().enumerate() {
25570 if i > 0 {
25571 self.write_space();
25572 }
25573 self.write(k);
25574 self.write("='");
25575 self.write(v);
25576 self.write("'");
25577 }
25578 self.write(")");
25579 }
25580 }
25581 if let Some(ref encryption) = creds.encryption {
25582 self.write_space();
25583 self.write_keyword("ENCRYPTION");
25584 self.write(" = ");
25585 self.write(encryption);
25586 }
25587 }
25588 }
25589
25590 if !e.params.is_empty() {
25592 if e.with_wrapped {
25593 self.write_space();
25595 self.write_keyword("WITH");
25596 self.write(" (");
25597 for (i, param) in e.params.iter().enumerate() {
25598 if i > 0 {
25599 self.write(", ");
25600 }
25601 self.generate_copy_param_with_format(param)?;
25602 }
25603 self.write(")");
25604 } else {
25605 for param in &e.params {
25609 if self.config.pretty {
25610 self.write_newline();
25611 } else {
25612 self.write_space();
25613 }
25614 self.write(¶m.name);
25616 if let Some(ref value) = param.value {
25617 if param.eq {
25619 self.write(" = ");
25620 } else {
25621 self.write(" ");
25622 }
25623 if !param.values.is_empty() {
25624 self.write("(");
25625 for (i, v) in param.values.iter().enumerate() {
25626 if i > 0 {
25627 self.write_space();
25628 }
25629 self.generate_copy_nested_param(v)?;
25630 }
25631 self.write(")");
25632 } else {
25633 self.generate_copy_param_value(value)?;
25635 }
25636 } else if !param.values.is_empty() {
25637 if param.eq {
25639 self.write(" = (");
25640 } else {
25641 self.write(" (");
25642 }
25643 let is_key_value_pairs = param
25648 .values
25649 .first()
25650 .map_or(false, |v| matches!(v, Expression::Eq(_)));
25651 let sep = if is_key_value_pairs && param.eq {
25652 " "
25653 } else {
25654 ", "
25655 };
25656 for (i, v) in param.values.iter().enumerate() {
25657 if i > 0 {
25658 self.write(sep);
25659 }
25660 self.generate_copy_nested_param(v)?;
25661 }
25662 self.write(")");
25663 }
25664 }
25665 }
25666 }
25667
25668 Ok(())
25669 }
25670
25671 fn generate_copy_param_with_format(&mut self, param: &CopyParameter) -> Result<()> {
25674 self.write_keyword(¶m.name);
25675 if !param.values.is_empty() {
25676 self.write(" = (");
25678 for (i, v) in param.values.iter().enumerate() {
25679 if i > 0 {
25680 self.write(", ");
25681 }
25682 self.generate_copy_nested_param(v)?;
25683 }
25684 self.write(")");
25685 } else if let Some(ref value) = param.value {
25686 if param.eq {
25687 self.write(" = ");
25688 } else {
25689 self.write(" ");
25690 }
25691 self.generate_expression(value)?;
25692 }
25693 Ok(())
25694 }
25695
25696 fn generate_copy_nested_param(&mut self, expr: &Expression) -> Result<()> {
25698 match expr {
25699 Expression::Eq(eq) => {
25700 match &eq.left {
25702 Expression::Column(c) => self.write(&c.name.name),
25703 _ => self.generate_expression(&eq.left)?,
25704 }
25705 self.write("=");
25706 match &eq.right {
25708 Expression::Literal(Literal::String(s)) => {
25709 self.write("'");
25710 self.write(s);
25711 self.write("'");
25712 }
25713 Expression::Tuple(t) => {
25714 self.write("(");
25716 if self.config.pretty {
25717 self.write_newline();
25718 self.indent_level += 1;
25719 for (i, item) in t.expressions.iter().enumerate() {
25720 if i > 0 {
25721 self.write(", ");
25722 }
25723 self.write_indent();
25724 self.generate_expression(item)?;
25725 }
25726 self.write_newline();
25727 self.indent_level -= 1;
25728 } else {
25729 for (i, item) in t.expressions.iter().enumerate() {
25730 if i > 0 {
25731 self.write(", ");
25732 }
25733 self.generate_expression(item)?;
25734 }
25735 }
25736 self.write(")");
25737 }
25738 _ => self.generate_expression(&eq.right)?,
25739 }
25740 Ok(())
25741 }
25742 Expression::Column(c) => {
25743 self.write(&c.name.name);
25745 Ok(())
25746 }
25747 _ => self.generate_expression(expr),
25748 }
25749 }
25750
25751 fn generate_copy_param_value(&mut self, expr: &Expression) -> Result<()> {
25754 match expr {
25755 Expression::Column(c) => {
25756 if c.name.quoted {
25758 self.write("\"");
25759 self.write(&c.name.name);
25760 self.write("\"");
25761 } else {
25762 self.write(&c.name.name);
25763 }
25764 Ok(())
25765 }
25766 Expression::Identifier(id) => {
25767 if id.quoted {
25769 self.write("\"");
25770 self.write(&id.name);
25771 self.write("\"");
25772 } else {
25773 self.write(&id.name);
25774 }
25775 Ok(())
25776 }
25777 Expression::Literal(Literal::String(s)) => {
25778 self.write("'");
25780 self.write(s);
25781 self.write("'");
25782 Ok(())
25783 }
25784 _ => self.generate_expression(expr),
25785 }
25786 }
25787
25788 fn generate_copy_parameter(&mut self, e: &CopyParameter) -> Result<()> {
25789 self.write_keyword(&e.name);
25790 if let Some(ref value) = e.value {
25791 if e.eq {
25792 self.write(" = ");
25793 } else {
25794 self.write(" ");
25795 }
25796 self.generate_expression(value)?;
25797 }
25798 if !e.values.is_empty() {
25799 if e.eq {
25800 self.write(" = ");
25801 } else {
25802 self.write(" ");
25803 }
25804 self.write("(");
25805 for (i, v) in e.values.iter().enumerate() {
25806 if i > 0 {
25807 self.write(", ");
25808 }
25809 self.generate_expression(v)?;
25810 }
25811 self.write(")");
25812 }
25813 Ok(())
25814 }
25815
25816 fn generate_corr(&mut self, e: &Corr) -> Result<()> {
25817 self.write_keyword("CORR");
25819 self.write("(");
25820 self.generate_expression(&e.this)?;
25821 self.write(", ");
25822 self.generate_expression(&e.expression)?;
25823 self.write(")");
25824 Ok(())
25825 }
25826
25827 fn generate_cosine_distance(&mut self, e: &CosineDistance) -> Result<()> {
25828 self.write_keyword("COSINE_DISTANCE");
25830 self.write("(");
25831 self.generate_expression(&e.this)?;
25832 self.write(", ");
25833 self.generate_expression(&e.expression)?;
25834 self.write(")");
25835 Ok(())
25836 }
25837
25838 fn generate_covar_pop(&mut self, e: &CovarPop) -> Result<()> {
25839 self.write_keyword("COVAR_POP");
25841 self.write("(");
25842 self.generate_expression(&e.this)?;
25843 self.write(", ");
25844 self.generate_expression(&e.expression)?;
25845 self.write(")");
25846 Ok(())
25847 }
25848
25849 fn generate_covar_samp(&mut self, e: &CovarSamp) -> Result<()> {
25850 self.write_keyword("COVAR_SAMP");
25852 self.write("(");
25853 self.generate_expression(&e.this)?;
25854 self.write(", ");
25855 self.generate_expression(&e.expression)?;
25856 self.write(")");
25857 Ok(())
25858 }
25859
25860 fn generate_credentials(&mut self, e: &Credentials) -> Result<()> {
25861 self.write_keyword("CREDENTIALS");
25863 self.write(" (");
25864 for (i, (key, value)) in e.credentials.iter().enumerate() {
25865 if i > 0 {
25866 self.write(", ");
25867 }
25868 self.write(key);
25869 self.write("='");
25870 self.write(value);
25871 self.write("'");
25872 }
25873 self.write(")");
25874 Ok(())
25875 }
25876
25877 fn generate_credentials_property(&mut self, e: &CredentialsProperty) -> Result<()> {
25878 self.write_keyword("CREDENTIALS");
25880 self.write("=(");
25881 for (i, expr) in e.expressions.iter().enumerate() {
25882 if i > 0 {
25883 self.write(", ");
25884 }
25885 self.generate_expression(expr)?;
25886 }
25887 self.write(")");
25888 Ok(())
25889 }
25890
25891 fn generate_cte(&mut self, e: &Cte) -> Result<()> {
25892 use crate::dialects::DialectType;
25893
25894 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !e.alias_first {
25897 self.generate_expression(&e.this)?;
25898 self.write_space();
25899 self.write_keyword("AS");
25900 self.write_space();
25901 self.generate_identifier(&e.alias)?;
25902 return Ok(());
25903 }
25904 self.write(&e.alias.name);
25905
25906 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
25908
25909 if !e.columns.is_empty() && !skip_cte_columns {
25910 self.write("(");
25911 for (i, col) in e.columns.iter().enumerate() {
25912 if i > 0 {
25913 self.write(", ");
25914 }
25915 self.write(&col.name);
25916 }
25917 self.write(")");
25918 }
25919 if !e.key_expressions.is_empty() {
25921 self.write_space();
25922 self.write_keyword("USING KEY");
25923 self.write(" (");
25924 for (i, key) in e.key_expressions.iter().enumerate() {
25925 if i > 0 {
25926 self.write(", ");
25927 }
25928 self.write(&key.name);
25929 }
25930 self.write(")");
25931 }
25932 self.write_space();
25933 self.write_keyword("AS");
25934 self.write_space();
25935 if let Some(materialized) = e.materialized {
25936 if materialized {
25937 self.write_keyword("MATERIALIZED");
25938 } else {
25939 self.write_keyword("NOT MATERIALIZED");
25940 }
25941 self.write_space();
25942 }
25943 self.write("(");
25944 self.generate_expression(&e.this)?;
25945 self.write(")");
25946 Ok(())
25947 }
25948
25949 fn generate_cube(&mut self, e: &Cube) -> Result<()> {
25950 if e.expressions.is_empty() {
25952 self.write_keyword("WITH CUBE");
25953 } else {
25954 self.write_keyword("CUBE");
25955 self.write("(");
25956 for (i, expr) in e.expressions.iter().enumerate() {
25957 if i > 0 {
25958 self.write(", ");
25959 }
25960 self.generate_expression(expr)?;
25961 }
25962 self.write(")");
25963 }
25964 Ok(())
25965 }
25966
25967 fn generate_current_datetime(&mut self, e: &CurrentDatetime) -> Result<()> {
25968 self.write_keyword("CURRENT_DATETIME");
25970 if let Some(this) = &e.this {
25971 self.write("(");
25972 self.generate_expression(this)?;
25973 self.write(")");
25974 }
25975 Ok(())
25976 }
25977
25978 fn generate_current_schema(&mut self, _e: &CurrentSchema) -> Result<()> {
25979 self.write_keyword("CURRENT_SCHEMA");
25981 Ok(())
25982 }
25983
25984 fn generate_current_schemas(&mut self, e: &CurrentSchemas) -> Result<()> {
25985 self.write_keyword("CURRENT_SCHEMAS");
25987 self.write("(");
25988 if let Some(this) = &e.this {
25989 self.generate_expression(this)?;
25990 }
25991 self.write(")");
25992 Ok(())
25993 }
25994
25995 fn generate_current_user(&mut self, e: &CurrentUser) -> Result<()> {
25996 self.write_keyword("CURRENT_USER");
25998 let needs_parens = e.this.is_some()
26000 || matches!(
26001 self.config.dialect,
26002 Some(DialectType::Snowflake)
26003 | Some(DialectType::Spark)
26004 | Some(DialectType::Hive)
26005 | Some(DialectType::DuckDB)
26006 | Some(DialectType::BigQuery)
26007 | Some(DialectType::MySQL)
26008 | Some(DialectType::Databricks)
26009 );
26010 if needs_parens {
26011 self.write("()");
26012 }
26013 Ok(())
26014 }
26015
26016 fn generate_d_pipe(&mut self, e: &DPipe) -> Result<()> {
26017 if self.config.dialect == Some(DialectType::Solr) {
26019 self.generate_expression(&e.this)?;
26020 self.write(" ");
26021 self.write_keyword("OR");
26022 self.write(" ");
26023 self.generate_expression(&e.expression)?;
26024 } else {
26025 self.generate_expression(&e.this)?;
26027 self.write(" || ");
26028 self.generate_expression(&e.expression)?;
26029 }
26030 Ok(())
26031 }
26032
26033 fn generate_data_blocksize_property(&mut self, e: &DataBlocksizeProperty) -> Result<()> {
26034 self.write_keyword("DATABLOCKSIZE");
26036 self.write("=");
26037 if let Some(size) = e.size {
26038 self.write(&size.to_string());
26039 if let Some(units) = &e.units {
26040 self.write_space();
26041 self.generate_expression(units)?;
26042 }
26043 } else if e.minimum.is_some() {
26044 self.write_keyword("MINIMUM");
26045 } else if e.maximum.is_some() {
26046 self.write_keyword("MAXIMUM");
26047 } else if e.default.is_some() {
26048 self.write_keyword("DEFAULT");
26049 }
26050 Ok(())
26051 }
26052
26053 fn generate_data_deletion_property(&mut self, e: &DataDeletionProperty) -> Result<()> {
26054 self.write_keyword("DATA_DELETION");
26056 self.write("=");
26057
26058 let is_on = matches!(&*e.on, Expression::Boolean(BooleanLiteral { value: true }));
26059 let has_options = e.filter_column.is_some() || e.retention_period.is_some();
26060
26061 if is_on {
26062 self.write_keyword("ON");
26063 if has_options {
26064 self.write("(");
26065 let mut first = true;
26066 if let Some(filter_column) = &e.filter_column {
26067 self.write_keyword("FILTER_COLUMN");
26068 self.write("=");
26069 self.generate_expression(filter_column)?;
26070 first = false;
26071 }
26072 if let Some(retention_period) = &e.retention_period {
26073 if !first {
26074 self.write(", ");
26075 }
26076 self.write_keyword("RETENTION_PERIOD");
26077 self.write("=");
26078 self.generate_expression(retention_period)?;
26079 }
26080 self.write(")");
26081 }
26082 } else {
26083 self.write_keyword("OFF");
26084 }
26085 Ok(())
26086 }
26087
26088 fn generate_date_func(&mut self, e: &UnaryFunc) -> Result<()> {
26092 use crate::dialects::DialectType;
26093 use crate::expressions::Literal;
26094
26095 match self.config.dialect {
26096 Some(DialectType::Exasol) => {
26098 self.write_keyword("TO_DATE");
26099 self.write("(");
26100 match &e.this {
26102 Expression::Literal(Literal::String(s)) => {
26103 self.write("'");
26104 self.write(s);
26105 self.write("'");
26106 }
26107 _ => {
26108 self.generate_expression(&e.this)?;
26109 }
26110 }
26111 self.write(")");
26112 }
26113 _ => {
26115 self.write_keyword("DATE");
26116 self.write("(");
26117 self.generate_expression(&e.this)?;
26118 self.write(")");
26119 }
26120 }
26121 Ok(())
26122 }
26123
26124 fn generate_date_bin(&mut self, e: &DateBin) -> Result<()> {
26125 self.write_keyword("DATE_BIN");
26127 self.write("(");
26128 self.generate_expression(&e.this)?;
26129 self.write(", ");
26130 self.generate_expression(&e.expression)?;
26131 if let Some(origin) = &e.origin {
26132 self.write(", ");
26133 self.generate_expression(origin)?;
26134 }
26135 self.write(")");
26136 Ok(())
26137 }
26138
26139 fn generate_date_format_column_constraint(
26140 &mut self,
26141 e: &DateFormatColumnConstraint,
26142 ) -> Result<()> {
26143 self.write_keyword("FORMAT");
26145 self.write_space();
26146 self.generate_expression(&e.this)?;
26147 Ok(())
26148 }
26149
26150 fn generate_date_from_parts(&mut self, e: &DateFromParts) -> Result<()> {
26151 self.write_keyword("DATE_FROM_PARTS");
26153 self.write("(");
26154 let mut first = true;
26155 if let Some(year) = &e.year {
26156 self.generate_expression(year)?;
26157 first = false;
26158 }
26159 if let Some(month) = &e.month {
26160 if !first {
26161 self.write(", ");
26162 }
26163 self.generate_expression(month)?;
26164 first = false;
26165 }
26166 if let Some(day) = &e.day {
26167 if !first {
26168 self.write(", ");
26169 }
26170 self.generate_expression(day)?;
26171 }
26172 self.write(")");
26173 Ok(())
26174 }
26175
26176 fn generate_datetime(&mut self, e: &Datetime) -> Result<()> {
26177 self.write_keyword("DATETIME");
26179 self.write("(");
26180 self.generate_expression(&e.this)?;
26181 if let Some(expr) = &e.expression {
26182 self.write(", ");
26183 self.generate_expression(expr)?;
26184 }
26185 self.write(")");
26186 Ok(())
26187 }
26188
26189 fn generate_datetime_add(&mut self, e: &DatetimeAdd) -> Result<()> {
26190 self.write_keyword("DATETIME_ADD");
26192 self.write("(");
26193 self.generate_expression(&e.this)?;
26194 self.write(", ");
26195 self.generate_expression(&e.expression)?;
26196 if let Some(unit) = &e.unit {
26197 self.write(", ");
26198 self.write_keyword(unit);
26199 }
26200 self.write(")");
26201 Ok(())
26202 }
26203
26204 fn generate_datetime_diff(&mut self, e: &DatetimeDiff) -> Result<()> {
26205 self.write_keyword("DATETIME_DIFF");
26207 self.write("(");
26208 self.generate_expression(&e.this)?;
26209 self.write(", ");
26210 self.generate_expression(&e.expression)?;
26211 if let Some(unit) = &e.unit {
26212 self.write(", ");
26213 self.write_keyword(unit);
26214 }
26215 self.write(")");
26216 Ok(())
26217 }
26218
26219 fn generate_datetime_sub(&mut self, e: &DatetimeSub) -> Result<()> {
26220 self.write_keyword("DATETIME_SUB");
26222 self.write("(");
26223 self.generate_expression(&e.this)?;
26224 self.write(", ");
26225 self.generate_expression(&e.expression)?;
26226 if let Some(unit) = &e.unit {
26227 self.write(", ");
26228 self.write_keyword(unit);
26229 }
26230 self.write(")");
26231 Ok(())
26232 }
26233
26234 fn generate_datetime_trunc(&mut self, e: &DatetimeTrunc) -> Result<()> {
26235 self.write_keyword("DATETIME_TRUNC");
26237 self.write("(");
26238 self.generate_expression(&e.this)?;
26239 self.write(", ");
26240 self.write_keyword(&e.unit);
26241 if let Some(zone) = &e.zone {
26242 self.write(", ");
26243 self.generate_expression(zone)?;
26244 }
26245 self.write(")");
26246 Ok(())
26247 }
26248
26249 fn generate_dayname(&mut self, e: &Dayname) -> Result<()> {
26250 self.write_keyword("DAYNAME");
26252 self.write("(");
26253 self.generate_expression(&e.this)?;
26254 self.write(")");
26255 Ok(())
26256 }
26257
26258 fn generate_declare(&mut self, e: &Declare) -> Result<()> {
26259 self.write_keyword("DECLARE");
26261 self.write_space();
26262 for (i, expr) in e.expressions.iter().enumerate() {
26263 if i > 0 {
26264 self.write(", ");
26265 }
26266 self.generate_expression(expr)?;
26267 }
26268 Ok(())
26269 }
26270
26271 fn generate_declare_item(&mut self, e: &DeclareItem) -> Result<()> {
26272 use crate::dialects::DialectType;
26273
26274 self.generate_expression(&e.this)?;
26276 for name in &e.additional_names {
26278 self.write(", ");
26279 self.generate_expression(name)?;
26280 }
26281 if let Some(kind) = &e.kind {
26282 self.write_space();
26283 match self.config.dialect {
26287 Some(DialectType::BigQuery) => {
26288 self.write(kind);
26289 }
26290 Some(DialectType::TSQL) => {
26291 let is_complex_table = kind.starts_with("TABLE")
26295 && (kind.contains("CLUSTERED") || kind.contains("INDEX"));
26296
26297 if is_complex_table {
26298 self.write(kind);
26300 } else {
26301 if !kind.starts_with("CURSOR") {
26303 self.write_keyword("AS");
26304 self.write_space();
26305 }
26306 if kind == "INT" {
26308 self.write("INTEGER");
26309 } else if kind.starts_with("TABLE") {
26310 let normalized = kind
26312 .replace(" INT ", " INTEGER ")
26313 .replace(" INT,", " INTEGER,")
26314 .replace(" INT)", " INTEGER)")
26315 .replace("(INT ", "(INTEGER ");
26316 self.write(&normalized);
26317 } else {
26318 self.write(kind);
26319 }
26320 }
26321 }
26322 _ => {
26323 if e.has_as {
26324 self.write_keyword("AS");
26325 self.write_space();
26326 }
26327 self.write(kind);
26328 }
26329 }
26330 }
26331 if let Some(default) = &e.default {
26332 match self.config.dialect {
26334 Some(DialectType::BigQuery) => {
26335 self.write_space();
26336 self.write_keyword("DEFAULT");
26337 self.write_space();
26338 }
26339 _ => {
26340 self.write(" = ");
26341 }
26342 }
26343 self.generate_expression(default)?;
26344 }
26345 Ok(())
26346 }
26347
26348 fn generate_decode_case(&mut self, e: &DecodeCase) -> Result<()> {
26349 self.write_keyword("DECODE");
26351 self.write("(");
26352 for (i, expr) in e.expressions.iter().enumerate() {
26353 if i > 0 {
26354 self.write(", ");
26355 }
26356 self.generate_expression(expr)?;
26357 }
26358 self.write(")");
26359 Ok(())
26360 }
26361
26362 fn generate_decompress_binary(&mut self, e: &DecompressBinary) -> Result<()> {
26363 self.write_keyword("DECOMPRESS");
26365 self.write("(");
26366 self.generate_expression(&e.this)?;
26367 self.write(", '");
26368 self.write(&e.method);
26369 self.write("')");
26370 Ok(())
26371 }
26372
26373 fn generate_decompress_string(&mut self, e: &DecompressString) -> Result<()> {
26374 self.write_keyword("DECOMPRESS");
26376 self.write("(");
26377 self.generate_expression(&e.this)?;
26378 self.write(", '");
26379 self.write(&e.method);
26380 self.write("')");
26381 Ok(())
26382 }
26383
26384 fn generate_decrypt(&mut self, e: &Decrypt) -> Result<()> {
26385 self.write_keyword("DECRYPT");
26387 self.write("(");
26388 self.generate_expression(&e.this)?;
26389 if let Some(passphrase) = &e.passphrase {
26390 self.write(", ");
26391 self.generate_expression(passphrase)?;
26392 }
26393 if let Some(aad) = &e.aad {
26394 self.write(", ");
26395 self.generate_expression(aad)?;
26396 }
26397 if let Some(method) = &e.encryption_method {
26398 self.write(", ");
26399 self.generate_expression(method)?;
26400 }
26401 self.write(")");
26402 Ok(())
26403 }
26404
26405 fn generate_decrypt_raw(&mut self, e: &DecryptRaw) -> Result<()> {
26406 self.write_keyword("DECRYPT_RAW");
26408 self.write("(");
26409 self.generate_expression(&e.this)?;
26410 if let Some(key) = &e.key {
26411 self.write(", ");
26412 self.generate_expression(key)?;
26413 }
26414 if let Some(iv) = &e.iv {
26415 self.write(", ");
26416 self.generate_expression(iv)?;
26417 }
26418 if let Some(aad) = &e.aad {
26419 self.write(", ");
26420 self.generate_expression(aad)?;
26421 }
26422 if let Some(method) = &e.encryption_method {
26423 self.write(", ");
26424 self.generate_expression(method)?;
26425 }
26426 self.write(")");
26427 Ok(())
26428 }
26429
26430 fn generate_definer_property(&mut self, e: &DefinerProperty) -> Result<()> {
26431 self.write_keyword("DEFINER");
26433 self.write(" = ");
26434 self.generate_expression(&e.this)?;
26435 Ok(())
26436 }
26437
26438 fn generate_detach(&mut self, e: &Detach) -> Result<()> {
26439 self.write_keyword("DETACH");
26441 if e.exists {
26442 self.write_keyword(" DATABASE IF EXISTS");
26443 }
26444 self.write_space();
26445 self.generate_expression(&e.this)?;
26446 Ok(())
26447 }
26448
26449 fn generate_dict_property(&mut self, e: &DictProperty) -> Result<()> {
26450 let property_name = match e.this.as_ref() {
26451 Expression::Identifier(id) => id.name.as_str(),
26452 Expression::Var(v) => v.this.as_str(),
26453 _ => "DICTIONARY",
26454 };
26455 self.write_keyword(property_name);
26456 self.write("(");
26457 self.write(&e.kind);
26458 if let Some(settings) = &e.settings {
26459 self.write("(");
26460 if let Expression::Tuple(t) = settings.as_ref() {
26461 if self.config.pretty && !t.expressions.is_empty() {
26462 self.write_newline();
26463 self.indent_level += 1;
26464 for (i, pair) in t.expressions.iter().enumerate() {
26465 if i > 0 {
26466 self.write(",");
26467 self.write_newline();
26468 }
26469 self.write_indent();
26470 if let Expression::Tuple(pair_tuple) = pair {
26471 if let Some(k) = pair_tuple.expressions.first() {
26472 self.generate_expression(k)?;
26473 }
26474 if let Some(v) = pair_tuple.expressions.get(1) {
26475 self.write(" ");
26476 self.generate_expression(v)?;
26477 }
26478 } else {
26479 self.generate_expression(pair)?;
26480 }
26481 }
26482 self.indent_level -= 1;
26483 self.write_newline();
26484 self.write_indent();
26485 } else {
26486 for (i, pair) in t.expressions.iter().enumerate() {
26487 if i > 0 {
26488 self.write(", ");
26489 }
26490 if let Expression::Tuple(pair_tuple) = pair {
26491 if let Some(k) = pair_tuple.expressions.first() {
26492 self.generate_expression(k)?;
26493 }
26494 if let Some(v) = pair_tuple.expressions.get(1) {
26495 self.write(" ");
26496 self.generate_expression(v)?;
26497 }
26498 } else {
26499 self.generate_expression(pair)?;
26500 }
26501 }
26502 }
26503 } else {
26504 self.generate_expression(settings)?;
26505 }
26506 self.write(")");
26507 } else if property_name.eq_ignore_ascii_case("LAYOUT") {
26508 self.write("()");
26509 }
26510 self.write(")");
26511 Ok(())
26512 }
26513
26514 fn generate_dict_range(&mut self, e: &DictRange) -> Result<()> {
26515 let property_name = match e.this.as_ref() {
26516 Expression::Identifier(id) => id.name.as_str(),
26517 Expression::Var(v) => v.this.as_str(),
26518 _ => "RANGE",
26519 };
26520 self.write_keyword(property_name);
26521 self.write("(");
26522 if let Some(min) = &e.min {
26523 self.write_keyword("MIN");
26524 self.write_space();
26525 self.generate_expression(min)?;
26526 }
26527 if let Some(max) = &e.max {
26528 self.write_space();
26529 self.write_keyword("MAX");
26530 self.write_space();
26531 self.generate_expression(max)?;
26532 }
26533 self.write(")");
26534 Ok(())
26535 }
26536
26537 fn generate_directory(&mut self, e: &Directory) -> Result<()> {
26538 if e.local.is_some() {
26540 self.write_keyword("LOCAL ");
26541 }
26542 self.write_keyword("DIRECTORY");
26543 self.write_space();
26544 self.generate_expression(&e.this)?;
26545 if let Some(row_format) = &e.row_format {
26546 self.write_space();
26547 self.generate_expression(row_format)?;
26548 }
26549 Ok(())
26550 }
26551
26552 fn generate_dist_key_property(&mut self, e: &DistKeyProperty) -> Result<()> {
26553 self.write_keyword("DISTKEY");
26555 self.write("(");
26556 self.generate_expression(&e.this)?;
26557 self.write(")");
26558 Ok(())
26559 }
26560
26561 fn generate_dist_style_property(&mut self, e: &DistStyleProperty) -> Result<()> {
26562 self.write_keyword("DISTSTYLE");
26564 self.write_space();
26565 self.generate_expression(&e.this)?;
26566 Ok(())
26567 }
26568
26569 fn generate_distribute_by(&mut self, e: &DistributeBy) -> Result<()> {
26570 self.write_keyword("DISTRIBUTE BY");
26572 self.write_space();
26573 for (i, expr) in e.expressions.iter().enumerate() {
26574 if i > 0 {
26575 self.write(", ");
26576 }
26577 self.generate_expression(expr)?;
26578 }
26579 Ok(())
26580 }
26581
26582 fn generate_distributed_by_property(&mut self, e: &DistributedByProperty) -> Result<()> {
26583 self.write_keyword("DISTRIBUTED BY");
26585 self.write_space();
26586 self.write(&e.kind);
26587 if !e.expressions.is_empty() {
26588 self.write(" (");
26589 for (i, expr) in e.expressions.iter().enumerate() {
26590 if i > 0 {
26591 self.write(", ");
26592 }
26593 self.generate_expression(expr)?;
26594 }
26595 self.write(")");
26596 }
26597 if let Some(buckets) = &e.buckets {
26598 self.write_space();
26599 self.write_keyword("BUCKETS");
26600 self.write_space();
26601 self.generate_expression(buckets)?;
26602 }
26603 if let Some(order) = &e.order {
26604 self.write_space();
26605 self.generate_expression(order)?;
26606 }
26607 Ok(())
26608 }
26609
26610 fn generate_dot_product(&mut self, e: &DotProduct) -> Result<()> {
26611 self.write_keyword("DOT_PRODUCT");
26613 self.write("(");
26614 self.generate_expression(&e.this)?;
26615 self.write(", ");
26616 self.generate_expression(&e.expression)?;
26617 self.write(")");
26618 Ok(())
26619 }
26620
26621 fn generate_drop_partition(&mut self, e: &DropPartition) -> Result<()> {
26622 self.write_keyword("DROP");
26624 if e.exists {
26625 self.write_keyword(" IF EXISTS ");
26626 } else {
26627 self.write_space();
26628 }
26629 for (i, expr) in e.expressions.iter().enumerate() {
26630 if i > 0 {
26631 self.write(", ");
26632 }
26633 self.generate_expression(expr)?;
26634 }
26635 Ok(())
26636 }
26637
26638 fn generate_duplicate_key_property(&mut self, e: &DuplicateKeyProperty) -> Result<()> {
26639 self.write_keyword("DUPLICATE KEY");
26641 self.write(" (");
26642 for (i, expr) in e.expressions.iter().enumerate() {
26643 if i > 0 {
26644 self.write(", ");
26645 }
26646 self.generate_expression(expr)?;
26647 }
26648 self.write(")");
26649 Ok(())
26650 }
26651
26652 fn generate_elt(&mut self, e: &Elt) -> Result<()> {
26653 self.write_keyword("ELT");
26655 self.write("(");
26656 self.generate_expression(&e.this)?;
26657 for expr in &e.expressions {
26658 self.write(", ");
26659 self.generate_expression(expr)?;
26660 }
26661 self.write(")");
26662 Ok(())
26663 }
26664
26665 fn generate_encode(&mut self, e: &Encode) -> Result<()> {
26666 self.write_keyword("ENCODE");
26668 self.write("(");
26669 self.generate_expression(&e.this)?;
26670 if let Some(charset) = &e.charset {
26671 self.write(", ");
26672 self.generate_expression(charset)?;
26673 }
26674 self.write(")");
26675 Ok(())
26676 }
26677
26678 fn generate_encode_property(&mut self, e: &EncodeProperty) -> Result<()> {
26679 if e.key.is_some() {
26681 self.write_keyword("KEY ");
26682 }
26683 self.write_keyword("ENCODE");
26684 self.write_space();
26685 self.generate_expression(&e.this)?;
26686 if !e.properties.is_empty() {
26687 self.write(" (");
26688 for (i, prop) in e.properties.iter().enumerate() {
26689 if i > 0 {
26690 self.write(", ");
26691 }
26692 self.generate_expression(prop)?;
26693 }
26694 self.write(")");
26695 }
26696 Ok(())
26697 }
26698
26699 fn generate_encrypt(&mut self, e: &Encrypt) -> Result<()> {
26700 self.write_keyword("ENCRYPT");
26702 self.write("(");
26703 self.generate_expression(&e.this)?;
26704 if let Some(passphrase) = &e.passphrase {
26705 self.write(", ");
26706 self.generate_expression(passphrase)?;
26707 }
26708 if let Some(aad) = &e.aad {
26709 self.write(", ");
26710 self.generate_expression(aad)?;
26711 }
26712 if let Some(method) = &e.encryption_method {
26713 self.write(", ");
26714 self.generate_expression(method)?;
26715 }
26716 self.write(")");
26717 Ok(())
26718 }
26719
26720 fn generate_encrypt_raw(&mut self, e: &EncryptRaw) -> Result<()> {
26721 self.write_keyword("ENCRYPT_RAW");
26723 self.write("(");
26724 self.generate_expression(&e.this)?;
26725 if let Some(key) = &e.key {
26726 self.write(", ");
26727 self.generate_expression(key)?;
26728 }
26729 if let Some(iv) = &e.iv {
26730 self.write(", ");
26731 self.generate_expression(iv)?;
26732 }
26733 if let Some(aad) = &e.aad {
26734 self.write(", ");
26735 self.generate_expression(aad)?;
26736 }
26737 if let Some(method) = &e.encryption_method {
26738 self.write(", ");
26739 self.generate_expression(method)?;
26740 }
26741 self.write(")");
26742 Ok(())
26743 }
26744
26745 fn generate_engine_property(&mut self, e: &EngineProperty) -> Result<()> {
26746 self.write_keyword("ENGINE");
26748 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
26749 self.write("=");
26750 } else {
26751 self.write(" = ");
26752 }
26753 self.generate_expression(&e.this)?;
26754 Ok(())
26755 }
26756
26757 fn generate_enviroment_property(&mut self, e: &EnviromentProperty) -> Result<()> {
26758 self.write_keyword("ENVIRONMENT");
26760 self.write(" (");
26761 for (i, expr) in e.expressions.iter().enumerate() {
26762 if i > 0 {
26763 self.write(", ");
26764 }
26765 self.generate_expression(expr)?;
26766 }
26767 self.write(")");
26768 Ok(())
26769 }
26770
26771 fn generate_ephemeral_column_constraint(
26772 &mut self,
26773 e: &EphemeralColumnConstraint,
26774 ) -> Result<()> {
26775 self.write_keyword("EPHEMERAL");
26777 if let Some(this) = &e.this {
26778 self.write_space();
26779 self.generate_expression(this)?;
26780 }
26781 Ok(())
26782 }
26783
26784 fn generate_equal_null(&mut self, e: &EqualNull) -> Result<()> {
26785 self.write_keyword("EQUAL_NULL");
26787 self.write("(");
26788 self.generate_expression(&e.this)?;
26789 self.write(", ");
26790 self.generate_expression(&e.expression)?;
26791 self.write(")");
26792 Ok(())
26793 }
26794
26795 fn generate_euclidean_distance(&mut self, e: &EuclideanDistance) -> Result<()> {
26796 use crate::dialects::DialectType;
26797
26798 match self.config.dialect {
26800 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
26801 self.generate_expression(&e.this)?;
26802 self.write(" <-> ");
26803 self.generate_expression(&e.expression)?;
26804 }
26805 _ => {
26806 self.write_keyword("EUCLIDEAN_DISTANCE");
26808 self.write("(");
26809 self.generate_expression(&e.this)?;
26810 self.write(", ");
26811 self.generate_expression(&e.expression)?;
26812 self.write(")");
26813 }
26814 }
26815 Ok(())
26816 }
26817
26818 fn generate_execute_as_property(&mut self, e: &ExecuteAsProperty) -> Result<()> {
26819 self.write_keyword("EXECUTE AS");
26821 self.write_space();
26822 self.generate_expression(&e.this)?;
26823 Ok(())
26824 }
26825
26826 fn generate_export(&mut self, e: &Export) -> Result<()> {
26827 self.write_keyword("EXPORT DATA");
26829 if let Some(connection) = &e.connection {
26830 self.write_space();
26831 self.write_keyword("WITH CONNECTION");
26832 self.write_space();
26833 self.generate_expression(connection)?;
26834 }
26835 if !e.options.is_empty() {
26836 self.write_space();
26837 self.generate_options_clause(&e.options)?;
26838 }
26839 self.write_space();
26840 self.write_keyword("AS");
26841 self.write_space();
26842 self.generate_expression(&e.this)?;
26843 Ok(())
26844 }
26845
26846 fn generate_external_property(&mut self, e: &ExternalProperty) -> Result<()> {
26847 self.write_keyword("EXTERNAL");
26849 if let Some(this) = &e.this {
26850 self.write_space();
26851 self.generate_expression(this)?;
26852 }
26853 Ok(())
26854 }
26855
26856 fn generate_fallback_property(&mut self, e: &FallbackProperty) -> Result<()> {
26857 if e.no.is_some() {
26859 self.write_keyword("NO ");
26860 }
26861 self.write_keyword("FALLBACK");
26862 if e.protection.is_some() {
26863 self.write_keyword(" PROTECTION");
26864 }
26865 Ok(())
26866 }
26867
26868 fn generate_farm_fingerprint(&mut self, e: &FarmFingerprint) -> Result<()> {
26869 self.write_keyword("FARM_FINGERPRINT");
26871 self.write("(");
26872 for (i, expr) in e.expressions.iter().enumerate() {
26873 if i > 0 {
26874 self.write(", ");
26875 }
26876 self.generate_expression(expr)?;
26877 }
26878 self.write(")");
26879 Ok(())
26880 }
26881
26882 fn generate_features_at_time(&mut self, e: &FeaturesAtTime) -> Result<()> {
26883 self.write_keyword("FEATURES_AT_TIME");
26885 self.write("(");
26886 self.generate_expression(&e.this)?;
26887 if let Some(time) = &e.time {
26888 self.write(", ");
26889 self.generate_expression(time)?;
26890 }
26891 if let Some(num_rows) = &e.num_rows {
26892 self.write(", ");
26893 self.generate_expression(num_rows)?;
26894 }
26895 if let Some(ignore_nulls) = &e.ignore_feature_nulls {
26896 self.write(", ");
26897 self.generate_expression(ignore_nulls)?;
26898 }
26899 self.write(")");
26900 Ok(())
26901 }
26902
26903 fn generate_fetch(&mut self, e: &Fetch) -> Result<()> {
26904 let use_limit = !e.percent
26906 && !e.with_ties
26907 && e.count.is_some()
26908 && matches!(
26909 self.config.dialect,
26910 Some(DialectType::Spark)
26911 | Some(DialectType::Hive)
26912 | Some(DialectType::DuckDB)
26913 | Some(DialectType::SQLite)
26914 | Some(DialectType::MySQL)
26915 | Some(DialectType::BigQuery)
26916 | Some(DialectType::Databricks)
26917 | Some(DialectType::StarRocks)
26918 | Some(DialectType::Doris)
26919 | Some(DialectType::Athena)
26920 | Some(DialectType::ClickHouse)
26921 );
26922
26923 if use_limit {
26924 self.write_keyword("LIMIT");
26925 self.write_space();
26926 self.generate_expression(e.count.as_ref().unwrap())?;
26927 return Ok(());
26928 }
26929
26930 self.write_keyword("FETCH");
26932 if !e.direction.is_empty() {
26933 self.write_space();
26934 self.write_keyword(&e.direction);
26935 }
26936 if let Some(count) = &e.count {
26937 self.write_space();
26938 self.generate_expression(count)?;
26939 }
26940 if e.percent {
26942 self.write_keyword(" PERCENT");
26943 }
26944 if e.rows {
26945 self.write_keyword(" ROWS");
26946 }
26947 if e.with_ties {
26948 self.write_keyword(" WITH TIES");
26949 } else if e.rows {
26950 self.write_keyword(" ONLY");
26951 } else {
26952 self.write_keyword(" ROWS ONLY");
26953 }
26954 Ok(())
26955 }
26956
26957 fn generate_file_format_property(&mut self, e: &FileFormatProperty) -> Result<()> {
26958 if e.hive_format.is_some() {
26962 self.write_keyword("STORED AS");
26964 self.write_space();
26965 if let Some(this) = &e.this {
26966 if let Expression::Identifier(id) = this.as_ref() {
26968 self.write_keyword(&id.name.to_uppercase());
26969 } else {
26970 self.generate_expression(this)?;
26971 }
26972 }
26973 } else if matches!(self.config.dialect, Some(DialectType::Hive)) {
26974 self.write_keyword("STORED AS");
26976 self.write_space();
26977 if let Some(this) = &e.this {
26978 if let Expression::Identifier(id) = this.as_ref() {
26979 self.write_keyword(&id.name.to_uppercase());
26980 } else {
26981 self.generate_expression(this)?;
26982 }
26983 }
26984 } else if matches!(
26985 self.config.dialect,
26986 Some(DialectType::Spark) | Some(DialectType::Databricks)
26987 ) {
26988 self.write_keyword("USING");
26990 self.write_space();
26991 if let Some(this) = &e.this {
26992 self.generate_expression(this)?;
26993 }
26994 } else {
26995 self.write_keyword("FILE_FORMAT");
26997 self.write(" = ");
26998 if let Some(this) = &e.this {
26999 self.generate_expression(this)?;
27000 } else if !e.expressions.is_empty() {
27001 self.write("(");
27002 for (i, expr) in e.expressions.iter().enumerate() {
27003 if i > 0 {
27004 self.write(", ");
27005 }
27006 self.generate_expression(expr)?;
27007 }
27008 self.write(")");
27009 }
27010 }
27011 Ok(())
27012 }
27013
27014 fn generate_filter(&mut self, e: &Filter) -> Result<()> {
27015 self.generate_expression(&e.this)?;
27017 self.write_space();
27018 self.write_keyword("FILTER");
27019 self.write("(");
27020 self.write_keyword("WHERE");
27021 self.write_space();
27022 self.generate_expression(&e.expression)?;
27023 self.write(")");
27024 Ok(())
27025 }
27026
27027 fn generate_float64(&mut self, e: &Float64) -> Result<()> {
27028 self.write_keyword("FLOAT64");
27030 self.write("(");
27031 self.generate_expression(&e.this)?;
27032 if let Some(expr) = &e.expression {
27033 self.write(", ");
27034 self.generate_expression(expr)?;
27035 }
27036 self.write(")");
27037 Ok(())
27038 }
27039
27040 fn generate_for_in(&mut self, e: &ForIn) -> Result<()> {
27041 self.write_keyword("FOR");
27043 self.write_space();
27044 self.generate_expression(&e.this)?;
27045 self.write_space();
27046 self.write_keyword("DO");
27047 self.write_space();
27048 self.generate_expression(&e.expression)?;
27049 Ok(())
27050 }
27051
27052 fn generate_foreign_key(&mut self, e: &ForeignKey) -> Result<()> {
27053 self.write_keyword("FOREIGN KEY");
27055 if !e.expressions.is_empty() {
27056 self.write(" (");
27057 for (i, expr) in e.expressions.iter().enumerate() {
27058 if i > 0 {
27059 self.write(", ");
27060 }
27061 self.generate_expression(expr)?;
27062 }
27063 self.write(")");
27064 }
27065 if let Some(reference) = &e.reference {
27066 self.write_space();
27067 self.generate_expression(reference)?;
27068 }
27069 if let Some(delete) = &e.delete {
27070 self.write_space();
27071 self.write_keyword("ON DELETE");
27072 self.write_space();
27073 self.generate_expression(delete)?;
27074 }
27075 if let Some(update) = &e.update {
27076 self.write_space();
27077 self.write_keyword("ON UPDATE");
27078 self.write_space();
27079 self.generate_expression(update)?;
27080 }
27081 if !e.options.is_empty() {
27082 self.write_space();
27083 for (i, opt) in e.options.iter().enumerate() {
27084 if i > 0 {
27085 self.write_space();
27086 }
27087 self.generate_expression(opt)?;
27088 }
27089 }
27090 Ok(())
27091 }
27092
27093 fn generate_format(&mut self, e: &Format) -> Result<()> {
27094 self.write_keyword("FORMAT");
27096 self.write("(");
27097 self.generate_expression(&e.this)?;
27098 for expr in &e.expressions {
27099 self.write(", ");
27100 self.generate_expression(expr)?;
27101 }
27102 self.write(")");
27103 Ok(())
27104 }
27105
27106 fn generate_format_phrase(&mut self, e: &FormatPhrase) -> Result<()> {
27107 self.generate_expression(&e.this)?;
27109 self.write(" (");
27110 self.write_keyword("FORMAT");
27111 self.write(" '");
27112 self.write(&e.format);
27113 self.write("')");
27114 Ok(())
27115 }
27116
27117 fn generate_freespace_property(&mut self, e: &FreespaceProperty) -> Result<()> {
27118 self.write_keyword("FREESPACE");
27120 self.write("=");
27121 self.generate_expression(&e.this)?;
27122 if e.percent.is_some() {
27123 self.write_keyword(" PERCENT");
27124 }
27125 Ok(())
27126 }
27127
27128 fn generate_from(&mut self, e: &From) -> Result<()> {
27129 self.write_keyword("FROM");
27131 self.write_space();
27132
27133 use crate::dialects::DialectType;
27137 let has_tablesample = e
27138 .expressions
27139 .iter()
27140 .any(|expr| matches!(expr, Expression::TableSample(_)));
27141 let is_cross_join_dialect = matches!(
27142 self.config.dialect,
27143 Some(DialectType::BigQuery)
27144 | Some(DialectType::Hive)
27145 | Some(DialectType::Spark)
27146 | Some(DialectType::Databricks)
27147 | Some(DialectType::SQLite)
27148 | Some(DialectType::ClickHouse)
27149 );
27150 let source_is_same_as_target2 = self.config.source_dialect.is_some()
27151 && self.config.source_dialect == self.config.dialect;
27152 let source_is_cross_join_dialect2 = matches!(
27153 self.config.source_dialect,
27154 Some(DialectType::BigQuery)
27155 | Some(DialectType::Hive)
27156 | Some(DialectType::Spark)
27157 | Some(DialectType::Databricks)
27158 | Some(DialectType::SQLite)
27159 | Some(DialectType::ClickHouse)
27160 );
27161 let use_cross_join = !has_tablesample
27162 && is_cross_join_dialect
27163 && (source_is_same_as_target2
27164 || source_is_cross_join_dialect2
27165 || self.config.source_dialect.is_none());
27166
27167 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
27169
27170 for (i, expr) in e.expressions.iter().enumerate() {
27171 if i > 0 {
27172 if use_cross_join {
27173 self.write(" CROSS JOIN ");
27174 } else {
27175 self.write(", ");
27176 }
27177 }
27178 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
27179 self.write("(");
27180 self.generate_expression(expr)?;
27181 self.write(")");
27182 } else {
27183 self.generate_expression(expr)?;
27184 }
27185 }
27186 Ok(())
27187 }
27188
27189 fn generate_from_base(&mut self, e: &FromBase) -> Result<()> {
27190 self.write_keyword("FROM_BASE");
27192 self.write("(");
27193 self.generate_expression(&e.this)?;
27194 self.write(", ");
27195 self.generate_expression(&e.expression)?;
27196 self.write(")");
27197 Ok(())
27198 }
27199
27200 fn generate_from_time_zone(&mut self, e: &FromTimeZone) -> Result<()> {
27201 self.generate_expression(&e.this)?;
27203 if let Some(zone) = &e.zone {
27204 self.write_space();
27205 self.write_keyword("AT TIME ZONE");
27206 self.write_space();
27207 self.generate_expression(zone)?;
27208 self.write_space();
27209 self.write_keyword("AT TIME ZONE");
27210 self.write(" 'UTC'");
27211 }
27212 Ok(())
27213 }
27214
27215 fn generate_gap_fill(&mut self, e: &GapFill) -> Result<()> {
27216 self.write_keyword("GAP_FILL");
27218 self.write("(");
27219 self.generate_expression(&e.this)?;
27220 if let Some(ts_column) = &e.ts_column {
27221 self.write(", ");
27222 self.generate_expression(ts_column)?;
27223 }
27224 if let Some(bucket_width) = &e.bucket_width {
27225 self.write(", ");
27226 self.generate_expression(bucket_width)?;
27227 }
27228 if let Some(partitioning_columns) = &e.partitioning_columns {
27229 self.write(", ");
27230 self.generate_expression(partitioning_columns)?;
27231 }
27232 if let Some(value_columns) = &e.value_columns {
27233 self.write(", ");
27234 self.generate_expression(value_columns)?;
27235 }
27236 self.write(")");
27237 Ok(())
27238 }
27239
27240 fn generate_generate_date_array(&mut self, e: &GenerateDateArray) -> Result<()> {
27241 self.write_keyword("GENERATE_DATE_ARRAY");
27243 self.write("(");
27244 let mut first = true;
27245 if let Some(start) = &e.start {
27246 self.generate_expression(start)?;
27247 first = false;
27248 }
27249 if let Some(end) = &e.end {
27250 if !first {
27251 self.write(", ");
27252 }
27253 self.generate_expression(end)?;
27254 first = false;
27255 }
27256 if let Some(step) = &e.step {
27257 if !first {
27258 self.write(", ");
27259 }
27260 self.generate_expression(step)?;
27261 }
27262 self.write(")");
27263 Ok(())
27264 }
27265
27266 fn generate_generate_embedding(&mut self, e: &GenerateEmbedding) -> Result<()> {
27267 self.write_keyword("ML.GENERATE_EMBEDDING");
27269 self.write("(");
27270 self.generate_expression(&e.this)?;
27271 self.write(", ");
27272 self.generate_expression(&e.expression)?;
27273 if let Some(params) = &e.params_struct {
27274 self.write(", ");
27275 self.generate_expression(params)?;
27276 }
27277 self.write(")");
27278 Ok(())
27279 }
27280
27281 fn generate_generate_series(&mut self, e: &GenerateSeries) -> Result<()> {
27282 let fn_name = match self.config.dialect {
27284 Some(DialectType::Presto)
27285 | Some(DialectType::Trino)
27286 | Some(DialectType::Athena)
27287 | Some(DialectType::Spark)
27288 | Some(DialectType::Databricks)
27289 | Some(DialectType::Hive) => "SEQUENCE",
27290 _ => "GENERATE_SERIES",
27291 };
27292 self.write_keyword(fn_name);
27293 self.write("(");
27294 let mut first = true;
27295 if let Some(start) = &e.start {
27296 self.generate_expression(start)?;
27297 first = false;
27298 }
27299 if let Some(end) = &e.end {
27300 if !first {
27301 self.write(", ");
27302 }
27303 self.generate_expression(end)?;
27304 first = false;
27305 }
27306 if let Some(step) = &e.step {
27307 if !first {
27308 self.write(", ");
27309 }
27310 if matches!(
27313 self.config.dialect,
27314 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
27315 ) {
27316 if let Some(converted) = self.convert_week_interval_to_day(step) {
27317 self.generate_expression(&converted)?;
27318 } else {
27319 self.generate_expression(step)?;
27320 }
27321 } else {
27322 self.generate_expression(step)?;
27323 }
27324 }
27325 self.write(")");
27326 Ok(())
27327 }
27328
27329 fn convert_week_interval_to_day(&self, expr: &Expression) -> Option<Expression> {
27332 use crate::expressions::*;
27333 if let Expression::Interval(ref iv) = expr {
27334 let (is_week, count_str) = if let Some(IntervalUnitSpec::Simple {
27336 unit: IntervalUnit::Week,
27337 ..
27338 }) = &iv.unit
27339 {
27340 let count = match &iv.this {
27342 Some(Expression::Literal(Literal::String(s))) => s.clone(),
27343 Some(Expression::Literal(Literal::Number(s))) => s.clone(),
27344 _ => return None,
27345 };
27346 (true, count)
27347 } else if iv.unit.is_none() {
27348 if let Some(Expression::Literal(Literal::String(s))) = &iv.this {
27350 let parts: Vec<&str> = s.trim().splitn(2, char::is_whitespace).collect();
27351 if parts.len() == 2 && parts[1].eq_ignore_ascii_case("WEEK") {
27352 (true, parts[0].to_string())
27353 } else {
27354 (false, String::new())
27355 }
27356 } else {
27357 (false, String::new())
27358 }
27359 } else {
27360 (false, String::new())
27361 };
27362
27363 if is_week {
27364 let count_expr = Expression::Literal(Literal::Number(count_str));
27366 let day_interval = Expression::Interval(Box::new(Interval {
27367 this: Some(Expression::Literal(Literal::String("7".to_string()))),
27368 unit: Some(IntervalUnitSpec::Simple {
27369 unit: IntervalUnit::Day,
27370 use_plural: false,
27371 }),
27372 }));
27373 let mul = Expression::Mul(Box::new(BinaryOp {
27374 left: count_expr,
27375 right: day_interval,
27376 left_comments: vec![],
27377 operator_comments: vec![],
27378 trailing_comments: vec![],
27379 }));
27380 return Some(Expression::Paren(Box::new(Paren {
27381 this: mul,
27382 trailing_comments: vec![],
27383 })));
27384 }
27385 }
27386 None
27387 }
27388
27389 fn generate_generate_timestamp_array(&mut self, e: &GenerateTimestampArray) -> Result<()> {
27390 self.write_keyword("GENERATE_TIMESTAMP_ARRAY");
27392 self.write("(");
27393 let mut first = true;
27394 if let Some(start) = &e.start {
27395 self.generate_expression(start)?;
27396 first = false;
27397 }
27398 if let Some(end) = &e.end {
27399 if !first {
27400 self.write(", ");
27401 }
27402 self.generate_expression(end)?;
27403 first = false;
27404 }
27405 if let Some(step) = &e.step {
27406 if !first {
27407 self.write(", ");
27408 }
27409 self.generate_expression(step)?;
27410 }
27411 self.write(")");
27412 Ok(())
27413 }
27414
27415 fn generate_generated_as_identity_column_constraint(
27416 &mut self,
27417 e: &GeneratedAsIdentityColumnConstraint,
27418 ) -> Result<()> {
27419 use crate::dialects::DialectType;
27420
27421 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
27423 self.write_keyword("AUTOINCREMENT");
27424 if let Some(start) = &e.start {
27425 self.write_keyword(" START ");
27426 self.generate_expression(start)?;
27427 }
27428 if let Some(increment) = &e.increment {
27429 self.write_keyword(" INCREMENT ");
27430 self.generate_expression(increment)?;
27431 }
27432 return Ok(());
27433 }
27434
27435 self.write_keyword("GENERATED");
27437 if let Some(this) = &e.this {
27438 if let Expression::Boolean(b) = this.as_ref() {
27440 if b.value {
27441 self.write_keyword(" ALWAYS");
27442 } else {
27443 self.write_keyword(" BY DEFAULT");
27444 if e.on_null.is_some() {
27445 self.write_keyword(" ON NULL");
27446 }
27447 }
27448 } else {
27449 self.write_keyword(" ALWAYS");
27450 }
27451 }
27452 self.write_keyword(" AS IDENTITY");
27453 let has_options = e.start.is_some()
27455 || e.increment.is_some()
27456 || e.minvalue.is_some()
27457 || e.maxvalue.is_some();
27458 if has_options {
27459 self.write(" (");
27460 let mut first = true;
27461 if let Some(start) = &e.start {
27462 self.write_keyword("START WITH ");
27463 self.generate_expression(start)?;
27464 first = false;
27465 }
27466 if let Some(increment) = &e.increment {
27467 if !first {
27468 self.write(" ");
27469 }
27470 self.write_keyword("INCREMENT BY ");
27471 self.generate_expression(increment)?;
27472 first = false;
27473 }
27474 if let Some(minvalue) = &e.minvalue {
27475 if !first {
27476 self.write(" ");
27477 }
27478 self.write_keyword("MINVALUE ");
27479 self.generate_expression(minvalue)?;
27480 first = false;
27481 }
27482 if let Some(maxvalue) = &e.maxvalue {
27483 if !first {
27484 self.write(" ");
27485 }
27486 self.write_keyword("MAXVALUE ");
27487 self.generate_expression(maxvalue)?;
27488 }
27489 self.write(")");
27490 }
27491 Ok(())
27492 }
27493
27494 fn generate_generated_as_row_column_constraint(
27495 &mut self,
27496 e: &GeneratedAsRowColumnConstraint,
27497 ) -> Result<()> {
27498 self.write_keyword("GENERATED ALWAYS AS ROW ");
27500 if e.start.is_some() {
27501 self.write_keyword("START");
27502 } else {
27503 self.write_keyword("END");
27504 }
27505 if e.hidden.is_some() {
27506 self.write_keyword(" HIDDEN");
27507 }
27508 Ok(())
27509 }
27510
27511 fn generate_get(&mut self, e: &Get) -> Result<()> {
27512 self.write_keyword("GET");
27514 self.write_space();
27515 self.generate_expression(&e.this)?;
27516 if let Some(target) = &e.target {
27517 self.write_space();
27518 self.generate_expression(target)?;
27519 }
27520 for prop in &e.properties {
27521 self.write_space();
27522 self.generate_expression(prop)?;
27523 }
27524 Ok(())
27525 }
27526
27527 fn generate_get_extract(&mut self, e: &GetExtract) -> Result<()> {
27528 self.generate_expression(&e.this)?;
27530 self.write("[");
27531 self.generate_expression(&e.expression)?;
27532 self.write("]");
27533 Ok(())
27534 }
27535
27536 fn generate_getbit(&mut self, e: &Getbit) -> Result<()> {
27537 self.write_keyword("GETBIT");
27539 self.write("(");
27540 self.generate_expression(&e.this)?;
27541 self.write(", ");
27542 self.generate_expression(&e.expression)?;
27543 self.write(")");
27544 Ok(())
27545 }
27546
27547 fn generate_grant_principal(&mut self, e: &GrantPrincipal) -> Result<()> {
27548 if e.is_role {
27550 self.write_keyword("ROLE");
27551 self.write_space();
27552 } else if e.is_group {
27553 self.write_keyword("GROUP");
27554 self.write_space();
27555 }
27556 self.write(&e.name.name);
27557 Ok(())
27558 }
27559
27560 fn generate_grant_privilege(&mut self, e: &GrantPrivilege) -> Result<()> {
27561 self.generate_expression(&e.this)?;
27563 if !e.expressions.is_empty() {
27564 self.write("(");
27565 for (i, expr) in e.expressions.iter().enumerate() {
27566 if i > 0 {
27567 self.write(", ");
27568 }
27569 self.generate_expression(expr)?;
27570 }
27571 self.write(")");
27572 }
27573 Ok(())
27574 }
27575
27576 fn generate_group(&mut self, e: &Group) -> Result<()> {
27577 self.write_keyword("GROUP BY");
27579 match e.all {
27581 Some(true) => {
27582 self.write_space();
27583 self.write_keyword("ALL");
27584 }
27585 Some(false) => {
27586 self.write_space();
27587 self.write_keyword("DISTINCT");
27588 }
27589 None => {}
27590 }
27591 if !e.expressions.is_empty() {
27592 self.write_space();
27593 for (i, expr) in e.expressions.iter().enumerate() {
27594 if i > 0 {
27595 self.write(", ");
27596 }
27597 self.generate_expression(expr)?;
27598 }
27599 }
27600 if let Some(cube) = &e.cube {
27602 if !e.expressions.is_empty() {
27603 self.write(", ");
27604 } else {
27605 self.write_space();
27606 }
27607 self.generate_expression(cube)?;
27608 }
27609 if let Some(rollup) = &e.rollup {
27610 if !e.expressions.is_empty() || e.cube.is_some() {
27611 self.write(", ");
27612 } else {
27613 self.write_space();
27614 }
27615 self.generate_expression(rollup)?;
27616 }
27617 if let Some(grouping_sets) = &e.grouping_sets {
27618 if !e.expressions.is_empty() || e.cube.is_some() || e.rollup.is_some() {
27619 self.write(", ");
27620 } else {
27621 self.write_space();
27622 }
27623 self.generate_expression(grouping_sets)?;
27624 }
27625 if let Some(totals) = &e.totals {
27626 self.write_space();
27627 self.write_keyword("WITH TOTALS");
27628 self.generate_expression(totals)?;
27629 }
27630 Ok(())
27631 }
27632
27633 fn generate_group_by(&mut self, e: &GroupBy) -> Result<()> {
27634 self.write_keyword("GROUP BY");
27636 match e.all {
27638 Some(true) => {
27639 self.write_space();
27640 self.write_keyword("ALL");
27641 }
27642 Some(false) => {
27643 self.write_space();
27644 self.write_keyword("DISTINCT");
27645 }
27646 None => {}
27647 }
27648
27649 let mut trailing_cube = false;
27652 let mut trailing_rollup = false;
27653 let mut regular_expressions: Vec<&Expression> = Vec::new();
27654
27655 for expr in &e.expressions {
27656 match expr {
27657 Expression::Cube(c) if c.expressions.is_empty() => {
27658 trailing_cube = true;
27659 }
27660 Expression::Rollup(r) if r.expressions.is_empty() => {
27661 trailing_rollup = true;
27662 }
27663 _ => {
27664 regular_expressions.push(expr);
27665 }
27666 }
27667 }
27668
27669 if self.config.pretty {
27671 self.write_newline();
27672 self.indent_level += 1;
27673 for (i, expr) in regular_expressions.iter().enumerate() {
27674 if i > 0 {
27675 self.write(",");
27676 self.write_newline();
27677 }
27678 self.write_indent();
27679 self.generate_expression(expr)?;
27680 }
27681 self.indent_level -= 1;
27682 } else {
27683 self.write_space();
27684 for (i, expr) in regular_expressions.iter().enumerate() {
27685 if i > 0 {
27686 self.write(", ");
27687 }
27688 self.generate_expression(expr)?;
27689 }
27690 }
27691
27692 if trailing_cube {
27694 self.write_space();
27695 self.write_keyword("WITH CUBE");
27696 } else if trailing_rollup {
27697 self.write_space();
27698 self.write_keyword("WITH ROLLUP");
27699 }
27700
27701 if e.totals {
27703 self.write_space();
27704 self.write_keyword("WITH TOTALS");
27705 }
27706
27707 Ok(())
27708 }
27709
27710 fn generate_grouping(&mut self, e: &Grouping) -> Result<()> {
27711 self.write_keyword("GROUPING");
27713 self.write("(");
27714 for (i, expr) in e.expressions.iter().enumerate() {
27715 if i > 0 {
27716 self.write(", ");
27717 }
27718 self.generate_expression(expr)?;
27719 }
27720 self.write(")");
27721 Ok(())
27722 }
27723
27724 fn generate_grouping_id(&mut self, e: &GroupingId) -> Result<()> {
27725 self.write_keyword("GROUPING_ID");
27727 self.write("(");
27728 for (i, expr) in e.expressions.iter().enumerate() {
27729 if i > 0 {
27730 self.write(", ");
27731 }
27732 self.generate_expression(expr)?;
27733 }
27734 self.write(")");
27735 Ok(())
27736 }
27737
27738 fn generate_grouping_sets(&mut self, e: &GroupingSets) -> Result<()> {
27739 self.write_keyword("GROUPING SETS");
27741 self.write(" (");
27742 for (i, expr) in e.expressions.iter().enumerate() {
27743 if i > 0 {
27744 self.write(", ");
27745 }
27746 self.generate_expression(expr)?;
27747 }
27748 self.write(")");
27749 Ok(())
27750 }
27751
27752 fn generate_hash_agg(&mut self, e: &HashAgg) -> Result<()> {
27753 self.write_keyword("HASH_AGG");
27755 self.write("(");
27756 self.generate_expression(&e.this)?;
27757 for expr in &e.expressions {
27758 self.write(", ");
27759 self.generate_expression(expr)?;
27760 }
27761 self.write(")");
27762 Ok(())
27763 }
27764
27765 fn generate_having(&mut self, e: &Having) -> Result<()> {
27766 self.write_keyword("HAVING");
27768 self.write_space();
27769 self.generate_expression(&e.this)?;
27770 Ok(())
27771 }
27772
27773 fn generate_having_max(&mut self, e: &HavingMax) -> Result<()> {
27774 self.generate_expression(&e.this)?;
27776 self.write_space();
27777 self.write_keyword("HAVING");
27778 self.write_space();
27779 if e.max.is_some() {
27780 self.write_keyword("MAX");
27781 } else {
27782 self.write_keyword("MIN");
27783 }
27784 self.write_space();
27785 self.generate_expression(&e.expression)?;
27786 Ok(())
27787 }
27788
27789 fn generate_heredoc(&mut self, e: &Heredoc) -> Result<()> {
27790 use crate::dialects::DialectType;
27791 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
27793 if let Expression::Literal(Literal::String(ref s)) = *e.this {
27795 return self.generate_string_literal(s);
27796 }
27797 }
27798 if matches!(
27800 self.config.dialect,
27801 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
27802 ) {
27803 self.write("$");
27804 if let Some(tag) = &e.tag {
27805 self.generate_expression(tag)?;
27806 }
27807 self.write("$");
27808 self.generate_expression(&e.this)?;
27809 self.write("$");
27810 if let Some(tag) = &e.tag {
27811 self.generate_expression(tag)?;
27812 }
27813 self.write("$");
27814 return Ok(());
27815 }
27816 self.write("$");
27818 if let Some(tag) = &e.tag {
27819 self.generate_expression(tag)?;
27820 }
27821 self.write("$");
27822 self.generate_expression(&e.this)?;
27823 self.write("$");
27824 if let Some(tag) = &e.tag {
27825 self.generate_expression(tag)?;
27826 }
27827 self.write("$");
27828 Ok(())
27829 }
27830
27831 fn generate_hex_encode(&mut self, e: &HexEncode) -> Result<()> {
27832 self.write_keyword("HEX_ENCODE");
27834 self.write("(");
27835 self.generate_expression(&e.this)?;
27836 self.write(")");
27837 Ok(())
27838 }
27839
27840 fn generate_historical_data(&mut self, e: &HistoricalData) -> Result<()> {
27841 match e.this.as_ref() {
27844 Expression::Identifier(id) => self.write(&id.name),
27845 other => self.generate_expression(other)?,
27846 }
27847 self.write(" (");
27848 self.write(&e.kind);
27849 self.write(" => ");
27850 self.generate_expression(&e.expression)?;
27851 self.write(")");
27852 Ok(())
27853 }
27854
27855 fn generate_hll(&mut self, e: &Hll) -> Result<()> {
27856 self.write_keyword("HLL");
27858 self.write("(");
27859 self.generate_expression(&e.this)?;
27860 for expr in &e.expressions {
27861 self.write(", ");
27862 self.generate_expression(expr)?;
27863 }
27864 self.write(")");
27865 Ok(())
27866 }
27867
27868 fn generate_in_out_column_constraint(&mut self, e: &InOutColumnConstraint) -> Result<()> {
27869 if e.input_.is_some() && e.output.is_some() {
27871 self.write_keyword("IN OUT");
27872 } else if e.input_.is_some() {
27873 self.write_keyword("IN");
27874 } else if e.output.is_some() {
27875 self.write_keyword("OUT");
27876 }
27877 Ok(())
27878 }
27879
27880 fn generate_include_property(&mut self, e: &IncludeProperty) -> Result<()> {
27881 self.write_keyword("INCLUDE");
27883 self.write_space();
27884 self.generate_expression(&e.this)?;
27885 if let Some(column_def) = &e.column_def {
27886 self.write_space();
27887 self.generate_expression(column_def)?;
27888 }
27889 if let Some(alias) = &e.alias {
27890 self.write_space();
27891 self.write_keyword("AS");
27892 self.write_space();
27893 self.write(alias);
27894 }
27895 Ok(())
27896 }
27897
27898 fn generate_index(&mut self, e: &Index) -> Result<()> {
27899 if e.unique {
27901 self.write_keyword("UNIQUE");
27902 self.write_space();
27903 }
27904 if e.primary.is_some() {
27905 self.write_keyword("PRIMARY");
27906 self.write_space();
27907 }
27908 if e.amp.is_some() {
27909 self.write_keyword("AMP");
27910 self.write_space();
27911 }
27912 if e.table.is_none() {
27913 self.write_keyword("INDEX");
27914 self.write_space();
27915 }
27916 if let Some(name) = &e.this {
27917 self.generate_expression(name)?;
27918 self.write_space();
27919 }
27920 if let Some(table) = &e.table {
27921 self.write_keyword("ON");
27922 self.write_space();
27923 self.generate_expression(table)?;
27924 }
27925 if !e.params.is_empty() {
27926 self.write("(");
27927 for (i, param) in e.params.iter().enumerate() {
27928 if i > 0 {
27929 self.write(", ");
27930 }
27931 self.generate_expression(param)?;
27932 }
27933 self.write(")");
27934 }
27935 Ok(())
27936 }
27937
27938 fn generate_index_column_constraint(&mut self, e: &IndexColumnConstraint) -> Result<()> {
27939 if let Some(kind) = &e.kind {
27941 self.write(kind);
27942 self.write_space();
27943 }
27944 self.write_keyword("INDEX");
27945 if let Some(this) = &e.this {
27946 self.write_space();
27947 self.generate_expression(this)?;
27948 }
27949 if let Some(index_type) = &e.index_type {
27950 self.write_space();
27951 self.write_keyword("USING");
27952 self.write_space();
27953 self.generate_expression(index_type)?;
27954 }
27955 if !e.expressions.is_empty() {
27956 self.write(" (");
27957 for (i, expr) in e.expressions.iter().enumerate() {
27958 if i > 0 {
27959 self.write(", ");
27960 }
27961 self.generate_expression(expr)?;
27962 }
27963 self.write(")");
27964 }
27965 for opt in &e.options {
27966 self.write_space();
27967 self.generate_expression(opt)?;
27968 }
27969 Ok(())
27970 }
27971
27972 fn generate_index_constraint_option(&mut self, e: &IndexConstraintOption) -> Result<()> {
27973 if let Some(key_block_size) = &e.key_block_size {
27975 self.write_keyword("KEY_BLOCK_SIZE");
27976 self.write(" = ");
27977 self.generate_expression(key_block_size)?;
27978 } else if let Some(using) = &e.using {
27979 self.write_keyword("USING");
27980 self.write_space();
27981 self.generate_expression(using)?;
27982 } else if let Some(parser) = &e.parser {
27983 self.write_keyword("WITH PARSER");
27984 self.write_space();
27985 self.generate_expression(parser)?;
27986 } else if let Some(comment) = &e.comment {
27987 self.write_keyword("COMMENT");
27988 self.write_space();
27989 self.generate_expression(comment)?;
27990 } else if let Some(visible) = &e.visible {
27991 self.generate_expression(visible)?;
27992 } else if let Some(engine_attr) = &e.engine_attr {
27993 self.write_keyword("ENGINE_ATTRIBUTE");
27994 self.write(" = ");
27995 self.generate_expression(engine_attr)?;
27996 } else if let Some(secondary_engine_attr) = &e.secondary_engine_attr {
27997 self.write_keyword("SECONDARY_ENGINE_ATTRIBUTE");
27998 self.write(" = ");
27999 self.generate_expression(secondary_engine_attr)?;
28000 }
28001 Ok(())
28002 }
28003
28004 fn generate_index_parameters(&mut self, e: &IndexParameters) -> Result<()> {
28005 if let Some(using) = &e.using {
28007 self.write_keyword("USING");
28008 self.write_space();
28009 self.generate_expression(using)?;
28010 }
28011 if !e.columns.is_empty() {
28012 self.write("(");
28013 for (i, col) in e.columns.iter().enumerate() {
28014 if i > 0 {
28015 self.write(", ");
28016 }
28017 self.generate_expression(col)?;
28018 }
28019 self.write(")");
28020 }
28021 if let Some(partition_by) = &e.partition_by {
28022 self.write_space();
28023 self.write_keyword("PARTITION BY");
28024 self.write_space();
28025 self.generate_expression(partition_by)?;
28026 }
28027 if let Some(where_) = &e.where_ {
28028 self.write_space();
28029 self.generate_expression(where_)?;
28030 }
28031 if let Some(include) = &e.include {
28032 self.write_space();
28033 self.write_keyword("INCLUDE");
28034 self.write(" (");
28035 self.generate_expression(include)?;
28036 self.write(")");
28037 }
28038 if let Some(with_storage) = &e.with_storage {
28039 self.write_space();
28040 self.write_keyword("WITH");
28041 self.write(" (");
28042 self.generate_expression(with_storage)?;
28043 self.write(")");
28044 }
28045 if let Some(tablespace) = &e.tablespace {
28046 self.write_space();
28047 self.write_keyword("USING INDEX TABLESPACE");
28048 self.write_space();
28049 self.generate_expression(tablespace)?;
28050 }
28051 Ok(())
28052 }
28053
28054 fn generate_index_table_hint(&mut self, e: &IndexTableHint) -> Result<()> {
28055 if let Expression::Identifier(id) = &*e.this {
28059 self.write_keyword(&id.name);
28060 } else {
28061 self.generate_expression(&e.this)?;
28062 }
28063 self.write_space();
28064 self.write_keyword("INDEX");
28065 if let Some(target) = &e.target {
28066 self.write_space();
28067 self.write_keyword("FOR");
28068 self.write_space();
28069 if let Expression::Identifier(id) = &**target {
28070 self.write_keyword(&id.name);
28071 } else {
28072 self.generate_expression(target)?;
28073 }
28074 }
28075 self.write(" (");
28077 for (i, expr) in e.expressions.iter().enumerate() {
28078 if i > 0 {
28079 self.write(", ");
28080 }
28081 self.generate_expression(expr)?;
28082 }
28083 self.write(")");
28084 Ok(())
28085 }
28086
28087 fn generate_inherits_property(&mut self, e: &InheritsProperty) -> Result<()> {
28088 self.write_keyword("INHERITS");
28090 self.write(" (");
28091 for (i, expr) in e.expressions.iter().enumerate() {
28092 if i > 0 {
28093 self.write(", ");
28094 }
28095 self.generate_expression(expr)?;
28096 }
28097 self.write(")");
28098 Ok(())
28099 }
28100
28101 fn generate_input_model_property(&mut self, e: &InputModelProperty) -> Result<()> {
28102 self.write_keyword("INPUT");
28104 self.write("(");
28105 self.generate_expression(&e.this)?;
28106 self.write(")");
28107 Ok(())
28108 }
28109
28110 fn generate_input_output_format(&mut self, e: &InputOutputFormat) -> Result<()> {
28111 if let Some(input_format) = &e.input_format {
28113 self.write_keyword("INPUTFORMAT");
28114 self.write_space();
28115 self.generate_expression(input_format)?;
28116 }
28117 if let Some(output_format) = &e.output_format {
28118 if e.input_format.is_some() {
28119 self.write(" ");
28120 }
28121 self.write_keyword("OUTPUTFORMAT");
28122 self.write_space();
28123 self.generate_expression(output_format)?;
28124 }
28125 Ok(())
28126 }
28127
28128 fn generate_install(&mut self, e: &Install) -> Result<()> {
28129 if e.force.is_some() {
28131 self.write_keyword("FORCE");
28132 self.write_space();
28133 }
28134 self.write_keyword("INSTALL");
28135 self.write_space();
28136 self.generate_expression(&e.this)?;
28137 if let Some(from) = &e.from_ {
28138 self.write_space();
28139 self.write_keyword("FROM");
28140 self.write_space();
28141 self.generate_expression(from)?;
28142 }
28143 Ok(())
28144 }
28145
28146 fn generate_interval_op(&mut self, e: &IntervalOp) -> Result<()> {
28147 self.write_keyword("INTERVAL");
28149 self.write_space();
28150 self.generate_expression(&e.expression)?;
28152 if let Some(unit) = &e.unit {
28153 self.write_space();
28154 self.write(unit);
28155 }
28156 Ok(())
28157 }
28158
28159 fn generate_interval_span(&mut self, e: &IntervalSpan) -> Result<()> {
28160 self.write(&format!("{:?}", e.this).to_uppercase());
28162 self.write_space();
28163 self.write_keyword("TO");
28164 self.write_space();
28165 self.write(&format!("{:?}", e.expression).to_uppercase());
28166 Ok(())
28167 }
28168
28169 fn generate_into_clause(&mut self, e: &IntoClause) -> Result<()> {
28170 self.write_keyword("INTO");
28172 if e.temporary {
28173 self.write_keyword(" TEMPORARY");
28174 }
28175 if e.unlogged.is_some() {
28176 self.write_keyword(" UNLOGGED");
28177 }
28178 if let Some(this) = &e.this {
28179 self.write_space();
28180 self.generate_expression(this)?;
28181 }
28182 if !e.expressions.is_empty() {
28183 self.write(" (");
28184 for (i, expr) in e.expressions.iter().enumerate() {
28185 if i > 0 {
28186 self.write(", ");
28187 }
28188 self.generate_expression(expr)?;
28189 }
28190 self.write(")");
28191 }
28192 Ok(())
28193 }
28194
28195 fn generate_introducer(&mut self, e: &Introducer) -> Result<()> {
28196 self.generate_expression(&e.this)?;
28198 self.write_space();
28199 self.generate_expression(&e.expression)?;
28200 Ok(())
28201 }
28202
28203 fn generate_isolated_loading_property(&mut self, e: &IsolatedLoadingProperty) -> Result<()> {
28204 self.write_keyword("WITH");
28206 if e.no.is_some() {
28207 self.write_keyword(" NO");
28208 }
28209 if e.concurrent.is_some() {
28210 self.write_keyword(" CONCURRENT");
28211 }
28212 self.write_keyword(" ISOLATED LOADING");
28213 if let Some(target) = &e.target {
28214 self.write_space();
28215 self.generate_expression(target)?;
28216 }
28217 Ok(())
28218 }
28219
28220 fn generate_json(&mut self, e: &JSON) -> Result<()> {
28221 self.write_keyword("JSON");
28223 if let Some(this) = &e.this {
28224 self.write_space();
28225 self.generate_expression(this)?;
28226 }
28227 if let Some(with_) = &e.with_ {
28228 if let Expression::Boolean(b) = with_.as_ref() {
28230 if b.value {
28231 self.write_keyword(" WITH");
28232 } else {
28233 self.write_keyword(" WITHOUT");
28234 }
28235 }
28236 }
28237 if e.unique {
28238 self.write_keyword(" UNIQUE KEYS");
28239 }
28240 Ok(())
28241 }
28242
28243 fn generate_json_array(&mut self, e: &JSONArray) -> Result<()> {
28244 self.write_keyword("JSON_ARRAY");
28246 self.write("(");
28247 for (i, expr) in e.expressions.iter().enumerate() {
28248 if i > 0 {
28249 self.write(", ");
28250 }
28251 self.generate_expression(expr)?;
28252 }
28253 if let Some(null_handling) = &e.null_handling {
28254 self.write_space();
28255 self.generate_expression(null_handling)?;
28256 }
28257 if let Some(return_type) = &e.return_type {
28258 self.write_space();
28259 self.write_keyword("RETURNING");
28260 self.write_space();
28261 self.generate_expression(return_type)?;
28262 }
28263 if e.strict.is_some() {
28264 self.write_space();
28265 self.write_keyword("STRICT");
28266 }
28267 self.write(")");
28268 Ok(())
28269 }
28270
28271 fn generate_json_array_agg_struct(&mut self, e: &JSONArrayAgg) -> Result<()> {
28272 self.write_keyword("JSON_ARRAYAGG");
28274 self.write("(");
28275 self.generate_expression(&e.this)?;
28276 if let Some(order) = &e.order {
28277 self.write_space();
28278 if let Expression::OrderBy(ob) = order.as_ref() {
28280 self.write_keyword("ORDER BY");
28281 self.write_space();
28282 for (i, ord) in ob.expressions.iter().enumerate() {
28283 if i > 0 {
28284 self.write(", ");
28285 }
28286 self.generate_ordered(ord)?;
28287 }
28288 } else {
28289 self.generate_expression(order)?;
28291 }
28292 }
28293 if let Some(null_handling) = &e.null_handling {
28294 self.write_space();
28295 self.generate_expression(null_handling)?;
28296 }
28297 if let Some(return_type) = &e.return_type {
28298 self.write_space();
28299 self.write_keyword("RETURNING");
28300 self.write_space();
28301 self.generate_expression(return_type)?;
28302 }
28303 if e.strict.is_some() {
28304 self.write_space();
28305 self.write_keyword("STRICT");
28306 }
28307 self.write(")");
28308 Ok(())
28309 }
28310
28311 fn generate_json_object_agg_struct(&mut self, e: &JSONObjectAgg) -> Result<()> {
28312 self.write_keyword("JSON_OBJECTAGG");
28314 self.write("(");
28315 for (i, expr) in e.expressions.iter().enumerate() {
28316 if i > 0 {
28317 self.write(", ");
28318 }
28319 self.generate_expression(expr)?;
28320 }
28321 if let Some(null_handling) = &e.null_handling {
28322 self.write_space();
28323 self.generate_expression(null_handling)?;
28324 }
28325 if let Some(unique_keys) = &e.unique_keys {
28326 self.write_space();
28327 if let Expression::Boolean(b) = unique_keys.as_ref() {
28328 if b.value {
28329 self.write_keyword("WITH UNIQUE KEYS");
28330 } else {
28331 self.write_keyword("WITHOUT UNIQUE KEYS");
28332 }
28333 }
28334 }
28335 if let Some(return_type) = &e.return_type {
28336 self.write_space();
28337 self.write_keyword("RETURNING");
28338 self.write_space();
28339 self.generate_expression(return_type)?;
28340 }
28341 self.write(")");
28342 Ok(())
28343 }
28344
28345 fn generate_json_array_append(&mut self, e: &JSONArrayAppend) -> Result<()> {
28346 self.write_keyword("JSON_ARRAY_APPEND");
28348 self.write("(");
28349 self.generate_expression(&e.this)?;
28350 for expr in &e.expressions {
28351 self.write(", ");
28352 self.generate_expression(expr)?;
28353 }
28354 self.write(")");
28355 Ok(())
28356 }
28357
28358 fn generate_json_array_contains(&mut self, e: &JSONArrayContains) -> Result<()> {
28359 self.write_keyword("JSON_ARRAY_CONTAINS");
28361 self.write("(");
28362 self.generate_expression(&e.this)?;
28363 self.write(", ");
28364 self.generate_expression(&e.expression)?;
28365 self.write(")");
28366 Ok(())
28367 }
28368
28369 fn generate_json_array_insert(&mut self, e: &JSONArrayInsert) -> Result<()> {
28370 self.write_keyword("JSON_ARRAY_INSERT");
28372 self.write("(");
28373 self.generate_expression(&e.this)?;
28374 for expr in &e.expressions {
28375 self.write(", ");
28376 self.generate_expression(expr)?;
28377 }
28378 self.write(")");
28379 Ok(())
28380 }
28381
28382 fn generate_jsonb_exists(&mut self, e: &JSONBExists) -> Result<()> {
28383 self.write_keyword("JSONB_EXISTS");
28385 self.write("(");
28386 self.generate_expression(&e.this)?;
28387 if let Some(path) = &e.path {
28388 self.write(", ");
28389 self.generate_expression(path)?;
28390 }
28391 self.write(")");
28392 Ok(())
28393 }
28394
28395 fn generate_jsonb_extract_scalar(&mut self, e: &JSONBExtractScalar) -> Result<()> {
28396 self.write_keyword("JSONB_EXTRACT_SCALAR");
28398 self.write("(");
28399 self.generate_expression(&e.this)?;
28400 self.write(", ");
28401 self.generate_expression(&e.expression)?;
28402 self.write(")");
28403 Ok(())
28404 }
28405
28406 fn generate_jsonb_object_agg(&mut self, e: &JSONBObjectAgg) -> Result<()> {
28407 self.write_keyword("JSONB_OBJECT_AGG");
28409 self.write("(");
28410 self.generate_expression(&e.this)?;
28411 self.write(", ");
28412 self.generate_expression(&e.expression)?;
28413 self.write(")");
28414 Ok(())
28415 }
28416
28417 fn generate_json_column_def(&mut self, e: &JSONColumnDef) -> Result<()> {
28418 if let Some(nested_schema) = &e.nested_schema {
28420 self.write_keyword("NESTED");
28421 if let Some(path) = &e.path {
28422 self.write_space();
28423 self.write_keyword("PATH");
28424 self.write_space();
28425 self.generate_expression(path)?;
28426 }
28427 self.write_space();
28428 self.generate_expression(nested_schema)?;
28429 } else {
28430 if let Some(this) = &e.this {
28431 self.generate_expression(this)?;
28432 }
28433 if let Some(kind) = &e.kind {
28434 self.write_space();
28435 self.write(kind);
28436 }
28437 if let Some(path) = &e.path {
28438 self.write_space();
28439 self.write_keyword("PATH");
28440 self.write_space();
28441 self.generate_expression(path)?;
28442 }
28443 if e.ordinality.is_some() {
28444 self.write_keyword(" FOR ORDINALITY");
28445 }
28446 }
28447 Ok(())
28448 }
28449
28450 fn generate_json_exists(&mut self, e: &JSONExists) -> Result<()> {
28451 self.write_keyword("JSON_EXISTS");
28453 self.write("(");
28454 self.generate_expression(&e.this)?;
28455 if let Some(path) = &e.path {
28456 self.write(", ");
28457 self.generate_expression(path)?;
28458 }
28459 if let Some(passing) = &e.passing {
28460 self.write_space();
28461 self.write_keyword("PASSING");
28462 self.write_space();
28463 self.generate_expression(passing)?;
28464 }
28465 if let Some(on_condition) = &e.on_condition {
28466 self.write_space();
28467 self.generate_expression(on_condition)?;
28468 }
28469 self.write(")");
28470 Ok(())
28471 }
28472
28473 fn generate_json_cast(&mut self, e: &JSONCast) -> Result<()> {
28474 self.generate_expression(&e.this)?;
28475 self.write(".:");
28476 self.generate_data_type(&e.to)?;
28477 Ok(())
28478 }
28479
28480 fn generate_json_extract_array(&mut self, e: &JSONExtractArray) -> Result<()> {
28481 self.write_keyword("JSON_EXTRACT_ARRAY");
28483 self.write("(");
28484 self.generate_expression(&e.this)?;
28485 if let Some(expr) = &e.expression {
28486 self.write(", ");
28487 self.generate_expression(expr)?;
28488 }
28489 self.write(")");
28490 Ok(())
28491 }
28492
28493 fn generate_json_extract_quote(&mut self, e: &JSONExtractQuote) -> Result<()> {
28494 if let Some(option) = &e.option {
28496 self.generate_expression(option)?;
28497 self.write_space();
28498 }
28499 self.write_keyword("QUOTES");
28500 if e.scalar.is_some() {
28501 self.write_keyword(" SCALAR_ONLY");
28502 }
28503 Ok(())
28504 }
28505
28506 fn generate_json_extract_scalar(&mut self, e: &JSONExtractScalar) -> Result<()> {
28507 self.write_keyword("JSON_EXTRACT_SCALAR");
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_extract_path(&mut self, e: &JSONExtract) -> Result<()> {
28518 if e.variant_extract.is_some() {
28522 use crate::dialects::DialectType;
28523 if matches!(self.config.dialect, Some(DialectType::Databricks)) {
28524 self.generate_expression(&e.this)?;
28526 self.write(":");
28527 match e.expression.as_ref() {
28530 Expression::Literal(Literal::String(s)) => {
28531 self.write(s);
28532 }
28533 _ => {
28534 self.generate_expression(&e.expression)?;
28536 }
28537 }
28538 } else {
28539 self.write_keyword("GET_PATH");
28541 self.write("(");
28542 self.generate_expression(&e.this)?;
28543 self.write(", ");
28544 self.generate_expression(&e.expression)?;
28545 self.write(")");
28546 }
28547 } else {
28548 self.write_keyword("JSON_EXTRACT");
28549 self.write("(");
28550 self.generate_expression(&e.this)?;
28551 self.write(", ");
28552 self.generate_expression(&e.expression)?;
28553 for expr in &e.expressions {
28554 self.write(", ");
28555 self.generate_expression(expr)?;
28556 }
28557 self.write(")");
28558 }
28559 Ok(())
28560 }
28561
28562 fn generate_json_format(&mut self, e: &JSONFormat) -> Result<()> {
28563 if let Some(this) = &e.this {
28566 self.generate_expression(this)?;
28567 self.write_space();
28568 }
28569 self.write_keyword("FORMAT JSON");
28570 Ok(())
28571 }
28572
28573 fn generate_json_key_value(&mut self, e: &JSONKeyValue) -> Result<()> {
28574 self.generate_expression(&e.this)?;
28576 self.write(": ");
28577 self.generate_expression(&e.expression)?;
28578 Ok(())
28579 }
28580
28581 fn generate_json_keys(&mut self, e: &JSONKeys) -> Result<()> {
28582 self.write_keyword("JSON_KEYS");
28584 self.write("(");
28585 self.generate_expression(&e.this)?;
28586 if let Some(expr) = &e.expression {
28587 self.write(", ");
28588 self.generate_expression(expr)?;
28589 }
28590 for expr in &e.expressions {
28591 self.write(", ");
28592 self.generate_expression(expr)?;
28593 }
28594 self.write(")");
28595 Ok(())
28596 }
28597
28598 fn generate_json_keys_at_depth(&mut self, e: &JSONKeysAtDepth) -> Result<()> {
28599 self.write_keyword("JSON_KEYS");
28601 self.write("(");
28602 self.generate_expression(&e.this)?;
28603 if let Some(expr) = &e.expression {
28604 self.write(", ");
28605 self.generate_expression(expr)?;
28606 }
28607 self.write(")");
28608 Ok(())
28609 }
28610
28611 fn generate_json_path_expr(&mut self, e: &JSONPath) -> Result<()> {
28612 let mut path_str = String::new();
28615 for expr in &e.expressions {
28616 match expr {
28617 Expression::JSONPathRoot(_) => {
28618 path_str.push('$');
28619 }
28620 Expression::JSONPathKey(k) => {
28621 if let Expression::Literal(crate::expressions::Literal::String(s)) =
28623 k.this.as_ref()
28624 {
28625 path_str.push('.');
28626 let needs_quoting = s.chars().any(|c| !c.is_alphanumeric() && c != '_');
28628 if needs_quoting {
28629 path_str.push('"');
28630 path_str.push_str(s);
28631 path_str.push('"');
28632 } else {
28633 path_str.push_str(s);
28634 }
28635 }
28636 }
28637 Expression::JSONPathSubscript(s) => {
28638 if let Expression::Literal(crate::expressions::Literal::Number(n)) =
28640 s.this.as_ref()
28641 {
28642 path_str.push('[');
28643 path_str.push_str(n);
28644 path_str.push(']');
28645 }
28646 }
28647 _ => {
28648 let mut temp_gen = Self::with_config(self.config.clone());
28650 temp_gen.generate_expression(expr)?;
28651 path_str.push_str(&temp_gen.output);
28652 }
28653 }
28654 }
28655 self.write("'");
28657 self.write(&path_str);
28658 self.write("'");
28659 Ok(())
28660 }
28661
28662 fn generate_json_path_filter(&mut self, e: &JSONPathFilter) -> Result<()> {
28663 self.write("?(");
28665 self.generate_expression(&e.this)?;
28666 self.write(")");
28667 Ok(())
28668 }
28669
28670 fn generate_json_path_key(&mut self, e: &JSONPathKey) -> Result<()> {
28671 self.write(".");
28673 self.generate_expression(&e.this)?;
28674 Ok(())
28675 }
28676
28677 fn generate_json_path_recursive(&mut self, e: &JSONPathRecursive) -> Result<()> {
28678 self.write("..");
28680 if let Some(this) = &e.this {
28681 self.generate_expression(this)?;
28682 }
28683 Ok(())
28684 }
28685
28686 fn generate_json_path_root(&mut self) -> Result<()> {
28687 self.write("$");
28689 Ok(())
28690 }
28691
28692 fn generate_json_path_script(&mut self, e: &JSONPathScript) -> Result<()> {
28693 self.write("(");
28695 self.generate_expression(&e.this)?;
28696 self.write(")");
28697 Ok(())
28698 }
28699
28700 fn generate_json_path_selector(&mut self, e: &JSONPathSelector) -> Result<()> {
28701 self.generate_expression(&e.this)?;
28703 Ok(())
28704 }
28705
28706 fn generate_json_path_slice(&mut self, e: &JSONPathSlice) -> Result<()> {
28707 self.write("[");
28709 if let Some(start) = &e.start {
28710 self.generate_expression(start)?;
28711 }
28712 self.write(":");
28713 if let Some(end) = &e.end {
28714 self.generate_expression(end)?;
28715 }
28716 if let Some(step) = &e.step {
28717 self.write(":");
28718 self.generate_expression(step)?;
28719 }
28720 self.write("]");
28721 Ok(())
28722 }
28723
28724 fn generate_json_path_subscript(&mut self, e: &JSONPathSubscript) -> Result<()> {
28725 self.write("[");
28727 self.generate_expression(&e.this)?;
28728 self.write("]");
28729 Ok(())
28730 }
28731
28732 fn generate_json_path_union(&mut self, e: &JSONPathUnion) -> Result<()> {
28733 self.write("[");
28735 for (i, expr) in e.expressions.iter().enumerate() {
28736 if i > 0 {
28737 self.write(", ");
28738 }
28739 self.generate_expression(expr)?;
28740 }
28741 self.write("]");
28742 Ok(())
28743 }
28744
28745 fn generate_json_remove(&mut self, e: &JSONRemove) -> Result<()> {
28746 self.write_keyword("JSON_REMOVE");
28748 self.write("(");
28749 self.generate_expression(&e.this)?;
28750 for expr in &e.expressions {
28751 self.write(", ");
28752 self.generate_expression(expr)?;
28753 }
28754 self.write(")");
28755 Ok(())
28756 }
28757
28758 fn generate_json_schema(&mut self, e: &JSONSchema) -> Result<()> {
28759 self.write_keyword("COLUMNS");
28762 self.write("(");
28763
28764 if self.config.pretty && !e.expressions.is_empty() {
28765 let mut expr_strings: Vec<String> = Vec::with_capacity(e.expressions.len());
28767 for expr in &e.expressions {
28768 let mut temp_gen = Generator::with_config(self.config.clone());
28769 temp_gen.generate_expression(expr)?;
28770 expr_strings.push(temp_gen.output);
28771 }
28772
28773 if self.too_wide(&expr_strings) {
28775 self.write_newline();
28777 self.indent_level += 1;
28778 for (i, expr_str) in expr_strings.iter().enumerate() {
28779 if i > 0 {
28780 self.write(",");
28781 self.write_newline();
28782 }
28783 self.write_indent();
28784 self.write(expr_str);
28785 }
28786 self.write_newline();
28787 self.indent_level -= 1;
28788 self.write_indent();
28789 } else {
28790 for (i, expr_str) in expr_strings.iter().enumerate() {
28792 if i > 0 {
28793 self.write(", ");
28794 }
28795 self.write(expr_str);
28796 }
28797 }
28798 } else {
28799 for (i, expr) in e.expressions.iter().enumerate() {
28801 if i > 0 {
28802 self.write(", ");
28803 }
28804 self.generate_expression(expr)?;
28805 }
28806 }
28807 self.write(")");
28808 Ok(())
28809 }
28810
28811 fn generate_json_set(&mut self, e: &JSONSet) -> Result<()> {
28812 self.write_keyword("JSON_SET");
28814 self.write("(");
28815 self.generate_expression(&e.this)?;
28816 for expr in &e.expressions {
28817 self.write(", ");
28818 self.generate_expression(expr)?;
28819 }
28820 self.write(")");
28821 Ok(())
28822 }
28823
28824 fn generate_json_strip_nulls(&mut self, e: &JSONStripNulls) -> Result<()> {
28825 self.write_keyword("JSON_STRIP_NULLS");
28827 self.write("(");
28828 self.generate_expression(&e.this)?;
28829 if let Some(expr) = &e.expression {
28830 self.write(", ");
28831 self.generate_expression(expr)?;
28832 }
28833 self.write(")");
28834 Ok(())
28835 }
28836
28837 fn generate_json_table(&mut self, e: &JSONTable) -> Result<()> {
28838 self.write_keyword("JSON_TABLE");
28840 self.write("(");
28841 self.generate_expression(&e.this)?;
28842 if let Some(path) = &e.path {
28843 self.write(", ");
28844 self.generate_expression(path)?;
28845 }
28846 if let Some(error_handling) = &e.error_handling {
28847 self.write_space();
28848 self.generate_expression(error_handling)?;
28849 }
28850 if let Some(empty_handling) = &e.empty_handling {
28851 self.write_space();
28852 self.generate_expression(empty_handling)?;
28853 }
28854 if let Some(schema) = &e.schema {
28855 self.write_space();
28856 self.generate_expression(schema)?;
28857 }
28858 self.write(")");
28859 Ok(())
28860 }
28861
28862 fn generate_json_type(&mut self, e: &JSONType) -> Result<()> {
28863 self.write_keyword("JSON_TYPE");
28865 self.write("(");
28866 self.generate_expression(&e.this)?;
28867 self.write(")");
28868 Ok(())
28869 }
28870
28871 fn generate_json_value(&mut self, e: &JSONValue) -> Result<()> {
28872 self.write_keyword("JSON_VALUE");
28874 self.write("(");
28875 self.generate_expression(&e.this)?;
28876 if let Some(path) = &e.path {
28877 self.write(", ");
28878 self.generate_expression(path)?;
28879 }
28880 if let Some(returning) = &e.returning {
28881 self.write_space();
28882 self.write_keyword("RETURNING");
28883 self.write_space();
28884 self.generate_expression(returning)?;
28885 }
28886 if let Some(on_condition) = &e.on_condition {
28887 self.write_space();
28888 self.generate_expression(on_condition)?;
28889 }
28890 self.write(")");
28891 Ok(())
28892 }
28893
28894 fn generate_json_value_array(&mut self, e: &JSONValueArray) -> Result<()> {
28895 self.write_keyword("JSON_VALUE_ARRAY");
28897 self.write("(");
28898 self.generate_expression(&e.this)?;
28899 self.write(")");
28900 Ok(())
28901 }
28902
28903 fn generate_jarowinkler_similarity(&mut self, e: &JarowinklerSimilarity) -> Result<()> {
28904 self.write_keyword("JAROWINKLER_SIMILARITY");
28906 self.write("(");
28907 self.generate_expression(&e.this)?;
28908 self.write(", ");
28909 self.generate_expression(&e.expression)?;
28910 self.write(")");
28911 Ok(())
28912 }
28913
28914 fn generate_join_hint(&mut self, e: &JoinHint) -> Result<()> {
28915 self.generate_expression(&e.this)?;
28917 self.write("(");
28918 for (i, expr) in e.expressions.iter().enumerate() {
28919 if i > 0 {
28920 self.write(", ");
28921 }
28922 self.generate_expression(expr)?;
28923 }
28924 self.write(")");
28925 Ok(())
28926 }
28927
28928 fn generate_journal_property(&mut self, e: &JournalProperty) -> Result<()> {
28929 if e.no.is_some() {
28931 self.write_keyword("NO ");
28932 }
28933 if let Some(local) = &e.local {
28934 self.generate_expression(local)?;
28935 self.write_space();
28936 }
28937 if e.dual.is_some() {
28938 self.write_keyword("DUAL ");
28939 }
28940 if e.before.is_some() {
28941 self.write_keyword("BEFORE ");
28942 }
28943 if e.after.is_some() {
28944 self.write_keyword("AFTER ");
28945 }
28946 self.write_keyword("JOURNAL");
28947 Ok(())
28948 }
28949
28950 fn generate_language_property(&mut self, e: &LanguageProperty) -> Result<()> {
28951 self.write_keyword("LANGUAGE");
28953 self.write_space();
28954 self.generate_expression(&e.this)?;
28955 Ok(())
28956 }
28957
28958 fn generate_lateral(&mut self, e: &Lateral) -> Result<()> {
28959 if e.view.is_some() {
28961 self.write_keyword("LATERAL VIEW");
28963 if e.outer.is_some() {
28964 self.write_space();
28965 self.write_keyword("OUTER");
28966 }
28967 self.write_space();
28968 self.generate_expression(&e.this)?;
28969 if let Some(alias) = &e.alias {
28970 self.write_space();
28971 self.write(alias);
28972 }
28973 } else {
28974 self.write_keyword("LATERAL");
28976 self.write_space();
28977 self.generate_expression(&e.this)?;
28978 if e.ordinality.is_some() {
28979 self.write_space();
28980 self.write_keyword("WITH ORDINALITY");
28981 }
28982 if let Some(alias) = &e.alias {
28983 self.write_space();
28984 self.write_keyword("AS");
28985 self.write_space();
28986 self.write(alias);
28987 if !e.column_aliases.is_empty() {
28988 self.write("(");
28989 for (i, col) in e.column_aliases.iter().enumerate() {
28990 if i > 0 {
28991 self.write(", ");
28992 }
28993 self.write(col);
28994 }
28995 self.write(")");
28996 }
28997 }
28998 }
28999 Ok(())
29000 }
29001
29002 fn generate_like_property(&mut self, e: &LikeProperty) -> Result<()> {
29003 self.write_keyword("LIKE");
29005 self.write_space();
29006 self.generate_expression(&e.this)?;
29007 for expr in &e.expressions {
29008 self.write_space();
29009 self.generate_expression(expr)?;
29010 }
29011 Ok(())
29012 }
29013
29014 fn generate_limit(&mut self, e: &Limit) -> Result<()> {
29015 self.write_keyword("LIMIT");
29016 self.write_space();
29017 self.write_limit_expr(&e.this)?;
29018 if e.percent {
29019 self.write_space();
29020 self.write_keyword("PERCENT");
29021 }
29022 for comment in &e.comments {
29024 self.write(" ");
29025 self.write_formatted_comment(comment);
29026 }
29027 Ok(())
29028 }
29029
29030 fn generate_limit_options(&mut self, e: &LimitOptions) -> Result<()> {
29031 if e.percent.is_some() {
29033 self.write_keyword(" PERCENT");
29034 }
29035 if e.rows.is_some() {
29036 self.write_keyword(" ROWS");
29037 }
29038 if e.with_ties.is_some() {
29039 self.write_keyword(" WITH TIES");
29040 } else if e.rows.is_some() {
29041 self.write_keyword(" ONLY");
29042 }
29043 Ok(())
29044 }
29045
29046 fn generate_list(&mut self, e: &List) -> Result<()> {
29047 use crate::dialects::DialectType;
29048 let is_materialize = matches!(self.config.dialect, Some(DialectType::Materialize));
29049
29050 if e.expressions.len() == 1 {
29052 if let Expression::Select(_) = &e.expressions[0] {
29053 self.write_keyword("LIST");
29054 self.write("(");
29055 self.generate_expression(&e.expressions[0])?;
29056 self.write(")");
29057 return Ok(());
29058 }
29059 }
29060
29061 if is_materialize {
29063 self.write_keyword("LIST");
29064 self.write("[");
29065 for (i, expr) in e.expressions.iter().enumerate() {
29066 if i > 0 {
29067 self.write(", ");
29068 }
29069 self.generate_expression(expr)?;
29070 }
29071 self.write("]");
29072 } else {
29073 self.write_keyword("LIST");
29075 self.write("(");
29076 for (i, expr) in e.expressions.iter().enumerate() {
29077 if i > 0 {
29078 self.write(", ");
29079 }
29080 self.generate_expression(expr)?;
29081 }
29082 self.write(")");
29083 }
29084 Ok(())
29085 }
29086
29087 fn generate_tomap(&mut self, e: &ToMap) -> Result<()> {
29088 if let Expression::Select(_) = &*e.this {
29090 self.write_keyword("MAP");
29091 self.write("(");
29092 self.generate_expression(&e.this)?;
29093 self.write(")");
29094 return Ok(());
29095 }
29096
29097 let is_duckdb = matches!(self.config.dialect, Some(DialectType::DuckDB));
29098
29099 self.write_keyword("MAP");
29101 if is_duckdb {
29102 self.write(" {");
29103 } else {
29104 self.write("[");
29105 }
29106 if let Expression::Struct(s) = &*e.this {
29107 for (i, (_, expr)) in s.fields.iter().enumerate() {
29108 if i > 0 {
29109 self.write(", ");
29110 }
29111 if let Expression::PropertyEQ(op) = expr {
29112 self.generate_expression(&op.left)?;
29113 if is_duckdb {
29114 self.write(": ");
29115 } else {
29116 self.write(" => ");
29117 }
29118 self.generate_expression(&op.right)?;
29119 } else {
29120 self.generate_expression(expr)?;
29121 }
29122 }
29123 }
29124 if is_duckdb {
29125 self.write("}");
29126 } else {
29127 self.write("]");
29128 }
29129 Ok(())
29130 }
29131
29132 fn generate_localtime(&mut self, e: &Localtime) -> Result<()> {
29133 self.write_keyword("LOCALTIME");
29135 if let Some(precision) = &e.this {
29136 self.write("(");
29137 self.generate_expression(precision)?;
29138 self.write(")");
29139 }
29140 Ok(())
29141 }
29142
29143 fn generate_localtimestamp(&mut self, e: &Localtimestamp) -> Result<()> {
29144 self.write_keyword("LOCALTIMESTAMP");
29146 if let Some(precision) = &e.this {
29147 self.write("(");
29148 self.generate_expression(precision)?;
29149 self.write(")");
29150 }
29151 Ok(())
29152 }
29153
29154 fn generate_location_property(&mut self, e: &LocationProperty) -> Result<()> {
29155 self.write_keyword("LOCATION");
29157 self.write_space();
29158 self.generate_expression(&e.this)?;
29159 Ok(())
29160 }
29161
29162 fn generate_lock(&mut self, e: &Lock) -> Result<()> {
29163 if e.update.is_some() {
29165 if e.key.is_some() {
29166 self.write_keyword("FOR NO KEY UPDATE");
29167 } else {
29168 self.write_keyword("FOR UPDATE");
29169 }
29170 } else {
29171 if e.key.is_some() {
29172 self.write_keyword("FOR KEY SHARE");
29173 } else {
29174 self.write_keyword("FOR SHARE");
29175 }
29176 }
29177 if !e.expressions.is_empty() {
29178 self.write_keyword(" OF ");
29179 for (i, expr) in e.expressions.iter().enumerate() {
29180 if i > 0 {
29181 self.write(", ");
29182 }
29183 self.generate_expression(expr)?;
29184 }
29185 }
29186 if let Some(wait) = &e.wait {
29191 match wait.as_ref() {
29192 Expression::Boolean(b) => {
29193 if b.value {
29194 self.write_keyword(" NOWAIT");
29195 } else {
29196 self.write_keyword(" SKIP LOCKED");
29197 }
29198 }
29199 _ => {
29200 self.write_keyword(" WAIT ");
29202 self.generate_expression(wait)?;
29203 }
29204 }
29205 }
29206 Ok(())
29207 }
29208
29209 fn generate_lock_property(&mut self, e: &LockProperty) -> Result<()> {
29210 self.write_keyword("LOCK");
29212 self.write_space();
29213 self.generate_expression(&e.this)?;
29214 Ok(())
29215 }
29216
29217 fn generate_locking_property(&mut self, e: &LockingProperty) -> Result<()> {
29218 self.write_keyword("LOCKING");
29220 self.write_space();
29221 self.write(&e.kind);
29222 if let Some(this) = &e.this {
29223 self.write_space();
29224 self.generate_expression(this)?;
29225 }
29226 if let Some(for_or_in) = &e.for_or_in {
29227 self.write_space();
29228 self.generate_expression(for_or_in)?;
29229 }
29230 if let Some(lock_type) = &e.lock_type {
29231 self.write_space();
29232 self.generate_expression(lock_type)?;
29233 }
29234 if e.override_.is_some() {
29235 self.write_keyword(" OVERRIDE");
29236 }
29237 Ok(())
29238 }
29239
29240 fn generate_locking_statement(&mut self, e: &LockingStatement) -> Result<()> {
29241 self.generate_expression(&e.this)?;
29243 self.write_space();
29244 self.generate_expression(&e.expression)?;
29245 Ok(())
29246 }
29247
29248 fn generate_log_property(&mut self, e: &LogProperty) -> Result<()> {
29249 if e.no.is_some() {
29251 self.write_keyword("NO ");
29252 }
29253 self.write_keyword("LOG");
29254 Ok(())
29255 }
29256
29257 fn generate_md5_digest(&mut self, e: &MD5Digest) -> Result<()> {
29258 self.write_keyword("MD5");
29260 self.write("(");
29261 self.generate_expression(&e.this)?;
29262 for expr in &e.expressions {
29263 self.write(", ");
29264 self.generate_expression(expr)?;
29265 }
29266 self.write(")");
29267 Ok(())
29268 }
29269
29270 fn generate_ml_forecast(&mut self, e: &MLForecast) -> Result<()> {
29271 self.write_keyword("ML.FORECAST");
29273 self.write("(");
29274 self.generate_expression(&e.this)?;
29275 if let Some(expression) = &e.expression {
29276 self.write(", ");
29277 self.generate_expression(expression)?;
29278 }
29279 if let Some(params) = &e.params_struct {
29280 self.write(", ");
29281 self.generate_expression(params)?;
29282 }
29283 self.write(")");
29284 Ok(())
29285 }
29286
29287 fn generate_ml_translate(&mut self, e: &MLTranslate) -> Result<()> {
29288 self.write_keyword("ML.TRANSLATE");
29290 self.write("(");
29291 self.generate_expression(&e.this)?;
29292 self.write(", ");
29293 self.generate_expression(&e.expression)?;
29294 if let Some(params) = &e.params_struct {
29295 self.write(", ");
29296 self.generate_expression(params)?;
29297 }
29298 self.write(")");
29299 Ok(())
29300 }
29301
29302 fn generate_make_interval(&mut self, e: &MakeInterval) -> Result<()> {
29303 self.write_keyword("MAKE_INTERVAL");
29305 self.write("(");
29306 let mut first = true;
29307 if let Some(year) = &e.year {
29308 self.write("years => ");
29309 self.generate_expression(year)?;
29310 first = false;
29311 }
29312 if let Some(month) = &e.month {
29313 if !first {
29314 self.write(", ");
29315 }
29316 self.write("months => ");
29317 self.generate_expression(month)?;
29318 first = false;
29319 }
29320 if let Some(week) = &e.week {
29321 if !first {
29322 self.write(", ");
29323 }
29324 self.write("weeks => ");
29325 self.generate_expression(week)?;
29326 first = false;
29327 }
29328 if let Some(day) = &e.day {
29329 if !first {
29330 self.write(", ");
29331 }
29332 self.write("days => ");
29333 self.generate_expression(day)?;
29334 first = false;
29335 }
29336 if let Some(hour) = &e.hour {
29337 if !first {
29338 self.write(", ");
29339 }
29340 self.write("hours => ");
29341 self.generate_expression(hour)?;
29342 first = false;
29343 }
29344 if let Some(minute) = &e.minute {
29345 if !first {
29346 self.write(", ");
29347 }
29348 self.write("mins => ");
29349 self.generate_expression(minute)?;
29350 first = false;
29351 }
29352 if let Some(second) = &e.second {
29353 if !first {
29354 self.write(", ");
29355 }
29356 self.write("secs => ");
29357 self.generate_expression(second)?;
29358 }
29359 self.write(")");
29360 Ok(())
29361 }
29362
29363 fn generate_manhattan_distance(&mut self, e: &ManhattanDistance) -> Result<()> {
29364 self.write_keyword("MANHATTAN_DISTANCE");
29366 self.write("(");
29367 self.generate_expression(&e.this)?;
29368 self.write(", ");
29369 self.generate_expression(&e.expression)?;
29370 self.write(")");
29371 Ok(())
29372 }
29373
29374 fn generate_map(&mut self, e: &Map) -> Result<()> {
29375 self.write_keyword("MAP");
29377 self.write("(");
29378 for (i, (key, value)) in e.keys.iter().zip(e.values.iter()).enumerate() {
29379 if i > 0 {
29380 self.write(", ");
29381 }
29382 self.generate_expression(key)?;
29383 self.write(", ");
29384 self.generate_expression(value)?;
29385 }
29386 self.write(")");
29387 Ok(())
29388 }
29389
29390 fn generate_map_cat(&mut self, e: &MapCat) -> Result<()> {
29391 self.write_keyword("MAP_CAT");
29393 self.write("(");
29394 self.generate_expression(&e.this)?;
29395 self.write(", ");
29396 self.generate_expression(&e.expression)?;
29397 self.write(")");
29398 Ok(())
29399 }
29400
29401 fn generate_map_delete(&mut self, e: &MapDelete) -> Result<()> {
29402 self.write_keyword("MAP_DELETE");
29404 self.write("(");
29405 self.generate_expression(&e.this)?;
29406 for expr in &e.expressions {
29407 self.write(", ");
29408 self.generate_expression(expr)?;
29409 }
29410 self.write(")");
29411 Ok(())
29412 }
29413
29414 fn generate_map_insert(&mut self, e: &MapInsert) -> Result<()> {
29415 self.write_keyword("MAP_INSERT");
29417 self.write("(");
29418 self.generate_expression(&e.this)?;
29419 if let Some(key) = &e.key {
29420 self.write(", ");
29421 self.generate_expression(key)?;
29422 }
29423 if let Some(value) = &e.value {
29424 self.write(", ");
29425 self.generate_expression(value)?;
29426 }
29427 if let Some(update_flag) = &e.update_flag {
29428 self.write(", ");
29429 self.generate_expression(update_flag)?;
29430 }
29431 self.write(")");
29432 Ok(())
29433 }
29434
29435 fn generate_map_pick(&mut self, e: &MapPick) -> Result<()> {
29436 self.write_keyword("MAP_PICK");
29438 self.write("(");
29439 self.generate_expression(&e.this)?;
29440 for expr in &e.expressions {
29441 self.write(", ");
29442 self.generate_expression(expr)?;
29443 }
29444 self.write(")");
29445 Ok(())
29446 }
29447
29448 fn generate_masking_policy_column_constraint(
29449 &mut self,
29450 e: &MaskingPolicyColumnConstraint,
29451 ) -> Result<()> {
29452 self.write_keyword("MASKING POLICY");
29454 self.write_space();
29455 self.generate_expression(&e.this)?;
29456 if !e.expressions.is_empty() {
29457 self.write_keyword(" USING");
29458 self.write(" (");
29459 for (i, expr) in e.expressions.iter().enumerate() {
29460 if i > 0 {
29461 self.write(", ");
29462 }
29463 self.generate_expression(expr)?;
29464 }
29465 self.write(")");
29466 }
29467 Ok(())
29468 }
29469
29470 fn generate_match_against(&mut self, e: &MatchAgainst) -> Result<()> {
29471 if matches!(
29472 self.config.dialect,
29473 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
29474 ) {
29475 if e.expressions.len() > 1 {
29476 self.write("(");
29477 }
29478 for (i, expr) in e.expressions.iter().enumerate() {
29479 if i > 0 {
29480 self.write_keyword(" OR ");
29481 }
29482 self.generate_expression(expr)?;
29483 self.write_space();
29484 self.write("@@");
29485 self.write_space();
29486 self.generate_expression(&e.this)?;
29487 }
29488 if e.expressions.len() > 1 {
29489 self.write(")");
29490 }
29491 return Ok(());
29492 }
29493
29494 self.write_keyword("MATCH");
29496 self.write("(");
29497 for (i, expr) in e.expressions.iter().enumerate() {
29498 if i > 0 {
29499 self.write(", ");
29500 }
29501 self.generate_expression(expr)?;
29502 }
29503 self.write(")");
29504 self.write_keyword(" AGAINST");
29505 self.write("(");
29506 self.generate_expression(&e.this)?;
29507 if let Some(modifier) = &e.modifier {
29508 self.write_space();
29509 self.generate_expression(modifier)?;
29510 }
29511 self.write(")");
29512 Ok(())
29513 }
29514
29515 fn generate_match_recognize_measure(&mut self, e: &MatchRecognizeMeasure) -> Result<()> {
29516 if let Some(window_frame) = &e.window_frame {
29518 self.write(&format!("{:?}", window_frame).to_uppercase());
29519 self.write_space();
29520 }
29521 self.generate_expression(&e.this)?;
29522 Ok(())
29523 }
29524
29525 fn generate_materialized_property(&mut self, e: &MaterializedProperty) -> Result<()> {
29526 self.write_keyword("MATERIALIZED");
29528 if let Some(this) = &e.this {
29529 self.write_space();
29530 self.generate_expression(this)?;
29531 }
29532 Ok(())
29533 }
29534
29535 fn generate_merge(&mut self, e: &Merge) -> Result<()> {
29536 if let Some(with_) = &e.with_ {
29539 self.generate_expression(with_)?;
29540 self.write_space();
29541 }
29542 self.write_keyword("MERGE INTO");
29543 self.write_space();
29544 self.generate_expression(&e.this)?;
29545
29546 if self.config.pretty {
29548 self.write_newline();
29549 self.write_indent();
29550 } else {
29551 self.write_space();
29552 }
29553 self.write_keyword("USING");
29554 self.write_space();
29555 self.generate_expression(&e.using)?;
29556
29557 if let Some(on) = &e.on {
29559 if self.config.pretty {
29560 self.write_newline();
29561 self.write_indent();
29562 } else {
29563 self.write_space();
29564 }
29565 self.write_keyword("ON");
29566 self.write_space();
29567 self.generate_expression(on)?;
29568 }
29569 if let Some(using_cond) = &e.using_cond {
29571 self.write_space();
29572 self.write_keyword("USING");
29573 self.write_space();
29574 self.write("(");
29575 if let Expression::Tuple(tuple) = using_cond.as_ref() {
29577 for (i, col) in tuple.expressions.iter().enumerate() {
29578 if i > 0 {
29579 self.write(", ");
29580 }
29581 self.generate_expression(col)?;
29582 }
29583 } else {
29584 self.generate_expression(using_cond)?;
29585 }
29586 self.write(")");
29587 }
29588 let saved_merge_strip = std::mem::take(&mut self.merge_strip_qualifiers);
29590 if matches!(
29591 self.config.dialect,
29592 Some(crate::DialectType::PostgreSQL)
29593 | Some(crate::DialectType::Redshift)
29594 | Some(crate::DialectType::Trino)
29595 | Some(crate::DialectType::Presto)
29596 | Some(crate::DialectType::Athena)
29597 ) {
29598 let mut names = Vec::new();
29599 match e.this.as_ref() {
29600 Expression::Alias(a) => {
29601 if let Expression::Table(t) = &a.this {
29603 names.push(t.name.name.clone());
29604 } else if let Expression::Identifier(id) = &a.this {
29605 names.push(id.name.clone());
29606 }
29607 names.push(a.alias.name.clone());
29608 }
29609 Expression::Table(t) => {
29610 names.push(t.name.name.clone());
29611 }
29612 Expression::Identifier(id) => {
29613 names.push(id.name.clone());
29614 }
29615 _ => {}
29616 }
29617 self.merge_strip_qualifiers = names;
29618 }
29619
29620 if let Some(whens) = &e.whens {
29622 if self.config.pretty {
29623 self.write_newline();
29624 self.write_indent();
29625 } else {
29626 self.write_space();
29627 }
29628 self.generate_expression(whens)?;
29629 }
29630
29631 self.merge_strip_qualifiers = saved_merge_strip;
29633
29634 if let Some(returning) = &e.returning {
29636 if self.config.pretty {
29637 self.write_newline();
29638 self.write_indent();
29639 } else {
29640 self.write_space();
29641 }
29642 self.generate_expression(returning)?;
29643 }
29644 Ok(())
29645 }
29646
29647 fn generate_merge_block_ratio_property(&mut self, e: &MergeBlockRatioProperty) -> Result<()> {
29648 if e.no.is_some() {
29650 self.write_keyword("NO MERGEBLOCKRATIO");
29651 } else if e.default.is_some() {
29652 self.write_keyword("DEFAULT MERGEBLOCKRATIO");
29653 } else {
29654 self.write_keyword("MERGEBLOCKRATIO");
29655 self.write("=");
29656 if let Some(this) = &e.this {
29657 self.generate_expression(this)?;
29658 }
29659 if e.percent.is_some() {
29660 self.write_keyword(" PERCENT");
29661 }
29662 }
29663 Ok(())
29664 }
29665
29666 fn generate_merge_tree_ttl(&mut self, e: &MergeTreeTTL) -> Result<()> {
29667 self.write_keyword("TTL");
29669 let pretty_clickhouse = self.config.pretty
29670 && matches!(
29671 self.config.dialect,
29672 Some(crate::dialects::DialectType::ClickHouse)
29673 );
29674
29675 if pretty_clickhouse {
29676 self.write_newline();
29677 self.indent_level += 1;
29678 for (i, expr) in e.expressions.iter().enumerate() {
29679 if i > 0 {
29680 self.write(",");
29681 self.write_newline();
29682 }
29683 self.write_indent();
29684 self.generate_expression(expr)?;
29685 }
29686 self.indent_level -= 1;
29687 } else {
29688 self.write_space();
29689 for (i, expr) in e.expressions.iter().enumerate() {
29690 if i > 0 {
29691 self.write(", ");
29692 }
29693 self.generate_expression(expr)?;
29694 }
29695 }
29696
29697 if let Some(where_) = &e.where_ {
29698 if pretty_clickhouse {
29699 self.write_newline();
29700 if let Expression::Where(w) = where_.as_ref() {
29701 self.write_indent();
29702 self.write_keyword("WHERE");
29703 self.write_newline();
29704 self.indent_level += 1;
29705 self.write_indent();
29706 self.generate_expression(&w.this)?;
29707 self.indent_level -= 1;
29708 } else {
29709 self.write_indent();
29710 self.generate_expression(where_)?;
29711 }
29712 } else {
29713 self.write_space();
29714 self.generate_expression(where_)?;
29715 }
29716 }
29717 if let Some(group) = &e.group {
29718 if pretty_clickhouse {
29719 self.write_newline();
29720 if let Expression::Group(g) = group.as_ref() {
29721 self.write_indent();
29722 self.write_keyword("GROUP BY");
29723 self.write_newline();
29724 self.indent_level += 1;
29725 for (i, expr) in g.expressions.iter().enumerate() {
29726 if i > 0 {
29727 self.write(",");
29728 self.write_newline();
29729 }
29730 self.write_indent();
29731 self.generate_expression(expr)?;
29732 }
29733 self.indent_level -= 1;
29734 } else {
29735 self.write_indent();
29736 self.generate_expression(group)?;
29737 }
29738 } else {
29739 self.write_space();
29740 self.generate_expression(group)?;
29741 }
29742 }
29743 if let Some(aggregates) = &e.aggregates {
29744 if pretty_clickhouse {
29745 self.write_newline();
29746 self.write_indent();
29747 self.write_keyword("SET");
29748 self.write_newline();
29749 self.indent_level += 1;
29750 if let Expression::Tuple(t) = aggregates.as_ref() {
29751 for (i, agg) in t.expressions.iter().enumerate() {
29752 if i > 0 {
29753 self.write(",");
29754 self.write_newline();
29755 }
29756 self.write_indent();
29757 self.generate_expression(agg)?;
29758 }
29759 } else {
29760 self.write_indent();
29761 self.generate_expression(aggregates)?;
29762 }
29763 self.indent_level -= 1;
29764 } else {
29765 self.write_space();
29766 self.write_keyword("SET");
29767 self.write_space();
29768 self.generate_expression(aggregates)?;
29769 }
29770 }
29771 Ok(())
29772 }
29773
29774 fn generate_merge_tree_ttl_action(&mut self, e: &MergeTreeTTLAction) -> Result<()> {
29775 self.generate_expression(&e.this)?;
29777 if e.delete.is_some() {
29778 self.write_keyword(" DELETE");
29779 }
29780 if let Some(recompress) = &e.recompress {
29781 self.write_keyword(" RECOMPRESS ");
29782 self.generate_expression(recompress)?;
29783 }
29784 if let Some(to_disk) = &e.to_disk {
29785 self.write_keyword(" TO DISK ");
29786 self.generate_expression(to_disk)?;
29787 }
29788 if let Some(to_volume) = &e.to_volume {
29789 self.write_keyword(" TO VOLUME ");
29790 self.generate_expression(to_volume)?;
29791 }
29792 Ok(())
29793 }
29794
29795 fn generate_minhash(&mut self, e: &Minhash) -> Result<()> {
29796 self.write_keyword("MINHASH");
29798 self.write("(");
29799 self.generate_expression(&e.this)?;
29800 for expr in &e.expressions {
29801 self.write(", ");
29802 self.generate_expression(expr)?;
29803 }
29804 self.write(")");
29805 Ok(())
29806 }
29807
29808 fn generate_model_attribute(&mut self, e: &ModelAttribute) -> Result<()> {
29809 self.generate_expression(&e.this)?;
29811 self.write("!");
29812 self.generate_expression(&e.expression)?;
29813 Ok(())
29814 }
29815
29816 fn generate_monthname(&mut self, e: &Monthname) -> Result<()> {
29817 self.write_keyword("MONTHNAME");
29819 self.write("(");
29820 self.generate_expression(&e.this)?;
29821 self.write(")");
29822 Ok(())
29823 }
29824
29825 fn generate_multitable_inserts(&mut self, e: &MultitableInserts) -> Result<()> {
29826 for comment in &e.leading_comments {
29828 self.write_formatted_comment(comment);
29829 if self.config.pretty {
29830 self.write_newline();
29831 self.write_indent();
29832 } else {
29833 self.write_space();
29834 }
29835 }
29836 self.write_keyword("INSERT");
29838 self.write_space();
29839 self.write(&e.kind);
29840 if self.config.pretty {
29841 self.indent_level += 1;
29842 for expr in &e.expressions {
29843 self.write_newline();
29844 self.write_indent();
29845 self.generate_expression(expr)?;
29846 }
29847 self.indent_level -= 1;
29848 } else {
29849 for expr in &e.expressions {
29850 self.write_space();
29851 self.generate_expression(expr)?;
29852 }
29853 }
29854 if let Some(source) = &e.source {
29855 if self.config.pretty {
29856 self.write_newline();
29857 self.write_indent();
29858 } else {
29859 self.write_space();
29860 }
29861 self.generate_expression(source)?;
29862 }
29863 Ok(())
29864 }
29865
29866 fn generate_next_value_for(&mut self, e: &NextValueFor) -> Result<()> {
29867 self.write_keyword("NEXT VALUE FOR");
29869 self.write_space();
29870 self.generate_expression(&e.this)?;
29871 if let Some(order) = &e.order {
29872 self.write_space();
29873 self.write_keyword("OVER");
29874 self.write(" (");
29875 self.generate_expression(order)?;
29876 self.write(")");
29877 }
29878 Ok(())
29879 }
29880
29881 fn generate_normal(&mut self, e: &Normal) -> Result<()> {
29882 self.write_keyword("NORMAL");
29884 self.write("(");
29885 self.generate_expression(&e.this)?;
29886 if let Some(stddev) = &e.stddev {
29887 self.write(", ");
29888 self.generate_expression(stddev)?;
29889 }
29890 if let Some(gen) = &e.gen {
29891 self.write(", ");
29892 self.generate_expression(gen)?;
29893 }
29894 self.write(")");
29895 Ok(())
29896 }
29897
29898 fn generate_normalize(&mut self, e: &Normalize) -> Result<()> {
29899 if e.is_casefold.is_some() {
29901 self.write_keyword("NORMALIZE_AND_CASEFOLD");
29902 } else {
29903 self.write_keyword("NORMALIZE");
29904 }
29905 self.write("(");
29906 self.generate_expression(&e.this)?;
29907 if let Some(form) = &e.form {
29908 self.write(", ");
29909 self.generate_expression(form)?;
29910 }
29911 self.write(")");
29912 Ok(())
29913 }
29914
29915 fn generate_not_null_column_constraint(&mut self, e: &NotNullColumnConstraint) -> Result<()> {
29916 if e.allow_null.is_none() {
29918 self.write_keyword("NOT ");
29919 }
29920 self.write_keyword("NULL");
29921 Ok(())
29922 }
29923
29924 fn generate_nullif(&mut self, e: &Nullif) -> Result<()> {
29925 self.write_keyword("NULLIF");
29927 self.write("(");
29928 self.generate_expression(&e.this)?;
29929 self.write(", ");
29930 self.generate_expression(&e.expression)?;
29931 self.write(")");
29932 Ok(())
29933 }
29934
29935 fn generate_number_to_str(&mut self, e: &NumberToStr) -> Result<()> {
29936 self.write_keyword("FORMAT");
29938 self.write("(");
29939 self.generate_expression(&e.this)?;
29940 self.write(", '");
29941 self.write(&e.format);
29942 self.write("'");
29943 if let Some(culture) = &e.culture {
29944 self.write(", ");
29945 self.generate_expression(culture)?;
29946 }
29947 self.write(")");
29948 Ok(())
29949 }
29950
29951 fn generate_object_agg(&mut self, e: &ObjectAgg) -> Result<()> {
29952 self.write_keyword("OBJECT_AGG");
29954 self.write("(");
29955 self.generate_expression(&e.this)?;
29956 self.write(", ");
29957 self.generate_expression(&e.expression)?;
29958 self.write(")");
29959 Ok(())
29960 }
29961
29962 fn generate_object_identifier(&mut self, e: &ObjectIdentifier) -> Result<()> {
29963 self.generate_expression(&e.this)?;
29965 Ok(())
29966 }
29967
29968 fn generate_object_insert(&mut self, e: &ObjectInsert) -> Result<()> {
29969 self.write_keyword("OBJECT_INSERT");
29971 self.write("(");
29972 self.generate_expression(&e.this)?;
29973 if let Some(key) = &e.key {
29974 self.write(", ");
29975 self.generate_expression(key)?;
29976 }
29977 if let Some(value) = &e.value {
29978 self.write(", ");
29979 self.generate_expression(value)?;
29980 }
29981 if let Some(update_flag) = &e.update_flag {
29982 self.write(", ");
29983 self.generate_expression(update_flag)?;
29984 }
29985 self.write(")");
29986 Ok(())
29987 }
29988
29989 fn generate_offset(&mut self, e: &Offset) -> Result<()> {
29990 self.write_keyword("OFFSET");
29992 self.write_space();
29993 self.generate_expression(&e.this)?;
29994 if e.rows == Some(true)
29996 && matches!(
29997 self.config.dialect,
29998 Some(crate::dialects::DialectType::TSQL)
29999 | Some(crate::dialects::DialectType::Oracle)
30000 )
30001 {
30002 self.write_space();
30003 self.write_keyword("ROWS");
30004 }
30005 Ok(())
30006 }
30007
30008 fn generate_qualify(&mut self, e: &Qualify) -> Result<()> {
30009 self.write_keyword("QUALIFY");
30011 self.write_space();
30012 self.generate_expression(&e.this)?;
30013 Ok(())
30014 }
30015
30016 fn generate_on_cluster(&mut self, e: &OnCluster) -> Result<()> {
30017 self.write_keyword("ON CLUSTER");
30019 self.write_space();
30020 self.generate_expression(&e.this)?;
30021 Ok(())
30022 }
30023
30024 fn generate_on_commit_property(&mut self, e: &OnCommitProperty) -> Result<()> {
30025 self.write_keyword("ON COMMIT");
30027 if e.delete.is_some() {
30028 self.write_keyword(" DELETE ROWS");
30029 } else {
30030 self.write_keyword(" PRESERVE ROWS");
30031 }
30032 Ok(())
30033 }
30034
30035 fn generate_on_condition(&mut self, e: &OnCondition) -> Result<()> {
30036 if let Some(empty) = &e.empty {
30038 self.generate_expression(empty)?;
30039 self.write_keyword(" ON EMPTY");
30040 }
30041 if let Some(error) = &e.error {
30042 if e.empty.is_some() {
30043 self.write_space();
30044 }
30045 self.generate_expression(error)?;
30046 self.write_keyword(" ON ERROR");
30047 }
30048 if let Some(null) = &e.null {
30049 if e.empty.is_some() || e.error.is_some() {
30050 self.write_space();
30051 }
30052 self.generate_expression(null)?;
30053 self.write_keyword(" ON NULL");
30054 }
30055 Ok(())
30056 }
30057
30058 fn generate_on_conflict(&mut self, e: &OnConflict) -> Result<()> {
30059 if matches!(self.config.dialect, Some(DialectType::Materialize)) {
30061 return Ok(());
30062 }
30063 if e.duplicate.is_some() {
30065 self.write_keyword("ON DUPLICATE KEY UPDATE");
30067 for (i, expr) in e.expressions.iter().enumerate() {
30068 if i > 0 {
30069 self.write(",");
30070 }
30071 self.write_space();
30072 self.generate_expression(expr)?;
30073 }
30074 return Ok(());
30075 } else {
30076 self.write_keyword("ON CONFLICT");
30077 }
30078 if let Some(constraint) = &e.constraint {
30079 self.write_keyword(" ON CONSTRAINT ");
30080 self.generate_expression(constraint)?;
30081 }
30082 if let Some(conflict_keys) = &e.conflict_keys {
30083 if let Expression::Tuple(t) = conflict_keys.as_ref() {
30085 self.write("(");
30086 for (i, expr) in t.expressions.iter().enumerate() {
30087 if i > 0 {
30088 self.write(", ");
30089 }
30090 self.generate_expression(expr)?;
30091 }
30092 self.write(")");
30093 } else {
30094 self.write("(");
30095 self.generate_expression(conflict_keys)?;
30096 self.write(")");
30097 }
30098 }
30099 if let Some(index_predicate) = &e.index_predicate {
30100 self.write_keyword(" WHERE ");
30101 self.generate_expression(index_predicate)?;
30102 }
30103 if let Some(action) = &e.action {
30104 if let Expression::Identifier(id) = action.as_ref() {
30106 if id.name == "NOTHING" || id.name.to_uppercase() == "NOTHING" {
30107 self.write_keyword(" DO NOTHING");
30108 } else {
30109 self.write_keyword(" DO ");
30110 self.generate_expression(action)?;
30111 }
30112 } else if let Expression::Tuple(t) = action.as_ref() {
30113 self.write_keyword(" DO UPDATE SET ");
30115 for (i, expr) in t.expressions.iter().enumerate() {
30116 if i > 0 {
30117 self.write(", ");
30118 }
30119 self.generate_expression(expr)?;
30120 }
30121 } else {
30122 self.write_keyword(" DO ");
30123 self.generate_expression(action)?;
30124 }
30125 }
30126 if let Some(where_) = &e.where_ {
30128 self.write_keyword(" WHERE ");
30129 self.generate_expression(where_)?;
30130 }
30131 Ok(())
30132 }
30133
30134 fn generate_on_property(&mut self, e: &OnProperty) -> Result<()> {
30135 self.write_keyword("ON");
30137 self.write_space();
30138 self.generate_expression(&e.this)?;
30139 Ok(())
30140 }
30141
30142 fn generate_opclass(&mut self, e: &Opclass) -> Result<()> {
30143 self.generate_expression(&e.this)?;
30145 self.write_space();
30146 self.generate_expression(&e.expression)?;
30147 Ok(())
30148 }
30149
30150 fn generate_open_json(&mut self, e: &OpenJSON) -> Result<()> {
30151 self.write_keyword("OPENJSON");
30153 self.write("(");
30154 self.generate_expression(&e.this)?;
30155 if let Some(path) = &e.path {
30156 self.write(", ");
30157 self.generate_expression(path)?;
30158 }
30159 self.write(")");
30160 if !e.expressions.is_empty() {
30161 self.write_keyword(" WITH");
30162 if self.config.pretty {
30163 self.write(" (\n");
30164 self.indent_level += 2;
30165 for (i, expr) in e.expressions.iter().enumerate() {
30166 if i > 0 {
30167 self.write(",\n");
30168 }
30169 self.write_indent();
30170 self.generate_expression(expr)?;
30171 }
30172 self.write("\n");
30173 self.indent_level -= 2;
30174 self.write(")");
30175 } else {
30176 self.write(" (");
30177 for (i, expr) in e.expressions.iter().enumerate() {
30178 if i > 0 {
30179 self.write(", ");
30180 }
30181 self.generate_expression(expr)?;
30182 }
30183 self.write(")");
30184 }
30185 }
30186 Ok(())
30187 }
30188
30189 fn generate_open_json_column_def(&mut self, e: &OpenJSONColumnDef) -> Result<()> {
30190 self.generate_expression(&e.this)?;
30192 self.write_space();
30193 if let Some(ref dt) = e.data_type {
30195 self.generate_data_type(dt)?;
30196 } else if !e.kind.is_empty() {
30197 self.write(&e.kind);
30198 }
30199 if let Some(path) = &e.path {
30200 self.write_space();
30201 self.generate_expression(path)?;
30202 }
30203 if e.as_json.is_some() {
30204 self.write_keyword(" AS JSON");
30205 }
30206 Ok(())
30207 }
30208
30209 fn generate_operator(&mut self, e: &Operator) -> Result<()> {
30210 self.generate_expression(&e.this)?;
30212 self.write_space();
30213 if let Some(op) = &e.operator {
30214 self.write_keyword("OPERATOR");
30215 self.write("(");
30216 self.generate_expression(op)?;
30217 self.write(")");
30218 }
30219 for comment in &e.comments {
30221 self.write_space();
30222 self.write_formatted_comment(comment);
30223 }
30224 self.write_space();
30225 self.generate_expression(&e.expression)?;
30226 Ok(())
30227 }
30228
30229 fn generate_order_by(&mut self, e: &OrderBy) -> Result<()> {
30230 self.write_keyword("ORDER BY");
30232 let pretty_clickhouse_single_paren = self.config.pretty
30233 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
30234 && e.expressions.len() == 1
30235 && matches!(e.expressions[0].this, Expression::Paren(ref p) if !matches!(p.this, Expression::Tuple(_)));
30236 let clickhouse_single_tuple = matches!(self.config.dialect, Some(DialectType::ClickHouse))
30237 && e.expressions.len() == 1
30238 && matches!(e.expressions[0].this, Expression::Tuple(_))
30239 && !e.expressions[0].desc
30240 && e.expressions[0].nulls_first.is_none();
30241
30242 if pretty_clickhouse_single_paren {
30243 self.write_space();
30244 if let Expression::Paren(p) = &e.expressions[0].this {
30245 self.write("(");
30246 self.write_newline();
30247 self.indent_level += 1;
30248 self.write_indent();
30249 self.generate_expression(&p.this)?;
30250 self.indent_level -= 1;
30251 self.write_newline();
30252 self.write(")");
30253 }
30254 return Ok(());
30255 }
30256
30257 if clickhouse_single_tuple {
30258 self.write_space();
30259 if let Expression::Tuple(t) = &e.expressions[0].this {
30260 self.write("(");
30261 for (i, expr) in t.expressions.iter().enumerate() {
30262 if i > 0 {
30263 self.write(", ");
30264 }
30265 self.generate_expression(expr)?;
30266 }
30267 self.write(")");
30268 }
30269 return Ok(());
30270 }
30271
30272 self.write_space();
30273 for (i, ordered) in e.expressions.iter().enumerate() {
30274 if i > 0 {
30275 self.write(", ");
30276 }
30277 self.generate_expression(&ordered.this)?;
30278 if ordered.desc {
30279 self.write_space();
30280 self.write_keyword("DESC");
30281 } else if ordered.explicit_asc {
30282 self.write_space();
30283 self.write_keyword("ASC");
30284 }
30285 if let Some(nulls_first) = ordered.nulls_first {
30286 let skip_nulls_last =
30288 !nulls_first && matches!(self.config.dialect, Some(DialectType::Dremio));
30289 if !skip_nulls_last {
30290 self.write_space();
30291 self.write_keyword("NULLS");
30292 self.write_space();
30293 if nulls_first {
30294 self.write_keyword("FIRST");
30295 } else {
30296 self.write_keyword("LAST");
30297 }
30298 }
30299 }
30300 }
30301 Ok(())
30302 }
30303
30304 fn generate_output_model_property(&mut self, e: &OutputModelProperty) -> Result<()> {
30305 self.write_keyword("OUTPUT");
30307 self.write("(");
30308 if self.config.pretty {
30309 self.indent_level += 1;
30310 self.write_newline();
30311 self.write_indent();
30312 self.generate_expression(&e.this)?;
30313 self.indent_level -= 1;
30314 self.write_newline();
30315 } else {
30316 self.generate_expression(&e.this)?;
30317 }
30318 self.write(")");
30319 Ok(())
30320 }
30321
30322 fn generate_overflow_truncate_behavior(&mut self, e: &OverflowTruncateBehavior) -> Result<()> {
30323 self.write_keyword("TRUNCATE");
30325 if let Some(this) = &e.this {
30326 self.write_space();
30327 self.generate_expression(this)?;
30328 }
30329 if e.with_count.is_some() {
30330 self.write_keyword(" WITH COUNT");
30331 } else {
30332 self.write_keyword(" WITHOUT COUNT");
30333 }
30334 Ok(())
30335 }
30336
30337 fn generate_parameterized_agg(&mut self, e: &ParameterizedAgg) -> Result<()> {
30338 self.generate_expression(&e.this)?;
30340 self.write("(");
30341 for (i, expr) in e.expressions.iter().enumerate() {
30342 if i > 0 {
30343 self.write(", ");
30344 }
30345 self.generate_expression(expr)?;
30346 }
30347 self.write(")(");
30348 for (i, param) in e.params.iter().enumerate() {
30349 if i > 0 {
30350 self.write(", ");
30351 }
30352 self.generate_expression(param)?;
30353 }
30354 self.write(")");
30355 Ok(())
30356 }
30357
30358 fn generate_parse_datetime(&mut self, e: &ParseDatetime) -> Result<()> {
30359 self.write_keyword("PARSE_DATETIME");
30361 self.write("(");
30362 if let Some(format) = &e.format {
30363 self.write("'");
30364 self.write(format);
30365 self.write("', ");
30366 }
30367 self.generate_expression(&e.this)?;
30368 if let Some(zone) = &e.zone {
30369 self.write(", ");
30370 self.generate_expression(zone)?;
30371 }
30372 self.write(")");
30373 Ok(())
30374 }
30375
30376 fn generate_parse_ip(&mut self, e: &ParseIp) -> Result<()> {
30377 self.write_keyword("PARSE_IP");
30379 self.write("(");
30380 self.generate_expression(&e.this)?;
30381 if let Some(type_) = &e.type_ {
30382 self.write(", ");
30383 self.generate_expression(type_)?;
30384 }
30385 if let Some(permissive) = &e.permissive {
30386 self.write(", ");
30387 self.generate_expression(permissive)?;
30388 }
30389 self.write(")");
30390 Ok(())
30391 }
30392
30393 fn generate_parse_json(&mut self, e: &ParseJSON) -> Result<()> {
30394 self.write_keyword("PARSE_JSON");
30396 self.write("(");
30397 self.generate_expression(&e.this)?;
30398 if let Some(expression) = &e.expression {
30399 self.write(", ");
30400 self.generate_expression(expression)?;
30401 }
30402 self.write(")");
30403 Ok(())
30404 }
30405
30406 fn generate_parse_time(&mut self, e: &ParseTime) -> Result<()> {
30407 self.write_keyword("PARSE_TIME");
30409 self.write("(");
30410 self.write(&format!("'{}'", e.format));
30411 self.write(", ");
30412 self.generate_expression(&e.this)?;
30413 self.write(")");
30414 Ok(())
30415 }
30416
30417 fn generate_parse_url(&mut self, e: &ParseUrl) -> Result<()> {
30418 self.write_keyword("PARSE_URL");
30420 self.write("(");
30421 self.generate_expression(&e.this)?;
30422 if let Some(part) = &e.part_to_extract {
30423 self.write(", ");
30424 self.generate_expression(part)?;
30425 }
30426 if let Some(key) = &e.key {
30427 self.write(", ");
30428 self.generate_expression(key)?;
30429 }
30430 if let Some(permissive) = &e.permissive {
30431 self.write(", ");
30432 self.generate_expression(permissive)?;
30433 }
30434 self.write(")");
30435 Ok(())
30436 }
30437
30438 fn generate_partition_expr(&mut self, e: &Partition) -> Result<()> {
30439 if e.subpartition {
30441 self.write_keyword("SUBPARTITION");
30442 } else {
30443 self.write_keyword("PARTITION");
30444 }
30445 self.write("(");
30446 for (i, expr) in e.expressions.iter().enumerate() {
30447 if i > 0 {
30448 self.write(", ");
30449 }
30450 self.generate_expression(expr)?;
30451 }
30452 self.write(")");
30453 Ok(())
30454 }
30455
30456 fn generate_partition_bound_spec(&mut self, e: &PartitionBoundSpec) -> Result<()> {
30457 if let Some(this) = &e.this {
30459 if let Some(expression) = &e.expression {
30460 self.write_keyword("WITH");
30462 self.write(" (");
30463 self.write_keyword("MODULUS");
30464 self.write_space();
30465 self.generate_expression(this)?;
30466 self.write(", ");
30467 self.write_keyword("REMAINDER");
30468 self.write_space();
30469 self.generate_expression(expression)?;
30470 self.write(")");
30471 } else {
30472 self.write_keyword("IN");
30474 self.write(" (");
30475 self.generate_partition_bound_values(this)?;
30476 self.write(")");
30477 }
30478 } else if let (Some(from), Some(to)) = (&e.from_expressions, &e.to_expressions) {
30479 self.write_keyword("FROM");
30481 self.write(" (");
30482 self.generate_partition_bound_values(from)?;
30483 self.write(") ");
30484 self.write_keyword("TO");
30485 self.write(" (");
30486 self.generate_partition_bound_values(to)?;
30487 self.write(")");
30488 }
30489 Ok(())
30490 }
30491
30492 fn generate_partition_bound_values(&mut self, expr: &Expression) -> Result<()> {
30495 if let Expression::Tuple(t) = expr {
30496 for (i, e) in t.expressions.iter().enumerate() {
30497 if i > 0 {
30498 self.write(", ");
30499 }
30500 self.generate_expression(e)?;
30501 }
30502 Ok(())
30503 } else {
30504 self.generate_expression(expr)
30505 }
30506 }
30507
30508 fn generate_partition_by_list_property(&mut self, e: &PartitionByListProperty) -> Result<()> {
30509 self.write_keyword("PARTITION BY LIST");
30511 if let Some(partition_exprs) = &e.partition_expressions {
30512 self.write(" (");
30513 self.generate_doris_partition_expressions(partition_exprs)?;
30515 self.write(")");
30516 }
30517 if let Some(create_exprs) = &e.create_expressions {
30518 self.write(" (");
30519 self.generate_doris_partition_definitions(create_exprs)?;
30521 self.write(")");
30522 }
30523 Ok(())
30524 }
30525
30526 fn generate_partition_by_range_property(&mut self, e: &PartitionByRangeProperty) -> Result<()> {
30527 self.write_keyword("PARTITION BY RANGE");
30529 if let Some(partition_exprs) = &e.partition_expressions {
30530 self.write(" (");
30531 self.generate_doris_partition_expressions(partition_exprs)?;
30533 self.write(")");
30534 }
30535 if let Some(create_exprs) = &e.create_expressions {
30536 self.write(" (");
30537 self.generate_doris_partition_definitions(create_exprs)?;
30539 self.write(")");
30540 }
30541 Ok(())
30542 }
30543
30544 fn generate_doris_partition_expressions(&mut self, expr: &Expression) -> Result<()> {
30546 if let Expression::Tuple(t) = expr {
30547 for (i, e) in t.expressions.iter().enumerate() {
30548 if i > 0 {
30549 self.write(", ");
30550 }
30551 self.generate_expression(e)?;
30552 }
30553 } else {
30554 self.generate_expression(expr)?;
30555 }
30556 Ok(())
30557 }
30558
30559 fn generate_doris_partition_definitions(&mut self, expr: &Expression) -> Result<()> {
30561 match expr {
30562 Expression::Tuple(t) => {
30563 for (i, part) in t.expressions.iter().enumerate() {
30565 if i > 0 {
30566 self.write(", ");
30567 }
30568 if let Expression::Partition(p) = part {
30570 for (j, inner) in p.expressions.iter().enumerate() {
30571 if j > 0 {
30572 self.write(", ");
30573 }
30574 self.generate_expression(inner)?;
30575 }
30576 } else {
30577 self.generate_expression(part)?;
30578 }
30579 }
30580 }
30581 Expression::PartitionByRangePropertyDynamic(_) => {
30582 self.generate_expression(expr)?;
30584 }
30585 _ => {
30586 self.generate_expression(expr)?;
30587 }
30588 }
30589 Ok(())
30590 }
30591
30592 fn generate_partition_by_range_property_dynamic(
30593 &mut self,
30594 e: &PartitionByRangePropertyDynamic,
30595 ) -> Result<()> {
30596 if e.use_start_end {
30597 if let Some(start) = &e.start {
30599 self.write_keyword("START");
30600 self.write(" (");
30601 self.generate_expression(start)?;
30602 self.write(")");
30603 }
30604 if let Some(end) = &e.end {
30605 self.write_space();
30606 self.write_keyword("END");
30607 self.write(" (");
30608 self.generate_expression(end)?;
30609 self.write(")");
30610 }
30611 if let Some(every) = &e.every {
30612 self.write_space();
30613 self.write_keyword("EVERY");
30614 self.write(" (");
30615 self.generate_doris_interval(every)?;
30617 self.write(")");
30618 }
30619 } else {
30620 if let Some(start) = &e.start {
30622 self.write_keyword("FROM");
30623 self.write(" (");
30624 self.generate_expression(start)?;
30625 self.write(")");
30626 }
30627 if let Some(end) = &e.end {
30628 self.write_space();
30629 self.write_keyword("TO");
30630 self.write(" (");
30631 self.generate_expression(end)?;
30632 self.write(")");
30633 }
30634 if let Some(every) = &e.every {
30635 self.write_space();
30636 self.generate_doris_interval(every)?;
30638 }
30639 }
30640 Ok(())
30641 }
30642
30643 fn generate_doris_interval(&mut self, expr: &Expression) -> Result<()> {
30645 if let Expression::Interval(interval) = expr {
30646 self.write_keyword("INTERVAL");
30647 if let Some(ref value) = interval.this {
30648 self.write_space();
30649 match value {
30653 Expression::Literal(Literal::String(s))
30654 if s.chars()
30655 .all(|c| c.is_ascii_digit() || c == '.' || c == '-')
30656 && !s.is_empty() =>
30657 {
30658 self.write(s);
30659 }
30660 _ => {
30661 self.generate_expression(value)?;
30662 }
30663 }
30664 }
30665 if let Some(ref unit_spec) = interval.unit {
30666 self.write_space();
30667 self.write_interval_unit_spec(unit_spec)?;
30668 }
30669 Ok(())
30670 } else {
30671 self.generate_expression(expr)
30672 }
30673 }
30674
30675 fn generate_partition_by_truncate(&mut self, e: &PartitionByTruncate) -> Result<()> {
30676 self.write_keyword("TRUNCATE");
30678 self.write("(");
30679 self.generate_expression(&e.expression)?;
30680 self.write(", ");
30681 self.generate_expression(&e.this)?;
30682 self.write(")");
30683 Ok(())
30684 }
30685
30686 fn generate_partition_list(&mut self, e: &PartitionList) -> Result<()> {
30687 self.write_keyword("PARTITION");
30689 self.write_space();
30690 self.generate_expression(&e.this)?;
30691 self.write_space();
30692 self.write_keyword("VALUES IN");
30693 self.write(" (");
30694 for (i, expr) in e.expressions.iter().enumerate() {
30695 if i > 0 {
30696 self.write(", ");
30697 }
30698 self.generate_expression(expr)?;
30699 }
30700 self.write(")");
30701 Ok(())
30702 }
30703
30704 fn generate_partition_range(&mut self, e: &PartitionRange) -> Result<()> {
30705 if e.expressions.is_empty() && e.expression.is_some() {
30708 self.generate_expression(&e.this)?;
30710 self.write_space();
30711 self.write_keyword("TO");
30712 self.write_space();
30713 self.generate_expression(e.expression.as_ref().unwrap())?;
30714 return Ok(());
30715 }
30716
30717 self.write_keyword("PARTITION");
30719 self.write_space();
30720 self.generate_expression(&e.this)?;
30721 self.write_space();
30722
30723 if e.expressions.len() == 1 {
30725 self.write_keyword("VALUES LESS THAN");
30727 self.write(" (");
30728 self.generate_expression(&e.expressions[0])?;
30729 self.write(")");
30730 } else if !e.expressions.is_empty() {
30731 self.write_keyword("VALUES");
30733 self.write(" [");
30734 for (i, expr) in e.expressions.iter().enumerate() {
30735 if i > 0 {
30736 self.write(", ");
30737 }
30738 if let Expression::Tuple(t) = expr {
30740 self.write("(");
30741 for (j, inner) in t.expressions.iter().enumerate() {
30742 if j > 0 {
30743 self.write(", ");
30744 }
30745 self.generate_expression(inner)?;
30746 }
30747 self.write(")");
30748 } else {
30749 self.write("(");
30750 self.generate_expression(expr)?;
30751 self.write(")");
30752 }
30753 }
30754 self.write(")");
30755 }
30756 Ok(())
30757 }
30758
30759 fn generate_partitioned_by_bucket(&mut self, e: &PartitionedByBucket) -> Result<()> {
30760 self.write_keyword("BUCKET");
30762 self.write("(");
30763 self.generate_expression(&e.this)?;
30764 self.write(", ");
30765 self.generate_expression(&e.expression)?;
30766 self.write(")");
30767 Ok(())
30768 }
30769
30770 fn generate_partitioned_by_property(&mut self, e: &PartitionedByProperty) -> Result<()> {
30771 if matches!(
30773 self.config.dialect,
30774 Some(crate::dialects::DialectType::Teradata)
30775 | Some(crate::dialects::DialectType::ClickHouse)
30776 ) {
30777 self.write_keyword("PARTITION BY");
30778 } else {
30779 self.write_keyword("PARTITIONED BY");
30780 }
30781 self.write_space();
30782 if self.config.pretty {
30784 if let Expression::Tuple(ref tuple) = *e.this {
30785 self.write("(");
30786 self.write_newline();
30787 self.indent_level += 1;
30788 for (i, expr) in tuple.expressions.iter().enumerate() {
30789 if i > 0 {
30790 self.write(",");
30791 self.write_newline();
30792 }
30793 self.write_indent();
30794 self.generate_expression(expr)?;
30795 }
30796 self.indent_level -= 1;
30797 self.write_newline();
30798 self.write(")");
30799 } else {
30800 self.generate_expression(&e.this)?;
30801 }
30802 } else {
30803 self.generate_expression(&e.this)?;
30804 }
30805 Ok(())
30806 }
30807
30808 fn generate_partitioned_of_property(&mut self, e: &PartitionedOfProperty) -> Result<()> {
30809 self.write_keyword("PARTITION OF");
30811 self.write_space();
30812 self.generate_expression(&e.this)?;
30813 if let Expression::PartitionBoundSpec(_) = e.expression.as_ref() {
30815 self.write_space();
30816 self.write_keyword("FOR VALUES");
30817 self.write_space();
30818 self.generate_expression(&e.expression)?;
30819 } else {
30820 self.write_space();
30821 self.write_keyword("DEFAULT");
30822 }
30823 Ok(())
30824 }
30825
30826 fn generate_period_for_system_time_constraint(
30827 &mut self,
30828 e: &PeriodForSystemTimeConstraint,
30829 ) -> Result<()> {
30830 self.write_keyword("PERIOD FOR SYSTEM_TIME");
30832 self.write(" (");
30833 self.generate_expression(&e.this)?;
30834 self.write(", ");
30835 self.generate_expression(&e.expression)?;
30836 self.write(")");
30837 Ok(())
30838 }
30839
30840 fn generate_pivot_alias(&mut self, e: &PivotAlias) -> Result<()> {
30841 self.generate_expression(&e.this)?;
30844 self.write_space();
30845 self.write_keyword("AS");
30846 self.write_space();
30847 if self.config.unpivot_aliases_are_identifiers {
30849 match &e.alias {
30850 Expression::Literal(Literal::String(s)) => {
30851 self.generate_identifier(&Identifier::new(s.clone()))?;
30853 }
30854 Expression::Literal(Literal::Number(n)) => {
30855 let mut id = Identifier::new(n.clone());
30857 id.quoted = true;
30858 self.generate_identifier(&id)?;
30859 }
30860 other => {
30861 self.generate_expression(other)?;
30862 }
30863 }
30864 } else {
30865 self.generate_expression(&e.alias)?;
30866 }
30867 Ok(())
30868 }
30869
30870 fn generate_pivot_any(&mut self, e: &PivotAny) -> Result<()> {
30871 self.write_keyword("ANY");
30873 if let Some(this) = &e.this {
30874 self.write_space();
30875 self.generate_expression(this)?;
30876 }
30877 Ok(())
30878 }
30879
30880 fn generate_predict(&mut self, e: &Predict) -> Result<()> {
30881 self.write_keyword("ML.PREDICT");
30883 self.write("(");
30884 self.write_keyword("MODEL");
30885 self.write_space();
30886 self.generate_expression(&e.this)?;
30887 self.write(", ");
30888 self.generate_expression(&e.expression)?;
30889 if let Some(params) = &e.params_struct {
30890 self.write(", ");
30891 self.generate_expression(params)?;
30892 }
30893 self.write(")");
30894 Ok(())
30895 }
30896
30897 fn generate_previous_day(&mut self, e: &PreviousDay) -> Result<()> {
30898 self.write_keyword("PREVIOUS_DAY");
30900 self.write("(");
30901 self.generate_expression(&e.this)?;
30902 self.write(", ");
30903 self.generate_expression(&e.expression)?;
30904 self.write(")");
30905 Ok(())
30906 }
30907
30908 fn generate_primary_key(&mut self, e: &PrimaryKey) -> Result<()> {
30909 self.write_keyword("PRIMARY KEY");
30911 if let Some(name) = &e.this {
30912 self.write_space();
30913 self.generate_expression(name)?;
30914 }
30915 if !e.expressions.is_empty() {
30916 self.write(" (");
30917 for (i, expr) in e.expressions.iter().enumerate() {
30918 if i > 0 {
30919 self.write(", ");
30920 }
30921 self.generate_expression(expr)?;
30922 }
30923 self.write(")");
30924 }
30925 if let Some(include) = &e.include {
30926 self.write_space();
30927 self.generate_expression(include)?;
30928 }
30929 if !e.options.is_empty() {
30930 self.write_space();
30931 for (i, opt) in e.options.iter().enumerate() {
30932 if i > 0 {
30933 self.write_space();
30934 }
30935 self.generate_expression(opt)?;
30936 }
30937 }
30938 Ok(())
30939 }
30940
30941 fn generate_primary_key_column_constraint(
30942 &mut self,
30943 _e: &PrimaryKeyColumnConstraint,
30944 ) -> Result<()> {
30945 self.write_keyword("PRIMARY KEY");
30947 Ok(())
30948 }
30949
30950 fn generate_path_column_constraint(&mut self, e: &PathColumnConstraint) -> Result<()> {
30951 self.write_keyword("PATH");
30953 self.write_space();
30954 self.generate_expression(&e.this)?;
30955 Ok(())
30956 }
30957
30958 fn generate_projection_def(&mut self, e: &ProjectionDef) -> Result<()> {
30959 self.write_keyword("PROJECTION");
30961 self.write_space();
30962 self.generate_expression(&e.this)?;
30963 self.write(" (");
30964 self.generate_expression(&e.expression)?;
30965 self.write(")");
30966 Ok(())
30967 }
30968
30969 fn generate_properties(&mut self, e: &Properties) -> Result<()> {
30970 for (i, prop) in e.expressions.iter().enumerate() {
30972 if i > 0 {
30973 self.write(", ");
30974 }
30975 self.generate_expression(prop)?;
30976 }
30977 Ok(())
30978 }
30979
30980 fn generate_property(&mut self, e: &Property) -> Result<()> {
30981 self.generate_expression(&e.this)?;
30983 if let Some(value) = &e.value {
30984 self.write("=");
30985 self.generate_expression(value)?;
30986 }
30987 Ok(())
30988 }
30989
30990 fn generate_options_clause(&mut self, options: &[Expression]) -> Result<()> {
30992 self.write_keyword("OPTIONS");
30993 self.write(" (");
30994 for (i, opt) in options.iter().enumerate() {
30995 if i > 0 {
30996 self.write(", ");
30997 }
30998 self.generate_option_expression(opt)?;
30999 }
31000 self.write(")");
31001 Ok(())
31002 }
31003
31004 fn generate_properties_clause(&mut self, properties: &[Expression]) -> Result<()> {
31006 self.write_keyword("PROPERTIES");
31007 self.write(" (");
31008 for (i, prop) in properties.iter().enumerate() {
31009 if i > 0 {
31010 self.write(", ");
31011 }
31012 self.generate_option_expression(prop)?;
31013 }
31014 self.write(")");
31015 Ok(())
31016 }
31017
31018 fn generate_environment_clause(&mut self, environment: &[Expression]) -> Result<()> {
31020 self.write_keyword("ENVIRONMENT");
31021 self.write(" (");
31022 for (i, env_item) in environment.iter().enumerate() {
31023 if i > 0 {
31024 self.write(", ");
31025 }
31026 self.generate_environment_expression(env_item)?;
31027 }
31028 self.write(")");
31029 Ok(())
31030 }
31031
31032 fn generate_environment_expression(&mut self, expr: &Expression) -> Result<()> {
31034 match expr {
31035 Expression::Eq(eq) => {
31036 self.generate_expression(&eq.left)?;
31038 self.write(" = ");
31039 self.generate_expression(&eq.right)?;
31040 Ok(())
31041 }
31042 _ => self.generate_expression(expr),
31043 }
31044 }
31045
31046 fn generate_tblproperties_clause(&mut self, options: &[Expression]) -> Result<()> {
31048 self.write_keyword("TBLPROPERTIES");
31049 if self.config.pretty {
31050 self.write(" (");
31051 self.write_newline();
31052 self.indent_level += 1;
31053 for (i, opt) in options.iter().enumerate() {
31054 if i > 0 {
31055 self.write(",");
31056 self.write_newline();
31057 }
31058 self.write_indent();
31059 self.generate_option_expression(opt)?;
31060 }
31061 self.indent_level -= 1;
31062 self.write_newline();
31063 self.write(")");
31064 } else {
31065 self.write(" (");
31066 for (i, opt) in options.iter().enumerate() {
31067 if i > 0 {
31068 self.write(", ");
31069 }
31070 self.generate_option_expression(opt)?;
31071 }
31072 self.write(")");
31073 }
31074 Ok(())
31075 }
31076
31077 fn generate_option_expression(&mut self, expr: &Expression) -> Result<()> {
31079 match expr {
31080 Expression::Eq(eq) => {
31081 self.generate_expression(&eq.left)?;
31083 self.write("=");
31084 self.generate_expression(&eq.right)?;
31085 Ok(())
31086 }
31087 _ => self.generate_expression(expr),
31088 }
31089 }
31090
31091 fn generate_pseudo_type(&mut self, e: &PseudoType) -> Result<()> {
31092 self.generate_expression(&e.this)?;
31094 Ok(())
31095 }
31096
31097 fn generate_put(&mut self, e: &PutStmt) -> Result<()> {
31098 self.write_keyword("PUT");
31100 self.write_space();
31101
31102 if e.source_quoted {
31104 self.write("'");
31105 self.write(&e.source);
31106 self.write("'");
31107 } else {
31108 self.write(&e.source);
31109 }
31110
31111 self.write_space();
31112
31113 if let Expression::Literal(Literal::String(s)) = &e.target {
31115 self.write(s);
31116 } else {
31117 self.generate_expression(&e.target)?;
31118 }
31119
31120 for param in &e.params {
31122 self.write_space();
31123 self.write(¶m.name);
31124 if let Some(ref value) = param.value {
31125 self.write("=");
31126 self.generate_expression(value)?;
31127 }
31128 }
31129
31130 Ok(())
31131 }
31132
31133 fn generate_quantile(&mut self, e: &Quantile) -> Result<()> {
31134 self.write_keyword("QUANTILE");
31136 self.write("(");
31137 self.generate_expression(&e.this)?;
31138 if let Some(quantile) = &e.quantile {
31139 self.write(", ");
31140 self.generate_expression(quantile)?;
31141 }
31142 self.write(")");
31143 Ok(())
31144 }
31145
31146 fn generate_query_band(&mut self, e: &QueryBand) -> Result<()> {
31147 if matches!(
31149 self.config.dialect,
31150 Some(crate::dialects::DialectType::Teradata)
31151 ) {
31152 self.write_keyword("SET");
31153 self.write_space();
31154 }
31155 self.write_keyword("QUERY_BAND");
31156 self.write(" = ");
31157 self.generate_expression(&e.this)?;
31158 if e.update.is_some() {
31159 self.write_space();
31160 self.write_keyword("UPDATE");
31161 }
31162 if let Some(scope) = &e.scope {
31163 self.write_space();
31164 self.write_keyword("FOR");
31165 self.write_space();
31166 self.generate_expression(scope)?;
31167 }
31168 Ok(())
31169 }
31170
31171 fn generate_query_option(&mut self, e: &QueryOption) -> Result<()> {
31172 self.generate_expression(&e.this)?;
31174 if let Some(expression) = &e.expression {
31175 self.write(" = ");
31176 self.generate_expression(expression)?;
31177 }
31178 Ok(())
31179 }
31180
31181 fn generate_query_transform(&mut self, e: &QueryTransform) -> Result<()> {
31182 self.write_keyword("TRANSFORM");
31184 self.write("(");
31185 for (i, expr) in e.expressions.iter().enumerate() {
31186 if i > 0 {
31187 self.write(", ");
31188 }
31189 self.generate_expression(expr)?;
31190 }
31191 self.write(")");
31192 if let Some(row_format_before) = &e.row_format_before {
31193 self.write_space();
31194 self.generate_expression(row_format_before)?;
31195 }
31196 if let Some(record_writer) = &e.record_writer {
31197 self.write_space();
31198 self.write_keyword("RECORDWRITER");
31199 self.write_space();
31200 self.generate_expression(record_writer)?;
31201 }
31202 if let Some(command_script) = &e.command_script {
31203 self.write_space();
31204 self.write_keyword("USING");
31205 self.write_space();
31206 self.generate_expression(command_script)?;
31207 }
31208 if let Some(schema) = &e.schema {
31209 self.write_space();
31210 self.write_keyword("AS");
31211 self.write_space();
31212 self.generate_expression(schema)?;
31213 }
31214 if let Some(row_format_after) = &e.row_format_after {
31215 self.write_space();
31216 self.generate_expression(row_format_after)?;
31217 }
31218 if let Some(record_reader) = &e.record_reader {
31219 self.write_space();
31220 self.write_keyword("RECORDREADER");
31221 self.write_space();
31222 self.generate_expression(record_reader)?;
31223 }
31224 Ok(())
31225 }
31226
31227 fn generate_randn(&mut self, e: &Randn) -> Result<()> {
31228 self.write_keyword("RANDN");
31230 self.write("(");
31231 if let Some(this) = &e.this {
31232 self.generate_expression(this)?;
31233 }
31234 self.write(")");
31235 Ok(())
31236 }
31237
31238 fn generate_randstr(&mut self, e: &Randstr) -> Result<()> {
31239 self.write_keyword("RANDSTR");
31241 self.write("(");
31242 self.generate_expression(&e.this)?;
31243 if let Some(generator) = &e.generator {
31244 self.write(", ");
31245 self.generate_expression(generator)?;
31246 }
31247 self.write(")");
31248 Ok(())
31249 }
31250
31251 fn generate_range_bucket(&mut self, e: &RangeBucket) -> Result<()> {
31252 self.write_keyword("RANGE_BUCKET");
31254 self.write("(");
31255 self.generate_expression(&e.this)?;
31256 self.write(", ");
31257 self.generate_expression(&e.expression)?;
31258 self.write(")");
31259 Ok(())
31260 }
31261
31262 fn generate_range_n(&mut self, e: &RangeN) -> Result<()> {
31263 self.write_keyword("RANGE_N");
31265 self.write("(");
31266 self.generate_expression(&e.this)?;
31267 self.write_space();
31268 self.write_keyword("BETWEEN");
31269 self.write_space();
31270 for (i, expr) in e.expressions.iter().enumerate() {
31271 if i > 0 {
31272 self.write(", ");
31273 }
31274 self.generate_expression(expr)?;
31275 }
31276 if let Some(each) = &e.each {
31277 self.write_space();
31278 self.write_keyword("EACH");
31279 self.write_space();
31280 self.generate_expression(each)?;
31281 }
31282 self.write(")");
31283 Ok(())
31284 }
31285
31286 fn generate_read_csv(&mut self, e: &ReadCSV) -> Result<()> {
31287 self.write_keyword("READ_CSV");
31289 self.write("(");
31290 self.generate_expression(&e.this)?;
31291 for expr in &e.expressions {
31292 self.write(", ");
31293 self.generate_expression(expr)?;
31294 }
31295 self.write(")");
31296 Ok(())
31297 }
31298
31299 fn generate_read_parquet(&mut self, e: &ReadParquet) -> Result<()> {
31300 self.write_keyword("READ_PARQUET");
31302 self.write("(");
31303 for (i, expr) in e.expressions.iter().enumerate() {
31304 if i > 0 {
31305 self.write(", ");
31306 }
31307 self.generate_expression(expr)?;
31308 }
31309 self.write(")");
31310 Ok(())
31311 }
31312
31313 fn generate_recursive_with_search(&mut self, e: &RecursiveWithSearch) -> Result<()> {
31314 if e.kind == "CYCLE" {
31317 self.write_keyword("CYCLE");
31318 } else {
31319 self.write_keyword("SEARCH");
31320 self.write_space();
31321 self.write(&e.kind);
31322 self.write_space();
31323 self.write_keyword("FIRST BY");
31324 }
31325 self.write_space();
31326 self.generate_expression(&e.this)?;
31327 self.write_space();
31328 self.write_keyword("SET");
31329 self.write_space();
31330 self.generate_expression(&e.expression)?;
31331 if let Some(using) = &e.using {
31332 self.write_space();
31333 self.write_keyword("USING");
31334 self.write_space();
31335 self.generate_expression(using)?;
31336 }
31337 Ok(())
31338 }
31339
31340 fn generate_reduce(&mut self, e: &Reduce) -> Result<()> {
31341 self.write_keyword("REDUCE");
31343 self.write("(");
31344 self.generate_expression(&e.this)?;
31345 if let Some(initial) = &e.initial {
31346 self.write(", ");
31347 self.generate_expression(initial)?;
31348 }
31349 if let Some(merge) = &e.merge {
31350 self.write(", ");
31351 self.generate_expression(merge)?;
31352 }
31353 if let Some(finish) = &e.finish {
31354 self.write(", ");
31355 self.generate_expression(finish)?;
31356 }
31357 self.write(")");
31358 Ok(())
31359 }
31360
31361 fn generate_reference(&mut self, e: &Reference) -> Result<()> {
31362 self.write_keyword("REFERENCES");
31364 self.write_space();
31365 self.generate_expression(&e.this)?;
31366 if !e.expressions.is_empty() {
31367 self.write(" (");
31368 for (i, expr) in e.expressions.iter().enumerate() {
31369 if i > 0 {
31370 self.write(", ");
31371 }
31372 self.generate_expression(expr)?;
31373 }
31374 self.write(")");
31375 }
31376 for opt in &e.options {
31377 self.write_space();
31378 self.generate_expression(opt)?;
31379 }
31380 Ok(())
31381 }
31382
31383 fn generate_refresh(&mut self, e: &Refresh) -> Result<()> {
31384 self.write_keyword("REFRESH");
31386 if !e.kind.is_empty() {
31387 self.write_space();
31388 self.write_keyword(&e.kind);
31389 }
31390 self.write_space();
31391 self.generate_expression(&e.this)?;
31392 Ok(())
31393 }
31394
31395 fn generate_refresh_trigger_property(&mut self, e: &RefreshTriggerProperty) -> Result<()> {
31396 self.write_keyword("REFRESH");
31398 self.write_space();
31399 self.write_keyword(&e.method);
31400
31401 if let Some(ref kind) = e.kind {
31402 self.write_space();
31403 self.write_keyword("ON");
31404 self.write_space();
31405 self.write_keyword(kind);
31406
31407 if let Some(ref every) = e.every {
31409 self.write_space();
31410 self.write_keyword("EVERY");
31411 self.write_space();
31412 self.generate_expression(every)?;
31413 if let Some(ref unit) = e.unit {
31414 self.write_space();
31415 self.write_keyword(unit);
31416 }
31417 }
31418
31419 if let Some(ref starts) = e.starts {
31421 self.write_space();
31422 self.write_keyword("STARTS");
31423 self.write_space();
31424 self.generate_expression(starts)?;
31425 }
31426 }
31427 Ok(())
31428 }
31429
31430 fn generate_regexp_count(&mut self, e: &RegexpCount) -> Result<()> {
31431 self.write_keyword("REGEXP_COUNT");
31433 self.write("(");
31434 self.generate_expression(&e.this)?;
31435 self.write(", ");
31436 self.generate_expression(&e.expression)?;
31437 if let Some(position) = &e.position {
31438 self.write(", ");
31439 self.generate_expression(position)?;
31440 }
31441 if let Some(parameters) = &e.parameters {
31442 self.write(", ");
31443 self.generate_expression(parameters)?;
31444 }
31445 self.write(")");
31446 Ok(())
31447 }
31448
31449 fn generate_regexp_extract_all(&mut self, e: &RegexpExtractAll) -> Result<()> {
31450 self.write_keyword("REGEXP_EXTRACT_ALL");
31452 self.write("(");
31453 self.generate_expression(&e.this)?;
31454 self.write(", ");
31455 self.generate_expression(&e.expression)?;
31456 if let Some(group) = &e.group {
31457 self.write(", ");
31458 self.generate_expression(group)?;
31459 }
31460 self.write(")");
31461 Ok(())
31462 }
31463
31464 fn generate_regexp_full_match(&mut self, e: &RegexpFullMatch) -> Result<()> {
31465 self.write_keyword("REGEXP_FULL_MATCH");
31467 self.write("(");
31468 self.generate_expression(&e.this)?;
31469 self.write(", ");
31470 self.generate_expression(&e.expression)?;
31471 self.write(")");
31472 Ok(())
31473 }
31474
31475 fn generate_regexp_i_like(&mut self, e: &RegexpILike) -> Result<()> {
31476 use crate::dialects::DialectType;
31477 if matches!(
31479 self.config.dialect,
31480 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
31481 ) && e.flag.is_none()
31482 {
31483 self.generate_expression(&e.this)?;
31484 self.write(" ~* ");
31485 self.generate_expression(&e.expression)?;
31486 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
31487 self.write_keyword("REGEXP_LIKE");
31489 self.write("(");
31490 self.generate_expression(&e.this)?;
31491 self.write(", ");
31492 self.generate_expression(&e.expression)?;
31493 self.write(", ");
31494 if let Some(flag) = &e.flag {
31495 self.generate_expression(flag)?;
31496 } else {
31497 self.write("'i'");
31498 }
31499 self.write(")");
31500 } else {
31501 self.generate_expression(&e.this)?;
31503 self.write_space();
31504 self.write_keyword("REGEXP_ILIKE");
31505 self.write_space();
31506 self.generate_expression(&e.expression)?;
31507 if let Some(flag) = &e.flag {
31508 self.write(", ");
31509 self.generate_expression(flag)?;
31510 }
31511 }
31512 Ok(())
31513 }
31514
31515 fn generate_regexp_instr(&mut self, e: &RegexpInstr) -> Result<()> {
31516 self.write_keyword("REGEXP_INSTR");
31518 self.write("(");
31519 self.generate_expression(&e.this)?;
31520 self.write(", ");
31521 self.generate_expression(&e.expression)?;
31522 if let Some(position) = &e.position {
31523 self.write(", ");
31524 self.generate_expression(position)?;
31525 }
31526 if let Some(occurrence) = &e.occurrence {
31527 self.write(", ");
31528 self.generate_expression(occurrence)?;
31529 }
31530 if let Some(option) = &e.option {
31531 self.write(", ");
31532 self.generate_expression(option)?;
31533 }
31534 if let Some(parameters) = &e.parameters {
31535 self.write(", ");
31536 self.generate_expression(parameters)?;
31537 }
31538 if let Some(group) = &e.group {
31539 self.write(", ");
31540 self.generate_expression(group)?;
31541 }
31542 self.write(")");
31543 Ok(())
31544 }
31545
31546 fn generate_regexp_split(&mut self, e: &RegexpSplit) -> Result<()> {
31547 self.write_keyword("REGEXP_SPLIT");
31549 self.write("(");
31550 self.generate_expression(&e.this)?;
31551 self.write(", ");
31552 self.generate_expression(&e.expression)?;
31553 if let Some(limit) = &e.limit {
31554 self.write(", ");
31555 self.generate_expression(limit)?;
31556 }
31557 self.write(")");
31558 Ok(())
31559 }
31560
31561 fn generate_regr_avgx(&mut self, e: &RegrAvgx) -> Result<()> {
31562 self.write_keyword("REGR_AVGX");
31564 self.write("(");
31565 self.generate_expression(&e.this)?;
31566 self.write(", ");
31567 self.generate_expression(&e.expression)?;
31568 self.write(")");
31569 Ok(())
31570 }
31571
31572 fn generate_regr_avgy(&mut self, e: &RegrAvgy) -> Result<()> {
31573 self.write_keyword("REGR_AVGY");
31575 self.write("(");
31576 self.generate_expression(&e.this)?;
31577 self.write(", ");
31578 self.generate_expression(&e.expression)?;
31579 self.write(")");
31580 Ok(())
31581 }
31582
31583 fn generate_regr_count(&mut self, e: &RegrCount) -> Result<()> {
31584 self.write_keyword("REGR_COUNT");
31586 self.write("(");
31587 self.generate_expression(&e.this)?;
31588 self.write(", ");
31589 self.generate_expression(&e.expression)?;
31590 self.write(")");
31591 Ok(())
31592 }
31593
31594 fn generate_regr_intercept(&mut self, e: &RegrIntercept) -> Result<()> {
31595 self.write_keyword("REGR_INTERCEPT");
31597 self.write("(");
31598 self.generate_expression(&e.this)?;
31599 self.write(", ");
31600 self.generate_expression(&e.expression)?;
31601 self.write(")");
31602 Ok(())
31603 }
31604
31605 fn generate_regr_r2(&mut self, e: &RegrR2) -> Result<()> {
31606 self.write_keyword("REGR_R2");
31608 self.write("(");
31609 self.generate_expression(&e.this)?;
31610 self.write(", ");
31611 self.generate_expression(&e.expression)?;
31612 self.write(")");
31613 Ok(())
31614 }
31615
31616 fn generate_regr_slope(&mut self, e: &RegrSlope) -> Result<()> {
31617 self.write_keyword("REGR_SLOPE");
31619 self.write("(");
31620 self.generate_expression(&e.this)?;
31621 self.write(", ");
31622 self.generate_expression(&e.expression)?;
31623 self.write(")");
31624 Ok(())
31625 }
31626
31627 fn generate_regr_sxx(&mut self, e: &RegrSxx) -> Result<()> {
31628 self.write_keyword("REGR_SXX");
31630 self.write("(");
31631 self.generate_expression(&e.this)?;
31632 self.write(", ");
31633 self.generate_expression(&e.expression)?;
31634 self.write(")");
31635 Ok(())
31636 }
31637
31638 fn generate_regr_sxy(&mut self, e: &RegrSxy) -> Result<()> {
31639 self.write_keyword("REGR_SXY");
31641 self.write("(");
31642 self.generate_expression(&e.this)?;
31643 self.write(", ");
31644 self.generate_expression(&e.expression)?;
31645 self.write(")");
31646 Ok(())
31647 }
31648
31649 fn generate_regr_syy(&mut self, e: &RegrSyy) -> Result<()> {
31650 self.write_keyword("REGR_SYY");
31652 self.write("(");
31653 self.generate_expression(&e.this)?;
31654 self.write(", ");
31655 self.generate_expression(&e.expression)?;
31656 self.write(")");
31657 Ok(())
31658 }
31659
31660 fn generate_regr_valx(&mut self, e: &RegrValx) -> Result<()> {
31661 self.write_keyword("REGR_VALX");
31663 self.write("(");
31664 self.generate_expression(&e.this)?;
31665 self.write(", ");
31666 self.generate_expression(&e.expression)?;
31667 self.write(")");
31668 Ok(())
31669 }
31670
31671 fn generate_regr_valy(&mut self, e: &RegrValy) -> Result<()> {
31672 self.write_keyword("REGR_VALY");
31674 self.write("(");
31675 self.generate_expression(&e.this)?;
31676 self.write(", ");
31677 self.generate_expression(&e.expression)?;
31678 self.write(")");
31679 Ok(())
31680 }
31681
31682 fn generate_remote_with_connection_model_property(
31683 &mut self,
31684 e: &RemoteWithConnectionModelProperty,
31685 ) -> Result<()> {
31686 self.write_keyword("REMOTE WITH CONNECTION");
31688 self.write_space();
31689 self.generate_expression(&e.this)?;
31690 Ok(())
31691 }
31692
31693 fn generate_rename_column(&mut self, e: &RenameColumn) -> Result<()> {
31694 self.write_keyword("RENAME COLUMN");
31696 if e.exists {
31697 self.write_space();
31698 self.write_keyword("IF EXISTS");
31699 }
31700 self.write_space();
31701 self.generate_expression(&e.this)?;
31702 if let Some(to) = &e.to {
31703 self.write_space();
31704 self.write_keyword("TO");
31705 self.write_space();
31706 self.generate_expression(to)?;
31707 }
31708 Ok(())
31709 }
31710
31711 fn generate_replace_partition(&mut self, e: &ReplacePartition) -> Result<()> {
31712 self.write_keyword("REPLACE PARTITION");
31714 self.write_space();
31715 self.generate_expression(&e.expression)?;
31716 if let Some(source) = &e.source {
31717 self.write_space();
31718 self.write_keyword("FROM");
31719 self.write_space();
31720 self.generate_expression(source)?;
31721 }
31722 Ok(())
31723 }
31724
31725 fn generate_returning(&mut self, e: &Returning) -> Result<()> {
31726 let keyword = match self.config.dialect {
31729 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "OUTPUT",
31730 _ => "RETURNING",
31731 };
31732 self.write_keyword(keyword);
31733 self.write_space();
31734 for (i, expr) in e.expressions.iter().enumerate() {
31735 if i > 0 {
31736 self.write(", ");
31737 }
31738 self.generate_expression(expr)?;
31739 }
31740 if let Some(into) = &e.into {
31741 self.write_space();
31742 self.write_keyword("INTO");
31743 self.write_space();
31744 self.generate_expression(into)?;
31745 }
31746 Ok(())
31747 }
31748
31749 fn generate_output_clause(&mut self, output: &OutputClause) -> Result<()> {
31750 self.write_space();
31752 self.write_keyword("OUTPUT");
31753 self.write_space();
31754 for (i, expr) in output.columns.iter().enumerate() {
31755 if i > 0 {
31756 self.write(", ");
31757 }
31758 self.generate_expression(expr)?;
31759 }
31760 if let Some(into_table) = &output.into_table {
31761 self.write_space();
31762 self.write_keyword("INTO");
31763 self.write_space();
31764 self.generate_expression(into_table)?;
31765 }
31766 Ok(())
31767 }
31768
31769 fn generate_returns_property(&mut self, e: &ReturnsProperty) -> Result<()> {
31770 self.write_keyword("RETURNS");
31772 if e.is_table.is_some() {
31773 self.write_space();
31774 self.write_keyword("TABLE");
31775 }
31776 if let Some(table) = &e.table {
31777 self.write_space();
31778 self.generate_expression(table)?;
31779 } else if let Some(this) = &e.this {
31780 self.write_space();
31781 self.generate_expression(this)?;
31782 }
31783 if e.null.is_some() {
31784 self.write_space();
31785 self.write_keyword("NULL ON NULL INPUT");
31786 }
31787 Ok(())
31788 }
31789
31790 fn generate_rollback(&mut self, e: &Rollback) -> Result<()> {
31791 self.write_keyword("ROLLBACK");
31793
31794 if e.this.is_none()
31796 && matches!(
31797 self.config.dialect,
31798 Some(DialectType::TSQL) | Some(DialectType::Fabric)
31799 )
31800 {
31801 self.write_space();
31802 self.write_keyword("TRANSACTION");
31803 }
31804
31805 if let Some(this) = &e.this {
31807 let is_transaction_marker = matches!(
31809 this.as_ref(),
31810 Expression::Identifier(id) if id.name == "TRANSACTION"
31811 );
31812
31813 self.write_space();
31814 self.write_keyword("TRANSACTION");
31815
31816 if !is_transaction_marker {
31818 self.write_space();
31819 self.generate_expression(this)?;
31820 }
31821 }
31822
31823 if let Some(savepoint) = &e.savepoint {
31825 self.write_space();
31826 self.write_keyword("TO");
31827 self.write_space();
31828 self.generate_expression(savepoint)?;
31829 }
31830 Ok(())
31831 }
31832
31833 fn generate_rollup(&mut self, e: &Rollup) -> Result<()> {
31834 if e.expressions.is_empty() {
31836 self.write_keyword("WITH ROLLUP");
31837 } else {
31838 self.write_keyword("ROLLUP");
31839 self.write("(");
31840 for (i, expr) in e.expressions.iter().enumerate() {
31841 if i > 0 {
31842 self.write(", ");
31843 }
31844 self.generate_expression(expr)?;
31845 }
31846 self.write(")");
31847 }
31848 Ok(())
31849 }
31850
31851 fn generate_row_format_delimited_property(
31852 &mut self,
31853 e: &RowFormatDelimitedProperty,
31854 ) -> Result<()> {
31855 self.write_keyword("ROW FORMAT DELIMITED");
31857 if let Some(fields) = &e.fields {
31858 self.write_space();
31859 self.write_keyword("FIELDS TERMINATED BY");
31860 self.write_space();
31861 self.generate_expression(fields)?;
31862 }
31863 if let Some(escaped) = &e.escaped {
31864 self.write_space();
31865 self.write_keyword("ESCAPED BY");
31866 self.write_space();
31867 self.generate_expression(escaped)?;
31868 }
31869 if let Some(items) = &e.collection_items {
31870 self.write_space();
31871 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
31872 self.write_space();
31873 self.generate_expression(items)?;
31874 }
31875 if let Some(keys) = &e.map_keys {
31876 self.write_space();
31877 self.write_keyword("MAP KEYS TERMINATED BY");
31878 self.write_space();
31879 self.generate_expression(keys)?;
31880 }
31881 if let Some(lines) = &e.lines {
31882 self.write_space();
31883 self.write_keyword("LINES TERMINATED BY");
31884 self.write_space();
31885 self.generate_expression(lines)?;
31886 }
31887 if let Some(null) = &e.null {
31888 self.write_space();
31889 self.write_keyword("NULL DEFINED AS");
31890 self.write_space();
31891 self.generate_expression(null)?;
31892 }
31893 if let Some(serde) = &e.serde {
31894 self.write_space();
31895 self.generate_expression(serde)?;
31896 }
31897 Ok(())
31898 }
31899
31900 fn generate_row_format_property(&mut self, e: &RowFormatProperty) -> Result<()> {
31901 self.write_keyword("ROW FORMAT");
31903 self.write_space();
31904 self.generate_expression(&e.this)?;
31905 Ok(())
31906 }
31907
31908 fn generate_row_format_serde_property(&mut self, e: &RowFormatSerdeProperty) -> Result<()> {
31909 self.write_keyword("ROW FORMAT SERDE");
31911 self.write_space();
31912 self.generate_expression(&e.this)?;
31913 if let Some(props) = &e.serde_properties {
31914 self.write_space();
31915 self.generate_expression(props)?;
31917 }
31918 Ok(())
31919 }
31920
31921 fn generate_sha2(&mut self, e: &SHA2) -> Result<()> {
31922 self.write_keyword("SHA2");
31924 self.write("(");
31925 self.generate_expression(&e.this)?;
31926 if let Some(length) = e.length {
31927 self.write(", ");
31928 self.write(&length.to_string());
31929 }
31930 self.write(")");
31931 Ok(())
31932 }
31933
31934 fn generate_sha2_digest(&mut self, e: &SHA2Digest) -> Result<()> {
31935 self.write_keyword("SHA2_DIGEST");
31937 self.write("(");
31938 self.generate_expression(&e.this)?;
31939 if let Some(length) = e.length {
31940 self.write(", ");
31941 self.write(&length.to_string());
31942 }
31943 self.write(")");
31944 Ok(())
31945 }
31946
31947 fn generate_safe_add(&mut self, e: &SafeAdd) -> Result<()> {
31948 let name = if matches!(
31949 self.config.dialect,
31950 Some(crate::dialects::DialectType::Spark)
31951 | Some(crate::dialects::DialectType::Databricks)
31952 ) {
31953 "TRY_ADD"
31954 } else {
31955 "SAFE_ADD"
31956 };
31957 self.write_keyword(name);
31958 self.write("(");
31959 self.generate_expression(&e.this)?;
31960 self.write(", ");
31961 self.generate_expression(&e.expression)?;
31962 self.write(")");
31963 Ok(())
31964 }
31965
31966 fn generate_safe_divide(&mut self, e: &SafeDivide) -> Result<()> {
31967 self.write_keyword("SAFE_DIVIDE");
31969 self.write("(");
31970 self.generate_expression(&e.this)?;
31971 self.write(", ");
31972 self.generate_expression(&e.expression)?;
31973 self.write(")");
31974 Ok(())
31975 }
31976
31977 fn generate_safe_multiply(&mut self, e: &SafeMultiply) -> Result<()> {
31978 let name = if matches!(
31979 self.config.dialect,
31980 Some(crate::dialects::DialectType::Spark)
31981 | Some(crate::dialects::DialectType::Databricks)
31982 ) {
31983 "TRY_MULTIPLY"
31984 } else {
31985 "SAFE_MULTIPLY"
31986 };
31987 self.write_keyword(name);
31988 self.write("(");
31989 self.generate_expression(&e.this)?;
31990 self.write(", ");
31991 self.generate_expression(&e.expression)?;
31992 self.write(")");
31993 Ok(())
31994 }
31995
31996 fn generate_safe_subtract(&mut self, e: &SafeSubtract) -> Result<()> {
31997 let name = if matches!(
31998 self.config.dialect,
31999 Some(crate::dialects::DialectType::Spark)
32000 | Some(crate::dialects::DialectType::Databricks)
32001 ) {
32002 "TRY_SUBTRACT"
32003 } else {
32004 "SAFE_SUBTRACT"
32005 };
32006 self.write_keyword(name);
32007 self.write("(");
32008 self.generate_expression(&e.this)?;
32009 self.write(", ");
32010 self.generate_expression(&e.expression)?;
32011 self.write(")");
32012 Ok(())
32013 }
32014
32015 fn generate_sample_body(&mut self, sample: &Sample) -> Result<()> {
32018 if matches!(sample.method, SampleMethod::Bucket) {
32020 self.write(" (");
32021 self.write_keyword("BUCKET");
32022 self.write_space();
32023 if let Some(ref num) = sample.bucket_numerator {
32024 self.generate_expression(num)?;
32025 }
32026 self.write_space();
32027 self.write_keyword("OUT OF");
32028 self.write_space();
32029 if let Some(ref denom) = sample.bucket_denominator {
32030 self.generate_expression(denom)?;
32031 }
32032 if let Some(ref field) = sample.bucket_field {
32033 self.write_space();
32034 self.write_keyword("ON");
32035 self.write_space();
32036 self.generate_expression(field)?;
32037 }
32038 self.write(")");
32039 return Ok(());
32040 }
32041
32042 let is_snowflake = matches!(
32044 self.config.dialect,
32045 Some(crate::dialects::DialectType::Snowflake)
32046 );
32047 let is_postgres = matches!(
32048 self.config.dialect,
32049 Some(crate::dialects::DialectType::PostgreSQL)
32050 | Some(crate::dialects::DialectType::Redshift)
32051 );
32052 let is_databricks = matches!(
32054 self.config.dialect,
32055 Some(crate::dialects::DialectType::Databricks)
32056 );
32057 let is_spark = matches!(
32058 self.config.dialect,
32059 Some(crate::dialects::DialectType::Spark)
32060 );
32061 let suppress_method = is_databricks || is_spark || sample.suppress_method_output;
32062 let force_method = is_postgres && matches!(sample.method, SampleMethod::Bernoulli);
32064 if !suppress_method && (sample.explicit_method || is_snowflake || force_method) {
32065 self.write_space();
32066 if !sample.explicit_method && (is_snowflake || force_method) {
32067 self.write_keyword("BERNOULLI");
32069 } else {
32070 match sample.method {
32071 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
32072 SampleMethod::System => self.write_keyword("SYSTEM"),
32073 SampleMethod::Block => self.write_keyword("BLOCK"),
32074 SampleMethod::Row => self.write_keyword("ROW"),
32075 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
32076 SampleMethod::Percent => self.write_keyword("SYSTEM"),
32077 SampleMethod::Bucket => {} }
32079 }
32080 }
32081
32082 let emit_size_no_parens = !self.config.tablesample_requires_parens;
32084 if emit_size_no_parens {
32085 self.write_space();
32086 match &sample.size {
32087 Expression::Tuple(tuple) => {
32088 for (i, expr) in tuple.expressions.iter().enumerate() {
32089 if i > 0 {
32090 self.write(", ");
32091 }
32092 self.generate_expression(expr)?;
32093 }
32094 }
32095 expr => self.generate_expression(expr)?,
32096 }
32097 } else {
32098 self.write(" (");
32099 self.generate_expression(&sample.size)?;
32100 }
32101
32102 let is_rows_method = matches!(
32104 sample.method,
32105 SampleMethod::Reservoir | SampleMethod::Row | SampleMethod::Bucket
32106 );
32107 let is_percent = matches!(
32108 sample.method,
32109 SampleMethod::Percent
32110 | SampleMethod::System
32111 | SampleMethod::Bernoulli
32112 | SampleMethod::Block
32113 );
32114
32115 let is_presto = matches!(
32119 self.config.dialect,
32120 Some(crate::dialects::DialectType::Presto)
32121 | Some(crate::dialects::DialectType::Trino)
32122 | Some(crate::dialects::DialectType::Athena)
32123 );
32124 let should_output_unit = if is_databricks || is_spark {
32125 is_percent || is_rows_method || sample.unit_after_size
32127 } else if is_snowflake || is_postgres || is_presto {
32128 sample.unit_after_size
32129 } else {
32130 sample.unit_after_size || (sample.explicit_method && (is_rows_method || is_percent))
32131 };
32132
32133 if should_output_unit {
32134 self.write_space();
32135 if sample.is_percent {
32136 self.write_keyword("PERCENT");
32137 } else if is_rows_method && !sample.unit_after_size {
32138 self.write_keyword("ROWS");
32139 } else if sample.unit_after_size {
32140 match sample.method {
32141 SampleMethod::Percent
32142 | SampleMethod::System
32143 | SampleMethod::Bernoulli
32144 | SampleMethod::Block => {
32145 self.write_keyword("PERCENT");
32146 }
32147 SampleMethod::Row | SampleMethod::Reservoir => {
32148 self.write_keyword("ROWS");
32149 }
32150 _ => self.write_keyword("ROWS"),
32151 }
32152 } else {
32153 self.write_keyword("PERCENT");
32154 }
32155 }
32156
32157 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
32158 if let Some(ref offset) = sample.offset {
32159 self.write_space();
32160 self.write_keyword("OFFSET");
32161 self.write_space();
32162 self.generate_expression(offset)?;
32163 }
32164 }
32165 if !emit_size_no_parens {
32166 self.write(")");
32167 }
32168
32169 Ok(())
32170 }
32171
32172 fn generate_sample_property(&mut self, e: &SampleProperty) -> Result<()> {
32173 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
32175 self.write_keyword("SAMPLE BY");
32176 } else {
32177 self.write_keyword("SAMPLE");
32178 }
32179 self.write_space();
32180 self.generate_expression(&e.this)?;
32181 Ok(())
32182 }
32183
32184 fn generate_schema(&mut self, e: &Schema) -> Result<()> {
32185 if let Some(this) = &e.this {
32187 self.generate_expression(this)?;
32188 }
32189 if !e.expressions.is_empty() {
32190 if e.this.is_some() {
32192 self.write_space();
32193 }
32194 self.write("(");
32195 for (i, expr) in e.expressions.iter().enumerate() {
32196 if i > 0 {
32197 self.write(", ");
32198 }
32199 self.generate_expression(expr)?;
32200 }
32201 self.write(")");
32202 }
32203 Ok(())
32204 }
32205
32206 fn generate_schema_comment_property(&mut self, e: &SchemaCommentProperty) -> Result<()> {
32207 self.write_keyword("COMMENT");
32209 self.write_space();
32210 self.generate_expression(&e.this)?;
32211 Ok(())
32212 }
32213
32214 fn generate_scope_resolution(&mut self, e: &ScopeResolution) -> Result<()> {
32215 if let Some(this) = &e.this {
32217 self.generate_expression(this)?;
32218 self.write("::");
32219 }
32220 self.generate_expression(&e.expression)?;
32221 Ok(())
32222 }
32223
32224 fn generate_search(&mut self, e: &Search) -> Result<()> {
32225 self.write_keyword("SEARCH");
32227 self.write("(");
32228 self.generate_expression(&e.this)?;
32229 self.write(", ");
32230 self.generate_expression(&e.expression)?;
32231 if let Some(json_scope) = &e.json_scope {
32232 self.write(", ");
32233 self.generate_expression(json_scope)?;
32234 }
32235 if let Some(analyzer) = &e.analyzer {
32236 self.write(", ");
32237 self.generate_expression(analyzer)?;
32238 }
32239 if let Some(analyzer_options) = &e.analyzer_options {
32240 self.write(", ");
32241 self.generate_expression(analyzer_options)?;
32242 }
32243 if let Some(search_mode) = &e.search_mode {
32244 self.write(", ");
32245 self.generate_expression(search_mode)?;
32246 }
32247 self.write(")");
32248 Ok(())
32249 }
32250
32251 fn generate_search_ip(&mut self, e: &SearchIp) -> Result<()> {
32252 self.write_keyword("SEARCH_IP");
32254 self.write("(");
32255 self.generate_expression(&e.this)?;
32256 self.write(", ");
32257 self.generate_expression(&e.expression)?;
32258 self.write(")");
32259 Ok(())
32260 }
32261
32262 fn generate_security_property(&mut self, e: &SecurityProperty) -> Result<()> {
32263 self.write_keyword("SECURITY");
32265 self.write_space();
32266 self.generate_expression(&e.this)?;
32267 Ok(())
32268 }
32269
32270 fn generate_semantic_view(&mut self, e: &SemanticView) -> Result<()> {
32271 self.write("SEMANTIC_VIEW(");
32273
32274 if self.config.pretty {
32275 self.write_newline();
32277 self.indent_level += 1;
32278 self.write_indent();
32279 self.generate_expression(&e.this)?;
32280
32281 if let Some(metrics) = &e.metrics {
32282 self.write_newline();
32283 self.write_indent();
32284 self.write_keyword("METRICS");
32285 self.write_space();
32286 self.generate_semantic_view_tuple(metrics)?;
32287 }
32288 if let Some(dimensions) = &e.dimensions {
32289 self.write_newline();
32290 self.write_indent();
32291 self.write_keyword("DIMENSIONS");
32292 self.write_space();
32293 self.generate_semantic_view_tuple(dimensions)?;
32294 }
32295 if let Some(facts) = &e.facts {
32296 self.write_newline();
32297 self.write_indent();
32298 self.write_keyword("FACTS");
32299 self.write_space();
32300 self.generate_semantic_view_tuple(facts)?;
32301 }
32302 if let Some(where_) = &e.where_ {
32303 self.write_newline();
32304 self.write_indent();
32305 self.write_keyword("WHERE");
32306 self.write_space();
32307 self.generate_expression(where_)?;
32308 }
32309 self.write_newline();
32310 self.indent_level -= 1;
32311 self.write_indent();
32312 } else {
32313 self.generate_expression(&e.this)?;
32315 if let Some(metrics) = &e.metrics {
32316 self.write_space();
32317 self.write_keyword("METRICS");
32318 self.write_space();
32319 self.generate_semantic_view_tuple(metrics)?;
32320 }
32321 if let Some(dimensions) = &e.dimensions {
32322 self.write_space();
32323 self.write_keyword("DIMENSIONS");
32324 self.write_space();
32325 self.generate_semantic_view_tuple(dimensions)?;
32326 }
32327 if let Some(facts) = &e.facts {
32328 self.write_space();
32329 self.write_keyword("FACTS");
32330 self.write_space();
32331 self.generate_semantic_view_tuple(facts)?;
32332 }
32333 if let Some(where_) = &e.where_ {
32334 self.write_space();
32335 self.write_keyword("WHERE");
32336 self.write_space();
32337 self.generate_expression(where_)?;
32338 }
32339 }
32340 self.write(")");
32341 Ok(())
32342 }
32343
32344 fn generate_semantic_view_tuple(&mut self, expr: &Expression) -> Result<()> {
32346 if let Expression::Tuple(t) = expr {
32347 for (i, e) in t.expressions.iter().enumerate() {
32348 if i > 0 {
32349 self.write(", ");
32350 }
32351 self.generate_expression(e)?;
32352 }
32353 } else {
32354 self.generate_expression(expr)?;
32355 }
32356 Ok(())
32357 }
32358
32359 fn generate_sequence_properties(&mut self, e: &SequenceProperties) -> Result<()> {
32360 if let Some(start) = &e.start {
32362 self.write_keyword("START WITH");
32363 self.write_space();
32364 self.generate_expression(start)?;
32365 }
32366 if let Some(increment) = &e.increment {
32367 self.write_space();
32368 self.write_keyword("INCREMENT BY");
32369 self.write_space();
32370 self.generate_expression(increment)?;
32371 }
32372 if let Some(minvalue) = &e.minvalue {
32373 self.write_space();
32374 self.write_keyword("MINVALUE");
32375 self.write_space();
32376 self.generate_expression(minvalue)?;
32377 }
32378 if let Some(maxvalue) = &e.maxvalue {
32379 self.write_space();
32380 self.write_keyword("MAXVALUE");
32381 self.write_space();
32382 self.generate_expression(maxvalue)?;
32383 }
32384 if let Some(cache) = &e.cache {
32385 self.write_space();
32386 self.write_keyword("CACHE");
32387 self.write_space();
32388 self.generate_expression(cache)?;
32389 }
32390 if let Some(owned) = &e.owned {
32391 self.write_space();
32392 self.write_keyword("OWNED BY");
32393 self.write_space();
32394 self.generate_expression(owned)?;
32395 }
32396 for opt in &e.options {
32397 self.write_space();
32398 self.generate_expression(opt)?;
32399 }
32400 Ok(())
32401 }
32402
32403 fn generate_serde_properties(&mut self, e: &SerdeProperties) -> Result<()> {
32404 if e.with_.is_some() {
32406 self.write_keyword("WITH");
32407 self.write_space();
32408 }
32409 self.write_keyword("SERDEPROPERTIES");
32410 self.write(" (");
32411 for (i, expr) in e.expressions.iter().enumerate() {
32412 if i > 0 {
32413 self.write(", ");
32414 }
32415 match expr {
32417 Expression::Eq(eq) => {
32418 self.generate_expression(&eq.left)?;
32419 self.write("=");
32420 self.generate_expression(&eq.right)?;
32421 }
32422 _ => self.generate_expression(expr)?,
32423 }
32424 }
32425 self.write(")");
32426 Ok(())
32427 }
32428
32429 fn generate_session_parameter(&mut self, e: &SessionParameter) -> Result<()> {
32430 self.write("@@");
32432 if let Some(kind) = &e.kind {
32433 self.write(kind);
32434 self.write(".");
32435 }
32436 self.generate_expression(&e.this)?;
32437 Ok(())
32438 }
32439
32440 fn generate_set(&mut self, e: &Set) -> Result<()> {
32441 if e.unset.is_some() {
32443 self.write_keyword("UNSET");
32444 } else {
32445 self.write_keyword("SET");
32446 }
32447 if e.tag.is_some() {
32448 self.write_space();
32449 self.write_keyword("TAG");
32450 }
32451 if !e.expressions.is_empty() {
32452 self.write_space();
32453 for (i, expr) in e.expressions.iter().enumerate() {
32454 if i > 0 {
32455 self.write(", ");
32456 }
32457 self.generate_expression(expr)?;
32458 }
32459 }
32460 Ok(())
32461 }
32462
32463 fn generate_set_config_property(&mut self, e: &SetConfigProperty) -> Result<()> {
32464 self.write_keyword("SET");
32466 self.write_space();
32467 self.generate_expression(&e.this)?;
32468 Ok(())
32469 }
32470
32471 fn generate_set_item(&mut self, e: &SetItem) -> Result<()> {
32472 if let Some(kind) = &e.kind {
32474 self.write_keyword(kind);
32475 self.write_space();
32476 }
32477 self.generate_expression(&e.name)?;
32478 self.write(" = ");
32479 self.generate_expression(&e.value)?;
32480 Ok(())
32481 }
32482
32483 fn generate_set_operation(&mut self, e: &SetOperation) -> Result<()> {
32484 if let Some(with_) = &e.with_ {
32486 self.generate_expression(with_)?;
32487 self.write_space();
32488 }
32489 self.generate_expression(&e.this)?;
32490 self.write_space();
32491 if let Some(kind) = &e.kind {
32493 self.write_keyword(kind);
32494 }
32495 if e.distinct {
32496 self.write_space();
32497 self.write_keyword("DISTINCT");
32498 } else {
32499 self.write_space();
32500 self.write_keyword("ALL");
32501 }
32502 if e.by_name.is_some() {
32503 self.write_space();
32504 self.write_keyword("BY NAME");
32505 }
32506 self.write_space();
32507 self.generate_expression(&e.expression)?;
32508 Ok(())
32509 }
32510
32511 fn generate_set_property(&mut self, e: &SetProperty) -> Result<()> {
32512 if e.multi.is_some() {
32514 self.write_keyword("MULTISET");
32515 } else {
32516 self.write_keyword("SET");
32517 }
32518 Ok(())
32519 }
32520
32521 fn generate_settings_property(&mut self, e: &SettingsProperty) -> Result<()> {
32522 self.write_keyword("SETTINGS");
32524 if self.config.pretty && e.expressions.len() > 1 {
32525 self.indent_level += 1;
32527 for (i, expr) in e.expressions.iter().enumerate() {
32528 if i > 0 {
32529 self.write(",");
32530 }
32531 self.write_newline();
32532 self.write_indent();
32533 self.generate_expression(expr)?;
32534 }
32535 self.indent_level -= 1;
32536 } else {
32537 self.write_space();
32538 for (i, expr) in e.expressions.iter().enumerate() {
32539 if i > 0 {
32540 self.write(", ");
32541 }
32542 self.generate_expression(expr)?;
32543 }
32544 }
32545 Ok(())
32546 }
32547
32548 fn generate_sharing_property(&mut self, e: &SharingProperty) -> Result<()> {
32549 self.write_keyword("SHARING");
32551 if let Some(this) = &e.this {
32552 self.write(" = ");
32553 self.generate_expression(this)?;
32554 }
32555 Ok(())
32556 }
32557
32558 fn generate_slice(&mut self, e: &Slice) -> Result<()> {
32559 if let Some(begin) = &e.this {
32561 self.generate_expression(begin)?;
32562 }
32563 self.write(":");
32564 if let Some(end) = &e.expression {
32565 self.generate_expression(end)?;
32566 }
32567 if let Some(step) = &e.step {
32568 self.write(":");
32569 self.generate_expression(step)?;
32570 }
32571 Ok(())
32572 }
32573
32574 fn generate_sort_array(&mut self, e: &SortArray) -> Result<()> {
32575 self.write_keyword("SORT_ARRAY");
32577 self.write("(");
32578 self.generate_expression(&e.this)?;
32579 if let Some(asc) = &e.asc {
32580 self.write(", ");
32581 self.generate_expression(asc)?;
32582 }
32583 self.write(")");
32584 Ok(())
32585 }
32586
32587 fn generate_sort_by(&mut self, e: &SortBy) -> Result<()> {
32588 self.write_keyword("SORT BY");
32590 self.write_space();
32591 for (i, expr) in e.expressions.iter().enumerate() {
32592 if i > 0 {
32593 self.write(", ");
32594 }
32595 self.generate_ordered(expr)?;
32596 }
32597 Ok(())
32598 }
32599
32600 fn generate_sort_key_property(&mut self, e: &SortKeyProperty) -> Result<()> {
32601 if e.compound.is_some() {
32603 self.write_keyword("COMPOUND");
32604 self.write_space();
32605 }
32606 self.write_keyword("SORTKEY");
32607 self.write("(");
32608 if let Expression::Tuple(t) = e.this.as_ref() {
32610 for (i, expr) in t.expressions.iter().enumerate() {
32611 if i > 0 {
32612 self.write(", ");
32613 }
32614 self.generate_expression(expr)?;
32615 }
32616 } else {
32617 self.generate_expression(&e.this)?;
32618 }
32619 self.write(")");
32620 Ok(())
32621 }
32622
32623 fn generate_split_part(&mut self, e: &SplitPart) -> Result<()> {
32624 self.write_keyword("SPLIT_PART");
32626 self.write("(");
32627 self.generate_expression(&e.this)?;
32628 if let Some(delimiter) = &e.delimiter {
32629 self.write(", ");
32630 self.generate_expression(delimiter)?;
32631 }
32632 if let Some(part_index) = &e.part_index {
32633 self.write(", ");
32634 self.generate_expression(part_index)?;
32635 }
32636 self.write(")");
32637 Ok(())
32638 }
32639
32640 fn generate_sql_read_write_property(&mut self, e: &SqlReadWriteProperty) -> Result<()> {
32641 self.generate_expression(&e.this)?;
32643 Ok(())
32644 }
32645
32646 fn generate_sql_security_property(&mut self, e: &SqlSecurityProperty) -> Result<()> {
32647 self.write_keyword("SQL SECURITY");
32649 self.write_space();
32650 self.generate_expression(&e.this)?;
32651 Ok(())
32652 }
32653
32654 fn generate_st_distance(&mut self, e: &StDistance) -> Result<()> {
32655 self.write_keyword("ST_DISTANCE");
32657 self.write("(");
32658 self.generate_expression(&e.this)?;
32659 self.write(", ");
32660 self.generate_expression(&e.expression)?;
32661 if let Some(use_spheroid) = &e.use_spheroid {
32662 self.write(", ");
32663 self.generate_expression(use_spheroid)?;
32664 }
32665 self.write(")");
32666 Ok(())
32667 }
32668
32669 fn generate_st_point(&mut self, e: &StPoint) -> Result<()> {
32670 self.write_keyword("ST_POINT");
32672 self.write("(");
32673 self.generate_expression(&e.this)?;
32674 self.write(", ");
32675 self.generate_expression(&e.expression)?;
32676 self.write(")");
32677 Ok(())
32678 }
32679
32680 fn generate_stability_property(&mut self, e: &StabilityProperty) -> Result<()> {
32681 self.generate_expression(&e.this)?;
32683 Ok(())
32684 }
32685
32686 fn generate_standard_hash(&mut self, e: &StandardHash) -> Result<()> {
32687 self.write_keyword("STANDARD_HASH");
32689 self.write("(");
32690 self.generate_expression(&e.this)?;
32691 if let Some(expression) = &e.expression {
32692 self.write(", ");
32693 self.generate_expression(expression)?;
32694 }
32695 self.write(")");
32696 Ok(())
32697 }
32698
32699 fn generate_storage_handler_property(&mut self, e: &StorageHandlerProperty) -> Result<()> {
32700 self.write_keyword("STORED BY");
32702 self.write_space();
32703 self.generate_expression(&e.this)?;
32704 Ok(())
32705 }
32706
32707 fn generate_str_position(&mut self, e: &StrPosition) -> Result<()> {
32708 use crate::dialects::DialectType;
32711 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
32712 self.write_keyword("CHARINDEX");
32714 self.write("(");
32715 if let Some(substr) = &e.substr {
32716 self.generate_expression(substr)?;
32717 self.write(", ");
32718 }
32719 self.generate_expression(&e.this)?;
32720 if let Some(position) = &e.position {
32721 self.write(", ");
32722 self.generate_expression(position)?;
32723 }
32724 self.write(")");
32725 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
32726 self.write_keyword("POSITION");
32727 self.write("(");
32728 self.generate_expression(&e.this)?;
32729 if let Some(substr) = &e.substr {
32730 self.write(", ");
32731 self.generate_expression(substr)?;
32732 }
32733 if let Some(position) = &e.position {
32734 self.write(", ");
32735 self.generate_expression(position)?;
32736 }
32737 if let Some(occurrence) = &e.occurrence {
32738 self.write(", ");
32739 self.generate_expression(occurrence)?;
32740 }
32741 self.write(")");
32742 } else if matches!(
32743 self.config.dialect,
32744 Some(DialectType::SQLite)
32745 | Some(DialectType::Oracle)
32746 | Some(DialectType::BigQuery)
32747 | Some(DialectType::Teradata)
32748 ) {
32749 self.write_keyword("INSTR");
32750 self.write("(");
32751 self.generate_expression(&e.this)?;
32752 if let Some(substr) = &e.substr {
32753 self.write(", ");
32754 self.generate_expression(substr)?;
32755 }
32756 if let Some(position) = &e.position {
32757 self.write(", ");
32758 self.generate_expression(position)?;
32759 } else if e.occurrence.is_some() {
32760 self.write(", 1");
32763 }
32764 if let Some(occurrence) = &e.occurrence {
32765 self.write(", ");
32766 self.generate_expression(occurrence)?;
32767 }
32768 self.write(")");
32769 } else if matches!(
32770 self.config.dialect,
32771 Some(DialectType::MySQL)
32772 | Some(DialectType::SingleStore)
32773 | Some(DialectType::Doris)
32774 | Some(DialectType::StarRocks)
32775 | Some(DialectType::Hive)
32776 | Some(DialectType::Spark)
32777 | Some(DialectType::Databricks)
32778 ) {
32779 self.write_keyword("LOCATE");
32781 self.write("(");
32782 if let Some(substr) = &e.substr {
32783 self.generate_expression(substr)?;
32784 self.write(", ");
32785 }
32786 self.generate_expression(&e.this)?;
32787 if let Some(position) = &e.position {
32788 self.write(", ");
32789 self.generate_expression(position)?;
32790 }
32791 self.write(")");
32792 } else if matches!(self.config.dialect, Some(DialectType::TSQL)) {
32793 self.write_keyword("CHARINDEX");
32795 self.write("(");
32796 if let Some(substr) = &e.substr {
32797 self.generate_expression(substr)?;
32798 self.write(", ");
32799 }
32800 self.generate_expression(&e.this)?;
32801 if let Some(position) = &e.position {
32802 self.write(", ");
32803 self.generate_expression(position)?;
32804 }
32805 self.write(")");
32806 } else if matches!(
32807 self.config.dialect,
32808 Some(DialectType::PostgreSQL)
32809 | Some(DialectType::Materialize)
32810 | Some(DialectType::RisingWave)
32811 | Some(DialectType::Redshift)
32812 ) {
32813 self.write_keyword("POSITION");
32815 self.write("(");
32816 if let Some(substr) = &e.substr {
32817 self.generate_expression(substr)?;
32818 self.write(" IN ");
32819 }
32820 self.generate_expression(&e.this)?;
32821 self.write(")");
32822 } else {
32823 self.write_keyword("STRPOS");
32824 self.write("(");
32825 self.generate_expression(&e.this)?;
32826 if let Some(substr) = &e.substr {
32827 self.write(", ");
32828 self.generate_expression(substr)?;
32829 }
32830 if let Some(position) = &e.position {
32831 self.write(", ");
32832 self.generate_expression(position)?;
32833 }
32834 if let Some(occurrence) = &e.occurrence {
32835 self.write(", ");
32836 self.generate_expression(occurrence)?;
32837 }
32838 self.write(")");
32839 }
32840 Ok(())
32841 }
32842
32843 fn generate_str_to_date(&mut self, e: &StrToDate) -> Result<()> {
32844 match self.config.dialect {
32845 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
32846 self.write_keyword("TO_DATE");
32848 self.write("(");
32849 self.generate_expression(&e.this)?;
32850 if let Some(format) = &e.format {
32851 self.write(", '");
32852 self.write(&Self::strftime_to_java_format(format));
32853 self.write("'");
32854 }
32855 self.write(")");
32856 }
32857 Some(DialectType::DuckDB) => {
32858 self.write_keyword("CAST");
32860 self.write("(");
32861 self.write_keyword("STRPTIME");
32862 self.write("(");
32863 self.generate_expression(&e.this)?;
32864 if let Some(format) = &e.format {
32865 self.write(", '");
32866 self.write(format);
32867 self.write("'");
32868 }
32869 self.write(")");
32870 self.write_keyword(" AS ");
32871 self.write_keyword("DATE");
32872 self.write(")");
32873 }
32874 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
32875 self.write_keyword("TO_DATE");
32877 self.write("(");
32878 self.generate_expression(&e.this)?;
32879 if let Some(format) = &e.format {
32880 self.write(", '");
32881 self.write(&Self::strftime_to_postgres_format(format));
32882 self.write("'");
32883 }
32884 self.write(")");
32885 }
32886 Some(DialectType::BigQuery) => {
32887 self.write_keyword("PARSE_DATE");
32889 self.write("(");
32890 if let Some(format) = &e.format {
32891 self.write("'");
32892 self.write(format);
32893 self.write("'");
32894 self.write(", ");
32895 }
32896 self.generate_expression(&e.this)?;
32897 self.write(")");
32898 }
32899 Some(DialectType::Teradata) => {
32900 self.write_keyword("CAST");
32902 self.write("(");
32903 self.generate_expression(&e.this)?;
32904 self.write_keyword(" AS ");
32905 self.write_keyword("DATE");
32906 if let Some(format) = &e.format {
32907 self.write_keyword(" FORMAT ");
32908 self.write("'");
32909 self.write(&Self::strftime_to_teradata_format(format));
32910 self.write("'");
32911 }
32912 self.write(")");
32913 }
32914 _ => {
32915 self.write_keyword("STR_TO_DATE");
32917 self.write("(");
32918 self.generate_expression(&e.this)?;
32919 if let Some(format) = &e.format {
32920 self.write(", '");
32921 self.write(format);
32922 self.write("'");
32923 }
32924 self.write(")");
32925 }
32926 }
32927 Ok(())
32928 }
32929
32930 fn strftime_to_teradata_format(fmt: &str) -> String {
32932 let mut result = fmt.to_string();
32933 result = result.replace("%Y", "YYYY");
32934 result = result.replace("%y", "YY");
32935 result = result.replace("%m", "MM");
32936 result = result.replace("%B", "MMMM");
32937 result = result.replace("%b", "MMM");
32938 result = result.replace("%d", "DD");
32939 result = result.replace("%j", "DDD");
32940 result = result.replace("%H", "HH");
32941 result = result.replace("%M", "MI");
32942 result = result.replace("%S", "SS");
32943 result = result.replace("%f", "SSSSSS");
32944 result = result.replace("%A", "EEEE");
32945 result = result.replace("%a", "EEE");
32946 result
32947 }
32948
32949 pub fn strftime_to_java_format_static(fmt: &str) -> String {
32952 Self::strftime_to_java_format(fmt)
32953 }
32954
32955 fn strftime_to_java_format(fmt: &str) -> String {
32957 let mut result = fmt.to_string();
32958 result = result.replace("%-d", "d");
32960 result = result.replace("%-m", "M");
32961 result = result.replace("%-H", "H");
32962 result = result.replace("%-M", "m");
32963 result = result.replace("%-S", "s");
32964 result = result.replace("%Y", "yyyy");
32965 result = result.replace("%y", "yy");
32966 result = result.replace("%m", "MM");
32967 result = result.replace("%B", "MMMM");
32968 result = result.replace("%b", "MMM");
32969 result = result.replace("%d", "dd");
32970 result = result.replace("%j", "DDD");
32971 result = result.replace("%H", "HH");
32972 result = result.replace("%M", "mm");
32973 result = result.replace("%S", "ss");
32974 result = result.replace("%f", "SSSSSS");
32975 result = result.replace("%A", "EEEE");
32976 result = result.replace("%a", "EEE");
32977 result
32978 }
32979
32980 fn strftime_to_tsql_format(fmt: &str) -> String {
32983 let mut result = fmt.to_string();
32984 result = result.replace("%-d", "d");
32986 result = result.replace("%-m", "M");
32987 result = result.replace("%-H", "H");
32988 result = result.replace("%-M", "m");
32989 result = result.replace("%-S", "s");
32990 result = result.replace("%Y", "yyyy");
32991 result = result.replace("%y", "yy");
32992 result = result.replace("%m", "MM");
32993 result = result.replace("%B", "MMMM");
32994 result = result.replace("%b", "MMM");
32995 result = result.replace("%d", "dd");
32996 result = result.replace("%j", "DDD");
32997 result = result.replace("%H", "HH");
32998 result = result.replace("%M", "mm");
32999 result = result.replace("%S", "ss");
33000 result = result.replace("%f", "ffffff");
33001 result = result.replace("%A", "dddd");
33002 result = result.replace("%a", "ddd");
33003 result
33004 }
33005
33006 fn decompose_json_path(path: &str) -> Vec<String> {
33009 let mut parts = Vec::new();
33010 let path = if path.starts_with("$.") {
33012 &path[2..]
33013 } else if path.starts_with('$') {
33014 &path[1..]
33015 } else {
33016 path
33017 };
33018 if path.is_empty() {
33019 return parts;
33020 }
33021 let mut current = String::new();
33022 let chars: Vec<char> = path.chars().collect();
33023 let mut i = 0;
33024 while i < chars.len() {
33025 match chars[i] {
33026 '.' => {
33027 if !current.is_empty() {
33028 parts.push(current.clone());
33029 current.clear();
33030 }
33031 i += 1;
33032 }
33033 '[' => {
33034 if !current.is_empty() {
33035 parts.push(current.clone());
33036 current.clear();
33037 }
33038 i += 1;
33039 let mut bracket_content = String::new();
33041 while i < chars.len() && chars[i] != ']' {
33042 if chars[i] == '"' || chars[i] == '\'' {
33044 let quote = chars[i];
33045 i += 1;
33046 while i < chars.len() && chars[i] != quote {
33047 bracket_content.push(chars[i]);
33048 i += 1;
33049 }
33050 if i < chars.len() {
33051 i += 1;
33052 } } else {
33054 bracket_content.push(chars[i]);
33055 i += 1;
33056 }
33057 }
33058 if i < chars.len() {
33059 i += 1;
33060 } if bracket_content != "*" {
33063 parts.push(bracket_content);
33064 }
33065 }
33066 _ => {
33067 current.push(chars[i]);
33068 i += 1;
33069 }
33070 }
33071 }
33072 if !current.is_empty() {
33073 parts.push(current);
33074 }
33075 parts
33076 }
33077
33078 fn strftime_to_postgres_format(fmt: &str) -> String {
33080 let mut result = fmt.to_string();
33081 result = result.replace("%-d", "FMDD");
33083 result = result.replace("%-m", "FMMM");
33084 result = result.replace("%-H", "FMHH24");
33085 result = result.replace("%-M", "FMMI");
33086 result = result.replace("%-S", "FMSS");
33087 result = result.replace("%Y", "YYYY");
33088 result = result.replace("%y", "YY");
33089 result = result.replace("%m", "MM");
33090 result = result.replace("%B", "Month");
33091 result = result.replace("%b", "Mon");
33092 result = result.replace("%d", "DD");
33093 result = result.replace("%j", "DDD");
33094 result = result.replace("%H", "HH24");
33095 result = result.replace("%M", "MI");
33096 result = result.replace("%S", "SS");
33097 result = result.replace("%f", "US");
33098 result = result.replace("%A", "Day");
33099 result = result.replace("%a", "Dy");
33100 result
33101 }
33102
33103 fn strftime_to_snowflake_format(fmt: &str) -> String {
33105 let mut result = fmt.to_string();
33106 result = result.replace("%-d", "dd");
33108 result = result.replace("%-m", "mm"); result = result.replace("%Y", "yyyy");
33110 result = result.replace("%y", "yy");
33111 result = result.replace("%m", "mm");
33112 result = result.replace("%d", "DD");
33113 result = result.replace("%H", "hh24");
33114 result = result.replace("%M", "mi");
33115 result = result.replace("%S", "ss");
33116 result = result.replace("%f", "ff");
33117 result
33118 }
33119
33120 fn generate_str_to_map(&mut self, e: &StrToMap) -> Result<()> {
33121 self.write_keyword("STR_TO_MAP");
33123 self.write("(");
33124 self.generate_expression(&e.this)?;
33125 let needs_defaults = matches!(
33127 self.config.dialect,
33128 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
33129 );
33130 if let Some(pair_delim) = &e.pair_delim {
33131 self.write(", ");
33132 self.generate_expression(pair_delim)?;
33133 } else if needs_defaults {
33134 self.write(", ','");
33135 }
33136 if let Some(key_value_delim) = &e.key_value_delim {
33137 self.write(", ");
33138 self.generate_expression(key_value_delim)?;
33139 } else if needs_defaults {
33140 self.write(", ':'");
33141 }
33142 self.write(")");
33143 Ok(())
33144 }
33145
33146 fn generate_str_to_time(&mut self, e: &StrToTime) -> Result<()> {
33147 let is_strftime = e.format.contains('%');
33149 let to_strftime = |f: &str| -> String {
33151 if is_strftime {
33152 f.to_string()
33153 } else {
33154 Self::snowflake_format_to_strftime(f)
33155 }
33156 };
33157 let to_java = |f: &str| -> String {
33159 if is_strftime {
33160 Self::strftime_to_java_format(f)
33161 } else {
33162 Self::snowflake_format_to_spark(f)
33163 }
33164 };
33165 let to_pg = |f: &str| -> String {
33167 if is_strftime {
33168 Self::strftime_to_postgres_format(f)
33169 } else {
33170 Self::convert_strptime_to_postgres_format(f)
33171 }
33172 };
33173
33174 match self.config.dialect {
33175 Some(DialectType::Exasol) => {
33176 self.write_keyword("TO_DATE");
33177 self.write("(");
33178 self.generate_expression(&e.this)?;
33179 self.write(", '");
33180 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
33181 self.write("'");
33182 self.write(")");
33183 }
33184 Some(DialectType::BigQuery) => {
33185 let fmt = to_strftime(&e.format);
33187 let fmt = fmt.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
33189 self.write_keyword("PARSE_TIMESTAMP");
33190 self.write("('");
33191 self.write(&fmt);
33192 self.write("', ");
33193 self.generate_expression(&e.this)?;
33194 self.write(")");
33195 }
33196 Some(DialectType::Hive) => {
33197 let java_fmt = to_java(&e.format);
33200 if java_fmt == "yyyy-MM-dd HH:mm:ss"
33201 || java_fmt == "yyyy-MM-dd"
33202 || e.format == "yyyy-MM-dd HH:mm:ss"
33203 || e.format == "yyyy-MM-dd"
33204 {
33205 self.write_keyword("CAST");
33206 self.write("(");
33207 self.generate_expression(&e.this)?;
33208 self.write(" ");
33209 self.write_keyword("AS TIMESTAMP");
33210 self.write(")");
33211 } else {
33212 self.write_keyword("CAST");
33214 self.write("(");
33215 self.write_keyword("FROM_UNIXTIME");
33216 self.write("(");
33217 self.write_keyword("UNIX_TIMESTAMP");
33218 self.write("(");
33219 self.generate_expression(&e.this)?;
33220 self.write(", '");
33221 self.write(&java_fmt);
33222 self.write("')");
33223 self.write(") ");
33224 self.write_keyword("AS TIMESTAMP");
33225 self.write(")");
33226 }
33227 }
33228 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
33229 let java_fmt = to_java(&e.format);
33231 self.write_keyword("TO_TIMESTAMP");
33232 self.write("(");
33233 self.generate_expression(&e.this)?;
33234 self.write(", '");
33235 self.write(&java_fmt);
33236 self.write("')");
33237 }
33238 Some(DialectType::MySQL) => {
33239 let mut fmt = to_strftime(&e.format);
33241 fmt = fmt.replace("%-d", "%e");
33243 fmt = fmt.replace("%-m", "%c");
33244 fmt = fmt.replace("%H:%M:%S", "%T");
33245 self.write_keyword("STR_TO_DATE");
33246 self.write("(");
33247 self.generate_expression(&e.this)?;
33248 self.write(", '");
33249 self.write(&fmt);
33250 self.write("')");
33251 }
33252 Some(DialectType::Drill) => {
33253 let java_fmt = to_java(&e.format);
33255 let java_fmt = java_fmt.replace('T', "''T''");
33257 self.write_keyword("TO_TIMESTAMP");
33258 self.write("(");
33259 self.generate_expression(&e.this)?;
33260 self.write(", '");
33261 self.write(&java_fmt);
33262 self.write("')");
33263 }
33264 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
33265 let mut fmt = to_strftime(&e.format);
33267 fmt = fmt.replace("%-d", "%e");
33269 fmt = fmt.replace("%-m", "%c");
33270 fmt = fmt.replace("%H:%M:%S", "%T");
33271 self.write_keyword("DATE_PARSE");
33272 self.write("(");
33273 self.generate_expression(&e.this)?;
33274 self.write(", '");
33275 self.write(&fmt);
33276 self.write("')");
33277 }
33278 Some(DialectType::DuckDB) => {
33279 let fmt = to_strftime(&e.format);
33281 self.write_keyword("STRPTIME");
33282 self.write("(");
33283 self.generate_expression(&e.this)?;
33284 self.write(", '");
33285 self.write(&fmt);
33286 self.write("')");
33287 }
33288 Some(DialectType::PostgreSQL)
33289 | Some(DialectType::Redshift)
33290 | Some(DialectType::Materialize) => {
33291 let pg_fmt = to_pg(&e.format);
33293 self.write_keyword("TO_TIMESTAMP");
33294 self.write("(");
33295 self.generate_expression(&e.this)?;
33296 self.write(", '");
33297 self.write(&pg_fmt);
33298 self.write("')");
33299 }
33300 Some(DialectType::Oracle) => {
33301 let pg_fmt = to_pg(&e.format);
33303 self.write_keyword("TO_TIMESTAMP");
33304 self.write("(");
33305 self.generate_expression(&e.this)?;
33306 self.write(", '");
33307 self.write(&pg_fmt);
33308 self.write("')");
33309 }
33310 Some(DialectType::Snowflake) => {
33311 self.write_keyword("TO_TIMESTAMP");
33313 self.write("(");
33314 self.generate_expression(&e.this)?;
33315 self.write(", '");
33316 self.write(&e.format);
33317 self.write("')");
33318 }
33319 _ => {
33320 self.write_keyword("STR_TO_TIME");
33322 self.write("(");
33323 self.generate_expression(&e.this)?;
33324 self.write(", '");
33325 self.write(&e.format);
33326 self.write("'");
33327 self.write(")");
33328 }
33329 }
33330 Ok(())
33331 }
33332
33333 fn snowflake_format_to_strftime(format: &str) -> String {
33335 let mut result = String::new();
33336 let chars: Vec<char> = format.chars().collect();
33337 let mut i = 0;
33338 while i < chars.len() {
33339 let remaining = &format[i..];
33340 if remaining.starts_with("yyyy") {
33341 result.push_str("%Y");
33342 i += 4;
33343 } else if remaining.starts_with("yy") {
33344 result.push_str("%y");
33345 i += 2;
33346 } else if remaining.starts_with("mmmm") {
33347 result.push_str("%B"); i += 4;
33349 } else if remaining.starts_with("mon") {
33350 result.push_str("%b"); i += 3;
33352 } else if remaining.starts_with("mm") {
33353 result.push_str("%m");
33354 i += 2;
33355 } else if remaining.starts_with("DD") {
33356 result.push_str("%d");
33357 i += 2;
33358 } else if remaining.starts_with("dy") {
33359 result.push_str("%a"); i += 2;
33361 } else if remaining.starts_with("hh24") {
33362 result.push_str("%H");
33363 i += 4;
33364 } else if remaining.starts_with("hh12") {
33365 result.push_str("%I");
33366 i += 4;
33367 } else if remaining.starts_with("hh") {
33368 result.push_str("%H");
33369 i += 2;
33370 } else if remaining.starts_with("mi") {
33371 result.push_str("%M");
33372 i += 2;
33373 } else if remaining.starts_with("ss") {
33374 result.push_str("%S");
33375 i += 2;
33376 } else if remaining.starts_with("ff") {
33377 result.push_str("%f");
33379 i += 2;
33380 while i < chars.len() && chars[i].is_ascii_digit() {
33382 i += 1;
33383 }
33384 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
33385 result.push_str("%p");
33386 i += 2;
33387 } else if remaining.starts_with("tz") {
33388 result.push_str("%Z");
33389 i += 2;
33390 } else {
33391 result.push(chars[i]);
33392 i += 1;
33393 }
33394 }
33395 result
33396 }
33397
33398 fn snowflake_format_to_spark(format: &str) -> String {
33400 let mut result = String::new();
33401 let chars: Vec<char> = format.chars().collect();
33402 let mut i = 0;
33403 while i < chars.len() {
33404 let remaining = &format[i..];
33405 if remaining.starts_with("yyyy") {
33406 result.push_str("yyyy");
33407 i += 4;
33408 } else if remaining.starts_with("yy") {
33409 result.push_str("yy");
33410 i += 2;
33411 } else if remaining.starts_with("mmmm") {
33412 result.push_str("MMMM"); i += 4;
33414 } else if remaining.starts_with("mon") {
33415 result.push_str("MMM"); i += 3;
33417 } else if remaining.starts_with("mm") {
33418 result.push_str("MM");
33419 i += 2;
33420 } else if remaining.starts_with("DD") {
33421 result.push_str("dd");
33422 i += 2;
33423 } else if remaining.starts_with("dy") {
33424 result.push_str("EEE"); i += 2;
33426 } else if remaining.starts_with("hh24") {
33427 result.push_str("HH");
33428 i += 4;
33429 } else if remaining.starts_with("hh12") {
33430 result.push_str("hh");
33431 i += 4;
33432 } else if remaining.starts_with("hh") {
33433 result.push_str("HH");
33434 i += 2;
33435 } else if remaining.starts_with("mi") {
33436 result.push_str("mm");
33437 i += 2;
33438 } else if remaining.starts_with("ss") {
33439 result.push_str("ss");
33440 i += 2;
33441 } else if remaining.starts_with("ff") {
33442 result.push_str("SSS"); i += 2;
33444 while i < chars.len() && chars[i].is_ascii_digit() {
33446 i += 1;
33447 }
33448 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
33449 result.push_str("a");
33450 i += 2;
33451 } else if remaining.starts_with("tz") {
33452 result.push_str("z");
33453 i += 2;
33454 } else {
33455 result.push(chars[i]);
33456 i += 1;
33457 }
33458 }
33459 result
33460 }
33461
33462 fn generate_str_to_unix(&mut self, e: &StrToUnix) -> Result<()> {
33463 match self.config.dialect {
33464 Some(DialectType::DuckDB) => {
33465 self.write_keyword("EPOCH");
33467 self.write("(");
33468 self.write_keyword("STRPTIME");
33469 self.write("(");
33470 if let Some(this) = &e.this {
33471 self.generate_expression(this)?;
33472 }
33473 if let Some(format) = &e.format {
33474 self.write(", '");
33475 self.write(format);
33476 self.write("'");
33477 }
33478 self.write("))");
33479 }
33480 Some(DialectType::Hive) => {
33481 self.write_keyword("UNIX_TIMESTAMP");
33483 self.write("(");
33484 if let Some(this) = &e.this {
33485 self.generate_expression(this)?;
33486 }
33487 if let Some(format) = &e.format {
33488 let java_fmt = Self::strftime_to_java_format(format);
33489 if java_fmt != "yyyy-MM-dd HH:mm:ss" {
33490 self.write(", '");
33491 self.write(&java_fmt);
33492 self.write("'");
33493 }
33494 }
33495 self.write(")");
33496 }
33497 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
33498 self.write_keyword("UNIX_TIMESTAMP");
33500 self.write("(");
33501 if let Some(this) = &e.this {
33502 self.generate_expression(this)?;
33503 }
33504 if let Some(format) = &e.format {
33505 self.write(", '");
33506 self.write(format);
33507 self.write("'");
33508 }
33509 self.write(")");
33510 }
33511 Some(DialectType::Presto) | Some(DialectType::Trino) => {
33512 let c_fmt = e.format.as_deref().unwrap_or("%Y-%m-%d %T");
33515 let java_fmt = Self::strftime_to_java_format(c_fmt);
33516 self.write_keyword("TO_UNIXTIME");
33517 self.write("(");
33518 self.write_keyword("COALESCE");
33519 self.write("(");
33520 self.write_keyword("TRY");
33521 self.write("(");
33522 self.write_keyword("DATE_PARSE");
33523 self.write("(");
33524 self.write_keyword("CAST");
33525 self.write("(");
33526 if let Some(this) = &e.this {
33527 self.generate_expression(this)?;
33528 }
33529 self.write(" ");
33530 self.write_keyword("AS VARCHAR");
33531 self.write("), '");
33532 self.write(c_fmt);
33533 self.write("')), ");
33534 self.write_keyword("PARSE_DATETIME");
33535 self.write("(");
33536 self.write_keyword("DATE_FORMAT");
33537 self.write("(");
33538 self.write_keyword("CAST");
33539 self.write("(");
33540 if let Some(this) = &e.this {
33541 self.generate_expression(this)?;
33542 }
33543 self.write(" ");
33544 self.write_keyword("AS TIMESTAMP");
33545 self.write("), '");
33546 self.write(c_fmt);
33547 self.write("'), '");
33548 self.write(&java_fmt);
33549 self.write("')))");
33550 }
33551 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
33552 self.write_keyword("UNIX_TIMESTAMP");
33554 self.write("(");
33555 if let Some(this) = &e.this {
33556 self.generate_expression(this)?;
33557 }
33558 if let Some(format) = &e.format {
33559 let java_fmt = Self::strftime_to_java_format(format);
33560 self.write(", '");
33561 self.write(&java_fmt);
33562 self.write("'");
33563 }
33564 self.write(")");
33565 }
33566 _ => {
33567 self.write_keyword("STR_TO_UNIX");
33569 self.write("(");
33570 if let Some(this) = &e.this {
33571 self.generate_expression(this)?;
33572 }
33573 if let Some(format) = &e.format {
33574 self.write(", '");
33575 self.write(format);
33576 self.write("'");
33577 }
33578 self.write(")");
33579 }
33580 }
33581 Ok(())
33582 }
33583
33584 fn generate_string_to_array(&mut self, e: &StringToArray) -> Result<()> {
33585 self.write_keyword("STRING_TO_ARRAY");
33587 self.write("(");
33588 self.generate_expression(&e.this)?;
33589 if let Some(expression) = &e.expression {
33590 self.write(", ");
33591 self.generate_expression(expression)?;
33592 }
33593 if let Some(null_val) = &e.null {
33594 self.write(", ");
33595 self.generate_expression(null_val)?;
33596 }
33597 self.write(")");
33598 Ok(())
33599 }
33600
33601 fn generate_struct(&mut self, e: &Struct) -> Result<()> {
33602 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
33603 self.write_keyword("OBJECT_CONSTRUCT");
33605 self.write("(");
33606 for (i, (name, expr)) in e.fields.iter().enumerate() {
33607 if i > 0 {
33608 self.write(", ");
33609 }
33610 if let Some(name) = name {
33611 self.write("'");
33612 self.write(name);
33613 self.write("'");
33614 self.write(", ");
33615 } else {
33616 self.write("'_");
33617 self.write(&i.to_string());
33618 self.write("'");
33619 self.write(", ");
33620 }
33621 self.generate_expression(expr)?;
33622 }
33623 self.write(")");
33624 } else if self.config.struct_curly_brace_notation {
33625 self.write("{");
33627 for (i, (name, expr)) in e.fields.iter().enumerate() {
33628 if i > 0 {
33629 self.write(", ");
33630 }
33631 if let Some(name) = name {
33632 self.write("'");
33634 self.write(name);
33635 self.write("'");
33636 self.write(": ");
33637 } else {
33638 self.write("'_");
33640 self.write(&i.to_string());
33641 self.write("'");
33642 self.write(": ");
33643 }
33644 self.generate_expression(expr)?;
33645 }
33646 self.write("}");
33647 } else {
33648 let value_as_name = matches!(
33652 self.config.dialect,
33653 Some(DialectType::BigQuery)
33654 | Some(DialectType::Spark)
33655 | Some(DialectType::Databricks)
33656 | Some(DialectType::Hive)
33657 );
33658 self.write_keyword("STRUCT");
33659 self.write("(");
33660 for (i, (name, expr)) in e.fields.iter().enumerate() {
33661 if i > 0 {
33662 self.write(", ");
33663 }
33664 if let Some(name) = name {
33665 if value_as_name {
33666 self.generate_expression(expr)?;
33668 self.write_space();
33669 self.write_keyword("AS");
33670 self.write_space();
33671 let needs_quoting = name.contains(' ') || name.contains('-');
33673 if needs_quoting {
33674 if matches!(
33675 self.config.dialect,
33676 Some(DialectType::Spark)
33677 | Some(DialectType::Databricks)
33678 | Some(DialectType::Hive)
33679 ) {
33680 self.write("`");
33681 self.write(name);
33682 self.write("`");
33683 } else {
33684 self.write(name);
33685 }
33686 } else {
33687 self.write(name);
33688 }
33689 } else {
33690 self.write(name);
33692 self.write_space();
33693 self.write_keyword("AS");
33694 self.write_space();
33695 self.generate_expression(expr)?;
33696 }
33697 } else {
33698 self.generate_expression(expr)?;
33699 }
33700 }
33701 self.write(")");
33702 }
33703 Ok(())
33704 }
33705
33706 fn generate_stuff(&mut self, e: &Stuff) -> Result<()> {
33707 self.write_keyword("STUFF");
33709 self.write("(");
33710 self.generate_expression(&e.this)?;
33711 if let Some(start) = &e.start {
33712 self.write(", ");
33713 self.generate_expression(start)?;
33714 }
33715 if let Some(length) = e.length {
33716 self.write(", ");
33717 self.write(&length.to_string());
33718 }
33719 self.write(", ");
33720 self.generate_expression(&e.expression)?;
33721 self.write(")");
33722 Ok(())
33723 }
33724
33725 fn generate_substring_index(&mut self, e: &SubstringIndex) -> Result<()> {
33726 self.write_keyword("SUBSTRING_INDEX");
33728 self.write("(");
33729 self.generate_expression(&e.this)?;
33730 if let Some(delimiter) = &e.delimiter {
33731 self.write(", ");
33732 self.generate_expression(delimiter)?;
33733 }
33734 if let Some(count) = &e.count {
33735 self.write(", ");
33736 self.generate_expression(count)?;
33737 }
33738 self.write(")");
33739 Ok(())
33740 }
33741
33742 fn generate_summarize(&mut self, e: &Summarize) -> Result<()> {
33743 self.write_keyword("SUMMARIZE");
33745 if e.table.is_some() {
33746 self.write_space();
33747 self.write_keyword("TABLE");
33748 }
33749 self.write_space();
33750 self.generate_expression(&e.this)?;
33751 Ok(())
33752 }
33753
33754 fn generate_systimestamp(&mut self, _e: &Systimestamp) -> Result<()> {
33755 self.write_keyword("SYSTIMESTAMP");
33757 Ok(())
33758 }
33759
33760 fn generate_table_alias(&mut self, e: &TableAlias) -> Result<()> {
33761 if let Some(this) = &e.this {
33763 self.generate_expression(this)?;
33764 }
33765 if !e.columns.is_empty() {
33766 self.write("(");
33767 for (i, col) in e.columns.iter().enumerate() {
33768 if i > 0 {
33769 self.write(", ");
33770 }
33771 self.generate_expression(col)?;
33772 }
33773 self.write(")");
33774 }
33775 Ok(())
33776 }
33777
33778 fn generate_table_from_rows(&mut self, e: &TableFromRows) -> Result<()> {
33779 self.write_keyword("TABLE");
33781 self.write("(");
33782 self.generate_expression(&e.this)?;
33783 self.write(")");
33784 if let Some(alias) = &e.alias {
33785 self.write_space();
33786 self.write_keyword("AS");
33787 self.write_space();
33788 self.write(alias);
33789 }
33790 Ok(())
33791 }
33792
33793 fn generate_rows_from(&mut self, e: &RowsFrom) -> Result<()> {
33794 self.write_keyword("ROWS FROM");
33796 self.write(" (");
33797 for (i, expr) in e.expressions.iter().enumerate() {
33798 if i > 0 {
33799 self.write(", ");
33800 }
33801 match expr {
33805 Expression::Tuple(tuple) if tuple.expressions.len() == 2 => {
33806 self.generate_expression(&tuple.expressions[0])?;
33808 self.write_space();
33809 self.write_keyword("AS");
33810 self.write_space();
33811 self.generate_expression(&tuple.expressions[1])?;
33812 }
33813 _ => {
33814 self.generate_expression(expr)?;
33815 }
33816 }
33817 }
33818 self.write(")");
33819 if e.ordinality {
33820 self.write_space();
33821 self.write_keyword("WITH ORDINALITY");
33822 }
33823 if let Some(alias) = &e.alias {
33824 self.write_space();
33825 self.write_keyword("AS");
33826 self.write_space();
33827 self.generate_expression(alias)?;
33828 }
33829 Ok(())
33830 }
33831
33832 fn generate_table_sample(&mut self, e: &TableSample) -> Result<()> {
33833 use crate::dialects::DialectType;
33834
33835 if let (Some(this), Some(sample)) = (&e.this, &e.sample) {
33837 if self.config.alias_post_tablesample {
33839 if let Expression::Subquery(ref s) = **this {
33841 if let Some(ref alias) = s.alias {
33842 let mut subquery_no_alias = (**s).clone();
33844 subquery_no_alias.alias = None;
33845 subquery_no_alias.column_aliases = Vec::new();
33846 self.generate_expression(&Expression::Subquery(Box::new(
33847 subquery_no_alias,
33848 )))?;
33849 self.write_space();
33850 self.write_keyword("TABLESAMPLE");
33851 self.generate_sample_body(sample)?;
33852 if let Some(ref seed) = sample.seed {
33853 self.write_space();
33854 let use_seed = sample.use_seed_keyword
33855 && !matches!(
33856 self.config.dialect,
33857 Some(crate::dialects::DialectType::Databricks)
33858 | Some(crate::dialects::DialectType::Spark)
33859 );
33860 if use_seed {
33861 self.write_keyword("SEED");
33862 } else {
33863 self.write_keyword("REPEATABLE");
33864 }
33865 self.write(" (");
33866 self.generate_expression(seed)?;
33867 self.write(")");
33868 }
33869 self.write_space();
33870 self.write_keyword("AS");
33871 self.write_space();
33872 self.generate_identifier(alias)?;
33873 return Ok(());
33874 }
33875 } else if let Expression::Alias(ref a) = **this {
33876 self.generate_expression(&a.this)?;
33878 self.write_space();
33879 self.write_keyword("TABLESAMPLE");
33880 self.generate_sample_body(sample)?;
33881 if let Some(ref seed) = sample.seed {
33882 self.write_space();
33883 let use_seed = sample.use_seed_keyword
33884 && !matches!(
33885 self.config.dialect,
33886 Some(crate::dialects::DialectType::Databricks)
33887 | Some(crate::dialects::DialectType::Spark)
33888 );
33889 if use_seed {
33890 self.write_keyword("SEED");
33891 } else {
33892 self.write_keyword("REPEATABLE");
33893 }
33894 self.write(" (");
33895 self.generate_expression(seed)?;
33896 self.write(")");
33897 }
33898 self.write_space();
33900 self.write_keyword("AS");
33901 self.write_space();
33902 self.generate_identifier(&a.alias)?;
33903 return Ok(());
33904 }
33905 }
33906 self.generate_expression(this)?;
33908 self.write_space();
33909 self.write_keyword("TABLESAMPLE");
33910 self.generate_sample_body(sample)?;
33911 if let Some(ref seed) = sample.seed {
33913 self.write_space();
33914 let use_seed = sample.use_seed_keyword
33916 && !matches!(
33917 self.config.dialect,
33918 Some(crate::dialects::DialectType::Databricks)
33919 | Some(crate::dialects::DialectType::Spark)
33920 );
33921 if use_seed {
33922 self.write_keyword("SEED");
33923 } else {
33924 self.write_keyword("REPEATABLE");
33925 }
33926 self.write(" (");
33927 self.generate_expression(seed)?;
33928 self.write(")");
33929 }
33930 return Ok(());
33931 }
33932
33933 self.write_keyword("TABLESAMPLE");
33935 if let Some(method) = &e.method {
33936 self.write_space();
33937 self.write_keyword(method);
33938 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
33939 self.write_space();
33941 self.write_keyword("BERNOULLI");
33942 }
33943 if let (Some(numerator), Some(denominator)) = (&e.bucket_numerator, &e.bucket_denominator) {
33944 self.write_space();
33945 self.write_keyword("BUCKET");
33946 self.write_space();
33947 self.generate_expression(numerator)?;
33948 self.write_space();
33949 self.write_keyword("OUT OF");
33950 self.write_space();
33951 self.generate_expression(denominator)?;
33952 if let Some(field) = &e.bucket_field {
33953 self.write_space();
33954 self.write_keyword("ON");
33955 self.write_space();
33956 self.generate_expression(field)?;
33957 }
33958 } else if !e.expressions.is_empty() {
33959 self.write(" (");
33960 for (i, expr) in e.expressions.iter().enumerate() {
33961 if i > 0 {
33962 self.write(", ");
33963 }
33964 self.generate_expression(expr)?;
33965 }
33966 self.write(")");
33967 } else if let Some(percent) = &e.percent {
33968 self.write(" (");
33969 self.generate_expression(percent)?;
33970 self.write_space();
33971 self.write_keyword("PERCENT");
33972 self.write(")");
33973 }
33974 Ok(())
33975 }
33976
33977 fn generate_tag(&mut self, e: &Tag) -> Result<()> {
33978 if let Some(prefix) = &e.prefix {
33980 self.generate_expression(prefix)?;
33981 }
33982 if let Some(this) = &e.this {
33983 self.generate_expression(this)?;
33984 }
33985 if let Some(postfix) = &e.postfix {
33986 self.generate_expression(postfix)?;
33987 }
33988 Ok(())
33989 }
33990
33991 fn generate_tags(&mut self, e: &Tags) -> Result<()> {
33992 self.write_keyword("TAG");
33994 self.write(" (");
33995 for (i, expr) in e.expressions.iter().enumerate() {
33996 if i > 0 {
33997 self.write(", ");
33998 }
33999 self.generate_expression(expr)?;
34000 }
34001 self.write(")");
34002 Ok(())
34003 }
34004
34005 fn generate_temporary_property(&mut self, e: &TemporaryProperty) -> Result<()> {
34006 if let Some(this) = &e.this {
34008 self.generate_expression(this)?;
34009 self.write_space();
34010 }
34011 self.write_keyword("TEMPORARY");
34012 Ok(())
34013 }
34014
34015 fn generate_time_func(&mut self, e: &UnaryFunc) -> Result<()> {
34018 self.write_keyword("TIME");
34020 self.write("(");
34021 self.generate_expression(&e.this)?;
34022 self.write(")");
34023 Ok(())
34024 }
34025
34026 fn generate_time_add(&mut self, e: &TimeAdd) -> Result<()> {
34027 self.write_keyword("TIME_ADD");
34029 self.write("(");
34030 self.generate_expression(&e.this)?;
34031 self.write(", ");
34032 self.generate_expression(&e.expression)?;
34033 if let Some(unit) = &e.unit {
34034 self.write(", ");
34035 self.write_keyword(unit);
34036 }
34037 self.write(")");
34038 Ok(())
34039 }
34040
34041 fn generate_time_diff(&mut self, e: &TimeDiff) -> Result<()> {
34042 self.write_keyword("TIME_DIFF");
34044 self.write("(");
34045 self.generate_expression(&e.this)?;
34046 self.write(", ");
34047 self.generate_expression(&e.expression)?;
34048 if let Some(unit) = &e.unit {
34049 self.write(", ");
34050 self.write_keyword(unit);
34051 }
34052 self.write(")");
34053 Ok(())
34054 }
34055
34056 fn generate_time_from_parts(&mut self, e: &TimeFromParts) -> Result<()> {
34057 self.write_keyword("TIME_FROM_PARTS");
34059 self.write("(");
34060 let mut first = true;
34061 if let Some(hour) = &e.hour {
34062 self.generate_expression(hour)?;
34063 first = false;
34064 }
34065 if let Some(minute) = &e.min {
34066 if !first {
34067 self.write(", ");
34068 }
34069 self.generate_expression(minute)?;
34070 first = false;
34071 }
34072 if let Some(second) = &e.sec {
34073 if !first {
34074 self.write(", ");
34075 }
34076 self.generate_expression(second)?;
34077 first = false;
34078 }
34079 if let Some(ns) = &e.nano {
34080 if !first {
34081 self.write(", ");
34082 }
34083 self.generate_expression(ns)?;
34084 }
34085 self.write(")");
34086 Ok(())
34087 }
34088
34089 fn generate_time_slice(&mut self, e: &TimeSlice) -> Result<()> {
34090 self.write_keyword("TIME_SLICE");
34092 self.write("(");
34093 self.generate_expression(&e.this)?;
34094 self.write(", ");
34095 self.generate_expression(&e.expression)?;
34096 self.write(", ");
34097 self.write_keyword(&e.unit);
34098 self.write(")");
34099 Ok(())
34100 }
34101
34102 fn generate_time_str_to_time(&mut self, e: &TimeStrToTime) -> Result<()> {
34103 self.write_keyword("TIME_STR_TO_TIME");
34105 self.write("(");
34106 self.generate_expression(&e.this)?;
34107 self.write(")");
34108 Ok(())
34109 }
34110
34111 fn generate_time_sub(&mut self, e: &TimeSub) -> Result<()> {
34112 self.write_keyword("TIME_SUB");
34114 self.write("(");
34115 self.generate_expression(&e.this)?;
34116 self.write(", ");
34117 self.generate_expression(&e.expression)?;
34118 if let Some(unit) = &e.unit {
34119 self.write(", ");
34120 self.write_keyword(unit);
34121 }
34122 self.write(")");
34123 Ok(())
34124 }
34125
34126 fn generate_time_to_str(&mut self, e: &TimeToStr) -> Result<()> {
34127 match self.config.dialect {
34128 Some(DialectType::Exasol) => {
34129 self.write_keyword("TO_CHAR");
34131 self.write("(");
34132 self.generate_expression(&e.this)?;
34133 self.write(", '");
34134 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
34135 self.write("'");
34136 self.write(")");
34137 }
34138 Some(DialectType::PostgreSQL)
34139 | Some(DialectType::Redshift)
34140 | Some(DialectType::Materialize) => {
34141 self.write_keyword("TO_CHAR");
34143 self.write("(");
34144 self.generate_expression(&e.this)?;
34145 self.write(", '");
34146 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
34147 self.write("'");
34148 self.write(")");
34149 }
34150 Some(DialectType::Oracle) => {
34151 self.write_keyword("TO_CHAR");
34153 self.write("(");
34154 self.generate_expression(&e.this)?;
34155 self.write(", '");
34156 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
34157 self.write("'");
34158 self.write(")");
34159 }
34160 Some(DialectType::Drill) => {
34161 self.write_keyword("TO_CHAR");
34163 self.write("(");
34164 self.generate_expression(&e.this)?;
34165 self.write(", '");
34166 self.write(&Self::strftime_to_java_format(&e.format));
34167 self.write("'");
34168 self.write(")");
34169 }
34170 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
34171 self.write_keyword("FORMAT");
34173 self.write("(");
34174 self.generate_expression(&e.this)?;
34175 self.write(", '");
34176 self.write(&Self::strftime_to_tsql_format(&e.format));
34177 self.write("'");
34178 self.write(")");
34179 }
34180 Some(DialectType::DuckDB) => {
34181 self.write_keyword("STRFTIME");
34183 self.write("(");
34184 self.generate_expression(&e.this)?;
34185 self.write(", '");
34186 self.write(&e.format);
34187 self.write("'");
34188 self.write(")");
34189 }
34190 Some(DialectType::BigQuery) => {
34191 let fmt = e.format.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
34194 self.write_keyword("FORMAT_DATE");
34195 self.write("('");
34196 self.write(&fmt);
34197 self.write("', ");
34198 self.generate_expression(&e.this)?;
34199 self.write(")");
34200 }
34201 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
34202 self.write_keyword("DATE_FORMAT");
34204 self.write("(");
34205 self.generate_expression(&e.this)?;
34206 self.write(", '");
34207 self.write(&Self::strftime_to_java_format(&e.format));
34208 self.write("'");
34209 self.write(")");
34210 }
34211 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
34212 self.write_keyword("DATE_FORMAT");
34214 self.write("(");
34215 self.generate_expression(&e.this)?;
34216 self.write(", '");
34217 self.write(&e.format);
34218 self.write("'");
34219 self.write(")");
34220 }
34221 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
34222 self.write_keyword("DATE_FORMAT");
34224 self.write("(");
34225 self.generate_expression(&e.this)?;
34226 self.write(", '");
34227 self.write(&e.format);
34228 self.write("'");
34229 self.write(")");
34230 }
34231 _ => {
34232 self.write_keyword("TIME_TO_STR");
34234 self.write("(");
34235 self.generate_expression(&e.this)?;
34236 self.write(", '");
34237 self.write(&e.format);
34238 self.write("'");
34239 self.write(")");
34240 }
34241 }
34242 Ok(())
34243 }
34244
34245 fn generate_time_to_unix(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
34246 match self.config.dialect {
34247 Some(DialectType::DuckDB) => {
34248 self.write_keyword("EPOCH");
34250 self.write("(");
34251 self.generate_expression(&e.this)?;
34252 self.write(")");
34253 }
34254 Some(DialectType::Hive)
34255 | Some(DialectType::Spark)
34256 | Some(DialectType::Databricks)
34257 | Some(DialectType::Doris)
34258 | Some(DialectType::StarRocks)
34259 | Some(DialectType::Drill) => {
34260 self.write_keyword("UNIX_TIMESTAMP");
34262 self.write("(");
34263 self.generate_expression(&e.this)?;
34264 self.write(")");
34265 }
34266 Some(DialectType::Presto) | Some(DialectType::Trino) => {
34267 self.write_keyword("TO_UNIXTIME");
34269 self.write("(");
34270 self.generate_expression(&e.this)?;
34271 self.write(")");
34272 }
34273 _ => {
34274 self.write_keyword("TIME_TO_UNIX");
34276 self.write("(");
34277 self.generate_expression(&e.this)?;
34278 self.write(")");
34279 }
34280 }
34281 Ok(())
34282 }
34283
34284 fn generate_time_str_to_date(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
34285 match self.config.dialect {
34286 Some(DialectType::Hive) => {
34287 self.write_keyword("TO_DATE");
34289 self.write("(");
34290 self.generate_expression(&e.this)?;
34291 self.write(")");
34292 }
34293 _ => {
34294 self.write_keyword("TIME_STR_TO_DATE");
34296 self.write("(");
34297 self.generate_expression(&e.this)?;
34298 self.write(")");
34299 }
34300 }
34301 Ok(())
34302 }
34303
34304 fn generate_time_trunc(&mut self, e: &TimeTrunc) -> Result<()> {
34305 self.write_keyword("TIME_TRUNC");
34307 self.write("(");
34308 self.generate_expression(&e.this)?;
34309 self.write(", ");
34310 self.write_keyword(&e.unit);
34311 self.write(")");
34312 Ok(())
34313 }
34314
34315 fn generate_time_unit(&mut self, e: &TimeUnit) -> Result<()> {
34316 if let Some(unit) = &e.unit {
34318 self.write_keyword(unit);
34319 }
34320 Ok(())
34321 }
34322
34323 fn generate_timestamp_func(&mut self, e: &TimestampFunc) -> Result<()> {
34327 use crate::dialects::DialectType;
34328 use crate::expressions::Literal;
34329
34330 match self.config.dialect {
34331 Some(DialectType::Exasol) => {
34333 self.write_keyword("TO_TIMESTAMP");
34334 self.write("(");
34335 if let Some(this) = &e.this {
34337 match this.as_ref() {
34338 Expression::Literal(Literal::String(s)) => {
34339 self.write("'");
34340 self.write(s);
34341 self.write("'");
34342 }
34343 _ => {
34344 self.generate_expression(this)?;
34345 }
34346 }
34347 }
34348 self.write(")");
34349 }
34350 _ => {
34352 self.write_keyword("TIMESTAMP");
34353 self.write("(");
34354 if let Some(this) = &e.this {
34355 self.generate_expression(this)?;
34356 }
34357 if let Some(zone) = &e.zone {
34358 self.write(", ");
34359 self.generate_expression(zone)?;
34360 }
34361 self.write(")");
34362 }
34363 }
34364 Ok(())
34365 }
34366
34367 fn generate_timestamp_add(&mut self, e: &TimestampAdd) -> Result<()> {
34368 self.write_keyword("TIMESTAMP_ADD");
34370 self.write("(");
34371 self.generate_expression(&e.this)?;
34372 self.write(", ");
34373 self.generate_expression(&e.expression)?;
34374 if let Some(unit) = &e.unit {
34375 self.write(", ");
34376 self.write_keyword(unit);
34377 }
34378 self.write(")");
34379 Ok(())
34380 }
34381
34382 fn generate_timestamp_diff(&mut self, e: &TimestampDiff) -> Result<()> {
34383 self.write_keyword("TIMESTAMP_DIFF");
34385 self.write("(");
34386 self.generate_expression(&e.this)?;
34387 self.write(", ");
34388 self.generate_expression(&e.expression)?;
34389 if let Some(unit) = &e.unit {
34390 self.write(", ");
34391 self.write_keyword(unit);
34392 }
34393 self.write(")");
34394 Ok(())
34395 }
34396
34397 fn generate_timestamp_from_parts(&mut self, e: &TimestampFromParts) -> Result<()> {
34398 self.write_keyword("TIMESTAMP_FROM_PARTS");
34400 self.write("(");
34401 if let Some(this) = &e.this {
34402 self.generate_expression(this)?;
34403 }
34404 if let Some(expression) = &e.expression {
34405 self.write(", ");
34406 self.generate_expression(expression)?;
34407 }
34408 if let Some(zone) = &e.zone {
34409 self.write(", ");
34410 self.generate_expression(zone)?;
34411 }
34412 if let Some(milli) = &e.milli {
34413 self.write(", ");
34414 self.generate_expression(milli)?;
34415 }
34416 self.write(")");
34417 Ok(())
34418 }
34419
34420 fn generate_timestamp_sub(&mut self, e: &TimestampSub) -> Result<()> {
34421 self.write_keyword("TIMESTAMP_SUB");
34423 self.write("(");
34424 self.generate_expression(&e.this)?;
34425 self.write(", ");
34426 self.write_keyword("INTERVAL");
34427 self.write_space();
34428 self.generate_expression(&e.expression)?;
34429 if let Some(unit) = &e.unit {
34430 self.write_space();
34431 self.write_keyword(unit);
34432 }
34433 self.write(")");
34434 Ok(())
34435 }
34436
34437 fn generate_timestamp_tz_from_parts(&mut self, e: &TimestampTzFromParts) -> Result<()> {
34438 self.write_keyword("TIMESTAMP_TZ_FROM_PARTS");
34440 self.write("(");
34441 if let Some(zone) = &e.zone {
34442 self.generate_expression(zone)?;
34443 }
34444 self.write(")");
34445 Ok(())
34446 }
34447
34448 fn generate_to_binary(&mut self, e: &ToBinary) -> Result<()> {
34449 self.write_keyword("TO_BINARY");
34451 self.write("(");
34452 self.generate_expression(&e.this)?;
34453 if let Some(format) = &e.format {
34454 self.write(", '");
34455 self.write(format);
34456 self.write("'");
34457 }
34458 self.write(")");
34459 Ok(())
34460 }
34461
34462 fn generate_to_boolean(&mut self, e: &ToBoolean) -> Result<()> {
34463 self.write_keyword("TO_BOOLEAN");
34465 self.write("(");
34466 self.generate_expression(&e.this)?;
34467 self.write(")");
34468 Ok(())
34469 }
34470
34471 fn generate_to_char(&mut self, e: &ToChar) -> Result<()> {
34472 self.write_keyword("TO_CHAR");
34474 self.write("(");
34475 self.generate_expression(&e.this)?;
34476 if let Some(format) = &e.format {
34477 self.write(", '");
34478 self.write(format);
34479 self.write("'");
34480 }
34481 if let Some(nlsparam) = &e.nlsparam {
34482 self.write(", ");
34483 self.generate_expression(nlsparam)?;
34484 }
34485 self.write(")");
34486 Ok(())
34487 }
34488
34489 fn generate_to_decfloat(&mut self, e: &ToDecfloat) -> Result<()> {
34490 self.write_keyword("TO_DECFLOAT");
34492 self.write("(");
34493 self.generate_expression(&e.this)?;
34494 if let Some(format) = &e.format {
34495 self.write(", '");
34496 self.write(format);
34497 self.write("'");
34498 }
34499 self.write(")");
34500 Ok(())
34501 }
34502
34503 fn generate_to_double(&mut self, e: &ToDouble) -> Result<()> {
34504 self.write_keyword("TO_DOUBLE");
34506 self.write("(");
34507 self.generate_expression(&e.this)?;
34508 if let Some(format) = &e.format {
34509 self.write(", '");
34510 self.write(format);
34511 self.write("'");
34512 }
34513 self.write(")");
34514 Ok(())
34515 }
34516
34517 fn generate_to_file(&mut self, e: &ToFile) -> Result<()> {
34518 self.write_keyword("TO_FILE");
34520 self.write("(");
34521 self.generate_expression(&e.this)?;
34522 if let Some(path) = &e.path {
34523 self.write(", ");
34524 self.generate_expression(path)?;
34525 }
34526 self.write(")");
34527 Ok(())
34528 }
34529
34530 fn generate_to_number(&mut self, e: &ToNumber) -> Result<()> {
34531 let is_safe = e.safe.is_some();
34534 if is_safe {
34535 self.write_keyword("TRY_TO_NUMBER");
34536 } else {
34537 self.write_keyword("TO_NUMBER");
34538 }
34539 self.write("(");
34540 self.generate_expression(&e.this)?;
34541 if let Some(format) = &e.format {
34542 self.write(", ");
34543 self.generate_expression(format)?;
34544 }
34545 if let Some(nlsparam) = &e.nlsparam {
34546 self.write(", ");
34547 self.generate_expression(nlsparam)?;
34548 }
34549 if let Some(precision) = &e.precision {
34550 self.write(", ");
34551 self.generate_expression(precision)?;
34552 }
34553 if let Some(scale) = &e.scale {
34554 self.write(", ");
34555 self.generate_expression(scale)?;
34556 }
34557 self.write(")");
34558 Ok(())
34559 }
34560
34561 fn generate_to_table_property(&mut self, e: &ToTableProperty) -> Result<()> {
34562 self.write_keyword("TO_TABLE");
34564 self.write_space();
34565 self.generate_expression(&e.this)?;
34566 Ok(())
34567 }
34568
34569 fn generate_transaction(&mut self, e: &Transaction) -> Result<()> {
34570 let mark_text = e.mark.as_ref().map(|m| match m.as_ref() {
34572 Expression::Identifier(id) => id.name.clone(),
34573 Expression::Literal(Literal::String(s)) => s.clone(),
34574 _ => String::new(),
34575 });
34576
34577 let is_start = mark_text.as_ref().map_or(false, |s| s == "START");
34578 let has_transaction_keyword = mark_text.as_ref().map_or(false, |s| s == "TRANSACTION");
34579 let has_with_mark = e.mark.as_ref().map_or(false, |m| {
34580 matches!(m.as_ref(), Expression::Literal(Literal::String(_)))
34581 });
34582
34583 let use_start_transaction = matches!(
34585 self.config.dialect,
34586 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
34587 );
34588 let strip_transaction = matches!(
34590 self.config.dialect,
34591 Some(DialectType::Snowflake)
34592 | Some(DialectType::PostgreSQL)
34593 | Some(DialectType::Redshift)
34594 | Some(DialectType::MySQL)
34595 | Some(DialectType::Hive)
34596 | Some(DialectType::Spark)
34597 | Some(DialectType::Databricks)
34598 | Some(DialectType::DuckDB)
34599 | Some(DialectType::Oracle)
34600 | Some(DialectType::Doris)
34601 | Some(DialectType::StarRocks)
34602 | Some(DialectType::Materialize)
34603 | Some(DialectType::ClickHouse)
34604 );
34605
34606 if is_start || use_start_transaction {
34607 self.write_keyword("START TRANSACTION");
34609 if let Some(modes) = &e.modes {
34610 self.write_space();
34611 self.generate_expression(modes)?;
34612 }
34613 } else {
34614 self.write_keyword("BEGIN");
34616
34617 let is_kind = e.this.as_ref().map_or(false, |t| {
34619 if let Expression::Identifier(id) = t.as_ref() {
34620 matches!(
34621 id.name.to_uppercase().as_str(),
34622 "DEFERRED" | "IMMEDIATE" | "EXCLUSIVE"
34623 )
34624 } else {
34625 false
34626 }
34627 });
34628
34629 if is_kind {
34631 if let Some(this) = &e.this {
34632 self.write_space();
34633 if let Expression::Identifier(id) = this.as_ref() {
34634 self.write_keyword(&id.name);
34635 }
34636 }
34637 }
34638
34639 if (has_transaction_keyword || has_with_mark) && !strip_transaction {
34641 self.write_space();
34642 self.write_keyword("TRANSACTION");
34643 }
34644
34645 if !is_kind {
34647 if let Some(this) = &e.this {
34648 self.write_space();
34649 self.generate_expression(this)?;
34650 }
34651 }
34652
34653 if has_with_mark {
34655 self.write_space();
34656 self.write_keyword("WITH MARK");
34657 if let Some(Expression::Literal(Literal::String(desc))) = e.mark.as_deref() {
34658 if !desc.is_empty() {
34659 self.write_space();
34660 self.write(&format!("'{}'", desc));
34661 }
34662 }
34663 }
34664
34665 if let Some(modes) = &e.modes {
34667 self.write_space();
34668 self.generate_expression(modes)?;
34669 }
34670 }
34671 Ok(())
34672 }
34673
34674 fn generate_transform(&mut self, e: &Transform) -> Result<()> {
34675 self.write_keyword("TRANSFORM");
34677 self.write("(");
34678 self.generate_expression(&e.this)?;
34679 self.write(", ");
34680 self.generate_expression(&e.expression)?;
34681 self.write(")");
34682 Ok(())
34683 }
34684
34685 fn generate_transform_model_property(&mut self, e: &TransformModelProperty) -> Result<()> {
34686 self.write_keyword("TRANSFORM");
34688 self.write("(");
34689 if self.config.pretty && !e.expressions.is_empty() {
34690 self.indent_level += 1;
34691 for (i, expr) in e.expressions.iter().enumerate() {
34692 if i > 0 {
34693 self.write(",");
34694 }
34695 self.write_newline();
34696 self.write_indent();
34697 self.generate_expression(expr)?;
34698 }
34699 self.indent_level -= 1;
34700 self.write_newline();
34701 self.write(")");
34702 } else {
34703 for (i, expr) in e.expressions.iter().enumerate() {
34704 if i > 0 {
34705 self.write(", ");
34706 }
34707 self.generate_expression(expr)?;
34708 }
34709 self.write(")");
34710 }
34711 Ok(())
34712 }
34713
34714 fn generate_transient_property(&mut self, e: &TransientProperty) -> Result<()> {
34715 use crate::dialects::DialectType;
34716 if let Some(this) = &e.this {
34718 self.generate_expression(this)?;
34719 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
34720 self.write_space();
34721 }
34722 }
34723 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
34724 self.write_keyword("TRANSIENT");
34725 }
34726 Ok(())
34727 }
34728
34729 fn generate_translate(&mut self, e: &Translate) -> Result<()> {
34730 self.write_keyword("TRANSLATE");
34732 self.write("(");
34733 self.generate_expression(&e.this)?;
34734 if let Some(from) = &e.from_ {
34735 self.write(", ");
34736 self.generate_expression(from)?;
34737 }
34738 if let Some(to) = &e.to {
34739 self.write(", ");
34740 self.generate_expression(to)?;
34741 }
34742 self.write(")");
34743 Ok(())
34744 }
34745
34746 fn generate_translate_characters(&mut self, e: &TranslateCharacters) -> Result<()> {
34747 self.write_keyword("TRANSLATE");
34749 self.write("(");
34750 self.generate_expression(&e.this)?;
34751 self.write_space();
34752 self.write_keyword("USING");
34753 self.write_space();
34754 self.generate_expression(&e.expression)?;
34755 if e.with_error.is_some() {
34756 self.write_space();
34757 self.write_keyword("WITH ERROR");
34758 }
34759 self.write(")");
34760 Ok(())
34761 }
34762
34763 fn generate_truncate_table(&mut self, e: &TruncateTable) -> Result<()> {
34764 self.write_keyword("TRUNCATE TABLE");
34766 self.write_space();
34767 for (i, expr) in e.expressions.iter().enumerate() {
34768 if i > 0 {
34769 self.write(", ");
34770 }
34771 self.generate_expression(expr)?;
34772 }
34773 Ok(())
34774 }
34775
34776 fn generate_try_base64_decode_binary(&mut self, e: &TryBase64DecodeBinary) -> Result<()> {
34777 self.write_keyword("TRY_BASE64_DECODE_BINARY");
34779 self.write("(");
34780 self.generate_expression(&e.this)?;
34781 if let Some(alphabet) = &e.alphabet {
34782 self.write(", ");
34783 self.generate_expression(alphabet)?;
34784 }
34785 self.write(")");
34786 Ok(())
34787 }
34788
34789 fn generate_try_base64_decode_string(&mut self, e: &TryBase64DecodeString) -> Result<()> {
34790 self.write_keyword("TRY_BASE64_DECODE_STRING");
34792 self.write("(");
34793 self.generate_expression(&e.this)?;
34794 if let Some(alphabet) = &e.alphabet {
34795 self.write(", ");
34796 self.generate_expression(alphabet)?;
34797 }
34798 self.write(")");
34799 Ok(())
34800 }
34801
34802 fn generate_try_to_decfloat(&mut self, e: &TryToDecfloat) -> Result<()> {
34803 self.write_keyword("TRY_TO_DECFLOAT");
34805 self.write("(");
34806 self.generate_expression(&e.this)?;
34807 if let Some(format) = &e.format {
34808 self.write(", '");
34809 self.write(format);
34810 self.write("'");
34811 }
34812 self.write(")");
34813 Ok(())
34814 }
34815
34816 fn generate_ts_or_ds_add(&mut self, e: &TsOrDsAdd) -> Result<()> {
34817 self.write_keyword("TS_OR_DS_ADD");
34819 self.write("(");
34820 self.generate_expression(&e.this)?;
34821 self.write(", ");
34822 self.generate_expression(&e.expression)?;
34823 if let Some(unit) = &e.unit {
34824 self.write(", ");
34825 self.write_keyword(unit);
34826 }
34827 if let Some(return_type) = &e.return_type {
34828 self.write(", ");
34829 self.generate_expression(return_type)?;
34830 }
34831 self.write(")");
34832 Ok(())
34833 }
34834
34835 fn generate_ts_or_ds_diff(&mut self, e: &TsOrDsDiff) -> Result<()> {
34836 self.write_keyword("TS_OR_DS_DIFF");
34838 self.write("(");
34839 self.generate_expression(&e.this)?;
34840 self.write(", ");
34841 self.generate_expression(&e.expression)?;
34842 if let Some(unit) = &e.unit {
34843 self.write(", ");
34844 self.write_keyword(unit);
34845 }
34846 self.write(")");
34847 Ok(())
34848 }
34849
34850 fn generate_ts_or_ds_to_date(&mut self, e: &TsOrDsToDate) -> Result<()> {
34851 let default_time_format = "%Y-%m-%d %H:%M:%S";
34852 let default_date_format = "%Y-%m-%d";
34853 let has_non_default_format = e.format.as_ref().map_or(false, |f| {
34854 f != default_time_format && f != default_date_format
34855 });
34856
34857 if has_non_default_format {
34858 let fmt = e.format.as_ref().unwrap();
34860 match self.config.dialect {
34861 Some(DialectType::MySQL) | Some(DialectType::StarRocks) => {
34862 let str_to_time = crate::expressions::StrToTime {
34865 this: Box::new((*e.this).clone()),
34866 format: fmt.clone(),
34867 zone: None,
34868 safe: None,
34869 target_type: None,
34870 };
34871 self.generate_str_to_time(&str_to_time)?;
34872 }
34873 Some(DialectType::Hive)
34874 | Some(DialectType::Spark)
34875 | Some(DialectType::Databricks) => {
34876 self.write_keyword("TO_DATE");
34878 self.write("(");
34879 self.generate_expression(&e.this)?;
34880 self.write(", '");
34881 self.write(&Self::strftime_to_java_format(fmt));
34882 self.write("')");
34883 }
34884 Some(DialectType::Snowflake) => {
34885 self.write_keyword("TO_DATE");
34887 self.write("(");
34888 self.generate_expression(&e.this)?;
34889 self.write(", '");
34890 self.write(&Self::strftime_to_snowflake_format(fmt));
34891 self.write("')");
34892 }
34893 Some(DialectType::Doris) => {
34894 self.write_keyword("TO_DATE");
34896 self.write("(");
34897 self.generate_expression(&e.this)?;
34898 self.write(")");
34899 }
34900 _ => {
34901 self.write_keyword("CAST");
34903 self.write("(");
34904 let str_to_time = crate::expressions::StrToTime {
34905 this: Box::new((*e.this).clone()),
34906 format: fmt.clone(),
34907 zone: None,
34908 safe: None,
34909 target_type: None,
34910 };
34911 self.generate_str_to_time(&str_to_time)?;
34912 self.write_keyword(" AS ");
34913 self.write_keyword("DATE");
34914 self.write(")");
34915 }
34916 }
34917 } else {
34918 match self.config.dialect {
34920 Some(DialectType::MySQL)
34921 | Some(DialectType::SQLite)
34922 | Some(DialectType::StarRocks) => {
34923 self.write_keyword("DATE");
34925 self.write("(");
34926 self.generate_expression(&e.this)?;
34927 self.write(")");
34928 }
34929 Some(DialectType::Hive)
34930 | Some(DialectType::Spark)
34931 | Some(DialectType::Databricks)
34932 | Some(DialectType::Snowflake)
34933 | Some(DialectType::Doris) => {
34934 self.write_keyword("TO_DATE");
34936 self.write("(");
34937 self.generate_expression(&e.this)?;
34938 self.write(")");
34939 }
34940 Some(DialectType::Presto)
34941 | Some(DialectType::Trino)
34942 | Some(DialectType::Athena) => {
34943 self.write_keyword("CAST");
34945 self.write("(");
34946 self.write_keyword("CAST");
34947 self.write("(");
34948 self.generate_expression(&e.this)?;
34949 self.write_keyword(" AS ");
34950 self.write_keyword("TIMESTAMP");
34951 self.write(")");
34952 self.write_keyword(" AS ");
34953 self.write_keyword("DATE");
34954 self.write(")");
34955 }
34956 Some(DialectType::ClickHouse) => {
34957 self.write_keyword("CAST");
34959 self.write("(");
34960 self.generate_expression(&e.this)?;
34961 self.write_keyword(" AS ");
34962 self.write("Nullable(DATE)");
34963 self.write(")");
34964 }
34965 _ => {
34966 self.write_keyword("CAST");
34968 self.write("(");
34969 self.generate_expression(&e.this)?;
34970 self.write_keyword(" AS ");
34971 self.write_keyword("DATE");
34972 self.write(")");
34973 }
34974 }
34975 }
34976 Ok(())
34977 }
34978
34979 fn generate_ts_or_ds_to_time(&mut self, e: &TsOrDsToTime) -> Result<()> {
34980 self.write_keyword("TS_OR_DS_TO_TIME");
34982 self.write("(");
34983 self.generate_expression(&e.this)?;
34984 if let Some(format) = &e.format {
34985 self.write(", '");
34986 self.write(format);
34987 self.write("'");
34988 }
34989 self.write(")");
34990 Ok(())
34991 }
34992
34993 fn generate_unhex(&mut self, e: &Unhex) -> Result<()> {
34994 self.write_keyword("UNHEX");
34996 self.write("(");
34997 self.generate_expression(&e.this)?;
34998 if let Some(expression) = &e.expression {
34999 self.write(", ");
35000 self.generate_expression(expression)?;
35001 }
35002 self.write(")");
35003 Ok(())
35004 }
35005
35006 fn generate_unicode_string(&mut self, e: &UnicodeString) -> Result<()> {
35007 self.write("U&");
35009 self.generate_expression(&e.this)?;
35010 if let Some(escape) = &e.escape {
35011 self.write_space();
35012 self.write_keyword("UESCAPE");
35013 self.write_space();
35014 self.generate_expression(escape)?;
35015 }
35016 Ok(())
35017 }
35018
35019 fn generate_uniform(&mut self, e: &Uniform) -> Result<()> {
35020 self.write_keyword("UNIFORM");
35022 self.write("(");
35023 self.generate_expression(&e.this)?;
35024 self.write(", ");
35025 self.generate_expression(&e.expression)?;
35026 if let Some(gen) = &e.gen {
35027 self.write(", ");
35028 self.generate_expression(gen)?;
35029 }
35030 if let Some(seed) = &e.seed {
35031 self.write(", ");
35032 self.generate_expression(seed)?;
35033 }
35034 self.write(")");
35035 Ok(())
35036 }
35037
35038 fn generate_unique_column_constraint(&mut self, e: &UniqueColumnConstraint) -> Result<()> {
35039 self.write_keyword("UNIQUE");
35041 if e.nulls.is_some() {
35043 self.write(" NULLS NOT DISTINCT");
35044 }
35045 if let Some(this) = &e.this {
35046 self.write_space();
35047 self.generate_expression(this)?;
35048 }
35049 if let Some(index_type) = &e.index_type {
35050 self.write(" USING ");
35051 self.generate_expression(index_type)?;
35052 }
35053 if let Some(on_conflict) = &e.on_conflict {
35054 self.write_space();
35055 self.generate_expression(on_conflict)?;
35056 }
35057 for opt in &e.options {
35058 self.write_space();
35059 self.generate_expression(opt)?;
35060 }
35061 Ok(())
35062 }
35063
35064 fn generate_unique_key_property(&mut self, e: &UniqueKeyProperty) -> Result<()> {
35065 self.write_keyword("UNIQUE KEY");
35067 self.write(" (");
35068 for (i, expr) in e.expressions.iter().enumerate() {
35069 if i > 0 {
35070 self.write(", ");
35071 }
35072 self.generate_expression(expr)?;
35073 }
35074 self.write(")");
35075 Ok(())
35076 }
35077
35078 fn generate_rollup_property(&mut self, e: &RollupProperty) -> Result<()> {
35079 self.write_keyword("ROLLUP");
35081 self.write(" (");
35082 for (i, index) in e.expressions.iter().enumerate() {
35083 if i > 0 {
35084 self.write(", ");
35085 }
35086 self.generate_identifier(&index.name)?;
35087 self.write("(");
35088 for (j, col) in index.expressions.iter().enumerate() {
35089 if j > 0 {
35090 self.write(", ");
35091 }
35092 self.generate_identifier(col)?;
35093 }
35094 self.write(")");
35095 }
35096 self.write(")");
35097 Ok(())
35098 }
35099
35100 fn generate_unix_to_str(&mut self, e: &UnixToStr) -> Result<()> {
35101 match self.config.dialect {
35102 Some(DialectType::DuckDB) => {
35103 self.write_keyword("STRFTIME");
35105 self.write("(");
35106 self.write_keyword("TO_TIMESTAMP");
35107 self.write("(");
35108 self.generate_expression(&e.this)?;
35109 self.write("), '");
35110 if let Some(format) = &e.format {
35111 self.write(format);
35112 }
35113 self.write("')");
35114 }
35115 Some(DialectType::Hive) => {
35116 self.write_keyword("FROM_UNIXTIME");
35118 self.write("(");
35119 self.generate_expression(&e.this)?;
35120 if let Some(format) = &e.format {
35121 if format != "yyyy-MM-dd HH:mm:ss" {
35122 self.write(", '");
35123 self.write(format);
35124 self.write("'");
35125 }
35126 }
35127 self.write(")");
35128 }
35129 Some(DialectType::Presto) | Some(DialectType::Trino) => {
35130 self.write_keyword("DATE_FORMAT");
35132 self.write("(");
35133 self.write_keyword("FROM_UNIXTIME");
35134 self.write("(");
35135 self.generate_expression(&e.this)?;
35136 self.write("), '");
35137 if let Some(format) = &e.format {
35138 self.write(format);
35139 }
35140 self.write("')");
35141 }
35142 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
35143 self.write_keyword("FROM_UNIXTIME");
35145 self.write("(");
35146 self.generate_expression(&e.this)?;
35147 if let Some(format) = &e.format {
35148 self.write(", '");
35149 self.write(format);
35150 self.write("'");
35151 }
35152 self.write(")");
35153 }
35154 _ => {
35155 self.write_keyword("UNIX_TO_STR");
35157 self.write("(");
35158 self.generate_expression(&e.this)?;
35159 if let Some(format) = &e.format {
35160 self.write(", '");
35161 self.write(format);
35162 self.write("'");
35163 }
35164 self.write(")");
35165 }
35166 }
35167 Ok(())
35168 }
35169
35170 fn generate_unix_to_time(&mut self, e: &UnixToTime) -> Result<()> {
35171 use crate::dialects::DialectType;
35172 let scale = e.scale.unwrap_or(0); match self.config.dialect {
35175 Some(DialectType::Snowflake) => {
35176 self.write_keyword("TO_TIMESTAMP");
35178 self.write("(");
35179 self.generate_expression(&e.this)?;
35180 if let Some(s) = e.scale {
35181 if s > 0 {
35182 self.write(", ");
35183 self.write(&s.to_string());
35184 }
35185 }
35186 self.write(")");
35187 }
35188 Some(DialectType::BigQuery) => {
35189 match scale {
35192 0 => {
35193 self.write_keyword("TIMESTAMP_SECONDS");
35194 self.write("(");
35195 self.generate_expression(&e.this)?;
35196 self.write(")");
35197 }
35198 3 => {
35199 self.write_keyword("TIMESTAMP_MILLIS");
35200 self.write("(");
35201 self.generate_expression(&e.this)?;
35202 self.write(")");
35203 }
35204 6 => {
35205 self.write_keyword("TIMESTAMP_MICROS");
35206 self.write("(");
35207 self.generate_expression(&e.this)?;
35208 self.write(")");
35209 }
35210 _ => {
35211 self.write_keyword("TIMESTAMP_SECONDS");
35213 self.write("(CAST(");
35214 self.generate_expression(&e.this)?;
35215 self.write(&format!(" / POWER(10, {}) AS INT64))", scale));
35216 }
35217 }
35218 }
35219 Some(DialectType::Spark) => {
35220 match scale {
35225 0 => {
35226 self.write_keyword("CAST");
35227 self.write("(");
35228 self.write_keyword("FROM_UNIXTIME");
35229 self.write("(");
35230 self.generate_expression(&e.this)?;
35231 self.write(") ");
35232 self.write_keyword("AS TIMESTAMP");
35233 self.write(")");
35234 }
35235 3 => {
35236 self.write_keyword("TIMESTAMP_MILLIS");
35237 self.write("(");
35238 self.generate_expression(&e.this)?;
35239 self.write(")");
35240 }
35241 6 => {
35242 self.write_keyword("TIMESTAMP_MICROS");
35243 self.write("(");
35244 self.generate_expression(&e.this)?;
35245 self.write(")");
35246 }
35247 _ => {
35248 self.write_keyword("TIMESTAMP_SECONDS");
35249 self.write("(");
35250 self.generate_expression(&e.this)?;
35251 self.write(&format!(" / POWER(10, {}))", scale));
35252 }
35253 }
35254 }
35255 Some(DialectType::Databricks) => {
35256 match scale {
35260 0 => {
35261 self.write_keyword("CAST");
35262 self.write("(");
35263 self.write_keyword("FROM_UNIXTIME");
35264 self.write("(");
35265 self.generate_expression(&e.this)?;
35266 self.write(") ");
35267 self.write_keyword("AS TIMESTAMP");
35268 self.write(")");
35269 }
35270 3 => {
35271 self.write_keyword("TIMESTAMP_MILLIS");
35272 self.write("(");
35273 self.generate_expression(&e.this)?;
35274 self.write(")");
35275 }
35276 6 => {
35277 self.write_keyword("TIMESTAMP_MICROS");
35278 self.write("(");
35279 self.generate_expression(&e.this)?;
35280 self.write(")");
35281 }
35282 _ => {
35283 self.write_keyword("TIMESTAMP_SECONDS");
35284 self.write("(");
35285 self.generate_expression(&e.this)?;
35286 self.write(&format!(" / POWER(10, {}))", scale));
35287 }
35288 }
35289 }
35290 Some(DialectType::Hive) => {
35291 if scale == 0 {
35293 self.write_keyword("FROM_UNIXTIME");
35294 self.write("(");
35295 self.generate_expression(&e.this)?;
35296 self.write(")");
35297 } else {
35298 self.write_keyword("FROM_UNIXTIME");
35299 self.write("(");
35300 self.generate_expression(&e.this)?;
35301 self.write(&format!(" / POWER(10, {})", scale));
35302 self.write(")");
35303 }
35304 }
35305 Some(DialectType::Presto) | Some(DialectType::Trino) => {
35306 if scale == 0 {
35309 self.write_keyword("FROM_UNIXTIME");
35310 self.write("(");
35311 self.generate_expression(&e.this)?;
35312 self.write(")");
35313 } else {
35314 self.write_keyword("FROM_UNIXTIME");
35315 self.write("(CAST(");
35316 self.generate_expression(&e.this)?;
35317 self.write(&format!(" AS DOUBLE) / POW(10, {}))", scale));
35318 }
35319 }
35320 Some(DialectType::DuckDB) => {
35321 match scale {
35325 0 => {
35326 self.write_keyword("TO_TIMESTAMP");
35327 self.write("(");
35328 self.generate_expression(&e.this)?;
35329 self.write(")");
35330 }
35331 3 => {
35332 self.write_keyword("EPOCH_MS");
35333 self.write("(");
35334 self.generate_expression(&e.this)?;
35335 self.write(")");
35336 }
35337 6 => {
35338 self.write_keyword("MAKE_TIMESTAMP");
35339 self.write("(");
35340 self.generate_expression(&e.this)?;
35341 self.write(")");
35342 }
35343 _ => {
35344 self.write_keyword("TO_TIMESTAMP");
35345 self.write("(");
35346 self.generate_expression(&e.this)?;
35347 self.write(&format!(" / POWER(10, {}))", scale));
35348 self.write_keyword(" AT TIME ZONE");
35349 self.write(" 'UTC'");
35350 }
35351 }
35352 }
35353 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
35354 self.write_keyword("FROM_UNIXTIME");
35356 self.write("(");
35357 self.generate_expression(&e.this)?;
35358 self.write(")");
35359 }
35360 Some(DialectType::Oracle) => {
35361 self.write("TO_DATE('1970-01-01', 'YYYY-MM-DD') + (");
35363 self.generate_expression(&e.this)?;
35364 self.write(" / 86400)");
35365 }
35366 Some(DialectType::Redshift) => {
35367 self.write("(TIMESTAMP 'epoch' + ");
35370 if scale == 0 {
35371 self.generate_expression(&e.this)?;
35372 } else {
35373 self.write("(");
35374 self.generate_expression(&e.this)?;
35375 self.write(&format!(" / POWER(10, {}))", scale));
35376 }
35377 self.write(" * INTERVAL '1 SECOND')");
35378 }
35379 _ => {
35380 self.write_keyword("TO_TIMESTAMP");
35382 self.write("(");
35383 self.generate_expression(&e.this)?;
35384 if let Some(s) = e.scale {
35385 self.write(", ");
35386 self.write(&s.to_string());
35387 }
35388 self.write(")");
35389 }
35390 }
35391 Ok(())
35392 }
35393
35394 fn generate_unpivot_columns(&mut self, e: &UnpivotColumns) -> Result<()> {
35395 if !matches!(&*e.this, Expression::Null(_)) {
35397 self.write_keyword("NAME");
35398 self.write_space();
35399 self.generate_expression(&e.this)?;
35400 }
35401 if !e.expressions.is_empty() {
35402 self.write_space();
35403 self.write_keyword("VALUE");
35404 self.write_space();
35405 for (i, expr) in e.expressions.iter().enumerate() {
35406 if i > 0 {
35407 self.write(", ");
35408 }
35409 self.generate_expression(expr)?;
35410 }
35411 }
35412 Ok(())
35413 }
35414
35415 fn generate_user_defined_function(&mut self, e: &UserDefinedFunction) -> Result<()> {
35416 if e.wrapped.is_some() {
35418 self.write("(");
35419 }
35420 self.generate_expression(&e.this)?;
35421 if e.wrapped.is_some() {
35422 self.write(")");
35423 }
35424 self.write("(");
35425 for (i, expr) in e.expressions.iter().enumerate() {
35426 if i > 0 {
35427 self.write(", ");
35428 }
35429 self.generate_expression(expr)?;
35430 }
35431 self.write(")");
35432 Ok(())
35433 }
35434
35435 fn generate_using_template_property(&mut self, e: &UsingTemplateProperty) -> Result<()> {
35436 self.write_keyword("USING TEMPLATE");
35438 self.write_space();
35439 self.generate_expression(&e.this)?;
35440 Ok(())
35441 }
35442
35443 fn generate_utc_time(&mut self, _e: &UtcTime) -> Result<()> {
35444 self.write_keyword("UTC_TIME");
35446 Ok(())
35447 }
35448
35449 fn generate_utc_timestamp(&mut self, _e: &UtcTimestamp) -> Result<()> {
35450 self.write_keyword("UTC_TIMESTAMP");
35452 Ok(())
35453 }
35454
35455 fn generate_uuid(&mut self, e: &Uuid) -> Result<()> {
35456 use crate::dialects::DialectType;
35457 let func_name = match self.config.dialect {
35459 Some(DialectType::Snowflake) => "UUID_STRING",
35460 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
35461 Some(DialectType::BigQuery) => "GENERATE_UUID",
35462 _ => {
35463 if let Some(name) = &e.name {
35464 name.as_str()
35465 } else {
35466 "UUID"
35467 }
35468 }
35469 };
35470 self.write_keyword(func_name);
35471 self.write("(");
35472 if let Some(this) = &e.this {
35473 self.generate_expression(this)?;
35474 }
35475 self.write(")");
35476 Ok(())
35477 }
35478
35479 fn generate_var_map(&mut self, e: &VarMap) -> Result<()> {
35480 self.write_keyword("MAP");
35482 self.write("(");
35483 let mut first = true;
35484 for (k, v) in e.keys.iter().zip(e.values.iter()) {
35485 if !first {
35486 self.write(", ");
35487 }
35488 self.generate_expression(k)?;
35489 self.write(", ");
35490 self.generate_expression(v)?;
35491 first = false;
35492 }
35493 self.write(")");
35494 Ok(())
35495 }
35496
35497 fn generate_vector_search(&mut self, e: &VectorSearch) -> Result<()> {
35498 self.write_keyword("VECTOR_SEARCH");
35500 self.write("(");
35501 self.generate_expression(&e.this)?;
35502 if let Some(col) = &e.column_to_search {
35503 self.write(", ");
35504 self.generate_expression(col)?;
35505 }
35506 if let Some(query_table) = &e.query_table {
35507 self.write(", ");
35508 self.generate_expression(query_table)?;
35509 }
35510 if let Some(query_col) = &e.query_column_to_search {
35511 self.write(", ");
35512 self.generate_expression(query_col)?;
35513 }
35514 if let Some(top_k) = &e.top_k {
35515 self.write(", ");
35516 self.generate_expression(top_k)?;
35517 }
35518 if let Some(dist_type) = &e.distance_type {
35519 self.write(", ");
35520 self.generate_expression(dist_type)?;
35521 }
35522 self.write(")");
35523 Ok(())
35524 }
35525
35526 fn generate_version(&mut self, e: &Version) -> Result<()> {
35527 use crate::dialects::DialectType;
35533 let skip_for = matches!(
35534 self.config.dialect,
35535 Some(DialectType::Hive) | Some(DialectType::Spark)
35536 );
35537 if !skip_for {
35538 self.write_keyword("FOR");
35539 self.write_space();
35540 }
35541 match e.this.as_ref() {
35543 Expression::Identifier(ident) => {
35544 self.write_keyword(&ident.name);
35545 }
35546 _ => {
35547 self.generate_expression(&e.this)?;
35548 }
35549 }
35550 self.write_space();
35551 self.write_keyword(&e.kind);
35552 if let Some(expression) = &e.expression {
35553 self.write_space();
35554 self.generate_expression(expression)?;
35555 }
35556 Ok(())
35557 }
35558
35559 fn generate_view_attribute_property(&mut self, e: &ViewAttributeProperty) -> Result<()> {
35560 self.generate_expression(&e.this)?;
35562 Ok(())
35563 }
35564
35565 fn generate_volatile_property(&mut self, e: &VolatileProperty) -> Result<()> {
35566 if e.this.is_some() {
35568 self.write_keyword("NOT VOLATILE");
35569 } else {
35570 self.write_keyword("VOLATILE");
35571 }
35572 Ok(())
35573 }
35574
35575 fn generate_watermark_column_constraint(
35576 &mut self,
35577 e: &WatermarkColumnConstraint,
35578 ) -> Result<()> {
35579 self.write_keyword("WATERMARK FOR");
35581 self.write_space();
35582 self.generate_expression(&e.this)?;
35583 self.write_space();
35584 self.write_keyword("AS");
35585 self.write_space();
35586 self.generate_expression(&e.expression)?;
35587 Ok(())
35588 }
35589
35590 fn generate_week(&mut self, e: &Week) -> Result<()> {
35591 self.write_keyword("WEEK");
35593 self.write("(");
35594 self.generate_expression(&e.this)?;
35595 if let Some(mode) = &e.mode {
35596 self.write(", ");
35597 self.generate_expression(mode)?;
35598 }
35599 self.write(")");
35600 Ok(())
35601 }
35602
35603 fn generate_when(&mut self, e: &When) -> Result<()> {
35604 self.write_keyword("WHEN");
35608 self.write_space();
35609
35610 if let Some(matched) = &e.matched {
35612 match matched.as_ref() {
35614 Expression::Boolean(b) if b.value => {
35615 self.write_keyword("MATCHED");
35616 }
35617 _ => {
35618 self.write_keyword("NOT MATCHED");
35619 }
35620 }
35621 } else {
35622 self.write_keyword("NOT MATCHED");
35623 }
35624
35625 if self.config.matched_by_source {
35630 if let Some(source) = &e.source {
35631 if let Expression::Boolean(b) = source.as_ref() {
35632 if b.value {
35633 self.write_space();
35635 self.write_keyword("BY SOURCE");
35636 }
35637 } else {
35639 self.write_space();
35641 self.write_keyword("BY SOURCE");
35642 }
35643 }
35644 }
35645
35646 if let Some(condition) = &e.condition {
35648 self.write_space();
35649 self.write_keyword("AND");
35650 self.write_space();
35651 self.generate_expression(condition)?;
35652 }
35653
35654 self.write_space();
35655 self.write_keyword("THEN");
35656 self.write_space();
35657
35658 self.generate_merge_action(&e.then)?;
35661
35662 Ok(())
35663 }
35664
35665 fn generate_merge_action(&mut self, action: &Expression) -> Result<()> {
35666 match action {
35667 Expression::Tuple(tuple) => {
35668 let elements = &tuple.expressions;
35669 if elements.is_empty() {
35670 return self.generate_expression(action);
35671 }
35672 match &elements[0] {
35674 Expression::Var(v) if v.this == "INSERT" => {
35675 self.write_keyword("INSERT");
35676 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
35678 self.write(" *");
35679 } else {
35680 let mut values_idx = 1;
35681 if elements.len() > 1 {
35683 if let Expression::Tuple(cols) = &elements[1] {
35684 if elements.len() > 2 {
35686 self.write(" (");
35688 for (i, col) in cols.expressions.iter().enumerate() {
35689 if i > 0 {
35690 self.write(", ");
35691 }
35692 if !self.merge_strip_qualifiers.is_empty() {
35694 let stripped = self.strip_merge_qualifier(col);
35695 self.generate_expression(&stripped)?;
35696 } else {
35697 self.generate_expression(col)?;
35698 }
35699 }
35700 self.write(")");
35701 values_idx = 2;
35702 } else {
35703 values_idx = 1;
35705 }
35706 }
35707 }
35708 if values_idx < elements.len() {
35710 let is_row = matches!(&elements[values_idx], Expression::Var(v) if v.this == "ROW");
35712 if !is_row {
35713 self.write_space();
35714 self.write_keyword("VALUES");
35715 }
35716 self.write(" ");
35717 if let Expression::Tuple(vals) = &elements[values_idx] {
35718 self.write("(");
35719 for (i, val) in vals.expressions.iter().enumerate() {
35720 if i > 0 {
35721 self.write(", ");
35722 }
35723 self.generate_expression(val)?;
35724 }
35725 self.write(")");
35726 } else {
35727 self.generate_expression(&elements[values_idx])?;
35728 }
35729 }
35730 } }
35732 Expression::Var(v) if v.this == "UPDATE" => {
35733 self.write_keyword("UPDATE");
35734 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
35736 self.write(" *");
35737 } else if elements.len() > 1 {
35738 self.write_space();
35739 self.write_keyword("SET");
35740 if self.config.pretty {
35742 self.write_newline();
35743 self.indent_level += 1;
35744 self.write_indent();
35745 } else {
35746 self.write_space();
35747 }
35748 if let Expression::Tuple(assignments) = &elements[1] {
35749 for (i, assignment) in assignments.expressions.iter().enumerate() {
35750 if i > 0 {
35751 if self.config.pretty {
35752 self.write(",");
35753 self.write_newline();
35754 self.write_indent();
35755 } else {
35756 self.write(", ");
35757 }
35758 }
35759 if !self.merge_strip_qualifiers.is_empty() {
35761 self.generate_merge_set_assignment(assignment)?;
35762 } else {
35763 self.generate_expression(assignment)?;
35764 }
35765 }
35766 } else {
35767 self.generate_expression(&elements[1])?;
35768 }
35769 if self.config.pretty {
35770 self.indent_level -= 1;
35771 }
35772 }
35773 }
35774 _ => {
35775 self.generate_expression(action)?;
35777 }
35778 }
35779 }
35780 Expression::Var(v)
35781 if v.this == "INSERT"
35782 || v.this == "UPDATE"
35783 || v.this == "DELETE"
35784 || v.this == "DO NOTHING" =>
35785 {
35786 self.write_keyword(&v.this);
35787 }
35788 _ => {
35789 self.generate_expression(action)?;
35790 }
35791 }
35792 Ok(())
35793 }
35794
35795 fn generate_merge_set_assignment(&mut self, assignment: &Expression) -> Result<()> {
35797 match assignment {
35798 Expression::Eq(eq) => {
35799 let stripped_left = self.strip_merge_qualifier(&eq.left);
35801 self.generate_expression(&stripped_left)?;
35802 self.write(" = ");
35803 self.generate_expression(&eq.right)?;
35804 Ok(())
35805 }
35806 other => self.generate_expression(other),
35807 }
35808 }
35809
35810 fn strip_merge_qualifier(&self, expr: &Expression) -> Expression {
35812 match expr {
35813 Expression::Column(col) => {
35814 if let Some(ref table_ident) = col.table {
35815 if self
35816 .merge_strip_qualifiers
35817 .iter()
35818 .any(|n| n.eq_ignore_ascii_case(&table_ident.name))
35819 {
35820 let mut col = col.clone();
35822 col.table = None;
35823 return Expression::Column(col);
35824 }
35825 }
35826 expr.clone()
35827 }
35828 Expression::Dot(dot) => {
35829 if let Expression::Identifier(id) = &dot.this {
35831 if self
35832 .merge_strip_qualifiers
35833 .iter()
35834 .any(|n| n.eq_ignore_ascii_case(&id.name))
35835 {
35836 return Expression::Identifier(dot.field.clone());
35837 }
35838 }
35839 expr.clone()
35840 }
35841 _ => expr.clone(),
35842 }
35843 }
35844
35845 fn generate_whens(&mut self, e: &Whens) -> Result<()> {
35846 for (i, expr) in e.expressions.iter().enumerate() {
35848 if i > 0 {
35849 if self.config.pretty {
35851 self.write_newline();
35852 self.write_indent();
35853 } else {
35854 self.write_space();
35855 }
35856 }
35857 self.generate_expression(expr)?;
35858 }
35859 Ok(())
35860 }
35861
35862 fn generate_where(&mut self, e: &Where) -> Result<()> {
35863 self.write_keyword("WHERE");
35865 self.write_space();
35866 self.generate_expression(&e.this)?;
35867 Ok(())
35868 }
35869
35870 fn generate_width_bucket(&mut self, e: &WidthBucket) -> Result<()> {
35871 self.write_keyword("WIDTH_BUCKET");
35873 self.write("(");
35874 self.generate_expression(&e.this)?;
35875 if let Some(min_value) = &e.min_value {
35876 self.write(", ");
35877 self.generate_expression(min_value)?;
35878 }
35879 if let Some(max_value) = &e.max_value {
35880 self.write(", ");
35881 self.generate_expression(max_value)?;
35882 }
35883 if let Some(num_buckets) = &e.num_buckets {
35884 self.write(", ");
35885 self.generate_expression(num_buckets)?;
35886 }
35887 self.write(")");
35888 Ok(())
35889 }
35890
35891 fn generate_window(&mut self, e: &WindowSpec) -> Result<()> {
35892 self.generate_window_spec(e)
35894 }
35895
35896 fn generate_window_spec(&mut self, e: &WindowSpec) -> Result<()> {
35897 let mut has_content = false;
35899
35900 if !e.partition_by.is_empty() {
35902 self.write_keyword("PARTITION BY");
35903 self.write_space();
35904 for (i, expr) in e.partition_by.iter().enumerate() {
35905 if i > 0 {
35906 self.write(", ");
35907 }
35908 self.generate_expression(expr)?;
35909 }
35910 has_content = true;
35911 }
35912
35913 if !e.order_by.is_empty() {
35915 if has_content {
35916 self.write_space();
35917 }
35918 self.write_keyword("ORDER BY");
35919 self.write_space();
35920 for (i, ordered) in e.order_by.iter().enumerate() {
35921 if i > 0 {
35922 self.write(", ");
35923 }
35924 self.generate_expression(&ordered.this)?;
35925 if ordered.desc {
35926 self.write_space();
35927 self.write_keyword("DESC");
35928 } else if ordered.explicit_asc {
35929 self.write_space();
35930 self.write_keyword("ASC");
35931 }
35932 if let Some(nulls_first) = ordered.nulls_first {
35933 self.write_space();
35934 self.write_keyword("NULLS");
35935 self.write_space();
35936 if nulls_first {
35937 self.write_keyword("FIRST");
35938 } else {
35939 self.write_keyword("LAST");
35940 }
35941 }
35942 }
35943 has_content = true;
35944 }
35945
35946 if let Some(frame) = &e.frame {
35948 if has_content {
35949 self.write_space();
35950 }
35951 self.generate_window_frame(frame)?;
35952 }
35953
35954 Ok(())
35955 }
35956
35957 fn generate_with_data_property(&mut self, e: &WithDataProperty) -> Result<()> {
35958 self.write_keyword("WITH");
35960 self.write_space();
35961 if e.no.is_some() {
35962 self.write_keyword("NO");
35963 self.write_space();
35964 }
35965 self.write_keyword("DATA");
35966
35967 if let Some(statistics) = &e.statistics {
35969 self.write_space();
35970 self.write_keyword("AND");
35971 self.write_space();
35972 match statistics.as_ref() {
35974 Expression::Boolean(b) if !b.value => {
35975 self.write_keyword("NO");
35976 self.write_space();
35977 }
35978 _ => {}
35979 }
35980 self.write_keyword("STATISTICS");
35981 }
35982 Ok(())
35983 }
35984
35985 fn generate_with_fill(&mut self, e: &WithFill) -> Result<()> {
35986 self.write_keyword("WITH FILL");
35988
35989 if let Some(from_) = &e.from_ {
35990 self.write_space();
35991 self.write_keyword("FROM");
35992 self.write_space();
35993 self.generate_expression(from_)?;
35994 }
35995
35996 if let Some(to) = &e.to {
35997 self.write_space();
35998 self.write_keyword("TO");
35999 self.write_space();
36000 self.generate_expression(to)?;
36001 }
36002
36003 if let Some(step) = &e.step {
36004 self.write_space();
36005 self.write_keyword("STEP");
36006 self.write_space();
36007 self.generate_expression(step)?;
36008 }
36009
36010 if let Some(staleness) = &e.staleness {
36011 self.write_space();
36012 self.write_keyword("STALENESS");
36013 self.write_space();
36014 self.generate_expression(staleness)?;
36015 }
36016
36017 if let Some(interpolate) = &e.interpolate {
36018 self.write_space();
36019 self.write_keyword("INTERPOLATE");
36020 self.write(" (");
36021 self.generate_interpolate_item(interpolate)?;
36023 self.write(")");
36024 }
36025
36026 Ok(())
36027 }
36028
36029 fn generate_interpolate_item(&mut self, expr: &Expression) -> Result<()> {
36031 match expr {
36032 Expression::Alias(alias) => {
36033 self.generate_identifier(&alias.alias)?;
36035 self.write_space();
36036 self.write_keyword("AS");
36037 self.write_space();
36038 self.generate_expression(&alias.this)?;
36039 }
36040 Expression::Tuple(tuple) => {
36041 for (i, item) in tuple.expressions.iter().enumerate() {
36042 if i > 0 {
36043 self.write(", ");
36044 }
36045 self.generate_interpolate_item(item)?;
36046 }
36047 }
36048 other => {
36049 self.generate_expression(other)?;
36050 }
36051 }
36052 Ok(())
36053 }
36054
36055 fn generate_with_journal_table_property(&mut self, e: &WithJournalTableProperty) -> Result<()> {
36056 self.write_keyword("WITH JOURNAL TABLE");
36058 self.write("=");
36059 self.generate_expression(&e.this)?;
36060 Ok(())
36061 }
36062
36063 fn generate_with_operator(&mut self, e: &WithOperator) -> Result<()> {
36064 self.generate_expression(&e.this)?;
36066 self.write_space();
36067 self.write_keyword("WITH");
36068 self.write_space();
36069 self.write_keyword(&e.op);
36070 Ok(())
36071 }
36072
36073 fn generate_with_procedure_options(&mut self, e: &WithProcedureOptions) -> Result<()> {
36074 self.write_keyword("WITH");
36076 self.write_space();
36077 for (i, expr) in e.expressions.iter().enumerate() {
36078 if i > 0 {
36079 self.write(", ");
36080 }
36081 self.generate_expression(expr)?;
36082 }
36083 Ok(())
36084 }
36085
36086 fn generate_with_schema_binding_property(
36087 &mut self,
36088 e: &WithSchemaBindingProperty,
36089 ) -> Result<()> {
36090 self.write_keyword("WITH");
36092 self.write_space();
36093 self.generate_expression(&e.this)?;
36094 Ok(())
36095 }
36096
36097 fn generate_with_system_versioning_property(
36098 &mut self,
36099 e: &WithSystemVersioningProperty,
36100 ) -> Result<()> {
36101 let mut parts = Vec::new();
36107
36108 if let Some(this) = &e.this {
36109 let mut s = String::from("HISTORY_TABLE=");
36111 let mut gen = Generator::new();
36112 gen.generate_expression(this)?;
36113 s.push_str(&gen.output);
36114 parts.push(s);
36115 }
36116
36117 if let Some(data_consistency) = &e.data_consistency {
36118 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
36119 let mut gen = Generator::new();
36120 gen.generate_expression(data_consistency)?;
36121 s.push_str(&gen.output);
36122 parts.push(s);
36123 }
36124
36125 if let Some(retention_period) = &e.retention_period {
36126 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
36127 let mut gen = Generator::new();
36128 gen.generate_expression(retention_period)?;
36129 s.push_str(&gen.output);
36130 parts.push(s);
36131 }
36132
36133 self.write_keyword("SYSTEM_VERSIONING");
36134 self.write("=");
36135
36136 if !parts.is_empty() {
36137 self.write_keyword("ON");
36138 self.write("(");
36139 self.write(&parts.join(", "));
36140 self.write(")");
36141 } else if e.on.is_some() {
36142 self.write_keyword("ON");
36143 } else {
36144 self.write_keyword("OFF");
36145 }
36146
36147 if e.with_.is_some() {
36149 let inner = self.output.clone();
36150 self.output.clear();
36151 self.write("WITH(");
36152 self.write(&inner);
36153 self.write(")");
36154 }
36155
36156 Ok(())
36157 }
36158
36159 fn generate_with_table_hint(&mut self, e: &WithTableHint) -> Result<()> {
36160 self.write_keyword("WITH");
36162 self.write(" (");
36163 for (i, expr) in e.expressions.iter().enumerate() {
36164 if i > 0 {
36165 self.write(", ");
36166 }
36167 self.generate_expression(expr)?;
36168 }
36169 self.write(")");
36170 Ok(())
36171 }
36172
36173 fn generate_xml_element(&mut self, e: &XMLElement) -> Result<()> {
36174 self.write_keyword("XMLELEMENT");
36177 self.write("(");
36178
36179 if e.evalname.is_some() {
36180 self.write_keyword("EVALNAME");
36181 } else {
36182 self.write_keyword("NAME");
36183 }
36184 self.write_space();
36185 self.generate_expression(&e.this)?;
36186
36187 for expr in &e.expressions {
36188 self.write(", ");
36189 self.generate_expression(expr)?;
36190 }
36191 self.write(")");
36192 Ok(())
36193 }
36194
36195 fn generate_xml_get(&mut self, e: &XMLGet) -> Result<()> {
36196 self.write_keyword("XMLGET");
36198 self.write("(");
36199 self.generate_expression(&e.this)?;
36200 self.write(", ");
36201 self.generate_expression(&e.expression)?;
36202 if let Some(instance) = &e.instance {
36203 self.write(", ");
36204 self.generate_expression(instance)?;
36205 }
36206 self.write(")");
36207 Ok(())
36208 }
36209
36210 fn generate_xml_key_value_option(&mut self, e: &XMLKeyValueOption) -> Result<()> {
36211 self.generate_expression(&e.this)?;
36213 if let Some(expression) = &e.expression {
36214 self.write("(");
36215 self.generate_expression(expression)?;
36216 self.write(")");
36217 }
36218 Ok(())
36219 }
36220
36221 fn generate_xml_table(&mut self, e: &XMLTable) -> Result<()> {
36222 self.write_keyword("XMLTABLE");
36224 self.write("(");
36225
36226 if self.config.pretty {
36227 self.indent_level += 1;
36228 self.write_newline();
36229 self.write_indent();
36230 self.generate_expression(&e.this)?;
36231
36232 if let Some(passing) = &e.passing {
36233 self.write_newline();
36234 self.write_indent();
36235 self.write_keyword("PASSING");
36236 if let Expression::Tuple(tuple) = passing.as_ref() {
36237 for expr in &tuple.expressions {
36238 self.write_newline();
36239 self.indent_level += 1;
36240 self.write_indent();
36241 self.generate_expression(expr)?;
36242 self.indent_level -= 1;
36243 }
36244 } else {
36245 self.write_newline();
36246 self.indent_level += 1;
36247 self.write_indent();
36248 self.generate_expression(passing)?;
36249 self.indent_level -= 1;
36250 }
36251 }
36252
36253 if e.by_ref.is_some() {
36254 self.write_newline();
36255 self.write_indent();
36256 self.write_keyword("RETURNING SEQUENCE BY REF");
36257 }
36258
36259 if !e.columns.is_empty() {
36260 self.write_newline();
36261 self.write_indent();
36262 self.write_keyword("COLUMNS");
36263 for (i, col) in e.columns.iter().enumerate() {
36264 self.write_newline();
36265 self.indent_level += 1;
36266 self.write_indent();
36267 self.generate_expression(col)?;
36268 self.indent_level -= 1;
36269 if i < e.columns.len() - 1 {
36270 self.write(",");
36271 }
36272 }
36273 }
36274
36275 self.indent_level -= 1;
36276 self.write_newline();
36277 self.write_indent();
36278 self.write(")");
36279 return Ok(());
36280 }
36281
36282 if let Some(namespaces) = &e.namespaces {
36284 self.write_keyword("XMLNAMESPACES");
36285 self.write("(");
36286 if let Expression::Tuple(tuple) = namespaces.as_ref() {
36288 for (i, expr) in tuple.expressions.iter().enumerate() {
36289 if i > 0 {
36290 self.write(", ");
36291 }
36292 if !matches!(expr, Expression::Alias(_)) {
36295 self.write_keyword("DEFAULT");
36296 self.write_space();
36297 }
36298 self.generate_expression(expr)?;
36299 }
36300 } else {
36301 if !matches!(namespaces.as_ref(), Expression::Alias(_)) {
36303 self.write_keyword("DEFAULT");
36304 self.write_space();
36305 }
36306 self.generate_expression(namespaces)?;
36307 }
36308 self.write("), ");
36309 }
36310
36311 self.generate_expression(&e.this)?;
36313
36314 if let Some(passing) = &e.passing {
36316 self.write_space();
36317 self.write_keyword("PASSING");
36318 self.write_space();
36319 if let Expression::Tuple(tuple) = passing.as_ref() {
36321 for (i, expr) in tuple.expressions.iter().enumerate() {
36322 if i > 0 {
36323 self.write(", ");
36324 }
36325 self.generate_expression(expr)?;
36326 }
36327 } else {
36328 self.generate_expression(passing)?;
36329 }
36330 }
36331
36332 if e.by_ref.is_some() {
36334 self.write_space();
36335 self.write_keyword("RETURNING SEQUENCE BY REF");
36336 }
36337
36338 if !e.columns.is_empty() {
36340 self.write_space();
36341 self.write_keyword("COLUMNS");
36342 self.write_space();
36343 for (i, col) in e.columns.iter().enumerate() {
36344 if i > 0 {
36345 self.write(", ");
36346 }
36347 self.generate_expression(col)?;
36348 }
36349 }
36350
36351 self.write(")");
36352 Ok(())
36353 }
36354
36355 fn generate_xor(&mut self, e: &Xor) -> Result<()> {
36356 if let Some(this) = &e.this {
36359 self.generate_expression(this)?;
36360 if let Some(expression) = &e.expression {
36361 self.write_space();
36362 self.write_keyword("XOR");
36363 self.write_space();
36364 self.generate_expression(expression)?;
36365 }
36366 }
36367
36368 for (i, expr) in e.expressions.iter().enumerate() {
36370 if i > 0 || e.this.is_some() {
36371 self.write_space();
36372 self.write_keyword("XOR");
36373 self.write_space();
36374 }
36375 self.generate_expression(expr)?;
36376 }
36377 Ok(())
36378 }
36379
36380 fn generate_zipf(&mut self, e: &Zipf) -> Result<()> {
36381 self.write_keyword("ZIPF");
36383 self.write("(");
36384 self.generate_expression(&e.this)?;
36385 if let Some(elementcount) = &e.elementcount {
36386 self.write(", ");
36387 self.generate_expression(elementcount)?;
36388 }
36389 if let Some(gen) = &e.gen {
36390 self.write(", ");
36391 self.generate_expression(gen)?;
36392 }
36393 self.write(")");
36394 Ok(())
36395 }
36396}
36397
36398impl Default for Generator {
36399 fn default() -> Self {
36400 Self::new()
36401 }
36402}
36403
36404#[cfg(test)]
36405mod tests {
36406 use super::*;
36407 use crate::parser::Parser;
36408
36409 fn roundtrip(sql: &str) -> String {
36410 let ast = Parser::parse_sql(sql).unwrap();
36411 Generator::sql(&ast[0]).unwrap()
36412 }
36413
36414 #[test]
36415 fn test_simple_select() {
36416 let result = roundtrip("SELECT 1");
36417 assert_eq!(result, "SELECT 1");
36418 }
36419
36420 #[test]
36421 fn test_select_from() {
36422 let result = roundtrip("SELECT a, b FROM t");
36423 assert_eq!(result, "SELECT a, b FROM t");
36424 }
36425
36426 #[test]
36427 fn test_select_where() {
36428 let result = roundtrip("SELECT * FROM t WHERE x = 1");
36429 assert_eq!(result, "SELECT * FROM t WHERE x = 1");
36430 }
36431
36432 #[test]
36433 fn test_select_join() {
36434 let result = roundtrip("SELECT * FROM a JOIN b ON a.id = b.id");
36435 assert_eq!(result, "SELECT * FROM a JOIN b ON a.id = b.id");
36436 }
36437
36438 #[test]
36439 fn test_insert() {
36440 let result = roundtrip("INSERT INTO t (a, b) VALUES (1, 2)");
36441 assert_eq!(result, "INSERT INTO t (a, b) VALUES (1, 2)");
36442 }
36443
36444 #[test]
36445 fn test_pretty_print() {
36446 let ast = Parser::parse_sql("SELECT a, b FROM t WHERE x = 1").unwrap();
36447 let result = Generator::pretty_sql(&ast[0]).unwrap();
36448 assert!(result.contains('\n'));
36449 }
36450
36451 #[test]
36452 fn test_window_function() {
36453 let result = roundtrip("SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)");
36454 assert_eq!(
36455 result,
36456 "SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)"
36457 );
36458 }
36459
36460 #[test]
36461 fn test_window_function_with_frame() {
36462 let result = roundtrip("SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
36463 assert_eq!(result, "SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
36464 }
36465
36466 #[test]
36467 fn test_aggregate_with_filter() {
36468 let result = roundtrip("SELECT COUNT(*) FILTER (WHERE status = 1) FROM orders");
36469 assert_eq!(
36470 result,
36471 "SELECT COUNT(*) FILTER(WHERE status = 1) FROM orders"
36472 );
36473 }
36474
36475 #[test]
36476 fn test_subscript() {
36477 let result = roundtrip("SELECT arr[0]");
36478 assert_eq!(result, "SELECT arr[0]");
36479 }
36480
36481 #[test]
36483 fn test_create_table() {
36484 let result = roundtrip("CREATE TABLE users (id INT, name VARCHAR(100))");
36485 assert_eq!(result, "CREATE TABLE users (id INT, name VARCHAR(100))");
36486 }
36487
36488 #[test]
36489 fn test_create_table_with_constraints() {
36490 let result = roundtrip(
36491 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)",
36492 );
36493 assert_eq!(
36494 result,
36495 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)"
36496 );
36497 }
36498
36499 #[test]
36500 fn test_create_table_if_not_exists() {
36501 let result = roundtrip("CREATE TABLE IF NOT EXISTS t (id INT)");
36502 assert_eq!(result, "CREATE TABLE IF NOT EXISTS t (id INT)");
36503 }
36504
36505 #[test]
36506 fn test_drop_table() {
36507 let result = roundtrip("DROP TABLE users");
36508 assert_eq!(result, "DROP TABLE users");
36509 }
36510
36511 #[test]
36512 fn test_drop_table_if_exists_cascade() {
36513 let result = roundtrip("DROP TABLE IF EXISTS users CASCADE");
36514 assert_eq!(result, "DROP TABLE IF EXISTS users CASCADE");
36515 }
36516
36517 #[test]
36518 fn test_alter_table_add_column() {
36519 let result = roundtrip("ALTER TABLE users ADD COLUMN email VARCHAR(255)");
36520 assert_eq!(result, "ALTER TABLE users ADD COLUMN email VARCHAR(255)");
36521 }
36522
36523 #[test]
36524 fn test_alter_table_drop_column() {
36525 let result = roundtrip("ALTER TABLE users DROP COLUMN email");
36526 assert_eq!(result, "ALTER TABLE users DROP COLUMN email");
36527 }
36528
36529 #[test]
36530 fn test_create_index() {
36531 let result = roundtrip("CREATE INDEX idx_name ON users(name)");
36532 assert_eq!(result, "CREATE INDEX idx_name ON users(name)");
36533 }
36534
36535 #[test]
36536 fn test_create_unique_index() {
36537 let result = roundtrip("CREATE UNIQUE INDEX idx_email ON users(email)");
36538 assert_eq!(result, "CREATE UNIQUE INDEX idx_email ON users(email)");
36539 }
36540
36541 #[test]
36542 fn test_drop_index() {
36543 let result = roundtrip("DROP INDEX idx_name");
36544 assert_eq!(result, "DROP INDEX idx_name");
36545 }
36546
36547 #[test]
36548 fn test_create_view() {
36549 let result = roundtrip("CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1");
36550 assert_eq!(
36551 result,
36552 "CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1"
36553 );
36554 }
36555
36556 #[test]
36557 fn test_drop_view() {
36558 let result = roundtrip("DROP VIEW active_users");
36559 assert_eq!(result, "DROP VIEW active_users");
36560 }
36561
36562 #[test]
36563 fn test_truncate() {
36564 let result = roundtrip("TRUNCATE TABLE users");
36565 assert_eq!(result, "TRUNCATE TABLE users");
36566 }
36567
36568 #[test]
36569 fn test_string_literal_escaping_default() {
36570 let result = roundtrip("SELECT 'hello'");
36572 assert_eq!(result, "SELECT 'hello'");
36573
36574 let result = roundtrip("SELECT 'it''s a test'");
36576 assert_eq!(result, "SELECT 'it''s a test'");
36577 }
36578
36579 #[test]
36580 fn test_not_in_style_prefix_default_generic() {
36581 let result = roundtrip("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')");
36582 assert_eq!(
36583 result,
36584 "SELECT id FROM users WHERE NOT status IN ('deleted', 'banned')"
36585 );
36586 }
36587
36588 #[test]
36589 fn test_not_in_style_infix_generic_override() {
36590 let ast =
36591 Parser::parse_sql("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')")
36592 .unwrap();
36593 let config = GeneratorConfig {
36594 not_in_style: NotInStyle::Infix,
36595 ..Default::default()
36596 };
36597 let mut gen = Generator::with_config(config);
36598 let result = gen.generate(&ast[0]).unwrap();
36599 assert_eq!(
36600 result,
36601 "SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')"
36602 );
36603 }
36604
36605 #[test]
36606 fn test_string_literal_escaping_mysql() {
36607 use crate::dialects::DialectType;
36608
36609 let config = GeneratorConfig {
36610 dialect: Some(DialectType::MySQL),
36611 ..Default::default()
36612 };
36613
36614 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
36615 let mut gen = Generator::with_config(config.clone());
36616 let result = gen.generate(&ast[0]).unwrap();
36617 assert_eq!(result, "SELECT 'hello'");
36618
36619 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
36621 let mut gen = Generator::with_config(config.clone());
36622 let result = gen.generate(&ast[0]).unwrap();
36623 assert_eq!(result, "SELECT 'it''s'");
36624 }
36625
36626 #[test]
36627 fn test_string_literal_escaping_postgres() {
36628 use crate::dialects::DialectType;
36629
36630 let config = GeneratorConfig {
36631 dialect: Some(DialectType::PostgreSQL),
36632 ..Default::default()
36633 };
36634
36635 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
36636 let mut gen = Generator::with_config(config.clone());
36637 let result = gen.generate(&ast[0]).unwrap();
36638 assert_eq!(result, "SELECT 'hello'");
36639
36640 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
36642 let mut gen = Generator::with_config(config.clone());
36643 let result = gen.generate(&ast[0]).unwrap();
36644 assert_eq!(result, "SELECT 'it''s'");
36645 }
36646
36647 #[test]
36648 fn test_string_literal_escaping_bigquery() {
36649 use crate::dialects::DialectType;
36650
36651 let config = GeneratorConfig {
36652 dialect: Some(DialectType::BigQuery),
36653 ..Default::default()
36654 };
36655
36656 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
36657 let mut gen = Generator::with_config(config.clone());
36658 let result = gen.generate(&ast[0]).unwrap();
36659 assert_eq!(result, "SELECT 'hello'");
36660
36661 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
36663 let mut gen = Generator::with_config(config.clone());
36664 let result = gen.generate(&ast[0]).unwrap();
36665 assert_eq!(result, "SELECT 'it\\'s'");
36666 }
36667
36668 #[test]
36669 fn test_generate_deep_and_chain_without_stack_growth() {
36670 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
36671 Expression::column("c0"),
36672 Expression::number(0),
36673 )));
36674
36675 for i in 1..2500 {
36676 let predicate = Expression::Eq(Box::new(BinaryOp::new(
36677 Expression::column(format!("c{i}")),
36678 Expression::number(i as i64),
36679 )));
36680 expr = Expression::And(Box::new(BinaryOp::new(expr, predicate)));
36681 }
36682
36683 let sql = Generator::sql(&expr).expect("deep AND chain should generate");
36684 assert!(sql.contains("c2499 = 2499"), "{}", sql);
36685 }
36686
36687 #[test]
36688 fn test_generate_deep_or_chain_without_stack_growth() {
36689 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
36690 Expression::column("c0"),
36691 Expression::number(0),
36692 )));
36693
36694 for i in 1..2500 {
36695 let predicate = Expression::Eq(Box::new(BinaryOp::new(
36696 Expression::column(format!("c{i}")),
36697 Expression::number(i as i64),
36698 )));
36699 expr = Expression::Or(Box::new(BinaryOp::new(expr, predicate)));
36700 }
36701
36702 let sql = Generator::sql(&expr).expect("deep OR chain should generate");
36703 assert!(sql.contains("c2499 = 2499"), "{}", sql);
36704 }
36705}