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 });
3814 }
3815 self.write(&v.this);
3816 Ok(())
3817 }
3818 Expression::Variadic(e) => {
3819 self.write_keyword("VARIADIC");
3820 self.write_space();
3821 self.generate_expression(&e.this)?;
3822 Ok(())
3823 }
3824 Expression::VarMap(e) => self.generate_var_map(e),
3825 Expression::VectorSearch(e) => self.generate_vector_search(e),
3826 Expression::Version(e) => self.generate_version(e),
3827 Expression::ViewAttributeProperty(e) => self.generate_view_attribute_property(e),
3828 Expression::VolatileProperty(e) => self.generate_volatile_property(e),
3829 Expression::WatermarkColumnConstraint(e) => {
3830 self.generate_watermark_column_constraint(e)
3831 }
3832 Expression::Week(e) => self.generate_week(e),
3833 Expression::When(e) => self.generate_when(e),
3834 Expression::Whens(e) => self.generate_whens(e),
3835 Expression::Where(e) => self.generate_where(e),
3836 Expression::WidthBucket(e) => self.generate_width_bucket(e),
3837 Expression::Window(e) => self.generate_window(e),
3838 Expression::WindowSpec(e) => self.generate_window_spec(e),
3839 Expression::WithDataProperty(e) => self.generate_with_data_property(e),
3840 Expression::WithFill(e) => self.generate_with_fill(e),
3841 Expression::WithJournalTableProperty(e) => self.generate_with_journal_table_property(e),
3842 Expression::WithOperator(e) => self.generate_with_operator(e),
3843 Expression::WithProcedureOptions(e) => self.generate_with_procedure_options(e),
3844 Expression::WithSchemaBindingProperty(e) => {
3845 self.generate_with_schema_binding_property(e)
3846 }
3847 Expression::WithSystemVersioningProperty(e) => {
3848 self.generate_with_system_versioning_property(e)
3849 }
3850 Expression::WithTableHint(e) => self.generate_with_table_hint(e),
3851 Expression::XMLElement(e) => self.generate_xml_element(e),
3852 Expression::XMLGet(e) => self.generate_xml_get(e),
3853 Expression::XMLKeyValueOption(e) => self.generate_xml_key_value_option(e),
3854 Expression::XMLTable(e) => self.generate_xml_table(e),
3855 Expression::Xor(e) => self.generate_xor(e),
3856 Expression::Zipf(e) => self.generate_zipf(e),
3857 _ => {
3858 self.write(&format!("/* unimplemented: {:?} */", expr));
3860 Ok(())
3861 }
3862 }
3863 }
3864
3865 fn generate_select(&mut self, select: &Select) -> Result<()> {
3866 use crate::dialects::DialectType;
3867
3868 for comment in &select.leading_comments {
3870 self.write_formatted_comment(comment);
3871 self.write(" ");
3872 }
3873
3874 if let Some(with) = &select.with {
3876 self.generate_with(with)?;
3877 if self.config.pretty {
3878 self.write_newline();
3879 self.write_indent();
3880 } else {
3881 self.write_space();
3882 }
3883 }
3884
3885 for comment in &select.post_select_comments {
3888 self.write_formatted_comment(comment);
3889 self.write(" ");
3890 }
3891
3892 self.write_keyword("SELECT");
3893
3894 if let Some(hint) = &select.hint {
3896 self.generate_hint(hint)?;
3897 }
3898
3899 let use_top_from_limit = matches!(self.config.dialect, Some(DialectType::TSQL))
3903 && select.top.is_none()
3904 && select.limit.is_some()
3905 && select.offset.is_none(); let is_top_dialect = matches!(
3910 self.config.dialect,
3911 Some(DialectType::TSQL) | Some(DialectType::Teradata) | Some(DialectType::Fabric)
3912 );
3913 let keep_top_verbatim = !is_top_dialect
3914 && select.limit.is_none()
3915 && select
3916 .top
3917 .as_ref()
3918 .map_or(false, |top| top.percent || top.with_ties);
3919
3920 if select.distinct && (is_top_dialect || select.top.is_some()) {
3921 self.write_space();
3922 self.write_keyword("DISTINCT");
3923 }
3924
3925 if is_top_dialect || keep_top_verbatim {
3926 if let Some(top) = &select.top {
3927 self.write_space();
3928 self.write_keyword("TOP");
3929 if top.parenthesized {
3930 self.write(" (");
3931 self.generate_expression(&top.this)?;
3932 self.write(")");
3933 } else {
3934 self.write_space();
3935 self.generate_expression(&top.this)?;
3936 }
3937 if top.percent {
3938 self.write_space();
3939 self.write_keyword("PERCENT");
3940 }
3941 if top.with_ties {
3942 self.write_space();
3943 self.write_keyword("WITH TIES");
3944 }
3945 } else if use_top_from_limit {
3946 if let Some(limit) = &select.limit {
3948 self.write_space();
3949 self.write_keyword("TOP");
3950 let is_simple_literal =
3952 matches!(&limit.this, Expression::Literal(Literal::Number(_)));
3953 if is_simple_literal {
3954 self.write_space();
3955 self.generate_expression(&limit.this)?;
3956 } else {
3957 self.write(" (");
3958 self.generate_expression(&limit.this)?;
3959 self.write(")");
3960 }
3961 }
3962 }
3963 }
3964
3965 if select.distinct && !is_top_dialect && select.top.is_none() {
3966 self.write_space();
3967 self.write_keyword("DISTINCT");
3968 }
3969
3970 if let Some(distinct_on) = &select.distinct_on {
3972 self.write_space();
3973 self.write_keyword("ON");
3974 self.write(" (");
3975 for (i, expr) in distinct_on.iter().enumerate() {
3976 if i > 0 {
3977 self.write(", ");
3978 }
3979 self.generate_expression(expr)?;
3980 }
3981 self.write(")");
3982 }
3983
3984 for modifier in &select.operation_modifiers {
3986 self.write_space();
3987 self.write_keyword(modifier);
3988 }
3989
3990 if let Some(kind) = &select.kind {
3992 self.write_space();
3993 self.write_keyword("AS");
3994 self.write_space();
3995 self.write_keyword(kind);
3996 }
3997
3998 if !select.expressions.is_empty() {
4000 if self.config.pretty {
4001 self.write_newline();
4002 self.indent_level += 1;
4003 } else {
4004 self.write_space();
4005 }
4006 }
4007
4008 for (i, expr) in select.expressions.iter().enumerate() {
4009 if i > 0 {
4010 self.write(",");
4011 if self.config.pretty {
4012 self.write_newline();
4013 } else {
4014 self.write_space();
4015 }
4016 }
4017 if self.config.pretty {
4018 self.write_indent();
4019 }
4020 self.generate_expression(expr)?;
4021 }
4022
4023 if self.config.pretty && !select.expressions.is_empty() {
4024 self.indent_level -= 1;
4025 }
4026
4027 if let Some(into) = &select.into {
4030 if self.config.pretty {
4031 self.write_newline();
4032 self.write_indent();
4033 } else {
4034 self.write_space();
4035 }
4036 if into.bulk_collect {
4037 self.write_keyword("BULK COLLECT INTO");
4038 } else {
4039 self.write_keyword("INTO");
4040 }
4041 if into.temporary {
4042 self.write_space();
4043 self.write_keyword("TEMPORARY");
4044 }
4045 if into.unlogged {
4046 self.write_space();
4047 self.write_keyword("UNLOGGED");
4048 }
4049 self.write_space();
4050 if !into.expressions.is_empty() {
4052 for (i, expr) in into.expressions.iter().enumerate() {
4053 if i > 0 {
4054 self.write(", ");
4055 }
4056 self.generate_expression(expr)?;
4057 }
4058 } else {
4059 self.generate_expression(&into.this)?;
4060 }
4061 }
4062
4063 if let Some(from) = &select.from {
4065 if self.config.pretty {
4066 self.write_newline();
4067 self.write_indent();
4068 } else {
4069 self.write_space();
4070 }
4071 self.write_keyword("FROM");
4072 self.write_space();
4073
4074 let has_tablesample = from
4079 .expressions
4080 .iter()
4081 .any(|e| matches!(e, Expression::TableSample(_)));
4082 let is_cross_join_dialect = matches!(
4083 self.config.dialect,
4084 Some(DialectType::BigQuery)
4085 | Some(DialectType::Hive)
4086 | Some(DialectType::Spark)
4087 | Some(DialectType::Databricks)
4088 | Some(DialectType::SQLite)
4089 | Some(DialectType::ClickHouse)
4090 );
4091 let source_is_same_as_target = self.config.source_dialect.is_some()
4094 && self.config.source_dialect == self.config.dialect;
4095 let source_is_cross_join_dialect = matches!(
4096 self.config.source_dialect,
4097 Some(DialectType::BigQuery)
4098 | Some(DialectType::Hive)
4099 | Some(DialectType::Spark)
4100 | Some(DialectType::Databricks)
4101 | Some(DialectType::SQLite)
4102 | Some(DialectType::ClickHouse)
4103 );
4104 let use_cross_join = !has_tablesample
4105 && is_cross_join_dialect
4106 && (source_is_same_as_target
4107 || source_is_cross_join_dialect
4108 || self.config.source_dialect.is_none());
4109
4110 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
4112
4113 for (i, expr) in from.expressions.iter().enumerate() {
4114 if i > 0 {
4115 if use_cross_join {
4116 self.write(" CROSS JOIN ");
4117 } else {
4118 self.write(", ");
4119 }
4120 }
4121 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
4122 self.write("(");
4123 self.generate_expression(expr)?;
4124 self.write(")");
4125 } else {
4126 self.generate_expression(expr)?;
4127 }
4128 }
4129 }
4130
4131 if self.config.pretty {
4135 self.generate_joins_with_nesting(&select.joins)?;
4136 } else {
4137 for join in &select.joins {
4138 self.generate_join(join)?;
4139 }
4140 for join in select.joins.iter().rev() {
4142 if join.deferred_condition {
4143 self.generate_join_condition(join)?;
4144 }
4145 }
4146 }
4147
4148 for lateral_view in &select.lateral_views {
4150 self.generate_lateral_view(lateral_view)?;
4151 }
4152
4153 if let Some(prewhere) = &select.prewhere {
4155 self.write_clause_condition("PREWHERE", prewhere)?;
4156 }
4157
4158 if let Some(where_clause) = &select.where_clause {
4160 self.write_clause_condition("WHERE", &where_clause.this)?;
4161 }
4162
4163 if let Some(connect) = &select.connect {
4165 self.generate_connect(connect)?;
4166 }
4167
4168 if let Some(group_by) = &select.group_by {
4170 if self.config.pretty {
4171 for comment in &group_by.comments {
4173 self.write_newline();
4174 self.write_indent();
4175 self.write_formatted_comment(comment);
4176 }
4177 self.write_newline();
4178 self.write_indent();
4179 } else {
4180 self.write_space();
4181 for comment in &group_by.comments {
4183 self.write_formatted_comment(comment);
4184 self.write_space();
4185 }
4186 }
4187 self.write_keyword("GROUP BY");
4188 match group_by.all {
4190 Some(true) => {
4191 self.write_space();
4192 self.write_keyword("ALL");
4193 }
4194 Some(false) => {
4195 self.write_space();
4196 self.write_keyword("DISTINCT");
4197 }
4198 None => {}
4199 }
4200 if !group_by.expressions.is_empty() {
4201 let mut trailing_cube = false;
4204 let mut trailing_rollup = false;
4205 let mut plain_expressions: Vec<&Expression> = Vec::new();
4206 let mut grouping_sets_expressions: Vec<&Expression> = Vec::new();
4207 let mut cube_expressions: Vec<&Expression> = Vec::new();
4208 let mut rollup_expressions: Vec<&Expression> = Vec::new();
4209
4210 for expr in &group_by.expressions {
4211 match expr {
4212 Expression::Cube(c) if c.expressions.is_empty() => {
4213 trailing_cube = true;
4214 }
4215 Expression::Rollup(r) if r.expressions.is_empty() => {
4216 trailing_rollup = true;
4217 }
4218 Expression::Function(f) if f.name == "CUBE" => {
4219 cube_expressions.push(expr);
4220 }
4221 Expression::Function(f) if f.name == "ROLLUP" => {
4222 rollup_expressions.push(expr);
4223 }
4224 Expression::Function(f) if f.name == "GROUPING SETS" => {
4225 grouping_sets_expressions.push(expr);
4226 }
4227 _ => {
4228 plain_expressions.push(expr);
4229 }
4230 }
4231 }
4232
4233 let mut regular_expressions: Vec<&Expression> = Vec::new();
4235 regular_expressions.extend(plain_expressions);
4236 regular_expressions.extend(grouping_sets_expressions);
4237 regular_expressions.extend(cube_expressions);
4238 regular_expressions.extend(rollup_expressions);
4239
4240 if self.config.pretty {
4241 self.write_newline();
4242 self.indent_level += 1;
4243 self.write_indent();
4244 } else {
4245 self.write_space();
4246 }
4247
4248 for (i, expr) in regular_expressions.iter().enumerate() {
4249 if i > 0 {
4250 if self.config.pretty {
4251 self.write(",");
4252 self.write_newline();
4253 self.write_indent();
4254 } else {
4255 self.write(", ");
4256 }
4257 }
4258 self.generate_expression(expr)?;
4259 }
4260
4261 if self.config.pretty {
4262 self.indent_level -= 1;
4263 }
4264
4265 if trailing_cube {
4267 self.write_space();
4268 self.write_keyword("WITH CUBE");
4269 } else if trailing_rollup {
4270 self.write_space();
4271 self.write_keyword("WITH ROLLUP");
4272 }
4273 }
4274
4275 if group_by.totals {
4277 self.write_space();
4278 self.write_keyword("WITH TOTALS");
4279 }
4280 }
4281
4282 if let Some(having) = &select.having {
4284 if self.config.pretty {
4285 for comment in &having.comments {
4287 self.write_newline();
4288 self.write_indent();
4289 self.write_formatted_comment(comment);
4290 }
4291 } else {
4292 for comment in &having.comments {
4293 self.write_space();
4294 self.write_formatted_comment(comment);
4295 }
4296 }
4297 self.write_clause_condition("HAVING", &having.this)?;
4298 }
4299
4300 if select.qualify_after_window {
4302 if let Some(windows) = &select.windows {
4304 self.write_window_clause(windows)?;
4305 }
4306 if let Some(qualify) = &select.qualify {
4307 self.write_clause_condition("QUALIFY", &qualify.this)?;
4308 }
4309 } else {
4310 if let Some(qualify) = &select.qualify {
4312 self.write_clause_condition("QUALIFY", &qualify.this)?;
4313 }
4314 if let Some(windows) = &select.windows {
4315 self.write_window_clause(windows)?;
4316 }
4317 }
4318
4319 if let Some(distribute_by) = &select.distribute_by {
4321 self.write_clause_expressions("DISTRIBUTE BY", &distribute_by.expressions)?;
4322 }
4323
4324 if let Some(cluster_by) = &select.cluster_by {
4326 self.write_order_clause("CLUSTER BY", &cluster_by.expressions)?;
4327 }
4328
4329 if let Some(sort_by) = &select.sort_by {
4331 self.write_order_clause("SORT BY", &sort_by.expressions)?;
4332 }
4333
4334 if let Some(order_by) = &select.order_by {
4336 if self.config.pretty {
4337 for comment in &order_by.comments {
4339 self.write_newline();
4340 self.write_indent();
4341 self.write_formatted_comment(comment);
4342 }
4343 } else {
4344 for comment in &order_by.comments {
4345 self.write_space();
4346 self.write_formatted_comment(comment);
4347 }
4348 }
4349 let keyword = if order_by.siblings {
4350 "ORDER SIBLINGS BY"
4351 } else {
4352 "ORDER BY"
4353 };
4354 self.write_order_clause(keyword, &order_by.expressions)?;
4355 }
4356
4357 if select.order_by.is_none()
4359 && select.fetch.is_some()
4360 && matches!(
4361 self.config.dialect,
4362 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4363 )
4364 {
4365 if self.config.pretty {
4366 self.write_newline();
4367 self.write_indent();
4368 } else {
4369 self.write_space();
4370 }
4371 self.write_keyword("ORDER BY (SELECT NULL) OFFSET 0 ROWS");
4372 }
4373
4374 let is_presto_like = matches!(
4379 self.config.dialect,
4380 Some(DialectType::Presto) | Some(DialectType::Trino)
4381 );
4382
4383 if is_presto_like && select.offset.is_some() {
4384 if let Some(offset) = &select.offset {
4386 if self.config.pretty {
4387 self.write_newline();
4388 self.write_indent();
4389 } else {
4390 self.write_space();
4391 }
4392 self.write_keyword("OFFSET");
4393 self.write_space();
4394 self.write_limit_expr(&offset.this)?;
4395 if offset.rows == Some(true) {
4396 self.write_space();
4397 self.write_keyword("ROWS");
4398 }
4399 }
4400 if let Some(limit) = &select.limit {
4401 if self.config.pretty {
4402 self.write_newline();
4403 self.write_indent();
4404 } else {
4405 self.write_space();
4406 }
4407 self.write_keyword("LIMIT");
4408 self.write_space();
4409 self.write_limit_expr(&limit.this)?;
4410 if limit.percent {
4411 self.write_space();
4412 self.write_keyword("PERCENT");
4413 }
4414 for comment in &limit.comments {
4416 self.write(" ");
4417 self.write_formatted_comment(comment);
4418 }
4419 }
4420 } else {
4421 let fetch_as_limit = select.fetch.as_ref().map_or(false, |fetch| {
4423 !fetch.percent
4424 && !fetch.with_ties
4425 && fetch.count.is_some()
4426 && matches!(
4427 self.config.dialect,
4428 Some(DialectType::Spark)
4429 | Some(DialectType::Hive)
4430 | Some(DialectType::DuckDB)
4431 | Some(DialectType::SQLite)
4432 | Some(DialectType::MySQL)
4433 | Some(DialectType::BigQuery)
4434 | Some(DialectType::Databricks)
4435 | Some(DialectType::StarRocks)
4436 | Some(DialectType::Doris)
4437 | Some(DialectType::Athena)
4438 | Some(DialectType::ClickHouse)
4439 | Some(DialectType::Redshift)
4440 )
4441 });
4442
4443 if let Some(limit) = &select.limit {
4445 if !matches!(self.config.dialect, Some(DialectType::TSQL)) {
4447 if self.config.pretty {
4448 self.write_newline();
4449 self.write_indent();
4450 } else {
4451 self.write_space();
4452 }
4453 self.write_keyword("LIMIT");
4454 self.write_space();
4455 self.write_limit_expr(&limit.this)?;
4456 if limit.percent {
4457 self.write_space();
4458 self.write_keyword("PERCENT");
4459 }
4460 for comment in &limit.comments {
4462 self.write(" ");
4463 self.write_formatted_comment(comment);
4464 }
4465 }
4466 }
4467
4468 if select.top.is_some() && !is_top_dialect && select.limit.is_none() {
4470 if let Some(top) = &select.top {
4471 if !top.percent && !top.with_ties {
4472 if self.config.pretty {
4473 self.write_newline();
4474 self.write_indent();
4475 } else {
4476 self.write_space();
4477 }
4478 self.write_keyword("LIMIT");
4479 self.write_space();
4480 self.generate_expression(&top.this)?;
4481 }
4482 }
4483 }
4484
4485 if fetch_as_limit && select.offset.is_some() {
4488 if let Some(fetch) = &select.fetch {
4489 if self.config.pretty {
4490 self.write_newline();
4491 self.write_indent();
4492 } else {
4493 self.write_space();
4494 }
4495 self.write_keyword("LIMIT");
4496 self.write_space();
4497 self.generate_expression(fetch.count.as_ref().unwrap())?;
4498 }
4499 }
4500
4501 if let Some(offset) = &select.offset {
4505 if self.config.pretty {
4506 self.write_newline();
4507 self.write_indent();
4508 } else {
4509 self.write_space();
4510 }
4511 if matches!(self.config.dialect, Some(DialectType::TSQL)) {
4512 self.write_keyword("OFFSET");
4514 self.write_space();
4515 self.write_limit_expr(&offset.this)?;
4516 self.write_space();
4517 self.write_keyword("ROWS");
4518 if let Some(limit) = &select.limit {
4520 self.write_space();
4521 self.write_keyword("FETCH NEXT");
4522 self.write_space();
4523 self.write_limit_expr(&limit.this)?;
4524 self.write_space();
4525 self.write_keyword("ROWS ONLY");
4526 }
4527 } else {
4528 self.write_keyword("OFFSET");
4529 self.write_space();
4530 self.write_limit_expr(&offset.this)?;
4531 if offset.rows == Some(true) {
4533 self.write_space();
4534 self.write_keyword("ROWS");
4535 }
4536 }
4537 }
4538 }
4539
4540 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4542 if let Some(limit_by) = &select.limit_by {
4543 if !limit_by.is_empty() {
4544 self.write_space();
4545 self.write_keyword("BY");
4546 self.write_space();
4547 for (i, expr) in limit_by.iter().enumerate() {
4548 if i > 0 {
4549 self.write(", ");
4550 }
4551 self.generate_expression(expr)?;
4552 }
4553 }
4554 }
4555 }
4556
4557 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4559 if let Some(settings) = &select.settings {
4560 if self.config.pretty {
4561 self.write_newline();
4562 self.write_indent();
4563 } else {
4564 self.write_space();
4565 }
4566 self.write_keyword("SETTINGS");
4567 self.write_space();
4568 for (i, expr) in settings.iter().enumerate() {
4569 if i > 0 {
4570 self.write(", ");
4571 }
4572 self.generate_expression(expr)?;
4573 }
4574 }
4575
4576 if let Some(format_expr) = &select.format {
4577 if self.config.pretty {
4578 self.write_newline();
4579 self.write_indent();
4580 } else {
4581 self.write_space();
4582 }
4583 self.write_keyword("FORMAT");
4584 self.write_space();
4585 self.generate_expression(format_expr)?;
4586 }
4587 }
4588
4589 if let Some(fetch) = &select.fetch {
4591 let fetch_already_as_limit = select.offset.is_some()
4593 && !fetch.percent
4594 && !fetch.with_ties
4595 && fetch.count.is_some()
4596 && matches!(
4597 self.config.dialect,
4598 Some(DialectType::Spark)
4599 | Some(DialectType::Hive)
4600 | Some(DialectType::DuckDB)
4601 | Some(DialectType::SQLite)
4602 | Some(DialectType::MySQL)
4603 | Some(DialectType::BigQuery)
4604 | Some(DialectType::Databricks)
4605 | Some(DialectType::StarRocks)
4606 | Some(DialectType::Doris)
4607 | Some(DialectType::Athena)
4608 | Some(DialectType::ClickHouse)
4609 | Some(DialectType::Redshift)
4610 );
4611
4612 if fetch_already_as_limit {
4613 } else {
4615 if self.config.pretty {
4616 self.write_newline();
4617 self.write_indent();
4618 } else {
4619 self.write_space();
4620 }
4621
4622 let use_limit = !fetch.percent
4624 && !fetch.with_ties
4625 && fetch.count.is_some()
4626 && matches!(
4627 self.config.dialect,
4628 Some(DialectType::Spark)
4629 | Some(DialectType::Hive)
4630 | Some(DialectType::DuckDB)
4631 | Some(DialectType::SQLite)
4632 | Some(DialectType::MySQL)
4633 | Some(DialectType::BigQuery)
4634 | Some(DialectType::Databricks)
4635 | Some(DialectType::StarRocks)
4636 | Some(DialectType::Doris)
4637 | Some(DialectType::Athena)
4638 | Some(DialectType::ClickHouse)
4639 | Some(DialectType::Redshift)
4640 );
4641
4642 if use_limit {
4643 self.write_keyword("LIMIT");
4644 self.write_space();
4645 self.generate_expression(fetch.count.as_ref().unwrap())?;
4646 } else {
4647 self.write_keyword("FETCH");
4648 self.write_space();
4649 self.write_keyword(&fetch.direction);
4650 if let Some(ref count) = fetch.count {
4651 self.write_space();
4652 self.generate_expression(count)?;
4653 }
4654 if fetch.percent {
4655 self.write_space();
4656 self.write_keyword("PERCENT");
4657 }
4658 if fetch.rows {
4659 self.write_space();
4660 self.write_keyword("ROWS");
4661 }
4662 if fetch.with_ties {
4663 self.write_space();
4664 self.write_keyword("WITH TIES");
4665 } else {
4666 self.write_space();
4667 self.write_keyword("ONLY");
4668 }
4669 }
4670 } }
4672
4673 if let Some(sample) = &select.sample {
4675 use crate::dialects::DialectType;
4676 if self.config.pretty {
4677 self.write_newline();
4678 } else {
4679 self.write_space();
4680 }
4681
4682 if sample.is_using_sample {
4683 self.write_keyword("USING SAMPLE");
4685 self.generate_sample_body(sample)?;
4686 } else {
4687 self.write_keyword("TABLESAMPLE");
4688
4689 let snowflake_bernoulli =
4691 matches!(self.config.dialect, Some(DialectType::Snowflake))
4692 && !sample.explicit_method;
4693 if snowflake_bernoulli {
4694 self.write_space();
4695 self.write_keyword("BERNOULLI");
4696 }
4697
4698 if matches!(sample.method, SampleMethod::Bucket) {
4700 self.write_space();
4701 self.write("(");
4702 self.write_keyword("BUCKET");
4703 self.write_space();
4704 if let Some(ref num) = sample.bucket_numerator {
4705 self.generate_expression(num)?;
4706 }
4707 self.write_space();
4708 self.write_keyword("OUT OF");
4709 self.write_space();
4710 if let Some(ref denom) = sample.bucket_denominator {
4711 self.generate_expression(denom)?;
4712 }
4713 if let Some(ref field) = sample.bucket_field {
4714 self.write_space();
4715 self.write_keyword("ON");
4716 self.write_space();
4717 self.generate_expression(field)?;
4718 }
4719 self.write(")");
4720 } else if sample.unit_after_size {
4721 if sample.explicit_method && sample.method_before_size {
4723 self.write_space();
4724 match sample.method {
4725 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
4726 SampleMethod::System => self.write_keyword("SYSTEM"),
4727 SampleMethod::Block => self.write_keyword("BLOCK"),
4728 SampleMethod::Row => self.write_keyword("ROW"),
4729 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
4730 _ => {}
4731 }
4732 }
4733 self.write(" (");
4734 self.generate_expression(&sample.size)?;
4735 self.write_space();
4736 match sample.method {
4737 SampleMethod::Percent => self.write_keyword("PERCENT"),
4738 SampleMethod::Row => self.write_keyword("ROWS"),
4739 SampleMethod::Reservoir => self.write_keyword("ROWS"),
4740 _ => {
4741 self.write_keyword("PERCENT");
4742 }
4743 }
4744 self.write(")");
4745 } else {
4746 self.write_space();
4748 match sample.method {
4749 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
4750 SampleMethod::System => self.write_keyword("SYSTEM"),
4751 SampleMethod::Block => self.write_keyword("BLOCK"),
4752 SampleMethod::Row => self.write_keyword("ROW"),
4753 SampleMethod::Percent => self.write_keyword("BERNOULLI"),
4754 SampleMethod::Bucket => {}
4755 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
4756 }
4757 self.write(" (");
4758 self.generate_expression(&sample.size)?;
4759 if matches!(sample.method, SampleMethod::Percent) {
4760 self.write_space();
4761 self.write_keyword("PERCENT");
4762 }
4763 self.write(")");
4764 }
4765 }
4766
4767 if let Some(seed) = &sample.seed {
4768 self.write_space();
4769 let use_seed = sample.use_seed_keyword
4771 && !matches!(
4772 self.config.dialect,
4773 Some(crate::dialects::DialectType::Databricks)
4774 | Some(crate::dialects::DialectType::Spark)
4775 );
4776 if use_seed {
4777 self.write_keyword("SEED");
4778 } else {
4779 self.write_keyword("REPEATABLE");
4780 }
4781 self.write(" (");
4782 self.generate_expression(seed)?;
4783 self.write(")");
4784 }
4785 }
4786
4787 if self.config.locking_reads_supported {
4790 for lock in &select.locks {
4791 if self.config.pretty {
4792 self.write_newline();
4793 self.write_indent();
4794 } else {
4795 self.write_space();
4796 }
4797 self.generate_lock(lock)?;
4798 }
4799 }
4800
4801 if !select.for_xml.is_empty() {
4803 if self.config.pretty {
4804 self.write_newline();
4805 self.write_indent();
4806 } else {
4807 self.write_space();
4808 }
4809 self.write_keyword("FOR XML");
4810 for (i, opt) in select.for_xml.iter().enumerate() {
4811 if self.config.pretty {
4812 if i > 0 {
4813 self.write(",");
4814 }
4815 self.write_newline();
4816 self.write_indent();
4817 self.write(" "); } else {
4819 if i > 0 {
4820 self.write(",");
4821 }
4822 self.write_space();
4823 }
4824 self.generate_for_xml_option(opt)?;
4825 }
4826 }
4827
4828 if let Some(ref option) = select.option {
4830 if matches!(
4831 self.config.dialect,
4832 Some(crate::dialects::DialectType::TSQL)
4833 | Some(crate::dialects::DialectType::Fabric)
4834 ) {
4835 self.write_space();
4836 self.write(option);
4837 }
4838 }
4839
4840 Ok(())
4841 }
4842
4843 fn generate_for_xml_option(&mut self, opt: &Expression) -> Result<()> {
4845 match opt {
4846 Expression::QueryOption(qo) => {
4847 if let Expression::Var(var) = &*qo.this {
4849 self.write(&var.this);
4850 } else {
4851 self.generate_expression(&qo.this)?;
4852 }
4853 if let Some(expr) = &qo.expression {
4855 self.write("(");
4856 self.generate_expression(expr)?;
4857 self.write(")");
4858 }
4859 }
4860 _ => {
4861 self.generate_expression(opt)?;
4862 }
4863 }
4864 Ok(())
4865 }
4866
4867 fn generate_with(&mut self, with: &With) -> Result<()> {
4868 use crate::dialects::DialectType;
4869
4870 for comment in &with.leading_comments {
4872 self.write_formatted_comment(comment);
4873 self.write(" ");
4874 }
4875 self.write_keyword("WITH");
4876 if with.recursive && self.config.cte_recursive_keyword_required {
4877 self.write_space();
4878 self.write_keyword("RECURSIVE");
4879 }
4880 self.write_space();
4881
4882 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
4884
4885 for (i, cte) in with.ctes.iter().enumerate() {
4886 if i > 0 {
4887 self.write(",");
4888 if self.config.pretty {
4889 self.write_space();
4890 } else {
4891 self.write(" ");
4892 }
4893 }
4894 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !cte.alias_first {
4895 self.generate_expression(&cte.this)?;
4896 self.write_space();
4897 self.write_keyword("AS");
4898 self.write_space();
4899 self.generate_identifier(&cte.alias)?;
4900 continue;
4901 }
4902 self.generate_identifier(&cte.alias)?;
4903 for comment in &cte.comments {
4905 self.write_space();
4906 self.write_formatted_comment(comment);
4907 }
4908 if !cte.columns.is_empty() && !skip_cte_columns {
4909 self.write("(");
4910 for (j, col) in cte.columns.iter().enumerate() {
4911 if j > 0 {
4912 self.write(", ");
4913 }
4914 self.generate_identifier(col)?;
4915 }
4916 self.write(")");
4917 }
4918 if !cte.key_expressions.is_empty() {
4920 self.write_space();
4921 self.write_keyword("USING KEY");
4922 self.write(" (");
4923 for (i, key) in cte.key_expressions.iter().enumerate() {
4924 if i > 0 {
4925 self.write(", ");
4926 }
4927 self.generate_identifier(key)?;
4928 }
4929 self.write(")");
4930 }
4931 self.write_space();
4932 self.write_keyword("AS");
4933 if let Some(materialized) = cte.materialized {
4935 self.write_space();
4936 if materialized {
4937 self.write_keyword("MATERIALIZED");
4938 } else {
4939 self.write_keyword("NOT MATERIALIZED");
4940 }
4941 }
4942 self.write(" (");
4943 if self.config.pretty {
4944 self.write_newline();
4945 self.indent_level += 1;
4946 self.write_indent();
4947 }
4948 let wrap_values_in_select = matches!(
4951 self.config.dialect,
4952 Some(DialectType::Spark) | Some(DialectType::Databricks)
4953 ) && matches!(&cte.this, Expression::Values(_));
4954
4955 if wrap_values_in_select {
4956 self.write_keyword("SELECT");
4957 self.write(" * ");
4958 self.write_keyword("FROM");
4959 self.write_space();
4960 }
4961 self.generate_expression(&cte.this)?;
4962 if self.config.pretty {
4963 self.write_newline();
4964 self.indent_level -= 1;
4965 self.write_indent();
4966 }
4967 self.write(")");
4968 }
4969
4970 if let Some(search) = &with.search {
4972 self.write_space();
4973 self.generate_expression(search)?;
4974 }
4975
4976 Ok(())
4977 }
4978
4979 fn generate_joins_with_nesting(&mut self, joins: &[Join]) -> Result<()> {
4983 let mut i = 0;
4984 while i < joins.len() {
4985 if joins[i].deferred_condition {
4986 let parent_group = joins[i].nesting_group;
4987
4988 self.generate_join_without_condition(&joins[i])?;
4991
4992 let child_start = i + 1;
4994 let mut child_end = child_start;
4995 while child_end < joins.len()
4996 && !joins[child_end].deferred_condition
4997 && joins[child_end].nesting_group == parent_group
4998 {
4999 child_end += 1;
5000 }
5001
5002 if child_start < child_end {
5004 self.indent_level += 1;
5005 for j in child_start..child_end {
5006 self.generate_join(&joins[j])?;
5007 }
5008 self.indent_level -= 1;
5009 }
5010
5011 self.generate_join_condition(&joins[i])?;
5013
5014 i = child_end;
5015 } else {
5016 self.generate_join(&joins[i])?;
5018 i += 1;
5019 }
5020 }
5021 Ok(())
5022 }
5023
5024 fn generate_join_without_condition(&mut self, join: &Join) -> Result<()> {
5027 let mut join_copy = join.clone();
5030 join_copy.on = None;
5031 join_copy.using = Vec::new();
5032 join_copy.deferred_condition = false;
5033 self.generate_join(&join_copy)
5034 }
5035
5036 fn generate_join(&mut self, join: &Join) -> Result<()> {
5037 if join.kind == JoinKind::Implicit {
5039 self.write(",");
5040 if self.config.pretty {
5041 self.write_newline();
5042 self.write_indent();
5043 } else {
5044 self.write_space();
5045 }
5046 self.generate_expression(&join.this)?;
5047 return Ok(());
5048 }
5049
5050 if self.config.pretty {
5051 self.write_newline();
5052 self.write_indent();
5053 } else {
5054 self.write_space();
5055 }
5056
5057 let hint_str = if self.config.join_hints {
5060 join.join_hint
5061 .as_ref()
5062 .map(|h| format!(" {}", h))
5063 .unwrap_or_default()
5064 } else {
5065 String::new()
5066 };
5067
5068 let clickhouse_join_keyword =
5069 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
5070 if let Some(hint) = &join.join_hint {
5071 let mut global = false;
5072 let mut strictness: Option<&'static str> = None;
5073 for part in hint.split_whitespace() {
5074 match part.to_uppercase().as_str() {
5075 "GLOBAL" => global = true,
5076 "ANY" => strictness = Some("ANY"),
5077 "ASOF" => strictness = Some("ASOF"),
5078 "SEMI" => strictness = Some("SEMI"),
5079 "ANTI" => strictness = Some("ANTI"),
5080 _ => {}
5081 }
5082 }
5083
5084 if global || strictness.is_some() {
5085 let join_type = match join.kind {
5086 JoinKind::Left => {
5087 if join.use_outer_keyword {
5088 "LEFT OUTER"
5089 } else if join.use_inner_keyword {
5090 "LEFT INNER"
5091 } else {
5092 "LEFT"
5093 }
5094 }
5095 JoinKind::Right => {
5096 if join.use_outer_keyword {
5097 "RIGHT OUTER"
5098 } else if join.use_inner_keyword {
5099 "RIGHT INNER"
5100 } else {
5101 "RIGHT"
5102 }
5103 }
5104 JoinKind::Full => {
5105 if join.use_outer_keyword {
5106 "FULL OUTER"
5107 } else {
5108 "FULL"
5109 }
5110 }
5111 JoinKind::Inner => {
5112 if join.use_inner_keyword {
5113 "INNER"
5114 } else {
5115 ""
5116 }
5117 }
5118 _ => "",
5119 };
5120
5121 let mut parts = Vec::new();
5122 if global {
5123 parts.push("GLOBAL");
5124 }
5125 if !join_type.is_empty() {
5126 parts.push(join_type);
5127 }
5128 if let Some(strict) = strictness {
5129 parts.push(strict);
5130 }
5131 parts.push("JOIN");
5132 Some(parts.join(" "))
5133 } else {
5134 None
5135 }
5136 } else {
5137 None
5138 }
5139 } else {
5140 None
5141 };
5142
5143 if !join.comments.is_empty() {
5147 if self.config.pretty {
5148 let trimmed = self.output.trim_end().len();
5153 self.output.truncate(trimmed);
5154 for comment in &join.comments {
5155 self.write_newline();
5156 self.write_indent();
5157 self.write_formatted_comment(comment);
5158 }
5159 self.write_newline();
5160 self.write_indent();
5161 } else {
5162 for comment in &join.comments {
5163 self.write_formatted_comment(comment);
5164 self.write_space();
5165 }
5166 }
5167 }
5168
5169 let directed_str = if join.directed { " DIRECTED" } else { "" };
5170
5171 if let Some(keyword) = clickhouse_join_keyword {
5172 self.write_keyword(&keyword);
5173 } else {
5174 match join.kind {
5175 JoinKind::Inner => {
5176 if join.use_inner_keyword {
5177 self.write_keyword(&format!("INNER{}{} JOIN", hint_str, directed_str));
5178 } else {
5179 self.write_keyword(&format!(
5180 "{}{}JOIN",
5181 if hint_str.is_empty() {
5182 String::new()
5183 } else {
5184 format!("{} ", hint_str.trim())
5185 },
5186 if directed_str.is_empty() {
5187 ""
5188 } else {
5189 "DIRECTED "
5190 }
5191 ));
5192 }
5193 }
5194 JoinKind::Left => {
5195 if join.use_outer_keyword {
5196 self.write_keyword(&format!("LEFT OUTER{}{} JOIN", hint_str, directed_str));
5197 } else if join.use_inner_keyword {
5198 self.write_keyword(&format!("LEFT INNER{}{} JOIN", hint_str, directed_str));
5199 } else {
5200 self.write_keyword(&format!("LEFT{}{} JOIN", hint_str, directed_str));
5201 }
5202 }
5203 JoinKind::Right => {
5204 if join.use_outer_keyword {
5205 self.write_keyword(&format!(
5206 "RIGHT OUTER{}{} JOIN",
5207 hint_str, directed_str
5208 ));
5209 } else if join.use_inner_keyword {
5210 self.write_keyword(&format!(
5211 "RIGHT INNER{}{} JOIN",
5212 hint_str, directed_str
5213 ));
5214 } else {
5215 self.write_keyword(&format!("RIGHT{}{} JOIN", hint_str, directed_str));
5216 }
5217 }
5218 JoinKind::Full => {
5219 if join.use_outer_keyword {
5220 self.write_keyword(&format!("FULL OUTER{}{} JOIN", hint_str, directed_str));
5221 } else {
5222 self.write_keyword(&format!("FULL{}{} JOIN", hint_str, directed_str));
5223 }
5224 }
5225 JoinKind::Outer => self.write_keyword(&format!("OUTER{} JOIN", directed_str)),
5226 JoinKind::Cross => self.write_keyword(&format!("CROSS{} JOIN", directed_str)),
5227 JoinKind::Natural => {
5228 if join.use_inner_keyword {
5229 self.write_keyword(&format!("NATURAL INNER{} JOIN", directed_str));
5230 } else {
5231 self.write_keyword(&format!("NATURAL{} JOIN", directed_str));
5232 }
5233 }
5234 JoinKind::NaturalLeft => {
5235 if join.use_outer_keyword {
5236 self.write_keyword(&format!("NATURAL LEFT OUTER{} JOIN", directed_str));
5237 } else {
5238 self.write_keyword(&format!("NATURAL LEFT{} JOIN", directed_str));
5239 }
5240 }
5241 JoinKind::NaturalRight => {
5242 if join.use_outer_keyword {
5243 self.write_keyword(&format!("NATURAL RIGHT OUTER{} JOIN", directed_str));
5244 } else {
5245 self.write_keyword(&format!("NATURAL RIGHT{} JOIN", directed_str));
5246 }
5247 }
5248 JoinKind::NaturalFull => {
5249 if join.use_outer_keyword {
5250 self.write_keyword(&format!("NATURAL FULL OUTER{} JOIN", directed_str));
5251 } else {
5252 self.write_keyword(&format!("NATURAL FULL{} JOIN", directed_str));
5253 }
5254 }
5255 JoinKind::Semi => self.write_keyword("SEMI JOIN"),
5256 JoinKind::Anti => self.write_keyword("ANTI JOIN"),
5257 JoinKind::LeftSemi => self.write_keyword("LEFT SEMI JOIN"),
5258 JoinKind::LeftAnti => self.write_keyword("LEFT ANTI JOIN"),
5259 JoinKind::RightSemi => self.write_keyword("RIGHT SEMI JOIN"),
5260 JoinKind::RightAnti => self.write_keyword("RIGHT ANTI JOIN"),
5261 JoinKind::CrossApply => {
5262 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
5264 self.write_keyword("CROSS APPLY");
5265 } else {
5266 self.write_keyword("INNER JOIN LATERAL");
5267 }
5268 }
5269 JoinKind::OuterApply => {
5270 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
5272 self.write_keyword("OUTER APPLY");
5273 } else {
5274 self.write_keyword("LEFT JOIN LATERAL");
5275 }
5276 }
5277 JoinKind::AsOf => self.write_keyword("ASOF JOIN"),
5278 JoinKind::AsOfLeft => {
5279 if join.use_outer_keyword {
5280 self.write_keyword("ASOF LEFT OUTER JOIN");
5281 } else {
5282 self.write_keyword("ASOF LEFT JOIN");
5283 }
5284 }
5285 JoinKind::AsOfRight => {
5286 if join.use_outer_keyword {
5287 self.write_keyword("ASOF RIGHT OUTER JOIN");
5288 } else {
5289 self.write_keyword("ASOF RIGHT JOIN");
5290 }
5291 }
5292 JoinKind::Lateral => self.write_keyword("LATERAL JOIN"),
5293 JoinKind::LeftLateral => {
5294 if join.use_outer_keyword {
5295 self.write_keyword("LEFT OUTER LATERAL JOIN");
5296 } else {
5297 self.write_keyword("LEFT LATERAL JOIN");
5298 }
5299 }
5300 JoinKind::Straight => self.write_keyword("STRAIGHT_JOIN"),
5301 JoinKind::Implicit => {
5302 use crate::dialects::DialectType;
5306 let is_cj_dialect = matches!(
5307 self.config.dialect,
5308 Some(DialectType::BigQuery)
5309 | Some(DialectType::Hive)
5310 | Some(DialectType::Spark)
5311 | Some(DialectType::Databricks)
5312 );
5313 let source_is_same = self.config.source_dialect.is_some()
5314 && self.config.source_dialect == self.config.dialect;
5315 let source_is_cj = matches!(
5316 self.config.source_dialect,
5317 Some(DialectType::BigQuery)
5318 | Some(DialectType::Hive)
5319 | Some(DialectType::Spark)
5320 | Some(DialectType::Databricks)
5321 );
5322 if is_cj_dialect
5323 && (source_is_same || source_is_cj || self.config.source_dialect.is_none())
5324 {
5325 self.write_keyword("CROSS JOIN");
5326 } else {
5327 self.output.truncate(self.output.trim_end().len());
5331 self.write(",");
5332 }
5333 }
5334 JoinKind::Array => self.write_keyword("ARRAY JOIN"),
5335 JoinKind::LeftArray => self.write_keyword("LEFT ARRAY JOIN"),
5336 JoinKind::Paste => self.write_keyword("PASTE JOIN"),
5337 }
5338 }
5339
5340 if matches!(join.kind, JoinKind::Array | JoinKind::LeftArray) {
5342 self.write_space();
5343 match &join.this {
5344 Expression::Tuple(t) => {
5345 for (i, item) in t.expressions.iter().enumerate() {
5346 if i > 0 {
5347 self.write(", ");
5348 }
5349 self.generate_expression(item)?;
5350 }
5351 }
5352 other => {
5353 self.generate_expression(other)?;
5354 }
5355 }
5356 } else {
5357 self.write_space();
5358 self.generate_expression(&join.this)?;
5359 }
5360
5361 if !join.deferred_condition {
5363 if let Some(match_cond) = &join.match_condition {
5365 self.write_space();
5366 self.write_keyword("MATCH_CONDITION");
5367 self.write(" (");
5368 self.generate_expression(match_cond)?;
5369 self.write(")");
5370 }
5371
5372 if let Some(on) = &join.on {
5373 if self.config.pretty {
5374 self.write_newline();
5375 self.indent_level += 1;
5376 self.write_indent();
5377 self.write_keyword("ON");
5378 self.write_space();
5379 self.generate_join_on_condition(on)?;
5380 self.indent_level -= 1;
5381 } else {
5382 self.write_space();
5383 self.write_keyword("ON");
5384 self.write_space();
5385 self.generate_expression(on)?;
5386 }
5387 }
5388
5389 if !join.using.is_empty() {
5390 if self.config.pretty {
5391 self.write_newline();
5392 self.indent_level += 1;
5393 self.write_indent();
5394 self.write_keyword("USING");
5395 self.write(" (");
5396 for (i, col) in join.using.iter().enumerate() {
5397 if i > 0 {
5398 self.write(", ");
5399 }
5400 self.generate_identifier(col)?;
5401 }
5402 self.write(")");
5403 self.indent_level -= 1;
5404 } else {
5405 self.write_space();
5406 self.write_keyword("USING");
5407 self.write(" (");
5408 for (i, col) in join.using.iter().enumerate() {
5409 if i > 0 {
5410 self.write(", ");
5411 }
5412 self.generate_identifier(col)?;
5413 }
5414 self.write(")");
5415 }
5416 }
5417 }
5418
5419 for pivot in &join.pivots {
5421 self.write_space();
5422 self.generate_expression(pivot)?;
5423 }
5424
5425 Ok(())
5426 }
5427
5428 fn generate_join_condition(&mut self, join: &Join) -> Result<()> {
5430 if let Some(match_cond) = &join.match_condition {
5432 self.write_space();
5433 self.write_keyword("MATCH_CONDITION");
5434 self.write(" (");
5435 self.generate_expression(match_cond)?;
5436 self.write(")");
5437 }
5438
5439 if let Some(on) = &join.on {
5440 if self.config.pretty {
5441 self.write_newline();
5442 self.indent_level += 1;
5443 self.write_indent();
5444 self.write_keyword("ON");
5445 self.write_space();
5446 self.generate_join_on_condition(on)?;
5448 self.indent_level -= 1;
5449 } else {
5450 self.write_space();
5451 self.write_keyword("ON");
5452 self.write_space();
5453 self.generate_expression(on)?;
5454 }
5455 }
5456
5457 if !join.using.is_empty() {
5458 if self.config.pretty {
5459 self.write_newline();
5460 self.indent_level += 1;
5461 self.write_indent();
5462 self.write_keyword("USING");
5463 self.write(" (");
5464 for (i, col) in join.using.iter().enumerate() {
5465 if i > 0 {
5466 self.write(", ");
5467 }
5468 self.generate_identifier(col)?;
5469 }
5470 self.write(")");
5471 self.indent_level -= 1;
5472 } else {
5473 self.write_space();
5474 self.write_keyword("USING");
5475 self.write(" (");
5476 for (i, col) in join.using.iter().enumerate() {
5477 if i > 0 {
5478 self.write(", ");
5479 }
5480 self.generate_identifier(col)?;
5481 }
5482 self.write(")");
5483 }
5484 }
5485
5486 for pivot in &join.pivots {
5488 self.write_space();
5489 self.generate_expression(pivot)?;
5490 }
5491
5492 Ok(())
5493 }
5494
5495 fn generate_join_on_condition(&mut self, expr: &Expression) -> Result<()> {
5497 if let Expression::And(and_op) = expr {
5498 if let Some(conditions) = self.flatten_connector_terms(and_op, ConnectorOperator::And) {
5499 self.generate_expression(conditions[0])?;
5500 for condition in conditions.iter().skip(1) {
5501 self.write_newline();
5502 self.write_indent();
5503 self.write_keyword("AND");
5504 self.write_space();
5505 self.generate_expression(condition)?;
5506 }
5507 return Ok(());
5508 }
5509 }
5510
5511 self.generate_expression(expr)
5512 }
5513
5514 fn generate_joined_table(&mut self, jt: &JoinedTable) -> Result<()> {
5515 self.write("(");
5517 self.generate_expression(&jt.left)?;
5518
5519 for join in &jt.joins {
5521 self.generate_join(join)?;
5522 }
5523
5524 for lv in &jt.lateral_views {
5526 self.generate_lateral_view(lv)?;
5527 }
5528
5529 self.write(")");
5530
5531 if let Some(alias) = &jt.alias {
5533 self.write_space();
5534 self.write_keyword("AS");
5535 self.write_space();
5536 self.generate_identifier(alias)?;
5537 }
5538
5539 Ok(())
5540 }
5541
5542 fn generate_lateral_view(&mut self, lv: &LateralView) -> Result<()> {
5543 use crate::dialects::DialectType;
5544
5545 if self.config.pretty {
5546 self.write_newline();
5547 self.write_indent();
5548 } else {
5549 self.write_space();
5550 }
5551
5552 let use_lateral_join = matches!(
5555 self.config.dialect,
5556 Some(DialectType::PostgreSQL)
5557 | Some(DialectType::DuckDB)
5558 | Some(DialectType::Snowflake)
5559 | Some(DialectType::TSQL)
5560 | Some(DialectType::Presto)
5561 | Some(DialectType::Trino)
5562 | Some(DialectType::Athena)
5563 );
5564
5565 let use_unnest = matches!(
5567 self.config.dialect,
5568 Some(DialectType::DuckDB)
5569 | Some(DialectType::Presto)
5570 | Some(DialectType::Trino)
5571 | Some(DialectType::Athena)
5572 );
5573
5574 let (is_posexplode, func_args) = match &lv.this {
5576 Expression::Explode(uf) => {
5577 (false, vec![uf.this.clone()])
5579 }
5580 Expression::Unnest(uf) => {
5581 let mut args = vec![uf.this.clone()];
5582 args.extend(uf.expressions.clone());
5583 (false, args)
5584 }
5585 Expression::Function(func) => {
5586 let name = func.name.to_uppercase();
5587 if name == "POSEXPLODE" || name == "POSEXPLODE_OUTER" {
5588 (true, func.args.clone())
5589 } else if name == "EXPLODE" || name == "EXPLODE_OUTER" || name == "INLINE" {
5590 (false, func.args.clone())
5591 } else {
5592 (false, vec![])
5593 }
5594 }
5595 _ => (false, vec![]),
5596 };
5597
5598 if use_lateral_join {
5599 if lv.outer {
5601 self.write_keyword("LEFT JOIN LATERAL");
5602 } else {
5603 self.write_keyword("CROSS JOIN");
5604 }
5605 self.write_space();
5606
5607 if use_unnest && !func_args.is_empty() {
5608 let unnest_args = if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
5611 func_args
5613 .iter()
5614 .map(|a| {
5615 if let Expression::Function(ref f) = a {
5616 if f.name.to_uppercase() == "ARRAY" && f.args.len() == 1 {
5617 return Expression::ArrayFunc(Box::new(
5618 crate::expressions::ArrayConstructor {
5619 expressions: f.args.clone(),
5620 bracket_notation: true,
5621 use_list_keyword: false,
5622 },
5623 ));
5624 }
5625 }
5626 a.clone()
5627 })
5628 .collect::<Vec<_>>()
5629 } else if matches!(
5630 self.config.dialect,
5631 Some(DialectType::Presto)
5632 | Some(DialectType::Trino)
5633 | Some(DialectType::Athena)
5634 ) {
5635 func_args
5637 .iter()
5638 .map(|a| {
5639 if let Expression::Function(ref f) = a {
5640 if f.name.to_uppercase() == "ARRAY" && f.args.len() >= 1 {
5641 return Expression::ArrayFunc(Box::new(
5642 crate::expressions::ArrayConstructor {
5643 expressions: f.args.clone(),
5644 bracket_notation: true,
5645 use_list_keyword: false,
5646 },
5647 ));
5648 }
5649 }
5650 a.clone()
5651 })
5652 .collect::<Vec<_>>()
5653 } else {
5654 func_args
5655 };
5656
5657 if is_posexplode {
5659 self.write_keyword("LATERAL");
5660 self.write(" (");
5661 self.write_keyword("SELECT");
5662 self.write_space();
5663
5664 let pos_alias = if !lv.column_aliases.is_empty() {
5667 lv.column_aliases[0].clone()
5668 } else {
5669 Identifier::new("pos")
5670 };
5671 let data_aliases: Vec<Identifier> = if lv.column_aliases.len() > 1 {
5672 lv.column_aliases[1..].to_vec()
5673 } else {
5674 vec![Identifier::new("col")]
5675 };
5676
5677 self.generate_identifier(&pos_alias)?;
5679 self.write(" - 1");
5680 self.write_space();
5681 self.write_keyword("AS");
5682 self.write_space();
5683 self.generate_identifier(&pos_alias)?;
5684
5685 for data_col in &data_aliases {
5687 self.write(", ");
5688 self.generate_identifier(data_col)?;
5689 }
5690
5691 self.write_space();
5692 self.write_keyword("FROM");
5693 self.write_space();
5694 self.write_keyword("UNNEST");
5695 self.write("(");
5696 for (i, arg) in unnest_args.iter().enumerate() {
5697 if i > 0 {
5698 self.write(", ");
5699 }
5700 self.generate_expression(arg)?;
5701 }
5702 self.write(")");
5703 self.write_space();
5704 self.write_keyword("WITH ORDINALITY");
5705 self.write_space();
5706 self.write_keyword("AS");
5707 self.write_space();
5708
5709 let table_alias_ident = lv
5711 .table_alias
5712 .clone()
5713 .unwrap_or_else(|| Identifier::new("t"));
5714 self.generate_identifier(&table_alias_ident)?;
5715 self.write("(");
5716 for (i, data_col) in data_aliases.iter().enumerate() {
5717 if i > 0 {
5718 self.write(", ");
5719 }
5720 self.generate_identifier(data_col)?;
5721 }
5722 self.write(", ");
5723 self.generate_identifier(&pos_alias)?;
5724 self.write("))");
5725 } else {
5726 self.write_keyword("UNNEST");
5727 self.write("(");
5728 for (i, arg) in unnest_args.iter().enumerate() {
5729 if i > 0 {
5730 self.write(", ");
5731 }
5732 self.generate_expression(arg)?;
5733 }
5734 self.write(")");
5735
5736 if let Some(alias) = &lv.table_alias {
5738 self.write_space();
5739 self.write_keyword("AS");
5740 self.write_space();
5741 self.generate_identifier(alias)?;
5742 if !lv.column_aliases.is_empty() {
5743 self.write("(");
5744 for (i, col) in lv.column_aliases.iter().enumerate() {
5745 if i > 0 {
5746 self.write(", ");
5747 }
5748 self.generate_identifier(col)?;
5749 }
5750 self.write(")");
5751 }
5752 } else if !lv.column_aliases.is_empty() {
5753 self.write_space();
5754 self.write_keyword("AS");
5755 self.write(" t(");
5756 for (i, col) in lv.column_aliases.iter().enumerate() {
5757 if i > 0 {
5758 self.write(", ");
5759 }
5760 self.generate_identifier(col)?;
5761 }
5762 self.write(")");
5763 }
5764 }
5765 } else {
5766 if !lv.outer {
5768 self.write_keyword("LATERAL");
5769 self.write_space();
5770 }
5771 self.generate_expression(&lv.this)?;
5772
5773 if let Some(alias) = &lv.table_alias {
5775 self.write_space();
5776 self.write_keyword("AS");
5777 self.write_space();
5778 self.generate_identifier(alias)?;
5779 if !lv.column_aliases.is_empty() {
5780 self.write("(");
5781 for (i, col) in lv.column_aliases.iter().enumerate() {
5782 if i > 0 {
5783 self.write(", ");
5784 }
5785 self.generate_identifier(col)?;
5786 }
5787 self.write(")");
5788 }
5789 } else if !lv.column_aliases.is_empty() {
5790 self.write_space();
5791 self.write_keyword("AS");
5792 self.write(" t(");
5793 for (i, col) in lv.column_aliases.iter().enumerate() {
5794 if i > 0 {
5795 self.write(", ");
5796 }
5797 self.generate_identifier(col)?;
5798 }
5799 self.write(")");
5800 }
5801 }
5802
5803 if lv.outer {
5805 self.write_space();
5806 self.write_keyword("ON TRUE");
5807 }
5808 } else {
5809 self.write_keyword("LATERAL VIEW");
5811 if lv.outer {
5812 self.write_space();
5813 self.write_keyword("OUTER");
5814 }
5815 if self.config.pretty {
5816 self.write_newline();
5817 self.write_indent();
5818 } else {
5819 self.write_space();
5820 }
5821 self.generate_expression(&lv.this)?;
5822
5823 if let Some(alias) = &lv.table_alias {
5825 self.write_space();
5826 self.generate_identifier(alias)?;
5827 }
5828
5829 if !lv.column_aliases.is_empty() {
5831 self.write_space();
5832 self.write_keyword("AS");
5833 self.write_space();
5834 for (i, col) in lv.column_aliases.iter().enumerate() {
5835 if i > 0 {
5836 self.write(", ");
5837 }
5838 self.generate_identifier(col)?;
5839 }
5840 }
5841 }
5842
5843 Ok(())
5844 }
5845
5846 fn generate_union(&mut self, union: &Union) -> Result<()> {
5847 if let Some(with) = &union.with {
5849 self.generate_with(with)?;
5850 self.write_space();
5851 }
5852 self.generate_expression(&union.left)?;
5853 if self.config.pretty {
5854 self.write_newline();
5855 self.write_indent();
5856 } else {
5857 self.write_space();
5858 }
5859
5860 if let Some(side) = &union.side {
5862 self.write_keyword(side);
5863 self.write_space();
5864 }
5865 if let Some(kind) = &union.kind {
5866 self.write_keyword(kind);
5867 self.write_space();
5868 }
5869
5870 self.write_keyword("UNION");
5871 if union.all {
5872 self.write_space();
5873 self.write_keyword("ALL");
5874 } else if union.distinct {
5875 self.write_space();
5876 self.write_keyword("DISTINCT");
5877 }
5878
5879 if union.corresponding || union.by_name {
5882 self.write_space();
5883 self.write_keyword("BY NAME");
5884 }
5885 if !union.on_columns.is_empty() {
5886 self.write_space();
5887 self.write_keyword("ON");
5888 self.write(" (");
5889 for (i, col) in union.on_columns.iter().enumerate() {
5890 if i > 0 {
5891 self.write(", ");
5892 }
5893 self.generate_expression(col)?;
5894 }
5895 self.write(")");
5896 }
5897
5898 if self.config.pretty {
5899 self.write_newline();
5900 self.write_indent();
5901 } else {
5902 self.write_space();
5903 }
5904 self.generate_expression(&union.right)?;
5905 if let Some(order_by) = &union.order_by {
5907 if self.config.pretty {
5908 self.write_newline();
5909 } else {
5910 self.write_space();
5911 }
5912 self.write_keyword("ORDER BY");
5913 self.write_space();
5914 for (i, ordered) in order_by.expressions.iter().enumerate() {
5915 if i > 0 {
5916 self.write(", ");
5917 }
5918 self.generate_ordered(ordered)?;
5919 }
5920 }
5921 if let Some(limit) = &union.limit {
5922 if self.config.pretty {
5923 self.write_newline();
5924 } else {
5925 self.write_space();
5926 }
5927 self.write_keyword("LIMIT");
5928 self.write_space();
5929 self.generate_expression(limit)?;
5930 }
5931 if let Some(offset) = &union.offset {
5932 if self.config.pretty {
5933 self.write_newline();
5934 } else {
5935 self.write_space();
5936 }
5937 self.write_keyword("OFFSET");
5938 self.write_space();
5939 self.generate_expression(offset)?;
5940 }
5941 if let Some(distribute_by) = &union.distribute_by {
5943 self.write_space();
5944 self.write_keyword("DISTRIBUTE BY");
5945 self.write_space();
5946 for (i, expr) in distribute_by.expressions.iter().enumerate() {
5947 if i > 0 {
5948 self.write(", ");
5949 }
5950 self.generate_expression(expr)?;
5951 }
5952 }
5953 if let Some(sort_by) = &union.sort_by {
5955 self.write_space();
5956 self.write_keyword("SORT BY");
5957 self.write_space();
5958 for (i, ord) in sort_by.expressions.iter().enumerate() {
5959 if i > 0 {
5960 self.write(", ");
5961 }
5962 self.generate_ordered(ord)?;
5963 }
5964 }
5965 if let Some(cluster_by) = &union.cluster_by {
5967 self.write_space();
5968 self.write_keyword("CLUSTER BY");
5969 self.write_space();
5970 for (i, ord) in cluster_by.expressions.iter().enumerate() {
5971 if i > 0 {
5972 self.write(", ");
5973 }
5974 self.generate_ordered(ord)?;
5975 }
5976 }
5977 Ok(())
5978 }
5979
5980 fn generate_intersect(&mut self, intersect: &Intersect) -> Result<()> {
5981 if let Some(with) = &intersect.with {
5983 self.generate_with(with)?;
5984 self.write_space();
5985 }
5986 self.generate_expression(&intersect.left)?;
5987 if self.config.pretty {
5988 self.write_newline();
5989 self.write_indent();
5990 } else {
5991 self.write_space();
5992 }
5993
5994 if let Some(side) = &intersect.side {
5996 self.write_keyword(side);
5997 self.write_space();
5998 }
5999 if let Some(kind) = &intersect.kind {
6000 self.write_keyword(kind);
6001 self.write_space();
6002 }
6003
6004 self.write_keyword("INTERSECT");
6005 if intersect.all {
6006 self.write_space();
6007 self.write_keyword("ALL");
6008 } else if intersect.distinct {
6009 self.write_space();
6010 self.write_keyword("DISTINCT");
6011 }
6012
6013 if intersect.corresponding || intersect.by_name {
6016 self.write_space();
6017 self.write_keyword("BY NAME");
6018 }
6019 if !intersect.on_columns.is_empty() {
6020 self.write_space();
6021 self.write_keyword("ON");
6022 self.write(" (");
6023 for (i, col) in intersect.on_columns.iter().enumerate() {
6024 if i > 0 {
6025 self.write(", ");
6026 }
6027 self.generate_expression(col)?;
6028 }
6029 self.write(")");
6030 }
6031
6032 if self.config.pretty {
6033 self.write_newline();
6034 self.write_indent();
6035 } else {
6036 self.write_space();
6037 }
6038 self.generate_expression(&intersect.right)?;
6039 if let Some(order_by) = &intersect.order_by {
6041 if self.config.pretty {
6042 self.write_newline();
6043 } else {
6044 self.write_space();
6045 }
6046 self.write_keyword("ORDER BY");
6047 self.write_space();
6048 for (i, ordered) in order_by.expressions.iter().enumerate() {
6049 if i > 0 {
6050 self.write(", ");
6051 }
6052 self.generate_ordered(ordered)?;
6053 }
6054 }
6055 if let Some(limit) = &intersect.limit {
6056 if self.config.pretty {
6057 self.write_newline();
6058 } else {
6059 self.write_space();
6060 }
6061 self.write_keyword("LIMIT");
6062 self.write_space();
6063 self.generate_expression(limit)?;
6064 }
6065 if let Some(offset) = &intersect.offset {
6066 if self.config.pretty {
6067 self.write_newline();
6068 } else {
6069 self.write_space();
6070 }
6071 self.write_keyword("OFFSET");
6072 self.write_space();
6073 self.generate_expression(offset)?;
6074 }
6075 if let Some(distribute_by) = &intersect.distribute_by {
6077 self.write_space();
6078 self.write_keyword("DISTRIBUTE BY");
6079 self.write_space();
6080 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6081 if i > 0 {
6082 self.write(", ");
6083 }
6084 self.generate_expression(expr)?;
6085 }
6086 }
6087 if let Some(sort_by) = &intersect.sort_by {
6089 self.write_space();
6090 self.write_keyword("SORT BY");
6091 self.write_space();
6092 for (i, ord) in sort_by.expressions.iter().enumerate() {
6093 if i > 0 {
6094 self.write(", ");
6095 }
6096 self.generate_ordered(ord)?;
6097 }
6098 }
6099 if let Some(cluster_by) = &intersect.cluster_by {
6101 self.write_space();
6102 self.write_keyword("CLUSTER BY");
6103 self.write_space();
6104 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6105 if i > 0 {
6106 self.write(", ");
6107 }
6108 self.generate_ordered(ord)?;
6109 }
6110 }
6111 Ok(())
6112 }
6113
6114 fn generate_except(&mut self, except: &Except) -> Result<()> {
6115 use crate::dialects::DialectType;
6116
6117 if let Some(with) = &except.with {
6119 self.generate_with(with)?;
6120 self.write_space();
6121 }
6122
6123 self.generate_expression(&except.left)?;
6124 if self.config.pretty {
6125 self.write_newline();
6126 self.write_indent();
6127 } else {
6128 self.write_space();
6129 }
6130
6131 if let Some(side) = &except.side {
6133 self.write_keyword(side);
6134 self.write_space();
6135 }
6136 if let Some(kind) = &except.kind {
6137 self.write_keyword(kind);
6138 self.write_space();
6139 }
6140
6141 match self.config.dialect {
6143 Some(DialectType::Oracle) if !except.all => {
6144 self.write_keyword("MINUS");
6145 }
6146 Some(DialectType::ClickHouse) => {
6147 self.write_keyword("EXCEPT");
6149 if except.distinct {
6150 self.write_space();
6151 self.write_keyword("DISTINCT");
6152 }
6153 }
6154 Some(DialectType::BigQuery) => {
6155 self.write_keyword("EXCEPT");
6157 if except.all {
6158 self.write_space();
6159 self.write_keyword("ALL");
6160 } else {
6161 self.write_space();
6162 self.write_keyword("DISTINCT");
6163 }
6164 }
6165 _ => {
6166 self.write_keyword("EXCEPT");
6167 if except.all {
6168 self.write_space();
6169 self.write_keyword("ALL");
6170 } else if except.distinct {
6171 self.write_space();
6172 self.write_keyword("DISTINCT");
6173 }
6174 }
6175 }
6176
6177 if except.corresponding || except.by_name {
6180 self.write_space();
6181 self.write_keyword("BY NAME");
6182 }
6183 if !except.on_columns.is_empty() {
6184 self.write_space();
6185 self.write_keyword("ON");
6186 self.write(" (");
6187 for (i, col) in except.on_columns.iter().enumerate() {
6188 if i > 0 {
6189 self.write(", ");
6190 }
6191 self.generate_expression(col)?;
6192 }
6193 self.write(")");
6194 }
6195
6196 if self.config.pretty {
6197 self.write_newline();
6198 self.write_indent();
6199 } else {
6200 self.write_space();
6201 }
6202 self.generate_expression(&except.right)?;
6203 if let Some(order_by) = &except.order_by {
6205 if self.config.pretty {
6206 self.write_newline();
6207 } else {
6208 self.write_space();
6209 }
6210 self.write_keyword("ORDER BY");
6211 self.write_space();
6212 for (i, ordered) in order_by.expressions.iter().enumerate() {
6213 if i > 0 {
6214 self.write(", ");
6215 }
6216 self.generate_ordered(ordered)?;
6217 }
6218 }
6219 if let Some(limit) = &except.limit {
6220 if self.config.pretty {
6221 self.write_newline();
6222 } else {
6223 self.write_space();
6224 }
6225 self.write_keyword("LIMIT");
6226 self.write_space();
6227 self.generate_expression(limit)?;
6228 }
6229 if let Some(offset) = &except.offset {
6230 if self.config.pretty {
6231 self.write_newline();
6232 } else {
6233 self.write_space();
6234 }
6235 self.write_keyword("OFFSET");
6236 self.write_space();
6237 self.generate_expression(offset)?;
6238 }
6239 if let Some(distribute_by) = &except.distribute_by {
6241 self.write_space();
6242 self.write_keyword("DISTRIBUTE BY");
6243 self.write_space();
6244 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6245 if i > 0 {
6246 self.write(", ");
6247 }
6248 self.generate_expression(expr)?;
6249 }
6250 }
6251 if let Some(sort_by) = &except.sort_by {
6253 self.write_space();
6254 self.write_keyword("SORT BY");
6255 self.write_space();
6256 for (i, ord) in sort_by.expressions.iter().enumerate() {
6257 if i > 0 {
6258 self.write(", ");
6259 }
6260 self.generate_ordered(ord)?;
6261 }
6262 }
6263 if let Some(cluster_by) = &except.cluster_by {
6265 self.write_space();
6266 self.write_keyword("CLUSTER BY");
6267 self.write_space();
6268 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6269 if i > 0 {
6270 self.write(", ");
6271 }
6272 self.generate_ordered(ord)?;
6273 }
6274 }
6275 Ok(())
6276 }
6277
6278 fn generate_insert(&mut self, insert: &Insert) -> Result<()> {
6279 let prepend_query_cte = if insert.with.is_none() {
6281 use crate::dialects::DialectType;
6282 let should_prepend = matches!(
6283 self.config.dialect,
6284 Some(DialectType::TSQL)
6285 | Some(DialectType::Fabric)
6286 | Some(DialectType::Spark)
6287 | Some(DialectType::Databricks)
6288 | Some(DialectType::Hive)
6289 );
6290 if should_prepend {
6291 if let Some(Expression::Select(select)) = &insert.query {
6292 select.with.clone()
6293 } else {
6294 None
6295 }
6296 } else {
6297 None
6298 }
6299 } else {
6300 None
6301 };
6302
6303 if let Some(with) = &insert.with {
6305 self.generate_with(with)?;
6306 self.write_space();
6307 } else if let Some(with) = &prepend_query_cte {
6308 self.generate_with(with)?;
6309 self.write_space();
6310 }
6311
6312 for comment in &insert.leading_comments {
6314 self.write_formatted_comment(comment);
6315 self.write(" ");
6316 }
6317
6318 if let Some(dir) = &insert.directory {
6320 self.write_keyword("INSERT OVERWRITE");
6321 if dir.local {
6322 self.write_space();
6323 self.write_keyword("LOCAL");
6324 }
6325 self.write_space();
6326 self.write_keyword("DIRECTORY");
6327 self.write_space();
6328 self.write("'");
6329 self.write(&dir.path);
6330 self.write("'");
6331
6332 if let Some(row_format) = &dir.row_format {
6334 self.write_space();
6335 self.write_keyword("ROW FORMAT");
6336 if row_format.delimited {
6337 self.write_space();
6338 self.write_keyword("DELIMITED");
6339 }
6340 if let Some(val) = &row_format.fields_terminated_by {
6341 self.write_space();
6342 self.write_keyword("FIELDS TERMINATED BY");
6343 self.write_space();
6344 self.write("'");
6345 self.write(val);
6346 self.write("'");
6347 }
6348 if let Some(val) = &row_format.collection_items_terminated_by {
6349 self.write_space();
6350 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
6351 self.write_space();
6352 self.write("'");
6353 self.write(val);
6354 self.write("'");
6355 }
6356 if let Some(val) = &row_format.map_keys_terminated_by {
6357 self.write_space();
6358 self.write_keyword("MAP KEYS TERMINATED BY");
6359 self.write_space();
6360 self.write("'");
6361 self.write(val);
6362 self.write("'");
6363 }
6364 if let Some(val) = &row_format.lines_terminated_by {
6365 self.write_space();
6366 self.write_keyword("LINES TERMINATED BY");
6367 self.write_space();
6368 self.write("'");
6369 self.write(val);
6370 self.write("'");
6371 }
6372 if let Some(val) = &row_format.null_defined_as {
6373 self.write_space();
6374 self.write_keyword("NULL DEFINED AS");
6375 self.write_space();
6376 self.write("'");
6377 self.write(val);
6378 self.write("'");
6379 }
6380 }
6381
6382 if let Some(format) = &dir.stored_as {
6384 self.write_space();
6385 self.write_keyword("STORED AS");
6386 self.write_space();
6387 self.write_keyword(format);
6388 }
6389
6390 if let Some(query) = &insert.query {
6392 self.write_space();
6393 self.generate_expression(query)?;
6394 }
6395
6396 return Ok(());
6397 }
6398
6399 if insert.is_replace {
6400 self.write_keyword("REPLACE INTO");
6402 } else if insert.overwrite {
6403 self.write_keyword("INSERT");
6405 if let Some(ref hint) = insert.hint {
6407 self.generate_hint(hint)?;
6408 }
6409 self.write(&self.config.insert_overwrite.to_uppercase());
6410 } else if let Some(ref action) = insert.conflict_action {
6411 self.write_keyword("INSERT OR");
6413 self.write_space();
6414 self.write_keyword(action);
6415 self.write_space();
6416 self.write_keyword("INTO");
6417 } else if insert.ignore {
6418 self.write_keyword("INSERT IGNORE INTO");
6420 } else {
6421 self.write_keyword("INSERT");
6422 if let Some(ref hint) = insert.hint {
6424 self.generate_hint(hint)?;
6425 }
6426 self.write_space();
6427 self.write_keyword("INTO");
6428 }
6429 if let Some(ref func) = insert.function_target {
6431 self.write_space();
6432 self.write_keyword("FUNCTION");
6433 self.write_space();
6434 self.generate_expression(func)?;
6435 } else {
6436 self.write_space();
6437 self.generate_table(&insert.table)?;
6438 }
6439
6440 if let Some(ref alias) = insert.alias {
6442 self.write_space();
6443 if insert.alias_explicit_as {
6444 self.write_keyword("AS");
6445 self.write_space();
6446 }
6447 self.generate_identifier(alias)?;
6448 }
6449
6450 if insert.if_exists {
6452 self.write_space();
6453 self.write_keyword("IF EXISTS");
6454 }
6455
6456 if let Some(ref replace_where) = insert.replace_where {
6458 if self.config.pretty {
6459 self.write_newline();
6460 self.write_indent();
6461 } else {
6462 self.write_space();
6463 }
6464 self.write_keyword("REPLACE WHERE");
6465 self.write_space();
6466 self.generate_expression(replace_where)?;
6467 }
6468
6469 if !insert.partition.is_empty() {
6471 self.write_space();
6472 self.write_keyword("PARTITION");
6473 self.write("(");
6474 for (i, (col, val)) in insert.partition.iter().enumerate() {
6475 if i > 0 {
6476 self.write(", ");
6477 }
6478 self.generate_identifier(col)?;
6479 if let Some(v) = val {
6480 self.write(" = ");
6481 self.generate_expression(v)?;
6482 }
6483 }
6484 self.write(")");
6485 }
6486
6487 if let Some(ref partition_by) = insert.partition_by {
6489 self.write_space();
6490 self.write_keyword("PARTITION BY");
6491 self.write_space();
6492 self.generate_expression(partition_by)?;
6493 }
6494
6495 if !insert.settings.is_empty() {
6497 self.write_space();
6498 self.write_keyword("SETTINGS");
6499 self.write_space();
6500 for (i, setting) in insert.settings.iter().enumerate() {
6501 if i > 0 {
6502 self.write(", ");
6503 }
6504 self.generate_expression(setting)?;
6505 }
6506 }
6507
6508 if !insert.columns.is_empty() {
6509 if insert.alias.is_some() && insert.alias_explicit_as {
6510 self.write("(");
6512 } else {
6513 self.write(" (");
6515 }
6516 for (i, col) in insert.columns.iter().enumerate() {
6517 if i > 0 {
6518 self.write(", ");
6519 }
6520 self.generate_identifier(col)?;
6521 }
6522 self.write(")");
6523 }
6524
6525 if let Some(ref output) = insert.output {
6527 self.generate_output_clause(output)?;
6528 }
6529
6530 if insert.by_name {
6532 self.write_space();
6533 self.write_keyword("BY NAME");
6534 }
6535
6536 if insert.default_values {
6537 self.write_space();
6538 self.write_keyword("DEFAULT VALUES");
6539 } else if let Some(query) = &insert.query {
6540 if self.config.pretty {
6541 self.write_newline();
6542 } else {
6543 self.write_space();
6544 }
6545 if prepend_query_cte.is_some() {
6547 if let Expression::Select(select) = query {
6548 let mut select_no_with = select.clone();
6549 select_no_with.with = None;
6550 self.generate_select(&select_no_with)?;
6551 } else {
6552 self.generate_expression(query)?;
6553 }
6554 } else {
6555 self.generate_expression(query)?;
6556 }
6557 } else if !insert.values.is_empty() {
6558 if self.config.pretty {
6559 self.write_newline();
6561 self.write_keyword("VALUES");
6562 self.write_newline();
6563 self.indent_level += 1;
6564 for (i, row) in insert.values.iter().enumerate() {
6565 if i > 0 {
6566 self.write(",");
6567 self.write_newline();
6568 }
6569 self.write_indent();
6570 self.write("(");
6571 for (j, val) in row.iter().enumerate() {
6572 if j > 0 {
6573 self.write(", ");
6574 }
6575 self.generate_expression(val)?;
6576 }
6577 self.write(")");
6578 }
6579 self.indent_level -= 1;
6580 } else {
6581 self.write_space();
6583 self.write_keyword("VALUES");
6584 for (i, row) in insert.values.iter().enumerate() {
6585 if i > 0 {
6586 self.write(",");
6587 }
6588 self.write(" (");
6589 for (j, val) in row.iter().enumerate() {
6590 if j > 0 {
6591 self.write(", ");
6592 }
6593 self.generate_expression(val)?;
6594 }
6595 self.write(")");
6596 }
6597 }
6598 }
6599
6600 if let Some(ref source) = insert.source {
6602 self.write_space();
6603 self.write_keyword("TABLE");
6604 self.write_space();
6605 self.generate_expression(source)?;
6606 }
6607
6608 if let Some(alias) = &insert.source_alias {
6610 self.write_space();
6611 self.write_keyword("AS");
6612 self.write_space();
6613 self.generate_identifier(alias)?;
6614 }
6615
6616 if let Some(on_conflict) = &insert.on_conflict {
6618 if !matches!(self.config.dialect, Some(DialectType::Materialize)) {
6619 self.write_space();
6620 self.generate_expression(on_conflict)?;
6621 }
6622 }
6623
6624 if !insert.returning.is_empty() {
6626 self.write_space();
6627 self.write_keyword("RETURNING");
6628 self.write_space();
6629 for (i, expr) in insert.returning.iter().enumerate() {
6630 if i > 0 {
6631 self.write(", ");
6632 }
6633 self.generate_expression(expr)?;
6634 }
6635 }
6636
6637 Ok(())
6638 }
6639
6640 fn generate_update(&mut self, update: &Update) -> Result<()> {
6641 for comment in &update.leading_comments {
6643 self.write_formatted_comment(comment);
6644 self.write(" ");
6645 }
6646
6647 if let Some(ref with) = update.with {
6649 self.generate_with(with)?;
6650 self.write_space();
6651 }
6652
6653 self.write_keyword("UPDATE");
6654 self.write_space();
6655 self.generate_table(&update.table)?;
6656
6657 let mysql_like_update_from = matches!(
6658 self.config.dialect,
6659 Some(DialectType::MySQL) | Some(DialectType::SingleStore)
6660 ) && update.from_clause.is_some();
6661
6662 let mut set_pairs = update.set.clone();
6663
6664 let mut pre_set_joins = update.table_joins.clone();
6666 if mysql_like_update_from {
6667 let target_name = update
6668 .table
6669 .alias
6670 .as_ref()
6671 .map(|a| a.name.clone())
6672 .unwrap_or_else(|| update.table.name.name.clone());
6673
6674 for (col, _) in &mut set_pairs {
6675 if !col.name.contains('.') {
6676 col.name = format!("{}.{}", target_name, col.name);
6677 }
6678 }
6679
6680 if let Some(from_clause) = &update.from_clause {
6681 for table_expr in &from_clause.expressions {
6682 pre_set_joins.push(crate::expressions::Join {
6683 this: table_expr.clone(),
6684 on: Some(Expression::Boolean(crate::expressions::BooleanLiteral {
6685 value: true,
6686 })),
6687 using: Vec::new(),
6688 kind: crate::expressions::JoinKind::Inner,
6689 use_inner_keyword: false,
6690 use_outer_keyword: false,
6691 deferred_condition: false,
6692 join_hint: None,
6693 match_condition: None,
6694 pivots: Vec::new(),
6695 comments: Vec::new(),
6696 nesting_group: 0,
6697 directed: false,
6698 });
6699 }
6700 }
6701 for join in &update.from_joins {
6702 let mut join = join.clone();
6703 if join.on.is_none() && join.using.is_empty() {
6704 join.on = Some(Expression::Boolean(crate::expressions::BooleanLiteral {
6705 value: true,
6706 }));
6707 }
6708 pre_set_joins.push(join);
6709 }
6710 }
6711
6712 for extra_table in &update.extra_tables {
6714 self.write(", ");
6715 self.generate_table(extra_table)?;
6716 }
6717
6718 for join in &pre_set_joins {
6720 self.generate_join(join)?;
6722 }
6723
6724 let teradata_from_before_set = matches!(self.config.dialect, Some(DialectType::Teradata));
6726 if teradata_from_before_set && !mysql_like_update_from {
6727 if let Some(ref from_clause) = update.from_clause {
6728 self.write_space();
6729 self.write_keyword("FROM");
6730 self.write_space();
6731 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
6732 if i > 0 {
6733 self.write(", ");
6734 }
6735 self.generate_expression(table_expr)?;
6736 }
6737 }
6738 for join in &update.from_joins {
6739 self.generate_join(join)?;
6740 }
6741 }
6742
6743 self.write_space();
6744 self.write_keyword("SET");
6745 self.write_space();
6746
6747 for (i, (col, val)) in set_pairs.iter().enumerate() {
6748 if i > 0 {
6749 self.write(", ");
6750 }
6751 self.generate_identifier(col)?;
6752 self.write(" = ");
6753 self.generate_expression(val)?;
6754 }
6755
6756 if let Some(ref output) = update.output {
6758 self.generate_output_clause(output)?;
6759 }
6760
6761 if !mysql_like_update_from && !teradata_from_before_set {
6763 if let Some(ref from_clause) = update.from_clause {
6764 self.write_space();
6765 self.write_keyword("FROM");
6766 self.write_space();
6767 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
6769 if i > 0 {
6770 self.write(", ");
6771 }
6772 self.generate_expression(table_expr)?;
6773 }
6774 }
6775 }
6776
6777 if !mysql_like_update_from && !teradata_from_before_set {
6778 for join in &update.from_joins {
6780 self.generate_join(join)?;
6781 }
6782 }
6783
6784 if let Some(where_clause) = &update.where_clause {
6785 self.write_space();
6786 self.write_keyword("WHERE");
6787 self.write_space();
6788 self.generate_expression(&where_clause.this)?;
6789 }
6790
6791 if !update.returning.is_empty() {
6793 self.write_space();
6794 self.write_keyword("RETURNING");
6795 self.write_space();
6796 for (i, expr) in update.returning.iter().enumerate() {
6797 if i > 0 {
6798 self.write(", ");
6799 }
6800 self.generate_expression(expr)?;
6801 }
6802 }
6803
6804 if let Some(ref order_by) = update.order_by {
6806 self.write_space();
6807 self.generate_order_by(order_by)?;
6808 }
6809
6810 if let Some(ref limit) = update.limit {
6812 self.write_space();
6813 self.write_keyword("LIMIT");
6814 self.write_space();
6815 self.generate_expression(limit)?;
6816 }
6817
6818 Ok(())
6819 }
6820
6821 fn generate_delete(&mut self, delete: &Delete) -> Result<()> {
6822 if let Some(with) = &delete.with {
6824 self.generate_with(with)?;
6825 self.write_space();
6826 }
6827
6828 for comment in &delete.leading_comments {
6830 self.write_formatted_comment(comment);
6831 self.write(" ");
6832 }
6833
6834 if !delete.tables.is_empty() && !delete.tables_from_using {
6836 self.write_keyword("DELETE");
6838 self.write_space();
6839 for (i, tbl) in delete.tables.iter().enumerate() {
6840 if i > 0 {
6841 self.write(", ");
6842 }
6843 self.generate_table(tbl)?;
6844 }
6845 if let Some(ref output) = delete.output {
6847 self.generate_output_clause(output)?;
6848 }
6849 self.write_space();
6850 self.write_keyword("FROM");
6851 self.write_space();
6852 self.generate_table(&delete.table)?;
6853 } else if !delete.tables.is_empty() && delete.tables_from_using {
6854 self.write_keyword("DELETE FROM");
6856 self.write_space();
6857 for (i, tbl) in delete.tables.iter().enumerate() {
6858 if i > 0 {
6859 self.write(", ");
6860 }
6861 self.generate_table(tbl)?;
6862 }
6863 } else if delete.no_from && matches!(self.config.dialect, Some(DialectType::BigQuery)) {
6864 self.write_keyword("DELETE");
6866 self.write_space();
6867 self.generate_table(&delete.table)?;
6868 } else {
6869 self.write_keyword("DELETE FROM");
6870 self.write_space();
6871 self.generate_table(&delete.table)?;
6872 }
6873
6874 if let Some(ref on_cluster) = delete.on_cluster {
6876 self.write_space();
6877 self.generate_on_cluster(on_cluster)?;
6878 }
6879
6880 if let Some(ref idx) = delete.force_index {
6882 self.write_space();
6883 self.write_keyword("FORCE INDEX");
6884 self.write(" (");
6885 self.write(idx);
6886 self.write(")");
6887 }
6888
6889 if let Some(ref alias) = delete.alias {
6891 self.write_space();
6892 if delete.alias_explicit_as
6893 || matches!(self.config.dialect, Some(DialectType::BigQuery))
6894 {
6895 self.write_keyword("AS");
6896 self.write_space();
6897 }
6898 self.generate_identifier(alias)?;
6899 }
6900
6901 if !delete.tables_from_using {
6903 for join in &delete.joins {
6904 self.generate_join(join)?;
6905 }
6906 }
6907
6908 if !delete.using.is_empty() {
6910 self.write_space();
6911 self.write_keyword("USING");
6912 for (i, table) in delete.using.iter().enumerate() {
6913 if i > 0 {
6914 self.write(",");
6915 }
6916 self.write_space();
6917 if !table.hints.is_empty() && table.name.is_empty() {
6919 self.generate_expression(&table.hints[0])?;
6921 if let Some(ref alias) = table.alias {
6922 self.write_space();
6923 if table.alias_explicit_as {
6924 self.write_keyword("AS");
6925 self.write_space();
6926 }
6927 self.generate_identifier(alias)?;
6928 if !table.column_aliases.is_empty() {
6929 self.write("(");
6930 for (j, col_alias) in table.column_aliases.iter().enumerate() {
6931 if j > 0 {
6932 self.write(", ");
6933 }
6934 self.generate_identifier(col_alias)?;
6935 }
6936 self.write(")");
6937 }
6938 }
6939 } else {
6940 self.generate_table(table)?;
6941 }
6942 }
6943 }
6944
6945 if delete.tables_from_using {
6947 for join in &delete.joins {
6948 self.generate_join(join)?;
6949 }
6950 }
6951
6952 let output_already_emitted =
6954 !delete.tables.is_empty() && !delete.tables_from_using && delete.output.is_some();
6955 if !output_already_emitted {
6956 if let Some(ref output) = delete.output {
6957 self.generate_output_clause(output)?;
6958 }
6959 }
6960
6961 if let Some(where_clause) = &delete.where_clause {
6962 self.write_space();
6963 self.write_keyword("WHERE");
6964 self.write_space();
6965 self.generate_expression(&where_clause.this)?;
6966 }
6967
6968 if let Some(ref order_by) = delete.order_by {
6970 self.write_space();
6971 self.generate_order_by(order_by)?;
6972 }
6973
6974 if let Some(ref limit) = delete.limit {
6976 self.write_space();
6977 self.write_keyword("LIMIT");
6978 self.write_space();
6979 self.generate_expression(limit)?;
6980 }
6981
6982 if !delete.returning.is_empty() {
6984 self.write_space();
6985 self.write_keyword("RETURNING");
6986 self.write_space();
6987 for (i, expr) in delete.returning.iter().enumerate() {
6988 if i > 0 {
6989 self.write(", ");
6990 }
6991 self.generate_expression(expr)?;
6992 }
6993 }
6994
6995 Ok(())
6996 }
6997
6998 fn generate_create_table(&mut self, ct: &CreateTable) -> Result<()> {
7001 let saved_athena_hive_context = self.athena_hive_context;
7005 let is_clickhouse = matches!(self.config.dialect, Some(DialectType::ClickHouse));
7006 if matches!(
7007 self.config.dialect,
7008 Some(crate::dialects::DialectType::Athena)
7009 ) {
7010 let is_external = ct
7014 .table_modifier
7015 .as_ref()
7016 .map(|m| m.eq_ignore_ascii_case("EXTERNAL"))
7017 .unwrap_or(false);
7018 let has_as_select = ct.as_select.is_some();
7019 self.athena_hive_context = is_external || !has_as_select;
7020 }
7021
7022 if matches!(
7024 self.config.dialect,
7025 Some(crate::dialects::DialectType::TSQL)
7026 ) {
7027 if let Some(ref query) = ct.as_select {
7028 if let Some(with_cte) = &ct.with_cte {
7030 self.generate_with(with_cte)?;
7031 self.write_space();
7032 }
7033
7034 self.write_keyword("SELECT");
7036 self.write(" * ");
7037 self.write_keyword("INTO");
7038 self.write_space();
7039
7040 if ct.temporary {
7042 self.write("#");
7043 }
7044 self.generate_table(&ct.name)?;
7045
7046 self.write_space();
7047 self.write_keyword("FROM");
7048 self.write(" (");
7049 let aliased_query = Self::add_column_aliases_to_query(query.clone());
7051 self.generate_expression(&aliased_query)?;
7052 self.write(") ");
7053 self.write_keyword("AS");
7054 self.write(" temp");
7055 return Ok(());
7056 }
7057 }
7058
7059 if let Some(with_cte) = &ct.with_cte {
7061 self.generate_with(with_cte)?;
7062 self.write_space();
7063 }
7064
7065 for comment in &ct.leading_comments {
7067 self.write_formatted_comment(comment);
7068 self.write(" ");
7069 }
7070 self.write_keyword("CREATE");
7071
7072 if ct.or_replace {
7073 self.write_space();
7074 self.write_keyword("OR REPLACE");
7075 }
7076
7077 if ct.temporary {
7078 self.write_space();
7079 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
7081 self.write_keyword("GLOBAL TEMPORARY");
7082 } else {
7083 self.write_keyword("TEMPORARY");
7084 }
7085 }
7086
7087 let is_dictionary = ct
7089 .table_modifier
7090 .as_ref()
7091 .map(|m| m.eq_ignore_ascii_case("DICTIONARY"))
7092 .unwrap_or(false);
7093 if let Some(ref modifier) = ct.table_modifier {
7094 let skip_transient = modifier.eq_ignore_ascii_case("TRANSIENT")
7096 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None);
7097 let is_teradata_modifier = modifier.eq_ignore_ascii_case("VOLATILE")
7099 || modifier.eq_ignore_ascii_case("SET")
7100 || modifier.eq_ignore_ascii_case("MULTISET")
7101 || modifier.to_uppercase().contains("VOLATILE")
7102 || modifier.to_uppercase().starts_with("SET ")
7103 || modifier.to_uppercase().starts_with("MULTISET ");
7104 let skip_teradata =
7105 is_teradata_modifier && !matches!(self.config.dialect, Some(DialectType::Teradata));
7106 if !skip_transient && !skip_teradata {
7107 self.write_space();
7108 self.write_keyword(modifier);
7109 }
7110 }
7111
7112 if !is_dictionary {
7113 self.write_space();
7114 self.write_keyword("TABLE");
7115 }
7116
7117 if ct.if_not_exists {
7118 self.write_space();
7119 self.write_keyword("IF NOT EXISTS");
7120 }
7121
7122 self.write_space();
7123 self.generate_table(&ct.name)?;
7124
7125 if let Some(ref on_cluster) = ct.on_cluster {
7127 self.write_space();
7128 self.generate_on_cluster(on_cluster)?;
7129 }
7130
7131 if matches!(
7133 self.config.dialect,
7134 Some(crate::dialects::DialectType::Teradata)
7135 ) && !ct.teradata_post_name_options.is_empty()
7136 {
7137 for opt in &ct.teradata_post_name_options {
7138 self.write(", ");
7139 self.write(opt);
7140 }
7141 }
7142
7143 if ct.copy_grants {
7145 self.write_space();
7146 self.write_keyword("COPY GRANTS");
7147 }
7148
7149 if let Some(ref using_template) = ct.using_template {
7151 self.write_space();
7152 self.write_keyword("USING TEMPLATE");
7153 self.write_space();
7154 self.generate_expression(using_template)?;
7155 return Ok(());
7156 }
7157
7158 if let Some(ref clone_source) = ct.clone_source {
7160 self.write_space();
7161 if ct.is_copy && self.config.supports_table_copy {
7162 self.write_keyword("COPY");
7164 } else if ct.shallow_clone {
7165 self.write_keyword("SHALLOW CLONE");
7166 } else {
7167 self.write_keyword("CLONE");
7168 }
7169 self.write_space();
7170 self.generate_table(clone_source)?;
7171 if let Some(ref at_clause) = ct.clone_at_clause {
7173 self.write_space();
7174 self.generate_expression(at_clause)?;
7175 }
7176 return Ok(());
7177 }
7178
7179 if let Some(ref partition_of) = ct.partition_of {
7183 self.write_space();
7184
7185 if let Expression::PartitionedOfProperty(ref pop) = partition_of {
7187 self.write_keyword("PARTITION OF");
7189 self.write_space();
7190 self.generate_expression(&pop.this)?;
7191
7192 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
7194 self.write(" (");
7195 let mut first = true;
7196 for col in &ct.columns {
7197 if !first {
7198 self.write(", ");
7199 }
7200 first = false;
7201 self.generate_column_def(col)?;
7202 }
7203 for constraint in &ct.constraints {
7204 if !first {
7205 self.write(", ");
7206 }
7207 first = false;
7208 self.generate_table_constraint(constraint)?;
7209 }
7210 self.write(")");
7211 }
7212
7213 if let Expression::PartitionBoundSpec(_) = pop.expression.as_ref() {
7215 self.write_space();
7216 self.write_keyword("FOR VALUES");
7217 self.write_space();
7218 self.generate_expression(&pop.expression)?;
7219 } else {
7220 self.write_space();
7221 self.write_keyword("DEFAULT");
7222 }
7223 } else {
7224 self.generate_expression(partition_of)?;
7226
7227 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
7229 self.write(" (");
7230 let mut first = true;
7231 for col in &ct.columns {
7232 if !first {
7233 self.write(", ");
7234 }
7235 first = false;
7236 self.generate_column_def(col)?;
7237 }
7238 for constraint in &ct.constraints {
7239 if !first {
7240 self.write(", ");
7241 }
7242 first = false;
7243 self.generate_table_constraint(constraint)?;
7244 }
7245 self.write(")");
7246 }
7247 }
7248
7249 for prop in &ct.properties {
7251 self.write_space();
7252 self.generate_expression(prop)?;
7253 }
7254
7255 return Ok(());
7256 }
7257
7258 self.sqlite_inline_pk_columns.clear();
7261 if matches!(
7262 self.config.dialect,
7263 Some(crate::dialects::DialectType::SQLite)
7264 ) {
7265 for constraint in &ct.constraints {
7266 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7267 if columns.len() == 1 && name.is_none() {
7269 let pk_col_name = columns[0].name.to_lowercase();
7270 if ct
7272 .columns
7273 .iter()
7274 .any(|c| c.name.name.to_lowercase() == pk_col_name)
7275 {
7276 self.sqlite_inline_pk_columns.insert(pk_col_name);
7277 }
7278 }
7279 }
7280 }
7281 }
7282
7283 if !ct.columns.is_empty() {
7285 if self.config.pretty {
7286 self.write(" (");
7288 self.write_newline();
7289 self.indent_level += 1;
7290 for (i, col) in ct.columns.iter().enumerate() {
7291 if i > 0 {
7292 self.write(",");
7293 self.write_newline();
7294 }
7295 self.write_indent();
7296 self.generate_column_def(col)?;
7297 }
7298 for constraint in &ct.constraints {
7300 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7302 if columns.len() == 1
7303 && name.is_none()
7304 && self
7305 .sqlite_inline_pk_columns
7306 .contains(&columns[0].name.to_lowercase())
7307 {
7308 continue;
7309 }
7310 }
7311 self.write(",");
7312 self.write_newline();
7313 self.write_indent();
7314 self.generate_table_constraint(constraint)?;
7315 }
7316 self.indent_level -= 1;
7317 self.write_newline();
7318 self.write(")");
7319 } else {
7320 self.write(" (");
7321 for (i, col) in ct.columns.iter().enumerate() {
7322 if i > 0 {
7323 self.write(", ");
7324 }
7325 self.generate_column_def(col)?;
7326 }
7327 let mut first_constraint = true;
7329 for constraint in &ct.constraints {
7330 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7332 if columns.len() == 1
7333 && name.is_none()
7334 && self
7335 .sqlite_inline_pk_columns
7336 .contains(&columns[0].name.to_lowercase())
7337 {
7338 continue;
7339 }
7340 }
7341 if first_constraint {
7342 self.write(", ");
7343 first_constraint = false;
7344 } else {
7345 self.write(", ");
7346 }
7347 self.generate_table_constraint(constraint)?;
7348 }
7349 self.write(")");
7350 }
7351 } else if !ct.constraints.is_empty() {
7352 let has_like_only = ct
7354 .constraints
7355 .iter()
7356 .all(|c| matches!(c, TableConstraint::Like { .. }));
7357 let has_tags_only = ct
7358 .constraints
7359 .iter()
7360 .all(|c| matches!(c, TableConstraint::Tags(_)));
7361 let is_pg_like = matches!(
7365 self.config.dialect,
7366 Some(crate::dialects::DialectType::PostgreSQL)
7367 | Some(crate::dialects::DialectType::CockroachDB)
7368 | Some(crate::dialects::DialectType::Materialize)
7369 | Some(crate::dialects::DialectType::RisingWave)
7370 | Some(crate::dialects::DialectType::Redshift)
7371 | Some(crate::dialects::DialectType::Presto)
7372 | Some(crate::dialects::DialectType::Trino)
7373 | Some(crate::dialects::DialectType::Athena)
7374 );
7375 let use_parens = if has_like_only {
7376 is_pg_like
7377 } else {
7378 !has_tags_only
7379 };
7380 if self.config.pretty && use_parens {
7381 self.write(" (");
7382 self.write_newline();
7383 self.indent_level += 1;
7384 for (i, constraint) in ct.constraints.iter().enumerate() {
7385 if i > 0 {
7386 self.write(",");
7387 self.write_newline();
7388 }
7389 self.write_indent();
7390 self.generate_table_constraint(constraint)?;
7391 }
7392 self.indent_level -= 1;
7393 self.write_newline();
7394 self.write(")");
7395 } else {
7396 if use_parens {
7397 self.write(" (");
7398 } else {
7399 self.write_space();
7400 }
7401 for (i, constraint) in ct.constraints.iter().enumerate() {
7402 if i > 0 {
7403 self.write(", ");
7404 }
7405 self.generate_table_constraint(constraint)?;
7406 }
7407 if use_parens {
7408 self.write(")");
7409 }
7410 }
7411 }
7412
7413 if let Some(ref on_prop) = ct.on_property {
7415 self.write(" ");
7416 self.write_keyword("ON");
7417 self.write(" ");
7418 self.generate_expression(&on_prop.this)?;
7419 }
7420
7421 if !is_clickhouse {
7424 for prop in &ct.properties {
7425 if let Expression::SchemaCommentProperty(_) = prop {
7426 if self.config.pretty {
7427 self.write_newline();
7428 } else {
7429 self.write_space();
7430 }
7431 self.generate_expression(prop)?;
7432 }
7433 }
7434 }
7435
7436 if !ct.with_properties.is_empty() {
7438 let is_snowflake_special_table = matches!(
7440 self.config.dialect,
7441 Some(crate::dialects::DialectType::Snowflake)
7442 ) && (ct.table_modifier.as_deref() == Some("ICEBERG")
7443 || ct.table_modifier.as_deref() == Some("DYNAMIC"));
7444 if is_snowflake_special_table {
7445 for (key, value) in &ct.with_properties {
7446 self.write_space();
7447 self.write(key);
7448 self.write("=");
7449 self.write(value);
7450 }
7451 } else if self.config.pretty {
7452 self.write_newline();
7453 self.write_keyword("WITH");
7454 self.write(" (");
7455 self.write_newline();
7456 self.indent_level += 1;
7457 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
7458 if i > 0 {
7459 self.write(",");
7460 self.write_newline();
7461 }
7462 self.write_indent();
7463 self.write(key);
7464 self.write("=");
7465 self.write(value);
7466 }
7467 self.indent_level -= 1;
7468 self.write_newline();
7469 self.write(")");
7470 } else {
7471 self.write_space();
7472 self.write_keyword("WITH");
7473 self.write(" (");
7474 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
7475 if i > 0 {
7476 self.write(", ");
7477 }
7478 self.write(key);
7479 self.write("=");
7480 self.write(value);
7481 }
7482 self.write(")");
7483 }
7484 }
7485
7486 let (pre_as_properties, post_as_properties): (Vec<&Expression>, Vec<&Expression>) =
7487 if is_clickhouse && ct.as_select.is_some() {
7488 let mut pre = Vec::new();
7489 let mut post = Vec::new();
7490 for prop in &ct.properties {
7491 if matches!(prop, Expression::SchemaCommentProperty(_)) {
7492 post.push(prop);
7493 } else {
7494 pre.push(prop);
7495 }
7496 }
7497 (pre, post)
7498 } else {
7499 (ct.properties.iter().collect(), Vec::new())
7500 };
7501
7502 for prop in pre_as_properties {
7504 if !is_clickhouse && matches!(prop, Expression::SchemaCommentProperty(_)) {
7506 continue;
7507 }
7508 if self.config.pretty {
7509 self.write_newline();
7510 } else {
7511 self.write_space();
7512 }
7513 if let Expression::Properties(props) = prop {
7517 let is_hive_dialect = matches!(
7518 self.config.dialect,
7519 Some(crate::dialects::DialectType::Hive)
7520 | Some(crate::dialects::DialectType::Spark)
7521 | Some(crate::dialects::DialectType::Databricks)
7522 | Some(crate::dialects::DialectType::Athena)
7523 );
7524 let is_doris_starrocks = matches!(
7525 self.config.dialect,
7526 Some(crate::dialects::DialectType::Doris)
7527 | Some(crate::dialects::DialectType::StarRocks)
7528 );
7529 if is_hive_dialect {
7530 self.generate_tblproperties_clause(&props.expressions)?;
7531 } else if is_doris_starrocks {
7532 self.generate_properties_clause(&props.expressions)?;
7533 } else {
7534 self.generate_options_clause(&props.expressions)?;
7535 }
7536 } else {
7537 self.generate_expression(prop)?;
7538 }
7539 }
7540
7541 for prop in &ct.post_table_properties {
7543 if let Expression::WithSystemVersioningProperty(ref svp) = prop {
7544 self.write(" WITH(");
7545 self.generate_system_versioning_content(svp)?;
7546 self.write(")");
7547 } else if let Expression::Properties(props) = prop {
7548 let is_doris_starrocks = matches!(
7550 self.config.dialect,
7551 Some(crate::dialects::DialectType::Doris)
7552 | Some(crate::dialects::DialectType::StarRocks)
7553 );
7554 self.write_space();
7555 if is_doris_starrocks {
7556 self.generate_properties_clause(&props.expressions)?;
7557 } else {
7558 self.generate_options_clause(&props.expressions)?;
7559 }
7560 } else {
7561 self.write_space();
7562 self.generate_expression(prop)?;
7563 }
7564 }
7565
7566 if let Some(ref rollup) = ct.rollup {
7569 if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
7570 self.write_space();
7571 self.generate_rollup_property(rollup)?;
7572 }
7573 }
7574
7575 let is_mysql_compatible = matches!(
7579 self.config.dialect,
7580 Some(DialectType::MySQL)
7581 | Some(DialectType::SingleStore)
7582 | Some(DialectType::Doris)
7583 | Some(DialectType::StarRocks)
7584 | None
7585 );
7586 let is_hive_compatible = matches!(
7587 self.config.dialect,
7588 Some(DialectType::Hive)
7589 | Some(DialectType::Spark)
7590 | Some(DialectType::Databricks)
7591 | Some(DialectType::Athena)
7592 );
7593 let mysql_pretty_options =
7594 self.config.pretty && matches!(self.config.dialect, Some(DialectType::MySQL));
7595 for (key, value) in &ct.mysql_table_options {
7596 let should_output = if is_mysql_compatible {
7598 true
7599 } else if is_hive_compatible && key == "COMMENT" {
7600 true } else {
7602 false
7603 };
7604 if should_output {
7605 if mysql_pretty_options {
7606 self.write_newline();
7607 self.write_indent();
7608 } else {
7609 self.write_space();
7610 }
7611 self.write_keyword(key);
7612 if key == "COMMENT" && !self.config.schema_comment_with_eq {
7614 self.write_space();
7615 } else {
7616 self.write("=");
7617 }
7618 self.write(value);
7619 }
7620 }
7621
7622 if ct.temporary
7624 && matches!(
7625 self.config.dialect,
7626 Some(DialectType::Spark) | Some(DialectType::Databricks)
7627 )
7628 && ct.as_select.is_none()
7629 {
7630 self.write_space();
7631 self.write_keyword("USING PARQUET");
7632 }
7633
7634 if !ct.inherits.is_empty() {
7636 self.write_space();
7637 self.write_keyword("INHERITS");
7638 self.write(" (");
7639 for (i, parent) in ct.inherits.iter().enumerate() {
7640 if i > 0 {
7641 self.write(", ");
7642 }
7643 self.generate_table(parent)?;
7644 }
7645 self.write(")");
7646 }
7647
7648 if let Some(ref query) = ct.as_select {
7650 self.write_space();
7651 self.write_keyword("AS");
7652 self.write_space();
7653 if ct.as_select_parenthesized {
7654 self.write("(");
7655 }
7656 self.generate_expression(query)?;
7657 if ct.as_select_parenthesized {
7658 self.write(")");
7659 }
7660
7661 if let Some(with_data) = ct.with_data {
7663 self.write_space();
7664 self.write_keyword("WITH");
7665 if !with_data {
7666 self.write_space();
7667 self.write_keyword("NO");
7668 }
7669 self.write_space();
7670 self.write_keyword("DATA");
7671 }
7672
7673 if let Some(with_statistics) = ct.with_statistics {
7675 self.write_space();
7676 self.write_keyword("AND");
7677 if !with_statistics {
7678 self.write_space();
7679 self.write_keyword("NO");
7680 }
7681 self.write_space();
7682 self.write_keyword("STATISTICS");
7683 }
7684
7685 for index in &ct.teradata_indexes {
7687 self.write_space();
7688 match index.kind {
7689 TeradataIndexKind::NoPrimary => {
7690 self.write_keyword("NO PRIMARY INDEX");
7691 }
7692 TeradataIndexKind::Primary => {
7693 self.write_keyword("PRIMARY INDEX");
7694 }
7695 TeradataIndexKind::PrimaryAmp => {
7696 self.write_keyword("PRIMARY AMP INDEX");
7697 }
7698 TeradataIndexKind::Unique => {
7699 self.write_keyword("UNIQUE INDEX");
7700 }
7701 TeradataIndexKind::UniquePrimary => {
7702 self.write_keyword("UNIQUE PRIMARY INDEX");
7703 }
7704 TeradataIndexKind::Secondary => {
7705 self.write_keyword("INDEX");
7706 }
7707 }
7708 if let Some(ref name) = index.name {
7710 self.write_space();
7711 self.write(name);
7712 }
7713 if !index.columns.is_empty() {
7715 self.write(" (");
7716 for (i, col) in index.columns.iter().enumerate() {
7717 if i > 0 {
7718 self.write(", ");
7719 }
7720 self.write(col);
7721 }
7722 self.write(")");
7723 }
7724 }
7725
7726 if let Some(ref on_commit) = ct.on_commit {
7728 self.write_space();
7729 self.write_keyword("ON COMMIT");
7730 self.write_space();
7731 match on_commit {
7732 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
7733 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
7734 }
7735 }
7736
7737 if !post_as_properties.is_empty() {
7738 for prop in post_as_properties {
7739 self.write_space();
7740 self.generate_expression(prop)?;
7741 }
7742 }
7743
7744 self.athena_hive_context = saved_athena_hive_context;
7746 return Ok(());
7747 }
7748
7749 if let Some(ref on_commit) = ct.on_commit {
7751 self.write_space();
7752 self.write_keyword("ON COMMIT");
7753 self.write_space();
7754 match on_commit {
7755 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
7756 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
7757 }
7758 }
7759
7760 self.athena_hive_context = saved_athena_hive_context;
7762
7763 Ok(())
7764 }
7765
7766 fn generate_column_def_expr(&mut self, col: &ColumnDef) -> Result<()> {
7769 self.generate_identifier(&col.name)?;
7771 if !matches!(col.data_type, DataType::Unknown) {
7773 self.write_space();
7774 self.generate_data_type(&col.data_type)?;
7775 }
7776 for constraint in &col.constraints {
7778 if let ColumnConstraint::Path(path_expr) = constraint {
7779 self.write_space();
7780 self.write_keyword("PATH");
7781 self.write_space();
7782 self.generate_expression(path_expr)?;
7783 }
7784 }
7785 Ok(())
7786 }
7787
7788 fn generate_column_def(&mut self, col: &ColumnDef) -> Result<()> {
7789 let has_computed_no_type = matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
7791 && col
7792 .constraints
7793 .iter()
7794 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
7795 let omit_computed_type = !self.config.computed_column_with_type
7797 && col
7798 .constraints
7799 .iter()
7800 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
7801
7802 let is_partition_column_spec = matches!(col.data_type, DataType::Unknown);
7805
7806 let has_no_type = col.no_type
7809 || (matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
7810 && col.constraints.is_empty());
7811
7812 self.generate_identifier(&col.name)?;
7813
7814 let serial_expansion = if matches!(
7816 self.config.dialect,
7817 Some(DialectType::Materialize) | Some(DialectType::PostgreSQL)
7818 ) {
7819 if let DataType::Custom { ref name } = col.data_type {
7820 match name.to_uppercase().as_str() {
7821 "SERIAL" => Some("INT"),
7822 "BIGSERIAL" => Some("BIGINT"),
7823 "SMALLSERIAL" => Some("SMALLINT"),
7824 _ => None,
7825 }
7826 } else {
7827 None
7828 }
7829 } else {
7830 None
7831 };
7832
7833 if !has_computed_no_type && !omit_computed_type && !is_partition_column_spec && !has_no_type
7834 {
7835 self.write_space();
7836 let saved_nullable_depth = self.clickhouse_nullable_depth;
7839 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
7840 self.clickhouse_nullable_depth = -1;
7841 }
7842 if let Some(int_type) = serial_expansion {
7843 self.write_keyword(int_type);
7845 } else if col.unsigned && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
7846 let unsigned_type = match &col.data_type {
7848 DataType::Int { .. } => Some("UINTEGER"),
7849 DataType::BigInt { .. } => Some("UBIGINT"),
7850 DataType::SmallInt { .. } => Some("USMALLINT"),
7851 DataType::TinyInt { .. } => Some("UTINYINT"),
7852 _ => None,
7853 };
7854 if let Some(utype) = unsigned_type {
7855 self.write_keyword(utype);
7856 } else {
7857 self.generate_data_type(&col.data_type)?;
7858 }
7859 } else {
7860 self.generate_data_type(&col.data_type)?;
7861 }
7862 self.clickhouse_nullable_depth = saved_nullable_depth;
7863 }
7864
7865 if col.unsigned && !matches!(self.config.dialect, Some(DialectType::DuckDB)) {
7868 self.write_space();
7869 self.write_keyword("UNSIGNED");
7870 }
7871 if col.zerofill {
7872 self.write_space();
7873 self.write_keyword("ZEROFILL");
7874 }
7875
7876 if let Some(ref charset) = col.character_set {
7880 self.write_space();
7881 self.write_keyword("CHARACTER SET");
7882 self.write_space();
7883 self.write(charset);
7884 }
7885
7886 if col.uppercase {
7887 self.write_space();
7888 self.write_keyword("UPPERCASE");
7889 }
7890
7891 if let Some(casespecific) = col.casespecific {
7892 self.write_space();
7893 if casespecific {
7894 self.write_keyword("CASESPECIFIC");
7895 } else {
7896 self.write_keyword("NOT CASESPECIFIC");
7897 }
7898 }
7899
7900 if let Some(ref format) = col.format {
7901 self.write_space();
7902 self.write_keyword("FORMAT");
7903 self.write(" '");
7904 self.write(format);
7905 self.write("'");
7906 }
7907
7908 if let Some(ref title) = col.title {
7909 self.write_space();
7910 self.write_keyword("TITLE");
7911 self.write(" '");
7912 self.write(title);
7913 self.write("'");
7914 }
7915
7916 if let Some(length) = col.inline_length {
7917 self.write_space();
7918 self.write_keyword("INLINE LENGTH");
7919 self.write(" ");
7920 self.write(&length.to_string());
7921 }
7922
7923 if let Some(ref compress) = col.compress {
7924 self.write_space();
7925 self.write_keyword("COMPRESS");
7926 if !compress.is_empty() {
7927 if compress.len() == 1 {
7929 if let Expression::Literal(Literal::String(_)) = &compress[0] {
7930 self.write_space();
7931 self.generate_expression(&compress[0])?;
7932 } else {
7933 self.write(" (");
7934 self.generate_expression(&compress[0])?;
7935 self.write(")");
7936 }
7937 } else {
7938 self.write(" (");
7939 for (i, val) in compress.iter().enumerate() {
7940 if i > 0 {
7941 self.write(", ");
7942 }
7943 self.generate_expression(val)?;
7944 }
7945 self.write(")");
7946 }
7947 }
7948 }
7949
7950 if !col.constraint_order.is_empty() {
7953 let mut references_idx = 0;
7956 let mut check_idx = 0;
7957 let mut generated_idx = 0;
7958 let mut collate_idx = 0;
7959 let mut comment_idx = 0;
7960 let defer_not_null_after_identity = false;
7963 let mut pending_not_null_after_identity = false;
7964
7965 for constraint_type in &col.constraint_order {
7966 match constraint_type {
7967 ConstraintType::PrimaryKey => {
7968 if col.primary_key
7970 && !matches!(self.config.dialect, Some(DialectType::Materialize))
7971 {
7972 if let Some(ref cname) = col.primary_key_constraint_name {
7973 self.write_space();
7974 self.write_keyword("CONSTRAINT");
7975 self.write_space();
7976 self.write(cname);
7977 }
7978 self.write_space();
7979 self.write_keyword("PRIMARY KEY");
7980 if let Some(ref order) = col.primary_key_order {
7981 self.write_space();
7982 match order {
7983 SortOrder::Asc => self.write_keyword("ASC"),
7984 SortOrder::Desc => self.write_keyword("DESC"),
7985 }
7986 }
7987 }
7988 }
7989 ConstraintType::Unique => {
7990 if col.unique {
7991 if let Some(ref cname) = col.unique_constraint_name {
7992 self.write_space();
7993 self.write_keyword("CONSTRAINT");
7994 self.write_space();
7995 self.write(cname);
7996 }
7997 self.write_space();
7998 self.write_keyword("UNIQUE");
7999 if col.unique_nulls_not_distinct {
8001 self.write(" NULLS NOT DISTINCT");
8002 }
8003 }
8004 }
8005 ConstraintType::NotNull => {
8006 if col.nullable == Some(false) {
8007 if defer_not_null_after_identity {
8008 pending_not_null_after_identity = true;
8009 continue;
8010 }
8011 if let Some(ref cname) = col.not_null_constraint_name {
8012 self.write_space();
8013 self.write_keyword("CONSTRAINT");
8014 self.write_space();
8015 self.write(cname);
8016 }
8017 self.write_space();
8018 self.write_keyword("NOT NULL");
8019 }
8020 }
8021 ConstraintType::Null => {
8022 if col.nullable == Some(true) {
8023 self.write_space();
8024 self.write_keyword("NULL");
8025 }
8026 }
8027 ConstraintType::Default => {
8028 if let Some(ref default) = col.default {
8029 self.write_space();
8030 self.write_keyword("DEFAULT");
8031 self.write_space();
8032 self.generate_expression(default)?;
8033 }
8034 }
8035 ConstraintType::AutoIncrement => {
8036 if col.auto_increment {
8037 if matches!(
8039 self.config.dialect,
8040 Some(crate::dialects::DialectType::DuckDB)
8041 ) {
8042 } else if matches!(
8044 self.config.dialect,
8045 Some(crate::dialects::DialectType::Materialize)
8046 ) {
8047 if !matches!(col.nullable, Some(false)) {
8049 self.write_space();
8050 self.write_keyword("NOT NULL");
8051 }
8052 } else if matches!(
8053 self.config.dialect,
8054 Some(crate::dialects::DialectType::PostgreSQL)
8055 ) {
8056 self.write_space();
8058 self.generate_auto_increment_keyword(col)?;
8059 } else {
8060 self.write_space();
8061 self.generate_auto_increment_keyword(col)?;
8062 if pending_not_null_after_identity {
8063 self.write_space();
8064 self.write_keyword("NOT NULL");
8065 pending_not_null_after_identity = false;
8066 }
8067 }
8068 } }
8070 ConstraintType::References => {
8071 while references_idx < col.constraints.len() {
8073 if let ColumnConstraint::References(fk_ref) =
8074 &col.constraints[references_idx]
8075 {
8076 if let Some(ref name) = fk_ref.constraint_name {
8078 self.write_space();
8079 self.write_keyword("CONSTRAINT");
8080 self.write_space();
8081 self.write(name);
8082 }
8083 self.write_space();
8084 if fk_ref.has_foreign_key_keywords {
8085 self.write_keyword("FOREIGN KEY");
8086 self.write_space();
8087 }
8088 self.write_keyword("REFERENCES");
8089 self.write_space();
8090 self.generate_table(&fk_ref.table)?;
8091 if !fk_ref.columns.is_empty() {
8092 self.write(" (");
8093 for (i, c) in fk_ref.columns.iter().enumerate() {
8094 if i > 0 {
8095 self.write(", ");
8096 }
8097 self.generate_identifier(c)?;
8098 }
8099 self.write(")");
8100 }
8101 self.generate_referential_actions(fk_ref)?;
8102 references_idx += 1;
8103 break;
8104 }
8105 references_idx += 1;
8106 }
8107 }
8108 ConstraintType::Check => {
8109 while check_idx < col.constraints.len() {
8111 if let ColumnConstraint::Check(expr) = &col.constraints[check_idx] {
8112 if check_idx == 0 {
8114 if let Some(ref cname) = col.check_constraint_name {
8115 self.write_space();
8116 self.write_keyword("CONSTRAINT");
8117 self.write_space();
8118 self.write(cname);
8119 }
8120 }
8121 self.write_space();
8122 self.write_keyword("CHECK");
8123 self.write(" (");
8124 self.generate_expression(expr)?;
8125 self.write(")");
8126 check_idx += 1;
8127 break;
8128 }
8129 check_idx += 1;
8130 }
8131 }
8132 ConstraintType::GeneratedAsIdentity => {
8133 while generated_idx < col.constraints.len() {
8135 if let ColumnConstraint::GeneratedAsIdentity(gen) =
8136 &col.constraints[generated_idx]
8137 {
8138 self.write_space();
8139 if matches!(
8141 self.config.dialect,
8142 Some(crate::dialects::DialectType::Redshift)
8143 ) {
8144 self.write_keyword("IDENTITY");
8145 self.write("(");
8146 if let Some(ref start) = gen.start {
8147 self.generate_expression(start)?;
8148 } else {
8149 self.write("0");
8150 }
8151 self.write(", ");
8152 if let Some(ref incr) = gen.increment {
8153 self.generate_expression(incr)?;
8154 } else {
8155 self.write("1");
8156 }
8157 self.write(")");
8158 } else {
8159 self.write_keyword("GENERATED");
8160 if gen.always {
8161 self.write_space();
8162 self.write_keyword("ALWAYS");
8163 } else {
8164 self.write_space();
8165 self.write_keyword("BY DEFAULT");
8166 if gen.on_null {
8167 self.write_space();
8168 self.write_keyword("ON NULL");
8169 }
8170 }
8171 self.write_space();
8172 self.write_keyword("AS IDENTITY");
8173
8174 let has_options = gen.start.is_some()
8175 || gen.increment.is_some()
8176 || gen.minvalue.is_some()
8177 || gen.maxvalue.is_some()
8178 || gen.cycle.is_some();
8179 if has_options {
8180 self.write(" (");
8181 let mut first = true;
8182 if let Some(ref start) = gen.start {
8183 if !first {
8184 self.write(" ");
8185 }
8186 first = false;
8187 self.write_keyword("START WITH");
8188 self.write_space();
8189 self.generate_expression(start)?;
8190 }
8191 if let Some(ref incr) = gen.increment {
8192 if !first {
8193 self.write(" ");
8194 }
8195 first = false;
8196 self.write_keyword("INCREMENT BY");
8197 self.write_space();
8198 self.generate_expression(incr)?;
8199 }
8200 if let Some(ref minv) = gen.minvalue {
8201 if !first {
8202 self.write(" ");
8203 }
8204 first = false;
8205 self.write_keyword("MINVALUE");
8206 self.write_space();
8207 self.generate_expression(minv)?;
8208 }
8209 if let Some(ref maxv) = gen.maxvalue {
8210 if !first {
8211 self.write(" ");
8212 }
8213 first = false;
8214 self.write_keyword("MAXVALUE");
8215 self.write_space();
8216 self.generate_expression(maxv)?;
8217 }
8218 if let Some(cycle) = gen.cycle {
8219 if !first {
8220 self.write(" ");
8221 }
8222 if cycle {
8223 self.write_keyword("CYCLE");
8224 } else {
8225 self.write_keyword("NO CYCLE");
8226 }
8227 }
8228 self.write(")");
8229 }
8230 }
8231 generated_idx += 1;
8232 break;
8233 }
8234 generated_idx += 1;
8235 }
8236 }
8237 ConstraintType::Collate => {
8238 while collate_idx < col.constraints.len() {
8240 if let ColumnConstraint::Collate(collation) =
8241 &col.constraints[collate_idx]
8242 {
8243 self.write_space();
8244 self.write_keyword("COLLATE");
8245 self.write_space();
8246 self.generate_identifier(collation)?;
8247 collate_idx += 1;
8248 break;
8249 }
8250 collate_idx += 1;
8251 }
8252 }
8253 ConstraintType::Comment => {
8254 while comment_idx < col.constraints.len() {
8256 if let ColumnConstraint::Comment(comment) =
8257 &col.constraints[comment_idx]
8258 {
8259 self.write_space();
8260 self.write_keyword("COMMENT");
8261 self.write_space();
8262 self.generate_string_literal(comment)?;
8263 comment_idx += 1;
8264 break;
8265 }
8266 comment_idx += 1;
8267 }
8268 }
8269 ConstraintType::Tags => {
8270 for constraint in &col.constraints {
8272 if let ColumnConstraint::Tags(tags) = constraint {
8273 self.write_space();
8274 self.write_keyword("TAG");
8275 self.write(" (");
8276 for (i, expr) in tags.expressions.iter().enumerate() {
8277 if i > 0 {
8278 self.write(", ");
8279 }
8280 self.generate_expression(expr)?;
8281 }
8282 self.write(")");
8283 break;
8284 }
8285 }
8286 }
8287 ConstraintType::ComputedColumn => {
8288 for constraint in &col.constraints {
8290 if let ColumnConstraint::ComputedColumn(cc) = constraint {
8291 self.write_space();
8292 self.generate_computed_column_inline(cc)?;
8293 break;
8294 }
8295 }
8296 }
8297 ConstraintType::GeneratedAsRow => {
8298 for constraint in &col.constraints {
8300 if let ColumnConstraint::GeneratedAsRow(gar) = constraint {
8301 self.write_space();
8302 self.generate_generated_as_row_inline(gar)?;
8303 break;
8304 }
8305 }
8306 }
8307 ConstraintType::OnUpdate => {
8308 if let Some(ref expr) = col.on_update {
8309 self.write_space();
8310 self.write_keyword("ON UPDATE");
8311 self.write_space();
8312 self.generate_expression(expr)?;
8313 }
8314 }
8315 ConstraintType::Encode => {
8316 if let Some(ref encoding) = col.encoding {
8317 self.write_space();
8318 self.write_keyword("ENCODE");
8319 self.write_space();
8320 self.write(encoding);
8321 }
8322 }
8323 ConstraintType::Path => {
8324 for constraint in &col.constraints {
8326 if let ColumnConstraint::Path(path_expr) = constraint {
8327 self.write_space();
8328 self.write_keyword("PATH");
8329 self.write_space();
8330 self.generate_expression(path_expr)?;
8331 break;
8332 }
8333 }
8334 }
8335 }
8336 }
8337 if pending_not_null_after_identity {
8338 self.write_space();
8339 self.write_keyword("NOT NULL");
8340 }
8341 } else {
8342 if col.primary_key {
8344 self.write_space();
8345 self.write_keyword("PRIMARY KEY");
8346 if let Some(ref order) = col.primary_key_order {
8347 self.write_space();
8348 match order {
8349 SortOrder::Asc => self.write_keyword("ASC"),
8350 SortOrder::Desc => self.write_keyword("DESC"),
8351 }
8352 }
8353 }
8354
8355 if col.unique {
8356 self.write_space();
8357 self.write_keyword("UNIQUE");
8358 if col.unique_nulls_not_distinct {
8360 self.write(" NULLS NOT DISTINCT");
8361 }
8362 }
8363
8364 match col.nullable {
8365 Some(false) => {
8366 self.write_space();
8367 self.write_keyword("NOT NULL");
8368 }
8369 Some(true) => {
8370 self.write_space();
8371 self.write_keyword("NULL");
8372 }
8373 None => {}
8374 }
8375
8376 if let Some(ref default) = col.default {
8377 self.write_space();
8378 self.write_keyword("DEFAULT");
8379 self.write_space();
8380 self.generate_expression(default)?;
8381 }
8382
8383 if col.auto_increment {
8384 self.write_space();
8385 self.generate_auto_increment_keyword(col)?;
8386 }
8387
8388 for constraint in &col.constraints {
8390 match constraint {
8391 ColumnConstraint::References(fk_ref) => {
8392 self.write_space();
8393 if fk_ref.has_foreign_key_keywords {
8394 self.write_keyword("FOREIGN KEY");
8395 self.write_space();
8396 }
8397 self.write_keyword("REFERENCES");
8398 self.write_space();
8399 self.generate_table(&fk_ref.table)?;
8400 if !fk_ref.columns.is_empty() {
8401 self.write(" (");
8402 for (i, c) in fk_ref.columns.iter().enumerate() {
8403 if i > 0 {
8404 self.write(", ");
8405 }
8406 self.generate_identifier(c)?;
8407 }
8408 self.write(")");
8409 }
8410 self.generate_referential_actions(fk_ref)?;
8411 }
8412 ColumnConstraint::Check(expr) => {
8413 self.write_space();
8414 self.write_keyword("CHECK");
8415 self.write(" (");
8416 self.generate_expression(expr)?;
8417 self.write(")");
8418 }
8419 ColumnConstraint::GeneratedAsIdentity(gen) => {
8420 self.write_space();
8421 if matches!(
8423 self.config.dialect,
8424 Some(crate::dialects::DialectType::Redshift)
8425 ) {
8426 self.write_keyword("IDENTITY");
8427 self.write("(");
8428 if let Some(ref start) = gen.start {
8429 self.generate_expression(start)?;
8430 } else {
8431 self.write("0");
8432 }
8433 self.write(", ");
8434 if let Some(ref incr) = gen.increment {
8435 self.generate_expression(incr)?;
8436 } else {
8437 self.write("1");
8438 }
8439 self.write(")");
8440 } else {
8441 self.write_keyword("GENERATED");
8442 if gen.always {
8443 self.write_space();
8444 self.write_keyword("ALWAYS");
8445 } else {
8446 self.write_space();
8447 self.write_keyword("BY DEFAULT");
8448 if gen.on_null {
8449 self.write_space();
8450 self.write_keyword("ON NULL");
8451 }
8452 }
8453 self.write_space();
8454 self.write_keyword("AS IDENTITY");
8455
8456 let has_options = gen.start.is_some()
8457 || gen.increment.is_some()
8458 || gen.minvalue.is_some()
8459 || gen.maxvalue.is_some()
8460 || gen.cycle.is_some();
8461 if has_options {
8462 self.write(" (");
8463 let mut first = true;
8464 if let Some(ref start) = gen.start {
8465 if !first {
8466 self.write(" ");
8467 }
8468 first = false;
8469 self.write_keyword("START WITH");
8470 self.write_space();
8471 self.generate_expression(start)?;
8472 }
8473 if let Some(ref incr) = gen.increment {
8474 if !first {
8475 self.write(" ");
8476 }
8477 first = false;
8478 self.write_keyword("INCREMENT BY");
8479 self.write_space();
8480 self.generate_expression(incr)?;
8481 }
8482 if let Some(ref minv) = gen.minvalue {
8483 if !first {
8484 self.write(" ");
8485 }
8486 first = false;
8487 self.write_keyword("MINVALUE");
8488 self.write_space();
8489 self.generate_expression(minv)?;
8490 }
8491 if let Some(ref maxv) = gen.maxvalue {
8492 if !first {
8493 self.write(" ");
8494 }
8495 first = false;
8496 self.write_keyword("MAXVALUE");
8497 self.write_space();
8498 self.generate_expression(maxv)?;
8499 }
8500 if let Some(cycle) = gen.cycle {
8501 if !first {
8502 self.write(" ");
8503 }
8504 if cycle {
8505 self.write_keyword("CYCLE");
8506 } else {
8507 self.write_keyword("NO CYCLE");
8508 }
8509 }
8510 self.write(")");
8511 }
8512 }
8513 }
8514 ColumnConstraint::Collate(collation) => {
8515 self.write_space();
8516 self.write_keyword("COLLATE");
8517 self.write_space();
8518 self.generate_identifier(collation)?;
8519 }
8520 ColumnConstraint::Comment(comment) => {
8521 self.write_space();
8522 self.write_keyword("COMMENT");
8523 self.write_space();
8524 self.generate_string_literal(comment)?;
8525 }
8526 ColumnConstraint::Path(path_expr) => {
8527 self.write_space();
8528 self.write_keyword("PATH");
8529 self.write_space();
8530 self.generate_expression(path_expr)?;
8531 }
8532 _ => {} }
8534 }
8535
8536 if let Some(ref encoding) = col.encoding {
8538 self.write_space();
8539 self.write_keyword("ENCODE");
8540 self.write_space();
8541 self.write(encoding);
8542 }
8543 }
8544
8545 if let Some(ref codec) = col.codec {
8547 self.write_space();
8548 self.write_keyword("CODEC");
8549 self.write("(");
8550 self.write(codec);
8551 self.write(")");
8552 }
8553
8554 if let Some(ref ephemeral) = col.ephemeral {
8556 self.write_space();
8557 self.write_keyword("EPHEMERAL");
8558 if let Some(ref expr) = ephemeral {
8559 self.write_space();
8560 self.generate_expression(expr)?;
8561 }
8562 }
8563
8564 if let Some(ref mat_expr) = col.materialized_expr {
8566 self.write_space();
8567 self.write_keyword("MATERIALIZED");
8568 self.write_space();
8569 self.generate_expression(mat_expr)?;
8570 }
8571
8572 if let Some(ref alias_expr) = col.alias_expr {
8574 self.write_space();
8575 self.write_keyword("ALIAS");
8576 self.write_space();
8577 self.generate_expression(alias_expr)?;
8578 }
8579
8580 if let Some(ref ttl_expr) = col.ttl_expr {
8582 self.write_space();
8583 self.write_keyword("TTL");
8584 self.write_space();
8585 self.generate_expression(ttl_expr)?;
8586 }
8587
8588 if col.not_for_replication
8590 && matches!(
8591 self.config.dialect,
8592 Some(crate::dialects::DialectType::TSQL)
8593 | Some(crate::dialects::DialectType::Fabric)
8594 )
8595 {
8596 self.write_space();
8597 self.write_keyword("NOT FOR REPLICATION");
8598 }
8599
8600 if !col.options.is_empty() {
8602 self.write_space();
8603 self.generate_options_clause(&col.options)?;
8604 }
8605
8606 if !col.primary_key
8609 && self
8610 .sqlite_inline_pk_columns
8611 .contains(&col.name.name.to_lowercase())
8612 {
8613 self.write_space();
8614 self.write_keyword("PRIMARY KEY");
8615 }
8616
8617 if serial_expansion.is_some() {
8620 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
8621 self.write_space();
8622 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY NOT NULL");
8623 } else if matches!(self.config.dialect, Some(DialectType::Materialize)) {
8624 self.write_space();
8625 self.write_keyword("NOT NULL");
8626 }
8627 }
8628
8629 Ok(())
8630 }
8631
8632 fn generate_table_constraint(&mut self, constraint: &TableConstraint) -> Result<()> {
8633 match constraint {
8634 TableConstraint::PrimaryKey {
8635 name,
8636 columns,
8637 include_columns,
8638 modifiers,
8639 has_constraint_keyword,
8640 } => {
8641 if let Some(ref n) = name {
8642 if *has_constraint_keyword {
8643 self.write_keyword("CONSTRAINT");
8644 self.write_space();
8645 self.generate_identifier(n)?;
8646 self.write_space();
8647 }
8648 }
8649 self.write_keyword("PRIMARY KEY");
8650 if let Some(ref clustered) = modifiers.clustered {
8652 self.write_space();
8653 self.write_keyword(clustered);
8654 }
8655 if let Some(ref n) = name {
8657 if !*has_constraint_keyword {
8658 self.write_space();
8659 self.generate_identifier(n)?;
8660 }
8661 }
8662 self.write(" (");
8663 for (i, col) in columns.iter().enumerate() {
8664 if i > 0 {
8665 self.write(", ");
8666 }
8667 self.generate_identifier(col)?;
8668 }
8669 self.write(")");
8670 if !include_columns.is_empty() {
8671 self.write_space();
8672 self.write_keyword("INCLUDE");
8673 self.write(" (");
8674 for (i, col) in include_columns.iter().enumerate() {
8675 if i > 0 {
8676 self.write(", ");
8677 }
8678 self.generate_identifier(col)?;
8679 }
8680 self.write(")");
8681 }
8682 self.generate_constraint_modifiers(modifiers);
8683 }
8684 TableConstraint::Unique {
8685 name,
8686 columns,
8687 columns_parenthesized,
8688 modifiers,
8689 has_constraint_keyword,
8690 nulls_not_distinct,
8691 } => {
8692 if let Some(ref n) = name {
8693 if *has_constraint_keyword {
8694 self.write_keyword("CONSTRAINT");
8695 self.write_space();
8696 self.generate_identifier(n)?;
8697 self.write_space();
8698 }
8699 }
8700 self.write_keyword("UNIQUE");
8701 if let Some(ref clustered) = modifiers.clustered {
8703 self.write_space();
8704 self.write_keyword(clustered);
8705 }
8706 if *nulls_not_distinct {
8708 self.write(" NULLS NOT DISTINCT");
8709 }
8710 if let Some(ref n) = name {
8712 if !*has_constraint_keyword {
8713 self.write_space();
8714 self.generate_identifier(n)?;
8715 }
8716 }
8717 if *columns_parenthesized {
8718 self.write(" (");
8719 for (i, col) in columns.iter().enumerate() {
8720 if i > 0 {
8721 self.write(", ");
8722 }
8723 self.generate_identifier(col)?;
8724 }
8725 self.write(")");
8726 } else {
8727 for col in columns.iter() {
8729 self.write_space();
8730 self.generate_identifier(col)?;
8731 }
8732 }
8733 self.generate_constraint_modifiers(modifiers);
8734 }
8735 TableConstraint::ForeignKey {
8736 name,
8737 columns,
8738 references,
8739 on_delete,
8740 on_update,
8741 modifiers,
8742 } => {
8743 if let Some(ref n) = name {
8744 self.write_keyword("CONSTRAINT");
8745 self.write_space();
8746 self.generate_identifier(n)?;
8747 self.write_space();
8748 }
8749 self.write_keyword("FOREIGN KEY");
8750 self.write(" (");
8751 for (i, col) in columns.iter().enumerate() {
8752 if i > 0 {
8753 self.write(", ");
8754 }
8755 self.generate_identifier(col)?;
8756 }
8757 self.write(")");
8758 if let Some(ref refs) = references {
8759 self.write(" ");
8760 self.write_keyword("REFERENCES");
8761 self.write_space();
8762 self.generate_table(&refs.table)?;
8763 if !refs.columns.is_empty() {
8764 if self.config.pretty {
8765 self.write(" (");
8766 self.write_newline();
8767 self.indent_level += 1;
8768 for (i, col) in refs.columns.iter().enumerate() {
8769 if i > 0 {
8770 self.write(",");
8771 self.write_newline();
8772 }
8773 self.write_indent();
8774 self.generate_identifier(col)?;
8775 }
8776 self.indent_level -= 1;
8777 self.write_newline();
8778 self.write_indent();
8779 self.write(")");
8780 } else {
8781 self.write(" (");
8782 for (i, col) in refs.columns.iter().enumerate() {
8783 if i > 0 {
8784 self.write(", ");
8785 }
8786 self.generate_identifier(col)?;
8787 }
8788 self.write(")");
8789 }
8790 }
8791 self.generate_referential_actions(refs)?;
8792 } else {
8793 if let Some(ref action) = on_delete {
8795 self.write_space();
8796 self.write_keyword("ON DELETE");
8797 self.write_space();
8798 self.generate_referential_action(action);
8799 }
8800 if let Some(ref action) = on_update {
8801 self.write_space();
8802 self.write_keyword("ON UPDATE");
8803 self.write_space();
8804 self.generate_referential_action(action);
8805 }
8806 }
8807 self.generate_constraint_modifiers(modifiers);
8808 }
8809 TableConstraint::Check {
8810 name,
8811 expression,
8812 modifiers,
8813 } => {
8814 if let Some(ref n) = name {
8815 self.write_keyword("CONSTRAINT");
8816 self.write_space();
8817 self.generate_identifier(n)?;
8818 self.write_space();
8819 }
8820 self.write_keyword("CHECK");
8821 self.write(" (");
8822 self.generate_expression(expression)?;
8823 self.write(")");
8824 self.generate_constraint_modifiers(modifiers);
8825 }
8826 TableConstraint::Index {
8827 name,
8828 columns,
8829 kind,
8830 modifiers,
8831 use_key_keyword,
8832 expression,
8833 index_type,
8834 granularity,
8835 } => {
8836 if expression.is_some() {
8838 self.write_keyword("INDEX");
8839 if let Some(ref n) = name {
8840 self.write_space();
8841 self.generate_identifier(n)?;
8842 }
8843 if let Some(ref expr) = expression {
8844 self.write_space();
8845 self.generate_expression(expr)?;
8846 }
8847 if let Some(ref idx_type) = index_type {
8848 self.write_space();
8849 self.write_keyword("TYPE");
8850 self.write_space();
8851 self.generate_expression(idx_type)?;
8852 }
8853 if let Some(ref gran) = granularity {
8854 self.write_space();
8855 self.write_keyword("GRANULARITY");
8856 self.write_space();
8857 self.generate_expression(gran)?;
8858 }
8859 } else {
8860 use crate::dialects::DialectType;
8864 let index_keyword = if *use_key_keyword
8865 && !matches!(self.config.dialect, Some(DialectType::MySQL))
8866 {
8867 "KEY"
8868 } else {
8869 "INDEX"
8870 };
8871
8872 if let Some(ref k) = kind {
8874 self.write_keyword(k);
8875 if k != "UNIQUE" {
8877 self.write_space();
8878 self.write_keyword(index_keyword);
8879 }
8880 } else {
8881 self.write_keyword(index_keyword);
8882 }
8883
8884 if modifiers.using_before_columns && name.is_none() {
8886 if let Some(ref using) = modifiers.using {
8887 self.write_space();
8888 self.write_keyword("USING");
8889 self.write_space();
8890 self.write_keyword(using);
8891 }
8892 }
8893
8894 if let Some(ref n) = name {
8896 self.write_space();
8897 self.generate_identifier(n)?;
8898 }
8899
8900 if modifiers.using_before_columns && name.is_some() {
8902 if let Some(ref using) = modifiers.using {
8903 self.write_space();
8904 self.write_keyword("USING");
8905 self.write_space();
8906 self.write_keyword(using);
8907 }
8908 }
8909
8910 self.write(" (");
8912 for (i, col) in columns.iter().enumerate() {
8913 if i > 0 {
8914 self.write(", ");
8915 }
8916 self.generate_identifier(col)?;
8917 }
8918 self.write(")");
8919
8920 if !modifiers.using_before_columns {
8922 if let Some(ref using) = modifiers.using {
8923 self.write_space();
8924 self.write_keyword("USING");
8925 self.write_space();
8926 self.write_keyword(using);
8927 }
8928 }
8929
8930 self.generate_constraint_modifiers_without_using(modifiers);
8932 }
8933 }
8934 TableConstraint::Projection { name, expression } => {
8935 self.write_keyword("PROJECTION");
8937 self.write_space();
8938 self.generate_identifier(name)?;
8939 self.write(" (");
8940 self.generate_expression(expression)?;
8941 self.write(")");
8942 }
8943 TableConstraint::Like { source, options } => {
8944 self.write_keyword("LIKE");
8945 self.write_space();
8946 self.generate_table(source)?;
8947 for (action, prop) in options {
8948 self.write_space();
8949 match action {
8950 LikeOptionAction::Including => self.write_keyword("INCLUDING"),
8951 LikeOptionAction::Excluding => self.write_keyword("EXCLUDING"),
8952 }
8953 self.write_space();
8954 self.write_keyword(prop);
8955 }
8956 }
8957 TableConstraint::PeriodForSystemTime { start_col, end_col } => {
8958 self.write_keyword("PERIOD FOR SYSTEM_TIME");
8959 self.write(" (");
8960 self.generate_identifier(start_col)?;
8961 self.write(", ");
8962 self.generate_identifier(end_col)?;
8963 self.write(")");
8964 }
8965 TableConstraint::Exclude {
8966 name,
8967 using,
8968 elements,
8969 include_columns,
8970 where_clause,
8971 with_params,
8972 using_index_tablespace,
8973 modifiers: _,
8974 } => {
8975 if let Some(ref n) = name {
8976 self.write_keyword("CONSTRAINT");
8977 self.write_space();
8978 self.generate_identifier(n)?;
8979 self.write_space();
8980 }
8981 self.write_keyword("EXCLUDE");
8982 if let Some(ref method) = using {
8983 self.write_space();
8984 self.write_keyword("USING");
8985 self.write_space();
8986 self.write(method);
8987 self.write("(");
8988 } else {
8989 self.write(" (");
8990 }
8991 for (i, elem) in elements.iter().enumerate() {
8992 if i > 0 {
8993 self.write(", ");
8994 }
8995 self.write(&elem.expression);
8996 self.write_space();
8997 self.write_keyword("WITH");
8998 self.write_space();
8999 self.write(&elem.operator);
9000 }
9001 self.write(")");
9002 if !include_columns.is_empty() {
9003 self.write_space();
9004 self.write_keyword("INCLUDE");
9005 self.write(" (");
9006 for (i, col) in include_columns.iter().enumerate() {
9007 if i > 0 {
9008 self.write(", ");
9009 }
9010 self.generate_identifier(col)?;
9011 }
9012 self.write(")");
9013 }
9014 if !with_params.is_empty() {
9015 self.write_space();
9016 self.write_keyword("WITH");
9017 self.write(" (");
9018 for (i, (key, val)) in with_params.iter().enumerate() {
9019 if i > 0 {
9020 self.write(", ");
9021 }
9022 self.write(key);
9023 self.write("=");
9024 self.write(val);
9025 }
9026 self.write(")");
9027 }
9028 if let Some(ref tablespace) = using_index_tablespace {
9029 self.write_space();
9030 self.write_keyword("USING INDEX TABLESPACE");
9031 self.write_space();
9032 self.write(tablespace);
9033 }
9034 if let Some(ref where_expr) = where_clause {
9035 self.write_space();
9036 self.write_keyword("WHERE");
9037 self.write(" (");
9038 self.generate_expression(where_expr)?;
9039 self.write(")");
9040 }
9041 }
9042 TableConstraint::Tags(tags) => {
9043 self.write_keyword("TAG");
9044 self.write(" (");
9045 for (i, expr) in tags.expressions.iter().enumerate() {
9046 if i > 0 {
9047 self.write(", ");
9048 }
9049 self.generate_expression(expr)?;
9050 }
9051 self.write(")");
9052 }
9053 TableConstraint::InitiallyDeferred { deferred } => {
9054 self.write_keyword("INITIALLY");
9055 self.write_space();
9056 if *deferred {
9057 self.write_keyword("DEFERRED");
9058 } else {
9059 self.write_keyword("IMMEDIATE");
9060 }
9061 }
9062 }
9063 Ok(())
9064 }
9065
9066 fn generate_constraint_modifiers(&mut self, modifiers: &ConstraintModifiers) {
9067 if let Some(using) = &modifiers.using {
9069 self.write_space();
9070 self.write_keyword("USING");
9071 self.write_space();
9072 self.write_keyword(using);
9073 }
9074 if let Some(enforced) = modifiers.enforced {
9076 self.write_space();
9077 if enforced {
9078 self.write_keyword("ENFORCED");
9079 } else {
9080 self.write_keyword("NOT ENFORCED");
9081 }
9082 }
9083 if let Some(deferrable) = modifiers.deferrable {
9085 self.write_space();
9086 if deferrable {
9087 self.write_keyword("DEFERRABLE");
9088 } else {
9089 self.write_keyword("NOT DEFERRABLE");
9090 }
9091 }
9092 if let Some(initially_deferred) = modifiers.initially_deferred {
9094 self.write_space();
9095 if initially_deferred {
9096 self.write_keyword("INITIALLY DEFERRED");
9097 } else {
9098 self.write_keyword("INITIALLY IMMEDIATE");
9099 }
9100 }
9101 if modifiers.norely {
9103 self.write_space();
9104 self.write_keyword("NORELY");
9105 }
9106 if modifiers.rely {
9108 self.write_space();
9109 self.write_keyword("RELY");
9110 }
9111 if modifiers.not_valid {
9113 self.write_space();
9114 self.write_keyword("NOT VALID");
9115 }
9116 if let Some(on_conflict) = &modifiers.on_conflict {
9118 self.write_space();
9119 self.write_keyword("ON CONFLICT");
9120 self.write_space();
9121 self.write_keyword(on_conflict);
9122 }
9123 if !modifiers.with_options.is_empty() {
9125 self.write_space();
9126 self.write_keyword("WITH");
9127 self.write(" (");
9128 for (i, (key, value)) in modifiers.with_options.iter().enumerate() {
9129 if i > 0 {
9130 self.write(", ");
9131 }
9132 self.write(key);
9133 self.write("=");
9134 self.write(value);
9135 }
9136 self.write(")");
9137 }
9138 if let Some(ref fg) = modifiers.on_filegroup {
9140 self.write_space();
9141 self.write_keyword("ON");
9142 self.write_space();
9143 let _ = self.generate_identifier(fg);
9144 }
9145 }
9146
9147 fn generate_constraint_modifiers_without_using(&mut self, modifiers: &ConstraintModifiers) {
9149 if let Some(enforced) = modifiers.enforced {
9151 self.write_space();
9152 if enforced {
9153 self.write_keyword("ENFORCED");
9154 } else {
9155 self.write_keyword("NOT ENFORCED");
9156 }
9157 }
9158 if let Some(deferrable) = modifiers.deferrable {
9160 self.write_space();
9161 if deferrable {
9162 self.write_keyword("DEFERRABLE");
9163 } else {
9164 self.write_keyword("NOT DEFERRABLE");
9165 }
9166 }
9167 if let Some(initially_deferred) = modifiers.initially_deferred {
9169 self.write_space();
9170 if initially_deferred {
9171 self.write_keyword("INITIALLY DEFERRED");
9172 } else {
9173 self.write_keyword("INITIALLY IMMEDIATE");
9174 }
9175 }
9176 if modifiers.norely {
9178 self.write_space();
9179 self.write_keyword("NORELY");
9180 }
9181 if modifiers.rely {
9183 self.write_space();
9184 self.write_keyword("RELY");
9185 }
9186 if modifiers.not_valid {
9188 self.write_space();
9189 self.write_keyword("NOT VALID");
9190 }
9191 if let Some(on_conflict) = &modifiers.on_conflict {
9193 self.write_space();
9194 self.write_keyword("ON CONFLICT");
9195 self.write_space();
9196 self.write_keyword(on_conflict);
9197 }
9198 self.generate_index_specific_modifiers(modifiers);
9200 }
9201
9202 fn generate_index_specific_modifiers(&mut self, modifiers: &ConstraintModifiers) {
9204 if let Some(ref comment) = modifiers.comment {
9205 self.write_space();
9206 self.write_keyword("COMMENT");
9207 self.write(" '");
9208 self.write(comment);
9209 self.write("'");
9210 }
9211 if let Some(visible) = modifiers.visible {
9212 self.write_space();
9213 if visible {
9214 self.write_keyword("VISIBLE");
9215 } else {
9216 self.write_keyword("INVISIBLE");
9217 }
9218 }
9219 if let Some(ref attr) = modifiers.engine_attribute {
9220 self.write_space();
9221 self.write_keyword("ENGINE_ATTRIBUTE");
9222 self.write(" = '");
9223 self.write(attr);
9224 self.write("'");
9225 }
9226 if let Some(ref parser) = modifiers.with_parser {
9227 self.write_space();
9228 self.write_keyword("WITH PARSER");
9229 self.write_space();
9230 self.write(parser);
9231 }
9232 }
9233
9234 fn generate_referential_actions(&mut self, fk_ref: &ForeignKeyRef) -> Result<()> {
9235 if !fk_ref.match_after_actions {
9237 if let Some(ref match_type) = fk_ref.match_type {
9238 self.write_space();
9239 self.write_keyword("MATCH");
9240 self.write_space();
9241 match match_type {
9242 MatchType::Full => self.write_keyword("FULL"),
9243 MatchType::Partial => self.write_keyword("PARTIAL"),
9244 MatchType::Simple => self.write_keyword("SIMPLE"),
9245 }
9246 }
9247 }
9248
9249 if fk_ref.on_update_first {
9251 if let Some(ref action) = fk_ref.on_update {
9252 self.write_space();
9253 self.write_keyword("ON UPDATE");
9254 self.write_space();
9255 self.generate_referential_action(action);
9256 }
9257 if let Some(ref action) = fk_ref.on_delete {
9258 self.write_space();
9259 self.write_keyword("ON DELETE");
9260 self.write_space();
9261 self.generate_referential_action(action);
9262 }
9263 } else {
9264 if let Some(ref action) = fk_ref.on_delete {
9265 self.write_space();
9266 self.write_keyword("ON DELETE");
9267 self.write_space();
9268 self.generate_referential_action(action);
9269 }
9270 if let Some(ref action) = fk_ref.on_update {
9271 self.write_space();
9272 self.write_keyword("ON UPDATE");
9273 self.write_space();
9274 self.generate_referential_action(action);
9275 }
9276 }
9277
9278 if fk_ref.match_after_actions {
9280 if let Some(ref match_type) = fk_ref.match_type {
9281 self.write_space();
9282 self.write_keyword("MATCH");
9283 self.write_space();
9284 match match_type {
9285 MatchType::Full => self.write_keyword("FULL"),
9286 MatchType::Partial => self.write_keyword("PARTIAL"),
9287 MatchType::Simple => self.write_keyword("SIMPLE"),
9288 }
9289 }
9290 }
9291
9292 if let Some(deferrable) = fk_ref.deferrable {
9294 self.write_space();
9295 if deferrable {
9296 self.write_keyword("DEFERRABLE");
9297 } else {
9298 self.write_keyword("NOT DEFERRABLE");
9299 }
9300 }
9301
9302 Ok(())
9303 }
9304
9305 fn generate_referential_action(&mut self, action: &ReferentialAction) {
9306 match action {
9307 ReferentialAction::Cascade => self.write_keyword("CASCADE"),
9308 ReferentialAction::SetNull => self.write_keyword("SET NULL"),
9309 ReferentialAction::SetDefault => self.write_keyword("SET DEFAULT"),
9310 ReferentialAction::Restrict => self.write_keyword("RESTRICT"),
9311 ReferentialAction::NoAction => self.write_keyword("NO ACTION"),
9312 }
9313 }
9314
9315 fn generate_drop_table(&mut self, dt: &DropTable) -> Result<()> {
9316 let saved_athena_hive_context = self.athena_hive_context;
9318 if matches!(
9319 self.config.dialect,
9320 Some(crate::dialects::DialectType::Athena)
9321 ) {
9322 self.athena_hive_context = true;
9323 }
9324
9325 for comment in &dt.leading_comments {
9327 self.write_formatted_comment(comment);
9328 self.write_space();
9329 }
9330 self.write_keyword("DROP TABLE");
9331
9332 if dt.if_exists {
9333 self.write_space();
9334 self.write_keyword("IF EXISTS");
9335 }
9336
9337 self.write_space();
9338 for (i, table) in dt.names.iter().enumerate() {
9339 if i > 0 {
9340 self.write(", ");
9341 }
9342 self.generate_table(table)?;
9343 }
9344
9345 if dt.cascade_constraints {
9346 self.write_space();
9347 self.write_keyword("CASCADE CONSTRAINTS");
9348 } else if dt.cascade {
9349 self.write_space();
9350 self.write_keyword("CASCADE");
9351 }
9352
9353 if dt.purge {
9354 self.write_space();
9355 self.write_keyword("PURGE");
9356 }
9357
9358 self.athena_hive_context = saved_athena_hive_context;
9360
9361 Ok(())
9362 }
9363
9364 fn generate_alter_table(&mut self, at: &AlterTable) -> Result<()> {
9365 let saved_athena_hive_context = self.athena_hive_context;
9367 if matches!(
9368 self.config.dialect,
9369 Some(crate::dialects::DialectType::Athena)
9370 ) {
9371 self.athena_hive_context = true;
9372 }
9373
9374 self.write_keyword("ALTER TABLE");
9375 if at.if_exists {
9376 self.write_space();
9377 self.write_keyword("IF EXISTS");
9378 }
9379 self.write_space();
9380 self.generate_table(&at.name)?;
9381
9382 if let Some(ref on_cluster) = at.on_cluster {
9384 self.write_space();
9385 self.generate_on_cluster(on_cluster)?;
9386 }
9387
9388 if let Some(ref partition) = at.partition {
9390 self.write_space();
9391 self.write_keyword("PARTITION");
9392 self.write("(");
9393 for (i, (key, value)) in partition.iter().enumerate() {
9394 if i > 0 {
9395 self.write(", ");
9396 }
9397 self.generate_identifier(key)?;
9398 self.write(" = ");
9399 self.generate_expression(value)?;
9400 }
9401 self.write(")");
9402 }
9403
9404 if let Some(ref with_check) = at.with_check {
9406 self.write_space();
9407 self.write_keyword(with_check);
9408 }
9409
9410 if self.config.pretty {
9411 self.write_newline();
9413 self.indent_level += 1;
9414 for (i, action) in at.actions.iter().enumerate() {
9415 let is_continuation = i > 0
9417 && matches!(
9418 (&at.actions[i - 1], action),
9419 (
9420 AlterTableAction::AddColumn { .. },
9421 AlterTableAction::AddColumn { .. }
9422 ) | (
9423 AlterTableAction::AddConstraint(_),
9424 AlterTableAction::AddConstraint(_)
9425 )
9426 );
9427 if i > 0 {
9428 self.write(",");
9429 self.write_newline();
9430 }
9431 self.write_indent();
9432 self.generate_alter_action_with_continuation(action, is_continuation)?;
9433 }
9434 self.indent_level -= 1;
9435 } else {
9436 for (i, action) in at.actions.iter().enumerate() {
9437 let is_continuation = i > 0
9439 && matches!(
9440 (&at.actions[i - 1], action),
9441 (
9442 AlterTableAction::AddColumn { .. },
9443 AlterTableAction::AddColumn { .. }
9444 ) | (
9445 AlterTableAction::AddConstraint(_),
9446 AlterTableAction::AddConstraint(_)
9447 )
9448 );
9449 if i > 0 {
9450 self.write(",");
9451 }
9452 self.write_space();
9453 self.generate_alter_action_with_continuation(action, is_continuation)?;
9454 }
9455 }
9456
9457 if let Some(ref algorithm) = at.algorithm {
9459 self.write(", ");
9460 self.write_keyword("ALGORITHM");
9461 self.write("=");
9462 self.write_keyword(algorithm);
9463 }
9464 if let Some(ref lock) = at.lock {
9465 self.write(", ");
9466 self.write_keyword("LOCK");
9467 self.write("=");
9468 self.write_keyword(lock);
9469 }
9470
9471 self.athena_hive_context = saved_athena_hive_context;
9473
9474 Ok(())
9475 }
9476
9477 fn generate_alter_action_with_continuation(
9478 &mut self,
9479 action: &AlterTableAction,
9480 is_continuation: bool,
9481 ) -> Result<()> {
9482 match action {
9483 AlterTableAction::AddColumn {
9484 column,
9485 if_not_exists,
9486 position,
9487 } => {
9488 use crate::dialects::DialectType;
9489 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
9493 let is_tsql_like = matches!(
9494 self.config.dialect,
9495 Some(DialectType::TSQL) | Some(DialectType::Fabric)
9496 );
9497 let is_athena = matches!(self.config.dialect, Some(DialectType::Athena));
9499
9500 if is_continuation && (is_snowflake || is_tsql_like) {
9501 } else if is_snowflake {
9503 self.write_keyword("ADD");
9504 self.write_space();
9505 } else if is_athena {
9506 self.write_keyword("ADD COLUMNS");
9508 self.write(" (");
9509 } else if self.config.alter_table_include_column_keyword {
9510 self.write_keyword("ADD COLUMN");
9511 self.write_space();
9512 } else {
9513 self.write_keyword("ADD");
9515 self.write_space();
9516 }
9517
9518 if *if_not_exists {
9519 self.write_keyword("IF NOT EXISTS");
9520 self.write_space();
9521 }
9522 self.generate_column_def(column)?;
9523
9524 if is_athena {
9526 self.write(")");
9527 }
9528
9529 if let Some(pos) = position {
9531 self.write_space();
9532 match pos {
9533 ColumnPosition::First => self.write_keyword("FIRST"),
9534 ColumnPosition::After(col_name) => {
9535 self.write_keyword("AFTER");
9536 self.write_space();
9537 self.generate_identifier(col_name)?;
9538 }
9539 }
9540 }
9541 }
9542 AlterTableAction::DropColumn {
9543 name,
9544 if_exists,
9545 cascade,
9546 } => {
9547 self.write_keyword("DROP COLUMN");
9548 if *if_exists {
9549 self.write_space();
9550 self.write_keyword("IF EXISTS");
9551 }
9552 self.write_space();
9553 self.generate_identifier(name)?;
9554 if *cascade {
9555 self.write_space();
9556 self.write_keyword("CASCADE");
9557 }
9558 }
9559 AlterTableAction::DropColumns { names } => {
9560 self.write_keyword("DROP COLUMNS");
9561 self.write(" (");
9562 for (i, name) in names.iter().enumerate() {
9563 if i > 0 {
9564 self.write(", ");
9565 }
9566 self.generate_identifier(name)?;
9567 }
9568 self.write(")");
9569 }
9570 AlterTableAction::RenameColumn {
9571 old_name,
9572 new_name,
9573 if_exists,
9574 } => {
9575 self.write_keyword("RENAME COLUMN");
9576 if *if_exists {
9577 self.write_space();
9578 self.write_keyword("IF EXISTS");
9579 }
9580 self.write_space();
9581 self.generate_identifier(old_name)?;
9582 self.write_space();
9583 self.write_keyword("TO");
9584 self.write_space();
9585 self.generate_identifier(new_name)?;
9586 }
9587 AlterTableAction::AlterColumn {
9588 name,
9589 action,
9590 use_modify_keyword,
9591 } => {
9592 use crate::dialects::DialectType;
9593 let use_modify = *use_modify_keyword
9596 || (matches!(self.config.dialect, Some(DialectType::MySQL))
9597 && matches!(action, AlterColumnAction::SetDataType { .. }));
9598 if use_modify {
9599 self.write_keyword("MODIFY COLUMN");
9600 self.write_space();
9601 self.generate_identifier(name)?;
9602 if let AlterColumnAction::SetDataType {
9604 data_type,
9605 using: _,
9606 collate,
9607 } = action
9608 {
9609 self.write_space();
9610 self.generate_data_type(data_type)?;
9611 if let Some(collate_name) = collate {
9613 self.write_space();
9614 self.write_keyword("COLLATE");
9615 self.write_space();
9616 self.write(&format!("'{}'", collate_name));
9618 }
9619 } else {
9620 self.write_space();
9621 self.generate_alter_column_action(action)?;
9622 }
9623 } else if matches!(self.config.dialect, Some(DialectType::Hive))
9624 && matches!(action, AlterColumnAction::SetDataType { .. })
9625 {
9626 self.write_keyword("CHANGE COLUMN");
9628 self.write_space();
9629 self.generate_identifier(name)?;
9630 self.write_space();
9631 self.generate_identifier(name)?;
9632 if let AlterColumnAction::SetDataType { data_type, .. } = action {
9633 self.write_space();
9634 self.generate_data_type(data_type)?;
9635 }
9636 } else {
9637 self.write_keyword("ALTER COLUMN");
9638 self.write_space();
9639 self.generate_identifier(name)?;
9640 self.write_space();
9641 self.generate_alter_column_action(action)?;
9642 }
9643 }
9644 AlterTableAction::RenameTable(new_name) => {
9645 let mysql_like = matches!(
9647 self.config.dialect,
9648 Some(DialectType::MySQL)
9649 | Some(DialectType::Doris)
9650 | Some(DialectType::StarRocks)
9651 | Some(DialectType::SingleStore)
9652 );
9653 if mysql_like {
9654 self.write_keyword("RENAME");
9655 } else {
9656 self.write_keyword("RENAME TO");
9657 }
9658 self.write_space();
9659 let rename_table_with_db = !matches!(
9661 self.config.dialect,
9662 Some(DialectType::Doris)
9663 | Some(DialectType::DuckDB)
9664 | Some(DialectType::BigQuery)
9665 | Some(DialectType::PostgreSQL)
9666 );
9667 if !rename_table_with_db {
9668 let mut stripped = new_name.clone();
9669 stripped.schema = None;
9670 stripped.catalog = None;
9671 self.generate_table(&stripped)?;
9672 } else {
9673 self.generate_table(new_name)?;
9674 }
9675 }
9676 AlterTableAction::AddConstraint(constraint) => {
9677 if !is_continuation {
9680 self.write_keyword("ADD");
9681 self.write_space();
9682 }
9683 self.generate_table_constraint(constraint)?;
9684 }
9685 AlterTableAction::DropConstraint { name, if_exists } => {
9686 self.write_keyword("DROP CONSTRAINT");
9687 if *if_exists {
9688 self.write_space();
9689 self.write_keyword("IF EXISTS");
9690 }
9691 self.write_space();
9692 self.generate_identifier(name)?;
9693 }
9694 AlterTableAction::DropForeignKey { name } => {
9695 self.write_keyword("DROP FOREIGN KEY");
9696 self.write_space();
9697 self.generate_identifier(name)?;
9698 }
9699 AlterTableAction::DropPartition {
9700 partitions,
9701 if_exists,
9702 } => {
9703 self.write_keyword("DROP");
9704 if *if_exists {
9705 self.write_space();
9706 self.write_keyword("IF EXISTS");
9707 }
9708 for (i, partition) in partitions.iter().enumerate() {
9709 if i > 0 {
9710 self.write(",");
9711 }
9712 self.write_space();
9713 self.write_keyword("PARTITION");
9714 if partition.len() == 1 && partition[0].0.name == "__expr__" {
9716 self.write_space();
9718 self.generate_expression(&partition[0].1)?;
9719 } else if partition.len() == 1 && partition[0].0.name == "ALL" {
9720 self.write_space();
9722 self.write_keyword("ALL");
9723 } else if partition.len() == 1 && partition[0].0.name == "ID" {
9724 self.write_space();
9726 self.write_keyword("ID");
9727 self.write_space();
9728 self.generate_expression(&partition[0].1)?;
9729 } else {
9730 self.write("(");
9732 for (j, (key, value)) in partition.iter().enumerate() {
9733 if j > 0 {
9734 self.write(", ");
9735 }
9736 self.generate_identifier(key)?;
9737 self.write(" = ");
9738 self.generate_expression(value)?;
9739 }
9740 self.write(")");
9741 }
9742 }
9743 }
9744 AlterTableAction::Delete { where_clause } => {
9745 self.write_keyword("DELETE");
9746 self.write_space();
9747 self.write_keyword("WHERE");
9748 self.write_space();
9749 self.generate_expression(where_clause)?;
9750 }
9751 AlterTableAction::SwapWith(target) => {
9752 self.write_keyword("SWAP WITH");
9753 self.write_space();
9754 self.generate_table(target)?;
9755 }
9756 AlterTableAction::SetProperty { properties } => {
9757 use crate::dialects::DialectType;
9758 self.write_keyword("SET");
9759 let is_trino_presto = matches!(
9761 self.config.dialect,
9762 Some(DialectType::Trino) | Some(DialectType::Presto)
9763 );
9764 if is_trino_presto {
9765 self.write_space();
9766 self.write_keyword("PROPERTIES");
9767 }
9768 let eq = if is_trino_presto { " = " } else { "=" };
9769 for (i, (key, value)) in properties.iter().enumerate() {
9770 if i > 0 {
9771 self.write(",");
9772 }
9773 self.write_space();
9774 if key.contains(' ') {
9776 self.generate_string_literal(key)?;
9777 } else {
9778 self.write(key);
9779 }
9780 self.write(eq);
9781 self.generate_expression(value)?;
9782 }
9783 }
9784 AlterTableAction::UnsetProperty { properties } => {
9785 self.write_keyword("UNSET");
9786 for (i, name) in properties.iter().enumerate() {
9787 if i > 0 {
9788 self.write(",");
9789 }
9790 self.write_space();
9791 self.write(name);
9792 }
9793 }
9794 AlterTableAction::ClusterBy { expressions } => {
9795 self.write_keyword("CLUSTER BY");
9796 self.write(" (");
9797 for (i, expr) in expressions.iter().enumerate() {
9798 if i > 0 {
9799 self.write(", ");
9800 }
9801 self.generate_expression(expr)?;
9802 }
9803 self.write(")");
9804 }
9805 AlterTableAction::SetTag { expressions } => {
9806 self.write_keyword("SET TAG");
9807 for (i, (key, value)) in expressions.iter().enumerate() {
9808 if i > 0 {
9809 self.write(",");
9810 }
9811 self.write_space();
9812 self.write(key);
9813 self.write(" = ");
9814 self.generate_expression(value)?;
9815 }
9816 }
9817 AlterTableAction::UnsetTag { names } => {
9818 self.write_keyword("UNSET TAG");
9819 for (i, name) in names.iter().enumerate() {
9820 if i > 0 {
9821 self.write(",");
9822 }
9823 self.write_space();
9824 self.write(name);
9825 }
9826 }
9827 AlterTableAction::SetOptions { expressions } => {
9828 self.write_keyword("SET");
9829 self.write(" (");
9830 for (i, expr) in expressions.iter().enumerate() {
9831 if i > 0 {
9832 self.write(", ");
9833 }
9834 self.generate_expression(expr)?;
9835 }
9836 self.write(")");
9837 }
9838 AlterTableAction::AlterIndex { name, visible } => {
9839 self.write_keyword("ALTER INDEX");
9840 self.write_space();
9841 self.generate_identifier(name)?;
9842 self.write_space();
9843 if *visible {
9844 self.write_keyword("VISIBLE");
9845 } else {
9846 self.write_keyword("INVISIBLE");
9847 }
9848 }
9849 AlterTableAction::SetAttribute { attribute } => {
9850 self.write_keyword("SET");
9851 self.write_space();
9852 self.write_keyword(attribute);
9853 }
9854 AlterTableAction::SetStageFileFormat { options } => {
9855 self.write_keyword("SET");
9856 self.write_space();
9857 self.write_keyword("STAGE_FILE_FORMAT");
9858 self.write(" = (");
9859 if let Some(opts) = options {
9860 self.generate_space_separated_properties(opts)?;
9861 }
9862 self.write(")");
9863 }
9864 AlterTableAction::SetStageCopyOptions { options } => {
9865 self.write_keyword("SET");
9866 self.write_space();
9867 self.write_keyword("STAGE_COPY_OPTIONS");
9868 self.write(" = (");
9869 if let Some(opts) = options {
9870 self.generate_space_separated_properties(opts)?;
9871 }
9872 self.write(")");
9873 }
9874 AlterTableAction::AddColumns { columns, cascade } => {
9875 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
9878 if is_oracle {
9879 self.write_keyword("ADD");
9880 } else {
9881 self.write_keyword("ADD COLUMNS");
9882 }
9883 self.write(" (");
9884 for (i, col) in columns.iter().enumerate() {
9885 if i > 0 {
9886 self.write(", ");
9887 }
9888 self.generate_column_def(col)?;
9889 }
9890 self.write(")");
9891 if *cascade {
9892 self.write_space();
9893 self.write_keyword("CASCADE");
9894 }
9895 }
9896 AlterTableAction::ChangeColumn {
9897 old_name,
9898 new_name,
9899 data_type,
9900 comment,
9901 cascade,
9902 } => {
9903 use crate::dialects::DialectType;
9904 let is_spark = matches!(
9905 self.config.dialect,
9906 Some(DialectType::Spark) | Some(DialectType::Databricks)
9907 );
9908 let is_rename = old_name.name != new_name.name;
9909
9910 if is_spark {
9911 if is_rename {
9912 self.write_keyword("RENAME COLUMN");
9914 self.write_space();
9915 self.generate_identifier(old_name)?;
9916 self.write_space();
9917 self.write_keyword("TO");
9918 self.write_space();
9919 self.generate_identifier(new_name)?;
9920 } else if comment.is_some() {
9921 self.write_keyword("ALTER COLUMN");
9923 self.write_space();
9924 self.generate_identifier(old_name)?;
9925 self.write_space();
9926 self.write_keyword("COMMENT");
9927 self.write_space();
9928 self.write("'");
9929 self.write(comment.as_ref().unwrap());
9930 self.write("'");
9931 } else if data_type.is_some() {
9932 self.write_keyword("ALTER COLUMN");
9934 self.write_space();
9935 self.generate_identifier(old_name)?;
9936 self.write_space();
9937 self.write_keyword("TYPE");
9938 self.write_space();
9939 self.generate_data_type(data_type.as_ref().unwrap())?;
9940 } else {
9941 self.write_keyword("CHANGE COLUMN");
9943 self.write_space();
9944 self.generate_identifier(old_name)?;
9945 self.write_space();
9946 self.generate_identifier(new_name)?;
9947 }
9948 } else {
9949 if data_type.is_some() {
9951 self.write_keyword("CHANGE COLUMN");
9952 } else {
9953 self.write_keyword("CHANGE");
9954 }
9955 self.write_space();
9956 self.generate_identifier(old_name)?;
9957 self.write_space();
9958 self.generate_identifier(new_name)?;
9959 if let Some(ref dt) = data_type {
9960 self.write_space();
9961 self.generate_data_type(dt)?;
9962 }
9963 if let Some(ref c) = comment {
9964 self.write_space();
9965 self.write_keyword("COMMENT");
9966 self.write_space();
9967 self.write("'");
9968 self.write(c);
9969 self.write("'");
9970 }
9971 if *cascade {
9972 self.write_space();
9973 self.write_keyword("CASCADE");
9974 }
9975 }
9976 }
9977 AlterTableAction::AddPartition {
9978 partition,
9979 if_not_exists,
9980 location,
9981 } => {
9982 self.write_keyword("ADD");
9983 self.write_space();
9984 if *if_not_exists {
9985 self.write_keyword("IF NOT EXISTS");
9986 self.write_space();
9987 }
9988 self.generate_expression(partition)?;
9989 if let Some(ref loc) = location {
9990 self.write_space();
9991 self.write_keyword("LOCATION");
9992 self.write_space();
9993 self.generate_expression(loc)?;
9994 }
9995 }
9996 AlterTableAction::AlterSortKey {
9997 this,
9998 expressions,
9999 compound,
10000 } => {
10001 self.write_keyword("ALTER");
10003 if *compound {
10004 self.write_space();
10005 self.write_keyword("COMPOUND");
10006 }
10007 self.write_space();
10008 self.write_keyword("SORTKEY");
10009 self.write_space();
10010 if let Some(style) = this {
10011 self.write_keyword(style);
10012 } else if !expressions.is_empty() {
10013 self.write("(");
10014 for (i, expr) in expressions.iter().enumerate() {
10015 if i > 0 {
10016 self.write(", ");
10017 }
10018 self.generate_expression(expr)?;
10019 }
10020 self.write(")");
10021 }
10022 }
10023 AlterTableAction::AlterDistStyle { style, distkey } => {
10024 self.write_keyword("ALTER");
10026 self.write_space();
10027 self.write_keyword("DISTSTYLE");
10028 self.write_space();
10029 self.write_keyword(style);
10030 if let Some(col) = distkey {
10031 self.write_space();
10032 self.write_keyword("DISTKEY");
10033 self.write_space();
10034 self.generate_identifier(col)?;
10035 }
10036 }
10037 AlterTableAction::SetTableProperties { properties } => {
10038 self.write_keyword("SET TABLE PROPERTIES");
10040 self.write(" (");
10041 for (i, (key, value)) in properties.iter().enumerate() {
10042 if i > 0 {
10043 self.write(", ");
10044 }
10045 self.generate_expression(key)?;
10046 self.write(" = ");
10047 self.generate_expression(value)?;
10048 }
10049 self.write(")");
10050 }
10051 AlterTableAction::SetLocation { location } => {
10052 self.write_keyword("SET LOCATION");
10054 self.write_space();
10055 self.write("'");
10056 self.write(location);
10057 self.write("'");
10058 }
10059 AlterTableAction::SetFileFormat { format } => {
10060 self.write_keyword("SET FILE FORMAT");
10062 self.write_space();
10063 self.write_keyword(format);
10064 }
10065 AlterTableAction::ReplacePartition { partition, source } => {
10066 self.write_keyword("REPLACE PARTITION");
10068 self.write_space();
10069 self.generate_expression(partition)?;
10070 if let Some(src) = source {
10071 self.write_space();
10072 self.write_keyword("FROM");
10073 self.write_space();
10074 self.generate_expression(src)?;
10075 }
10076 }
10077 AlterTableAction::Raw { sql } => {
10078 self.write(sql);
10079 }
10080 }
10081 Ok(())
10082 }
10083
10084 fn generate_alter_column_action(&mut self, action: &AlterColumnAction) -> Result<()> {
10085 match action {
10086 AlterColumnAction::SetDataType {
10087 data_type,
10088 using,
10089 collate,
10090 } => {
10091 use crate::dialects::DialectType;
10092 let is_no_prefix = matches!(
10097 self.config.dialect,
10098 Some(DialectType::TSQL) | Some(DialectType::Fabric) | Some(DialectType::Hive)
10099 );
10100 let is_type_only = matches!(
10101 self.config.dialect,
10102 Some(DialectType::Redshift)
10103 | Some(DialectType::Spark)
10104 | Some(DialectType::Databricks)
10105 );
10106 if is_type_only {
10107 self.write_keyword("TYPE");
10108 self.write_space();
10109 } else if !is_no_prefix {
10110 self.write_keyword("SET DATA TYPE");
10111 self.write_space();
10112 }
10113 self.generate_data_type(data_type)?;
10114 if let Some(ref collation) = collate {
10115 self.write_space();
10116 self.write_keyword("COLLATE");
10117 self.write_space();
10118 self.write(collation);
10119 }
10120 if let Some(ref using_expr) = using {
10121 self.write_space();
10122 self.write_keyword("USING");
10123 self.write_space();
10124 self.generate_expression(using_expr)?;
10125 }
10126 }
10127 AlterColumnAction::SetDefault(expr) => {
10128 self.write_keyword("SET DEFAULT");
10129 self.write_space();
10130 self.generate_expression(expr)?;
10131 }
10132 AlterColumnAction::DropDefault => {
10133 self.write_keyword("DROP DEFAULT");
10134 }
10135 AlterColumnAction::SetNotNull => {
10136 self.write_keyword("SET NOT NULL");
10137 }
10138 AlterColumnAction::DropNotNull => {
10139 self.write_keyword("DROP NOT NULL");
10140 }
10141 AlterColumnAction::Comment(comment) => {
10142 self.write_keyword("COMMENT");
10143 self.write_space();
10144 self.generate_string_literal(comment)?;
10145 }
10146 AlterColumnAction::SetVisible => {
10147 self.write_keyword("SET VISIBLE");
10148 }
10149 AlterColumnAction::SetInvisible => {
10150 self.write_keyword("SET INVISIBLE");
10151 }
10152 }
10153 Ok(())
10154 }
10155
10156 fn generate_create_index(&mut self, ci: &CreateIndex) -> Result<()> {
10157 self.write_keyword("CREATE");
10158
10159 if ci.unique {
10160 self.write_space();
10161 self.write_keyword("UNIQUE");
10162 }
10163
10164 if let Some(ref clustered) = ci.clustered {
10166 self.write_space();
10167 self.write_keyword(clustered);
10168 }
10169
10170 self.write_space();
10171 self.write_keyword("INDEX");
10172
10173 if ci.concurrently {
10175 self.write_space();
10176 self.write_keyword("CONCURRENTLY");
10177 }
10178
10179 if ci.if_not_exists {
10180 self.write_space();
10181 self.write_keyword("IF NOT EXISTS");
10182 }
10183
10184 if !ci.name.name.is_empty() {
10186 self.write_space();
10187 self.generate_identifier(&ci.name)?;
10188 }
10189 self.write_space();
10190 self.write_keyword("ON");
10191 if matches!(self.config.dialect, Some(DialectType::Hive)) {
10193 self.write_space();
10194 self.write_keyword("TABLE");
10195 }
10196 self.write_space();
10197 self.generate_table(&ci.table)?;
10198
10199 if !ci.columns.is_empty() || ci.using.is_some() {
10202 let space_before_paren = false;
10203
10204 if let Some(ref using) = ci.using {
10205 self.write_space();
10206 self.write_keyword("USING");
10207 self.write_space();
10208 self.write(using);
10209 if space_before_paren {
10210 self.write(" (");
10211 } else {
10212 self.write("(");
10213 }
10214 } else {
10215 if space_before_paren {
10216 self.write(" (");
10217 } else {
10218 self.write("(");
10219 }
10220 }
10221 for (i, col) in ci.columns.iter().enumerate() {
10222 if i > 0 {
10223 self.write(", ");
10224 }
10225 self.generate_identifier(&col.column)?;
10226 if let Some(ref opclass) = col.opclass {
10227 self.write_space();
10228 self.write(opclass);
10229 }
10230 if col.desc {
10231 self.write_space();
10232 self.write_keyword("DESC");
10233 } else if col.asc {
10234 self.write_space();
10235 self.write_keyword("ASC");
10236 }
10237 if let Some(nulls_first) = col.nulls_first {
10238 self.write_space();
10239 self.write_keyword("NULLS");
10240 self.write_space();
10241 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
10242 }
10243 }
10244 self.write(")");
10245 }
10246
10247 if !ci.include_columns.is_empty() {
10249 self.write_space();
10250 self.write_keyword("INCLUDE");
10251 self.write(" (");
10252 for (i, col) in ci.include_columns.iter().enumerate() {
10253 if i > 0 {
10254 self.write(", ");
10255 }
10256 self.generate_identifier(col)?;
10257 }
10258 self.write(")");
10259 }
10260
10261 if !ci.with_options.is_empty() {
10263 self.write_space();
10264 self.write_keyword("WITH");
10265 self.write(" (");
10266 for (i, (key, value)) in ci.with_options.iter().enumerate() {
10267 if i > 0 {
10268 self.write(", ");
10269 }
10270 self.write(key);
10271 self.write("=");
10272 self.write(value);
10273 }
10274 self.write(")");
10275 }
10276
10277 if let Some(ref where_clause) = ci.where_clause {
10279 self.write_space();
10280 self.write_keyword("WHERE");
10281 self.write_space();
10282 self.generate_expression(where_clause)?;
10283 }
10284
10285 if let Some(ref on_fg) = ci.on_filegroup {
10287 self.write_space();
10288 self.write_keyword("ON");
10289 self.write_space();
10290 self.write(on_fg);
10291 }
10292
10293 Ok(())
10294 }
10295
10296 fn generate_drop_index(&mut self, di: &DropIndex) -> Result<()> {
10297 self.write_keyword("DROP INDEX");
10298
10299 if di.concurrently {
10300 self.write_space();
10301 self.write_keyword("CONCURRENTLY");
10302 }
10303
10304 if di.if_exists {
10305 self.write_space();
10306 self.write_keyword("IF EXISTS");
10307 }
10308
10309 self.write_space();
10310 self.generate_identifier(&di.name)?;
10311
10312 if let Some(ref table) = di.table {
10313 self.write_space();
10314 self.write_keyword("ON");
10315 self.write_space();
10316 self.generate_table(table)?;
10317 }
10318
10319 Ok(())
10320 }
10321
10322 fn generate_create_view(&mut self, cv: &CreateView) -> Result<()> {
10323 self.write_keyword("CREATE");
10324
10325 if let Some(ref algorithm) = cv.algorithm {
10327 self.write_space();
10328 self.write_keyword("ALGORITHM");
10329 self.write("=");
10330 self.write_keyword(algorithm);
10331 }
10332
10333 if let Some(ref definer) = cv.definer {
10335 self.write_space();
10336 self.write_keyword("DEFINER");
10337 self.write("=");
10338 self.write(definer);
10339 }
10340
10341 if cv.security_sql_style {
10343 if let Some(ref security) = cv.security {
10344 self.write_space();
10345 self.write_keyword("SQL SECURITY");
10346 self.write_space();
10347 match security {
10348 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
10349 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
10350 FunctionSecurity::None => self.write_keyword("NONE"),
10351 }
10352 }
10353 }
10354
10355 if cv.or_replace {
10356 self.write_space();
10357 self.write_keyword("OR REPLACE");
10358 }
10359
10360 if cv.temporary {
10361 self.write_space();
10362 self.write_keyword("TEMPORARY");
10363 }
10364
10365 if cv.materialized {
10366 self.write_space();
10367 self.write_keyword("MATERIALIZED");
10368 }
10369
10370 if cv.secure {
10372 self.write_space();
10373 self.write_keyword("SECURE");
10374 }
10375
10376 self.write_space();
10377 self.write_keyword("VIEW");
10378
10379 if cv.if_not_exists {
10380 self.write_space();
10381 self.write_keyword("IF NOT EXISTS");
10382 }
10383
10384 self.write_space();
10385 self.generate_table(&cv.name)?;
10386
10387 if let Some(ref on_cluster) = cv.on_cluster {
10389 self.write_space();
10390 self.generate_on_cluster(on_cluster)?;
10391 }
10392
10393 if let Some(ref to_table) = cv.to_table {
10395 self.write_space();
10396 self.write_keyword("TO");
10397 self.write_space();
10398 self.generate_table(to_table)?;
10399 }
10400
10401 if !cv.materialized {
10404 if !cv.columns.is_empty() {
10406 self.write(" (");
10407 for (i, col) in cv.columns.iter().enumerate() {
10408 if i > 0 {
10409 self.write(", ");
10410 }
10411 self.generate_identifier(&col.name)?;
10412 if !col.options.is_empty() {
10414 self.write_space();
10415 self.generate_options_clause(&col.options)?;
10416 }
10417 if let Some(ref comment) = col.comment {
10418 self.write_space();
10419 self.write_keyword("COMMENT");
10420 self.write_space();
10421 self.generate_string_literal(comment)?;
10422 }
10423 }
10424 self.write(")");
10425 }
10426
10427 if !cv.security_sql_style {
10429 if let Some(ref security) = cv.security {
10430 self.write_space();
10431 self.write_keyword("SECURITY");
10432 self.write_space();
10433 match security {
10434 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
10435 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
10436 FunctionSecurity::None => self.write_keyword("NONE"),
10437 }
10438 }
10439 }
10440
10441 if cv.copy_grants {
10443 self.write_space();
10444 self.write_keyword("COPY GRANTS");
10445 }
10446 } else {
10447 if cv.copy_grants {
10449 self.write_space();
10450 self.write_keyword("COPY GRANTS");
10451 }
10452
10453 if let Some(ref schema) = cv.schema {
10455 self.write(" (");
10456 for (i, expr) in schema.expressions.iter().enumerate() {
10457 if i > 0 {
10458 self.write(", ");
10459 }
10460 self.generate_expression(expr)?;
10461 }
10462 self.write(")");
10463 } else if !cv.columns.is_empty() {
10464 self.write(" (");
10466 for (i, col) in cv.columns.iter().enumerate() {
10467 if i > 0 {
10468 self.write(", ");
10469 }
10470 self.generate_identifier(&col.name)?;
10471 if !col.options.is_empty() {
10473 self.write_space();
10474 self.generate_options_clause(&col.options)?;
10475 }
10476 if let Some(ref comment) = col.comment {
10477 self.write_space();
10478 self.write_keyword("COMMENT");
10479 self.write_space();
10480 self.generate_string_literal(comment)?;
10481 }
10482 }
10483 self.write(")");
10484 }
10485
10486 if let Some(ref unique_key) = cv.unique_key {
10488 self.write_space();
10489 self.write_keyword("KEY");
10490 self.write(" (");
10491 for (i, expr) in unique_key.expressions.iter().enumerate() {
10492 if i > 0 {
10493 self.write(", ");
10494 }
10495 self.generate_expression(expr)?;
10496 }
10497 self.write(")");
10498 }
10499 }
10500
10501 if let Some(ref comment) = cv.comment {
10503 self.write_space();
10504 self.write_keyword("COMMENT");
10505 self.write("=");
10506 self.generate_string_literal(comment)?;
10507 }
10508
10509 if !cv.tags.is_empty() {
10511 self.write_space();
10512 self.write_keyword("TAG");
10513 self.write(" (");
10514 for (i, (name, value)) in cv.tags.iter().enumerate() {
10515 if i > 0 {
10516 self.write(", ");
10517 }
10518 self.write(name);
10519 self.write("='");
10520 self.write(value);
10521 self.write("'");
10522 }
10523 self.write(")");
10524 }
10525
10526 if !cv.options.is_empty() {
10528 self.write_space();
10529 self.generate_options_clause(&cv.options)?;
10530 }
10531
10532 if let Some(ref build) = cv.build {
10534 self.write_space();
10535 self.write_keyword("BUILD");
10536 self.write_space();
10537 self.write_keyword(build);
10538 }
10539
10540 if let Some(ref refresh) = cv.refresh {
10542 self.write_space();
10543 self.generate_refresh_trigger_property(refresh)?;
10544 }
10545
10546 if let Some(auto_refresh) = cv.auto_refresh {
10548 self.write_space();
10549 self.write_keyword("AUTO REFRESH");
10550 self.write_space();
10551 if auto_refresh {
10552 self.write_keyword("YES");
10553 } else {
10554 self.write_keyword("NO");
10555 }
10556 }
10557
10558 for prop in &cv.table_properties {
10560 self.write_space();
10561 self.generate_expression(prop)?;
10562 }
10563
10564 if !matches!(&cv.query, Expression::Null(_)) {
10566 self.write_space();
10567 self.write_keyword("AS");
10568 self.write_space();
10569
10570 if let Some(ref mode) = cv.locking_mode {
10572 self.write_keyword("LOCKING");
10573 self.write_space();
10574 self.write_keyword(mode);
10575 if let Some(ref access) = cv.locking_access {
10576 self.write_space();
10577 self.write_keyword("FOR");
10578 self.write_space();
10579 self.write_keyword(access);
10580 }
10581 self.write_space();
10582 }
10583
10584 if cv.query_parenthesized {
10585 self.write("(");
10586 }
10587 self.generate_expression(&cv.query)?;
10588 if cv.query_parenthesized {
10589 self.write(")");
10590 }
10591 }
10592
10593 if cv.no_schema_binding {
10595 self.write_space();
10596 self.write_keyword("WITH NO SCHEMA BINDING");
10597 }
10598
10599 Ok(())
10600 }
10601
10602 fn generate_drop_view(&mut self, dv: &DropView) -> Result<()> {
10603 self.write_keyword("DROP");
10604
10605 if dv.materialized {
10606 self.write_space();
10607 self.write_keyword("MATERIALIZED");
10608 }
10609
10610 self.write_space();
10611 self.write_keyword("VIEW");
10612
10613 if dv.if_exists {
10614 self.write_space();
10615 self.write_keyword("IF EXISTS");
10616 }
10617
10618 self.write_space();
10619 self.generate_table(&dv.name)?;
10620
10621 Ok(())
10622 }
10623
10624 fn generate_truncate(&mut self, tr: &Truncate) -> Result<()> {
10625 match tr.target {
10626 TruncateTarget::Database => self.write_keyword("TRUNCATE DATABASE"),
10627 TruncateTarget::Table => self.write_keyword("TRUNCATE TABLE"),
10628 }
10629 if tr.if_exists {
10630 self.write_space();
10631 self.write_keyword("IF EXISTS");
10632 }
10633 self.write_space();
10634 self.generate_table(&tr.table)?;
10635
10636 if let Some(ref on_cluster) = tr.on_cluster {
10638 self.write_space();
10639 self.generate_on_cluster(on_cluster)?;
10640 }
10641
10642 if !tr.extra_tables.is_empty() {
10644 let skip_first = if let Some(first) = tr.extra_tables.first() {
10646 first.table.name == tr.table.name && first.star
10647 } else {
10648 false
10649 };
10650
10651 let strip_star = matches!(
10653 self.config.dialect,
10654 Some(crate::dialects::DialectType::PostgreSQL)
10655 | Some(crate::dialects::DialectType::Redshift)
10656 );
10657 if skip_first && !strip_star {
10658 self.write("*");
10659 }
10660
10661 for (i, entry) in tr.extra_tables.iter().enumerate() {
10663 if i == 0 && skip_first {
10664 continue; }
10666 self.write(", ");
10667 self.generate_table(&entry.table)?;
10668 if entry.star && !strip_star {
10669 self.write("*");
10670 }
10671 }
10672 }
10673
10674 if let Some(identity) = &tr.identity {
10676 self.write_space();
10677 match identity {
10678 TruncateIdentity::Restart => self.write_keyword("RESTART IDENTITY"),
10679 TruncateIdentity::Continue => self.write_keyword("CONTINUE IDENTITY"),
10680 }
10681 }
10682
10683 if tr.cascade {
10684 self.write_space();
10685 self.write_keyword("CASCADE");
10686 }
10687
10688 if tr.restrict {
10689 self.write_space();
10690 self.write_keyword("RESTRICT");
10691 }
10692
10693 if let Some(ref partition) = tr.partition {
10695 self.write_space();
10696 self.generate_expression(partition)?;
10697 }
10698
10699 Ok(())
10700 }
10701
10702 fn generate_use(&mut self, u: &Use) -> Result<()> {
10703 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
10705 self.write_keyword("DATABASE");
10706 self.write_space();
10707 self.generate_identifier(&u.this)?;
10708 return Ok(());
10709 }
10710
10711 self.write_keyword("USE");
10712
10713 if let Some(kind) = &u.kind {
10714 self.write_space();
10715 match kind {
10716 UseKind::Database => self.write_keyword("DATABASE"),
10717 UseKind::Schema => self.write_keyword("SCHEMA"),
10718 UseKind::Role => self.write_keyword("ROLE"),
10719 UseKind::Warehouse => self.write_keyword("WAREHOUSE"),
10720 UseKind::Catalog => self.write_keyword("CATALOG"),
10721 UseKind::SecondaryRoles => self.write_keyword("SECONDARY ROLES"),
10722 }
10723 }
10724
10725 self.write_space();
10726 if matches!(&u.kind, Some(UseKind::SecondaryRoles)) {
10729 self.write(&u.this.name);
10730 } else {
10731 self.generate_identifier(&u.this)?;
10732 }
10733 Ok(())
10734 }
10735
10736 fn generate_cache(&mut self, c: &Cache) -> Result<()> {
10737 self.write_keyword("CACHE");
10738 if c.lazy {
10739 self.write_space();
10740 self.write_keyword("LAZY");
10741 }
10742 self.write_space();
10743 self.write_keyword("TABLE");
10744 self.write_space();
10745 self.generate_identifier(&c.table)?;
10746
10747 if !c.options.is_empty() {
10749 self.write_space();
10750 self.write_keyword("OPTIONS");
10751 self.write("(");
10752 for (i, (key, value)) in c.options.iter().enumerate() {
10753 if i > 0 {
10754 self.write(", ");
10755 }
10756 self.generate_expression(key)?;
10757 self.write(" = ");
10758 self.generate_expression(value)?;
10759 }
10760 self.write(")");
10761 }
10762
10763 if let Some(query) = &c.query {
10765 self.write_space();
10766 self.write_keyword("AS");
10767 self.write_space();
10768 self.generate_expression(query)?;
10769 }
10770
10771 Ok(())
10772 }
10773
10774 fn generate_uncache(&mut self, u: &Uncache) -> Result<()> {
10775 self.write_keyword("UNCACHE TABLE");
10776 if u.if_exists {
10777 self.write_space();
10778 self.write_keyword("IF EXISTS");
10779 }
10780 self.write_space();
10781 self.generate_identifier(&u.table)?;
10782 Ok(())
10783 }
10784
10785 fn generate_load_data(&mut self, l: &LoadData) -> Result<()> {
10786 self.write_keyword("LOAD DATA");
10787 if l.local {
10788 self.write_space();
10789 self.write_keyword("LOCAL");
10790 }
10791 self.write_space();
10792 self.write_keyword("INPATH");
10793 self.write_space();
10794 self.write("'");
10795 self.write(&l.inpath);
10796 self.write("'");
10797
10798 if l.overwrite {
10799 self.write_space();
10800 self.write_keyword("OVERWRITE");
10801 }
10802
10803 self.write_space();
10804 self.write_keyword("INTO TABLE");
10805 self.write_space();
10806 self.generate_expression(&l.table)?;
10807
10808 if !l.partition.is_empty() {
10810 self.write_space();
10811 self.write_keyword("PARTITION");
10812 self.write("(");
10813 for (i, (col, val)) in l.partition.iter().enumerate() {
10814 if i > 0 {
10815 self.write(", ");
10816 }
10817 self.generate_identifier(col)?;
10818 self.write(" = ");
10819 self.generate_expression(val)?;
10820 }
10821 self.write(")");
10822 }
10823
10824 if let Some(fmt) = &l.input_format {
10826 self.write_space();
10827 self.write_keyword("INPUTFORMAT");
10828 self.write_space();
10829 self.write("'");
10830 self.write(fmt);
10831 self.write("'");
10832 }
10833
10834 if let Some(serde) = &l.serde {
10836 self.write_space();
10837 self.write_keyword("SERDE");
10838 self.write_space();
10839 self.write("'");
10840 self.write(serde);
10841 self.write("'");
10842 }
10843
10844 Ok(())
10845 }
10846
10847 fn generate_pragma(&mut self, p: &Pragma) -> Result<()> {
10848 self.write_keyword("PRAGMA");
10849 self.write_space();
10850
10851 if let Some(schema) = &p.schema {
10853 self.generate_identifier(schema)?;
10854 self.write(".");
10855 }
10856
10857 self.generate_identifier(&p.name)?;
10859
10860 if let Some(value) = &p.value {
10862 self.write(" = ");
10863 self.generate_expression(value)?;
10864 } else if !p.args.is_empty() {
10865 self.write("(");
10866 for (i, arg) in p.args.iter().enumerate() {
10867 if i > 0 {
10868 self.write(", ");
10869 }
10870 self.generate_expression(arg)?;
10871 }
10872 self.write(")");
10873 }
10874
10875 Ok(())
10876 }
10877
10878 fn generate_grant(&mut self, g: &Grant) -> Result<()> {
10879 self.write_keyword("GRANT");
10880 self.write_space();
10881
10882 for (i, privilege) in g.privileges.iter().enumerate() {
10884 if i > 0 {
10885 self.write(", ");
10886 }
10887 self.write_keyword(&privilege.name);
10888 if !privilege.columns.is_empty() {
10890 self.write("(");
10891 for (j, col) in privilege.columns.iter().enumerate() {
10892 if j > 0 {
10893 self.write(", ");
10894 }
10895 self.write(col);
10896 }
10897 self.write(")");
10898 }
10899 }
10900
10901 self.write_space();
10902 self.write_keyword("ON");
10903 self.write_space();
10904
10905 if let Some(kind) = &g.kind {
10907 self.write_keyword(kind);
10908 self.write_space();
10909 }
10910
10911 {
10913 use crate::dialects::DialectType;
10914 let should_upper = matches!(
10915 self.config.dialect,
10916 Some(DialectType::PostgreSQL)
10917 | Some(DialectType::CockroachDB)
10918 | Some(DialectType::Materialize)
10919 | Some(DialectType::RisingWave)
10920 ) && (g.kind.as_deref() == Some("FUNCTION")
10921 || g.kind.as_deref() == Some("PROCEDURE"));
10922 if should_upper {
10923 use crate::expressions::Identifier;
10924 let upper_id = Identifier {
10925 name: g.securable.name.to_uppercase(),
10926 quoted: g.securable.quoted,
10927 ..g.securable.clone()
10928 };
10929 self.generate_identifier(&upper_id)?;
10930 } else {
10931 self.generate_identifier(&g.securable)?;
10932 }
10933 }
10934
10935 if !g.function_params.is_empty() {
10937 self.write("(");
10938 for (i, param) in g.function_params.iter().enumerate() {
10939 if i > 0 {
10940 self.write(", ");
10941 }
10942 self.write(param);
10943 }
10944 self.write(")");
10945 }
10946
10947 self.write_space();
10948 self.write_keyword("TO");
10949 self.write_space();
10950
10951 for (i, principal) in g.principals.iter().enumerate() {
10953 if i > 0 {
10954 self.write(", ");
10955 }
10956 if principal.is_role {
10957 self.write_keyword("ROLE");
10958 self.write_space();
10959 } else if principal.is_group {
10960 self.write_keyword("GROUP");
10961 self.write_space();
10962 }
10963 self.generate_identifier(&principal.name)?;
10964 }
10965
10966 if g.grant_option {
10968 self.write_space();
10969 self.write_keyword("WITH GRANT OPTION");
10970 }
10971
10972 if let Some(ref principal) = g.as_principal {
10974 self.write_space();
10975 self.write_keyword("AS");
10976 self.write_space();
10977 self.generate_identifier(principal)?;
10978 }
10979
10980 Ok(())
10981 }
10982
10983 fn generate_revoke(&mut self, r: &Revoke) -> Result<()> {
10984 self.write_keyword("REVOKE");
10985 self.write_space();
10986
10987 if r.grant_option {
10989 self.write_keyword("GRANT OPTION FOR");
10990 self.write_space();
10991 }
10992
10993 for (i, privilege) in r.privileges.iter().enumerate() {
10995 if i > 0 {
10996 self.write(", ");
10997 }
10998 self.write_keyword(&privilege.name);
10999 if !privilege.columns.is_empty() {
11001 self.write("(");
11002 for (j, col) in privilege.columns.iter().enumerate() {
11003 if j > 0 {
11004 self.write(", ");
11005 }
11006 self.write(col);
11007 }
11008 self.write(")");
11009 }
11010 }
11011
11012 self.write_space();
11013 self.write_keyword("ON");
11014 self.write_space();
11015
11016 if let Some(kind) = &r.kind {
11018 self.write_keyword(kind);
11019 self.write_space();
11020 }
11021
11022 {
11024 use crate::dialects::DialectType;
11025 let should_upper = matches!(
11026 self.config.dialect,
11027 Some(DialectType::PostgreSQL)
11028 | Some(DialectType::CockroachDB)
11029 | Some(DialectType::Materialize)
11030 | Some(DialectType::RisingWave)
11031 ) && (r.kind.as_deref() == Some("FUNCTION")
11032 || r.kind.as_deref() == Some("PROCEDURE"));
11033 if should_upper {
11034 use crate::expressions::Identifier;
11035 let upper_id = Identifier {
11036 name: r.securable.name.to_uppercase(),
11037 quoted: r.securable.quoted,
11038 ..r.securable.clone()
11039 };
11040 self.generate_identifier(&upper_id)?;
11041 } else {
11042 self.generate_identifier(&r.securable)?;
11043 }
11044 }
11045
11046 if !r.function_params.is_empty() {
11048 self.write("(");
11049 for (i, param) in r.function_params.iter().enumerate() {
11050 if i > 0 {
11051 self.write(", ");
11052 }
11053 self.write(param);
11054 }
11055 self.write(")");
11056 }
11057
11058 self.write_space();
11059 self.write_keyword("FROM");
11060 self.write_space();
11061
11062 for (i, principal) in r.principals.iter().enumerate() {
11064 if i > 0 {
11065 self.write(", ");
11066 }
11067 if principal.is_role {
11068 self.write_keyword("ROLE");
11069 self.write_space();
11070 } else if principal.is_group {
11071 self.write_keyword("GROUP");
11072 self.write_space();
11073 }
11074 self.generate_identifier(&principal.name)?;
11075 }
11076
11077 if r.cascade {
11079 self.write_space();
11080 self.write_keyword("CASCADE");
11081 } else if r.restrict {
11082 self.write_space();
11083 self.write_keyword("RESTRICT");
11084 }
11085
11086 Ok(())
11087 }
11088
11089 fn generate_comment(&mut self, c: &Comment) -> Result<()> {
11090 self.write_keyword("COMMENT");
11091
11092 if c.exists {
11094 self.write_space();
11095 self.write_keyword("IF EXISTS");
11096 }
11097
11098 self.write_space();
11099 self.write_keyword("ON");
11100
11101 if c.materialized {
11103 self.write_space();
11104 self.write_keyword("MATERIALIZED");
11105 }
11106
11107 self.write_space();
11108 self.write_keyword(&c.kind);
11109 self.write_space();
11110
11111 self.generate_expression(&c.this)?;
11113
11114 self.write_space();
11115 self.write_keyword("IS");
11116 self.write_space();
11117
11118 self.generate_expression(&c.expression)?;
11120
11121 Ok(())
11122 }
11123
11124 fn generate_set_statement(&mut self, s: &SetStatement) -> Result<()> {
11125 self.write_keyword("SET");
11126
11127 for (i, item) in s.items.iter().enumerate() {
11128 if i > 0 {
11129 self.write(",");
11130 }
11131 self.write_space();
11132
11133 if let Some(ref kind) = item.kind {
11135 self.write_keyword(kind);
11136 self.write_space();
11137 }
11138
11139 let name_str = match &item.name {
11141 Expression::Identifier(id) => Some(id.name.as_str()),
11142 _ => None,
11143 };
11144
11145 let is_transaction = name_str == Some("TRANSACTION");
11146 let is_character_set = name_str == Some("CHARACTER SET");
11147 let is_names = name_str == Some("NAMES");
11148 let is_collate = name_str == Some("COLLATE");
11149 let has_variable_kind = item.kind.as_deref() == Some("VARIABLE");
11150 let name_has_variable_prefix = name_str.map_or(false, |n| n.starts_with("VARIABLE "));
11151 let is_variable = has_variable_kind || name_has_variable_prefix;
11152 let is_value_only =
11153 matches!(&item.value, Expression::Identifier(id) if id.name.is_empty());
11154
11155 if is_transaction {
11156 self.write_keyword("TRANSACTION");
11158 if let Expression::Identifier(id) = &item.value {
11159 if !id.name.is_empty() {
11160 self.write_space();
11161 self.write(&id.name);
11162 }
11163 }
11164 } else if is_character_set {
11165 self.write_keyword("CHARACTER SET");
11167 self.write_space();
11168 self.generate_set_value(&item.value)?;
11169 } else if is_names {
11170 self.write_keyword("NAMES");
11172 self.write_space();
11173 self.generate_set_value(&item.value)?;
11174 } else if is_collate {
11175 self.write_keyword("COLLATE");
11177 self.write_space();
11178 self.generate_set_value(&item.value)?;
11179 } else if is_variable {
11180 if name_has_variable_prefix && !has_variable_kind {
11184 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
11185 self.write_keyword("VARIABLE");
11186 self.write_space();
11187 }
11188 }
11189 if let Some(ns) = name_str {
11191 let var_name = if name_has_variable_prefix {
11192 &ns["VARIABLE ".len()..]
11193 } else {
11194 ns
11195 };
11196 self.write(var_name);
11197 } else {
11198 self.generate_expression(&item.name)?;
11199 }
11200 self.write(" = ");
11201 self.generate_set_value(&item.value)?;
11202 } else if is_value_only {
11203 self.generate_expression(&item.name)?;
11205 } else if item.no_equals && matches!(self.config.dialect, Some(DialectType::TSQL)) {
11206 self.generate_expression(&item.name)?;
11208 self.write_space();
11209 self.generate_set_value(&item.value)?;
11210 } else {
11211 match &item.name {
11214 Expression::Identifier(id) => {
11215 self.write(&id.name);
11216 }
11217 _ => {
11218 self.generate_expression(&item.name)?;
11219 }
11220 }
11221 self.write(" = ");
11222 self.generate_set_value(&item.value)?;
11223 }
11224 }
11225
11226 Ok(())
11227 }
11228
11229 fn generate_set_value(&mut self, value: &Expression) -> Result<()> {
11232 if let Expression::Identifier(id) = value {
11233 match id.name.as_str() {
11234 "DEFAULT" | "ON" | "OFF" => {
11235 self.write_keyword(&id.name);
11236 return Ok(());
11237 }
11238 _ => {}
11239 }
11240 }
11241 self.generate_expression(value)
11242 }
11243
11244 fn generate_alter_view(&mut self, av: &AlterView) -> Result<()> {
11247 self.write_keyword("ALTER");
11248 if let Some(ref algorithm) = av.algorithm {
11250 self.write_space();
11251 self.write_keyword("ALGORITHM");
11252 self.write(" = ");
11253 self.write_keyword(algorithm);
11254 }
11255 if let Some(ref definer) = av.definer {
11256 self.write_space();
11257 self.write_keyword("DEFINER");
11258 self.write(" = ");
11259 self.write(definer);
11260 }
11261 if let Some(ref sql_security) = av.sql_security {
11262 self.write_space();
11263 self.write_keyword("SQL SECURITY");
11264 self.write(" = ");
11265 self.write_keyword(sql_security);
11266 }
11267 self.write_space();
11268 self.write_keyword("VIEW");
11269 self.write_space();
11270 self.generate_table(&av.name)?;
11271
11272 if !av.columns.is_empty() {
11274 self.write(" (");
11275 for (i, col) in av.columns.iter().enumerate() {
11276 if i > 0 {
11277 self.write(", ");
11278 }
11279 self.generate_identifier(&col.name)?;
11280 if let Some(ref comment) = col.comment {
11281 self.write_space();
11282 self.write_keyword("COMMENT");
11283 self.write(" ");
11284 self.generate_string_literal(comment)?;
11285 }
11286 }
11287 self.write(")");
11288 }
11289
11290 if let Some(ref opt) = av.with_option {
11292 self.write_space();
11293 self.write_keyword("WITH");
11294 self.write_space();
11295 self.write_keyword(opt);
11296 }
11297
11298 for action in &av.actions {
11299 self.write_space();
11300 match action {
11301 AlterViewAction::Rename(new_name) => {
11302 self.write_keyword("RENAME TO");
11303 self.write_space();
11304 self.generate_table(new_name)?;
11305 }
11306 AlterViewAction::OwnerTo(owner) => {
11307 self.write_keyword("OWNER TO");
11308 self.write_space();
11309 self.generate_identifier(owner)?;
11310 }
11311 AlterViewAction::SetSchema(schema) => {
11312 self.write_keyword("SET SCHEMA");
11313 self.write_space();
11314 self.generate_identifier(schema)?;
11315 }
11316 AlterViewAction::SetAuthorization(auth) => {
11317 self.write_keyword("SET AUTHORIZATION");
11318 self.write_space();
11319 self.write(auth);
11320 }
11321 AlterViewAction::AlterColumn { name, action } => {
11322 self.write_keyword("ALTER COLUMN");
11323 self.write_space();
11324 self.generate_identifier(name)?;
11325 self.write_space();
11326 self.generate_alter_column_action(action)?;
11327 }
11328 AlterViewAction::AsSelect(query) => {
11329 self.write_keyword("AS");
11330 self.write_space();
11331 self.generate_expression(query)?;
11332 }
11333 AlterViewAction::SetTblproperties(props) => {
11334 self.write_keyword("SET TBLPROPERTIES");
11335 self.write(" (");
11336 for (i, (key, value)) in props.iter().enumerate() {
11337 if i > 0 {
11338 self.write(", ");
11339 }
11340 self.generate_string_literal(key)?;
11341 self.write("=");
11342 self.generate_string_literal(value)?;
11343 }
11344 self.write(")");
11345 }
11346 AlterViewAction::UnsetTblproperties(keys) => {
11347 self.write_keyword("UNSET TBLPROPERTIES");
11348 self.write(" (");
11349 for (i, key) in keys.iter().enumerate() {
11350 if i > 0 {
11351 self.write(", ");
11352 }
11353 self.generate_string_literal(key)?;
11354 }
11355 self.write(")");
11356 }
11357 }
11358 }
11359
11360 Ok(())
11361 }
11362
11363 fn generate_alter_index(&mut self, ai: &AlterIndex) -> Result<()> {
11364 self.write_keyword("ALTER INDEX");
11365 self.write_space();
11366 self.generate_identifier(&ai.name)?;
11367
11368 if let Some(table) = &ai.table {
11369 self.write_space();
11370 self.write_keyword("ON");
11371 self.write_space();
11372 self.generate_table(table)?;
11373 }
11374
11375 for action in &ai.actions {
11376 self.write_space();
11377 match action {
11378 AlterIndexAction::Rename(new_name) => {
11379 self.write_keyword("RENAME TO");
11380 self.write_space();
11381 self.generate_identifier(new_name)?;
11382 }
11383 AlterIndexAction::SetTablespace(tablespace) => {
11384 self.write_keyword("SET TABLESPACE");
11385 self.write_space();
11386 self.generate_identifier(tablespace)?;
11387 }
11388 AlterIndexAction::Visible(visible) => {
11389 if *visible {
11390 self.write_keyword("VISIBLE");
11391 } else {
11392 self.write_keyword("INVISIBLE");
11393 }
11394 }
11395 }
11396 }
11397
11398 Ok(())
11399 }
11400
11401 fn generate_create_schema(&mut self, cs: &CreateSchema) -> Result<()> {
11402 for comment in &cs.leading_comments {
11404 self.write_formatted_comment(comment);
11405 self.write_space();
11406 }
11407
11408 let saved_athena_hive_context = self.athena_hive_context;
11410 if matches!(
11411 self.config.dialect,
11412 Some(crate::dialects::DialectType::Athena)
11413 ) {
11414 self.athena_hive_context = true;
11415 }
11416
11417 self.write_keyword("CREATE SCHEMA");
11418
11419 if cs.if_not_exists {
11420 self.write_space();
11421 self.write_keyword("IF NOT EXISTS");
11422 }
11423
11424 self.write_space();
11425 self.generate_identifier(&cs.name)?;
11426
11427 if let Some(ref clone_src) = cs.clone_from {
11428 self.write_keyword(" CLONE ");
11429 self.generate_identifier(clone_src)?;
11430 }
11431
11432 if let Some(ref at_clause) = cs.at_clause {
11433 self.write_space();
11434 self.generate_expression(at_clause)?;
11435 }
11436
11437 if let Some(auth) = &cs.authorization {
11438 self.write_space();
11439 self.write_keyword("AUTHORIZATION");
11440 self.write_space();
11441 self.generate_identifier(auth)?;
11442 }
11443
11444 let with_properties: Vec<_> = cs
11447 .properties
11448 .iter()
11449 .filter(|p| matches!(p, Expression::Property(_)))
11450 .collect();
11451 let other_properties: Vec<_> = cs
11452 .properties
11453 .iter()
11454 .filter(|p| !matches!(p, Expression::Property(_)))
11455 .collect();
11456
11457 if !with_properties.is_empty() {
11459 self.write_space();
11460 self.write_keyword("WITH");
11461 self.write(" (");
11462 for (i, prop) in with_properties.iter().enumerate() {
11463 if i > 0 {
11464 self.write(", ");
11465 }
11466 self.generate_expression(prop)?;
11467 }
11468 self.write(")");
11469 }
11470
11471 for prop in other_properties {
11473 self.write_space();
11474 self.generate_expression(prop)?;
11475 }
11476
11477 self.athena_hive_context = saved_athena_hive_context;
11479
11480 Ok(())
11481 }
11482
11483 fn generate_drop_schema(&mut self, ds: &DropSchema) -> Result<()> {
11484 self.write_keyword("DROP SCHEMA");
11485
11486 if ds.if_exists {
11487 self.write_space();
11488 self.write_keyword("IF EXISTS");
11489 }
11490
11491 self.write_space();
11492 self.generate_identifier(&ds.name)?;
11493
11494 if ds.cascade {
11495 self.write_space();
11496 self.write_keyword("CASCADE");
11497 }
11498
11499 Ok(())
11500 }
11501
11502 fn generate_drop_namespace(&mut self, dn: &DropNamespace) -> Result<()> {
11503 self.write_keyword("DROP NAMESPACE");
11504
11505 if dn.if_exists {
11506 self.write_space();
11507 self.write_keyword("IF EXISTS");
11508 }
11509
11510 self.write_space();
11511 self.generate_identifier(&dn.name)?;
11512
11513 if dn.cascade {
11514 self.write_space();
11515 self.write_keyword("CASCADE");
11516 }
11517
11518 Ok(())
11519 }
11520
11521 fn generate_create_database(&mut self, cd: &CreateDatabase) -> Result<()> {
11522 self.write_keyword("CREATE DATABASE");
11523
11524 if cd.if_not_exists {
11525 self.write_space();
11526 self.write_keyword("IF NOT EXISTS");
11527 }
11528
11529 self.write_space();
11530 self.generate_identifier(&cd.name)?;
11531
11532 if let Some(ref clone_src) = cd.clone_from {
11533 self.write_keyword(" CLONE ");
11534 self.generate_identifier(clone_src)?;
11535 }
11536
11537 if let Some(ref at_clause) = cd.at_clause {
11539 self.write_space();
11540 self.generate_expression(at_clause)?;
11541 }
11542
11543 for option in &cd.options {
11544 self.write_space();
11545 match option {
11546 DatabaseOption::CharacterSet(charset) => {
11547 self.write_keyword("CHARACTER SET");
11548 self.write(" = ");
11549 self.write(&format!("'{}'", charset));
11550 }
11551 DatabaseOption::Collate(collate) => {
11552 self.write_keyword("COLLATE");
11553 self.write(" = ");
11554 self.write(&format!("'{}'", collate));
11555 }
11556 DatabaseOption::Owner(owner) => {
11557 self.write_keyword("OWNER");
11558 self.write(" = ");
11559 self.generate_identifier(owner)?;
11560 }
11561 DatabaseOption::Template(template) => {
11562 self.write_keyword("TEMPLATE");
11563 self.write(" = ");
11564 self.generate_identifier(template)?;
11565 }
11566 DatabaseOption::Encoding(encoding) => {
11567 self.write_keyword("ENCODING");
11568 self.write(" = ");
11569 self.write(&format!("'{}'", encoding));
11570 }
11571 DatabaseOption::Location(location) => {
11572 self.write_keyword("LOCATION");
11573 self.write(" = ");
11574 self.write(&format!("'{}'", location));
11575 }
11576 }
11577 }
11578
11579 Ok(())
11580 }
11581
11582 fn generate_drop_database(&mut self, dd: &DropDatabase) -> Result<()> {
11583 self.write_keyword("DROP DATABASE");
11584
11585 if dd.if_exists {
11586 self.write_space();
11587 self.write_keyword("IF EXISTS");
11588 }
11589
11590 self.write_space();
11591 self.generate_identifier(&dd.name)?;
11592
11593 Ok(())
11594 }
11595
11596 fn generate_create_function(&mut self, cf: &CreateFunction) -> Result<()> {
11597 self.write_keyword("CREATE");
11598
11599 if cf.or_replace {
11600 self.write_space();
11601 self.write_keyword("OR REPLACE");
11602 }
11603
11604 if cf.temporary {
11605 self.write_space();
11606 self.write_keyword("TEMPORARY");
11607 }
11608
11609 self.write_space();
11610 if cf.is_table_function {
11611 self.write_keyword("TABLE FUNCTION");
11612 } else {
11613 self.write_keyword("FUNCTION");
11614 }
11615
11616 if cf.if_not_exists {
11617 self.write_space();
11618 self.write_keyword("IF NOT EXISTS");
11619 }
11620
11621 self.write_space();
11622 self.generate_table(&cf.name)?;
11623 if cf.has_parens {
11624 let func_multiline = self.config.pretty
11625 && matches!(
11626 self.config.dialect,
11627 Some(crate::dialects::DialectType::TSQL)
11628 | Some(crate::dialects::DialectType::Fabric)
11629 )
11630 && !cf.parameters.is_empty();
11631 if func_multiline {
11632 self.write("(\n");
11633 self.indent_level += 2;
11634 self.write_indent();
11635 self.generate_function_parameters(&cf.parameters)?;
11636 self.write("\n");
11637 self.indent_level -= 2;
11638 self.write(")");
11639 } else {
11640 self.write("(");
11641 self.generate_function_parameters(&cf.parameters)?;
11642 self.write(")");
11643 }
11644 }
11645
11646 let use_multiline = self.config.pretty
11649 && matches!(
11650 self.config.dialect,
11651 Some(crate::dialects::DialectType::BigQuery)
11652 | Some(crate::dialects::DialectType::TSQL)
11653 | Some(crate::dialects::DialectType::Fabric)
11654 );
11655
11656 if cf.language_first {
11657 if let Some(lang) = &cf.language {
11659 if use_multiline {
11660 self.write_newline();
11661 } else {
11662 self.write_space();
11663 }
11664 self.write_keyword("LANGUAGE");
11665 self.write_space();
11666 self.write(lang);
11667 }
11668
11669 if let Some(sql_data) = &cf.sql_data_access {
11671 self.write_space();
11672 match sql_data {
11673 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
11674 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
11675 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
11676 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
11677 }
11678 }
11679
11680 if let Some(ref rtb) = cf.returns_table_body {
11681 if use_multiline {
11682 self.write_newline();
11683 } else {
11684 self.write_space();
11685 }
11686 self.write_keyword("RETURNS");
11687 self.write_space();
11688 self.write(rtb);
11689 } else if let Some(return_type) = &cf.return_type {
11690 if use_multiline {
11691 self.write_newline();
11692 } else {
11693 self.write_space();
11694 }
11695 self.write_keyword("RETURNS");
11696 self.write_space();
11697 self.generate_data_type(return_type)?;
11698 }
11699 } else {
11700 let is_duckdb = matches!(
11703 self.config.dialect,
11704 Some(crate::dialects::DialectType::DuckDB)
11705 );
11706 if let Some(ref rtb) = cf.returns_table_body {
11707 if !(is_duckdb && rtb.is_empty()) {
11708 if use_multiline {
11709 self.write_newline();
11710 } else {
11711 self.write_space();
11712 }
11713 self.write_keyword("RETURNS");
11714 self.write_space();
11715 self.write(rtb);
11716 }
11717 } else if let Some(return_type) = &cf.return_type {
11718 if use_multiline {
11719 self.write_newline();
11720 } else {
11721 self.write_space();
11722 }
11723 self.write_keyword("RETURNS");
11724 self.write_space();
11725 self.generate_data_type(return_type)?;
11726 }
11727 }
11728
11729 if !cf.property_order.is_empty() {
11731 let is_bigquery = matches!(
11733 self.config.dialect,
11734 Some(crate::dialects::DialectType::BigQuery)
11735 );
11736 let property_order = if is_bigquery {
11737 let mut reordered = Vec::new();
11739 let mut has_as = false;
11740 let mut has_options = false;
11741 for prop in &cf.property_order {
11742 match prop {
11743 FunctionPropertyKind::As => has_as = true,
11744 FunctionPropertyKind::Options => has_options = true,
11745 _ => {}
11746 }
11747 }
11748 if has_as && has_options {
11749 for prop in &cf.property_order {
11751 if *prop != FunctionPropertyKind::As
11752 && *prop != FunctionPropertyKind::Options
11753 {
11754 reordered.push(*prop);
11755 }
11756 }
11757 reordered.push(FunctionPropertyKind::Options);
11758 reordered.push(FunctionPropertyKind::As);
11759 reordered
11760 } else {
11761 cf.property_order.clone()
11762 }
11763 } else {
11764 cf.property_order.clone()
11765 };
11766
11767 for prop in &property_order {
11768 match prop {
11769 FunctionPropertyKind::Set => {
11770 self.generate_function_set_options(cf)?;
11771 }
11772 FunctionPropertyKind::As => {
11773 self.generate_function_body(cf)?;
11774 }
11775 FunctionPropertyKind::Language => {
11776 if !cf.language_first {
11777 if let Some(lang) = &cf.language {
11779 let use_multiline = self.config.pretty
11781 && matches!(
11782 self.config.dialect,
11783 Some(crate::dialects::DialectType::BigQuery)
11784 );
11785 if use_multiline {
11786 self.write_newline();
11787 } else {
11788 self.write_space();
11789 }
11790 self.write_keyword("LANGUAGE");
11791 self.write_space();
11792 self.write(lang);
11793 }
11794 }
11795 }
11796 FunctionPropertyKind::Determinism => {
11797 self.generate_function_determinism(cf)?;
11798 }
11799 FunctionPropertyKind::NullInput => {
11800 self.generate_function_null_input(cf)?;
11801 }
11802 FunctionPropertyKind::Security => {
11803 self.generate_function_security(cf)?;
11804 }
11805 FunctionPropertyKind::SqlDataAccess => {
11806 if !cf.language_first {
11807 self.generate_function_sql_data_access(cf)?;
11809 }
11810 }
11811 FunctionPropertyKind::Options => {
11812 if !cf.options.is_empty() {
11813 self.write_space();
11814 self.generate_options_clause(&cf.options)?;
11815 }
11816 }
11817 FunctionPropertyKind::Environment => {
11818 if !cf.environment.is_empty() {
11819 self.write_space();
11820 self.generate_environment_clause(&cf.environment)?;
11821 }
11822 }
11823 }
11824 }
11825
11826 if !cf.options.is_empty() && !cf.property_order.contains(&FunctionPropertyKind::Options)
11828 {
11829 self.write_space();
11830 self.generate_options_clause(&cf.options)?;
11831 }
11832
11833 if !cf.environment.is_empty()
11835 && !cf
11836 .property_order
11837 .contains(&FunctionPropertyKind::Environment)
11838 {
11839 self.write_space();
11840 self.generate_environment_clause(&cf.environment)?;
11841 }
11842 } else {
11843 if matches!(
11846 self.config.dialect,
11847 Some(crate::dialects::DialectType::BigQuery)
11848 ) {
11849 self.generate_function_determinism(cf)?;
11850 }
11851
11852 let use_multiline = self.config.pretty
11854 && matches!(
11855 self.config.dialect,
11856 Some(crate::dialects::DialectType::BigQuery)
11857 );
11858
11859 if !cf.language_first {
11860 if let Some(lang) = &cf.language {
11861 if use_multiline {
11862 self.write_newline();
11863 } else {
11864 self.write_space();
11865 }
11866 self.write_keyword("LANGUAGE");
11867 self.write_space();
11868 self.write(lang);
11869 }
11870
11871 self.generate_function_sql_data_access(cf)?;
11873 }
11874
11875 if !matches!(
11877 self.config.dialect,
11878 Some(crate::dialects::DialectType::BigQuery)
11879 ) {
11880 self.generate_function_determinism(cf)?;
11881 }
11882
11883 self.generate_function_null_input(cf)?;
11884 self.generate_function_security(cf)?;
11885 self.generate_function_set_options(cf)?;
11886
11887 if !cf.options.is_empty() {
11889 self.write_space();
11890 self.generate_options_clause(&cf.options)?;
11891 }
11892
11893 if !cf.environment.is_empty() {
11895 self.write_space();
11896 self.generate_environment_clause(&cf.environment)?;
11897 }
11898
11899 self.generate_function_body(cf)?;
11900 }
11901
11902 Ok(())
11903 }
11904
11905 fn generate_function_set_options(&mut self, cf: &CreateFunction) -> Result<()> {
11907 for opt in &cf.set_options {
11908 self.write_space();
11909 self.write_keyword("SET");
11910 self.write_space();
11911 self.write(&opt.name);
11912 match &opt.value {
11913 FunctionSetValue::Value { value, use_to } => {
11914 if *use_to {
11915 self.write(" TO ");
11916 } else {
11917 self.write(" = ");
11918 }
11919 self.write(value);
11920 }
11921 FunctionSetValue::FromCurrent => {
11922 self.write_space();
11923 self.write_keyword("FROM CURRENT");
11924 }
11925 }
11926 }
11927 Ok(())
11928 }
11929
11930 fn generate_function_body(&mut self, cf: &CreateFunction) -> Result<()> {
11932 if let Some(body) = &cf.body {
11933 self.write_space();
11935 let use_multiline = self.config.pretty
11937 && matches!(
11938 self.config.dialect,
11939 Some(crate::dialects::DialectType::BigQuery)
11940 );
11941 match body {
11942 FunctionBody::Block(block) => {
11943 self.write_keyword("AS");
11944 if matches!(
11945 self.config.dialect,
11946 Some(crate::dialects::DialectType::TSQL)
11947 ) {
11948 self.write(" BEGIN ");
11949 self.write(block);
11950 self.write(" END");
11951 } else if matches!(
11952 self.config.dialect,
11953 Some(crate::dialects::DialectType::PostgreSQL)
11954 ) {
11955 self.write(" $$");
11956 self.write(block);
11957 self.write("$$");
11958 } else {
11959 let escaped = self.escape_block_for_single_quote(block);
11961 if use_multiline {
11963 self.write_newline();
11964 } else {
11965 self.write(" ");
11966 }
11967 self.write("'");
11968 self.write(&escaped);
11969 self.write("'");
11970 }
11971 }
11972 FunctionBody::StringLiteral(s) => {
11973 self.write_keyword("AS");
11974 if use_multiline {
11976 self.write_newline();
11977 } else {
11978 self.write(" ");
11979 }
11980 self.write("'");
11981 self.write(s);
11982 self.write("'");
11983 }
11984 FunctionBody::Expression(expr) => {
11985 self.write_keyword("AS");
11986 self.write_space();
11987 self.generate_expression(expr)?;
11988 }
11989 FunctionBody::External(name) => {
11990 self.write_keyword("EXTERNAL NAME");
11991 self.write(" '");
11992 self.write(name);
11993 self.write("'");
11994 }
11995 FunctionBody::Return(expr) => {
11996 if matches!(
11997 self.config.dialect,
11998 Some(crate::dialects::DialectType::DuckDB)
11999 ) {
12000 self.write_keyword("AS");
12002 self.write_space();
12003 if cf.returns_table_body.is_some() {
12005 self.write_keyword("TABLE");
12006 self.write_space();
12007 }
12008 self.generate_expression(expr)?;
12009 } else {
12010 if self.config.create_function_return_as {
12011 self.write_keyword("AS");
12012 if self.config.pretty
12014 && matches!(
12015 self.config.dialect,
12016 Some(crate::dialects::DialectType::TSQL)
12017 | Some(crate::dialects::DialectType::Fabric)
12018 )
12019 {
12020 self.write_newline();
12021 } else {
12022 self.write_space();
12023 }
12024 }
12025 self.write_keyword("RETURN");
12026 self.write_space();
12027 self.generate_expression(expr)?;
12028 }
12029 }
12030 FunctionBody::Statements(stmts) => {
12031 self.write_keyword("AS");
12032 self.write(" BEGIN ");
12033 for (i, stmt) in stmts.iter().enumerate() {
12034 if i > 0 {
12035 self.write(" ");
12036 }
12037 self.generate_expression(stmt)?;
12038 }
12039 self.write(" END");
12040 }
12041 FunctionBody::DollarQuoted { content, tag } => {
12042 self.write_keyword("AS");
12043 self.write(" ");
12044 let supports_dollar_quoting = matches!(
12046 self.config.dialect,
12047 Some(crate::dialects::DialectType::PostgreSQL)
12048 | Some(crate::dialects::DialectType::Databricks)
12049 | Some(crate::dialects::DialectType::Redshift)
12050 | Some(crate::dialects::DialectType::DuckDB)
12051 );
12052 if supports_dollar_quoting {
12053 self.write("$");
12055 if let Some(t) = tag {
12056 self.write(t);
12057 }
12058 self.write("$");
12059 self.write(content);
12060 self.write("$");
12061 if let Some(t) = tag {
12062 self.write(t);
12063 }
12064 self.write("$");
12065 } else {
12066 let escaped = self.escape_block_for_single_quote(content);
12068 self.write("'");
12069 self.write(&escaped);
12070 self.write("'");
12071 }
12072 }
12073 }
12074 }
12075 Ok(())
12076 }
12077
12078 fn generate_function_determinism(&mut self, cf: &CreateFunction) -> Result<()> {
12080 if let Some(det) = cf.deterministic {
12081 self.write_space();
12082 if matches!(
12083 self.config.dialect,
12084 Some(crate::dialects::DialectType::BigQuery)
12085 ) {
12086 if det {
12088 self.write_keyword("DETERMINISTIC");
12089 } else {
12090 self.write_keyword("NOT DETERMINISTIC");
12091 }
12092 } else {
12093 if det {
12095 self.write_keyword("IMMUTABLE");
12096 } else {
12097 self.write_keyword("VOLATILE");
12098 }
12099 }
12100 }
12101 Ok(())
12102 }
12103
12104 fn generate_function_null_input(&mut self, cf: &CreateFunction) -> Result<()> {
12106 if let Some(returns_null) = cf.returns_null_on_null_input {
12107 self.write_space();
12108 if returns_null {
12109 if cf.strict {
12110 self.write_keyword("STRICT");
12111 } else {
12112 self.write_keyword("RETURNS NULL ON NULL INPUT");
12113 }
12114 } else {
12115 self.write_keyword("CALLED ON NULL INPUT");
12116 }
12117 }
12118 Ok(())
12119 }
12120
12121 fn generate_function_security(&mut self, cf: &CreateFunction) -> Result<()> {
12123 if let Some(security) = &cf.security {
12124 self.write_space();
12125 self.write_keyword("SECURITY");
12126 self.write_space();
12127 match security {
12128 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
12129 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
12130 FunctionSecurity::None => self.write_keyword("NONE"),
12131 }
12132 }
12133 Ok(())
12134 }
12135
12136 fn generate_function_sql_data_access(&mut self, cf: &CreateFunction) -> Result<()> {
12138 if let Some(sql_data) = &cf.sql_data_access {
12139 self.write_space();
12140 match sql_data {
12141 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
12142 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
12143 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
12144 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
12145 }
12146 }
12147 Ok(())
12148 }
12149
12150 fn generate_function_parameters(&mut self, params: &[FunctionParameter]) -> Result<()> {
12151 for (i, param) in params.iter().enumerate() {
12152 if i > 0 {
12153 self.write(", ");
12154 }
12155
12156 if let Some(mode) = ¶m.mode {
12157 if let Some(text) = ¶m.mode_text {
12158 self.write(text);
12159 } else {
12160 match mode {
12161 ParameterMode::In => self.write_keyword("IN"),
12162 ParameterMode::Out => self.write_keyword("OUT"),
12163 ParameterMode::InOut => self.write_keyword("INOUT"),
12164 ParameterMode::Variadic => self.write_keyword("VARIADIC"),
12165 }
12166 }
12167 self.write_space();
12168 }
12169
12170 if let Some(name) = ¶m.name {
12171 self.generate_identifier(name)?;
12172 let skip_type =
12174 matches!(¶m.data_type, DataType::Custom { name } if name.is_empty());
12175 if !skip_type {
12176 self.write_space();
12177 self.generate_data_type(¶m.data_type)?;
12178 }
12179 } else {
12180 self.generate_data_type(¶m.data_type)?;
12181 }
12182
12183 if let Some(default) = ¶m.default {
12184 if self.config.parameter_default_equals {
12185 self.write(" = ");
12186 } else {
12187 self.write(" DEFAULT ");
12188 }
12189 self.generate_expression(default)?;
12190 }
12191 }
12192
12193 Ok(())
12194 }
12195
12196 fn generate_drop_function(&mut self, df: &DropFunction) -> Result<()> {
12197 self.write_keyword("DROP FUNCTION");
12198
12199 if df.if_exists {
12200 self.write_space();
12201 self.write_keyword("IF EXISTS");
12202 }
12203
12204 self.write_space();
12205 self.generate_table(&df.name)?;
12206
12207 if let Some(params) = &df.parameters {
12208 self.write(" (");
12209 for (i, dt) in params.iter().enumerate() {
12210 if i > 0 {
12211 self.write(", ");
12212 }
12213 self.generate_data_type(dt)?;
12214 }
12215 self.write(")");
12216 }
12217
12218 if df.cascade {
12219 self.write_space();
12220 self.write_keyword("CASCADE");
12221 }
12222
12223 Ok(())
12224 }
12225
12226 fn generate_create_procedure(&mut self, cp: &CreateProcedure) -> Result<()> {
12227 self.write_keyword("CREATE");
12228
12229 if cp.or_replace {
12230 self.write_space();
12231 self.write_keyword("OR REPLACE");
12232 }
12233
12234 self.write_space();
12235 if cp.use_proc_keyword {
12236 self.write_keyword("PROC");
12237 } else {
12238 self.write_keyword("PROCEDURE");
12239 }
12240
12241 if cp.if_not_exists {
12242 self.write_space();
12243 self.write_keyword("IF NOT EXISTS");
12244 }
12245
12246 self.write_space();
12247 self.generate_table(&cp.name)?;
12248 if cp.has_parens {
12249 self.write("(");
12250 self.generate_function_parameters(&cp.parameters)?;
12251 self.write(")");
12252 } else if !cp.parameters.is_empty() {
12253 self.write_space();
12255 self.generate_function_parameters(&cp.parameters)?;
12256 }
12257
12258 if let Some(return_type) = &cp.return_type {
12260 self.write_space();
12261 self.write_keyword("RETURNS");
12262 self.write_space();
12263 self.generate_data_type(return_type)?;
12264 }
12265
12266 if let Some(execute_as) = &cp.execute_as {
12268 self.write_space();
12269 self.write_keyword("EXECUTE AS");
12270 self.write_space();
12271 self.write_keyword(execute_as);
12272 }
12273
12274 if let Some(lang) = &cp.language {
12275 self.write_space();
12276 self.write_keyword("LANGUAGE");
12277 self.write_space();
12278 self.write(lang);
12279 }
12280
12281 if let Some(security) = &cp.security {
12282 self.write_space();
12283 self.write_keyword("SECURITY");
12284 self.write_space();
12285 match security {
12286 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
12287 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
12288 FunctionSecurity::None => self.write_keyword("NONE"),
12289 }
12290 }
12291
12292 if !cp.with_options.is_empty() {
12294 self.write_space();
12295 self.write_keyword("WITH");
12296 self.write_space();
12297 for (i, opt) in cp.with_options.iter().enumerate() {
12298 if i > 0 {
12299 self.write(", ");
12300 }
12301 self.write(opt);
12302 }
12303 }
12304
12305 if let Some(body) = &cp.body {
12306 self.write_space();
12307 match body {
12308 FunctionBody::Block(block) => {
12309 self.write_keyword("AS");
12310 if matches!(
12311 self.config.dialect,
12312 Some(crate::dialects::DialectType::TSQL)
12313 ) {
12314 self.write(" BEGIN ");
12315 self.write(block);
12316 self.write(" END");
12317 } else if matches!(
12318 self.config.dialect,
12319 Some(crate::dialects::DialectType::PostgreSQL)
12320 ) {
12321 self.write(" $$");
12322 self.write(block);
12323 self.write("$$");
12324 } else {
12325 let escaped = self.escape_block_for_single_quote(block);
12327 self.write(" '");
12328 self.write(&escaped);
12329 self.write("'");
12330 }
12331 }
12332 FunctionBody::StringLiteral(s) => {
12333 self.write_keyword("AS");
12334 self.write(" '");
12335 self.write(s);
12336 self.write("'");
12337 }
12338 FunctionBody::Expression(expr) => {
12339 self.write_keyword("AS");
12340 self.write_space();
12341 self.generate_expression(expr)?;
12342 }
12343 FunctionBody::External(name) => {
12344 self.write_keyword("EXTERNAL NAME");
12345 self.write(" '");
12346 self.write(name);
12347 self.write("'");
12348 }
12349 FunctionBody::Return(expr) => {
12350 self.write_keyword("RETURN");
12351 self.write_space();
12352 self.generate_expression(expr)?;
12353 }
12354 FunctionBody::Statements(stmts) => {
12355 self.write_keyword("AS");
12356 self.write(" BEGIN ");
12357 for (i, stmt) in stmts.iter().enumerate() {
12358 if i > 0 {
12359 self.write(" ");
12360 }
12361 self.generate_expression(stmt)?;
12362 }
12363 self.write(" END");
12364 }
12365 FunctionBody::DollarQuoted { content, tag } => {
12366 self.write_keyword("AS");
12367 self.write(" ");
12368 let supports_dollar_quoting = matches!(
12370 self.config.dialect,
12371 Some(crate::dialects::DialectType::PostgreSQL)
12372 | Some(crate::dialects::DialectType::Databricks)
12373 | Some(crate::dialects::DialectType::Redshift)
12374 | Some(crate::dialects::DialectType::DuckDB)
12375 );
12376 if supports_dollar_quoting {
12377 self.write("$");
12379 if let Some(t) = tag {
12380 self.write(t);
12381 }
12382 self.write("$");
12383 self.write(content);
12384 self.write("$");
12385 if let Some(t) = tag {
12386 self.write(t);
12387 }
12388 self.write("$");
12389 } else {
12390 let escaped = self.escape_block_for_single_quote(content);
12392 self.write("'");
12393 self.write(&escaped);
12394 self.write("'");
12395 }
12396 }
12397 }
12398 }
12399
12400 Ok(())
12401 }
12402
12403 fn generate_drop_procedure(&mut self, dp: &DropProcedure) -> Result<()> {
12404 self.write_keyword("DROP PROCEDURE");
12405
12406 if dp.if_exists {
12407 self.write_space();
12408 self.write_keyword("IF EXISTS");
12409 }
12410
12411 self.write_space();
12412 self.generate_table(&dp.name)?;
12413
12414 if let Some(params) = &dp.parameters {
12415 self.write(" (");
12416 for (i, dt) in params.iter().enumerate() {
12417 if i > 0 {
12418 self.write(", ");
12419 }
12420 self.generate_data_type(dt)?;
12421 }
12422 self.write(")");
12423 }
12424
12425 if dp.cascade {
12426 self.write_space();
12427 self.write_keyword("CASCADE");
12428 }
12429
12430 Ok(())
12431 }
12432
12433 fn generate_create_sequence(&mut self, cs: &CreateSequence) -> Result<()> {
12434 self.write_keyword("CREATE");
12435
12436 if cs.or_replace {
12437 self.write_space();
12438 self.write_keyword("OR REPLACE");
12439 }
12440
12441 if cs.temporary {
12442 self.write_space();
12443 self.write_keyword("TEMPORARY");
12444 }
12445
12446 self.write_space();
12447 self.write_keyword("SEQUENCE");
12448
12449 if cs.if_not_exists {
12450 self.write_space();
12451 self.write_keyword("IF NOT EXISTS");
12452 }
12453
12454 self.write_space();
12455 self.generate_table(&cs.name)?;
12456
12457 if let Some(as_type) = &cs.as_type {
12459 self.write_space();
12460 self.write_keyword("AS");
12461 self.write_space();
12462 self.generate_data_type(as_type)?;
12463 }
12464
12465 if let Some(comment) = &cs.comment {
12467 self.write_space();
12468 self.write_keyword("COMMENT");
12469 self.write("=");
12470 self.generate_string_literal(comment)?;
12471 }
12472
12473 if !cs.property_order.is_empty() {
12475 for prop in &cs.property_order {
12476 match prop {
12477 SeqPropKind::Start => {
12478 if let Some(start) = cs.start {
12479 self.write_space();
12480 self.write_keyword("START WITH");
12481 self.write(&format!(" {}", start));
12482 }
12483 }
12484 SeqPropKind::Increment => {
12485 if let Some(inc) = cs.increment {
12486 self.write_space();
12487 self.write_keyword("INCREMENT BY");
12488 self.write(&format!(" {}", inc));
12489 }
12490 }
12491 SeqPropKind::Minvalue => {
12492 if let Some(min) = &cs.minvalue {
12493 self.write_space();
12494 match min {
12495 SequenceBound::Value(v) => {
12496 self.write_keyword("MINVALUE");
12497 self.write(&format!(" {}", v));
12498 }
12499 SequenceBound::None => {
12500 self.write_keyword("NO MINVALUE");
12501 }
12502 }
12503 }
12504 }
12505 SeqPropKind::Maxvalue => {
12506 if let Some(max) = &cs.maxvalue {
12507 self.write_space();
12508 match max {
12509 SequenceBound::Value(v) => {
12510 self.write_keyword("MAXVALUE");
12511 self.write(&format!(" {}", v));
12512 }
12513 SequenceBound::None => {
12514 self.write_keyword("NO MAXVALUE");
12515 }
12516 }
12517 }
12518 }
12519 SeqPropKind::Cache => {
12520 if let Some(cache) = cs.cache {
12521 self.write_space();
12522 self.write_keyword("CACHE");
12523 self.write(&format!(" {}", cache));
12524 }
12525 }
12526 SeqPropKind::NoCache => {
12527 self.write_space();
12528 self.write_keyword("NO CACHE");
12529 }
12530 SeqPropKind::NoCacheWord => {
12531 self.write_space();
12532 self.write_keyword("NOCACHE");
12533 }
12534 SeqPropKind::Cycle => {
12535 self.write_space();
12536 self.write_keyword("CYCLE");
12537 }
12538 SeqPropKind::NoCycle => {
12539 self.write_space();
12540 self.write_keyword("NO CYCLE");
12541 }
12542 SeqPropKind::NoCycleWord => {
12543 self.write_space();
12544 self.write_keyword("NOCYCLE");
12545 }
12546 SeqPropKind::OwnedBy => {
12547 if !cs.owned_by_none {
12549 if let Some(owned) = &cs.owned_by {
12550 self.write_space();
12551 self.write_keyword("OWNED BY");
12552 self.write_space();
12553 self.generate_table(owned)?;
12554 }
12555 }
12556 }
12557 SeqPropKind::Order => {
12558 self.write_space();
12559 self.write_keyword("ORDER");
12560 }
12561 SeqPropKind::NoOrder => {
12562 self.write_space();
12563 self.write_keyword("NOORDER");
12564 }
12565 SeqPropKind::Comment => {
12566 }
12568 SeqPropKind::Sharing => {
12569 if let Some(val) = &cs.sharing {
12570 self.write_space();
12571 self.write(&format!("SHARING={}", val));
12572 }
12573 }
12574 SeqPropKind::Keep => {
12575 self.write_space();
12576 self.write_keyword("KEEP");
12577 }
12578 SeqPropKind::NoKeep => {
12579 self.write_space();
12580 self.write_keyword("NOKEEP");
12581 }
12582 SeqPropKind::Scale => {
12583 self.write_space();
12584 self.write_keyword("SCALE");
12585 if let Some(modifier) = &cs.scale_modifier {
12586 if !modifier.is_empty() {
12587 self.write_space();
12588 self.write_keyword(modifier);
12589 }
12590 }
12591 }
12592 SeqPropKind::NoScale => {
12593 self.write_space();
12594 self.write_keyword("NOSCALE");
12595 }
12596 SeqPropKind::Shard => {
12597 self.write_space();
12598 self.write_keyword("SHARD");
12599 if let Some(modifier) = &cs.shard_modifier {
12600 if !modifier.is_empty() {
12601 self.write_space();
12602 self.write_keyword(modifier);
12603 }
12604 }
12605 }
12606 SeqPropKind::NoShard => {
12607 self.write_space();
12608 self.write_keyword("NOSHARD");
12609 }
12610 SeqPropKind::Session => {
12611 self.write_space();
12612 self.write_keyword("SESSION");
12613 }
12614 SeqPropKind::Global => {
12615 self.write_space();
12616 self.write_keyword("GLOBAL");
12617 }
12618 SeqPropKind::NoMinvalueWord => {
12619 self.write_space();
12620 self.write_keyword("NOMINVALUE");
12621 }
12622 SeqPropKind::NoMaxvalueWord => {
12623 self.write_space();
12624 self.write_keyword("NOMAXVALUE");
12625 }
12626 }
12627 }
12628 } else {
12629 if let Some(inc) = cs.increment {
12631 self.write_space();
12632 self.write_keyword("INCREMENT BY");
12633 self.write(&format!(" {}", inc));
12634 }
12635
12636 if let Some(min) = &cs.minvalue {
12637 self.write_space();
12638 match min {
12639 SequenceBound::Value(v) => {
12640 self.write_keyword("MINVALUE");
12641 self.write(&format!(" {}", v));
12642 }
12643 SequenceBound::None => {
12644 self.write_keyword("NO MINVALUE");
12645 }
12646 }
12647 }
12648
12649 if let Some(max) = &cs.maxvalue {
12650 self.write_space();
12651 match max {
12652 SequenceBound::Value(v) => {
12653 self.write_keyword("MAXVALUE");
12654 self.write(&format!(" {}", v));
12655 }
12656 SequenceBound::None => {
12657 self.write_keyword("NO MAXVALUE");
12658 }
12659 }
12660 }
12661
12662 if let Some(start) = cs.start {
12663 self.write_space();
12664 self.write_keyword("START WITH");
12665 self.write(&format!(" {}", start));
12666 }
12667
12668 if let Some(cache) = cs.cache {
12669 self.write_space();
12670 self.write_keyword("CACHE");
12671 self.write(&format!(" {}", cache));
12672 }
12673
12674 if cs.cycle {
12675 self.write_space();
12676 self.write_keyword("CYCLE");
12677 }
12678
12679 if let Some(owned) = &cs.owned_by {
12680 self.write_space();
12681 self.write_keyword("OWNED BY");
12682 self.write_space();
12683 self.generate_table(owned)?;
12684 }
12685 }
12686
12687 Ok(())
12688 }
12689
12690 fn generate_drop_sequence(&mut self, ds: &DropSequence) -> Result<()> {
12691 self.write_keyword("DROP SEQUENCE");
12692
12693 if ds.if_exists {
12694 self.write_space();
12695 self.write_keyword("IF EXISTS");
12696 }
12697
12698 self.write_space();
12699 self.generate_table(&ds.name)?;
12700
12701 if ds.cascade {
12702 self.write_space();
12703 self.write_keyword("CASCADE");
12704 }
12705
12706 Ok(())
12707 }
12708
12709 fn generate_alter_sequence(&mut self, als: &AlterSequence) -> Result<()> {
12710 self.write_keyword("ALTER SEQUENCE");
12711
12712 if als.if_exists {
12713 self.write_space();
12714 self.write_keyword("IF EXISTS");
12715 }
12716
12717 self.write_space();
12718 self.generate_table(&als.name)?;
12719
12720 if let Some(inc) = als.increment {
12721 self.write_space();
12722 self.write_keyword("INCREMENT BY");
12723 self.write(&format!(" {}", inc));
12724 }
12725
12726 if let Some(min) = &als.minvalue {
12727 self.write_space();
12728 match min {
12729 SequenceBound::Value(v) => {
12730 self.write_keyword("MINVALUE");
12731 self.write(&format!(" {}", v));
12732 }
12733 SequenceBound::None => {
12734 self.write_keyword("NO MINVALUE");
12735 }
12736 }
12737 }
12738
12739 if let Some(max) = &als.maxvalue {
12740 self.write_space();
12741 match max {
12742 SequenceBound::Value(v) => {
12743 self.write_keyword("MAXVALUE");
12744 self.write(&format!(" {}", v));
12745 }
12746 SequenceBound::None => {
12747 self.write_keyword("NO MAXVALUE");
12748 }
12749 }
12750 }
12751
12752 if let Some(start) = als.start {
12753 self.write_space();
12754 self.write_keyword("START WITH");
12755 self.write(&format!(" {}", start));
12756 }
12757
12758 if let Some(restart) = &als.restart {
12759 self.write_space();
12760 self.write_keyword("RESTART");
12761 if let Some(val) = restart {
12762 self.write_keyword(" WITH");
12763 self.write(&format!(" {}", val));
12764 }
12765 }
12766
12767 if let Some(cache) = als.cache {
12768 self.write_space();
12769 self.write_keyword("CACHE");
12770 self.write(&format!(" {}", cache));
12771 }
12772
12773 if let Some(cycle) = als.cycle {
12774 self.write_space();
12775 if cycle {
12776 self.write_keyword("CYCLE");
12777 } else {
12778 self.write_keyword("NO CYCLE");
12779 }
12780 }
12781
12782 if let Some(owned) = &als.owned_by {
12783 self.write_space();
12784 self.write_keyword("OWNED BY");
12785 self.write_space();
12786 if let Some(table) = owned {
12787 self.generate_table(table)?;
12788 } else {
12789 self.write_keyword("NONE");
12790 }
12791 }
12792
12793 Ok(())
12794 }
12795
12796 fn generate_create_trigger(&mut self, ct: &CreateTrigger) -> Result<()> {
12797 self.write_keyword("CREATE");
12798
12799 if ct.or_replace {
12800 self.write_space();
12801 self.write_keyword("OR REPLACE");
12802 }
12803
12804 if ct.constraint {
12805 self.write_space();
12806 self.write_keyword("CONSTRAINT");
12807 }
12808
12809 self.write_space();
12810 self.write_keyword("TRIGGER");
12811 self.write_space();
12812 self.generate_identifier(&ct.name)?;
12813
12814 self.write_space();
12815 match ct.timing {
12816 TriggerTiming::Before => self.write_keyword("BEFORE"),
12817 TriggerTiming::After => self.write_keyword("AFTER"),
12818 TriggerTiming::InsteadOf => self.write_keyword("INSTEAD OF"),
12819 }
12820
12821 for (i, event) in ct.events.iter().enumerate() {
12823 if i > 0 {
12824 self.write_keyword(" OR");
12825 }
12826 self.write_space();
12827 match event {
12828 TriggerEvent::Insert => self.write_keyword("INSERT"),
12829 TriggerEvent::Update(cols) => {
12830 self.write_keyword("UPDATE");
12831 if let Some(cols) = cols {
12832 self.write_space();
12833 self.write_keyword("OF");
12834 for (j, col) in cols.iter().enumerate() {
12835 if j > 0 {
12836 self.write(",");
12837 }
12838 self.write_space();
12839 self.generate_identifier(col)?;
12840 }
12841 }
12842 }
12843 TriggerEvent::Delete => self.write_keyword("DELETE"),
12844 TriggerEvent::Truncate => self.write_keyword("TRUNCATE"),
12845 }
12846 }
12847
12848 self.write_space();
12849 self.write_keyword("ON");
12850 self.write_space();
12851 self.generate_table(&ct.table)?;
12852
12853 if let Some(ref_clause) = &ct.referencing {
12855 self.write_space();
12856 self.write_keyword("REFERENCING");
12857 if let Some(old_table) = &ref_clause.old_table {
12858 self.write_space();
12859 self.write_keyword("OLD TABLE AS");
12860 self.write_space();
12861 self.generate_identifier(old_table)?;
12862 }
12863 if let Some(new_table) = &ref_clause.new_table {
12864 self.write_space();
12865 self.write_keyword("NEW TABLE AS");
12866 self.write_space();
12867 self.generate_identifier(new_table)?;
12868 }
12869 if let Some(old_row) = &ref_clause.old_row {
12870 self.write_space();
12871 self.write_keyword("OLD ROW AS");
12872 self.write_space();
12873 self.generate_identifier(old_row)?;
12874 }
12875 if let Some(new_row) = &ref_clause.new_row {
12876 self.write_space();
12877 self.write_keyword("NEW ROW AS");
12878 self.write_space();
12879 self.generate_identifier(new_row)?;
12880 }
12881 }
12882
12883 if let Some(deferrable) = ct.deferrable {
12885 self.write_space();
12886 if deferrable {
12887 self.write_keyword("DEFERRABLE");
12888 } else {
12889 self.write_keyword("NOT DEFERRABLE");
12890 }
12891 }
12892
12893 if let Some(initially) = ct.initially_deferred {
12894 self.write_space();
12895 self.write_keyword("INITIALLY");
12896 self.write_space();
12897 if initially {
12898 self.write_keyword("DEFERRED");
12899 } else {
12900 self.write_keyword("IMMEDIATE");
12901 }
12902 }
12903
12904 self.write_space();
12905 self.write_keyword("FOR EACH");
12906 self.write_space();
12907 match ct.for_each {
12908 TriggerForEach::Row => self.write_keyword("ROW"),
12909 TriggerForEach::Statement => self.write_keyword("STATEMENT"),
12910 }
12911
12912 if let Some(when) = &ct.when {
12914 self.write_space();
12915 self.write_keyword("WHEN");
12916 self.write(" (");
12917 self.generate_expression(when)?;
12918 self.write(")");
12919 }
12920
12921 self.write_space();
12923 match &ct.body {
12924 TriggerBody::Execute { function, args } => {
12925 self.write_keyword("EXECUTE FUNCTION");
12926 self.write_space();
12927 self.generate_table(function)?;
12928 self.write("(");
12929 for (i, arg) in args.iter().enumerate() {
12930 if i > 0 {
12931 self.write(", ");
12932 }
12933 self.generate_expression(arg)?;
12934 }
12935 self.write(")");
12936 }
12937 TriggerBody::Block(block) => {
12938 self.write_keyword("BEGIN");
12939 self.write_space();
12940 self.write(block);
12941 self.write_space();
12942 self.write_keyword("END");
12943 }
12944 }
12945
12946 Ok(())
12947 }
12948
12949 fn generate_drop_trigger(&mut self, dt: &DropTrigger) -> Result<()> {
12950 self.write_keyword("DROP TRIGGER");
12951
12952 if dt.if_exists {
12953 self.write_space();
12954 self.write_keyword("IF EXISTS");
12955 }
12956
12957 self.write_space();
12958 self.generate_identifier(&dt.name)?;
12959
12960 if let Some(table) = &dt.table {
12961 self.write_space();
12962 self.write_keyword("ON");
12963 self.write_space();
12964 self.generate_table(table)?;
12965 }
12966
12967 if dt.cascade {
12968 self.write_space();
12969 self.write_keyword("CASCADE");
12970 }
12971
12972 Ok(())
12973 }
12974
12975 fn generate_create_type(&mut self, ct: &CreateType) -> Result<()> {
12976 self.write_keyword("CREATE TYPE");
12977
12978 if ct.if_not_exists {
12979 self.write_space();
12980 self.write_keyword("IF NOT EXISTS");
12981 }
12982
12983 self.write_space();
12984 self.generate_table(&ct.name)?;
12985
12986 self.write_space();
12987 self.write_keyword("AS");
12988 self.write_space();
12989
12990 match &ct.definition {
12991 TypeDefinition::Enum(values) => {
12992 self.write_keyword("ENUM");
12993 self.write(" (");
12994 for (i, val) in values.iter().enumerate() {
12995 if i > 0 {
12996 self.write(", ");
12997 }
12998 self.write(&format!("'{}'", val));
12999 }
13000 self.write(")");
13001 }
13002 TypeDefinition::Composite(attrs) => {
13003 self.write("(");
13004 for (i, attr) in attrs.iter().enumerate() {
13005 if i > 0 {
13006 self.write(", ");
13007 }
13008 self.generate_identifier(&attr.name)?;
13009 self.write_space();
13010 self.generate_data_type(&attr.data_type)?;
13011 if let Some(collate) = &attr.collate {
13012 self.write_space();
13013 self.write_keyword("COLLATE");
13014 self.write_space();
13015 self.generate_identifier(collate)?;
13016 }
13017 }
13018 self.write(")");
13019 }
13020 TypeDefinition::Range {
13021 subtype,
13022 subtype_diff,
13023 canonical,
13024 } => {
13025 self.write_keyword("RANGE");
13026 self.write(" (");
13027 self.write_keyword("SUBTYPE");
13028 self.write(" = ");
13029 self.generate_data_type(subtype)?;
13030 if let Some(diff) = subtype_diff {
13031 self.write(", ");
13032 self.write_keyword("SUBTYPE_DIFF");
13033 self.write(" = ");
13034 self.write(diff);
13035 }
13036 if let Some(canon) = canonical {
13037 self.write(", ");
13038 self.write_keyword("CANONICAL");
13039 self.write(" = ");
13040 self.write(canon);
13041 }
13042 self.write(")");
13043 }
13044 TypeDefinition::Base {
13045 input,
13046 output,
13047 internallength,
13048 } => {
13049 self.write("(");
13050 self.write_keyword("INPUT");
13051 self.write(" = ");
13052 self.write(input);
13053 self.write(", ");
13054 self.write_keyword("OUTPUT");
13055 self.write(" = ");
13056 self.write(output);
13057 if let Some(len) = internallength {
13058 self.write(", ");
13059 self.write_keyword("INTERNALLENGTH");
13060 self.write(" = ");
13061 self.write(&len.to_string());
13062 }
13063 self.write(")");
13064 }
13065 TypeDefinition::Domain {
13066 base_type,
13067 default,
13068 constraints,
13069 } => {
13070 self.generate_data_type(base_type)?;
13071 if let Some(def) = default {
13072 self.write_space();
13073 self.write_keyword("DEFAULT");
13074 self.write_space();
13075 self.generate_expression(def)?;
13076 }
13077 for constr in constraints {
13078 self.write_space();
13079 if let Some(name) = &constr.name {
13080 self.write_keyword("CONSTRAINT");
13081 self.write_space();
13082 self.generate_identifier(name)?;
13083 self.write_space();
13084 }
13085 self.write_keyword("CHECK");
13086 self.write(" (");
13087 self.generate_expression(&constr.check)?;
13088 self.write(")");
13089 }
13090 }
13091 }
13092
13093 Ok(())
13094 }
13095
13096 fn generate_drop_type(&mut self, dt: &DropType) -> Result<()> {
13097 self.write_keyword("DROP TYPE");
13098
13099 if dt.if_exists {
13100 self.write_space();
13101 self.write_keyword("IF EXISTS");
13102 }
13103
13104 self.write_space();
13105 self.generate_table(&dt.name)?;
13106
13107 if dt.cascade {
13108 self.write_space();
13109 self.write_keyword("CASCADE");
13110 }
13111
13112 Ok(())
13113 }
13114
13115 fn generate_describe(&mut self, d: &Describe) -> Result<()> {
13116 let saved_athena_hive_context = self.athena_hive_context;
13118 if matches!(
13119 self.config.dialect,
13120 Some(crate::dialects::DialectType::Athena)
13121 ) {
13122 self.athena_hive_context = true;
13123 }
13124
13125 for comment in &d.leading_comments {
13127 self.write_formatted_comment(comment);
13128 self.write(" ");
13129 }
13130
13131 self.write_keyword("DESCRIBE");
13132
13133 if d.extended {
13134 self.write_space();
13135 self.write_keyword("EXTENDED");
13136 } else if d.formatted {
13137 self.write_space();
13138 self.write_keyword("FORMATTED");
13139 }
13140
13141 if let Some(ref style) = d.style {
13143 self.write_space();
13144 self.write_keyword(style);
13145 }
13146
13147 let should_output_kind = match self.config.dialect {
13149 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
13151 false
13152 }
13153 Some(DialectType::Snowflake) => true,
13155 _ => d.kind.is_some(),
13156 };
13157 if should_output_kind {
13158 if let Some(ref kind) = d.kind {
13159 self.write_space();
13160 self.write_keyword(kind);
13161 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
13162 self.write_space();
13163 self.write_keyword("TABLE");
13164 }
13165 }
13166
13167 self.write_space();
13168 self.generate_expression(&d.target)?;
13169
13170 if let Some(ref partition) = d.partition {
13172 self.write_space();
13173 self.generate_expression(partition)?;
13174 }
13175
13176 if d.as_json {
13178 self.write_space();
13179 self.write_keyword("AS JSON");
13180 }
13181
13182 for (name, value) in &d.properties {
13184 self.write_space();
13185 self.write(name);
13186 self.write("=");
13187 self.write(value);
13188 }
13189
13190 self.athena_hive_context = saved_athena_hive_context;
13192
13193 Ok(())
13194 }
13195
13196 fn generate_show(&mut self, s: &Show) -> Result<()> {
13199 self.write_keyword("SHOW");
13200 self.write_space();
13201
13202 let show_terse = s.terse
13205 && !matches!(
13206 s.this.as_str(),
13207 "PRIMARY KEYS" | "UNIQUE KEYS" | "IMPORTED KEYS"
13208 );
13209 if show_terse {
13210 self.write_keyword("TERSE");
13211 self.write_space();
13212 }
13213
13214 self.write_keyword(&s.this);
13216
13217 if let Some(ref target_expr) = s.target {
13219 self.write_space();
13220 self.generate_expression(target_expr)?;
13221 }
13222
13223 if s.history {
13225 self.write_space();
13226 self.write_keyword("HISTORY");
13227 }
13228
13229 if let Some(ref for_target) = s.for_target {
13231 self.write_space();
13232 self.write_keyword("FOR");
13233 self.write_space();
13234 self.generate_expression(for_target)?;
13235 }
13236
13237 use crate::dialects::DialectType;
13241 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
13242
13243 if !is_snowflake && s.from.is_some() {
13244 if let Some(ref scope_kind) = s.scope_kind {
13248 self.write_space();
13249 self.write_keyword("IN");
13250 self.write_space();
13251 self.write_keyword(scope_kind);
13252 if let Some(ref scope) = s.scope {
13253 self.write_space();
13254 self.generate_expression(scope)?;
13255 }
13256 } else if let Some(ref scope) = s.scope {
13257 self.write_space();
13258 self.write_keyword("IN");
13259 self.write_space();
13260 self.generate_expression(scope)?;
13261 }
13262
13263 if let Some(ref from) = s.from {
13265 self.write_space();
13266 self.write_keyword("FROM");
13267 self.write_space();
13268 self.generate_expression(from)?;
13269 }
13270
13271 if let Some(ref db) = s.db {
13273 self.write_space();
13274 self.write_keyword("FROM");
13275 self.write_space();
13276 self.generate_expression(db)?;
13277 }
13278
13279 if let Some(ref like) = s.like {
13281 self.write_space();
13282 self.write_keyword("LIKE");
13283 self.write_space();
13284 self.generate_expression(like)?;
13285 }
13286 } else {
13287 if let Some(ref like) = s.like {
13291 self.write_space();
13292 self.write_keyword("LIKE");
13293 self.write_space();
13294 self.generate_expression(like)?;
13295 }
13296
13297 if let Some(ref scope_kind) = s.scope_kind {
13299 self.write_space();
13300 self.write_keyword("IN");
13301 self.write_space();
13302 self.write_keyword(scope_kind);
13303 if let Some(ref scope) = s.scope {
13304 self.write_space();
13305 self.generate_expression(scope)?;
13306 }
13307 } else if let Some(ref scope) = s.scope {
13308 self.write_space();
13309 self.write_keyword("IN");
13310 self.write_space();
13311 self.generate_expression(scope)?;
13312 }
13313 }
13314
13315 if let Some(ref starts_with) = s.starts_with {
13317 self.write_space();
13318 self.write_keyword("STARTS WITH");
13319 self.write_space();
13320 self.generate_expression(starts_with)?;
13321 }
13322
13323 if let Some(ref limit) = s.limit {
13325 self.write_space();
13326 self.generate_limit(limit)?;
13327 }
13328
13329 if is_snowflake {
13331 if let Some(ref from) = s.from {
13332 self.write_space();
13333 self.write_keyword("FROM");
13334 self.write_space();
13335 self.generate_expression(from)?;
13336 }
13337 }
13338
13339 if let Some(ref where_clause) = s.where_clause {
13341 self.write_space();
13342 self.write_keyword("WHERE");
13343 self.write_space();
13344 self.generate_expression(where_clause)?;
13345 }
13346
13347 if let Some(is_mutex) = s.mutex {
13349 self.write_space();
13350 if is_mutex {
13351 self.write_keyword("MUTEX");
13352 } else {
13353 self.write_keyword("STATUS");
13354 }
13355 }
13356
13357 if !s.privileges.is_empty() {
13359 self.write_space();
13360 self.write_keyword("WITH PRIVILEGES");
13361 self.write_space();
13362 for (i, priv_name) in s.privileges.iter().enumerate() {
13363 if i > 0 {
13364 self.write(", ");
13365 }
13366 self.write_keyword(priv_name);
13367 }
13368 }
13369
13370 Ok(())
13371 }
13372
13373 fn generate_literal(&mut self, lit: &Literal) -> Result<()> {
13376 use crate::dialects::DialectType;
13377 match lit {
13378 Literal::String(s) => {
13379 self.generate_string_literal(s)?;
13380 }
13381 Literal::Number(n) => {
13382 if matches!(self.config.dialect, Some(DialectType::MySQL))
13383 && n.len() > 2
13384 && (n.starts_with("0x") || n.starts_with("0X"))
13385 && !n[2..].chars().all(|c| c.is_ascii_hexdigit())
13386 {
13387 return self.generate_identifier(&Identifier {
13388 name: n.clone(),
13389 quoted: true,
13390 trailing_comments: Vec::new(),
13391 });
13392 }
13393 let n = if n.contains('_')
13397 && !matches!(
13398 self.config.dialect,
13399 Some(DialectType::ClickHouse)
13400 | Some(DialectType::DuckDB)
13401 | Some(DialectType::PostgreSQL)
13402 | Some(DialectType::Hive)
13403 | Some(DialectType::Spark)
13404 | Some(DialectType::Databricks)
13405 ) {
13406 std::borrow::Cow::Owned(n.replace('_', ""))
13407 } else {
13408 std::borrow::Cow::Borrowed(n.as_str())
13409 };
13410 if n.starts_with('.') {
13413 self.write("0");
13414 self.write(&n);
13415 } else if n.starts_with("-.") {
13416 self.write("-0");
13418 self.write(&n[1..]);
13419 } else {
13420 self.write(&n);
13421 }
13422 }
13423 Literal::HexString(h) => {
13424 match self.config.dialect {
13426 Some(DialectType::Spark)
13427 | Some(DialectType::Databricks)
13428 | Some(DialectType::Teradata) => self.write("X'"),
13429 _ => self.write("x'"),
13430 }
13431 self.write(h);
13432 self.write("'");
13433 }
13434 Literal::HexNumber(h) => {
13435 match self.config.dialect {
13439 Some(DialectType::BigQuery)
13440 | Some(DialectType::TSQL)
13441 | Some(DialectType::Fabric) => {
13442 self.write("0x");
13443 self.write(h);
13444 }
13445 _ => {
13446 if let Ok(val) = u64::from_str_radix(h, 16) {
13448 self.write(&val.to_string());
13449 } else {
13450 self.write("0x");
13452 self.write(h);
13453 }
13454 }
13455 }
13456 }
13457 Literal::BitString(b) => {
13458 self.write("B'");
13460 self.write(b);
13461 self.write("'");
13462 }
13463 Literal::ByteString(b) => {
13464 self.write("b'");
13466 self.write_escaped_byte_string(b);
13468 self.write("'");
13469 }
13470 Literal::NationalString(s) => {
13471 let keep_n_prefix = matches!(
13474 self.config.dialect,
13475 Some(DialectType::TSQL)
13476 | Some(DialectType::Oracle)
13477 | Some(DialectType::MySQL)
13478 | None
13479 );
13480 if keep_n_prefix {
13481 self.write("N'");
13482 } else {
13483 self.write("'");
13484 }
13485 self.write(s);
13486 self.write("'");
13487 }
13488 Literal::Date(d) => {
13489 self.generate_date_literal(d)?;
13490 }
13491 Literal::Time(t) => {
13492 self.generate_time_literal(t)?;
13493 }
13494 Literal::Timestamp(ts) => {
13495 self.generate_timestamp_literal(ts)?;
13496 }
13497 Literal::Datetime(dt) => {
13498 self.generate_datetime_literal(dt)?;
13499 }
13500 Literal::TripleQuotedString(s, _quote_char) => {
13501 if matches!(
13503 self.config.dialect,
13504 Some(crate::dialects::DialectType::BigQuery)
13505 | Some(crate::dialects::DialectType::DuckDB)
13506 | Some(crate::dialects::DialectType::Snowflake)
13507 | Some(crate::dialects::DialectType::Spark)
13508 | Some(crate::dialects::DialectType::Hive)
13509 | Some(crate::dialects::DialectType::Presto)
13510 | Some(crate::dialects::DialectType::Trino)
13511 | Some(crate::dialects::DialectType::PostgreSQL)
13512 | Some(crate::dialects::DialectType::MySQL)
13513 | Some(crate::dialects::DialectType::Redshift)
13514 | Some(crate::dialects::DialectType::TSQL)
13515 | Some(crate::dialects::DialectType::Oracle)
13516 | Some(crate::dialects::DialectType::ClickHouse)
13517 | Some(crate::dialects::DialectType::Databricks)
13518 | Some(crate::dialects::DialectType::SQLite)
13519 ) {
13520 self.generate_string_literal(s)?;
13521 } else {
13522 let quotes = format!("{0}{0}{0}", _quote_char);
13524 self.write("es);
13525 self.write(s);
13526 self.write("es);
13527 }
13528 }
13529 Literal::EscapeString(s) => {
13530 use crate::dialects::DialectType;
13534 let content = if let Some(c) = s.strip_prefix("e:") {
13535 c
13536 } else if let Some(c) = s.strip_prefix("E:") {
13537 c
13538 } else {
13539 s.as_str()
13540 };
13541
13542 if matches!(
13544 self.config.dialect,
13545 Some(DialectType::MySQL) | Some(DialectType::TiDB)
13546 ) {
13547 self.write(content);
13548 } else {
13549 let prefix = if matches!(
13551 self.config.dialect,
13552 Some(DialectType::SingleStore)
13553 | Some(DialectType::DuckDB)
13554 | Some(DialectType::PostgreSQL)
13555 | Some(DialectType::CockroachDB)
13556 | Some(DialectType::Materialize)
13557 | Some(DialectType::RisingWave)
13558 ) {
13559 "e'"
13560 } else {
13561 "E'"
13562 };
13563
13564 let normalized = content.replace("\\'", "''");
13566 self.write(prefix);
13567 self.write(&normalized);
13568 self.write("'");
13569 }
13570 }
13571 Literal::DollarString(s) => {
13572 use crate::dialects::DialectType;
13575 let (_tag, content) = crate::tokens::parse_dollar_string_token(s);
13577 let escape_backslash = matches!(self.config.dialect, Some(DialectType::Snowflake));
13579 let use_backslash_quote =
13583 matches!(self.config.dialect, Some(DialectType::Snowflake));
13584
13585 let mut escaped = String::with_capacity(content.len() + 4);
13586 for ch in content.chars() {
13587 if escape_backslash && ch == '\\' {
13588 escaped.push('\\');
13590 escaped.push('\\');
13591 } else if ch == '\'' {
13592 if use_backslash_quote {
13593 escaped.push('\\');
13594 escaped.push('\'');
13595 } else {
13596 escaped.push('\'');
13597 escaped.push('\'');
13598 }
13599 } else {
13600 escaped.push(ch);
13601 }
13602 }
13603 self.write("'");
13604 self.write(&escaped);
13605 self.write("'");
13606 }
13607 Literal::RawString(s) => {
13608 use crate::dialects::DialectType;
13614
13615 let escape_backslash = matches!(
13617 self.config.dialect,
13618 Some(DialectType::BigQuery)
13619 | Some(DialectType::MySQL)
13620 | Some(DialectType::SingleStore)
13621 | Some(DialectType::TiDB)
13622 | Some(DialectType::Hive)
13623 | Some(DialectType::Spark)
13624 | Some(DialectType::Databricks)
13625 | Some(DialectType::Drill)
13626 | Some(DialectType::Snowflake)
13627 | Some(DialectType::Redshift)
13628 | Some(DialectType::ClickHouse)
13629 );
13630
13631 let backslash_escapes_quote = matches!(
13634 self.config.dialect,
13635 Some(DialectType::BigQuery)
13636 | Some(DialectType::Hive)
13637 | Some(DialectType::Spark)
13638 | Some(DialectType::Databricks)
13639 | Some(DialectType::Drill)
13640 | Some(DialectType::Snowflake)
13641 | Some(DialectType::Redshift)
13642 );
13643
13644 let supports_escape_sequences = escape_backslash;
13647
13648 let mut escaped = String::with_capacity(s.len() + 4);
13649 for ch in s.chars() {
13650 if escape_backslash && ch == '\\' {
13651 escaped.push('\\');
13653 escaped.push('\\');
13654 } else if ch == '\'' {
13655 if backslash_escapes_quote {
13656 escaped.push('\\');
13658 escaped.push('\'');
13659 } else {
13660 escaped.push('\'');
13662 escaped.push('\'');
13663 }
13664 } else if supports_escape_sequences {
13665 match ch {
13668 '\n' => {
13669 escaped.push('\\');
13670 escaped.push('n');
13671 }
13672 '\r' => {
13673 escaped.push('\\');
13674 escaped.push('r');
13675 }
13676 '\t' => {
13677 escaped.push('\\');
13678 escaped.push('t');
13679 }
13680 '\x07' => {
13681 escaped.push('\\');
13682 escaped.push('a');
13683 }
13684 '\x08' => {
13685 escaped.push('\\');
13686 escaped.push('b');
13687 }
13688 '\x0C' => {
13689 escaped.push('\\');
13690 escaped.push('f');
13691 }
13692 '\x0B' => {
13693 escaped.push('\\');
13694 escaped.push('v');
13695 }
13696 _ => escaped.push(ch),
13697 }
13698 } else {
13699 escaped.push(ch);
13700 }
13701 }
13702 self.write("'");
13703 self.write(&escaped);
13704 self.write("'");
13705 }
13706 }
13707 Ok(())
13708 }
13709
13710 fn generate_date_literal(&mut self, d: &str) -> Result<()> {
13712 use crate::dialects::DialectType;
13713
13714 match self.config.dialect {
13715 Some(DialectType::TSQL) => {
13717 self.write("CAST('");
13718 self.write(d);
13719 self.write("' AS DATE)");
13720 }
13721 Some(DialectType::BigQuery) => {
13724 self.write("CAST('");
13725 self.write(d);
13726 self.write("' AS DATE)");
13727 }
13728 Some(DialectType::Exasol) => {
13731 self.write("CAST('");
13732 self.write(d);
13733 self.write("' AS DATE)");
13734 }
13735 Some(DialectType::Snowflake) => {
13738 self.write("CAST('");
13739 self.write(d);
13740 self.write("' AS DATE)");
13741 }
13742 Some(DialectType::PostgreSQL)
13744 | Some(DialectType::MySQL)
13745 | Some(DialectType::SingleStore)
13746 | Some(DialectType::TiDB)
13747 | Some(DialectType::Redshift) => {
13748 self.write("CAST('");
13749 self.write(d);
13750 self.write("' AS DATE)");
13751 }
13752 Some(DialectType::DuckDB)
13754 | Some(DialectType::Presto)
13755 | Some(DialectType::Trino)
13756 | Some(DialectType::Athena)
13757 | Some(DialectType::Spark)
13758 | Some(DialectType::Databricks)
13759 | Some(DialectType::Hive) => {
13760 self.write("CAST('");
13761 self.write(d);
13762 self.write("' AS DATE)");
13763 }
13764 Some(DialectType::Oracle) => {
13766 self.write("TO_DATE('");
13767 self.write(d);
13768 self.write("', 'YYYY-MM-DD')");
13769 }
13770 _ => {
13772 self.write_keyword("DATE");
13773 self.write(" '");
13774 self.write(d);
13775 self.write("'");
13776 }
13777 }
13778 Ok(())
13779 }
13780
13781 fn generate_time_literal(&mut self, t: &str) -> Result<()> {
13783 use crate::dialects::DialectType;
13784
13785 match self.config.dialect {
13786 Some(DialectType::TSQL) => {
13788 self.write("CAST('");
13789 self.write(t);
13790 self.write("' AS TIME)");
13791 }
13792 _ => {
13794 self.write_keyword("TIME");
13795 self.write(" '");
13796 self.write(t);
13797 self.write("'");
13798 }
13799 }
13800 Ok(())
13801 }
13802
13803 fn generate_dremio_date_expression(&mut self, expr: &Expression) -> Result<()> {
13805 use crate::expressions::Literal;
13806
13807 match expr {
13808 Expression::Literal(Literal::Date(d)) => {
13809 self.write("CAST('");
13811 self.write(d);
13812 self.write("' AS DATE)");
13813 }
13814 _ => {
13815 self.generate_expression(expr)?;
13817 }
13818 }
13819 Ok(())
13820 }
13821
13822 fn generate_timestamp_literal(&mut self, ts: &str) -> Result<()> {
13824 use crate::dialects::DialectType;
13825
13826 match self.config.dialect {
13827 Some(DialectType::TSQL) => {
13829 self.write("CAST('");
13830 self.write(ts);
13831 self.write("' AS DATETIME2)");
13832 }
13833 Some(DialectType::BigQuery) => {
13836 self.write("CAST('");
13837 self.write(ts);
13838 self.write("' AS TIMESTAMP)");
13839 }
13840 Some(DialectType::Snowflake) => {
13843 self.write("CAST('");
13844 self.write(ts);
13845 self.write("' AS TIMESTAMP)");
13846 }
13847 Some(DialectType::Dremio) => {
13850 self.write("CAST('");
13851 self.write(ts);
13852 self.write("' AS TIMESTAMP)");
13853 }
13854 Some(DialectType::Exasol) => {
13857 self.write("CAST('");
13858 self.write(ts);
13859 self.write("' AS TIMESTAMP)");
13860 }
13861 Some(DialectType::Oracle) => {
13864 self.write("TO_TIMESTAMP('");
13865 self.write(ts);
13866 self.write("', 'YYYY-MM-DD HH24:MI:SS.FF6')");
13867 }
13868 Some(DialectType::Presto) | Some(DialectType::Trino) => {
13870 if Self::timestamp_has_timezone(ts) {
13871 self.write("CAST('");
13872 self.write(ts);
13873 self.write("' AS TIMESTAMP WITH TIME ZONE)");
13874 } else {
13875 self.write("CAST('");
13876 self.write(ts);
13877 self.write("' AS TIMESTAMP)");
13878 }
13879 }
13880 Some(DialectType::ClickHouse) => {
13882 self.write("CAST('");
13883 self.write(ts);
13884 self.write("' AS Nullable(DateTime))");
13885 }
13886 Some(DialectType::Spark) => {
13888 self.write("CAST('");
13889 self.write(ts);
13890 self.write("' AS TIMESTAMP)");
13891 }
13892 Some(DialectType::Redshift) => {
13895 if ts == "epoch" {
13896 self.write_keyword("TIMESTAMP");
13897 self.write(" '");
13898 self.write(ts);
13899 self.write("'");
13900 } else {
13901 self.write("CAST('");
13902 self.write(ts);
13903 self.write("' AS TIMESTAMP)");
13904 }
13905 }
13906 Some(DialectType::PostgreSQL)
13908 | Some(DialectType::Hive)
13909 | Some(DialectType::SQLite)
13910 | Some(DialectType::DuckDB)
13911 | Some(DialectType::Athena)
13912 | Some(DialectType::Drill)
13913 | Some(DialectType::Teradata) => {
13914 self.write("CAST('");
13915 self.write(ts);
13916 self.write("' AS TIMESTAMP)");
13917 }
13918 Some(DialectType::MySQL) | Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
13920 self.write("CAST('");
13921 self.write(ts);
13922 self.write("' AS DATETIME)");
13923 }
13924 Some(DialectType::Databricks) => {
13926 self.write("CAST('");
13927 self.write(ts);
13928 self.write("' AS TIMESTAMP_NTZ)");
13929 }
13930 _ => {
13932 self.write_keyword("TIMESTAMP");
13933 self.write(" '");
13934 self.write(ts);
13935 self.write("'");
13936 }
13937 }
13938 Ok(())
13939 }
13940
13941 fn timestamp_has_timezone(ts: &str) -> bool {
13944 let ts_lower = ts.to_lowercase();
13948
13949 let continent_prefixes = [
13951 "africa/",
13952 "america/",
13953 "antarctica/",
13954 "arctic/",
13955 "asia/",
13956 "atlantic/",
13957 "australia/",
13958 "europe/",
13959 "indian/",
13960 "pacific/",
13961 "etc/",
13962 "brazil/",
13963 "canada/",
13964 "chile/",
13965 "mexico/",
13966 "us/",
13967 ];
13968
13969 for prefix in &continent_prefixes {
13970 if ts_lower.contains(prefix) {
13971 return true;
13972 }
13973 }
13974
13975 let tz_abbrevs = [
13978 " utc", " gmt", " cet", " cest", " eet", " eest", " wet", " west", " est", " edt",
13979 " cst", " cdt", " mst", " mdt", " pst", " pdt", " ist", " bst", " jst", " kst", " hkt",
13980 " sgt", " aest", " aedt", " acst", " acdt", " awst",
13981 ];
13982
13983 for abbrev in &tz_abbrevs {
13984 if ts_lower.ends_with(abbrev) {
13985 return true;
13986 }
13987 }
13988
13989 let trimmed = ts.trim();
13993 if let Some(last_space) = trimmed.rfind(' ') {
13994 let suffix = &trimmed[last_space + 1..];
13995 if (suffix.starts_with('+') || suffix.starts_with('-')) && suffix.len() > 1 {
13996 let rest = &suffix[1..];
13998 if rest.chars().all(|c| c.is_ascii_digit() || c == ':') {
13999 return true;
14000 }
14001 }
14002 }
14003
14004 false
14005 }
14006
14007 fn generate_datetime_literal(&mut self, dt: &str) -> Result<()> {
14009 use crate::dialects::DialectType;
14010
14011 match self.config.dialect {
14012 Some(DialectType::BigQuery) => {
14015 self.write("CAST('");
14016 self.write(dt);
14017 self.write("' AS DATETIME)");
14018 }
14019 Some(DialectType::DuckDB) => {
14021 self.write("CAST('");
14022 self.write(dt);
14023 self.write("' AS TIMESTAMP)");
14024 }
14025 _ => {
14028 self.write_keyword("DATETIME");
14029 self.write(" '");
14030 self.write(dt);
14031 self.write("'");
14032 }
14033 }
14034 Ok(())
14035 }
14036
14037 fn generate_string_literal(&mut self, s: &str) -> Result<()> {
14039 use crate::dialects::DialectType;
14040
14041 match self.config.dialect {
14042 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
14046 self.write("'");
14048 for c in s.chars() {
14049 match c {
14050 '\'' => self.write("\\'"),
14051 '\\' => self.write("\\\\"),
14052 '\n' => self.write("\\n"),
14053 '\r' => self.write("\\r"),
14054 '\t' => self.write("\\t"),
14055 '\0' => self.write("\\0"),
14056 _ => self.output.push(c),
14057 }
14058 }
14059 self.write("'");
14060 }
14061 Some(DialectType::Drill) => {
14062 self.write("'");
14065 for c in s.chars() {
14066 match c {
14067 '\'' => self.write("''"),
14068 '\\' => self.write("\\\\"),
14069 '\n' => self.write("\\n"),
14070 '\r' => self.write("\\r"),
14071 '\t' => self.write("\\t"),
14072 '\0' => self.write("\\0"),
14073 _ => self.output.push(c),
14074 }
14075 }
14076 self.write("'");
14077 }
14078 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB) => {
14079 self.write("'");
14080 for c in s.chars() {
14081 match c {
14082 '\'' => self.write("''"),
14084 '\\' => self.write("\\\\"),
14085 '\n' => self.write("\\n"),
14086 '\r' => self.write("\\r"),
14087 '\t' => self.write("\\t"),
14088 '\0' => self.output.push('\0'),
14090 _ => self.output.push(c),
14091 }
14092 }
14093 self.write("'");
14094 }
14095 Some(DialectType::BigQuery) => {
14097 self.write("'");
14098 for c in s.chars() {
14099 match c {
14100 '\'' => self.write("\\'"),
14101 '\\' => self.write("\\\\"),
14102 '\n' => self.write("\\n"),
14103 '\r' => self.write("\\r"),
14104 '\t' => self.write("\\t"),
14105 '\0' => self.write("\\0"),
14106 '\x07' => self.write("\\a"),
14107 '\x08' => self.write("\\b"),
14108 '\x0C' => self.write("\\f"),
14109 '\x0B' => self.write("\\v"),
14110 _ => self.output.push(c),
14111 }
14112 }
14113 self.write("'");
14114 }
14115 Some(DialectType::Athena) => {
14119 if self.athena_hive_context {
14120 self.write("'");
14122 for c in s.chars() {
14123 match c {
14124 '\'' => self.write("\\'"),
14125 '\\' => self.write("\\\\"),
14126 '\n' => self.write("\\n"),
14127 '\r' => self.write("\\r"),
14128 '\t' => self.write("\\t"),
14129 '\0' => self.write("\\0"),
14130 _ => self.output.push(c),
14131 }
14132 }
14133 self.write("'");
14134 } else {
14135 self.write("'");
14137 for c in s.chars() {
14138 match c {
14139 '\'' => self.write("''"),
14140 _ => self.output.push(c),
14142 }
14143 }
14144 self.write("'");
14145 }
14146 }
14147 Some(DialectType::Snowflake) => {
14152 self.write("'");
14153 for c in s.chars() {
14154 match c {
14155 '\'' => self.write("\\'"),
14156 '\n' => self.write("\\n"),
14159 '\r' => self.write("\\r"),
14160 '\t' => self.write("\\t"),
14161 _ => self.output.push(c),
14162 }
14163 }
14164 self.write("'");
14165 }
14166 Some(DialectType::PostgreSQL) => {
14168 self.write("'");
14169 for c in s.chars() {
14170 match c {
14171 '\'' => self.write("''"),
14172 _ => self.output.push(c),
14173 }
14174 }
14175 self.write("'");
14176 }
14177 Some(DialectType::Redshift) => {
14179 self.write("'");
14180 for c in s.chars() {
14181 match c {
14182 '\'' => self.write("\\'"),
14183 _ => self.output.push(c),
14184 }
14185 }
14186 self.write("'");
14187 }
14188 Some(DialectType::Oracle) => {
14190 self.write("'");
14191 self.write(&s.replace('\'', "''"));
14192 self.write("'");
14193 }
14194 Some(DialectType::ClickHouse) => {
14197 self.write("'");
14198 for c in s.chars() {
14199 match c {
14200 '\'' => self.write("''"),
14201 '\\' => self.write("\\\\"),
14202 '\n' => self.write("\\n"),
14203 '\r' => self.write("\\r"),
14204 '\t' => self.write("\\t"),
14205 '\0' => self.write("\\0"),
14206 '\x07' => self.write("\\a"),
14207 '\x08' => self.write("\\b"),
14208 '\x0C' => self.write("\\f"),
14209 '\x0B' => self.write("\\v"),
14210 c if c.is_control() || (c as u32) < 0x20 => {
14212 let byte = c as u32;
14213 if byte < 256 {
14214 self.write(&format!("\\x{:02X}", byte));
14215 } else {
14216 self.output.push(c);
14217 }
14218 }
14219 _ => self.output.push(c),
14220 }
14221 }
14222 self.write("'");
14223 }
14224 _ => {
14227 self.write("'");
14228 self.write(&s.replace('\'', "''"));
14229 self.write("'");
14230 }
14231 }
14232 Ok(())
14233 }
14234
14235 fn write_escaped_byte_string(&mut self, s: &str) {
14238 for c in s.chars() {
14239 match c {
14240 '\'' => self.write("\\'"),
14242 '\\' => self.write("\\\\"),
14244 _ if !c.is_control() => self.output.push(c),
14246 _ => {
14248 let byte = c as u32;
14249 if byte < 256 {
14250 self.write(&format!("\\x{:02x}", byte));
14251 } else {
14252 for b in c.to_string().as_bytes() {
14254 self.write(&format!("\\x{:02x}", b));
14255 }
14256 }
14257 }
14258 }
14259 }
14260 }
14261
14262 fn generate_boolean(&mut self, b: &BooleanLiteral) -> Result<()> {
14263 use crate::dialects::DialectType;
14264
14265 match self.config.dialect {
14267 Some(DialectType::TSQL) => {
14270 self.write(if b.value { "1" } else { "0" });
14271 }
14272 Some(DialectType::Oracle) => {
14274 self.write(if b.value { "1" } else { "0" });
14275 }
14276 Some(DialectType::MySQL) => {
14278 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
14279 }
14280 _ => {
14282 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
14283 }
14284 }
14285 Ok(())
14286 }
14287
14288 fn generate_alias_identifier(&mut self, id: &Identifier) -> Result<()> {
14291 let name = &id.name;
14292 let quote_style = &self.config.identifier_quote_style;
14293
14294 let needs_quoting = id.quoted || self.is_reserved_keyword(name);
14298
14299 let output_name = if self.config.normalize_identifiers && !id.quoted {
14301 name.to_lowercase()
14302 } else {
14303 name.to_string()
14304 };
14305
14306 if needs_quoting {
14307 let escaped_name = if quote_style.start == quote_style.end {
14309 output_name.replace(
14310 quote_style.end,
14311 &format!("{}{}", quote_style.end, quote_style.end),
14312 )
14313 } else {
14314 output_name.replace(
14315 quote_style.end,
14316 &format!("{}{}", quote_style.end, quote_style.end),
14317 )
14318 };
14319 self.write(&format!(
14320 "{}{}{}",
14321 quote_style.start, escaped_name, quote_style.end
14322 ));
14323 } else {
14324 self.write(&output_name);
14325 }
14326
14327 for comment in &id.trailing_comments {
14329 self.write(" ");
14330 self.write_formatted_comment(comment);
14331 }
14332 Ok(())
14333 }
14334
14335 fn generate_identifier(&mut self, id: &Identifier) -> Result<()> {
14336 use crate::dialects::DialectType;
14337
14338 let name = &id.name;
14339
14340 let quote_style = if matches!(self.config.dialect, Some(DialectType::Athena))
14342 && self.athena_hive_context
14343 {
14344 &IdentifierQuoteStyle::BACKTICK
14345 } else {
14346 &self.config.identifier_quote_style
14347 };
14348
14349 let starts_with_digit = name.chars().next().map_or(false, |c| c.is_ascii_digit());
14356 let needs_digit_quoting = starts_with_digit
14357 && !self.config.identifiers_can_start_with_digit
14358 && self.config.dialect.is_some();
14359 let mysql_invalid_hex_identifier = matches!(self.config.dialect, Some(DialectType::MySQL))
14360 && name.len() > 2
14361 && (name.starts_with("0x") || name.starts_with("0X"))
14362 && !name[2..].chars().all(|c| c.is_ascii_hexdigit());
14363 let needs_quoting = id.quoted
14364 || self.is_reserved_keyword(name)
14365 || self.config.always_quote_identifiers
14366 || needs_digit_quoting
14367 || mysql_invalid_hex_identifier;
14368
14369 let (base_name, suffix) = if needs_quoting {
14372 if let Some(paren_pos) = name.find('(') {
14374 let base = &name[..paren_pos];
14375 let rest = &name[paren_pos..];
14376 if rest.starts_with('(')
14378 && (rest.ends_with(')') || rest.ends_with(") ASC") || rest.ends_with(") DESC"))
14379 {
14380 let close_paren = rest.find(')').unwrap_or(rest.len());
14382 let inside = &rest[1..close_paren];
14383 if inside.chars().all(|c| c.is_ascii_digit()) {
14384 (base.to_string(), rest.to_string())
14385 } else {
14386 (name.to_string(), String::new())
14387 }
14388 } else {
14389 (name.to_string(), String::new())
14390 }
14391 } else if name.ends_with(" ASC") {
14392 let base = &name[..name.len() - 4];
14393 (base.to_string(), " ASC".to_string())
14394 } else if name.ends_with(" DESC") {
14395 let base = &name[..name.len() - 5];
14396 (base.to_string(), " DESC".to_string())
14397 } else {
14398 (name.to_string(), String::new())
14399 }
14400 } else {
14401 (name.to_string(), String::new())
14402 };
14403
14404 let output_name = if self.config.normalize_identifiers && !id.quoted {
14408 base_name.to_lowercase()
14409 } else if matches!(self.config.dialect, Some(DialectType::Exasol))
14410 && !id.quoted
14411 && self.is_reserved_keyword(name)
14412 {
14413 base_name.to_uppercase()
14416 } else {
14417 base_name
14418 };
14419
14420 if needs_quoting {
14421 let escaped_name = if quote_style.start == quote_style.end {
14423 output_name.replace(
14425 quote_style.end,
14426 &format!("{}{}", quote_style.end, quote_style.end),
14427 )
14428 } else {
14429 output_name.replace(
14431 quote_style.end,
14432 &format!("{}{}", quote_style.end, quote_style.end),
14433 )
14434 };
14435 self.write(&format!(
14436 "{}{}{}{}",
14437 quote_style.start, escaped_name, quote_style.end, suffix
14438 ));
14439 } else {
14440 self.write(&output_name);
14441 }
14442
14443 for comment in &id.trailing_comments {
14445 self.write(" ");
14446 self.write_formatted_comment(comment);
14447 }
14448 Ok(())
14449 }
14450
14451 fn generate_column(&mut self, col: &Column) -> Result<()> {
14452 use crate::dialects::DialectType;
14453
14454 if let Some(table) = &col.table {
14455 let is_exasol_local_prefix = matches!(self.config.dialect, Some(DialectType::Exasol))
14459 && !table.quoted
14460 && table.name.eq_ignore_ascii_case("LOCAL");
14461
14462 if is_exasol_local_prefix {
14463 self.write("LOCAL");
14465 } else {
14466 self.generate_identifier(table)?;
14467 }
14468 self.write(".");
14469 }
14470 self.generate_identifier(&col.name)?;
14471 if col.join_mark && self.config.supports_column_join_marks {
14474 self.write(" (+)");
14475 }
14476 for comment in &col.trailing_comments {
14478 self.write_space();
14479 self.write_formatted_comment(comment);
14480 }
14481 Ok(())
14482 }
14483
14484 fn generate_pseudocolumn(&mut self, pc: &Pseudocolumn) -> Result<()> {
14487 use crate::dialects::DialectType;
14488 use crate::expressions::PseudocolumnType;
14489
14490 if pc.kind == PseudocolumnType::Sysdate
14492 && !matches!(
14493 self.config.dialect,
14494 Some(DialectType::Oracle) | Some(DialectType::Redshift) | None
14495 )
14496 {
14497 self.write_keyword("CURRENT_TIMESTAMP");
14498 if matches!(
14500 self.config.dialect,
14501 Some(DialectType::MySQL)
14502 | Some(DialectType::ClickHouse)
14503 | Some(DialectType::Spark)
14504 | Some(DialectType::Databricks)
14505 | Some(DialectType::Hive)
14506 ) {
14507 self.write("()");
14508 }
14509 } else {
14510 self.write(pc.kind.as_str());
14511 }
14512 Ok(())
14513 }
14514
14515 fn generate_connect(&mut self, connect: &Connect) -> Result<()> {
14517 use crate::dialects::DialectType;
14518
14519 let supports_connect_by = matches!(
14522 self.config.dialect,
14523 Some(DialectType::Oracle) | Some(DialectType::Snowflake)
14524 );
14525
14526 if !supports_connect_by && self.config.dialect.is_some() {
14527 if self.config.pretty {
14529 self.write_newline();
14530 } else {
14531 self.write_space();
14532 }
14533 self.write("/* CONNECT BY requires manual conversion to recursive CTE */");
14534 }
14535
14536 if let Some(start) = &connect.start {
14538 if self.config.pretty {
14539 self.write_newline();
14540 } else {
14541 self.write_space();
14542 }
14543 self.write_keyword("START WITH");
14544 self.write_space();
14545 self.generate_expression(start)?;
14546 }
14547
14548 if self.config.pretty {
14550 self.write_newline();
14551 } else {
14552 self.write_space();
14553 }
14554 self.write_keyword("CONNECT BY");
14555 if connect.nocycle {
14556 self.write_space();
14557 self.write_keyword("NOCYCLE");
14558 }
14559 self.write_space();
14560 self.generate_expression(&connect.connect)?;
14561
14562 Ok(())
14563 }
14564
14565 fn generate_connect_expr(&mut self, connect: &Connect) -> Result<()> {
14567 self.generate_connect(connect)
14568 }
14569
14570 fn generate_prior(&mut self, prior: &Prior) -> Result<()> {
14572 self.write_keyword("PRIOR");
14573 self.write_space();
14574 self.generate_expression(&prior.this)?;
14575 Ok(())
14576 }
14577
14578 fn generate_connect_by_root(&mut self, cbr: &ConnectByRoot) -> Result<()> {
14581 self.write_keyword("CONNECT_BY_ROOT");
14582 self.write_space();
14583 self.generate_expression(&cbr.this)?;
14584 Ok(())
14585 }
14586
14587 fn generate_match_recognize(&mut self, mr: &MatchRecognize) -> Result<()> {
14589 use crate::dialects::DialectType;
14590
14591 let supports_match_recognize = matches!(
14593 self.config.dialect,
14594 Some(DialectType::Oracle)
14595 | Some(DialectType::Snowflake)
14596 | Some(DialectType::Presto)
14597 | Some(DialectType::Trino)
14598 );
14599
14600 if let Some(source) = &mr.this {
14602 self.generate_expression(source)?;
14603 }
14604
14605 if !supports_match_recognize {
14606 self.write("/* MATCH_RECOGNIZE not supported in this dialect */");
14607 return Ok(());
14608 }
14609
14610 if self.config.pretty {
14612 self.write_newline();
14613 } else {
14614 self.write_space();
14615 }
14616
14617 self.write_keyword("MATCH_RECOGNIZE");
14618 self.write(" (");
14619
14620 if self.config.pretty {
14621 self.indent_level += 1;
14622 }
14623
14624 let mut needs_separator = false;
14625
14626 if let Some(partition_by) = &mr.partition_by {
14628 if !partition_by.is_empty() {
14629 if self.config.pretty {
14630 self.write_newline();
14631 self.write_indent();
14632 }
14633 self.write_keyword("PARTITION BY");
14634 self.write_space();
14635 for (i, expr) in partition_by.iter().enumerate() {
14636 if i > 0 {
14637 self.write(", ");
14638 }
14639 self.generate_expression(expr)?;
14640 }
14641 needs_separator = true;
14642 }
14643 }
14644
14645 if let Some(order_by) = &mr.order_by {
14647 if !order_by.is_empty() {
14648 if needs_separator {
14649 if self.config.pretty {
14650 self.write_newline();
14651 self.write_indent();
14652 } else {
14653 self.write_space();
14654 }
14655 } else if self.config.pretty {
14656 self.write_newline();
14657 self.write_indent();
14658 }
14659 self.write_keyword("ORDER BY");
14660 if self.config.pretty {
14662 self.indent_level += 1;
14663 for (i, ordered) in order_by.iter().enumerate() {
14664 if i > 0 {
14665 self.write(",");
14666 }
14667 self.write_newline();
14668 self.write_indent();
14669 self.generate_ordered(ordered)?;
14670 }
14671 self.indent_level -= 1;
14672 } else {
14673 self.write_space();
14674 for (i, ordered) in order_by.iter().enumerate() {
14675 if i > 0 {
14676 self.write(", ");
14677 }
14678 self.generate_ordered(ordered)?;
14679 }
14680 }
14681 needs_separator = true;
14682 }
14683 }
14684
14685 if let Some(measures) = &mr.measures {
14687 if !measures.is_empty() {
14688 if needs_separator {
14689 if self.config.pretty {
14690 self.write_newline();
14691 self.write_indent();
14692 } else {
14693 self.write_space();
14694 }
14695 } else if self.config.pretty {
14696 self.write_newline();
14697 self.write_indent();
14698 }
14699 self.write_keyword("MEASURES");
14700 if self.config.pretty {
14702 self.indent_level += 1;
14703 for (i, measure) in measures.iter().enumerate() {
14704 if i > 0 {
14705 self.write(",");
14706 }
14707 self.write_newline();
14708 self.write_indent();
14709 if let Some(semantics) = &measure.window_frame {
14711 match semantics {
14712 MatchRecognizeSemantics::Running => {
14713 self.write_keyword("RUNNING");
14714 self.write_space();
14715 }
14716 MatchRecognizeSemantics::Final => {
14717 self.write_keyword("FINAL");
14718 self.write_space();
14719 }
14720 }
14721 }
14722 self.generate_expression(&measure.this)?;
14723 }
14724 self.indent_level -= 1;
14725 } else {
14726 self.write_space();
14727 for (i, measure) in measures.iter().enumerate() {
14728 if i > 0 {
14729 self.write(", ");
14730 }
14731 if let Some(semantics) = &measure.window_frame {
14733 match semantics {
14734 MatchRecognizeSemantics::Running => {
14735 self.write_keyword("RUNNING");
14736 self.write_space();
14737 }
14738 MatchRecognizeSemantics::Final => {
14739 self.write_keyword("FINAL");
14740 self.write_space();
14741 }
14742 }
14743 }
14744 self.generate_expression(&measure.this)?;
14745 }
14746 }
14747 needs_separator = true;
14748 }
14749 }
14750
14751 if let Some(rows) = &mr.rows {
14753 if needs_separator {
14754 if self.config.pretty {
14755 self.write_newline();
14756 self.write_indent();
14757 } else {
14758 self.write_space();
14759 }
14760 } else if self.config.pretty {
14761 self.write_newline();
14762 self.write_indent();
14763 }
14764 match rows {
14765 MatchRecognizeRows::OneRowPerMatch => {
14766 self.write_keyword("ONE ROW PER MATCH");
14767 }
14768 MatchRecognizeRows::AllRowsPerMatch => {
14769 self.write_keyword("ALL ROWS PER MATCH");
14770 }
14771 MatchRecognizeRows::AllRowsPerMatchShowEmptyMatches => {
14772 self.write_keyword("ALL ROWS PER MATCH SHOW EMPTY MATCHES");
14773 }
14774 MatchRecognizeRows::AllRowsPerMatchOmitEmptyMatches => {
14775 self.write_keyword("ALL ROWS PER MATCH OMIT EMPTY MATCHES");
14776 }
14777 MatchRecognizeRows::AllRowsPerMatchWithUnmatchedRows => {
14778 self.write_keyword("ALL ROWS PER MATCH WITH UNMATCHED ROWS");
14779 }
14780 }
14781 needs_separator = true;
14782 }
14783
14784 if let Some(after) = &mr.after {
14786 if needs_separator {
14787 if self.config.pretty {
14788 self.write_newline();
14789 self.write_indent();
14790 } else {
14791 self.write_space();
14792 }
14793 } else if self.config.pretty {
14794 self.write_newline();
14795 self.write_indent();
14796 }
14797 match after {
14798 MatchRecognizeAfter::PastLastRow => {
14799 self.write_keyword("AFTER MATCH SKIP PAST LAST ROW");
14800 }
14801 MatchRecognizeAfter::ToNextRow => {
14802 self.write_keyword("AFTER MATCH SKIP TO NEXT ROW");
14803 }
14804 MatchRecognizeAfter::ToFirst(ident) => {
14805 self.write_keyword("AFTER MATCH SKIP TO FIRST");
14806 self.write_space();
14807 self.generate_identifier(ident)?;
14808 }
14809 MatchRecognizeAfter::ToLast(ident) => {
14810 self.write_keyword("AFTER MATCH SKIP TO LAST");
14811 self.write_space();
14812 self.generate_identifier(ident)?;
14813 }
14814 }
14815 needs_separator = true;
14816 }
14817
14818 if let Some(pattern) = &mr.pattern {
14820 if needs_separator {
14821 if self.config.pretty {
14822 self.write_newline();
14823 self.write_indent();
14824 } else {
14825 self.write_space();
14826 }
14827 } else if self.config.pretty {
14828 self.write_newline();
14829 self.write_indent();
14830 }
14831 self.write_keyword("PATTERN");
14832 self.write_space();
14833 self.write("(");
14834 self.write(pattern);
14835 self.write(")");
14836 needs_separator = true;
14837 }
14838
14839 if let Some(define) = &mr.define {
14841 if !define.is_empty() {
14842 if needs_separator {
14843 if self.config.pretty {
14844 self.write_newline();
14845 self.write_indent();
14846 } else {
14847 self.write_space();
14848 }
14849 } else if self.config.pretty {
14850 self.write_newline();
14851 self.write_indent();
14852 }
14853 self.write_keyword("DEFINE");
14854 if self.config.pretty {
14856 self.indent_level += 1;
14857 for (i, (name, expr)) in define.iter().enumerate() {
14858 if i > 0 {
14859 self.write(",");
14860 }
14861 self.write_newline();
14862 self.write_indent();
14863 self.generate_identifier(name)?;
14864 self.write(" AS ");
14865 self.generate_expression(expr)?;
14866 }
14867 self.indent_level -= 1;
14868 } else {
14869 self.write_space();
14870 for (i, (name, expr)) in define.iter().enumerate() {
14871 if i > 0 {
14872 self.write(", ");
14873 }
14874 self.generate_identifier(name)?;
14875 self.write(" AS ");
14876 self.generate_expression(expr)?;
14877 }
14878 }
14879 }
14880 }
14881
14882 if self.config.pretty {
14883 self.indent_level -= 1;
14884 self.write_newline();
14885 }
14886 self.write(")");
14887
14888 if let Some(alias) = &mr.alias {
14890 self.write(" ");
14891 if mr.alias_explicit_as {
14892 self.write_keyword("AS");
14893 self.write(" ");
14894 }
14895 self.generate_identifier(alias)?;
14896 }
14897
14898 Ok(())
14899 }
14900
14901 fn generate_hint(&mut self, hint: &Hint) -> Result<()> {
14903 use crate::dialects::DialectType;
14904
14905 let supports_hints = matches!(
14907 self.config.dialect,
14908 None | Some(DialectType::Oracle) | Some(DialectType::MySQL) |
14910 Some(DialectType::Spark) | Some(DialectType::Hive) |
14911 Some(DialectType::Databricks) | Some(DialectType::PostgreSQL)
14912 );
14913
14914 if !supports_hints || hint.expressions.is_empty() {
14915 return Ok(());
14916 }
14917
14918 let mut hint_strings: Vec<String> = Vec::new();
14921 for expr in &hint.expressions {
14922 match expr {
14923 HintExpression::Raw(text) => {
14924 let parsed = self.parse_raw_hint_text(text);
14926 hint_strings.extend(parsed);
14927 }
14928 _ => {
14929 hint_strings.push(self.hint_expression_to_string(expr)?);
14930 }
14931 }
14932 }
14933
14934 let use_multiline = self.config.pretty && hint_strings.len() > 1;
14938
14939 if use_multiline {
14940 self.write(" /*+ ");
14942 for (i, hint_str) in hint_strings.iter().enumerate() {
14943 if i > 0 {
14944 self.write_newline();
14945 self.write(" "); }
14947 self.write(hint_str);
14948 }
14949 self.write(" */");
14950 } else {
14951 self.write(" /*+ ");
14953 let sep = match self.config.dialect {
14954 Some(DialectType::Spark) | Some(DialectType::Databricks) => ", ",
14955 _ => " ",
14956 };
14957 for (i, hint_str) in hint_strings.iter().enumerate() {
14958 if i > 0 {
14959 self.write(sep);
14960 }
14961 self.write(hint_str);
14962 }
14963 self.write(" */");
14964 }
14965
14966 Ok(())
14967 }
14968
14969 fn parse_raw_hint_text(&self, text: &str) -> Vec<String> {
14973 let mut results = Vec::new();
14974 let mut chars = text.chars().peekable();
14975 let mut current = String::new();
14976 let mut paren_depth = 0;
14977 let mut has_unparseable_content = false;
14978 let mut position_after_last_function = 0;
14979 let mut char_position = 0;
14980
14981 while let Some(c) = chars.next() {
14982 char_position += c.len_utf8();
14983 match c {
14984 '(' => {
14985 paren_depth += 1;
14986 current.push(c);
14987 }
14988 ')' => {
14989 paren_depth -= 1;
14990 current.push(c);
14991 if paren_depth == 0 {
14993 let trimmed = current.trim().to_string();
14994 if !trimmed.is_empty() {
14995 let formatted = self.format_hint_function(&trimmed);
14997 results.push(formatted);
14998 }
14999 current.clear();
15000 position_after_last_function = char_position;
15001 }
15002 }
15003 ' ' | '\t' | '\n' | ',' if paren_depth == 0 => {
15004 }
15006 _ if paren_depth == 0 => {
15007 current.push(c);
15009 }
15010 _ => {
15011 current.push(c);
15012 }
15013 }
15014 }
15015
15016 let remaining_text = text[position_after_last_function..].trim();
15018 if !remaining_text.is_empty() {
15019 let words: Vec<&str> = remaining_text.split_whitespace().collect();
15023 let looks_like_hint_functions = words.iter().all(|word| {
15024 word.contains('(') || (word.chars().all(|c| c.is_ascii_uppercase() || c == '_'))
15026 });
15027
15028 if !looks_like_hint_functions && words.len() > 1 {
15029 has_unparseable_content = true;
15030 }
15031 }
15032
15033 if has_unparseable_content {
15035 return vec![text.trim().to_string()];
15036 }
15037
15038 if results.is_empty() {
15040 results.push(text.trim().to_string());
15041 }
15042
15043 results
15044 }
15045
15046 fn format_hint_function(&self, hint: &str) -> String {
15049 if !self.config.pretty {
15050 return hint.to_string();
15051 }
15052
15053 if let Some(paren_pos) = hint.find('(') {
15055 if hint.ends_with(')') {
15056 let name = &hint[..paren_pos];
15057 let args_str = &hint[paren_pos + 1..hint.len() - 1];
15058
15059 let args: Vec<&str> = args_str.split_whitespace().collect();
15061
15062 let total_args_width: usize =
15064 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() {
15068 let mut result = format!("{}(\n", name);
15069 for arg in &args {
15070 result.push_str(" "); result.push_str(arg);
15072 result.push('\n');
15073 }
15074 result.push_str(" )"); return result;
15076 }
15077 }
15078 }
15079
15080 hint.to_string()
15081 }
15082
15083 fn hint_expression_to_string(&mut self, expr: &HintExpression) -> Result<String> {
15085 match expr {
15086 HintExpression::Function { name, args } => {
15087 let arg_strings: Vec<String> = args
15089 .iter()
15090 .map(|arg| {
15091 let mut gen = Generator::with_config(self.config.clone());
15092 gen.generate_expression(arg)?;
15093 Ok(gen.output)
15094 })
15095 .collect::<Result<Vec<_>>>()?;
15096
15097 let total_args_width: usize = arg_strings.iter().map(|s| s.len()).sum::<usize>()
15099 + arg_strings.len().saturating_sub(1); let args_multiline =
15104 self.config.pretty && total_args_width > self.config.max_text_width;
15105
15106 if args_multiline && !arg_strings.is_empty() {
15107 let mut result = format!("{}(\n", name);
15109 for arg_str in &arg_strings {
15110 result.push_str(" "); result.push_str(arg_str);
15112 result.push('\n');
15113 }
15114 result.push_str(" )"); Ok(result)
15116 } else {
15117 let args_str = arg_strings.join(" ");
15119 Ok(format!("{}({})", name, args_str))
15120 }
15121 }
15122 HintExpression::Identifier(name) => Ok(name.clone()),
15123 HintExpression::Raw(text) => {
15124 if self.config.pretty {
15126 Ok(self.format_hint_function(text))
15127 } else {
15128 Ok(text.clone())
15129 }
15130 }
15131 }
15132 }
15133
15134 fn generate_table(&mut self, table: &TableRef) -> Result<()> {
15135 if table.only {
15137 self.write_keyword("ONLY");
15138 self.write_space();
15139 }
15140
15141 if let Some(ref identifier_func) = table.identifier_func {
15143 self.generate_expression(identifier_func)?;
15144 } else {
15145 if let Some(catalog) = &table.catalog {
15146 self.generate_identifier(catalog)?;
15147 self.write(".");
15148 }
15149 if let Some(schema) = &table.schema {
15150 self.generate_identifier(schema)?;
15151 self.write(".");
15152 }
15153 self.generate_identifier(&table.name)?;
15154 }
15155
15156 if let Some(changes) = &table.changes {
15158 self.write(" ");
15159 self.generate_changes(changes)?;
15160 }
15161
15162 if !table.partitions.is_empty() {
15164 self.write_space();
15165 self.write_keyword("PARTITION");
15166 self.write("(");
15167 for (i, partition) in table.partitions.iter().enumerate() {
15168 if i > 0 {
15169 self.write(", ");
15170 }
15171 self.generate_identifier(partition)?;
15172 }
15173 self.write(")");
15174 }
15175
15176 if table.changes.is_none() {
15179 if let Some(when) = &table.when {
15180 self.write_space();
15181 self.generate_historical_data(when)?;
15182 }
15183 }
15184
15185 if let Some(ref system_time) = table.system_time {
15187 self.write_space();
15188 self.write(system_time);
15189 }
15190
15191 if let Some(ref version) = table.version {
15193 self.write_space();
15194 self.generate_version(version)?;
15195 }
15196
15197 let alias_post_tablesample = self.config.alias_post_tablesample;
15201
15202 if alias_post_tablesample {
15203 self.generate_table_sample_clause(table)?;
15205 }
15206
15207 let is_sqlite_hint = matches!(self.config.dialect, Some(DialectType::SQLite))
15210 && table.hints.iter().any(|h| {
15211 if let Expression::Identifier(id) = h {
15212 id.name.starts_with("INDEXED BY") || id.name == "NOT INDEXED"
15213 } else {
15214 false
15215 }
15216 });
15217 if !table.hints.is_empty() && !is_sqlite_hint {
15218 for hint in &table.hints {
15219 self.write_space();
15220 self.generate_expression(hint)?;
15221 }
15222 }
15223
15224 if let Some(alias) = &table.alias {
15225 self.write_space();
15226 let always_use_as = self.config.dialect.is_none()
15229 || matches!(
15230 self.config.dialect,
15231 Some(DialectType::Generic)
15232 | Some(DialectType::PostgreSQL)
15233 | Some(DialectType::Redshift)
15234 | Some(DialectType::Snowflake)
15235 | Some(DialectType::BigQuery)
15236 | Some(DialectType::Presto)
15237 | Some(DialectType::Trino)
15238 | Some(DialectType::TSQL)
15239 | Some(DialectType::Fabric)
15240 | Some(DialectType::MySQL)
15241 | Some(DialectType::Spark)
15242 | Some(DialectType::Hive)
15243 | Some(DialectType::SQLite)
15244 | Some(DialectType::Drill)
15245 );
15246 let is_stage_ref = table.name.name.starts_with('@');
15247 let suppress_as = matches!(self.config.dialect, Some(DialectType::Oracle));
15249 if !suppress_as && (table.alias_explicit_as || always_use_as || is_stage_ref) {
15250 self.write_keyword("AS");
15251 self.write_space();
15252 }
15253 self.generate_identifier(alias)?;
15254
15255 if !table.column_aliases.is_empty() && self.config.supports_table_alias_columns {
15258 self.write("(");
15259 for (i, col_alias) in table.column_aliases.iter().enumerate() {
15260 if i > 0 {
15261 self.write(", ");
15262 }
15263 self.generate_identifier(col_alias)?;
15264 }
15265 self.write(")");
15266 }
15267 }
15268
15269 if !alias_post_tablesample {
15271 self.generate_table_sample_clause(table)?;
15272 }
15273
15274 if is_sqlite_hint {
15276 for hint in &table.hints {
15277 self.write_space();
15278 self.generate_expression(hint)?;
15279 }
15280 }
15281
15282 if table.final_ && matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
15284 self.write_space();
15285 self.write_keyword("FINAL");
15286 }
15287
15288 for comment in &table.trailing_comments {
15290 self.write_space();
15291 self.write_formatted_comment(comment);
15292 }
15293
15294 Ok(())
15295 }
15296
15297 fn generate_table_sample_clause(&mut self, table: &TableRef) -> Result<()> {
15299 if let Some(ref ts) = table.table_sample {
15300 self.write_space();
15301 if ts.is_using_sample {
15302 self.write_keyword("USING SAMPLE");
15303 } else {
15304 self.write_keyword(self.config.tablesample_keywords);
15306 }
15307 self.generate_sample_body(ts)?;
15308 if let Some(ref seed) = ts.seed {
15310 self.write_space();
15311 self.write_keyword(self.config.tablesample_seed_keyword);
15312 self.write(" (");
15313 self.generate_expression(seed)?;
15314 self.write(")");
15315 }
15316 }
15317 Ok(())
15318 }
15319
15320 fn generate_stage_reference(&mut self, sr: &StageReference) -> Result<()> {
15321 if sr.quoted {
15325 self.write("'");
15326 }
15327
15328 self.write(&sr.name);
15329 if let Some(path) = &sr.path {
15330 self.write(path);
15331 }
15332
15333 if sr.quoted {
15334 self.write("'");
15335 }
15336
15337 let has_options = sr.file_format.is_some() || sr.pattern.is_some();
15339 if has_options {
15340 self.write(" (");
15341 let mut first = true;
15342
15343 if let Some(file_format) = &sr.file_format {
15344 if !first {
15345 self.write(", ");
15346 }
15347 self.write_keyword("FILE_FORMAT");
15348 self.write(" => ");
15349 self.generate_expression(file_format)?;
15350 first = false;
15351 }
15352
15353 if let Some(pattern) = &sr.pattern {
15354 if !first {
15355 self.write(", ");
15356 }
15357 self.write_keyword("PATTERN");
15358 self.write(" => '");
15359 self.write(pattern);
15360 self.write("'");
15361 }
15362
15363 self.write(")");
15364 }
15365 Ok(())
15366 }
15367
15368 fn generate_star(&mut self, star: &Star) -> Result<()> {
15369 use crate::dialects::DialectType;
15370
15371 if let Some(table) = &star.table {
15372 self.generate_identifier(table)?;
15373 self.write(".");
15374 }
15375 self.write("*");
15376
15377 if let Some(except) = &star.except {
15379 if !except.is_empty() {
15380 self.write_space();
15381 match self.config.dialect {
15383 Some(DialectType::BigQuery) => self.write_keyword("EXCEPT"),
15384 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => {
15385 self.write_keyword("EXCLUDE")
15386 }
15387 _ => self.write_keyword("EXCEPT"), }
15389 self.write(" (");
15390 for (i, col) in except.iter().enumerate() {
15391 if i > 0 {
15392 self.write(", ");
15393 }
15394 self.generate_identifier(col)?;
15395 }
15396 self.write(")");
15397 }
15398 }
15399
15400 if let Some(replace) = &star.replace {
15402 if !replace.is_empty() {
15403 self.write_space();
15404 self.write_keyword("REPLACE");
15405 self.write(" (");
15406 for (i, alias) in replace.iter().enumerate() {
15407 if i > 0 {
15408 self.write(", ");
15409 }
15410 self.generate_expression(&alias.this)?;
15411 self.write_space();
15412 self.write_keyword("AS");
15413 self.write_space();
15414 self.generate_identifier(&alias.alias)?;
15415 }
15416 self.write(")");
15417 }
15418 }
15419
15420 if let Some(rename) = &star.rename {
15422 if !rename.is_empty() {
15423 self.write_space();
15424 self.write_keyword("RENAME");
15425 self.write(" (");
15426 for (i, (old_name, new_name)) in rename.iter().enumerate() {
15427 if i > 0 {
15428 self.write(", ");
15429 }
15430 self.generate_identifier(old_name)?;
15431 self.write_space();
15432 self.write_keyword("AS");
15433 self.write_space();
15434 self.generate_identifier(new_name)?;
15435 }
15436 self.write(")");
15437 }
15438 }
15439
15440 for comment in &star.trailing_comments {
15442 self.write_space();
15443 self.write_formatted_comment(comment);
15444 }
15445
15446 Ok(())
15447 }
15448
15449 fn generate_braced_wildcard(&mut self, expr: &Expression) -> Result<()> {
15451 self.write("{");
15452 match expr {
15453 Expression::Star(star) => {
15454 self.generate_star(star)?;
15456 }
15457 Expression::ILike(ilike) => {
15458 self.generate_expression(&ilike.left)?;
15460 self.write_space();
15461 self.write_keyword("ILIKE");
15462 self.write_space();
15463 self.generate_expression(&ilike.right)?;
15464 }
15465 _ => {
15466 self.generate_expression(expr)?;
15467 }
15468 }
15469 self.write("}");
15470 Ok(())
15471 }
15472
15473 fn generate_alias(&mut self, alias: &Alias) -> Result<()> {
15474 match &alias.this {
15478 Expression::Column(col) => {
15479 if let Some(table) = &col.table {
15481 self.generate_identifier(table)?;
15482 self.write(".");
15483 }
15484 self.generate_identifier(&col.name)?;
15485 }
15486 _ => {
15487 self.generate_expression(&alias.this)?;
15488 }
15489 }
15490
15491 if !alias.pre_alias_comments.is_empty() && !alias.trailing_comments.is_empty() {
15495 for comment in &alias.pre_alias_comments {
15496 self.write_space();
15497 self.write_formatted_comment(comment);
15498 }
15499 }
15500
15501 use crate::dialects::DialectType;
15502
15503 let is_table_source = matches!(
15509 &alias.this,
15510 Expression::JSONTable(_)
15511 | Expression::XMLTable(_)
15512 | Expression::TableFromRows(_)
15513 | Expression::Unnest(_)
15514 | Expression::MatchRecognize(_)
15515 | Expression::Select(_)
15516 | Expression::Subquery(_)
15517 | Expression::Paren(_)
15518 );
15519 let dialect_skips_table_alias_as = matches!(self.config.dialect, Some(DialectType::Oracle));
15520 let skip_as = is_table_source && dialect_skips_table_alias_as;
15521
15522 self.write_space();
15523 if !skip_as {
15524 self.write_keyword("AS");
15525 self.write_space();
15526 }
15527
15528 let skip_column_aliases = matches!(self.config.dialect, Some(DialectType::BigQuery));
15530
15531 if alias.alias.is_empty() && !alias.column_aliases.is_empty() && !skip_column_aliases {
15533 self.write("(");
15535 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
15536 if i > 0 {
15537 self.write(", ");
15538 }
15539 self.generate_alias_identifier(col_alias)?;
15540 }
15541 self.write(")");
15542 } else if !alias.column_aliases.is_empty() && !skip_column_aliases {
15543 self.generate_alias_identifier(&alias.alias)?;
15545 self.write("(");
15546 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
15547 if i > 0 {
15548 self.write(", ");
15549 }
15550 self.generate_alias_identifier(col_alias)?;
15551 }
15552 self.write(")");
15553 } else {
15554 self.generate_alias_identifier(&alias.alias)?;
15556 }
15557
15558 for comment in &alias.trailing_comments {
15560 self.write_space();
15561 self.write_formatted_comment(comment);
15562 }
15563
15564 if alias.trailing_comments.is_empty() {
15569 for comment in &alias.pre_alias_comments {
15570 self.write_space();
15571 self.write_formatted_comment(comment);
15572 }
15573 }
15574
15575 Ok(())
15576 }
15577
15578 fn generate_cast(&mut self, cast: &Cast) -> Result<()> {
15579 use crate::dialects::DialectType;
15580
15581 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
15583 self.generate_expression(&cast.this)?;
15584 self.write(" :> ");
15585 self.generate_data_type(&cast.to)?;
15586 return Ok(());
15587 }
15588
15589 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
15591 let is_unknown_type = matches!(cast.to, DataType::Unknown)
15592 || matches!(cast.to, DataType::Custom { ref name } if name.is_empty());
15593 if is_unknown_type {
15594 if let Some(format) = &cast.format {
15595 self.write_keyword("CAST");
15596 self.write("(");
15597 self.generate_expression(&cast.this)?;
15598 self.write_space();
15599 self.write_keyword("AS");
15600 self.write_space();
15601 self.write_keyword("FORMAT");
15602 self.write_space();
15603 self.generate_expression(format)?;
15604 self.write(")");
15605 return Ok(());
15606 }
15607 }
15608 }
15609
15610 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
15613 if let Some(format) = &cast.format {
15614 let is_date = matches!(cast.to, DataType::Date);
15616 let is_timestamp = matches!(cast.to, DataType::Timestamp { .. });
15617
15618 if is_date || is_timestamp {
15619 let func_name = if is_date { "TO_DATE" } else { "TO_TIMESTAMP" };
15620 self.write_keyword(func_name);
15621 self.write("(");
15622 self.generate_expression(&cast.this)?;
15623 self.write(", ");
15624
15625 if let Expression::Literal(Literal::String(fmt_str)) = format.as_ref() {
15628 let normalized = self.normalize_oracle_format(fmt_str);
15629 self.write("'");
15630 self.write(&normalized);
15631 self.write("'");
15632 } else {
15633 self.generate_expression(format)?;
15634 }
15635
15636 self.write(")");
15637 return Ok(());
15638 }
15639 }
15640 }
15641
15642 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
15645 if let Expression::Array(arr) = &cast.this {
15646 self.generate_data_type(&cast.to)?;
15647 self.write("[");
15649 for (i, expr) in arr.expressions.iter().enumerate() {
15650 if i > 0 {
15651 self.write(", ");
15652 }
15653 self.generate_expression(expr)?;
15654 }
15655 self.write("]");
15656 return Ok(());
15657 }
15658 if matches!(&cast.this, Expression::ArrayFunc(_)) {
15659 self.generate_data_type(&cast.to)?;
15660 self.generate_expression(&cast.this)?;
15661 return Ok(());
15662 }
15663 }
15664
15665 if matches!(
15668 self.config.dialect,
15669 Some(DialectType::DuckDB) | Some(DialectType::Presto) | Some(DialectType::Trino)
15670 ) {
15671 if let Expression::Struct(ref s) = cast.this {
15672 let all_unnamed = s.fields.iter().all(|(name, _)| name.is_none());
15673 if all_unnamed && matches!(cast.to, DataType::Struct { .. }) {
15674 self.write_keyword("CAST");
15675 self.write("(");
15676 self.generate_struct_as_row(s)?;
15677 self.write_space();
15678 self.write_keyword("AS");
15679 self.write_space();
15680 self.generate_data_type(&cast.to)?;
15681 self.write(")");
15682 return Ok(());
15683 }
15684 }
15685 }
15686
15687 let use_double_colon = cast.double_colon_syntax && self.dialect_prefers_double_colon();
15690
15691 if use_double_colon {
15692 self.generate_expression(&cast.this)?;
15694 self.write("::");
15695 self.generate_data_type(&cast.to)?;
15696 } else {
15697 self.write_keyword("CAST");
15699 self.write("(");
15700 self.generate_expression(&cast.this)?;
15701 self.write_space();
15702 self.write_keyword("AS");
15703 self.write_space();
15704 if matches!(
15707 self.config.dialect,
15708 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB)
15709 ) {
15710 match &cast.to {
15711 DataType::Custom { ref name } => {
15712 let upper = name.to_uppercase();
15713 match upper.as_str() {
15714 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" | "LONGBLOB" | "MEDIUMBLOB"
15715 | "TINYBLOB" => {
15716 self.write_keyword("CHAR");
15717 }
15718 _ => {
15719 self.generate_data_type(&cast.to)?;
15720 }
15721 }
15722 }
15723 DataType::VarChar { length, .. } => {
15724 self.write_keyword("CHAR");
15726 if let Some(n) = length {
15727 self.write(&format!("({})", n));
15728 }
15729 }
15730 DataType::Text => {
15731 self.write_keyword("CHAR");
15733 }
15734 DataType::Timestamp {
15735 precision,
15736 timezone: false,
15737 } => {
15738 self.write_keyword("DATETIME");
15740 if let Some(p) = precision {
15741 self.write(&format!("({})", p));
15742 }
15743 }
15744 _ => {
15745 self.generate_data_type(&cast.to)?;
15746 }
15747 }
15748 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
15749 match &cast.to {
15751 DataType::String { length } => {
15752 self.write_keyword("VARCHAR");
15753 if let Some(n) = length {
15754 self.write(&format!("({})", n));
15755 }
15756 }
15757 _ => {
15758 self.generate_data_type(&cast.to)?;
15759 }
15760 }
15761 } else {
15762 self.generate_data_type(&cast.to)?;
15763 }
15764
15765 if let Some(default) = &cast.default {
15767 self.write_space();
15768 self.write_keyword("DEFAULT");
15769 self.write_space();
15770 self.generate_expression(default)?;
15771 self.write_space();
15772 self.write_keyword("ON");
15773 self.write_space();
15774 self.write_keyword("CONVERSION");
15775 self.write_space();
15776 self.write_keyword("ERROR");
15777 }
15778
15779 if let Some(format) = &cast.format {
15782 if matches!(
15784 self.config.dialect,
15785 Some(crate::dialects::DialectType::Oracle)
15786 ) {
15787 self.write(", ");
15788 } else {
15789 self.write_space();
15790 self.write_keyword("FORMAT");
15791 self.write_space();
15792 }
15793 self.generate_expression(format)?;
15794 }
15795
15796 self.write(")");
15797 for comment in &cast.trailing_comments {
15799 self.write_space();
15800 self.write_formatted_comment(comment);
15801 }
15802 }
15803 Ok(())
15804 }
15805
15806 fn generate_struct_as_row(&mut self, s: &crate::expressions::Struct) -> Result<()> {
15809 self.write_keyword("ROW");
15810 self.write("(");
15811 for (i, (_, expr)) in s.fields.iter().enumerate() {
15812 if i > 0 {
15813 self.write(", ");
15814 }
15815 if let Expression::Struct(ref inner_s) = expr {
15817 self.generate_struct_as_row(inner_s)?;
15818 } else {
15819 self.generate_expression(expr)?;
15820 }
15821 }
15822 self.write(")");
15823 Ok(())
15824 }
15825
15826 fn normalize_oracle_format(&self, format: &str) -> String {
15829 let mut result = String::new();
15832 let chars: Vec<char> = format.chars().collect();
15833 let mut i = 0;
15834
15835 while i < chars.len() {
15836 if i + 1 < chars.len() && chars[i] == 'H' && chars[i + 1] == 'H' {
15837 if i + 2 < chars.len() {
15839 let next = chars[i + 2];
15840 if next == '1' || next == '2' {
15841 result.push('H');
15843 result.push('H');
15844 i += 2;
15845 continue;
15846 }
15847 }
15848 result.push_str("HH12");
15850 i += 2;
15851 } else {
15852 result.push(chars[i]);
15853 i += 1;
15854 }
15855 }
15856
15857 result
15858 }
15859
15860 fn dialect_prefers_double_colon(&self) -> bool {
15864 false
15867 }
15868
15869 fn generate_mod_func(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
15871 use crate::dialects::DialectType;
15872
15873 let use_percent_operator = matches!(
15875 self.config.dialect,
15876 Some(DialectType::Snowflake)
15877 | Some(DialectType::MySQL)
15878 | Some(DialectType::Presto)
15879 | Some(DialectType::Trino)
15880 | Some(DialectType::PostgreSQL)
15881 | Some(DialectType::DuckDB)
15882 | Some(DialectType::Hive)
15883 | Some(DialectType::Spark)
15884 | Some(DialectType::Databricks)
15885 | Some(DialectType::Athena)
15886 );
15887
15888 if use_percent_operator {
15889 let needs_paren = |e: &Expression| matches!(e, Expression::Add(_) | Expression::Sub(_));
15892 if needs_paren(&f.this) {
15893 self.write("(");
15894 self.generate_expression(&f.this)?;
15895 self.write(")");
15896 } else {
15897 self.generate_expression(&f.this)?;
15898 }
15899 self.write(" % ");
15900 if needs_paren(&f.expression) {
15901 self.write("(");
15902 self.generate_expression(&f.expression)?;
15903 self.write(")");
15904 } else {
15905 self.generate_expression(&f.expression)?;
15906 }
15907 Ok(())
15908 } else {
15909 self.generate_binary_func("MOD", &f.this, &f.expression)
15910 }
15911 }
15912
15913 fn generate_ifnull(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
15915 use crate::dialects::DialectType;
15916
15917 let func_name = match self.config.dialect {
15919 Some(DialectType::Snowflake) => "COALESCE",
15920 _ => "IFNULL",
15921 };
15922
15923 self.generate_binary_func(func_name, &f.this, &f.expression)
15924 }
15925
15926 fn generate_nvl(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
15928 if let Some(ref original_name) = f.original_name {
15930 return self.generate_binary_func(original_name, &f.this, &f.expression);
15931 }
15932
15933 use crate::dialects::DialectType;
15935 let func_name = match self.config.dialect {
15936 Some(DialectType::Snowflake)
15937 | Some(DialectType::ClickHouse)
15938 | Some(DialectType::PostgreSQL)
15939 | Some(DialectType::Presto)
15940 | Some(DialectType::Trino)
15941 | Some(DialectType::Athena)
15942 | Some(DialectType::DuckDB)
15943 | Some(DialectType::BigQuery)
15944 | Some(DialectType::Spark)
15945 | Some(DialectType::Databricks)
15946 | Some(DialectType::Hive) => "COALESCE",
15947 Some(DialectType::MySQL)
15948 | Some(DialectType::Doris)
15949 | Some(DialectType::StarRocks)
15950 | Some(DialectType::SingleStore)
15951 | Some(DialectType::TiDB) => "IFNULL",
15952 _ => "NVL",
15953 };
15954
15955 self.generate_binary_func(func_name, &f.this, &f.expression)
15956 }
15957
15958 fn generate_stddev_samp(&mut self, f: &crate::expressions::AggFunc) -> Result<()> {
15960 use crate::dialects::DialectType;
15961
15962 let func_name = match self.config.dialect {
15964 Some(DialectType::Snowflake) => "STDDEV",
15965 _ => "STDDEV_SAMP",
15966 };
15967
15968 self.generate_agg_func(func_name, f)
15969 }
15970
15971 fn generate_collation(&mut self, coll: &CollationExpr) -> Result<()> {
15972 self.generate_expression(&coll.this)?;
15973 self.write_space();
15974 self.write_keyword("COLLATE");
15975 self.write_space();
15976 if coll.quoted {
15977 self.write("'");
15979 self.write(&coll.collation);
15980 self.write("'");
15981 } else if coll.double_quoted {
15982 self.write("\"");
15984 self.write(&coll.collation);
15985 self.write("\"");
15986 } else {
15987 self.write(&coll.collation);
15989 }
15990 Ok(())
15991 }
15992
15993 fn generate_case(&mut self, case: &Case) -> Result<()> {
15994 let multiline_case = if self.config.pretty {
15996 let mut statements: Vec<String> = Vec::new();
15998 let operand_str = if let Some(operand) = &case.operand {
15999 let s = self.generate_to_string(operand)?;
16000 statements.push(format!("CASE {}", s));
16001 s
16002 } else {
16003 statements.push("CASE".to_string());
16004 String::new()
16005 };
16006 let _ = operand_str;
16007 for (condition, result) in &case.whens {
16008 statements.push(format!("WHEN {}", self.generate_to_string(condition)?));
16009 statements.push(format!("THEN {}", self.generate_to_string(result)?));
16010 }
16011 if let Some(else_) = &case.else_ {
16012 statements.push(format!("ELSE {}", self.generate_to_string(else_)?));
16013 }
16014 statements.push("END".to_string());
16015 self.too_wide(&statements)
16016 } else {
16017 false
16018 };
16019
16020 self.write_keyword("CASE");
16021 if let Some(operand) = &case.operand {
16022 self.write_space();
16023 self.generate_expression(operand)?;
16024 }
16025 if multiline_case {
16026 self.indent_level += 1;
16027 }
16028 for (condition, result) in &case.whens {
16029 if multiline_case {
16030 self.write_newline();
16031 self.write_indent();
16032 } else {
16033 self.write_space();
16034 }
16035 self.write_keyword("WHEN");
16036 self.write_space();
16037 self.generate_expression(condition)?;
16038 if multiline_case {
16039 self.write_newline();
16040 self.write_indent();
16041 } else {
16042 self.write_space();
16043 }
16044 self.write_keyword("THEN");
16045 self.write_space();
16046 self.generate_expression(result)?;
16047 }
16048 if let Some(else_) = &case.else_ {
16049 if multiline_case {
16050 self.write_newline();
16051 self.write_indent();
16052 } else {
16053 self.write_space();
16054 }
16055 self.write_keyword("ELSE");
16056 self.write_space();
16057 self.generate_expression(else_)?;
16058 }
16059 if multiline_case {
16060 self.indent_level -= 1;
16061 self.write_newline();
16062 self.write_indent();
16063 } else {
16064 self.write_space();
16065 }
16066 self.write_keyword("END");
16067 for comment in &case.comments {
16069 self.write(" ");
16070 self.write_formatted_comment(comment);
16071 }
16072 Ok(())
16073 }
16074
16075 fn generate_function(&mut self, func: &Function) -> Result<()> {
16076 let normalized_name = self.normalize_func_name(&func.name);
16078 let upper_name = func.name.to_uppercase();
16079
16080 if matches!(self.config.dialect, Some(DialectType::DuckDB))
16082 && upper_name == "ARRAY_CONSTRUCT_COMPACT"
16083 {
16084 self.write("LIST_FILTER(");
16085 self.write("[");
16086 for (i, arg) in func.args.iter().enumerate() {
16087 if i > 0 {
16088 self.write(", ");
16089 }
16090 self.generate_expression(arg)?;
16091 }
16092 self.write("], _u -> NOT _u IS NULL)");
16093 return Ok(());
16094 }
16095
16096 if upper_name == "STRUCT"
16098 && !matches!(
16099 self.config.dialect,
16100 Some(DialectType::BigQuery)
16101 | Some(DialectType::Spark)
16102 | Some(DialectType::Databricks)
16103 | Some(DialectType::Hive)
16104 | None
16105 )
16106 {
16107 return self.generate_struct_function_cross_dialect(func);
16108 }
16109
16110 if upper_name == "__SS_JSON_PATH_QMARK__" && func.args.len() == 2 {
16113 self.generate_expression(&func.args[0])?;
16114 self.write("::?");
16115 if let Expression::Literal(crate::expressions::Literal::String(key)) = &func.args[1] {
16117 self.write(key);
16118 } else {
16119 self.generate_expression(&func.args[1])?;
16120 }
16121 return Ok(());
16122 }
16123
16124 if upper_name == "__PG_BITWISE_XOR__" && func.args.len() == 2 {
16126 self.generate_expression(&func.args[0])?;
16127 self.write(" # ");
16128 self.generate_expression(&func.args[1])?;
16129 return Ok(());
16130 }
16131
16132 if matches!(
16134 self.config.dialect,
16135 Some(DialectType::Spark | DialectType::Databricks | DialectType::Hive)
16136 ) && upper_name == "TRY"
16137 && func.args.len() == 1
16138 {
16139 self.generate_expression(&func.args[0])?;
16140 return Ok(());
16141 }
16142
16143 if self.config.dialect == Some(DialectType::ClickHouse)
16145 && upper_name == "TOSTARTOFDAY"
16146 && func.args.len() == 1
16147 {
16148 self.write("dateTrunc('DAY', ");
16149 self.generate_expression(&func.args[0])?;
16150 self.write(")");
16151 return Ok(());
16152 }
16153
16154 if self.config.dialect == Some(DialectType::Redshift)
16156 && upper_name == "CONCAT"
16157 && func.args.len() >= 2
16158 {
16159 for (i, arg) in func.args.iter().enumerate() {
16160 if i > 0 {
16161 self.write(" || ");
16162 }
16163 self.generate_expression(arg)?;
16164 }
16165 return Ok(());
16166 }
16167
16168 if self.config.dialect == Some(DialectType::Redshift)
16170 && upper_name == "CONCAT_WS"
16171 && func.args.len() >= 2
16172 {
16173 let sep = &func.args[0];
16174 for (i, arg) in func.args.iter().skip(1).enumerate() {
16175 if i > 0 {
16176 self.write(" || ");
16177 self.generate_expression(sep)?;
16178 self.write(" || ");
16179 }
16180 self.generate_expression(arg)?;
16181 }
16182 return Ok(());
16183 }
16184
16185 if self.config.dialect == Some(DialectType::Redshift)
16188 && (upper_name == "DATEDIFF" || upper_name == "DATE_DIFF")
16189 && func.args.len() == 3
16190 {
16191 self.write_keyword("DATEDIFF");
16192 self.write("(");
16193 self.write_redshift_date_part(&func.args[0]);
16195 self.write(", ");
16196 self.generate_expression(&func.args[1])?;
16197 self.write(", ");
16198 self.generate_expression(&func.args[2])?;
16199 self.write(")");
16200 return Ok(());
16201 }
16202
16203 if self.config.dialect == Some(DialectType::Redshift)
16206 && (upper_name == "DATEADD" || upper_name == "DATE_ADD")
16207 && func.args.len() == 3
16208 {
16209 self.write_keyword("DATEADD");
16210 self.write("(");
16211 self.write_redshift_date_part(&func.args[0]);
16213 self.write(", ");
16214 self.generate_expression(&func.args[1])?;
16215 self.write(", ");
16216 self.generate_expression(&func.args[2])?;
16217 self.write(")");
16218 return Ok(());
16219 }
16220
16221 if upper_name == "UUID_STRING"
16223 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None)
16224 {
16225 let func_name = match self.config.dialect {
16226 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
16227 Some(DialectType::BigQuery) => "GENERATE_UUID",
16228 _ => "UUID",
16229 };
16230 self.write_keyword(func_name);
16231 self.write("()");
16232 return Ok(());
16233 }
16234
16235 if self.config.dialect == Some(DialectType::Redshift)
16238 && upper_name == "DATE_TRUNC"
16239 && func.args.len() == 2
16240 {
16241 self.write_keyword("DATE_TRUNC");
16242 self.write("(");
16243 self.write_redshift_date_part_quoted(&func.args[0]);
16245 self.write(", ");
16246 self.generate_expression(&func.args[1])?;
16247 self.write(")");
16248 return Ok(());
16249 }
16250
16251 if matches!(
16253 self.config.dialect,
16254 Some(DialectType::TSQL) | Some(DialectType::Fabric)
16255 ) && (upper_name == "DATE_PART" || upper_name == "DATEPART")
16256 && func.args.len() == 2
16257 {
16258 self.write_keyword("DATEPART");
16259 self.write("(");
16260 self.generate_expression(&func.args[0])?;
16261 self.write(", ");
16262 self.generate_expression(&func.args[1])?;
16263 self.write(")");
16264 return Ok(());
16265 }
16266
16267 if matches!(
16269 self.config.dialect,
16270 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
16271 ) && (upper_name == "DATE_PART" || upper_name == "DATEPART")
16272 && func.args.len() == 2
16273 {
16274 self.write_keyword("EXTRACT");
16275 self.write("(");
16276 match &func.args[0] {
16278 Expression::Literal(crate::expressions::Literal::String(s)) => {
16279 self.write(&s.to_lowercase());
16280 }
16281 _ => self.generate_expression(&func.args[0])?,
16282 }
16283 self.write_space();
16284 self.write_keyword("FROM");
16285 self.write_space();
16286 self.generate_expression(&func.args[1])?;
16287 self.write(")");
16288 return Ok(());
16289 }
16290
16291 if self.config.dialect == Some(DialectType::Dremio)
16294 && (upper_name == "DATE_PART" || upper_name == "DATEPART")
16295 && func.args.len() == 2
16296 {
16297 self.write_keyword("EXTRACT");
16298 self.write("(");
16299 self.generate_expression(&func.args[0])?;
16300 self.write_space();
16301 self.write_keyword("FROM");
16302 self.write_space();
16303 self.generate_dremio_date_expression(&func.args[1])?;
16305 self.write(")");
16306 return Ok(());
16307 }
16308
16309 if self.config.dialect == Some(DialectType::Dremio)
16311 && upper_name == "CURRENT_DATE_UTC"
16312 && func.args.is_empty()
16313 {
16314 self.write_keyword("CURRENT_DATE_UTC");
16315 return Ok(());
16316 }
16317
16318 if self.config.dialect == Some(DialectType::Dremio)
16322 && upper_name == "DATETYPE"
16323 && func.args.len() == 3
16324 {
16325 fn get_int_literal(expr: &Expression) -> Option<i64> {
16327 if let Expression::Literal(crate::expressions::Literal::Number(s)) = expr {
16328 s.parse::<i64>().ok()
16329 } else {
16330 None
16331 }
16332 }
16333
16334 if let (Some(year), Some(month), Some(day)) = (
16336 get_int_literal(&func.args[0]),
16337 get_int_literal(&func.args[1]),
16338 get_int_literal(&func.args[2]),
16339 ) {
16340 self.write_keyword("DATE");
16342 self.write(&format!("('{:04}-{:02}-{:02}')", year, month, day));
16343 return Ok(());
16344 }
16345
16346 self.write_keyword("CAST");
16348 self.write("(");
16349 self.write_keyword("CONCAT");
16350 self.write("(");
16351 self.generate_expression(&func.args[0])?;
16352 self.write(", '-', ");
16353 self.generate_expression(&func.args[1])?;
16354 self.write(", '-', ");
16355 self.generate_expression(&func.args[2])?;
16356 self.write(")");
16357 self.write_space();
16358 self.write_keyword("AS");
16359 self.write_space();
16360 self.write_keyword("DATE");
16361 self.write(")");
16362 return Ok(());
16363 }
16364
16365 let is_presto_like = matches!(
16368 self.config.dialect,
16369 Some(DialectType::Presto) | Some(DialectType::Trino)
16370 );
16371 if is_presto_like && upper_name == "DATE_ADD" && func.args.len() == 3 {
16372 self.write_keyword("DATE_ADD");
16373 self.write("(");
16374 self.generate_expression(&func.args[0])?;
16376 self.write(", ");
16377 let interval = &func.args[1];
16379 let needs_cast = !self.returns_integer_type(interval);
16380 if needs_cast {
16381 self.write_keyword("CAST");
16382 self.write("(");
16383 }
16384 self.generate_expression(interval)?;
16385 if needs_cast {
16386 self.write_space();
16387 self.write_keyword("AS");
16388 self.write_space();
16389 self.write_keyword("BIGINT");
16390 self.write(")");
16391 }
16392 self.write(", ");
16393 self.generate_expression(&func.args[2])?;
16395 self.write(")");
16396 return Ok(());
16397 }
16398
16399 let use_brackets = func.use_bracket_syntax;
16401
16402 let has_ordinality = upper_name.ends_with(" WITH ORDINALITY");
16407 let output_name = if has_ordinality {
16408 let base_name = &func.name[..func.name.len() - " WITH ORDINALITY".len()];
16409 self.normalize_func_name(base_name)
16410 } else {
16411 normalized_name.clone()
16412 };
16413
16414 if func.name.contains('.') && !has_ordinality {
16417 if func.quoted {
16420 self.write("`");
16421 self.write(&func.name);
16422 self.write("`");
16423 } else {
16424 self.write(&func.name);
16425 }
16426 } else {
16427 self.write(&output_name);
16428 }
16429
16430 let force_parens = func.no_parens && func.args.is_empty() && !func.distinct && {
16433 let needs_parens = match upper_name.as_str() {
16434 "CURRENT_USER" | "SESSION_USER" | "SYSTEM_USER" => matches!(
16435 self.config.dialect,
16436 Some(DialectType::Snowflake)
16437 | Some(DialectType::Spark)
16438 | Some(DialectType::Databricks)
16439 | Some(DialectType::Hive)
16440 ),
16441 _ => false,
16442 };
16443 !needs_parens
16444 };
16445 if force_parens {
16446 for comment in &func.trailing_comments {
16448 self.write_space();
16449 self.write_formatted_comment(comment);
16450 }
16451 return Ok(());
16452 }
16453
16454 if upper_name == "CUBE" || upper_name == "ROLLUP" || upper_name == "GROUPING SETS" {
16456 self.write(" (");
16457 } else if use_brackets {
16458 self.write("[");
16459 } else {
16460 self.write("(");
16461 }
16462 if func.distinct {
16463 self.write_keyword("DISTINCT");
16464 self.write_space();
16465 }
16466
16467 let compact_pretty_func = matches!(self.config.dialect, Some(DialectType::Snowflake))
16469 && (upper_name == "TABLE" || upper_name == "FLATTEN");
16470 let is_grouping_func =
16472 upper_name == "GROUPING SETS" || upper_name == "CUBE" || upper_name == "ROLLUP";
16473 let should_split = if self.config.pretty && !func.args.is_empty() && !compact_pretty_func {
16474 if is_grouping_func {
16475 true
16476 } else {
16477 let mut expr_strings: Vec<String> = Vec::with_capacity(func.args.len());
16479 for arg in &func.args {
16480 let mut temp_gen = Generator::with_config(self.config.clone());
16481 temp_gen.config.pretty = false; temp_gen.generate_expression(arg)?;
16483 expr_strings.push(temp_gen.output);
16484 }
16485 self.too_wide(&expr_strings)
16486 }
16487 } else {
16488 false
16489 };
16490
16491 if should_split {
16492 self.write_newline();
16494 self.indent_level += 1;
16495 for (i, arg) in func.args.iter().enumerate() {
16496 self.write_indent();
16497 self.generate_expression(arg)?;
16498 if i + 1 < func.args.len() {
16499 self.write(",");
16500 }
16501 self.write_newline();
16502 }
16503 self.indent_level -= 1;
16504 self.write_indent();
16505 } else {
16506 for (i, arg) in func.args.iter().enumerate() {
16508 if i > 0 {
16509 self.write(", ");
16510 }
16511 self.generate_expression(arg)?;
16512 }
16513 }
16514
16515 if use_brackets {
16516 self.write("]");
16517 } else {
16518 self.write(")");
16519 }
16520 if has_ordinality {
16522 self.write_space();
16523 self.write_keyword("WITH ORDINALITY");
16524 }
16525 for comment in &func.trailing_comments {
16527 self.write_space();
16528 self.write_formatted_comment(comment);
16529 }
16530 Ok(())
16531 }
16532
16533 fn generate_aggregate_function(&mut self, func: &AggregateFunction) -> Result<()> {
16534 let mut normalized_name = self.normalize_func_name(&func.name);
16536
16537 let upper = normalized_name.to_uppercase();
16539 if upper == "MAX_BY" || upper == "MIN_BY" {
16540 let is_max = upper == "MAX_BY";
16541 match self.config.dialect {
16542 Some(DialectType::ClickHouse) => {
16543 normalized_name = if is_max {
16544 "argMax".to_string()
16545 } else {
16546 "argMin".to_string()
16547 };
16548 }
16549 Some(DialectType::DuckDB) => {
16550 normalized_name = if is_max {
16551 "ARG_MAX".to_string()
16552 } else {
16553 "ARG_MIN".to_string()
16554 };
16555 }
16556 _ => {}
16557 }
16558 }
16559 self.write(&normalized_name);
16560 self.write("(");
16561 if func.distinct {
16562 self.write_keyword("DISTINCT");
16563 self.write_space();
16564 }
16565
16566 let is_count = normalized_name.eq_ignore_ascii_case("COUNT");
16570 let needs_multi_arg_transform =
16571 func.distinct && is_count && func.args.len() > 1 && !self.config.multi_arg_distinct;
16572
16573 if needs_multi_arg_transform {
16574 self.write_keyword("CASE");
16576 for arg in &func.args {
16577 self.write_space();
16578 self.write_keyword("WHEN");
16579 self.write_space();
16580 self.generate_expression(arg)?;
16581 self.write_space();
16582 self.write_keyword("IS NULL THEN NULL");
16583 }
16584 self.write_space();
16585 self.write_keyword("ELSE");
16586 self.write(" (");
16587 for (i, arg) in func.args.iter().enumerate() {
16588 if i > 0 {
16589 self.write(", ");
16590 }
16591 self.generate_expression(arg)?;
16592 }
16593 self.write(")");
16594 self.write_space();
16595 self.write_keyword("END");
16596 } else {
16597 for (i, arg) in func.args.iter().enumerate() {
16598 if i > 0 {
16599 self.write(", ");
16600 }
16601 self.generate_expression(arg)?;
16602 }
16603 }
16604
16605 if self.config.ignore_nulls_in_func
16607 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
16608 {
16609 if let Some(ignore) = func.ignore_nulls {
16610 self.write_space();
16611 if ignore {
16612 self.write_keyword("IGNORE NULLS");
16613 } else {
16614 self.write_keyword("RESPECT NULLS");
16615 }
16616 }
16617 }
16618
16619 if !func.order_by.is_empty() {
16621 self.write_space();
16622 self.write_keyword("ORDER BY");
16623 self.write_space();
16624 for (i, ord) in func.order_by.iter().enumerate() {
16625 if i > 0 {
16626 self.write(", ");
16627 }
16628 self.generate_ordered(ord)?;
16629 }
16630 }
16631
16632 if let Some(limit) = &func.limit {
16634 self.write_space();
16635 self.write_keyword("LIMIT");
16636 self.write_space();
16637 if let Expression::Tuple(t) = limit.as_ref() {
16639 if t.expressions.len() == 2 {
16640 self.generate_expression(&t.expressions[0])?;
16641 self.write(", ");
16642 self.generate_expression(&t.expressions[1])?;
16643 } else {
16644 self.generate_expression(limit)?;
16645 }
16646 } else {
16647 self.generate_expression(limit)?;
16648 }
16649 }
16650
16651 self.write(")");
16652
16653 if !self.config.ignore_nulls_in_func
16655 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
16656 {
16657 if let Some(ignore) = func.ignore_nulls {
16658 self.write_space();
16659 if ignore {
16660 self.write_keyword("IGNORE NULLS");
16661 } else {
16662 self.write_keyword("RESPECT NULLS");
16663 }
16664 }
16665 }
16666
16667 if let Some(filter) = &func.filter {
16668 self.write_space();
16669 self.write_keyword("FILTER");
16670 self.write("(");
16671 self.write_keyword("WHERE");
16672 self.write_space();
16673 self.generate_expression(filter)?;
16674 self.write(")");
16675 }
16676
16677 Ok(())
16678 }
16679
16680 fn generate_window_function(&mut self, wf: &WindowFunction) -> Result<()> {
16681 self.generate_expression(&wf.this)?;
16682
16683 if let Some(keep) = &wf.keep {
16685 self.write_space();
16686 self.write_keyword("KEEP");
16687 self.write(" (");
16688 self.write_keyword("DENSE_RANK");
16689 self.write_space();
16690 if keep.first {
16691 self.write_keyword("FIRST");
16692 } else {
16693 self.write_keyword("LAST");
16694 }
16695 self.write_space();
16696 self.write_keyword("ORDER BY");
16697 self.write_space();
16698 for (i, ord) in keep.order_by.iter().enumerate() {
16699 if i > 0 {
16700 self.write(", ");
16701 }
16702 self.generate_ordered(ord)?;
16703 }
16704 self.write(")");
16705 }
16706
16707 let has_over = !wf.over.partition_by.is_empty()
16709 || !wf.over.order_by.is_empty()
16710 || wf.over.frame.is_some()
16711 || wf.over.window_name.is_some();
16712
16713 if has_over {
16715 self.write_space();
16716 self.write_keyword("OVER");
16717
16718 let has_specs = !wf.over.partition_by.is_empty()
16720 || !wf.over.order_by.is_empty()
16721 || wf.over.frame.is_some();
16722
16723 if wf.over.window_name.is_some() && !has_specs {
16724 self.write_space();
16726 self.write(&wf.over.window_name.as_ref().unwrap().name);
16727 } else {
16728 self.write(" (");
16730 self.generate_over(&wf.over)?;
16731 self.write(")");
16732 }
16733 } else if wf.keep.is_none() {
16734 self.write_space();
16736 self.write_keyword("OVER");
16737 self.write(" ()");
16738 }
16739
16740 Ok(())
16741 }
16742
16743 fn generate_within_group(&mut self, wg: &WithinGroup) -> Result<()> {
16745 self.generate_expression(&wg.this)?;
16746 self.write_space();
16747 self.write_keyword("WITHIN GROUP");
16748 self.write(" (");
16749 self.write_keyword("ORDER BY");
16750 self.write_space();
16751 for (i, ord) in wg.order_by.iter().enumerate() {
16752 if i > 0 {
16753 self.write(", ");
16754 }
16755 self.generate_ordered(ord)?;
16756 }
16757 self.write(")");
16758 Ok(())
16759 }
16760
16761 fn generate_over(&mut self, over: &Over) -> Result<()> {
16763 let mut has_content = false;
16764
16765 if let Some(name) = &over.window_name {
16767 self.write(&name.name);
16768 has_content = true;
16769 }
16770
16771 if !over.partition_by.is_empty() {
16773 if has_content {
16774 self.write_space();
16775 }
16776 self.write_keyword("PARTITION BY");
16777 self.write_space();
16778 for (i, expr) in over.partition_by.iter().enumerate() {
16779 if i > 0 {
16780 self.write(", ");
16781 }
16782 self.generate_expression(expr)?;
16783 }
16784 has_content = true;
16785 }
16786
16787 if !over.order_by.is_empty() {
16789 if has_content {
16790 self.write_space();
16791 }
16792 self.write_keyword("ORDER BY");
16793 self.write_space();
16794 for (i, ordered) in over.order_by.iter().enumerate() {
16795 if i > 0 {
16796 self.write(", ");
16797 }
16798 self.generate_ordered(ordered)?;
16799 }
16800 has_content = true;
16801 }
16802
16803 if let Some(frame) = &over.frame {
16805 if has_content {
16806 self.write_space();
16807 }
16808 self.generate_window_frame(frame)?;
16809 }
16810
16811 Ok(())
16812 }
16813
16814 fn generate_window_frame(&mut self, frame: &WindowFrame) -> Result<()> {
16815 let lowercase_frame = self.config.lowercase_window_frame_keywords;
16817
16818 if !lowercase_frame {
16820 if let Some(kind_text) = &frame.kind_text {
16821 self.write(kind_text);
16822 } else {
16823 match frame.kind {
16824 WindowFrameKind::Rows => self.write_keyword("ROWS"),
16825 WindowFrameKind::Range => self.write_keyword("RANGE"),
16826 WindowFrameKind::Groups => self.write_keyword("GROUPS"),
16827 }
16828 }
16829 } else {
16830 match frame.kind {
16831 WindowFrameKind::Rows => self.write("rows"),
16832 WindowFrameKind::Range => self.write("range"),
16833 WindowFrameKind::Groups => self.write("groups"),
16834 }
16835 }
16836
16837 self.write_space();
16840 let should_normalize = self.config.normalize_window_frame_between
16841 && frame.end.is_none()
16842 && matches!(
16843 frame.start,
16844 WindowFrameBound::Preceding(_)
16845 | WindowFrameBound::Following(_)
16846 | WindowFrameBound::UnboundedPreceding
16847 | WindowFrameBound::UnboundedFollowing
16848 );
16849
16850 if let Some(end) = &frame.end {
16851 self.write_keyword("BETWEEN");
16853 self.write_space();
16854 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
16855 self.write_space();
16856 self.write_keyword("AND");
16857 self.write_space();
16858 self.generate_window_frame_bound(end, frame.end_side_text.as_deref())?;
16859 } else if should_normalize {
16860 self.write_keyword("BETWEEN");
16862 self.write_space();
16863 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
16864 self.write_space();
16865 self.write_keyword("AND");
16866 self.write_space();
16867 self.write_keyword("CURRENT ROW");
16868 } else {
16869 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
16871 }
16872
16873 if let Some(exclude) = &frame.exclude {
16875 self.write_space();
16876 self.write_keyword("EXCLUDE");
16877 self.write_space();
16878 match exclude {
16879 WindowFrameExclude::CurrentRow => self.write_keyword("CURRENT ROW"),
16880 WindowFrameExclude::Group => self.write_keyword("GROUP"),
16881 WindowFrameExclude::Ties => self.write_keyword("TIES"),
16882 WindowFrameExclude::NoOthers => self.write_keyword("NO OTHERS"),
16883 }
16884 }
16885
16886 Ok(())
16887 }
16888
16889 fn generate_window_frame_bound(
16890 &mut self,
16891 bound: &WindowFrameBound,
16892 side_text: Option<&str>,
16893 ) -> Result<()> {
16894 let lowercase_frame = self.config.lowercase_window_frame_keywords;
16896
16897 match bound {
16898 WindowFrameBound::CurrentRow => {
16899 self.write_keyword("CURRENT ROW");
16900 }
16901 WindowFrameBound::UnboundedPreceding => {
16902 self.write_keyword("UNBOUNDED");
16903 self.write_space();
16904 if lowercase_frame {
16905 self.write("preceding");
16906 } else if let Some(text) = side_text {
16907 self.write(text);
16908 } else {
16909 self.write_keyword("PRECEDING");
16910 }
16911 }
16912 WindowFrameBound::UnboundedFollowing => {
16913 self.write_keyword("UNBOUNDED");
16914 self.write_space();
16915 if lowercase_frame {
16916 self.write("following");
16917 } else if let Some(text) = side_text {
16918 self.write(text);
16919 } else {
16920 self.write_keyword("FOLLOWING");
16921 }
16922 }
16923 WindowFrameBound::Preceding(expr) => {
16924 self.generate_expression(expr)?;
16925 self.write_space();
16926 if lowercase_frame {
16927 self.write("preceding");
16928 } else if let Some(text) = side_text {
16929 self.write(text);
16930 } else {
16931 self.write_keyword("PRECEDING");
16932 }
16933 }
16934 WindowFrameBound::Following(expr) => {
16935 self.generate_expression(expr)?;
16936 self.write_space();
16937 if lowercase_frame {
16938 self.write("following");
16939 } else if let Some(text) = side_text {
16940 self.write(text);
16941 } else {
16942 self.write_keyword("FOLLOWING");
16943 }
16944 }
16945 WindowFrameBound::BarePreceding => {
16946 if lowercase_frame {
16947 self.write("preceding");
16948 } else if let Some(text) = side_text {
16949 self.write(text);
16950 } else {
16951 self.write_keyword("PRECEDING");
16952 }
16953 }
16954 WindowFrameBound::BareFollowing => {
16955 if lowercase_frame {
16956 self.write("following");
16957 } else if let Some(text) = side_text {
16958 self.write(text);
16959 } else {
16960 self.write_keyword("FOLLOWING");
16961 }
16962 }
16963 WindowFrameBound::Value(expr) => {
16964 self.generate_expression(expr)?;
16966 }
16967 }
16968 Ok(())
16969 }
16970
16971 fn generate_interval(&mut self, interval: &Interval) -> Result<()> {
16972 let skip_interval_keyword = matches!(self.config.dialect, Some(DialectType::Oracle))
16975 && matches!(&interval.unit, Some(IntervalUnitSpec::ExprSpan(_)))
16976 && !matches!(&interval.this, Some(Expression::Literal(_)));
16977
16978 if self.config.single_string_interval {
16981 if let (
16982 Some(Expression::Literal(Literal::String(ref val))),
16983 Some(IntervalUnitSpec::Simple {
16984 ref unit,
16985 ref use_plural,
16986 }),
16987 ) = (&interval.this, &interval.unit)
16988 {
16989 self.write_keyword("INTERVAL");
16990 self.write_space();
16991 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
16992 let unit_str = self.interval_unit_str(unit, effective_plural);
16993 self.write("'");
16994 self.write(val);
16995 self.write(" ");
16996 self.write(&unit_str);
16997 self.write("'");
16998 return Ok(());
16999 }
17000 }
17001
17002 if !skip_interval_keyword {
17003 self.write_keyword("INTERVAL");
17004 }
17005
17006 if let Some(ref value) = interval.this {
17008 if !skip_interval_keyword {
17009 self.write_space();
17010 }
17011 let needs_parens = interval.unit.is_some()
17015 && matches!(
17016 value,
17017 Expression::Add(_)
17018 | Expression::Sub(_)
17019 | Expression::Mul(_)
17020 | Expression::Div(_)
17021 | Expression::Mod(_)
17022 | Expression::BitwiseAnd(_)
17023 | Expression::BitwiseOr(_)
17024 | Expression::BitwiseXor(_)
17025 );
17026 if needs_parens {
17027 self.write("(");
17028 }
17029 self.generate_expression(value)?;
17030 if needs_parens {
17031 self.write(")");
17032 }
17033 }
17034
17035 if let Some(ref unit_spec) = interval.unit {
17037 self.write_space();
17038 self.write_interval_unit_spec(unit_spec)?;
17039 }
17040
17041 Ok(())
17042 }
17043
17044 fn interval_unit_str(&self, unit: &IntervalUnit, use_plural: bool) -> &'static str {
17046 match (unit, use_plural) {
17047 (IntervalUnit::Year, false) => "YEAR",
17048 (IntervalUnit::Year, true) => "YEARS",
17049 (IntervalUnit::Quarter, false) => "QUARTER",
17050 (IntervalUnit::Quarter, true) => "QUARTERS",
17051 (IntervalUnit::Month, false) => "MONTH",
17052 (IntervalUnit::Month, true) => "MONTHS",
17053 (IntervalUnit::Week, false) => "WEEK",
17054 (IntervalUnit::Week, true) => "WEEKS",
17055 (IntervalUnit::Day, false) => "DAY",
17056 (IntervalUnit::Day, true) => "DAYS",
17057 (IntervalUnit::Hour, false) => "HOUR",
17058 (IntervalUnit::Hour, true) => "HOURS",
17059 (IntervalUnit::Minute, false) => "MINUTE",
17060 (IntervalUnit::Minute, true) => "MINUTES",
17061 (IntervalUnit::Second, false) => "SECOND",
17062 (IntervalUnit::Second, true) => "SECONDS",
17063 (IntervalUnit::Millisecond, false) => "MILLISECOND",
17064 (IntervalUnit::Millisecond, true) => "MILLISECONDS",
17065 (IntervalUnit::Microsecond, false) => "MICROSECOND",
17066 (IntervalUnit::Microsecond, true) => "MICROSECONDS",
17067 (IntervalUnit::Nanosecond, false) => "NANOSECOND",
17068 (IntervalUnit::Nanosecond, true) => "NANOSECONDS",
17069 }
17070 }
17071
17072 fn write_interval_unit_spec(&mut self, unit_spec: &IntervalUnitSpec) -> Result<()> {
17073 match unit_spec {
17074 IntervalUnitSpec::Simple { unit, use_plural } => {
17075 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
17077 self.write_simple_interval_unit(unit, effective_plural);
17078 }
17079 IntervalUnitSpec::Span(span) => {
17080 self.write_simple_interval_unit(&span.this, false);
17081 self.write_space();
17082 self.write_keyword("TO");
17083 self.write_space();
17084 self.write_simple_interval_unit(&span.expression, false);
17085 }
17086 IntervalUnitSpec::ExprSpan(span) => {
17087 self.generate_expression(&span.this)?;
17089 self.write_space();
17090 self.write_keyword("TO");
17091 self.write_space();
17092 self.generate_expression(&span.expression)?;
17093 }
17094 IntervalUnitSpec::Expr(expr) => {
17095 self.generate_expression(expr)?;
17096 }
17097 }
17098 Ok(())
17099 }
17100
17101 fn write_simple_interval_unit(&mut self, unit: &IntervalUnit, use_plural: bool) {
17102 match (unit, use_plural) {
17104 (IntervalUnit::Year, false) => self.write_keyword("YEAR"),
17105 (IntervalUnit::Year, true) => self.write_keyword("YEARS"),
17106 (IntervalUnit::Quarter, false) => self.write_keyword("QUARTER"),
17107 (IntervalUnit::Quarter, true) => self.write_keyword("QUARTERS"),
17108 (IntervalUnit::Month, false) => self.write_keyword("MONTH"),
17109 (IntervalUnit::Month, true) => self.write_keyword("MONTHS"),
17110 (IntervalUnit::Week, false) => self.write_keyword("WEEK"),
17111 (IntervalUnit::Week, true) => self.write_keyword("WEEKS"),
17112 (IntervalUnit::Day, false) => self.write_keyword("DAY"),
17113 (IntervalUnit::Day, true) => self.write_keyword("DAYS"),
17114 (IntervalUnit::Hour, false) => self.write_keyword("HOUR"),
17115 (IntervalUnit::Hour, true) => self.write_keyword("HOURS"),
17116 (IntervalUnit::Minute, false) => self.write_keyword("MINUTE"),
17117 (IntervalUnit::Minute, true) => self.write_keyword("MINUTES"),
17118 (IntervalUnit::Second, false) => self.write_keyword("SECOND"),
17119 (IntervalUnit::Second, true) => self.write_keyword("SECONDS"),
17120 (IntervalUnit::Millisecond, false) => self.write_keyword("MILLISECOND"),
17121 (IntervalUnit::Millisecond, true) => self.write_keyword("MILLISECONDS"),
17122 (IntervalUnit::Microsecond, false) => self.write_keyword("MICROSECOND"),
17123 (IntervalUnit::Microsecond, true) => self.write_keyword("MICROSECONDS"),
17124 (IntervalUnit::Nanosecond, false) => self.write_keyword("NANOSECOND"),
17125 (IntervalUnit::Nanosecond, true) => self.write_keyword("NANOSECONDS"),
17126 }
17127 }
17128
17129 fn write_redshift_date_part(&mut self, expr: &Expression) {
17132 let part_str = self.extract_date_part_string(expr);
17133 if let Some(part) = part_str {
17134 let normalized = self.normalize_date_part(&part);
17135 self.write_keyword(&normalized);
17136 } else {
17137 let _ = self.generate_expression(expr);
17139 }
17140 }
17141
17142 fn write_redshift_date_part_quoted(&mut self, expr: &Expression) {
17145 let part_str = self.extract_date_part_string(expr);
17146 if let Some(part) = part_str {
17147 let normalized = self.normalize_date_part(&part);
17148 self.write("'");
17149 self.write(&normalized);
17150 self.write("'");
17151 } else {
17152 let _ = self.generate_expression(expr);
17154 }
17155 }
17156
17157 fn extract_date_part_string(&self, expr: &Expression) -> Option<String> {
17159 match expr {
17160 Expression::Literal(crate::expressions::Literal::String(s)) => Some(s.clone()),
17161 Expression::Identifier(id) => Some(id.name.clone()),
17162 Expression::Column(col) if col.table.is_none() => {
17163 Some(col.name.name.clone())
17165 }
17166 _ => None,
17167 }
17168 }
17169
17170 fn normalize_date_part(&self, part: &str) -> String {
17173 let lower = part.to_lowercase();
17174 match lower.as_str() {
17175 "day" | "days" | "d" => "DAY".to_string(),
17176 "month" | "months" | "mon" | "mm" => "MONTH".to_string(),
17177 "year" | "years" | "y" | "yy" | "yyyy" => "YEAR".to_string(),
17178 "week" | "weeks" | "w" | "wk" => "WEEK".to_string(),
17179 "hour" | "hours" | "h" | "hh" => "HOUR".to_string(),
17180 "minute" | "minutes" | "m" | "mi" | "n" => "MINUTE".to_string(),
17181 "second" | "seconds" | "s" | "ss" => "SECOND".to_string(),
17182 "millisecond" | "milliseconds" | "ms" => "MILLISECOND".to_string(),
17183 "microsecond" | "microseconds" | "us" => "MICROSECOND".to_string(),
17184 "quarter" | "quarters" | "q" | "qq" => "QUARTER".to_string(),
17185 _ => part.to_uppercase(),
17186 }
17187 }
17188
17189 fn write_datetime_field(&mut self, field: &DateTimeField) {
17190 match field {
17191 DateTimeField::Year => self.write_keyword("YEAR"),
17192 DateTimeField::Month => self.write_keyword("MONTH"),
17193 DateTimeField::Day => self.write_keyword("DAY"),
17194 DateTimeField::Hour => self.write_keyword("HOUR"),
17195 DateTimeField::Minute => self.write_keyword("MINUTE"),
17196 DateTimeField::Second => self.write_keyword("SECOND"),
17197 DateTimeField::Millisecond => self.write_keyword("MILLISECOND"),
17198 DateTimeField::Microsecond => self.write_keyword("MICROSECOND"),
17199 DateTimeField::DayOfWeek => {
17200 let name = match self.config.dialect {
17201 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFWEEK",
17202 _ => "DOW",
17203 };
17204 self.write_keyword(name);
17205 }
17206 DateTimeField::DayOfYear => {
17207 let name = match self.config.dialect {
17208 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFYEAR",
17209 _ => "DOY",
17210 };
17211 self.write_keyword(name);
17212 }
17213 DateTimeField::Week => self.write_keyword("WEEK"),
17214 DateTimeField::WeekWithModifier(modifier) => {
17215 self.write_keyword("WEEK");
17216 self.write("(");
17217 self.write(modifier);
17218 self.write(")");
17219 }
17220 DateTimeField::Quarter => self.write_keyword("QUARTER"),
17221 DateTimeField::Epoch => self.write_keyword("EPOCH"),
17222 DateTimeField::Timezone => self.write_keyword("TIMEZONE"),
17223 DateTimeField::TimezoneHour => self.write_keyword("TIMEZONE_HOUR"),
17224 DateTimeField::TimezoneMinute => self.write_keyword("TIMEZONE_MINUTE"),
17225 DateTimeField::Date => self.write_keyword("DATE"),
17226 DateTimeField::Time => self.write_keyword("TIME"),
17227 DateTimeField::Custom(name) => self.write(name),
17228 }
17229 }
17230
17231 fn write_datetime_field_lower(&mut self, field: &DateTimeField) {
17233 match field {
17234 DateTimeField::Year => self.write("year"),
17235 DateTimeField::Month => self.write("month"),
17236 DateTimeField::Day => self.write("day"),
17237 DateTimeField::Hour => self.write("hour"),
17238 DateTimeField::Minute => self.write("minute"),
17239 DateTimeField::Second => self.write("second"),
17240 DateTimeField::Millisecond => self.write("millisecond"),
17241 DateTimeField::Microsecond => self.write("microsecond"),
17242 DateTimeField::DayOfWeek => self.write("dow"),
17243 DateTimeField::DayOfYear => self.write("doy"),
17244 DateTimeField::Week => self.write("week"),
17245 DateTimeField::WeekWithModifier(modifier) => {
17246 self.write("week(");
17247 self.write(modifier);
17248 self.write(")");
17249 }
17250 DateTimeField::Quarter => self.write("quarter"),
17251 DateTimeField::Epoch => self.write("epoch"),
17252 DateTimeField::Timezone => self.write("timezone"),
17253 DateTimeField::TimezoneHour => self.write("timezone_hour"),
17254 DateTimeField::TimezoneMinute => self.write("timezone_minute"),
17255 DateTimeField::Date => self.write("date"),
17256 DateTimeField::Time => self.write("time"),
17257 DateTimeField::Custom(name) => self.write(name),
17258 }
17259 }
17260
17261 fn generate_simple_func(&mut self, name: &str, arg: &Expression) -> Result<()> {
17264 self.write_keyword(name);
17265 self.write("(");
17266 self.generate_expression(arg)?;
17267 self.write(")");
17268 Ok(())
17269 }
17270
17271 fn generate_unary_func(
17273 &mut self,
17274 default_name: &str,
17275 f: &crate::expressions::UnaryFunc,
17276 ) -> Result<()> {
17277 let name = f.original_name.as_deref().unwrap_or(default_name);
17278 self.write_keyword(name);
17279 self.write("(");
17280 self.generate_expression(&f.this)?;
17281 self.write(")");
17282 Ok(())
17283 }
17284
17285 fn generate_sqrt_cbrt(
17287 &mut self,
17288 f: &crate::expressions::UnaryFunc,
17289 func_name: &str,
17290 _op: &str,
17291 ) -> Result<()> {
17292 self.write_keyword(func_name);
17295 self.write("(");
17296 self.generate_expression(&f.this)?;
17297 self.write(")");
17298 Ok(())
17299 }
17300
17301 fn generate_binary_func(
17302 &mut self,
17303 name: &str,
17304 arg1: &Expression,
17305 arg2: &Expression,
17306 ) -> Result<()> {
17307 self.write_keyword(name);
17308 self.write("(");
17309 self.generate_expression(arg1)?;
17310 self.write(", ");
17311 self.generate_expression(arg2)?;
17312 self.write(")");
17313 Ok(())
17314 }
17315
17316 fn generate_char_func(&mut self, f: &crate::expressions::CharFunc) -> Result<()> {
17320 let func_name = f.name.as_deref().unwrap_or("CHAR");
17322 self.write_keyword(func_name);
17323 self.write("(");
17324 for (i, arg) in f.args.iter().enumerate() {
17325 if i > 0 {
17326 self.write(", ");
17327 }
17328 self.generate_expression(arg)?;
17329 }
17330 if let Some(ref charset) = f.charset {
17331 self.write(" ");
17332 self.write_keyword("USING");
17333 self.write(" ");
17334 self.write(charset);
17335 }
17336 self.write(")");
17337 Ok(())
17338 }
17339
17340 fn generate_power(&mut self, f: &BinaryFunc) -> Result<()> {
17341 use crate::dialects::DialectType;
17342
17343 match self.config.dialect {
17344 Some(DialectType::Teradata) => {
17345 self.generate_expression(&f.this)?;
17347 self.write(" ** ");
17348 self.generate_expression(&f.expression)?;
17349 Ok(())
17350 }
17351 _ => {
17352 self.generate_binary_func("POWER", &f.this, &f.expression)
17354 }
17355 }
17356 }
17357
17358 fn generate_vararg_func(&mut self, name: &str, args: &[Expression]) -> Result<()> {
17359 self.write_func_name(name);
17360 self.write("(");
17361 for (i, arg) in args.iter().enumerate() {
17362 if i > 0 {
17363 self.write(", ");
17364 }
17365 self.generate_expression(arg)?;
17366 }
17367 self.write(")");
17368 Ok(())
17369 }
17370
17371 fn generate_concat_ws(&mut self, f: &ConcatWs) -> Result<()> {
17374 self.write_keyword("CONCAT_WS");
17375 self.write("(");
17376 self.generate_expression(&f.separator)?;
17377 for expr in &f.expressions {
17378 self.write(", ");
17379 self.generate_expression(expr)?;
17380 }
17381 self.write(")");
17382 Ok(())
17383 }
17384
17385 fn generate_substring(&mut self, f: &SubstringFunc) -> Result<()> {
17386 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
17388 if is_oracle {
17389 self.write_keyword("SUBSTR");
17390 } else {
17391 self.write_keyword("SUBSTRING");
17392 }
17393 self.write("(");
17394 self.generate_expression(&f.this)?;
17395 let force_from_for = matches!(self.config.dialect, Some(DialectType::PostgreSQL));
17397 let use_comma_syntax = matches!(
17399 self.config.dialect,
17400 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
17401 );
17402 if (f.from_for_syntax || force_from_for) && !use_comma_syntax {
17403 self.write_space();
17405 self.write_keyword("FROM");
17406 self.write_space();
17407 self.generate_expression(&f.start)?;
17408 if let Some(length) = &f.length {
17409 self.write_space();
17410 self.write_keyword("FOR");
17411 self.write_space();
17412 self.generate_expression(length)?;
17413 }
17414 } else {
17415 self.write(", ");
17417 self.generate_expression(&f.start)?;
17418 if let Some(length) = &f.length {
17419 self.write(", ");
17420 self.generate_expression(length)?;
17421 }
17422 }
17423 self.write(")");
17424 Ok(())
17425 }
17426
17427 fn generate_overlay(&mut self, f: &OverlayFunc) -> Result<()> {
17428 self.write_keyword("OVERLAY");
17429 self.write("(");
17430 self.generate_expression(&f.this)?;
17431 self.write_space();
17432 self.write_keyword("PLACING");
17433 self.write_space();
17434 self.generate_expression(&f.replacement)?;
17435 self.write_space();
17436 self.write_keyword("FROM");
17437 self.write_space();
17438 self.generate_expression(&f.from)?;
17439 if let Some(length) = &f.length {
17440 self.write_space();
17441 self.write_keyword("FOR");
17442 self.write_space();
17443 self.generate_expression(length)?;
17444 }
17445 self.write(")");
17446 Ok(())
17447 }
17448
17449 fn generate_trim(&mut self, f: &TrimFunc) -> Result<()> {
17450 if f.position_explicit && f.characters.is_none() {
17453 match f.position {
17454 TrimPosition::Leading => {
17455 self.write_keyword("LTRIM");
17456 self.write("(");
17457 self.generate_expression(&f.this)?;
17458 self.write(")");
17459 return Ok(());
17460 }
17461 TrimPosition::Trailing => {
17462 self.write_keyword("RTRIM");
17463 self.write("(");
17464 self.generate_expression(&f.this)?;
17465 self.write(")");
17466 return Ok(());
17467 }
17468 TrimPosition::Both => {
17469 }
17472 }
17473 }
17474
17475 self.write_keyword("TRIM");
17476 self.write("(");
17477 let force_standard = f.characters.is_some()
17480 && !f.sql_standard_syntax
17481 && matches!(
17482 self.config.dialect,
17483 Some(DialectType::Hive)
17484 | Some(DialectType::Spark)
17485 | Some(DialectType::Databricks)
17486 | Some(DialectType::ClickHouse)
17487 );
17488 let use_standard = (f.sql_standard_syntax || force_standard)
17489 && !(f.position_explicit
17490 && f.characters.is_none()
17491 && matches!(f.position, TrimPosition::Both));
17492 if use_standard {
17493 if f.position_explicit {
17496 match f.position {
17497 TrimPosition::Both => self.write_keyword("BOTH"),
17498 TrimPosition::Leading => self.write_keyword("LEADING"),
17499 TrimPosition::Trailing => self.write_keyword("TRAILING"),
17500 }
17501 self.write_space();
17502 }
17503 if let Some(chars) = &f.characters {
17504 self.generate_expression(chars)?;
17505 self.write_space();
17506 }
17507 self.write_keyword("FROM");
17508 self.write_space();
17509 self.generate_expression(&f.this)?;
17510 } else {
17511 self.generate_expression(&f.this)?;
17513 if let Some(chars) = &f.characters {
17514 self.write(", ");
17515 self.generate_expression(chars)?;
17516 }
17517 }
17518 self.write(")");
17519 Ok(())
17520 }
17521
17522 fn generate_replace(&mut self, f: &ReplaceFunc) -> Result<()> {
17523 self.write_keyword("REPLACE");
17524 self.write("(");
17525 self.generate_expression(&f.this)?;
17526 self.write(", ");
17527 self.generate_expression(&f.old)?;
17528 self.write(", ");
17529 self.generate_expression(&f.new)?;
17530 self.write(")");
17531 Ok(())
17532 }
17533
17534 fn generate_left_right(&mut self, name: &str, f: &LeftRightFunc) -> Result<()> {
17535 self.write_keyword(name);
17536 self.write("(");
17537 self.generate_expression(&f.this)?;
17538 self.write(", ");
17539 self.generate_expression(&f.length)?;
17540 self.write(")");
17541 Ok(())
17542 }
17543
17544 fn generate_repeat(&mut self, f: &RepeatFunc) -> Result<()> {
17545 self.write_keyword("REPEAT");
17546 self.write("(");
17547 self.generate_expression(&f.this)?;
17548 self.write(", ");
17549 self.generate_expression(&f.times)?;
17550 self.write(")");
17551 Ok(())
17552 }
17553
17554 fn generate_pad(&mut self, name: &str, f: &PadFunc) -> Result<()> {
17555 self.write_keyword(name);
17556 self.write("(");
17557 self.generate_expression(&f.this)?;
17558 self.write(", ");
17559 self.generate_expression(&f.length)?;
17560 if let Some(fill) = &f.fill {
17561 self.write(", ");
17562 self.generate_expression(fill)?;
17563 }
17564 self.write(")");
17565 Ok(())
17566 }
17567
17568 fn generate_split(&mut self, f: &SplitFunc) -> Result<()> {
17569 self.write_keyword("SPLIT");
17570 self.write("(");
17571 self.generate_expression(&f.this)?;
17572 self.write(", ");
17573 self.generate_expression(&f.delimiter)?;
17574 self.write(")");
17575 Ok(())
17576 }
17577
17578 fn generate_regexp_like(&mut self, f: &RegexpFunc) -> Result<()> {
17579 use crate::dialects::DialectType;
17580 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) && f.flags.is_none() {
17582 self.generate_expression(&f.this)?;
17583 self.write(" ~ ");
17584 self.generate_expression(&f.pattern)?;
17585 } else if matches!(
17586 self.config.dialect,
17587 Some(DialectType::SingleStore)
17588 | Some(DialectType::Spark)
17589 | Some(DialectType::Hive)
17590 | Some(DialectType::Databricks)
17591 ) && f.flags.is_none()
17592 {
17593 self.generate_expression(&f.this)?;
17595 self.write_keyword(" RLIKE ");
17596 self.generate_expression(&f.pattern)?;
17597 } else if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
17598 self.write_keyword("REGEXP");
17600 self.write("(");
17601 self.generate_expression(&f.this)?;
17602 self.write(", ");
17603 self.generate_expression(&f.pattern)?;
17604 if let Some(flags) = &f.flags {
17605 self.write(", ");
17606 self.generate_expression(flags)?;
17607 }
17608 self.write(")");
17609 } else {
17610 self.write_keyword("REGEXP_LIKE");
17611 self.write("(");
17612 self.generate_expression(&f.this)?;
17613 self.write(", ");
17614 self.generate_expression(&f.pattern)?;
17615 if let Some(flags) = &f.flags {
17616 self.write(", ");
17617 self.generate_expression(flags)?;
17618 }
17619 self.write(")");
17620 }
17621 Ok(())
17622 }
17623
17624 fn generate_regexp_replace(&mut self, f: &RegexpReplaceFunc) -> Result<()> {
17625 self.write_keyword("REGEXP_REPLACE");
17626 self.write("(");
17627 self.generate_expression(&f.this)?;
17628 self.write(", ");
17629 self.generate_expression(&f.pattern)?;
17630 self.write(", ");
17631 self.generate_expression(&f.replacement)?;
17632 if let Some(flags) = &f.flags {
17633 self.write(", ");
17634 self.generate_expression(flags)?;
17635 }
17636 self.write(")");
17637 Ok(())
17638 }
17639
17640 fn generate_regexp_extract(&mut self, f: &RegexpExtractFunc) -> Result<()> {
17641 self.write_keyword("REGEXP_EXTRACT");
17642 self.write("(");
17643 self.generate_expression(&f.this)?;
17644 self.write(", ");
17645 self.generate_expression(&f.pattern)?;
17646 if let Some(group) = &f.group {
17647 self.write(", ");
17648 self.generate_expression(group)?;
17649 }
17650 self.write(")");
17651 Ok(())
17652 }
17653
17654 fn generate_round(&mut self, f: &RoundFunc) -> Result<()> {
17657 self.write_keyword("ROUND");
17658 self.write("(");
17659 self.generate_expression(&f.this)?;
17660 if let Some(decimals) = &f.decimals {
17661 self.write(", ");
17662 self.generate_expression(decimals)?;
17663 }
17664 self.write(")");
17665 Ok(())
17666 }
17667
17668 fn generate_floor(&mut self, f: &FloorFunc) -> Result<()> {
17669 self.write_keyword("FLOOR");
17670 self.write("(");
17671 self.generate_expression(&f.this)?;
17672 if let Some(to) = &f.to {
17674 self.write(" ");
17675 self.write_keyword("TO");
17676 self.write(" ");
17677 self.generate_expression(to)?;
17678 } else if let Some(scale) = &f.scale {
17679 self.write(", ");
17680 self.generate_expression(scale)?;
17681 }
17682 self.write(")");
17683 Ok(())
17684 }
17685
17686 fn generate_ceil(&mut self, f: &CeilFunc) -> Result<()> {
17687 self.write_keyword("CEIL");
17688 self.write("(");
17689 self.generate_expression(&f.this)?;
17690 if let Some(to) = &f.to {
17692 self.write(" ");
17693 self.write_keyword("TO");
17694 self.write(" ");
17695 self.generate_expression(to)?;
17696 } else if let Some(decimals) = &f.decimals {
17697 self.write(", ");
17698 self.generate_expression(decimals)?;
17699 }
17700 self.write(")");
17701 Ok(())
17702 }
17703
17704 fn generate_log(&mut self, f: &LogFunc) -> Result<()> {
17705 use crate::expressions::Literal;
17706
17707 if let Some(base) = &f.base {
17708 if self.is_log_base_none() {
17711 if matches!(base, Expression::Literal(Literal::Number(s)) if s == "2") {
17712 self.write_func_name("LOG2");
17713 self.write("(");
17714 self.generate_expression(&f.this)?;
17715 self.write(")");
17716 return Ok(());
17717 } else if matches!(base, Expression::Literal(Literal::Number(s)) if s == "10") {
17718 self.write_func_name("LOG10");
17719 self.write("(");
17720 self.generate_expression(&f.this)?;
17721 self.write(")");
17722 return Ok(());
17723 }
17724 }
17726
17727 self.write_func_name("LOG");
17728 self.write("(");
17729 if self.is_log_value_first() {
17730 self.generate_expression(&f.this)?;
17732 self.write(", ");
17733 self.generate_expression(base)?;
17734 } else {
17735 self.generate_expression(base)?;
17737 self.write(", ");
17738 self.generate_expression(&f.this)?;
17739 }
17740 self.write(")");
17741 } else {
17742 self.write_func_name("LOG");
17744 self.write("(");
17745 self.generate_expression(&f.this)?;
17746 self.write(")");
17747 }
17748 Ok(())
17749 }
17750
17751 fn is_log_value_first(&self) -> bool {
17754 use crate::dialects::DialectType;
17755 matches!(
17756 self.config.dialect,
17757 Some(DialectType::BigQuery)
17758 | Some(DialectType::TSQL)
17759 | Some(DialectType::Tableau)
17760 | Some(DialectType::Fabric)
17761 )
17762 }
17763
17764 fn is_log_base_none(&self) -> bool {
17767 use crate::dialects::DialectType;
17768 matches!(
17769 self.config.dialect,
17770 Some(DialectType::Presto)
17771 | Some(DialectType::Trino)
17772 | Some(DialectType::ClickHouse)
17773 | Some(DialectType::Athena)
17774 )
17775 }
17776
17777 fn generate_current_time(&mut self, f: &CurrentTime) -> Result<()> {
17780 self.write_keyword("CURRENT_TIME");
17781 if let Some(precision) = f.precision {
17782 self.write(&format!("({})", precision));
17783 }
17784 Ok(())
17785 }
17786
17787 fn generate_current_timestamp(&mut self, f: &CurrentTimestamp) -> Result<()> {
17788 use crate::dialects::DialectType;
17789
17790 if f.sysdate {
17792 match self.config.dialect {
17793 Some(DialectType::Oracle) | Some(DialectType::Redshift) => {
17794 self.write_keyword("SYSDATE");
17795 return Ok(());
17796 }
17797 Some(DialectType::Snowflake) => {
17798 self.write_keyword("SYSDATE");
17800 self.write("()");
17801 return Ok(());
17802 }
17803 _ => {
17804 }
17806 }
17807 }
17808
17809 self.write_keyword("CURRENT_TIMESTAMP");
17810 if let Some(precision) = f.precision {
17812 self.write(&format!("({})", precision));
17813 } else if matches!(
17814 self.config.dialect,
17815 Some(crate::dialects::DialectType::MySQL)
17816 | Some(crate::dialects::DialectType::SingleStore)
17817 | Some(crate::dialects::DialectType::TiDB)
17818 | Some(crate::dialects::DialectType::Spark)
17819 | Some(crate::dialects::DialectType::Hive)
17820 | Some(crate::dialects::DialectType::Databricks)
17821 | Some(crate::dialects::DialectType::ClickHouse)
17822 | Some(crate::dialects::DialectType::BigQuery)
17823 | Some(crate::dialects::DialectType::Snowflake)
17824 ) {
17825 self.write("()");
17826 }
17827 Ok(())
17828 }
17829
17830 fn generate_at_time_zone(&mut self, f: &AtTimeZone) -> Result<()> {
17831 if self.config.dialect == Some(DialectType::Exasol) {
17833 self.write_keyword("CONVERT_TZ");
17834 self.write("(");
17835 self.generate_expression(&f.this)?;
17836 self.write(", 'UTC', ");
17837 self.generate_expression(&f.zone)?;
17838 self.write(")");
17839 return Ok(());
17840 }
17841
17842 self.generate_expression(&f.this)?;
17843 self.write_space();
17844 self.write_keyword("AT TIME ZONE");
17845 self.write_space();
17846 self.generate_expression(&f.zone)?;
17847 Ok(())
17848 }
17849
17850 fn generate_date_add(&mut self, f: &DateAddFunc, name: &str) -> Result<()> {
17851 use crate::dialects::DialectType;
17852
17853 let is_presto_like = matches!(
17856 self.config.dialect,
17857 Some(DialectType::Presto) | Some(DialectType::Trino)
17858 );
17859
17860 if is_presto_like {
17861 self.write_keyword(name);
17862 self.write("(");
17863 self.write("'");
17865 self.write_simple_interval_unit(&f.unit, false);
17866 self.write("'");
17867 self.write(", ");
17868 let needs_cast = !self.returns_integer_type(&f.interval);
17870 if needs_cast {
17871 self.write_keyword("CAST");
17872 self.write("(");
17873 }
17874 self.generate_expression(&f.interval)?;
17875 if needs_cast {
17876 self.write_space();
17877 self.write_keyword("AS");
17878 self.write_space();
17879 self.write_keyword("BIGINT");
17880 self.write(")");
17881 }
17882 self.write(", ");
17883 self.generate_expression(&f.this)?;
17884 self.write(")");
17885 } else {
17886 self.write_keyword(name);
17887 self.write("(");
17888 self.generate_expression(&f.this)?;
17889 self.write(", ");
17890 self.write_keyword("INTERVAL");
17891 self.write_space();
17892 self.generate_expression(&f.interval)?;
17893 self.write_space();
17894 self.write_simple_interval_unit(&f.unit, false); self.write(")");
17896 }
17897 Ok(())
17898 }
17899
17900 fn returns_integer_type(&self, expr: &Expression) -> bool {
17903 use crate::expressions::{DataType, Literal};
17904 match expr {
17905 Expression::Literal(Literal::Number(n)) => !n.contains('.'),
17907
17908 Expression::Floor(f) => self.returns_integer_type(&f.this),
17910
17911 Expression::Round(f) => {
17913 f.decimals.is_none() && self.returns_integer_type(&f.this)
17915 }
17916
17917 Expression::Sign(f) => self.returns_integer_type(&f.this),
17919
17920 Expression::Abs(f) => self.returns_integer_type(&f.this),
17922
17923 Expression::Mul(op) => {
17925 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
17926 }
17927 Expression::Add(op) => {
17928 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
17929 }
17930 Expression::Sub(op) => {
17931 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
17932 }
17933 Expression::Mod(op) => self.returns_integer_type(&op.left),
17934
17935 Expression::Cast(c) => matches!(
17937 &c.to,
17938 DataType::BigInt { .. }
17939 | DataType::Int { .. }
17940 | DataType::SmallInt { .. }
17941 | DataType::TinyInt { .. }
17942 ),
17943
17944 Expression::Neg(op) => self.returns_integer_type(&op.this),
17946
17947 Expression::Paren(p) => self.returns_integer_type(&p.this),
17949
17950 _ => false,
17953 }
17954 }
17955
17956 fn generate_datediff(&mut self, f: &DateDiffFunc) -> Result<()> {
17957 self.write_keyword("DATEDIFF");
17958 self.write("(");
17959 if let Some(unit) = &f.unit {
17960 self.write_simple_interval_unit(unit, false); self.write(", ");
17962 }
17963 self.generate_expression(&f.this)?;
17964 self.write(", ");
17965 self.generate_expression(&f.expression)?;
17966 self.write(")");
17967 Ok(())
17968 }
17969
17970 fn generate_date_trunc(&mut self, f: &DateTruncFunc) -> Result<()> {
17971 self.write_keyword("DATE_TRUNC");
17972 self.write("('");
17973 self.write_datetime_field(&f.unit);
17974 self.write("', ");
17975 self.generate_expression(&f.this)?;
17976 self.write(")");
17977 Ok(())
17978 }
17979
17980 fn generate_last_day(&mut self, f: &LastDayFunc) -> Result<()> {
17981 use crate::dialects::DialectType;
17982 use crate::expressions::DateTimeField;
17983
17984 self.write_keyword("LAST_DAY");
17985 self.write("(");
17986 self.generate_expression(&f.this)?;
17987 if let Some(unit) = &f.unit {
17988 self.write(", ");
17989 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
17992 if let DateTimeField::WeekWithModifier(_) = unit {
17993 self.write_keyword("WEEK");
17994 } else {
17995 self.write_datetime_field(unit);
17996 }
17997 } else {
17998 self.write_datetime_field(unit);
17999 }
18000 }
18001 self.write(")");
18002 Ok(())
18003 }
18004
18005 fn generate_extract(&mut self, f: &ExtractFunc) -> Result<()> {
18006 if matches!(
18008 self.config.dialect,
18009 Some(DialectType::TSQL) | Some(DialectType::Fabric)
18010 ) {
18011 self.write_keyword("DATEPART");
18012 self.write("(");
18013 self.write_datetime_field(&f.field);
18014 self.write(", ");
18015 self.generate_expression(&f.this)?;
18016 self.write(")");
18017 return Ok(());
18018 }
18019 self.write_keyword("EXTRACT");
18020 self.write("(");
18021 if matches!(
18023 self.config.dialect,
18024 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
18025 ) {
18026 self.write_datetime_field_lower(&f.field);
18027 } else {
18028 self.write_datetime_field(&f.field);
18029 }
18030 self.write_space();
18031 self.write_keyword("FROM");
18032 self.write_space();
18033 self.generate_expression(&f.this)?;
18034 self.write(")");
18035 Ok(())
18036 }
18037
18038 fn generate_to_date(&mut self, f: &ToDateFunc) -> Result<()> {
18039 self.write_keyword("TO_DATE");
18040 self.write("(");
18041 self.generate_expression(&f.this)?;
18042 if let Some(format) = &f.format {
18043 self.write(", ");
18044 self.generate_expression(format)?;
18045 }
18046 self.write(")");
18047 Ok(())
18048 }
18049
18050 fn generate_to_timestamp(&mut self, f: &ToTimestampFunc) -> Result<()> {
18051 self.write_keyword("TO_TIMESTAMP");
18052 self.write("(");
18053 self.generate_expression(&f.this)?;
18054 if let Some(format) = &f.format {
18055 self.write(", ");
18056 self.generate_expression(format)?;
18057 }
18058 self.write(")");
18059 Ok(())
18060 }
18061
18062 fn generate_if_func(&mut self, f: &IfFunc) -> Result<()> {
18065 use crate::dialects::DialectType;
18066
18067 if self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic) {
18069 self.write_keyword("CASE WHEN");
18070 self.write_space();
18071 self.generate_expression(&f.condition)?;
18072 self.write_space();
18073 self.write_keyword("THEN");
18074 self.write_space();
18075 self.generate_expression(&f.true_value)?;
18076 if let Some(false_val) = &f.false_value {
18077 self.write_space();
18078 self.write_keyword("ELSE");
18079 self.write_space();
18080 self.generate_expression(false_val)?;
18081 }
18082 self.write_space();
18083 self.write_keyword("END");
18084 return Ok(());
18085 }
18086
18087 if self.config.dialect == Some(DialectType::Exasol) {
18089 self.write_keyword("IF");
18090 self.write_space();
18091 self.generate_expression(&f.condition)?;
18092 self.write_space();
18093 self.write_keyword("THEN");
18094 self.write_space();
18095 self.generate_expression(&f.true_value)?;
18096 if let Some(false_val) = &f.false_value {
18097 self.write_space();
18098 self.write_keyword("ELSE");
18099 self.write_space();
18100 self.generate_expression(false_val)?;
18101 }
18102 self.write_space();
18103 self.write_keyword("ENDIF");
18104 return Ok(());
18105 }
18106
18107 let func_name = match self.config.dialect {
18109 Some(DialectType::Snowflake) => "IFF",
18110 Some(DialectType::SQLite) | Some(DialectType::TSQL) => "IIF",
18111 Some(DialectType::Drill) => "`IF`",
18112 _ => "IF",
18113 };
18114 self.write(func_name);
18115 self.write("(");
18116 self.generate_expression(&f.condition)?;
18117 self.write(", ");
18118 self.generate_expression(&f.true_value)?;
18119 if let Some(false_val) = &f.false_value {
18120 self.write(", ");
18121 self.generate_expression(false_val)?;
18122 }
18123 self.write(")");
18124 Ok(())
18125 }
18126
18127 fn generate_nvl2(&mut self, f: &Nvl2Func) -> Result<()> {
18128 self.write_keyword("NVL2");
18129 self.write("(");
18130 self.generate_expression(&f.this)?;
18131 self.write(", ");
18132 self.generate_expression(&f.true_value)?;
18133 self.write(", ");
18134 self.generate_expression(&f.false_value)?;
18135 self.write(")");
18136 Ok(())
18137 }
18138
18139 fn generate_count(&mut self, f: &CountFunc) -> Result<()> {
18142 let count_name = match self.config.normalize_functions {
18144 NormalizeFunctions::Upper => "COUNT".to_string(),
18145 NormalizeFunctions::Lower => "count".to_string(),
18146 NormalizeFunctions::None => f
18147 .original_name
18148 .clone()
18149 .unwrap_or_else(|| "COUNT".to_string()),
18150 };
18151 self.write(&count_name);
18152 self.write("(");
18153 if f.distinct {
18154 self.write_keyword("DISTINCT");
18155 self.write_space();
18156 }
18157 if f.star {
18158 self.write("*");
18159 } else if let Some(ref expr) = f.this {
18160 if let Expression::Tuple(tuple) = expr {
18162 let needs_transform =
18166 f.distinct && tuple.expressions.len() > 1 && !self.config.multi_arg_distinct;
18167
18168 if needs_transform {
18169 self.write_keyword("CASE");
18171 for e in &tuple.expressions {
18172 self.write_space();
18173 self.write_keyword("WHEN");
18174 self.write_space();
18175 self.generate_expression(e)?;
18176 self.write_space();
18177 self.write_keyword("IS NULL THEN NULL");
18178 }
18179 self.write_space();
18180 self.write_keyword("ELSE");
18181 self.write(" (");
18182 for (i, e) in tuple.expressions.iter().enumerate() {
18183 if i > 0 {
18184 self.write(", ");
18185 }
18186 self.generate_expression(e)?;
18187 }
18188 self.write(")");
18189 self.write_space();
18190 self.write_keyword("END");
18191 } else {
18192 for (i, e) in tuple.expressions.iter().enumerate() {
18193 if i > 0 {
18194 self.write(", ");
18195 }
18196 self.generate_expression(e)?;
18197 }
18198 }
18199 } else {
18200 self.generate_expression(expr)?;
18201 }
18202 }
18203 if let Some(ignore) = f.ignore_nulls {
18205 self.write_space();
18206 if ignore {
18207 self.write_keyword("IGNORE NULLS");
18208 } else {
18209 self.write_keyword("RESPECT NULLS");
18210 }
18211 }
18212 self.write(")");
18213 if let Some(ref filter) = f.filter {
18214 self.write_space();
18215 self.write_keyword("FILTER");
18216 self.write("(");
18217 self.write_keyword("WHERE");
18218 self.write_space();
18219 self.generate_expression(filter)?;
18220 self.write(")");
18221 }
18222 Ok(())
18223 }
18224
18225 fn generate_agg_func(&mut self, name: &str, f: &AggFunc) -> Result<()> {
18226 let func_name = match self.config.normalize_functions {
18228 NormalizeFunctions::Upper => name.to_uppercase(),
18229 NormalizeFunctions::Lower => name.to_lowercase(),
18230 NormalizeFunctions::None => {
18231 if let Some(ref original) = f.name {
18234 original.clone()
18235 } else {
18236 name.to_lowercase()
18237 }
18238 }
18239 };
18240 self.write(&func_name);
18241 self.write("(");
18242 if f.distinct {
18243 self.write_keyword("DISTINCT");
18244 self.write_space();
18245 }
18246 if !matches!(f.this, Expression::Null(_)) {
18248 self.generate_expression(&f.this)?;
18249 }
18250 if self.config.ignore_nulls_in_func
18253 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
18254 {
18255 match f.ignore_nulls {
18256 Some(true) => {
18257 self.write_space();
18258 self.write_keyword("IGNORE NULLS");
18259 }
18260 Some(false) => {
18261 self.write_space();
18262 self.write_keyword("RESPECT NULLS");
18263 }
18264 None => {}
18265 }
18266 }
18267 if let Some((ref expr, is_max)) = f.having_max {
18270 self.write_space();
18271 self.write_keyword("HAVING");
18272 self.write_space();
18273 if is_max {
18274 self.write_keyword("MAX");
18275 } else {
18276 self.write_keyword("MIN");
18277 }
18278 self.write_space();
18279 self.generate_expression(expr)?;
18280 }
18281 if !f.order_by.is_empty() {
18283 self.write_space();
18284 self.write_keyword("ORDER BY");
18285 self.write_space();
18286 for (i, ord) in f.order_by.iter().enumerate() {
18287 if i > 0 {
18288 self.write(", ");
18289 }
18290 self.generate_ordered(ord)?;
18291 }
18292 }
18293 if let Some(ref limit) = f.limit {
18295 self.write_space();
18296 self.write_keyword("LIMIT");
18297 self.write_space();
18298 if let Expression::Tuple(t) = limit.as_ref() {
18300 if t.expressions.len() == 2 {
18301 self.generate_expression(&t.expressions[0])?;
18302 self.write(", ");
18303 self.generate_expression(&t.expressions[1])?;
18304 } else {
18305 self.generate_expression(limit)?;
18306 }
18307 } else {
18308 self.generate_expression(limit)?;
18309 }
18310 }
18311 self.write(")");
18312 if !self.config.ignore_nulls_in_func
18315 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
18316 {
18317 match f.ignore_nulls {
18318 Some(true) => {
18319 self.write_space();
18320 self.write_keyword("IGNORE NULLS");
18321 }
18322 Some(false) => {
18323 self.write_space();
18324 self.write_keyword("RESPECT NULLS");
18325 }
18326 None => {}
18327 }
18328 }
18329 if let Some(ref filter) = f.filter {
18330 self.write_space();
18331 self.write_keyword("FILTER");
18332 self.write("(");
18333 self.write_keyword("WHERE");
18334 self.write_space();
18335 self.generate_expression(filter)?;
18336 self.write(")");
18337 }
18338 Ok(())
18339 }
18340
18341 fn generate_group_concat(&mut self, f: &GroupConcatFunc) -> Result<()> {
18342 self.write_keyword("GROUP_CONCAT");
18343 self.write("(");
18344 if f.distinct {
18345 self.write_keyword("DISTINCT");
18346 self.write_space();
18347 }
18348 self.generate_expression(&f.this)?;
18349 if let Some(ref order_by) = f.order_by {
18350 self.write_space();
18351 self.write_keyword("ORDER BY");
18352 self.write_space();
18353 for (i, ord) in order_by.iter().enumerate() {
18354 if i > 0 {
18355 self.write(", ");
18356 }
18357 self.generate_ordered(ord)?;
18358 }
18359 }
18360 if let Some(ref sep) = f.separator {
18361 if matches!(
18364 self.config.dialect,
18365 Some(crate::dialects::DialectType::SQLite)
18366 ) {
18367 self.write(", ");
18368 self.generate_expression(sep)?;
18369 } else {
18370 self.write_space();
18371 self.write_keyword("SEPARATOR");
18372 self.write_space();
18373 self.generate_expression(sep)?;
18374 }
18375 }
18376 self.write(")");
18377 if let Some(ref filter) = f.filter {
18378 self.write_space();
18379 self.write_keyword("FILTER");
18380 self.write("(");
18381 self.write_keyword("WHERE");
18382 self.write_space();
18383 self.generate_expression(filter)?;
18384 self.write(")");
18385 }
18386 Ok(())
18387 }
18388
18389 fn generate_string_agg(&mut self, f: &StringAggFunc) -> Result<()> {
18390 let is_tsql = matches!(
18391 self.config.dialect,
18392 Some(crate::dialects::DialectType::TSQL)
18393 );
18394 self.write_keyword("STRING_AGG");
18395 self.write("(");
18396 if f.distinct {
18397 self.write_keyword("DISTINCT");
18398 self.write_space();
18399 }
18400 self.generate_expression(&f.this)?;
18401 if let Some(ref separator) = f.separator {
18402 self.write(", ");
18403 self.generate_expression(separator)?;
18404 }
18405 if !is_tsql {
18407 if let Some(ref order_by) = f.order_by {
18408 self.write_space();
18409 self.write_keyword("ORDER BY");
18410 self.write_space();
18411 for (i, ord) in order_by.iter().enumerate() {
18412 if i > 0 {
18413 self.write(", ");
18414 }
18415 self.generate_ordered(ord)?;
18416 }
18417 }
18418 }
18419 if let Some(ref limit) = f.limit {
18420 self.write_space();
18421 self.write_keyword("LIMIT");
18422 self.write_space();
18423 self.generate_expression(limit)?;
18424 }
18425 self.write(")");
18426 if is_tsql {
18428 if let Some(ref order_by) = f.order_by {
18429 self.write_space();
18430 self.write_keyword("WITHIN GROUP");
18431 self.write(" (");
18432 self.write_keyword("ORDER BY");
18433 self.write_space();
18434 for (i, ord) in order_by.iter().enumerate() {
18435 if i > 0 {
18436 self.write(", ");
18437 }
18438 self.generate_ordered(ord)?;
18439 }
18440 self.write(")");
18441 }
18442 }
18443 if let Some(ref filter) = f.filter {
18444 self.write_space();
18445 self.write_keyword("FILTER");
18446 self.write("(");
18447 self.write_keyword("WHERE");
18448 self.write_space();
18449 self.generate_expression(filter)?;
18450 self.write(")");
18451 }
18452 Ok(())
18453 }
18454
18455 fn generate_listagg(&mut self, f: &ListAggFunc) -> Result<()> {
18456 use crate::dialects::DialectType;
18457 self.write_keyword("LISTAGG");
18458 self.write("(");
18459 if f.distinct {
18460 self.write_keyword("DISTINCT");
18461 self.write_space();
18462 }
18463 self.generate_expression(&f.this)?;
18464 if let Some(ref sep) = f.separator {
18465 self.write(", ");
18466 self.generate_expression(sep)?;
18467 } else if matches!(
18468 self.config.dialect,
18469 Some(DialectType::Trino) | Some(DialectType::Presto)
18470 ) {
18471 self.write(", ','");
18473 }
18474 if let Some(ref overflow) = f.on_overflow {
18475 self.write_space();
18476 self.write_keyword("ON OVERFLOW");
18477 self.write_space();
18478 match overflow {
18479 ListAggOverflow::Error => self.write_keyword("ERROR"),
18480 ListAggOverflow::Truncate { filler, with_count } => {
18481 self.write_keyword("TRUNCATE");
18482 if let Some(ref fill) = filler {
18483 self.write_space();
18484 self.generate_expression(fill)?;
18485 }
18486 if *with_count {
18487 self.write_space();
18488 self.write_keyword("WITH COUNT");
18489 } else {
18490 self.write_space();
18491 self.write_keyword("WITHOUT COUNT");
18492 }
18493 }
18494 }
18495 }
18496 self.write(")");
18497 if let Some(ref order_by) = f.order_by {
18498 self.write_space();
18499 self.write_keyword("WITHIN GROUP");
18500 self.write(" (");
18501 self.write_keyword("ORDER BY");
18502 self.write_space();
18503 for (i, ord) in order_by.iter().enumerate() {
18504 if i > 0 {
18505 self.write(", ");
18506 }
18507 self.generate_ordered(ord)?;
18508 }
18509 self.write(")");
18510 }
18511 if let Some(ref filter) = f.filter {
18512 self.write_space();
18513 self.write_keyword("FILTER");
18514 self.write("(");
18515 self.write_keyword("WHERE");
18516 self.write_space();
18517 self.generate_expression(filter)?;
18518 self.write(")");
18519 }
18520 Ok(())
18521 }
18522
18523 fn generate_sum_if(&mut self, f: &SumIfFunc) -> Result<()> {
18524 self.write_keyword("SUM_IF");
18525 self.write("(");
18526 self.generate_expression(&f.this)?;
18527 self.write(", ");
18528 self.generate_expression(&f.condition)?;
18529 self.write(")");
18530 if let Some(ref filter) = f.filter {
18531 self.write_space();
18532 self.write_keyword("FILTER");
18533 self.write("(");
18534 self.write_keyword("WHERE");
18535 self.write_space();
18536 self.generate_expression(filter)?;
18537 self.write(")");
18538 }
18539 Ok(())
18540 }
18541
18542 fn generate_approx_percentile(&mut self, f: &ApproxPercentileFunc) -> Result<()> {
18543 self.write_keyword("APPROX_PERCENTILE");
18544 self.write("(");
18545 self.generate_expression(&f.this)?;
18546 self.write(", ");
18547 self.generate_expression(&f.percentile)?;
18548 if let Some(ref acc) = f.accuracy {
18549 self.write(", ");
18550 self.generate_expression(acc)?;
18551 }
18552 self.write(")");
18553 if let Some(ref filter) = f.filter {
18554 self.write_space();
18555 self.write_keyword("FILTER");
18556 self.write("(");
18557 self.write_keyword("WHERE");
18558 self.write_space();
18559 self.generate_expression(filter)?;
18560 self.write(")");
18561 }
18562 Ok(())
18563 }
18564
18565 fn generate_percentile(&mut self, name: &str, f: &PercentileFunc) -> Result<()> {
18566 self.write_keyword(name);
18567 self.write("(");
18568 self.generate_expression(&f.percentile)?;
18569 self.write(")");
18570 if let Some(ref order_by) = f.order_by {
18571 self.write_space();
18572 self.write_keyword("WITHIN GROUP");
18573 self.write(" (");
18574 self.write_keyword("ORDER BY");
18575 self.write_space();
18576 self.generate_expression(&f.this)?;
18577 for ord in order_by.iter() {
18578 if ord.desc {
18579 self.write_space();
18580 self.write_keyword("DESC");
18581 }
18582 }
18583 self.write(")");
18584 }
18585 if let Some(ref filter) = f.filter {
18586 self.write_space();
18587 self.write_keyword("FILTER");
18588 self.write("(");
18589 self.write_keyword("WHERE");
18590 self.write_space();
18591 self.generate_expression(filter)?;
18592 self.write(")");
18593 }
18594 Ok(())
18595 }
18596
18597 fn generate_ntile(&mut self, f: &NTileFunc) -> Result<()> {
18600 self.write_keyword("NTILE");
18601 self.write("(");
18602 if let Some(num_buckets) = &f.num_buckets {
18603 self.generate_expression(num_buckets)?;
18604 }
18605 if let Some(order_by) = &f.order_by {
18606 self.write_keyword(" ORDER BY ");
18607 for (i, ob) in order_by.iter().enumerate() {
18608 if i > 0 {
18609 self.write(", ");
18610 }
18611 self.generate_ordered(ob)?;
18612 }
18613 }
18614 self.write(")");
18615 Ok(())
18616 }
18617
18618 fn generate_lead_lag(&mut self, name: &str, f: &LeadLagFunc) -> Result<()> {
18619 self.write_keyword(name);
18620 self.write("(");
18621 self.generate_expression(&f.this)?;
18622 if let Some(ref offset) = f.offset {
18623 self.write(", ");
18624 self.generate_expression(offset)?;
18625 if let Some(ref default) = f.default {
18626 self.write(", ");
18627 self.generate_expression(default)?;
18628 }
18629 }
18630 if f.ignore_nulls && self.config.ignore_nulls_in_func {
18632 self.write_space();
18633 self.write_keyword("IGNORE NULLS");
18634 }
18635 self.write(")");
18636 if f.ignore_nulls && !self.config.ignore_nulls_in_func {
18638 self.write_space();
18639 self.write_keyword("IGNORE NULLS");
18640 }
18641 Ok(())
18642 }
18643
18644 fn generate_value_func(&mut self, name: &str, f: &ValueFunc) -> Result<()> {
18645 self.write_keyword(name);
18646 self.write("(");
18647 self.generate_expression(&f.this)?;
18648 if self.config.ignore_nulls_in_func {
18650 match f.ignore_nulls {
18651 Some(true) => {
18652 self.write_space();
18653 self.write_keyword("IGNORE NULLS");
18654 }
18655 Some(false) => {
18656 self.write_space();
18657 self.write_keyword("RESPECT NULLS");
18658 }
18659 None => {}
18660 }
18661 }
18662 self.write(")");
18663 if !self.config.ignore_nulls_in_func {
18665 match f.ignore_nulls {
18666 Some(true) => {
18667 self.write_space();
18668 self.write_keyword("IGNORE NULLS");
18669 }
18670 Some(false) => {
18671 self.write_space();
18672 self.write_keyword("RESPECT NULLS");
18673 }
18674 None => {}
18675 }
18676 }
18677 Ok(())
18678 }
18679
18680 fn generate_nth_value(&mut self, f: &NthValueFunc) -> Result<()> {
18681 self.write_keyword("NTH_VALUE");
18682 self.write("(");
18683 self.generate_expression(&f.this)?;
18684 self.write(", ");
18685 self.generate_expression(&f.offset)?;
18686 if self.config.ignore_nulls_in_func {
18688 match f.ignore_nulls {
18689 Some(true) => {
18690 self.write_space();
18691 self.write_keyword("IGNORE NULLS");
18692 }
18693 Some(false) => {
18694 self.write_space();
18695 self.write_keyword("RESPECT NULLS");
18696 }
18697 None => {}
18698 }
18699 }
18700 self.write(")");
18701 if matches!(
18703 self.config.dialect,
18704 Some(crate::dialects::DialectType::Snowflake)
18705 ) {
18706 match f.from_first {
18707 Some(true) => {
18708 self.write_space();
18709 self.write_keyword("FROM FIRST");
18710 }
18711 Some(false) => {
18712 self.write_space();
18713 self.write_keyword("FROM LAST");
18714 }
18715 None => {}
18716 }
18717 }
18718 if !self.config.ignore_nulls_in_func {
18720 match f.ignore_nulls {
18721 Some(true) => {
18722 self.write_space();
18723 self.write_keyword("IGNORE NULLS");
18724 }
18725 Some(false) => {
18726 self.write_space();
18727 self.write_keyword("RESPECT NULLS");
18728 }
18729 None => {}
18730 }
18731 }
18732 Ok(())
18733 }
18734
18735 fn generate_position(&mut self, f: &PositionFunc) -> Result<()> {
18738 if matches!(
18741 self.config.dialect,
18742 Some(crate::dialects::DialectType::ClickHouse)
18743 ) {
18744 self.write_keyword("POSITION");
18745 self.write("(");
18746 self.generate_expression(&f.string)?;
18747 self.write(", ");
18748 self.generate_expression(&f.substring)?;
18749 if let Some(ref start) = f.start {
18750 self.write(", ");
18751 self.generate_expression(start)?;
18752 }
18753 self.write(")");
18754 return Ok(());
18755 }
18756
18757 self.write_keyword("POSITION");
18758 self.write("(");
18759 self.generate_expression(&f.substring)?;
18760 self.write_space();
18761 self.write_keyword("IN");
18762 self.write_space();
18763 self.generate_expression(&f.string)?;
18764 if let Some(ref start) = f.start {
18765 self.write(", ");
18766 self.generate_expression(start)?;
18767 }
18768 self.write(")");
18769 Ok(())
18770 }
18771
18772 fn generate_rand(&mut self, f: &Rand) -> Result<()> {
18775 if f.lower.is_some() || f.upper.is_some() {
18777 self.write_keyword("RANDOM");
18778 self.write("(");
18779 if let Some(ref lower) = f.lower {
18780 self.generate_expression(lower)?;
18781 }
18782 if let Some(ref upper) = f.upper {
18783 self.write(", ");
18784 self.generate_expression(upper)?;
18785 }
18786 self.write(")");
18787 return Ok(());
18788 }
18789 let func_name = match self.config.dialect {
18791 Some(crate::dialects::DialectType::Snowflake)
18792 | Some(crate::dialects::DialectType::DuckDB) => "RANDOM",
18793 _ => "RAND",
18794 };
18795 self.write_keyword(func_name);
18796 self.write("(");
18797 if !matches!(
18799 self.config.dialect,
18800 Some(crate::dialects::DialectType::DuckDB)
18801 ) {
18802 if let Some(ref seed) = f.seed {
18803 self.generate_expression(seed)?;
18804 }
18805 }
18806 self.write(")");
18807 Ok(())
18808 }
18809
18810 fn generate_truncate_func(&mut self, f: &TruncateFunc) -> Result<()> {
18811 self.write_keyword("TRUNCATE");
18812 self.write("(");
18813 self.generate_expression(&f.this)?;
18814 if let Some(ref decimals) = f.decimals {
18815 self.write(", ");
18816 self.generate_expression(decimals)?;
18817 }
18818 self.write(")");
18819 Ok(())
18820 }
18821
18822 fn generate_decode(&mut self, f: &DecodeFunc) -> Result<()> {
18825 self.write_keyword("DECODE");
18826 self.write("(");
18827 self.generate_expression(&f.this)?;
18828 for (search, result) in &f.search_results {
18829 self.write(", ");
18830 self.generate_expression(search)?;
18831 self.write(", ");
18832 self.generate_expression(result)?;
18833 }
18834 if let Some(ref default) = f.default {
18835 self.write(", ");
18836 self.generate_expression(default)?;
18837 }
18838 self.write(")");
18839 Ok(())
18840 }
18841
18842 fn generate_date_format(&mut self, name: &str, f: &DateFormatFunc) -> Result<()> {
18845 self.write_keyword(name);
18846 self.write("(");
18847 self.generate_expression(&f.this)?;
18848 self.write(", ");
18849 self.generate_expression(&f.format)?;
18850 self.write(")");
18851 Ok(())
18852 }
18853
18854 fn generate_from_unixtime(&mut self, f: &FromUnixtimeFunc) -> Result<()> {
18855 self.write_keyword("FROM_UNIXTIME");
18856 self.write("(");
18857 self.generate_expression(&f.this)?;
18858 if let Some(ref format) = f.format {
18859 self.write(", ");
18860 self.generate_expression(format)?;
18861 }
18862 self.write(")");
18863 Ok(())
18864 }
18865
18866 fn generate_unix_timestamp(&mut self, f: &UnixTimestampFunc) -> Result<()> {
18867 self.write_keyword("UNIX_TIMESTAMP");
18868 self.write("(");
18869 if let Some(ref expr) = f.this {
18870 self.generate_expression(expr)?;
18871 if let Some(ref format) = f.format {
18872 self.write(", ");
18873 self.generate_expression(format)?;
18874 }
18875 } else if matches!(
18876 self.config.dialect,
18877 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
18878 ) {
18879 self.write_keyword("CURRENT_TIMESTAMP");
18881 self.write("()");
18882 }
18883 self.write(")");
18884 Ok(())
18885 }
18886
18887 fn generate_make_date(&mut self, f: &MakeDateFunc) -> Result<()> {
18888 self.write_keyword("MAKE_DATE");
18889 self.write("(");
18890 self.generate_expression(&f.year)?;
18891 self.write(", ");
18892 self.generate_expression(&f.month)?;
18893 self.write(", ");
18894 self.generate_expression(&f.day)?;
18895 self.write(")");
18896 Ok(())
18897 }
18898
18899 fn generate_make_timestamp(&mut self, f: &MakeTimestampFunc) -> Result<()> {
18900 self.write_keyword("MAKE_TIMESTAMP");
18901 self.write("(");
18902 self.generate_expression(&f.year)?;
18903 self.write(", ");
18904 self.generate_expression(&f.month)?;
18905 self.write(", ");
18906 self.generate_expression(&f.day)?;
18907 self.write(", ");
18908 self.generate_expression(&f.hour)?;
18909 self.write(", ");
18910 self.generate_expression(&f.minute)?;
18911 self.write(", ");
18912 self.generate_expression(&f.second)?;
18913 if let Some(ref tz) = f.timezone {
18914 self.write(", ");
18915 self.generate_expression(tz)?;
18916 }
18917 self.write(")");
18918 Ok(())
18919 }
18920
18921 fn extract_struct_field_names(expr: &Expression) -> Option<Vec<String>> {
18923 match expr {
18924 Expression::Struct(s) => {
18925 if s.fields.iter().all(|(name, _)| name.is_some()) {
18926 Some(
18927 s.fields
18928 .iter()
18929 .map(|(name, _)| name.as_deref().unwrap_or("").to_string())
18930 .collect(),
18931 )
18932 } else {
18933 None
18934 }
18935 }
18936 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => {
18937 if f.args.iter().all(|a| matches!(a, Expression::Alias(_))) {
18939 Some(
18940 f.args
18941 .iter()
18942 .filter_map(|a| {
18943 if let Expression::Alias(alias) = a {
18944 Some(alias.alias.name.clone())
18945 } else {
18946 None
18947 }
18948 })
18949 .collect(),
18950 )
18951 } else {
18952 None
18953 }
18954 }
18955 _ => None,
18956 }
18957 }
18958
18959 fn struct_has_unnamed_fields(expr: &Expression) -> bool {
18961 match expr {
18962 Expression::Struct(s) => s.fields.iter().any(|(name, _)| name.is_none()),
18963 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => {
18964 f.args.iter().any(|a| !matches!(a, Expression::Alias(_)))
18965 }
18966 _ => false,
18967 }
18968 }
18969
18970 fn struct_field_count(expr: &Expression) -> usize {
18972 match expr {
18973 Expression::Struct(s) => s.fields.len(),
18974 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => f.args.len(),
18975 _ => 0,
18976 }
18977 }
18978
18979 fn apply_struct_field_names(expr: &Expression, field_names: &[String]) -> Expression {
18981 match expr {
18982 Expression::Struct(s) => {
18983 let mut new_fields = Vec::with_capacity(s.fields.len());
18984 for (i, (name, value)) in s.fields.iter().enumerate() {
18985 if name.is_none() && i < field_names.len() {
18986 new_fields.push((Some(field_names[i].clone()), value.clone()));
18987 } else {
18988 new_fields.push((name.clone(), value.clone()));
18989 }
18990 }
18991 Expression::Struct(Box::new(crate::expressions::Struct { fields: new_fields }))
18992 }
18993 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => {
18994 let mut new_args = Vec::with_capacity(f.args.len());
18995 for (i, arg) in f.args.iter().enumerate() {
18996 if !matches!(arg, Expression::Alias(_)) && i < field_names.len() {
18997 new_args.push(Expression::Alias(Box::new(crate::expressions::Alias {
18999 this: arg.clone(),
19000 alias: crate::expressions::Identifier::new(field_names[i].clone()),
19001 column_aliases: Vec::new(),
19002 pre_alias_comments: Vec::new(),
19003 trailing_comments: Vec::new(),
19004 })));
19005 } else {
19006 new_args.push(arg.clone());
19007 }
19008 }
19009 Expression::Function(Box::new(crate::expressions::Function {
19010 name: f.name.clone(),
19011 args: new_args,
19012 distinct: f.distinct,
19013 trailing_comments: f.trailing_comments.clone(),
19014 use_bracket_syntax: f.use_bracket_syntax,
19015 no_parens: f.no_parens,
19016 quoted: f.quoted,
19017 }))
19018 }
19019 _ => expr.clone(),
19020 }
19021 }
19022
19023 fn inherit_struct_field_names(expressions: &[Expression]) -> Vec<Expression> {
19027 let first = match expressions.first() {
19028 Some(e) => e,
19029 None => return expressions.to_vec(),
19030 };
19031
19032 let field_names = match Self::extract_struct_field_names(first) {
19033 Some(names) if !names.is_empty() => names,
19034 _ => return expressions.to_vec(),
19035 };
19036
19037 let mut result = Vec::with_capacity(expressions.len());
19038 for (idx, expr) in expressions.iter().enumerate() {
19039 if idx == 0 {
19040 result.push(expr.clone());
19041 continue;
19042 }
19043 if Self::struct_field_count(expr) == field_names.len()
19045 && Self::struct_has_unnamed_fields(expr)
19046 {
19047 result.push(Self::apply_struct_field_names(expr, &field_names));
19048 } else {
19049 result.push(expr.clone());
19050 }
19051 }
19052 result
19053 }
19054
19055 fn generate_array_constructor(&mut self, f: &ArrayConstructor) -> Result<()> {
19058 let needs_inheritance = matches!(
19061 self.config.dialect,
19062 Some(DialectType::DuckDB)
19063 | Some(DialectType::Spark)
19064 | Some(DialectType::Databricks)
19065 | Some(DialectType::Hive)
19066 | Some(DialectType::Snowflake)
19067 | Some(DialectType::Presto)
19068 | Some(DialectType::Trino)
19069 );
19070 let propagated: Vec<Expression>;
19071 let expressions = if needs_inheritance && f.expressions.len() > 1 {
19072 propagated = Self::inherit_struct_field_names(&f.expressions);
19073 &propagated
19074 } else {
19075 &f.expressions
19076 };
19077
19078 let should_split = if self.config.pretty && !expressions.is_empty() {
19080 let mut expr_strings: Vec<String> = Vec::with_capacity(expressions.len());
19081 for expr in expressions {
19082 let mut temp_gen = Generator::with_config(self.config.clone());
19083 temp_gen.config.pretty = false;
19084 temp_gen.generate_expression(expr)?;
19085 expr_strings.push(temp_gen.output);
19086 }
19087 self.too_wide(&expr_strings)
19088 } else {
19089 false
19090 };
19091
19092 if f.bracket_notation {
19093 let (open, close) = match self.config.dialect {
19097 None
19098 | Some(DialectType::Generic)
19099 | Some(DialectType::Spark)
19100 | Some(DialectType::Databricks)
19101 | Some(DialectType::Hive) => {
19102 self.write_keyword("ARRAY");
19103 ("(", ")")
19104 }
19105 Some(DialectType::Presto)
19106 | Some(DialectType::Trino)
19107 | Some(DialectType::PostgreSQL)
19108 | Some(DialectType::Redshift)
19109 | Some(DialectType::Materialize)
19110 | Some(DialectType::RisingWave)
19111 | Some(DialectType::CockroachDB) => {
19112 self.write_keyword("ARRAY");
19113 ("[", "]")
19114 }
19115 _ => ("[", "]"),
19116 };
19117 self.write(open);
19118 if should_split {
19119 self.write_newline();
19120 self.indent_level += 1;
19121 for (i, expr) in expressions.iter().enumerate() {
19122 self.write_indent();
19123 self.generate_expression(expr)?;
19124 if i + 1 < expressions.len() {
19125 self.write(",");
19126 }
19127 self.write_newline();
19128 }
19129 self.indent_level -= 1;
19130 self.write_indent();
19131 } else {
19132 for (i, expr) in expressions.iter().enumerate() {
19133 if i > 0 {
19134 self.write(", ");
19135 }
19136 self.generate_expression(expr)?;
19137 }
19138 }
19139 self.write(close);
19140 } else {
19141 if f.use_list_keyword {
19143 self.write_keyword("LIST");
19144 } else {
19145 self.write_keyword("ARRAY");
19146 }
19147 let has_subquery = expressions
19150 .iter()
19151 .any(|e| matches!(e, Expression::Select(_)));
19152 let (open, close) = if matches!(
19153 self.config.dialect,
19154 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive)
19155 ) || (matches!(self.config.dialect, Some(DialectType::BigQuery))
19156 && has_subquery)
19157 {
19158 ("(", ")")
19159 } else {
19160 ("[", "]")
19161 };
19162 self.write(open);
19163 if should_split {
19164 self.write_newline();
19165 self.indent_level += 1;
19166 for (i, expr) in expressions.iter().enumerate() {
19167 self.write_indent();
19168 self.generate_expression(expr)?;
19169 if i + 1 < expressions.len() {
19170 self.write(",");
19171 }
19172 self.write_newline();
19173 }
19174 self.indent_level -= 1;
19175 self.write_indent();
19176 } else {
19177 for (i, expr) in expressions.iter().enumerate() {
19178 if i > 0 {
19179 self.write(", ");
19180 }
19181 self.generate_expression(expr)?;
19182 }
19183 }
19184 self.write(close);
19185 }
19186 Ok(())
19187 }
19188
19189 fn generate_array_sort(&mut self, f: &ArraySortFunc) -> Result<()> {
19190 self.write_keyword("ARRAY_SORT");
19191 self.write("(");
19192 self.generate_expression(&f.this)?;
19193 if let Some(ref comp) = f.comparator {
19194 self.write(", ");
19195 self.generate_expression(comp)?;
19196 }
19197 self.write(")");
19198 Ok(())
19199 }
19200
19201 fn generate_array_join(&mut self, name: &str, f: &ArrayJoinFunc) -> Result<()> {
19202 self.write_keyword(name);
19203 self.write("(");
19204 self.generate_expression(&f.this)?;
19205 self.write(", ");
19206 self.generate_expression(&f.separator)?;
19207 if let Some(ref null_rep) = f.null_replacement {
19208 self.write(", ");
19209 self.generate_expression(null_rep)?;
19210 }
19211 self.write(")");
19212 Ok(())
19213 }
19214
19215 fn generate_unnest(&mut self, f: &UnnestFunc) -> Result<()> {
19216 self.write_keyword("UNNEST");
19217 self.write("(");
19218 self.generate_expression(&f.this)?;
19219 for extra in &f.expressions {
19220 self.write(", ");
19221 self.generate_expression(extra)?;
19222 }
19223 self.write(")");
19224 if f.with_ordinality {
19225 self.write_space();
19226 if self.config.unnest_with_ordinality {
19227 self.write_keyword("WITH ORDINALITY");
19229 } else if f.offset_alias.is_some() {
19230 if let Some(ref alias) = f.alias {
19233 self.write_keyword("AS");
19234 self.write_space();
19235 self.generate_identifier(alias)?;
19236 self.write_space();
19237 }
19238 self.write_keyword("WITH OFFSET");
19239 if let Some(ref offset_alias) = f.offset_alias {
19240 self.write_space();
19241 self.write_keyword("AS");
19242 self.write_space();
19243 self.generate_identifier(offset_alias)?;
19244 }
19245 } else {
19246 self.write_keyword("WITH OFFSET");
19248 if f.alias.is_none() {
19249 self.write(" AS offset");
19250 }
19251 }
19252 }
19253 if let Some(ref alias) = f.alias {
19254 let should_add_alias = if !f.with_ordinality {
19256 true
19257 } else if self.config.unnest_with_ordinality {
19258 true
19260 } else if f.offset_alias.is_some() {
19261 false
19263 } else {
19264 true
19266 };
19267 if should_add_alias {
19268 self.write_space();
19269 self.write_keyword("AS");
19270 self.write_space();
19271 self.generate_identifier(alias)?;
19272 }
19273 }
19274 Ok(())
19275 }
19276
19277 fn generate_array_filter(&mut self, f: &ArrayFilterFunc) -> Result<()> {
19278 self.write_keyword("FILTER");
19279 self.write("(");
19280 self.generate_expression(&f.this)?;
19281 self.write(", ");
19282 self.generate_expression(&f.filter)?;
19283 self.write(")");
19284 Ok(())
19285 }
19286
19287 fn generate_array_transform(&mut self, f: &ArrayTransformFunc) -> Result<()> {
19288 self.write_keyword("TRANSFORM");
19289 self.write("(");
19290 self.generate_expression(&f.this)?;
19291 self.write(", ");
19292 self.generate_expression(&f.transform)?;
19293 self.write(")");
19294 Ok(())
19295 }
19296
19297 fn generate_sequence(&mut self, name: &str, f: &SequenceFunc) -> Result<()> {
19298 self.write_keyword(name);
19299 self.write("(");
19300 self.generate_expression(&f.start)?;
19301 self.write(", ");
19302 self.generate_expression(&f.stop)?;
19303 if let Some(ref step) = f.step {
19304 self.write(", ");
19305 self.generate_expression(step)?;
19306 }
19307 self.write(")");
19308 Ok(())
19309 }
19310
19311 fn generate_struct_constructor(&mut self, f: &StructConstructor) -> Result<()> {
19314 self.write_keyword("STRUCT");
19315 self.write("(");
19316 for (i, (name, expr)) in f.fields.iter().enumerate() {
19317 if i > 0 {
19318 self.write(", ");
19319 }
19320 if let Some(ref id) = name {
19321 self.generate_identifier(id)?;
19322 self.write(" ");
19323 self.write_keyword("AS");
19324 self.write(" ");
19325 }
19326 self.generate_expression(expr)?;
19327 }
19328 self.write(")");
19329 Ok(())
19330 }
19331
19332 fn generate_struct_function_cross_dialect(&mut self, func: &Function) -> Result<()> {
19334 let mut names: Vec<Option<String>> = Vec::new();
19337 let mut values: Vec<&Expression> = Vec::new();
19338 let mut all_named = true;
19339
19340 for arg in &func.args {
19341 match arg {
19342 Expression::Alias(a) => {
19343 names.push(Some(a.alias.name.clone()));
19344 values.push(&a.this);
19345 }
19346 _ => {
19347 names.push(None);
19348 values.push(arg);
19349 all_named = false;
19350 }
19351 }
19352 }
19353
19354 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
19355 self.write("{");
19357 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
19358 if i > 0 {
19359 self.write(", ");
19360 }
19361 if let Some(n) = name {
19362 self.write("'");
19363 self.write(n);
19364 self.write("'");
19365 } else {
19366 self.write("'_");
19367 self.write(&i.to_string());
19368 self.write("'");
19369 }
19370 self.write(": ");
19371 self.generate_expression(value)?;
19372 }
19373 self.write("}");
19374 return Ok(());
19375 }
19376
19377 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
19378 self.write_keyword("OBJECT_CONSTRUCT");
19380 self.write("(");
19381 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
19382 if i > 0 {
19383 self.write(", ");
19384 }
19385 if let Some(n) = name {
19386 self.write("'");
19387 self.write(n);
19388 self.write("'");
19389 } else {
19390 self.write("'_");
19391 self.write(&i.to_string());
19392 self.write("'");
19393 }
19394 self.write(", ");
19395 self.generate_expression(value)?;
19396 }
19397 self.write(")");
19398 return Ok(());
19399 }
19400
19401 if matches!(
19402 self.config.dialect,
19403 Some(DialectType::Presto) | Some(DialectType::Trino)
19404 ) {
19405 if all_named && !names.is_empty() {
19406 self.write_keyword("CAST");
19409 self.write("(");
19410 self.write_keyword("ROW");
19411 self.write("(");
19412 for (i, value) in values.iter().enumerate() {
19413 if i > 0 {
19414 self.write(", ");
19415 }
19416 self.generate_expression(value)?;
19417 }
19418 self.write(")");
19419 self.write(" ");
19420 self.write_keyword("AS");
19421 self.write(" ");
19422 self.write_keyword("ROW");
19423 self.write("(");
19424 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
19425 if i > 0 {
19426 self.write(", ");
19427 }
19428 if let Some(n) = name {
19429 self.write(n);
19430 }
19431 self.write(" ");
19432 let type_str = Self::infer_sql_type_for_presto(value);
19433 self.write_keyword(&type_str);
19434 }
19435 self.write(")");
19436 self.write(")");
19437 } else {
19438 self.write_keyword("ROW");
19440 self.write("(");
19441 for (i, value) in values.iter().enumerate() {
19442 if i > 0 {
19443 self.write(", ");
19444 }
19445 self.generate_expression(value)?;
19446 }
19447 self.write(")");
19448 }
19449 return Ok(());
19450 }
19451
19452 self.write_keyword("ROW");
19454 self.write("(");
19455 for (i, value) in values.iter().enumerate() {
19456 if i > 0 {
19457 self.write(", ");
19458 }
19459 self.generate_expression(value)?;
19460 }
19461 self.write(")");
19462 Ok(())
19463 }
19464
19465 fn infer_sql_type_for_presto(expr: &Expression) -> String {
19467 match expr {
19468 Expression::Literal(crate::expressions::Literal::String(_)) => "VARCHAR".to_string(),
19469 Expression::Literal(crate::expressions::Literal::Number(n)) => {
19470 if n.contains('.') {
19471 "DOUBLE".to_string()
19472 } else {
19473 "INTEGER".to_string()
19474 }
19475 }
19476 Expression::Boolean(_) => "BOOLEAN".to_string(),
19477 Expression::Literal(crate::expressions::Literal::Date(_)) => "DATE".to_string(),
19478 Expression::Literal(crate::expressions::Literal::Timestamp(_)) => {
19479 "TIMESTAMP".to_string()
19480 }
19481 Expression::Literal(crate::expressions::Literal::Datetime(_)) => {
19482 "TIMESTAMP".to_string()
19483 }
19484 Expression::Array(_) | Expression::ArrayFunc(_) => {
19485 "ARRAY(VARCHAR)".to_string()
19487 }
19488 Expression::Struct(_) | Expression::StructFunc(_) => "ROW".to_string(),
19490 Expression::Function(f) => {
19491 let up = f.name.to_uppercase();
19492 if up == "STRUCT" {
19493 "ROW".to_string()
19494 } else if up == "CURRENT_DATE" {
19495 "DATE".to_string()
19496 } else if up == "CURRENT_TIMESTAMP" || up == "NOW" {
19497 "TIMESTAMP".to_string()
19498 } else {
19499 "VARCHAR".to_string()
19500 }
19501 }
19502 _ => "VARCHAR".to_string(),
19503 }
19504 }
19505
19506 fn generate_struct_extract(&mut self, f: &StructExtractFunc) -> Result<()> {
19507 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
19509 self.write_keyword("STRUCT_EXTRACT");
19510 self.write("(");
19511 self.generate_expression(&f.this)?;
19512 self.write(", ");
19513 self.write("'");
19515 self.write(&f.field.name);
19516 self.write("'");
19517 self.write(")");
19518 return Ok(());
19519 }
19520 self.generate_expression(&f.this)?;
19521 self.write(".");
19522 self.generate_identifier(&f.field)
19523 }
19524
19525 fn generate_named_struct(&mut self, f: &NamedStructFunc) -> Result<()> {
19526 self.write_keyword("NAMED_STRUCT");
19527 self.write("(");
19528 for (i, (name, value)) in f.pairs.iter().enumerate() {
19529 if i > 0 {
19530 self.write(", ");
19531 }
19532 self.generate_expression(name)?;
19533 self.write(", ");
19534 self.generate_expression(value)?;
19535 }
19536 self.write(")");
19537 Ok(())
19538 }
19539
19540 fn generate_map_constructor(&mut self, f: &MapConstructor) -> Result<()> {
19543 if f.curly_brace_syntax {
19544 if f.with_map_keyword {
19546 self.write_keyword("MAP");
19547 self.write(" ");
19548 }
19549 self.write("{");
19550 for (i, (key, val)) in f.keys.iter().zip(f.values.iter()).enumerate() {
19551 if i > 0 {
19552 self.write(", ");
19553 }
19554 self.generate_expression(key)?;
19555 self.write(": ");
19556 self.generate_expression(val)?;
19557 }
19558 self.write("}");
19559 } else {
19560 self.write_keyword("MAP");
19562 self.write("(");
19563 self.write_keyword("ARRAY");
19564 self.write("[");
19565 for (i, key) in f.keys.iter().enumerate() {
19566 if i > 0 {
19567 self.write(", ");
19568 }
19569 self.generate_expression(key)?;
19570 }
19571 self.write("], ");
19572 self.write_keyword("ARRAY");
19573 self.write("[");
19574 for (i, val) in f.values.iter().enumerate() {
19575 if i > 0 {
19576 self.write(", ");
19577 }
19578 self.generate_expression(val)?;
19579 }
19580 self.write("])");
19581 }
19582 Ok(())
19583 }
19584
19585 fn generate_transform_func(&mut self, name: &str, f: &TransformFunc) -> Result<()> {
19586 self.write_keyword(name);
19587 self.write("(");
19588 self.generate_expression(&f.this)?;
19589 self.write(", ");
19590 self.generate_expression(&f.transform)?;
19591 self.write(")");
19592 Ok(())
19593 }
19594
19595 fn generate_json_extract(&mut self, name: &str, f: &JsonExtractFunc) -> Result<()> {
19598 use crate::dialects::DialectType;
19599
19600 let use_arrow = f.arrow_syntax && self.dialect_supports_json_arrow();
19602
19603 if use_arrow {
19604 self.generate_expression(&f.this)?;
19606 if name == "JSON_EXTRACT_SCALAR" || name == "JSON_EXTRACT_PATH_TEXT" {
19607 self.write(" ->> ");
19608 } else {
19609 self.write(" -> ");
19610 }
19611 self.generate_expression(&f.path)?;
19612 return Ok(());
19613 }
19614
19615 if f.hash_arrow_syntax
19617 && matches!(
19618 self.config.dialect,
19619 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
19620 )
19621 {
19622 self.generate_expression(&f.this)?;
19623 self.write(" #>> ");
19624 self.generate_expression(&f.path)?;
19625 return Ok(());
19626 }
19627
19628 let func_name = if matches!(self.config.dialect, Some(DialectType::Redshift)) {
19631 match name {
19632 "JSON_EXTRACT_SCALAR"
19633 | "JSON_EXTRACT_PATH_TEXT"
19634 | "JSON_EXTRACT"
19635 | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH_TEXT",
19636 _ => name,
19637 }
19638 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
19639 match name {
19640 "JSON_EXTRACT_SCALAR" | "JSON_EXTRACT_PATH_TEXT" => "JSON_EXTRACT_PATH_TEXT",
19641 "JSON_EXTRACT" | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH",
19642 _ => name,
19643 }
19644 } else {
19645 name
19646 };
19647
19648 self.write_keyword(func_name);
19649 self.write("(");
19650 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
19652 if let Expression::Cast(ref cast) = f.this {
19653 if matches!(cast.to, crate::expressions::DataType::Json) {
19654 self.generate_expression(&cast.this)?;
19655 } else {
19656 self.generate_expression(&f.this)?;
19657 }
19658 } else {
19659 self.generate_expression(&f.this)?;
19660 }
19661 } else {
19662 self.generate_expression(&f.this)?;
19663 }
19664 if matches!(
19667 self.config.dialect,
19668 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
19669 ) && (func_name == "JSON_EXTRACT_PATH" || func_name == "JSON_EXTRACT_PATH_TEXT")
19670 {
19671 if let Expression::Literal(Literal::String(ref s)) = f.path {
19672 let parts = Self::decompose_json_path(s);
19673 for part in &parts {
19674 self.write(", '");
19675 self.write(part);
19676 self.write("'");
19677 }
19678 } else {
19679 self.write(", ");
19680 self.generate_expression(&f.path)?;
19681 }
19682 } else {
19683 self.write(", ");
19684 self.generate_expression(&f.path)?;
19685 }
19686
19687 if let Some(ref wrapper) = f.wrapper_option {
19690 self.write_space();
19691 self.write_keyword(wrapper);
19692 }
19693 if let Some(ref quotes) = f.quotes_option {
19694 self.write_space();
19695 self.write_keyword(quotes);
19696 if f.on_scalar_string {
19697 self.write_space();
19698 self.write_keyword("ON SCALAR STRING");
19699 }
19700 }
19701 if let Some(ref on_err) = f.on_error {
19702 self.write_space();
19703 self.write_keyword(on_err);
19704 }
19705 if let Some(ref ret_type) = f.returning {
19706 self.write_space();
19707 self.write_keyword("RETURNING");
19708 self.write_space();
19709 self.generate_data_type(ret_type)?;
19710 }
19711
19712 self.write(")");
19713 Ok(())
19714 }
19715
19716 fn dialect_supports_json_arrow(&self) -> bool {
19718 use crate::dialects::DialectType;
19719 match self.config.dialect {
19720 Some(DialectType::PostgreSQL) => true,
19722 Some(DialectType::MySQL) => true,
19723 Some(DialectType::DuckDB) => true,
19724 Some(DialectType::CockroachDB) => true,
19725 Some(DialectType::StarRocks) => true,
19726 Some(DialectType::SQLite) => true,
19727 _ => false,
19729 }
19730 }
19731
19732 fn generate_json_path(&mut self, name: &str, f: &JsonPathFunc) -> Result<()> {
19733 use crate::dialects::DialectType;
19734
19735 if matches!(
19737 self.config.dialect,
19738 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
19739 ) && name == "JSON_EXTRACT_PATH"
19740 {
19741 self.generate_expression(&f.this)?;
19742 self.write(" #> ");
19743 if f.paths.len() == 1 {
19744 self.generate_expression(&f.paths[0])?;
19745 } else {
19746 self.write_keyword("ARRAY");
19748 self.write("[");
19749 for (i, path) in f.paths.iter().enumerate() {
19750 if i > 0 {
19751 self.write(", ");
19752 }
19753 self.generate_expression(path)?;
19754 }
19755 self.write("]");
19756 }
19757 return Ok(());
19758 }
19759
19760 self.write_keyword(name);
19761 self.write("(");
19762 self.generate_expression(&f.this)?;
19763 for path in &f.paths {
19764 self.write(", ");
19765 self.generate_expression(path)?;
19766 }
19767 self.write(")");
19768 Ok(())
19769 }
19770
19771 fn generate_json_object(&mut self, f: &JsonObjectFunc) -> Result<()> {
19772 use crate::dialects::DialectType;
19773
19774 self.write_keyword("JSON_OBJECT");
19775 self.write("(");
19776 if f.star {
19777 self.write("*");
19778 } else {
19779 let use_comma_syntax = self.config.json_key_value_pair_sep == ","
19783 || matches!(
19784 self.config.dialect,
19785 Some(DialectType::BigQuery)
19786 | Some(DialectType::MySQL)
19787 | Some(DialectType::SQLite)
19788 );
19789
19790 for (i, (key, value)) in f.pairs.iter().enumerate() {
19791 if i > 0 {
19792 self.write(", ");
19793 }
19794 self.generate_expression(key)?;
19795 if use_comma_syntax {
19796 self.write(", ");
19797 } else {
19798 self.write(": ");
19799 }
19800 self.generate_expression(value)?;
19801 }
19802 }
19803 if let Some(null_handling) = f.null_handling {
19804 self.write_space();
19805 match null_handling {
19806 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
19807 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
19808 }
19809 }
19810 if f.with_unique_keys {
19811 self.write_space();
19812 self.write_keyword("WITH UNIQUE KEYS");
19813 }
19814 if let Some(ref ret_type) = f.returning_type {
19815 self.write_space();
19816 self.write_keyword("RETURNING");
19817 self.write_space();
19818 self.generate_data_type(ret_type)?;
19819 if f.format_json {
19820 self.write_space();
19821 self.write_keyword("FORMAT JSON");
19822 }
19823 if let Some(ref enc) = f.encoding {
19824 self.write_space();
19825 self.write_keyword("ENCODING");
19826 self.write_space();
19827 self.write(enc);
19828 }
19829 }
19830 self.write(")");
19831 Ok(())
19832 }
19833
19834 fn generate_json_modify(&mut self, name: &str, f: &JsonModifyFunc) -> Result<()> {
19835 self.write_keyword(name);
19836 self.write("(");
19837 self.generate_expression(&f.this)?;
19838 for (path, value) in &f.path_values {
19839 self.write(", ");
19840 self.generate_expression(path)?;
19841 self.write(", ");
19842 self.generate_expression(value)?;
19843 }
19844 self.write(")");
19845 Ok(())
19846 }
19847
19848 fn generate_json_array_agg(&mut self, f: &JsonArrayAggFunc) -> Result<()> {
19849 self.write_keyword("JSON_ARRAYAGG");
19850 self.write("(");
19851 self.generate_expression(&f.this)?;
19852 if let Some(ref order_by) = f.order_by {
19853 self.write_space();
19854 self.write_keyword("ORDER BY");
19855 self.write_space();
19856 for (i, ord) in order_by.iter().enumerate() {
19857 if i > 0 {
19858 self.write(", ");
19859 }
19860 self.generate_ordered(ord)?;
19861 }
19862 }
19863 if let Some(null_handling) = f.null_handling {
19864 self.write_space();
19865 match null_handling {
19866 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
19867 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
19868 }
19869 }
19870 self.write(")");
19871 if let Some(ref filter) = f.filter {
19872 self.write_space();
19873 self.write_keyword("FILTER");
19874 self.write("(");
19875 self.write_keyword("WHERE");
19876 self.write_space();
19877 self.generate_expression(filter)?;
19878 self.write(")");
19879 }
19880 Ok(())
19881 }
19882
19883 fn generate_json_object_agg(&mut self, f: &JsonObjectAggFunc) -> Result<()> {
19884 self.write_keyword("JSON_OBJECTAGG");
19885 self.write("(");
19886 self.generate_expression(&f.key)?;
19887 self.write(": ");
19888 self.generate_expression(&f.value)?;
19889 if let Some(null_handling) = f.null_handling {
19890 self.write_space();
19891 match null_handling {
19892 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
19893 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
19894 }
19895 }
19896 self.write(")");
19897 if let Some(ref filter) = f.filter {
19898 self.write_space();
19899 self.write_keyword("FILTER");
19900 self.write("(");
19901 self.write_keyword("WHERE");
19902 self.write_space();
19903 self.generate_expression(filter)?;
19904 self.write(")");
19905 }
19906 Ok(())
19907 }
19908
19909 fn generate_convert(&mut self, f: &ConvertFunc) -> Result<()> {
19912 use crate::dialects::DialectType;
19913
19914 if self.config.dialect == Some(DialectType::Redshift) {
19916 self.write_keyword("CAST");
19917 self.write("(");
19918 self.generate_expression(&f.this)?;
19919 self.write_space();
19920 self.write_keyword("AS");
19921 self.write_space();
19922 self.generate_data_type(&f.to)?;
19923 self.write(")");
19924 return Ok(());
19925 }
19926
19927 self.write_keyword("CONVERT");
19928 self.write("(");
19929 self.generate_data_type(&f.to)?;
19930 self.write(", ");
19931 self.generate_expression(&f.this)?;
19932 if let Some(ref style) = f.style {
19933 self.write(", ");
19934 self.generate_expression(style)?;
19935 }
19936 self.write(")");
19937 Ok(())
19938 }
19939
19940 fn generate_lambda(&mut self, f: &LambdaExpr) -> Result<()> {
19943 if f.colon {
19944 self.write_keyword("LAMBDA");
19946 self.write_space();
19947 for (i, param) in f.parameters.iter().enumerate() {
19948 if i > 0 {
19949 self.write(", ");
19950 }
19951 self.generate_identifier(param)?;
19952 }
19953 self.write(" : ");
19954 } else {
19955 if f.parameters.len() == 1 {
19957 self.generate_identifier(&f.parameters[0])?;
19958 } else {
19959 self.write("(");
19960 for (i, param) in f.parameters.iter().enumerate() {
19961 if i > 0 {
19962 self.write(", ");
19963 }
19964 self.generate_identifier(param)?;
19965 }
19966 self.write(")");
19967 }
19968 self.write(" -> ");
19969 }
19970 self.generate_expression(&f.body)
19971 }
19972
19973 fn generate_named_argument(&mut self, f: &NamedArgument) -> Result<()> {
19974 self.generate_identifier(&f.name)?;
19975 match f.separator {
19976 NamedArgSeparator::DArrow => self.write(" => "),
19977 NamedArgSeparator::ColonEq => self.write(" := "),
19978 NamedArgSeparator::Eq => self.write(" = "),
19979 }
19980 self.generate_expression(&f.value)
19981 }
19982
19983 fn generate_table_argument(&mut self, f: &TableArgument) -> Result<()> {
19984 self.write_keyword(&f.prefix);
19985 self.write(" ");
19986 self.generate_expression(&f.this)
19987 }
19988
19989 fn generate_parameter(&mut self, f: &Parameter) -> Result<()> {
19990 match f.style {
19991 ParameterStyle::Question => self.write("?"),
19992 ParameterStyle::Dollar => {
19993 self.write("$");
19994 if let Some(idx) = f.index {
19995 self.write(&idx.to_string());
19996 } else if let Some(ref name) = f.name {
19997 self.write(name);
19999 }
20000 }
20001 ParameterStyle::DollarBrace => {
20002 self.write("${");
20004 if let Some(ref name) = f.name {
20005 self.write(name);
20006 }
20007 if let Some(ref expr) = f.expression {
20008 self.write(":");
20009 self.write(expr);
20010 }
20011 self.write("}");
20012 }
20013 ParameterStyle::Colon => {
20014 self.write(":");
20015 if let Some(idx) = f.index {
20016 self.write(&idx.to_string());
20017 } else if let Some(ref name) = f.name {
20018 self.write(name);
20019 }
20020 }
20021 ParameterStyle::At => {
20022 self.write("@");
20023 if let Some(ref name) = f.name {
20024 if f.string_quoted {
20025 self.write("'");
20026 self.write(name);
20027 self.write("'");
20028 } else if f.quoted {
20029 self.write("\"");
20030 self.write(name);
20031 self.write("\"");
20032 } else {
20033 self.write(name);
20034 }
20035 }
20036 }
20037 ParameterStyle::DoubleAt => {
20038 self.write("@@");
20039 if let Some(ref name) = f.name {
20040 self.write(name);
20041 }
20042 }
20043 ParameterStyle::DoubleDollar => {
20044 self.write("$$");
20045 if let Some(ref name) = f.name {
20046 self.write(name);
20047 }
20048 }
20049 ParameterStyle::Percent => {
20050 if let Some(ref name) = f.name {
20051 self.write("%(");
20053 self.write(name);
20054 self.write(")s");
20055 } else {
20056 self.write("%s");
20058 }
20059 }
20060 ParameterStyle::Brace => {
20061 self.write("{");
20064 if let Some(ref name) = f.name {
20065 self.write(name);
20066 }
20067 if let Some(ref expr) = f.expression {
20068 self.write(": ");
20069 self.write(expr);
20070 }
20071 self.write("}");
20072 }
20073 }
20074 Ok(())
20075 }
20076
20077 fn generate_placeholder(&mut self, f: &Placeholder) -> Result<()> {
20078 self.write("?");
20079 if let Some(idx) = f.index {
20080 self.write(&idx.to_string());
20081 }
20082 Ok(())
20083 }
20084
20085 fn generate_sql_comment(&mut self, f: &SqlComment) -> Result<()> {
20086 if f.is_block {
20087 self.write("/*");
20088 self.write(&f.text);
20089 self.write("*/");
20090 } else {
20091 self.write("--");
20092 self.write(&f.text);
20093 }
20094 Ok(())
20095 }
20096
20097 fn generate_similar_to(&mut self, f: &SimilarToExpr) -> Result<()> {
20100 self.generate_expression(&f.this)?;
20101 if f.not {
20102 self.write_space();
20103 self.write_keyword("NOT");
20104 }
20105 self.write_space();
20106 self.write_keyword("SIMILAR TO");
20107 self.write_space();
20108 self.generate_expression(&f.pattern)?;
20109 if let Some(ref escape) = f.escape {
20110 self.write_space();
20111 self.write_keyword("ESCAPE");
20112 self.write_space();
20113 self.generate_expression(escape)?;
20114 }
20115 Ok(())
20116 }
20117
20118 fn generate_quantified(&mut self, name: &str, f: &QuantifiedExpr) -> Result<()> {
20119 self.generate_expression(&f.this)?;
20120 self.write_space();
20121 if let Some(op) = &f.op {
20123 match op {
20124 QuantifiedOp::Eq => self.write("="),
20125 QuantifiedOp::Neq => self.write("<>"),
20126 QuantifiedOp::Lt => self.write("<"),
20127 QuantifiedOp::Lte => self.write("<="),
20128 QuantifiedOp::Gt => self.write(">"),
20129 QuantifiedOp::Gte => self.write(">="),
20130 }
20131 self.write_space();
20132 }
20133 self.write_keyword(name);
20134
20135 if matches!(&f.subquery, Expression::Subquery(_)) {
20137 self.write_space();
20138 self.generate_expression(&f.subquery)?;
20139 } else {
20140 self.write("(");
20141
20142 let is_statement = matches!(
20143 &f.subquery,
20144 Expression::Select(_)
20145 | Expression::Union(_)
20146 | Expression::Intersect(_)
20147 | Expression::Except(_)
20148 );
20149
20150 if self.config.pretty && is_statement {
20151 self.write_newline();
20152 self.indent_level += 1;
20153 self.write_indent();
20154 }
20155 self.generate_expression(&f.subquery)?;
20156 if self.config.pretty && is_statement {
20157 self.write_newline();
20158 self.indent_level -= 1;
20159 self.write_indent();
20160 }
20161 self.write(")");
20162 }
20163 Ok(())
20164 }
20165
20166 fn generate_overlaps(&mut self, f: &OverlapsExpr) -> Result<()> {
20167 if let (Some(this), Some(expr)) = (&f.this, &f.expression) {
20169 self.generate_expression(this)?;
20170 self.write_space();
20171 self.write_keyword("OVERLAPS");
20172 self.write_space();
20173 self.generate_expression(expr)?;
20174 } else if let (Some(ls), Some(le), Some(rs), Some(re)) =
20175 (&f.left_start, &f.left_end, &f.right_start, &f.right_end)
20176 {
20177 self.write("(");
20179 self.generate_expression(ls)?;
20180 self.write(", ");
20181 self.generate_expression(le)?;
20182 self.write(")");
20183 self.write_space();
20184 self.write_keyword("OVERLAPS");
20185 self.write_space();
20186 self.write("(");
20187 self.generate_expression(rs)?;
20188 self.write(", ");
20189 self.generate_expression(re)?;
20190 self.write(")");
20191 }
20192 Ok(())
20193 }
20194
20195 fn generate_try_cast(&mut self, cast: &Cast) -> Result<()> {
20198 use crate::dialects::DialectType;
20199
20200 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
20202 self.generate_expression(&cast.this)?;
20203 self.write(" !:> ");
20204 self.generate_data_type(&cast.to)?;
20205 return Ok(());
20206 }
20207
20208 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
20210 self.write_keyword("TRYCAST");
20211 self.write("(");
20212 self.generate_expression(&cast.this)?;
20213 self.write_space();
20214 self.write_keyword("AS");
20215 self.write_space();
20216 self.generate_data_type(&cast.to)?;
20217 self.write(")");
20218 return Ok(());
20219 }
20220
20221 let keyword = if matches!(
20223 self.config.dialect,
20224 Some(DialectType::Hive)
20225 | Some(DialectType::MySQL)
20226 | Some(DialectType::SQLite)
20227 | Some(DialectType::Oracle)
20228 | Some(DialectType::ClickHouse)
20229 | Some(DialectType::Redshift)
20230 | Some(DialectType::PostgreSQL)
20231 | Some(DialectType::StarRocks)
20232 | Some(DialectType::Doris)
20233 ) {
20234 "CAST"
20235 } else {
20236 "TRY_CAST"
20237 };
20238
20239 self.write_keyword(keyword);
20240 self.write("(");
20241 self.generate_expression(&cast.this)?;
20242 self.write_space();
20243 self.write_keyword("AS");
20244 self.write_space();
20245 self.generate_data_type(&cast.to)?;
20246
20247 if let Some(format) = &cast.format {
20249 self.write_space();
20250 self.write_keyword("FORMAT");
20251 self.write_space();
20252 self.generate_expression(format)?;
20253 }
20254
20255 self.write(")");
20256 Ok(())
20257 }
20258
20259 fn generate_safe_cast(&mut self, cast: &Cast) -> Result<()> {
20260 self.write_keyword("SAFE_CAST");
20261 self.write("(");
20262 self.generate_expression(&cast.this)?;
20263 self.write_space();
20264 self.write_keyword("AS");
20265 self.write_space();
20266 self.generate_data_type(&cast.to)?;
20267
20268 if let Some(format) = &cast.format {
20270 self.write_space();
20271 self.write_keyword("FORMAT");
20272 self.write_space();
20273 self.generate_expression(format)?;
20274 }
20275
20276 self.write(")");
20277 Ok(())
20278 }
20279
20280 fn generate_subscript(&mut self, s: &Subscript) -> Result<()> {
20283 self.generate_expression(&s.this)?;
20284 self.write("[");
20285 self.generate_expression(&s.index)?;
20286 self.write("]");
20287 Ok(())
20288 }
20289
20290 fn generate_dot_access(&mut self, d: &DotAccess) -> Result<()> {
20291 self.generate_expression(&d.this)?;
20292 let use_colon = matches!(self.config.dialect, Some(DialectType::Snowflake))
20295 && matches!(
20296 &d.this,
20297 Expression::Cast(_) | Expression::SafeCast(_) | Expression::TryCast(_)
20298 );
20299 if use_colon {
20300 self.write(":");
20301 } else {
20302 self.write(".");
20303 }
20304 self.generate_identifier(&d.field)
20305 }
20306
20307 fn generate_method_call(&mut self, m: &MethodCall) -> Result<()> {
20308 self.generate_expression(&m.this)?;
20309 self.write(".");
20310 if m.method.quoted {
20313 let q = self.config.identifier_quote;
20314 self.write(&format!("{}{}{}", q, m.method.name, q));
20315 } else {
20316 self.write(&m.method.name);
20317 }
20318 self.write("(");
20319 for (i, arg) in m.args.iter().enumerate() {
20320 if i > 0 {
20321 self.write(", ");
20322 }
20323 self.generate_expression(arg)?;
20324 }
20325 self.write(")");
20326 Ok(())
20327 }
20328
20329 fn generate_array_slice(&mut self, s: &ArraySlice) -> Result<()> {
20330 let needs_parens = matches!(
20333 &s.this,
20334 Expression::JsonExtract(f) if f.arrow_syntax
20335 ) || matches!(
20336 &s.this,
20337 Expression::JsonExtractScalar(f) if f.arrow_syntax
20338 );
20339
20340 if needs_parens {
20341 self.write("(");
20342 }
20343 self.generate_expression(&s.this)?;
20344 if needs_parens {
20345 self.write(")");
20346 }
20347 self.write("[");
20348 if let Some(start) = &s.start {
20349 self.generate_expression(start)?;
20350 }
20351 self.write(":");
20352 if let Some(end) = &s.end {
20353 self.generate_expression(end)?;
20354 }
20355 self.write("]");
20356 Ok(())
20357 }
20358
20359 fn generate_binary_op(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
20360 match &op.left {
20364 Expression::Column(col) => {
20365 if let Some(table) = &col.table {
20368 self.generate_identifier(table)?;
20369 self.write(".");
20370 }
20371 self.generate_identifier(&col.name)?;
20372 if col.join_mark && self.config.supports_column_join_marks {
20374 self.write(" (+)");
20375 }
20376 if op.left_comments.is_empty() {
20378 for comment in &col.trailing_comments {
20379 self.write_space();
20380 self.write_formatted_comment(comment);
20381 }
20382 }
20383 }
20384 Expression::Add(inner_op)
20385 | Expression::Sub(inner_op)
20386 | Expression::Mul(inner_op)
20387 | Expression::Div(inner_op)
20388 | Expression::Concat(inner_op) => {
20389 self.generate_binary_op_no_trailing(inner_op, match &op.left {
20391 Expression::Add(_) => "+",
20392 Expression::Sub(_) => "-",
20393 Expression::Mul(_) => "*",
20394 Expression::Div(_) => "/",
20395 Expression::Concat(_) => "||",
20396 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
20397 })?;
20398 }
20399 _ => {
20400 self.generate_expression(&op.left)?;
20401 }
20402 }
20403 for comment in &op.left_comments {
20405 self.write_space();
20406 self.write_formatted_comment(comment);
20407 }
20408 if self.config.pretty
20409 && matches!(self.config.dialect, Some(DialectType::Snowflake))
20410 && (operator == "AND" || operator == "OR")
20411 {
20412 self.write_newline();
20413 self.write_indent();
20414 self.write_keyword(operator);
20415 } else {
20416 self.write_space();
20417 if operator.chars().all(|c| c.is_alphabetic()) {
20418 self.write_keyword(operator);
20419 } else {
20420 self.write(operator);
20421 }
20422 }
20423 for comment in &op.operator_comments {
20425 self.write_space();
20426 self.write_formatted_comment(comment);
20427 }
20428 self.write_space();
20429 self.generate_expression(&op.right)?;
20430 for comment in &op.trailing_comments {
20432 self.write_space();
20433 self.write_formatted_comment(comment);
20434 }
20435 Ok(())
20436 }
20437
20438 fn generate_connector_op(&mut self, op: &BinaryOp, connector: ConnectorOperator) -> Result<()> {
20439 let keyword = connector.keyword();
20440 let Some(terms) = self.flatten_connector_terms(op, connector) else {
20441 return self.generate_binary_op(op, keyword);
20442 };
20443
20444 self.generate_expression(terms[0])?;
20445 for term in terms.iter().skip(1) {
20446 if self.config.pretty && matches!(self.config.dialect, Some(DialectType::Snowflake)) {
20447 self.write_newline();
20448 self.write_indent();
20449 self.write_keyword(keyword);
20450 } else {
20451 self.write_space();
20452 self.write_keyword(keyword);
20453 }
20454 self.write_space();
20455 self.generate_expression(term)?;
20456 }
20457
20458 Ok(())
20459 }
20460
20461 fn flatten_connector_terms<'a>(
20462 &self,
20463 root: &'a BinaryOp,
20464 connector: ConnectorOperator,
20465 ) -> Option<Vec<&'a Expression>> {
20466 if !root.left_comments.is_empty()
20467 || !root.operator_comments.is_empty()
20468 || !root.trailing_comments.is_empty()
20469 {
20470 return None;
20471 }
20472
20473 let mut terms = Vec::new();
20474 let mut stack: Vec<&Expression> = vec![&root.right, &root.left];
20475
20476 while let Some(expr) = stack.pop() {
20477 match (connector, expr) {
20478 (ConnectorOperator::And, Expression::And(inner))
20479 if inner.left_comments.is_empty()
20480 && inner.operator_comments.is_empty()
20481 && inner.trailing_comments.is_empty() =>
20482 {
20483 stack.push(&inner.right);
20484 stack.push(&inner.left);
20485 }
20486 (ConnectorOperator::Or, Expression::Or(inner))
20487 if inner.left_comments.is_empty()
20488 && inner.operator_comments.is_empty()
20489 && inner.trailing_comments.is_empty() =>
20490 {
20491 stack.push(&inner.right);
20492 stack.push(&inner.left);
20493 }
20494 _ => terms.push(expr),
20495 }
20496 }
20497
20498 if terms.len() > 1 {
20499 Some(terms)
20500 } else {
20501 None
20502 }
20503 }
20504
20505 fn generate_like_op(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
20507 self.generate_expression(&op.left)?;
20508 self.write_space();
20509 if operator == "ILIKE" && matches!(self.config.dialect, Some(DialectType::Drill)) {
20511 self.write("`ILIKE`");
20512 } else {
20513 self.write_keyword(operator);
20514 }
20515 if let Some(quantifier) = &op.quantifier {
20516 self.write_space();
20517 self.write_keyword(quantifier);
20518 }
20519 self.write_space();
20520 self.generate_expression(&op.right)?;
20521 if let Some(escape) = &op.escape {
20522 self.write_space();
20523 self.write_keyword("ESCAPE");
20524 self.write_space();
20525 self.generate_expression(escape)?;
20526 }
20527 Ok(())
20528 }
20529
20530 fn generate_null_safe_eq(&mut self, op: &BinaryOp) -> Result<()> {
20533 use crate::dialects::DialectType;
20534 self.generate_expression(&op.left)?;
20535 self.write_space();
20536 if matches!(self.config.dialect, Some(DialectType::MySQL)) {
20537 self.write("<=>");
20538 } else {
20539 self.write_keyword("IS NOT DISTINCT FROM");
20540 }
20541 self.write_space();
20542 self.generate_expression(&op.right)?;
20543 Ok(())
20544 }
20545
20546 fn generate_null_safe_neq(&mut self, op: &BinaryOp) -> Result<()> {
20548 self.generate_expression(&op.left)?;
20549 self.write_space();
20550 self.write_keyword("IS DISTINCT FROM");
20551 self.write_space();
20552 self.generate_expression(&op.right)?;
20553 Ok(())
20554 }
20555
20556 fn generate_binary_op_no_trailing(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
20558 match &op.left {
20560 Expression::Column(col) => {
20561 if let Some(table) = &col.table {
20562 self.generate_identifier(table)?;
20563 self.write(".");
20564 }
20565 self.generate_identifier(&col.name)?;
20566 if col.join_mark && self.config.supports_column_join_marks {
20568 self.write(" (+)");
20569 }
20570 }
20571 Expression::Add(inner_op)
20572 | Expression::Sub(inner_op)
20573 | Expression::Mul(inner_op)
20574 | Expression::Div(inner_op)
20575 | Expression::Concat(inner_op) => {
20576 self.generate_binary_op_no_trailing(inner_op, match &op.left {
20577 Expression::Add(_) => "+",
20578 Expression::Sub(_) => "-",
20579 Expression::Mul(_) => "*",
20580 Expression::Div(_) => "/",
20581 Expression::Concat(_) => "||",
20582 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
20583 })?;
20584 }
20585 _ => {
20586 self.generate_expression(&op.left)?;
20587 }
20588 }
20589 for comment in &op.left_comments {
20591 self.write_space();
20592 self.write_formatted_comment(comment);
20593 }
20594 self.write_space();
20595 if operator.chars().all(|c| c.is_alphabetic()) {
20596 self.write_keyword(operator);
20597 } else {
20598 self.write(operator);
20599 }
20600 for comment in &op.operator_comments {
20602 self.write_space();
20603 self.write_formatted_comment(comment);
20604 }
20605 self.write_space();
20606 match &op.right {
20609 Expression::Column(col) => {
20610 if let Some(table) = &col.table {
20611 self.generate_identifier(table)?;
20612 self.write(".");
20613 }
20614 self.generate_identifier(&col.name)?;
20615 if col.join_mark && self.config.supports_column_join_marks {
20617 self.write(" (+)");
20618 }
20619 }
20620 _ => {
20621 self.generate_expression(&op.right)?;
20622 }
20623 }
20624 Ok(())
20626 }
20627
20628 fn generate_unary_op(&mut self, op: &UnaryOp, operator: &str) -> Result<()> {
20629 if operator.chars().all(|c| c.is_alphabetic()) {
20630 self.write_keyword(operator);
20631 self.write_space();
20632 } else {
20633 self.write(operator);
20634 if matches!(&op.this, Expression::Neg(_) | Expression::BitwiseNot(_)) {
20636 self.write_space();
20637 }
20638 }
20639 self.generate_expression(&op.this)
20640 }
20641
20642 fn generate_in(&mut self, in_expr: &In) -> Result<()> {
20643 let is_generic =
20647 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
20648 let use_prefix_not =
20649 in_expr.not && is_generic && self.config.not_in_style == NotInStyle::Prefix;
20650 if use_prefix_not {
20651 self.write_keyword("NOT");
20652 self.write_space();
20653 }
20654 self.generate_expression(&in_expr.this)?;
20655 if in_expr.global {
20656 self.write_space();
20657 self.write_keyword("GLOBAL");
20658 }
20659 if in_expr.not && !use_prefix_not {
20660 self.write_space();
20661 self.write_keyword("NOT");
20662 }
20663 self.write_space();
20664 self.write_keyword("IN");
20665
20666 if let Some(unnest_expr) = &in_expr.unnest {
20668 self.write_space();
20669 self.write_keyword("UNNEST");
20670 self.write("(");
20671 self.generate_expression(unnest_expr)?;
20672 self.write(")");
20673 return Ok(());
20674 }
20675
20676 if let Some(query) = &in_expr.query {
20677 let is_bare = in_expr.expressions.is_empty()
20680 && !matches!(
20681 query,
20682 Expression::Select(_)
20683 | Expression::Union(_)
20684 | Expression::Intersect(_)
20685 | Expression::Except(_)
20686 | Expression::Subquery(_)
20687 );
20688 if is_bare {
20689 self.write_space();
20691 self.generate_expression(query)?;
20692 } else {
20693 self.write(" (");
20695 let is_statement = matches!(
20696 query,
20697 Expression::Select(_)
20698 | Expression::Union(_)
20699 | Expression::Intersect(_)
20700 | Expression::Except(_)
20701 | Expression::Subquery(_)
20702 );
20703 if self.config.pretty && is_statement {
20704 self.write_newline();
20705 self.indent_level += 1;
20706 self.write_indent();
20707 }
20708 self.generate_expression(query)?;
20709 if self.config.pretty && is_statement {
20710 self.write_newline();
20711 self.indent_level -= 1;
20712 self.write_indent();
20713 }
20714 self.write(")");
20715 }
20716 } else {
20717 let is_duckdb = matches!(
20721 self.config.dialect,
20722 Some(crate::dialects::DialectType::DuckDB)
20723 );
20724 let is_clickhouse = matches!(
20725 self.config.dialect,
20726 Some(crate::dialects::DialectType::ClickHouse)
20727 );
20728 let single_expr = in_expr.expressions.len() == 1;
20729 if is_clickhouse && single_expr {
20730 if let Expression::Array(arr) = &in_expr.expressions[0] {
20731 self.write(" (");
20733 for (i, expr) in arr.expressions.iter().enumerate() {
20734 if i > 0 {
20735 self.write(", ");
20736 }
20737 self.generate_expression(expr)?;
20738 }
20739 self.write(")");
20740 } else {
20741 self.write_space();
20742 self.generate_expression(&in_expr.expressions[0])?;
20743 }
20744 } else {
20745 let is_bare_ref = single_expr
20746 && matches!(
20747 &in_expr.expressions[0],
20748 Expression::Column(_) | Expression::Identifier(_) | Expression::Dot(_)
20749 );
20750 if (is_duckdb && is_bare_ref) || (in_expr.is_field && single_expr) {
20751 self.write_space();
20754 self.generate_expression(&in_expr.expressions[0])?;
20755 } else {
20756 self.write(" (");
20758 for (i, expr) in in_expr.expressions.iter().enumerate() {
20759 if i > 0 {
20760 self.write(", ");
20761 }
20762 self.generate_expression(expr)?;
20763 }
20764 self.write(")");
20765 }
20766 }
20767 }
20768
20769 Ok(())
20770 }
20771
20772 fn generate_between(&mut self, between: &Between) -> Result<()> {
20773 let use_prefix_not = between.not
20775 && (self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic));
20776 if use_prefix_not {
20777 self.write_keyword("NOT");
20778 self.write_space();
20779 }
20780 self.generate_expression(&between.this)?;
20781 if between.not && !use_prefix_not {
20782 self.write_space();
20783 self.write_keyword("NOT");
20784 }
20785 self.write_space();
20786 self.write_keyword("BETWEEN");
20787 if let Some(sym) = between.symmetric {
20789 if sym {
20790 self.write(" SYMMETRIC");
20791 } else {
20792 self.write(" ASYMMETRIC");
20793 }
20794 }
20795 self.write_space();
20796 self.generate_expression(&between.low)?;
20797 self.write_space();
20798 self.write_keyword("AND");
20799 self.write_space();
20800 self.generate_expression(&between.high)
20801 }
20802
20803 fn generate_is_null(&mut self, is_null: &IsNull) -> Result<()> {
20804 let use_prefix_not = is_null.not
20806 && (self.config.dialect.is_none()
20807 || self.config.dialect == Some(DialectType::Generic)
20808 || is_null.postfix_form);
20809 if use_prefix_not {
20810 self.write_keyword("NOT");
20812 self.write_space();
20813 self.generate_expression(&is_null.this)?;
20814 self.write_space();
20815 self.write_keyword("IS");
20816 self.write_space();
20817 self.write_keyword("NULL");
20818 } else {
20819 self.generate_expression(&is_null.this)?;
20820 self.write_space();
20821 self.write_keyword("IS");
20822 if is_null.not {
20823 self.write_space();
20824 self.write_keyword("NOT");
20825 }
20826 self.write_space();
20827 self.write_keyword("NULL");
20828 }
20829 Ok(())
20830 }
20831
20832 fn generate_is_true(&mut self, is_true: &IsTrueFalse) -> Result<()> {
20833 self.generate_expression(&is_true.this)?;
20834 self.write_space();
20835 self.write_keyword("IS");
20836 if is_true.not {
20837 self.write_space();
20838 self.write_keyword("NOT");
20839 }
20840 self.write_space();
20841 self.write_keyword("TRUE");
20842 Ok(())
20843 }
20844
20845 fn generate_is_false(&mut self, is_false: &IsTrueFalse) -> Result<()> {
20846 self.generate_expression(&is_false.this)?;
20847 self.write_space();
20848 self.write_keyword("IS");
20849 if is_false.not {
20850 self.write_space();
20851 self.write_keyword("NOT");
20852 }
20853 self.write_space();
20854 self.write_keyword("FALSE");
20855 Ok(())
20856 }
20857
20858 fn generate_is_json(&mut self, is_json: &IsJson) -> Result<()> {
20859 self.generate_expression(&is_json.this)?;
20860 self.write_space();
20861 self.write_keyword("IS");
20862 if is_json.negated {
20863 self.write_space();
20864 self.write_keyword("NOT");
20865 }
20866 self.write_space();
20867 self.write_keyword("JSON");
20868
20869 if let Some(ref json_type) = is_json.json_type {
20871 self.write_space();
20872 self.write_keyword(json_type);
20873 }
20874
20875 match &is_json.unique_keys {
20877 Some(JsonUniqueKeys::With) => {
20878 self.write_space();
20879 self.write_keyword("WITH UNIQUE KEYS");
20880 }
20881 Some(JsonUniqueKeys::Without) => {
20882 self.write_space();
20883 self.write_keyword("WITHOUT UNIQUE KEYS");
20884 }
20885 Some(JsonUniqueKeys::Shorthand) => {
20886 self.write_space();
20887 self.write_keyword("UNIQUE KEYS");
20888 }
20889 None => {}
20890 }
20891
20892 Ok(())
20893 }
20894
20895 fn generate_is(&mut self, is_expr: &BinaryOp) -> Result<()> {
20896 self.generate_expression(&is_expr.left)?;
20897 self.write_space();
20898 self.write_keyword("IS");
20899 self.write_space();
20900 self.generate_expression(&is_expr.right)
20901 }
20902
20903 fn generate_exists(&mut self, exists: &Exists) -> Result<()> {
20904 if exists.not {
20905 self.write_keyword("NOT");
20906 self.write_space();
20907 }
20908 self.write_keyword("EXISTS");
20909 self.write("(");
20910 let is_statement = matches!(
20911 &exists.this,
20912 Expression::Select(_)
20913 | Expression::Union(_)
20914 | Expression::Intersect(_)
20915 | Expression::Except(_)
20916 );
20917 if self.config.pretty && is_statement {
20918 self.write_newline();
20919 self.indent_level += 1;
20920 self.write_indent();
20921 self.generate_expression(&exists.this)?;
20922 self.write_newline();
20923 self.indent_level -= 1;
20924 self.write_indent();
20925 self.write(")");
20926 } else {
20927 self.generate_expression(&exists.this)?;
20928 self.write(")");
20929 }
20930 Ok(())
20931 }
20932
20933 fn generate_member_of(&mut self, op: &BinaryOp) -> Result<()> {
20934 self.generate_expression(&op.left)?;
20935 self.write_space();
20936 self.write_keyword("MEMBER OF");
20937 self.write("(");
20938 self.generate_expression(&op.right)?;
20939 self.write(")");
20940 Ok(())
20941 }
20942
20943 fn generate_subquery(&mut self, subquery: &Subquery) -> Result<()> {
20944 if subquery.lateral {
20945 self.write_keyword("LATERAL");
20946 self.write_space();
20947 }
20948
20949 let skip_outer_parens = if let Expression::Paren(ref p) = &subquery.this {
20953 matches!(
20954 &p.this,
20955 Expression::Select(_)
20956 | Expression::Union(_)
20957 | Expression::Intersect(_)
20958 | Expression::Except(_)
20959 | Expression::Subquery(_)
20960 )
20961 } else {
20962 false
20963 };
20964
20965 let is_statement = matches!(
20967 &subquery.this,
20968 Expression::Select(_)
20969 | Expression::Union(_)
20970 | Expression::Intersect(_)
20971 | Expression::Except(_)
20972 | Expression::Merge(_)
20973 );
20974
20975 if !skip_outer_parens {
20976 self.write("(");
20977 if self.config.pretty && is_statement {
20978 self.write_newline();
20979 self.indent_level += 1;
20980 self.write_indent();
20981 }
20982 }
20983 self.generate_expression(&subquery.this)?;
20984
20985 if subquery.modifiers_inside {
20987 if let Some(order_by) = &subquery.order_by {
20989 self.write_space();
20990 self.write_keyword("ORDER BY");
20991 self.write_space();
20992 for (i, ord) in order_by.expressions.iter().enumerate() {
20993 if i > 0 {
20994 self.write(", ");
20995 }
20996 self.generate_ordered(ord)?;
20997 }
20998 }
20999
21000 if let Some(limit) = &subquery.limit {
21001 self.write_space();
21002 self.write_keyword("LIMIT");
21003 self.write_space();
21004 self.generate_expression(&limit.this)?;
21005 if limit.percent {
21006 self.write_space();
21007 self.write_keyword("PERCENT");
21008 }
21009 }
21010
21011 if let Some(offset) = &subquery.offset {
21012 self.write_space();
21013 self.write_keyword("OFFSET");
21014 self.write_space();
21015 self.generate_expression(&offset.this)?;
21016 }
21017 }
21018
21019 if !skip_outer_parens {
21020 if self.config.pretty && is_statement {
21021 self.write_newline();
21022 self.indent_level -= 1;
21023 self.write_indent();
21024 }
21025 self.write(")");
21026 }
21027
21028 if !subquery.modifiers_inside {
21030 if let Some(order_by) = &subquery.order_by {
21031 self.write_space();
21032 self.write_keyword("ORDER BY");
21033 self.write_space();
21034 for (i, ord) in order_by.expressions.iter().enumerate() {
21035 if i > 0 {
21036 self.write(", ");
21037 }
21038 self.generate_ordered(ord)?;
21039 }
21040 }
21041
21042 if let Some(limit) = &subquery.limit {
21043 self.write_space();
21044 self.write_keyword("LIMIT");
21045 self.write_space();
21046 self.generate_expression(&limit.this)?;
21047 if limit.percent {
21048 self.write_space();
21049 self.write_keyword("PERCENT");
21050 }
21051 }
21052
21053 if let Some(offset) = &subquery.offset {
21054 self.write_space();
21055 self.write_keyword("OFFSET");
21056 self.write_space();
21057 self.generate_expression(&offset.this)?;
21058 }
21059
21060 if let Some(distribute_by) = &subquery.distribute_by {
21062 self.write_space();
21063 self.write_keyword("DISTRIBUTE BY");
21064 self.write_space();
21065 for (i, expr) in distribute_by.expressions.iter().enumerate() {
21066 if i > 0 {
21067 self.write(", ");
21068 }
21069 self.generate_expression(expr)?;
21070 }
21071 }
21072
21073 if let Some(sort_by) = &subquery.sort_by {
21075 self.write_space();
21076 self.write_keyword("SORT BY");
21077 self.write_space();
21078 for (i, ord) in sort_by.expressions.iter().enumerate() {
21079 if i > 0 {
21080 self.write(", ");
21081 }
21082 self.generate_ordered(ord)?;
21083 }
21084 }
21085
21086 if let Some(cluster_by) = &subquery.cluster_by {
21088 self.write_space();
21089 self.write_keyword("CLUSTER BY");
21090 self.write_space();
21091 for (i, ord) in cluster_by.expressions.iter().enumerate() {
21092 if i > 0 {
21093 self.write(", ");
21094 }
21095 self.generate_ordered(ord)?;
21096 }
21097 }
21098 }
21099
21100 if let Some(alias) = &subquery.alias {
21101 self.write_space();
21102 let skip_as = matches!(
21104 self.config.dialect,
21105 Some(crate::dialects::DialectType::Oracle)
21106 );
21107 if !skip_as {
21108 self.write_keyword("AS");
21109 self.write_space();
21110 }
21111 self.generate_identifier(alias)?;
21112 if !subquery.column_aliases.is_empty() {
21113 self.write("(");
21114 for (i, col) in subquery.column_aliases.iter().enumerate() {
21115 if i > 0 {
21116 self.write(", ");
21117 }
21118 self.generate_identifier(col)?;
21119 }
21120 self.write(")");
21121 }
21122 }
21123 for comment in &subquery.trailing_comments {
21125 self.write(" ");
21126 self.write_formatted_comment(comment);
21127 }
21128 Ok(())
21129 }
21130
21131 fn generate_pivot(&mut self, pivot: &Pivot) -> Result<()> {
21132 if let Some(ref with) = pivot.with {
21134 self.generate_with(with)?;
21135 self.write_space();
21136 }
21137
21138 let direction = if pivot.unpivot { "UNPIVOT" } else { "PIVOT" };
21139
21140 let is_redshift_unpivot = pivot.unpivot
21144 && pivot.expressions.is_empty()
21145 && pivot.fields.is_empty()
21146 && pivot.using.is_empty()
21147 && pivot.into.is_none()
21148 && !matches!(&pivot.this, Expression::Null(_));
21149
21150 if is_redshift_unpivot {
21151 self.write_keyword("UNPIVOT");
21153 self.write_space();
21154 self.generate_expression(&pivot.this)?;
21155 if let Some(alias) = &pivot.alias {
21157 self.write_space();
21158 self.write_keyword("AS");
21159 self.write_space();
21160 self.write(&alias.name);
21162 }
21163 return Ok(());
21164 }
21165
21166 let is_simplified = !pivot.using.is_empty()
21168 || pivot.into.is_some()
21169 || (pivot.fields.is_empty()
21170 && !pivot.expressions.is_empty()
21171 && !matches!(&pivot.this, Expression::Null(_)));
21172
21173 if is_simplified {
21174 self.write_keyword(direction);
21178 self.write_space();
21179 self.generate_expression(&pivot.this)?;
21180
21181 if !pivot.expressions.is_empty() {
21182 self.write_space();
21183 self.write_keyword("ON");
21184 self.write_space();
21185 for (i, expr) in pivot.expressions.iter().enumerate() {
21186 if i > 0 {
21187 self.write(", ");
21188 }
21189 self.generate_expression(expr)?;
21190 }
21191 }
21192
21193 if let Some(into) = &pivot.into {
21195 self.write_space();
21196 self.write_keyword("INTO");
21197 self.write_space();
21198 self.generate_expression(into)?;
21199 }
21200
21201 if !pivot.using.is_empty() {
21203 self.write_space();
21204 self.write_keyword("USING");
21205 self.write_space();
21206 for (i, expr) in pivot.using.iter().enumerate() {
21207 if i > 0 {
21208 self.write(", ");
21209 }
21210 self.generate_expression(expr)?;
21211 }
21212 }
21213
21214 if let Some(group) = &pivot.group {
21216 self.write_space();
21217 self.generate_expression(group)?;
21218 }
21219 } else {
21220 if !matches!(&pivot.this, Expression::Null(_)) {
21225 self.generate_expression(&pivot.this)?;
21226 self.write_space();
21227 }
21228 self.write_keyword(direction);
21229 self.write("(");
21230
21231 for (i, expr) in pivot.expressions.iter().enumerate() {
21233 if i > 0 {
21234 self.write(", ");
21235 }
21236 self.generate_expression(expr)?;
21237 }
21238
21239 if !pivot.fields.is_empty() {
21241 if !pivot.expressions.is_empty() {
21242 self.write_space();
21243 }
21244 self.write_keyword("FOR");
21245 self.write_space();
21246 for (i, field) in pivot.fields.iter().enumerate() {
21247 if i > 0 {
21248 self.write_space();
21249 }
21250 self.generate_expression(field)?;
21252 }
21253 }
21254
21255 if let Some(default_val) = &pivot.default_on_null {
21257 self.write_space();
21258 self.write_keyword("DEFAULT ON NULL");
21259 self.write(" (");
21260 self.generate_expression(default_val)?;
21261 self.write(")");
21262 }
21263
21264 if let Some(group) = &pivot.group {
21266 self.write_space();
21267 self.generate_expression(group)?;
21268 }
21269
21270 self.write(")");
21271 }
21272
21273 if let Some(alias) = &pivot.alias {
21275 self.write_space();
21276 self.write_keyword("AS");
21277 self.write_space();
21278 self.generate_identifier(alias)?;
21279 }
21280
21281 Ok(())
21282 }
21283
21284 fn generate_unpivot(&mut self, unpivot: &Unpivot) -> Result<()> {
21285 self.generate_expression(&unpivot.this)?;
21286 self.write_space();
21287 self.write_keyword("UNPIVOT");
21288 if let Some(include) = unpivot.include_nulls {
21290 self.write_space();
21291 if include {
21292 self.write_keyword("INCLUDE NULLS");
21293 } else {
21294 self.write_keyword("EXCLUDE NULLS");
21295 }
21296 self.write_space();
21297 }
21298 self.write("(");
21299 if unpivot.value_column_parenthesized {
21300 self.write("(");
21301 }
21302 self.generate_identifier(&unpivot.value_column)?;
21303 for extra_col in &unpivot.extra_value_columns {
21305 self.write(", ");
21306 self.generate_identifier(extra_col)?;
21307 }
21308 if unpivot.value_column_parenthesized {
21309 self.write(")");
21310 }
21311 self.write_space();
21312 self.write_keyword("FOR");
21313 self.write_space();
21314 self.generate_identifier(&unpivot.name_column)?;
21315 self.write_space();
21316 self.write_keyword("IN");
21317 self.write(" (");
21318 for (i, col) in unpivot.columns.iter().enumerate() {
21319 if i > 0 {
21320 self.write(", ");
21321 }
21322 self.generate_expression(col)?;
21323 }
21324 self.write("))");
21325 if let Some(alias) = &unpivot.alias {
21326 self.write_space();
21327 self.write_keyword("AS");
21328 self.write_space();
21329 self.generate_identifier(alias)?;
21330 }
21331 Ok(())
21332 }
21333
21334 fn generate_values(&mut self, values: &Values) -> Result<()> {
21335 self.write_keyword("VALUES");
21336 for (i, row) in values.expressions.iter().enumerate() {
21337 if i > 0 {
21338 self.write(",");
21339 }
21340 self.write(" (");
21341 for (j, expr) in row.expressions.iter().enumerate() {
21342 if j > 0 {
21343 self.write(", ");
21344 }
21345 self.generate_expression(expr)?;
21346 }
21347 self.write(")");
21348 }
21349 if let Some(alias) = &values.alias {
21350 self.write_space();
21351 self.write_keyword("AS");
21352 self.write_space();
21353 self.generate_identifier(alias)?;
21354 if !values.column_aliases.is_empty() {
21355 self.write("(");
21356 for (i, col) in values.column_aliases.iter().enumerate() {
21357 if i > 0 {
21358 self.write(", ");
21359 }
21360 self.generate_identifier(col)?;
21361 }
21362 self.write(")");
21363 }
21364 }
21365 Ok(())
21366 }
21367
21368 fn generate_array(&mut self, arr: &Array) -> Result<()> {
21369 let needs_inheritance = matches!(
21371 self.config.dialect,
21372 Some(DialectType::DuckDB)
21373 | Some(DialectType::Spark)
21374 | Some(DialectType::Databricks)
21375 | Some(DialectType::Hive)
21376 | Some(DialectType::Snowflake)
21377 | Some(DialectType::Presto)
21378 | Some(DialectType::Trino)
21379 );
21380 let propagated: Vec<Expression>;
21381 let expressions = if needs_inheritance && arr.expressions.len() > 1 {
21382 propagated = Self::inherit_struct_field_names(&arr.expressions);
21383 &propagated
21384 } else {
21385 &arr.expressions
21386 };
21387
21388 let use_parens =
21391 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
21392 if !self.config.array_bracket_only {
21393 self.write_keyword("ARRAY");
21394 }
21395 if use_parens {
21396 self.write("(");
21397 } else {
21398 self.write("[");
21399 }
21400 for (i, expr) in expressions.iter().enumerate() {
21401 if i > 0 {
21402 self.write(", ");
21403 }
21404 self.generate_expression(expr)?;
21405 }
21406 if use_parens {
21407 self.write(")");
21408 } else {
21409 self.write("]");
21410 }
21411 Ok(())
21412 }
21413
21414 fn generate_tuple(&mut self, tuple: &Tuple) -> Result<()> {
21415 if tuple.expressions.len() == 2 {
21418 if let Expression::TableAlias(_) = &tuple.expressions[1] {
21419 self.generate_expression(&tuple.expressions[0])?;
21421 self.write_space();
21422 self.write_keyword("AS");
21423 self.write_space();
21424 self.generate_expression(&tuple.expressions[1])?;
21425 return Ok(());
21426 }
21427 }
21428
21429 let expand_tuple = if self.config.pretty && tuple.expressions.len() > 1 {
21432 let mut expr_strings: Vec<String> = Vec::with_capacity(tuple.expressions.len());
21433 for expr in &tuple.expressions {
21434 expr_strings.push(self.generate_to_string(expr)?);
21435 }
21436 self.too_wide(&expr_strings)
21437 } else {
21438 false
21439 };
21440
21441 if expand_tuple {
21442 self.write("(");
21443 self.write_newline();
21444 self.indent_level += 1;
21445 for (i, expr) in tuple.expressions.iter().enumerate() {
21446 if i > 0 {
21447 self.write(",");
21448 self.write_newline();
21449 }
21450 self.write_indent();
21451 self.generate_expression(expr)?;
21452 }
21453 self.indent_level -= 1;
21454 self.write_newline();
21455 self.write_indent();
21456 self.write(")");
21457 } else {
21458 self.write("(");
21459 for (i, expr) in tuple.expressions.iter().enumerate() {
21460 if i > 0 {
21461 self.write(", ");
21462 }
21463 self.generate_expression(expr)?;
21464 }
21465 self.write(")");
21466 }
21467 Ok(())
21468 }
21469
21470 fn generate_pipe_operator(&mut self, pipe: &PipeOperator) -> Result<()> {
21471 self.generate_expression(&pipe.this)?;
21472 self.write(" |> ");
21473 self.generate_expression(&pipe.expression)?;
21474 Ok(())
21475 }
21476
21477 fn generate_ordered(&mut self, ordered: &Ordered) -> Result<()> {
21478 self.generate_expression(&ordered.this)?;
21479 if ordered.desc {
21480 self.write_space();
21481 self.write_keyword("DESC");
21482 } else if ordered.explicit_asc {
21483 self.write_space();
21484 self.write_keyword("ASC");
21485 }
21486 if let Some(nulls_first) = ordered.nulls_first {
21487 let is_asc = !ordered.desc;
21501 let is_nulls_are_large = matches!(
21502 self.config.dialect,
21503 Some(DialectType::Oracle)
21504 | Some(DialectType::PostgreSQL)
21505 | Some(DialectType::Redshift)
21506 | Some(DialectType::Snowflake)
21507 );
21508 let is_nulls_are_last = matches!(
21509 self.config.dialect,
21510 Some(DialectType::Dremio)
21511 | Some(DialectType::DuckDB)
21512 | Some(DialectType::Presto)
21513 | Some(DialectType::Trino)
21514 | Some(DialectType::Athena)
21515 | Some(DialectType::ClickHouse)
21516 | Some(DialectType::Drill)
21517 | Some(DialectType::Exasol)
21518 );
21519
21520 let is_default_nulls = if is_nulls_are_large {
21522 (is_asc && !nulls_first) || (!is_asc && nulls_first)
21524 } else if is_nulls_are_last {
21525 !nulls_first
21527 } else {
21528 false
21529 };
21530
21531 if !is_default_nulls {
21532 self.write_space();
21533 self.write_keyword("NULLS");
21534 self.write_space();
21535 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
21536 }
21537 }
21538 if let Some(ref with_fill) = ordered.with_fill {
21540 self.write_space();
21541 self.generate_with_fill(with_fill)?;
21542 }
21543 Ok(())
21544 }
21545
21546 fn write_clickhouse_type(&mut self, type_str: &str) {
21548 if self.clickhouse_nullable_depth < 0 {
21549 self.write(type_str);
21551 } else {
21552 self.write(&format!("Nullable({})", type_str));
21553 }
21554 }
21555
21556 fn generate_data_type(&mut self, dt: &DataType) -> Result<()> {
21557 use crate::dialects::DialectType;
21558
21559 match dt {
21560 DataType::Boolean => {
21561 match self.config.dialect {
21563 Some(DialectType::TSQL) => self.write_keyword("BIT"),
21564 Some(DialectType::MySQL) => self.write_keyword("BOOLEAN"), Some(DialectType::Oracle) => {
21566 self.write_keyword("NUMBER(1)")
21568 }
21569 Some(DialectType::ClickHouse) => self.write("Bool"), _ => self.write_keyword("BOOLEAN"),
21571 }
21572 }
21573 DataType::TinyInt { length } => {
21574 match self.config.dialect {
21578 Some(DialectType::PostgreSQL)
21579 | Some(DialectType::Redshift)
21580 | Some(DialectType::Oracle)
21581 | Some(DialectType::Exasol) => {
21582 self.write_keyword("SMALLINT");
21583 }
21584 Some(DialectType::Teradata) => {
21585 self.write_keyword("BYTEINT");
21587 }
21588 Some(DialectType::Dremio) => {
21589 self.write_keyword("INT");
21591 }
21592 Some(DialectType::ClickHouse) => {
21593 self.write_clickhouse_type("Int8");
21594 }
21595 _ => {
21596 self.write_keyword("TINYINT");
21597 }
21598 }
21599 if let Some(n) = length {
21600 if !matches!(
21601 self.config.dialect,
21602 Some(DialectType::Dremio) | Some(DialectType::ClickHouse)
21603 ) {
21604 self.write(&format!("({})", n));
21605 }
21606 }
21607 }
21608 DataType::SmallInt { length } => {
21609 match self.config.dialect {
21611 Some(DialectType::Dremio) => {
21612 self.write_keyword("INT");
21613 }
21614 Some(DialectType::SQLite) | Some(DialectType::Drill) => {
21615 self.write_keyword("INTEGER");
21616 }
21617 Some(DialectType::BigQuery) => {
21618 self.write_keyword("INT64");
21619 }
21620 Some(DialectType::ClickHouse) => {
21621 self.write_clickhouse_type("Int16");
21622 }
21623 _ => {
21624 self.write_keyword("SMALLINT");
21625 if let Some(n) = length {
21626 self.write(&format!("({})", n));
21627 }
21628 }
21629 }
21630 }
21631 DataType::Int {
21632 length,
21633 integer_spelling,
21634 } => {
21635 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
21637 self.write_keyword("INT64");
21638 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
21639 self.write_clickhouse_type("Int32");
21640 } else {
21641 let use_integer = match self.config.dialect {
21643 Some(DialectType::TSQL)
21644 | Some(DialectType::Fabric)
21645 | Some(DialectType::Presto)
21646 | Some(DialectType::Trino)
21647 | Some(DialectType::SQLite)
21648 | Some(DialectType::Redshift) => true,
21649 Some(DialectType::Databricks) => *integer_spelling,
21651 _ => false,
21652 };
21653 if use_integer {
21654 self.write_keyword("INTEGER");
21655 } else {
21656 self.write_keyword("INT");
21657 }
21658 if let Some(n) = length {
21659 self.write(&format!("({})", n));
21660 }
21661 }
21662 }
21663 DataType::BigInt { length } => {
21664 match self.config.dialect {
21666 Some(DialectType::Oracle) => {
21667 self.write_keyword("INT");
21669 }
21670 Some(DialectType::ClickHouse) => {
21671 self.write_clickhouse_type("Int64");
21672 }
21673 _ => {
21674 self.write_keyword("BIGINT");
21675 if let Some(n) = length {
21676 self.write(&format!("({})", n));
21677 }
21678 }
21679 }
21680 }
21681 DataType::Float {
21682 precision,
21683 scale,
21684 real_spelling,
21685 } => {
21686 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
21690 self.write_clickhouse_type("Float32");
21691 } else if *real_spelling
21692 && !matches!(
21693 self.config.dialect,
21694 Some(DialectType::Spark)
21695 | Some(DialectType::Databricks)
21696 | Some(DialectType::Hive)
21697 | Some(DialectType::Snowflake)
21698 | Some(DialectType::MySQL)
21699 | Some(DialectType::BigQuery)
21700 )
21701 {
21702 self.write_keyword("REAL")
21703 } else {
21704 match self.config.dialect {
21705 Some(DialectType::PostgreSQL) => self.write_keyword("REAL"),
21706 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
21707 _ => self.write_keyword("FLOAT"),
21708 }
21709 }
21710 if !matches!(
21713 self.config.dialect,
21714 Some(DialectType::Spark)
21715 | Some(DialectType::Databricks)
21716 | Some(DialectType::Hive)
21717 | Some(DialectType::Presto)
21718 | Some(DialectType::Trino)
21719 ) {
21720 if let Some(p) = precision {
21721 self.write(&format!("({}", p));
21722 if let Some(s) = scale {
21723 self.write(&format!(", {})", s));
21724 } else {
21725 self.write(")");
21726 }
21727 }
21728 }
21729 }
21730 DataType::Double { precision, scale } => {
21731 match self.config.dialect {
21733 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
21734 self.write_keyword("FLOAT")
21735 } Some(DialectType::Oracle) => self.write_keyword("DOUBLE PRECISION"),
21737 Some(DialectType::ClickHouse) => self.write_clickhouse_type("Float64"),
21738 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
21739 Some(DialectType::SQLite) => self.write_keyword("REAL"),
21740 Some(DialectType::PostgreSQL)
21741 | Some(DialectType::Redshift)
21742 | Some(DialectType::Teradata)
21743 | Some(DialectType::Materialize) => self.write_keyword("DOUBLE PRECISION"),
21744 _ => self.write_keyword("DOUBLE"),
21745 }
21746 if let Some(p) = precision {
21748 self.write(&format!("({}", p));
21749 if let Some(s) = scale {
21750 self.write(&format!(", {})", s));
21751 } else {
21752 self.write(")");
21753 }
21754 }
21755 }
21756 DataType::Decimal { precision, scale } => {
21757 match self.config.dialect {
21759 Some(DialectType::ClickHouse) => {
21760 self.write("Decimal");
21761 if let Some(p) = precision {
21762 self.write(&format!("({}", p));
21763 if let Some(s) = scale {
21764 self.write(&format!(", {}", s));
21765 }
21766 self.write(")");
21767 }
21768 }
21769 Some(DialectType::Oracle) => {
21770 self.write_keyword("NUMBER");
21772 if let Some(p) = precision {
21773 self.write(&format!("({}", p));
21774 if let Some(s) = scale {
21775 self.write(&format!(", {}", s));
21776 }
21777 self.write(")");
21778 }
21779 }
21780 Some(DialectType::BigQuery) => {
21781 self.write_keyword("NUMERIC");
21783 if let Some(p) = precision {
21784 self.write(&format!("({}", p));
21785 if let Some(s) = scale {
21786 self.write(&format!(", {}", s));
21787 }
21788 self.write(")");
21789 }
21790 }
21791 _ => {
21792 self.write_keyword("DECIMAL");
21793 if let Some(p) = precision {
21794 self.write(&format!("({}", p));
21795 if let Some(s) = scale {
21796 self.write(&format!(", {}", s));
21797 }
21798 self.write(")");
21799 }
21800 }
21801 }
21802 }
21803 DataType::Char { length } => {
21804 match self.config.dialect {
21806 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
21807 self.write_keyword("TEXT");
21809 }
21810 Some(DialectType::Hive)
21811 | Some(DialectType::Spark)
21812 | Some(DialectType::Databricks) => {
21813 if length.is_some()
21816 && !matches!(self.config.dialect, Some(DialectType::Hive))
21817 {
21818 self.write_keyword("CHAR");
21819 if let Some(n) = length {
21820 self.write(&format!("({})", n));
21821 }
21822 } else {
21823 self.write_keyword("STRING");
21824 }
21825 }
21826 Some(DialectType::Dremio) => {
21827 self.write_keyword("VARCHAR");
21829 if let Some(n) = length {
21830 self.write(&format!("({})", n));
21831 }
21832 }
21833 _ => {
21834 self.write_keyword("CHAR");
21835 if let Some(n) = length {
21836 self.write(&format!("({})", n));
21837 }
21838 }
21839 }
21840 }
21841 DataType::VarChar {
21842 length,
21843 parenthesized_length,
21844 } => {
21845 match self.config.dialect {
21847 Some(DialectType::Oracle) => {
21848 self.write_keyword("VARCHAR2");
21849 if let Some(n) = length {
21850 self.write(&format!("({})", n));
21851 }
21852 }
21853 Some(DialectType::DuckDB) => {
21854 self.write_keyword("TEXT");
21856 if let Some(n) = length {
21857 self.write(&format!("({})", n));
21858 }
21859 }
21860 Some(DialectType::SQLite) => {
21861 self.write_keyword("TEXT");
21863 if let Some(n) = length {
21864 self.write(&format!("({})", n));
21865 }
21866 }
21867 Some(DialectType::MySQL) if length.is_none() => {
21868 self.write_keyword("TEXT");
21870 }
21871 Some(DialectType::Hive)
21872 | Some(DialectType::Spark)
21873 | Some(DialectType::Databricks)
21874 if length.is_none() =>
21875 {
21876 self.write_keyword("STRING");
21878 }
21879 _ => {
21880 self.write_keyword("VARCHAR");
21881 if let Some(n) = length {
21882 if *parenthesized_length {
21884 self.write(&format!("(({}))", n));
21885 } else {
21886 self.write(&format!("({})", n));
21887 }
21888 }
21889 }
21890 }
21891 }
21892 DataType::Text => {
21893 match self.config.dialect {
21895 Some(DialectType::Oracle) => self.write_keyword("CLOB"),
21896 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
21897 self.write_keyword("VARCHAR(MAX)")
21898 }
21899 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
21900 Some(DialectType::Snowflake)
21901 | Some(DialectType::Dremio)
21902 | Some(DialectType::Drill) => self.write_keyword("VARCHAR"),
21903 Some(DialectType::Exasol) => self.write_keyword("LONG VARCHAR"),
21904 Some(DialectType::Presto)
21905 | Some(DialectType::Trino)
21906 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
21907 Some(DialectType::Spark)
21908 | Some(DialectType::Databricks)
21909 | Some(DialectType::Hive) => self.write_keyword("STRING"),
21910 Some(DialectType::Redshift) => self.write_keyword("VARCHAR(MAX)"),
21911 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
21912 self.write_keyword("STRING")
21913 }
21914 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
21915 _ => self.write_keyword("TEXT"),
21916 }
21917 }
21918 DataType::TextWithLength { length } => {
21919 match self.config.dialect {
21921 Some(DialectType::Oracle) => self.write(&format!("CLOB({})", length)),
21922 Some(DialectType::Hive)
21923 | Some(DialectType::Spark)
21924 | Some(DialectType::Databricks) => {
21925 self.write(&format!("VARCHAR({})", length));
21926 }
21927 Some(DialectType::Redshift) => self.write(&format!("VARCHAR({})", length)),
21928 Some(DialectType::BigQuery) => self.write(&format!("STRING({})", length)),
21929 Some(DialectType::Snowflake)
21930 | Some(DialectType::Presto)
21931 | Some(DialectType::Trino)
21932 | Some(DialectType::Athena)
21933 | Some(DialectType::Drill)
21934 | Some(DialectType::Dremio) => {
21935 self.write(&format!("VARCHAR({})", length));
21936 }
21937 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
21938 self.write(&format!("VARCHAR({})", length))
21939 }
21940 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
21941 self.write(&format!("STRING({})", length))
21942 }
21943 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
21944 _ => self.write(&format!("TEXT({})", length)),
21945 }
21946 }
21947 DataType::String { length } => {
21948 match self.config.dialect {
21950 Some(DialectType::ClickHouse) => {
21951 self.write("String");
21953 if let Some(n) = length {
21954 self.write(&format!("({})", n));
21955 }
21956 }
21957 Some(DialectType::BigQuery)
21958 | Some(DialectType::Hive)
21959 | Some(DialectType::Spark)
21960 | Some(DialectType::Databricks)
21961 | Some(DialectType::StarRocks)
21962 | Some(DialectType::Doris) => {
21963 self.write_keyword("STRING");
21964 if let Some(n) = length {
21965 self.write(&format!("({})", n));
21966 }
21967 }
21968 Some(DialectType::PostgreSQL) => {
21969 if let Some(n) = length {
21971 self.write_keyword("VARCHAR");
21972 self.write(&format!("({})", n));
21973 } else {
21974 self.write_keyword("TEXT");
21975 }
21976 }
21977 Some(DialectType::Redshift) => {
21978 if let Some(n) = length {
21980 self.write_keyword("VARCHAR");
21981 self.write(&format!("({})", n));
21982 } else {
21983 self.write_keyword("VARCHAR(MAX)");
21984 }
21985 }
21986 Some(DialectType::MySQL) => {
21987 if let Some(n) = length {
21989 self.write_keyword("VARCHAR");
21990 self.write(&format!("({})", n));
21991 } else {
21992 self.write_keyword("TEXT");
21993 }
21994 }
21995 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
21996 if let Some(n) = length {
21998 self.write_keyword("VARCHAR");
21999 self.write(&format!("({})", n));
22000 } else {
22001 self.write_keyword("VARCHAR(MAX)");
22002 }
22003 }
22004 Some(DialectType::Oracle) => {
22005 self.write_keyword("CLOB");
22007 }
22008 Some(DialectType::DuckDB) | Some(DialectType::Materialize) => {
22009 self.write_keyword("TEXT");
22011 if let Some(n) = length {
22012 self.write(&format!("({})", n));
22013 }
22014 }
22015 Some(DialectType::Presto)
22016 | Some(DialectType::Trino)
22017 | Some(DialectType::Drill)
22018 | Some(DialectType::Dremio) => {
22019 self.write_keyword("VARCHAR");
22021 if let Some(n) = length {
22022 self.write(&format!("({})", n));
22023 }
22024 }
22025 Some(DialectType::Snowflake) => {
22026 self.write_keyword("STRING");
22029 if let Some(n) = length {
22030 self.write(&format!("({})", n));
22031 }
22032 }
22033 _ => {
22034 self.write_keyword("STRING");
22036 if let Some(n) = length {
22037 self.write(&format!("({})", n));
22038 }
22039 }
22040 }
22041 }
22042 DataType::Binary { length } => {
22043 match self.config.dialect {
22045 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
22046 self.write_keyword("BYTEA");
22047 if let Some(n) = length {
22048 self.write(&format!("({})", n));
22049 }
22050 }
22051 Some(DialectType::Redshift) => {
22052 self.write_keyword("VARBYTE");
22053 if let Some(n) = length {
22054 self.write(&format!("({})", n));
22055 }
22056 }
22057 Some(DialectType::DuckDB)
22058 | Some(DialectType::SQLite)
22059 | Some(DialectType::Oracle) => {
22060 self.write_keyword("BLOB");
22062 if let Some(n) = length {
22063 self.write(&format!("({})", n));
22064 }
22065 }
22066 Some(DialectType::Presto)
22067 | Some(DialectType::Trino)
22068 | Some(DialectType::Athena)
22069 | Some(DialectType::Drill)
22070 | Some(DialectType::Dremio) => {
22071 self.write_keyword("VARBINARY");
22073 if let Some(n) = length {
22074 self.write(&format!("({})", n));
22075 }
22076 }
22077 Some(DialectType::ClickHouse) => {
22078 if self.clickhouse_nullable_depth < 0 {
22080 self.write("BINARY");
22081 } else {
22082 self.write("Nullable(BINARY");
22083 }
22084 if let Some(n) = length {
22085 self.write(&format!("({})", n));
22086 }
22087 if self.clickhouse_nullable_depth >= 0 {
22088 self.write(")");
22089 }
22090 }
22091 _ => {
22092 self.write_keyword("BINARY");
22093 if let Some(n) = length {
22094 self.write(&format!("({})", n));
22095 }
22096 }
22097 }
22098 }
22099 DataType::VarBinary { length } => {
22100 match self.config.dialect {
22102 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
22103 self.write_keyword("BYTEA");
22104 if let Some(n) = length {
22105 self.write(&format!("({})", n));
22106 }
22107 }
22108 Some(DialectType::Redshift) => {
22109 self.write_keyword("VARBYTE");
22110 if let Some(n) = length {
22111 self.write(&format!("({})", n));
22112 }
22113 }
22114 Some(DialectType::DuckDB)
22115 | Some(DialectType::SQLite)
22116 | Some(DialectType::Oracle) => {
22117 self.write_keyword("BLOB");
22119 if let Some(n) = length {
22120 self.write(&format!("({})", n));
22121 }
22122 }
22123 Some(DialectType::Exasol) => {
22124 self.write_keyword("VARCHAR");
22126 }
22127 Some(DialectType::Spark)
22128 | Some(DialectType::Hive)
22129 | Some(DialectType::Databricks) => {
22130 self.write_keyword("BINARY");
22132 if let Some(n) = length {
22133 self.write(&format!("({})", n));
22134 }
22135 }
22136 Some(DialectType::ClickHouse) => {
22137 self.write_clickhouse_type("String");
22139 }
22140 _ => {
22141 self.write_keyword("VARBINARY");
22142 if let Some(n) = length {
22143 self.write(&format!("({})", n));
22144 }
22145 }
22146 }
22147 }
22148 DataType::Blob => {
22149 match self.config.dialect {
22151 Some(DialectType::PostgreSQL) => self.write_keyword("BYTEA"),
22152 Some(DialectType::Redshift) => self.write_keyword("VARBYTE"),
22153 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
22154 self.write_keyword("VARBINARY")
22155 }
22156 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
22157 Some(DialectType::Exasol) => self.write_keyword("VARCHAR"),
22158 Some(DialectType::Presto)
22159 | Some(DialectType::Trino)
22160 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
22161 Some(DialectType::DuckDB) => {
22162 self.write_keyword("VARBINARY");
22165 }
22166 Some(DialectType::Spark)
22167 | Some(DialectType::Databricks)
22168 | Some(DialectType::Hive) => self.write_keyword("BINARY"),
22169 Some(DialectType::ClickHouse) => {
22170 self.write("Nullable(String)");
22174 }
22175 _ => self.write_keyword("BLOB"),
22176 }
22177 }
22178 DataType::Bit { length } => {
22179 match self.config.dialect {
22181 Some(DialectType::Dremio)
22182 | Some(DialectType::Spark)
22183 | Some(DialectType::Databricks)
22184 | Some(DialectType::Hive)
22185 | Some(DialectType::Snowflake)
22186 | Some(DialectType::BigQuery)
22187 | Some(DialectType::Presto)
22188 | Some(DialectType::Trino)
22189 | Some(DialectType::ClickHouse)
22190 | Some(DialectType::Redshift) => {
22191 self.write_keyword("BOOLEAN");
22193 }
22194 _ => {
22195 self.write_keyword("BIT");
22196 if let Some(n) = length {
22197 self.write(&format!("({})", n));
22198 }
22199 }
22200 }
22201 }
22202 DataType::VarBit { length } => {
22203 self.write_keyword("VARBIT");
22204 if let Some(n) = length {
22205 self.write(&format!("({})", n));
22206 }
22207 }
22208 DataType::Date => self.write_keyword("DATE"),
22209 DataType::Time {
22210 precision,
22211 timezone,
22212 } => {
22213 if *timezone {
22214 match self.config.dialect {
22216 Some(DialectType::DuckDB) => {
22217 self.write_keyword("TIMETZ");
22219 }
22220 Some(DialectType::PostgreSQL) => {
22221 self.write_keyword("TIMETZ");
22223 if let Some(p) = precision {
22224 self.write(&format!("({})", p));
22225 }
22226 }
22227 _ => {
22228 self.write_keyword("TIME");
22230 if let Some(p) = precision {
22231 self.write(&format!("({})", p));
22232 }
22233 self.write_keyword(" WITH TIME ZONE");
22234 }
22235 }
22236 } else {
22237 if matches!(
22239 self.config.dialect,
22240 Some(DialectType::Spark)
22241 | Some(DialectType::Databricks)
22242 | Some(DialectType::Hive)
22243 ) {
22244 self.write_keyword("TIMESTAMP");
22245 } else {
22246 self.write_keyword("TIME");
22247 if let Some(p) = precision {
22248 self.write(&format!("({})", p));
22249 }
22250 }
22251 }
22252 }
22253 DataType::Timestamp {
22254 precision,
22255 timezone,
22256 } => {
22257 match self.config.dialect {
22259 Some(DialectType::ClickHouse) => {
22260 self.write("DateTime");
22261 if let Some(p) = precision {
22262 self.write(&format!("({})", p));
22263 }
22264 }
22265 Some(DialectType::TSQL) => {
22266 if *timezone {
22267 self.write_keyword("DATETIMEOFFSET");
22268 } else {
22269 self.write_keyword("DATETIME2");
22270 }
22271 if let Some(p) = precision {
22272 self.write(&format!("({})", p));
22273 }
22274 }
22275 Some(DialectType::MySQL) => {
22276 self.write_keyword("TIMESTAMP");
22278 if let Some(p) = precision {
22279 self.write(&format!("({})", p));
22280 }
22281 }
22282 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
22283 self.write_keyword("DATETIME");
22285 if let Some(p) = precision {
22286 self.write(&format!("({})", p));
22287 }
22288 }
22289 Some(DialectType::BigQuery) => {
22290 if *timezone {
22292 self.write_keyword("TIMESTAMP");
22293 } else {
22294 self.write_keyword("DATETIME");
22295 }
22296 }
22297 Some(DialectType::DuckDB) => {
22298 if *timezone {
22300 self.write_keyword("TIMESTAMPTZ");
22301 } else {
22302 self.write_keyword("TIMESTAMP");
22303 if let Some(p) = precision {
22304 self.write(&format!("({})", p));
22305 }
22306 }
22307 }
22308 _ => {
22309 if *timezone && !self.config.tz_to_with_time_zone {
22310 self.write_keyword("TIMESTAMPTZ");
22312 if let Some(p) = precision {
22313 self.write(&format!("({})", p));
22314 }
22315 } else {
22316 self.write_keyword("TIMESTAMP");
22317 if let Some(p) = precision {
22318 self.write(&format!("({})", p));
22319 }
22320 if *timezone {
22321 self.write_space();
22322 self.write_keyword("WITH TIME ZONE");
22323 }
22324 }
22325 }
22326 }
22327 }
22328 DataType::Interval { unit, to } => {
22329 self.write_keyword("INTERVAL");
22330 if let Some(u) = unit {
22331 self.write_space();
22332 self.write_keyword(u);
22333 }
22334 if let Some(t) = to {
22336 self.write_space();
22337 self.write_keyword("TO");
22338 self.write_space();
22339 self.write_keyword(t);
22340 }
22341 }
22342 DataType::Json => {
22343 match self.config.dialect {
22345 Some(DialectType::Oracle) => self.write_keyword("JSON"), Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"), Some(DialectType::MySQL) => self.write_keyword("JSON"),
22348 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
22349 _ => self.write_keyword("JSON"),
22350 }
22351 }
22352 DataType::JsonB => {
22353 match self.config.dialect {
22355 Some(DialectType::PostgreSQL) => self.write_keyword("JSONB"),
22356 Some(DialectType::Doris) => self.write_keyword("JSONB"),
22357 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
22358 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
22359 Some(DialectType::DuckDB) => self.write_keyword("JSON"), _ => self.write_keyword("JSON"), }
22362 }
22363 DataType::Uuid => {
22364 match self.config.dialect {
22366 Some(DialectType::TSQL) => self.write_keyword("UNIQUEIDENTIFIER"),
22367 Some(DialectType::MySQL) => self.write_keyword("CHAR(36)"),
22368 Some(DialectType::Oracle) => self.write_keyword("RAW(16)"),
22369 Some(DialectType::BigQuery)
22370 | Some(DialectType::Spark)
22371 | Some(DialectType::Databricks) => self.write_keyword("STRING"),
22372 _ => self.write_keyword("UUID"),
22373 }
22374 }
22375 DataType::Array {
22376 element_type,
22377 dimension,
22378 } => {
22379 match self.config.dialect {
22381 Some(DialectType::PostgreSQL)
22382 | Some(DialectType::Redshift)
22383 | Some(DialectType::DuckDB) => {
22384 self.generate_data_type(element_type)?;
22386 if let Some(dim) = dimension {
22387 self.write(&format!("[{}]", dim));
22388 } else {
22389 self.write("[]");
22390 }
22391 }
22392 Some(DialectType::BigQuery) => {
22393 self.write_keyword("ARRAY<");
22394 self.generate_data_type(element_type)?;
22395 self.write(">");
22396 }
22397 Some(DialectType::Snowflake)
22398 | Some(DialectType::Presto)
22399 | Some(DialectType::Trino)
22400 | Some(DialectType::ClickHouse) => {
22401 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
22403 self.write("Array(");
22404 } else {
22405 self.write_keyword("ARRAY(");
22406 }
22407 self.generate_data_type(element_type)?;
22408 self.write(")");
22409 }
22410 Some(DialectType::TSQL)
22411 | Some(DialectType::MySQL)
22412 | Some(DialectType::Oracle) => {
22413 match self.config.dialect {
22416 Some(DialectType::MySQL) => self.write_keyword("JSON"),
22417 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
22418 _ => self.write_keyword("JSON"),
22419 }
22420 }
22421 _ => {
22422 self.write_keyword("ARRAY<");
22424 self.generate_data_type(element_type)?;
22425 self.write(">");
22426 }
22427 }
22428 }
22429 DataType::List { element_type } => {
22430 self.generate_data_type(element_type)?;
22432 self.write_keyword(" LIST");
22433 }
22434 DataType::Map {
22435 key_type,
22436 value_type,
22437 } => {
22438 match self.config.dialect {
22440 Some(DialectType::Materialize) => {
22441 self.write_keyword("MAP[");
22443 self.generate_data_type(key_type)?;
22444 self.write(" => ");
22445 self.generate_data_type(value_type)?;
22446 self.write("]");
22447 }
22448 Some(DialectType::Snowflake)
22449 | Some(DialectType::RisingWave)
22450 | Some(DialectType::DuckDB)
22451 | Some(DialectType::Presto)
22452 | Some(DialectType::Trino)
22453 | Some(DialectType::Athena) => {
22454 self.write_keyword("MAP(");
22455 self.generate_data_type(key_type)?;
22456 self.write(", ");
22457 self.generate_data_type(value_type)?;
22458 self.write(")");
22459 }
22460 Some(DialectType::ClickHouse) => {
22461 self.write("Map(");
22464 self.clickhouse_nullable_depth = -1; self.generate_data_type(key_type)?;
22466 self.clickhouse_nullable_depth = 0;
22467 self.write(", ");
22468 self.generate_data_type(value_type)?;
22469 self.write(")");
22470 }
22471 _ => {
22472 self.write_keyword("MAP<");
22473 self.generate_data_type(key_type)?;
22474 self.write(", ");
22475 self.generate_data_type(value_type)?;
22476 self.write(">");
22477 }
22478 }
22479 }
22480 DataType::Vector {
22481 element_type,
22482 dimension,
22483 } => {
22484 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
22485 self.write_keyword("VECTOR(");
22487 if let Some(dim) = dimension {
22488 self.write(&dim.to_string());
22489 }
22490 let type_alias = element_type.as_ref().and_then(|et| match et.as_ref() {
22492 DataType::TinyInt { .. } => Some("I8"),
22493 DataType::SmallInt { .. } => Some("I16"),
22494 DataType::Int { .. } => Some("I32"),
22495 DataType::BigInt { .. } => Some("I64"),
22496 DataType::Float { .. } => Some("F32"),
22497 DataType::Double { .. } => Some("F64"),
22498 _ => None,
22499 });
22500 if let Some(alias) = type_alias {
22501 if dimension.is_some() {
22502 self.write(", ");
22503 }
22504 self.write(alias);
22505 }
22506 self.write(")");
22507 } else {
22508 self.write_keyword("VECTOR(");
22510 if let Some(ref et) = element_type {
22511 self.generate_data_type(et)?;
22512 if dimension.is_some() {
22513 self.write(", ");
22514 }
22515 }
22516 if let Some(dim) = dimension {
22517 self.write(&dim.to_string());
22518 }
22519 self.write(")");
22520 }
22521 }
22522 DataType::Object { fields, modifier } => {
22523 self.write_keyword("OBJECT(");
22524 for (i, (name, dt, not_null)) in fields.iter().enumerate() {
22525 if i > 0 {
22526 self.write(", ");
22527 }
22528 self.write(name);
22529 self.write(" ");
22530 self.generate_data_type(dt)?;
22531 if *not_null {
22532 self.write_keyword(" NOT NULL");
22533 }
22534 }
22535 self.write(")");
22536 if let Some(mod_str) = modifier {
22537 self.write(" ");
22538 self.write_keyword(mod_str);
22539 }
22540 }
22541 DataType::Struct { fields, nested } => {
22542 match self.config.dialect {
22544 Some(DialectType::Snowflake) => {
22545 self.write_keyword("OBJECT(");
22547 for (i, field) in fields.iter().enumerate() {
22548 if i > 0 {
22549 self.write(", ");
22550 }
22551 if !field.name.is_empty() {
22552 self.write(&field.name);
22553 self.write(" ");
22554 }
22555 self.generate_data_type(&field.data_type)?;
22556 }
22557 self.write(")");
22558 }
22559 Some(DialectType::Presto) | Some(DialectType::Trino) => {
22560 self.write_keyword("ROW(");
22562 for (i, field) in fields.iter().enumerate() {
22563 if i > 0 {
22564 self.write(", ");
22565 }
22566 if !field.name.is_empty() {
22567 self.write(&field.name);
22568 self.write(" ");
22569 }
22570 self.generate_data_type(&field.data_type)?;
22571 }
22572 self.write(")");
22573 }
22574 Some(DialectType::DuckDB) => {
22575 self.write_keyword("STRUCT(");
22577 for (i, field) in fields.iter().enumerate() {
22578 if i > 0 {
22579 self.write(", ");
22580 }
22581 if !field.name.is_empty() {
22582 self.write(&field.name);
22583 self.write(" ");
22584 }
22585 self.generate_data_type(&field.data_type)?;
22586 }
22587 self.write(")");
22588 }
22589 Some(DialectType::ClickHouse) => {
22590 self.write("Tuple(");
22592 for (i, field) in fields.iter().enumerate() {
22593 if i > 0 {
22594 self.write(", ");
22595 }
22596 if !field.name.is_empty() {
22597 self.write(&field.name);
22598 self.write(" ");
22599 }
22600 self.generate_data_type(&field.data_type)?;
22601 }
22602 self.write(")");
22603 }
22604 Some(DialectType::SingleStore) => {
22605 self.write_keyword("RECORD(");
22607 for (i, field) in fields.iter().enumerate() {
22608 if i > 0 {
22609 self.write(", ");
22610 }
22611 if !field.name.is_empty() {
22612 self.write(&field.name);
22613 self.write(" ");
22614 }
22615 self.generate_data_type(&field.data_type)?;
22616 }
22617 self.write(")");
22618 }
22619 _ => {
22620 let force_angle_brackets = matches!(
22622 self.config.dialect,
22623 Some(DialectType::Hive)
22624 | Some(DialectType::Spark)
22625 | Some(DialectType::Databricks)
22626 );
22627 if *nested && !force_angle_brackets {
22628 self.write_keyword("STRUCT(");
22629 for (i, field) in fields.iter().enumerate() {
22630 if i > 0 {
22631 self.write(", ");
22632 }
22633 if !field.name.is_empty() {
22634 self.write(&field.name);
22635 self.write(" ");
22636 }
22637 self.generate_data_type(&field.data_type)?;
22638 }
22639 self.write(")");
22640 } else {
22641 self.write_keyword("STRUCT<");
22642 for (i, field) in fields.iter().enumerate() {
22643 if i > 0 {
22644 self.write(", ");
22645 }
22646 if !field.name.is_empty() {
22647 self.write(&field.name);
22649 self.write(self.config.struct_field_sep);
22650 }
22651 self.generate_data_type(&field.data_type)?;
22653 if let Some(comment) = &field.comment {
22655 self.write(" COMMENT '");
22656 self.write(comment);
22657 self.write("'");
22658 }
22659 if !field.options.is_empty() {
22661 self.write(" ");
22662 self.generate_options_clause(&field.options)?;
22663 }
22664 }
22665 self.write(">");
22666 }
22667 }
22668 }
22669 }
22670 DataType::Enum {
22671 values,
22672 assignments,
22673 } => {
22674 if self.config.dialect == Some(DialectType::ClickHouse) {
22677 self.write("Enum(");
22678 } else {
22679 self.write_keyword("ENUM(");
22680 }
22681 for (i, val) in values.iter().enumerate() {
22682 if i > 0 {
22683 self.write(", ");
22684 }
22685 self.write("'");
22686 self.write(val);
22687 self.write("'");
22688 if let Some(Some(assignment)) = assignments.get(i) {
22689 self.write(" = ");
22690 self.write(assignment);
22691 }
22692 }
22693 self.write(")");
22694 }
22695 DataType::Set { values } => {
22696 self.write_keyword("SET(");
22698 for (i, val) in values.iter().enumerate() {
22699 if i > 0 {
22700 self.write(", ");
22701 }
22702 self.write("'");
22703 self.write(val);
22704 self.write("'");
22705 }
22706 self.write(")");
22707 }
22708 DataType::Union { fields } => {
22709 self.write_keyword("UNION(");
22711 for (i, (name, dt)) in fields.iter().enumerate() {
22712 if i > 0 {
22713 self.write(", ");
22714 }
22715 if !name.is_empty() {
22716 self.write(name);
22717 self.write(" ");
22718 }
22719 self.generate_data_type(dt)?;
22720 }
22721 self.write(")");
22722 }
22723 DataType::Nullable { inner } => {
22724 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
22726 self.write("Nullable(");
22727 let saved_depth = self.clickhouse_nullable_depth;
22729 self.clickhouse_nullable_depth = -1;
22730 self.generate_data_type(inner)?;
22731 self.clickhouse_nullable_depth = saved_depth;
22732 self.write(")");
22733 } else {
22734 match inner.as_ref() {
22736 DataType::Custom { name } if name.to_uppercase() == "DATETIME" => {
22737 self.generate_data_type(&DataType::Timestamp {
22738 precision: None,
22739 timezone: false,
22740 })?;
22741 }
22742 _ => {
22743 self.generate_data_type(inner)?;
22744 }
22745 }
22746 }
22747 }
22748 DataType::Custom { name } => {
22749 let name_upper = name.to_uppercase();
22751 match self.config.dialect {
22752 Some(DialectType::ClickHouse) => {
22753 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
22754 (name_upper[..idx].to_string(), &name[idx..])
22755 } else {
22756 (name_upper.clone(), "")
22757 };
22758 let mapped = match base_upper.as_str() {
22759 "DATETIME" | "TIMESTAMPTZ" | "TIMESTAMP" | "TIMESTAMPNTZ"
22760 | "SMALLDATETIME" | "DATETIME2" => "DateTime",
22761 "DATETIME64" => "DateTime64",
22762 "DATE32" => "Date32",
22763 "INT" => "Int32",
22764 "MEDIUMINT" => "Int32",
22765 "INT8" => "Int8",
22766 "INT16" => "Int16",
22767 "INT32" => "Int32",
22768 "INT64" => "Int64",
22769 "INT128" => "Int128",
22770 "INT256" => "Int256",
22771 "UINT8" => "UInt8",
22772 "UINT16" => "UInt16",
22773 "UINT32" => "UInt32",
22774 "UINT64" => "UInt64",
22775 "UINT128" => "UInt128",
22776 "UINT256" => "UInt256",
22777 "FLOAT32" => "Float32",
22778 "FLOAT64" => "Float64",
22779 "DECIMAL32" => "Decimal32",
22780 "DECIMAL64" => "Decimal64",
22781 "DECIMAL128" => "Decimal128",
22782 "DECIMAL256" => "Decimal256",
22783 "ENUM" => "Enum",
22784 "ENUM8" => "Enum8",
22785 "ENUM16" => "Enum16",
22786 "FIXEDSTRING" => "FixedString",
22787 "NESTED" => "Nested",
22788 "LOWCARDINALITY" => "LowCardinality",
22789 "NULLABLE" => "Nullable",
22790 "IPV4" => "IPv4",
22791 "IPV6" => "IPv6",
22792 "POINT" => "Point",
22793 "RING" => "Ring",
22794 "LINESTRING" => "LineString",
22795 "MULTILINESTRING" => "MultiLineString",
22796 "POLYGON" => "Polygon",
22797 "MULTIPOLYGON" => "MultiPolygon",
22798 "AGGREGATEFUNCTION" => "AggregateFunction",
22799 "SIMPLEAGGREGATEFUNCTION" => "SimpleAggregateFunction",
22800 "DYNAMIC" => "Dynamic",
22801 _ => "",
22802 };
22803 if mapped.is_empty() {
22804 self.write(name);
22805 } else {
22806 self.write(mapped);
22807 self.write(suffix);
22808 }
22809 }
22810 Some(DialectType::MySQL)
22811 if name_upper == "TIMESTAMPTZ" || name_upper == "TIMESTAMPLTZ" =>
22812 {
22813 self.write_keyword("TIMESTAMP");
22815 }
22816 Some(DialectType::TSQL) if name_upper == "VARIANT" => {
22817 self.write_keyword("SQL_VARIANT");
22818 }
22819 Some(DialectType::DuckDB) if name_upper == "DECFLOAT" => {
22820 self.write_keyword("DECIMAL(38, 5)");
22821 }
22822 Some(DialectType::Exasol) => {
22823 match name_upper.as_str() {
22825 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => self.write_keyword("VARCHAR"),
22827 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => self.write_keyword("VARCHAR"),
22829 "MEDIUMINT" => self.write_keyword("INT"),
22831 "DECIMAL32" | "DECIMAL64" | "DECIMAL128" | "DECIMAL256" => {
22833 self.write_keyword("DECIMAL")
22834 }
22835 "DATETIME" => self.write_keyword("TIMESTAMP"),
22837 "TIMESTAMPLTZ" => self.write_keyword("TIMESTAMP WITH LOCAL TIME ZONE"),
22838 _ => self.write(name),
22839 }
22840 }
22841 Some(DialectType::Dremio) => {
22842 match name_upper.as_str() {
22844 "TIMESTAMPNTZ" | "DATETIME" => self.write_keyword("TIMESTAMP"),
22845 "ARRAY" => self.write_keyword("LIST"),
22846 "NCHAR" => self.write_keyword("VARCHAR"),
22847 _ => self.write(name),
22848 }
22849 }
22850 _ => {
22852 let (base_upper, _args_str) = if let Some(idx) = name_upper.find('(') {
22854 (name_upper[..idx].to_string(), Some(&name[idx..]))
22855 } else {
22856 (name_upper.clone(), None)
22857 };
22858
22859 match base_upper.as_str() {
22860 "INT64"
22861 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
22862 {
22863 self.write_keyword("BIGINT");
22864 }
22865 "FLOAT64"
22866 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
22867 {
22868 self.write_keyword("DOUBLE");
22869 }
22870 "BOOL"
22871 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
22872 {
22873 self.write_keyword("BOOLEAN");
22874 }
22875 "BYTES"
22876 if matches!(
22877 self.config.dialect,
22878 Some(DialectType::Spark)
22879 | Some(DialectType::Hive)
22880 | Some(DialectType::Databricks)
22881 ) =>
22882 {
22883 self.write_keyword("BINARY");
22884 }
22885 "BYTES"
22886 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
22887 {
22888 self.write_keyword("VARBINARY");
22889 }
22890 "DATETIME2" | "SMALLDATETIME"
22892 if !matches!(
22893 self.config.dialect,
22894 Some(DialectType::TSQL) | Some(DialectType::Fabric)
22895 ) =>
22896 {
22897 if matches!(
22899 self.config.dialect,
22900 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
22901 ) {
22902 self.write_keyword("TIMESTAMP");
22903 if let Some(args) = _args_str {
22904 self.write(args);
22905 }
22906 } else {
22907 self.write_keyword("TIMESTAMP");
22908 }
22909 }
22910 "DATETIMEOFFSET"
22912 if !matches!(
22913 self.config.dialect,
22914 Some(DialectType::TSQL) | Some(DialectType::Fabric)
22915 ) =>
22916 {
22917 if matches!(
22918 self.config.dialect,
22919 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
22920 ) {
22921 self.write_keyword("TIMESTAMPTZ");
22922 if let Some(args) = _args_str {
22923 self.write(args);
22924 }
22925 } else {
22926 self.write_keyword("TIMESTAMPTZ");
22927 }
22928 }
22929 "UNIQUEIDENTIFIER"
22931 if !matches!(
22932 self.config.dialect,
22933 Some(DialectType::TSQL) | Some(DialectType::Fabric)
22934 ) =>
22935 {
22936 match self.config.dialect {
22937 Some(DialectType::Spark)
22938 | Some(DialectType::Databricks)
22939 | Some(DialectType::Hive) => self.write_keyword("STRING"),
22940 _ => self.write_keyword("UUID"),
22941 }
22942 }
22943 "BIT"
22945 if !matches!(
22946 self.config.dialect,
22947 Some(DialectType::TSQL)
22948 | Some(DialectType::Fabric)
22949 | Some(DialectType::PostgreSQL)
22950 | Some(DialectType::MySQL)
22951 | Some(DialectType::DuckDB)
22952 ) =>
22953 {
22954 self.write_keyword("BOOLEAN");
22955 }
22956 "NVARCHAR"
22958 if !matches!(
22959 self.config.dialect,
22960 Some(DialectType::TSQL) | Some(DialectType::Fabric)
22961 ) =>
22962 {
22963 match self.config.dialect {
22964 Some(DialectType::Oracle) => {
22965 self.write_keyword("NVARCHAR2");
22967 if let Some(args) = _args_str {
22968 self.write(args);
22969 }
22970 }
22971 Some(DialectType::BigQuery) => {
22972 self.write_keyword("STRING");
22974 }
22975 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
22976 self.write_keyword("TEXT");
22977 if let Some(args) = _args_str {
22978 self.write(args);
22979 }
22980 }
22981 Some(DialectType::Hive) => {
22982 self.write_keyword("STRING");
22984 }
22985 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
22986 if _args_str.is_some() {
22987 self.write_keyword("VARCHAR");
22988 self.write(_args_str.unwrap());
22989 } else {
22990 self.write_keyword("STRING");
22991 }
22992 }
22993 _ => {
22994 self.write_keyword("VARCHAR");
22995 if let Some(args) = _args_str {
22996 self.write(args);
22997 }
22998 }
22999 }
23000 }
23001 "NCHAR"
23003 if !matches!(
23004 self.config.dialect,
23005 Some(DialectType::TSQL) | Some(DialectType::Fabric)
23006 ) =>
23007 {
23008 match self.config.dialect {
23009 Some(DialectType::Oracle) => {
23010 self.write_keyword("NCHAR");
23012 if let Some(args) = _args_str {
23013 self.write(args);
23014 }
23015 }
23016 Some(DialectType::BigQuery) => {
23017 self.write_keyword("STRING");
23019 }
23020 Some(DialectType::Hive) => {
23021 self.write_keyword("STRING");
23023 }
23024 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
23025 self.write_keyword("TEXT");
23026 if let Some(args) = _args_str {
23027 self.write(args);
23028 }
23029 }
23030 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
23031 if _args_str.is_some() {
23032 self.write_keyword("CHAR");
23033 self.write(_args_str.unwrap());
23034 } else {
23035 self.write_keyword("STRING");
23036 }
23037 }
23038 _ => {
23039 self.write_keyword("CHAR");
23040 if let Some(args) = _args_str {
23041 self.write(args);
23042 }
23043 }
23044 }
23045 }
23046 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => match self.config.dialect {
23049 Some(DialectType::MySQL)
23050 | Some(DialectType::SingleStore)
23051 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
23052 Some(DialectType::Spark)
23053 | Some(DialectType::Databricks)
23054 | Some(DialectType::Hive) => self.write_keyword("TEXT"),
23055 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
23056 Some(DialectType::Presto)
23057 | Some(DialectType::Trino)
23058 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
23059 Some(DialectType::Snowflake)
23060 | Some(DialectType::Redshift)
23061 | Some(DialectType::Dremio) => self.write_keyword("VARCHAR"),
23062 _ => self.write_keyword("TEXT"),
23063 },
23064 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => match self.config.dialect {
23067 Some(DialectType::MySQL)
23068 | Some(DialectType::SingleStore)
23069 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
23070 Some(DialectType::Spark)
23071 | Some(DialectType::Databricks)
23072 | Some(DialectType::Hive) => self.write_keyword("BLOB"),
23073 Some(DialectType::DuckDB) => self.write_keyword("VARBINARY"),
23074 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
23075 Some(DialectType::Presto)
23076 | Some(DialectType::Trino)
23077 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
23078 Some(DialectType::Snowflake)
23079 | Some(DialectType::Redshift)
23080 | Some(DialectType::Dremio) => self.write_keyword("VARBINARY"),
23081 _ => self.write_keyword("BLOB"),
23082 },
23083 "LONGVARCHAR" => match self.config.dialect {
23085 Some(DialectType::SQLite) => self.write_keyword("TEXT"),
23086 _ => self.write_keyword("VARCHAR"),
23087 },
23088 "DATETIME" => {
23090 match self.config.dialect {
23091 Some(DialectType::MySQL)
23092 | Some(DialectType::Doris)
23093 | Some(DialectType::StarRocks)
23094 | Some(DialectType::TSQL)
23095 | Some(DialectType::Fabric)
23096 | Some(DialectType::BigQuery)
23097 | Some(DialectType::SQLite)
23098 | Some(DialectType::Snowflake) => {
23099 self.write_keyword("DATETIME");
23100 if let Some(args) = _args_str {
23101 self.write(args);
23102 }
23103 }
23104 Some(_) => {
23105 self.write_keyword("TIMESTAMP");
23107 if let Some(args) = _args_str {
23108 self.write(args);
23109 }
23110 }
23111 None => {
23112 self.write(name);
23114 }
23115 }
23116 }
23117 "VARCHAR2"
23119 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
23120 {
23121 match self.config.dialect {
23122 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
23123 self.write_keyword("TEXT");
23124 }
23125 Some(DialectType::Hive)
23126 | Some(DialectType::Spark)
23127 | Some(DialectType::Databricks)
23128 | Some(DialectType::BigQuery)
23129 | Some(DialectType::ClickHouse)
23130 | Some(DialectType::StarRocks)
23131 | Some(DialectType::Doris) => {
23132 self.write_keyword("STRING");
23133 }
23134 _ => {
23135 self.write_keyword("VARCHAR");
23136 if let Some(args) = _args_str {
23137 self.write(args);
23138 }
23139 }
23140 }
23141 }
23142 "NVARCHAR2"
23143 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
23144 {
23145 match self.config.dialect {
23146 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
23147 self.write_keyword("TEXT");
23148 }
23149 Some(DialectType::Hive)
23150 | Some(DialectType::Spark)
23151 | Some(DialectType::Databricks)
23152 | Some(DialectType::BigQuery)
23153 | Some(DialectType::ClickHouse)
23154 | Some(DialectType::StarRocks)
23155 | Some(DialectType::Doris) => {
23156 self.write_keyword("STRING");
23157 }
23158 _ => {
23159 self.write_keyword("VARCHAR");
23160 if let Some(args) = _args_str {
23161 self.write(args);
23162 }
23163 }
23164 }
23165 }
23166 _ => self.write(name),
23167 }
23168 }
23169 }
23170 }
23171 DataType::Geometry { subtype, srid } => {
23172 match self.config.dialect {
23174 Some(DialectType::MySQL) => {
23175 if let Some(sub) = subtype {
23177 self.write_keyword(sub);
23178 if let Some(s) = srid {
23179 self.write(" SRID ");
23180 self.write(&s.to_string());
23181 }
23182 } else {
23183 self.write_keyword("GEOMETRY");
23184 }
23185 }
23186 Some(DialectType::BigQuery) => {
23187 self.write_keyword("GEOGRAPHY");
23189 }
23190 Some(DialectType::Teradata) => {
23191 self.write_keyword("ST_GEOMETRY");
23193 if subtype.is_some() || srid.is_some() {
23194 self.write("(");
23195 if let Some(sub) = subtype {
23196 self.write_keyword(sub);
23197 }
23198 if let Some(s) = srid {
23199 if subtype.is_some() {
23200 self.write(", ");
23201 }
23202 self.write(&s.to_string());
23203 }
23204 self.write(")");
23205 }
23206 }
23207 _ => {
23208 self.write_keyword("GEOMETRY");
23210 if subtype.is_some() || srid.is_some() {
23211 self.write("(");
23212 if let Some(sub) = subtype {
23213 self.write_keyword(sub);
23214 }
23215 if let Some(s) = srid {
23216 if subtype.is_some() {
23217 self.write(", ");
23218 }
23219 self.write(&s.to_string());
23220 }
23221 self.write(")");
23222 }
23223 }
23224 }
23225 }
23226 DataType::Geography { subtype, srid } => {
23227 match self.config.dialect {
23229 Some(DialectType::MySQL) => {
23230 if let Some(sub) = subtype {
23232 self.write_keyword(sub);
23233 } else {
23234 self.write_keyword("GEOMETRY");
23235 }
23236 let effective_srid = srid.unwrap_or(4326);
23238 self.write(" SRID ");
23239 self.write(&effective_srid.to_string());
23240 }
23241 Some(DialectType::BigQuery) => {
23242 self.write_keyword("GEOGRAPHY");
23244 }
23245 Some(DialectType::Snowflake) => {
23246 self.write_keyword("GEOGRAPHY");
23248 }
23249 _ => {
23250 self.write_keyword("GEOGRAPHY");
23252 if subtype.is_some() || srid.is_some() {
23253 self.write("(");
23254 if let Some(sub) = subtype {
23255 self.write_keyword(sub);
23256 }
23257 if let Some(s) = srid {
23258 if subtype.is_some() {
23259 self.write(", ");
23260 }
23261 self.write(&s.to_string());
23262 }
23263 self.write(")");
23264 }
23265 }
23266 }
23267 }
23268 DataType::CharacterSet { name } => {
23269 self.write_keyword("CHAR CHARACTER SET ");
23271 self.write(name);
23272 }
23273 _ => self.write("UNKNOWN"),
23274 }
23275 Ok(())
23276 }
23277
23278 fn write(&mut self, s: &str) {
23281 self.output.push_str(s);
23282 }
23283
23284 fn write_space(&mut self) {
23285 self.output.push(' ');
23286 }
23287
23288 fn write_keyword(&mut self, keyword: &str) {
23289 if self.config.uppercase_keywords {
23290 self.output.push_str(keyword);
23291 } else {
23292 self.output.push_str(&keyword.to_lowercase());
23293 }
23294 }
23295
23296 fn write_func_name(&mut self, name: &str) {
23298 let normalized = self.normalize_func_name(name);
23299 self.output.push_str(&normalized);
23300 }
23301
23302 fn convert_strptime_to_exasol_format(format: &str) -> String {
23306 let mut result = String::new();
23307 let chars: Vec<char> = format.chars().collect();
23308 let mut i = 0;
23309 while i < chars.len() {
23310 if chars[i] == '%' && i + 1 < chars.len() {
23311 let spec = chars[i + 1];
23312 let exasol_spec = match spec {
23313 'Y' => "YYYY",
23314 'y' => "YY",
23315 'm' => "MM",
23316 'd' => "DD",
23317 'H' => "HH",
23318 'M' => "MI",
23319 'S' => "SS",
23320 'a' => "DY", 'A' => "DAY", 'b' => "MON", 'B' => "MONTH", 'I' => "H12", 'u' => "ID", 'V' => "IW", 'G' => "IYYY", 'W' => "UW", 'U' => "UW", 'z' => "Z", _ => {
23332 result.push('%');
23334 result.push(spec);
23335 i += 2;
23336 continue;
23337 }
23338 };
23339 result.push_str(exasol_spec);
23340 i += 2;
23341 } else {
23342 result.push(chars[i]);
23343 i += 1;
23344 }
23345 }
23346 result
23347 }
23348
23349 fn convert_strptime_to_postgres_format(format: &str) -> String {
23353 let mut result = String::new();
23354 let chars: Vec<char> = format.chars().collect();
23355 let mut i = 0;
23356 while i < chars.len() {
23357 if chars[i] == '%' && i + 1 < chars.len() {
23358 if chars[i + 1] == '-' && i + 2 < chars.len() {
23360 let spec = chars[i + 2];
23361 let pg_spec = match spec {
23362 'd' => "FMDD",
23363 'm' => "FMMM",
23364 'H' => "FMHH24",
23365 'M' => "FMMI",
23366 'S' => "FMSS",
23367 _ => {
23368 result.push('%');
23369 result.push('-');
23370 result.push(spec);
23371 i += 3;
23372 continue;
23373 }
23374 };
23375 result.push_str(pg_spec);
23376 i += 3;
23377 continue;
23378 }
23379 let spec = chars[i + 1];
23380 let pg_spec = match spec {
23381 'Y' => "YYYY",
23382 'y' => "YY",
23383 'm' => "MM",
23384 'd' => "DD",
23385 'H' => "HH24",
23386 'I' => "HH12",
23387 'M' => "MI",
23388 'S' => "SS",
23389 'f' => "US", 'u' => "D", 'j' => "DDD", 'z' => "OF", 'Z' => "TZ", 'A' => "TMDay", 'a' => "TMDy", 'b' => "TMMon", 'B' => "TMMonth", 'U' => "WW", _ => {
23400 result.push('%');
23402 result.push(spec);
23403 i += 2;
23404 continue;
23405 }
23406 };
23407 result.push_str(pg_spec);
23408 i += 2;
23409 } else {
23410 result.push(chars[i]);
23411 i += 1;
23412 }
23413 }
23414 result
23415 }
23416
23417 fn write_limit_expr(&mut self, expr: &Expression) -> Result<()> {
23419 if self.config.limit_only_literals {
23420 if let Some(value) = Self::try_evaluate_constant(expr) {
23421 self.write(&value.to_string());
23422 return Ok(());
23423 }
23424 }
23425 self.generate_expression(expr)
23426 }
23427
23428 fn write_formatted_comment(&mut self, comment: &str) {
23432 let content = if comment.starts_with("/*") && comment.ends_with("*/") {
23435 &comment[2..comment.len() - 2]
23438 } else if comment.starts_with("--") {
23439 &comment[2..]
23442 } else {
23443 comment
23445 };
23446 if content.trim().is_empty() {
23448 return;
23449 }
23450 self.output.push_str("/*");
23452 if !content.starts_with(' ') {
23453 self.output.push(' ');
23454 }
23455 self.output.push_str(content);
23456 if !content.ends_with(' ') {
23457 self.output.push(' ');
23458 }
23459 self.output.push_str("*/");
23460 }
23461
23462 fn escape_block_for_single_quote(&self, block: &str) -> String {
23465 let escape_backslash = matches!(
23466 self.config.dialect,
23467 Some(crate::dialects::DialectType::Snowflake)
23468 );
23469 let mut escaped = String::with_capacity(block.len() + 4);
23470 for ch in block.chars() {
23471 if ch == '\'' {
23472 escaped.push('\\');
23473 escaped.push('\'');
23474 } else if escape_backslash && ch == '\\' {
23475 escaped.push('\\');
23476 escaped.push('\\');
23477 } else {
23478 escaped.push(ch);
23479 }
23480 }
23481 escaped
23482 }
23483
23484 fn write_newline(&mut self) {
23485 self.output.push('\n');
23486 }
23487
23488 fn write_indent(&mut self) {
23489 for _ in 0..self.indent_level {
23490 self.output.push_str(&self.config.indent);
23491 }
23492 }
23493
23494 fn too_wide(&self, args: &[String]) -> bool {
23500 args.iter().map(|s| s.len()).sum::<usize>() > self.config.max_text_width
23501 }
23502
23503 fn generate_to_string(&self, expr: &Expression) -> Result<String> {
23506 let config = GeneratorConfig {
23507 pretty: false,
23508 dialect: self.config.dialect,
23509 ..Default::default()
23510 };
23511 let mut gen = Generator::with_config(config);
23512 gen.generate_expression(expr)?;
23513 Ok(gen.output)
23514 }
23515
23516 fn write_clause_condition(&mut self, keyword: &str, condition: &Expression) -> Result<()> {
23519 if self.config.pretty {
23520 self.write_newline();
23521 self.write_indent();
23522 self.write_keyword(keyword);
23523 self.write_newline();
23524 self.indent_level += 1;
23525 self.write_indent();
23526 self.generate_expression(condition)?;
23527 self.indent_level -= 1;
23528 } else {
23529 self.write_space();
23530 self.write_keyword(keyword);
23531 self.write_space();
23532 self.generate_expression(condition)?;
23533 }
23534 Ok(())
23535 }
23536
23537 fn write_clause_expressions(&mut self, keyword: &str, exprs: &[Expression]) -> Result<()> {
23540 if exprs.is_empty() {
23541 return Ok(());
23542 }
23543
23544 if self.config.pretty {
23545 self.write_newline();
23546 self.write_indent();
23547 self.write_keyword(keyword);
23548 self.write_newline();
23549 self.indent_level += 1;
23550 for (i, expr) in exprs.iter().enumerate() {
23551 if i > 0 {
23552 self.write(",");
23553 self.write_newline();
23554 }
23555 self.write_indent();
23556 self.generate_expression(expr)?;
23557 }
23558 self.indent_level -= 1;
23559 } else {
23560 self.write_space();
23561 self.write_keyword(keyword);
23562 self.write_space();
23563 for (i, expr) in exprs.iter().enumerate() {
23564 if i > 0 {
23565 self.write(", ");
23566 }
23567 self.generate_expression(expr)?;
23568 }
23569 }
23570 Ok(())
23571 }
23572
23573 fn write_order_clause(&mut self, keyword: &str, orderings: &[Ordered]) -> Result<()> {
23575 if orderings.is_empty() {
23576 return Ok(());
23577 }
23578
23579 if self.config.pretty {
23580 self.write_newline();
23581 self.write_indent();
23582 self.write_keyword(keyword);
23583 self.write_newline();
23584 self.indent_level += 1;
23585 for (i, ordered) in orderings.iter().enumerate() {
23586 if i > 0 {
23587 self.write(",");
23588 self.write_newline();
23589 }
23590 self.write_indent();
23591 self.generate_ordered(ordered)?;
23592 }
23593 self.indent_level -= 1;
23594 } else {
23595 self.write_space();
23596 self.write_keyword(keyword);
23597 self.write_space();
23598 for (i, ordered) in orderings.iter().enumerate() {
23599 if i > 0 {
23600 self.write(", ");
23601 }
23602 self.generate_ordered(ordered)?;
23603 }
23604 }
23605 Ok(())
23606 }
23607
23608 fn write_window_clause(&mut self, windows: &[NamedWindow]) -> Result<()> {
23610 if windows.is_empty() {
23611 return Ok(());
23612 }
23613
23614 if self.config.pretty {
23615 self.write_newline();
23616 self.write_indent();
23617 self.write_keyword("WINDOW");
23618 self.write_newline();
23619 self.indent_level += 1;
23620 for (i, named_window) in windows.iter().enumerate() {
23621 if i > 0 {
23622 self.write(",");
23623 self.write_newline();
23624 }
23625 self.write_indent();
23626 self.generate_identifier(&named_window.name)?;
23627 self.write_space();
23628 self.write_keyword("AS");
23629 self.write(" (");
23630 self.generate_over(&named_window.spec)?;
23631 self.write(")");
23632 }
23633 self.indent_level -= 1;
23634 } else {
23635 self.write_space();
23636 self.write_keyword("WINDOW");
23637 self.write_space();
23638 for (i, named_window) in windows.iter().enumerate() {
23639 if i > 0 {
23640 self.write(", ");
23641 }
23642 self.generate_identifier(&named_window.name)?;
23643 self.write_space();
23644 self.write_keyword("AS");
23645 self.write(" (");
23646 self.generate_over(&named_window.spec)?;
23647 self.write(")");
23648 }
23649 }
23650 Ok(())
23651 }
23652
23653 fn generate_ai_agg(&mut self, e: &AIAgg) -> Result<()> {
23655 self.write_keyword("AI_AGG");
23657 self.write("(");
23658 self.generate_expression(&e.this)?;
23659 self.write(", ");
23660 self.generate_expression(&e.expression)?;
23661 self.write(")");
23662 Ok(())
23663 }
23664
23665 fn generate_ai_classify(&mut self, e: &AIClassify) -> Result<()> {
23666 self.write_keyword("AI_CLASSIFY");
23668 self.write("(");
23669 self.generate_expression(&e.this)?;
23670 if let Some(categories) = &e.categories {
23671 self.write(", ");
23672 self.generate_expression(categories)?;
23673 }
23674 if let Some(config) = &e.config {
23675 self.write(", ");
23676 self.generate_expression(config)?;
23677 }
23678 self.write(")");
23679 Ok(())
23680 }
23681
23682 fn generate_add_partition(&mut self, e: &AddPartition) -> Result<()> {
23683 self.write_keyword("ADD");
23685 self.write_space();
23686 if e.exists {
23687 self.write_keyword("IF NOT EXISTS");
23688 self.write_space();
23689 }
23690 self.generate_expression(&e.this)?;
23691 if let Some(location) = &e.location {
23692 self.write_space();
23693 self.generate_expression(location)?;
23694 }
23695 Ok(())
23696 }
23697
23698 fn generate_algorithm_property(&mut self, e: &AlgorithmProperty) -> Result<()> {
23699 self.write_keyword("ALGORITHM");
23701 self.write("=");
23702 self.generate_expression(&e.this)?;
23703 Ok(())
23704 }
23705
23706 fn generate_aliases(&mut self, e: &Aliases) -> Result<()> {
23707 self.generate_expression(&e.this)?;
23709 self.write_space();
23710 self.write_keyword("AS");
23711 self.write(" (");
23712 for (i, expr) in e.expressions.iter().enumerate() {
23713 if i > 0 {
23714 self.write(", ");
23715 }
23716 self.generate_expression(expr)?;
23717 }
23718 self.write(")");
23719 Ok(())
23720 }
23721
23722 fn generate_allowed_values_property(&mut self, e: &AllowedValuesProperty) -> Result<()> {
23723 self.write_keyword("ALLOWED_VALUES");
23725 self.write_space();
23726 for (i, expr) in e.expressions.iter().enumerate() {
23727 if i > 0 {
23728 self.write(", ");
23729 }
23730 self.generate_expression(expr)?;
23731 }
23732 Ok(())
23733 }
23734
23735 fn generate_alter_column(&mut self, e: &AlterColumn) -> Result<()> {
23736 self.write_keyword("ALTER COLUMN");
23738 self.write_space();
23739 self.generate_expression(&e.this)?;
23740
23741 if let Some(dtype) = &e.dtype {
23742 self.write_space();
23743 self.write_keyword("SET DATA TYPE");
23744 self.write_space();
23745 self.generate_expression(dtype)?;
23746 if let Some(collate) = &e.collate {
23747 self.write_space();
23748 self.write_keyword("COLLATE");
23749 self.write_space();
23750 self.generate_expression(collate)?;
23751 }
23752 if let Some(using) = &e.using {
23753 self.write_space();
23754 self.write_keyword("USING");
23755 self.write_space();
23756 self.generate_expression(using)?;
23757 }
23758 } else if let Some(default) = &e.default {
23759 self.write_space();
23760 self.write_keyword("SET DEFAULT");
23761 self.write_space();
23762 self.generate_expression(default)?;
23763 } else if let Some(comment) = &e.comment {
23764 self.write_space();
23765 self.write_keyword("COMMENT");
23766 self.write_space();
23767 self.generate_expression(comment)?;
23768 } else if let Some(drop) = &e.drop {
23769 self.write_space();
23770 self.write_keyword("DROP");
23771 self.write_space();
23772 self.generate_expression(drop)?;
23773 } else if let Some(visible) = &e.visible {
23774 self.write_space();
23775 self.generate_expression(visible)?;
23776 } else if let Some(rename_to) = &e.rename_to {
23777 self.write_space();
23778 self.write_keyword("RENAME TO");
23779 self.write_space();
23780 self.generate_expression(rename_to)?;
23781 } else if let Some(allow_null) = &e.allow_null {
23782 self.write_space();
23783 self.generate_expression(allow_null)?;
23784 }
23785 Ok(())
23786 }
23787
23788 fn generate_alter_session(&mut self, e: &AlterSession) -> Result<()> {
23789 self.write_keyword("ALTER SESSION");
23791 self.write_space();
23792 if e.unset.is_some() {
23793 self.write_keyword("UNSET");
23794 } else {
23795 self.write_keyword("SET");
23796 }
23797 self.write_space();
23798 for (i, expr) in e.expressions.iter().enumerate() {
23799 if i > 0 {
23800 self.write(", ");
23801 }
23802 self.generate_expression(expr)?;
23803 }
23804 Ok(())
23805 }
23806
23807 fn generate_alter_set(&mut self, e: &AlterSet) -> Result<()> {
23808 self.write_keyword("SET");
23810
23811 if let Some(opt) = &e.option {
23813 self.write_space();
23814 self.generate_expression(opt)?;
23815 }
23816
23817 if !e.expressions.is_empty() {
23820 let is_properties = e
23822 .expressions
23823 .iter()
23824 .any(|expr| matches!(expr, Expression::Eq(_)));
23825 if is_properties && e.option.is_none() {
23826 self.write_space();
23827 self.write_keyword("PROPERTIES");
23828 }
23829 self.write_space();
23830 for (i, expr) in e.expressions.iter().enumerate() {
23831 if i > 0 {
23832 self.write(", ");
23833 }
23834 self.generate_expression(expr)?;
23835 }
23836 }
23837
23838 if let Some(file_format) = &e.file_format {
23840 self.write(" ");
23841 self.write_keyword("STAGE_FILE_FORMAT");
23842 self.write(" = (");
23843 self.generate_space_separated_properties(file_format)?;
23844 self.write(")");
23845 }
23846
23847 if let Some(copy_options) = &e.copy_options {
23849 self.write(" ");
23850 self.write_keyword("STAGE_COPY_OPTIONS");
23851 self.write(" = (");
23852 self.generate_space_separated_properties(copy_options)?;
23853 self.write(")");
23854 }
23855
23856 if let Some(tag) = &e.tag {
23858 self.write(" ");
23859 self.write_keyword("TAG");
23860 self.write(" ");
23861 self.generate_expression(tag)?;
23862 }
23863
23864 Ok(())
23865 }
23866
23867 fn generate_space_separated_properties(&mut self, expr: &Expression) -> Result<()> {
23869 match expr {
23870 Expression::Tuple(t) => {
23871 for (i, prop) in t.expressions.iter().enumerate() {
23872 if i > 0 {
23873 self.write(" ");
23874 }
23875 self.generate_expression(prop)?;
23876 }
23877 }
23878 _ => {
23879 self.generate_expression(expr)?;
23880 }
23881 }
23882 Ok(())
23883 }
23884
23885 fn generate_alter_sort_key(&mut self, e: &AlterSortKey) -> Result<()> {
23886 self.write_keyword("ALTER");
23888 if e.compound.is_some() {
23889 self.write_space();
23890 self.write_keyword("COMPOUND");
23891 }
23892 self.write_space();
23893 self.write_keyword("SORTKEY");
23894 self.write_space();
23895 if let Some(this) = &e.this {
23896 self.generate_expression(this)?;
23897 } else if !e.expressions.is_empty() {
23898 self.write("(");
23899 for (i, expr) in e.expressions.iter().enumerate() {
23900 if i > 0 {
23901 self.write(", ");
23902 }
23903 self.generate_expression(expr)?;
23904 }
23905 self.write(")");
23906 }
23907 Ok(())
23908 }
23909
23910 fn generate_analyze(&mut self, e: &Analyze) -> Result<()> {
23911 self.write_keyword("ANALYZE");
23913 if !e.options.is_empty() {
23914 self.write_space();
23915 for (i, opt) in e.options.iter().enumerate() {
23916 if i > 0 {
23917 self.write_space();
23918 }
23919 if let Expression::Identifier(id) = opt {
23921 self.write_keyword(&id.name);
23922 } else {
23923 self.generate_expression(opt)?;
23924 }
23925 }
23926 }
23927 if let Some(kind) = &e.kind {
23928 self.write_space();
23929 self.write_keyword(kind);
23930 }
23931 if let Some(this) = &e.this {
23932 self.write_space();
23933 self.generate_expression(this)?;
23934 }
23935 if !e.columns.is_empty() {
23937 self.write("(");
23938 for (i, col) in e.columns.iter().enumerate() {
23939 if i > 0 {
23940 self.write(", ");
23941 }
23942 self.write(col);
23943 }
23944 self.write(")");
23945 }
23946 if let Some(partition) = &e.partition {
23947 self.write_space();
23948 self.generate_expression(partition)?;
23949 }
23950 if let Some(mode) = &e.mode {
23951 self.write_space();
23952 self.generate_expression(mode)?;
23953 }
23954 if let Some(expression) = &e.expression {
23955 self.write_space();
23956 self.generate_expression(expression)?;
23957 }
23958 if !e.properties.is_empty() {
23959 self.write_space();
23960 self.write_keyword(self.config.with_properties_prefix);
23961 self.write(" (");
23962 for (i, prop) in e.properties.iter().enumerate() {
23963 if i > 0 {
23964 self.write(", ");
23965 }
23966 self.generate_expression(prop)?;
23967 }
23968 self.write(")");
23969 }
23970 Ok(())
23971 }
23972
23973 fn generate_analyze_delete(&mut self, e: &AnalyzeDelete) -> Result<()> {
23974 self.write_keyword("DELETE");
23976 if let Some(kind) = &e.kind {
23977 self.write_space();
23978 self.write_keyword(kind);
23979 }
23980 self.write_space();
23981 self.write_keyword("STATISTICS");
23982 Ok(())
23983 }
23984
23985 fn generate_analyze_histogram(&mut self, e: &AnalyzeHistogram) -> Result<()> {
23986 if let Expression::Identifier(id) = e.this.as_ref() {
23989 self.write_keyword(&id.name);
23990 } else {
23991 self.generate_expression(&e.this)?;
23992 }
23993 self.write_space();
23994 self.write_keyword("HISTOGRAM ON");
23995 self.write_space();
23996 for (i, expr) in e.expressions.iter().enumerate() {
23997 if i > 0 {
23998 self.write(", ");
23999 }
24000 self.generate_expression(expr)?;
24001 }
24002 if let Some(expression) = &e.expression {
24003 self.write_space();
24004 self.generate_expression(expression)?;
24005 }
24006 if let Some(update_options) = &e.update_options {
24007 self.write_space();
24008 self.generate_expression(update_options)?;
24009 self.write_space();
24010 self.write_keyword("UPDATE");
24011 }
24012 Ok(())
24013 }
24014
24015 fn generate_analyze_list_chained_rows(&mut self, e: &AnalyzeListChainedRows) -> Result<()> {
24016 self.write_keyword("LIST CHAINED ROWS");
24018 if let Some(expression) = &e.expression {
24019 self.write_space();
24020 self.write_keyword("INTO");
24021 self.write_space();
24022 self.generate_expression(expression)?;
24023 }
24024 Ok(())
24025 }
24026
24027 fn generate_analyze_sample(&mut self, e: &AnalyzeSample) -> Result<()> {
24028 self.write_keyword("SAMPLE");
24030 self.write_space();
24031 if let Some(sample) = &e.sample {
24032 self.generate_expression(sample)?;
24033 self.write_space();
24034 }
24035 self.write_keyword(&e.kind);
24036 Ok(())
24037 }
24038
24039 fn generate_analyze_statistics(&mut self, e: &AnalyzeStatistics) -> Result<()> {
24040 self.write_keyword(&e.kind);
24042 if let Some(option) = &e.option {
24043 self.write_space();
24044 self.generate_expression(option)?;
24045 }
24046 self.write_space();
24047 self.write_keyword("STATISTICS");
24048 if let Some(this) = &e.this {
24049 self.write_space();
24050 self.generate_expression(this)?;
24051 }
24052 if !e.expressions.is_empty() {
24053 self.write_space();
24054 for (i, expr) in e.expressions.iter().enumerate() {
24055 if i > 0 {
24056 self.write(", ");
24057 }
24058 self.generate_expression(expr)?;
24059 }
24060 }
24061 Ok(())
24062 }
24063
24064 fn generate_analyze_validate(&mut self, e: &AnalyzeValidate) -> Result<()> {
24065 self.write_keyword("VALIDATE");
24067 self.write_space();
24068 self.write_keyword(&e.kind);
24069 if let Some(this) = &e.this {
24070 self.write_space();
24071 if let Expression::Identifier(id) = this.as_ref() {
24073 self.write_keyword(&id.name);
24074 } else {
24075 self.generate_expression(this)?;
24076 }
24077 }
24078 if let Some(expression) = &e.expression {
24079 self.write_space();
24080 self.write_keyword("INTO");
24081 self.write_space();
24082 self.generate_expression(expression)?;
24083 }
24084 Ok(())
24085 }
24086
24087 fn generate_analyze_with(&mut self, e: &AnalyzeWith) -> Result<()> {
24088 self.write_keyword("WITH");
24090 self.write_space();
24091 for (i, expr) in e.expressions.iter().enumerate() {
24092 if i > 0 {
24093 self.write(", ");
24094 }
24095 self.generate_expression(expr)?;
24096 }
24097 Ok(())
24098 }
24099
24100 fn generate_anonymous(&mut self, e: &Anonymous) -> Result<()> {
24101 self.generate_expression(&e.this)?;
24104 self.write("(");
24105 for (i, arg) in e.expressions.iter().enumerate() {
24106 if i > 0 {
24107 self.write(", ");
24108 }
24109 self.generate_expression(arg)?;
24110 }
24111 self.write(")");
24112 Ok(())
24113 }
24114
24115 fn generate_anonymous_agg_func(&mut self, e: &AnonymousAggFunc) -> Result<()> {
24116 self.generate_expression(&e.this)?;
24118 self.write("(");
24119 for (i, arg) in e.expressions.iter().enumerate() {
24120 if i > 0 {
24121 self.write(", ");
24122 }
24123 self.generate_expression(arg)?;
24124 }
24125 self.write(")");
24126 Ok(())
24127 }
24128
24129 fn generate_apply(&mut self, e: &Apply) -> Result<()> {
24130 self.generate_expression(&e.this)?;
24132 self.write_space();
24133 self.write_keyword("APPLY");
24134 self.write("(");
24135 self.generate_expression(&e.expression)?;
24136 self.write(")");
24137 Ok(())
24138 }
24139
24140 fn generate_approx_percentile_estimate(&mut self, e: &ApproxPercentileEstimate) -> Result<()> {
24141 self.write_keyword("APPROX_PERCENTILE_ESTIMATE");
24143 self.write("(");
24144 self.generate_expression(&e.this)?;
24145 if let Some(percentile) = &e.percentile {
24146 self.write(", ");
24147 self.generate_expression(percentile)?;
24148 }
24149 self.write(")");
24150 Ok(())
24151 }
24152
24153 fn generate_approx_quantile(&mut self, e: &ApproxQuantile) -> Result<()> {
24154 self.write_keyword("APPROX_QUANTILE");
24156 self.write("(");
24157 self.generate_expression(&e.this)?;
24158 if let Some(quantile) = &e.quantile {
24159 self.write(", ");
24160 self.generate_expression(quantile)?;
24161 }
24162 if let Some(accuracy) = &e.accuracy {
24163 self.write(", ");
24164 self.generate_expression(accuracy)?;
24165 }
24166 if let Some(weight) = &e.weight {
24167 self.write(", ");
24168 self.generate_expression(weight)?;
24169 }
24170 self.write(")");
24171 Ok(())
24172 }
24173
24174 fn generate_approx_quantiles(&mut self, e: &ApproxQuantiles) -> Result<()> {
24175 self.write_keyword("APPROX_QUANTILES");
24177 self.write("(");
24178 self.generate_expression(&e.this)?;
24179 if let Some(expression) = &e.expression {
24180 self.write(", ");
24181 self.generate_expression(expression)?;
24182 }
24183 self.write(")");
24184 Ok(())
24185 }
24186
24187 fn generate_approx_top_k(&mut self, e: &ApproxTopK) -> Result<()> {
24188 self.write_keyword("APPROX_TOP_K");
24190 self.write("(");
24191 self.generate_expression(&e.this)?;
24192 if let Some(expression) = &e.expression {
24193 self.write(", ");
24194 self.generate_expression(expression)?;
24195 }
24196 if let Some(counters) = &e.counters {
24197 self.write(", ");
24198 self.generate_expression(counters)?;
24199 }
24200 self.write(")");
24201 Ok(())
24202 }
24203
24204 fn generate_approx_top_k_accumulate(&mut self, e: &ApproxTopKAccumulate) -> Result<()> {
24205 self.write_keyword("APPROX_TOP_K_ACCUMULATE");
24207 self.write("(");
24208 self.generate_expression(&e.this)?;
24209 if let Some(expression) = &e.expression {
24210 self.write(", ");
24211 self.generate_expression(expression)?;
24212 }
24213 self.write(")");
24214 Ok(())
24215 }
24216
24217 fn generate_approx_top_k_combine(&mut self, e: &ApproxTopKCombine) -> Result<()> {
24218 self.write_keyword("APPROX_TOP_K_COMBINE");
24220 self.write("(");
24221 self.generate_expression(&e.this)?;
24222 if let Some(expression) = &e.expression {
24223 self.write(", ");
24224 self.generate_expression(expression)?;
24225 }
24226 self.write(")");
24227 Ok(())
24228 }
24229
24230 fn generate_approx_top_k_estimate(&mut self, e: &ApproxTopKEstimate) -> Result<()> {
24231 self.write_keyword("APPROX_TOP_K_ESTIMATE");
24233 self.write("(");
24234 self.generate_expression(&e.this)?;
24235 if let Some(expression) = &e.expression {
24236 self.write(", ");
24237 self.generate_expression(expression)?;
24238 }
24239 self.write(")");
24240 Ok(())
24241 }
24242
24243 fn generate_approx_top_sum(&mut self, e: &ApproxTopSum) -> Result<()> {
24244 self.write_keyword("APPROX_TOP_SUM");
24246 self.write("(");
24247 self.generate_expression(&e.this)?;
24248 self.write(", ");
24249 self.generate_expression(&e.expression)?;
24250 if let Some(count) = &e.count {
24251 self.write(", ");
24252 self.generate_expression(count)?;
24253 }
24254 self.write(")");
24255 Ok(())
24256 }
24257
24258 fn generate_arg_max(&mut self, e: &ArgMax) -> Result<()> {
24259 self.write_keyword("ARG_MAX");
24261 self.write("(");
24262 self.generate_expression(&e.this)?;
24263 self.write(", ");
24264 self.generate_expression(&e.expression)?;
24265 if let Some(count) = &e.count {
24266 self.write(", ");
24267 self.generate_expression(count)?;
24268 }
24269 self.write(")");
24270 Ok(())
24271 }
24272
24273 fn generate_arg_min(&mut self, e: &ArgMin) -> Result<()> {
24274 self.write_keyword("ARG_MIN");
24276 self.write("(");
24277 self.generate_expression(&e.this)?;
24278 self.write(", ");
24279 self.generate_expression(&e.expression)?;
24280 if let Some(count) = &e.count {
24281 self.write(", ");
24282 self.generate_expression(count)?;
24283 }
24284 self.write(")");
24285 Ok(())
24286 }
24287
24288 fn generate_array_all(&mut self, e: &ArrayAll) -> Result<()> {
24289 self.write_keyword("ARRAY_ALL");
24291 self.write("(");
24292 self.generate_expression(&e.this)?;
24293 self.write(", ");
24294 self.generate_expression(&e.expression)?;
24295 self.write(")");
24296 Ok(())
24297 }
24298
24299 fn generate_array_any(&mut self, e: &ArrayAny) -> Result<()> {
24300 self.write_keyword("ARRAY_ANY");
24302 self.write("(");
24303 self.generate_expression(&e.this)?;
24304 self.write(", ");
24305 self.generate_expression(&e.expression)?;
24306 self.write(")");
24307 Ok(())
24308 }
24309
24310 fn generate_array_construct_compact(&mut self, e: &ArrayConstructCompact) -> Result<()> {
24311 self.write_keyword("ARRAY_CONSTRUCT_COMPACT");
24313 self.write("(");
24314 for (i, expr) in e.expressions.iter().enumerate() {
24315 if i > 0 {
24316 self.write(", ");
24317 }
24318 self.generate_expression(expr)?;
24319 }
24320 self.write(")");
24321 Ok(())
24322 }
24323
24324 fn generate_array_sum(&mut self, e: &ArraySum) -> Result<()> {
24325 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
24327 self.write("arraySum");
24328 } else {
24329 self.write_keyword("ARRAY_SUM");
24330 }
24331 self.write("(");
24332 self.generate_expression(&e.this)?;
24333 if let Some(expression) = &e.expression {
24334 self.write(", ");
24335 self.generate_expression(expression)?;
24336 }
24337 self.write(")");
24338 Ok(())
24339 }
24340
24341 fn generate_at_index(&mut self, e: &AtIndex) -> Result<()> {
24342 self.generate_expression(&e.this)?;
24344 self.write_space();
24345 self.write_keyword("AT");
24346 self.write_space();
24347 self.generate_expression(&e.expression)?;
24348 Ok(())
24349 }
24350
24351 fn generate_attach(&mut self, e: &Attach) -> Result<()> {
24352 self.write_keyword("ATTACH");
24354 if e.exists {
24355 self.write_space();
24356 self.write_keyword("IF NOT EXISTS");
24357 }
24358 self.write_space();
24359 self.generate_expression(&e.this)?;
24360 if !e.expressions.is_empty() {
24361 self.write(" (");
24362 for (i, expr) in e.expressions.iter().enumerate() {
24363 if i > 0 {
24364 self.write(", ");
24365 }
24366 self.generate_expression(expr)?;
24367 }
24368 self.write(")");
24369 }
24370 Ok(())
24371 }
24372
24373 fn generate_attach_option(&mut self, e: &AttachOption) -> Result<()> {
24374 self.generate_expression(&e.this)?;
24377 if let Some(expression) = &e.expression {
24378 self.write_space();
24379 self.generate_expression(expression)?;
24380 }
24381 Ok(())
24382 }
24383
24384 fn generate_auto_increment_keyword(
24388 &mut self,
24389 col: &crate::expressions::ColumnDef,
24390 ) -> Result<()> {
24391 use crate::dialects::DialectType;
24392 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
24393 self.write_keyword("IDENTITY");
24394 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
24395 self.write("(");
24396 if let Some(ref start) = col.auto_increment_start {
24397 self.generate_expression(start)?;
24398 } else {
24399 self.write("0");
24400 }
24401 self.write(", ");
24402 if let Some(ref inc) = col.auto_increment_increment {
24403 self.generate_expression(inc)?;
24404 } else {
24405 self.write("1");
24406 }
24407 self.write(")");
24408 }
24409 } else if matches!(
24410 self.config.dialect,
24411 Some(DialectType::Snowflake) | Some(DialectType::SQLite)
24412 ) {
24413 self.write_keyword("AUTOINCREMENT");
24414 if let Some(ref start) = col.auto_increment_start {
24415 self.write_space();
24416 self.write_keyword("START");
24417 self.write_space();
24418 self.generate_expression(start)?;
24419 }
24420 if let Some(ref inc) = col.auto_increment_increment {
24421 self.write_space();
24422 self.write_keyword("INCREMENT");
24423 self.write_space();
24424 self.generate_expression(inc)?;
24425 }
24426 if let Some(order) = col.auto_increment_order {
24427 self.write_space();
24428 if order {
24429 self.write_keyword("ORDER");
24430 } else {
24431 self.write_keyword("NOORDER");
24432 }
24433 }
24434 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
24435 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
24436 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
24437 self.write(" (");
24438 let mut first = true;
24439 if let Some(ref start) = col.auto_increment_start {
24440 self.write_keyword("START WITH");
24441 self.write_space();
24442 self.generate_expression(start)?;
24443 first = false;
24444 }
24445 if let Some(ref inc) = col.auto_increment_increment {
24446 if !first {
24447 self.write_space();
24448 }
24449 self.write_keyword("INCREMENT BY");
24450 self.write_space();
24451 self.generate_expression(inc)?;
24452 }
24453 self.write(")");
24454 }
24455 } else if matches!(self.config.dialect, Some(DialectType::Databricks)) {
24456 self.write_keyword("GENERATED ALWAYS AS IDENTITY");
24457 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
24458 self.write(" (");
24459 let mut first = true;
24460 if let Some(ref start) = col.auto_increment_start {
24461 self.write_keyword("START WITH");
24462 self.write_space();
24463 self.generate_expression(start)?;
24464 first = false;
24465 }
24466 if let Some(ref inc) = col.auto_increment_increment {
24467 if !first {
24468 self.write_space();
24469 }
24470 self.write_keyword("INCREMENT BY");
24471 self.write_space();
24472 self.generate_expression(inc)?;
24473 }
24474 self.write(")");
24475 }
24476 } else if matches!(
24477 self.config.dialect,
24478 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24479 ) {
24480 self.write_keyword("IDENTITY");
24481 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
24482 self.write("(");
24483 if let Some(ref start) = col.auto_increment_start {
24484 self.generate_expression(start)?;
24485 } else {
24486 self.write("0");
24487 }
24488 self.write(", ");
24489 if let Some(ref inc) = col.auto_increment_increment {
24490 self.generate_expression(inc)?;
24491 } else {
24492 self.write("1");
24493 }
24494 self.write(")");
24495 }
24496 } else {
24497 self.write_keyword("AUTO_INCREMENT");
24498 if let Some(ref start) = col.auto_increment_start {
24499 self.write_space();
24500 self.write_keyword("START");
24501 self.write_space();
24502 self.generate_expression(start)?;
24503 }
24504 if let Some(ref inc) = col.auto_increment_increment {
24505 self.write_space();
24506 self.write_keyword("INCREMENT");
24507 self.write_space();
24508 self.generate_expression(inc)?;
24509 }
24510 if let Some(order) = col.auto_increment_order {
24511 self.write_space();
24512 if order {
24513 self.write_keyword("ORDER");
24514 } else {
24515 self.write_keyword("NOORDER");
24516 }
24517 }
24518 }
24519 Ok(())
24520 }
24521
24522 fn generate_auto_increment_property(&mut self, e: &AutoIncrementProperty) -> Result<()> {
24523 self.write_keyword("AUTO_INCREMENT");
24525 self.write("=");
24526 self.generate_expression(&e.this)?;
24527 Ok(())
24528 }
24529
24530 fn generate_auto_refresh_property(&mut self, e: &AutoRefreshProperty) -> Result<()> {
24531 self.write_keyword("AUTO_REFRESH");
24533 self.write("=");
24534 self.generate_expression(&e.this)?;
24535 Ok(())
24536 }
24537
24538 fn generate_backup_property(&mut self, e: &BackupProperty) -> Result<()> {
24539 self.write_keyword("BACKUP");
24541 self.write_space();
24542 self.generate_expression(&e.this)?;
24543 Ok(())
24544 }
24545
24546 fn generate_base64_decode_binary(&mut self, e: &Base64DecodeBinary) -> Result<()> {
24547 self.write_keyword("BASE64_DECODE_BINARY");
24549 self.write("(");
24550 self.generate_expression(&e.this)?;
24551 if let Some(alphabet) = &e.alphabet {
24552 self.write(", ");
24553 self.generate_expression(alphabet)?;
24554 }
24555 self.write(")");
24556 Ok(())
24557 }
24558
24559 fn generate_base64_decode_string(&mut self, e: &Base64DecodeString) -> Result<()> {
24560 self.write_keyword("BASE64_DECODE_STRING");
24562 self.write("(");
24563 self.generate_expression(&e.this)?;
24564 if let Some(alphabet) = &e.alphabet {
24565 self.write(", ");
24566 self.generate_expression(alphabet)?;
24567 }
24568 self.write(")");
24569 Ok(())
24570 }
24571
24572 fn generate_base64_encode(&mut self, e: &Base64Encode) -> Result<()> {
24573 self.write_keyword("BASE64_ENCODE");
24575 self.write("(");
24576 self.generate_expression(&e.this)?;
24577 if let Some(max_line_length) = &e.max_line_length {
24578 self.write(", ");
24579 self.generate_expression(max_line_length)?;
24580 }
24581 if let Some(alphabet) = &e.alphabet {
24582 self.write(", ");
24583 self.generate_expression(alphabet)?;
24584 }
24585 self.write(")");
24586 Ok(())
24587 }
24588
24589 fn generate_block_compression_property(&mut self, e: &BlockCompressionProperty) -> Result<()> {
24590 self.write_keyword("BLOCKCOMPRESSION");
24592 self.write("=");
24593 if let Some(autotemp) = &e.autotemp {
24594 self.write_keyword("AUTOTEMP");
24595 self.write("(");
24596 self.generate_expression(autotemp)?;
24597 self.write(")");
24598 }
24599 if let Some(always) = &e.always {
24600 self.generate_expression(always)?;
24601 }
24602 if let Some(default) = &e.default {
24603 self.generate_expression(default)?;
24604 }
24605 if let Some(manual) = &e.manual {
24606 self.generate_expression(manual)?;
24607 }
24608 if let Some(never) = &e.never {
24609 self.generate_expression(never)?;
24610 }
24611 Ok(())
24612 }
24613
24614 fn generate_booland(&mut self, e: &Booland) -> Result<()> {
24615 self.write("((");
24617 self.generate_expression(&e.this)?;
24618 self.write(") ");
24619 self.write_keyword("AND");
24620 self.write(" (");
24621 self.generate_expression(&e.expression)?;
24622 self.write("))");
24623 Ok(())
24624 }
24625
24626 fn generate_boolor(&mut self, e: &Boolor) -> Result<()> {
24627 self.write("((");
24629 self.generate_expression(&e.this)?;
24630 self.write(") ");
24631 self.write_keyword("OR");
24632 self.write(" (");
24633 self.generate_expression(&e.expression)?;
24634 self.write("))");
24635 Ok(())
24636 }
24637
24638 fn generate_build_property(&mut self, e: &BuildProperty) -> Result<()> {
24639 self.write_keyword("BUILD");
24641 self.write_space();
24642 self.generate_expression(&e.this)?;
24643 Ok(())
24644 }
24645
24646 fn generate_byte_string(&mut self, e: &ByteString) -> Result<()> {
24647 self.generate_expression(&e.this)?;
24649 Ok(())
24650 }
24651
24652 fn generate_case_specific_column_constraint(
24653 &mut self,
24654 e: &CaseSpecificColumnConstraint,
24655 ) -> Result<()> {
24656 if e.not_.is_some() {
24658 self.write_keyword("NOT");
24659 self.write_space();
24660 }
24661 self.write_keyword("CASESPECIFIC");
24662 Ok(())
24663 }
24664
24665 fn generate_cast_to_str_type(&mut self, e: &CastToStrType) -> Result<()> {
24666 self.write_keyword("CAST");
24668 self.write("(");
24669 self.generate_expression(&e.this)?;
24670 if self.config.dialect == Some(DialectType::ClickHouse) {
24671 self.write(", ");
24673 } else {
24674 self.write_space();
24675 self.write_keyword("AS");
24676 self.write_space();
24677 }
24678 if let Some(to) = &e.to {
24679 self.generate_expression(to)?;
24680 }
24681 self.write(")");
24682 Ok(())
24683 }
24684
24685 fn generate_changes(&mut self, e: &Changes) -> Result<()> {
24686 self.write_keyword("CHANGES");
24689 self.write(" (");
24690 if let Some(information) = &e.information {
24691 self.write_keyword("INFORMATION");
24692 self.write(" => ");
24693 self.generate_expression(information)?;
24694 }
24695 self.write(")");
24696 if let Some(at_before) = &e.at_before {
24698 self.write(" ");
24699 self.generate_expression(at_before)?;
24700 }
24701 if let Some(end) = &e.end {
24702 self.write(" ");
24703 self.generate_expression(end)?;
24704 }
24705 Ok(())
24706 }
24707
24708 fn generate_character_set_column_constraint(
24709 &mut self,
24710 e: &CharacterSetColumnConstraint,
24711 ) -> Result<()> {
24712 self.write_keyword("CHARACTER SET");
24714 self.write_space();
24715 self.generate_expression(&e.this)?;
24716 Ok(())
24717 }
24718
24719 fn generate_character_set_property(&mut self, e: &CharacterSetProperty) -> Result<()> {
24720 if e.default.is_some() {
24722 self.write_keyword("DEFAULT");
24723 self.write_space();
24724 }
24725 self.write_keyword("CHARACTER SET");
24726 self.write("=");
24727 self.generate_expression(&e.this)?;
24728 Ok(())
24729 }
24730
24731 fn generate_check_column_constraint(&mut self, e: &CheckColumnConstraint) -> Result<()> {
24732 self.write_keyword("CHECK");
24734 self.write(" (");
24735 self.generate_expression(&e.this)?;
24736 self.write(")");
24737 if e.enforced.is_some() {
24738 self.write_space();
24739 self.write_keyword("ENFORCED");
24740 }
24741 Ok(())
24742 }
24743
24744 fn generate_check_json(&mut self, e: &CheckJson) -> Result<()> {
24745 self.write_keyword("CHECK_JSON");
24747 self.write("(");
24748 self.generate_expression(&e.this)?;
24749 self.write(")");
24750 Ok(())
24751 }
24752
24753 fn generate_check_xml(&mut self, e: &CheckXml) -> Result<()> {
24754 self.write_keyword("CHECK_XML");
24756 self.write("(");
24757 self.generate_expression(&e.this)?;
24758 self.write(")");
24759 Ok(())
24760 }
24761
24762 fn generate_checksum_property(&mut self, e: &ChecksumProperty) -> Result<()> {
24763 self.write_keyword("CHECKSUM");
24765 self.write("=");
24766 if e.on.is_some() {
24767 self.write_keyword("ON");
24768 } else if e.default.is_some() {
24769 self.write_keyword("DEFAULT");
24770 } else {
24771 self.write_keyword("OFF");
24772 }
24773 Ok(())
24774 }
24775
24776 fn generate_clone(&mut self, e: &Clone) -> Result<()> {
24777 if e.shallow.is_some() {
24779 self.write_keyword("SHALLOW");
24780 self.write_space();
24781 }
24782 if e.copy.is_some() {
24783 self.write_keyword("COPY");
24784 } else {
24785 self.write_keyword("CLONE");
24786 }
24787 self.write_space();
24788 self.generate_expression(&e.this)?;
24789 Ok(())
24790 }
24791
24792 fn generate_cluster_by(&mut self, e: &ClusterBy) -> Result<()> {
24793 self.write_keyword("CLUSTER BY");
24795 self.write(" (");
24796 for (i, ord) in e.expressions.iter().enumerate() {
24797 if i > 0 {
24798 self.write(", ");
24799 }
24800 self.generate_ordered(ord)?;
24801 }
24802 self.write(")");
24803 Ok(())
24804 }
24805
24806 fn generate_clustered_by_property(&mut self, e: &ClusteredByProperty) -> Result<()> {
24807 self.write_keyword("CLUSTERED BY");
24809 self.write(" (");
24810 for (i, expr) in e.expressions.iter().enumerate() {
24811 if i > 0 {
24812 self.write(", ");
24813 }
24814 self.generate_expression(expr)?;
24815 }
24816 self.write(")");
24817 if let Some(sorted_by) = &e.sorted_by {
24818 self.write_space();
24819 self.write_keyword("SORTED BY");
24820 self.write(" (");
24821 if let Expression::Tuple(t) = sorted_by.as_ref() {
24823 for (i, expr) in t.expressions.iter().enumerate() {
24824 if i > 0 {
24825 self.write(", ");
24826 }
24827 self.generate_expression(expr)?;
24828 }
24829 } else {
24830 self.generate_expression(sorted_by)?;
24831 }
24832 self.write(")");
24833 }
24834 if let Some(buckets) = &e.buckets {
24835 self.write_space();
24836 self.write_keyword("INTO");
24837 self.write_space();
24838 self.generate_expression(buckets)?;
24839 self.write_space();
24840 self.write_keyword("BUCKETS");
24841 }
24842 Ok(())
24843 }
24844
24845 fn generate_collate_property(&mut self, e: &CollateProperty) -> Result<()> {
24846 if e.default.is_some() {
24850 self.write_keyword("DEFAULT");
24851 self.write_space();
24852 }
24853 self.write_keyword("COLLATE");
24854 match self.config.dialect {
24856 Some(DialectType::BigQuery) => self.write_space(),
24857 _ => self.write("="),
24858 }
24859 self.generate_expression(&e.this)?;
24860 Ok(())
24861 }
24862
24863 fn generate_column_constraint(&mut self, e: &ColumnConstraint) -> Result<()> {
24864 match e {
24866 ColumnConstraint::NotNull => {
24867 self.write_keyword("NOT NULL");
24868 }
24869 ColumnConstraint::Null => {
24870 self.write_keyword("NULL");
24871 }
24872 ColumnConstraint::Unique => {
24873 self.write_keyword("UNIQUE");
24874 }
24875 ColumnConstraint::PrimaryKey => {
24876 self.write_keyword("PRIMARY KEY");
24877 }
24878 ColumnConstraint::Default(expr) => {
24879 self.write_keyword("DEFAULT");
24880 self.write_space();
24881 self.generate_expression(expr)?;
24882 }
24883 ColumnConstraint::Check(expr) => {
24884 self.write_keyword("CHECK");
24885 self.write(" (");
24886 self.generate_expression(expr)?;
24887 self.write(")");
24888 }
24889 ColumnConstraint::References(fk_ref) => {
24890 if fk_ref.has_foreign_key_keywords {
24891 self.write_keyword("FOREIGN KEY");
24892 self.write_space();
24893 }
24894 self.write_keyword("REFERENCES");
24895 self.write_space();
24896 self.generate_table(&fk_ref.table)?;
24897 if !fk_ref.columns.is_empty() {
24898 self.write(" (");
24899 for (i, col) in fk_ref.columns.iter().enumerate() {
24900 if i > 0 {
24901 self.write(", ");
24902 }
24903 self.generate_identifier(col)?;
24904 }
24905 self.write(")");
24906 }
24907 }
24908 ColumnConstraint::GeneratedAsIdentity(gen) => {
24909 self.write_keyword("GENERATED");
24910 self.write_space();
24911 if gen.always {
24912 self.write_keyword("ALWAYS");
24913 } else {
24914 self.write_keyword("BY DEFAULT");
24915 if gen.on_null {
24916 self.write_space();
24917 self.write_keyword("ON NULL");
24918 }
24919 }
24920 self.write_space();
24921 self.write_keyword("AS IDENTITY");
24922 }
24923 ColumnConstraint::Collate(collation) => {
24924 self.write_keyword("COLLATE");
24925 self.write_space();
24926 self.generate_identifier(collation)?;
24927 }
24928 ColumnConstraint::Comment(comment) => {
24929 self.write_keyword("COMMENT");
24930 self.write(" '");
24931 self.write(comment);
24932 self.write("'");
24933 }
24934 ColumnConstraint::ComputedColumn(cc) => {
24935 self.generate_computed_column_inline(cc)?;
24936 }
24937 ColumnConstraint::GeneratedAsRow(gar) => {
24938 self.generate_generated_as_row_inline(gar)?;
24939 }
24940 ColumnConstraint::Tags(tags) => {
24941 self.write_keyword("TAG");
24942 self.write(" (");
24943 for (i, expr) in tags.expressions.iter().enumerate() {
24944 if i > 0 {
24945 self.write(", ");
24946 }
24947 self.generate_expression(expr)?;
24948 }
24949 self.write(")");
24950 }
24951 ColumnConstraint::Path(path_expr) => {
24952 self.write_keyword("PATH");
24953 self.write_space();
24954 self.generate_expression(path_expr)?;
24955 }
24956 }
24957 Ok(())
24958 }
24959
24960 fn generate_column_position(&mut self, e: &ColumnPosition) -> Result<()> {
24961 match e {
24963 ColumnPosition::First => {
24964 self.write_keyword("FIRST");
24965 }
24966 ColumnPosition::After(ident) => {
24967 self.write_keyword("AFTER");
24968 self.write_space();
24969 self.generate_identifier(ident)?;
24970 }
24971 }
24972 Ok(())
24973 }
24974
24975 fn generate_column_prefix(&mut self, e: &ColumnPrefix) -> Result<()> {
24976 self.generate_expression(&e.this)?;
24978 self.write("(");
24979 self.generate_expression(&e.expression)?;
24980 self.write(")");
24981 Ok(())
24982 }
24983
24984 fn generate_columns(&mut self, e: &Columns) -> Result<()> {
24985 if let Some(ref unpack) = e.unpack {
24988 if let Expression::Boolean(b) = unpack.as_ref() {
24989 if b.value {
24990 self.write("*");
24991 }
24992 }
24993 }
24994 self.write_keyword("COLUMNS");
24995 self.write("(");
24996 self.generate_expression(&e.this)?;
24997 self.write(")");
24998 Ok(())
24999 }
25000
25001 fn generate_combined_agg_func(&mut self, e: &CombinedAggFunc) -> Result<()> {
25002 self.generate_expression(&e.this)?;
25004 self.write("(");
25005 for (i, expr) in e.expressions.iter().enumerate() {
25006 if i > 0 {
25007 self.write(", ");
25008 }
25009 self.generate_expression(expr)?;
25010 }
25011 self.write(")");
25012 Ok(())
25013 }
25014
25015 fn generate_combined_parameterized_agg(&mut self, e: &CombinedParameterizedAgg) -> Result<()> {
25016 self.generate_expression(&e.this)?;
25018 self.write("(");
25019 for (i, param) in e.params.iter().enumerate() {
25020 if i > 0 {
25021 self.write(", ");
25022 }
25023 self.generate_expression(param)?;
25024 }
25025 self.write(")(");
25026 for (i, expr) in e.expressions.iter().enumerate() {
25027 if i > 0 {
25028 self.write(", ");
25029 }
25030 self.generate_expression(expr)?;
25031 }
25032 self.write(")");
25033 Ok(())
25034 }
25035
25036 fn generate_commit(&mut self, e: &Commit) -> Result<()> {
25037 self.write_keyword("COMMIT");
25039
25040 if e.this.is_none()
25042 && matches!(
25043 self.config.dialect,
25044 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25045 )
25046 {
25047 self.write_space();
25048 self.write_keyword("TRANSACTION");
25049 }
25050
25051 if let Some(this) = &e.this {
25053 let is_transaction_marker = matches!(
25055 this.as_ref(),
25056 Expression::Identifier(id) if id.name == "TRANSACTION"
25057 );
25058
25059 self.write_space();
25060 self.write_keyword("TRANSACTION");
25061
25062 if !is_transaction_marker {
25064 self.write_space();
25065 self.generate_expression(this)?;
25066 }
25067 }
25068
25069 if let Some(durability) = &e.durability {
25071 self.write_space();
25072 self.write_keyword("WITH");
25073 self.write(" (");
25074 self.write_keyword("DELAYED_DURABILITY");
25075 self.write(" = ");
25076 if let Expression::Boolean(BooleanLiteral { value: true }) = durability.as_ref() {
25077 self.write_keyword("ON");
25078 } else {
25079 self.write_keyword("OFF");
25080 }
25081 self.write(")");
25082 }
25083
25084 if let Some(chain) = &e.chain {
25086 self.write_space();
25087 if let Expression::Boolean(BooleanLiteral { value: false }) = chain.as_ref() {
25088 self.write_keyword("AND NO CHAIN");
25089 } else {
25090 self.write_keyword("AND CHAIN");
25091 }
25092 }
25093 Ok(())
25094 }
25095
25096 fn generate_comprehension(&mut self, e: &Comprehension) -> Result<()> {
25097 self.write("[");
25099 self.generate_expression(&e.this)?;
25100 self.write_space();
25101 self.write_keyword("FOR");
25102 self.write_space();
25103 self.generate_expression(&e.expression)?;
25104 if let Some(pos) = &e.position {
25106 self.write(", ");
25107 self.generate_expression(pos)?;
25108 }
25109 if let Some(iterator) = &e.iterator {
25110 self.write_space();
25111 self.write_keyword("IN");
25112 self.write_space();
25113 self.generate_expression(iterator)?;
25114 }
25115 if let Some(condition) = &e.condition {
25116 self.write_space();
25117 self.write_keyword("IF");
25118 self.write_space();
25119 self.generate_expression(condition)?;
25120 }
25121 self.write("]");
25122 Ok(())
25123 }
25124
25125 fn generate_compress(&mut self, e: &Compress) -> Result<()> {
25126 self.write_keyword("COMPRESS");
25128 self.write("(");
25129 self.generate_expression(&e.this)?;
25130 if let Some(method) = &e.method {
25131 self.write(", '");
25132 self.write(method);
25133 self.write("'");
25134 }
25135 self.write(")");
25136 Ok(())
25137 }
25138
25139 fn generate_compress_column_constraint(&mut self, e: &CompressColumnConstraint) -> Result<()> {
25140 self.write_keyword("COMPRESS");
25142 if let Some(this) = &e.this {
25143 self.write_space();
25144 self.generate_expression(this)?;
25145 }
25146 Ok(())
25147 }
25148
25149 fn generate_computed_column_constraint(&mut self, e: &ComputedColumnConstraint) -> Result<()> {
25150 self.write_keyword("AS");
25152 self.write_space();
25153 self.generate_expression(&e.this)?;
25154 if e.not_null.is_some() {
25155 self.write_space();
25156 self.write_keyword("PERSISTED NOT NULL");
25157 } else if e.persisted.is_some() {
25158 self.write_space();
25159 self.write_keyword("PERSISTED");
25160 }
25161 Ok(())
25162 }
25163
25164 fn generate_computed_column_inline(&mut self, cc: &ComputedColumn) -> Result<()> {
25168 let computed_expr = if matches!(
25169 self.config.dialect,
25170 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25171 ) {
25172 match &*cc.expression {
25173 Expression::Year(y) if !matches!(&y.this, Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
25174 {
25175 let wrapped = Expression::Cast(Box::new(Cast {
25176 this: y.this.clone(),
25177 to: DataType::Date,
25178 trailing_comments: Vec::new(),
25179 double_colon_syntax: false,
25180 format: None,
25181 default: None,
25182 }));
25183 Expression::Year(Box::new(UnaryFunc::new(wrapped)))
25184 }
25185 Expression::Function(f)
25186 if f.name.eq_ignore_ascii_case("YEAR")
25187 && f.args.len() == 1
25188 && !matches!(&f.args[0], Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
25189 {
25190 let wrapped = Expression::Cast(Box::new(Cast {
25191 this: f.args[0].clone(),
25192 to: DataType::Date,
25193 trailing_comments: Vec::new(),
25194 double_colon_syntax: false,
25195 format: None,
25196 default: None,
25197 }));
25198 Expression::Function(Box::new(Function::new("YEAR".to_string(), vec![wrapped])))
25199 }
25200 _ => *cc.expression.clone(),
25201 }
25202 } else {
25203 *cc.expression.clone()
25204 };
25205
25206 match cc.persistence_kind.as_deref() {
25207 Some("STORED") | Some("VIRTUAL") => {
25208 self.write_keyword("GENERATED ALWAYS AS");
25210 self.write(" (");
25211 self.generate_expression(&computed_expr)?;
25212 self.write(")");
25213 self.write_space();
25214 if cc.persisted {
25215 self.write_keyword("STORED");
25216 } else {
25217 self.write_keyword("VIRTUAL");
25218 }
25219 }
25220 Some("PERSISTED") => {
25221 self.write_keyword("AS");
25223 self.write(" (");
25224 self.generate_expression(&computed_expr)?;
25225 self.write(")");
25226 self.write_space();
25227 self.write_keyword("PERSISTED");
25228 if let Some(ref dt) = cc.data_type {
25230 self.write_space();
25231 self.generate_data_type(dt)?;
25232 }
25233 if cc.not_null {
25234 self.write_space();
25235 self.write_keyword("NOT NULL");
25236 }
25237 }
25238 _ => {
25239 if matches!(
25242 self.config.dialect,
25243 Some(DialectType::Spark)
25244 | Some(DialectType::Databricks)
25245 | Some(DialectType::Hive)
25246 ) {
25247 self.write_keyword("GENERATED ALWAYS AS");
25248 self.write(" (");
25249 self.generate_expression(&computed_expr)?;
25250 self.write(")");
25251 } else if matches!(
25252 self.config.dialect,
25253 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25254 ) {
25255 self.write_keyword("AS");
25256 let omit_parens = matches!(computed_expr, Expression::Year(_))
25257 || matches!(&computed_expr, Expression::Function(f) if f.name.eq_ignore_ascii_case("YEAR"));
25258 if omit_parens {
25259 self.write_space();
25260 self.generate_expression(&computed_expr)?;
25261 } else {
25262 self.write(" (");
25263 self.generate_expression(&computed_expr)?;
25264 self.write(")");
25265 }
25266 } else {
25267 self.write_keyword("AS");
25268 self.write(" (");
25269 self.generate_expression(&computed_expr)?;
25270 self.write(")");
25271 }
25272 }
25273 }
25274 Ok(())
25275 }
25276
25277 fn generate_generated_as_row_inline(&mut self, gar: &GeneratedAsRow) -> Result<()> {
25280 self.write_keyword("GENERATED ALWAYS AS ROW ");
25281 if gar.start {
25282 self.write_keyword("START");
25283 } else {
25284 self.write_keyword("END");
25285 }
25286 if gar.hidden {
25287 self.write_space();
25288 self.write_keyword("HIDDEN");
25289 }
25290 Ok(())
25291 }
25292
25293 fn generate_system_versioning_content(
25295 &mut self,
25296 e: &WithSystemVersioningProperty,
25297 ) -> Result<()> {
25298 let mut parts = Vec::new();
25299
25300 if let Some(this) = &e.this {
25301 let mut s = String::from("HISTORY_TABLE=");
25302 let mut gen = Generator::new();
25303 gen.config = self.config.clone();
25304 gen.generate_expression(this)?;
25305 s.push_str(&gen.output);
25306 parts.push(s);
25307 }
25308
25309 if let Some(data_consistency) = &e.data_consistency {
25310 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
25311 let mut gen = Generator::new();
25312 gen.config = self.config.clone();
25313 gen.generate_expression(data_consistency)?;
25314 s.push_str(&gen.output);
25315 parts.push(s);
25316 }
25317
25318 if let Some(retention_period) = &e.retention_period {
25319 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
25320 let mut gen = Generator::new();
25321 gen.config = self.config.clone();
25322 gen.generate_expression(retention_period)?;
25323 s.push_str(&gen.output);
25324 parts.push(s);
25325 }
25326
25327 self.write_keyword("SYSTEM_VERSIONING");
25328 self.write("=");
25329
25330 if !parts.is_empty() {
25331 self.write_keyword("ON");
25332 self.write("(");
25333 self.write(&parts.join(", "));
25334 self.write(")");
25335 } else if e.on.is_some() {
25336 self.write_keyword("ON");
25337 } else {
25338 self.write_keyword("OFF");
25339 }
25340
25341 Ok(())
25342 }
25343
25344 fn generate_conditional_insert(&mut self, e: &ConditionalInsert) -> Result<()> {
25345 if e.else_.is_some() {
25348 self.write_keyword("ELSE");
25349 self.write_space();
25350 } else if let Some(expression) = &e.expression {
25351 self.write_keyword("WHEN");
25352 self.write_space();
25353 self.generate_expression(expression)?;
25354 self.write_space();
25355 self.write_keyword("THEN");
25356 self.write_space();
25357 }
25358
25359 if let Expression::Insert(insert) = e.this.as_ref() {
25362 self.write_keyword("INTO");
25363 self.write_space();
25364 self.generate_table(&insert.table)?;
25365
25366 if !insert.columns.is_empty() {
25368 self.write(" (");
25369 for (i, col) in insert.columns.iter().enumerate() {
25370 if i > 0 {
25371 self.write(", ");
25372 }
25373 self.generate_identifier(col)?;
25374 }
25375 self.write(")");
25376 }
25377
25378 if !insert.values.is_empty() {
25380 self.write_space();
25381 self.write_keyword("VALUES");
25382 for (row_idx, row) in insert.values.iter().enumerate() {
25383 if row_idx > 0 {
25384 self.write(", ");
25385 }
25386 self.write(" (");
25387 for (i, val) in row.iter().enumerate() {
25388 if i > 0 {
25389 self.write(", ");
25390 }
25391 self.generate_expression(val)?;
25392 }
25393 self.write(")");
25394 }
25395 }
25396 } else {
25397 self.generate_expression(&e.this)?;
25399 }
25400 Ok(())
25401 }
25402
25403 fn generate_constraint(&mut self, e: &Constraint) -> Result<()> {
25404 self.write_keyword("CONSTRAINT");
25406 self.write_space();
25407 self.generate_expression(&e.this)?;
25408 if !e.expressions.is_empty() {
25409 self.write_space();
25410 for (i, expr) in e.expressions.iter().enumerate() {
25411 if i > 0 {
25412 self.write_space();
25413 }
25414 self.generate_expression(expr)?;
25415 }
25416 }
25417 Ok(())
25418 }
25419
25420 fn generate_convert_timezone(&mut self, e: &ConvertTimezone) -> Result<()> {
25421 self.write_keyword("CONVERT_TIMEZONE");
25423 self.write("(");
25424 let mut first = true;
25425 if let Some(source_tz) = &e.source_tz {
25426 self.generate_expression(source_tz)?;
25427 first = false;
25428 }
25429 if let Some(target_tz) = &e.target_tz {
25430 if !first {
25431 self.write(", ");
25432 }
25433 self.generate_expression(target_tz)?;
25434 first = false;
25435 }
25436 if let Some(timestamp) = &e.timestamp {
25437 if !first {
25438 self.write(", ");
25439 }
25440 self.generate_expression(timestamp)?;
25441 }
25442 self.write(")");
25443 Ok(())
25444 }
25445
25446 fn generate_convert_to_charset(&mut self, e: &ConvertToCharset) -> Result<()> {
25447 self.write_keyword("CONVERT");
25449 self.write("(");
25450 self.generate_expression(&e.this)?;
25451 if let Some(dest) = &e.dest {
25452 self.write_space();
25453 self.write_keyword("USING");
25454 self.write_space();
25455 self.generate_expression(dest)?;
25456 }
25457 self.write(")");
25458 Ok(())
25459 }
25460
25461 fn generate_copy(&mut self, e: &CopyStmt) -> Result<()> {
25462 self.write_keyword("COPY");
25463 if e.is_into {
25464 self.write_space();
25465 self.write_keyword("INTO");
25466 }
25467 self.write_space();
25468
25469 if let Expression::Literal(Literal::String(s)) = &e.this {
25471 if s.starts_with('@') {
25472 self.write(s);
25473 } else {
25474 self.generate_expression(&e.this)?;
25475 }
25476 } else {
25477 self.generate_expression(&e.this)?;
25478 }
25479
25480 if e.kind {
25482 if self.config.pretty {
25484 self.write_newline();
25485 } else {
25486 self.write_space();
25487 }
25488 self.write_keyword("FROM");
25489 self.write_space();
25490 } else if !e.files.is_empty() {
25491 if self.config.pretty {
25493 self.write_newline();
25494 } else {
25495 self.write_space();
25496 }
25497 self.write_keyword("TO");
25498 self.write_space();
25499 }
25500
25501 for (i, file) in e.files.iter().enumerate() {
25503 if i > 0 {
25504 self.write_space();
25505 }
25506 if let Expression::Literal(Literal::String(s)) = file {
25508 if s.starts_with('@') {
25509 self.write(s);
25510 } else {
25511 self.generate_expression(file)?;
25512 }
25513 } else if let Expression::Identifier(id) = file {
25514 if id.quoted {
25516 self.write("`");
25517 self.write(&id.name);
25518 self.write("`");
25519 } else {
25520 self.generate_expression(file)?;
25521 }
25522 } else {
25523 self.generate_expression(file)?;
25524 }
25525 }
25526
25527 if !e.with_wrapped {
25529 if let Some(ref creds) = e.credentials {
25530 if let Some(ref storage) = creds.storage {
25531 if self.config.pretty {
25532 self.write_newline();
25533 } else {
25534 self.write_space();
25535 }
25536 self.write_keyword("STORAGE_INTEGRATION");
25537 self.write(" = ");
25538 self.write(storage);
25539 }
25540 if creds.credentials.is_empty() {
25541 if self.config.pretty {
25543 self.write_newline();
25544 } else {
25545 self.write_space();
25546 }
25547 self.write_keyword("CREDENTIALS");
25548 self.write(" = ()");
25549 } else {
25550 if self.config.pretty {
25551 self.write_newline();
25552 } else {
25553 self.write_space();
25554 }
25555 self.write_keyword("CREDENTIALS");
25556 if creds.credentials.len() == 1 && creds.credentials[0].0.is_empty() {
25559 self.write(" '");
25561 self.write(&creds.credentials[0].1);
25562 self.write("'");
25563 } else {
25564 self.write(" = (");
25566 for (i, (k, v)) in creds.credentials.iter().enumerate() {
25567 if i > 0 {
25568 self.write_space();
25569 }
25570 self.write(k);
25571 self.write("='");
25572 self.write(v);
25573 self.write("'");
25574 }
25575 self.write(")");
25576 }
25577 }
25578 if let Some(ref encryption) = creds.encryption {
25579 self.write_space();
25580 self.write_keyword("ENCRYPTION");
25581 self.write(" = ");
25582 self.write(encryption);
25583 }
25584 }
25585 }
25586
25587 if !e.params.is_empty() {
25589 if e.with_wrapped {
25590 self.write_space();
25592 self.write_keyword("WITH");
25593 self.write(" (");
25594 for (i, param) in e.params.iter().enumerate() {
25595 if i > 0 {
25596 self.write(", ");
25597 }
25598 self.generate_copy_param_with_format(param)?;
25599 }
25600 self.write(")");
25601 } else {
25602 for param in &e.params {
25606 if self.config.pretty {
25607 self.write_newline();
25608 } else {
25609 self.write_space();
25610 }
25611 self.write(¶m.name);
25613 if let Some(ref value) = param.value {
25614 if param.eq {
25616 self.write(" = ");
25617 } else {
25618 self.write(" ");
25619 }
25620 if !param.values.is_empty() {
25621 self.write("(");
25622 for (i, v) in param.values.iter().enumerate() {
25623 if i > 0 {
25624 self.write_space();
25625 }
25626 self.generate_copy_nested_param(v)?;
25627 }
25628 self.write(")");
25629 } else {
25630 self.generate_copy_param_value(value)?;
25632 }
25633 } else if !param.values.is_empty() {
25634 if param.eq {
25636 self.write(" = (");
25637 } else {
25638 self.write(" (");
25639 }
25640 let is_key_value_pairs = param
25645 .values
25646 .first()
25647 .map_or(false, |v| matches!(v, Expression::Eq(_)));
25648 let sep = if is_key_value_pairs && param.eq {
25649 " "
25650 } else {
25651 ", "
25652 };
25653 for (i, v) in param.values.iter().enumerate() {
25654 if i > 0 {
25655 self.write(sep);
25656 }
25657 self.generate_copy_nested_param(v)?;
25658 }
25659 self.write(")");
25660 }
25661 }
25662 }
25663 }
25664
25665 Ok(())
25666 }
25667
25668 fn generate_copy_param_with_format(&mut self, param: &CopyParameter) -> Result<()> {
25671 self.write_keyword(¶m.name);
25672 if !param.values.is_empty() {
25673 self.write(" = (");
25675 for (i, v) in param.values.iter().enumerate() {
25676 if i > 0 {
25677 self.write(", ");
25678 }
25679 self.generate_copy_nested_param(v)?;
25680 }
25681 self.write(")");
25682 } else if let Some(ref value) = param.value {
25683 if param.eq {
25684 self.write(" = ");
25685 } else {
25686 self.write(" ");
25687 }
25688 self.generate_expression(value)?;
25689 }
25690 Ok(())
25691 }
25692
25693 fn generate_copy_nested_param(&mut self, expr: &Expression) -> Result<()> {
25695 match expr {
25696 Expression::Eq(eq) => {
25697 match &eq.left {
25699 Expression::Column(c) => self.write(&c.name.name),
25700 _ => self.generate_expression(&eq.left)?,
25701 }
25702 self.write("=");
25703 match &eq.right {
25705 Expression::Literal(Literal::String(s)) => {
25706 self.write("'");
25707 self.write(s);
25708 self.write("'");
25709 }
25710 Expression::Tuple(t) => {
25711 self.write("(");
25713 if self.config.pretty {
25714 self.write_newline();
25715 self.indent_level += 1;
25716 for (i, item) in t.expressions.iter().enumerate() {
25717 if i > 0 {
25718 self.write(", ");
25719 }
25720 self.write_indent();
25721 self.generate_expression(item)?;
25722 }
25723 self.write_newline();
25724 self.indent_level -= 1;
25725 } else {
25726 for (i, item) in t.expressions.iter().enumerate() {
25727 if i > 0 {
25728 self.write(", ");
25729 }
25730 self.generate_expression(item)?;
25731 }
25732 }
25733 self.write(")");
25734 }
25735 _ => self.generate_expression(&eq.right)?,
25736 }
25737 Ok(())
25738 }
25739 Expression::Column(c) => {
25740 self.write(&c.name.name);
25742 Ok(())
25743 }
25744 _ => self.generate_expression(expr),
25745 }
25746 }
25747
25748 fn generate_copy_param_value(&mut self, expr: &Expression) -> Result<()> {
25751 match expr {
25752 Expression::Column(c) => {
25753 if c.name.quoted {
25755 self.write("\"");
25756 self.write(&c.name.name);
25757 self.write("\"");
25758 } else {
25759 self.write(&c.name.name);
25760 }
25761 Ok(())
25762 }
25763 Expression::Identifier(id) => {
25764 if id.quoted {
25766 self.write("\"");
25767 self.write(&id.name);
25768 self.write("\"");
25769 } else {
25770 self.write(&id.name);
25771 }
25772 Ok(())
25773 }
25774 Expression::Literal(Literal::String(s)) => {
25775 self.write("'");
25777 self.write(s);
25778 self.write("'");
25779 Ok(())
25780 }
25781 _ => self.generate_expression(expr),
25782 }
25783 }
25784
25785 fn generate_copy_parameter(&mut self, e: &CopyParameter) -> Result<()> {
25786 self.write_keyword(&e.name);
25787 if let Some(ref value) = e.value {
25788 if e.eq {
25789 self.write(" = ");
25790 } else {
25791 self.write(" ");
25792 }
25793 self.generate_expression(value)?;
25794 }
25795 if !e.values.is_empty() {
25796 if e.eq {
25797 self.write(" = ");
25798 } else {
25799 self.write(" ");
25800 }
25801 self.write("(");
25802 for (i, v) in e.values.iter().enumerate() {
25803 if i > 0 {
25804 self.write(", ");
25805 }
25806 self.generate_expression(v)?;
25807 }
25808 self.write(")");
25809 }
25810 Ok(())
25811 }
25812
25813 fn generate_corr(&mut self, e: &Corr) -> Result<()> {
25814 self.write_keyword("CORR");
25816 self.write("(");
25817 self.generate_expression(&e.this)?;
25818 self.write(", ");
25819 self.generate_expression(&e.expression)?;
25820 self.write(")");
25821 Ok(())
25822 }
25823
25824 fn generate_cosine_distance(&mut self, e: &CosineDistance) -> Result<()> {
25825 self.write_keyword("COSINE_DISTANCE");
25827 self.write("(");
25828 self.generate_expression(&e.this)?;
25829 self.write(", ");
25830 self.generate_expression(&e.expression)?;
25831 self.write(")");
25832 Ok(())
25833 }
25834
25835 fn generate_covar_pop(&mut self, e: &CovarPop) -> Result<()> {
25836 self.write_keyword("COVAR_POP");
25838 self.write("(");
25839 self.generate_expression(&e.this)?;
25840 self.write(", ");
25841 self.generate_expression(&e.expression)?;
25842 self.write(")");
25843 Ok(())
25844 }
25845
25846 fn generate_covar_samp(&mut self, e: &CovarSamp) -> Result<()> {
25847 self.write_keyword("COVAR_SAMP");
25849 self.write("(");
25850 self.generate_expression(&e.this)?;
25851 self.write(", ");
25852 self.generate_expression(&e.expression)?;
25853 self.write(")");
25854 Ok(())
25855 }
25856
25857 fn generate_credentials(&mut self, e: &Credentials) -> Result<()> {
25858 self.write_keyword("CREDENTIALS");
25860 self.write(" (");
25861 for (i, (key, value)) in e.credentials.iter().enumerate() {
25862 if i > 0 {
25863 self.write(", ");
25864 }
25865 self.write(key);
25866 self.write("='");
25867 self.write(value);
25868 self.write("'");
25869 }
25870 self.write(")");
25871 Ok(())
25872 }
25873
25874 fn generate_credentials_property(&mut self, e: &CredentialsProperty) -> Result<()> {
25875 self.write_keyword("CREDENTIALS");
25877 self.write("=(");
25878 for (i, expr) in e.expressions.iter().enumerate() {
25879 if i > 0 {
25880 self.write(", ");
25881 }
25882 self.generate_expression(expr)?;
25883 }
25884 self.write(")");
25885 Ok(())
25886 }
25887
25888 fn generate_cte(&mut self, e: &Cte) -> Result<()> {
25889 use crate::dialects::DialectType;
25890
25891 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !e.alias_first {
25894 self.generate_expression(&e.this)?;
25895 self.write_space();
25896 self.write_keyword("AS");
25897 self.write_space();
25898 self.generate_identifier(&e.alias)?;
25899 return Ok(());
25900 }
25901 self.write(&e.alias.name);
25902
25903 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
25905
25906 if !e.columns.is_empty() && !skip_cte_columns {
25907 self.write("(");
25908 for (i, col) in e.columns.iter().enumerate() {
25909 if i > 0 {
25910 self.write(", ");
25911 }
25912 self.write(&col.name);
25913 }
25914 self.write(")");
25915 }
25916 if !e.key_expressions.is_empty() {
25918 self.write_space();
25919 self.write_keyword("USING KEY");
25920 self.write(" (");
25921 for (i, key) in e.key_expressions.iter().enumerate() {
25922 if i > 0 {
25923 self.write(", ");
25924 }
25925 self.write(&key.name);
25926 }
25927 self.write(")");
25928 }
25929 self.write_space();
25930 self.write_keyword("AS");
25931 self.write_space();
25932 if let Some(materialized) = e.materialized {
25933 if materialized {
25934 self.write_keyword("MATERIALIZED");
25935 } else {
25936 self.write_keyword("NOT MATERIALIZED");
25937 }
25938 self.write_space();
25939 }
25940 self.write("(");
25941 self.generate_expression(&e.this)?;
25942 self.write(")");
25943 Ok(())
25944 }
25945
25946 fn generate_cube(&mut self, e: &Cube) -> Result<()> {
25947 if e.expressions.is_empty() {
25949 self.write_keyword("WITH CUBE");
25950 } else {
25951 self.write_keyword("CUBE");
25952 self.write("(");
25953 for (i, expr) in e.expressions.iter().enumerate() {
25954 if i > 0 {
25955 self.write(", ");
25956 }
25957 self.generate_expression(expr)?;
25958 }
25959 self.write(")");
25960 }
25961 Ok(())
25962 }
25963
25964 fn generate_current_datetime(&mut self, e: &CurrentDatetime) -> Result<()> {
25965 self.write_keyword("CURRENT_DATETIME");
25967 if let Some(this) = &e.this {
25968 self.write("(");
25969 self.generate_expression(this)?;
25970 self.write(")");
25971 }
25972 Ok(())
25973 }
25974
25975 fn generate_current_schema(&mut self, _e: &CurrentSchema) -> Result<()> {
25976 self.write_keyword("CURRENT_SCHEMA");
25978 Ok(())
25979 }
25980
25981 fn generate_current_schemas(&mut self, e: &CurrentSchemas) -> Result<()> {
25982 self.write_keyword("CURRENT_SCHEMAS");
25984 self.write("(");
25985 if let Some(this) = &e.this {
25986 self.generate_expression(this)?;
25987 }
25988 self.write(")");
25989 Ok(())
25990 }
25991
25992 fn generate_current_user(&mut self, e: &CurrentUser) -> Result<()> {
25993 self.write_keyword("CURRENT_USER");
25995 let needs_parens = e.this.is_some()
25997 || matches!(
25998 self.config.dialect,
25999 Some(DialectType::Snowflake)
26000 | Some(DialectType::Spark)
26001 | Some(DialectType::Hive)
26002 | Some(DialectType::DuckDB)
26003 | Some(DialectType::BigQuery)
26004 | Some(DialectType::MySQL)
26005 | Some(DialectType::Databricks)
26006 );
26007 if needs_parens {
26008 self.write("()");
26009 }
26010 Ok(())
26011 }
26012
26013 fn generate_d_pipe(&mut self, e: &DPipe) -> Result<()> {
26014 if self.config.dialect == Some(DialectType::Solr) {
26016 self.generate_expression(&e.this)?;
26017 self.write(" ");
26018 self.write_keyword("OR");
26019 self.write(" ");
26020 self.generate_expression(&e.expression)?;
26021 } else {
26022 self.generate_expression(&e.this)?;
26024 self.write(" || ");
26025 self.generate_expression(&e.expression)?;
26026 }
26027 Ok(())
26028 }
26029
26030 fn generate_data_blocksize_property(&mut self, e: &DataBlocksizeProperty) -> Result<()> {
26031 self.write_keyword("DATABLOCKSIZE");
26033 self.write("=");
26034 if let Some(size) = e.size {
26035 self.write(&size.to_string());
26036 if let Some(units) = &e.units {
26037 self.write_space();
26038 self.generate_expression(units)?;
26039 }
26040 } else if e.minimum.is_some() {
26041 self.write_keyword("MINIMUM");
26042 } else if e.maximum.is_some() {
26043 self.write_keyword("MAXIMUM");
26044 } else if e.default.is_some() {
26045 self.write_keyword("DEFAULT");
26046 }
26047 Ok(())
26048 }
26049
26050 fn generate_data_deletion_property(&mut self, e: &DataDeletionProperty) -> Result<()> {
26051 self.write_keyword("DATA_DELETION");
26053 self.write("=");
26054
26055 let is_on = matches!(&*e.on, Expression::Boolean(BooleanLiteral { value: true }));
26056 let has_options = e.filter_column.is_some() || e.retention_period.is_some();
26057
26058 if is_on {
26059 self.write_keyword("ON");
26060 if has_options {
26061 self.write("(");
26062 let mut first = true;
26063 if let Some(filter_column) = &e.filter_column {
26064 self.write_keyword("FILTER_COLUMN");
26065 self.write("=");
26066 self.generate_expression(filter_column)?;
26067 first = false;
26068 }
26069 if let Some(retention_period) = &e.retention_period {
26070 if !first {
26071 self.write(", ");
26072 }
26073 self.write_keyword("RETENTION_PERIOD");
26074 self.write("=");
26075 self.generate_expression(retention_period)?;
26076 }
26077 self.write(")");
26078 }
26079 } else {
26080 self.write_keyword("OFF");
26081 }
26082 Ok(())
26083 }
26084
26085 fn generate_date_func(&mut self, e: &UnaryFunc) -> Result<()> {
26089 use crate::dialects::DialectType;
26090 use crate::expressions::Literal;
26091
26092 match self.config.dialect {
26093 Some(DialectType::Exasol) => {
26095 self.write_keyword("TO_DATE");
26096 self.write("(");
26097 match &e.this {
26099 Expression::Literal(Literal::String(s)) => {
26100 self.write("'");
26101 self.write(s);
26102 self.write("'");
26103 }
26104 _ => {
26105 self.generate_expression(&e.this)?;
26106 }
26107 }
26108 self.write(")");
26109 }
26110 _ => {
26112 self.write_keyword("DATE");
26113 self.write("(");
26114 self.generate_expression(&e.this)?;
26115 self.write(")");
26116 }
26117 }
26118 Ok(())
26119 }
26120
26121 fn generate_date_bin(&mut self, e: &DateBin) -> Result<()> {
26122 self.write_keyword("DATE_BIN");
26124 self.write("(");
26125 self.generate_expression(&e.this)?;
26126 self.write(", ");
26127 self.generate_expression(&e.expression)?;
26128 if let Some(origin) = &e.origin {
26129 self.write(", ");
26130 self.generate_expression(origin)?;
26131 }
26132 self.write(")");
26133 Ok(())
26134 }
26135
26136 fn generate_date_format_column_constraint(
26137 &mut self,
26138 e: &DateFormatColumnConstraint,
26139 ) -> Result<()> {
26140 self.write_keyword("FORMAT");
26142 self.write_space();
26143 self.generate_expression(&e.this)?;
26144 Ok(())
26145 }
26146
26147 fn generate_date_from_parts(&mut self, e: &DateFromParts) -> Result<()> {
26148 self.write_keyword("DATE_FROM_PARTS");
26150 self.write("(");
26151 let mut first = true;
26152 if let Some(year) = &e.year {
26153 self.generate_expression(year)?;
26154 first = false;
26155 }
26156 if let Some(month) = &e.month {
26157 if !first {
26158 self.write(", ");
26159 }
26160 self.generate_expression(month)?;
26161 first = false;
26162 }
26163 if let Some(day) = &e.day {
26164 if !first {
26165 self.write(", ");
26166 }
26167 self.generate_expression(day)?;
26168 }
26169 self.write(")");
26170 Ok(())
26171 }
26172
26173 fn generate_datetime(&mut self, e: &Datetime) -> Result<()> {
26174 self.write_keyword("DATETIME");
26176 self.write("(");
26177 self.generate_expression(&e.this)?;
26178 if let Some(expr) = &e.expression {
26179 self.write(", ");
26180 self.generate_expression(expr)?;
26181 }
26182 self.write(")");
26183 Ok(())
26184 }
26185
26186 fn generate_datetime_add(&mut self, e: &DatetimeAdd) -> Result<()> {
26187 self.write_keyword("DATETIME_ADD");
26189 self.write("(");
26190 self.generate_expression(&e.this)?;
26191 self.write(", ");
26192 self.generate_expression(&e.expression)?;
26193 if let Some(unit) = &e.unit {
26194 self.write(", ");
26195 self.write_keyword(unit);
26196 }
26197 self.write(")");
26198 Ok(())
26199 }
26200
26201 fn generate_datetime_diff(&mut self, e: &DatetimeDiff) -> Result<()> {
26202 self.write_keyword("DATETIME_DIFF");
26204 self.write("(");
26205 self.generate_expression(&e.this)?;
26206 self.write(", ");
26207 self.generate_expression(&e.expression)?;
26208 if let Some(unit) = &e.unit {
26209 self.write(", ");
26210 self.write_keyword(unit);
26211 }
26212 self.write(")");
26213 Ok(())
26214 }
26215
26216 fn generate_datetime_sub(&mut self, e: &DatetimeSub) -> Result<()> {
26217 self.write_keyword("DATETIME_SUB");
26219 self.write("(");
26220 self.generate_expression(&e.this)?;
26221 self.write(", ");
26222 self.generate_expression(&e.expression)?;
26223 if let Some(unit) = &e.unit {
26224 self.write(", ");
26225 self.write_keyword(unit);
26226 }
26227 self.write(")");
26228 Ok(())
26229 }
26230
26231 fn generate_datetime_trunc(&mut self, e: &DatetimeTrunc) -> Result<()> {
26232 self.write_keyword("DATETIME_TRUNC");
26234 self.write("(");
26235 self.generate_expression(&e.this)?;
26236 self.write(", ");
26237 self.write_keyword(&e.unit);
26238 if let Some(zone) = &e.zone {
26239 self.write(", ");
26240 self.generate_expression(zone)?;
26241 }
26242 self.write(")");
26243 Ok(())
26244 }
26245
26246 fn generate_dayname(&mut self, e: &Dayname) -> Result<()> {
26247 self.write_keyword("DAYNAME");
26249 self.write("(");
26250 self.generate_expression(&e.this)?;
26251 self.write(")");
26252 Ok(())
26253 }
26254
26255 fn generate_declare(&mut self, e: &Declare) -> Result<()> {
26256 self.write_keyword("DECLARE");
26258 self.write_space();
26259 for (i, expr) in e.expressions.iter().enumerate() {
26260 if i > 0 {
26261 self.write(", ");
26262 }
26263 self.generate_expression(expr)?;
26264 }
26265 Ok(())
26266 }
26267
26268 fn generate_declare_item(&mut self, e: &DeclareItem) -> Result<()> {
26269 use crate::dialects::DialectType;
26270
26271 self.generate_expression(&e.this)?;
26273 for name in &e.additional_names {
26275 self.write(", ");
26276 self.generate_expression(name)?;
26277 }
26278 if let Some(kind) = &e.kind {
26279 self.write_space();
26280 match self.config.dialect {
26284 Some(DialectType::BigQuery) => {
26285 self.write(kind);
26286 }
26287 Some(DialectType::TSQL) => {
26288 let is_complex_table = kind.starts_with("TABLE")
26292 && (kind.contains("CLUSTERED") || kind.contains("INDEX"));
26293
26294 if is_complex_table {
26295 self.write(kind);
26297 } else {
26298 if !kind.starts_with("CURSOR") {
26300 self.write_keyword("AS");
26301 self.write_space();
26302 }
26303 if kind == "INT" {
26305 self.write("INTEGER");
26306 } else if kind.starts_with("TABLE") {
26307 let normalized = kind
26309 .replace(" INT ", " INTEGER ")
26310 .replace(" INT,", " INTEGER,")
26311 .replace(" INT)", " INTEGER)")
26312 .replace("(INT ", "(INTEGER ");
26313 self.write(&normalized);
26314 } else {
26315 self.write(kind);
26316 }
26317 }
26318 }
26319 _ => {
26320 if e.has_as {
26321 self.write_keyword("AS");
26322 self.write_space();
26323 }
26324 self.write(kind);
26325 }
26326 }
26327 }
26328 if let Some(default) = &e.default {
26329 match self.config.dialect {
26331 Some(DialectType::BigQuery) => {
26332 self.write_space();
26333 self.write_keyword("DEFAULT");
26334 self.write_space();
26335 }
26336 _ => {
26337 self.write(" = ");
26338 }
26339 }
26340 self.generate_expression(default)?;
26341 }
26342 Ok(())
26343 }
26344
26345 fn generate_decode_case(&mut self, e: &DecodeCase) -> Result<()> {
26346 self.write_keyword("DECODE");
26348 self.write("(");
26349 for (i, expr) in e.expressions.iter().enumerate() {
26350 if i > 0 {
26351 self.write(", ");
26352 }
26353 self.generate_expression(expr)?;
26354 }
26355 self.write(")");
26356 Ok(())
26357 }
26358
26359 fn generate_decompress_binary(&mut self, e: &DecompressBinary) -> Result<()> {
26360 self.write_keyword("DECOMPRESS");
26362 self.write("(");
26363 self.generate_expression(&e.this)?;
26364 self.write(", '");
26365 self.write(&e.method);
26366 self.write("')");
26367 Ok(())
26368 }
26369
26370 fn generate_decompress_string(&mut self, e: &DecompressString) -> Result<()> {
26371 self.write_keyword("DECOMPRESS");
26373 self.write("(");
26374 self.generate_expression(&e.this)?;
26375 self.write(", '");
26376 self.write(&e.method);
26377 self.write("')");
26378 Ok(())
26379 }
26380
26381 fn generate_decrypt(&mut self, e: &Decrypt) -> Result<()> {
26382 self.write_keyword("DECRYPT");
26384 self.write("(");
26385 self.generate_expression(&e.this)?;
26386 if let Some(passphrase) = &e.passphrase {
26387 self.write(", ");
26388 self.generate_expression(passphrase)?;
26389 }
26390 if let Some(aad) = &e.aad {
26391 self.write(", ");
26392 self.generate_expression(aad)?;
26393 }
26394 if let Some(method) = &e.encryption_method {
26395 self.write(", ");
26396 self.generate_expression(method)?;
26397 }
26398 self.write(")");
26399 Ok(())
26400 }
26401
26402 fn generate_decrypt_raw(&mut self, e: &DecryptRaw) -> Result<()> {
26403 self.write_keyword("DECRYPT_RAW");
26405 self.write("(");
26406 self.generate_expression(&e.this)?;
26407 if let Some(key) = &e.key {
26408 self.write(", ");
26409 self.generate_expression(key)?;
26410 }
26411 if let Some(iv) = &e.iv {
26412 self.write(", ");
26413 self.generate_expression(iv)?;
26414 }
26415 if let Some(aad) = &e.aad {
26416 self.write(", ");
26417 self.generate_expression(aad)?;
26418 }
26419 if let Some(method) = &e.encryption_method {
26420 self.write(", ");
26421 self.generate_expression(method)?;
26422 }
26423 self.write(")");
26424 Ok(())
26425 }
26426
26427 fn generate_definer_property(&mut self, e: &DefinerProperty) -> Result<()> {
26428 self.write_keyword("DEFINER");
26430 self.write(" = ");
26431 self.generate_expression(&e.this)?;
26432 Ok(())
26433 }
26434
26435 fn generate_detach(&mut self, e: &Detach) -> Result<()> {
26436 self.write_keyword("DETACH");
26438 if e.exists {
26439 self.write_keyword(" DATABASE IF EXISTS");
26440 }
26441 self.write_space();
26442 self.generate_expression(&e.this)?;
26443 Ok(())
26444 }
26445
26446 fn generate_dict_property(&mut self, e: &DictProperty) -> Result<()> {
26447 let property_name = match e.this.as_ref() {
26448 Expression::Identifier(id) => id.name.as_str(),
26449 Expression::Var(v) => v.this.as_str(),
26450 _ => "DICTIONARY",
26451 };
26452 self.write_keyword(property_name);
26453 self.write("(");
26454 self.write(&e.kind);
26455 if let Some(settings) = &e.settings {
26456 self.write("(");
26457 if let Expression::Tuple(t) = settings.as_ref() {
26458 if self.config.pretty && !t.expressions.is_empty() {
26459 self.write_newline();
26460 self.indent_level += 1;
26461 for (i, pair) in t.expressions.iter().enumerate() {
26462 if i > 0 {
26463 self.write(",");
26464 self.write_newline();
26465 }
26466 self.write_indent();
26467 if let Expression::Tuple(pair_tuple) = pair {
26468 if let Some(k) = pair_tuple.expressions.first() {
26469 self.generate_expression(k)?;
26470 }
26471 if let Some(v) = pair_tuple.expressions.get(1) {
26472 self.write(" ");
26473 self.generate_expression(v)?;
26474 }
26475 } else {
26476 self.generate_expression(pair)?;
26477 }
26478 }
26479 self.indent_level -= 1;
26480 self.write_newline();
26481 self.write_indent();
26482 } else {
26483 for (i, pair) in t.expressions.iter().enumerate() {
26484 if i > 0 {
26485 self.write(", ");
26486 }
26487 if let Expression::Tuple(pair_tuple) = pair {
26488 if let Some(k) = pair_tuple.expressions.first() {
26489 self.generate_expression(k)?;
26490 }
26491 if let Some(v) = pair_tuple.expressions.get(1) {
26492 self.write(" ");
26493 self.generate_expression(v)?;
26494 }
26495 } else {
26496 self.generate_expression(pair)?;
26497 }
26498 }
26499 }
26500 } else {
26501 self.generate_expression(settings)?;
26502 }
26503 self.write(")");
26504 } else if property_name.eq_ignore_ascii_case("LAYOUT") {
26505 self.write("()");
26506 }
26507 self.write(")");
26508 Ok(())
26509 }
26510
26511 fn generate_dict_range(&mut self, e: &DictRange) -> Result<()> {
26512 let property_name = match e.this.as_ref() {
26513 Expression::Identifier(id) => id.name.as_str(),
26514 Expression::Var(v) => v.this.as_str(),
26515 _ => "RANGE",
26516 };
26517 self.write_keyword(property_name);
26518 self.write("(");
26519 if let Some(min) = &e.min {
26520 self.write_keyword("MIN");
26521 self.write_space();
26522 self.generate_expression(min)?;
26523 }
26524 if let Some(max) = &e.max {
26525 self.write_space();
26526 self.write_keyword("MAX");
26527 self.write_space();
26528 self.generate_expression(max)?;
26529 }
26530 self.write(")");
26531 Ok(())
26532 }
26533
26534 fn generate_directory(&mut self, e: &Directory) -> Result<()> {
26535 if e.local.is_some() {
26537 self.write_keyword("LOCAL ");
26538 }
26539 self.write_keyword("DIRECTORY");
26540 self.write_space();
26541 self.generate_expression(&e.this)?;
26542 if let Some(row_format) = &e.row_format {
26543 self.write_space();
26544 self.generate_expression(row_format)?;
26545 }
26546 Ok(())
26547 }
26548
26549 fn generate_dist_key_property(&mut self, e: &DistKeyProperty) -> Result<()> {
26550 self.write_keyword("DISTKEY");
26552 self.write("(");
26553 self.generate_expression(&e.this)?;
26554 self.write(")");
26555 Ok(())
26556 }
26557
26558 fn generate_dist_style_property(&mut self, e: &DistStyleProperty) -> Result<()> {
26559 self.write_keyword("DISTSTYLE");
26561 self.write_space();
26562 self.generate_expression(&e.this)?;
26563 Ok(())
26564 }
26565
26566 fn generate_distribute_by(&mut self, e: &DistributeBy) -> Result<()> {
26567 self.write_keyword("DISTRIBUTE BY");
26569 self.write_space();
26570 for (i, expr) in e.expressions.iter().enumerate() {
26571 if i > 0 {
26572 self.write(", ");
26573 }
26574 self.generate_expression(expr)?;
26575 }
26576 Ok(())
26577 }
26578
26579 fn generate_distributed_by_property(&mut self, e: &DistributedByProperty) -> Result<()> {
26580 self.write_keyword("DISTRIBUTED BY");
26582 self.write_space();
26583 self.write(&e.kind);
26584 if !e.expressions.is_empty() {
26585 self.write(" (");
26586 for (i, expr) in e.expressions.iter().enumerate() {
26587 if i > 0 {
26588 self.write(", ");
26589 }
26590 self.generate_expression(expr)?;
26591 }
26592 self.write(")");
26593 }
26594 if let Some(buckets) = &e.buckets {
26595 self.write_space();
26596 self.write_keyword("BUCKETS");
26597 self.write_space();
26598 self.generate_expression(buckets)?;
26599 }
26600 if let Some(order) = &e.order {
26601 self.write_space();
26602 self.generate_expression(order)?;
26603 }
26604 Ok(())
26605 }
26606
26607 fn generate_dot_product(&mut self, e: &DotProduct) -> Result<()> {
26608 self.write_keyword("DOT_PRODUCT");
26610 self.write("(");
26611 self.generate_expression(&e.this)?;
26612 self.write(", ");
26613 self.generate_expression(&e.expression)?;
26614 self.write(")");
26615 Ok(())
26616 }
26617
26618 fn generate_drop_partition(&mut self, e: &DropPartition) -> Result<()> {
26619 self.write_keyword("DROP");
26621 if e.exists {
26622 self.write_keyword(" IF EXISTS ");
26623 } else {
26624 self.write_space();
26625 }
26626 for (i, expr) in e.expressions.iter().enumerate() {
26627 if i > 0 {
26628 self.write(", ");
26629 }
26630 self.generate_expression(expr)?;
26631 }
26632 Ok(())
26633 }
26634
26635 fn generate_duplicate_key_property(&mut self, e: &DuplicateKeyProperty) -> Result<()> {
26636 self.write_keyword("DUPLICATE KEY");
26638 self.write(" (");
26639 for (i, expr) in e.expressions.iter().enumerate() {
26640 if i > 0 {
26641 self.write(", ");
26642 }
26643 self.generate_expression(expr)?;
26644 }
26645 self.write(")");
26646 Ok(())
26647 }
26648
26649 fn generate_elt(&mut self, e: &Elt) -> Result<()> {
26650 self.write_keyword("ELT");
26652 self.write("(");
26653 self.generate_expression(&e.this)?;
26654 for expr in &e.expressions {
26655 self.write(", ");
26656 self.generate_expression(expr)?;
26657 }
26658 self.write(")");
26659 Ok(())
26660 }
26661
26662 fn generate_encode(&mut self, e: &Encode) -> Result<()> {
26663 self.write_keyword("ENCODE");
26665 self.write("(");
26666 self.generate_expression(&e.this)?;
26667 if let Some(charset) = &e.charset {
26668 self.write(", ");
26669 self.generate_expression(charset)?;
26670 }
26671 self.write(")");
26672 Ok(())
26673 }
26674
26675 fn generate_encode_property(&mut self, e: &EncodeProperty) -> Result<()> {
26676 if e.key.is_some() {
26678 self.write_keyword("KEY ");
26679 }
26680 self.write_keyword("ENCODE");
26681 self.write_space();
26682 self.generate_expression(&e.this)?;
26683 if !e.properties.is_empty() {
26684 self.write(" (");
26685 for (i, prop) in e.properties.iter().enumerate() {
26686 if i > 0 {
26687 self.write(", ");
26688 }
26689 self.generate_expression(prop)?;
26690 }
26691 self.write(")");
26692 }
26693 Ok(())
26694 }
26695
26696 fn generate_encrypt(&mut self, e: &Encrypt) -> Result<()> {
26697 self.write_keyword("ENCRYPT");
26699 self.write("(");
26700 self.generate_expression(&e.this)?;
26701 if let Some(passphrase) = &e.passphrase {
26702 self.write(", ");
26703 self.generate_expression(passphrase)?;
26704 }
26705 if let Some(aad) = &e.aad {
26706 self.write(", ");
26707 self.generate_expression(aad)?;
26708 }
26709 if let Some(method) = &e.encryption_method {
26710 self.write(", ");
26711 self.generate_expression(method)?;
26712 }
26713 self.write(")");
26714 Ok(())
26715 }
26716
26717 fn generate_encrypt_raw(&mut self, e: &EncryptRaw) -> Result<()> {
26718 self.write_keyword("ENCRYPT_RAW");
26720 self.write("(");
26721 self.generate_expression(&e.this)?;
26722 if let Some(key) = &e.key {
26723 self.write(", ");
26724 self.generate_expression(key)?;
26725 }
26726 if let Some(iv) = &e.iv {
26727 self.write(", ");
26728 self.generate_expression(iv)?;
26729 }
26730 if let Some(aad) = &e.aad {
26731 self.write(", ");
26732 self.generate_expression(aad)?;
26733 }
26734 if let Some(method) = &e.encryption_method {
26735 self.write(", ");
26736 self.generate_expression(method)?;
26737 }
26738 self.write(")");
26739 Ok(())
26740 }
26741
26742 fn generate_engine_property(&mut self, e: &EngineProperty) -> Result<()> {
26743 self.write_keyword("ENGINE");
26745 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
26746 self.write("=");
26747 } else {
26748 self.write(" = ");
26749 }
26750 self.generate_expression(&e.this)?;
26751 Ok(())
26752 }
26753
26754 fn generate_enviroment_property(&mut self, e: &EnviromentProperty) -> Result<()> {
26755 self.write_keyword("ENVIRONMENT");
26757 self.write(" (");
26758 for (i, expr) in e.expressions.iter().enumerate() {
26759 if i > 0 {
26760 self.write(", ");
26761 }
26762 self.generate_expression(expr)?;
26763 }
26764 self.write(")");
26765 Ok(())
26766 }
26767
26768 fn generate_ephemeral_column_constraint(
26769 &mut self,
26770 e: &EphemeralColumnConstraint,
26771 ) -> Result<()> {
26772 self.write_keyword("EPHEMERAL");
26774 if let Some(this) = &e.this {
26775 self.write_space();
26776 self.generate_expression(this)?;
26777 }
26778 Ok(())
26779 }
26780
26781 fn generate_equal_null(&mut self, e: &EqualNull) -> Result<()> {
26782 self.write_keyword("EQUAL_NULL");
26784 self.write("(");
26785 self.generate_expression(&e.this)?;
26786 self.write(", ");
26787 self.generate_expression(&e.expression)?;
26788 self.write(")");
26789 Ok(())
26790 }
26791
26792 fn generate_euclidean_distance(&mut self, e: &EuclideanDistance) -> Result<()> {
26793 use crate::dialects::DialectType;
26794
26795 match self.config.dialect {
26797 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
26798 self.generate_expression(&e.this)?;
26799 self.write(" <-> ");
26800 self.generate_expression(&e.expression)?;
26801 }
26802 _ => {
26803 self.write_keyword("EUCLIDEAN_DISTANCE");
26805 self.write("(");
26806 self.generate_expression(&e.this)?;
26807 self.write(", ");
26808 self.generate_expression(&e.expression)?;
26809 self.write(")");
26810 }
26811 }
26812 Ok(())
26813 }
26814
26815 fn generate_execute_as_property(&mut self, e: &ExecuteAsProperty) -> Result<()> {
26816 self.write_keyword("EXECUTE AS");
26818 self.write_space();
26819 self.generate_expression(&e.this)?;
26820 Ok(())
26821 }
26822
26823 fn generate_export(&mut self, e: &Export) -> Result<()> {
26824 self.write_keyword("EXPORT DATA");
26826 if let Some(connection) = &e.connection {
26827 self.write_space();
26828 self.write_keyword("WITH CONNECTION");
26829 self.write_space();
26830 self.generate_expression(connection)?;
26831 }
26832 if !e.options.is_empty() {
26833 self.write_space();
26834 self.generate_options_clause(&e.options)?;
26835 }
26836 self.write_space();
26837 self.write_keyword("AS");
26838 self.write_space();
26839 self.generate_expression(&e.this)?;
26840 Ok(())
26841 }
26842
26843 fn generate_external_property(&mut self, e: &ExternalProperty) -> Result<()> {
26844 self.write_keyword("EXTERNAL");
26846 if let Some(this) = &e.this {
26847 self.write_space();
26848 self.generate_expression(this)?;
26849 }
26850 Ok(())
26851 }
26852
26853 fn generate_fallback_property(&mut self, e: &FallbackProperty) -> Result<()> {
26854 if e.no.is_some() {
26856 self.write_keyword("NO ");
26857 }
26858 self.write_keyword("FALLBACK");
26859 if e.protection.is_some() {
26860 self.write_keyword(" PROTECTION");
26861 }
26862 Ok(())
26863 }
26864
26865 fn generate_farm_fingerprint(&mut self, e: &FarmFingerprint) -> Result<()> {
26866 self.write_keyword("FARM_FINGERPRINT");
26868 self.write("(");
26869 for (i, expr) in e.expressions.iter().enumerate() {
26870 if i > 0 {
26871 self.write(", ");
26872 }
26873 self.generate_expression(expr)?;
26874 }
26875 self.write(")");
26876 Ok(())
26877 }
26878
26879 fn generate_features_at_time(&mut self, e: &FeaturesAtTime) -> Result<()> {
26880 self.write_keyword("FEATURES_AT_TIME");
26882 self.write("(");
26883 self.generate_expression(&e.this)?;
26884 if let Some(time) = &e.time {
26885 self.write(", ");
26886 self.generate_expression(time)?;
26887 }
26888 if let Some(num_rows) = &e.num_rows {
26889 self.write(", ");
26890 self.generate_expression(num_rows)?;
26891 }
26892 if let Some(ignore_nulls) = &e.ignore_feature_nulls {
26893 self.write(", ");
26894 self.generate_expression(ignore_nulls)?;
26895 }
26896 self.write(")");
26897 Ok(())
26898 }
26899
26900 fn generate_fetch(&mut self, e: &Fetch) -> Result<()> {
26901 let use_limit = !e.percent
26903 && !e.with_ties
26904 && e.count.is_some()
26905 && matches!(
26906 self.config.dialect,
26907 Some(DialectType::Spark)
26908 | Some(DialectType::Hive)
26909 | Some(DialectType::DuckDB)
26910 | Some(DialectType::SQLite)
26911 | Some(DialectType::MySQL)
26912 | Some(DialectType::BigQuery)
26913 | Some(DialectType::Databricks)
26914 | Some(DialectType::StarRocks)
26915 | Some(DialectType::Doris)
26916 | Some(DialectType::Athena)
26917 | Some(DialectType::ClickHouse)
26918 );
26919
26920 if use_limit {
26921 self.write_keyword("LIMIT");
26922 self.write_space();
26923 self.generate_expression(e.count.as_ref().unwrap())?;
26924 return Ok(());
26925 }
26926
26927 self.write_keyword("FETCH");
26929 if !e.direction.is_empty() {
26930 self.write_space();
26931 self.write_keyword(&e.direction);
26932 }
26933 if let Some(count) = &e.count {
26934 self.write_space();
26935 self.generate_expression(count)?;
26936 }
26937 if e.percent {
26939 self.write_keyword(" PERCENT");
26940 }
26941 if e.rows {
26942 self.write_keyword(" ROWS");
26943 }
26944 if e.with_ties {
26945 self.write_keyword(" WITH TIES");
26946 } else if e.rows {
26947 self.write_keyword(" ONLY");
26948 } else {
26949 self.write_keyword(" ROWS ONLY");
26950 }
26951 Ok(())
26952 }
26953
26954 fn generate_file_format_property(&mut self, e: &FileFormatProperty) -> Result<()> {
26955 if e.hive_format.is_some() {
26959 self.write_keyword("STORED AS");
26961 self.write_space();
26962 if let Some(this) = &e.this {
26963 if let Expression::Identifier(id) = this.as_ref() {
26965 self.write_keyword(&id.name.to_uppercase());
26966 } else {
26967 self.generate_expression(this)?;
26968 }
26969 }
26970 } else if matches!(self.config.dialect, Some(DialectType::Hive)) {
26971 self.write_keyword("STORED AS");
26973 self.write_space();
26974 if let Some(this) = &e.this {
26975 if let Expression::Identifier(id) = this.as_ref() {
26976 self.write_keyword(&id.name.to_uppercase());
26977 } else {
26978 self.generate_expression(this)?;
26979 }
26980 }
26981 } else if matches!(
26982 self.config.dialect,
26983 Some(DialectType::Spark) | Some(DialectType::Databricks)
26984 ) {
26985 self.write_keyword("USING");
26987 self.write_space();
26988 if let Some(this) = &e.this {
26989 self.generate_expression(this)?;
26990 }
26991 } else {
26992 self.write_keyword("FILE_FORMAT");
26994 self.write(" = ");
26995 if let Some(this) = &e.this {
26996 self.generate_expression(this)?;
26997 } else if !e.expressions.is_empty() {
26998 self.write("(");
26999 for (i, expr) in e.expressions.iter().enumerate() {
27000 if i > 0 {
27001 self.write(", ");
27002 }
27003 self.generate_expression(expr)?;
27004 }
27005 self.write(")");
27006 }
27007 }
27008 Ok(())
27009 }
27010
27011 fn generate_filter(&mut self, e: &Filter) -> Result<()> {
27012 self.generate_expression(&e.this)?;
27014 self.write_space();
27015 self.write_keyword("FILTER");
27016 self.write("(");
27017 self.write_keyword("WHERE");
27018 self.write_space();
27019 self.generate_expression(&e.expression)?;
27020 self.write(")");
27021 Ok(())
27022 }
27023
27024 fn generate_float64(&mut self, e: &Float64) -> Result<()> {
27025 self.write_keyword("FLOAT64");
27027 self.write("(");
27028 self.generate_expression(&e.this)?;
27029 if let Some(expr) = &e.expression {
27030 self.write(", ");
27031 self.generate_expression(expr)?;
27032 }
27033 self.write(")");
27034 Ok(())
27035 }
27036
27037 fn generate_for_in(&mut self, e: &ForIn) -> Result<()> {
27038 self.write_keyword("FOR");
27040 self.write_space();
27041 self.generate_expression(&e.this)?;
27042 self.write_space();
27043 self.write_keyword("DO");
27044 self.write_space();
27045 self.generate_expression(&e.expression)?;
27046 Ok(())
27047 }
27048
27049 fn generate_foreign_key(&mut self, e: &ForeignKey) -> Result<()> {
27050 self.write_keyword("FOREIGN KEY");
27052 if !e.expressions.is_empty() {
27053 self.write(" (");
27054 for (i, expr) in e.expressions.iter().enumerate() {
27055 if i > 0 {
27056 self.write(", ");
27057 }
27058 self.generate_expression(expr)?;
27059 }
27060 self.write(")");
27061 }
27062 if let Some(reference) = &e.reference {
27063 self.write_space();
27064 self.generate_expression(reference)?;
27065 }
27066 if let Some(delete) = &e.delete {
27067 self.write_space();
27068 self.write_keyword("ON DELETE");
27069 self.write_space();
27070 self.generate_expression(delete)?;
27071 }
27072 if let Some(update) = &e.update {
27073 self.write_space();
27074 self.write_keyword("ON UPDATE");
27075 self.write_space();
27076 self.generate_expression(update)?;
27077 }
27078 if !e.options.is_empty() {
27079 self.write_space();
27080 for (i, opt) in e.options.iter().enumerate() {
27081 if i > 0 {
27082 self.write_space();
27083 }
27084 self.generate_expression(opt)?;
27085 }
27086 }
27087 Ok(())
27088 }
27089
27090 fn generate_format(&mut self, e: &Format) -> Result<()> {
27091 self.write_keyword("FORMAT");
27093 self.write("(");
27094 self.generate_expression(&e.this)?;
27095 for expr in &e.expressions {
27096 self.write(", ");
27097 self.generate_expression(expr)?;
27098 }
27099 self.write(")");
27100 Ok(())
27101 }
27102
27103 fn generate_format_phrase(&mut self, e: &FormatPhrase) -> Result<()> {
27104 self.generate_expression(&e.this)?;
27106 self.write(" (");
27107 self.write_keyword("FORMAT");
27108 self.write(" '");
27109 self.write(&e.format);
27110 self.write("')");
27111 Ok(())
27112 }
27113
27114 fn generate_freespace_property(&mut self, e: &FreespaceProperty) -> Result<()> {
27115 self.write_keyword("FREESPACE");
27117 self.write("=");
27118 self.generate_expression(&e.this)?;
27119 if e.percent.is_some() {
27120 self.write_keyword(" PERCENT");
27121 }
27122 Ok(())
27123 }
27124
27125 fn generate_from(&mut self, e: &From) -> Result<()> {
27126 self.write_keyword("FROM");
27128 self.write_space();
27129
27130 use crate::dialects::DialectType;
27134 let has_tablesample = e
27135 .expressions
27136 .iter()
27137 .any(|expr| matches!(expr, Expression::TableSample(_)));
27138 let is_cross_join_dialect = matches!(
27139 self.config.dialect,
27140 Some(DialectType::BigQuery)
27141 | Some(DialectType::Hive)
27142 | Some(DialectType::Spark)
27143 | Some(DialectType::Databricks)
27144 | Some(DialectType::SQLite)
27145 | Some(DialectType::ClickHouse)
27146 );
27147 let source_is_same_as_target2 = self.config.source_dialect.is_some()
27148 && self.config.source_dialect == self.config.dialect;
27149 let source_is_cross_join_dialect2 = matches!(
27150 self.config.source_dialect,
27151 Some(DialectType::BigQuery)
27152 | Some(DialectType::Hive)
27153 | Some(DialectType::Spark)
27154 | Some(DialectType::Databricks)
27155 | Some(DialectType::SQLite)
27156 | Some(DialectType::ClickHouse)
27157 );
27158 let use_cross_join = !has_tablesample
27159 && is_cross_join_dialect
27160 && (source_is_same_as_target2
27161 || source_is_cross_join_dialect2
27162 || self.config.source_dialect.is_none());
27163
27164 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
27166
27167 for (i, expr) in e.expressions.iter().enumerate() {
27168 if i > 0 {
27169 if use_cross_join {
27170 self.write(" CROSS JOIN ");
27171 } else {
27172 self.write(", ");
27173 }
27174 }
27175 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
27176 self.write("(");
27177 self.generate_expression(expr)?;
27178 self.write(")");
27179 } else {
27180 self.generate_expression(expr)?;
27181 }
27182 }
27183 Ok(())
27184 }
27185
27186 fn generate_from_base(&mut self, e: &FromBase) -> Result<()> {
27187 self.write_keyword("FROM_BASE");
27189 self.write("(");
27190 self.generate_expression(&e.this)?;
27191 self.write(", ");
27192 self.generate_expression(&e.expression)?;
27193 self.write(")");
27194 Ok(())
27195 }
27196
27197 fn generate_from_time_zone(&mut self, e: &FromTimeZone) -> Result<()> {
27198 self.generate_expression(&e.this)?;
27200 if let Some(zone) = &e.zone {
27201 self.write_space();
27202 self.write_keyword("AT TIME ZONE");
27203 self.write_space();
27204 self.generate_expression(zone)?;
27205 self.write_space();
27206 self.write_keyword("AT TIME ZONE");
27207 self.write(" 'UTC'");
27208 }
27209 Ok(())
27210 }
27211
27212 fn generate_gap_fill(&mut self, e: &GapFill) -> Result<()> {
27213 self.write_keyword("GAP_FILL");
27215 self.write("(");
27216 self.generate_expression(&e.this)?;
27217 if let Some(ts_column) = &e.ts_column {
27218 self.write(", ");
27219 self.generate_expression(ts_column)?;
27220 }
27221 if let Some(bucket_width) = &e.bucket_width {
27222 self.write(", ");
27223 self.generate_expression(bucket_width)?;
27224 }
27225 if let Some(partitioning_columns) = &e.partitioning_columns {
27226 self.write(", ");
27227 self.generate_expression(partitioning_columns)?;
27228 }
27229 if let Some(value_columns) = &e.value_columns {
27230 self.write(", ");
27231 self.generate_expression(value_columns)?;
27232 }
27233 self.write(")");
27234 Ok(())
27235 }
27236
27237 fn generate_generate_date_array(&mut self, e: &GenerateDateArray) -> Result<()> {
27238 self.write_keyword("GENERATE_DATE_ARRAY");
27240 self.write("(");
27241 let mut first = true;
27242 if let Some(start) = &e.start {
27243 self.generate_expression(start)?;
27244 first = false;
27245 }
27246 if let Some(end) = &e.end {
27247 if !first {
27248 self.write(", ");
27249 }
27250 self.generate_expression(end)?;
27251 first = false;
27252 }
27253 if let Some(step) = &e.step {
27254 if !first {
27255 self.write(", ");
27256 }
27257 self.generate_expression(step)?;
27258 }
27259 self.write(")");
27260 Ok(())
27261 }
27262
27263 fn generate_generate_embedding(&mut self, e: &GenerateEmbedding) -> Result<()> {
27264 self.write_keyword("ML.GENERATE_EMBEDDING");
27266 self.write("(");
27267 self.generate_expression(&e.this)?;
27268 self.write(", ");
27269 self.generate_expression(&e.expression)?;
27270 if let Some(params) = &e.params_struct {
27271 self.write(", ");
27272 self.generate_expression(params)?;
27273 }
27274 self.write(")");
27275 Ok(())
27276 }
27277
27278 fn generate_generate_series(&mut self, e: &GenerateSeries) -> Result<()> {
27279 let fn_name = match self.config.dialect {
27281 Some(DialectType::Presto)
27282 | Some(DialectType::Trino)
27283 | Some(DialectType::Athena)
27284 | Some(DialectType::Spark)
27285 | Some(DialectType::Databricks)
27286 | Some(DialectType::Hive) => "SEQUENCE",
27287 _ => "GENERATE_SERIES",
27288 };
27289 self.write_keyword(fn_name);
27290 self.write("(");
27291 let mut first = true;
27292 if let Some(start) = &e.start {
27293 self.generate_expression(start)?;
27294 first = false;
27295 }
27296 if let Some(end) = &e.end {
27297 if !first {
27298 self.write(", ");
27299 }
27300 self.generate_expression(end)?;
27301 first = false;
27302 }
27303 if let Some(step) = &e.step {
27304 if !first {
27305 self.write(", ");
27306 }
27307 if matches!(
27310 self.config.dialect,
27311 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
27312 ) {
27313 if let Some(converted) = self.convert_week_interval_to_day(step) {
27314 self.generate_expression(&converted)?;
27315 } else {
27316 self.generate_expression(step)?;
27317 }
27318 } else {
27319 self.generate_expression(step)?;
27320 }
27321 }
27322 self.write(")");
27323 Ok(())
27324 }
27325
27326 fn convert_week_interval_to_day(&self, expr: &Expression) -> Option<Expression> {
27329 use crate::expressions::*;
27330 if let Expression::Interval(ref iv) = expr {
27331 let (is_week, count_str) = if let Some(IntervalUnitSpec::Simple {
27333 unit: IntervalUnit::Week,
27334 ..
27335 }) = &iv.unit
27336 {
27337 let count = match &iv.this {
27339 Some(Expression::Literal(Literal::String(s))) => s.clone(),
27340 Some(Expression::Literal(Literal::Number(s))) => s.clone(),
27341 _ => return None,
27342 };
27343 (true, count)
27344 } else if iv.unit.is_none() {
27345 if let Some(Expression::Literal(Literal::String(s))) = &iv.this {
27347 let parts: Vec<&str> = s.trim().splitn(2, char::is_whitespace).collect();
27348 if parts.len() == 2 && parts[1].eq_ignore_ascii_case("WEEK") {
27349 (true, parts[0].to_string())
27350 } else {
27351 (false, String::new())
27352 }
27353 } else {
27354 (false, String::new())
27355 }
27356 } else {
27357 (false, String::new())
27358 };
27359
27360 if is_week {
27361 let count_expr = Expression::Literal(Literal::Number(count_str));
27363 let day_interval = Expression::Interval(Box::new(Interval {
27364 this: Some(Expression::Literal(Literal::String("7".to_string()))),
27365 unit: Some(IntervalUnitSpec::Simple {
27366 unit: IntervalUnit::Day,
27367 use_plural: false,
27368 }),
27369 }));
27370 let mul = Expression::Mul(Box::new(BinaryOp {
27371 left: count_expr,
27372 right: day_interval,
27373 left_comments: vec![],
27374 operator_comments: vec![],
27375 trailing_comments: vec![],
27376 }));
27377 return Some(Expression::Paren(Box::new(Paren {
27378 this: mul,
27379 trailing_comments: vec![],
27380 })));
27381 }
27382 }
27383 None
27384 }
27385
27386 fn generate_generate_timestamp_array(&mut self, e: &GenerateTimestampArray) -> Result<()> {
27387 self.write_keyword("GENERATE_TIMESTAMP_ARRAY");
27389 self.write("(");
27390 let mut first = true;
27391 if let Some(start) = &e.start {
27392 self.generate_expression(start)?;
27393 first = false;
27394 }
27395 if let Some(end) = &e.end {
27396 if !first {
27397 self.write(", ");
27398 }
27399 self.generate_expression(end)?;
27400 first = false;
27401 }
27402 if let Some(step) = &e.step {
27403 if !first {
27404 self.write(", ");
27405 }
27406 self.generate_expression(step)?;
27407 }
27408 self.write(")");
27409 Ok(())
27410 }
27411
27412 fn generate_generated_as_identity_column_constraint(
27413 &mut self,
27414 e: &GeneratedAsIdentityColumnConstraint,
27415 ) -> Result<()> {
27416 use crate::dialects::DialectType;
27417
27418 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
27420 self.write_keyword("AUTOINCREMENT");
27421 if let Some(start) = &e.start {
27422 self.write_keyword(" START ");
27423 self.generate_expression(start)?;
27424 }
27425 if let Some(increment) = &e.increment {
27426 self.write_keyword(" INCREMENT ");
27427 self.generate_expression(increment)?;
27428 }
27429 return Ok(());
27430 }
27431
27432 self.write_keyword("GENERATED");
27434 if let Some(this) = &e.this {
27435 if let Expression::Boolean(b) = this.as_ref() {
27437 if b.value {
27438 self.write_keyword(" ALWAYS");
27439 } else {
27440 self.write_keyword(" BY DEFAULT");
27441 if e.on_null.is_some() {
27442 self.write_keyword(" ON NULL");
27443 }
27444 }
27445 } else {
27446 self.write_keyword(" ALWAYS");
27447 }
27448 }
27449 self.write_keyword(" AS IDENTITY");
27450 let has_options = e.start.is_some()
27452 || e.increment.is_some()
27453 || e.minvalue.is_some()
27454 || e.maxvalue.is_some();
27455 if has_options {
27456 self.write(" (");
27457 let mut first = true;
27458 if let Some(start) = &e.start {
27459 self.write_keyword("START WITH ");
27460 self.generate_expression(start)?;
27461 first = false;
27462 }
27463 if let Some(increment) = &e.increment {
27464 if !first {
27465 self.write(" ");
27466 }
27467 self.write_keyword("INCREMENT BY ");
27468 self.generate_expression(increment)?;
27469 first = false;
27470 }
27471 if let Some(minvalue) = &e.minvalue {
27472 if !first {
27473 self.write(" ");
27474 }
27475 self.write_keyword("MINVALUE ");
27476 self.generate_expression(minvalue)?;
27477 first = false;
27478 }
27479 if let Some(maxvalue) = &e.maxvalue {
27480 if !first {
27481 self.write(" ");
27482 }
27483 self.write_keyword("MAXVALUE ");
27484 self.generate_expression(maxvalue)?;
27485 }
27486 self.write(")");
27487 }
27488 Ok(())
27489 }
27490
27491 fn generate_generated_as_row_column_constraint(
27492 &mut self,
27493 e: &GeneratedAsRowColumnConstraint,
27494 ) -> Result<()> {
27495 self.write_keyword("GENERATED ALWAYS AS ROW ");
27497 if e.start.is_some() {
27498 self.write_keyword("START");
27499 } else {
27500 self.write_keyword("END");
27501 }
27502 if e.hidden.is_some() {
27503 self.write_keyword(" HIDDEN");
27504 }
27505 Ok(())
27506 }
27507
27508 fn generate_get(&mut self, e: &Get) -> Result<()> {
27509 self.write_keyword("GET");
27511 self.write_space();
27512 self.generate_expression(&e.this)?;
27513 if let Some(target) = &e.target {
27514 self.write_space();
27515 self.generate_expression(target)?;
27516 }
27517 for prop in &e.properties {
27518 self.write_space();
27519 self.generate_expression(prop)?;
27520 }
27521 Ok(())
27522 }
27523
27524 fn generate_get_extract(&mut self, e: &GetExtract) -> Result<()> {
27525 self.generate_expression(&e.this)?;
27527 self.write("[");
27528 self.generate_expression(&e.expression)?;
27529 self.write("]");
27530 Ok(())
27531 }
27532
27533 fn generate_getbit(&mut self, e: &Getbit) -> Result<()> {
27534 self.write_keyword("GETBIT");
27536 self.write("(");
27537 self.generate_expression(&e.this)?;
27538 self.write(", ");
27539 self.generate_expression(&e.expression)?;
27540 self.write(")");
27541 Ok(())
27542 }
27543
27544 fn generate_grant_principal(&mut self, e: &GrantPrincipal) -> Result<()> {
27545 if e.is_role {
27547 self.write_keyword("ROLE");
27548 self.write_space();
27549 } else if e.is_group {
27550 self.write_keyword("GROUP");
27551 self.write_space();
27552 }
27553 self.write(&e.name.name);
27554 Ok(())
27555 }
27556
27557 fn generate_grant_privilege(&mut self, e: &GrantPrivilege) -> Result<()> {
27558 self.generate_expression(&e.this)?;
27560 if !e.expressions.is_empty() {
27561 self.write("(");
27562 for (i, expr) in e.expressions.iter().enumerate() {
27563 if i > 0 {
27564 self.write(", ");
27565 }
27566 self.generate_expression(expr)?;
27567 }
27568 self.write(")");
27569 }
27570 Ok(())
27571 }
27572
27573 fn generate_group(&mut self, e: &Group) -> Result<()> {
27574 self.write_keyword("GROUP BY");
27576 match e.all {
27578 Some(true) => {
27579 self.write_space();
27580 self.write_keyword("ALL");
27581 }
27582 Some(false) => {
27583 self.write_space();
27584 self.write_keyword("DISTINCT");
27585 }
27586 None => {}
27587 }
27588 if !e.expressions.is_empty() {
27589 self.write_space();
27590 for (i, expr) in e.expressions.iter().enumerate() {
27591 if i > 0 {
27592 self.write(", ");
27593 }
27594 self.generate_expression(expr)?;
27595 }
27596 }
27597 if let Some(cube) = &e.cube {
27599 if !e.expressions.is_empty() {
27600 self.write(", ");
27601 } else {
27602 self.write_space();
27603 }
27604 self.generate_expression(cube)?;
27605 }
27606 if let Some(rollup) = &e.rollup {
27607 if !e.expressions.is_empty() || e.cube.is_some() {
27608 self.write(", ");
27609 } else {
27610 self.write_space();
27611 }
27612 self.generate_expression(rollup)?;
27613 }
27614 if let Some(grouping_sets) = &e.grouping_sets {
27615 if !e.expressions.is_empty() || e.cube.is_some() || e.rollup.is_some() {
27616 self.write(", ");
27617 } else {
27618 self.write_space();
27619 }
27620 self.generate_expression(grouping_sets)?;
27621 }
27622 if let Some(totals) = &e.totals {
27623 self.write_space();
27624 self.write_keyword("WITH TOTALS");
27625 self.generate_expression(totals)?;
27626 }
27627 Ok(())
27628 }
27629
27630 fn generate_group_by(&mut self, e: &GroupBy) -> Result<()> {
27631 self.write_keyword("GROUP BY");
27633 match e.all {
27635 Some(true) => {
27636 self.write_space();
27637 self.write_keyword("ALL");
27638 }
27639 Some(false) => {
27640 self.write_space();
27641 self.write_keyword("DISTINCT");
27642 }
27643 None => {}
27644 }
27645
27646 let mut trailing_cube = false;
27649 let mut trailing_rollup = false;
27650 let mut regular_expressions: Vec<&Expression> = Vec::new();
27651
27652 for expr in &e.expressions {
27653 match expr {
27654 Expression::Cube(c) if c.expressions.is_empty() => {
27655 trailing_cube = true;
27656 }
27657 Expression::Rollup(r) if r.expressions.is_empty() => {
27658 trailing_rollup = true;
27659 }
27660 _ => {
27661 regular_expressions.push(expr);
27662 }
27663 }
27664 }
27665
27666 if self.config.pretty {
27668 self.write_newline();
27669 self.indent_level += 1;
27670 for (i, expr) in regular_expressions.iter().enumerate() {
27671 if i > 0 {
27672 self.write(",");
27673 self.write_newline();
27674 }
27675 self.write_indent();
27676 self.generate_expression(expr)?;
27677 }
27678 self.indent_level -= 1;
27679 } else {
27680 self.write_space();
27681 for (i, expr) in regular_expressions.iter().enumerate() {
27682 if i > 0 {
27683 self.write(", ");
27684 }
27685 self.generate_expression(expr)?;
27686 }
27687 }
27688
27689 if trailing_cube {
27691 self.write_space();
27692 self.write_keyword("WITH CUBE");
27693 } else if trailing_rollup {
27694 self.write_space();
27695 self.write_keyword("WITH ROLLUP");
27696 }
27697
27698 if e.totals {
27700 self.write_space();
27701 self.write_keyword("WITH TOTALS");
27702 }
27703
27704 Ok(())
27705 }
27706
27707 fn generate_grouping(&mut self, e: &Grouping) -> Result<()> {
27708 self.write_keyword("GROUPING");
27710 self.write("(");
27711 for (i, expr) in e.expressions.iter().enumerate() {
27712 if i > 0 {
27713 self.write(", ");
27714 }
27715 self.generate_expression(expr)?;
27716 }
27717 self.write(")");
27718 Ok(())
27719 }
27720
27721 fn generate_grouping_id(&mut self, e: &GroupingId) -> Result<()> {
27722 self.write_keyword("GROUPING_ID");
27724 self.write("(");
27725 for (i, expr) in e.expressions.iter().enumerate() {
27726 if i > 0 {
27727 self.write(", ");
27728 }
27729 self.generate_expression(expr)?;
27730 }
27731 self.write(")");
27732 Ok(())
27733 }
27734
27735 fn generate_grouping_sets(&mut self, e: &GroupingSets) -> Result<()> {
27736 self.write_keyword("GROUPING SETS");
27738 self.write(" (");
27739 for (i, expr) in e.expressions.iter().enumerate() {
27740 if i > 0 {
27741 self.write(", ");
27742 }
27743 self.generate_expression(expr)?;
27744 }
27745 self.write(")");
27746 Ok(())
27747 }
27748
27749 fn generate_hash_agg(&mut self, e: &HashAgg) -> Result<()> {
27750 self.write_keyword("HASH_AGG");
27752 self.write("(");
27753 self.generate_expression(&e.this)?;
27754 for expr in &e.expressions {
27755 self.write(", ");
27756 self.generate_expression(expr)?;
27757 }
27758 self.write(")");
27759 Ok(())
27760 }
27761
27762 fn generate_having(&mut self, e: &Having) -> Result<()> {
27763 self.write_keyword("HAVING");
27765 self.write_space();
27766 self.generate_expression(&e.this)?;
27767 Ok(())
27768 }
27769
27770 fn generate_having_max(&mut self, e: &HavingMax) -> Result<()> {
27771 self.generate_expression(&e.this)?;
27773 self.write_space();
27774 self.write_keyword("HAVING");
27775 self.write_space();
27776 if e.max.is_some() {
27777 self.write_keyword("MAX");
27778 } else {
27779 self.write_keyword("MIN");
27780 }
27781 self.write_space();
27782 self.generate_expression(&e.expression)?;
27783 Ok(())
27784 }
27785
27786 fn generate_heredoc(&mut self, e: &Heredoc) -> Result<()> {
27787 use crate::dialects::DialectType;
27788 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
27790 if let Expression::Literal(Literal::String(ref s)) = *e.this {
27792 return self.generate_string_literal(s);
27793 }
27794 }
27795 if matches!(
27797 self.config.dialect,
27798 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
27799 ) {
27800 self.write("$");
27801 if let Some(tag) = &e.tag {
27802 self.generate_expression(tag)?;
27803 }
27804 self.write("$");
27805 self.generate_expression(&e.this)?;
27806 self.write("$");
27807 if let Some(tag) = &e.tag {
27808 self.generate_expression(tag)?;
27809 }
27810 self.write("$");
27811 return Ok(());
27812 }
27813 self.write("$");
27815 if let Some(tag) = &e.tag {
27816 self.generate_expression(tag)?;
27817 }
27818 self.write("$");
27819 self.generate_expression(&e.this)?;
27820 self.write("$");
27821 if let Some(tag) = &e.tag {
27822 self.generate_expression(tag)?;
27823 }
27824 self.write("$");
27825 Ok(())
27826 }
27827
27828 fn generate_hex_encode(&mut self, e: &HexEncode) -> Result<()> {
27829 self.write_keyword("HEX_ENCODE");
27831 self.write("(");
27832 self.generate_expression(&e.this)?;
27833 self.write(")");
27834 Ok(())
27835 }
27836
27837 fn generate_historical_data(&mut self, e: &HistoricalData) -> Result<()> {
27838 match e.this.as_ref() {
27841 Expression::Identifier(id) => self.write(&id.name),
27842 other => self.generate_expression(other)?,
27843 }
27844 self.write(" (");
27845 self.write(&e.kind);
27846 self.write(" => ");
27847 self.generate_expression(&e.expression)?;
27848 self.write(")");
27849 Ok(())
27850 }
27851
27852 fn generate_hll(&mut self, e: &Hll) -> Result<()> {
27853 self.write_keyword("HLL");
27855 self.write("(");
27856 self.generate_expression(&e.this)?;
27857 for expr in &e.expressions {
27858 self.write(", ");
27859 self.generate_expression(expr)?;
27860 }
27861 self.write(")");
27862 Ok(())
27863 }
27864
27865 fn generate_in_out_column_constraint(&mut self, e: &InOutColumnConstraint) -> Result<()> {
27866 if e.input_.is_some() && e.output.is_some() {
27868 self.write_keyword("IN OUT");
27869 } else if e.input_.is_some() {
27870 self.write_keyword("IN");
27871 } else if e.output.is_some() {
27872 self.write_keyword("OUT");
27873 }
27874 Ok(())
27875 }
27876
27877 fn generate_include_property(&mut self, e: &IncludeProperty) -> Result<()> {
27878 self.write_keyword("INCLUDE");
27880 self.write_space();
27881 self.generate_expression(&e.this)?;
27882 if let Some(column_def) = &e.column_def {
27883 self.write_space();
27884 self.generate_expression(column_def)?;
27885 }
27886 if let Some(alias) = &e.alias {
27887 self.write_space();
27888 self.write_keyword("AS");
27889 self.write_space();
27890 self.write(alias);
27891 }
27892 Ok(())
27893 }
27894
27895 fn generate_index(&mut self, e: &Index) -> Result<()> {
27896 if e.unique {
27898 self.write_keyword("UNIQUE");
27899 self.write_space();
27900 }
27901 if e.primary.is_some() {
27902 self.write_keyword("PRIMARY");
27903 self.write_space();
27904 }
27905 if e.amp.is_some() {
27906 self.write_keyword("AMP");
27907 self.write_space();
27908 }
27909 if e.table.is_none() {
27910 self.write_keyword("INDEX");
27911 self.write_space();
27912 }
27913 if let Some(name) = &e.this {
27914 self.generate_expression(name)?;
27915 self.write_space();
27916 }
27917 if let Some(table) = &e.table {
27918 self.write_keyword("ON");
27919 self.write_space();
27920 self.generate_expression(table)?;
27921 }
27922 if !e.params.is_empty() {
27923 self.write("(");
27924 for (i, param) in e.params.iter().enumerate() {
27925 if i > 0 {
27926 self.write(", ");
27927 }
27928 self.generate_expression(param)?;
27929 }
27930 self.write(")");
27931 }
27932 Ok(())
27933 }
27934
27935 fn generate_index_column_constraint(&mut self, e: &IndexColumnConstraint) -> Result<()> {
27936 if let Some(kind) = &e.kind {
27938 self.write(kind);
27939 self.write_space();
27940 }
27941 self.write_keyword("INDEX");
27942 if let Some(this) = &e.this {
27943 self.write_space();
27944 self.generate_expression(this)?;
27945 }
27946 if let Some(index_type) = &e.index_type {
27947 self.write_space();
27948 self.write_keyword("USING");
27949 self.write_space();
27950 self.generate_expression(index_type)?;
27951 }
27952 if !e.expressions.is_empty() {
27953 self.write(" (");
27954 for (i, expr) in e.expressions.iter().enumerate() {
27955 if i > 0 {
27956 self.write(", ");
27957 }
27958 self.generate_expression(expr)?;
27959 }
27960 self.write(")");
27961 }
27962 for opt in &e.options {
27963 self.write_space();
27964 self.generate_expression(opt)?;
27965 }
27966 Ok(())
27967 }
27968
27969 fn generate_index_constraint_option(&mut self, e: &IndexConstraintOption) -> Result<()> {
27970 if let Some(key_block_size) = &e.key_block_size {
27972 self.write_keyword("KEY_BLOCK_SIZE");
27973 self.write(" = ");
27974 self.generate_expression(key_block_size)?;
27975 } else if let Some(using) = &e.using {
27976 self.write_keyword("USING");
27977 self.write_space();
27978 self.generate_expression(using)?;
27979 } else if let Some(parser) = &e.parser {
27980 self.write_keyword("WITH PARSER");
27981 self.write_space();
27982 self.generate_expression(parser)?;
27983 } else if let Some(comment) = &e.comment {
27984 self.write_keyword("COMMENT");
27985 self.write_space();
27986 self.generate_expression(comment)?;
27987 } else if let Some(visible) = &e.visible {
27988 self.generate_expression(visible)?;
27989 } else if let Some(engine_attr) = &e.engine_attr {
27990 self.write_keyword("ENGINE_ATTRIBUTE");
27991 self.write(" = ");
27992 self.generate_expression(engine_attr)?;
27993 } else if let Some(secondary_engine_attr) = &e.secondary_engine_attr {
27994 self.write_keyword("SECONDARY_ENGINE_ATTRIBUTE");
27995 self.write(" = ");
27996 self.generate_expression(secondary_engine_attr)?;
27997 }
27998 Ok(())
27999 }
28000
28001 fn generate_index_parameters(&mut self, e: &IndexParameters) -> Result<()> {
28002 if let Some(using) = &e.using {
28004 self.write_keyword("USING");
28005 self.write_space();
28006 self.generate_expression(using)?;
28007 }
28008 if !e.columns.is_empty() {
28009 self.write("(");
28010 for (i, col) in e.columns.iter().enumerate() {
28011 if i > 0 {
28012 self.write(", ");
28013 }
28014 self.generate_expression(col)?;
28015 }
28016 self.write(")");
28017 }
28018 if let Some(partition_by) = &e.partition_by {
28019 self.write_space();
28020 self.write_keyword("PARTITION BY");
28021 self.write_space();
28022 self.generate_expression(partition_by)?;
28023 }
28024 if let Some(where_) = &e.where_ {
28025 self.write_space();
28026 self.generate_expression(where_)?;
28027 }
28028 if let Some(include) = &e.include {
28029 self.write_space();
28030 self.write_keyword("INCLUDE");
28031 self.write(" (");
28032 self.generate_expression(include)?;
28033 self.write(")");
28034 }
28035 if let Some(with_storage) = &e.with_storage {
28036 self.write_space();
28037 self.write_keyword("WITH");
28038 self.write(" (");
28039 self.generate_expression(with_storage)?;
28040 self.write(")");
28041 }
28042 if let Some(tablespace) = &e.tablespace {
28043 self.write_space();
28044 self.write_keyword("USING INDEX TABLESPACE");
28045 self.write_space();
28046 self.generate_expression(tablespace)?;
28047 }
28048 Ok(())
28049 }
28050
28051 fn generate_index_table_hint(&mut self, e: &IndexTableHint) -> Result<()> {
28052 if let Expression::Identifier(id) = &*e.this {
28056 self.write_keyword(&id.name);
28057 } else {
28058 self.generate_expression(&e.this)?;
28059 }
28060 self.write_space();
28061 self.write_keyword("INDEX");
28062 if let Some(target) = &e.target {
28063 self.write_space();
28064 self.write_keyword("FOR");
28065 self.write_space();
28066 if let Expression::Identifier(id) = &**target {
28067 self.write_keyword(&id.name);
28068 } else {
28069 self.generate_expression(target)?;
28070 }
28071 }
28072 self.write(" (");
28074 for (i, expr) in e.expressions.iter().enumerate() {
28075 if i > 0 {
28076 self.write(", ");
28077 }
28078 self.generate_expression(expr)?;
28079 }
28080 self.write(")");
28081 Ok(())
28082 }
28083
28084 fn generate_inherits_property(&mut self, e: &InheritsProperty) -> Result<()> {
28085 self.write_keyword("INHERITS");
28087 self.write(" (");
28088 for (i, expr) in e.expressions.iter().enumerate() {
28089 if i > 0 {
28090 self.write(", ");
28091 }
28092 self.generate_expression(expr)?;
28093 }
28094 self.write(")");
28095 Ok(())
28096 }
28097
28098 fn generate_input_model_property(&mut self, e: &InputModelProperty) -> Result<()> {
28099 self.write_keyword("INPUT");
28101 self.write("(");
28102 self.generate_expression(&e.this)?;
28103 self.write(")");
28104 Ok(())
28105 }
28106
28107 fn generate_input_output_format(&mut self, e: &InputOutputFormat) -> Result<()> {
28108 if let Some(input_format) = &e.input_format {
28110 self.write_keyword("INPUTFORMAT");
28111 self.write_space();
28112 self.generate_expression(input_format)?;
28113 }
28114 if let Some(output_format) = &e.output_format {
28115 if e.input_format.is_some() {
28116 self.write(" ");
28117 }
28118 self.write_keyword("OUTPUTFORMAT");
28119 self.write_space();
28120 self.generate_expression(output_format)?;
28121 }
28122 Ok(())
28123 }
28124
28125 fn generate_install(&mut self, e: &Install) -> Result<()> {
28126 if e.force.is_some() {
28128 self.write_keyword("FORCE");
28129 self.write_space();
28130 }
28131 self.write_keyword("INSTALL");
28132 self.write_space();
28133 self.generate_expression(&e.this)?;
28134 if let Some(from) = &e.from_ {
28135 self.write_space();
28136 self.write_keyword("FROM");
28137 self.write_space();
28138 self.generate_expression(from)?;
28139 }
28140 Ok(())
28141 }
28142
28143 fn generate_interval_op(&mut self, e: &IntervalOp) -> Result<()> {
28144 self.write_keyword("INTERVAL");
28146 self.write_space();
28147 self.generate_expression(&e.expression)?;
28149 if let Some(unit) = &e.unit {
28150 self.write_space();
28151 self.write(unit);
28152 }
28153 Ok(())
28154 }
28155
28156 fn generate_interval_span(&mut self, e: &IntervalSpan) -> Result<()> {
28157 self.write(&format!("{:?}", e.this).to_uppercase());
28159 self.write_space();
28160 self.write_keyword("TO");
28161 self.write_space();
28162 self.write(&format!("{:?}", e.expression).to_uppercase());
28163 Ok(())
28164 }
28165
28166 fn generate_into_clause(&mut self, e: &IntoClause) -> Result<()> {
28167 self.write_keyword("INTO");
28169 if e.temporary {
28170 self.write_keyword(" TEMPORARY");
28171 }
28172 if e.unlogged.is_some() {
28173 self.write_keyword(" UNLOGGED");
28174 }
28175 if let Some(this) = &e.this {
28176 self.write_space();
28177 self.generate_expression(this)?;
28178 }
28179 if !e.expressions.is_empty() {
28180 self.write(" (");
28181 for (i, expr) in e.expressions.iter().enumerate() {
28182 if i > 0 {
28183 self.write(", ");
28184 }
28185 self.generate_expression(expr)?;
28186 }
28187 self.write(")");
28188 }
28189 Ok(())
28190 }
28191
28192 fn generate_introducer(&mut self, e: &Introducer) -> Result<()> {
28193 self.generate_expression(&e.this)?;
28195 self.write_space();
28196 self.generate_expression(&e.expression)?;
28197 Ok(())
28198 }
28199
28200 fn generate_isolated_loading_property(&mut self, e: &IsolatedLoadingProperty) -> Result<()> {
28201 self.write_keyword("WITH");
28203 if e.no.is_some() {
28204 self.write_keyword(" NO");
28205 }
28206 if e.concurrent.is_some() {
28207 self.write_keyword(" CONCURRENT");
28208 }
28209 self.write_keyword(" ISOLATED LOADING");
28210 if let Some(target) = &e.target {
28211 self.write_space();
28212 self.generate_expression(target)?;
28213 }
28214 Ok(())
28215 }
28216
28217 fn generate_json(&mut self, e: &JSON) -> Result<()> {
28218 self.write_keyword("JSON");
28220 if let Some(this) = &e.this {
28221 self.write_space();
28222 self.generate_expression(this)?;
28223 }
28224 if let Some(with_) = &e.with_ {
28225 if let Expression::Boolean(b) = with_.as_ref() {
28227 if b.value {
28228 self.write_keyword(" WITH");
28229 } else {
28230 self.write_keyword(" WITHOUT");
28231 }
28232 }
28233 }
28234 if e.unique {
28235 self.write_keyword(" UNIQUE KEYS");
28236 }
28237 Ok(())
28238 }
28239
28240 fn generate_json_array(&mut self, e: &JSONArray) -> Result<()> {
28241 self.write_keyword("JSON_ARRAY");
28243 self.write("(");
28244 for (i, expr) in e.expressions.iter().enumerate() {
28245 if i > 0 {
28246 self.write(", ");
28247 }
28248 self.generate_expression(expr)?;
28249 }
28250 if let Some(null_handling) = &e.null_handling {
28251 self.write_space();
28252 self.generate_expression(null_handling)?;
28253 }
28254 if let Some(return_type) = &e.return_type {
28255 self.write_space();
28256 self.write_keyword("RETURNING");
28257 self.write_space();
28258 self.generate_expression(return_type)?;
28259 }
28260 if e.strict.is_some() {
28261 self.write_space();
28262 self.write_keyword("STRICT");
28263 }
28264 self.write(")");
28265 Ok(())
28266 }
28267
28268 fn generate_json_array_agg_struct(&mut self, e: &JSONArrayAgg) -> Result<()> {
28269 self.write_keyword("JSON_ARRAYAGG");
28271 self.write("(");
28272 self.generate_expression(&e.this)?;
28273 if let Some(order) = &e.order {
28274 self.write_space();
28275 if let Expression::OrderBy(ob) = order.as_ref() {
28277 self.write_keyword("ORDER BY");
28278 self.write_space();
28279 for (i, ord) in ob.expressions.iter().enumerate() {
28280 if i > 0 {
28281 self.write(", ");
28282 }
28283 self.generate_ordered(ord)?;
28284 }
28285 } else {
28286 self.generate_expression(order)?;
28288 }
28289 }
28290 if let Some(null_handling) = &e.null_handling {
28291 self.write_space();
28292 self.generate_expression(null_handling)?;
28293 }
28294 if let Some(return_type) = &e.return_type {
28295 self.write_space();
28296 self.write_keyword("RETURNING");
28297 self.write_space();
28298 self.generate_expression(return_type)?;
28299 }
28300 if e.strict.is_some() {
28301 self.write_space();
28302 self.write_keyword("STRICT");
28303 }
28304 self.write(")");
28305 Ok(())
28306 }
28307
28308 fn generate_json_object_agg_struct(&mut self, e: &JSONObjectAgg) -> Result<()> {
28309 self.write_keyword("JSON_OBJECTAGG");
28311 self.write("(");
28312 for (i, expr) in e.expressions.iter().enumerate() {
28313 if i > 0 {
28314 self.write(", ");
28315 }
28316 self.generate_expression(expr)?;
28317 }
28318 if let Some(null_handling) = &e.null_handling {
28319 self.write_space();
28320 self.generate_expression(null_handling)?;
28321 }
28322 if let Some(unique_keys) = &e.unique_keys {
28323 self.write_space();
28324 if let Expression::Boolean(b) = unique_keys.as_ref() {
28325 if b.value {
28326 self.write_keyword("WITH UNIQUE KEYS");
28327 } else {
28328 self.write_keyword("WITHOUT UNIQUE KEYS");
28329 }
28330 }
28331 }
28332 if let Some(return_type) = &e.return_type {
28333 self.write_space();
28334 self.write_keyword("RETURNING");
28335 self.write_space();
28336 self.generate_expression(return_type)?;
28337 }
28338 self.write(")");
28339 Ok(())
28340 }
28341
28342 fn generate_json_array_append(&mut self, e: &JSONArrayAppend) -> Result<()> {
28343 self.write_keyword("JSON_ARRAY_APPEND");
28345 self.write("(");
28346 self.generate_expression(&e.this)?;
28347 for expr in &e.expressions {
28348 self.write(", ");
28349 self.generate_expression(expr)?;
28350 }
28351 self.write(")");
28352 Ok(())
28353 }
28354
28355 fn generate_json_array_contains(&mut self, e: &JSONArrayContains) -> Result<()> {
28356 self.write_keyword("JSON_ARRAY_CONTAINS");
28358 self.write("(");
28359 self.generate_expression(&e.this)?;
28360 self.write(", ");
28361 self.generate_expression(&e.expression)?;
28362 self.write(")");
28363 Ok(())
28364 }
28365
28366 fn generate_json_array_insert(&mut self, e: &JSONArrayInsert) -> Result<()> {
28367 self.write_keyword("JSON_ARRAY_INSERT");
28369 self.write("(");
28370 self.generate_expression(&e.this)?;
28371 for expr in &e.expressions {
28372 self.write(", ");
28373 self.generate_expression(expr)?;
28374 }
28375 self.write(")");
28376 Ok(())
28377 }
28378
28379 fn generate_jsonb_exists(&mut self, e: &JSONBExists) -> Result<()> {
28380 self.write_keyword("JSONB_EXISTS");
28382 self.write("(");
28383 self.generate_expression(&e.this)?;
28384 if let Some(path) = &e.path {
28385 self.write(", ");
28386 self.generate_expression(path)?;
28387 }
28388 self.write(")");
28389 Ok(())
28390 }
28391
28392 fn generate_jsonb_extract_scalar(&mut self, e: &JSONBExtractScalar) -> Result<()> {
28393 self.write_keyword("JSONB_EXTRACT_SCALAR");
28395 self.write("(");
28396 self.generate_expression(&e.this)?;
28397 self.write(", ");
28398 self.generate_expression(&e.expression)?;
28399 self.write(")");
28400 Ok(())
28401 }
28402
28403 fn generate_jsonb_object_agg(&mut self, e: &JSONBObjectAgg) -> Result<()> {
28404 self.write_keyword("JSONB_OBJECT_AGG");
28406 self.write("(");
28407 self.generate_expression(&e.this)?;
28408 self.write(", ");
28409 self.generate_expression(&e.expression)?;
28410 self.write(")");
28411 Ok(())
28412 }
28413
28414 fn generate_json_column_def(&mut self, e: &JSONColumnDef) -> Result<()> {
28415 if let Some(nested_schema) = &e.nested_schema {
28417 self.write_keyword("NESTED");
28418 if let Some(path) = &e.path {
28419 self.write_space();
28420 self.write_keyword("PATH");
28421 self.write_space();
28422 self.generate_expression(path)?;
28423 }
28424 self.write_space();
28425 self.generate_expression(nested_schema)?;
28426 } else {
28427 if let Some(this) = &e.this {
28428 self.generate_expression(this)?;
28429 }
28430 if let Some(kind) = &e.kind {
28431 self.write_space();
28432 self.write(kind);
28433 }
28434 if let Some(path) = &e.path {
28435 self.write_space();
28436 self.write_keyword("PATH");
28437 self.write_space();
28438 self.generate_expression(path)?;
28439 }
28440 if e.ordinality.is_some() {
28441 self.write_keyword(" FOR ORDINALITY");
28442 }
28443 }
28444 Ok(())
28445 }
28446
28447 fn generate_json_exists(&mut self, e: &JSONExists) -> Result<()> {
28448 self.write_keyword("JSON_EXISTS");
28450 self.write("(");
28451 self.generate_expression(&e.this)?;
28452 if let Some(path) = &e.path {
28453 self.write(", ");
28454 self.generate_expression(path)?;
28455 }
28456 if let Some(passing) = &e.passing {
28457 self.write_space();
28458 self.write_keyword("PASSING");
28459 self.write_space();
28460 self.generate_expression(passing)?;
28461 }
28462 if let Some(on_condition) = &e.on_condition {
28463 self.write_space();
28464 self.generate_expression(on_condition)?;
28465 }
28466 self.write(")");
28467 Ok(())
28468 }
28469
28470 fn generate_json_cast(&mut self, e: &JSONCast) -> Result<()> {
28471 self.generate_expression(&e.this)?;
28472 self.write(".:");
28473 self.generate_data_type(&e.to)?;
28474 Ok(())
28475 }
28476
28477 fn generate_json_extract_array(&mut self, e: &JSONExtractArray) -> Result<()> {
28478 self.write_keyword("JSON_EXTRACT_ARRAY");
28480 self.write("(");
28481 self.generate_expression(&e.this)?;
28482 if let Some(expr) = &e.expression {
28483 self.write(", ");
28484 self.generate_expression(expr)?;
28485 }
28486 self.write(")");
28487 Ok(())
28488 }
28489
28490 fn generate_json_extract_quote(&mut self, e: &JSONExtractQuote) -> Result<()> {
28491 if let Some(option) = &e.option {
28493 self.generate_expression(option)?;
28494 self.write_space();
28495 }
28496 self.write_keyword("QUOTES");
28497 if e.scalar.is_some() {
28498 self.write_keyword(" SCALAR_ONLY");
28499 }
28500 Ok(())
28501 }
28502
28503 fn generate_json_extract_scalar(&mut self, e: &JSONExtractScalar) -> Result<()> {
28504 self.write_keyword("JSON_EXTRACT_SCALAR");
28506 self.write("(");
28507 self.generate_expression(&e.this)?;
28508 self.write(", ");
28509 self.generate_expression(&e.expression)?;
28510 self.write(")");
28511 Ok(())
28512 }
28513
28514 fn generate_json_extract_path(&mut self, e: &JSONExtract) -> Result<()> {
28515 if e.variant_extract.is_some() {
28519 use crate::dialects::DialectType;
28520 if matches!(self.config.dialect, Some(DialectType::Databricks)) {
28521 self.generate_expression(&e.this)?;
28523 self.write(":");
28524 match e.expression.as_ref() {
28527 Expression::Literal(Literal::String(s)) => {
28528 self.write(s);
28529 }
28530 _ => {
28531 self.generate_expression(&e.expression)?;
28533 }
28534 }
28535 } else {
28536 self.write_keyword("GET_PATH");
28538 self.write("(");
28539 self.generate_expression(&e.this)?;
28540 self.write(", ");
28541 self.generate_expression(&e.expression)?;
28542 self.write(")");
28543 }
28544 } else {
28545 self.write_keyword("JSON_EXTRACT");
28546 self.write("(");
28547 self.generate_expression(&e.this)?;
28548 self.write(", ");
28549 self.generate_expression(&e.expression)?;
28550 for expr in &e.expressions {
28551 self.write(", ");
28552 self.generate_expression(expr)?;
28553 }
28554 self.write(")");
28555 }
28556 Ok(())
28557 }
28558
28559 fn generate_json_format(&mut self, e: &JSONFormat) -> Result<()> {
28560 if let Some(this) = &e.this {
28563 self.generate_expression(this)?;
28564 self.write_space();
28565 }
28566 self.write_keyword("FORMAT JSON");
28567 Ok(())
28568 }
28569
28570 fn generate_json_key_value(&mut self, e: &JSONKeyValue) -> Result<()> {
28571 self.generate_expression(&e.this)?;
28573 self.write(": ");
28574 self.generate_expression(&e.expression)?;
28575 Ok(())
28576 }
28577
28578 fn generate_json_keys(&mut self, e: &JSONKeys) -> Result<()> {
28579 self.write_keyword("JSON_KEYS");
28581 self.write("(");
28582 self.generate_expression(&e.this)?;
28583 if let Some(expr) = &e.expression {
28584 self.write(", ");
28585 self.generate_expression(expr)?;
28586 }
28587 for expr in &e.expressions {
28588 self.write(", ");
28589 self.generate_expression(expr)?;
28590 }
28591 self.write(")");
28592 Ok(())
28593 }
28594
28595 fn generate_json_keys_at_depth(&mut self, e: &JSONKeysAtDepth) -> Result<()> {
28596 self.write_keyword("JSON_KEYS");
28598 self.write("(");
28599 self.generate_expression(&e.this)?;
28600 if let Some(expr) = &e.expression {
28601 self.write(", ");
28602 self.generate_expression(expr)?;
28603 }
28604 self.write(")");
28605 Ok(())
28606 }
28607
28608 fn generate_json_path_expr(&mut self, e: &JSONPath) -> Result<()> {
28609 let mut path_str = String::new();
28612 for expr in &e.expressions {
28613 match expr {
28614 Expression::JSONPathRoot(_) => {
28615 path_str.push('$');
28616 }
28617 Expression::JSONPathKey(k) => {
28618 if let Expression::Literal(crate::expressions::Literal::String(s)) =
28620 k.this.as_ref()
28621 {
28622 path_str.push('.');
28623 let needs_quoting = s.chars().any(|c| !c.is_alphanumeric() && c != '_');
28625 if needs_quoting {
28626 path_str.push('"');
28627 path_str.push_str(s);
28628 path_str.push('"');
28629 } else {
28630 path_str.push_str(s);
28631 }
28632 }
28633 }
28634 Expression::JSONPathSubscript(s) => {
28635 if let Expression::Literal(crate::expressions::Literal::Number(n)) =
28637 s.this.as_ref()
28638 {
28639 path_str.push('[');
28640 path_str.push_str(n);
28641 path_str.push(']');
28642 }
28643 }
28644 _ => {
28645 let mut temp_gen = Self::with_config(self.config.clone());
28647 temp_gen.generate_expression(expr)?;
28648 path_str.push_str(&temp_gen.output);
28649 }
28650 }
28651 }
28652 self.write("'");
28654 self.write(&path_str);
28655 self.write("'");
28656 Ok(())
28657 }
28658
28659 fn generate_json_path_filter(&mut self, e: &JSONPathFilter) -> Result<()> {
28660 self.write("?(");
28662 self.generate_expression(&e.this)?;
28663 self.write(")");
28664 Ok(())
28665 }
28666
28667 fn generate_json_path_key(&mut self, e: &JSONPathKey) -> Result<()> {
28668 self.write(".");
28670 self.generate_expression(&e.this)?;
28671 Ok(())
28672 }
28673
28674 fn generate_json_path_recursive(&mut self, e: &JSONPathRecursive) -> Result<()> {
28675 self.write("..");
28677 if let Some(this) = &e.this {
28678 self.generate_expression(this)?;
28679 }
28680 Ok(())
28681 }
28682
28683 fn generate_json_path_root(&mut self) -> Result<()> {
28684 self.write("$");
28686 Ok(())
28687 }
28688
28689 fn generate_json_path_script(&mut self, e: &JSONPathScript) -> Result<()> {
28690 self.write("(");
28692 self.generate_expression(&e.this)?;
28693 self.write(")");
28694 Ok(())
28695 }
28696
28697 fn generate_json_path_selector(&mut self, e: &JSONPathSelector) -> Result<()> {
28698 self.generate_expression(&e.this)?;
28700 Ok(())
28701 }
28702
28703 fn generate_json_path_slice(&mut self, e: &JSONPathSlice) -> Result<()> {
28704 self.write("[");
28706 if let Some(start) = &e.start {
28707 self.generate_expression(start)?;
28708 }
28709 self.write(":");
28710 if let Some(end) = &e.end {
28711 self.generate_expression(end)?;
28712 }
28713 if let Some(step) = &e.step {
28714 self.write(":");
28715 self.generate_expression(step)?;
28716 }
28717 self.write("]");
28718 Ok(())
28719 }
28720
28721 fn generate_json_path_subscript(&mut self, e: &JSONPathSubscript) -> Result<()> {
28722 self.write("[");
28724 self.generate_expression(&e.this)?;
28725 self.write("]");
28726 Ok(())
28727 }
28728
28729 fn generate_json_path_union(&mut self, e: &JSONPathUnion) -> Result<()> {
28730 self.write("[");
28732 for (i, expr) in e.expressions.iter().enumerate() {
28733 if i > 0 {
28734 self.write(", ");
28735 }
28736 self.generate_expression(expr)?;
28737 }
28738 self.write("]");
28739 Ok(())
28740 }
28741
28742 fn generate_json_remove(&mut self, e: &JSONRemove) -> Result<()> {
28743 self.write_keyword("JSON_REMOVE");
28745 self.write("(");
28746 self.generate_expression(&e.this)?;
28747 for expr in &e.expressions {
28748 self.write(", ");
28749 self.generate_expression(expr)?;
28750 }
28751 self.write(")");
28752 Ok(())
28753 }
28754
28755 fn generate_json_schema(&mut self, e: &JSONSchema) -> Result<()> {
28756 self.write_keyword("COLUMNS");
28759 self.write("(");
28760
28761 if self.config.pretty && !e.expressions.is_empty() {
28762 let mut expr_strings: Vec<String> = Vec::with_capacity(e.expressions.len());
28764 for expr in &e.expressions {
28765 let mut temp_gen = Generator::with_config(self.config.clone());
28766 temp_gen.generate_expression(expr)?;
28767 expr_strings.push(temp_gen.output);
28768 }
28769
28770 if self.too_wide(&expr_strings) {
28772 self.write_newline();
28774 self.indent_level += 1;
28775 for (i, expr_str) in expr_strings.iter().enumerate() {
28776 if i > 0 {
28777 self.write(",");
28778 self.write_newline();
28779 }
28780 self.write_indent();
28781 self.write(expr_str);
28782 }
28783 self.write_newline();
28784 self.indent_level -= 1;
28785 self.write_indent();
28786 } else {
28787 for (i, expr_str) in expr_strings.iter().enumerate() {
28789 if i > 0 {
28790 self.write(", ");
28791 }
28792 self.write(expr_str);
28793 }
28794 }
28795 } else {
28796 for (i, expr) in e.expressions.iter().enumerate() {
28798 if i > 0 {
28799 self.write(", ");
28800 }
28801 self.generate_expression(expr)?;
28802 }
28803 }
28804 self.write(")");
28805 Ok(())
28806 }
28807
28808 fn generate_json_set(&mut self, e: &JSONSet) -> Result<()> {
28809 self.write_keyword("JSON_SET");
28811 self.write("(");
28812 self.generate_expression(&e.this)?;
28813 for expr in &e.expressions {
28814 self.write(", ");
28815 self.generate_expression(expr)?;
28816 }
28817 self.write(")");
28818 Ok(())
28819 }
28820
28821 fn generate_json_strip_nulls(&mut self, e: &JSONStripNulls) -> Result<()> {
28822 self.write_keyword("JSON_STRIP_NULLS");
28824 self.write("(");
28825 self.generate_expression(&e.this)?;
28826 if let Some(expr) = &e.expression {
28827 self.write(", ");
28828 self.generate_expression(expr)?;
28829 }
28830 self.write(")");
28831 Ok(())
28832 }
28833
28834 fn generate_json_table(&mut self, e: &JSONTable) -> Result<()> {
28835 self.write_keyword("JSON_TABLE");
28837 self.write("(");
28838 self.generate_expression(&e.this)?;
28839 if let Some(path) = &e.path {
28840 self.write(", ");
28841 self.generate_expression(path)?;
28842 }
28843 if let Some(error_handling) = &e.error_handling {
28844 self.write_space();
28845 self.generate_expression(error_handling)?;
28846 }
28847 if let Some(empty_handling) = &e.empty_handling {
28848 self.write_space();
28849 self.generate_expression(empty_handling)?;
28850 }
28851 if let Some(schema) = &e.schema {
28852 self.write_space();
28853 self.generate_expression(schema)?;
28854 }
28855 self.write(")");
28856 Ok(())
28857 }
28858
28859 fn generate_json_type(&mut self, e: &JSONType) -> Result<()> {
28860 self.write_keyword("JSON_TYPE");
28862 self.write("(");
28863 self.generate_expression(&e.this)?;
28864 self.write(")");
28865 Ok(())
28866 }
28867
28868 fn generate_json_value(&mut self, e: &JSONValue) -> Result<()> {
28869 self.write_keyword("JSON_VALUE");
28871 self.write("(");
28872 self.generate_expression(&e.this)?;
28873 if let Some(path) = &e.path {
28874 self.write(", ");
28875 self.generate_expression(path)?;
28876 }
28877 if let Some(returning) = &e.returning {
28878 self.write_space();
28879 self.write_keyword("RETURNING");
28880 self.write_space();
28881 self.generate_expression(returning)?;
28882 }
28883 if let Some(on_condition) = &e.on_condition {
28884 self.write_space();
28885 self.generate_expression(on_condition)?;
28886 }
28887 self.write(")");
28888 Ok(())
28889 }
28890
28891 fn generate_json_value_array(&mut self, e: &JSONValueArray) -> Result<()> {
28892 self.write_keyword("JSON_VALUE_ARRAY");
28894 self.write("(");
28895 self.generate_expression(&e.this)?;
28896 self.write(")");
28897 Ok(())
28898 }
28899
28900 fn generate_jarowinkler_similarity(&mut self, e: &JarowinklerSimilarity) -> Result<()> {
28901 self.write_keyword("JAROWINKLER_SIMILARITY");
28903 self.write("(");
28904 self.generate_expression(&e.this)?;
28905 self.write(", ");
28906 self.generate_expression(&e.expression)?;
28907 self.write(")");
28908 Ok(())
28909 }
28910
28911 fn generate_join_hint(&mut self, e: &JoinHint) -> Result<()> {
28912 self.generate_expression(&e.this)?;
28914 self.write("(");
28915 for (i, expr) in e.expressions.iter().enumerate() {
28916 if i > 0 {
28917 self.write(", ");
28918 }
28919 self.generate_expression(expr)?;
28920 }
28921 self.write(")");
28922 Ok(())
28923 }
28924
28925 fn generate_journal_property(&mut self, e: &JournalProperty) -> Result<()> {
28926 if e.no.is_some() {
28928 self.write_keyword("NO ");
28929 }
28930 if let Some(local) = &e.local {
28931 self.generate_expression(local)?;
28932 self.write_space();
28933 }
28934 if e.dual.is_some() {
28935 self.write_keyword("DUAL ");
28936 }
28937 if e.before.is_some() {
28938 self.write_keyword("BEFORE ");
28939 }
28940 if e.after.is_some() {
28941 self.write_keyword("AFTER ");
28942 }
28943 self.write_keyword("JOURNAL");
28944 Ok(())
28945 }
28946
28947 fn generate_language_property(&mut self, e: &LanguageProperty) -> Result<()> {
28948 self.write_keyword("LANGUAGE");
28950 self.write_space();
28951 self.generate_expression(&e.this)?;
28952 Ok(())
28953 }
28954
28955 fn generate_lateral(&mut self, e: &Lateral) -> Result<()> {
28956 if e.view.is_some() {
28958 self.write_keyword("LATERAL VIEW");
28960 if e.outer.is_some() {
28961 self.write_space();
28962 self.write_keyword("OUTER");
28963 }
28964 self.write_space();
28965 self.generate_expression(&e.this)?;
28966 if let Some(alias) = &e.alias {
28967 self.write_space();
28968 self.write(alias);
28969 }
28970 } else {
28971 self.write_keyword("LATERAL");
28973 self.write_space();
28974 self.generate_expression(&e.this)?;
28975 if e.ordinality.is_some() {
28976 self.write_space();
28977 self.write_keyword("WITH ORDINALITY");
28978 }
28979 if let Some(alias) = &e.alias {
28980 self.write_space();
28981 self.write_keyword("AS");
28982 self.write_space();
28983 self.write(alias);
28984 if !e.column_aliases.is_empty() {
28985 self.write("(");
28986 for (i, col) in e.column_aliases.iter().enumerate() {
28987 if i > 0 {
28988 self.write(", ");
28989 }
28990 self.write(col);
28991 }
28992 self.write(")");
28993 }
28994 }
28995 }
28996 Ok(())
28997 }
28998
28999 fn generate_like_property(&mut self, e: &LikeProperty) -> Result<()> {
29000 self.write_keyword("LIKE");
29002 self.write_space();
29003 self.generate_expression(&e.this)?;
29004 for expr in &e.expressions {
29005 self.write_space();
29006 self.generate_expression(expr)?;
29007 }
29008 Ok(())
29009 }
29010
29011 fn generate_limit(&mut self, e: &Limit) -> Result<()> {
29012 self.write_keyword("LIMIT");
29013 self.write_space();
29014 self.write_limit_expr(&e.this)?;
29015 if e.percent {
29016 self.write_space();
29017 self.write_keyword("PERCENT");
29018 }
29019 for comment in &e.comments {
29021 self.write(" ");
29022 self.write_formatted_comment(comment);
29023 }
29024 Ok(())
29025 }
29026
29027 fn generate_limit_options(&mut self, e: &LimitOptions) -> Result<()> {
29028 if e.percent.is_some() {
29030 self.write_keyword(" PERCENT");
29031 }
29032 if e.rows.is_some() {
29033 self.write_keyword(" ROWS");
29034 }
29035 if e.with_ties.is_some() {
29036 self.write_keyword(" WITH TIES");
29037 } else if e.rows.is_some() {
29038 self.write_keyword(" ONLY");
29039 }
29040 Ok(())
29041 }
29042
29043 fn generate_list(&mut self, e: &List) -> Result<()> {
29044 use crate::dialects::DialectType;
29045 let is_materialize = matches!(self.config.dialect, Some(DialectType::Materialize));
29046
29047 if e.expressions.len() == 1 {
29049 if let Expression::Select(_) = &e.expressions[0] {
29050 self.write_keyword("LIST");
29051 self.write("(");
29052 self.generate_expression(&e.expressions[0])?;
29053 self.write(")");
29054 return Ok(());
29055 }
29056 }
29057
29058 if is_materialize {
29060 self.write_keyword("LIST");
29061 self.write("[");
29062 for (i, expr) in e.expressions.iter().enumerate() {
29063 if i > 0 {
29064 self.write(", ");
29065 }
29066 self.generate_expression(expr)?;
29067 }
29068 self.write("]");
29069 } else {
29070 self.write_keyword("LIST");
29072 self.write("(");
29073 for (i, expr) in e.expressions.iter().enumerate() {
29074 if i > 0 {
29075 self.write(", ");
29076 }
29077 self.generate_expression(expr)?;
29078 }
29079 self.write(")");
29080 }
29081 Ok(())
29082 }
29083
29084 fn generate_tomap(&mut self, e: &ToMap) -> Result<()> {
29085 if let Expression::Select(_) = &*e.this {
29087 self.write_keyword("MAP");
29088 self.write("(");
29089 self.generate_expression(&e.this)?;
29090 self.write(")");
29091 return Ok(());
29092 }
29093
29094 let is_duckdb = matches!(self.config.dialect, Some(DialectType::DuckDB));
29095
29096 self.write_keyword("MAP");
29098 if is_duckdb {
29099 self.write(" {");
29100 } else {
29101 self.write("[");
29102 }
29103 if let Expression::Struct(s) = &*e.this {
29104 for (i, (_, expr)) in s.fields.iter().enumerate() {
29105 if i > 0 {
29106 self.write(", ");
29107 }
29108 if let Expression::PropertyEQ(op) = expr {
29109 self.generate_expression(&op.left)?;
29110 if is_duckdb {
29111 self.write(": ");
29112 } else {
29113 self.write(" => ");
29114 }
29115 self.generate_expression(&op.right)?;
29116 } else {
29117 self.generate_expression(expr)?;
29118 }
29119 }
29120 }
29121 if is_duckdb {
29122 self.write("}");
29123 } else {
29124 self.write("]");
29125 }
29126 Ok(())
29127 }
29128
29129 fn generate_localtime(&mut self, e: &Localtime) -> Result<()> {
29130 self.write_keyword("LOCALTIME");
29132 if let Some(precision) = &e.this {
29133 self.write("(");
29134 self.generate_expression(precision)?;
29135 self.write(")");
29136 }
29137 Ok(())
29138 }
29139
29140 fn generate_localtimestamp(&mut self, e: &Localtimestamp) -> Result<()> {
29141 self.write_keyword("LOCALTIMESTAMP");
29143 if let Some(precision) = &e.this {
29144 self.write("(");
29145 self.generate_expression(precision)?;
29146 self.write(")");
29147 }
29148 Ok(())
29149 }
29150
29151 fn generate_location_property(&mut self, e: &LocationProperty) -> Result<()> {
29152 self.write_keyword("LOCATION");
29154 self.write_space();
29155 self.generate_expression(&e.this)?;
29156 Ok(())
29157 }
29158
29159 fn generate_lock(&mut self, e: &Lock) -> Result<()> {
29160 if e.update.is_some() {
29162 if e.key.is_some() {
29163 self.write_keyword("FOR NO KEY UPDATE");
29164 } else {
29165 self.write_keyword("FOR UPDATE");
29166 }
29167 } else {
29168 if e.key.is_some() {
29169 self.write_keyword("FOR KEY SHARE");
29170 } else {
29171 self.write_keyword("FOR SHARE");
29172 }
29173 }
29174 if !e.expressions.is_empty() {
29175 self.write_keyword(" OF ");
29176 for (i, expr) in e.expressions.iter().enumerate() {
29177 if i > 0 {
29178 self.write(", ");
29179 }
29180 self.generate_expression(expr)?;
29181 }
29182 }
29183 if let Some(wait) = &e.wait {
29188 match wait.as_ref() {
29189 Expression::Boolean(b) => {
29190 if b.value {
29191 self.write_keyword(" NOWAIT");
29192 } else {
29193 self.write_keyword(" SKIP LOCKED");
29194 }
29195 }
29196 _ => {
29197 self.write_keyword(" WAIT ");
29199 self.generate_expression(wait)?;
29200 }
29201 }
29202 }
29203 Ok(())
29204 }
29205
29206 fn generate_lock_property(&mut self, e: &LockProperty) -> Result<()> {
29207 self.write_keyword("LOCK");
29209 self.write_space();
29210 self.generate_expression(&e.this)?;
29211 Ok(())
29212 }
29213
29214 fn generate_locking_property(&mut self, e: &LockingProperty) -> Result<()> {
29215 self.write_keyword("LOCKING");
29217 self.write_space();
29218 self.write(&e.kind);
29219 if let Some(this) = &e.this {
29220 self.write_space();
29221 self.generate_expression(this)?;
29222 }
29223 if let Some(for_or_in) = &e.for_or_in {
29224 self.write_space();
29225 self.generate_expression(for_or_in)?;
29226 }
29227 if let Some(lock_type) = &e.lock_type {
29228 self.write_space();
29229 self.generate_expression(lock_type)?;
29230 }
29231 if e.override_.is_some() {
29232 self.write_keyword(" OVERRIDE");
29233 }
29234 Ok(())
29235 }
29236
29237 fn generate_locking_statement(&mut self, e: &LockingStatement) -> Result<()> {
29238 self.generate_expression(&e.this)?;
29240 self.write_space();
29241 self.generate_expression(&e.expression)?;
29242 Ok(())
29243 }
29244
29245 fn generate_log_property(&mut self, e: &LogProperty) -> Result<()> {
29246 if e.no.is_some() {
29248 self.write_keyword("NO ");
29249 }
29250 self.write_keyword("LOG");
29251 Ok(())
29252 }
29253
29254 fn generate_md5_digest(&mut self, e: &MD5Digest) -> Result<()> {
29255 self.write_keyword("MD5");
29257 self.write("(");
29258 self.generate_expression(&e.this)?;
29259 for expr in &e.expressions {
29260 self.write(", ");
29261 self.generate_expression(expr)?;
29262 }
29263 self.write(")");
29264 Ok(())
29265 }
29266
29267 fn generate_ml_forecast(&mut self, e: &MLForecast) -> Result<()> {
29268 self.write_keyword("ML.FORECAST");
29270 self.write("(");
29271 self.generate_expression(&e.this)?;
29272 if let Some(expression) = &e.expression {
29273 self.write(", ");
29274 self.generate_expression(expression)?;
29275 }
29276 if let Some(params) = &e.params_struct {
29277 self.write(", ");
29278 self.generate_expression(params)?;
29279 }
29280 self.write(")");
29281 Ok(())
29282 }
29283
29284 fn generate_ml_translate(&mut self, e: &MLTranslate) -> Result<()> {
29285 self.write_keyword("ML.TRANSLATE");
29287 self.write("(");
29288 self.generate_expression(&e.this)?;
29289 self.write(", ");
29290 self.generate_expression(&e.expression)?;
29291 if let Some(params) = &e.params_struct {
29292 self.write(", ");
29293 self.generate_expression(params)?;
29294 }
29295 self.write(")");
29296 Ok(())
29297 }
29298
29299 fn generate_make_interval(&mut self, e: &MakeInterval) -> Result<()> {
29300 self.write_keyword("MAKE_INTERVAL");
29302 self.write("(");
29303 let mut first = true;
29304 if let Some(year) = &e.year {
29305 self.write("years => ");
29306 self.generate_expression(year)?;
29307 first = false;
29308 }
29309 if let Some(month) = &e.month {
29310 if !first {
29311 self.write(", ");
29312 }
29313 self.write("months => ");
29314 self.generate_expression(month)?;
29315 first = false;
29316 }
29317 if let Some(week) = &e.week {
29318 if !first {
29319 self.write(", ");
29320 }
29321 self.write("weeks => ");
29322 self.generate_expression(week)?;
29323 first = false;
29324 }
29325 if let Some(day) = &e.day {
29326 if !first {
29327 self.write(", ");
29328 }
29329 self.write("days => ");
29330 self.generate_expression(day)?;
29331 first = false;
29332 }
29333 if let Some(hour) = &e.hour {
29334 if !first {
29335 self.write(", ");
29336 }
29337 self.write("hours => ");
29338 self.generate_expression(hour)?;
29339 first = false;
29340 }
29341 if let Some(minute) = &e.minute {
29342 if !first {
29343 self.write(", ");
29344 }
29345 self.write("mins => ");
29346 self.generate_expression(minute)?;
29347 first = false;
29348 }
29349 if let Some(second) = &e.second {
29350 if !first {
29351 self.write(", ");
29352 }
29353 self.write("secs => ");
29354 self.generate_expression(second)?;
29355 }
29356 self.write(")");
29357 Ok(())
29358 }
29359
29360 fn generate_manhattan_distance(&mut self, e: &ManhattanDistance) -> Result<()> {
29361 self.write_keyword("MANHATTAN_DISTANCE");
29363 self.write("(");
29364 self.generate_expression(&e.this)?;
29365 self.write(", ");
29366 self.generate_expression(&e.expression)?;
29367 self.write(")");
29368 Ok(())
29369 }
29370
29371 fn generate_map(&mut self, e: &Map) -> Result<()> {
29372 self.write_keyword("MAP");
29374 self.write("(");
29375 for (i, (key, value)) in e.keys.iter().zip(e.values.iter()).enumerate() {
29376 if i > 0 {
29377 self.write(", ");
29378 }
29379 self.generate_expression(key)?;
29380 self.write(", ");
29381 self.generate_expression(value)?;
29382 }
29383 self.write(")");
29384 Ok(())
29385 }
29386
29387 fn generate_map_cat(&mut self, e: &MapCat) -> Result<()> {
29388 self.write_keyword("MAP_CAT");
29390 self.write("(");
29391 self.generate_expression(&e.this)?;
29392 self.write(", ");
29393 self.generate_expression(&e.expression)?;
29394 self.write(")");
29395 Ok(())
29396 }
29397
29398 fn generate_map_delete(&mut self, e: &MapDelete) -> Result<()> {
29399 self.write_keyword("MAP_DELETE");
29401 self.write("(");
29402 self.generate_expression(&e.this)?;
29403 for expr in &e.expressions {
29404 self.write(", ");
29405 self.generate_expression(expr)?;
29406 }
29407 self.write(")");
29408 Ok(())
29409 }
29410
29411 fn generate_map_insert(&mut self, e: &MapInsert) -> Result<()> {
29412 self.write_keyword("MAP_INSERT");
29414 self.write("(");
29415 self.generate_expression(&e.this)?;
29416 if let Some(key) = &e.key {
29417 self.write(", ");
29418 self.generate_expression(key)?;
29419 }
29420 if let Some(value) = &e.value {
29421 self.write(", ");
29422 self.generate_expression(value)?;
29423 }
29424 if let Some(update_flag) = &e.update_flag {
29425 self.write(", ");
29426 self.generate_expression(update_flag)?;
29427 }
29428 self.write(")");
29429 Ok(())
29430 }
29431
29432 fn generate_map_pick(&mut self, e: &MapPick) -> Result<()> {
29433 self.write_keyword("MAP_PICK");
29435 self.write("(");
29436 self.generate_expression(&e.this)?;
29437 for expr in &e.expressions {
29438 self.write(", ");
29439 self.generate_expression(expr)?;
29440 }
29441 self.write(")");
29442 Ok(())
29443 }
29444
29445 fn generate_masking_policy_column_constraint(
29446 &mut self,
29447 e: &MaskingPolicyColumnConstraint,
29448 ) -> Result<()> {
29449 self.write_keyword("MASKING POLICY");
29451 self.write_space();
29452 self.generate_expression(&e.this)?;
29453 if !e.expressions.is_empty() {
29454 self.write_keyword(" USING");
29455 self.write(" (");
29456 for (i, expr) in e.expressions.iter().enumerate() {
29457 if i > 0 {
29458 self.write(", ");
29459 }
29460 self.generate_expression(expr)?;
29461 }
29462 self.write(")");
29463 }
29464 Ok(())
29465 }
29466
29467 fn generate_match_against(&mut self, e: &MatchAgainst) -> Result<()> {
29468 if matches!(
29469 self.config.dialect,
29470 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
29471 ) {
29472 if e.expressions.len() > 1 {
29473 self.write("(");
29474 }
29475 for (i, expr) in e.expressions.iter().enumerate() {
29476 if i > 0 {
29477 self.write_keyword(" OR ");
29478 }
29479 self.generate_expression(expr)?;
29480 self.write_space();
29481 self.write("@@");
29482 self.write_space();
29483 self.generate_expression(&e.this)?;
29484 }
29485 if e.expressions.len() > 1 {
29486 self.write(")");
29487 }
29488 return Ok(());
29489 }
29490
29491 self.write_keyword("MATCH");
29493 self.write("(");
29494 for (i, expr) in e.expressions.iter().enumerate() {
29495 if i > 0 {
29496 self.write(", ");
29497 }
29498 self.generate_expression(expr)?;
29499 }
29500 self.write(")");
29501 self.write_keyword(" AGAINST");
29502 self.write("(");
29503 self.generate_expression(&e.this)?;
29504 if let Some(modifier) = &e.modifier {
29505 self.write_space();
29506 self.generate_expression(modifier)?;
29507 }
29508 self.write(")");
29509 Ok(())
29510 }
29511
29512 fn generate_match_recognize_measure(&mut self, e: &MatchRecognizeMeasure) -> Result<()> {
29513 if let Some(window_frame) = &e.window_frame {
29515 self.write(&format!("{:?}", window_frame).to_uppercase());
29516 self.write_space();
29517 }
29518 self.generate_expression(&e.this)?;
29519 Ok(())
29520 }
29521
29522 fn generate_materialized_property(&mut self, e: &MaterializedProperty) -> Result<()> {
29523 self.write_keyword("MATERIALIZED");
29525 if let Some(this) = &e.this {
29526 self.write_space();
29527 self.generate_expression(this)?;
29528 }
29529 Ok(())
29530 }
29531
29532 fn generate_merge(&mut self, e: &Merge) -> Result<()> {
29533 if let Some(with_) = &e.with_ {
29536 self.generate_expression(with_)?;
29537 self.write_space();
29538 }
29539 self.write_keyword("MERGE INTO");
29540 self.write_space();
29541 self.generate_expression(&e.this)?;
29542
29543 if self.config.pretty {
29545 self.write_newline();
29546 self.write_indent();
29547 } else {
29548 self.write_space();
29549 }
29550 self.write_keyword("USING");
29551 self.write_space();
29552 self.generate_expression(&e.using)?;
29553
29554 if let Some(on) = &e.on {
29556 if self.config.pretty {
29557 self.write_newline();
29558 self.write_indent();
29559 } else {
29560 self.write_space();
29561 }
29562 self.write_keyword("ON");
29563 self.write_space();
29564 self.generate_expression(on)?;
29565 }
29566 if let Some(using_cond) = &e.using_cond {
29568 self.write_space();
29569 self.write_keyword("USING");
29570 self.write_space();
29571 self.write("(");
29572 if let Expression::Tuple(tuple) = using_cond.as_ref() {
29574 for (i, col) in tuple.expressions.iter().enumerate() {
29575 if i > 0 {
29576 self.write(", ");
29577 }
29578 self.generate_expression(col)?;
29579 }
29580 } else {
29581 self.generate_expression(using_cond)?;
29582 }
29583 self.write(")");
29584 }
29585 let saved_merge_strip = std::mem::take(&mut self.merge_strip_qualifiers);
29587 if matches!(
29588 self.config.dialect,
29589 Some(crate::DialectType::PostgreSQL)
29590 | Some(crate::DialectType::Redshift)
29591 | Some(crate::DialectType::Trino)
29592 | Some(crate::DialectType::Presto)
29593 | Some(crate::DialectType::Athena)
29594 ) {
29595 let mut names = Vec::new();
29596 match e.this.as_ref() {
29597 Expression::Alias(a) => {
29598 if let Expression::Table(t) = &a.this {
29600 names.push(t.name.name.clone());
29601 } else if let Expression::Identifier(id) = &a.this {
29602 names.push(id.name.clone());
29603 }
29604 names.push(a.alias.name.clone());
29605 }
29606 Expression::Table(t) => {
29607 names.push(t.name.name.clone());
29608 }
29609 Expression::Identifier(id) => {
29610 names.push(id.name.clone());
29611 }
29612 _ => {}
29613 }
29614 self.merge_strip_qualifiers = names;
29615 }
29616
29617 if let Some(whens) = &e.whens {
29619 if self.config.pretty {
29620 self.write_newline();
29621 self.write_indent();
29622 } else {
29623 self.write_space();
29624 }
29625 self.generate_expression(whens)?;
29626 }
29627
29628 self.merge_strip_qualifiers = saved_merge_strip;
29630
29631 if let Some(returning) = &e.returning {
29633 if self.config.pretty {
29634 self.write_newline();
29635 self.write_indent();
29636 } else {
29637 self.write_space();
29638 }
29639 self.generate_expression(returning)?;
29640 }
29641 Ok(())
29642 }
29643
29644 fn generate_merge_block_ratio_property(&mut self, e: &MergeBlockRatioProperty) -> Result<()> {
29645 if e.no.is_some() {
29647 self.write_keyword("NO MERGEBLOCKRATIO");
29648 } else if e.default.is_some() {
29649 self.write_keyword("DEFAULT MERGEBLOCKRATIO");
29650 } else {
29651 self.write_keyword("MERGEBLOCKRATIO");
29652 self.write("=");
29653 if let Some(this) = &e.this {
29654 self.generate_expression(this)?;
29655 }
29656 if e.percent.is_some() {
29657 self.write_keyword(" PERCENT");
29658 }
29659 }
29660 Ok(())
29661 }
29662
29663 fn generate_merge_tree_ttl(&mut self, e: &MergeTreeTTL) -> Result<()> {
29664 self.write_keyword("TTL");
29666 let pretty_clickhouse = self.config.pretty
29667 && matches!(
29668 self.config.dialect,
29669 Some(crate::dialects::DialectType::ClickHouse)
29670 );
29671
29672 if pretty_clickhouse {
29673 self.write_newline();
29674 self.indent_level += 1;
29675 for (i, expr) in e.expressions.iter().enumerate() {
29676 if i > 0 {
29677 self.write(",");
29678 self.write_newline();
29679 }
29680 self.write_indent();
29681 self.generate_expression(expr)?;
29682 }
29683 self.indent_level -= 1;
29684 } else {
29685 self.write_space();
29686 for (i, expr) in e.expressions.iter().enumerate() {
29687 if i > 0 {
29688 self.write(", ");
29689 }
29690 self.generate_expression(expr)?;
29691 }
29692 }
29693
29694 if let Some(where_) = &e.where_ {
29695 if pretty_clickhouse {
29696 self.write_newline();
29697 if let Expression::Where(w) = where_.as_ref() {
29698 self.write_indent();
29699 self.write_keyword("WHERE");
29700 self.write_newline();
29701 self.indent_level += 1;
29702 self.write_indent();
29703 self.generate_expression(&w.this)?;
29704 self.indent_level -= 1;
29705 } else {
29706 self.write_indent();
29707 self.generate_expression(where_)?;
29708 }
29709 } else {
29710 self.write_space();
29711 self.generate_expression(where_)?;
29712 }
29713 }
29714 if let Some(group) = &e.group {
29715 if pretty_clickhouse {
29716 self.write_newline();
29717 if let Expression::Group(g) = group.as_ref() {
29718 self.write_indent();
29719 self.write_keyword("GROUP BY");
29720 self.write_newline();
29721 self.indent_level += 1;
29722 for (i, expr) in g.expressions.iter().enumerate() {
29723 if i > 0 {
29724 self.write(",");
29725 self.write_newline();
29726 }
29727 self.write_indent();
29728 self.generate_expression(expr)?;
29729 }
29730 self.indent_level -= 1;
29731 } else {
29732 self.write_indent();
29733 self.generate_expression(group)?;
29734 }
29735 } else {
29736 self.write_space();
29737 self.generate_expression(group)?;
29738 }
29739 }
29740 if let Some(aggregates) = &e.aggregates {
29741 if pretty_clickhouse {
29742 self.write_newline();
29743 self.write_indent();
29744 self.write_keyword("SET");
29745 self.write_newline();
29746 self.indent_level += 1;
29747 if let Expression::Tuple(t) = aggregates.as_ref() {
29748 for (i, agg) in t.expressions.iter().enumerate() {
29749 if i > 0 {
29750 self.write(",");
29751 self.write_newline();
29752 }
29753 self.write_indent();
29754 self.generate_expression(agg)?;
29755 }
29756 } else {
29757 self.write_indent();
29758 self.generate_expression(aggregates)?;
29759 }
29760 self.indent_level -= 1;
29761 } else {
29762 self.write_space();
29763 self.write_keyword("SET");
29764 self.write_space();
29765 self.generate_expression(aggregates)?;
29766 }
29767 }
29768 Ok(())
29769 }
29770
29771 fn generate_merge_tree_ttl_action(&mut self, e: &MergeTreeTTLAction) -> Result<()> {
29772 self.generate_expression(&e.this)?;
29774 if e.delete.is_some() {
29775 self.write_keyword(" DELETE");
29776 }
29777 if let Some(recompress) = &e.recompress {
29778 self.write_keyword(" RECOMPRESS ");
29779 self.generate_expression(recompress)?;
29780 }
29781 if let Some(to_disk) = &e.to_disk {
29782 self.write_keyword(" TO DISK ");
29783 self.generate_expression(to_disk)?;
29784 }
29785 if let Some(to_volume) = &e.to_volume {
29786 self.write_keyword(" TO VOLUME ");
29787 self.generate_expression(to_volume)?;
29788 }
29789 Ok(())
29790 }
29791
29792 fn generate_minhash(&mut self, e: &Minhash) -> Result<()> {
29793 self.write_keyword("MINHASH");
29795 self.write("(");
29796 self.generate_expression(&e.this)?;
29797 for expr in &e.expressions {
29798 self.write(", ");
29799 self.generate_expression(expr)?;
29800 }
29801 self.write(")");
29802 Ok(())
29803 }
29804
29805 fn generate_model_attribute(&mut self, e: &ModelAttribute) -> Result<()> {
29806 self.generate_expression(&e.this)?;
29808 self.write("!");
29809 self.generate_expression(&e.expression)?;
29810 Ok(())
29811 }
29812
29813 fn generate_monthname(&mut self, e: &Monthname) -> Result<()> {
29814 self.write_keyword("MONTHNAME");
29816 self.write("(");
29817 self.generate_expression(&e.this)?;
29818 self.write(")");
29819 Ok(())
29820 }
29821
29822 fn generate_multitable_inserts(&mut self, e: &MultitableInserts) -> Result<()> {
29823 for comment in &e.leading_comments {
29825 self.write_formatted_comment(comment);
29826 if self.config.pretty {
29827 self.write_newline();
29828 self.write_indent();
29829 } else {
29830 self.write_space();
29831 }
29832 }
29833 self.write_keyword("INSERT");
29835 self.write_space();
29836 self.write(&e.kind);
29837 if self.config.pretty {
29838 self.indent_level += 1;
29839 for expr in &e.expressions {
29840 self.write_newline();
29841 self.write_indent();
29842 self.generate_expression(expr)?;
29843 }
29844 self.indent_level -= 1;
29845 } else {
29846 for expr in &e.expressions {
29847 self.write_space();
29848 self.generate_expression(expr)?;
29849 }
29850 }
29851 if let Some(source) = &e.source {
29852 if self.config.pretty {
29853 self.write_newline();
29854 self.write_indent();
29855 } else {
29856 self.write_space();
29857 }
29858 self.generate_expression(source)?;
29859 }
29860 Ok(())
29861 }
29862
29863 fn generate_next_value_for(&mut self, e: &NextValueFor) -> Result<()> {
29864 self.write_keyword("NEXT VALUE FOR");
29866 self.write_space();
29867 self.generate_expression(&e.this)?;
29868 if let Some(order) = &e.order {
29869 self.write_space();
29870 self.write_keyword("OVER");
29871 self.write(" (");
29872 self.generate_expression(order)?;
29873 self.write(")");
29874 }
29875 Ok(())
29876 }
29877
29878 fn generate_normal(&mut self, e: &Normal) -> Result<()> {
29879 self.write_keyword("NORMAL");
29881 self.write("(");
29882 self.generate_expression(&e.this)?;
29883 if let Some(stddev) = &e.stddev {
29884 self.write(", ");
29885 self.generate_expression(stddev)?;
29886 }
29887 if let Some(gen) = &e.gen {
29888 self.write(", ");
29889 self.generate_expression(gen)?;
29890 }
29891 self.write(")");
29892 Ok(())
29893 }
29894
29895 fn generate_normalize(&mut self, e: &Normalize) -> Result<()> {
29896 if e.is_casefold.is_some() {
29898 self.write_keyword("NORMALIZE_AND_CASEFOLD");
29899 } else {
29900 self.write_keyword("NORMALIZE");
29901 }
29902 self.write("(");
29903 self.generate_expression(&e.this)?;
29904 if let Some(form) = &e.form {
29905 self.write(", ");
29906 self.generate_expression(form)?;
29907 }
29908 self.write(")");
29909 Ok(())
29910 }
29911
29912 fn generate_not_null_column_constraint(&mut self, e: &NotNullColumnConstraint) -> Result<()> {
29913 if e.allow_null.is_none() {
29915 self.write_keyword("NOT ");
29916 }
29917 self.write_keyword("NULL");
29918 Ok(())
29919 }
29920
29921 fn generate_nullif(&mut self, e: &Nullif) -> Result<()> {
29922 self.write_keyword("NULLIF");
29924 self.write("(");
29925 self.generate_expression(&e.this)?;
29926 self.write(", ");
29927 self.generate_expression(&e.expression)?;
29928 self.write(")");
29929 Ok(())
29930 }
29931
29932 fn generate_number_to_str(&mut self, e: &NumberToStr) -> Result<()> {
29933 self.write_keyword("FORMAT");
29935 self.write("(");
29936 self.generate_expression(&e.this)?;
29937 self.write(", '");
29938 self.write(&e.format);
29939 self.write("'");
29940 if let Some(culture) = &e.culture {
29941 self.write(", ");
29942 self.generate_expression(culture)?;
29943 }
29944 self.write(")");
29945 Ok(())
29946 }
29947
29948 fn generate_object_agg(&mut self, e: &ObjectAgg) -> Result<()> {
29949 self.write_keyword("OBJECT_AGG");
29951 self.write("(");
29952 self.generate_expression(&e.this)?;
29953 self.write(", ");
29954 self.generate_expression(&e.expression)?;
29955 self.write(")");
29956 Ok(())
29957 }
29958
29959 fn generate_object_identifier(&mut self, e: &ObjectIdentifier) -> Result<()> {
29960 self.generate_expression(&e.this)?;
29962 Ok(())
29963 }
29964
29965 fn generate_object_insert(&mut self, e: &ObjectInsert) -> Result<()> {
29966 self.write_keyword("OBJECT_INSERT");
29968 self.write("(");
29969 self.generate_expression(&e.this)?;
29970 if let Some(key) = &e.key {
29971 self.write(", ");
29972 self.generate_expression(key)?;
29973 }
29974 if let Some(value) = &e.value {
29975 self.write(", ");
29976 self.generate_expression(value)?;
29977 }
29978 if let Some(update_flag) = &e.update_flag {
29979 self.write(", ");
29980 self.generate_expression(update_flag)?;
29981 }
29982 self.write(")");
29983 Ok(())
29984 }
29985
29986 fn generate_offset(&mut self, e: &Offset) -> Result<()> {
29987 self.write_keyword("OFFSET");
29989 self.write_space();
29990 self.generate_expression(&e.this)?;
29991 if e.rows == Some(true)
29993 && matches!(
29994 self.config.dialect,
29995 Some(crate::dialects::DialectType::TSQL)
29996 | Some(crate::dialects::DialectType::Oracle)
29997 )
29998 {
29999 self.write_space();
30000 self.write_keyword("ROWS");
30001 }
30002 Ok(())
30003 }
30004
30005 fn generate_qualify(&mut self, e: &Qualify) -> Result<()> {
30006 self.write_keyword("QUALIFY");
30008 self.write_space();
30009 self.generate_expression(&e.this)?;
30010 Ok(())
30011 }
30012
30013 fn generate_on_cluster(&mut self, e: &OnCluster) -> Result<()> {
30014 self.write_keyword("ON CLUSTER");
30016 self.write_space();
30017 self.generate_expression(&e.this)?;
30018 Ok(())
30019 }
30020
30021 fn generate_on_commit_property(&mut self, e: &OnCommitProperty) -> Result<()> {
30022 self.write_keyword("ON COMMIT");
30024 if e.delete.is_some() {
30025 self.write_keyword(" DELETE ROWS");
30026 } else {
30027 self.write_keyword(" PRESERVE ROWS");
30028 }
30029 Ok(())
30030 }
30031
30032 fn generate_on_condition(&mut self, e: &OnCondition) -> Result<()> {
30033 if let Some(empty) = &e.empty {
30035 self.generate_expression(empty)?;
30036 self.write_keyword(" ON EMPTY");
30037 }
30038 if let Some(error) = &e.error {
30039 if e.empty.is_some() {
30040 self.write_space();
30041 }
30042 self.generate_expression(error)?;
30043 self.write_keyword(" ON ERROR");
30044 }
30045 if let Some(null) = &e.null {
30046 if e.empty.is_some() || e.error.is_some() {
30047 self.write_space();
30048 }
30049 self.generate_expression(null)?;
30050 self.write_keyword(" ON NULL");
30051 }
30052 Ok(())
30053 }
30054
30055 fn generate_on_conflict(&mut self, e: &OnConflict) -> Result<()> {
30056 if matches!(self.config.dialect, Some(DialectType::Materialize)) {
30058 return Ok(());
30059 }
30060 if e.duplicate.is_some() {
30062 self.write_keyword("ON DUPLICATE KEY UPDATE");
30064 for (i, expr) in e.expressions.iter().enumerate() {
30065 if i > 0 {
30066 self.write(",");
30067 }
30068 self.write_space();
30069 self.generate_expression(expr)?;
30070 }
30071 return Ok(());
30072 } else {
30073 self.write_keyword("ON CONFLICT");
30074 }
30075 if let Some(constraint) = &e.constraint {
30076 self.write_keyword(" ON CONSTRAINT ");
30077 self.generate_expression(constraint)?;
30078 }
30079 if let Some(conflict_keys) = &e.conflict_keys {
30080 if let Expression::Tuple(t) = conflict_keys.as_ref() {
30082 self.write("(");
30083 for (i, expr) in t.expressions.iter().enumerate() {
30084 if i > 0 {
30085 self.write(", ");
30086 }
30087 self.generate_expression(expr)?;
30088 }
30089 self.write(")");
30090 } else {
30091 self.write("(");
30092 self.generate_expression(conflict_keys)?;
30093 self.write(")");
30094 }
30095 }
30096 if let Some(index_predicate) = &e.index_predicate {
30097 self.write_keyword(" WHERE ");
30098 self.generate_expression(index_predicate)?;
30099 }
30100 if let Some(action) = &e.action {
30101 if let Expression::Identifier(id) = action.as_ref() {
30103 if id.name == "NOTHING" || id.name.to_uppercase() == "NOTHING" {
30104 self.write_keyword(" DO NOTHING");
30105 } else {
30106 self.write_keyword(" DO ");
30107 self.generate_expression(action)?;
30108 }
30109 } else if let Expression::Tuple(t) = action.as_ref() {
30110 self.write_keyword(" DO UPDATE SET ");
30112 for (i, expr) in t.expressions.iter().enumerate() {
30113 if i > 0 {
30114 self.write(", ");
30115 }
30116 self.generate_expression(expr)?;
30117 }
30118 } else {
30119 self.write_keyword(" DO ");
30120 self.generate_expression(action)?;
30121 }
30122 }
30123 if let Some(where_) = &e.where_ {
30125 self.write_keyword(" WHERE ");
30126 self.generate_expression(where_)?;
30127 }
30128 Ok(())
30129 }
30130
30131 fn generate_on_property(&mut self, e: &OnProperty) -> Result<()> {
30132 self.write_keyword("ON");
30134 self.write_space();
30135 self.generate_expression(&e.this)?;
30136 Ok(())
30137 }
30138
30139 fn generate_opclass(&mut self, e: &Opclass) -> Result<()> {
30140 self.generate_expression(&e.this)?;
30142 self.write_space();
30143 self.generate_expression(&e.expression)?;
30144 Ok(())
30145 }
30146
30147 fn generate_open_json(&mut self, e: &OpenJSON) -> Result<()> {
30148 self.write_keyword("OPENJSON");
30150 self.write("(");
30151 self.generate_expression(&e.this)?;
30152 if let Some(path) = &e.path {
30153 self.write(", ");
30154 self.generate_expression(path)?;
30155 }
30156 self.write(")");
30157 if !e.expressions.is_empty() {
30158 self.write_keyword(" WITH");
30159 if self.config.pretty {
30160 self.write(" (\n");
30161 self.indent_level += 2;
30162 for (i, expr) in e.expressions.iter().enumerate() {
30163 if i > 0 {
30164 self.write(",\n");
30165 }
30166 self.write_indent();
30167 self.generate_expression(expr)?;
30168 }
30169 self.write("\n");
30170 self.indent_level -= 2;
30171 self.write(")");
30172 } else {
30173 self.write(" (");
30174 for (i, expr) in e.expressions.iter().enumerate() {
30175 if i > 0 {
30176 self.write(", ");
30177 }
30178 self.generate_expression(expr)?;
30179 }
30180 self.write(")");
30181 }
30182 }
30183 Ok(())
30184 }
30185
30186 fn generate_open_json_column_def(&mut self, e: &OpenJSONColumnDef) -> Result<()> {
30187 self.generate_expression(&e.this)?;
30189 self.write_space();
30190 if let Some(ref dt) = e.data_type {
30192 self.generate_data_type(dt)?;
30193 } else if !e.kind.is_empty() {
30194 self.write(&e.kind);
30195 }
30196 if let Some(path) = &e.path {
30197 self.write_space();
30198 self.generate_expression(path)?;
30199 }
30200 if e.as_json.is_some() {
30201 self.write_keyword(" AS JSON");
30202 }
30203 Ok(())
30204 }
30205
30206 fn generate_operator(&mut self, e: &Operator) -> Result<()> {
30207 self.generate_expression(&e.this)?;
30209 self.write_space();
30210 if let Some(op) = &e.operator {
30211 self.write_keyword("OPERATOR");
30212 self.write("(");
30213 self.generate_expression(op)?;
30214 self.write(")");
30215 }
30216 for comment in &e.comments {
30218 self.write_space();
30219 self.write_formatted_comment(comment);
30220 }
30221 self.write_space();
30222 self.generate_expression(&e.expression)?;
30223 Ok(())
30224 }
30225
30226 fn generate_order_by(&mut self, e: &OrderBy) -> Result<()> {
30227 self.write_keyword("ORDER BY");
30229 let pretty_clickhouse_single_paren = self.config.pretty
30230 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
30231 && e.expressions.len() == 1
30232 && matches!(e.expressions[0].this, Expression::Paren(ref p) if !matches!(p.this, Expression::Tuple(_)));
30233 let clickhouse_single_tuple = matches!(self.config.dialect, Some(DialectType::ClickHouse))
30234 && e.expressions.len() == 1
30235 && matches!(e.expressions[0].this, Expression::Tuple(_))
30236 && !e.expressions[0].desc
30237 && e.expressions[0].nulls_first.is_none();
30238
30239 if pretty_clickhouse_single_paren {
30240 self.write_space();
30241 if let Expression::Paren(p) = &e.expressions[0].this {
30242 self.write("(");
30243 self.write_newline();
30244 self.indent_level += 1;
30245 self.write_indent();
30246 self.generate_expression(&p.this)?;
30247 self.indent_level -= 1;
30248 self.write_newline();
30249 self.write(")");
30250 }
30251 return Ok(());
30252 }
30253
30254 if clickhouse_single_tuple {
30255 self.write_space();
30256 if let Expression::Tuple(t) = &e.expressions[0].this {
30257 self.write("(");
30258 for (i, expr) in t.expressions.iter().enumerate() {
30259 if i > 0 {
30260 self.write(", ");
30261 }
30262 self.generate_expression(expr)?;
30263 }
30264 self.write(")");
30265 }
30266 return Ok(());
30267 }
30268
30269 self.write_space();
30270 for (i, ordered) in e.expressions.iter().enumerate() {
30271 if i > 0 {
30272 self.write(", ");
30273 }
30274 self.generate_expression(&ordered.this)?;
30275 if ordered.desc {
30276 self.write_space();
30277 self.write_keyword("DESC");
30278 } else if ordered.explicit_asc {
30279 self.write_space();
30280 self.write_keyword("ASC");
30281 }
30282 if let Some(nulls_first) = ordered.nulls_first {
30283 let skip_nulls_last =
30285 !nulls_first && matches!(self.config.dialect, Some(DialectType::Dremio));
30286 if !skip_nulls_last {
30287 self.write_space();
30288 self.write_keyword("NULLS");
30289 self.write_space();
30290 if nulls_first {
30291 self.write_keyword("FIRST");
30292 } else {
30293 self.write_keyword("LAST");
30294 }
30295 }
30296 }
30297 }
30298 Ok(())
30299 }
30300
30301 fn generate_output_model_property(&mut self, e: &OutputModelProperty) -> Result<()> {
30302 self.write_keyword("OUTPUT");
30304 self.write("(");
30305 if self.config.pretty {
30306 self.indent_level += 1;
30307 self.write_newline();
30308 self.write_indent();
30309 self.generate_expression(&e.this)?;
30310 self.indent_level -= 1;
30311 self.write_newline();
30312 } else {
30313 self.generate_expression(&e.this)?;
30314 }
30315 self.write(")");
30316 Ok(())
30317 }
30318
30319 fn generate_overflow_truncate_behavior(&mut self, e: &OverflowTruncateBehavior) -> Result<()> {
30320 self.write_keyword("TRUNCATE");
30322 if let Some(this) = &e.this {
30323 self.write_space();
30324 self.generate_expression(this)?;
30325 }
30326 if e.with_count.is_some() {
30327 self.write_keyword(" WITH COUNT");
30328 } else {
30329 self.write_keyword(" WITHOUT COUNT");
30330 }
30331 Ok(())
30332 }
30333
30334 fn generate_parameterized_agg(&mut self, e: &ParameterizedAgg) -> Result<()> {
30335 self.generate_expression(&e.this)?;
30337 self.write("(");
30338 for (i, expr) in e.expressions.iter().enumerate() {
30339 if i > 0 {
30340 self.write(", ");
30341 }
30342 self.generate_expression(expr)?;
30343 }
30344 self.write(")(");
30345 for (i, param) in e.params.iter().enumerate() {
30346 if i > 0 {
30347 self.write(", ");
30348 }
30349 self.generate_expression(param)?;
30350 }
30351 self.write(")");
30352 Ok(())
30353 }
30354
30355 fn generate_parse_datetime(&mut self, e: &ParseDatetime) -> Result<()> {
30356 self.write_keyword("PARSE_DATETIME");
30358 self.write("(");
30359 if let Some(format) = &e.format {
30360 self.write("'");
30361 self.write(format);
30362 self.write("', ");
30363 }
30364 self.generate_expression(&e.this)?;
30365 if let Some(zone) = &e.zone {
30366 self.write(", ");
30367 self.generate_expression(zone)?;
30368 }
30369 self.write(")");
30370 Ok(())
30371 }
30372
30373 fn generate_parse_ip(&mut self, e: &ParseIp) -> Result<()> {
30374 self.write_keyword("PARSE_IP");
30376 self.write("(");
30377 self.generate_expression(&e.this)?;
30378 if let Some(type_) = &e.type_ {
30379 self.write(", ");
30380 self.generate_expression(type_)?;
30381 }
30382 if let Some(permissive) = &e.permissive {
30383 self.write(", ");
30384 self.generate_expression(permissive)?;
30385 }
30386 self.write(")");
30387 Ok(())
30388 }
30389
30390 fn generate_parse_json(&mut self, e: &ParseJSON) -> Result<()> {
30391 self.write_keyword("PARSE_JSON");
30393 self.write("(");
30394 self.generate_expression(&e.this)?;
30395 if let Some(expression) = &e.expression {
30396 self.write(", ");
30397 self.generate_expression(expression)?;
30398 }
30399 self.write(")");
30400 Ok(())
30401 }
30402
30403 fn generate_parse_time(&mut self, e: &ParseTime) -> Result<()> {
30404 self.write_keyword("PARSE_TIME");
30406 self.write("(");
30407 self.write(&format!("'{}'", e.format));
30408 self.write(", ");
30409 self.generate_expression(&e.this)?;
30410 self.write(")");
30411 Ok(())
30412 }
30413
30414 fn generate_parse_url(&mut self, e: &ParseUrl) -> Result<()> {
30415 self.write_keyword("PARSE_URL");
30417 self.write("(");
30418 self.generate_expression(&e.this)?;
30419 if let Some(part) = &e.part_to_extract {
30420 self.write(", ");
30421 self.generate_expression(part)?;
30422 }
30423 if let Some(key) = &e.key {
30424 self.write(", ");
30425 self.generate_expression(key)?;
30426 }
30427 if let Some(permissive) = &e.permissive {
30428 self.write(", ");
30429 self.generate_expression(permissive)?;
30430 }
30431 self.write(")");
30432 Ok(())
30433 }
30434
30435 fn generate_partition_expr(&mut self, e: &Partition) -> Result<()> {
30436 if e.subpartition {
30438 self.write_keyword("SUBPARTITION");
30439 } else {
30440 self.write_keyword("PARTITION");
30441 }
30442 self.write("(");
30443 for (i, expr) in e.expressions.iter().enumerate() {
30444 if i > 0 {
30445 self.write(", ");
30446 }
30447 self.generate_expression(expr)?;
30448 }
30449 self.write(")");
30450 Ok(())
30451 }
30452
30453 fn generate_partition_bound_spec(&mut self, e: &PartitionBoundSpec) -> Result<()> {
30454 if let Some(this) = &e.this {
30456 if let Some(expression) = &e.expression {
30457 self.write_keyword("WITH");
30459 self.write(" (");
30460 self.write_keyword("MODULUS");
30461 self.write_space();
30462 self.generate_expression(this)?;
30463 self.write(", ");
30464 self.write_keyword("REMAINDER");
30465 self.write_space();
30466 self.generate_expression(expression)?;
30467 self.write(")");
30468 } else {
30469 self.write_keyword("IN");
30471 self.write(" (");
30472 self.generate_partition_bound_values(this)?;
30473 self.write(")");
30474 }
30475 } else if let (Some(from), Some(to)) = (&e.from_expressions, &e.to_expressions) {
30476 self.write_keyword("FROM");
30478 self.write(" (");
30479 self.generate_partition_bound_values(from)?;
30480 self.write(") ");
30481 self.write_keyword("TO");
30482 self.write(" (");
30483 self.generate_partition_bound_values(to)?;
30484 self.write(")");
30485 }
30486 Ok(())
30487 }
30488
30489 fn generate_partition_bound_values(&mut self, expr: &Expression) -> Result<()> {
30492 if let Expression::Tuple(t) = expr {
30493 for (i, e) in t.expressions.iter().enumerate() {
30494 if i > 0 {
30495 self.write(", ");
30496 }
30497 self.generate_expression(e)?;
30498 }
30499 Ok(())
30500 } else {
30501 self.generate_expression(expr)
30502 }
30503 }
30504
30505 fn generate_partition_by_list_property(&mut self, e: &PartitionByListProperty) -> Result<()> {
30506 self.write_keyword("PARTITION BY LIST");
30508 if let Some(partition_exprs) = &e.partition_expressions {
30509 self.write(" (");
30510 self.generate_doris_partition_expressions(partition_exprs)?;
30512 self.write(")");
30513 }
30514 if let Some(create_exprs) = &e.create_expressions {
30515 self.write(" (");
30516 self.generate_doris_partition_definitions(create_exprs)?;
30518 self.write(")");
30519 }
30520 Ok(())
30521 }
30522
30523 fn generate_partition_by_range_property(&mut self, e: &PartitionByRangeProperty) -> Result<()> {
30524 self.write_keyword("PARTITION BY RANGE");
30526 if let Some(partition_exprs) = &e.partition_expressions {
30527 self.write(" (");
30528 self.generate_doris_partition_expressions(partition_exprs)?;
30530 self.write(")");
30531 }
30532 if let Some(create_exprs) = &e.create_expressions {
30533 self.write(" (");
30534 self.generate_doris_partition_definitions(create_exprs)?;
30536 self.write(")");
30537 }
30538 Ok(())
30539 }
30540
30541 fn generate_doris_partition_expressions(&mut self, expr: &Expression) -> Result<()> {
30543 if let Expression::Tuple(t) = expr {
30544 for (i, e) in t.expressions.iter().enumerate() {
30545 if i > 0 {
30546 self.write(", ");
30547 }
30548 self.generate_expression(e)?;
30549 }
30550 } else {
30551 self.generate_expression(expr)?;
30552 }
30553 Ok(())
30554 }
30555
30556 fn generate_doris_partition_definitions(&mut self, expr: &Expression) -> Result<()> {
30558 match expr {
30559 Expression::Tuple(t) => {
30560 for (i, part) in t.expressions.iter().enumerate() {
30562 if i > 0 {
30563 self.write(", ");
30564 }
30565 if let Expression::Partition(p) = part {
30567 for (j, inner) in p.expressions.iter().enumerate() {
30568 if j > 0 {
30569 self.write(", ");
30570 }
30571 self.generate_expression(inner)?;
30572 }
30573 } else {
30574 self.generate_expression(part)?;
30575 }
30576 }
30577 }
30578 Expression::PartitionByRangePropertyDynamic(_) => {
30579 self.generate_expression(expr)?;
30581 }
30582 _ => {
30583 self.generate_expression(expr)?;
30584 }
30585 }
30586 Ok(())
30587 }
30588
30589 fn generate_partition_by_range_property_dynamic(
30590 &mut self,
30591 e: &PartitionByRangePropertyDynamic,
30592 ) -> Result<()> {
30593 if e.use_start_end {
30594 if let Some(start) = &e.start {
30596 self.write_keyword("START");
30597 self.write(" (");
30598 self.generate_expression(start)?;
30599 self.write(")");
30600 }
30601 if let Some(end) = &e.end {
30602 self.write_space();
30603 self.write_keyword("END");
30604 self.write(" (");
30605 self.generate_expression(end)?;
30606 self.write(")");
30607 }
30608 if let Some(every) = &e.every {
30609 self.write_space();
30610 self.write_keyword("EVERY");
30611 self.write(" (");
30612 self.generate_doris_interval(every)?;
30614 self.write(")");
30615 }
30616 } else {
30617 if let Some(start) = &e.start {
30619 self.write_keyword("FROM");
30620 self.write(" (");
30621 self.generate_expression(start)?;
30622 self.write(")");
30623 }
30624 if let Some(end) = &e.end {
30625 self.write_space();
30626 self.write_keyword("TO");
30627 self.write(" (");
30628 self.generate_expression(end)?;
30629 self.write(")");
30630 }
30631 if let Some(every) = &e.every {
30632 self.write_space();
30633 self.generate_doris_interval(every)?;
30635 }
30636 }
30637 Ok(())
30638 }
30639
30640 fn generate_doris_interval(&mut self, expr: &Expression) -> Result<()> {
30642 if let Expression::Interval(interval) = expr {
30643 self.write_keyword("INTERVAL");
30644 if let Some(ref value) = interval.this {
30645 self.write_space();
30646 match value {
30650 Expression::Literal(Literal::String(s))
30651 if s.chars()
30652 .all(|c| c.is_ascii_digit() || c == '.' || c == '-')
30653 && !s.is_empty() =>
30654 {
30655 self.write(s);
30656 }
30657 _ => {
30658 self.generate_expression(value)?;
30659 }
30660 }
30661 }
30662 if let Some(ref unit_spec) = interval.unit {
30663 self.write_space();
30664 self.write_interval_unit_spec(unit_spec)?;
30665 }
30666 Ok(())
30667 } else {
30668 self.generate_expression(expr)
30669 }
30670 }
30671
30672 fn generate_partition_by_truncate(&mut self, e: &PartitionByTruncate) -> Result<()> {
30673 self.write_keyword("TRUNCATE");
30675 self.write("(");
30676 self.generate_expression(&e.expression)?;
30677 self.write(", ");
30678 self.generate_expression(&e.this)?;
30679 self.write(")");
30680 Ok(())
30681 }
30682
30683 fn generate_partition_list(&mut self, e: &PartitionList) -> Result<()> {
30684 self.write_keyword("PARTITION");
30686 self.write_space();
30687 self.generate_expression(&e.this)?;
30688 self.write_space();
30689 self.write_keyword("VALUES IN");
30690 self.write(" (");
30691 for (i, expr) in e.expressions.iter().enumerate() {
30692 if i > 0 {
30693 self.write(", ");
30694 }
30695 self.generate_expression(expr)?;
30696 }
30697 self.write(")");
30698 Ok(())
30699 }
30700
30701 fn generate_partition_range(&mut self, e: &PartitionRange) -> Result<()> {
30702 if e.expressions.is_empty() && e.expression.is_some() {
30705 self.generate_expression(&e.this)?;
30707 self.write_space();
30708 self.write_keyword("TO");
30709 self.write_space();
30710 self.generate_expression(e.expression.as_ref().unwrap())?;
30711 return Ok(());
30712 }
30713
30714 self.write_keyword("PARTITION");
30716 self.write_space();
30717 self.generate_expression(&e.this)?;
30718 self.write_space();
30719
30720 if e.expressions.len() == 1 {
30722 self.write_keyword("VALUES LESS THAN");
30724 self.write(" (");
30725 self.generate_expression(&e.expressions[0])?;
30726 self.write(")");
30727 } else if !e.expressions.is_empty() {
30728 self.write_keyword("VALUES");
30730 self.write(" [");
30731 for (i, expr) in e.expressions.iter().enumerate() {
30732 if i > 0 {
30733 self.write(", ");
30734 }
30735 if let Expression::Tuple(t) = expr {
30737 self.write("(");
30738 for (j, inner) in t.expressions.iter().enumerate() {
30739 if j > 0 {
30740 self.write(", ");
30741 }
30742 self.generate_expression(inner)?;
30743 }
30744 self.write(")");
30745 } else {
30746 self.write("(");
30747 self.generate_expression(expr)?;
30748 self.write(")");
30749 }
30750 }
30751 self.write(")");
30752 }
30753 Ok(())
30754 }
30755
30756 fn generate_partitioned_by_bucket(&mut self, e: &PartitionedByBucket) -> Result<()> {
30757 self.write_keyword("BUCKET");
30759 self.write("(");
30760 self.generate_expression(&e.this)?;
30761 self.write(", ");
30762 self.generate_expression(&e.expression)?;
30763 self.write(")");
30764 Ok(())
30765 }
30766
30767 fn generate_partitioned_by_property(&mut self, e: &PartitionedByProperty) -> Result<()> {
30768 if matches!(
30770 self.config.dialect,
30771 Some(crate::dialects::DialectType::Teradata)
30772 | Some(crate::dialects::DialectType::ClickHouse)
30773 ) {
30774 self.write_keyword("PARTITION BY");
30775 } else {
30776 self.write_keyword("PARTITIONED BY");
30777 }
30778 self.write_space();
30779 if self.config.pretty {
30781 if let Expression::Tuple(ref tuple) = *e.this {
30782 self.write("(");
30783 self.write_newline();
30784 self.indent_level += 1;
30785 for (i, expr) in tuple.expressions.iter().enumerate() {
30786 if i > 0 {
30787 self.write(",");
30788 self.write_newline();
30789 }
30790 self.write_indent();
30791 self.generate_expression(expr)?;
30792 }
30793 self.indent_level -= 1;
30794 self.write_newline();
30795 self.write(")");
30796 } else {
30797 self.generate_expression(&e.this)?;
30798 }
30799 } else {
30800 self.generate_expression(&e.this)?;
30801 }
30802 Ok(())
30803 }
30804
30805 fn generate_partitioned_of_property(&mut self, e: &PartitionedOfProperty) -> Result<()> {
30806 self.write_keyword("PARTITION OF");
30808 self.write_space();
30809 self.generate_expression(&e.this)?;
30810 if let Expression::PartitionBoundSpec(_) = e.expression.as_ref() {
30812 self.write_space();
30813 self.write_keyword("FOR VALUES");
30814 self.write_space();
30815 self.generate_expression(&e.expression)?;
30816 } else {
30817 self.write_space();
30818 self.write_keyword("DEFAULT");
30819 }
30820 Ok(())
30821 }
30822
30823 fn generate_period_for_system_time_constraint(
30824 &mut self,
30825 e: &PeriodForSystemTimeConstraint,
30826 ) -> Result<()> {
30827 self.write_keyword("PERIOD FOR SYSTEM_TIME");
30829 self.write(" (");
30830 self.generate_expression(&e.this)?;
30831 self.write(", ");
30832 self.generate_expression(&e.expression)?;
30833 self.write(")");
30834 Ok(())
30835 }
30836
30837 fn generate_pivot_alias(&mut self, e: &PivotAlias) -> Result<()> {
30838 self.generate_expression(&e.this)?;
30841 self.write_space();
30842 self.write_keyword("AS");
30843 self.write_space();
30844 if self.config.unpivot_aliases_are_identifiers {
30846 match &e.alias {
30847 Expression::Literal(Literal::String(s)) => {
30848 self.generate_identifier(&Identifier::new(s.clone()))?;
30850 }
30851 Expression::Literal(Literal::Number(n)) => {
30852 let mut id = Identifier::new(n.clone());
30854 id.quoted = true;
30855 self.generate_identifier(&id)?;
30856 }
30857 other => {
30858 self.generate_expression(other)?;
30859 }
30860 }
30861 } else {
30862 self.generate_expression(&e.alias)?;
30863 }
30864 Ok(())
30865 }
30866
30867 fn generate_pivot_any(&mut self, e: &PivotAny) -> Result<()> {
30868 self.write_keyword("ANY");
30870 if let Some(this) = &e.this {
30871 self.write_space();
30872 self.generate_expression(this)?;
30873 }
30874 Ok(())
30875 }
30876
30877 fn generate_predict(&mut self, e: &Predict) -> Result<()> {
30878 self.write_keyword("ML.PREDICT");
30880 self.write("(");
30881 self.write_keyword("MODEL");
30882 self.write_space();
30883 self.generate_expression(&e.this)?;
30884 self.write(", ");
30885 self.generate_expression(&e.expression)?;
30886 if let Some(params) = &e.params_struct {
30887 self.write(", ");
30888 self.generate_expression(params)?;
30889 }
30890 self.write(")");
30891 Ok(())
30892 }
30893
30894 fn generate_previous_day(&mut self, e: &PreviousDay) -> Result<()> {
30895 self.write_keyword("PREVIOUS_DAY");
30897 self.write("(");
30898 self.generate_expression(&e.this)?;
30899 self.write(", ");
30900 self.generate_expression(&e.expression)?;
30901 self.write(")");
30902 Ok(())
30903 }
30904
30905 fn generate_primary_key(&mut self, e: &PrimaryKey) -> Result<()> {
30906 self.write_keyword("PRIMARY KEY");
30908 if let Some(name) = &e.this {
30909 self.write_space();
30910 self.generate_expression(name)?;
30911 }
30912 if !e.expressions.is_empty() {
30913 self.write(" (");
30914 for (i, expr) in e.expressions.iter().enumerate() {
30915 if i > 0 {
30916 self.write(", ");
30917 }
30918 self.generate_expression(expr)?;
30919 }
30920 self.write(")");
30921 }
30922 if let Some(include) = &e.include {
30923 self.write_space();
30924 self.generate_expression(include)?;
30925 }
30926 if !e.options.is_empty() {
30927 self.write_space();
30928 for (i, opt) in e.options.iter().enumerate() {
30929 if i > 0 {
30930 self.write_space();
30931 }
30932 self.generate_expression(opt)?;
30933 }
30934 }
30935 Ok(())
30936 }
30937
30938 fn generate_primary_key_column_constraint(
30939 &mut self,
30940 _e: &PrimaryKeyColumnConstraint,
30941 ) -> Result<()> {
30942 self.write_keyword("PRIMARY KEY");
30944 Ok(())
30945 }
30946
30947 fn generate_path_column_constraint(&mut self, e: &PathColumnConstraint) -> Result<()> {
30948 self.write_keyword("PATH");
30950 self.write_space();
30951 self.generate_expression(&e.this)?;
30952 Ok(())
30953 }
30954
30955 fn generate_projection_def(&mut self, e: &ProjectionDef) -> Result<()> {
30956 self.write_keyword("PROJECTION");
30958 self.write_space();
30959 self.generate_expression(&e.this)?;
30960 self.write(" (");
30961 self.generate_expression(&e.expression)?;
30962 self.write(")");
30963 Ok(())
30964 }
30965
30966 fn generate_properties(&mut self, e: &Properties) -> Result<()> {
30967 for (i, prop) in e.expressions.iter().enumerate() {
30969 if i > 0 {
30970 self.write(", ");
30971 }
30972 self.generate_expression(prop)?;
30973 }
30974 Ok(())
30975 }
30976
30977 fn generate_property(&mut self, e: &Property) -> Result<()> {
30978 self.generate_expression(&e.this)?;
30980 if let Some(value) = &e.value {
30981 self.write("=");
30982 self.generate_expression(value)?;
30983 }
30984 Ok(())
30985 }
30986
30987 fn generate_options_clause(&mut self, options: &[Expression]) -> Result<()> {
30989 self.write_keyword("OPTIONS");
30990 self.write(" (");
30991 for (i, opt) in options.iter().enumerate() {
30992 if i > 0 {
30993 self.write(", ");
30994 }
30995 self.generate_option_expression(opt)?;
30996 }
30997 self.write(")");
30998 Ok(())
30999 }
31000
31001 fn generate_properties_clause(&mut self, properties: &[Expression]) -> Result<()> {
31003 self.write_keyword("PROPERTIES");
31004 self.write(" (");
31005 for (i, prop) in properties.iter().enumerate() {
31006 if i > 0 {
31007 self.write(", ");
31008 }
31009 self.generate_option_expression(prop)?;
31010 }
31011 self.write(")");
31012 Ok(())
31013 }
31014
31015 fn generate_environment_clause(&mut self, environment: &[Expression]) -> Result<()> {
31017 self.write_keyword("ENVIRONMENT");
31018 self.write(" (");
31019 for (i, env_item) in environment.iter().enumerate() {
31020 if i > 0 {
31021 self.write(", ");
31022 }
31023 self.generate_environment_expression(env_item)?;
31024 }
31025 self.write(")");
31026 Ok(())
31027 }
31028
31029 fn generate_environment_expression(&mut self, expr: &Expression) -> Result<()> {
31031 match expr {
31032 Expression::Eq(eq) => {
31033 self.generate_expression(&eq.left)?;
31035 self.write(" = ");
31036 self.generate_expression(&eq.right)?;
31037 Ok(())
31038 }
31039 _ => self.generate_expression(expr),
31040 }
31041 }
31042
31043 fn generate_tblproperties_clause(&mut self, options: &[Expression]) -> Result<()> {
31045 self.write_keyword("TBLPROPERTIES");
31046 if self.config.pretty {
31047 self.write(" (");
31048 self.write_newline();
31049 self.indent_level += 1;
31050 for (i, opt) in options.iter().enumerate() {
31051 if i > 0 {
31052 self.write(",");
31053 self.write_newline();
31054 }
31055 self.write_indent();
31056 self.generate_option_expression(opt)?;
31057 }
31058 self.indent_level -= 1;
31059 self.write_newline();
31060 self.write(")");
31061 } else {
31062 self.write(" (");
31063 for (i, opt) in options.iter().enumerate() {
31064 if i > 0 {
31065 self.write(", ");
31066 }
31067 self.generate_option_expression(opt)?;
31068 }
31069 self.write(")");
31070 }
31071 Ok(())
31072 }
31073
31074 fn generate_option_expression(&mut self, expr: &Expression) -> Result<()> {
31076 match expr {
31077 Expression::Eq(eq) => {
31078 self.generate_expression(&eq.left)?;
31080 self.write("=");
31081 self.generate_expression(&eq.right)?;
31082 Ok(())
31083 }
31084 _ => self.generate_expression(expr),
31085 }
31086 }
31087
31088 fn generate_pseudo_type(&mut self, e: &PseudoType) -> Result<()> {
31089 self.generate_expression(&e.this)?;
31091 Ok(())
31092 }
31093
31094 fn generate_put(&mut self, e: &PutStmt) -> Result<()> {
31095 self.write_keyword("PUT");
31097 self.write_space();
31098
31099 if e.source_quoted {
31101 self.write("'");
31102 self.write(&e.source);
31103 self.write("'");
31104 } else {
31105 self.write(&e.source);
31106 }
31107
31108 self.write_space();
31109
31110 if let Expression::Literal(Literal::String(s)) = &e.target {
31112 self.write(s);
31113 } else {
31114 self.generate_expression(&e.target)?;
31115 }
31116
31117 for param in &e.params {
31119 self.write_space();
31120 self.write(¶m.name);
31121 if let Some(ref value) = param.value {
31122 self.write("=");
31123 self.generate_expression(value)?;
31124 }
31125 }
31126
31127 Ok(())
31128 }
31129
31130 fn generate_quantile(&mut self, e: &Quantile) -> Result<()> {
31131 self.write_keyword("QUANTILE");
31133 self.write("(");
31134 self.generate_expression(&e.this)?;
31135 if let Some(quantile) = &e.quantile {
31136 self.write(", ");
31137 self.generate_expression(quantile)?;
31138 }
31139 self.write(")");
31140 Ok(())
31141 }
31142
31143 fn generate_query_band(&mut self, e: &QueryBand) -> Result<()> {
31144 if matches!(
31146 self.config.dialect,
31147 Some(crate::dialects::DialectType::Teradata)
31148 ) {
31149 self.write_keyword("SET");
31150 self.write_space();
31151 }
31152 self.write_keyword("QUERY_BAND");
31153 self.write(" = ");
31154 self.generate_expression(&e.this)?;
31155 if e.update.is_some() {
31156 self.write_space();
31157 self.write_keyword("UPDATE");
31158 }
31159 if let Some(scope) = &e.scope {
31160 self.write_space();
31161 self.write_keyword("FOR");
31162 self.write_space();
31163 self.generate_expression(scope)?;
31164 }
31165 Ok(())
31166 }
31167
31168 fn generate_query_option(&mut self, e: &QueryOption) -> Result<()> {
31169 self.generate_expression(&e.this)?;
31171 if let Some(expression) = &e.expression {
31172 self.write(" = ");
31173 self.generate_expression(expression)?;
31174 }
31175 Ok(())
31176 }
31177
31178 fn generate_query_transform(&mut self, e: &QueryTransform) -> Result<()> {
31179 self.write_keyword("TRANSFORM");
31181 self.write("(");
31182 for (i, expr) in e.expressions.iter().enumerate() {
31183 if i > 0 {
31184 self.write(", ");
31185 }
31186 self.generate_expression(expr)?;
31187 }
31188 self.write(")");
31189 if let Some(row_format_before) = &e.row_format_before {
31190 self.write_space();
31191 self.generate_expression(row_format_before)?;
31192 }
31193 if let Some(record_writer) = &e.record_writer {
31194 self.write_space();
31195 self.write_keyword("RECORDWRITER");
31196 self.write_space();
31197 self.generate_expression(record_writer)?;
31198 }
31199 if let Some(command_script) = &e.command_script {
31200 self.write_space();
31201 self.write_keyword("USING");
31202 self.write_space();
31203 self.generate_expression(command_script)?;
31204 }
31205 if let Some(schema) = &e.schema {
31206 self.write_space();
31207 self.write_keyword("AS");
31208 self.write_space();
31209 self.generate_expression(schema)?;
31210 }
31211 if let Some(row_format_after) = &e.row_format_after {
31212 self.write_space();
31213 self.generate_expression(row_format_after)?;
31214 }
31215 if let Some(record_reader) = &e.record_reader {
31216 self.write_space();
31217 self.write_keyword("RECORDREADER");
31218 self.write_space();
31219 self.generate_expression(record_reader)?;
31220 }
31221 Ok(())
31222 }
31223
31224 fn generate_randn(&mut self, e: &Randn) -> Result<()> {
31225 self.write_keyword("RANDN");
31227 self.write("(");
31228 if let Some(this) = &e.this {
31229 self.generate_expression(this)?;
31230 }
31231 self.write(")");
31232 Ok(())
31233 }
31234
31235 fn generate_randstr(&mut self, e: &Randstr) -> Result<()> {
31236 self.write_keyword("RANDSTR");
31238 self.write("(");
31239 self.generate_expression(&e.this)?;
31240 if let Some(generator) = &e.generator {
31241 self.write(", ");
31242 self.generate_expression(generator)?;
31243 }
31244 self.write(")");
31245 Ok(())
31246 }
31247
31248 fn generate_range_bucket(&mut self, e: &RangeBucket) -> Result<()> {
31249 self.write_keyword("RANGE_BUCKET");
31251 self.write("(");
31252 self.generate_expression(&e.this)?;
31253 self.write(", ");
31254 self.generate_expression(&e.expression)?;
31255 self.write(")");
31256 Ok(())
31257 }
31258
31259 fn generate_range_n(&mut self, e: &RangeN) -> Result<()> {
31260 self.write_keyword("RANGE_N");
31262 self.write("(");
31263 self.generate_expression(&e.this)?;
31264 self.write_space();
31265 self.write_keyword("BETWEEN");
31266 self.write_space();
31267 for (i, expr) in e.expressions.iter().enumerate() {
31268 if i > 0 {
31269 self.write(", ");
31270 }
31271 self.generate_expression(expr)?;
31272 }
31273 if let Some(each) = &e.each {
31274 self.write_space();
31275 self.write_keyword("EACH");
31276 self.write_space();
31277 self.generate_expression(each)?;
31278 }
31279 self.write(")");
31280 Ok(())
31281 }
31282
31283 fn generate_read_csv(&mut self, e: &ReadCSV) -> Result<()> {
31284 self.write_keyword("READ_CSV");
31286 self.write("(");
31287 self.generate_expression(&e.this)?;
31288 for expr in &e.expressions {
31289 self.write(", ");
31290 self.generate_expression(expr)?;
31291 }
31292 self.write(")");
31293 Ok(())
31294 }
31295
31296 fn generate_read_parquet(&mut self, e: &ReadParquet) -> Result<()> {
31297 self.write_keyword("READ_PARQUET");
31299 self.write("(");
31300 for (i, expr) in e.expressions.iter().enumerate() {
31301 if i > 0 {
31302 self.write(", ");
31303 }
31304 self.generate_expression(expr)?;
31305 }
31306 self.write(")");
31307 Ok(())
31308 }
31309
31310 fn generate_recursive_with_search(&mut self, e: &RecursiveWithSearch) -> Result<()> {
31311 if e.kind == "CYCLE" {
31314 self.write_keyword("CYCLE");
31315 } else {
31316 self.write_keyword("SEARCH");
31317 self.write_space();
31318 self.write(&e.kind);
31319 self.write_space();
31320 self.write_keyword("FIRST BY");
31321 }
31322 self.write_space();
31323 self.generate_expression(&e.this)?;
31324 self.write_space();
31325 self.write_keyword("SET");
31326 self.write_space();
31327 self.generate_expression(&e.expression)?;
31328 if let Some(using) = &e.using {
31329 self.write_space();
31330 self.write_keyword("USING");
31331 self.write_space();
31332 self.generate_expression(using)?;
31333 }
31334 Ok(())
31335 }
31336
31337 fn generate_reduce(&mut self, e: &Reduce) -> Result<()> {
31338 self.write_keyword("REDUCE");
31340 self.write("(");
31341 self.generate_expression(&e.this)?;
31342 if let Some(initial) = &e.initial {
31343 self.write(", ");
31344 self.generate_expression(initial)?;
31345 }
31346 if let Some(merge) = &e.merge {
31347 self.write(", ");
31348 self.generate_expression(merge)?;
31349 }
31350 if let Some(finish) = &e.finish {
31351 self.write(", ");
31352 self.generate_expression(finish)?;
31353 }
31354 self.write(")");
31355 Ok(())
31356 }
31357
31358 fn generate_reference(&mut self, e: &Reference) -> Result<()> {
31359 self.write_keyword("REFERENCES");
31361 self.write_space();
31362 self.generate_expression(&e.this)?;
31363 if !e.expressions.is_empty() {
31364 self.write(" (");
31365 for (i, expr) in e.expressions.iter().enumerate() {
31366 if i > 0 {
31367 self.write(", ");
31368 }
31369 self.generate_expression(expr)?;
31370 }
31371 self.write(")");
31372 }
31373 for opt in &e.options {
31374 self.write_space();
31375 self.generate_expression(opt)?;
31376 }
31377 Ok(())
31378 }
31379
31380 fn generate_refresh(&mut self, e: &Refresh) -> Result<()> {
31381 self.write_keyword("REFRESH");
31383 if !e.kind.is_empty() {
31384 self.write_space();
31385 self.write_keyword(&e.kind);
31386 }
31387 self.write_space();
31388 self.generate_expression(&e.this)?;
31389 Ok(())
31390 }
31391
31392 fn generate_refresh_trigger_property(&mut self, e: &RefreshTriggerProperty) -> Result<()> {
31393 self.write_keyword("REFRESH");
31395 self.write_space();
31396 self.write_keyword(&e.method);
31397
31398 if let Some(ref kind) = e.kind {
31399 self.write_space();
31400 self.write_keyword("ON");
31401 self.write_space();
31402 self.write_keyword(kind);
31403
31404 if let Some(ref every) = e.every {
31406 self.write_space();
31407 self.write_keyword("EVERY");
31408 self.write_space();
31409 self.generate_expression(every)?;
31410 if let Some(ref unit) = e.unit {
31411 self.write_space();
31412 self.write_keyword(unit);
31413 }
31414 }
31415
31416 if let Some(ref starts) = e.starts {
31418 self.write_space();
31419 self.write_keyword("STARTS");
31420 self.write_space();
31421 self.generate_expression(starts)?;
31422 }
31423 }
31424 Ok(())
31425 }
31426
31427 fn generate_regexp_count(&mut self, e: &RegexpCount) -> Result<()> {
31428 self.write_keyword("REGEXP_COUNT");
31430 self.write("(");
31431 self.generate_expression(&e.this)?;
31432 self.write(", ");
31433 self.generate_expression(&e.expression)?;
31434 if let Some(position) = &e.position {
31435 self.write(", ");
31436 self.generate_expression(position)?;
31437 }
31438 if let Some(parameters) = &e.parameters {
31439 self.write(", ");
31440 self.generate_expression(parameters)?;
31441 }
31442 self.write(")");
31443 Ok(())
31444 }
31445
31446 fn generate_regexp_extract_all(&mut self, e: &RegexpExtractAll) -> Result<()> {
31447 self.write_keyword("REGEXP_EXTRACT_ALL");
31449 self.write("(");
31450 self.generate_expression(&e.this)?;
31451 self.write(", ");
31452 self.generate_expression(&e.expression)?;
31453 if let Some(group) = &e.group {
31454 self.write(", ");
31455 self.generate_expression(group)?;
31456 }
31457 self.write(")");
31458 Ok(())
31459 }
31460
31461 fn generate_regexp_full_match(&mut self, e: &RegexpFullMatch) -> Result<()> {
31462 self.write_keyword("REGEXP_FULL_MATCH");
31464 self.write("(");
31465 self.generate_expression(&e.this)?;
31466 self.write(", ");
31467 self.generate_expression(&e.expression)?;
31468 self.write(")");
31469 Ok(())
31470 }
31471
31472 fn generate_regexp_i_like(&mut self, e: &RegexpILike) -> Result<()> {
31473 use crate::dialects::DialectType;
31474 if matches!(
31476 self.config.dialect,
31477 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
31478 ) && e.flag.is_none()
31479 {
31480 self.generate_expression(&e.this)?;
31481 self.write(" ~* ");
31482 self.generate_expression(&e.expression)?;
31483 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
31484 self.write_keyword("REGEXP_LIKE");
31486 self.write("(");
31487 self.generate_expression(&e.this)?;
31488 self.write(", ");
31489 self.generate_expression(&e.expression)?;
31490 self.write(", ");
31491 if let Some(flag) = &e.flag {
31492 self.generate_expression(flag)?;
31493 } else {
31494 self.write("'i'");
31495 }
31496 self.write(")");
31497 } else {
31498 self.generate_expression(&e.this)?;
31500 self.write_space();
31501 self.write_keyword("REGEXP_ILIKE");
31502 self.write_space();
31503 self.generate_expression(&e.expression)?;
31504 if let Some(flag) = &e.flag {
31505 self.write(", ");
31506 self.generate_expression(flag)?;
31507 }
31508 }
31509 Ok(())
31510 }
31511
31512 fn generate_regexp_instr(&mut self, e: &RegexpInstr) -> Result<()> {
31513 self.write_keyword("REGEXP_INSTR");
31515 self.write("(");
31516 self.generate_expression(&e.this)?;
31517 self.write(", ");
31518 self.generate_expression(&e.expression)?;
31519 if let Some(position) = &e.position {
31520 self.write(", ");
31521 self.generate_expression(position)?;
31522 }
31523 if let Some(occurrence) = &e.occurrence {
31524 self.write(", ");
31525 self.generate_expression(occurrence)?;
31526 }
31527 if let Some(option) = &e.option {
31528 self.write(", ");
31529 self.generate_expression(option)?;
31530 }
31531 if let Some(parameters) = &e.parameters {
31532 self.write(", ");
31533 self.generate_expression(parameters)?;
31534 }
31535 if let Some(group) = &e.group {
31536 self.write(", ");
31537 self.generate_expression(group)?;
31538 }
31539 self.write(")");
31540 Ok(())
31541 }
31542
31543 fn generate_regexp_split(&mut self, e: &RegexpSplit) -> Result<()> {
31544 self.write_keyword("REGEXP_SPLIT");
31546 self.write("(");
31547 self.generate_expression(&e.this)?;
31548 self.write(", ");
31549 self.generate_expression(&e.expression)?;
31550 if let Some(limit) = &e.limit {
31551 self.write(", ");
31552 self.generate_expression(limit)?;
31553 }
31554 self.write(")");
31555 Ok(())
31556 }
31557
31558 fn generate_regr_avgx(&mut self, e: &RegrAvgx) -> Result<()> {
31559 self.write_keyword("REGR_AVGX");
31561 self.write("(");
31562 self.generate_expression(&e.this)?;
31563 self.write(", ");
31564 self.generate_expression(&e.expression)?;
31565 self.write(")");
31566 Ok(())
31567 }
31568
31569 fn generate_regr_avgy(&mut self, e: &RegrAvgy) -> Result<()> {
31570 self.write_keyword("REGR_AVGY");
31572 self.write("(");
31573 self.generate_expression(&e.this)?;
31574 self.write(", ");
31575 self.generate_expression(&e.expression)?;
31576 self.write(")");
31577 Ok(())
31578 }
31579
31580 fn generate_regr_count(&mut self, e: &RegrCount) -> Result<()> {
31581 self.write_keyword("REGR_COUNT");
31583 self.write("(");
31584 self.generate_expression(&e.this)?;
31585 self.write(", ");
31586 self.generate_expression(&e.expression)?;
31587 self.write(")");
31588 Ok(())
31589 }
31590
31591 fn generate_regr_intercept(&mut self, e: &RegrIntercept) -> Result<()> {
31592 self.write_keyword("REGR_INTERCEPT");
31594 self.write("(");
31595 self.generate_expression(&e.this)?;
31596 self.write(", ");
31597 self.generate_expression(&e.expression)?;
31598 self.write(")");
31599 Ok(())
31600 }
31601
31602 fn generate_regr_r2(&mut self, e: &RegrR2) -> Result<()> {
31603 self.write_keyword("REGR_R2");
31605 self.write("(");
31606 self.generate_expression(&e.this)?;
31607 self.write(", ");
31608 self.generate_expression(&e.expression)?;
31609 self.write(")");
31610 Ok(())
31611 }
31612
31613 fn generate_regr_slope(&mut self, e: &RegrSlope) -> Result<()> {
31614 self.write_keyword("REGR_SLOPE");
31616 self.write("(");
31617 self.generate_expression(&e.this)?;
31618 self.write(", ");
31619 self.generate_expression(&e.expression)?;
31620 self.write(")");
31621 Ok(())
31622 }
31623
31624 fn generate_regr_sxx(&mut self, e: &RegrSxx) -> Result<()> {
31625 self.write_keyword("REGR_SXX");
31627 self.write("(");
31628 self.generate_expression(&e.this)?;
31629 self.write(", ");
31630 self.generate_expression(&e.expression)?;
31631 self.write(")");
31632 Ok(())
31633 }
31634
31635 fn generate_regr_sxy(&mut self, e: &RegrSxy) -> Result<()> {
31636 self.write_keyword("REGR_SXY");
31638 self.write("(");
31639 self.generate_expression(&e.this)?;
31640 self.write(", ");
31641 self.generate_expression(&e.expression)?;
31642 self.write(")");
31643 Ok(())
31644 }
31645
31646 fn generate_regr_syy(&mut self, e: &RegrSyy) -> Result<()> {
31647 self.write_keyword("REGR_SYY");
31649 self.write("(");
31650 self.generate_expression(&e.this)?;
31651 self.write(", ");
31652 self.generate_expression(&e.expression)?;
31653 self.write(")");
31654 Ok(())
31655 }
31656
31657 fn generate_regr_valx(&mut self, e: &RegrValx) -> Result<()> {
31658 self.write_keyword("REGR_VALX");
31660 self.write("(");
31661 self.generate_expression(&e.this)?;
31662 self.write(", ");
31663 self.generate_expression(&e.expression)?;
31664 self.write(")");
31665 Ok(())
31666 }
31667
31668 fn generate_regr_valy(&mut self, e: &RegrValy) -> Result<()> {
31669 self.write_keyword("REGR_VALY");
31671 self.write("(");
31672 self.generate_expression(&e.this)?;
31673 self.write(", ");
31674 self.generate_expression(&e.expression)?;
31675 self.write(")");
31676 Ok(())
31677 }
31678
31679 fn generate_remote_with_connection_model_property(
31680 &mut self,
31681 e: &RemoteWithConnectionModelProperty,
31682 ) -> Result<()> {
31683 self.write_keyword("REMOTE WITH CONNECTION");
31685 self.write_space();
31686 self.generate_expression(&e.this)?;
31687 Ok(())
31688 }
31689
31690 fn generate_rename_column(&mut self, e: &RenameColumn) -> Result<()> {
31691 self.write_keyword("RENAME COLUMN");
31693 if e.exists {
31694 self.write_space();
31695 self.write_keyword("IF EXISTS");
31696 }
31697 self.write_space();
31698 self.generate_expression(&e.this)?;
31699 if let Some(to) = &e.to {
31700 self.write_space();
31701 self.write_keyword("TO");
31702 self.write_space();
31703 self.generate_expression(to)?;
31704 }
31705 Ok(())
31706 }
31707
31708 fn generate_replace_partition(&mut self, e: &ReplacePartition) -> Result<()> {
31709 self.write_keyword("REPLACE PARTITION");
31711 self.write_space();
31712 self.generate_expression(&e.expression)?;
31713 if let Some(source) = &e.source {
31714 self.write_space();
31715 self.write_keyword("FROM");
31716 self.write_space();
31717 self.generate_expression(source)?;
31718 }
31719 Ok(())
31720 }
31721
31722 fn generate_returning(&mut self, e: &Returning) -> Result<()> {
31723 let keyword = match self.config.dialect {
31726 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "OUTPUT",
31727 _ => "RETURNING",
31728 };
31729 self.write_keyword(keyword);
31730 self.write_space();
31731 for (i, expr) in e.expressions.iter().enumerate() {
31732 if i > 0 {
31733 self.write(", ");
31734 }
31735 self.generate_expression(expr)?;
31736 }
31737 if let Some(into) = &e.into {
31738 self.write_space();
31739 self.write_keyword("INTO");
31740 self.write_space();
31741 self.generate_expression(into)?;
31742 }
31743 Ok(())
31744 }
31745
31746 fn generate_output_clause(&mut self, output: &OutputClause) -> Result<()> {
31747 self.write_space();
31749 self.write_keyword("OUTPUT");
31750 self.write_space();
31751 for (i, expr) in output.columns.iter().enumerate() {
31752 if i > 0 {
31753 self.write(", ");
31754 }
31755 self.generate_expression(expr)?;
31756 }
31757 if let Some(into_table) = &output.into_table {
31758 self.write_space();
31759 self.write_keyword("INTO");
31760 self.write_space();
31761 self.generate_expression(into_table)?;
31762 }
31763 Ok(())
31764 }
31765
31766 fn generate_returns_property(&mut self, e: &ReturnsProperty) -> Result<()> {
31767 self.write_keyword("RETURNS");
31769 if e.is_table.is_some() {
31770 self.write_space();
31771 self.write_keyword("TABLE");
31772 }
31773 if let Some(table) = &e.table {
31774 self.write_space();
31775 self.generate_expression(table)?;
31776 } else if let Some(this) = &e.this {
31777 self.write_space();
31778 self.generate_expression(this)?;
31779 }
31780 if e.null.is_some() {
31781 self.write_space();
31782 self.write_keyword("NULL ON NULL INPUT");
31783 }
31784 Ok(())
31785 }
31786
31787 fn generate_rollback(&mut self, e: &Rollback) -> Result<()> {
31788 self.write_keyword("ROLLBACK");
31790
31791 if e.this.is_none()
31793 && matches!(
31794 self.config.dialect,
31795 Some(DialectType::TSQL) | Some(DialectType::Fabric)
31796 )
31797 {
31798 self.write_space();
31799 self.write_keyword("TRANSACTION");
31800 }
31801
31802 if let Some(this) = &e.this {
31804 let is_transaction_marker = matches!(
31806 this.as_ref(),
31807 Expression::Identifier(id) if id.name == "TRANSACTION"
31808 );
31809
31810 self.write_space();
31811 self.write_keyword("TRANSACTION");
31812
31813 if !is_transaction_marker {
31815 self.write_space();
31816 self.generate_expression(this)?;
31817 }
31818 }
31819
31820 if let Some(savepoint) = &e.savepoint {
31822 self.write_space();
31823 self.write_keyword("TO");
31824 self.write_space();
31825 self.generate_expression(savepoint)?;
31826 }
31827 Ok(())
31828 }
31829
31830 fn generate_rollup(&mut self, e: &Rollup) -> Result<()> {
31831 if e.expressions.is_empty() {
31833 self.write_keyword("WITH ROLLUP");
31834 } else {
31835 self.write_keyword("ROLLUP");
31836 self.write("(");
31837 for (i, expr) in e.expressions.iter().enumerate() {
31838 if i > 0 {
31839 self.write(", ");
31840 }
31841 self.generate_expression(expr)?;
31842 }
31843 self.write(")");
31844 }
31845 Ok(())
31846 }
31847
31848 fn generate_row_format_delimited_property(
31849 &mut self,
31850 e: &RowFormatDelimitedProperty,
31851 ) -> Result<()> {
31852 self.write_keyword("ROW FORMAT DELIMITED");
31854 if let Some(fields) = &e.fields {
31855 self.write_space();
31856 self.write_keyword("FIELDS TERMINATED BY");
31857 self.write_space();
31858 self.generate_expression(fields)?;
31859 }
31860 if let Some(escaped) = &e.escaped {
31861 self.write_space();
31862 self.write_keyword("ESCAPED BY");
31863 self.write_space();
31864 self.generate_expression(escaped)?;
31865 }
31866 if let Some(items) = &e.collection_items {
31867 self.write_space();
31868 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
31869 self.write_space();
31870 self.generate_expression(items)?;
31871 }
31872 if let Some(keys) = &e.map_keys {
31873 self.write_space();
31874 self.write_keyword("MAP KEYS TERMINATED BY");
31875 self.write_space();
31876 self.generate_expression(keys)?;
31877 }
31878 if let Some(lines) = &e.lines {
31879 self.write_space();
31880 self.write_keyword("LINES TERMINATED BY");
31881 self.write_space();
31882 self.generate_expression(lines)?;
31883 }
31884 if let Some(null) = &e.null {
31885 self.write_space();
31886 self.write_keyword("NULL DEFINED AS");
31887 self.write_space();
31888 self.generate_expression(null)?;
31889 }
31890 if let Some(serde) = &e.serde {
31891 self.write_space();
31892 self.generate_expression(serde)?;
31893 }
31894 Ok(())
31895 }
31896
31897 fn generate_row_format_property(&mut self, e: &RowFormatProperty) -> Result<()> {
31898 self.write_keyword("ROW FORMAT");
31900 self.write_space();
31901 self.generate_expression(&e.this)?;
31902 Ok(())
31903 }
31904
31905 fn generate_row_format_serde_property(&mut self, e: &RowFormatSerdeProperty) -> Result<()> {
31906 self.write_keyword("ROW FORMAT SERDE");
31908 self.write_space();
31909 self.generate_expression(&e.this)?;
31910 if let Some(props) = &e.serde_properties {
31911 self.write_space();
31912 self.generate_expression(props)?;
31914 }
31915 Ok(())
31916 }
31917
31918 fn generate_sha2(&mut self, e: &SHA2) -> Result<()> {
31919 self.write_keyword("SHA2");
31921 self.write("(");
31922 self.generate_expression(&e.this)?;
31923 if let Some(length) = e.length {
31924 self.write(", ");
31925 self.write(&length.to_string());
31926 }
31927 self.write(")");
31928 Ok(())
31929 }
31930
31931 fn generate_sha2_digest(&mut self, e: &SHA2Digest) -> Result<()> {
31932 self.write_keyword("SHA2_DIGEST");
31934 self.write("(");
31935 self.generate_expression(&e.this)?;
31936 if let Some(length) = e.length {
31937 self.write(", ");
31938 self.write(&length.to_string());
31939 }
31940 self.write(")");
31941 Ok(())
31942 }
31943
31944 fn generate_safe_add(&mut self, e: &SafeAdd) -> Result<()> {
31945 let name = if matches!(
31946 self.config.dialect,
31947 Some(crate::dialects::DialectType::Spark)
31948 | Some(crate::dialects::DialectType::Databricks)
31949 ) {
31950 "TRY_ADD"
31951 } else {
31952 "SAFE_ADD"
31953 };
31954 self.write_keyword(name);
31955 self.write("(");
31956 self.generate_expression(&e.this)?;
31957 self.write(", ");
31958 self.generate_expression(&e.expression)?;
31959 self.write(")");
31960 Ok(())
31961 }
31962
31963 fn generate_safe_divide(&mut self, e: &SafeDivide) -> Result<()> {
31964 self.write_keyword("SAFE_DIVIDE");
31966 self.write("(");
31967 self.generate_expression(&e.this)?;
31968 self.write(", ");
31969 self.generate_expression(&e.expression)?;
31970 self.write(")");
31971 Ok(())
31972 }
31973
31974 fn generate_safe_multiply(&mut self, e: &SafeMultiply) -> Result<()> {
31975 let name = if matches!(
31976 self.config.dialect,
31977 Some(crate::dialects::DialectType::Spark)
31978 | Some(crate::dialects::DialectType::Databricks)
31979 ) {
31980 "TRY_MULTIPLY"
31981 } else {
31982 "SAFE_MULTIPLY"
31983 };
31984 self.write_keyword(name);
31985 self.write("(");
31986 self.generate_expression(&e.this)?;
31987 self.write(", ");
31988 self.generate_expression(&e.expression)?;
31989 self.write(")");
31990 Ok(())
31991 }
31992
31993 fn generate_safe_subtract(&mut self, e: &SafeSubtract) -> Result<()> {
31994 let name = if matches!(
31995 self.config.dialect,
31996 Some(crate::dialects::DialectType::Spark)
31997 | Some(crate::dialects::DialectType::Databricks)
31998 ) {
31999 "TRY_SUBTRACT"
32000 } else {
32001 "SAFE_SUBTRACT"
32002 };
32003 self.write_keyword(name);
32004 self.write("(");
32005 self.generate_expression(&e.this)?;
32006 self.write(", ");
32007 self.generate_expression(&e.expression)?;
32008 self.write(")");
32009 Ok(())
32010 }
32011
32012 fn generate_sample_body(&mut self, sample: &Sample) -> Result<()> {
32015 if matches!(sample.method, SampleMethod::Bucket) {
32017 self.write(" (");
32018 self.write_keyword("BUCKET");
32019 self.write_space();
32020 if let Some(ref num) = sample.bucket_numerator {
32021 self.generate_expression(num)?;
32022 }
32023 self.write_space();
32024 self.write_keyword("OUT OF");
32025 self.write_space();
32026 if let Some(ref denom) = sample.bucket_denominator {
32027 self.generate_expression(denom)?;
32028 }
32029 if let Some(ref field) = sample.bucket_field {
32030 self.write_space();
32031 self.write_keyword("ON");
32032 self.write_space();
32033 self.generate_expression(field)?;
32034 }
32035 self.write(")");
32036 return Ok(());
32037 }
32038
32039 let is_snowflake = matches!(
32041 self.config.dialect,
32042 Some(crate::dialects::DialectType::Snowflake)
32043 );
32044 let is_postgres = matches!(
32045 self.config.dialect,
32046 Some(crate::dialects::DialectType::PostgreSQL)
32047 | Some(crate::dialects::DialectType::Redshift)
32048 );
32049 let is_databricks = matches!(
32051 self.config.dialect,
32052 Some(crate::dialects::DialectType::Databricks)
32053 );
32054 let is_spark = matches!(
32055 self.config.dialect,
32056 Some(crate::dialects::DialectType::Spark)
32057 );
32058 let suppress_method = is_databricks || is_spark || sample.suppress_method_output;
32059 let force_method = is_postgres && matches!(sample.method, SampleMethod::Bernoulli);
32061 if !suppress_method && (sample.explicit_method || is_snowflake || force_method) {
32062 self.write_space();
32063 if !sample.explicit_method && (is_snowflake || force_method) {
32064 self.write_keyword("BERNOULLI");
32066 } else {
32067 match sample.method {
32068 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
32069 SampleMethod::System => self.write_keyword("SYSTEM"),
32070 SampleMethod::Block => self.write_keyword("BLOCK"),
32071 SampleMethod::Row => self.write_keyword("ROW"),
32072 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
32073 SampleMethod::Percent => self.write_keyword("SYSTEM"),
32074 SampleMethod::Bucket => {} }
32076 }
32077 }
32078
32079 let emit_size_no_parens = !self.config.tablesample_requires_parens;
32081 if emit_size_no_parens {
32082 self.write_space();
32083 match &sample.size {
32084 Expression::Tuple(tuple) => {
32085 for (i, expr) in tuple.expressions.iter().enumerate() {
32086 if i > 0 {
32087 self.write(", ");
32088 }
32089 self.generate_expression(expr)?;
32090 }
32091 }
32092 expr => self.generate_expression(expr)?,
32093 }
32094 } else {
32095 self.write(" (");
32096 self.generate_expression(&sample.size)?;
32097 }
32098
32099 let is_rows_method = matches!(
32101 sample.method,
32102 SampleMethod::Reservoir | SampleMethod::Row | SampleMethod::Bucket
32103 );
32104 let is_percent = matches!(
32105 sample.method,
32106 SampleMethod::Percent
32107 | SampleMethod::System
32108 | SampleMethod::Bernoulli
32109 | SampleMethod::Block
32110 );
32111
32112 let is_presto = matches!(
32116 self.config.dialect,
32117 Some(crate::dialects::DialectType::Presto)
32118 | Some(crate::dialects::DialectType::Trino)
32119 | Some(crate::dialects::DialectType::Athena)
32120 );
32121 let should_output_unit = if is_databricks || is_spark {
32122 is_percent || is_rows_method || sample.unit_after_size
32124 } else if is_snowflake || is_postgres || is_presto {
32125 sample.unit_after_size
32126 } else {
32127 sample.unit_after_size || (sample.explicit_method && (is_rows_method || is_percent))
32128 };
32129
32130 if should_output_unit {
32131 self.write_space();
32132 if sample.is_percent {
32133 self.write_keyword("PERCENT");
32134 } else if is_rows_method && !sample.unit_after_size {
32135 self.write_keyword("ROWS");
32136 } else if sample.unit_after_size {
32137 match sample.method {
32138 SampleMethod::Percent
32139 | SampleMethod::System
32140 | SampleMethod::Bernoulli
32141 | SampleMethod::Block => {
32142 self.write_keyword("PERCENT");
32143 }
32144 SampleMethod::Row | SampleMethod::Reservoir => {
32145 self.write_keyword("ROWS");
32146 }
32147 _ => self.write_keyword("ROWS"),
32148 }
32149 } else {
32150 self.write_keyword("PERCENT");
32151 }
32152 }
32153
32154 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
32155 if let Some(ref offset) = sample.offset {
32156 self.write_space();
32157 self.write_keyword("OFFSET");
32158 self.write_space();
32159 self.generate_expression(offset)?;
32160 }
32161 }
32162 if !emit_size_no_parens {
32163 self.write(")");
32164 }
32165
32166 Ok(())
32167 }
32168
32169 fn generate_sample_property(&mut self, e: &SampleProperty) -> Result<()> {
32170 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
32172 self.write_keyword("SAMPLE BY");
32173 } else {
32174 self.write_keyword("SAMPLE");
32175 }
32176 self.write_space();
32177 self.generate_expression(&e.this)?;
32178 Ok(())
32179 }
32180
32181 fn generate_schema(&mut self, e: &Schema) -> Result<()> {
32182 if let Some(this) = &e.this {
32184 self.generate_expression(this)?;
32185 }
32186 if !e.expressions.is_empty() {
32187 if e.this.is_some() {
32189 self.write_space();
32190 }
32191 self.write("(");
32192 for (i, expr) in e.expressions.iter().enumerate() {
32193 if i > 0 {
32194 self.write(", ");
32195 }
32196 self.generate_expression(expr)?;
32197 }
32198 self.write(")");
32199 }
32200 Ok(())
32201 }
32202
32203 fn generate_schema_comment_property(&mut self, e: &SchemaCommentProperty) -> Result<()> {
32204 self.write_keyword("COMMENT");
32206 self.write_space();
32207 self.generate_expression(&e.this)?;
32208 Ok(())
32209 }
32210
32211 fn generate_scope_resolution(&mut self, e: &ScopeResolution) -> Result<()> {
32212 if let Some(this) = &e.this {
32214 self.generate_expression(this)?;
32215 self.write("::");
32216 }
32217 self.generate_expression(&e.expression)?;
32218 Ok(())
32219 }
32220
32221 fn generate_search(&mut self, e: &Search) -> Result<()> {
32222 self.write_keyword("SEARCH");
32224 self.write("(");
32225 self.generate_expression(&e.this)?;
32226 self.write(", ");
32227 self.generate_expression(&e.expression)?;
32228 if let Some(json_scope) = &e.json_scope {
32229 self.write(", ");
32230 self.generate_expression(json_scope)?;
32231 }
32232 if let Some(analyzer) = &e.analyzer {
32233 self.write(", ");
32234 self.generate_expression(analyzer)?;
32235 }
32236 if let Some(analyzer_options) = &e.analyzer_options {
32237 self.write(", ");
32238 self.generate_expression(analyzer_options)?;
32239 }
32240 if let Some(search_mode) = &e.search_mode {
32241 self.write(", ");
32242 self.generate_expression(search_mode)?;
32243 }
32244 self.write(")");
32245 Ok(())
32246 }
32247
32248 fn generate_search_ip(&mut self, e: &SearchIp) -> Result<()> {
32249 self.write_keyword("SEARCH_IP");
32251 self.write("(");
32252 self.generate_expression(&e.this)?;
32253 self.write(", ");
32254 self.generate_expression(&e.expression)?;
32255 self.write(")");
32256 Ok(())
32257 }
32258
32259 fn generate_security_property(&mut self, e: &SecurityProperty) -> Result<()> {
32260 self.write_keyword("SECURITY");
32262 self.write_space();
32263 self.generate_expression(&e.this)?;
32264 Ok(())
32265 }
32266
32267 fn generate_semantic_view(&mut self, e: &SemanticView) -> Result<()> {
32268 self.write("SEMANTIC_VIEW(");
32270
32271 if self.config.pretty {
32272 self.write_newline();
32274 self.indent_level += 1;
32275 self.write_indent();
32276 self.generate_expression(&e.this)?;
32277
32278 if let Some(metrics) = &e.metrics {
32279 self.write_newline();
32280 self.write_indent();
32281 self.write_keyword("METRICS");
32282 self.write_space();
32283 self.generate_semantic_view_tuple(metrics)?;
32284 }
32285 if let Some(dimensions) = &e.dimensions {
32286 self.write_newline();
32287 self.write_indent();
32288 self.write_keyword("DIMENSIONS");
32289 self.write_space();
32290 self.generate_semantic_view_tuple(dimensions)?;
32291 }
32292 if let Some(facts) = &e.facts {
32293 self.write_newline();
32294 self.write_indent();
32295 self.write_keyword("FACTS");
32296 self.write_space();
32297 self.generate_semantic_view_tuple(facts)?;
32298 }
32299 if let Some(where_) = &e.where_ {
32300 self.write_newline();
32301 self.write_indent();
32302 self.write_keyword("WHERE");
32303 self.write_space();
32304 self.generate_expression(where_)?;
32305 }
32306 self.write_newline();
32307 self.indent_level -= 1;
32308 self.write_indent();
32309 } else {
32310 self.generate_expression(&e.this)?;
32312 if let Some(metrics) = &e.metrics {
32313 self.write_space();
32314 self.write_keyword("METRICS");
32315 self.write_space();
32316 self.generate_semantic_view_tuple(metrics)?;
32317 }
32318 if let Some(dimensions) = &e.dimensions {
32319 self.write_space();
32320 self.write_keyword("DIMENSIONS");
32321 self.write_space();
32322 self.generate_semantic_view_tuple(dimensions)?;
32323 }
32324 if let Some(facts) = &e.facts {
32325 self.write_space();
32326 self.write_keyword("FACTS");
32327 self.write_space();
32328 self.generate_semantic_view_tuple(facts)?;
32329 }
32330 if let Some(where_) = &e.where_ {
32331 self.write_space();
32332 self.write_keyword("WHERE");
32333 self.write_space();
32334 self.generate_expression(where_)?;
32335 }
32336 }
32337 self.write(")");
32338 Ok(())
32339 }
32340
32341 fn generate_semantic_view_tuple(&mut self, expr: &Expression) -> Result<()> {
32343 if let Expression::Tuple(t) = expr {
32344 for (i, e) in t.expressions.iter().enumerate() {
32345 if i > 0 {
32346 self.write(", ");
32347 }
32348 self.generate_expression(e)?;
32349 }
32350 } else {
32351 self.generate_expression(expr)?;
32352 }
32353 Ok(())
32354 }
32355
32356 fn generate_sequence_properties(&mut self, e: &SequenceProperties) -> Result<()> {
32357 if let Some(start) = &e.start {
32359 self.write_keyword("START WITH");
32360 self.write_space();
32361 self.generate_expression(start)?;
32362 }
32363 if let Some(increment) = &e.increment {
32364 self.write_space();
32365 self.write_keyword("INCREMENT BY");
32366 self.write_space();
32367 self.generate_expression(increment)?;
32368 }
32369 if let Some(minvalue) = &e.minvalue {
32370 self.write_space();
32371 self.write_keyword("MINVALUE");
32372 self.write_space();
32373 self.generate_expression(minvalue)?;
32374 }
32375 if let Some(maxvalue) = &e.maxvalue {
32376 self.write_space();
32377 self.write_keyword("MAXVALUE");
32378 self.write_space();
32379 self.generate_expression(maxvalue)?;
32380 }
32381 if let Some(cache) = &e.cache {
32382 self.write_space();
32383 self.write_keyword("CACHE");
32384 self.write_space();
32385 self.generate_expression(cache)?;
32386 }
32387 if let Some(owned) = &e.owned {
32388 self.write_space();
32389 self.write_keyword("OWNED BY");
32390 self.write_space();
32391 self.generate_expression(owned)?;
32392 }
32393 for opt in &e.options {
32394 self.write_space();
32395 self.generate_expression(opt)?;
32396 }
32397 Ok(())
32398 }
32399
32400 fn generate_serde_properties(&mut self, e: &SerdeProperties) -> Result<()> {
32401 if e.with_.is_some() {
32403 self.write_keyword("WITH");
32404 self.write_space();
32405 }
32406 self.write_keyword("SERDEPROPERTIES");
32407 self.write(" (");
32408 for (i, expr) in e.expressions.iter().enumerate() {
32409 if i > 0 {
32410 self.write(", ");
32411 }
32412 match expr {
32414 Expression::Eq(eq) => {
32415 self.generate_expression(&eq.left)?;
32416 self.write("=");
32417 self.generate_expression(&eq.right)?;
32418 }
32419 _ => self.generate_expression(expr)?,
32420 }
32421 }
32422 self.write(")");
32423 Ok(())
32424 }
32425
32426 fn generate_session_parameter(&mut self, e: &SessionParameter) -> Result<()> {
32427 self.write("@@");
32429 if let Some(kind) = &e.kind {
32430 self.write(kind);
32431 self.write(".");
32432 }
32433 self.generate_expression(&e.this)?;
32434 Ok(())
32435 }
32436
32437 fn generate_set(&mut self, e: &Set) -> Result<()> {
32438 if e.unset.is_some() {
32440 self.write_keyword("UNSET");
32441 } else {
32442 self.write_keyword("SET");
32443 }
32444 if e.tag.is_some() {
32445 self.write_space();
32446 self.write_keyword("TAG");
32447 }
32448 if !e.expressions.is_empty() {
32449 self.write_space();
32450 for (i, expr) in e.expressions.iter().enumerate() {
32451 if i > 0 {
32452 self.write(", ");
32453 }
32454 self.generate_expression(expr)?;
32455 }
32456 }
32457 Ok(())
32458 }
32459
32460 fn generate_set_config_property(&mut self, e: &SetConfigProperty) -> Result<()> {
32461 self.write_keyword("SET");
32463 self.write_space();
32464 self.generate_expression(&e.this)?;
32465 Ok(())
32466 }
32467
32468 fn generate_set_item(&mut self, e: &SetItem) -> Result<()> {
32469 if let Some(kind) = &e.kind {
32471 self.write_keyword(kind);
32472 self.write_space();
32473 }
32474 self.generate_expression(&e.name)?;
32475 self.write(" = ");
32476 self.generate_expression(&e.value)?;
32477 Ok(())
32478 }
32479
32480 fn generate_set_operation(&mut self, e: &SetOperation) -> Result<()> {
32481 if let Some(with_) = &e.with_ {
32483 self.generate_expression(with_)?;
32484 self.write_space();
32485 }
32486 self.generate_expression(&e.this)?;
32487 self.write_space();
32488 if let Some(kind) = &e.kind {
32490 self.write_keyword(kind);
32491 }
32492 if e.distinct {
32493 self.write_space();
32494 self.write_keyword("DISTINCT");
32495 } else {
32496 self.write_space();
32497 self.write_keyword("ALL");
32498 }
32499 if e.by_name.is_some() {
32500 self.write_space();
32501 self.write_keyword("BY NAME");
32502 }
32503 self.write_space();
32504 self.generate_expression(&e.expression)?;
32505 Ok(())
32506 }
32507
32508 fn generate_set_property(&mut self, e: &SetProperty) -> Result<()> {
32509 if e.multi.is_some() {
32511 self.write_keyword("MULTISET");
32512 } else {
32513 self.write_keyword("SET");
32514 }
32515 Ok(())
32516 }
32517
32518 fn generate_settings_property(&mut self, e: &SettingsProperty) -> Result<()> {
32519 self.write_keyword("SETTINGS");
32521 if self.config.pretty && e.expressions.len() > 1 {
32522 self.indent_level += 1;
32524 for (i, expr) in e.expressions.iter().enumerate() {
32525 if i > 0 {
32526 self.write(",");
32527 }
32528 self.write_newline();
32529 self.write_indent();
32530 self.generate_expression(expr)?;
32531 }
32532 self.indent_level -= 1;
32533 } else {
32534 self.write_space();
32535 for (i, expr) in e.expressions.iter().enumerate() {
32536 if i > 0 {
32537 self.write(", ");
32538 }
32539 self.generate_expression(expr)?;
32540 }
32541 }
32542 Ok(())
32543 }
32544
32545 fn generate_sharing_property(&mut self, e: &SharingProperty) -> Result<()> {
32546 self.write_keyword("SHARING");
32548 if let Some(this) = &e.this {
32549 self.write(" = ");
32550 self.generate_expression(this)?;
32551 }
32552 Ok(())
32553 }
32554
32555 fn generate_slice(&mut self, e: &Slice) -> Result<()> {
32556 if let Some(begin) = &e.this {
32558 self.generate_expression(begin)?;
32559 }
32560 self.write(":");
32561 if let Some(end) = &e.expression {
32562 self.generate_expression(end)?;
32563 }
32564 if let Some(step) = &e.step {
32565 self.write(":");
32566 self.generate_expression(step)?;
32567 }
32568 Ok(())
32569 }
32570
32571 fn generate_sort_array(&mut self, e: &SortArray) -> Result<()> {
32572 self.write_keyword("SORT_ARRAY");
32574 self.write("(");
32575 self.generate_expression(&e.this)?;
32576 if let Some(asc) = &e.asc {
32577 self.write(", ");
32578 self.generate_expression(asc)?;
32579 }
32580 self.write(")");
32581 Ok(())
32582 }
32583
32584 fn generate_sort_by(&mut self, e: &SortBy) -> Result<()> {
32585 self.write_keyword("SORT BY");
32587 self.write_space();
32588 for (i, expr) in e.expressions.iter().enumerate() {
32589 if i > 0 {
32590 self.write(", ");
32591 }
32592 self.generate_ordered(expr)?;
32593 }
32594 Ok(())
32595 }
32596
32597 fn generate_sort_key_property(&mut self, e: &SortKeyProperty) -> Result<()> {
32598 if e.compound.is_some() {
32600 self.write_keyword("COMPOUND");
32601 self.write_space();
32602 }
32603 self.write_keyword("SORTKEY");
32604 self.write("(");
32605 if let Expression::Tuple(t) = e.this.as_ref() {
32607 for (i, expr) in t.expressions.iter().enumerate() {
32608 if i > 0 {
32609 self.write(", ");
32610 }
32611 self.generate_expression(expr)?;
32612 }
32613 } else {
32614 self.generate_expression(&e.this)?;
32615 }
32616 self.write(")");
32617 Ok(())
32618 }
32619
32620 fn generate_split_part(&mut self, e: &SplitPart) -> Result<()> {
32621 self.write_keyword("SPLIT_PART");
32623 self.write("(");
32624 self.generate_expression(&e.this)?;
32625 if let Some(delimiter) = &e.delimiter {
32626 self.write(", ");
32627 self.generate_expression(delimiter)?;
32628 }
32629 if let Some(part_index) = &e.part_index {
32630 self.write(", ");
32631 self.generate_expression(part_index)?;
32632 }
32633 self.write(")");
32634 Ok(())
32635 }
32636
32637 fn generate_sql_read_write_property(&mut self, e: &SqlReadWriteProperty) -> Result<()> {
32638 self.generate_expression(&e.this)?;
32640 Ok(())
32641 }
32642
32643 fn generate_sql_security_property(&mut self, e: &SqlSecurityProperty) -> Result<()> {
32644 self.write_keyword("SQL SECURITY");
32646 self.write_space();
32647 self.generate_expression(&e.this)?;
32648 Ok(())
32649 }
32650
32651 fn generate_st_distance(&mut self, e: &StDistance) -> Result<()> {
32652 self.write_keyword("ST_DISTANCE");
32654 self.write("(");
32655 self.generate_expression(&e.this)?;
32656 self.write(", ");
32657 self.generate_expression(&e.expression)?;
32658 if let Some(use_spheroid) = &e.use_spheroid {
32659 self.write(", ");
32660 self.generate_expression(use_spheroid)?;
32661 }
32662 self.write(")");
32663 Ok(())
32664 }
32665
32666 fn generate_st_point(&mut self, e: &StPoint) -> Result<()> {
32667 self.write_keyword("ST_POINT");
32669 self.write("(");
32670 self.generate_expression(&e.this)?;
32671 self.write(", ");
32672 self.generate_expression(&e.expression)?;
32673 self.write(")");
32674 Ok(())
32675 }
32676
32677 fn generate_stability_property(&mut self, e: &StabilityProperty) -> Result<()> {
32678 self.generate_expression(&e.this)?;
32680 Ok(())
32681 }
32682
32683 fn generate_standard_hash(&mut self, e: &StandardHash) -> Result<()> {
32684 self.write_keyword("STANDARD_HASH");
32686 self.write("(");
32687 self.generate_expression(&e.this)?;
32688 if let Some(expression) = &e.expression {
32689 self.write(", ");
32690 self.generate_expression(expression)?;
32691 }
32692 self.write(")");
32693 Ok(())
32694 }
32695
32696 fn generate_storage_handler_property(&mut self, e: &StorageHandlerProperty) -> Result<()> {
32697 self.write_keyword("STORED BY");
32699 self.write_space();
32700 self.generate_expression(&e.this)?;
32701 Ok(())
32702 }
32703
32704 fn generate_str_position(&mut self, e: &StrPosition) -> Result<()> {
32705 use crate::dialects::DialectType;
32708 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
32709 self.write_keyword("CHARINDEX");
32711 self.write("(");
32712 if let Some(substr) = &e.substr {
32713 self.generate_expression(substr)?;
32714 self.write(", ");
32715 }
32716 self.generate_expression(&e.this)?;
32717 if let Some(position) = &e.position {
32718 self.write(", ");
32719 self.generate_expression(position)?;
32720 }
32721 self.write(")");
32722 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
32723 self.write_keyword("POSITION");
32724 self.write("(");
32725 self.generate_expression(&e.this)?;
32726 if let Some(substr) = &e.substr {
32727 self.write(", ");
32728 self.generate_expression(substr)?;
32729 }
32730 if let Some(position) = &e.position {
32731 self.write(", ");
32732 self.generate_expression(position)?;
32733 }
32734 if let Some(occurrence) = &e.occurrence {
32735 self.write(", ");
32736 self.generate_expression(occurrence)?;
32737 }
32738 self.write(")");
32739 } else if matches!(
32740 self.config.dialect,
32741 Some(DialectType::SQLite)
32742 | Some(DialectType::Oracle)
32743 | Some(DialectType::BigQuery)
32744 | Some(DialectType::Teradata)
32745 ) {
32746 self.write_keyword("INSTR");
32747 self.write("(");
32748 self.generate_expression(&e.this)?;
32749 if let Some(substr) = &e.substr {
32750 self.write(", ");
32751 self.generate_expression(substr)?;
32752 }
32753 if let Some(position) = &e.position {
32754 self.write(", ");
32755 self.generate_expression(position)?;
32756 } else if e.occurrence.is_some() {
32757 self.write(", 1");
32760 }
32761 if let Some(occurrence) = &e.occurrence {
32762 self.write(", ");
32763 self.generate_expression(occurrence)?;
32764 }
32765 self.write(")");
32766 } else if matches!(
32767 self.config.dialect,
32768 Some(DialectType::MySQL)
32769 | Some(DialectType::SingleStore)
32770 | Some(DialectType::Doris)
32771 | Some(DialectType::StarRocks)
32772 | Some(DialectType::Hive)
32773 | Some(DialectType::Spark)
32774 | Some(DialectType::Databricks)
32775 ) {
32776 self.write_keyword("LOCATE");
32778 self.write("(");
32779 if let Some(substr) = &e.substr {
32780 self.generate_expression(substr)?;
32781 self.write(", ");
32782 }
32783 self.generate_expression(&e.this)?;
32784 if let Some(position) = &e.position {
32785 self.write(", ");
32786 self.generate_expression(position)?;
32787 }
32788 self.write(")");
32789 } else if matches!(self.config.dialect, Some(DialectType::TSQL)) {
32790 self.write_keyword("CHARINDEX");
32792 self.write("(");
32793 if let Some(substr) = &e.substr {
32794 self.generate_expression(substr)?;
32795 self.write(", ");
32796 }
32797 self.generate_expression(&e.this)?;
32798 if let Some(position) = &e.position {
32799 self.write(", ");
32800 self.generate_expression(position)?;
32801 }
32802 self.write(")");
32803 } else if matches!(
32804 self.config.dialect,
32805 Some(DialectType::PostgreSQL)
32806 | Some(DialectType::Materialize)
32807 | Some(DialectType::RisingWave)
32808 | Some(DialectType::Redshift)
32809 ) {
32810 self.write_keyword("POSITION");
32812 self.write("(");
32813 if let Some(substr) = &e.substr {
32814 self.generate_expression(substr)?;
32815 self.write(" IN ");
32816 }
32817 self.generate_expression(&e.this)?;
32818 self.write(")");
32819 } else {
32820 self.write_keyword("STRPOS");
32821 self.write("(");
32822 self.generate_expression(&e.this)?;
32823 if let Some(substr) = &e.substr {
32824 self.write(", ");
32825 self.generate_expression(substr)?;
32826 }
32827 if let Some(position) = &e.position {
32828 self.write(", ");
32829 self.generate_expression(position)?;
32830 }
32831 if let Some(occurrence) = &e.occurrence {
32832 self.write(", ");
32833 self.generate_expression(occurrence)?;
32834 }
32835 self.write(")");
32836 }
32837 Ok(())
32838 }
32839
32840 fn generate_str_to_date(&mut self, e: &StrToDate) -> Result<()> {
32841 match self.config.dialect {
32842 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
32843 self.write_keyword("TO_DATE");
32845 self.write("(");
32846 self.generate_expression(&e.this)?;
32847 if let Some(format) = &e.format {
32848 self.write(", '");
32849 self.write(&Self::strftime_to_java_format(format));
32850 self.write("'");
32851 }
32852 self.write(")");
32853 }
32854 Some(DialectType::DuckDB) => {
32855 self.write_keyword("CAST");
32857 self.write("(");
32858 self.write_keyword("STRPTIME");
32859 self.write("(");
32860 self.generate_expression(&e.this)?;
32861 if let Some(format) = &e.format {
32862 self.write(", '");
32863 self.write(format);
32864 self.write("'");
32865 }
32866 self.write(")");
32867 self.write_keyword(" AS ");
32868 self.write_keyword("DATE");
32869 self.write(")");
32870 }
32871 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
32872 self.write_keyword("TO_DATE");
32874 self.write("(");
32875 self.generate_expression(&e.this)?;
32876 if let Some(format) = &e.format {
32877 self.write(", '");
32878 self.write(&Self::strftime_to_postgres_format(format));
32879 self.write("'");
32880 }
32881 self.write(")");
32882 }
32883 Some(DialectType::BigQuery) => {
32884 self.write_keyword("PARSE_DATE");
32886 self.write("(");
32887 if let Some(format) = &e.format {
32888 self.write("'");
32889 self.write(format);
32890 self.write("'");
32891 self.write(", ");
32892 }
32893 self.generate_expression(&e.this)?;
32894 self.write(")");
32895 }
32896 Some(DialectType::Teradata) => {
32897 self.write_keyword("CAST");
32899 self.write("(");
32900 self.generate_expression(&e.this)?;
32901 self.write_keyword(" AS ");
32902 self.write_keyword("DATE");
32903 if let Some(format) = &e.format {
32904 self.write_keyword(" FORMAT ");
32905 self.write("'");
32906 self.write(&Self::strftime_to_teradata_format(format));
32907 self.write("'");
32908 }
32909 self.write(")");
32910 }
32911 _ => {
32912 self.write_keyword("STR_TO_DATE");
32914 self.write("(");
32915 self.generate_expression(&e.this)?;
32916 if let Some(format) = &e.format {
32917 self.write(", '");
32918 self.write(format);
32919 self.write("'");
32920 }
32921 self.write(")");
32922 }
32923 }
32924 Ok(())
32925 }
32926
32927 fn strftime_to_teradata_format(fmt: &str) -> String {
32929 let mut result = fmt.to_string();
32930 result = result.replace("%Y", "YYYY");
32931 result = result.replace("%y", "YY");
32932 result = result.replace("%m", "MM");
32933 result = result.replace("%B", "MMMM");
32934 result = result.replace("%b", "MMM");
32935 result = result.replace("%d", "DD");
32936 result = result.replace("%j", "DDD");
32937 result = result.replace("%H", "HH");
32938 result = result.replace("%M", "MI");
32939 result = result.replace("%S", "SS");
32940 result = result.replace("%f", "SSSSSS");
32941 result = result.replace("%A", "EEEE");
32942 result = result.replace("%a", "EEE");
32943 result
32944 }
32945
32946 pub fn strftime_to_java_format_static(fmt: &str) -> String {
32949 Self::strftime_to_java_format(fmt)
32950 }
32951
32952 fn strftime_to_java_format(fmt: &str) -> String {
32954 let mut result = fmt.to_string();
32955 result = result.replace("%-d", "d");
32957 result = result.replace("%-m", "M");
32958 result = result.replace("%-H", "H");
32959 result = result.replace("%-M", "m");
32960 result = result.replace("%-S", "s");
32961 result = result.replace("%Y", "yyyy");
32962 result = result.replace("%y", "yy");
32963 result = result.replace("%m", "MM");
32964 result = result.replace("%B", "MMMM");
32965 result = result.replace("%b", "MMM");
32966 result = result.replace("%d", "dd");
32967 result = result.replace("%j", "DDD");
32968 result = result.replace("%H", "HH");
32969 result = result.replace("%M", "mm");
32970 result = result.replace("%S", "ss");
32971 result = result.replace("%f", "SSSSSS");
32972 result = result.replace("%A", "EEEE");
32973 result = result.replace("%a", "EEE");
32974 result
32975 }
32976
32977 fn strftime_to_tsql_format(fmt: &str) -> String {
32980 let mut result = fmt.to_string();
32981 result = result.replace("%-d", "d");
32983 result = result.replace("%-m", "M");
32984 result = result.replace("%-H", "H");
32985 result = result.replace("%-M", "m");
32986 result = result.replace("%-S", "s");
32987 result = result.replace("%Y", "yyyy");
32988 result = result.replace("%y", "yy");
32989 result = result.replace("%m", "MM");
32990 result = result.replace("%B", "MMMM");
32991 result = result.replace("%b", "MMM");
32992 result = result.replace("%d", "dd");
32993 result = result.replace("%j", "DDD");
32994 result = result.replace("%H", "HH");
32995 result = result.replace("%M", "mm");
32996 result = result.replace("%S", "ss");
32997 result = result.replace("%f", "ffffff");
32998 result = result.replace("%A", "dddd");
32999 result = result.replace("%a", "ddd");
33000 result
33001 }
33002
33003 fn decompose_json_path(path: &str) -> Vec<String> {
33006 let mut parts = Vec::new();
33007 let path = if path.starts_with("$.") {
33009 &path[2..]
33010 } else if path.starts_with('$') {
33011 &path[1..]
33012 } else {
33013 path
33014 };
33015 if path.is_empty() {
33016 return parts;
33017 }
33018 let mut current = String::new();
33019 let chars: Vec<char> = path.chars().collect();
33020 let mut i = 0;
33021 while i < chars.len() {
33022 match chars[i] {
33023 '.' => {
33024 if !current.is_empty() {
33025 parts.push(current.clone());
33026 current.clear();
33027 }
33028 i += 1;
33029 }
33030 '[' => {
33031 if !current.is_empty() {
33032 parts.push(current.clone());
33033 current.clear();
33034 }
33035 i += 1;
33036 let mut bracket_content = String::new();
33038 while i < chars.len() && chars[i] != ']' {
33039 if chars[i] == '"' || chars[i] == '\'' {
33041 let quote = chars[i];
33042 i += 1;
33043 while i < chars.len() && chars[i] != quote {
33044 bracket_content.push(chars[i]);
33045 i += 1;
33046 }
33047 if i < chars.len() {
33048 i += 1;
33049 } } else {
33051 bracket_content.push(chars[i]);
33052 i += 1;
33053 }
33054 }
33055 if i < chars.len() {
33056 i += 1;
33057 } if bracket_content != "*" {
33060 parts.push(bracket_content);
33061 }
33062 }
33063 _ => {
33064 current.push(chars[i]);
33065 i += 1;
33066 }
33067 }
33068 }
33069 if !current.is_empty() {
33070 parts.push(current);
33071 }
33072 parts
33073 }
33074
33075 fn strftime_to_postgres_format(fmt: &str) -> String {
33077 let mut result = fmt.to_string();
33078 result = result.replace("%-d", "FMDD");
33080 result = result.replace("%-m", "FMMM");
33081 result = result.replace("%-H", "FMHH24");
33082 result = result.replace("%-M", "FMMI");
33083 result = result.replace("%-S", "FMSS");
33084 result = result.replace("%Y", "YYYY");
33085 result = result.replace("%y", "YY");
33086 result = result.replace("%m", "MM");
33087 result = result.replace("%B", "Month");
33088 result = result.replace("%b", "Mon");
33089 result = result.replace("%d", "DD");
33090 result = result.replace("%j", "DDD");
33091 result = result.replace("%H", "HH24");
33092 result = result.replace("%M", "MI");
33093 result = result.replace("%S", "SS");
33094 result = result.replace("%f", "US");
33095 result = result.replace("%A", "Day");
33096 result = result.replace("%a", "Dy");
33097 result
33098 }
33099
33100 fn strftime_to_snowflake_format(fmt: &str) -> String {
33102 let mut result = fmt.to_string();
33103 result = result.replace("%-d", "dd");
33105 result = result.replace("%-m", "mm"); result = result.replace("%Y", "yyyy");
33107 result = result.replace("%y", "yy");
33108 result = result.replace("%m", "mm");
33109 result = result.replace("%d", "DD");
33110 result = result.replace("%H", "hh24");
33111 result = result.replace("%M", "mi");
33112 result = result.replace("%S", "ss");
33113 result = result.replace("%f", "ff");
33114 result
33115 }
33116
33117 fn generate_str_to_map(&mut self, e: &StrToMap) -> Result<()> {
33118 self.write_keyword("STR_TO_MAP");
33120 self.write("(");
33121 self.generate_expression(&e.this)?;
33122 let needs_defaults = matches!(
33124 self.config.dialect,
33125 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
33126 );
33127 if let Some(pair_delim) = &e.pair_delim {
33128 self.write(", ");
33129 self.generate_expression(pair_delim)?;
33130 } else if needs_defaults {
33131 self.write(", ','");
33132 }
33133 if let Some(key_value_delim) = &e.key_value_delim {
33134 self.write(", ");
33135 self.generate_expression(key_value_delim)?;
33136 } else if needs_defaults {
33137 self.write(", ':'");
33138 }
33139 self.write(")");
33140 Ok(())
33141 }
33142
33143 fn generate_str_to_time(&mut self, e: &StrToTime) -> Result<()> {
33144 let is_strftime = e.format.contains('%');
33146 let to_strftime = |f: &str| -> String {
33148 if is_strftime {
33149 f.to_string()
33150 } else {
33151 Self::snowflake_format_to_strftime(f)
33152 }
33153 };
33154 let to_java = |f: &str| -> String {
33156 if is_strftime {
33157 Self::strftime_to_java_format(f)
33158 } else {
33159 Self::snowflake_format_to_spark(f)
33160 }
33161 };
33162 let to_pg = |f: &str| -> String {
33164 if is_strftime {
33165 Self::strftime_to_postgres_format(f)
33166 } else {
33167 Self::convert_strptime_to_postgres_format(f)
33168 }
33169 };
33170
33171 match self.config.dialect {
33172 Some(DialectType::Exasol) => {
33173 self.write_keyword("TO_DATE");
33174 self.write("(");
33175 self.generate_expression(&e.this)?;
33176 self.write(", '");
33177 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
33178 self.write("'");
33179 self.write(")");
33180 }
33181 Some(DialectType::BigQuery) => {
33182 let fmt = to_strftime(&e.format);
33184 let fmt = fmt.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
33186 self.write_keyword("PARSE_TIMESTAMP");
33187 self.write("('");
33188 self.write(&fmt);
33189 self.write("', ");
33190 self.generate_expression(&e.this)?;
33191 self.write(")");
33192 }
33193 Some(DialectType::Hive) => {
33194 let java_fmt = to_java(&e.format);
33197 if java_fmt == "yyyy-MM-dd HH:mm:ss"
33198 || java_fmt == "yyyy-MM-dd"
33199 || e.format == "yyyy-MM-dd HH:mm:ss"
33200 || e.format == "yyyy-MM-dd"
33201 {
33202 self.write_keyword("CAST");
33203 self.write("(");
33204 self.generate_expression(&e.this)?;
33205 self.write(" ");
33206 self.write_keyword("AS TIMESTAMP");
33207 self.write(")");
33208 } else {
33209 self.write_keyword("CAST");
33211 self.write("(");
33212 self.write_keyword("FROM_UNIXTIME");
33213 self.write("(");
33214 self.write_keyword("UNIX_TIMESTAMP");
33215 self.write("(");
33216 self.generate_expression(&e.this)?;
33217 self.write(", '");
33218 self.write(&java_fmt);
33219 self.write("')");
33220 self.write(") ");
33221 self.write_keyword("AS TIMESTAMP");
33222 self.write(")");
33223 }
33224 }
33225 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
33226 let java_fmt = to_java(&e.format);
33228 self.write_keyword("TO_TIMESTAMP");
33229 self.write("(");
33230 self.generate_expression(&e.this)?;
33231 self.write(", '");
33232 self.write(&java_fmt);
33233 self.write("')");
33234 }
33235 Some(DialectType::MySQL) => {
33236 let mut fmt = to_strftime(&e.format);
33238 fmt = fmt.replace("%-d", "%e");
33240 fmt = fmt.replace("%-m", "%c");
33241 fmt = fmt.replace("%H:%M:%S", "%T");
33242 self.write_keyword("STR_TO_DATE");
33243 self.write("(");
33244 self.generate_expression(&e.this)?;
33245 self.write(", '");
33246 self.write(&fmt);
33247 self.write("')");
33248 }
33249 Some(DialectType::Drill) => {
33250 let java_fmt = to_java(&e.format);
33252 let java_fmt = java_fmt.replace('T', "''T''");
33254 self.write_keyword("TO_TIMESTAMP");
33255 self.write("(");
33256 self.generate_expression(&e.this)?;
33257 self.write(", '");
33258 self.write(&java_fmt);
33259 self.write("')");
33260 }
33261 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
33262 let mut fmt = to_strftime(&e.format);
33264 fmt = fmt.replace("%-d", "%e");
33266 fmt = fmt.replace("%-m", "%c");
33267 fmt = fmt.replace("%H:%M:%S", "%T");
33268 self.write_keyword("DATE_PARSE");
33269 self.write("(");
33270 self.generate_expression(&e.this)?;
33271 self.write(", '");
33272 self.write(&fmt);
33273 self.write("')");
33274 }
33275 Some(DialectType::DuckDB) => {
33276 let fmt = to_strftime(&e.format);
33278 self.write_keyword("STRPTIME");
33279 self.write("(");
33280 self.generate_expression(&e.this)?;
33281 self.write(", '");
33282 self.write(&fmt);
33283 self.write("')");
33284 }
33285 Some(DialectType::PostgreSQL)
33286 | Some(DialectType::Redshift)
33287 | Some(DialectType::Materialize) => {
33288 let pg_fmt = to_pg(&e.format);
33290 self.write_keyword("TO_TIMESTAMP");
33291 self.write("(");
33292 self.generate_expression(&e.this)?;
33293 self.write(", '");
33294 self.write(&pg_fmt);
33295 self.write("')");
33296 }
33297 Some(DialectType::Oracle) => {
33298 let pg_fmt = to_pg(&e.format);
33300 self.write_keyword("TO_TIMESTAMP");
33301 self.write("(");
33302 self.generate_expression(&e.this)?;
33303 self.write(", '");
33304 self.write(&pg_fmt);
33305 self.write("')");
33306 }
33307 Some(DialectType::Snowflake) => {
33308 self.write_keyword("TO_TIMESTAMP");
33310 self.write("(");
33311 self.generate_expression(&e.this)?;
33312 self.write(", '");
33313 self.write(&e.format);
33314 self.write("')");
33315 }
33316 _ => {
33317 self.write_keyword("STR_TO_TIME");
33319 self.write("(");
33320 self.generate_expression(&e.this)?;
33321 self.write(", '");
33322 self.write(&e.format);
33323 self.write("'");
33324 self.write(")");
33325 }
33326 }
33327 Ok(())
33328 }
33329
33330 fn snowflake_format_to_strftime(format: &str) -> String {
33332 let mut result = String::new();
33333 let chars: Vec<char> = format.chars().collect();
33334 let mut i = 0;
33335 while i < chars.len() {
33336 let remaining = &format[i..];
33337 if remaining.starts_with("yyyy") {
33338 result.push_str("%Y");
33339 i += 4;
33340 } else if remaining.starts_with("yy") {
33341 result.push_str("%y");
33342 i += 2;
33343 } else if remaining.starts_with("mmmm") {
33344 result.push_str("%B"); i += 4;
33346 } else if remaining.starts_with("mon") {
33347 result.push_str("%b"); i += 3;
33349 } else if remaining.starts_with("mm") {
33350 result.push_str("%m");
33351 i += 2;
33352 } else if remaining.starts_with("DD") {
33353 result.push_str("%d");
33354 i += 2;
33355 } else if remaining.starts_with("dy") {
33356 result.push_str("%a"); i += 2;
33358 } else if remaining.starts_with("hh24") {
33359 result.push_str("%H");
33360 i += 4;
33361 } else if remaining.starts_with("hh12") {
33362 result.push_str("%I");
33363 i += 4;
33364 } else if remaining.starts_with("hh") {
33365 result.push_str("%H");
33366 i += 2;
33367 } else if remaining.starts_with("mi") {
33368 result.push_str("%M");
33369 i += 2;
33370 } else if remaining.starts_with("ss") {
33371 result.push_str("%S");
33372 i += 2;
33373 } else if remaining.starts_with("ff") {
33374 result.push_str("%f");
33376 i += 2;
33377 while i < chars.len() && chars[i].is_ascii_digit() {
33379 i += 1;
33380 }
33381 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
33382 result.push_str("%p");
33383 i += 2;
33384 } else if remaining.starts_with("tz") {
33385 result.push_str("%Z");
33386 i += 2;
33387 } else {
33388 result.push(chars[i]);
33389 i += 1;
33390 }
33391 }
33392 result
33393 }
33394
33395 fn snowflake_format_to_spark(format: &str) -> String {
33397 let mut result = String::new();
33398 let chars: Vec<char> = format.chars().collect();
33399 let mut i = 0;
33400 while i < chars.len() {
33401 let remaining = &format[i..];
33402 if remaining.starts_with("yyyy") {
33403 result.push_str("yyyy");
33404 i += 4;
33405 } else if remaining.starts_with("yy") {
33406 result.push_str("yy");
33407 i += 2;
33408 } else if remaining.starts_with("mmmm") {
33409 result.push_str("MMMM"); i += 4;
33411 } else if remaining.starts_with("mon") {
33412 result.push_str("MMM"); i += 3;
33414 } else if remaining.starts_with("mm") {
33415 result.push_str("MM");
33416 i += 2;
33417 } else if remaining.starts_with("DD") {
33418 result.push_str("dd");
33419 i += 2;
33420 } else if remaining.starts_with("dy") {
33421 result.push_str("EEE"); i += 2;
33423 } else if remaining.starts_with("hh24") {
33424 result.push_str("HH");
33425 i += 4;
33426 } else if remaining.starts_with("hh12") {
33427 result.push_str("hh");
33428 i += 4;
33429 } else if remaining.starts_with("hh") {
33430 result.push_str("HH");
33431 i += 2;
33432 } else if remaining.starts_with("mi") {
33433 result.push_str("mm");
33434 i += 2;
33435 } else if remaining.starts_with("ss") {
33436 result.push_str("ss");
33437 i += 2;
33438 } else if remaining.starts_with("ff") {
33439 result.push_str("SSS"); i += 2;
33441 while i < chars.len() && chars[i].is_ascii_digit() {
33443 i += 1;
33444 }
33445 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
33446 result.push_str("a");
33447 i += 2;
33448 } else if remaining.starts_with("tz") {
33449 result.push_str("z");
33450 i += 2;
33451 } else {
33452 result.push(chars[i]);
33453 i += 1;
33454 }
33455 }
33456 result
33457 }
33458
33459 fn generate_str_to_unix(&mut self, e: &StrToUnix) -> Result<()> {
33460 match self.config.dialect {
33461 Some(DialectType::DuckDB) => {
33462 self.write_keyword("EPOCH");
33464 self.write("(");
33465 self.write_keyword("STRPTIME");
33466 self.write("(");
33467 if let Some(this) = &e.this {
33468 self.generate_expression(this)?;
33469 }
33470 if let Some(format) = &e.format {
33471 self.write(", '");
33472 self.write(format);
33473 self.write("'");
33474 }
33475 self.write("))");
33476 }
33477 Some(DialectType::Hive) => {
33478 self.write_keyword("UNIX_TIMESTAMP");
33480 self.write("(");
33481 if let Some(this) = &e.this {
33482 self.generate_expression(this)?;
33483 }
33484 if let Some(format) = &e.format {
33485 let java_fmt = Self::strftime_to_java_format(format);
33486 if java_fmt != "yyyy-MM-dd HH:mm:ss" {
33487 self.write(", '");
33488 self.write(&java_fmt);
33489 self.write("'");
33490 }
33491 }
33492 self.write(")");
33493 }
33494 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
33495 self.write_keyword("UNIX_TIMESTAMP");
33497 self.write("(");
33498 if let Some(this) = &e.this {
33499 self.generate_expression(this)?;
33500 }
33501 if let Some(format) = &e.format {
33502 self.write(", '");
33503 self.write(format);
33504 self.write("'");
33505 }
33506 self.write(")");
33507 }
33508 Some(DialectType::Presto) | Some(DialectType::Trino) => {
33509 let c_fmt = e.format.as_deref().unwrap_or("%Y-%m-%d %T");
33512 let java_fmt = Self::strftime_to_java_format(c_fmt);
33513 self.write_keyword("TO_UNIXTIME");
33514 self.write("(");
33515 self.write_keyword("COALESCE");
33516 self.write("(");
33517 self.write_keyword("TRY");
33518 self.write("(");
33519 self.write_keyword("DATE_PARSE");
33520 self.write("(");
33521 self.write_keyword("CAST");
33522 self.write("(");
33523 if let Some(this) = &e.this {
33524 self.generate_expression(this)?;
33525 }
33526 self.write(" ");
33527 self.write_keyword("AS VARCHAR");
33528 self.write("), '");
33529 self.write(c_fmt);
33530 self.write("')), ");
33531 self.write_keyword("PARSE_DATETIME");
33532 self.write("(");
33533 self.write_keyword("DATE_FORMAT");
33534 self.write("(");
33535 self.write_keyword("CAST");
33536 self.write("(");
33537 if let Some(this) = &e.this {
33538 self.generate_expression(this)?;
33539 }
33540 self.write(" ");
33541 self.write_keyword("AS TIMESTAMP");
33542 self.write("), '");
33543 self.write(c_fmt);
33544 self.write("'), '");
33545 self.write(&java_fmt);
33546 self.write("')))");
33547 }
33548 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
33549 self.write_keyword("UNIX_TIMESTAMP");
33551 self.write("(");
33552 if let Some(this) = &e.this {
33553 self.generate_expression(this)?;
33554 }
33555 if let Some(format) = &e.format {
33556 let java_fmt = Self::strftime_to_java_format(format);
33557 self.write(", '");
33558 self.write(&java_fmt);
33559 self.write("'");
33560 }
33561 self.write(")");
33562 }
33563 _ => {
33564 self.write_keyword("STR_TO_UNIX");
33566 self.write("(");
33567 if let Some(this) = &e.this {
33568 self.generate_expression(this)?;
33569 }
33570 if let Some(format) = &e.format {
33571 self.write(", '");
33572 self.write(format);
33573 self.write("'");
33574 }
33575 self.write(")");
33576 }
33577 }
33578 Ok(())
33579 }
33580
33581 fn generate_string_to_array(&mut self, e: &StringToArray) -> Result<()> {
33582 self.write_keyword("STRING_TO_ARRAY");
33584 self.write("(");
33585 self.generate_expression(&e.this)?;
33586 if let Some(expression) = &e.expression {
33587 self.write(", ");
33588 self.generate_expression(expression)?;
33589 }
33590 if let Some(null_val) = &e.null {
33591 self.write(", ");
33592 self.generate_expression(null_val)?;
33593 }
33594 self.write(")");
33595 Ok(())
33596 }
33597
33598 fn generate_struct(&mut self, e: &Struct) -> Result<()> {
33599 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
33600 self.write_keyword("OBJECT_CONSTRUCT");
33602 self.write("(");
33603 for (i, (name, expr)) in e.fields.iter().enumerate() {
33604 if i > 0 {
33605 self.write(", ");
33606 }
33607 if let Some(name) = name {
33608 self.write("'");
33609 self.write(name);
33610 self.write("'");
33611 self.write(", ");
33612 } else {
33613 self.write("'_");
33614 self.write(&i.to_string());
33615 self.write("'");
33616 self.write(", ");
33617 }
33618 self.generate_expression(expr)?;
33619 }
33620 self.write(")");
33621 } else if self.config.struct_curly_brace_notation {
33622 self.write("{");
33624 for (i, (name, expr)) in e.fields.iter().enumerate() {
33625 if i > 0 {
33626 self.write(", ");
33627 }
33628 if let Some(name) = name {
33629 self.write("'");
33631 self.write(name);
33632 self.write("'");
33633 self.write(": ");
33634 } else {
33635 self.write("'_");
33637 self.write(&i.to_string());
33638 self.write("'");
33639 self.write(": ");
33640 }
33641 self.generate_expression(expr)?;
33642 }
33643 self.write("}");
33644 } else {
33645 let value_as_name = matches!(
33649 self.config.dialect,
33650 Some(DialectType::BigQuery)
33651 | Some(DialectType::Spark)
33652 | Some(DialectType::Databricks)
33653 | Some(DialectType::Hive)
33654 );
33655 self.write_keyword("STRUCT");
33656 self.write("(");
33657 for (i, (name, expr)) in e.fields.iter().enumerate() {
33658 if i > 0 {
33659 self.write(", ");
33660 }
33661 if let Some(name) = name {
33662 if value_as_name {
33663 self.generate_expression(expr)?;
33665 self.write_space();
33666 self.write_keyword("AS");
33667 self.write_space();
33668 let needs_quoting = name.contains(' ') || name.contains('-');
33670 if needs_quoting {
33671 if matches!(
33672 self.config.dialect,
33673 Some(DialectType::Spark)
33674 | Some(DialectType::Databricks)
33675 | Some(DialectType::Hive)
33676 ) {
33677 self.write("`");
33678 self.write(name);
33679 self.write("`");
33680 } else {
33681 self.write(name);
33682 }
33683 } else {
33684 self.write(name);
33685 }
33686 } else {
33687 self.write(name);
33689 self.write_space();
33690 self.write_keyword("AS");
33691 self.write_space();
33692 self.generate_expression(expr)?;
33693 }
33694 } else {
33695 self.generate_expression(expr)?;
33696 }
33697 }
33698 self.write(")");
33699 }
33700 Ok(())
33701 }
33702
33703 fn generate_stuff(&mut self, e: &Stuff) -> Result<()> {
33704 self.write_keyword("STUFF");
33706 self.write("(");
33707 self.generate_expression(&e.this)?;
33708 if let Some(start) = &e.start {
33709 self.write(", ");
33710 self.generate_expression(start)?;
33711 }
33712 if let Some(length) = e.length {
33713 self.write(", ");
33714 self.write(&length.to_string());
33715 }
33716 self.write(", ");
33717 self.generate_expression(&e.expression)?;
33718 self.write(")");
33719 Ok(())
33720 }
33721
33722 fn generate_substring_index(&mut self, e: &SubstringIndex) -> Result<()> {
33723 self.write_keyword("SUBSTRING_INDEX");
33725 self.write("(");
33726 self.generate_expression(&e.this)?;
33727 if let Some(delimiter) = &e.delimiter {
33728 self.write(", ");
33729 self.generate_expression(delimiter)?;
33730 }
33731 if let Some(count) = &e.count {
33732 self.write(", ");
33733 self.generate_expression(count)?;
33734 }
33735 self.write(")");
33736 Ok(())
33737 }
33738
33739 fn generate_summarize(&mut self, e: &Summarize) -> Result<()> {
33740 self.write_keyword("SUMMARIZE");
33742 if e.table.is_some() {
33743 self.write_space();
33744 self.write_keyword("TABLE");
33745 }
33746 self.write_space();
33747 self.generate_expression(&e.this)?;
33748 Ok(())
33749 }
33750
33751 fn generate_systimestamp(&mut self, _e: &Systimestamp) -> Result<()> {
33752 self.write_keyword("SYSTIMESTAMP");
33754 Ok(())
33755 }
33756
33757 fn generate_table_alias(&mut self, e: &TableAlias) -> Result<()> {
33758 if let Some(this) = &e.this {
33760 self.generate_expression(this)?;
33761 }
33762 if !e.columns.is_empty() {
33763 self.write("(");
33764 for (i, col) in e.columns.iter().enumerate() {
33765 if i > 0 {
33766 self.write(", ");
33767 }
33768 self.generate_expression(col)?;
33769 }
33770 self.write(")");
33771 }
33772 Ok(())
33773 }
33774
33775 fn generate_table_from_rows(&mut self, e: &TableFromRows) -> Result<()> {
33776 self.write_keyword("TABLE");
33778 self.write("(");
33779 self.generate_expression(&e.this)?;
33780 self.write(")");
33781 if let Some(alias) = &e.alias {
33782 self.write_space();
33783 self.write_keyword("AS");
33784 self.write_space();
33785 self.write(alias);
33786 }
33787 Ok(())
33788 }
33789
33790 fn generate_rows_from(&mut self, e: &RowsFrom) -> Result<()> {
33791 self.write_keyword("ROWS FROM");
33793 self.write(" (");
33794 for (i, expr) in e.expressions.iter().enumerate() {
33795 if i > 0 {
33796 self.write(", ");
33797 }
33798 match expr {
33802 Expression::Tuple(tuple) if tuple.expressions.len() == 2 => {
33803 self.generate_expression(&tuple.expressions[0])?;
33805 self.write_space();
33806 self.write_keyword("AS");
33807 self.write_space();
33808 self.generate_expression(&tuple.expressions[1])?;
33809 }
33810 _ => {
33811 self.generate_expression(expr)?;
33812 }
33813 }
33814 }
33815 self.write(")");
33816 if e.ordinality {
33817 self.write_space();
33818 self.write_keyword("WITH ORDINALITY");
33819 }
33820 if let Some(alias) = &e.alias {
33821 self.write_space();
33822 self.write_keyword("AS");
33823 self.write_space();
33824 self.generate_expression(alias)?;
33825 }
33826 Ok(())
33827 }
33828
33829 fn generate_table_sample(&mut self, e: &TableSample) -> Result<()> {
33830 use crate::dialects::DialectType;
33831
33832 if let (Some(this), Some(sample)) = (&e.this, &e.sample) {
33834 if self.config.alias_post_tablesample {
33836 if let Expression::Subquery(ref s) = **this {
33838 if let Some(ref alias) = s.alias {
33839 let mut subquery_no_alias = (**s).clone();
33841 subquery_no_alias.alias = None;
33842 subquery_no_alias.column_aliases = Vec::new();
33843 self.generate_expression(&Expression::Subquery(Box::new(
33844 subquery_no_alias,
33845 )))?;
33846 self.write_space();
33847 self.write_keyword("TABLESAMPLE");
33848 self.generate_sample_body(sample)?;
33849 if let Some(ref seed) = sample.seed {
33850 self.write_space();
33851 let use_seed = sample.use_seed_keyword
33852 && !matches!(
33853 self.config.dialect,
33854 Some(crate::dialects::DialectType::Databricks)
33855 | Some(crate::dialects::DialectType::Spark)
33856 );
33857 if use_seed {
33858 self.write_keyword("SEED");
33859 } else {
33860 self.write_keyword("REPEATABLE");
33861 }
33862 self.write(" (");
33863 self.generate_expression(seed)?;
33864 self.write(")");
33865 }
33866 self.write_space();
33867 self.write_keyword("AS");
33868 self.write_space();
33869 self.generate_identifier(alias)?;
33870 return Ok(());
33871 }
33872 } else if let Expression::Alias(ref a) = **this {
33873 self.generate_expression(&a.this)?;
33875 self.write_space();
33876 self.write_keyword("TABLESAMPLE");
33877 self.generate_sample_body(sample)?;
33878 if let Some(ref seed) = sample.seed {
33879 self.write_space();
33880 let use_seed = sample.use_seed_keyword
33881 && !matches!(
33882 self.config.dialect,
33883 Some(crate::dialects::DialectType::Databricks)
33884 | Some(crate::dialects::DialectType::Spark)
33885 );
33886 if use_seed {
33887 self.write_keyword("SEED");
33888 } else {
33889 self.write_keyword("REPEATABLE");
33890 }
33891 self.write(" (");
33892 self.generate_expression(seed)?;
33893 self.write(")");
33894 }
33895 self.write_space();
33897 self.write_keyword("AS");
33898 self.write_space();
33899 self.generate_identifier(&a.alias)?;
33900 return Ok(());
33901 }
33902 }
33903 self.generate_expression(this)?;
33905 self.write_space();
33906 self.write_keyword("TABLESAMPLE");
33907 self.generate_sample_body(sample)?;
33908 if let Some(ref seed) = sample.seed {
33910 self.write_space();
33911 let use_seed = sample.use_seed_keyword
33913 && !matches!(
33914 self.config.dialect,
33915 Some(crate::dialects::DialectType::Databricks)
33916 | Some(crate::dialects::DialectType::Spark)
33917 );
33918 if use_seed {
33919 self.write_keyword("SEED");
33920 } else {
33921 self.write_keyword("REPEATABLE");
33922 }
33923 self.write(" (");
33924 self.generate_expression(seed)?;
33925 self.write(")");
33926 }
33927 return Ok(());
33928 }
33929
33930 self.write_keyword("TABLESAMPLE");
33932 if let Some(method) = &e.method {
33933 self.write_space();
33934 self.write_keyword(method);
33935 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
33936 self.write_space();
33938 self.write_keyword("BERNOULLI");
33939 }
33940 if let (Some(numerator), Some(denominator)) = (&e.bucket_numerator, &e.bucket_denominator) {
33941 self.write_space();
33942 self.write_keyword("BUCKET");
33943 self.write_space();
33944 self.generate_expression(numerator)?;
33945 self.write_space();
33946 self.write_keyword("OUT OF");
33947 self.write_space();
33948 self.generate_expression(denominator)?;
33949 if let Some(field) = &e.bucket_field {
33950 self.write_space();
33951 self.write_keyword("ON");
33952 self.write_space();
33953 self.generate_expression(field)?;
33954 }
33955 } else if !e.expressions.is_empty() {
33956 self.write(" (");
33957 for (i, expr) in e.expressions.iter().enumerate() {
33958 if i > 0 {
33959 self.write(", ");
33960 }
33961 self.generate_expression(expr)?;
33962 }
33963 self.write(")");
33964 } else if let Some(percent) = &e.percent {
33965 self.write(" (");
33966 self.generate_expression(percent)?;
33967 self.write_space();
33968 self.write_keyword("PERCENT");
33969 self.write(")");
33970 }
33971 Ok(())
33972 }
33973
33974 fn generate_tag(&mut self, e: &Tag) -> Result<()> {
33975 if let Some(prefix) = &e.prefix {
33977 self.generate_expression(prefix)?;
33978 }
33979 if let Some(this) = &e.this {
33980 self.generate_expression(this)?;
33981 }
33982 if let Some(postfix) = &e.postfix {
33983 self.generate_expression(postfix)?;
33984 }
33985 Ok(())
33986 }
33987
33988 fn generate_tags(&mut self, e: &Tags) -> Result<()> {
33989 self.write_keyword("TAG");
33991 self.write(" (");
33992 for (i, expr) in e.expressions.iter().enumerate() {
33993 if i > 0 {
33994 self.write(", ");
33995 }
33996 self.generate_expression(expr)?;
33997 }
33998 self.write(")");
33999 Ok(())
34000 }
34001
34002 fn generate_temporary_property(&mut self, e: &TemporaryProperty) -> Result<()> {
34003 if let Some(this) = &e.this {
34005 self.generate_expression(this)?;
34006 self.write_space();
34007 }
34008 self.write_keyword("TEMPORARY");
34009 Ok(())
34010 }
34011
34012 fn generate_time_func(&mut self, e: &UnaryFunc) -> Result<()> {
34015 self.write_keyword("TIME");
34017 self.write("(");
34018 self.generate_expression(&e.this)?;
34019 self.write(")");
34020 Ok(())
34021 }
34022
34023 fn generate_time_add(&mut self, e: &TimeAdd) -> Result<()> {
34024 self.write_keyword("TIME_ADD");
34026 self.write("(");
34027 self.generate_expression(&e.this)?;
34028 self.write(", ");
34029 self.generate_expression(&e.expression)?;
34030 if let Some(unit) = &e.unit {
34031 self.write(", ");
34032 self.write_keyword(unit);
34033 }
34034 self.write(")");
34035 Ok(())
34036 }
34037
34038 fn generate_time_diff(&mut self, e: &TimeDiff) -> Result<()> {
34039 self.write_keyword("TIME_DIFF");
34041 self.write("(");
34042 self.generate_expression(&e.this)?;
34043 self.write(", ");
34044 self.generate_expression(&e.expression)?;
34045 if let Some(unit) = &e.unit {
34046 self.write(", ");
34047 self.write_keyword(unit);
34048 }
34049 self.write(")");
34050 Ok(())
34051 }
34052
34053 fn generate_time_from_parts(&mut self, e: &TimeFromParts) -> Result<()> {
34054 self.write_keyword("TIME_FROM_PARTS");
34056 self.write("(");
34057 let mut first = true;
34058 if let Some(hour) = &e.hour {
34059 self.generate_expression(hour)?;
34060 first = false;
34061 }
34062 if let Some(minute) = &e.min {
34063 if !first {
34064 self.write(", ");
34065 }
34066 self.generate_expression(minute)?;
34067 first = false;
34068 }
34069 if let Some(second) = &e.sec {
34070 if !first {
34071 self.write(", ");
34072 }
34073 self.generate_expression(second)?;
34074 first = false;
34075 }
34076 if let Some(ns) = &e.nano {
34077 if !first {
34078 self.write(", ");
34079 }
34080 self.generate_expression(ns)?;
34081 }
34082 self.write(")");
34083 Ok(())
34084 }
34085
34086 fn generate_time_slice(&mut self, e: &TimeSlice) -> Result<()> {
34087 self.write_keyword("TIME_SLICE");
34089 self.write("(");
34090 self.generate_expression(&e.this)?;
34091 self.write(", ");
34092 self.generate_expression(&e.expression)?;
34093 self.write(", ");
34094 self.write_keyword(&e.unit);
34095 self.write(")");
34096 Ok(())
34097 }
34098
34099 fn generate_time_str_to_time(&mut self, e: &TimeStrToTime) -> Result<()> {
34100 self.write_keyword("TIME_STR_TO_TIME");
34102 self.write("(");
34103 self.generate_expression(&e.this)?;
34104 self.write(")");
34105 Ok(())
34106 }
34107
34108 fn generate_time_sub(&mut self, e: &TimeSub) -> Result<()> {
34109 self.write_keyword("TIME_SUB");
34111 self.write("(");
34112 self.generate_expression(&e.this)?;
34113 self.write(", ");
34114 self.generate_expression(&e.expression)?;
34115 if let Some(unit) = &e.unit {
34116 self.write(", ");
34117 self.write_keyword(unit);
34118 }
34119 self.write(")");
34120 Ok(())
34121 }
34122
34123 fn generate_time_to_str(&mut self, e: &TimeToStr) -> Result<()> {
34124 match self.config.dialect {
34125 Some(DialectType::Exasol) => {
34126 self.write_keyword("TO_CHAR");
34128 self.write("(");
34129 self.generate_expression(&e.this)?;
34130 self.write(", '");
34131 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
34132 self.write("'");
34133 self.write(")");
34134 }
34135 Some(DialectType::PostgreSQL)
34136 | Some(DialectType::Redshift)
34137 | Some(DialectType::Materialize) => {
34138 self.write_keyword("TO_CHAR");
34140 self.write("(");
34141 self.generate_expression(&e.this)?;
34142 self.write(", '");
34143 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
34144 self.write("'");
34145 self.write(")");
34146 }
34147 Some(DialectType::Oracle) => {
34148 self.write_keyword("TO_CHAR");
34150 self.write("(");
34151 self.generate_expression(&e.this)?;
34152 self.write(", '");
34153 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
34154 self.write("'");
34155 self.write(")");
34156 }
34157 Some(DialectType::Drill) => {
34158 self.write_keyword("TO_CHAR");
34160 self.write("(");
34161 self.generate_expression(&e.this)?;
34162 self.write(", '");
34163 self.write(&Self::strftime_to_java_format(&e.format));
34164 self.write("'");
34165 self.write(")");
34166 }
34167 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
34168 self.write_keyword("FORMAT");
34170 self.write("(");
34171 self.generate_expression(&e.this)?;
34172 self.write(", '");
34173 self.write(&Self::strftime_to_tsql_format(&e.format));
34174 self.write("'");
34175 self.write(")");
34176 }
34177 Some(DialectType::DuckDB) => {
34178 self.write_keyword("STRFTIME");
34180 self.write("(");
34181 self.generate_expression(&e.this)?;
34182 self.write(", '");
34183 self.write(&e.format);
34184 self.write("'");
34185 self.write(")");
34186 }
34187 Some(DialectType::BigQuery) => {
34188 let fmt = e.format.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
34191 self.write_keyword("FORMAT_DATE");
34192 self.write("('");
34193 self.write(&fmt);
34194 self.write("', ");
34195 self.generate_expression(&e.this)?;
34196 self.write(")");
34197 }
34198 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
34199 self.write_keyword("DATE_FORMAT");
34201 self.write("(");
34202 self.generate_expression(&e.this)?;
34203 self.write(", '");
34204 self.write(&Self::strftime_to_java_format(&e.format));
34205 self.write("'");
34206 self.write(")");
34207 }
34208 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
34209 self.write_keyword("DATE_FORMAT");
34211 self.write("(");
34212 self.generate_expression(&e.this)?;
34213 self.write(", '");
34214 self.write(&e.format);
34215 self.write("'");
34216 self.write(")");
34217 }
34218 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
34219 self.write_keyword("DATE_FORMAT");
34221 self.write("(");
34222 self.generate_expression(&e.this)?;
34223 self.write(", '");
34224 self.write(&e.format);
34225 self.write("'");
34226 self.write(")");
34227 }
34228 _ => {
34229 self.write_keyword("TIME_TO_STR");
34231 self.write("(");
34232 self.generate_expression(&e.this)?;
34233 self.write(", '");
34234 self.write(&e.format);
34235 self.write("'");
34236 self.write(")");
34237 }
34238 }
34239 Ok(())
34240 }
34241
34242 fn generate_time_to_unix(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
34243 match self.config.dialect {
34244 Some(DialectType::DuckDB) => {
34245 self.write_keyword("EPOCH");
34247 self.write("(");
34248 self.generate_expression(&e.this)?;
34249 self.write(")");
34250 }
34251 Some(DialectType::Hive)
34252 | Some(DialectType::Spark)
34253 | Some(DialectType::Databricks)
34254 | Some(DialectType::Doris)
34255 | Some(DialectType::StarRocks)
34256 | Some(DialectType::Drill) => {
34257 self.write_keyword("UNIX_TIMESTAMP");
34259 self.write("(");
34260 self.generate_expression(&e.this)?;
34261 self.write(")");
34262 }
34263 Some(DialectType::Presto) | Some(DialectType::Trino) => {
34264 self.write_keyword("TO_UNIXTIME");
34266 self.write("(");
34267 self.generate_expression(&e.this)?;
34268 self.write(")");
34269 }
34270 _ => {
34271 self.write_keyword("TIME_TO_UNIX");
34273 self.write("(");
34274 self.generate_expression(&e.this)?;
34275 self.write(")");
34276 }
34277 }
34278 Ok(())
34279 }
34280
34281 fn generate_time_str_to_date(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
34282 match self.config.dialect {
34283 Some(DialectType::Hive) => {
34284 self.write_keyword("TO_DATE");
34286 self.write("(");
34287 self.generate_expression(&e.this)?;
34288 self.write(")");
34289 }
34290 _ => {
34291 self.write_keyword("TIME_STR_TO_DATE");
34293 self.write("(");
34294 self.generate_expression(&e.this)?;
34295 self.write(")");
34296 }
34297 }
34298 Ok(())
34299 }
34300
34301 fn generate_time_trunc(&mut self, e: &TimeTrunc) -> Result<()> {
34302 self.write_keyword("TIME_TRUNC");
34304 self.write("(");
34305 self.generate_expression(&e.this)?;
34306 self.write(", ");
34307 self.write_keyword(&e.unit);
34308 self.write(")");
34309 Ok(())
34310 }
34311
34312 fn generate_time_unit(&mut self, e: &TimeUnit) -> Result<()> {
34313 if let Some(unit) = &e.unit {
34315 self.write_keyword(unit);
34316 }
34317 Ok(())
34318 }
34319
34320 fn generate_timestamp_func(&mut self, e: &TimestampFunc) -> Result<()> {
34324 use crate::dialects::DialectType;
34325 use crate::expressions::Literal;
34326
34327 match self.config.dialect {
34328 Some(DialectType::Exasol) => {
34330 self.write_keyword("TO_TIMESTAMP");
34331 self.write("(");
34332 if let Some(this) = &e.this {
34334 match this.as_ref() {
34335 Expression::Literal(Literal::String(s)) => {
34336 self.write("'");
34337 self.write(s);
34338 self.write("'");
34339 }
34340 _ => {
34341 self.generate_expression(this)?;
34342 }
34343 }
34344 }
34345 self.write(")");
34346 }
34347 _ => {
34349 self.write_keyword("TIMESTAMP");
34350 self.write("(");
34351 if let Some(this) = &e.this {
34352 self.generate_expression(this)?;
34353 }
34354 if let Some(zone) = &e.zone {
34355 self.write(", ");
34356 self.generate_expression(zone)?;
34357 }
34358 self.write(")");
34359 }
34360 }
34361 Ok(())
34362 }
34363
34364 fn generate_timestamp_add(&mut self, e: &TimestampAdd) -> Result<()> {
34365 self.write_keyword("TIMESTAMP_ADD");
34367 self.write("(");
34368 self.generate_expression(&e.this)?;
34369 self.write(", ");
34370 self.generate_expression(&e.expression)?;
34371 if let Some(unit) = &e.unit {
34372 self.write(", ");
34373 self.write_keyword(unit);
34374 }
34375 self.write(")");
34376 Ok(())
34377 }
34378
34379 fn generate_timestamp_diff(&mut self, e: &TimestampDiff) -> Result<()> {
34380 self.write_keyword("TIMESTAMP_DIFF");
34382 self.write("(");
34383 self.generate_expression(&e.this)?;
34384 self.write(", ");
34385 self.generate_expression(&e.expression)?;
34386 if let Some(unit) = &e.unit {
34387 self.write(", ");
34388 self.write_keyword(unit);
34389 }
34390 self.write(")");
34391 Ok(())
34392 }
34393
34394 fn generate_timestamp_from_parts(&mut self, e: &TimestampFromParts) -> Result<()> {
34395 self.write_keyword("TIMESTAMP_FROM_PARTS");
34397 self.write("(");
34398 if let Some(this) = &e.this {
34399 self.generate_expression(this)?;
34400 }
34401 if let Some(expression) = &e.expression {
34402 self.write(", ");
34403 self.generate_expression(expression)?;
34404 }
34405 if let Some(zone) = &e.zone {
34406 self.write(", ");
34407 self.generate_expression(zone)?;
34408 }
34409 if let Some(milli) = &e.milli {
34410 self.write(", ");
34411 self.generate_expression(milli)?;
34412 }
34413 self.write(")");
34414 Ok(())
34415 }
34416
34417 fn generate_timestamp_sub(&mut self, e: &TimestampSub) -> Result<()> {
34418 self.write_keyword("TIMESTAMP_SUB");
34420 self.write("(");
34421 self.generate_expression(&e.this)?;
34422 self.write(", ");
34423 self.write_keyword("INTERVAL");
34424 self.write_space();
34425 self.generate_expression(&e.expression)?;
34426 if let Some(unit) = &e.unit {
34427 self.write_space();
34428 self.write_keyword(unit);
34429 }
34430 self.write(")");
34431 Ok(())
34432 }
34433
34434 fn generate_timestamp_tz_from_parts(&mut self, e: &TimestampTzFromParts) -> Result<()> {
34435 self.write_keyword("TIMESTAMP_TZ_FROM_PARTS");
34437 self.write("(");
34438 if let Some(zone) = &e.zone {
34439 self.generate_expression(zone)?;
34440 }
34441 self.write(")");
34442 Ok(())
34443 }
34444
34445 fn generate_to_binary(&mut self, e: &ToBinary) -> Result<()> {
34446 self.write_keyword("TO_BINARY");
34448 self.write("(");
34449 self.generate_expression(&e.this)?;
34450 if let Some(format) = &e.format {
34451 self.write(", '");
34452 self.write(format);
34453 self.write("'");
34454 }
34455 self.write(")");
34456 Ok(())
34457 }
34458
34459 fn generate_to_boolean(&mut self, e: &ToBoolean) -> Result<()> {
34460 self.write_keyword("TO_BOOLEAN");
34462 self.write("(");
34463 self.generate_expression(&e.this)?;
34464 self.write(")");
34465 Ok(())
34466 }
34467
34468 fn generate_to_char(&mut self, e: &ToChar) -> Result<()> {
34469 self.write_keyword("TO_CHAR");
34471 self.write("(");
34472 self.generate_expression(&e.this)?;
34473 if let Some(format) = &e.format {
34474 self.write(", '");
34475 self.write(format);
34476 self.write("'");
34477 }
34478 if let Some(nlsparam) = &e.nlsparam {
34479 self.write(", ");
34480 self.generate_expression(nlsparam)?;
34481 }
34482 self.write(")");
34483 Ok(())
34484 }
34485
34486 fn generate_to_decfloat(&mut self, e: &ToDecfloat) -> Result<()> {
34487 self.write_keyword("TO_DECFLOAT");
34489 self.write("(");
34490 self.generate_expression(&e.this)?;
34491 if let Some(format) = &e.format {
34492 self.write(", '");
34493 self.write(format);
34494 self.write("'");
34495 }
34496 self.write(")");
34497 Ok(())
34498 }
34499
34500 fn generate_to_double(&mut self, e: &ToDouble) -> Result<()> {
34501 self.write_keyword("TO_DOUBLE");
34503 self.write("(");
34504 self.generate_expression(&e.this)?;
34505 if let Some(format) = &e.format {
34506 self.write(", '");
34507 self.write(format);
34508 self.write("'");
34509 }
34510 self.write(")");
34511 Ok(())
34512 }
34513
34514 fn generate_to_file(&mut self, e: &ToFile) -> Result<()> {
34515 self.write_keyword("TO_FILE");
34517 self.write("(");
34518 self.generate_expression(&e.this)?;
34519 if let Some(path) = &e.path {
34520 self.write(", ");
34521 self.generate_expression(path)?;
34522 }
34523 self.write(")");
34524 Ok(())
34525 }
34526
34527 fn generate_to_number(&mut self, e: &ToNumber) -> Result<()> {
34528 let is_safe = e.safe.is_some();
34531 if is_safe {
34532 self.write_keyword("TRY_TO_NUMBER");
34533 } else {
34534 self.write_keyword("TO_NUMBER");
34535 }
34536 self.write("(");
34537 self.generate_expression(&e.this)?;
34538 if let Some(format) = &e.format {
34539 self.write(", ");
34540 self.generate_expression(format)?;
34541 }
34542 if let Some(nlsparam) = &e.nlsparam {
34543 self.write(", ");
34544 self.generate_expression(nlsparam)?;
34545 }
34546 if let Some(precision) = &e.precision {
34547 self.write(", ");
34548 self.generate_expression(precision)?;
34549 }
34550 if let Some(scale) = &e.scale {
34551 self.write(", ");
34552 self.generate_expression(scale)?;
34553 }
34554 self.write(")");
34555 Ok(())
34556 }
34557
34558 fn generate_to_table_property(&mut self, e: &ToTableProperty) -> Result<()> {
34559 self.write_keyword("TO_TABLE");
34561 self.write_space();
34562 self.generate_expression(&e.this)?;
34563 Ok(())
34564 }
34565
34566 fn generate_transaction(&mut self, e: &Transaction) -> Result<()> {
34567 let mark_text = e.mark.as_ref().map(|m| match m.as_ref() {
34569 Expression::Identifier(id) => id.name.clone(),
34570 Expression::Literal(Literal::String(s)) => s.clone(),
34571 _ => String::new(),
34572 });
34573
34574 let is_start = mark_text.as_ref().map_or(false, |s| s == "START");
34575 let has_transaction_keyword = mark_text.as_ref().map_or(false, |s| s == "TRANSACTION");
34576 let has_with_mark = e.mark.as_ref().map_or(false, |m| {
34577 matches!(m.as_ref(), Expression::Literal(Literal::String(_)))
34578 });
34579
34580 let use_start_transaction = matches!(
34582 self.config.dialect,
34583 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
34584 );
34585 let strip_transaction = matches!(
34587 self.config.dialect,
34588 Some(DialectType::Snowflake)
34589 | Some(DialectType::PostgreSQL)
34590 | Some(DialectType::Redshift)
34591 | Some(DialectType::MySQL)
34592 | Some(DialectType::Hive)
34593 | Some(DialectType::Spark)
34594 | Some(DialectType::Databricks)
34595 | Some(DialectType::DuckDB)
34596 | Some(DialectType::Oracle)
34597 | Some(DialectType::Doris)
34598 | Some(DialectType::StarRocks)
34599 | Some(DialectType::Materialize)
34600 | Some(DialectType::ClickHouse)
34601 );
34602
34603 if is_start || use_start_transaction {
34604 self.write_keyword("START TRANSACTION");
34606 if let Some(modes) = &e.modes {
34607 self.write_space();
34608 self.generate_expression(modes)?;
34609 }
34610 } else {
34611 self.write_keyword("BEGIN");
34613
34614 let is_kind = e.this.as_ref().map_or(false, |t| {
34616 if let Expression::Identifier(id) = t.as_ref() {
34617 matches!(
34618 id.name.to_uppercase().as_str(),
34619 "DEFERRED" | "IMMEDIATE" | "EXCLUSIVE"
34620 )
34621 } else {
34622 false
34623 }
34624 });
34625
34626 if is_kind {
34628 if let Some(this) = &e.this {
34629 self.write_space();
34630 if let Expression::Identifier(id) = this.as_ref() {
34631 self.write_keyword(&id.name);
34632 }
34633 }
34634 }
34635
34636 if (has_transaction_keyword || has_with_mark) && !strip_transaction {
34638 self.write_space();
34639 self.write_keyword("TRANSACTION");
34640 }
34641
34642 if !is_kind {
34644 if let Some(this) = &e.this {
34645 self.write_space();
34646 self.generate_expression(this)?;
34647 }
34648 }
34649
34650 if has_with_mark {
34652 self.write_space();
34653 self.write_keyword("WITH MARK");
34654 if let Some(Expression::Literal(Literal::String(desc))) = e.mark.as_deref() {
34655 if !desc.is_empty() {
34656 self.write_space();
34657 self.write(&format!("'{}'", desc));
34658 }
34659 }
34660 }
34661
34662 if let Some(modes) = &e.modes {
34664 self.write_space();
34665 self.generate_expression(modes)?;
34666 }
34667 }
34668 Ok(())
34669 }
34670
34671 fn generate_transform(&mut self, e: &Transform) -> Result<()> {
34672 self.write_keyword("TRANSFORM");
34674 self.write("(");
34675 self.generate_expression(&e.this)?;
34676 self.write(", ");
34677 self.generate_expression(&e.expression)?;
34678 self.write(")");
34679 Ok(())
34680 }
34681
34682 fn generate_transform_model_property(&mut self, e: &TransformModelProperty) -> Result<()> {
34683 self.write_keyword("TRANSFORM");
34685 self.write("(");
34686 if self.config.pretty && !e.expressions.is_empty() {
34687 self.indent_level += 1;
34688 for (i, expr) in e.expressions.iter().enumerate() {
34689 if i > 0 {
34690 self.write(",");
34691 }
34692 self.write_newline();
34693 self.write_indent();
34694 self.generate_expression(expr)?;
34695 }
34696 self.indent_level -= 1;
34697 self.write_newline();
34698 self.write(")");
34699 } else {
34700 for (i, expr) in e.expressions.iter().enumerate() {
34701 if i > 0 {
34702 self.write(", ");
34703 }
34704 self.generate_expression(expr)?;
34705 }
34706 self.write(")");
34707 }
34708 Ok(())
34709 }
34710
34711 fn generate_transient_property(&mut self, e: &TransientProperty) -> Result<()> {
34712 use crate::dialects::DialectType;
34713 if let Some(this) = &e.this {
34715 self.generate_expression(this)?;
34716 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
34717 self.write_space();
34718 }
34719 }
34720 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
34721 self.write_keyword("TRANSIENT");
34722 }
34723 Ok(())
34724 }
34725
34726 fn generate_translate(&mut self, e: &Translate) -> Result<()> {
34727 self.write_keyword("TRANSLATE");
34729 self.write("(");
34730 self.generate_expression(&e.this)?;
34731 if let Some(from) = &e.from_ {
34732 self.write(", ");
34733 self.generate_expression(from)?;
34734 }
34735 if let Some(to) = &e.to {
34736 self.write(", ");
34737 self.generate_expression(to)?;
34738 }
34739 self.write(")");
34740 Ok(())
34741 }
34742
34743 fn generate_translate_characters(&mut self, e: &TranslateCharacters) -> Result<()> {
34744 self.write_keyword("TRANSLATE");
34746 self.write("(");
34747 self.generate_expression(&e.this)?;
34748 self.write_space();
34749 self.write_keyword("USING");
34750 self.write_space();
34751 self.generate_expression(&e.expression)?;
34752 if e.with_error.is_some() {
34753 self.write_space();
34754 self.write_keyword("WITH ERROR");
34755 }
34756 self.write(")");
34757 Ok(())
34758 }
34759
34760 fn generate_truncate_table(&mut self, e: &TruncateTable) -> Result<()> {
34761 self.write_keyword("TRUNCATE TABLE");
34763 self.write_space();
34764 for (i, expr) in e.expressions.iter().enumerate() {
34765 if i > 0 {
34766 self.write(", ");
34767 }
34768 self.generate_expression(expr)?;
34769 }
34770 Ok(())
34771 }
34772
34773 fn generate_try_base64_decode_binary(&mut self, e: &TryBase64DecodeBinary) -> Result<()> {
34774 self.write_keyword("TRY_BASE64_DECODE_BINARY");
34776 self.write("(");
34777 self.generate_expression(&e.this)?;
34778 if let Some(alphabet) = &e.alphabet {
34779 self.write(", ");
34780 self.generate_expression(alphabet)?;
34781 }
34782 self.write(")");
34783 Ok(())
34784 }
34785
34786 fn generate_try_base64_decode_string(&mut self, e: &TryBase64DecodeString) -> Result<()> {
34787 self.write_keyword("TRY_BASE64_DECODE_STRING");
34789 self.write("(");
34790 self.generate_expression(&e.this)?;
34791 if let Some(alphabet) = &e.alphabet {
34792 self.write(", ");
34793 self.generate_expression(alphabet)?;
34794 }
34795 self.write(")");
34796 Ok(())
34797 }
34798
34799 fn generate_try_to_decfloat(&mut self, e: &TryToDecfloat) -> Result<()> {
34800 self.write_keyword("TRY_TO_DECFLOAT");
34802 self.write("(");
34803 self.generate_expression(&e.this)?;
34804 if let Some(format) = &e.format {
34805 self.write(", '");
34806 self.write(format);
34807 self.write("'");
34808 }
34809 self.write(")");
34810 Ok(())
34811 }
34812
34813 fn generate_ts_or_ds_add(&mut self, e: &TsOrDsAdd) -> Result<()> {
34814 self.write_keyword("TS_OR_DS_ADD");
34816 self.write("(");
34817 self.generate_expression(&e.this)?;
34818 self.write(", ");
34819 self.generate_expression(&e.expression)?;
34820 if let Some(unit) = &e.unit {
34821 self.write(", ");
34822 self.write_keyword(unit);
34823 }
34824 if let Some(return_type) = &e.return_type {
34825 self.write(", ");
34826 self.generate_expression(return_type)?;
34827 }
34828 self.write(")");
34829 Ok(())
34830 }
34831
34832 fn generate_ts_or_ds_diff(&mut self, e: &TsOrDsDiff) -> Result<()> {
34833 self.write_keyword("TS_OR_DS_DIFF");
34835 self.write("(");
34836 self.generate_expression(&e.this)?;
34837 self.write(", ");
34838 self.generate_expression(&e.expression)?;
34839 if let Some(unit) = &e.unit {
34840 self.write(", ");
34841 self.write_keyword(unit);
34842 }
34843 self.write(")");
34844 Ok(())
34845 }
34846
34847 fn generate_ts_or_ds_to_date(&mut self, e: &TsOrDsToDate) -> Result<()> {
34848 let default_time_format = "%Y-%m-%d %H:%M:%S";
34849 let default_date_format = "%Y-%m-%d";
34850 let has_non_default_format = e.format.as_ref().map_or(false, |f| {
34851 f != default_time_format && f != default_date_format
34852 });
34853
34854 if has_non_default_format {
34855 let fmt = e.format.as_ref().unwrap();
34857 match self.config.dialect {
34858 Some(DialectType::MySQL) | Some(DialectType::StarRocks) => {
34859 let str_to_time = crate::expressions::StrToTime {
34862 this: Box::new((*e.this).clone()),
34863 format: fmt.clone(),
34864 zone: None,
34865 safe: None,
34866 target_type: None,
34867 };
34868 self.generate_str_to_time(&str_to_time)?;
34869 }
34870 Some(DialectType::Hive)
34871 | Some(DialectType::Spark)
34872 | Some(DialectType::Databricks) => {
34873 self.write_keyword("TO_DATE");
34875 self.write("(");
34876 self.generate_expression(&e.this)?;
34877 self.write(", '");
34878 self.write(&Self::strftime_to_java_format(fmt));
34879 self.write("')");
34880 }
34881 Some(DialectType::Snowflake) => {
34882 self.write_keyword("TO_DATE");
34884 self.write("(");
34885 self.generate_expression(&e.this)?;
34886 self.write(", '");
34887 self.write(&Self::strftime_to_snowflake_format(fmt));
34888 self.write("')");
34889 }
34890 Some(DialectType::Doris) => {
34891 self.write_keyword("TO_DATE");
34893 self.write("(");
34894 self.generate_expression(&e.this)?;
34895 self.write(")");
34896 }
34897 _ => {
34898 self.write_keyword("CAST");
34900 self.write("(");
34901 let str_to_time = crate::expressions::StrToTime {
34902 this: Box::new((*e.this).clone()),
34903 format: fmt.clone(),
34904 zone: None,
34905 safe: None,
34906 target_type: None,
34907 };
34908 self.generate_str_to_time(&str_to_time)?;
34909 self.write_keyword(" AS ");
34910 self.write_keyword("DATE");
34911 self.write(")");
34912 }
34913 }
34914 } else {
34915 match self.config.dialect {
34917 Some(DialectType::MySQL)
34918 | Some(DialectType::SQLite)
34919 | Some(DialectType::StarRocks) => {
34920 self.write_keyword("DATE");
34922 self.write("(");
34923 self.generate_expression(&e.this)?;
34924 self.write(")");
34925 }
34926 Some(DialectType::Hive)
34927 | Some(DialectType::Spark)
34928 | Some(DialectType::Databricks)
34929 | Some(DialectType::Snowflake)
34930 | Some(DialectType::Doris) => {
34931 self.write_keyword("TO_DATE");
34933 self.write("(");
34934 self.generate_expression(&e.this)?;
34935 self.write(")");
34936 }
34937 Some(DialectType::Presto)
34938 | Some(DialectType::Trino)
34939 | Some(DialectType::Athena) => {
34940 self.write_keyword("CAST");
34942 self.write("(");
34943 self.write_keyword("CAST");
34944 self.write("(");
34945 self.generate_expression(&e.this)?;
34946 self.write_keyword(" AS ");
34947 self.write_keyword("TIMESTAMP");
34948 self.write(")");
34949 self.write_keyword(" AS ");
34950 self.write_keyword("DATE");
34951 self.write(")");
34952 }
34953 Some(DialectType::ClickHouse) => {
34954 self.write_keyword("CAST");
34956 self.write("(");
34957 self.generate_expression(&e.this)?;
34958 self.write_keyword(" AS ");
34959 self.write("Nullable(DATE)");
34960 self.write(")");
34961 }
34962 _ => {
34963 self.write_keyword("CAST");
34965 self.write("(");
34966 self.generate_expression(&e.this)?;
34967 self.write_keyword(" AS ");
34968 self.write_keyword("DATE");
34969 self.write(")");
34970 }
34971 }
34972 }
34973 Ok(())
34974 }
34975
34976 fn generate_ts_or_ds_to_time(&mut self, e: &TsOrDsToTime) -> Result<()> {
34977 self.write_keyword("TS_OR_DS_TO_TIME");
34979 self.write("(");
34980 self.generate_expression(&e.this)?;
34981 if let Some(format) = &e.format {
34982 self.write(", '");
34983 self.write(format);
34984 self.write("'");
34985 }
34986 self.write(")");
34987 Ok(())
34988 }
34989
34990 fn generate_unhex(&mut self, e: &Unhex) -> Result<()> {
34991 self.write_keyword("UNHEX");
34993 self.write("(");
34994 self.generate_expression(&e.this)?;
34995 if let Some(expression) = &e.expression {
34996 self.write(", ");
34997 self.generate_expression(expression)?;
34998 }
34999 self.write(")");
35000 Ok(())
35001 }
35002
35003 fn generate_unicode_string(&mut self, e: &UnicodeString) -> Result<()> {
35004 self.write("U&");
35006 self.generate_expression(&e.this)?;
35007 if let Some(escape) = &e.escape {
35008 self.write_space();
35009 self.write_keyword("UESCAPE");
35010 self.write_space();
35011 self.generate_expression(escape)?;
35012 }
35013 Ok(())
35014 }
35015
35016 fn generate_uniform(&mut self, e: &Uniform) -> Result<()> {
35017 self.write_keyword("UNIFORM");
35019 self.write("(");
35020 self.generate_expression(&e.this)?;
35021 self.write(", ");
35022 self.generate_expression(&e.expression)?;
35023 if let Some(gen) = &e.gen {
35024 self.write(", ");
35025 self.generate_expression(gen)?;
35026 }
35027 if let Some(seed) = &e.seed {
35028 self.write(", ");
35029 self.generate_expression(seed)?;
35030 }
35031 self.write(")");
35032 Ok(())
35033 }
35034
35035 fn generate_unique_column_constraint(&mut self, e: &UniqueColumnConstraint) -> Result<()> {
35036 self.write_keyword("UNIQUE");
35038 if e.nulls.is_some() {
35040 self.write(" NULLS NOT DISTINCT");
35041 }
35042 if let Some(this) = &e.this {
35043 self.write_space();
35044 self.generate_expression(this)?;
35045 }
35046 if let Some(index_type) = &e.index_type {
35047 self.write(" USING ");
35048 self.generate_expression(index_type)?;
35049 }
35050 if let Some(on_conflict) = &e.on_conflict {
35051 self.write_space();
35052 self.generate_expression(on_conflict)?;
35053 }
35054 for opt in &e.options {
35055 self.write_space();
35056 self.generate_expression(opt)?;
35057 }
35058 Ok(())
35059 }
35060
35061 fn generate_unique_key_property(&mut self, e: &UniqueKeyProperty) -> Result<()> {
35062 self.write_keyword("UNIQUE KEY");
35064 self.write(" (");
35065 for (i, expr) in e.expressions.iter().enumerate() {
35066 if i > 0 {
35067 self.write(", ");
35068 }
35069 self.generate_expression(expr)?;
35070 }
35071 self.write(")");
35072 Ok(())
35073 }
35074
35075 fn generate_rollup_property(&mut self, e: &RollupProperty) -> Result<()> {
35076 self.write_keyword("ROLLUP");
35078 self.write(" (");
35079 for (i, index) in e.expressions.iter().enumerate() {
35080 if i > 0 {
35081 self.write(", ");
35082 }
35083 self.generate_identifier(&index.name)?;
35084 self.write("(");
35085 for (j, col) in index.expressions.iter().enumerate() {
35086 if j > 0 {
35087 self.write(", ");
35088 }
35089 self.generate_identifier(col)?;
35090 }
35091 self.write(")");
35092 }
35093 self.write(")");
35094 Ok(())
35095 }
35096
35097 fn generate_unix_to_str(&mut self, e: &UnixToStr) -> Result<()> {
35098 match self.config.dialect {
35099 Some(DialectType::DuckDB) => {
35100 self.write_keyword("STRFTIME");
35102 self.write("(");
35103 self.write_keyword("TO_TIMESTAMP");
35104 self.write("(");
35105 self.generate_expression(&e.this)?;
35106 self.write("), '");
35107 if let Some(format) = &e.format {
35108 self.write(format);
35109 }
35110 self.write("')");
35111 }
35112 Some(DialectType::Hive) => {
35113 self.write_keyword("FROM_UNIXTIME");
35115 self.write("(");
35116 self.generate_expression(&e.this)?;
35117 if let Some(format) = &e.format {
35118 if format != "yyyy-MM-dd HH:mm:ss" {
35119 self.write(", '");
35120 self.write(format);
35121 self.write("'");
35122 }
35123 }
35124 self.write(")");
35125 }
35126 Some(DialectType::Presto) | Some(DialectType::Trino) => {
35127 self.write_keyword("DATE_FORMAT");
35129 self.write("(");
35130 self.write_keyword("FROM_UNIXTIME");
35131 self.write("(");
35132 self.generate_expression(&e.this)?;
35133 self.write("), '");
35134 if let Some(format) = &e.format {
35135 self.write(format);
35136 }
35137 self.write("')");
35138 }
35139 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
35140 self.write_keyword("FROM_UNIXTIME");
35142 self.write("(");
35143 self.generate_expression(&e.this)?;
35144 if let Some(format) = &e.format {
35145 self.write(", '");
35146 self.write(format);
35147 self.write("'");
35148 }
35149 self.write(")");
35150 }
35151 _ => {
35152 self.write_keyword("UNIX_TO_STR");
35154 self.write("(");
35155 self.generate_expression(&e.this)?;
35156 if let Some(format) = &e.format {
35157 self.write(", '");
35158 self.write(format);
35159 self.write("'");
35160 }
35161 self.write(")");
35162 }
35163 }
35164 Ok(())
35165 }
35166
35167 fn generate_unix_to_time(&mut self, e: &UnixToTime) -> Result<()> {
35168 use crate::dialects::DialectType;
35169 let scale = e.scale.unwrap_or(0); match self.config.dialect {
35172 Some(DialectType::Snowflake) => {
35173 self.write_keyword("TO_TIMESTAMP");
35175 self.write("(");
35176 self.generate_expression(&e.this)?;
35177 if let Some(s) = e.scale {
35178 if s > 0 {
35179 self.write(", ");
35180 self.write(&s.to_string());
35181 }
35182 }
35183 self.write(")");
35184 }
35185 Some(DialectType::BigQuery) => {
35186 match scale {
35189 0 => {
35190 self.write_keyword("TIMESTAMP_SECONDS");
35191 self.write("(");
35192 self.generate_expression(&e.this)?;
35193 self.write(")");
35194 }
35195 3 => {
35196 self.write_keyword("TIMESTAMP_MILLIS");
35197 self.write("(");
35198 self.generate_expression(&e.this)?;
35199 self.write(")");
35200 }
35201 6 => {
35202 self.write_keyword("TIMESTAMP_MICROS");
35203 self.write("(");
35204 self.generate_expression(&e.this)?;
35205 self.write(")");
35206 }
35207 _ => {
35208 self.write_keyword("TIMESTAMP_SECONDS");
35210 self.write("(CAST(");
35211 self.generate_expression(&e.this)?;
35212 self.write(&format!(" / POWER(10, {}) AS INT64))", scale));
35213 }
35214 }
35215 }
35216 Some(DialectType::Spark) => {
35217 match scale {
35222 0 => {
35223 self.write_keyword("CAST");
35224 self.write("(");
35225 self.write_keyword("FROM_UNIXTIME");
35226 self.write("(");
35227 self.generate_expression(&e.this)?;
35228 self.write(") ");
35229 self.write_keyword("AS TIMESTAMP");
35230 self.write(")");
35231 }
35232 3 => {
35233 self.write_keyword("TIMESTAMP_MILLIS");
35234 self.write("(");
35235 self.generate_expression(&e.this)?;
35236 self.write(")");
35237 }
35238 6 => {
35239 self.write_keyword("TIMESTAMP_MICROS");
35240 self.write("(");
35241 self.generate_expression(&e.this)?;
35242 self.write(")");
35243 }
35244 _ => {
35245 self.write_keyword("TIMESTAMP_SECONDS");
35246 self.write("(");
35247 self.generate_expression(&e.this)?;
35248 self.write(&format!(" / POWER(10, {}))", scale));
35249 }
35250 }
35251 }
35252 Some(DialectType::Databricks) => {
35253 match scale {
35257 0 => {
35258 self.write_keyword("CAST");
35259 self.write("(");
35260 self.write_keyword("FROM_UNIXTIME");
35261 self.write("(");
35262 self.generate_expression(&e.this)?;
35263 self.write(") ");
35264 self.write_keyword("AS TIMESTAMP");
35265 self.write(")");
35266 }
35267 3 => {
35268 self.write_keyword("TIMESTAMP_MILLIS");
35269 self.write("(");
35270 self.generate_expression(&e.this)?;
35271 self.write(")");
35272 }
35273 6 => {
35274 self.write_keyword("TIMESTAMP_MICROS");
35275 self.write("(");
35276 self.generate_expression(&e.this)?;
35277 self.write(")");
35278 }
35279 _ => {
35280 self.write_keyword("TIMESTAMP_SECONDS");
35281 self.write("(");
35282 self.generate_expression(&e.this)?;
35283 self.write(&format!(" / POWER(10, {}))", scale));
35284 }
35285 }
35286 }
35287 Some(DialectType::Hive) => {
35288 if scale == 0 {
35290 self.write_keyword("FROM_UNIXTIME");
35291 self.write("(");
35292 self.generate_expression(&e.this)?;
35293 self.write(")");
35294 } else {
35295 self.write_keyword("FROM_UNIXTIME");
35296 self.write("(");
35297 self.generate_expression(&e.this)?;
35298 self.write(&format!(" / POWER(10, {})", scale));
35299 self.write(")");
35300 }
35301 }
35302 Some(DialectType::Presto) | Some(DialectType::Trino) => {
35303 if scale == 0 {
35306 self.write_keyword("FROM_UNIXTIME");
35307 self.write("(");
35308 self.generate_expression(&e.this)?;
35309 self.write(")");
35310 } else {
35311 self.write_keyword("FROM_UNIXTIME");
35312 self.write("(CAST(");
35313 self.generate_expression(&e.this)?;
35314 self.write(&format!(" AS DOUBLE) / POW(10, {}))", scale));
35315 }
35316 }
35317 Some(DialectType::DuckDB) => {
35318 match scale {
35322 0 => {
35323 self.write_keyword("TO_TIMESTAMP");
35324 self.write("(");
35325 self.generate_expression(&e.this)?;
35326 self.write(")");
35327 }
35328 3 => {
35329 self.write_keyword("EPOCH_MS");
35330 self.write("(");
35331 self.generate_expression(&e.this)?;
35332 self.write(")");
35333 }
35334 6 => {
35335 self.write_keyword("MAKE_TIMESTAMP");
35336 self.write("(");
35337 self.generate_expression(&e.this)?;
35338 self.write(")");
35339 }
35340 _ => {
35341 self.write_keyword("TO_TIMESTAMP");
35342 self.write("(");
35343 self.generate_expression(&e.this)?;
35344 self.write(&format!(" / POWER(10, {}))", scale));
35345 self.write_keyword(" AT TIME ZONE");
35346 self.write(" 'UTC'");
35347 }
35348 }
35349 }
35350 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
35351 self.write_keyword("FROM_UNIXTIME");
35353 self.write("(");
35354 self.generate_expression(&e.this)?;
35355 self.write(")");
35356 }
35357 Some(DialectType::Oracle) => {
35358 self.write("TO_DATE('1970-01-01', 'YYYY-MM-DD') + (");
35360 self.generate_expression(&e.this)?;
35361 self.write(" / 86400)");
35362 }
35363 Some(DialectType::Redshift) => {
35364 self.write("(TIMESTAMP 'epoch' + ");
35367 if scale == 0 {
35368 self.generate_expression(&e.this)?;
35369 } else {
35370 self.write("(");
35371 self.generate_expression(&e.this)?;
35372 self.write(&format!(" / POWER(10, {}))", scale));
35373 }
35374 self.write(" * INTERVAL '1 SECOND')");
35375 }
35376 _ => {
35377 self.write_keyword("TO_TIMESTAMP");
35379 self.write("(");
35380 self.generate_expression(&e.this)?;
35381 if let Some(s) = e.scale {
35382 self.write(", ");
35383 self.write(&s.to_string());
35384 }
35385 self.write(")");
35386 }
35387 }
35388 Ok(())
35389 }
35390
35391 fn generate_unpivot_columns(&mut self, e: &UnpivotColumns) -> Result<()> {
35392 if !matches!(&*e.this, Expression::Null(_)) {
35394 self.write_keyword("NAME");
35395 self.write_space();
35396 self.generate_expression(&e.this)?;
35397 }
35398 if !e.expressions.is_empty() {
35399 self.write_space();
35400 self.write_keyword("VALUE");
35401 self.write_space();
35402 for (i, expr) in e.expressions.iter().enumerate() {
35403 if i > 0 {
35404 self.write(", ");
35405 }
35406 self.generate_expression(expr)?;
35407 }
35408 }
35409 Ok(())
35410 }
35411
35412 fn generate_user_defined_function(&mut self, e: &UserDefinedFunction) -> Result<()> {
35413 if e.wrapped.is_some() {
35415 self.write("(");
35416 }
35417 self.generate_expression(&e.this)?;
35418 if e.wrapped.is_some() {
35419 self.write(")");
35420 }
35421 self.write("(");
35422 for (i, expr) in e.expressions.iter().enumerate() {
35423 if i > 0 {
35424 self.write(", ");
35425 }
35426 self.generate_expression(expr)?;
35427 }
35428 self.write(")");
35429 Ok(())
35430 }
35431
35432 fn generate_using_template_property(&mut self, e: &UsingTemplateProperty) -> Result<()> {
35433 self.write_keyword("USING TEMPLATE");
35435 self.write_space();
35436 self.generate_expression(&e.this)?;
35437 Ok(())
35438 }
35439
35440 fn generate_utc_time(&mut self, _e: &UtcTime) -> Result<()> {
35441 self.write_keyword("UTC_TIME");
35443 Ok(())
35444 }
35445
35446 fn generate_utc_timestamp(&mut self, _e: &UtcTimestamp) -> Result<()> {
35447 self.write_keyword("UTC_TIMESTAMP");
35449 Ok(())
35450 }
35451
35452 fn generate_uuid(&mut self, e: &Uuid) -> Result<()> {
35453 use crate::dialects::DialectType;
35454 let func_name = match self.config.dialect {
35456 Some(DialectType::Snowflake) => "UUID_STRING",
35457 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
35458 Some(DialectType::BigQuery) => "GENERATE_UUID",
35459 _ => {
35460 if let Some(name) = &e.name {
35461 name.as_str()
35462 } else {
35463 "UUID"
35464 }
35465 }
35466 };
35467 self.write_keyword(func_name);
35468 self.write("(");
35469 if let Some(this) = &e.this {
35470 self.generate_expression(this)?;
35471 }
35472 self.write(")");
35473 Ok(())
35474 }
35475
35476 fn generate_var_map(&mut self, e: &VarMap) -> Result<()> {
35477 self.write_keyword("MAP");
35479 self.write("(");
35480 let mut first = true;
35481 for (k, v) in e.keys.iter().zip(e.values.iter()) {
35482 if !first {
35483 self.write(", ");
35484 }
35485 self.generate_expression(k)?;
35486 self.write(", ");
35487 self.generate_expression(v)?;
35488 first = false;
35489 }
35490 self.write(")");
35491 Ok(())
35492 }
35493
35494 fn generate_vector_search(&mut self, e: &VectorSearch) -> Result<()> {
35495 self.write_keyword("VECTOR_SEARCH");
35497 self.write("(");
35498 self.generate_expression(&e.this)?;
35499 if let Some(col) = &e.column_to_search {
35500 self.write(", ");
35501 self.generate_expression(col)?;
35502 }
35503 if let Some(query_table) = &e.query_table {
35504 self.write(", ");
35505 self.generate_expression(query_table)?;
35506 }
35507 if let Some(query_col) = &e.query_column_to_search {
35508 self.write(", ");
35509 self.generate_expression(query_col)?;
35510 }
35511 if let Some(top_k) = &e.top_k {
35512 self.write(", ");
35513 self.generate_expression(top_k)?;
35514 }
35515 if let Some(dist_type) = &e.distance_type {
35516 self.write(", ");
35517 self.generate_expression(dist_type)?;
35518 }
35519 self.write(")");
35520 Ok(())
35521 }
35522
35523 fn generate_version(&mut self, e: &Version) -> Result<()> {
35524 use crate::dialects::DialectType;
35530 let skip_for = matches!(
35531 self.config.dialect,
35532 Some(DialectType::Hive) | Some(DialectType::Spark)
35533 );
35534 if !skip_for {
35535 self.write_keyword("FOR");
35536 self.write_space();
35537 }
35538 match e.this.as_ref() {
35540 Expression::Identifier(ident) => {
35541 self.write_keyword(&ident.name);
35542 }
35543 _ => {
35544 self.generate_expression(&e.this)?;
35545 }
35546 }
35547 self.write_space();
35548 self.write_keyword(&e.kind);
35549 if let Some(expression) = &e.expression {
35550 self.write_space();
35551 self.generate_expression(expression)?;
35552 }
35553 Ok(())
35554 }
35555
35556 fn generate_view_attribute_property(&mut self, e: &ViewAttributeProperty) -> Result<()> {
35557 self.generate_expression(&e.this)?;
35559 Ok(())
35560 }
35561
35562 fn generate_volatile_property(&mut self, e: &VolatileProperty) -> Result<()> {
35563 if e.this.is_some() {
35565 self.write_keyword("NOT VOLATILE");
35566 } else {
35567 self.write_keyword("VOLATILE");
35568 }
35569 Ok(())
35570 }
35571
35572 fn generate_watermark_column_constraint(
35573 &mut self,
35574 e: &WatermarkColumnConstraint,
35575 ) -> Result<()> {
35576 self.write_keyword("WATERMARK FOR");
35578 self.write_space();
35579 self.generate_expression(&e.this)?;
35580 self.write_space();
35581 self.write_keyword("AS");
35582 self.write_space();
35583 self.generate_expression(&e.expression)?;
35584 Ok(())
35585 }
35586
35587 fn generate_week(&mut self, e: &Week) -> Result<()> {
35588 self.write_keyword("WEEK");
35590 self.write("(");
35591 self.generate_expression(&e.this)?;
35592 if let Some(mode) = &e.mode {
35593 self.write(", ");
35594 self.generate_expression(mode)?;
35595 }
35596 self.write(")");
35597 Ok(())
35598 }
35599
35600 fn generate_when(&mut self, e: &When) -> Result<()> {
35601 self.write_keyword("WHEN");
35605 self.write_space();
35606
35607 if let Some(matched) = &e.matched {
35609 match matched.as_ref() {
35611 Expression::Boolean(b) if b.value => {
35612 self.write_keyword("MATCHED");
35613 }
35614 _ => {
35615 self.write_keyword("NOT MATCHED");
35616 }
35617 }
35618 } else {
35619 self.write_keyword("NOT MATCHED");
35620 }
35621
35622 if self.config.matched_by_source {
35627 if let Some(source) = &e.source {
35628 if let Expression::Boolean(b) = source.as_ref() {
35629 if b.value {
35630 self.write_space();
35632 self.write_keyword("BY SOURCE");
35633 }
35634 } else {
35636 self.write_space();
35638 self.write_keyword("BY SOURCE");
35639 }
35640 }
35641 }
35642
35643 if let Some(condition) = &e.condition {
35645 self.write_space();
35646 self.write_keyword("AND");
35647 self.write_space();
35648 self.generate_expression(condition)?;
35649 }
35650
35651 self.write_space();
35652 self.write_keyword("THEN");
35653 self.write_space();
35654
35655 self.generate_merge_action(&e.then)?;
35658
35659 Ok(())
35660 }
35661
35662 fn generate_merge_action(&mut self, action: &Expression) -> Result<()> {
35663 match action {
35664 Expression::Tuple(tuple) => {
35665 let elements = &tuple.expressions;
35666 if elements.is_empty() {
35667 return self.generate_expression(action);
35668 }
35669 match &elements[0] {
35671 Expression::Var(v) if v.this == "INSERT" => {
35672 self.write_keyword("INSERT");
35673 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
35675 self.write(" *");
35676 } else {
35677 let mut values_idx = 1;
35678 if elements.len() > 1 {
35680 if let Expression::Tuple(cols) = &elements[1] {
35681 if elements.len() > 2 {
35683 self.write(" (");
35685 for (i, col) in cols.expressions.iter().enumerate() {
35686 if i > 0 {
35687 self.write(", ");
35688 }
35689 if !self.merge_strip_qualifiers.is_empty() {
35691 let stripped = self.strip_merge_qualifier(col);
35692 self.generate_expression(&stripped)?;
35693 } else {
35694 self.generate_expression(col)?;
35695 }
35696 }
35697 self.write(")");
35698 values_idx = 2;
35699 } else {
35700 values_idx = 1;
35702 }
35703 }
35704 }
35705 if values_idx < elements.len() {
35707 let is_row = matches!(&elements[values_idx], Expression::Var(v) if v.this == "ROW");
35709 if !is_row {
35710 self.write_space();
35711 self.write_keyword("VALUES");
35712 }
35713 self.write(" ");
35714 if let Expression::Tuple(vals) = &elements[values_idx] {
35715 self.write("(");
35716 for (i, val) in vals.expressions.iter().enumerate() {
35717 if i > 0 {
35718 self.write(", ");
35719 }
35720 self.generate_expression(val)?;
35721 }
35722 self.write(")");
35723 } else {
35724 self.generate_expression(&elements[values_idx])?;
35725 }
35726 }
35727 } }
35729 Expression::Var(v) if v.this == "UPDATE" => {
35730 self.write_keyword("UPDATE");
35731 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
35733 self.write(" *");
35734 } else if elements.len() > 1 {
35735 self.write_space();
35736 self.write_keyword("SET");
35737 if self.config.pretty {
35739 self.write_newline();
35740 self.indent_level += 1;
35741 self.write_indent();
35742 } else {
35743 self.write_space();
35744 }
35745 if let Expression::Tuple(assignments) = &elements[1] {
35746 for (i, assignment) in assignments.expressions.iter().enumerate() {
35747 if i > 0 {
35748 if self.config.pretty {
35749 self.write(",");
35750 self.write_newline();
35751 self.write_indent();
35752 } else {
35753 self.write(", ");
35754 }
35755 }
35756 if !self.merge_strip_qualifiers.is_empty() {
35758 self.generate_merge_set_assignment(assignment)?;
35759 } else {
35760 self.generate_expression(assignment)?;
35761 }
35762 }
35763 } else {
35764 self.generate_expression(&elements[1])?;
35765 }
35766 if self.config.pretty {
35767 self.indent_level -= 1;
35768 }
35769 }
35770 }
35771 _ => {
35772 self.generate_expression(action)?;
35774 }
35775 }
35776 }
35777 Expression::Var(v)
35778 if v.this == "INSERT"
35779 || v.this == "UPDATE"
35780 || v.this == "DELETE"
35781 || v.this == "DO NOTHING" =>
35782 {
35783 self.write_keyword(&v.this);
35784 }
35785 _ => {
35786 self.generate_expression(action)?;
35787 }
35788 }
35789 Ok(())
35790 }
35791
35792 fn generate_merge_set_assignment(&mut self, assignment: &Expression) -> Result<()> {
35794 match assignment {
35795 Expression::Eq(eq) => {
35796 let stripped_left = self.strip_merge_qualifier(&eq.left);
35798 self.generate_expression(&stripped_left)?;
35799 self.write(" = ");
35800 self.generate_expression(&eq.right)?;
35801 Ok(())
35802 }
35803 other => self.generate_expression(other),
35804 }
35805 }
35806
35807 fn strip_merge_qualifier(&self, expr: &Expression) -> Expression {
35809 match expr {
35810 Expression::Column(col) => {
35811 if let Some(ref table_ident) = col.table {
35812 if self
35813 .merge_strip_qualifiers
35814 .iter()
35815 .any(|n| n.eq_ignore_ascii_case(&table_ident.name))
35816 {
35817 let mut col = col.clone();
35819 col.table = None;
35820 return Expression::Column(col);
35821 }
35822 }
35823 expr.clone()
35824 }
35825 Expression::Dot(dot) => {
35826 if let Expression::Identifier(id) = &dot.this {
35828 if self
35829 .merge_strip_qualifiers
35830 .iter()
35831 .any(|n| n.eq_ignore_ascii_case(&id.name))
35832 {
35833 return Expression::Identifier(dot.field.clone());
35834 }
35835 }
35836 expr.clone()
35837 }
35838 _ => expr.clone(),
35839 }
35840 }
35841
35842 fn generate_whens(&mut self, e: &Whens) -> Result<()> {
35843 for (i, expr) in e.expressions.iter().enumerate() {
35845 if i > 0 {
35846 if self.config.pretty {
35848 self.write_newline();
35849 self.write_indent();
35850 } else {
35851 self.write_space();
35852 }
35853 }
35854 self.generate_expression(expr)?;
35855 }
35856 Ok(())
35857 }
35858
35859 fn generate_where(&mut self, e: &Where) -> Result<()> {
35860 self.write_keyword("WHERE");
35862 self.write_space();
35863 self.generate_expression(&e.this)?;
35864 Ok(())
35865 }
35866
35867 fn generate_width_bucket(&mut self, e: &WidthBucket) -> Result<()> {
35868 self.write_keyword("WIDTH_BUCKET");
35870 self.write("(");
35871 self.generate_expression(&e.this)?;
35872 if let Some(min_value) = &e.min_value {
35873 self.write(", ");
35874 self.generate_expression(min_value)?;
35875 }
35876 if let Some(max_value) = &e.max_value {
35877 self.write(", ");
35878 self.generate_expression(max_value)?;
35879 }
35880 if let Some(num_buckets) = &e.num_buckets {
35881 self.write(", ");
35882 self.generate_expression(num_buckets)?;
35883 }
35884 self.write(")");
35885 Ok(())
35886 }
35887
35888 fn generate_window(&mut self, e: &WindowSpec) -> Result<()> {
35889 self.generate_window_spec(e)
35891 }
35892
35893 fn generate_window_spec(&mut self, e: &WindowSpec) -> Result<()> {
35894 let mut has_content = false;
35896
35897 if !e.partition_by.is_empty() {
35899 self.write_keyword("PARTITION BY");
35900 self.write_space();
35901 for (i, expr) in e.partition_by.iter().enumerate() {
35902 if i > 0 {
35903 self.write(", ");
35904 }
35905 self.generate_expression(expr)?;
35906 }
35907 has_content = true;
35908 }
35909
35910 if !e.order_by.is_empty() {
35912 if has_content {
35913 self.write_space();
35914 }
35915 self.write_keyword("ORDER BY");
35916 self.write_space();
35917 for (i, ordered) in e.order_by.iter().enumerate() {
35918 if i > 0 {
35919 self.write(", ");
35920 }
35921 self.generate_expression(&ordered.this)?;
35922 if ordered.desc {
35923 self.write_space();
35924 self.write_keyword("DESC");
35925 } else if ordered.explicit_asc {
35926 self.write_space();
35927 self.write_keyword("ASC");
35928 }
35929 if let Some(nulls_first) = ordered.nulls_first {
35930 self.write_space();
35931 self.write_keyword("NULLS");
35932 self.write_space();
35933 if nulls_first {
35934 self.write_keyword("FIRST");
35935 } else {
35936 self.write_keyword("LAST");
35937 }
35938 }
35939 }
35940 has_content = true;
35941 }
35942
35943 if let Some(frame) = &e.frame {
35945 if has_content {
35946 self.write_space();
35947 }
35948 self.generate_window_frame(frame)?;
35949 }
35950
35951 Ok(())
35952 }
35953
35954 fn generate_with_data_property(&mut self, e: &WithDataProperty) -> Result<()> {
35955 self.write_keyword("WITH");
35957 self.write_space();
35958 if e.no.is_some() {
35959 self.write_keyword("NO");
35960 self.write_space();
35961 }
35962 self.write_keyword("DATA");
35963
35964 if let Some(statistics) = &e.statistics {
35966 self.write_space();
35967 self.write_keyword("AND");
35968 self.write_space();
35969 match statistics.as_ref() {
35971 Expression::Boolean(b) if !b.value => {
35972 self.write_keyword("NO");
35973 self.write_space();
35974 }
35975 _ => {}
35976 }
35977 self.write_keyword("STATISTICS");
35978 }
35979 Ok(())
35980 }
35981
35982 fn generate_with_fill(&mut self, e: &WithFill) -> Result<()> {
35983 self.write_keyword("WITH FILL");
35985
35986 if let Some(from_) = &e.from_ {
35987 self.write_space();
35988 self.write_keyword("FROM");
35989 self.write_space();
35990 self.generate_expression(from_)?;
35991 }
35992
35993 if let Some(to) = &e.to {
35994 self.write_space();
35995 self.write_keyword("TO");
35996 self.write_space();
35997 self.generate_expression(to)?;
35998 }
35999
36000 if let Some(step) = &e.step {
36001 self.write_space();
36002 self.write_keyword("STEP");
36003 self.write_space();
36004 self.generate_expression(step)?;
36005 }
36006
36007 if let Some(staleness) = &e.staleness {
36008 self.write_space();
36009 self.write_keyword("STALENESS");
36010 self.write_space();
36011 self.generate_expression(staleness)?;
36012 }
36013
36014 if let Some(interpolate) = &e.interpolate {
36015 self.write_space();
36016 self.write_keyword("INTERPOLATE");
36017 self.write(" (");
36018 self.generate_interpolate_item(interpolate)?;
36020 self.write(")");
36021 }
36022
36023 Ok(())
36024 }
36025
36026 fn generate_interpolate_item(&mut self, expr: &Expression) -> Result<()> {
36028 match expr {
36029 Expression::Alias(alias) => {
36030 self.generate_identifier(&alias.alias)?;
36032 self.write_space();
36033 self.write_keyword("AS");
36034 self.write_space();
36035 self.generate_expression(&alias.this)?;
36036 }
36037 Expression::Tuple(tuple) => {
36038 for (i, item) in tuple.expressions.iter().enumerate() {
36039 if i > 0 {
36040 self.write(", ");
36041 }
36042 self.generate_interpolate_item(item)?;
36043 }
36044 }
36045 other => {
36046 self.generate_expression(other)?;
36047 }
36048 }
36049 Ok(())
36050 }
36051
36052 fn generate_with_journal_table_property(&mut self, e: &WithJournalTableProperty) -> Result<()> {
36053 self.write_keyword("WITH JOURNAL TABLE");
36055 self.write("=");
36056 self.generate_expression(&e.this)?;
36057 Ok(())
36058 }
36059
36060 fn generate_with_operator(&mut self, e: &WithOperator) -> Result<()> {
36061 self.generate_expression(&e.this)?;
36063 self.write_space();
36064 self.write_keyword("WITH");
36065 self.write_space();
36066 self.write_keyword(&e.op);
36067 Ok(())
36068 }
36069
36070 fn generate_with_procedure_options(&mut self, e: &WithProcedureOptions) -> Result<()> {
36071 self.write_keyword("WITH");
36073 self.write_space();
36074 for (i, expr) in e.expressions.iter().enumerate() {
36075 if i > 0 {
36076 self.write(", ");
36077 }
36078 self.generate_expression(expr)?;
36079 }
36080 Ok(())
36081 }
36082
36083 fn generate_with_schema_binding_property(
36084 &mut self,
36085 e: &WithSchemaBindingProperty,
36086 ) -> Result<()> {
36087 self.write_keyword("WITH");
36089 self.write_space();
36090 self.generate_expression(&e.this)?;
36091 Ok(())
36092 }
36093
36094 fn generate_with_system_versioning_property(
36095 &mut self,
36096 e: &WithSystemVersioningProperty,
36097 ) -> Result<()> {
36098 let mut parts = Vec::new();
36104
36105 if let Some(this) = &e.this {
36106 let mut s = String::from("HISTORY_TABLE=");
36108 let mut gen = Generator::new();
36109 gen.generate_expression(this)?;
36110 s.push_str(&gen.output);
36111 parts.push(s);
36112 }
36113
36114 if let Some(data_consistency) = &e.data_consistency {
36115 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
36116 let mut gen = Generator::new();
36117 gen.generate_expression(data_consistency)?;
36118 s.push_str(&gen.output);
36119 parts.push(s);
36120 }
36121
36122 if let Some(retention_period) = &e.retention_period {
36123 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
36124 let mut gen = Generator::new();
36125 gen.generate_expression(retention_period)?;
36126 s.push_str(&gen.output);
36127 parts.push(s);
36128 }
36129
36130 self.write_keyword("SYSTEM_VERSIONING");
36131 self.write("=");
36132
36133 if !parts.is_empty() {
36134 self.write_keyword("ON");
36135 self.write("(");
36136 self.write(&parts.join(", "));
36137 self.write(")");
36138 } else if e.on.is_some() {
36139 self.write_keyword("ON");
36140 } else {
36141 self.write_keyword("OFF");
36142 }
36143
36144 if e.with_.is_some() {
36146 let inner = self.output.clone();
36147 self.output.clear();
36148 self.write("WITH(");
36149 self.write(&inner);
36150 self.write(")");
36151 }
36152
36153 Ok(())
36154 }
36155
36156 fn generate_with_table_hint(&mut self, e: &WithTableHint) -> Result<()> {
36157 self.write_keyword("WITH");
36159 self.write(" (");
36160 for (i, expr) in e.expressions.iter().enumerate() {
36161 if i > 0 {
36162 self.write(", ");
36163 }
36164 self.generate_expression(expr)?;
36165 }
36166 self.write(")");
36167 Ok(())
36168 }
36169
36170 fn generate_xml_element(&mut self, e: &XMLElement) -> Result<()> {
36171 self.write_keyword("XMLELEMENT");
36174 self.write("(");
36175
36176 if e.evalname.is_some() {
36177 self.write_keyword("EVALNAME");
36178 } else {
36179 self.write_keyword("NAME");
36180 }
36181 self.write_space();
36182 self.generate_expression(&e.this)?;
36183
36184 for expr in &e.expressions {
36185 self.write(", ");
36186 self.generate_expression(expr)?;
36187 }
36188 self.write(")");
36189 Ok(())
36190 }
36191
36192 fn generate_xml_get(&mut self, e: &XMLGet) -> Result<()> {
36193 self.write_keyword("XMLGET");
36195 self.write("(");
36196 self.generate_expression(&e.this)?;
36197 self.write(", ");
36198 self.generate_expression(&e.expression)?;
36199 if let Some(instance) = &e.instance {
36200 self.write(", ");
36201 self.generate_expression(instance)?;
36202 }
36203 self.write(")");
36204 Ok(())
36205 }
36206
36207 fn generate_xml_key_value_option(&mut self, e: &XMLKeyValueOption) -> Result<()> {
36208 self.generate_expression(&e.this)?;
36210 if let Some(expression) = &e.expression {
36211 self.write("(");
36212 self.generate_expression(expression)?;
36213 self.write(")");
36214 }
36215 Ok(())
36216 }
36217
36218 fn generate_xml_table(&mut self, e: &XMLTable) -> Result<()> {
36219 self.write_keyword("XMLTABLE");
36221 self.write("(");
36222
36223 if self.config.pretty {
36224 self.indent_level += 1;
36225 self.write_newline();
36226 self.write_indent();
36227 self.generate_expression(&e.this)?;
36228
36229 if let Some(passing) = &e.passing {
36230 self.write_newline();
36231 self.write_indent();
36232 self.write_keyword("PASSING");
36233 if let Expression::Tuple(tuple) = passing.as_ref() {
36234 for expr in &tuple.expressions {
36235 self.write_newline();
36236 self.indent_level += 1;
36237 self.write_indent();
36238 self.generate_expression(expr)?;
36239 self.indent_level -= 1;
36240 }
36241 } else {
36242 self.write_newline();
36243 self.indent_level += 1;
36244 self.write_indent();
36245 self.generate_expression(passing)?;
36246 self.indent_level -= 1;
36247 }
36248 }
36249
36250 if e.by_ref.is_some() {
36251 self.write_newline();
36252 self.write_indent();
36253 self.write_keyword("RETURNING SEQUENCE BY REF");
36254 }
36255
36256 if !e.columns.is_empty() {
36257 self.write_newline();
36258 self.write_indent();
36259 self.write_keyword("COLUMNS");
36260 for (i, col) in e.columns.iter().enumerate() {
36261 self.write_newline();
36262 self.indent_level += 1;
36263 self.write_indent();
36264 self.generate_expression(col)?;
36265 self.indent_level -= 1;
36266 if i < e.columns.len() - 1 {
36267 self.write(",");
36268 }
36269 }
36270 }
36271
36272 self.indent_level -= 1;
36273 self.write_newline();
36274 self.write_indent();
36275 self.write(")");
36276 return Ok(());
36277 }
36278
36279 if let Some(namespaces) = &e.namespaces {
36281 self.write_keyword("XMLNAMESPACES");
36282 self.write("(");
36283 if let Expression::Tuple(tuple) = namespaces.as_ref() {
36285 for (i, expr) in tuple.expressions.iter().enumerate() {
36286 if i > 0 {
36287 self.write(", ");
36288 }
36289 if !matches!(expr, Expression::Alias(_)) {
36292 self.write_keyword("DEFAULT");
36293 self.write_space();
36294 }
36295 self.generate_expression(expr)?;
36296 }
36297 } else {
36298 if !matches!(namespaces.as_ref(), Expression::Alias(_)) {
36300 self.write_keyword("DEFAULT");
36301 self.write_space();
36302 }
36303 self.generate_expression(namespaces)?;
36304 }
36305 self.write("), ");
36306 }
36307
36308 self.generate_expression(&e.this)?;
36310
36311 if let Some(passing) = &e.passing {
36313 self.write_space();
36314 self.write_keyword("PASSING");
36315 self.write_space();
36316 if let Expression::Tuple(tuple) = passing.as_ref() {
36318 for (i, expr) in tuple.expressions.iter().enumerate() {
36319 if i > 0 {
36320 self.write(", ");
36321 }
36322 self.generate_expression(expr)?;
36323 }
36324 } else {
36325 self.generate_expression(passing)?;
36326 }
36327 }
36328
36329 if e.by_ref.is_some() {
36331 self.write_space();
36332 self.write_keyword("RETURNING SEQUENCE BY REF");
36333 }
36334
36335 if !e.columns.is_empty() {
36337 self.write_space();
36338 self.write_keyword("COLUMNS");
36339 self.write_space();
36340 for (i, col) in e.columns.iter().enumerate() {
36341 if i > 0 {
36342 self.write(", ");
36343 }
36344 self.generate_expression(col)?;
36345 }
36346 }
36347
36348 self.write(")");
36349 Ok(())
36350 }
36351
36352 fn generate_xor(&mut self, e: &Xor) -> Result<()> {
36353 if let Some(this) = &e.this {
36356 self.generate_expression(this)?;
36357 if let Some(expression) = &e.expression {
36358 self.write_space();
36359 self.write_keyword("XOR");
36360 self.write_space();
36361 self.generate_expression(expression)?;
36362 }
36363 }
36364
36365 for (i, expr) in e.expressions.iter().enumerate() {
36367 if i > 0 || e.this.is_some() {
36368 self.write_space();
36369 self.write_keyword("XOR");
36370 self.write_space();
36371 }
36372 self.generate_expression(expr)?;
36373 }
36374 Ok(())
36375 }
36376
36377 fn generate_zipf(&mut self, e: &Zipf) -> Result<()> {
36378 self.write_keyword("ZIPF");
36380 self.write("(");
36381 self.generate_expression(&e.this)?;
36382 if let Some(elementcount) = &e.elementcount {
36383 self.write(", ");
36384 self.generate_expression(elementcount)?;
36385 }
36386 if let Some(gen) = &e.gen {
36387 self.write(", ");
36388 self.generate_expression(gen)?;
36389 }
36390 self.write(")");
36391 Ok(())
36392 }
36393}
36394
36395impl Default for Generator {
36396 fn default() -> Self {
36397 Self::new()
36398 }
36399}
36400
36401#[cfg(test)]
36402mod tests {
36403 use super::*;
36404 use crate::parser::Parser;
36405
36406 fn roundtrip(sql: &str) -> String {
36407 let ast = Parser::parse_sql(sql).unwrap();
36408 Generator::sql(&ast[0]).unwrap()
36409 }
36410
36411 #[test]
36412 fn test_simple_select() {
36413 let result = roundtrip("SELECT 1");
36414 assert_eq!(result, "SELECT 1");
36415 }
36416
36417 #[test]
36418 fn test_select_from() {
36419 let result = roundtrip("SELECT a, b FROM t");
36420 assert_eq!(result, "SELECT a, b FROM t");
36421 }
36422
36423 #[test]
36424 fn test_select_where() {
36425 let result = roundtrip("SELECT * FROM t WHERE x = 1");
36426 assert_eq!(result, "SELECT * FROM t WHERE x = 1");
36427 }
36428
36429 #[test]
36430 fn test_select_join() {
36431 let result = roundtrip("SELECT * FROM a JOIN b ON a.id = b.id");
36432 assert_eq!(result, "SELECT * FROM a JOIN b ON a.id = b.id");
36433 }
36434
36435 #[test]
36436 fn test_insert() {
36437 let result = roundtrip("INSERT INTO t (a, b) VALUES (1, 2)");
36438 assert_eq!(result, "INSERT INTO t (a, b) VALUES (1, 2)");
36439 }
36440
36441 #[test]
36442 fn test_pretty_print() {
36443 let ast = Parser::parse_sql("SELECT a, b FROM t WHERE x = 1").unwrap();
36444 let result = Generator::pretty_sql(&ast[0]).unwrap();
36445 assert!(result.contains('\n'));
36446 }
36447
36448 #[test]
36449 fn test_window_function() {
36450 let result = roundtrip("SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)");
36451 assert_eq!(
36452 result,
36453 "SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)"
36454 );
36455 }
36456
36457 #[test]
36458 fn test_window_function_with_frame() {
36459 let result = roundtrip("SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
36460 assert_eq!(result, "SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
36461 }
36462
36463 #[test]
36464 fn test_aggregate_with_filter() {
36465 let result = roundtrip("SELECT COUNT(*) FILTER (WHERE status = 1) FROM orders");
36466 assert_eq!(
36467 result,
36468 "SELECT COUNT(*) FILTER(WHERE status = 1) FROM orders"
36469 );
36470 }
36471
36472 #[test]
36473 fn test_subscript() {
36474 let result = roundtrip("SELECT arr[0]");
36475 assert_eq!(result, "SELECT arr[0]");
36476 }
36477
36478 #[test]
36480 fn test_create_table() {
36481 let result = roundtrip("CREATE TABLE users (id INT, name VARCHAR(100))");
36482 assert_eq!(result, "CREATE TABLE users (id INT, name VARCHAR(100))");
36483 }
36484
36485 #[test]
36486 fn test_create_table_with_constraints() {
36487 let result = roundtrip(
36488 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)",
36489 );
36490 assert_eq!(
36491 result,
36492 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)"
36493 );
36494 }
36495
36496 #[test]
36497 fn test_create_table_if_not_exists() {
36498 let result = roundtrip("CREATE TABLE IF NOT EXISTS t (id INT)");
36499 assert_eq!(result, "CREATE TABLE IF NOT EXISTS t (id INT)");
36500 }
36501
36502 #[test]
36503 fn test_drop_table() {
36504 let result = roundtrip("DROP TABLE users");
36505 assert_eq!(result, "DROP TABLE users");
36506 }
36507
36508 #[test]
36509 fn test_drop_table_if_exists_cascade() {
36510 let result = roundtrip("DROP TABLE IF EXISTS users CASCADE");
36511 assert_eq!(result, "DROP TABLE IF EXISTS users CASCADE");
36512 }
36513
36514 #[test]
36515 fn test_alter_table_add_column() {
36516 let result = roundtrip("ALTER TABLE users ADD COLUMN email VARCHAR(255)");
36517 assert_eq!(result, "ALTER TABLE users ADD COLUMN email VARCHAR(255)");
36518 }
36519
36520 #[test]
36521 fn test_alter_table_drop_column() {
36522 let result = roundtrip("ALTER TABLE users DROP COLUMN email");
36523 assert_eq!(result, "ALTER TABLE users DROP COLUMN email");
36524 }
36525
36526 #[test]
36527 fn test_create_index() {
36528 let result = roundtrip("CREATE INDEX idx_name ON users(name)");
36529 assert_eq!(result, "CREATE INDEX idx_name ON users(name)");
36530 }
36531
36532 #[test]
36533 fn test_create_unique_index() {
36534 let result = roundtrip("CREATE UNIQUE INDEX idx_email ON users(email)");
36535 assert_eq!(result, "CREATE UNIQUE INDEX idx_email ON users(email)");
36536 }
36537
36538 #[test]
36539 fn test_drop_index() {
36540 let result = roundtrip("DROP INDEX idx_name");
36541 assert_eq!(result, "DROP INDEX idx_name");
36542 }
36543
36544 #[test]
36545 fn test_create_view() {
36546 let result = roundtrip("CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1");
36547 assert_eq!(
36548 result,
36549 "CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1"
36550 );
36551 }
36552
36553 #[test]
36554 fn test_drop_view() {
36555 let result = roundtrip("DROP VIEW active_users");
36556 assert_eq!(result, "DROP VIEW active_users");
36557 }
36558
36559 #[test]
36560 fn test_truncate() {
36561 let result = roundtrip("TRUNCATE TABLE users");
36562 assert_eq!(result, "TRUNCATE TABLE users");
36563 }
36564
36565 #[test]
36566 fn test_string_literal_escaping_default() {
36567 let result = roundtrip("SELECT 'hello'");
36569 assert_eq!(result, "SELECT 'hello'");
36570
36571 let result = roundtrip("SELECT 'it''s a test'");
36573 assert_eq!(result, "SELECT 'it''s a test'");
36574 }
36575
36576 #[test]
36577 fn test_not_in_style_prefix_default_generic() {
36578 let result = roundtrip("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')");
36579 assert_eq!(
36580 result,
36581 "SELECT id FROM users WHERE NOT status IN ('deleted', 'banned')"
36582 );
36583 }
36584
36585 #[test]
36586 fn test_not_in_style_infix_generic_override() {
36587 let ast =
36588 Parser::parse_sql("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')")
36589 .unwrap();
36590 let config = GeneratorConfig {
36591 not_in_style: NotInStyle::Infix,
36592 ..Default::default()
36593 };
36594 let mut gen = Generator::with_config(config);
36595 let result = gen.generate(&ast[0]).unwrap();
36596 assert_eq!(
36597 result,
36598 "SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')"
36599 );
36600 }
36601
36602 #[test]
36603 fn test_string_literal_escaping_mysql() {
36604 use crate::dialects::DialectType;
36605
36606 let config = GeneratorConfig {
36607 dialect: Some(DialectType::MySQL),
36608 ..Default::default()
36609 };
36610
36611 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
36612 let mut gen = Generator::with_config(config.clone());
36613 let result = gen.generate(&ast[0]).unwrap();
36614 assert_eq!(result, "SELECT 'hello'");
36615
36616 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
36618 let mut gen = Generator::with_config(config.clone());
36619 let result = gen.generate(&ast[0]).unwrap();
36620 assert_eq!(result, "SELECT 'it''s'");
36621 }
36622
36623 #[test]
36624 fn test_string_literal_escaping_postgres() {
36625 use crate::dialects::DialectType;
36626
36627 let config = GeneratorConfig {
36628 dialect: Some(DialectType::PostgreSQL),
36629 ..Default::default()
36630 };
36631
36632 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
36633 let mut gen = Generator::with_config(config.clone());
36634 let result = gen.generate(&ast[0]).unwrap();
36635 assert_eq!(result, "SELECT 'hello'");
36636
36637 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
36639 let mut gen = Generator::with_config(config.clone());
36640 let result = gen.generate(&ast[0]).unwrap();
36641 assert_eq!(result, "SELECT 'it''s'");
36642 }
36643
36644 #[test]
36645 fn test_string_literal_escaping_bigquery() {
36646 use crate::dialects::DialectType;
36647
36648 let config = GeneratorConfig {
36649 dialect: Some(DialectType::BigQuery),
36650 ..Default::default()
36651 };
36652
36653 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
36654 let mut gen = Generator::with_config(config.clone());
36655 let result = gen.generate(&ast[0]).unwrap();
36656 assert_eq!(result, "SELECT 'hello'");
36657
36658 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
36660 let mut gen = Generator::with_config(config.clone());
36661 let result = gen.generate(&ast[0]).unwrap();
36662 assert_eq!(result, "SELECT 'it\\'s'");
36663 }
36664
36665 #[test]
36666 fn test_generate_deep_and_chain_without_stack_growth() {
36667 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
36668 Expression::column("c0"),
36669 Expression::number(0),
36670 )));
36671
36672 for i in 1..2500 {
36673 let predicate = Expression::Eq(Box::new(BinaryOp::new(
36674 Expression::column(format!("c{i}")),
36675 Expression::number(i as i64),
36676 )));
36677 expr = Expression::And(Box::new(BinaryOp::new(expr, predicate)));
36678 }
36679
36680 let sql = Generator::sql(&expr).expect("deep AND chain should generate");
36681 assert!(sql.contains("c2499 = 2499"), "{}", sql);
36682 }
36683
36684 #[test]
36685 fn test_generate_deep_or_chain_without_stack_growth() {
36686 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
36687 Expression::column("c0"),
36688 Expression::number(0),
36689 )));
36690
36691 for i in 1..2500 {
36692 let predicate = Expression::Eq(Box::new(BinaryOp::new(
36693 Expression::column(format!("c{i}")),
36694 Expression::number(i as i64),
36695 )));
36696 expr = Expression::Or(Box::new(BinaryOp::new(expr, predicate)));
36697 }
36698
36699 let sql = Generator::sql(&expr).expect("deep OR chain should generate");
36700 assert!(sql.contains("c2499 = 2499"), "{}", sql);
36701 }
36702}