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 inferred_type: None,
2173 })),
2174
2175 Expression::Identifier(ident) => Expression::Alias(Box::new(Alias {
2177 this: expr.clone(),
2178 alias: ident.clone(),
2179 column_aliases: Vec::new(),
2180 pre_alias_comments: Vec::new(),
2181 trailing_comments: Vec::new(),
2182 inferred_type: None,
2183 })),
2184
2185 Expression::Subquery(sq) => {
2187 let processed = Self::add_column_aliases_to_query(Expression::Subquery(sq.clone()));
2188 if sq.alias.is_some() {
2190 processed
2191 } else {
2192 processed
2194 }
2195 }
2196
2197 Expression::Star(_) => expr,
2199
2200 _ => expr,
2203 }
2204 }
2205
2206 fn try_evaluate_constant(expr: &Expression) -> Option<i64> {
2210 match expr {
2211 Expression::Literal(Literal::Number(n)) => n.parse::<i64>().ok(),
2212 Expression::Add(op) => {
2213 let left = Self::try_evaluate_constant(&op.left)?;
2214 let right = Self::try_evaluate_constant(&op.right)?;
2215 Some(left + right)
2216 }
2217 Expression::Sub(op) => {
2218 let left = Self::try_evaluate_constant(&op.left)?;
2219 let right = Self::try_evaluate_constant(&op.right)?;
2220 Some(left - right)
2221 }
2222 Expression::Mul(op) => {
2223 let left = Self::try_evaluate_constant(&op.left)?;
2224 let right = Self::try_evaluate_constant(&op.right)?;
2225 Some(left * right)
2226 }
2227 Expression::Div(op) => {
2228 let left = Self::try_evaluate_constant(&op.left)?;
2229 let right = Self::try_evaluate_constant(&op.right)?;
2230 if right != 0 {
2231 Some(left / right)
2232 } else {
2233 None
2234 }
2235 }
2236 Expression::Paren(p) => Self::try_evaluate_constant(&p.this),
2237 _ => None,
2238 }
2239 }
2240
2241 fn is_reserved_keyword(&self, name: &str) -> bool {
2243 use crate::dialects::DialectType;
2244 let lower = name.to_lowercase();
2245 let lower_ref = lower.as_str();
2246
2247 match self.config.dialect {
2248 Some(DialectType::BigQuery) => reserved_keywords::BIGQUERY_RESERVED.contains(lower_ref),
2249 Some(DialectType::MySQL) | Some(DialectType::TiDB) => {
2250 reserved_keywords::MYSQL_RESERVED.contains(lower_ref)
2251 }
2252 Some(DialectType::Doris) => reserved_keywords::DORIS_RESERVED.contains(lower_ref),
2253 Some(DialectType::SingleStore) => {
2254 reserved_keywords::SINGLESTORE_RESERVED.contains(lower_ref)
2255 }
2256 Some(DialectType::StarRocks) => {
2257 reserved_keywords::STARROCKS_RESERVED.contains(lower_ref)
2258 }
2259 Some(DialectType::PostgreSQL)
2260 | Some(DialectType::CockroachDB)
2261 | Some(DialectType::Materialize)
2262 | Some(DialectType::RisingWave) => {
2263 reserved_keywords::POSTGRES_RESERVED.contains(lower_ref)
2264 }
2265 Some(DialectType::Redshift) => reserved_keywords::REDSHIFT_RESERVED.contains(lower_ref),
2266 Some(DialectType::Snowflake) => false,
2269 Some(DialectType::ClickHouse) => false,
2271 Some(DialectType::DuckDB) => reserved_keywords::DUCKDB_RESERVED.contains(lower_ref),
2272 Some(DialectType::Teradata) => false,
2274 Some(DialectType::TSQL)
2276 | Some(DialectType::Fabric)
2277 | Some(DialectType::Oracle)
2278 | Some(DialectType::Spark)
2279 | Some(DialectType::Databricks)
2280 | Some(DialectType::Hive)
2281 | Some(DialectType::Solr) => false,
2282 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
2283 reserved_keywords::PRESTO_TRINO_RESERVED.contains(lower_ref)
2284 }
2285 Some(DialectType::SQLite) => reserved_keywords::SQLITE_RESERVED.contains(lower_ref),
2286 Some(DialectType::Generic) | None => false,
2288 _ => reserved_keywords::SQL_RESERVED.contains(lower_ref),
2290 }
2291 }
2292
2293 fn normalize_func_name(&self, name: &str) -> String {
2295 match self.config.normalize_functions {
2296 NormalizeFunctions::Upper => name.to_uppercase(),
2297 NormalizeFunctions::Lower => name.to_lowercase(),
2298 NormalizeFunctions::None => name.to_string(),
2299 }
2300 }
2301
2302 pub fn generate(&mut self, expr: &Expression) -> Result<String> {
2311 self.output.clear();
2312 self.generate_expression(expr)?;
2313 Ok(std::mem::take(&mut self.output))
2314 }
2315
2316 pub fn sql(expr: &Expression) -> Result<String> {
2322 let mut gen = Generator::new();
2323 gen.generate(expr)
2324 }
2325
2326 pub fn pretty_sql(expr: &Expression) -> Result<String> {
2331 let config = GeneratorConfig {
2332 pretty: true,
2333 ..Default::default()
2334 };
2335 let mut gen = Generator::with_config(config);
2336 let mut sql = gen.generate(expr)?;
2337 if !sql.ends_with(';') {
2339 sql.push(';');
2340 }
2341 Ok(sql)
2342 }
2343
2344 fn generate_expression(&mut self, expr: &Expression) -> Result<()> {
2345 match expr {
2346 Expression::Select(select) => self.generate_select(select),
2347 Expression::Union(union) => self.generate_union(union),
2348 Expression::Intersect(intersect) => self.generate_intersect(intersect),
2349 Expression::Except(except) => self.generate_except(except),
2350 Expression::Insert(insert) => self.generate_insert(insert),
2351 Expression::Update(update) => self.generate_update(update),
2352 Expression::Delete(delete) => self.generate_delete(delete),
2353 Expression::Literal(lit) => self.generate_literal(lit),
2354 Expression::Boolean(b) => self.generate_boolean(b),
2355 Expression::Null(_) => {
2356 self.write_keyword("NULL");
2357 Ok(())
2358 }
2359 Expression::Identifier(id) => self.generate_identifier(id),
2360 Expression::Column(col) => self.generate_column(col),
2361 Expression::Pseudocolumn(pc) => self.generate_pseudocolumn(pc),
2362 Expression::Connect(c) => self.generate_connect_expr(c),
2363 Expression::Prior(p) => self.generate_prior(p),
2364 Expression::ConnectByRoot(cbr) => self.generate_connect_by_root(cbr),
2365 Expression::MatchRecognize(mr) => self.generate_match_recognize(mr),
2366 Expression::Table(table) => self.generate_table(table),
2367 Expression::StageReference(sr) => self.generate_stage_reference(sr),
2368 Expression::HistoricalData(hd) => self.generate_historical_data(hd),
2369 Expression::JoinedTable(jt) => self.generate_joined_table(jt),
2370 Expression::Star(star) => self.generate_star(star),
2371 Expression::BracedWildcard(expr) => self.generate_braced_wildcard(expr),
2372 Expression::Alias(alias) => self.generate_alias(alias),
2373 Expression::Cast(cast) => self.generate_cast(cast),
2374 Expression::Collation(coll) => self.generate_collation(coll),
2375 Expression::Case(case) => self.generate_case(case),
2376 Expression::Function(func) => self.generate_function(func),
2377 Expression::AggregateFunction(func) => self.generate_aggregate_function(func),
2378 Expression::WindowFunction(wf) => self.generate_window_function(wf),
2379 Expression::WithinGroup(wg) => self.generate_within_group(wg),
2380 Expression::Interval(interval) => self.generate_interval(interval),
2381
2382 Expression::ConcatWs(f) => self.generate_concat_ws(f),
2384 Expression::Substring(f) => self.generate_substring(f),
2385 Expression::Upper(f) => self.generate_unary_func("UPPER", f),
2386 Expression::Lower(f) => self.generate_unary_func("LOWER", f),
2387 Expression::Length(f) => self.generate_unary_func("LENGTH", f),
2388 Expression::Trim(f) => self.generate_trim(f),
2389 Expression::LTrim(f) => self.generate_simple_func("LTRIM", &f.this),
2390 Expression::RTrim(f) => self.generate_simple_func("RTRIM", &f.this),
2391 Expression::Replace(f) => self.generate_replace(f),
2392 Expression::Reverse(f) => self.generate_simple_func("REVERSE", &f.this),
2393 Expression::Left(f) => self.generate_left_right("LEFT", f),
2394 Expression::Right(f) => self.generate_left_right("RIGHT", f),
2395 Expression::Repeat(f) => self.generate_repeat(f),
2396 Expression::Lpad(f) => self.generate_pad("LPAD", f),
2397 Expression::Rpad(f) => self.generate_pad("RPAD", f),
2398 Expression::Split(f) => self.generate_split(f),
2399 Expression::RegexpLike(f) => self.generate_regexp_like(f),
2400 Expression::RegexpReplace(f) => self.generate_regexp_replace(f),
2401 Expression::RegexpExtract(f) => self.generate_regexp_extract(f),
2402 Expression::Overlay(f) => self.generate_overlay(f),
2403
2404 Expression::Abs(f) => self.generate_simple_func("ABS", &f.this),
2406 Expression::Round(f) => self.generate_round(f),
2407 Expression::Floor(f) => self.generate_floor(f),
2408 Expression::Ceil(f) => self.generate_ceil(f),
2409 Expression::Power(f) => self.generate_power(f),
2410 Expression::Sqrt(f) => self.generate_sqrt_cbrt(f, "SQRT", "|/"),
2411 Expression::Cbrt(f) => self.generate_sqrt_cbrt(f, "CBRT", "||/"),
2412 Expression::Ln(f) => self.generate_simple_func("LN", &f.this),
2413 Expression::Log(f) => self.generate_log(f),
2414 Expression::Exp(f) => self.generate_simple_func("EXP", &f.this),
2415 Expression::Sign(f) => self.generate_simple_func("SIGN", &f.this),
2416 Expression::Greatest(f) => self.generate_vararg_func("GREATEST", &f.expressions),
2417 Expression::Least(f) => self.generate_vararg_func("LEAST", &f.expressions),
2418
2419 Expression::CurrentDate(_) => {
2421 self.write_keyword("CURRENT_DATE");
2422 Ok(())
2423 }
2424 Expression::CurrentTime(f) => self.generate_current_time(f),
2425 Expression::CurrentTimestamp(f) => self.generate_current_timestamp(f),
2426 Expression::AtTimeZone(f) => self.generate_at_time_zone(f),
2427 Expression::DateAdd(f) => self.generate_date_add(f, "DATE_ADD"),
2428 Expression::DateSub(f) => self.generate_date_add(f, "DATE_SUB"),
2429 Expression::DateDiff(f) => self.generate_datediff(f),
2430 Expression::DateTrunc(f) => self.generate_date_trunc(f),
2431 Expression::Extract(f) => self.generate_extract(f),
2432 Expression::ToDate(f) => self.generate_to_date(f),
2433 Expression::ToTimestamp(f) => self.generate_to_timestamp(f),
2434
2435 Expression::Coalesce(f) => {
2437 let func_name = f.original_name.as_deref().unwrap_or("COALESCE");
2439 self.generate_vararg_func(func_name, &f.expressions)
2440 }
2441 Expression::NullIf(f) => self.generate_binary_func("NULLIF", &f.this, &f.expression),
2442 Expression::IfFunc(f) => self.generate_if_func(f),
2443 Expression::IfNull(f) => self.generate_ifnull(f),
2444 Expression::Nvl(f) => self.generate_nvl(f),
2445 Expression::Nvl2(f) => self.generate_nvl2(f),
2446
2447 Expression::TryCast(cast) => self.generate_try_cast(cast),
2449 Expression::SafeCast(cast) => self.generate_safe_cast(cast),
2450
2451 Expression::Count(f) => self.generate_count(f),
2453 Expression::Sum(f) => self.generate_agg_func("SUM", f),
2454 Expression::Avg(f) => self.generate_agg_func("AVG", f),
2455 Expression::Min(f) => self.generate_agg_func("MIN", f),
2456 Expression::Max(f) => self.generate_agg_func("MAX", f),
2457 Expression::GroupConcat(f) => self.generate_group_concat(f),
2458 Expression::StringAgg(f) => self.generate_string_agg(f),
2459 Expression::ListAgg(f) => self.generate_listagg(f),
2460 Expression::ArrayAgg(f) => {
2461 let override_name = f
2464 .name
2465 .as_ref()
2466 .filter(|n| n.to_uppercase() != "ARRAY_AGG")
2467 .map(|n| n.to_uppercase());
2468 match override_name {
2469 Some(name) => self.generate_agg_func(&name, f),
2470 None => self.generate_agg_func("ARRAY_AGG", f),
2471 }
2472 }
2473 Expression::ArrayConcatAgg(f) => self.generate_agg_func("ARRAY_CONCAT_AGG", f),
2474 Expression::CountIf(f) => self.generate_agg_func("COUNT_IF", f),
2475 Expression::SumIf(f) => self.generate_sum_if(f),
2476 Expression::Stddev(f) => self.generate_agg_func("STDDEV", f),
2477 Expression::StddevPop(f) => self.generate_agg_func("STDDEV_POP", f),
2478 Expression::StddevSamp(f) => self.generate_stddev_samp(f),
2479 Expression::Variance(f) => self.generate_agg_func("VARIANCE", f),
2480 Expression::VarPop(f) => {
2481 let name = if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
2482 "VARIANCE_POP"
2483 } else {
2484 "VAR_POP"
2485 };
2486 self.generate_agg_func(name, f)
2487 }
2488 Expression::VarSamp(f) => self.generate_agg_func("VAR_SAMP", f),
2489 Expression::Skewness(f) => {
2490 let name = match self.config.dialect {
2491 Some(DialectType::Snowflake) => "SKEW",
2492 _ => "SKEWNESS",
2493 };
2494 self.generate_agg_func(name, f)
2495 }
2496 Expression::Median(f) => self.generate_agg_func("MEDIAN", f),
2497 Expression::Mode(f) => self.generate_agg_func("MODE", f),
2498 Expression::First(f) => self.generate_agg_func("FIRST", f),
2499 Expression::Last(f) => self.generate_agg_func("LAST", f),
2500 Expression::AnyValue(f) => self.generate_agg_func("ANY_VALUE", f),
2501 Expression::ApproxDistinct(f) => {
2502 match self.config.dialect {
2503 Some(DialectType::Hive)
2504 | Some(DialectType::Spark)
2505 | Some(DialectType::Databricks)
2506 | Some(DialectType::BigQuery) => {
2507 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2509 }
2510 Some(DialectType::Redshift) => {
2511 self.write_keyword("APPROXIMATE COUNT");
2513 self.write("(");
2514 self.write_keyword("DISTINCT");
2515 self.write(" ");
2516 self.generate_expression(&f.this)?;
2517 self.write(")");
2518 Ok(())
2519 }
2520 _ => self.generate_agg_func("APPROX_DISTINCT", f),
2521 }
2522 }
2523 Expression::ApproxCountDistinct(f) => {
2524 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2525 }
2526 Expression::ApproxPercentile(f) => self.generate_approx_percentile(f),
2527 Expression::Percentile(f) => self.generate_percentile("PERCENTILE", f),
2528 Expression::LogicalAnd(f) => {
2529 let name = match self.config.dialect {
2530 Some(DialectType::Snowflake) => "BOOLAND_AGG",
2531 Some(DialectType::Spark)
2532 | Some(DialectType::Databricks)
2533 | Some(DialectType::PostgreSQL)
2534 | Some(DialectType::DuckDB)
2535 | Some(DialectType::Redshift) => "BOOL_AND",
2536 Some(DialectType::Oracle)
2537 | Some(DialectType::SQLite)
2538 | Some(DialectType::MySQL) => "MIN",
2539 _ => "BOOL_AND",
2540 };
2541 self.generate_agg_func(name, f)
2542 }
2543 Expression::LogicalOr(f) => {
2544 let name = match self.config.dialect {
2545 Some(DialectType::Snowflake) => "BOOLOR_AGG",
2546 Some(DialectType::Spark)
2547 | Some(DialectType::Databricks)
2548 | Some(DialectType::PostgreSQL)
2549 | Some(DialectType::DuckDB)
2550 | Some(DialectType::Redshift) => "BOOL_OR",
2551 Some(DialectType::Oracle)
2552 | Some(DialectType::SQLite)
2553 | Some(DialectType::MySQL) => "MAX",
2554 _ => "BOOL_OR",
2555 };
2556 self.generate_agg_func(name, f)
2557 }
2558
2559 Expression::RowNumber(_) => {
2561 if self.config.dialect == Some(DialectType::ClickHouse) {
2562 self.write("row_number");
2563 } else {
2564 self.write_keyword("ROW_NUMBER");
2565 }
2566 self.write("()");
2567 Ok(())
2568 }
2569 Expression::Rank(r) => {
2570 self.write_keyword("RANK");
2571 self.write("(");
2572 if !r.args.is_empty() {
2574 for (i, arg) in r.args.iter().enumerate() {
2575 if i > 0 {
2576 self.write(", ");
2577 }
2578 self.generate_expression(arg)?;
2579 }
2580 } else if let Some(order_by) = &r.order_by {
2581 self.write_keyword(" ORDER BY ");
2583 for (i, ob) in order_by.iter().enumerate() {
2584 if i > 0 {
2585 self.write(", ");
2586 }
2587 self.generate_ordered(ob)?;
2588 }
2589 }
2590 self.write(")");
2591 Ok(())
2592 }
2593 Expression::DenseRank(dr) => {
2594 self.write_keyword("DENSE_RANK");
2595 self.write("(");
2596 for (i, arg) in dr.args.iter().enumerate() {
2598 if i > 0 {
2599 self.write(", ");
2600 }
2601 self.generate_expression(arg)?;
2602 }
2603 self.write(")");
2604 Ok(())
2605 }
2606 Expression::NTile(f) => self.generate_ntile(f),
2607 Expression::Lead(f) => self.generate_lead_lag("LEAD", f),
2608 Expression::Lag(f) => self.generate_lead_lag("LAG", f),
2609 Expression::FirstValue(f) => self.generate_value_func("FIRST_VALUE", f),
2610 Expression::LastValue(f) => self.generate_value_func("LAST_VALUE", f),
2611 Expression::NthValue(f) => self.generate_nth_value(f),
2612 Expression::PercentRank(pr) => {
2613 self.write_keyword("PERCENT_RANK");
2614 self.write("(");
2615 if !pr.args.is_empty() {
2617 for (i, arg) in pr.args.iter().enumerate() {
2618 if i > 0 {
2619 self.write(", ");
2620 }
2621 self.generate_expression(arg)?;
2622 }
2623 } else if let Some(order_by) = &pr.order_by {
2624 self.write_keyword(" ORDER BY ");
2626 for (i, ob) in order_by.iter().enumerate() {
2627 if i > 0 {
2628 self.write(", ");
2629 }
2630 self.generate_ordered(ob)?;
2631 }
2632 }
2633 self.write(")");
2634 Ok(())
2635 }
2636 Expression::CumeDist(cd) => {
2637 self.write_keyword("CUME_DIST");
2638 self.write("(");
2639 if !cd.args.is_empty() {
2641 for (i, arg) in cd.args.iter().enumerate() {
2642 if i > 0 {
2643 self.write(", ");
2644 }
2645 self.generate_expression(arg)?;
2646 }
2647 } else if let Some(order_by) = &cd.order_by {
2648 self.write_keyword(" ORDER BY ");
2650 for (i, ob) in order_by.iter().enumerate() {
2651 if i > 0 {
2652 self.write(", ");
2653 }
2654 self.generate_ordered(ob)?;
2655 }
2656 }
2657 self.write(")");
2658 Ok(())
2659 }
2660 Expression::PercentileCont(f) => self.generate_percentile("PERCENTILE_CONT", f),
2661 Expression::PercentileDisc(f) => self.generate_percentile("PERCENTILE_DISC", f),
2662
2663 Expression::Contains(f) => {
2665 self.generate_binary_func("CONTAINS", &f.this, &f.expression)
2666 }
2667 Expression::StartsWith(f) => {
2668 let name = match self.config.dialect {
2669 Some(DialectType::Spark) | Some(DialectType::Databricks) => "STARTSWITH",
2670 _ => "STARTS_WITH",
2671 };
2672 self.generate_binary_func(name, &f.this, &f.expression)
2673 }
2674 Expression::EndsWith(f) => {
2675 let name = match self.config.dialect {
2676 Some(DialectType::Snowflake) => "ENDSWITH",
2677 Some(DialectType::Spark) | Some(DialectType::Databricks) => "ENDSWITH",
2678 Some(DialectType::ClickHouse) => "endsWith",
2679 _ => "ENDS_WITH",
2680 };
2681 self.generate_binary_func(name, &f.this, &f.expression)
2682 }
2683 Expression::Position(f) => self.generate_position(f),
2684 Expression::Initcap(f) => match self.config.dialect {
2685 Some(DialectType::Presto)
2686 | Some(DialectType::Trino)
2687 | Some(DialectType::Athena) => {
2688 self.write_keyword("REGEXP_REPLACE");
2689 self.write("(");
2690 self.generate_expression(&f.this)?;
2691 self.write(", '(\\w)(\\w*)', x -> UPPER(x[1]) || LOWER(x[2]))");
2692 Ok(())
2693 }
2694 _ => self.generate_simple_func("INITCAP", &f.this),
2695 },
2696 Expression::Ascii(f) => self.generate_simple_func("ASCII", &f.this),
2697 Expression::Chr(f) => self.generate_simple_func("CHR", &f.this),
2698 Expression::CharFunc(f) => self.generate_char_func(f),
2699 Expression::Soundex(f) => self.generate_simple_func("SOUNDEX", &f.this),
2700 Expression::Levenshtein(f) => {
2701 self.generate_binary_func("LEVENSHTEIN", &f.this, &f.expression)
2702 }
2703
2704 Expression::ModFunc(f) => self.generate_mod_func(f),
2706 Expression::Random(_) => {
2707 self.write_keyword("RANDOM");
2708 self.write("()");
2709 Ok(())
2710 }
2711 Expression::Rand(f) => self.generate_rand(f),
2712 Expression::TruncFunc(f) => self.generate_truncate_func(f),
2713 Expression::Pi(_) => {
2714 self.write_keyword("PI");
2715 self.write("()");
2716 Ok(())
2717 }
2718 Expression::Radians(f) => self.generate_simple_func("RADIANS", &f.this),
2719 Expression::Degrees(f) => self.generate_simple_func("DEGREES", &f.this),
2720 Expression::Sin(f) => self.generate_simple_func("SIN", &f.this),
2721 Expression::Cos(f) => self.generate_simple_func("COS", &f.this),
2722 Expression::Tan(f) => self.generate_simple_func("TAN", &f.this),
2723 Expression::Asin(f) => self.generate_simple_func("ASIN", &f.this),
2724 Expression::Acos(f) => self.generate_simple_func("ACOS", &f.this),
2725 Expression::Atan(f) => self.generate_simple_func("ATAN", &f.this),
2726 Expression::Atan2(f) => {
2727 let name = f.original_name.as_deref().unwrap_or("ATAN2");
2728 self.generate_binary_func(name, &f.this, &f.expression)
2729 }
2730
2731 Expression::Decode(f) => self.generate_decode(f),
2733
2734 Expression::DateFormat(f) => self.generate_date_format("DATE_FORMAT", f),
2736 Expression::FormatDate(f) => self.generate_date_format("FORMAT_DATE", f),
2737 Expression::Year(f) => self.generate_simple_func("YEAR", &f.this),
2738 Expression::Month(f) => self.generate_simple_func("MONTH", &f.this),
2739 Expression::Day(f) => self.generate_simple_func("DAY", &f.this),
2740 Expression::Hour(f) => self.generate_simple_func("HOUR", &f.this),
2741 Expression::Minute(f) => self.generate_simple_func("MINUTE", &f.this),
2742 Expression::Second(f) => self.generate_simple_func("SECOND", &f.this),
2743 Expression::DayOfWeek(f) => {
2744 let name = match self.config.dialect {
2745 Some(DialectType::Presto)
2746 | Some(DialectType::Trino)
2747 | Some(DialectType::Athena) => "DAY_OF_WEEK",
2748 Some(DialectType::DuckDB) => "ISODOW",
2749 _ => "DAYOFWEEK",
2750 };
2751 self.generate_simple_func(name, &f.this)
2752 }
2753 Expression::DayOfMonth(f) => {
2754 let name = match self.config.dialect {
2755 Some(DialectType::Presto)
2756 | Some(DialectType::Trino)
2757 | Some(DialectType::Athena) => "DAY_OF_MONTH",
2758 _ => "DAYOFMONTH",
2759 };
2760 self.generate_simple_func(name, &f.this)
2761 }
2762 Expression::DayOfYear(f) => {
2763 let name = match self.config.dialect {
2764 Some(DialectType::Presto)
2765 | Some(DialectType::Trino)
2766 | Some(DialectType::Athena) => "DAY_OF_YEAR",
2767 _ => "DAYOFYEAR",
2768 };
2769 self.generate_simple_func(name, &f.this)
2770 }
2771 Expression::WeekOfYear(f) => {
2772 let name = match self.config.dialect {
2774 Some(DialectType::Hive)
2775 | Some(DialectType::DuckDB)
2776 | Some(DialectType::Spark)
2777 | Some(DialectType::Databricks)
2778 | Some(DialectType::MySQL) => "WEEKOFYEAR",
2779 _ => "WEEK_OF_YEAR",
2780 };
2781 self.generate_simple_func(name, &f.this)
2782 }
2783 Expression::Quarter(f) => self.generate_simple_func("QUARTER", &f.this),
2784 Expression::AddMonths(f) => {
2785 self.generate_binary_func("ADD_MONTHS", &f.this, &f.expression)
2786 }
2787 Expression::MonthsBetween(f) => {
2788 self.generate_binary_func("MONTHS_BETWEEN", &f.this, &f.expression)
2789 }
2790 Expression::LastDay(f) => self.generate_last_day(f),
2791 Expression::NextDay(f) => self.generate_binary_func("NEXT_DAY", &f.this, &f.expression),
2792 Expression::Epoch(f) => self.generate_simple_func("EPOCH", &f.this),
2793 Expression::EpochMs(f) => self.generate_simple_func("EPOCH_MS", &f.this),
2794 Expression::FromUnixtime(f) => self.generate_from_unixtime(f),
2795 Expression::UnixTimestamp(f) => self.generate_unix_timestamp(f),
2796 Expression::MakeDate(f) => self.generate_make_date(f),
2797 Expression::MakeTimestamp(f) => self.generate_make_timestamp(f),
2798 Expression::TimestampTrunc(f) => self.generate_date_trunc(f),
2799
2800 Expression::ArrayFunc(f) => self.generate_array_constructor(f),
2802 Expression::ArrayLength(f) => self.generate_simple_func("ARRAY_LENGTH", &f.this),
2803 Expression::ArraySize(f) => self.generate_simple_func("ARRAY_SIZE", &f.this),
2804 Expression::Cardinality(f) => self.generate_simple_func("CARDINALITY", &f.this),
2805 Expression::ArrayContains(f) => {
2806 self.generate_binary_func("ARRAY_CONTAINS", &f.this, &f.expression)
2807 }
2808 Expression::ArrayPosition(f) => {
2809 self.generate_binary_func("ARRAY_POSITION", &f.this, &f.expression)
2810 }
2811 Expression::ArrayAppend(f) => {
2812 self.generate_binary_func("ARRAY_APPEND", &f.this, &f.expression)
2813 }
2814 Expression::ArrayPrepend(f) => {
2815 self.generate_binary_func("ARRAY_PREPEND", &f.this, &f.expression)
2816 }
2817 Expression::ArrayConcat(f) => self.generate_vararg_func("ARRAY_CONCAT", &f.expressions),
2818 Expression::ArraySort(f) => self.generate_array_sort(f),
2819 Expression::ArrayReverse(f) => self.generate_simple_func("ARRAY_REVERSE", &f.this),
2820 Expression::ArrayDistinct(f) => self.generate_simple_func("ARRAY_DISTINCT", &f.this),
2821 Expression::ArrayJoin(f) => self.generate_array_join("ARRAY_JOIN", f),
2822 Expression::ArrayToString(f) => self.generate_array_join("ARRAY_TO_STRING", f),
2823 Expression::Unnest(f) => self.generate_unnest(f),
2824 Expression::Explode(f) => self.generate_simple_func("EXPLODE", &f.this),
2825 Expression::ExplodeOuter(f) => self.generate_simple_func("EXPLODE_OUTER", &f.this),
2826 Expression::ArrayFilter(f) => self.generate_array_filter(f),
2827 Expression::ArrayTransform(f) => self.generate_array_transform(f),
2828 Expression::ArrayFlatten(f) => self.generate_simple_func("FLATTEN", &f.this),
2829 Expression::ArrayCompact(f) => {
2830 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
2831 self.write("LIST_FILTER(");
2833 self.generate_expression(&f.this)?;
2834 self.write(", _u -> NOT _u IS NULL)");
2835 Ok(())
2836 } else {
2837 self.generate_simple_func("ARRAY_COMPACT", &f.this)
2838 }
2839 }
2840 Expression::ArrayIntersect(f) => {
2841 let func_name = f.original_name.as_deref().unwrap_or("ARRAY_INTERSECT");
2842 self.generate_vararg_func(func_name, &f.expressions)
2843 }
2844 Expression::ArrayUnion(f) => {
2845 self.generate_binary_func("ARRAY_UNION", &f.this, &f.expression)
2846 }
2847 Expression::ArrayExcept(f) => {
2848 self.generate_binary_func("ARRAY_EXCEPT", &f.this, &f.expression)
2849 }
2850 Expression::ArrayRemove(f) => {
2851 self.generate_binary_func("ARRAY_REMOVE", &f.this, &f.expression)
2852 }
2853 Expression::ArrayZip(f) => self.generate_vararg_func("ARRAYS_ZIP", &f.expressions),
2854 Expression::Sequence(f) => self.generate_sequence("SEQUENCE", f),
2855 Expression::Generate(f) => self.generate_sequence("GENERATE_SERIES", f),
2856
2857 Expression::StructFunc(f) => self.generate_struct_constructor(f),
2859 Expression::StructExtract(f) => self.generate_struct_extract(f),
2860 Expression::NamedStruct(f) => self.generate_named_struct(f),
2861
2862 Expression::MapFunc(f) => self.generate_map_constructor(f),
2864 Expression::MapFromEntries(f) => self.generate_simple_func("MAP_FROM_ENTRIES", &f.this),
2865 Expression::MapFromArrays(f) => {
2866 self.generate_binary_func("MAP_FROM_ARRAYS", &f.this, &f.expression)
2867 }
2868 Expression::MapKeys(f) => self.generate_simple_func("MAP_KEYS", &f.this),
2869 Expression::MapValues(f) => self.generate_simple_func("MAP_VALUES", &f.this),
2870 Expression::MapContainsKey(f) => {
2871 self.generate_binary_func("MAP_CONTAINS_KEY", &f.this, &f.expression)
2872 }
2873 Expression::MapConcat(f) => self.generate_vararg_func("MAP_CONCAT", &f.expressions),
2874 Expression::ElementAt(f) => {
2875 self.generate_binary_func("ELEMENT_AT", &f.this, &f.expression)
2876 }
2877 Expression::TransformKeys(f) => self.generate_transform_func("TRANSFORM_KEYS", f),
2878 Expression::TransformValues(f) => self.generate_transform_func("TRANSFORM_VALUES", f),
2879
2880 Expression::JsonExtract(f) => self.generate_json_extract("JSON_EXTRACT", f),
2882 Expression::JsonExtractScalar(f) => {
2883 self.generate_json_extract("JSON_EXTRACT_SCALAR", f)
2884 }
2885 Expression::JsonExtractPath(f) => self.generate_json_path("JSON_EXTRACT_PATH", f),
2886 Expression::JsonArray(f) => self.generate_vararg_func("JSON_ARRAY", &f.expressions),
2887 Expression::JsonObject(f) => self.generate_json_object(f),
2888 Expression::JsonQuery(f) => self.generate_json_extract("JSON_QUERY", f),
2889 Expression::JsonValue(f) => self.generate_json_extract("JSON_VALUE", f),
2890 Expression::JsonArrayLength(f) => {
2891 self.generate_simple_func("JSON_ARRAY_LENGTH", &f.this)
2892 }
2893 Expression::JsonKeys(f) => self.generate_simple_func("JSON_KEYS", &f.this),
2894 Expression::JsonType(f) => self.generate_simple_func("JSON_TYPE", &f.this),
2895 Expression::ParseJson(f) => {
2896 let name = match self.config.dialect {
2897 Some(DialectType::Presto)
2898 | Some(DialectType::Trino)
2899 | Some(DialectType::Athena) => "JSON_PARSE",
2900 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
2901 self.write_keyword("CAST");
2903 self.write("(");
2904 self.generate_expression(&f.this)?;
2905 self.write_keyword(" AS ");
2906 self.write_keyword("JSON");
2907 self.write(")");
2908 return Ok(());
2909 }
2910 Some(DialectType::Hive)
2911 | Some(DialectType::Spark)
2912 | Some(DialectType::MySQL)
2913 | Some(DialectType::SingleStore)
2914 | Some(DialectType::TiDB)
2915 | Some(DialectType::TSQL) => {
2916 self.generate_expression(&f.this)?;
2918 return Ok(());
2919 }
2920 Some(DialectType::DuckDB) => "JSON",
2921 _ => "PARSE_JSON",
2922 };
2923 self.generate_simple_func(name, &f.this)
2924 }
2925 Expression::ToJson(f) => self.generate_simple_func("TO_JSON", &f.this),
2926 Expression::JsonSet(f) => self.generate_json_modify("JSON_SET", f),
2927 Expression::JsonInsert(f) => self.generate_json_modify("JSON_INSERT", f),
2928 Expression::JsonRemove(f) => self.generate_json_path("JSON_REMOVE", f),
2929 Expression::JsonMergePatch(f) => {
2930 self.generate_binary_func("JSON_MERGE_PATCH", &f.this, &f.expression)
2931 }
2932 Expression::JsonArrayAgg(f) => self.generate_json_array_agg(f),
2933 Expression::JsonObjectAgg(f) => self.generate_json_object_agg(f),
2934
2935 Expression::Convert(f) => self.generate_convert(f),
2937 Expression::Typeof(f) => self.generate_simple_func("TYPEOF", &f.this),
2938
2939 Expression::Lambda(f) => self.generate_lambda(f),
2941 Expression::Parameter(f) => self.generate_parameter(f),
2942 Expression::Placeholder(f) => self.generate_placeholder(f),
2943 Expression::NamedArgument(f) => self.generate_named_argument(f),
2944 Expression::TableArgument(f) => self.generate_table_argument(f),
2945 Expression::SqlComment(f) => self.generate_sql_comment(f),
2946
2947 Expression::NullSafeEq(op) => self.generate_null_safe_eq(op),
2949 Expression::NullSafeNeq(op) => self.generate_null_safe_neq(op),
2950 Expression::Glob(op) => self.generate_binary_op(op, "GLOB"),
2951 Expression::SimilarTo(f) => self.generate_similar_to(f),
2952 Expression::Any(f) => self.generate_quantified("ANY", f),
2953 Expression::All(f) => self.generate_quantified("ALL", f),
2954 Expression::Overlaps(f) => self.generate_overlaps(f),
2955
2956 Expression::BitwiseLeftShift(op) => {
2958 if matches!(
2959 self.config.dialect,
2960 Some(DialectType::Presto) | Some(DialectType::Trino)
2961 ) {
2962 self.write_keyword("BITWISE_ARITHMETIC_SHIFT_LEFT");
2963 self.write("(");
2964 self.generate_expression(&op.left)?;
2965 self.write(", ");
2966 self.generate_expression(&op.right)?;
2967 self.write(")");
2968 Ok(())
2969 } else if matches!(
2970 self.config.dialect,
2971 Some(DialectType::Spark) | Some(DialectType::Databricks)
2972 ) {
2973 self.write_keyword("SHIFTLEFT");
2974 self.write("(");
2975 self.generate_expression(&op.left)?;
2976 self.write(", ");
2977 self.generate_expression(&op.right)?;
2978 self.write(")");
2979 Ok(())
2980 } else {
2981 self.generate_binary_op(op, "<<")
2982 }
2983 }
2984 Expression::BitwiseRightShift(op) => {
2985 if matches!(
2986 self.config.dialect,
2987 Some(DialectType::Presto) | Some(DialectType::Trino)
2988 ) {
2989 self.write_keyword("BITWISE_ARITHMETIC_SHIFT_RIGHT");
2990 self.write("(");
2991 self.generate_expression(&op.left)?;
2992 self.write(", ");
2993 self.generate_expression(&op.right)?;
2994 self.write(")");
2995 Ok(())
2996 } else if matches!(
2997 self.config.dialect,
2998 Some(DialectType::Spark) | Some(DialectType::Databricks)
2999 ) {
3000 self.write_keyword("SHIFTRIGHT");
3001 self.write("(");
3002 self.generate_expression(&op.left)?;
3003 self.write(", ");
3004 self.generate_expression(&op.right)?;
3005 self.write(")");
3006 Ok(())
3007 } else {
3008 self.generate_binary_op(op, ">>")
3009 }
3010 }
3011 Expression::BitwiseAndAgg(f) => self.generate_agg_func("BIT_AND", f),
3012 Expression::BitwiseOrAgg(f) => self.generate_agg_func("BIT_OR", f),
3013 Expression::BitwiseXorAgg(f) => self.generate_agg_func("BIT_XOR", f),
3014
3015 Expression::Subscript(s) => self.generate_subscript(s),
3017 Expression::Dot(d) => self.generate_dot_access(d),
3018 Expression::MethodCall(m) => self.generate_method_call(m),
3019 Expression::ArraySlice(s) => self.generate_array_slice(s),
3020
3021 Expression::And(op) => self.generate_connector_op(op, ConnectorOperator::And),
3022 Expression::Or(op) => self.generate_connector_op(op, ConnectorOperator::Or),
3023 Expression::Add(op) => self.generate_binary_op(op, "+"),
3024 Expression::Sub(op) => self.generate_binary_op(op, "-"),
3025 Expression::Mul(op) => self.generate_binary_op(op, "*"),
3026 Expression::Div(op) => self.generate_binary_op(op, "/"),
3027 Expression::IntDiv(f) => {
3028 use crate::dialects::DialectType;
3029 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
3030 self.generate_expression(&f.this)?;
3032 self.write(" // ");
3033 self.generate_expression(&f.expression)?;
3034 Ok(())
3035 } else if matches!(
3036 self.config.dialect,
3037 Some(DialectType::Hive | DialectType::Spark | DialectType::Databricks)
3038 ) {
3039 self.generate_expression(&f.this)?;
3041 self.write(" ");
3042 self.write_keyword("DIV");
3043 self.write(" ");
3044 self.generate_expression(&f.expression)?;
3045 Ok(())
3046 } else {
3047 self.write_keyword("DIV");
3049 self.write("(");
3050 self.generate_expression(&f.this)?;
3051 self.write(", ");
3052 self.generate_expression(&f.expression)?;
3053 self.write(")");
3054 Ok(())
3055 }
3056 }
3057 Expression::Mod(op) => {
3058 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
3059 self.generate_binary_op(op, "MOD")
3060 } else {
3061 self.generate_binary_op(op, "%")
3062 }
3063 }
3064 Expression::Eq(op) => self.generate_binary_op(op, "="),
3065 Expression::Neq(op) => self.generate_binary_op(op, "<>"),
3066 Expression::Lt(op) => self.generate_binary_op(op, "<"),
3067 Expression::Lte(op) => self.generate_binary_op(op, "<="),
3068 Expression::Gt(op) => self.generate_binary_op(op, ">"),
3069 Expression::Gte(op) => self.generate_binary_op(op, ">="),
3070 Expression::Like(op) => self.generate_like_op(op, "LIKE"),
3071 Expression::ILike(op) => self.generate_like_op(op, "ILIKE"),
3072 Expression::Match(op) => self.generate_binary_op(op, "MATCH"),
3073 Expression::Concat(op) => {
3074 if self.config.dialect == Some(DialectType::Solr) {
3076 self.generate_binary_op(op, "OR")
3077 } else if self.config.dialect == Some(DialectType::MySQL) {
3078 self.generate_mysql_concat_from_concat(op)
3079 } else {
3080 self.generate_binary_op(op, "||")
3081 }
3082 }
3083 Expression::BitwiseAnd(op) => {
3084 if matches!(
3086 self.config.dialect,
3087 Some(DialectType::Presto) | Some(DialectType::Trino)
3088 ) {
3089 self.write_keyword("BITWISE_AND");
3090 self.write("(");
3091 self.generate_expression(&op.left)?;
3092 self.write(", ");
3093 self.generate_expression(&op.right)?;
3094 self.write(")");
3095 Ok(())
3096 } else {
3097 self.generate_binary_op(op, "&")
3098 }
3099 }
3100 Expression::BitwiseOr(op) => {
3101 if matches!(
3103 self.config.dialect,
3104 Some(DialectType::Presto) | Some(DialectType::Trino)
3105 ) {
3106 self.write_keyword("BITWISE_OR");
3107 self.write("(");
3108 self.generate_expression(&op.left)?;
3109 self.write(", ");
3110 self.generate_expression(&op.right)?;
3111 self.write(")");
3112 Ok(())
3113 } else {
3114 self.generate_binary_op(op, "|")
3115 }
3116 }
3117 Expression::BitwiseXor(op) => {
3118 if matches!(
3120 self.config.dialect,
3121 Some(DialectType::Presto) | Some(DialectType::Trino)
3122 ) {
3123 self.write_keyword("BITWISE_XOR");
3124 self.write("(");
3125 self.generate_expression(&op.left)?;
3126 self.write(", ");
3127 self.generate_expression(&op.right)?;
3128 self.write(")");
3129 Ok(())
3130 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
3131 self.generate_binary_op(op, "#")
3132 } else {
3133 self.generate_binary_op(op, "^")
3134 }
3135 }
3136 Expression::Adjacent(op) => self.generate_binary_op(op, "-|-"),
3137 Expression::TsMatch(op) => self.generate_binary_op(op, "@@"),
3138 Expression::PropertyEQ(op) => self.generate_binary_op(op, ":="),
3139 Expression::ArrayContainsAll(op) => self.generate_binary_op(op, "@>"),
3140 Expression::ArrayContainedBy(op) => self.generate_binary_op(op, "<@"),
3141 Expression::ArrayOverlaps(op) => self.generate_binary_op(op, "&&"),
3142 Expression::JSONBContainsAllTopKeys(op) => self.generate_binary_op(op, "?&"),
3143 Expression::JSONBContainsAnyTopKeys(op) => self.generate_binary_op(op, "?|"),
3144 Expression::JSONBContains(f) => {
3145 self.generate_expression(&f.this)?;
3147 self.write_space();
3148 self.write("?");
3149 self.write_space();
3150 self.generate_expression(&f.expression)
3151 }
3152 Expression::JSONBDeleteAtPath(op) => self.generate_binary_op(op, "#-"),
3153 Expression::ExtendsLeft(op) => self.generate_binary_op(op, "&<"),
3154 Expression::ExtendsRight(op) => self.generate_binary_op(op, "&>"),
3155 Expression::Not(op) => self.generate_unary_op(op, "NOT"),
3156 Expression::Neg(op) => self.generate_unary_op(op, "-"),
3157 Expression::BitwiseNot(op) => {
3158 if matches!(
3160 self.config.dialect,
3161 Some(DialectType::Presto) | Some(DialectType::Trino)
3162 ) {
3163 self.write_keyword("BITWISE_NOT");
3164 self.write("(");
3165 self.generate_expression(&op.this)?;
3166 self.write(")");
3167 Ok(())
3168 } else {
3169 self.generate_unary_op(op, "~")
3170 }
3171 }
3172 Expression::In(in_expr) => self.generate_in(in_expr),
3173 Expression::Between(between) => self.generate_between(between),
3174 Expression::IsNull(is_null) => self.generate_is_null(is_null),
3175 Expression::IsTrue(is_true) => self.generate_is_true(is_true),
3176 Expression::IsFalse(is_false) => self.generate_is_false(is_false),
3177 Expression::IsJson(is_json) => self.generate_is_json(is_json),
3178 Expression::Is(is_expr) => self.generate_is(is_expr),
3179 Expression::Exists(exists) => self.generate_exists(exists),
3180 Expression::MemberOf(member_of) => self.generate_member_of(member_of),
3181 Expression::Subquery(subquery) => self.generate_subquery(subquery),
3182 Expression::Paren(paren) => {
3183 let skip_parens = matches!(&paren.this, Expression::JoinedTable(_));
3185
3186 if !skip_parens {
3187 self.write("(");
3188 if self.config.pretty {
3189 self.write_newline();
3190 self.indent_level += 1;
3191 self.write_indent();
3192 }
3193 }
3194 self.generate_expression(&paren.this)?;
3195 if !skip_parens {
3196 if self.config.pretty {
3197 self.write_newline();
3198 self.indent_level -= 1;
3199 self.write_indent();
3200 }
3201 self.write(")");
3202 }
3203 for comment in &paren.trailing_comments {
3205 self.write(" ");
3206 self.write_formatted_comment(comment);
3207 }
3208 Ok(())
3209 }
3210 Expression::Array(arr) => self.generate_array(arr),
3211 Expression::Tuple(tuple) => self.generate_tuple(tuple),
3212 Expression::PipeOperator(pipe) => self.generate_pipe_operator(pipe),
3213 Expression::Ordered(ordered) => self.generate_ordered(ordered),
3214 Expression::DataType(dt) => self.generate_data_type(dt),
3215 Expression::Raw(raw) => {
3216 self.write(&raw.sql);
3217 Ok(())
3218 }
3219 Expression::Command(cmd) => {
3220 self.write(&cmd.this);
3221 Ok(())
3222 }
3223 Expression::Kill(kill) => {
3224 self.write_keyword("KILL");
3225 if let Some(kind) = &kill.kind {
3226 self.write_space();
3227 self.write_keyword(kind);
3228 }
3229 self.write_space();
3230 self.generate_expression(&kill.this)?;
3231 Ok(())
3232 }
3233 Expression::Execute(exec) => {
3234 self.write_keyword("EXEC");
3235 self.write_space();
3236 self.generate_expression(&exec.this)?;
3237 for (i, param) in exec.parameters.iter().enumerate() {
3238 if i == 0 {
3239 self.write_space();
3240 } else {
3241 self.write(", ");
3242 }
3243 self.write(¶m.name);
3244 self.write("=");
3245 self.generate_expression(¶m.value)?;
3246 }
3247 Ok(())
3248 }
3249 Expression::Annotated(annotated) => {
3250 self.generate_expression(&annotated.this)?;
3251 for comment in &annotated.trailing_comments {
3252 self.write(" ");
3253 self.write_formatted_comment(comment);
3254 }
3255 Ok(())
3256 }
3257
3258 Expression::CreateTable(ct) => self.generate_create_table(ct),
3260 Expression::DropTable(dt) => self.generate_drop_table(dt),
3261 Expression::AlterTable(at) => self.generate_alter_table(at),
3262 Expression::CreateIndex(ci) => self.generate_create_index(ci),
3263 Expression::DropIndex(di) => self.generate_drop_index(di),
3264 Expression::CreateView(cv) => self.generate_create_view(cv),
3265 Expression::DropView(dv) => self.generate_drop_view(dv),
3266 Expression::AlterView(av) => self.generate_alter_view(av),
3267 Expression::AlterIndex(ai) => self.generate_alter_index(ai),
3268 Expression::Truncate(tr) => self.generate_truncate(tr),
3269 Expression::Use(u) => self.generate_use(u),
3270 Expression::CreateSchema(cs) => self.generate_create_schema(cs),
3272 Expression::DropSchema(ds) => self.generate_drop_schema(ds),
3273 Expression::DropNamespace(dn) => self.generate_drop_namespace(dn),
3274 Expression::CreateDatabase(cd) => self.generate_create_database(cd),
3275 Expression::DropDatabase(dd) => self.generate_drop_database(dd),
3276 Expression::CreateFunction(cf) => self.generate_create_function(cf),
3277 Expression::DropFunction(df) => self.generate_drop_function(df),
3278 Expression::CreateProcedure(cp) => self.generate_create_procedure(cp),
3279 Expression::DropProcedure(dp) => self.generate_drop_procedure(dp),
3280 Expression::CreateSequence(cs) => self.generate_create_sequence(cs),
3281 Expression::DropSequence(ds) => self.generate_drop_sequence(ds),
3282 Expression::AlterSequence(als) => self.generate_alter_sequence(als),
3283 Expression::CreateTrigger(ct) => self.generate_create_trigger(ct),
3284 Expression::DropTrigger(dt) => self.generate_drop_trigger(dt),
3285 Expression::CreateType(ct) => self.generate_create_type(ct),
3286 Expression::DropType(dt) => self.generate_drop_type(dt),
3287 Expression::Describe(d) => self.generate_describe(d),
3288 Expression::Show(s) => self.generate_show(s),
3289
3290 Expression::Cache(c) => self.generate_cache(c),
3292 Expression::Uncache(u) => self.generate_uncache(u),
3293 Expression::LoadData(l) => self.generate_load_data(l),
3294 Expression::Pragma(p) => self.generate_pragma(p),
3295 Expression::Grant(g) => self.generate_grant(g),
3296 Expression::Revoke(r) => self.generate_revoke(r),
3297 Expression::Comment(c) => self.generate_comment(c),
3298 Expression::SetStatement(s) => self.generate_set_statement(s),
3299
3300 Expression::Pivot(pivot) => self.generate_pivot(pivot),
3302 Expression::Unpivot(unpivot) => self.generate_unpivot(unpivot),
3303
3304 Expression::Values(values) => self.generate_values(values),
3306
3307 Expression::AIAgg(e) => self.generate_ai_agg(e),
3309 Expression::AIClassify(e) => self.generate_ai_classify(e),
3310 Expression::AddPartition(e) => self.generate_add_partition(e),
3311 Expression::AlgorithmProperty(e) => self.generate_algorithm_property(e),
3312 Expression::Aliases(e) => self.generate_aliases(e),
3313 Expression::AllowedValuesProperty(e) => self.generate_allowed_values_property(e),
3314 Expression::AlterColumn(e) => self.generate_alter_column(e),
3315 Expression::AlterSession(e) => self.generate_alter_session(e),
3316 Expression::AlterSet(e) => self.generate_alter_set(e),
3317 Expression::AlterSortKey(e) => self.generate_alter_sort_key(e),
3318 Expression::Analyze(e) => self.generate_analyze(e),
3319 Expression::AnalyzeDelete(e) => self.generate_analyze_delete(e),
3320 Expression::AnalyzeHistogram(e) => self.generate_analyze_histogram(e),
3321 Expression::AnalyzeListChainedRows(e) => self.generate_analyze_list_chained_rows(e),
3322 Expression::AnalyzeSample(e) => self.generate_analyze_sample(e),
3323 Expression::AnalyzeStatistics(e) => self.generate_analyze_statistics(e),
3324 Expression::AnalyzeValidate(e) => self.generate_analyze_validate(e),
3325 Expression::AnalyzeWith(e) => self.generate_analyze_with(e),
3326 Expression::Anonymous(e) => self.generate_anonymous(e),
3327 Expression::AnonymousAggFunc(e) => self.generate_anonymous_agg_func(e),
3328 Expression::Apply(e) => self.generate_apply(e),
3329 Expression::ApproxPercentileEstimate(e) => self.generate_approx_percentile_estimate(e),
3330 Expression::ApproxQuantile(e) => self.generate_approx_quantile(e),
3331 Expression::ApproxQuantiles(e) => self.generate_approx_quantiles(e),
3332 Expression::ApproxTopK(e) => self.generate_approx_top_k(e),
3333 Expression::ApproxTopKAccumulate(e) => self.generate_approx_top_k_accumulate(e),
3334 Expression::ApproxTopKCombine(e) => self.generate_approx_top_k_combine(e),
3335 Expression::ApproxTopKEstimate(e) => self.generate_approx_top_k_estimate(e),
3336 Expression::ApproxTopSum(e) => self.generate_approx_top_sum(e),
3337 Expression::ArgMax(e) => self.generate_arg_max(e),
3338 Expression::ArgMin(e) => self.generate_arg_min(e),
3339 Expression::ArrayAll(e) => self.generate_array_all(e),
3340 Expression::ArrayAny(e) => self.generate_array_any(e),
3341 Expression::ArrayConstructCompact(e) => self.generate_array_construct_compact(e),
3342 Expression::ArraySum(e) => self.generate_array_sum(e),
3343 Expression::AtIndex(e) => self.generate_at_index(e),
3344 Expression::Attach(e) => self.generate_attach(e),
3345 Expression::AttachOption(e) => self.generate_attach_option(e),
3346 Expression::AutoIncrementProperty(e) => self.generate_auto_increment_property(e),
3347 Expression::AutoRefreshProperty(e) => self.generate_auto_refresh_property(e),
3348 Expression::BackupProperty(e) => self.generate_backup_property(e),
3349 Expression::Base64DecodeBinary(e) => self.generate_base64_decode_binary(e),
3350 Expression::Base64DecodeString(e) => self.generate_base64_decode_string(e),
3351 Expression::Base64Encode(e) => self.generate_base64_encode(e),
3352 Expression::BlockCompressionProperty(e) => self.generate_block_compression_property(e),
3353 Expression::Booland(e) => self.generate_booland(e),
3354 Expression::Boolor(e) => self.generate_boolor(e),
3355 Expression::BuildProperty(e) => self.generate_build_property(e),
3356 Expression::ByteString(e) => self.generate_byte_string(e),
3357 Expression::CaseSpecificColumnConstraint(e) => {
3358 self.generate_case_specific_column_constraint(e)
3359 }
3360 Expression::CastToStrType(e) => self.generate_cast_to_str_type(e),
3361 Expression::Changes(e) => self.generate_changes(e),
3362 Expression::CharacterSetColumnConstraint(e) => {
3363 self.generate_character_set_column_constraint(e)
3364 }
3365 Expression::CharacterSetProperty(e) => self.generate_character_set_property(e),
3366 Expression::CheckColumnConstraint(e) => self.generate_check_column_constraint(e),
3367 Expression::CheckJson(e) => self.generate_check_json(e),
3368 Expression::CheckXml(e) => self.generate_check_xml(e),
3369 Expression::ChecksumProperty(e) => self.generate_checksum_property(e),
3370 Expression::Clone(e) => self.generate_clone(e),
3371 Expression::ClusterBy(e) => self.generate_cluster_by(e),
3372 Expression::ClusterByColumnsProperty(e) => self.generate_cluster_by_columns_property(e),
3373 Expression::ClusteredByProperty(e) => self.generate_clustered_by_property(e),
3374 Expression::CollateProperty(e) => self.generate_collate_property(e),
3375 Expression::ColumnConstraint(e) => self.generate_column_constraint(e),
3376 Expression::ColumnDef(e) => self.generate_column_def_expr(e),
3377 Expression::ColumnPosition(e) => self.generate_column_position(e),
3378 Expression::ColumnPrefix(e) => self.generate_column_prefix(e),
3379 Expression::Columns(e) => self.generate_columns(e),
3380 Expression::CombinedAggFunc(e) => self.generate_combined_agg_func(e),
3381 Expression::CombinedParameterizedAgg(e) => self.generate_combined_parameterized_agg(e),
3382 Expression::Commit(e) => self.generate_commit(e),
3383 Expression::Comprehension(e) => self.generate_comprehension(e),
3384 Expression::Compress(e) => self.generate_compress(e),
3385 Expression::CompressColumnConstraint(e) => self.generate_compress_column_constraint(e),
3386 Expression::ComputedColumnConstraint(e) => self.generate_computed_column_constraint(e),
3387 Expression::ConditionalInsert(e) => self.generate_conditional_insert(e),
3388 Expression::Constraint(e) => self.generate_constraint(e),
3389 Expression::ConvertTimezone(e) => self.generate_convert_timezone(e),
3390 Expression::ConvertToCharset(e) => self.generate_convert_to_charset(e),
3391 Expression::Copy(e) => self.generate_copy(e),
3392 Expression::CopyParameter(e) => self.generate_copy_parameter(e),
3393 Expression::Corr(e) => self.generate_corr(e),
3394 Expression::CosineDistance(e) => self.generate_cosine_distance(e),
3395 Expression::CovarPop(e) => self.generate_covar_pop(e),
3396 Expression::CovarSamp(e) => self.generate_covar_samp(e),
3397 Expression::Credentials(e) => self.generate_credentials(e),
3398 Expression::CredentialsProperty(e) => self.generate_credentials_property(e),
3399 Expression::Cte(e) => self.generate_cte(e),
3400 Expression::Cube(e) => self.generate_cube(e),
3401 Expression::CurrentDatetime(e) => self.generate_current_datetime(e),
3402 Expression::CurrentSchema(e) => self.generate_current_schema(e),
3403 Expression::CurrentSchemas(e) => self.generate_current_schemas(e),
3404 Expression::CurrentUser(e) => self.generate_current_user(e),
3405 Expression::DPipe(e) => self.generate_d_pipe(e),
3406 Expression::DataBlocksizeProperty(e) => self.generate_data_blocksize_property(e),
3407 Expression::DataDeletionProperty(e) => self.generate_data_deletion_property(e),
3408 Expression::Date(e) => self.generate_date_func(e),
3409 Expression::DateBin(e) => self.generate_date_bin(e),
3410 Expression::DateFormatColumnConstraint(e) => {
3411 self.generate_date_format_column_constraint(e)
3412 }
3413 Expression::DateFromParts(e) => self.generate_date_from_parts(e),
3414 Expression::Datetime(e) => self.generate_datetime(e),
3415 Expression::DatetimeAdd(e) => self.generate_datetime_add(e),
3416 Expression::DatetimeDiff(e) => self.generate_datetime_diff(e),
3417 Expression::DatetimeSub(e) => self.generate_datetime_sub(e),
3418 Expression::DatetimeTrunc(e) => self.generate_datetime_trunc(e),
3419 Expression::Dayname(e) => self.generate_dayname(e),
3420 Expression::Declare(e) => self.generate_declare(e),
3421 Expression::DeclareItem(e) => self.generate_declare_item(e),
3422 Expression::DecodeCase(e) => self.generate_decode_case(e),
3423 Expression::DecompressBinary(e) => self.generate_decompress_binary(e),
3424 Expression::DecompressString(e) => self.generate_decompress_string(e),
3425 Expression::Decrypt(e) => self.generate_decrypt(e),
3426 Expression::DecryptRaw(e) => self.generate_decrypt_raw(e),
3427 Expression::DefinerProperty(e) => self.generate_definer_property(e),
3428 Expression::Detach(e) => self.generate_detach(e),
3429 Expression::DictProperty(e) => self.generate_dict_property(e),
3430 Expression::DictRange(e) => self.generate_dict_range(e),
3431 Expression::Directory(e) => self.generate_directory(e),
3432 Expression::DistKeyProperty(e) => self.generate_dist_key_property(e),
3433 Expression::DistStyleProperty(e) => self.generate_dist_style_property(e),
3434 Expression::DistributeBy(e) => self.generate_distribute_by(e),
3435 Expression::DistributedByProperty(e) => self.generate_distributed_by_property(e),
3436 Expression::DotProduct(e) => self.generate_dot_product(e),
3437 Expression::DropPartition(e) => self.generate_drop_partition(e),
3438 Expression::DuplicateKeyProperty(e) => self.generate_duplicate_key_property(e),
3439 Expression::Elt(e) => self.generate_elt(e),
3440 Expression::Encode(e) => self.generate_encode(e),
3441 Expression::EncodeProperty(e) => self.generate_encode_property(e),
3442 Expression::Encrypt(e) => self.generate_encrypt(e),
3443 Expression::EncryptRaw(e) => self.generate_encrypt_raw(e),
3444 Expression::EngineProperty(e) => self.generate_engine_property(e),
3445 Expression::EnviromentProperty(e) => self.generate_enviroment_property(e),
3446 Expression::EphemeralColumnConstraint(e) => {
3447 self.generate_ephemeral_column_constraint(e)
3448 }
3449 Expression::EqualNull(e) => self.generate_equal_null(e),
3450 Expression::EuclideanDistance(e) => self.generate_euclidean_distance(e),
3451 Expression::ExecuteAsProperty(e) => self.generate_execute_as_property(e),
3452 Expression::Export(e) => self.generate_export(e),
3453 Expression::ExternalProperty(e) => self.generate_external_property(e),
3454 Expression::FallbackProperty(e) => self.generate_fallback_property(e),
3455 Expression::FarmFingerprint(e) => self.generate_farm_fingerprint(e),
3456 Expression::FeaturesAtTime(e) => self.generate_features_at_time(e),
3457 Expression::Fetch(e) => self.generate_fetch(e),
3458 Expression::FileFormatProperty(e) => self.generate_file_format_property(e),
3459 Expression::Filter(e) => self.generate_filter(e),
3460 Expression::Float64(e) => self.generate_float64(e),
3461 Expression::ForIn(e) => self.generate_for_in(e),
3462 Expression::ForeignKey(e) => self.generate_foreign_key(e),
3463 Expression::Format(e) => self.generate_format(e),
3464 Expression::FormatPhrase(e) => self.generate_format_phrase(e),
3465 Expression::FreespaceProperty(e) => self.generate_freespace_property(e),
3466 Expression::From(e) => self.generate_from(e),
3467 Expression::FromBase(e) => self.generate_from_base(e),
3468 Expression::FromTimeZone(e) => self.generate_from_time_zone(e),
3469 Expression::GapFill(e) => self.generate_gap_fill(e),
3470 Expression::GenerateDateArray(e) => self.generate_generate_date_array(e),
3471 Expression::GenerateEmbedding(e) => self.generate_generate_embedding(e),
3472 Expression::GenerateSeries(e) => self.generate_generate_series(e),
3473 Expression::GenerateTimestampArray(e) => self.generate_generate_timestamp_array(e),
3474 Expression::GeneratedAsIdentityColumnConstraint(e) => {
3475 self.generate_generated_as_identity_column_constraint(e)
3476 }
3477 Expression::GeneratedAsRowColumnConstraint(e) => {
3478 self.generate_generated_as_row_column_constraint(e)
3479 }
3480 Expression::Get(e) => self.generate_get(e),
3481 Expression::GetExtract(e) => self.generate_get_extract(e),
3482 Expression::Getbit(e) => self.generate_getbit(e),
3483 Expression::GrantPrincipal(e) => self.generate_grant_principal(e),
3484 Expression::GrantPrivilege(e) => self.generate_grant_privilege(e),
3485 Expression::Group(e) => self.generate_group(e),
3486 Expression::GroupBy(e) => self.generate_group_by(e),
3487 Expression::Grouping(e) => self.generate_grouping(e),
3488 Expression::GroupingId(e) => self.generate_grouping_id(e),
3489 Expression::GroupingSets(e) => self.generate_grouping_sets(e),
3490 Expression::HashAgg(e) => self.generate_hash_agg(e),
3491 Expression::Having(e) => self.generate_having(e),
3492 Expression::HavingMax(e) => self.generate_having_max(e),
3493 Expression::Heredoc(e) => self.generate_heredoc(e),
3494 Expression::HexEncode(e) => self.generate_hex_encode(e),
3495 Expression::Hll(e) => self.generate_hll(e),
3496 Expression::InOutColumnConstraint(e) => self.generate_in_out_column_constraint(e),
3497 Expression::IncludeProperty(e) => self.generate_include_property(e),
3498 Expression::Index(e) => self.generate_index(e),
3499 Expression::IndexColumnConstraint(e) => self.generate_index_column_constraint(e),
3500 Expression::IndexConstraintOption(e) => self.generate_index_constraint_option(e),
3501 Expression::IndexParameters(e) => self.generate_index_parameters(e),
3502 Expression::IndexTableHint(e) => self.generate_index_table_hint(e),
3503 Expression::InheritsProperty(e) => self.generate_inherits_property(e),
3504 Expression::InputModelProperty(e) => self.generate_input_model_property(e),
3505 Expression::InputOutputFormat(e) => self.generate_input_output_format(e),
3506 Expression::Install(e) => self.generate_install(e),
3507 Expression::IntervalOp(e) => self.generate_interval_op(e),
3508 Expression::IntervalSpan(e) => self.generate_interval_span(e),
3509 Expression::IntoClause(e) => self.generate_into_clause(e),
3510 Expression::Introducer(e) => self.generate_introducer(e),
3511 Expression::IsolatedLoadingProperty(e) => self.generate_isolated_loading_property(e),
3512 Expression::JSON(e) => self.generate_json(e),
3513 Expression::JSONArray(e) => self.generate_json_array(e),
3514 Expression::JSONArrayAgg(e) => self.generate_json_array_agg_struct(e),
3515 Expression::JSONArrayAppend(e) => self.generate_json_array_append(e),
3516 Expression::JSONArrayContains(e) => self.generate_json_array_contains(e),
3517 Expression::JSONArrayInsert(e) => self.generate_json_array_insert(e),
3518 Expression::JSONBExists(e) => self.generate_jsonb_exists(e),
3519 Expression::JSONBExtractScalar(e) => self.generate_jsonb_extract_scalar(e),
3520 Expression::JSONBObjectAgg(e) => self.generate_jsonb_object_agg(e),
3521 Expression::JSONObjectAgg(e) => self.generate_json_object_agg_struct(e),
3522 Expression::JSONColumnDef(e) => self.generate_json_column_def(e),
3523 Expression::JSONExists(e) => self.generate_json_exists(e),
3524 Expression::JSONCast(e) => self.generate_json_cast(e),
3525 Expression::JSONExtract(e) => self.generate_json_extract_path(e),
3526 Expression::JSONExtractArray(e) => self.generate_json_extract_array(e),
3527 Expression::JSONExtractQuote(e) => self.generate_json_extract_quote(e),
3528 Expression::JSONExtractScalar(e) => self.generate_json_extract_scalar(e),
3529 Expression::JSONFormat(e) => self.generate_json_format(e),
3530 Expression::JSONKeyValue(e) => self.generate_json_key_value(e),
3531 Expression::JSONKeys(e) => self.generate_json_keys(e),
3532 Expression::JSONKeysAtDepth(e) => self.generate_json_keys_at_depth(e),
3533 Expression::JSONPath(e) => self.generate_json_path_expr(e),
3534 Expression::JSONPathFilter(e) => self.generate_json_path_filter(e),
3535 Expression::JSONPathKey(e) => self.generate_json_path_key(e),
3536 Expression::JSONPathRecursive(e) => self.generate_json_path_recursive(e),
3537 Expression::JSONPathRoot(_) => self.generate_json_path_root(),
3538 Expression::JSONPathScript(e) => self.generate_json_path_script(e),
3539 Expression::JSONPathSelector(e) => self.generate_json_path_selector(e),
3540 Expression::JSONPathSlice(e) => self.generate_json_path_slice(e),
3541 Expression::JSONPathSubscript(e) => self.generate_json_path_subscript(e),
3542 Expression::JSONPathUnion(e) => self.generate_json_path_union(e),
3543 Expression::JSONRemove(e) => self.generate_json_remove(e),
3544 Expression::JSONSchema(e) => self.generate_json_schema(e),
3545 Expression::JSONSet(e) => self.generate_json_set(e),
3546 Expression::JSONStripNulls(e) => self.generate_json_strip_nulls(e),
3547 Expression::JSONTable(e) => self.generate_json_table(e),
3548 Expression::JSONType(e) => self.generate_json_type(e),
3549 Expression::JSONValue(e) => self.generate_json_value(e),
3550 Expression::JSONValueArray(e) => self.generate_json_value_array(e),
3551 Expression::JarowinklerSimilarity(e) => self.generate_jarowinkler_similarity(e),
3552 Expression::JoinHint(e) => self.generate_join_hint(e),
3553 Expression::JournalProperty(e) => self.generate_journal_property(e),
3554 Expression::LanguageProperty(e) => self.generate_language_property(e),
3555 Expression::Lateral(e) => self.generate_lateral(e),
3556 Expression::LikeProperty(e) => self.generate_like_property(e),
3557 Expression::Limit(e) => self.generate_limit(e),
3558 Expression::LimitOptions(e) => self.generate_limit_options(e),
3559 Expression::List(e) => self.generate_list(e),
3560 Expression::ToMap(e) => self.generate_tomap(e),
3561 Expression::Localtime(e) => self.generate_localtime(e),
3562 Expression::Localtimestamp(e) => self.generate_localtimestamp(e),
3563 Expression::LocationProperty(e) => self.generate_location_property(e),
3564 Expression::Lock(e) => self.generate_lock(e),
3565 Expression::LockProperty(e) => self.generate_lock_property(e),
3566 Expression::LockingProperty(e) => self.generate_locking_property(e),
3567 Expression::LockingStatement(e) => self.generate_locking_statement(e),
3568 Expression::LogProperty(e) => self.generate_log_property(e),
3569 Expression::MD5Digest(e) => self.generate_md5_digest(e),
3570 Expression::MLForecast(e) => self.generate_ml_forecast(e),
3571 Expression::MLTranslate(e) => self.generate_ml_translate(e),
3572 Expression::MakeInterval(e) => self.generate_make_interval(e),
3573 Expression::ManhattanDistance(e) => self.generate_manhattan_distance(e),
3574 Expression::Map(e) => self.generate_map(e),
3575 Expression::MapCat(e) => self.generate_map_cat(e),
3576 Expression::MapDelete(e) => self.generate_map_delete(e),
3577 Expression::MapInsert(e) => self.generate_map_insert(e),
3578 Expression::MapPick(e) => self.generate_map_pick(e),
3579 Expression::MaskingPolicyColumnConstraint(e) => {
3580 self.generate_masking_policy_column_constraint(e)
3581 }
3582 Expression::MatchAgainst(e) => self.generate_match_against(e),
3583 Expression::MatchRecognizeMeasure(e) => self.generate_match_recognize_measure(e),
3584 Expression::MaterializedProperty(e) => self.generate_materialized_property(e),
3585 Expression::Merge(e) => self.generate_merge(e),
3586 Expression::MergeBlockRatioProperty(e) => self.generate_merge_block_ratio_property(e),
3587 Expression::MergeTreeTTL(e) => self.generate_merge_tree_ttl(e),
3588 Expression::MergeTreeTTLAction(e) => self.generate_merge_tree_ttl_action(e),
3589 Expression::Minhash(e) => self.generate_minhash(e),
3590 Expression::ModelAttribute(e) => self.generate_model_attribute(e),
3591 Expression::Monthname(e) => self.generate_monthname(e),
3592 Expression::MultitableInserts(e) => self.generate_multitable_inserts(e),
3593 Expression::NextValueFor(e) => self.generate_next_value_for(e),
3594 Expression::Normal(e) => self.generate_normal(e),
3595 Expression::Normalize(e) => self.generate_normalize(e),
3596 Expression::NotNullColumnConstraint(e) => self.generate_not_null_column_constraint(e),
3597 Expression::Nullif(e) => self.generate_nullif(e),
3598 Expression::NumberToStr(e) => self.generate_number_to_str(e),
3599 Expression::ObjectAgg(e) => self.generate_object_agg(e),
3600 Expression::ObjectIdentifier(e) => self.generate_object_identifier(e),
3601 Expression::ObjectInsert(e) => self.generate_object_insert(e),
3602 Expression::Offset(e) => self.generate_offset(e),
3603 Expression::Qualify(e) => self.generate_qualify(e),
3604 Expression::OnCluster(e) => self.generate_on_cluster(e),
3605 Expression::OnCommitProperty(e) => self.generate_on_commit_property(e),
3606 Expression::OnCondition(e) => self.generate_on_condition(e),
3607 Expression::OnConflict(e) => self.generate_on_conflict(e),
3608 Expression::OnProperty(e) => self.generate_on_property(e),
3609 Expression::Opclass(e) => self.generate_opclass(e),
3610 Expression::OpenJSON(e) => self.generate_open_json(e),
3611 Expression::OpenJSONColumnDef(e) => self.generate_open_json_column_def(e),
3612 Expression::Operator(e) => self.generate_operator(e),
3613 Expression::OrderBy(e) => self.generate_order_by(e),
3614 Expression::OutputModelProperty(e) => self.generate_output_model_property(e),
3615 Expression::OverflowTruncateBehavior(e) => self.generate_overflow_truncate_behavior(e),
3616 Expression::ParameterizedAgg(e) => self.generate_parameterized_agg(e),
3617 Expression::ParseDatetime(e) => self.generate_parse_datetime(e),
3618 Expression::ParseIp(e) => self.generate_parse_ip(e),
3619 Expression::ParseJSON(e) => self.generate_parse_json(e),
3620 Expression::ParseTime(e) => self.generate_parse_time(e),
3621 Expression::ParseUrl(e) => self.generate_parse_url(e),
3622 Expression::Partition(e) => self.generate_partition_expr(e),
3623 Expression::PartitionBoundSpec(e) => self.generate_partition_bound_spec(e),
3624 Expression::PartitionByListProperty(e) => self.generate_partition_by_list_property(e),
3625 Expression::PartitionByRangeProperty(e) => self.generate_partition_by_range_property(e),
3626 Expression::PartitionByRangePropertyDynamic(e) => {
3627 self.generate_partition_by_range_property_dynamic(e)
3628 }
3629 Expression::PartitionByTruncate(e) => self.generate_partition_by_truncate(e),
3630 Expression::PartitionList(e) => self.generate_partition_list(e),
3631 Expression::PartitionRange(e) => self.generate_partition_range(e),
3632 Expression::PartitionByProperty(e) => self.generate_partition_by_property(e),
3633 Expression::PartitionedByBucket(e) => self.generate_partitioned_by_bucket(e),
3634 Expression::PartitionedByProperty(e) => self.generate_partitioned_by_property(e),
3635 Expression::PartitionedOfProperty(e) => self.generate_partitioned_of_property(e),
3636 Expression::PeriodForSystemTimeConstraint(e) => {
3637 self.generate_period_for_system_time_constraint(e)
3638 }
3639 Expression::PivotAlias(e) => self.generate_pivot_alias(e),
3640 Expression::PivotAny(e) => self.generate_pivot_any(e),
3641 Expression::Predict(e) => self.generate_predict(e),
3642 Expression::PreviousDay(e) => self.generate_previous_day(e),
3643 Expression::PrimaryKey(e) => self.generate_primary_key(e),
3644 Expression::PrimaryKeyColumnConstraint(e) => {
3645 self.generate_primary_key_column_constraint(e)
3646 }
3647 Expression::PathColumnConstraint(e) => self.generate_path_column_constraint(e),
3648 Expression::ProjectionDef(e) => self.generate_projection_def(e),
3649 Expression::OptionsProperty(e) => self.generate_options_property(e),
3650 Expression::Properties(e) => self.generate_properties(e),
3651 Expression::Property(e) => self.generate_property(e),
3652 Expression::PseudoType(e) => self.generate_pseudo_type(e),
3653 Expression::Put(e) => self.generate_put(e),
3654 Expression::Quantile(e) => self.generate_quantile(e),
3655 Expression::QueryBand(e) => self.generate_query_band(e),
3656 Expression::QueryOption(e) => self.generate_query_option(e),
3657 Expression::QueryTransform(e) => self.generate_query_transform(e),
3658 Expression::Randn(e) => self.generate_randn(e),
3659 Expression::Randstr(e) => self.generate_randstr(e),
3660 Expression::RangeBucket(e) => self.generate_range_bucket(e),
3661 Expression::RangeN(e) => self.generate_range_n(e),
3662 Expression::ReadCSV(e) => self.generate_read_csv(e),
3663 Expression::ReadParquet(e) => self.generate_read_parquet(e),
3664 Expression::RecursiveWithSearch(e) => self.generate_recursive_with_search(e),
3665 Expression::Reduce(e) => self.generate_reduce(e),
3666 Expression::Reference(e) => self.generate_reference(e),
3667 Expression::Refresh(e) => self.generate_refresh(e),
3668 Expression::RefreshTriggerProperty(e) => self.generate_refresh_trigger_property(e),
3669 Expression::RegexpCount(e) => self.generate_regexp_count(e),
3670 Expression::RegexpExtractAll(e) => self.generate_regexp_extract_all(e),
3671 Expression::RegexpFullMatch(e) => self.generate_regexp_full_match(e),
3672 Expression::RegexpILike(e) => self.generate_regexp_i_like(e),
3673 Expression::RegexpInstr(e) => self.generate_regexp_instr(e),
3674 Expression::RegexpSplit(e) => self.generate_regexp_split(e),
3675 Expression::RegrAvgx(e) => self.generate_regr_avgx(e),
3676 Expression::RegrAvgy(e) => self.generate_regr_avgy(e),
3677 Expression::RegrCount(e) => self.generate_regr_count(e),
3678 Expression::RegrIntercept(e) => self.generate_regr_intercept(e),
3679 Expression::RegrR2(e) => self.generate_regr_r2(e),
3680 Expression::RegrSlope(e) => self.generate_regr_slope(e),
3681 Expression::RegrSxx(e) => self.generate_regr_sxx(e),
3682 Expression::RegrSxy(e) => self.generate_regr_sxy(e),
3683 Expression::RegrSyy(e) => self.generate_regr_syy(e),
3684 Expression::RegrValx(e) => self.generate_regr_valx(e),
3685 Expression::RegrValy(e) => self.generate_regr_valy(e),
3686 Expression::RemoteWithConnectionModelProperty(e) => {
3687 self.generate_remote_with_connection_model_property(e)
3688 }
3689 Expression::RenameColumn(e) => self.generate_rename_column(e),
3690 Expression::ReplacePartition(e) => self.generate_replace_partition(e),
3691 Expression::Returning(e) => self.generate_returning(e),
3692 Expression::ReturnsProperty(e) => self.generate_returns_property(e),
3693 Expression::Rollback(e) => self.generate_rollback(e),
3694 Expression::Rollup(e) => self.generate_rollup(e),
3695 Expression::RowFormatDelimitedProperty(e) => {
3696 self.generate_row_format_delimited_property(e)
3697 }
3698 Expression::RowFormatProperty(e) => self.generate_row_format_property(e),
3699 Expression::RowFormatSerdeProperty(e) => self.generate_row_format_serde_property(e),
3700 Expression::SHA2(e) => self.generate_sha2(e),
3701 Expression::SHA2Digest(e) => self.generate_sha2_digest(e),
3702 Expression::SafeAdd(e) => self.generate_safe_add(e),
3703 Expression::SafeDivide(e) => self.generate_safe_divide(e),
3704 Expression::SafeMultiply(e) => self.generate_safe_multiply(e),
3705 Expression::SafeSubtract(e) => self.generate_safe_subtract(e),
3706 Expression::SampleProperty(e) => self.generate_sample_property(e),
3707 Expression::Schema(e) => self.generate_schema(e),
3708 Expression::SchemaCommentProperty(e) => self.generate_schema_comment_property(e),
3709 Expression::ScopeResolution(e) => self.generate_scope_resolution(e),
3710 Expression::Search(e) => self.generate_search(e),
3711 Expression::SearchIp(e) => self.generate_search_ip(e),
3712 Expression::SecurityProperty(e) => self.generate_security_property(e),
3713 Expression::SemanticView(e) => self.generate_semantic_view(e),
3714 Expression::SequenceProperties(e) => self.generate_sequence_properties(e),
3715 Expression::SerdeProperties(e) => self.generate_serde_properties(e),
3716 Expression::SessionParameter(e) => self.generate_session_parameter(e),
3717 Expression::Set(e) => self.generate_set(e),
3718 Expression::SetConfigProperty(e) => self.generate_set_config_property(e),
3719 Expression::SetItem(e) => self.generate_set_item(e),
3720 Expression::SetOperation(e) => self.generate_set_operation(e),
3721 Expression::SetProperty(e) => self.generate_set_property(e),
3722 Expression::SettingsProperty(e) => self.generate_settings_property(e),
3723 Expression::SharingProperty(e) => self.generate_sharing_property(e),
3724 Expression::Slice(e) => self.generate_slice(e),
3725 Expression::SortArray(e) => self.generate_sort_array(e),
3726 Expression::SortBy(e) => self.generate_sort_by(e),
3727 Expression::SortKeyProperty(e) => self.generate_sort_key_property(e),
3728 Expression::SplitPart(e) => self.generate_split_part(e),
3729 Expression::SqlReadWriteProperty(e) => self.generate_sql_read_write_property(e),
3730 Expression::SqlSecurityProperty(e) => self.generate_sql_security_property(e),
3731 Expression::StDistance(e) => self.generate_st_distance(e),
3732 Expression::StPoint(e) => self.generate_st_point(e),
3733 Expression::StabilityProperty(e) => self.generate_stability_property(e),
3734 Expression::StandardHash(e) => self.generate_standard_hash(e),
3735 Expression::StorageHandlerProperty(e) => self.generate_storage_handler_property(e),
3736 Expression::StrPosition(e) => self.generate_str_position(e),
3737 Expression::StrToDate(e) => self.generate_str_to_date(e),
3738 Expression::DateStrToDate(f) => self.generate_simple_func("DATE_STR_TO_DATE", &f.this),
3739 Expression::DateToDateStr(f) => self.generate_simple_func("DATE_TO_DATE_STR", &f.this),
3740 Expression::StrToMap(e) => self.generate_str_to_map(e),
3741 Expression::StrToTime(e) => self.generate_str_to_time(e),
3742 Expression::StrToUnix(e) => self.generate_str_to_unix(e),
3743 Expression::StringToArray(e) => self.generate_string_to_array(e),
3744 Expression::Struct(e) => self.generate_struct(e),
3745 Expression::Stuff(e) => self.generate_stuff(e),
3746 Expression::SubstringIndex(e) => self.generate_substring_index(e),
3747 Expression::Summarize(e) => self.generate_summarize(e),
3748 Expression::Systimestamp(e) => self.generate_systimestamp(e),
3749 Expression::TableAlias(e) => self.generate_table_alias(e),
3750 Expression::TableFromRows(e) => self.generate_table_from_rows(e),
3751 Expression::RowsFrom(e) => self.generate_rows_from(e),
3752 Expression::TableSample(e) => self.generate_table_sample(e),
3753 Expression::Tag(e) => self.generate_tag(e),
3754 Expression::Tags(e) => self.generate_tags(e),
3755 Expression::TemporaryProperty(e) => self.generate_temporary_property(e),
3756 Expression::Time(e) => self.generate_time_func(e),
3757 Expression::TimeAdd(e) => self.generate_time_add(e),
3758 Expression::TimeDiff(e) => self.generate_time_diff(e),
3759 Expression::TimeFromParts(e) => self.generate_time_from_parts(e),
3760 Expression::TimeSlice(e) => self.generate_time_slice(e),
3761 Expression::TimeStrToDate(e) => self.generate_time_str_to_date(e),
3762 Expression::TimeStrToTime(e) => self.generate_time_str_to_time(e),
3763 Expression::TimeSub(e) => self.generate_time_sub(e),
3764 Expression::TimeToStr(e) => self.generate_time_to_str(e),
3765 Expression::TimeToUnix(e) => self.generate_time_to_unix(e),
3766 Expression::TimeTrunc(e) => self.generate_time_trunc(e),
3767 Expression::TimeUnit(e) => self.generate_time_unit(e),
3768 Expression::Timestamp(e) => self.generate_timestamp_func(e),
3769 Expression::TimestampAdd(e) => self.generate_timestamp_add(e),
3770 Expression::TimestampDiff(e) => self.generate_timestamp_diff(e),
3771 Expression::TimestampFromParts(e) => self.generate_timestamp_from_parts(e),
3772 Expression::TimestampSub(e) => self.generate_timestamp_sub(e),
3773 Expression::TimestampTzFromParts(e) => self.generate_timestamp_tz_from_parts(e),
3774 Expression::ToBinary(e) => self.generate_to_binary(e),
3775 Expression::ToBoolean(e) => self.generate_to_boolean(e),
3776 Expression::ToChar(e) => self.generate_to_char(e),
3777 Expression::ToDecfloat(e) => self.generate_to_decfloat(e),
3778 Expression::ToDouble(e) => self.generate_to_double(e),
3779 Expression::ToFile(e) => self.generate_to_file(e),
3780 Expression::ToNumber(e) => self.generate_to_number(e),
3781 Expression::ToTableProperty(e) => self.generate_to_table_property(e),
3782 Expression::Transaction(e) => self.generate_transaction(e),
3783 Expression::Transform(e) => self.generate_transform(e),
3784 Expression::TransformModelProperty(e) => self.generate_transform_model_property(e),
3785 Expression::TransientProperty(e) => self.generate_transient_property(e),
3786 Expression::Translate(e) => self.generate_translate(e),
3787 Expression::TranslateCharacters(e) => self.generate_translate_characters(e),
3788 Expression::TruncateTable(e) => self.generate_truncate_table(e),
3789 Expression::TryBase64DecodeBinary(e) => self.generate_try_base64_decode_binary(e),
3790 Expression::TryBase64DecodeString(e) => self.generate_try_base64_decode_string(e),
3791 Expression::TryToDecfloat(e) => self.generate_try_to_decfloat(e),
3792 Expression::TsOrDsAdd(e) => self.generate_ts_or_ds_add(e),
3793 Expression::TsOrDsDiff(e) => self.generate_ts_or_ds_diff(e),
3794 Expression::TsOrDsToDate(e) => self.generate_ts_or_ds_to_date(e),
3795 Expression::TsOrDsToTime(e) => self.generate_ts_or_ds_to_time(e),
3796 Expression::Unhex(e) => self.generate_unhex(e),
3797 Expression::UnicodeString(e) => self.generate_unicode_string(e),
3798 Expression::Uniform(e) => self.generate_uniform(e),
3799 Expression::UniqueColumnConstraint(e) => self.generate_unique_column_constraint(e),
3800 Expression::UniqueKeyProperty(e) => self.generate_unique_key_property(e),
3801 Expression::RollupProperty(e) => self.generate_rollup_property(e),
3802 Expression::UnixToStr(e) => self.generate_unix_to_str(e),
3803 Expression::UnixToTime(e) => self.generate_unix_to_time(e),
3804 Expression::UnpivotColumns(e) => self.generate_unpivot_columns(e),
3805 Expression::UserDefinedFunction(e) => self.generate_user_defined_function(e),
3806 Expression::UsingTemplateProperty(e) => self.generate_using_template_property(e),
3807 Expression::UtcTime(e) => self.generate_utc_time(e),
3808 Expression::UtcTimestamp(e) => self.generate_utc_timestamp(e),
3809 Expression::Uuid(e) => self.generate_uuid(e),
3810 Expression::Var(v) => {
3811 if matches!(self.config.dialect, Some(DialectType::MySQL))
3812 && v.this.len() > 2
3813 && (v.this.starts_with("0x") || v.this.starts_with("0X"))
3814 && !v.this[2..].chars().all(|c| c.is_ascii_hexdigit())
3815 {
3816 return self.generate_identifier(&Identifier {
3817 name: v.this.clone(),
3818 quoted: true,
3819 trailing_comments: Vec::new(),
3820 span: None,
3821 });
3822 }
3823 self.write(&v.this);
3824 Ok(())
3825 }
3826 Expression::Variadic(e) => {
3827 self.write_keyword("VARIADIC");
3828 self.write_space();
3829 self.generate_expression(&e.this)?;
3830 Ok(())
3831 }
3832 Expression::VarMap(e) => self.generate_var_map(e),
3833 Expression::VectorSearch(e) => self.generate_vector_search(e),
3834 Expression::Version(e) => self.generate_version(e),
3835 Expression::ViewAttributeProperty(e) => self.generate_view_attribute_property(e),
3836 Expression::VolatileProperty(e) => self.generate_volatile_property(e),
3837 Expression::WatermarkColumnConstraint(e) => {
3838 self.generate_watermark_column_constraint(e)
3839 }
3840 Expression::Week(e) => self.generate_week(e),
3841 Expression::When(e) => self.generate_when(e),
3842 Expression::Whens(e) => self.generate_whens(e),
3843 Expression::Where(e) => self.generate_where(e),
3844 Expression::WidthBucket(e) => self.generate_width_bucket(e),
3845 Expression::Window(e) => self.generate_window(e),
3846 Expression::WindowSpec(e) => self.generate_window_spec(e),
3847 Expression::WithDataProperty(e) => self.generate_with_data_property(e),
3848 Expression::WithFill(e) => self.generate_with_fill(e),
3849 Expression::WithJournalTableProperty(e) => self.generate_with_journal_table_property(e),
3850 Expression::WithOperator(e) => self.generate_with_operator(e),
3851 Expression::WithProcedureOptions(e) => self.generate_with_procedure_options(e),
3852 Expression::WithSchemaBindingProperty(e) => {
3853 self.generate_with_schema_binding_property(e)
3854 }
3855 Expression::WithSystemVersioningProperty(e) => {
3856 self.generate_with_system_versioning_property(e)
3857 }
3858 Expression::WithTableHint(e) => self.generate_with_table_hint(e),
3859 Expression::XMLElement(e) => self.generate_xml_element(e),
3860 Expression::XMLGet(e) => self.generate_xml_get(e),
3861 Expression::XMLKeyValueOption(e) => self.generate_xml_key_value_option(e),
3862 Expression::XMLTable(e) => self.generate_xml_table(e),
3863 Expression::Xor(e) => self.generate_xor(e),
3864 Expression::Zipf(e) => self.generate_zipf(e),
3865 _ => {
3866 self.write(&format!("/* unimplemented: {:?} */", expr));
3868 Ok(())
3869 }
3870 }
3871 }
3872
3873 fn generate_select(&mut self, select: &Select) -> Result<()> {
3874 use crate::dialects::DialectType;
3875
3876 for comment in &select.leading_comments {
3878 self.write_formatted_comment(comment);
3879 self.write(" ");
3880 }
3881
3882 if let Some(with) = &select.with {
3884 self.generate_with(with)?;
3885 if self.config.pretty {
3886 self.write_newline();
3887 self.write_indent();
3888 } else {
3889 self.write_space();
3890 }
3891 }
3892
3893 for comment in &select.post_select_comments {
3896 self.write_formatted_comment(comment);
3897 self.write(" ");
3898 }
3899
3900 self.write_keyword("SELECT");
3901
3902 if let Some(hint) = &select.hint {
3904 self.generate_hint(hint)?;
3905 }
3906
3907 let use_top_from_limit = matches!(self.config.dialect, Some(DialectType::TSQL))
3911 && select.top.is_none()
3912 && select.limit.is_some()
3913 && select.offset.is_none(); let is_top_dialect = matches!(
3918 self.config.dialect,
3919 Some(DialectType::TSQL) | Some(DialectType::Teradata) | Some(DialectType::Fabric)
3920 );
3921 let keep_top_verbatim = !is_top_dialect
3922 && select.limit.is_none()
3923 && select
3924 .top
3925 .as_ref()
3926 .map_or(false, |top| top.percent || top.with_ties);
3927
3928 if select.distinct && (is_top_dialect || select.top.is_some()) {
3929 self.write_space();
3930 self.write_keyword("DISTINCT");
3931 }
3932
3933 if is_top_dialect || keep_top_verbatim {
3934 if let Some(top) = &select.top {
3935 self.write_space();
3936 self.write_keyword("TOP");
3937 if top.parenthesized {
3938 self.write(" (");
3939 self.generate_expression(&top.this)?;
3940 self.write(")");
3941 } else {
3942 self.write_space();
3943 self.generate_expression(&top.this)?;
3944 }
3945 if top.percent {
3946 self.write_space();
3947 self.write_keyword("PERCENT");
3948 }
3949 if top.with_ties {
3950 self.write_space();
3951 self.write_keyword("WITH TIES");
3952 }
3953 } else if use_top_from_limit {
3954 if let Some(limit) = &select.limit {
3956 self.write_space();
3957 self.write_keyword("TOP");
3958 let is_simple_literal =
3960 matches!(&limit.this, Expression::Literal(Literal::Number(_)));
3961 if is_simple_literal {
3962 self.write_space();
3963 self.generate_expression(&limit.this)?;
3964 } else {
3965 self.write(" (");
3966 self.generate_expression(&limit.this)?;
3967 self.write(")");
3968 }
3969 }
3970 }
3971 }
3972
3973 if select.distinct && !is_top_dialect && select.top.is_none() {
3974 self.write_space();
3975 self.write_keyword("DISTINCT");
3976 }
3977
3978 if let Some(distinct_on) = &select.distinct_on {
3980 self.write_space();
3981 self.write_keyword("ON");
3982 self.write(" (");
3983 for (i, expr) in distinct_on.iter().enumerate() {
3984 if i > 0 {
3985 self.write(", ");
3986 }
3987 self.generate_expression(expr)?;
3988 }
3989 self.write(")");
3990 }
3991
3992 for modifier in &select.operation_modifiers {
3994 self.write_space();
3995 self.write_keyword(modifier);
3996 }
3997
3998 if let Some(kind) = &select.kind {
4000 self.write_space();
4001 self.write_keyword("AS");
4002 self.write_space();
4003 self.write_keyword(kind);
4004 }
4005
4006 if !select.expressions.is_empty() {
4008 if self.config.pretty {
4009 self.write_newline();
4010 self.indent_level += 1;
4011 } else {
4012 self.write_space();
4013 }
4014 }
4015
4016 for (i, expr) in select.expressions.iter().enumerate() {
4017 if i > 0 {
4018 self.write(",");
4019 if self.config.pretty {
4020 self.write_newline();
4021 } else {
4022 self.write_space();
4023 }
4024 }
4025 if self.config.pretty {
4026 self.write_indent();
4027 }
4028 self.generate_expression(expr)?;
4029 }
4030
4031 if self.config.pretty && !select.expressions.is_empty() {
4032 self.indent_level -= 1;
4033 }
4034
4035 if let Some(into) = &select.into {
4038 if self.config.pretty {
4039 self.write_newline();
4040 self.write_indent();
4041 } else {
4042 self.write_space();
4043 }
4044 if into.bulk_collect {
4045 self.write_keyword("BULK COLLECT INTO");
4046 } else {
4047 self.write_keyword("INTO");
4048 }
4049 if into.temporary {
4050 self.write_space();
4051 self.write_keyword("TEMPORARY");
4052 }
4053 if into.unlogged {
4054 self.write_space();
4055 self.write_keyword("UNLOGGED");
4056 }
4057 self.write_space();
4058 if !into.expressions.is_empty() {
4060 for (i, expr) in into.expressions.iter().enumerate() {
4061 if i > 0 {
4062 self.write(", ");
4063 }
4064 self.generate_expression(expr)?;
4065 }
4066 } else {
4067 self.generate_expression(&into.this)?;
4068 }
4069 }
4070
4071 if let Some(from) = &select.from {
4073 if self.config.pretty {
4074 self.write_newline();
4075 self.write_indent();
4076 } else {
4077 self.write_space();
4078 }
4079 self.write_keyword("FROM");
4080 self.write_space();
4081
4082 let has_tablesample = from
4087 .expressions
4088 .iter()
4089 .any(|e| matches!(e, Expression::TableSample(_)));
4090 let is_cross_join_dialect = matches!(
4091 self.config.dialect,
4092 Some(DialectType::BigQuery)
4093 | Some(DialectType::Hive)
4094 | Some(DialectType::Spark)
4095 | Some(DialectType::Databricks)
4096 | Some(DialectType::SQLite)
4097 | Some(DialectType::ClickHouse)
4098 );
4099 let source_is_same_as_target = self.config.source_dialect.is_some()
4102 && self.config.source_dialect == self.config.dialect;
4103 let source_is_cross_join_dialect = matches!(
4104 self.config.source_dialect,
4105 Some(DialectType::BigQuery)
4106 | Some(DialectType::Hive)
4107 | Some(DialectType::Spark)
4108 | Some(DialectType::Databricks)
4109 | Some(DialectType::SQLite)
4110 | Some(DialectType::ClickHouse)
4111 );
4112 let use_cross_join = !has_tablesample
4113 && is_cross_join_dialect
4114 && (source_is_same_as_target
4115 || source_is_cross_join_dialect
4116 || self.config.source_dialect.is_none());
4117
4118 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
4120
4121 for (i, expr) in from.expressions.iter().enumerate() {
4122 if i > 0 {
4123 if use_cross_join {
4124 self.write(" CROSS JOIN ");
4125 } else {
4126 self.write(", ");
4127 }
4128 }
4129 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
4130 self.write("(");
4131 self.generate_expression(expr)?;
4132 self.write(")");
4133 } else {
4134 self.generate_expression(expr)?;
4135 }
4136 }
4137 }
4138
4139 if self.config.pretty {
4143 self.generate_joins_with_nesting(&select.joins)?;
4144 } else {
4145 for join in &select.joins {
4146 self.generate_join(join)?;
4147 }
4148 for join in select.joins.iter().rev() {
4150 if join.deferred_condition {
4151 self.generate_join_condition(join)?;
4152 }
4153 }
4154 }
4155
4156 for lateral_view in &select.lateral_views {
4158 self.generate_lateral_view(lateral_view)?;
4159 }
4160
4161 if let Some(prewhere) = &select.prewhere {
4163 self.write_clause_condition("PREWHERE", prewhere)?;
4164 }
4165
4166 if let Some(where_clause) = &select.where_clause {
4168 self.write_clause_condition("WHERE", &where_clause.this)?;
4169 }
4170
4171 if let Some(connect) = &select.connect {
4173 self.generate_connect(connect)?;
4174 }
4175
4176 if let Some(group_by) = &select.group_by {
4178 if self.config.pretty {
4179 for comment in &group_by.comments {
4181 self.write_newline();
4182 self.write_indent();
4183 self.write_formatted_comment(comment);
4184 }
4185 self.write_newline();
4186 self.write_indent();
4187 } else {
4188 self.write_space();
4189 for comment in &group_by.comments {
4191 self.write_formatted_comment(comment);
4192 self.write_space();
4193 }
4194 }
4195 self.write_keyword("GROUP BY");
4196 match group_by.all {
4198 Some(true) => {
4199 self.write_space();
4200 self.write_keyword("ALL");
4201 }
4202 Some(false) => {
4203 self.write_space();
4204 self.write_keyword("DISTINCT");
4205 }
4206 None => {}
4207 }
4208 if !group_by.expressions.is_empty() {
4209 let mut trailing_cube = false;
4212 let mut trailing_rollup = false;
4213 let mut plain_expressions: Vec<&Expression> = Vec::new();
4214 let mut grouping_sets_expressions: Vec<&Expression> = Vec::new();
4215 let mut cube_expressions: Vec<&Expression> = Vec::new();
4216 let mut rollup_expressions: Vec<&Expression> = Vec::new();
4217
4218 for expr in &group_by.expressions {
4219 match expr {
4220 Expression::Cube(c) if c.expressions.is_empty() => {
4221 trailing_cube = true;
4222 }
4223 Expression::Rollup(r) if r.expressions.is_empty() => {
4224 trailing_rollup = true;
4225 }
4226 Expression::Function(f) if f.name == "CUBE" => {
4227 cube_expressions.push(expr);
4228 }
4229 Expression::Function(f) if f.name == "ROLLUP" => {
4230 rollup_expressions.push(expr);
4231 }
4232 Expression::Function(f) if f.name == "GROUPING SETS" => {
4233 grouping_sets_expressions.push(expr);
4234 }
4235 _ => {
4236 plain_expressions.push(expr);
4237 }
4238 }
4239 }
4240
4241 let mut regular_expressions: Vec<&Expression> = Vec::new();
4243 regular_expressions.extend(plain_expressions);
4244 regular_expressions.extend(grouping_sets_expressions);
4245 regular_expressions.extend(cube_expressions);
4246 regular_expressions.extend(rollup_expressions);
4247
4248 if self.config.pretty {
4249 self.write_newline();
4250 self.indent_level += 1;
4251 self.write_indent();
4252 } else {
4253 self.write_space();
4254 }
4255
4256 for (i, expr) in regular_expressions.iter().enumerate() {
4257 if i > 0 {
4258 if self.config.pretty {
4259 self.write(",");
4260 self.write_newline();
4261 self.write_indent();
4262 } else {
4263 self.write(", ");
4264 }
4265 }
4266 self.generate_expression(expr)?;
4267 }
4268
4269 if self.config.pretty {
4270 self.indent_level -= 1;
4271 }
4272
4273 if trailing_cube {
4275 self.write_space();
4276 self.write_keyword("WITH CUBE");
4277 } else if trailing_rollup {
4278 self.write_space();
4279 self.write_keyword("WITH ROLLUP");
4280 }
4281 }
4282
4283 if group_by.totals {
4285 self.write_space();
4286 self.write_keyword("WITH TOTALS");
4287 }
4288 }
4289
4290 if let Some(having) = &select.having {
4292 if self.config.pretty {
4293 for comment in &having.comments {
4295 self.write_newline();
4296 self.write_indent();
4297 self.write_formatted_comment(comment);
4298 }
4299 } else {
4300 for comment in &having.comments {
4301 self.write_space();
4302 self.write_formatted_comment(comment);
4303 }
4304 }
4305 self.write_clause_condition("HAVING", &having.this)?;
4306 }
4307
4308 if select.qualify_after_window {
4310 if let Some(windows) = &select.windows {
4312 self.write_window_clause(windows)?;
4313 }
4314 if let Some(qualify) = &select.qualify {
4315 self.write_clause_condition("QUALIFY", &qualify.this)?;
4316 }
4317 } else {
4318 if let Some(qualify) = &select.qualify {
4320 self.write_clause_condition("QUALIFY", &qualify.this)?;
4321 }
4322 if let Some(windows) = &select.windows {
4323 self.write_window_clause(windows)?;
4324 }
4325 }
4326
4327 if let Some(distribute_by) = &select.distribute_by {
4329 self.write_clause_expressions("DISTRIBUTE BY", &distribute_by.expressions)?;
4330 }
4331
4332 if let Some(cluster_by) = &select.cluster_by {
4334 self.write_order_clause("CLUSTER BY", &cluster_by.expressions)?;
4335 }
4336
4337 if let Some(sort_by) = &select.sort_by {
4339 self.write_order_clause("SORT BY", &sort_by.expressions)?;
4340 }
4341
4342 if let Some(order_by) = &select.order_by {
4344 if self.config.pretty {
4345 for comment in &order_by.comments {
4347 self.write_newline();
4348 self.write_indent();
4349 self.write_formatted_comment(comment);
4350 }
4351 } else {
4352 for comment in &order_by.comments {
4353 self.write_space();
4354 self.write_formatted_comment(comment);
4355 }
4356 }
4357 let keyword = if order_by.siblings {
4358 "ORDER SIBLINGS BY"
4359 } else {
4360 "ORDER BY"
4361 };
4362 self.write_order_clause(keyword, &order_by.expressions)?;
4363 }
4364
4365 if select.order_by.is_none()
4367 && select.fetch.is_some()
4368 && matches!(
4369 self.config.dialect,
4370 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4371 )
4372 {
4373 if self.config.pretty {
4374 self.write_newline();
4375 self.write_indent();
4376 } else {
4377 self.write_space();
4378 }
4379 self.write_keyword("ORDER BY (SELECT NULL) OFFSET 0 ROWS");
4380 }
4381
4382 let is_presto_like = matches!(
4387 self.config.dialect,
4388 Some(DialectType::Presto) | Some(DialectType::Trino)
4389 );
4390
4391 if is_presto_like && select.offset.is_some() {
4392 if let Some(offset) = &select.offset {
4394 if self.config.pretty {
4395 self.write_newline();
4396 self.write_indent();
4397 } else {
4398 self.write_space();
4399 }
4400 self.write_keyword("OFFSET");
4401 self.write_space();
4402 self.write_limit_expr(&offset.this)?;
4403 if offset.rows == Some(true) {
4404 self.write_space();
4405 self.write_keyword("ROWS");
4406 }
4407 }
4408 if let Some(limit) = &select.limit {
4409 if self.config.pretty {
4410 self.write_newline();
4411 self.write_indent();
4412 } else {
4413 self.write_space();
4414 }
4415 self.write_keyword("LIMIT");
4416 self.write_space();
4417 self.write_limit_expr(&limit.this)?;
4418 if limit.percent {
4419 self.write_space();
4420 self.write_keyword("PERCENT");
4421 }
4422 for comment in &limit.comments {
4424 self.write(" ");
4425 self.write_formatted_comment(comment);
4426 }
4427 }
4428 } else {
4429 let fetch_as_limit = select.fetch.as_ref().map_or(false, |fetch| {
4431 !fetch.percent
4432 && !fetch.with_ties
4433 && fetch.count.is_some()
4434 && matches!(
4435 self.config.dialect,
4436 Some(DialectType::Spark)
4437 | Some(DialectType::Hive)
4438 | Some(DialectType::DuckDB)
4439 | Some(DialectType::SQLite)
4440 | Some(DialectType::MySQL)
4441 | Some(DialectType::BigQuery)
4442 | Some(DialectType::Databricks)
4443 | Some(DialectType::StarRocks)
4444 | Some(DialectType::Doris)
4445 | Some(DialectType::Athena)
4446 | Some(DialectType::ClickHouse)
4447 | Some(DialectType::Redshift)
4448 )
4449 });
4450
4451 if let Some(limit) = &select.limit {
4453 if !matches!(self.config.dialect, Some(DialectType::TSQL)) {
4455 if self.config.pretty {
4456 self.write_newline();
4457 self.write_indent();
4458 } else {
4459 self.write_space();
4460 }
4461 self.write_keyword("LIMIT");
4462 self.write_space();
4463 self.write_limit_expr(&limit.this)?;
4464 if limit.percent {
4465 self.write_space();
4466 self.write_keyword("PERCENT");
4467 }
4468 for comment in &limit.comments {
4470 self.write(" ");
4471 self.write_formatted_comment(comment);
4472 }
4473 }
4474 }
4475
4476 if select.top.is_some() && !is_top_dialect && select.limit.is_none() {
4478 if let Some(top) = &select.top {
4479 if !top.percent && !top.with_ties {
4480 if self.config.pretty {
4481 self.write_newline();
4482 self.write_indent();
4483 } else {
4484 self.write_space();
4485 }
4486 self.write_keyword("LIMIT");
4487 self.write_space();
4488 self.generate_expression(&top.this)?;
4489 }
4490 }
4491 }
4492
4493 if fetch_as_limit && select.offset.is_some() {
4496 if let Some(fetch) = &select.fetch {
4497 if self.config.pretty {
4498 self.write_newline();
4499 self.write_indent();
4500 } else {
4501 self.write_space();
4502 }
4503 self.write_keyword("LIMIT");
4504 self.write_space();
4505 self.generate_expression(fetch.count.as_ref().unwrap())?;
4506 }
4507 }
4508
4509 if let Some(offset) = &select.offset {
4513 if self.config.pretty {
4514 self.write_newline();
4515 self.write_indent();
4516 } else {
4517 self.write_space();
4518 }
4519 if matches!(self.config.dialect, Some(DialectType::TSQL)) {
4520 self.write_keyword("OFFSET");
4522 self.write_space();
4523 self.write_limit_expr(&offset.this)?;
4524 self.write_space();
4525 self.write_keyword("ROWS");
4526 if let Some(limit) = &select.limit {
4528 self.write_space();
4529 self.write_keyword("FETCH NEXT");
4530 self.write_space();
4531 self.write_limit_expr(&limit.this)?;
4532 self.write_space();
4533 self.write_keyword("ROWS ONLY");
4534 }
4535 } else {
4536 self.write_keyword("OFFSET");
4537 self.write_space();
4538 self.write_limit_expr(&offset.this)?;
4539 if offset.rows == Some(true) {
4541 self.write_space();
4542 self.write_keyword("ROWS");
4543 }
4544 }
4545 }
4546 }
4547
4548 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4550 if let Some(limit_by) = &select.limit_by {
4551 if !limit_by.is_empty() {
4552 self.write_space();
4553 self.write_keyword("BY");
4554 self.write_space();
4555 for (i, expr) in limit_by.iter().enumerate() {
4556 if i > 0 {
4557 self.write(", ");
4558 }
4559 self.generate_expression(expr)?;
4560 }
4561 }
4562 }
4563 }
4564
4565 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4567 if let Some(settings) = &select.settings {
4568 if self.config.pretty {
4569 self.write_newline();
4570 self.write_indent();
4571 } else {
4572 self.write_space();
4573 }
4574 self.write_keyword("SETTINGS");
4575 self.write_space();
4576 for (i, expr) in settings.iter().enumerate() {
4577 if i > 0 {
4578 self.write(", ");
4579 }
4580 self.generate_expression(expr)?;
4581 }
4582 }
4583
4584 if let Some(format_expr) = &select.format {
4585 if self.config.pretty {
4586 self.write_newline();
4587 self.write_indent();
4588 } else {
4589 self.write_space();
4590 }
4591 self.write_keyword("FORMAT");
4592 self.write_space();
4593 self.generate_expression(format_expr)?;
4594 }
4595 }
4596
4597 if let Some(fetch) = &select.fetch {
4599 let fetch_already_as_limit = select.offset.is_some()
4601 && !fetch.percent
4602 && !fetch.with_ties
4603 && fetch.count.is_some()
4604 && matches!(
4605 self.config.dialect,
4606 Some(DialectType::Spark)
4607 | Some(DialectType::Hive)
4608 | Some(DialectType::DuckDB)
4609 | Some(DialectType::SQLite)
4610 | Some(DialectType::MySQL)
4611 | Some(DialectType::BigQuery)
4612 | Some(DialectType::Databricks)
4613 | Some(DialectType::StarRocks)
4614 | Some(DialectType::Doris)
4615 | Some(DialectType::Athena)
4616 | Some(DialectType::ClickHouse)
4617 | Some(DialectType::Redshift)
4618 );
4619
4620 if fetch_already_as_limit {
4621 } else {
4623 if self.config.pretty {
4624 self.write_newline();
4625 self.write_indent();
4626 } else {
4627 self.write_space();
4628 }
4629
4630 let use_limit = !fetch.percent
4632 && !fetch.with_ties
4633 && fetch.count.is_some()
4634 && matches!(
4635 self.config.dialect,
4636 Some(DialectType::Spark)
4637 | Some(DialectType::Hive)
4638 | Some(DialectType::DuckDB)
4639 | Some(DialectType::SQLite)
4640 | Some(DialectType::MySQL)
4641 | Some(DialectType::BigQuery)
4642 | Some(DialectType::Databricks)
4643 | Some(DialectType::StarRocks)
4644 | Some(DialectType::Doris)
4645 | Some(DialectType::Athena)
4646 | Some(DialectType::ClickHouse)
4647 | Some(DialectType::Redshift)
4648 );
4649
4650 if use_limit {
4651 self.write_keyword("LIMIT");
4652 self.write_space();
4653 self.generate_expression(fetch.count.as_ref().unwrap())?;
4654 } else {
4655 self.write_keyword("FETCH");
4656 self.write_space();
4657 self.write_keyword(&fetch.direction);
4658 if let Some(ref count) = fetch.count {
4659 self.write_space();
4660 self.generate_expression(count)?;
4661 }
4662 if fetch.percent {
4663 self.write_space();
4664 self.write_keyword("PERCENT");
4665 }
4666 if fetch.rows {
4667 self.write_space();
4668 self.write_keyword("ROWS");
4669 }
4670 if fetch.with_ties {
4671 self.write_space();
4672 self.write_keyword("WITH TIES");
4673 } else {
4674 self.write_space();
4675 self.write_keyword("ONLY");
4676 }
4677 }
4678 } }
4680
4681 if let Some(sample) = &select.sample {
4683 use crate::dialects::DialectType;
4684 if self.config.pretty {
4685 self.write_newline();
4686 } else {
4687 self.write_space();
4688 }
4689
4690 if sample.is_using_sample {
4691 self.write_keyword("USING SAMPLE");
4693 self.generate_sample_body(sample)?;
4694 } else {
4695 self.write_keyword("TABLESAMPLE");
4696
4697 let snowflake_bernoulli =
4699 matches!(self.config.dialect, Some(DialectType::Snowflake))
4700 && !sample.explicit_method;
4701 if snowflake_bernoulli {
4702 self.write_space();
4703 self.write_keyword("BERNOULLI");
4704 }
4705
4706 if matches!(sample.method, SampleMethod::Bucket) {
4708 self.write_space();
4709 self.write("(");
4710 self.write_keyword("BUCKET");
4711 self.write_space();
4712 if let Some(ref num) = sample.bucket_numerator {
4713 self.generate_expression(num)?;
4714 }
4715 self.write_space();
4716 self.write_keyword("OUT OF");
4717 self.write_space();
4718 if let Some(ref denom) = sample.bucket_denominator {
4719 self.generate_expression(denom)?;
4720 }
4721 if let Some(ref field) = sample.bucket_field {
4722 self.write_space();
4723 self.write_keyword("ON");
4724 self.write_space();
4725 self.generate_expression(field)?;
4726 }
4727 self.write(")");
4728 } else if sample.unit_after_size {
4729 if sample.explicit_method && sample.method_before_size {
4731 self.write_space();
4732 match sample.method {
4733 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
4734 SampleMethod::System => self.write_keyword("SYSTEM"),
4735 SampleMethod::Block => self.write_keyword("BLOCK"),
4736 SampleMethod::Row => self.write_keyword("ROW"),
4737 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
4738 _ => {}
4739 }
4740 }
4741 self.write(" (");
4742 self.generate_expression(&sample.size)?;
4743 self.write_space();
4744 match sample.method {
4745 SampleMethod::Percent => self.write_keyword("PERCENT"),
4746 SampleMethod::Row => self.write_keyword("ROWS"),
4747 SampleMethod::Reservoir => self.write_keyword("ROWS"),
4748 _ => {
4749 self.write_keyword("PERCENT");
4750 }
4751 }
4752 self.write(")");
4753 } else {
4754 self.write_space();
4756 match sample.method {
4757 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
4758 SampleMethod::System => self.write_keyword("SYSTEM"),
4759 SampleMethod::Block => self.write_keyword("BLOCK"),
4760 SampleMethod::Row => self.write_keyword("ROW"),
4761 SampleMethod::Percent => self.write_keyword("BERNOULLI"),
4762 SampleMethod::Bucket => {}
4763 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
4764 }
4765 self.write(" (");
4766 self.generate_expression(&sample.size)?;
4767 if matches!(sample.method, SampleMethod::Percent) {
4768 self.write_space();
4769 self.write_keyword("PERCENT");
4770 }
4771 self.write(")");
4772 }
4773 }
4774
4775 if let Some(seed) = &sample.seed {
4776 self.write_space();
4777 let use_seed = sample.use_seed_keyword
4779 && !matches!(
4780 self.config.dialect,
4781 Some(crate::dialects::DialectType::Databricks)
4782 | Some(crate::dialects::DialectType::Spark)
4783 );
4784 if use_seed {
4785 self.write_keyword("SEED");
4786 } else {
4787 self.write_keyword("REPEATABLE");
4788 }
4789 self.write(" (");
4790 self.generate_expression(seed)?;
4791 self.write(")");
4792 }
4793 }
4794
4795 if self.config.locking_reads_supported {
4798 for lock in &select.locks {
4799 if self.config.pretty {
4800 self.write_newline();
4801 self.write_indent();
4802 } else {
4803 self.write_space();
4804 }
4805 self.generate_lock(lock)?;
4806 }
4807 }
4808
4809 if !select.for_xml.is_empty() {
4811 if self.config.pretty {
4812 self.write_newline();
4813 self.write_indent();
4814 } else {
4815 self.write_space();
4816 }
4817 self.write_keyword("FOR XML");
4818 for (i, opt) in select.for_xml.iter().enumerate() {
4819 if self.config.pretty {
4820 if i > 0 {
4821 self.write(",");
4822 }
4823 self.write_newline();
4824 self.write_indent();
4825 self.write(" "); } else {
4827 if i > 0 {
4828 self.write(",");
4829 }
4830 self.write_space();
4831 }
4832 self.generate_for_xml_option(opt)?;
4833 }
4834 }
4835
4836 if let Some(ref option) = select.option {
4838 if matches!(
4839 self.config.dialect,
4840 Some(crate::dialects::DialectType::TSQL)
4841 | Some(crate::dialects::DialectType::Fabric)
4842 ) {
4843 self.write_space();
4844 self.write(option);
4845 }
4846 }
4847
4848 Ok(())
4849 }
4850
4851 fn generate_for_xml_option(&mut self, opt: &Expression) -> Result<()> {
4853 match opt {
4854 Expression::QueryOption(qo) => {
4855 if let Expression::Var(var) = &*qo.this {
4857 self.write(&var.this);
4858 } else {
4859 self.generate_expression(&qo.this)?;
4860 }
4861 if let Some(expr) = &qo.expression {
4863 self.write("(");
4864 self.generate_expression(expr)?;
4865 self.write(")");
4866 }
4867 }
4868 _ => {
4869 self.generate_expression(opt)?;
4870 }
4871 }
4872 Ok(())
4873 }
4874
4875 fn generate_with(&mut self, with: &With) -> Result<()> {
4876 use crate::dialects::DialectType;
4877
4878 for comment in &with.leading_comments {
4880 self.write_formatted_comment(comment);
4881 self.write(" ");
4882 }
4883 self.write_keyword("WITH");
4884 if with.recursive && self.config.cte_recursive_keyword_required {
4885 self.write_space();
4886 self.write_keyword("RECURSIVE");
4887 }
4888 self.write_space();
4889
4890 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
4892
4893 for (i, cte) in with.ctes.iter().enumerate() {
4894 if i > 0 {
4895 self.write(",");
4896 if self.config.pretty {
4897 self.write_space();
4898 } else {
4899 self.write(" ");
4900 }
4901 }
4902 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !cte.alias_first {
4903 self.generate_expression(&cte.this)?;
4904 self.write_space();
4905 self.write_keyword("AS");
4906 self.write_space();
4907 self.generate_identifier(&cte.alias)?;
4908 continue;
4909 }
4910 self.generate_identifier(&cte.alias)?;
4911 for comment in &cte.comments {
4913 self.write_space();
4914 self.write_formatted_comment(comment);
4915 }
4916 if !cte.columns.is_empty() && !skip_cte_columns {
4917 self.write("(");
4918 for (j, col) in cte.columns.iter().enumerate() {
4919 if j > 0 {
4920 self.write(", ");
4921 }
4922 self.generate_identifier(col)?;
4923 }
4924 self.write(")");
4925 }
4926 if !cte.key_expressions.is_empty() {
4928 self.write_space();
4929 self.write_keyword("USING KEY");
4930 self.write(" (");
4931 for (i, key) in cte.key_expressions.iter().enumerate() {
4932 if i > 0 {
4933 self.write(", ");
4934 }
4935 self.generate_identifier(key)?;
4936 }
4937 self.write(")");
4938 }
4939 self.write_space();
4940 self.write_keyword("AS");
4941 if let Some(materialized) = cte.materialized {
4943 self.write_space();
4944 if materialized {
4945 self.write_keyword("MATERIALIZED");
4946 } else {
4947 self.write_keyword("NOT MATERIALIZED");
4948 }
4949 }
4950 self.write(" (");
4951 if self.config.pretty {
4952 self.write_newline();
4953 self.indent_level += 1;
4954 self.write_indent();
4955 }
4956 let wrap_values_in_select = matches!(
4959 self.config.dialect,
4960 Some(DialectType::Spark) | Some(DialectType::Databricks)
4961 ) && matches!(&cte.this, Expression::Values(_));
4962
4963 if wrap_values_in_select {
4964 self.write_keyword("SELECT");
4965 self.write(" * ");
4966 self.write_keyword("FROM");
4967 self.write_space();
4968 }
4969 self.generate_expression(&cte.this)?;
4970 if self.config.pretty {
4971 self.write_newline();
4972 self.indent_level -= 1;
4973 self.write_indent();
4974 }
4975 self.write(")");
4976 }
4977
4978 if let Some(search) = &with.search {
4980 self.write_space();
4981 self.generate_expression(search)?;
4982 }
4983
4984 Ok(())
4985 }
4986
4987 fn generate_joins_with_nesting(&mut self, joins: &[Join]) -> Result<()> {
4991 let mut i = 0;
4992 while i < joins.len() {
4993 if joins[i].deferred_condition {
4994 let parent_group = joins[i].nesting_group;
4995
4996 self.generate_join_without_condition(&joins[i])?;
4999
5000 let child_start = i + 1;
5002 let mut child_end = child_start;
5003 while child_end < joins.len()
5004 && !joins[child_end].deferred_condition
5005 && joins[child_end].nesting_group == parent_group
5006 {
5007 child_end += 1;
5008 }
5009
5010 if child_start < child_end {
5012 self.indent_level += 1;
5013 for j in child_start..child_end {
5014 self.generate_join(&joins[j])?;
5015 }
5016 self.indent_level -= 1;
5017 }
5018
5019 self.generate_join_condition(&joins[i])?;
5021
5022 i = child_end;
5023 } else {
5024 self.generate_join(&joins[i])?;
5026 i += 1;
5027 }
5028 }
5029 Ok(())
5030 }
5031
5032 fn generate_join_without_condition(&mut self, join: &Join) -> Result<()> {
5035 let mut join_copy = join.clone();
5038 join_copy.on = None;
5039 join_copy.using = Vec::new();
5040 join_copy.deferred_condition = false;
5041 self.generate_join(&join_copy)
5042 }
5043
5044 fn generate_join(&mut self, join: &Join) -> Result<()> {
5045 if join.kind == JoinKind::Implicit {
5047 self.write(",");
5048 if self.config.pretty {
5049 self.write_newline();
5050 self.write_indent();
5051 } else {
5052 self.write_space();
5053 }
5054 self.generate_expression(&join.this)?;
5055 return Ok(());
5056 }
5057
5058 if self.config.pretty {
5059 self.write_newline();
5060 self.write_indent();
5061 } else {
5062 self.write_space();
5063 }
5064
5065 let hint_str = if self.config.join_hints {
5068 join.join_hint
5069 .as_ref()
5070 .map(|h| format!(" {}", h))
5071 .unwrap_or_default()
5072 } else {
5073 String::new()
5074 };
5075
5076 let clickhouse_join_keyword =
5077 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
5078 if let Some(hint) = &join.join_hint {
5079 let mut global = false;
5080 let mut strictness: Option<&'static str> = None;
5081 for part in hint.split_whitespace() {
5082 match part.to_uppercase().as_str() {
5083 "GLOBAL" => global = true,
5084 "ANY" => strictness = Some("ANY"),
5085 "ASOF" => strictness = Some("ASOF"),
5086 "SEMI" => strictness = Some("SEMI"),
5087 "ANTI" => strictness = Some("ANTI"),
5088 _ => {}
5089 }
5090 }
5091
5092 if global || strictness.is_some() {
5093 let join_type = match join.kind {
5094 JoinKind::Left => {
5095 if join.use_outer_keyword {
5096 "LEFT OUTER"
5097 } else if join.use_inner_keyword {
5098 "LEFT INNER"
5099 } else {
5100 "LEFT"
5101 }
5102 }
5103 JoinKind::Right => {
5104 if join.use_outer_keyword {
5105 "RIGHT OUTER"
5106 } else if join.use_inner_keyword {
5107 "RIGHT INNER"
5108 } else {
5109 "RIGHT"
5110 }
5111 }
5112 JoinKind::Full => {
5113 if join.use_outer_keyword {
5114 "FULL OUTER"
5115 } else {
5116 "FULL"
5117 }
5118 }
5119 JoinKind::Inner => {
5120 if join.use_inner_keyword {
5121 "INNER"
5122 } else {
5123 ""
5124 }
5125 }
5126 _ => "",
5127 };
5128
5129 let mut parts = Vec::new();
5130 if global {
5131 parts.push("GLOBAL");
5132 }
5133 if !join_type.is_empty() {
5134 parts.push(join_type);
5135 }
5136 if let Some(strict) = strictness {
5137 parts.push(strict);
5138 }
5139 parts.push("JOIN");
5140 Some(parts.join(" "))
5141 } else {
5142 None
5143 }
5144 } else {
5145 None
5146 }
5147 } else {
5148 None
5149 };
5150
5151 if !join.comments.is_empty() {
5155 if self.config.pretty {
5156 let trimmed = self.output.trim_end().len();
5161 self.output.truncate(trimmed);
5162 for comment in &join.comments {
5163 self.write_newline();
5164 self.write_indent();
5165 self.write_formatted_comment(comment);
5166 }
5167 self.write_newline();
5168 self.write_indent();
5169 } else {
5170 for comment in &join.comments {
5171 self.write_formatted_comment(comment);
5172 self.write_space();
5173 }
5174 }
5175 }
5176
5177 let directed_str = if join.directed { " DIRECTED" } else { "" };
5178
5179 if let Some(keyword) = clickhouse_join_keyword {
5180 self.write_keyword(&keyword);
5181 } else {
5182 match join.kind {
5183 JoinKind::Inner => {
5184 if join.use_inner_keyword {
5185 self.write_keyword(&format!("INNER{}{} JOIN", hint_str, directed_str));
5186 } else {
5187 self.write_keyword(&format!(
5188 "{}{}JOIN",
5189 if hint_str.is_empty() {
5190 String::new()
5191 } else {
5192 format!("{} ", hint_str.trim())
5193 },
5194 if directed_str.is_empty() {
5195 ""
5196 } else {
5197 "DIRECTED "
5198 }
5199 ));
5200 }
5201 }
5202 JoinKind::Left => {
5203 if join.use_outer_keyword {
5204 self.write_keyword(&format!("LEFT OUTER{}{} JOIN", hint_str, directed_str));
5205 } else if join.use_inner_keyword {
5206 self.write_keyword(&format!("LEFT INNER{}{} JOIN", hint_str, directed_str));
5207 } else {
5208 self.write_keyword(&format!("LEFT{}{} JOIN", hint_str, directed_str));
5209 }
5210 }
5211 JoinKind::Right => {
5212 if join.use_outer_keyword {
5213 self.write_keyword(&format!(
5214 "RIGHT OUTER{}{} JOIN",
5215 hint_str, directed_str
5216 ));
5217 } else if join.use_inner_keyword {
5218 self.write_keyword(&format!(
5219 "RIGHT INNER{}{} JOIN",
5220 hint_str, directed_str
5221 ));
5222 } else {
5223 self.write_keyword(&format!("RIGHT{}{} JOIN", hint_str, directed_str));
5224 }
5225 }
5226 JoinKind::Full => {
5227 if join.use_outer_keyword {
5228 self.write_keyword(&format!("FULL OUTER{}{} JOIN", hint_str, directed_str));
5229 } else {
5230 self.write_keyword(&format!("FULL{}{} JOIN", hint_str, directed_str));
5231 }
5232 }
5233 JoinKind::Outer => self.write_keyword(&format!("OUTER{} JOIN", directed_str)),
5234 JoinKind::Cross => self.write_keyword(&format!("CROSS{} JOIN", directed_str)),
5235 JoinKind::Natural => {
5236 if join.use_inner_keyword {
5237 self.write_keyword(&format!("NATURAL INNER{} JOIN", directed_str));
5238 } else {
5239 self.write_keyword(&format!("NATURAL{} JOIN", directed_str));
5240 }
5241 }
5242 JoinKind::NaturalLeft => {
5243 if join.use_outer_keyword {
5244 self.write_keyword(&format!("NATURAL LEFT OUTER{} JOIN", directed_str));
5245 } else {
5246 self.write_keyword(&format!("NATURAL LEFT{} JOIN", directed_str));
5247 }
5248 }
5249 JoinKind::NaturalRight => {
5250 if join.use_outer_keyword {
5251 self.write_keyword(&format!("NATURAL RIGHT OUTER{} JOIN", directed_str));
5252 } else {
5253 self.write_keyword(&format!("NATURAL RIGHT{} JOIN", directed_str));
5254 }
5255 }
5256 JoinKind::NaturalFull => {
5257 if join.use_outer_keyword {
5258 self.write_keyword(&format!("NATURAL FULL OUTER{} JOIN", directed_str));
5259 } else {
5260 self.write_keyword(&format!("NATURAL FULL{} JOIN", directed_str));
5261 }
5262 }
5263 JoinKind::Semi => self.write_keyword("SEMI JOIN"),
5264 JoinKind::Anti => self.write_keyword("ANTI JOIN"),
5265 JoinKind::LeftSemi => self.write_keyword("LEFT SEMI JOIN"),
5266 JoinKind::LeftAnti => self.write_keyword("LEFT ANTI JOIN"),
5267 JoinKind::RightSemi => self.write_keyword("RIGHT SEMI JOIN"),
5268 JoinKind::RightAnti => self.write_keyword("RIGHT ANTI JOIN"),
5269 JoinKind::CrossApply => {
5270 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
5272 self.write_keyword("CROSS APPLY");
5273 } else {
5274 self.write_keyword("INNER JOIN LATERAL");
5275 }
5276 }
5277 JoinKind::OuterApply => {
5278 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
5280 self.write_keyword("OUTER APPLY");
5281 } else {
5282 self.write_keyword("LEFT JOIN LATERAL");
5283 }
5284 }
5285 JoinKind::AsOf => self.write_keyword("ASOF JOIN"),
5286 JoinKind::AsOfLeft => {
5287 if join.use_outer_keyword {
5288 self.write_keyword("ASOF LEFT OUTER JOIN");
5289 } else {
5290 self.write_keyword("ASOF LEFT JOIN");
5291 }
5292 }
5293 JoinKind::AsOfRight => {
5294 if join.use_outer_keyword {
5295 self.write_keyword("ASOF RIGHT OUTER JOIN");
5296 } else {
5297 self.write_keyword("ASOF RIGHT JOIN");
5298 }
5299 }
5300 JoinKind::Lateral => self.write_keyword("LATERAL JOIN"),
5301 JoinKind::LeftLateral => {
5302 if join.use_outer_keyword {
5303 self.write_keyword("LEFT OUTER LATERAL JOIN");
5304 } else {
5305 self.write_keyword("LEFT LATERAL JOIN");
5306 }
5307 }
5308 JoinKind::Straight => self.write_keyword("STRAIGHT_JOIN"),
5309 JoinKind::Implicit => {
5310 use crate::dialects::DialectType;
5314 let is_cj_dialect = matches!(
5315 self.config.dialect,
5316 Some(DialectType::BigQuery)
5317 | Some(DialectType::Hive)
5318 | Some(DialectType::Spark)
5319 | Some(DialectType::Databricks)
5320 );
5321 let source_is_same = self.config.source_dialect.is_some()
5322 && self.config.source_dialect == self.config.dialect;
5323 let source_is_cj = matches!(
5324 self.config.source_dialect,
5325 Some(DialectType::BigQuery)
5326 | Some(DialectType::Hive)
5327 | Some(DialectType::Spark)
5328 | Some(DialectType::Databricks)
5329 );
5330 if is_cj_dialect
5331 && (source_is_same || source_is_cj || self.config.source_dialect.is_none())
5332 {
5333 self.write_keyword("CROSS JOIN");
5334 } else {
5335 self.output.truncate(self.output.trim_end().len());
5339 self.write(",");
5340 }
5341 }
5342 JoinKind::Array => self.write_keyword("ARRAY JOIN"),
5343 JoinKind::LeftArray => self.write_keyword("LEFT ARRAY JOIN"),
5344 JoinKind::Paste => self.write_keyword("PASTE JOIN"),
5345 }
5346 }
5347
5348 if matches!(join.kind, JoinKind::Array | JoinKind::LeftArray) {
5350 self.write_space();
5351 match &join.this {
5352 Expression::Tuple(t) => {
5353 for (i, item) in t.expressions.iter().enumerate() {
5354 if i > 0 {
5355 self.write(", ");
5356 }
5357 self.generate_expression(item)?;
5358 }
5359 }
5360 other => {
5361 self.generate_expression(other)?;
5362 }
5363 }
5364 } else {
5365 self.write_space();
5366 self.generate_expression(&join.this)?;
5367 }
5368
5369 if !join.deferred_condition {
5371 if let Some(match_cond) = &join.match_condition {
5373 self.write_space();
5374 self.write_keyword("MATCH_CONDITION");
5375 self.write(" (");
5376 self.generate_expression(match_cond)?;
5377 self.write(")");
5378 }
5379
5380 if let Some(on) = &join.on {
5381 if self.config.pretty {
5382 self.write_newline();
5383 self.indent_level += 1;
5384 self.write_indent();
5385 self.write_keyword("ON");
5386 self.write_space();
5387 self.generate_join_on_condition(on)?;
5388 self.indent_level -= 1;
5389 } else {
5390 self.write_space();
5391 self.write_keyword("ON");
5392 self.write_space();
5393 self.generate_expression(on)?;
5394 }
5395 }
5396
5397 if !join.using.is_empty() {
5398 if self.config.pretty {
5399 self.write_newline();
5400 self.indent_level += 1;
5401 self.write_indent();
5402 self.write_keyword("USING");
5403 self.write(" (");
5404 for (i, col) in join.using.iter().enumerate() {
5405 if i > 0 {
5406 self.write(", ");
5407 }
5408 self.generate_identifier(col)?;
5409 }
5410 self.write(")");
5411 self.indent_level -= 1;
5412 } else {
5413 self.write_space();
5414 self.write_keyword("USING");
5415 self.write(" (");
5416 for (i, col) in join.using.iter().enumerate() {
5417 if i > 0 {
5418 self.write(", ");
5419 }
5420 self.generate_identifier(col)?;
5421 }
5422 self.write(")");
5423 }
5424 }
5425 }
5426
5427 for pivot in &join.pivots {
5429 self.write_space();
5430 self.generate_expression(pivot)?;
5431 }
5432
5433 Ok(())
5434 }
5435
5436 fn generate_join_condition(&mut self, join: &Join) -> Result<()> {
5438 if let Some(match_cond) = &join.match_condition {
5440 self.write_space();
5441 self.write_keyword("MATCH_CONDITION");
5442 self.write(" (");
5443 self.generate_expression(match_cond)?;
5444 self.write(")");
5445 }
5446
5447 if let Some(on) = &join.on {
5448 if self.config.pretty {
5449 self.write_newline();
5450 self.indent_level += 1;
5451 self.write_indent();
5452 self.write_keyword("ON");
5453 self.write_space();
5454 self.generate_join_on_condition(on)?;
5456 self.indent_level -= 1;
5457 } else {
5458 self.write_space();
5459 self.write_keyword("ON");
5460 self.write_space();
5461 self.generate_expression(on)?;
5462 }
5463 }
5464
5465 if !join.using.is_empty() {
5466 if self.config.pretty {
5467 self.write_newline();
5468 self.indent_level += 1;
5469 self.write_indent();
5470 self.write_keyword("USING");
5471 self.write(" (");
5472 for (i, col) in join.using.iter().enumerate() {
5473 if i > 0 {
5474 self.write(", ");
5475 }
5476 self.generate_identifier(col)?;
5477 }
5478 self.write(")");
5479 self.indent_level -= 1;
5480 } else {
5481 self.write_space();
5482 self.write_keyword("USING");
5483 self.write(" (");
5484 for (i, col) in join.using.iter().enumerate() {
5485 if i > 0 {
5486 self.write(", ");
5487 }
5488 self.generate_identifier(col)?;
5489 }
5490 self.write(")");
5491 }
5492 }
5493
5494 for pivot in &join.pivots {
5496 self.write_space();
5497 self.generate_expression(pivot)?;
5498 }
5499
5500 Ok(())
5501 }
5502
5503 fn generate_join_on_condition(&mut self, expr: &Expression) -> Result<()> {
5505 if let Expression::And(and_op) = expr {
5506 if let Some(conditions) = self.flatten_connector_terms(and_op, ConnectorOperator::And) {
5507 self.generate_expression(conditions[0])?;
5508 for condition in conditions.iter().skip(1) {
5509 self.write_newline();
5510 self.write_indent();
5511 self.write_keyword("AND");
5512 self.write_space();
5513 self.generate_expression(condition)?;
5514 }
5515 return Ok(());
5516 }
5517 }
5518
5519 self.generate_expression(expr)
5520 }
5521
5522 fn generate_joined_table(&mut self, jt: &JoinedTable) -> Result<()> {
5523 self.write("(");
5525 self.generate_expression(&jt.left)?;
5526
5527 for join in &jt.joins {
5529 self.generate_join(join)?;
5530 }
5531
5532 for lv in &jt.lateral_views {
5534 self.generate_lateral_view(lv)?;
5535 }
5536
5537 self.write(")");
5538
5539 if let Some(alias) = &jt.alias {
5541 self.write_space();
5542 self.write_keyword("AS");
5543 self.write_space();
5544 self.generate_identifier(alias)?;
5545 }
5546
5547 Ok(())
5548 }
5549
5550 fn generate_lateral_view(&mut self, lv: &LateralView) -> Result<()> {
5551 use crate::dialects::DialectType;
5552
5553 if self.config.pretty {
5554 self.write_newline();
5555 self.write_indent();
5556 } else {
5557 self.write_space();
5558 }
5559
5560 let use_lateral_join = matches!(
5563 self.config.dialect,
5564 Some(DialectType::PostgreSQL)
5565 | Some(DialectType::DuckDB)
5566 | Some(DialectType::Snowflake)
5567 | Some(DialectType::TSQL)
5568 | Some(DialectType::Presto)
5569 | Some(DialectType::Trino)
5570 | Some(DialectType::Athena)
5571 );
5572
5573 let use_unnest = matches!(
5575 self.config.dialect,
5576 Some(DialectType::DuckDB)
5577 | Some(DialectType::Presto)
5578 | Some(DialectType::Trino)
5579 | Some(DialectType::Athena)
5580 );
5581
5582 let (is_posexplode, func_args) = match &lv.this {
5584 Expression::Explode(uf) => {
5585 (false, vec![uf.this.clone()])
5587 }
5588 Expression::Unnest(uf) => {
5589 let mut args = vec![uf.this.clone()];
5590 args.extend(uf.expressions.clone());
5591 (false, args)
5592 }
5593 Expression::Function(func) => {
5594 let name = func.name.to_uppercase();
5595 if name == "POSEXPLODE" || name == "POSEXPLODE_OUTER" {
5596 (true, func.args.clone())
5597 } else if name == "EXPLODE" || name == "EXPLODE_OUTER" || name == "INLINE" {
5598 (false, func.args.clone())
5599 } else {
5600 (false, vec![])
5601 }
5602 }
5603 _ => (false, vec![]),
5604 };
5605
5606 if use_lateral_join {
5607 if lv.outer {
5609 self.write_keyword("LEFT JOIN LATERAL");
5610 } else {
5611 self.write_keyword("CROSS JOIN");
5612 }
5613 self.write_space();
5614
5615 if use_unnest && !func_args.is_empty() {
5616 let unnest_args = if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
5619 func_args
5621 .iter()
5622 .map(|a| {
5623 if let Expression::Function(ref f) = a {
5624 if f.name.to_uppercase() == "ARRAY" && f.args.len() == 1 {
5625 return Expression::ArrayFunc(Box::new(
5626 crate::expressions::ArrayConstructor {
5627 expressions: f.args.clone(),
5628 bracket_notation: true,
5629 use_list_keyword: false,
5630 },
5631 ));
5632 }
5633 }
5634 a.clone()
5635 })
5636 .collect::<Vec<_>>()
5637 } else if matches!(
5638 self.config.dialect,
5639 Some(DialectType::Presto)
5640 | Some(DialectType::Trino)
5641 | Some(DialectType::Athena)
5642 ) {
5643 func_args
5645 .iter()
5646 .map(|a| {
5647 if let Expression::Function(ref f) = a {
5648 if f.name.to_uppercase() == "ARRAY" && f.args.len() >= 1 {
5649 return Expression::ArrayFunc(Box::new(
5650 crate::expressions::ArrayConstructor {
5651 expressions: f.args.clone(),
5652 bracket_notation: true,
5653 use_list_keyword: false,
5654 },
5655 ));
5656 }
5657 }
5658 a.clone()
5659 })
5660 .collect::<Vec<_>>()
5661 } else {
5662 func_args
5663 };
5664
5665 if is_posexplode {
5667 self.write_keyword("LATERAL");
5668 self.write(" (");
5669 self.write_keyword("SELECT");
5670 self.write_space();
5671
5672 let pos_alias = if !lv.column_aliases.is_empty() {
5675 lv.column_aliases[0].clone()
5676 } else {
5677 Identifier::new("pos")
5678 };
5679 let data_aliases: Vec<Identifier> = if lv.column_aliases.len() > 1 {
5680 lv.column_aliases[1..].to_vec()
5681 } else {
5682 vec![Identifier::new("col")]
5683 };
5684
5685 self.generate_identifier(&pos_alias)?;
5687 self.write(" - 1");
5688 self.write_space();
5689 self.write_keyword("AS");
5690 self.write_space();
5691 self.generate_identifier(&pos_alias)?;
5692
5693 for data_col in &data_aliases {
5695 self.write(", ");
5696 self.generate_identifier(data_col)?;
5697 }
5698
5699 self.write_space();
5700 self.write_keyword("FROM");
5701 self.write_space();
5702 self.write_keyword("UNNEST");
5703 self.write("(");
5704 for (i, arg) in unnest_args.iter().enumerate() {
5705 if i > 0 {
5706 self.write(", ");
5707 }
5708 self.generate_expression(arg)?;
5709 }
5710 self.write(")");
5711 self.write_space();
5712 self.write_keyword("WITH ORDINALITY");
5713 self.write_space();
5714 self.write_keyword("AS");
5715 self.write_space();
5716
5717 let table_alias_ident = lv
5719 .table_alias
5720 .clone()
5721 .unwrap_or_else(|| Identifier::new("t"));
5722 self.generate_identifier(&table_alias_ident)?;
5723 self.write("(");
5724 for (i, data_col) in data_aliases.iter().enumerate() {
5725 if i > 0 {
5726 self.write(", ");
5727 }
5728 self.generate_identifier(data_col)?;
5729 }
5730 self.write(", ");
5731 self.generate_identifier(&pos_alias)?;
5732 self.write("))");
5733 } else {
5734 self.write_keyword("UNNEST");
5735 self.write("(");
5736 for (i, arg) in unnest_args.iter().enumerate() {
5737 if i > 0 {
5738 self.write(", ");
5739 }
5740 self.generate_expression(arg)?;
5741 }
5742 self.write(")");
5743
5744 if let Some(alias) = &lv.table_alias {
5746 self.write_space();
5747 self.write_keyword("AS");
5748 self.write_space();
5749 self.generate_identifier(alias)?;
5750 if !lv.column_aliases.is_empty() {
5751 self.write("(");
5752 for (i, col) in lv.column_aliases.iter().enumerate() {
5753 if i > 0 {
5754 self.write(", ");
5755 }
5756 self.generate_identifier(col)?;
5757 }
5758 self.write(")");
5759 }
5760 } else if !lv.column_aliases.is_empty() {
5761 self.write_space();
5762 self.write_keyword("AS");
5763 self.write(" t(");
5764 for (i, col) in lv.column_aliases.iter().enumerate() {
5765 if i > 0 {
5766 self.write(", ");
5767 }
5768 self.generate_identifier(col)?;
5769 }
5770 self.write(")");
5771 }
5772 }
5773 } else {
5774 if !lv.outer {
5776 self.write_keyword("LATERAL");
5777 self.write_space();
5778 }
5779 self.generate_expression(&lv.this)?;
5780
5781 if let Some(alias) = &lv.table_alias {
5783 self.write_space();
5784 self.write_keyword("AS");
5785 self.write_space();
5786 self.generate_identifier(alias)?;
5787 if !lv.column_aliases.is_empty() {
5788 self.write("(");
5789 for (i, col) in lv.column_aliases.iter().enumerate() {
5790 if i > 0 {
5791 self.write(", ");
5792 }
5793 self.generate_identifier(col)?;
5794 }
5795 self.write(")");
5796 }
5797 } else if !lv.column_aliases.is_empty() {
5798 self.write_space();
5799 self.write_keyword("AS");
5800 self.write(" t(");
5801 for (i, col) in lv.column_aliases.iter().enumerate() {
5802 if i > 0 {
5803 self.write(", ");
5804 }
5805 self.generate_identifier(col)?;
5806 }
5807 self.write(")");
5808 }
5809 }
5810
5811 if lv.outer {
5813 self.write_space();
5814 self.write_keyword("ON TRUE");
5815 }
5816 } else {
5817 self.write_keyword("LATERAL VIEW");
5819 if lv.outer {
5820 self.write_space();
5821 self.write_keyword("OUTER");
5822 }
5823 if self.config.pretty {
5824 self.write_newline();
5825 self.write_indent();
5826 } else {
5827 self.write_space();
5828 }
5829 self.generate_expression(&lv.this)?;
5830
5831 if let Some(alias) = &lv.table_alias {
5833 self.write_space();
5834 self.generate_identifier(alias)?;
5835 }
5836
5837 if !lv.column_aliases.is_empty() {
5839 self.write_space();
5840 self.write_keyword("AS");
5841 self.write_space();
5842 for (i, col) in lv.column_aliases.iter().enumerate() {
5843 if i > 0 {
5844 self.write(", ");
5845 }
5846 self.generate_identifier(col)?;
5847 }
5848 }
5849 }
5850
5851 Ok(())
5852 }
5853
5854 fn generate_union(&mut self, union: &Union) -> Result<()> {
5855 if let Some(with) = &union.with {
5857 self.generate_with(with)?;
5858 self.write_space();
5859 }
5860 self.generate_expression(&union.left)?;
5861 if self.config.pretty {
5862 self.write_newline();
5863 self.write_indent();
5864 } else {
5865 self.write_space();
5866 }
5867
5868 if let Some(side) = &union.side {
5870 self.write_keyword(side);
5871 self.write_space();
5872 }
5873 if let Some(kind) = &union.kind {
5874 self.write_keyword(kind);
5875 self.write_space();
5876 }
5877
5878 self.write_keyword("UNION");
5879 if union.all {
5880 self.write_space();
5881 self.write_keyword("ALL");
5882 } else if union.distinct {
5883 self.write_space();
5884 self.write_keyword("DISTINCT");
5885 }
5886
5887 if union.corresponding || union.by_name {
5890 self.write_space();
5891 self.write_keyword("BY NAME");
5892 }
5893 if !union.on_columns.is_empty() {
5894 self.write_space();
5895 self.write_keyword("ON");
5896 self.write(" (");
5897 for (i, col) in union.on_columns.iter().enumerate() {
5898 if i > 0 {
5899 self.write(", ");
5900 }
5901 self.generate_expression(col)?;
5902 }
5903 self.write(")");
5904 }
5905
5906 if self.config.pretty {
5907 self.write_newline();
5908 self.write_indent();
5909 } else {
5910 self.write_space();
5911 }
5912 self.generate_expression(&union.right)?;
5913 if let Some(order_by) = &union.order_by {
5915 if self.config.pretty {
5916 self.write_newline();
5917 } else {
5918 self.write_space();
5919 }
5920 self.write_keyword("ORDER BY");
5921 self.write_space();
5922 for (i, ordered) in order_by.expressions.iter().enumerate() {
5923 if i > 0 {
5924 self.write(", ");
5925 }
5926 self.generate_ordered(ordered)?;
5927 }
5928 }
5929 if let Some(limit) = &union.limit {
5930 if self.config.pretty {
5931 self.write_newline();
5932 } else {
5933 self.write_space();
5934 }
5935 self.write_keyword("LIMIT");
5936 self.write_space();
5937 self.generate_expression(limit)?;
5938 }
5939 if let Some(offset) = &union.offset {
5940 if self.config.pretty {
5941 self.write_newline();
5942 } else {
5943 self.write_space();
5944 }
5945 self.write_keyword("OFFSET");
5946 self.write_space();
5947 self.generate_expression(offset)?;
5948 }
5949 if let Some(distribute_by) = &union.distribute_by {
5951 self.write_space();
5952 self.write_keyword("DISTRIBUTE BY");
5953 self.write_space();
5954 for (i, expr) in distribute_by.expressions.iter().enumerate() {
5955 if i > 0 {
5956 self.write(", ");
5957 }
5958 self.generate_expression(expr)?;
5959 }
5960 }
5961 if let Some(sort_by) = &union.sort_by {
5963 self.write_space();
5964 self.write_keyword("SORT BY");
5965 self.write_space();
5966 for (i, ord) in sort_by.expressions.iter().enumerate() {
5967 if i > 0 {
5968 self.write(", ");
5969 }
5970 self.generate_ordered(ord)?;
5971 }
5972 }
5973 if let Some(cluster_by) = &union.cluster_by {
5975 self.write_space();
5976 self.write_keyword("CLUSTER BY");
5977 self.write_space();
5978 for (i, ord) in cluster_by.expressions.iter().enumerate() {
5979 if i > 0 {
5980 self.write(", ");
5981 }
5982 self.generate_ordered(ord)?;
5983 }
5984 }
5985 Ok(())
5986 }
5987
5988 fn generate_intersect(&mut self, intersect: &Intersect) -> Result<()> {
5989 if let Some(with) = &intersect.with {
5991 self.generate_with(with)?;
5992 self.write_space();
5993 }
5994 self.generate_expression(&intersect.left)?;
5995 if self.config.pretty {
5996 self.write_newline();
5997 self.write_indent();
5998 } else {
5999 self.write_space();
6000 }
6001
6002 if let Some(side) = &intersect.side {
6004 self.write_keyword(side);
6005 self.write_space();
6006 }
6007 if let Some(kind) = &intersect.kind {
6008 self.write_keyword(kind);
6009 self.write_space();
6010 }
6011
6012 self.write_keyword("INTERSECT");
6013 if intersect.all {
6014 self.write_space();
6015 self.write_keyword("ALL");
6016 } else if intersect.distinct {
6017 self.write_space();
6018 self.write_keyword("DISTINCT");
6019 }
6020
6021 if intersect.corresponding || intersect.by_name {
6024 self.write_space();
6025 self.write_keyword("BY NAME");
6026 }
6027 if !intersect.on_columns.is_empty() {
6028 self.write_space();
6029 self.write_keyword("ON");
6030 self.write(" (");
6031 for (i, col) in intersect.on_columns.iter().enumerate() {
6032 if i > 0 {
6033 self.write(", ");
6034 }
6035 self.generate_expression(col)?;
6036 }
6037 self.write(")");
6038 }
6039
6040 if self.config.pretty {
6041 self.write_newline();
6042 self.write_indent();
6043 } else {
6044 self.write_space();
6045 }
6046 self.generate_expression(&intersect.right)?;
6047 if let Some(order_by) = &intersect.order_by {
6049 if self.config.pretty {
6050 self.write_newline();
6051 } else {
6052 self.write_space();
6053 }
6054 self.write_keyword("ORDER BY");
6055 self.write_space();
6056 for (i, ordered) in order_by.expressions.iter().enumerate() {
6057 if i > 0 {
6058 self.write(", ");
6059 }
6060 self.generate_ordered(ordered)?;
6061 }
6062 }
6063 if let Some(limit) = &intersect.limit {
6064 if self.config.pretty {
6065 self.write_newline();
6066 } else {
6067 self.write_space();
6068 }
6069 self.write_keyword("LIMIT");
6070 self.write_space();
6071 self.generate_expression(limit)?;
6072 }
6073 if let Some(offset) = &intersect.offset {
6074 if self.config.pretty {
6075 self.write_newline();
6076 } else {
6077 self.write_space();
6078 }
6079 self.write_keyword("OFFSET");
6080 self.write_space();
6081 self.generate_expression(offset)?;
6082 }
6083 if let Some(distribute_by) = &intersect.distribute_by {
6085 self.write_space();
6086 self.write_keyword("DISTRIBUTE BY");
6087 self.write_space();
6088 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6089 if i > 0 {
6090 self.write(", ");
6091 }
6092 self.generate_expression(expr)?;
6093 }
6094 }
6095 if let Some(sort_by) = &intersect.sort_by {
6097 self.write_space();
6098 self.write_keyword("SORT BY");
6099 self.write_space();
6100 for (i, ord) in sort_by.expressions.iter().enumerate() {
6101 if i > 0 {
6102 self.write(", ");
6103 }
6104 self.generate_ordered(ord)?;
6105 }
6106 }
6107 if let Some(cluster_by) = &intersect.cluster_by {
6109 self.write_space();
6110 self.write_keyword("CLUSTER BY");
6111 self.write_space();
6112 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6113 if i > 0 {
6114 self.write(", ");
6115 }
6116 self.generate_ordered(ord)?;
6117 }
6118 }
6119 Ok(())
6120 }
6121
6122 fn generate_except(&mut self, except: &Except) -> Result<()> {
6123 use crate::dialects::DialectType;
6124
6125 if let Some(with) = &except.with {
6127 self.generate_with(with)?;
6128 self.write_space();
6129 }
6130
6131 self.generate_expression(&except.left)?;
6132 if self.config.pretty {
6133 self.write_newline();
6134 self.write_indent();
6135 } else {
6136 self.write_space();
6137 }
6138
6139 if let Some(side) = &except.side {
6141 self.write_keyword(side);
6142 self.write_space();
6143 }
6144 if let Some(kind) = &except.kind {
6145 self.write_keyword(kind);
6146 self.write_space();
6147 }
6148
6149 match self.config.dialect {
6151 Some(DialectType::Oracle) if !except.all => {
6152 self.write_keyword("MINUS");
6153 }
6154 Some(DialectType::ClickHouse) => {
6155 self.write_keyword("EXCEPT");
6157 if except.distinct {
6158 self.write_space();
6159 self.write_keyword("DISTINCT");
6160 }
6161 }
6162 Some(DialectType::BigQuery) => {
6163 self.write_keyword("EXCEPT");
6165 if except.all {
6166 self.write_space();
6167 self.write_keyword("ALL");
6168 } else {
6169 self.write_space();
6170 self.write_keyword("DISTINCT");
6171 }
6172 }
6173 _ => {
6174 self.write_keyword("EXCEPT");
6175 if except.all {
6176 self.write_space();
6177 self.write_keyword("ALL");
6178 } else if except.distinct {
6179 self.write_space();
6180 self.write_keyword("DISTINCT");
6181 }
6182 }
6183 }
6184
6185 if except.corresponding || except.by_name {
6188 self.write_space();
6189 self.write_keyword("BY NAME");
6190 }
6191 if !except.on_columns.is_empty() {
6192 self.write_space();
6193 self.write_keyword("ON");
6194 self.write(" (");
6195 for (i, col) in except.on_columns.iter().enumerate() {
6196 if i > 0 {
6197 self.write(", ");
6198 }
6199 self.generate_expression(col)?;
6200 }
6201 self.write(")");
6202 }
6203
6204 if self.config.pretty {
6205 self.write_newline();
6206 self.write_indent();
6207 } else {
6208 self.write_space();
6209 }
6210 self.generate_expression(&except.right)?;
6211 if let Some(order_by) = &except.order_by {
6213 if self.config.pretty {
6214 self.write_newline();
6215 } else {
6216 self.write_space();
6217 }
6218 self.write_keyword("ORDER BY");
6219 self.write_space();
6220 for (i, ordered) in order_by.expressions.iter().enumerate() {
6221 if i > 0 {
6222 self.write(", ");
6223 }
6224 self.generate_ordered(ordered)?;
6225 }
6226 }
6227 if let Some(limit) = &except.limit {
6228 if self.config.pretty {
6229 self.write_newline();
6230 } else {
6231 self.write_space();
6232 }
6233 self.write_keyword("LIMIT");
6234 self.write_space();
6235 self.generate_expression(limit)?;
6236 }
6237 if let Some(offset) = &except.offset {
6238 if self.config.pretty {
6239 self.write_newline();
6240 } else {
6241 self.write_space();
6242 }
6243 self.write_keyword("OFFSET");
6244 self.write_space();
6245 self.generate_expression(offset)?;
6246 }
6247 if let Some(distribute_by) = &except.distribute_by {
6249 self.write_space();
6250 self.write_keyword("DISTRIBUTE BY");
6251 self.write_space();
6252 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6253 if i > 0 {
6254 self.write(", ");
6255 }
6256 self.generate_expression(expr)?;
6257 }
6258 }
6259 if let Some(sort_by) = &except.sort_by {
6261 self.write_space();
6262 self.write_keyword("SORT BY");
6263 self.write_space();
6264 for (i, ord) in sort_by.expressions.iter().enumerate() {
6265 if i > 0 {
6266 self.write(", ");
6267 }
6268 self.generate_ordered(ord)?;
6269 }
6270 }
6271 if let Some(cluster_by) = &except.cluster_by {
6273 self.write_space();
6274 self.write_keyword("CLUSTER BY");
6275 self.write_space();
6276 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6277 if i > 0 {
6278 self.write(", ");
6279 }
6280 self.generate_ordered(ord)?;
6281 }
6282 }
6283 Ok(())
6284 }
6285
6286 fn generate_insert(&mut self, insert: &Insert) -> Result<()> {
6287 let prepend_query_cte = if insert.with.is_none() {
6289 use crate::dialects::DialectType;
6290 let should_prepend = matches!(
6291 self.config.dialect,
6292 Some(DialectType::TSQL)
6293 | Some(DialectType::Fabric)
6294 | Some(DialectType::Spark)
6295 | Some(DialectType::Databricks)
6296 | Some(DialectType::Hive)
6297 );
6298 if should_prepend {
6299 if let Some(Expression::Select(select)) = &insert.query {
6300 select.with.clone()
6301 } else {
6302 None
6303 }
6304 } else {
6305 None
6306 }
6307 } else {
6308 None
6309 };
6310
6311 if let Some(with) = &insert.with {
6313 self.generate_with(with)?;
6314 self.write_space();
6315 } else if let Some(with) = &prepend_query_cte {
6316 self.generate_with(with)?;
6317 self.write_space();
6318 }
6319
6320 for comment in &insert.leading_comments {
6322 self.write_formatted_comment(comment);
6323 self.write(" ");
6324 }
6325
6326 if let Some(dir) = &insert.directory {
6328 self.write_keyword("INSERT OVERWRITE");
6329 if dir.local {
6330 self.write_space();
6331 self.write_keyword("LOCAL");
6332 }
6333 self.write_space();
6334 self.write_keyword("DIRECTORY");
6335 self.write_space();
6336 self.write("'");
6337 self.write(&dir.path);
6338 self.write("'");
6339
6340 if let Some(row_format) = &dir.row_format {
6342 self.write_space();
6343 self.write_keyword("ROW FORMAT");
6344 if row_format.delimited {
6345 self.write_space();
6346 self.write_keyword("DELIMITED");
6347 }
6348 if let Some(val) = &row_format.fields_terminated_by {
6349 self.write_space();
6350 self.write_keyword("FIELDS TERMINATED BY");
6351 self.write_space();
6352 self.write("'");
6353 self.write(val);
6354 self.write("'");
6355 }
6356 if let Some(val) = &row_format.collection_items_terminated_by {
6357 self.write_space();
6358 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
6359 self.write_space();
6360 self.write("'");
6361 self.write(val);
6362 self.write("'");
6363 }
6364 if let Some(val) = &row_format.map_keys_terminated_by {
6365 self.write_space();
6366 self.write_keyword("MAP KEYS TERMINATED BY");
6367 self.write_space();
6368 self.write("'");
6369 self.write(val);
6370 self.write("'");
6371 }
6372 if let Some(val) = &row_format.lines_terminated_by {
6373 self.write_space();
6374 self.write_keyword("LINES TERMINATED BY");
6375 self.write_space();
6376 self.write("'");
6377 self.write(val);
6378 self.write("'");
6379 }
6380 if let Some(val) = &row_format.null_defined_as {
6381 self.write_space();
6382 self.write_keyword("NULL DEFINED AS");
6383 self.write_space();
6384 self.write("'");
6385 self.write(val);
6386 self.write("'");
6387 }
6388 }
6389
6390 if let Some(format) = &dir.stored_as {
6392 self.write_space();
6393 self.write_keyword("STORED AS");
6394 self.write_space();
6395 self.write_keyword(format);
6396 }
6397
6398 if let Some(query) = &insert.query {
6400 self.write_space();
6401 self.generate_expression(query)?;
6402 }
6403
6404 return Ok(());
6405 }
6406
6407 if insert.is_replace {
6408 self.write_keyword("REPLACE INTO");
6410 } else if insert.overwrite {
6411 self.write_keyword("INSERT");
6413 if let Some(ref hint) = insert.hint {
6415 self.generate_hint(hint)?;
6416 }
6417 self.write(&self.config.insert_overwrite.to_uppercase());
6418 } else if let Some(ref action) = insert.conflict_action {
6419 self.write_keyword("INSERT OR");
6421 self.write_space();
6422 self.write_keyword(action);
6423 self.write_space();
6424 self.write_keyword("INTO");
6425 } else if insert.ignore {
6426 self.write_keyword("INSERT IGNORE INTO");
6428 } else {
6429 self.write_keyword("INSERT");
6430 if let Some(ref hint) = insert.hint {
6432 self.generate_hint(hint)?;
6433 }
6434 self.write_space();
6435 self.write_keyword("INTO");
6436 }
6437 if let Some(ref func) = insert.function_target {
6439 self.write_space();
6440 self.write_keyword("FUNCTION");
6441 self.write_space();
6442 self.generate_expression(func)?;
6443 } else {
6444 self.write_space();
6445 self.generate_table(&insert.table)?;
6446 }
6447
6448 if let Some(ref alias) = insert.alias {
6450 self.write_space();
6451 if insert.alias_explicit_as {
6452 self.write_keyword("AS");
6453 self.write_space();
6454 }
6455 self.generate_identifier(alias)?;
6456 }
6457
6458 if insert.if_exists {
6460 self.write_space();
6461 self.write_keyword("IF EXISTS");
6462 }
6463
6464 if let Some(ref replace_where) = insert.replace_where {
6466 if self.config.pretty {
6467 self.write_newline();
6468 self.write_indent();
6469 } else {
6470 self.write_space();
6471 }
6472 self.write_keyword("REPLACE WHERE");
6473 self.write_space();
6474 self.generate_expression(replace_where)?;
6475 }
6476
6477 if !insert.partition.is_empty() {
6479 self.write_space();
6480 self.write_keyword("PARTITION");
6481 self.write("(");
6482 for (i, (col, val)) in insert.partition.iter().enumerate() {
6483 if i > 0 {
6484 self.write(", ");
6485 }
6486 self.generate_identifier(col)?;
6487 if let Some(v) = val {
6488 self.write(" = ");
6489 self.generate_expression(v)?;
6490 }
6491 }
6492 self.write(")");
6493 }
6494
6495 if let Some(ref partition_by) = insert.partition_by {
6497 self.write_space();
6498 self.write_keyword("PARTITION BY");
6499 self.write_space();
6500 self.generate_expression(partition_by)?;
6501 }
6502
6503 if !insert.settings.is_empty() {
6505 self.write_space();
6506 self.write_keyword("SETTINGS");
6507 self.write_space();
6508 for (i, setting) in insert.settings.iter().enumerate() {
6509 if i > 0 {
6510 self.write(", ");
6511 }
6512 self.generate_expression(setting)?;
6513 }
6514 }
6515
6516 if !insert.columns.is_empty() {
6517 if insert.alias.is_some() && insert.alias_explicit_as {
6518 self.write("(");
6520 } else {
6521 self.write(" (");
6523 }
6524 for (i, col) in insert.columns.iter().enumerate() {
6525 if i > 0 {
6526 self.write(", ");
6527 }
6528 self.generate_identifier(col)?;
6529 }
6530 self.write(")");
6531 }
6532
6533 if let Some(ref output) = insert.output {
6535 self.generate_output_clause(output)?;
6536 }
6537
6538 if insert.by_name {
6540 self.write_space();
6541 self.write_keyword("BY NAME");
6542 }
6543
6544 if insert.default_values {
6545 self.write_space();
6546 self.write_keyword("DEFAULT VALUES");
6547 } else if let Some(query) = &insert.query {
6548 if self.config.pretty {
6549 self.write_newline();
6550 } else {
6551 self.write_space();
6552 }
6553 if prepend_query_cte.is_some() {
6555 if let Expression::Select(select) = query {
6556 let mut select_no_with = select.clone();
6557 select_no_with.with = None;
6558 self.generate_select(&select_no_with)?;
6559 } else {
6560 self.generate_expression(query)?;
6561 }
6562 } else {
6563 self.generate_expression(query)?;
6564 }
6565 } else if !insert.values.is_empty() {
6566 if self.config.pretty {
6567 self.write_newline();
6569 self.write_keyword("VALUES");
6570 self.write_newline();
6571 self.indent_level += 1;
6572 for (i, row) in insert.values.iter().enumerate() {
6573 if i > 0 {
6574 self.write(",");
6575 self.write_newline();
6576 }
6577 self.write_indent();
6578 self.write("(");
6579 for (j, val) in row.iter().enumerate() {
6580 if j > 0 {
6581 self.write(", ");
6582 }
6583 self.generate_expression(val)?;
6584 }
6585 self.write(")");
6586 }
6587 self.indent_level -= 1;
6588 } else {
6589 self.write_space();
6591 self.write_keyword("VALUES");
6592 for (i, row) in insert.values.iter().enumerate() {
6593 if i > 0 {
6594 self.write(",");
6595 }
6596 self.write(" (");
6597 for (j, val) in row.iter().enumerate() {
6598 if j > 0 {
6599 self.write(", ");
6600 }
6601 self.generate_expression(val)?;
6602 }
6603 self.write(")");
6604 }
6605 }
6606 }
6607
6608 if let Some(ref source) = insert.source {
6610 self.write_space();
6611 self.write_keyword("TABLE");
6612 self.write_space();
6613 self.generate_expression(source)?;
6614 }
6615
6616 if let Some(alias) = &insert.source_alias {
6618 self.write_space();
6619 self.write_keyword("AS");
6620 self.write_space();
6621 self.generate_identifier(alias)?;
6622 }
6623
6624 if let Some(on_conflict) = &insert.on_conflict {
6626 if !matches!(self.config.dialect, Some(DialectType::Materialize)) {
6627 self.write_space();
6628 self.generate_expression(on_conflict)?;
6629 }
6630 }
6631
6632 if !insert.returning.is_empty() {
6634 self.write_space();
6635 self.write_keyword("RETURNING");
6636 self.write_space();
6637 for (i, expr) in insert.returning.iter().enumerate() {
6638 if i > 0 {
6639 self.write(", ");
6640 }
6641 self.generate_expression(expr)?;
6642 }
6643 }
6644
6645 Ok(())
6646 }
6647
6648 fn generate_update(&mut self, update: &Update) -> Result<()> {
6649 for comment in &update.leading_comments {
6651 self.write_formatted_comment(comment);
6652 self.write(" ");
6653 }
6654
6655 if let Some(ref with) = update.with {
6657 self.generate_with(with)?;
6658 self.write_space();
6659 }
6660
6661 self.write_keyword("UPDATE");
6662 self.write_space();
6663 self.generate_table(&update.table)?;
6664
6665 let mysql_like_update_from = matches!(
6666 self.config.dialect,
6667 Some(DialectType::MySQL) | Some(DialectType::SingleStore)
6668 ) && update.from_clause.is_some();
6669
6670 let mut set_pairs = update.set.clone();
6671
6672 let mut pre_set_joins = update.table_joins.clone();
6674 if mysql_like_update_from {
6675 let target_name = update
6676 .table
6677 .alias
6678 .as_ref()
6679 .map(|a| a.name.clone())
6680 .unwrap_or_else(|| update.table.name.name.clone());
6681
6682 for (col, _) in &mut set_pairs {
6683 if !col.name.contains('.') {
6684 col.name = format!("{}.{}", target_name, col.name);
6685 }
6686 }
6687
6688 if let Some(from_clause) = &update.from_clause {
6689 for table_expr in &from_clause.expressions {
6690 pre_set_joins.push(crate::expressions::Join {
6691 this: table_expr.clone(),
6692 on: Some(Expression::Boolean(crate::expressions::BooleanLiteral {
6693 value: true,
6694 })),
6695 using: Vec::new(),
6696 kind: crate::expressions::JoinKind::Inner,
6697 use_inner_keyword: false,
6698 use_outer_keyword: false,
6699 deferred_condition: false,
6700 join_hint: None,
6701 match_condition: None,
6702 pivots: Vec::new(),
6703 comments: Vec::new(),
6704 nesting_group: 0,
6705 directed: false,
6706 });
6707 }
6708 }
6709 for join in &update.from_joins {
6710 let mut join = join.clone();
6711 if join.on.is_none() && join.using.is_empty() {
6712 join.on = Some(Expression::Boolean(crate::expressions::BooleanLiteral {
6713 value: true,
6714 }));
6715 }
6716 pre_set_joins.push(join);
6717 }
6718 }
6719
6720 for extra_table in &update.extra_tables {
6722 self.write(", ");
6723 self.generate_table(extra_table)?;
6724 }
6725
6726 for join in &pre_set_joins {
6728 self.generate_join(join)?;
6730 }
6731
6732 let teradata_from_before_set = matches!(self.config.dialect, Some(DialectType::Teradata));
6734 if teradata_from_before_set && !mysql_like_update_from {
6735 if let Some(ref from_clause) = update.from_clause {
6736 self.write_space();
6737 self.write_keyword("FROM");
6738 self.write_space();
6739 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
6740 if i > 0 {
6741 self.write(", ");
6742 }
6743 self.generate_expression(table_expr)?;
6744 }
6745 }
6746 for join in &update.from_joins {
6747 self.generate_join(join)?;
6748 }
6749 }
6750
6751 self.write_space();
6752 self.write_keyword("SET");
6753 self.write_space();
6754
6755 for (i, (col, val)) in set_pairs.iter().enumerate() {
6756 if i > 0 {
6757 self.write(", ");
6758 }
6759 self.generate_identifier(col)?;
6760 self.write(" = ");
6761 self.generate_expression(val)?;
6762 }
6763
6764 if let Some(ref output) = update.output {
6766 self.generate_output_clause(output)?;
6767 }
6768
6769 if !mysql_like_update_from && !teradata_from_before_set {
6771 if let Some(ref from_clause) = update.from_clause {
6772 self.write_space();
6773 self.write_keyword("FROM");
6774 self.write_space();
6775 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
6777 if i > 0 {
6778 self.write(", ");
6779 }
6780 self.generate_expression(table_expr)?;
6781 }
6782 }
6783 }
6784
6785 if !mysql_like_update_from && !teradata_from_before_set {
6786 for join in &update.from_joins {
6788 self.generate_join(join)?;
6789 }
6790 }
6791
6792 if let Some(where_clause) = &update.where_clause {
6793 self.write_space();
6794 self.write_keyword("WHERE");
6795 self.write_space();
6796 self.generate_expression(&where_clause.this)?;
6797 }
6798
6799 if !update.returning.is_empty() {
6801 self.write_space();
6802 self.write_keyword("RETURNING");
6803 self.write_space();
6804 for (i, expr) in update.returning.iter().enumerate() {
6805 if i > 0 {
6806 self.write(", ");
6807 }
6808 self.generate_expression(expr)?;
6809 }
6810 }
6811
6812 if let Some(ref order_by) = update.order_by {
6814 self.write_space();
6815 self.generate_order_by(order_by)?;
6816 }
6817
6818 if let Some(ref limit) = update.limit {
6820 self.write_space();
6821 self.write_keyword("LIMIT");
6822 self.write_space();
6823 self.generate_expression(limit)?;
6824 }
6825
6826 Ok(())
6827 }
6828
6829 fn generate_delete(&mut self, delete: &Delete) -> Result<()> {
6830 if let Some(with) = &delete.with {
6832 self.generate_with(with)?;
6833 self.write_space();
6834 }
6835
6836 for comment in &delete.leading_comments {
6838 self.write_formatted_comment(comment);
6839 self.write(" ");
6840 }
6841
6842 if !delete.tables.is_empty() && !delete.tables_from_using {
6844 self.write_keyword("DELETE");
6846 self.write_space();
6847 for (i, tbl) in delete.tables.iter().enumerate() {
6848 if i > 0 {
6849 self.write(", ");
6850 }
6851 self.generate_table(tbl)?;
6852 }
6853 if let Some(ref output) = delete.output {
6855 self.generate_output_clause(output)?;
6856 }
6857 self.write_space();
6858 self.write_keyword("FROM");
6859 self.write_space();
6860 self.generate_table(&delete.table)?;
6861 } else if !delete.tables.is_empty() && delete.tables_from_using {
6862 self.write_keyword("DELETE FROM");
6864 self.write_space();
6865 for (i, tbl) in delete.tables.iter().enumerate() {
6866 if i > 0 {
6867 self.write(", ");
6868 }
6869 self.generate_table(tbl)?;
6870 }
6871 } else if delete.no_from && matches!(self.config.dialect, Some(DialectType::BigQuery)) {
6872 self.write_keyword("DELETE");
6874 self.write_space();
6875 self.generate_table(&delete.table)?;
6876 } else {
6877 self.write_keyword("DELETE FROM");
6878 self.write_space();
6879 self.generate_table(&delete.table)?;
6880 }
6881
6882 if let Some(ref on_cluster) = delete.on_cluster {
6884 self.write_space();
6885 self.generate_on_cluster(on_cluster)?;
6886 }
6887
6888 if let Some(ref idx) = delete.force_index {
6890 self.write_space();
6891 self.write_keyword("FORCE INDEX");
6892 self.write(" (");
6893 self.write(idx);
6894 self.write(")");
6895 }
6896
6897 if let Some(ref alias) = delete.alias {
6899 self.write_space();
6900 if delete.alias_explicit_as
6901 || matches!(self.config.dialect, Some(DialectType::BigQuery))
6902 {
6903 self.write_keyword("AS");
6904 self.write_space();
6905 }
6906 self.generate_identifier(alias)?;
6907 }
6908
6909 if !delete.tables_from_using {
6911 for join in &delete.joins {
6912 self.generate_join(join)?;
6913 }
6914 }
6915
6916 if !delete.using.is_empty() {
6918 self.write_space();
6919 self.write_keyword("USING");
6920 for (i, table) in delete.using.iter().enumerate() {
6921 if i > 0 {
6922 self.write(",");
6923 }
6924 self.write_space();
6925 if !table.hints.is_empty() && table.name.is_empty() {
6927 self.generate_expression(&table.hints[0])?;
6929 if let Some(ref alias) = table.alias {
6930 self.write_space();
6931 if table.alias_explicit_as {
6932 self.write_keyword("AS");
6933 self.write_space();
6934 }
6935 self.generate_identifier(alias)?;
6936 if !table.column_aliases.is_empty() {
6937 self.write("(");
6938 for (j, col_alias) in table.column_aliases.iter().enumerate() {
6939 if j > 0 {
6940 self.write(", ");
6941 }
6942 self.generate_identifier(col_alias)?;
6943 }
6944 self.write(")");
6945 }
6946 }
6947 } else {
6948 self.generate_table(table)?;
6949 }
6950 }
6951 }
6952
6953 if delete.tables_from_using {
6955 for join in &delete.joins {
6956 self.generate_join(join)?;
6957 }
6958 }
6959
6960 let output_already_emitted =
6962 !delete.tables.is_empty() && !delete.tables_from_using && delete.output.is_some();
6963 if !output_already_emitted {
6964 if let Some(ref output) = delete.output {
6965 self.generate_output_clause(output)?;
6966 }
6967 }
6968
6969 if let Some(where_clause) = &delete.where_clause {
6970 self.write_space();
6971 self.write_keyword("WHERE");
6972 self.write_space();
6973 self.generate_expression(&where_clause.this)?;
6974 }
6975
6976 if let Some(ref order_by) = delete.order_by {
6978 self.write_space();
6979 self.generate_order_by(order_by)?;
6980 }
6981
6982 if let Some(ref limit) = delete.limit {
6984 self.write_space();
6985 self.write_keyword("LIMIT");
6986 self.write_space();
6987 self.generate_expression(limit)?;
6988 }
6989
6990 if !delete.returning.is_empty() {
6992 self.write_space();
6993 self.write_keyword("RETURNING");
6994 self.write_space();
6995 for (i, expr) in delete.returning.iter().enumerate() {
6996 if i > 0 {
6997 self.write(", ");
6998 }
6999 self.generate_expression(expr)?;
7000 }
7001 }
7002
7003 Ok(())
7004 }
7005
7006 fn generate_create_table(&mut self, ct: &CreateTable) -> Result<()> {
7009 let saved_athena_hive_context = self.athena_hive_context;
7013 let is_clickhouse = matches!(self.config.dialect, Some(DialectType::ClickHouse));
7014 if matches!(
7015 self.config.dialect,
7016 Some(crate::dialects::DialectType::Athena)
7017 ) {
7018 let is_external = ct
7022 .table_modifier
7023 .as_ref()
7024 .map(|m| m.eq_ignore_ascii_case("EXTERNAL"))
7025 .unwrap_or(false);
7026 let has_as_select = ct.as_select.is_some();
7027 self.athena_hive_context = is_external || !has_as_select;
7028 }
7029
7030 if matches!(
7032 self.config.dialect,
7033 Some(crate::dialects::DialectType::TSQL)
7034 ) {
7035 if let Some(ref query) = ct.as_select {
7036 if let Some(with_cte) = &ct.with_cte {
7038 self.generate_with(with_cte)?;
7039 self.write_space();
7040 }
7041
7042 self.write_keyword("SELECT");
7044 self.write(" * ");
7045 self.write_keyword("INTO");
7046 self.write_space();
7047
7048 if ct.temporary {
7050 self.write("#");
7051 }
7052 self.generate_table(&ct.name)?;
7053
7054 self.write_space();
7055 self.write_keyword("FROM");
7056 self.write(" (");
7057 let aliased_query = Self::add_column_aliases_to_query(query.clone());
7059 self.generate_expression(&aliased_query)?;
7060 self.write(") ");
7061 self.write_keyword("AS");
7062 self.write(" temp");
7063 return Ok(());
7064 }
7065 }
7066
7067 if let Some(with_cte) = &ct.with_cte {
7069 self.generate_with(with_cte)?;
7070 self.write_space();
7071 }
7072
7073 for comment in &ct.leading_comments {
7075 self.write_formatted_comment(comment);
7076 self.write(" ");
7077 }
7078 self.write_keyword("CREATE");
7079
7080 if ct.or_replace {
7081 self.write_space();
7082 self.write_keyword("OR REPLACE");
7083 }
7084
7085 if ct.temporary {
7086 self.write_space();
7087 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
7089 self.write_keyword("GLOBAL TEMPORARY");
7090 } else {
7091 self.write_keyword("TEMPORARY");
7092 }
7093 }
7094
7095 let is_dictionary = ct
7097 .table_modifier
7098 .as_ref()
7099 .map(|m| m.eq_ignore_ascii_case("DICTIONARY"))
7100 .unwrap_or(false);
7101 if let Some(ref modifier) = ct.table_modifier {
7102 let skip_transient = modifier.eq_ignore_ascii_case("TRANSIENT")
7104 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None);
7105 let is_teradata_modifier = modifier.eq_ignore_ascii_case("VOLATILE")
7107 || modifier.eq_ignore_ascii_case("SET")
7108 || modifier.eq_ignore_ascii_case("MULTISET")
7109 || modifier.to_uppercase().contains("VOLATILE")
7110 || modifier.to_uppercase().starts_with("SET ")
7111 || modifier.to_uppercase().starts_with("MULTISET ");
7112 let skip_teradata =
7113 is_teradata_modifier && !matches!(self.config.dialect, Some(DialectType::Teradata));
7114 if !skip_transient && !skip_teradata {
7115 self.write_space();
7116 self.write_keyword(modifier);
7117 }
7118 }
7119
7120 if !is_dictionary {
7121 self.write_space();
7122 self.write_keyword("TABLE");
7123 }
7124
7125 if ct.if_not_exists {
7126 self.write_space();
7127 self.write_keyword("IF NOT EXISTS");
7128 }
7129
7130 self.write_space();
7131 self.generate_table(&ct.name)?;
7132
7133 if let Some(ref on_cluster) = ct.on_cluster {
7135 self.write_space();
7136 self.generate_on_cluster(on_cluster)?;
7137 }
7138
7139 if matches!(
7141 self.config.dialect,
7142 Some(crate::dialects::DialectType::Teradata)
7143 ) && !ct.teradata_post_name_options.is_empty()
7144 {
7145 for opt in &ct.teradata_post_name_options {
7146 self.write(", ");
7147 self.write(opt);
7148 }
7149 }
7150
7151 if ct.copy_grants {
7153 self.write_space();
7154 self.write_keyword("COPY GRANTS");
7155 }
7156
7157 if let Some(ref using_template) = ct.using_template {
7159 self.write_space();
7160 self.write_keyword("USING TEMPLATE");
7161 self.write_space();
7162 self.generate_expression(using_template)?;
7163 return Ok(());
7164 }
7165
7166 if let Some(ref clone_source) = ct.clone_source {
7168 self.write_space();
7169 if ct.is_copy && self.config.supports_table_copy {
7170 self.write_keyword("COPY");
7172 } else if ct.shallow_clone {
7173 self.write_keyword("SHALLOW CLONE");
7174 } else {
7175 self.write_keyword("CLONE");
7176 }
7177 self.write_space();
7178 self.generate_table(clone_source)?;
7179 if let Some(ref at_clause) = ct.clone_at_clause {
7181 self.write_space();
7182 self.generate_expression(at_clause)?;
7183 }
7184 return Ok(());
7185 }
7186
7187 if let Some(ref partition_of) = ct.partition_of {
7191 self.write_space();
7192
7193 if let Expression::PartitionedOfProperty(ref pop) = partition_of {
7195 self.write_keyword("PARTITION OF");
7197 self.write_space();
7198 self.generate_expression(&pop.this)?;
7199
7200 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
7202 self.write(" (");
7203 let mut first = true;
7204 for col in &ct.columns {
7205 if !first {
7206 self.write(", ");
7207 }
7208 first = false;
7209 self.generate_column_def(col)?;
7210 }
7211 for constraint in &ct.constraints {
7212 if !first {
7213 self.write(", ");
7214 }
7215 first = false;
7216 self.generate_table_constraint(constraint)?;
7217 }
7218 self.write(")");
7219 }
7220
7221 if let Expression::PartitionBoundSpec(_) = pop.expression.as_ref() {
7223 self.write_space();
7224 self.write_keyword("FOR VALUES");
7225 self.write_space();
7226 self.generate_expression(&pop.expression)?;
7227 } else {
7228 self.write_space();
7229 self.write_keyword("DEFAULT");
7230 }
7231 } else {
7232 self.generate_expression(partition_of)?;
7234
7235 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
7237 self.write(" (");
7238 let mut first = true;
7239 for col in &ct.columns {
7240 if !first {
7241 self.write(", ");
7242 }
7243 first = false;
7244 self.generate_column_def(col)?;
7245 }
7246 for constraint in &ct.constraints {
7247 if !first {
7248 self.write(", ");
7249 }
7250 first = false;
7251 self.generate_table_constraint(constraint)?;
7252 }
7253 self.write(")");
7254 }
7255 }
7256
7257 for prop in &ct.properties {
7259 self.write_space();
7260 self.generate_expression(prop)?;
7261 }
7262
7263 return Ok(());
7264 }
7265
7266 self.sqlite_inline_pk_columns.clear();
7269 if matches!(
7270 self.config.dialect,
7271 Some(crate::dialects::DialectType::SQLite)
7272 ) {
7273 for constraint in &ct.constraints {
7274 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7275 if columns.len() == 1 && name.is_none() {
7277 let pk_col_name = columns[0].name.to_lowercase();
7278 if ct
7280 .columns
7281 .iter()
7282 .any(|c| c.name.name.to_lowercase() == pk_col_name)
7283 {
7284 self.sqlite_inline_pk_columns.insert(pk_col_name);
7285 }
7286 }
7287 }
7288 }
7289 }
7290
7291 if !ct.columns.is_empty() {
7293 if self.config.pretty {
7294 self.write(" (");
7296 self.write_newline();
7297 self.indent_level += 1;
7298 for (i, col) in ct.columns.iter().enumerate() {
7299 if i > 0 {
7300 self.write(",");
7301 self.write_newline();
7302 }
7303 self.write_indent();
7304 self.generate_column_def(col)?;
7305 }
7306 for constraint in &ct.constraints {
7308 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7310 if columns.len() == 1
7311 && name.is_none()
7312 && self
7313 .sqlite_inline_pk_columns
7314 .contains(&columns[0].name.to_lowercase())
7315 {
7316 continue;
7317 }
7318 }
7319 self.write(",");
7320 self.write_newline();
7321 self.write_indent();
7322 self.generate_table_constraint(constraint)?;
7323 }
7324 self.indent_level -= 1;
7325 self.write_newline();
7326 self.write(")");
7327 } else {
7328 self.write(" (");
7329 for (i, col) in ct.columns.iter().enumerate() {
7330 if i > 0 {
7331 self.write(", ");
7332 }
7333 self.generate_column_def(col)?;
7334 }
7335 let mut first_constraint = true;
7337 for constraint in &ct.constraints {
7338 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7340 if columns.len() == 1
7341 && name.is_none()
7342 && self
7343 .sqlite_inline_pk_columns
7344 .contains(&columns[0].name.to_lowercase())
7345 {
7346 continue;
7347 }
7348 }
7349 if first_constraint {
7350 self.write(", ");
7351 first_constraint = false;
7352 } else {
7353 self.write(", ");
7354 }
7355 self.generate_table_constraint(constraint)?;
7356 }
7357 self.write(")");
7358 }
7359 } else if !ct.constraints.is_empty() {
7360 let has_like_only = ct
7362 .constraints
7363 .iter()
7364 .all(|c| matches!(c, TableConstraint::Like { .. }));
7365 let has_tags_only = ct
7366 .constraints
7367 .iter()
7368 .all(|c| matches!(c, TableConstraint::Tags(_)));
7369 let is_pg_like = matches!(
7373 self.config.dialect,
7374 Some(crate::dialects::DialectType::PostgreSQL)
7375 | Some(crate::dialects::DialectType::CockroachDB)
7376 | Some(crate::dialects::DialectType::Materialize)
7377 | Some(crate::dialects::DialectType::RisingWave)
7378 | Some(crate::dialects::DialectType::Redshift)
7379 | Some(crate::dialects::DialectType::Presto)
7380 | Some(crate::dialects::DialectType::Trino)
7381 | Some(crate::dialects::DialectType::Athena)
7382 );
7383 let use_parens = if has_like_only {
7384 is_pg_like
7385 } else {
7386 !has_tags_only
7387 };
7388 if self.config.pretty && use_parens {
7389 self.write(" (");
7390 self.write_newline();
7391 self.indent_level += 1;
7392 for (i, constraint) in ct.constraints.iter().enumerate() {
7393 if i > 0 {
7394 self.write(",");
7395 self.write_newline();
7396 }
7397 self.write_indent();
7398 self.generate_table_constraint(constraint)?;
7399 }
7400 self.indent_level -= 1;
7401 self.write_newline();
7402 self.write(")");
7403 } else {
7404 if use_parens {
7405 self.write(" (");
7406 } else {
7407 self.write_space();
7408 }
7409 for (i, constraint) in ct.constraints.iter().enumerate() {
7410 if i > 0 {
7411 self.write(", ");
7412 }
7413 self.generate_table_constraint(constraint)?;
7414 }
7415 if use_parens {
7416 self.write(")");
7417 }
7418 }
7419 }
7420
7421 if let Some(ref on_prop) = ct.on_property {
7423 self.write(" ");
7424 self.write_keyword("ON");
7425 self.write(" ");
7426 self.generate_expression(&on_prop.this)?;
7427 }
7428
7429 if !is_clickhouse {
7432 for prop in &ct.properties {
7433 if let Expression::SchemaCommentProperty(_) = prop {
7434 if self.config.pretty {
7435 self.write_newline();
7436 } else {
7437 self.write_space();
7438 }
7439 self.generate_expression(prop)?;
7440 }
7441 }
7442 }
7443
7444 if !ct.with_properties.is_empty() {
7446 let is_snowflake_special_table = matches!(
7448 self.config.dialect,
7449 Some(crate::dialects::DialectType::Snowflake)
7450 ) && (ct.table_modifier.as_deref() == Some("ICEBERG")
7451 || ct.table_modifier.as_deref() == Some("DYNAMIC"));
7452 if is_snowflake_special_table {
7453 for (key, value) in &ct.with_properties {
7454 self.write_space();
7455 self.write(key);
7456 self.write("=");
7457 self.write(value);
7458 }
7459 } else if self.config.pretty {
7460 self.write_newline();
7461 self.write_keyword("WITH");
7462 self.write(" (");
7463 self.write_newline();
7464 self.indent_level += 1;
7465 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
7466 if i > 0 {
7467 self.write(",");
7468 self.write_newline();
7469 }
7470 self.write_indent();
7471 self.write(key);
7472 self.write("=");
7473 self.write(value);
7474 }
7475 self.indent_level -= 1;
7476 self.write_newline();
7477 self.write(")");
7478 } else {
7479 self.write_space();
7480 self.write_keyword("WITH");
7481 self.write(" (");
7482 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
7483 if i > 0 {
7484 self.write(", ");
7485 }
7486 self.write(key);
7487 self.write("=");
7488 self.write(value);
7489 }
7490 self.write(")");
7491 }
7492 }
7493
7494 let (pre_as_properties, post_as_properties): (Vec<&Expression>, Vec<&Expression>) =
7495 if is_clickhouse && ct.as_select.is_some() {
7496 let mut pre = Vec::new();
7497 let mut post = Vec::new();
7498 for prop in &ct.properties {
7499 if matches!(prop, Expression::SchemaCommentProperty(_)) {
7500 post.push(prop);
7501 } else {
7502 pre.push(prop);
7503 }
7504 }
7505 (pre, post)
7506 } else {
7507 (ct.properties.iter().collect(), Vec::new())
7508 };
7509
7510 for prop in pre_as_properties {
7512 if !is_clickhouse && matches!(prop, Expression::SchemaCommentProperty(_)) {
7514 continue;
7515 }
7516 if self.config.pretty {
7517 self.write_newline();
7518 } else {
7519 self.write_space();
7520 }
7521 if let Expression::Properties(props) = prop {
7525 let is_hive_dialect = matches!(
7526 self.config.dialect,
7527 Some(crate::dialects::DialectType::Hive)
7528 | Some(crate::dialects::DialectType::Spark)
7529 | Some(crate::dialects::DialectType::Databricks)
7530 | Some(crate::dialects::DialectType::Athena)
7531 );
7532 let is_doris_starrocks = matches!(
7533 self.config.dialect,
7534 Some(crate::dialects::DialectType::Doris)
7535 | Some(crate::dialects::DialectType::StarRocks)
7536 );
7537 if is_hive_dialect {
7538 self.generate_tblproperties_clause(&props.expressions)?;
7539 } else if is_doris_starrocks {
7540 self.generate_properties_clause(&props.expressions)?;
7541 } else {
7542 self.generate_options_clause(&props.expressions)?;
7543 }
7544 } else {
7545 self.generate_expression(prop)?;
7546 }
7547 }
7548
7549 for prop in &ct.post_table_properties {
7551 if let Expression::WithSystemVersioningProperty(ref svp) = prop {
7552 self.write(" WITH(");
7553 self.generate_system_versioning_content(svp)?;
7554 self.write(")");
7555 } else if let Expression::Properties(props) = prop {
7556 let is_doris_starrocks = matches!(
7558 self.config.dialect,
7559 Some(crate::dialects::DialectType::Doris)
7560 | Some(crate::dialects::DialectType::StarRocks)
7561 );
7562 self.write_space();
7563 if is_doris_starrocks {
7564 self.generate_properties_clause(&props.expressions)?;
7565 } else {
7566 self.generate_options_clause(&props.expressions)?;
7567 }
7568 } else {
7569 self.write_space();
7570 self.generate_expression(prop)?;
7571 }
7572 }
7573
7574 if let Some(ref rollup) = ct.rollup {
7577 if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
7578 self.write_space();
7579 self.generate_rollup_property(rollup)?;
7580 }
7581 }
7582
7583 let is_mysql_compatible = matches!(
7587 self.config.dialect,
7588 Some(DialectType::MySQL)
7589 | Some(DialectType::SingleStore)
7590 | Some(DialectType::Doris)
7591 | Some(DialectType::StarRocks)
7592 | None
7593 );
7594 let is_hive_compatible = matches!(
7595 self.config.dialect,
7596 Some(DialectType::Hive)
7597 | Some(DialectType::Spark)
7598 | Some(DialectType::Databricks)
7599 | Some(DialectType::Athena)
7600 );
7601 let mysql_pretty_options =
7602 self.config.pretty && matches!(self.config.dialect, Some(DialectType::MySQL));
7603 for (key, value) in &ct.mysql_table_options {
7604 let should_output = if is_mysql_compatible {
7606 true
7607 } else if is_hive_compatible && key == "COMMENT" {
7608 true } else {
7610 false
7611 };
7612 if should_output {
7613 if mysql_pretty_options {
7614 self.write_newline();
7615 self.write_indent();
7616 } else {
7617 self.write_space();
7618 }
7619 self.write_keyword(key);
7620 if key == "COMMENT" && !self.config.schema_comment_with_eq {
7622 self.write_space();
7623 } else {
7624 self.write("=");
7625 }
7626 self.write(value);
7627 }
7628 }
7629
7630 if ct.temporary
7632 && matches!(
7633 self.config.dialect,
7634 Some(DialectType::Spark) | Some(DialectType::Databricks)
7635 )
7636 && ct.as_select.is_none()
7637 {
7638 self.write_space();
7639 self.write_keyword("USING PARQUET");
7640 }
7641
7642 if !ct.inherits.is_empty() {
7644 self.write_space();
7645 self.write_keyword("INHERITS");
7646 self.write(" (");
7647 for (i, parent) in ct.inherits.iter().enumerate() {
7648 if i > 0 {
7649 self.write(", ");
7650 }
7651 self.generate_table(parent)?;
7652 }
7653 self.write(")");
7654 }
7655
7656 if let Some(ref query) = ct.as_select {
7658 self.write_space();
7659 self.write_keyword("AS");
7660 self.write_space();
7661 if ct.as_select_parenthesized {
7662 self.write("(");
7663 }
7664 self.generate_expression(query)?;
7665 if ct.as_select_parenthesized {
7666 self.write(")");
7667 }
7668
7669 if let Some(with_data) = ct.with_data {
7671 self.write_space();
7672 self.write_keyword("WITH");
7673 if !with_data {
7674 self.write_space();
7675 self.write_keyword("NO");
7676 }
7677 self.write_space();
7678 self.write_keyword("DATA");
7679 }
7680
7681 if let Some(with_statistics) = ct.with_statistics {
7683 self.write_space();
7684 self.write_keyword("AND");
7685 if !with_statistics {
7686 self.write_space();
7687 self.write_keyword("NO");
7688 }
7689 self.write_space();
7690 self.write_keyword("STATISTICS");
7691 }
7692
7693 for index in &ct.teradata_indexes {
7695 self.write_space();
7696 match index.kind {
7697 TeradataIndexKind::NoPrimary => {
7698 self.write_keyword("NO PRIMARY INDEX");
7699 }
7700 TeradataIndexKind::Primary => {
7701 self.write_keyword("PRIMARY INDEX");
7702 }
7703 TeradataIndexKind::PrimaryAmp => {
7704 self.write_keyword("PRIMARY AMP INDEX");
7705 }
7706 TeradataIndexKind::Unique => {
7707 self.write_keyword("UNIQUE INDEX");
7708 }
7709 TeradataIndexKind::UniquePrimary => {
7710 self.write_keyword("UNIQUE PRIMARY INDEX");
7711 }
7712 TeradataIndexKind::Secondary => {
7713 self.write_keyword("INDEX");
7714 }
7715 }
7716 if let Some(ref name) = index.name {
7718 self.write_space();
7719 self.write(name);
7720 }
7721 if !index.columns.is_empty() {
7723 self.write(" (");
7724 for (i, col) in index.columns.iter().enumerate() {
7725 if i > 0 {
7726 self.write(", ");
7727 }
7728 self.write(col);
7729 }
7730 self.write(")");
7731 }
7732 }
7733
7734 if let Some(ref on_commit) = ct.on_commit {
7736 self.write_space();
7737 self.write_keyword("ON COMMIT");
7738 self.write_space();
7739 match on_commit {
7740 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
7741 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
7742 }
7743 }
7744
7745 if !post_as_properties.is_empty() {
7746 for prop in post_as_properties {
7747 self.write_space();
7748 self.generate_expression(prop)?;
7749 }
7750 }
7751
7752 self.athena_hive_context = saved_athena_hive_context;
7754 return Ok(());
7755 }
7756
7757 if let Some(ref on_commit) = ct.on_commit {
7759 self.write_space();
7760 self.write_keyword("ON COMMIT");
7761 self.write_space();
7762 match on_commit {
7763 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
7764 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
7765 }
7766 }
7767
7768 self.athena_hive_context = saved_athena_hive_context;
7770
7771 Ok(())
7772 }
7773
7774 fn generate_column_def_expr(&mut self, col: &ColumnDef) -> Result<()> {
7777 self.generate_identifier(&col.name)?;
7779 if !matches!(col.data_type, DataType::Unknown) {
7781 self.write_space();
7782 self.generate_data_type(&col.data_type)?;
7783 }
7784 for constraint in &col.constraints {
7786 if let ColumnConstraint::Path(path_expr) = constraint {
7787 self.write_space();
7788 self.write_keyword("PATH");
7789 self.write_space();
7790 self.generate_expression(path_expr)?;
7791 }
7792 }
7793 Ok(())
7794 }
7795
7796 fn generate_column_def(&mut self, col: &ColumnDef) -> Result<()> {
7797 let has_computed_no_type = matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
7799 && col
7800 .constraints
7801 .iter()
7802 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
7803 let omit_computed_type = !self.config.computed_column_with_type
7805 && col
7806 .constraints
7807 .iter()
7808 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
7809
7810 let is_partition_column_spec = matches!(col.data_type, DataType::Unknown);
7813
7814 let has_no_type = col.no_type
7817 || (matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
7818 && col.constraints.is_empty());
7819
7820 self.generate_identifier(&col.name)?;
7821
7822 let serial_expansion = if matches!(
7824 self.config.dialect,
7825 Some(DialectType::Materialize) | Some(DialectType::PostgreSQL)
7826 ) {
7827 if let DataType::Custom { ref name } = col.data_type {
7828 match name.to_uppercase().as_str() {
7829 "SERIAL" => Some("INT"),
7830 "BIGSERIAL" => Some("BIGINT"),
7831 "SMALLSERIAL" => Some("SMALLINT"),
7832 _ => None,
7833 }
7834 } else {
7835 None
7836 }
7837 } else {
7838 None
7839 };
7840
7841 if !has_computed_no_type && !omit_computed_type && !is_partition_column_spec && !has_no_type
7842 {
7843 self.write_space();
7844 let saved_nullable_depth = self.clickhouse_nullable_depth;
7847 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
7848 self.clickhouse_nullable_depth = -1;
7849 }
7850 if let Some(int_type) = serial_expansion {
7851 self.write_keyword(int_type);
7853 } else if col.unsigned && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
7854 let unsigned_type = match &col.data_type {
7856 DataType::Int { .. } => Some("UINTEGER"),
7857 DataType::BigInt { .. } => Some("UBIGINT"),
7858 DataType::SmallInt { .. } => Some("USMALLINT"),
7859 DataType::TinyInt { .. } => Some("UTINYINT"),
7860 _ => None,
7861 };
7862 if let Some(utype) = unsigned_type {
7863 self.write_keyword(utype);
7864 } else {
7865 self.generate_data_type(&col.data_type)?;
7866 }
7867 } else {
7868 self.generate_data_type(&col.data_type)?;
7869 }
7870 self.clickhouse_nullable_depth = saved_nullable_depth;
7871 }
7872
7873 if col.unsigned && !matches!(self.config.dialect, Some(DialectType::DuckDB)) {
7876 self.write_space();
7877 self.write_keyword("UNSIGNED");
7878 }
7879 if col.zerofill {
7880 self.write_space();
7881 self.write_keyword("ZEROFILL");
7882 }
7883
7884 if let Some(ref charset) = col.character_set {
7888 self.write_space();
7889 self.write_keyword("CHARACTER SET");
7890 self.write_space();
7891 self.write(charset);
7892 }
7893
7894 if col.uppercase {
7895 self.write_space();
7896 self.write_keyword("UPPERCASE");
7897 }
7898
7899 if let Some(casespecific) = col.casespecific {
7900 self.write_space();
7901 if casespecific {
7902 self.write_keyword("CASESPECIFIC");
7903 } else {
7904 self.write_keyword("NOT CASESPECIFIC");
7905 }
7906 }
7907
7908 if let Some(ref format) = col.format {
7909 self.write_space();
7910 self.write_keyword("FORMAT");
7911 self.write(" '");
7912 self.write(format);
7913 self.write("'");
7914 }
7915
7916 if let Some(ref title) = col.title {
7917 self.write_space();
7918 self.write_keyword("TITLE");
7919 self.write(" '");
7920 self.write(title);
7921 self.write("'");
7922 }
7923
7924 if let Some(length) = col.inline_length {
7925 self.write_space();
7926 self.write_keyword("INLINE LENGTH");
7927 self.write(" ");
7928 self.write(&length.to_string());
7929 }
7930
7931 if let Some(ref compress) = col.compress {
7932 self.write_space();
7933 self.write_keyword("COMPRESS");
7934 if !compress.is_empty() {
7935 if compress.len() == 1 {
7937 if let Expression::Literal(Literal::String(_)) = &compress[0] {
7938 self.write_space();
7939 self.generate_expression(&compress[0])?;
7940 } else {
7941 self.write(" (");
7942 self.generate_expression(&compress[0])?;
7943 self.write(")");
7944 }
7945 } else {
7946 self.write(" (");
7947 for (i, val) in compress.iter().enumerate() {
7948 if i > 0 {
7949 self.write(", ");
7950 }
7951 self.generate_expression(val)?;
7952 }
7953 self.write(")");
7954 }
7955 }
7956 }
7957
7958 if !col.constraint_order.is_empty() {
7961 let mut references_idx = 0;
7964 let mut check_idx = 0;
7965 let mut generated_idx = 0;
7966 let mut collate_idx = 0;
7967 let mut comment_idx = 0;
7968 let defer_not_null_after_identity = false;
7971 let mut pending_not_null_after_identity = false;
7972
7973 for constraint_type in &col.constraint_order {
7974 match constraint_type {
7975 ConstraintType::PrimaryKey => {
7976 if col.primary_key
7978 && !matches!(self.config.dialect, Some(DialectType::Materialize))
7979 {
7980 if let Some(ref cname) = col.primary_key_constraint_name {
7981 self.write_space();
7982 self.write_keyword("CONSTRAINT");
7983 self.write_space();
7984 self.write(cname);
7985 }
7986 self.write_space();
7987 self.write_keyword("PRIMARY KEY");
7988 if let Some(ref order) = col.primary_key_order {
7989 self.write_space();
7990 match order {
7991 SortOrder::Asc => self.write_keyword("ASC"),
7992 SortOrder::Desc => self.write_keyword("DESC"),
7993 }
7994 }
7995 }
7996 }
7997 ConstraintType::Unique => {
7998 if col.unique {
7999 if let Some(ref cname) = col.unique_constraint_name {
8000 self.write_space();
8001 self.write_keyword("CONSTRAINT");
8002 self.write_space();
8003 self.write(cname);
8004 }
8005 self.write_space();
8006 self.write_keyword("UNIQUE");
8007 if col.unique_nulls_not_distinct {
8009 self.write(" NULLS NOT DISTINCT");
8010 }
8011 }
8012 }
8013 ConstraintType::NotNull => {
8014 if col.nullable == Some(false) {
8015 if defer_not_null_after_identity {
8016 pending_not_null_after_identity = true;
8017 continue;
8018 }
8019 if let Some(ref cname) = col.not_null_constraint_name {
8020 self.write_space();
8021 self.write_keyword("CONSTRAINT");
8022 self.write_space();
8023 self.write(cname);
8024 }
8025 self.write_space();
8026 self.write_keyword("NOT NULL");
8027 }
8028 }
8029 ConstraintType::Null => {
8030 if col.nullable == Some(true) {
8031 self.write_space();
8032 self.write_keyword("NULL");
8033 }
8034 }
8035 ConstraintType::Default => {
8036 if let Some(ref default) = col.default {
8037 self.write_space();
8038 self.write_keyword("DEFAULT");
8039 self.write_space();
8040 self.generate_expression(default)?;
8041 }
8042 }
8043 ConstraintType::AutoIncrement => {
8044 if col.auto_increment {
8045 if matches!(
8047 self.config.dialect,
8048 Some(crate::dialects::DialectType::DuckDB)
8049 ) {
8050 } else if matches!(
8052 self.config.dialect,
8053 Some(crate::dialects::DialectType::Materialize)
8054 ) {
8055 if !matches!(col.nullable, Some(false)) {
8057 self.write_space();
8058 self.write_keyword("NOT NULL");
8059 }
8060 } else if matches!(
8061 self.config.dialect,
8062 Some(crate::dialects::DialectType::PostgreSQL)
8063 ) {
8064 self.write_space();
8066 self.generate_auto_increment_keyword(col)?;
8067 } else {
8068 self.write_space();
8069 self.generate_auto_increment_keyword(col)?;
8070 if pending_not_null_after_identity {
8071 self.write_space();
8072 self.write_keyword("NOT NULL");
8073 pending_not_null_after_identity = false;
8074 }
8075 }
8076 } }
8078 ConstraintType::References => {
8079 while references_idx < col.constraints.len() {
8081 if let ColumnConstraint::References(fk_ref) =
8082 &col.constraints[references_idx]
8083 {
8084 if let Some(ref name) = fk_ref.constraint_name {
8086 self.write_space();
8087 self.write_keyword("CONSTRAINT");
8088 self.write_space();
8089 self.write(name);
8090 }
8091 self.write_space();
8092 if fk_ref.has_foreign_key_keywords {
8093 self.write_keyword("FOREIGN KEY");
8094 self.write_space();
8095 }
8096 self.write_keyword("REFERENCES");
8097 self.write_space();
8098 self.generate_table(&fk_ref.table)?;
8099 if !fk_ref.columns.is_empty() {
8100 self.write(" (");
8101 for (i, c) in fk_ref.columns.iter().enumerate() {
8102 if i > 0 {
8103 self.write(", ");
8104 }
8105 self.generate_identifier(c)?;
8106 }
8107 self.write(")");
8108 }
8109 self.generate_referential_actions(fk_ref)?;
8110 references_idx += 1;
8111 break;
8112 }
8113 references_idx += 1;
8114 }
8115 }
8116 ConstraintType::Check => {
8117 while check_idx < col.constraints.len() {
8119 if let ColumnConstraint::Check(expr) = &col.constraints[check_idx] {
8120 if check_idx == 0 {
8122 if let Some(ref cname) = col.check_constraint_name {
8123 self.write_space();
8124 self.write_keyword("CONSTRAINT");
8125 self.write_space();
8126 self.write(cname);
8127 }
8128 }
8129 self.write_space();
8130 self.write_keyword("CHECK");
8131 self.write(" (");
8132 self.generate_expression(expr)?;
8133 self.write(")");
8134 check_idx += 1;
8135 break;
8136 }
8137 check_idx += 1;
8138 }
8139 }
8140 ConstraintType::GeneratedAsIdentity => {
8141 while generated_idx < col.constraints.len() {
8143 if let ColumnConstraint::GeneratedAsIdentity(gen) =
8144 &col.constraints[generated_idx]
8145 {
8146 self.write_space();
8147 if matches!(
8149 self.config.dialect,
8150 Some(crate::dialects::DialectType::Redshift)
8151 ) {
8152 self.write_keyword("IDENTITY");
8153 self.write("(");
8154 if let Some(ref start) = gen.start {
8155 self.generate_expression(start)?;
8156 } else {
8157 self.write("0");
8158 }
8159 self.write(", ");
8160 if let Some(ref incr) = gen.increment {
8161 self.generate_expression(incr)?;
8162 } else {
8163 self.write("1");
8164 }
8165 self.write(")");
8166 } else {
8167 self.write_keyword("GENERATED");
8168 if gen.always {
8169 self.write_space();
8170 self.write_keyword("ALWAYS");
8171 } else {
8172 self.write_space();
8173 self.write_keyword("BY DEFAULT");
8174 if gen.on_null {
8175 self.write_space();
8176 self.write_keyword("ON NULL");
8177 }
8178 }
8179 self.write_space();
8180 self.write_keyword("AS IDENTITY");
8181
8182 let has_options = gen.start.is_some()
8183 || gen.increment.is_some()
8184 || gen.minvalue.is_some()
8185 || gen.maxvalue.is_some()
8186 || gen.cycle.is_some();
8187 if has_options {
8188 self.write(" (");
8189 let mut first = true;
8190 if let Some(ref start) = gen.start {
8191 if !first {
8192 self.write(" ");
8193 }
8194 first = false;
8195 self.write_keyword("START WITH");
8196 self.write_space();
8197 self.generate_expression(start)?;
8198 }
8199 if let Some(ref incr) = gen.increment {
8200 if !first {
8201 self.write(" ");
8202 }
8203 first = false;
8204 self.write_keyword("INCREMENT BY");
8205 self.write_space();
8206 self.generate_expression(incr)?;
8207 }
8208 if let Some(ref minv) = gen.minvalue {
8209 if !first {
8210 self.write(" ");
8211 }
8212 first = false;
8213 self.write_keyword("MINVALUE");
8214 self.write_space();
8215 self.generate_expression(minv)?;
8216 }
8217 if let Some(ref maxv) = gen.maxvalue {
8218 if !first {
8219 self.write(" ");
8220 }
8221 first = false;
8222 self.write_keyword("MAXVALUE");
8223 self.write_space();
8224 self.generate_expression(maxv)?;
8225 }
8226 if let Some(cycle) = gen.cycle {
8227 if !first {
8228 self.write(" ");
8229 }
8230 if cycle {
8231 self.write_keyword("CYCLE");
8232 } else {
8233 self.write_keyword("NO CYCLE");
8234 }
8235 }
8236 self.write(")");
8237 }
8238 }
8239 generated_idx += 1;
8240 break;
8241 }
8242 generated_idx += 1;
8243 }
8244 }
8245 ConstraintType::Collate => {
8246 while collate_idx < col.constraints.len() {
8248 if let ColumnConstraint::Collate(collation) =
8249 &col.constraints[collate_idx]
8250 {
8251 self.write_space();
8252 self.write_keyword("COLLATE");
8253 self.write_space();
8254 self.generate_identifier(collation)?;
8255 collate_idx += 1;
8256 break;
8257 }
8258 collate_idx += 1;
8259 }
8260 }
8261 ConstraintType::Comment => {
8262 while comment_idx < col.constraints.len() {
8264 if let ColumnConstraint::Comment(comment) =
8265 &col.constraints[comment_idx]
8266 {
8267 self.write_space();
8268 self.write_keyword("COMMENT");
8269 self.write_space();
8270 self.generate_string_literal(comment)?;
8271 comment_idx += 1;
8272 break;
8273 }
8274 comment_idx += 1;
8275 }
8276 }
8277 ConstraintType::Tags => {
8278 for constraint in &col.constraints {
8280 if let ColumnConstraint::Tags(tags) = constraint {
8281 self.write_space();
8282 self.write_keyword("TAG");
8283 self.write(" (");
8284 for (i, expr) in tags.expressions.iter().enumerate() {
8285 if i > 0 {
8286 self.write(", ");
8287 }
8288 self.generate_expression(expr)?;
8289 }
8290 self.write(")");
8291 break;
8292 }
8293 }
8294 }
8295 ConstraintType::ComputedColumn => {
8296 for constraint in &col.constraints {
8298 if let ColumnConstraint::ComputedColumn(cc) = constraint {
8299 self.write_space();
8300 self.generate_computed_column_inline(cc)?;
8301 break;
8302 }
8303 }
8304 }
8305 ConstraintType::GeneratedAsRow => {
8306 for constraint in &col.constraints {
8308 if let ColumnConstraint::GeneratedAsRow(gar) = constraint {
8309 self.write_space();
8310 self.generate_generated_as_row_inline(gar)?;
8311 break;
8312 }
8313 }
8314 }
8315 ConstraintType::OnUpdate => {
8316 if let Some(ref expr) = col.on_update {
8317 self.write_space();
8318 self.write_keyword("ON UPDATE");
8319 self.write_space();
8320 self.generate_expression(expr)?;
8321 }
8322 }
8323 ConstraintType::Encode => {
8324 if let Some(ref encoding) = col.encoding {
8325 self.write_space();
8326 self.write_keyword("ENCODE");
8327 self.write_space();
8328 self.write(encoding);
8329 }
8330 }
8331 ConstraintType::Path => {
8332 for constraint in &col.constraints {
8334 if let ColumnConstraint::Path(path_expr) = constraint {
8335 self.write_space();
8336 self.write_keyword("PATH");
8337 self.write_space();
8338 self.generate_expression(path_expr)?;
8339 break;
8340 }
8341 }
8342 }
8343 }
8344 }
8345 if pending_not_null_after_identity {
8346 self.write_space();
8347 self.write_keyword("NOT NULL");
8348 }
8349 } else {
8350 if col.primary_key {
8352 self.write_space();
8353 self.write_keyword("PRIMARY KEY");
8354 if let Some(ref order) = col.primary_key_order {
8355 self.write_space();
8356 match order {
8357 SortOrder::Asc => self.write_keyword("ASC"),
8358 SortOrder::Desc => self.write_keyword("DESC"),
8359 }
8360 }
8361 }
8362
8363 if col.unique {
8364 self.write_space();
8365 self.write_keyword("UNIQUE");
8366 if col.unique_nulls_not_distinct {
8368 self.write(" NULLS NOT DISTINCT");
8369 }
8370 }
8371
8372 match col.nullable {
8373 Some(false) => {
8374 self.write_space();
8375 self.write_keyword("NOT NULL");
8376 }
8377 Some(true) => {
8378 self.write_space();
8379 self.write_keyword("NULL");
8380 }
8381 None => {}
8382 }
8383
8384 if let Some(ref default) = col.default {
8385 self.write_space();
8386 self.write_keyword("DEFAULT");
8387 self.write_space();
8388 self.generate_expression(default)?;
8389 }
8390
8391 if col.auto_increment {
8392 self.write_space();
8393 self.generate_auto_increment_keyword(col)?;
8394 }
8395
8396 for constraint in &col.constraints {
8398 match constraint {
8399 ColumnConstraint::References(fk_ref) => {
8400 self.write_space();
8401 if fk_ref.has_foreign_key_keywords {
8402 self.write_keyword("FOREIGN KEY");
8403 self.write_space();
8404 }
8405 self.write_keyword("REFERENCES");
8406 self.write_space();
8407 self.generate_table(&fk_ref.table)?;
8408 if !fk_ref.columns.is_empty() {
8409 self.write(" (");
8410 for (i, c) in fk_ref.columns.iter().enumerate() {
8411 if i > 0 {
8412 self.write(", ");
8413 }
8414 self.generate_identifier(c)?;
8415 }
8416 self.write(")");
8417 }
8418 self.generate_referential_actions(fk_ref)?;
8419 }
8420 ColumnConstraint::Check(expr) => {
8421 self.write_space();
8422 self.write_keyword("CHECK");
8423 self.write(" (");
8424 self.generate_expression(expr)?;
8425 self.write(")");
8426 }
8427 ColumnConstraint::GeneratedAsIdentity(gen) => {
8428 self.write_space();
8429 if matches!(
8431 self.config.dialect,
8432 Some(crate::dialects::DialectType::Redshift)
8433 ) {
8434 self.write_keyword("IDENTITY");
8435 self.write("(");
8436 if let Some(ref start) = gen.start {
8437 self.generate_expression(start)?;
8438 } else {
8439 self.write("0");
8440 }
8441 self.write(", ");
8442 if let Some(ref incr) = gen.increment {
8443 self.generate_expression(incr)?;
8444 } else {
8445 self.write("1");
8446 }
8447 self.write(")");
8448 } else {
8449 self.write_keyword("GENERATED");
8450 if gen.always {
8451 self.write_space();
8452 self.write_keyword("ALWAYS");
8453 } else {
8454 self.write_space();
8455 self.write_keyword("BY DEFAULT");
8456 if gen.on_null {
8457 self.write_space();
8458 self.write_keyword("ON NULL");
8459 }
8460 }
8461 self.write_space();
8462 self.write_keyword("AS IDENTITY");
8463
8464 let has_options = gen.start.is_some()
8465 || gen.increment.is_some()
8466 || gen.minvalue.is_some()
8467 || gen.maxvalue.is_some()
8468 || gen.cycle.is_some();
8469 if has_options {
8470 self.write(" (");
8471 let mut first = true;
8472 if let Some(ref start) = gen.start {
8473 if !first {
8474 self.write(" ");
8475 }
8476 first = false;
8477 self.write_keyword("START WITH");
8478 self.write_space();
8479 self.generate_expression(start)?;
8480 }
8481 if let Some(ref incr) = gen.increment {
8482 if !first {
8483 self.write(" ");
8484 }
8485 first = false;
8486 self.write_keyword("INCREMENT BY");
8487 self.write_space();
8488 self.generate_expression(incr)?;
8489 }
8490 if let Some(ref minv) = gen.minvalue {
8491 if !first {
8492 self.write(" ");
8493 }
8494 first = false;
8495 self.write_keyword("MINVALUE");
8496 self.write_space();
8497 self.generate_expression(minv)?;
8498 }
8499 if let Some(ref maxv) = gen.maxvalue {
8500 if !first {
8501 self.write(" ");
8502 }
8503 first = false;
8504 self.write_keyword("MAXVALUE");
8505 self.write_space();
8506 self.generate_expression(maxv)?;
8507 }
8508 if let Some(cycle) = gen.cycle {
8509 if !first {
8510 self.write(" ");
8511 }
8512 if cycle {
8513 self.write_keyword("CYCLE");
8514 } else {
8515 self.write_keyword("NO CYCLE");
8516 }
8517 }
8518 self.write(")");
8519 }
8520 }
8521 }
8522 ColumnConstraint::Collate(collation) => {
8523 self.write_space();
8524 self.write_keyword("COLLATE");
8525 self.write_space();
8526 self.generate_identifier(collation)?;
8527 }
8528 ColumnConstraint::Comment(comment) => {
8529 self.write_space();
8530 self.write_keyword("COMMENT");
8531 self.write_space();
8532 self.generate_string_literal(comment)?;
8533 }
8534 ColumnConstraint::Path(path_expr) => {
8535 self.write_space();
8536 self.write_keyword("PATH");
8537 self.write_space();
8538 self.generate_expression(path_expr)?;
8539 }
8540 _ => {} }
8542 }
8543
8544 if let Some(ref encoding) = col.encoding {
8546 self.write_space();
8547 self.write_keyword("ENCODE");
8548 self.write_space();
8549 self.write(encoding);
8550 }
8551 }
8552
8553 if let Some(ref codec) = col.codec {
8555 self.write_space();
8556 self.write_keyword("CODEC");
8557 self.write("(");
8558 self.write(codec);
8559 self.write(")");
8560 }
8561
8562 if let Some(ref ephemeral) = col.ephemeral {
8564 self.write_space();
8565 self.write_keyword("EPHEMERAL");
8566 if let Some(ref expr) = ephemeral {
8567 self.write_space();
8568 self.generate_expression(expr)?;
8569 }
8570 }
8571
8572 if let Some(ref mat_expr) = col.materialized_expr {
8574 self.write_space();
8575 self.write_keyword("MATERIALIZED");
8576 self.write_space();
8577 self.generate_expression(mat_expr)?;
8578 }
8579
8580 if let Some(ref alias_expr) = col.alias_expr {
8582 self.write_space();
8583 self.write_keyword("ALIAS");
8584 self.write_space();
8585 self.generate_expression(alias_expr)?;
8586 }
8587
8588 if let Some(ref ttl_expr) = col.ttl_expr {
8590 self.write_space();
8591 self.write_keyword("TTL");
8592 self.write_space();
8593 self.generate_expression(ttl_expr)?;
8594 }
8595
8596 if col.not_for_replication
8598 && matches!(
8599 self.config.dialect,
8600 Some(crate::dialects::DialectType::TSQL)
8601 | Some(crate::dialects::DialectType::Fabric)
8602 )
8603 {
8604 self.write_space();
8605 self.write_keyword("NOT FOR REPLICATION");
8606 }
8607
8608 if !col.options.is_empty() {
8610 self.write_space();
8611 self.generate_options_clause(&col.options)?;
8612 }
8613
8614 if !col.primary_key
8617 && self
8618 .sqlite_inline_pk_columns
8619 .contains(&col.name.name.to_lowercase())
8620 {
8621 self.write_space();
8622 self.write_keyword("PRIMARY KEY");
8623 }
8624
8625 if serial_expansion.is_some() {
8628 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
8629 self.write_space();
8630 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY NOT NULL");
8631 } else if matches!(self.config.dialect, Some(DialectType::Materialize)) {
8632 self.write_space();
8633 self.write_keyword("NOT NULL");
8634 }
8635 }
8636
8637 Ok(())
8638 }
8639
8640 fn generate_table_constraint(&mut self, constraint: &TableConstraint) -> Result<()> {
8641 match constraint {
8642 TableConstraint::PrimaryKey {
8643 name,
8644 columns,
8645 include_columns,
8646 modifiers,
8647 has_constraint_keyword,
8648 } => {
8649 if let Some(ref n) = name {
8650 if *has_constraint_keyword {
8651 self.write_keyword("CONSTRAINT");
8652 self.write_space();
8653 self.generate_identifier(n)?;
8654 self.write_space();
8655 }
8656 }
8657 self.write_keyword("PRIMARY KEY");
8658 if let Some(ref clustered) = modifiers.clustered {
8660 self.write_space();
8661 self.write_keyword(clustered);
8662 }
8663 if let Some(ref n) = name {
8665 if !*has_constraint_keyword {
8666 self.write_space();
8667 self.generate_identifier(n)?;
8668 }
8669 }
8670 self.write(" (");
8671 for (i, col) in columns.iter().enumerate() {
8672 if i > 0 {
8673 self.write(", ");
8674 }
8675 self.generate_identifier(col)?;
8676 }
8677 self.write(")");
8678 if !include_columns.is_empty() {
8679 self.write_space();
8680 self.write_keyword("INCLUDE");
8681 self.write(" (");
8682 for (i, col) in include_columns.iter().enumerate() {
8683 if i > 0 {
8684 self.write(", ");
8685 }
8686 self.generate_identifier(col)?;
8687 }
8688 self.write(")");
8689 }
8690 self.generate_constraint_modifiers(modifiers);
8691 }
8692 TableConstraint::Unique {
8693 name,
8694 columns,
8695 columns_parenthesized,
8696 modifiers,
8697 has_constraint_keyword,
8698 nulls_not_distinct,
8699 } => {
8700 if let Some(ref n) = name {
8701 if *has_constraint_keyword {
8702 self.write_keyword("CONSTRAINT");
8703 self.write_space();
8704 self.generate_identifier(n)?;
8705 self.write_space();
8706 }
8707 }
8708 self.write_keyword("UNIQUE");
8709 if let Some(ref clustered) = modifiers.clustered {
8711 self.write_space();
8712 self.write_keyword(clustered);
8713 }
8714 if *nulls_not_distinct {
8716 self.write(" NULLS NOT DISTINCT");
8717 }
8718 if let Some(ref n) = name {
8720 if !*has_constraint_keyword {
8721 self.write_space();
8722 self.generate_identifier(n)?;
8723 }
8724 }
8725 if *columns_parenthesized {
8726 self.write(" (");
8727 for (i, col) in columns.iter().enumerate() {
8728 if i > 0 {
8729 self.write(", ");
8730 }
8731 self.generate_identifier(col)?;
8732 }
8733 self.write(")");
8734 } else {
8735 for col in columns.iter() {
8737 self.write_space();
8738 self.generate_identifier(col)?;
8739 }
8740 }
8741 self.generate_constraint_modifiers(modifiers);
8742 }
8743 TableConstraint::ForeignKey {
8744 name,
8745 columns,
8746 references,
8747 on_delete,
8748 on_update,
8749 modifiers,
8750 } => {
8751 if let Some(ref n) = name {
8752 self.write_keyword("CONSTRAINT");
8753 self.write_space();
8754 self.generate_identifier(n)?;
8755 self.write_space();
8756 }
8757 self.write_keyword("FOREIGN KEY");
8758 self.write(" (");
8759 for (i, col) in columns.iter().enumerate() {
8760 if i > 0 {
8761 self.write(", ");
8762 }
8763 self.generate_identifier(col)?;
8764 }
8765 self.write(")");
8766 if let Some(ref refs) = references {
8767 self.write(" ");
8768 self.write_keyword("REFERENCES");
8769 self.write_space();
8770 self.generate_table(&refs.table)?;
8771 if !refs.columns.is_empty() {
8772 if self.config.pretty {
8773 self.write(" (");
8774 self.write_newline();
8775 self.indent_level += 1;
8776 for (i, col) in refs.columns.iter().enumerate() {
8777 if i > 0 {
8778 self.write(",");
8779 self.write_newline();
8780 }
8781 self.write_indent();
8782 self.generate_identifier(col)?;
8783 }
8784 self.indent_level -= 1;
8785 self.write_newline();
8786 self.write_indent();
8787 self.write(")");
8788 } else {
8789 self.write(" (");
8790 for (i, col) in refs.columns.iter().enumerate() {
8791 if i > 0 {
8792 self.write(", ");
8793 }
8794 self.generate_identifier(col)?;
8795 }
8796 self.write(")");
8797 }
8798 }
8799 self.generate_referential_actions(refs)?;
8800 } else {
8801 if let Some(ref action) = on_delete {
8803 self.write_space();
8804 self.write_keyword("ON DELETE");
8805 self.write_space();
8806 self.generate_referential_action(action);
8807 }
8808 if let Some(ref action) = on_update {
8809 self.write_space();
8810 self.write_keyword("ON UPDATE");
8811 self.write_space();
8812 self.generate_referential_action(action);
8813 }
8814 }
8815 self.generate_constraint_modifiers(modifiers);
8816 }
8817 TableConstraint::Check {
8818 name,
8819 expression,
8820 modifiers,
8821 } => {
8822 if let Some(ref n) = name {
8823 self.write_keyword("CONSTRAINT");
8824 self.write_space();
8825 self.generate_identifier(n)?;
8826 self.write_space();
8827 }
8828 self.write_keyword("CHECK");
8829 self.write(" (");
8830 self.generate_expression(expression)?;
8831 self.write(")");
8832 self.generate_constraint_modifiers(modifiers);
8833 }
8834 TableConstraint::Index {
8835 name,
8836 columns,
8837 kind,
8838 modifiers,
8839 use_key_keyword,
8840 expression,
8841 index_type,
8842 granularity,
8843 } => {
8844 if expression.is_some() {
8846 self.write_keyword("INDEX");
8847 if let Some(ref n) = name {
8848 self.write_space();
8849 self.generate_identifier(n)?;
8850 }
8851 if let Some(ref expr) = expression {
8852 self.write_space();
8853 self.generate_expression(expr)?;
8854 }
8855 if let Some(ref idx_type) = index_type {
8856 self.write_space();
8857 self.write_keyword("TYPE");
8858 self.write_space();
8859 self.generate_expression(idx_type)?;
8860 }
8861 if let Some(ref gran) = granularity {
8862 self.write_space();
8863 self.write_keyword("GRANULARITY");
8864 self.write_space();
8865 self.generate_expression(gran)?;
8866 }
8867 } else {
8868 use crate::dialects::DialectType;
8872 let index_keyword = if *use_key_keyword
8873 && !matches!(self.config.dialect, Some(DialectType::MySQL))
8874 {
8875 "KEY"
8876 } else {
8877 "INDEX"
8878 };
8879
8880 if let Some(ref k) = kind {
8882 self.write_keyword(k);
8883 if k != "UNIQUE" {
8885 self.write_space();
8886 self.write_keyword(index_keyword);
8887 }
8888 } else {
8889 self.write_keyword(index_keyword);
8890 }
8891
8892 if modifiers.using_before_columns && name.is_none() {
8894 if let Some(ref using) = modifiers.using {
8895 self.write_space();
8896 self.write_keyword("USING");
8897 self.write_space();
8898 self.write_keyword(using);
8899 }
8900 }
8901
8902 if let Some(ref n) = name {
8904 self.write_space();
8905 self.generate_identifier(n)?;
8906 }
8907
8908 if modifiers.using_before_columns && name.is_some() {
8910 if let Some(ref using) = modifiers.using {
8911 self.write_space();
8912 self.write_keyword("USING");
8913 self.write_space();
8914 self.write_keyword(using);
8915 }
8916 }
8917
8918 self.write(" (");
8920 for (i, col) in columns.iter().enumerate() {
8921 if i > 0 {
8922 self.write(", ");
8923 }
8924 self.generate_identifier(col)?;
8925 }
8926 self.write(")");
8927
8928 if !modifiers.using_before_columns {
8930 if let Some(ref using) = modifiers.using {
8931 self.write_space();
8932 self.write_keyword("USING");
8933 self.write_space();
8934 self.write_keyword(using);
8935 }
8936 }
8937
8938 self.generate_constraint_modifiers_without_using(modifiers);
8940 }
8941 }
8942 TableConstraint::Projection { name, expression } => {
8943 self.write_keyword("PROJECTION");
8945 self.write_space();
8946 self.generate_identifier(name)?;
8947 self.write(" (");
8948 self.generate_expression(expression)?;
8949 self.write(")");
8950 }
8951 TableConstraint::Like { source, options } => {
8952 self.write_keyword("LIKE");
8953 self.write_space();
8954 self.generate_table(source)?;
8955 for (action, prop) in options {
8956 self.write_space();
8957 match action {
8958 LikeOptionAction::Including => self.write_keyword("INCLUDING"),
8959 LikeOptionAction::Excluding => self.write_keyword("EXCLUDING"),
8960 }
8961 self.write_space();
8962 self.write_keyword(prop);
8963 }
8964 }
8965 TableConstraint::PeriodForSystemTime { start_col, end_col } => {
8966 self.write_keyword("PERIOD FOR SYSTEM_TIME");
8967 self.write(" (");
8968 self.generate_identifier(start_col)?;
8969 self.write(", ");
8970 self.generate_identifier(end_col)?;
8971 self.write(")");
8972 }
8973 TableConstraint::Exclude {
8974 name,
8975 using,
8976 elements,
8977 include_columns,
8978 where_clause,
8979 with_params,
8980 using_index_tablespace,
8981 modifiers: _,
8982 } => {
8983 if let Some(ref n) = name {
8984 self.write_keyword("CONSTRAINT");
8985 self.write_space();
8986 self.generate_identifier(n)?;
8987 self.write_space();
8988 }
8989 self.write_keyword("EXCLUDE");
8990 if let Some(ref method) = using {
8991 self.write_space();
8992 self.write_keyword("USING");
8993 self.write_space();
8994 self.write(method);
8995 self.write("(");
8996 } else {
8997 self.write(" (");
8998 }
8999 for (i, elem) in elements.iter().enumerate() {
9000 if i > 0 {
9001 self.write(", ");
9002 }
9003 self.write(&elem.expression);
9004 self.write_space();
9005 self.write_keyword("WITH");
9006 self.write_space();
9007 self.write(&elem.operator);
9008 }
9009 self.write(")");
9010 if !include_columns.is_empty() {
9011 self.write_space();
9012 self.write_keyword("INCLUDE");
9013 self.write(" (");
9014 for (i, col) in include_columns.iter().enumerate() {
9015 if i > 0 {
9016 self.write(", ");
9017 }
9018 self.generate_identifier(col)?;
9019 }
9020 self.write(")");
9021 }
9022 if !with_params.is_empty() {
9023 self.write_space();
9024 self.write_keyword("WITH");
9025 self.write(" (");
9026 for (i, (key, val)) in with_params.iter().enumerate() {
9027 if i > 0 {
9028 self.write(", ");
9029 }
9030 self.write(key);
9031 self.write("=");
9032 self.write(val);
9033 }
9034 self.write(")");
9035 }
9036 if let Some(ref tablespace) = using_index_tablespace {
9037 self.write_space();
9038 self.write_keyword("USING INDEX TABLESPACE");
9039 self.write_space();
9040 self.write(tablespace);
9041 }
9042 if let Some(ref where_expr) = where_clause {
9043 self.write_space();
9044 self.write_keyword("WHERE");
9045 self.write(" (");
9046 self.generate_expression(where_expr)?;
9047 self.write(")");
9048 }
9049 }
9050 TableConstraint::Tags(tags) => {
9051 self.write_keyword("TAG");
9052 self.write(" (");
9053 for (i, expr) in tags.expressions.iter().enumerate() {
9054 if i > 0 {
9055 self.write(", ");
9056 }
9057 self.generate_expression(expr)?;
9058 }
9059 self.write(")");
9060 }
9061 TableConstraint::InitiallyDeferred { deferred } => {
9062 self.write_keyword("INITIALLY");
9063 self.write_space();
9064 if *deferred {
9065 self.write_keyword("DEFERRED");
9066 } else {
9067 self.write_keyword("IMMEDIATE");
9068 }
9069 }
9070 }
9071 Ok(())
9072 }
9073
9074 fn generate_constraint_modifiers(&mut self, modifiers: &ConstraintModifiers) {
9075 if let Some(using) = &modifiers.using {
9077 self.write_space();
9078 self.write_keyword("USING");
9079 self.write_space();
9080 self.write_keyword(using);
9081 }
9082 if let Some(enforced) = modifiers.enforced {
9084 self.write_space();
9085 if enforced {
9086 self.write_keyword("ENFORCED");
9087 } else {
9088 self.write_keyword("NOT ENFORCED");
9089 }
9090 }
9091 if let Some(deferrable) = modifiers.deferrable {
9093 self.write_space();
9094 if deferrable {
9095 self.write_keyword("DEFERRABLE");
9096 } else {
9097 self.write_keyword("NOT DEFERRABLE");
9098 }
9099 }
9100 if let Some(initially_deferred) = modifiers.initially_deferred {
9102 self.write_space();
9103 if initially_deferred {
9104 self.write_keyword("INITIALLY DEFERRED");
9105 } else {
9106 self.write_keyword("INITIALLY IMMEDIATE");
9107 }
9108 }
9109 if modifiers.norely {
9111 self.write_space();
9112 self.write_keyword("NORELY");
9113 }
9114 if modifiers.rely {
9116 self.write_space();
9117 self.write_keyword("RELY");
9118 }
9119 if modifiers.not_valid {
9121 self.write_space();
9122 self.write_keyword("NOT VALID");
9123 }
9124 if let Some(on_conflict) = &modifiers.on_conflict {
9126 self.write_space();
9127 self.write_keyword("ON CONFLICT");
9128 self.write_space();
9129 self.write_keyword(on_conflict);
9130 }
9131 if !modifiers.with_options.is_empty() {
9133 self.write_space();
9134 self.write_keyword("WITH");
9135 self.write(" (");
9136 for (i, (key, value)) in modifiers.with_options.iter().enumerate() {
9137 if i > 0 {
9138 self.write(", ");
9139 }
9140 self.write(key);
9141 self.write("=");
9142 self.write(value);
9143 }
9144 self.write(")");
9145 }
9146 if let Some(ref fg) = modifiers.on_filegroup {
9148 self.write_space();
9149 self.write_keyword("ON");
9150 self.write_space();
9151 let _ = self.generate_identifier(fg);
9152 }
9153 }
9154
9155 fn generate_constraint_modifiers_without_using(&mut self, modifiers: &ConstraintModifiers) {
9157 if let Some(enforced) = modifiers.enforced {
9159 self.write_space();
9160 if enforced {
9161 self.write_keyword("ENFORCED");
9162 } else {
9163 self.write_keyword("NOT ENFORCED");
9164 }
9165 }
9166 if let Some(deferrable) = modifiers.deferrable {
9168 self.write_space();
9169 if deferrable {
9170 self.write_keyword("DEFERRABLE");
9171 } else {
9172 self.write_keyword("NOT DEFERRABLE");
9173 }
9174 }
9175 if let Some(initially_deferred) = modifiers.initially_deferred {
9177 self.write_space();
9178 if initially_deferred {
9179 self.write_keyword("INITIALLY DEFERRED");
9180 } else {
9181 self.write_keyword("INITIALLY IMMEDIATE");
9182 }
9183 }
9184 if modifiers.norely {
9186 self.write_space();
9187 self.write_keyword("NORELY");
9188 }
9189 if modifiers.rely {
9191 self.write_space();
9192 self.write_keyword("RELY");
9193 }
9194 if modifiers.not_valid {
9196 self.write_space();
9197 self.write_keyword("NOT VALID");
9198 }
9199 if let Some(on_conflict) = &modifiers.on_conflict {
9201 self.write_space();
9202 self.write_keyword("ON CONFLICT");
9203 self.write_space();
9204 self.write_keyword(on_conflict);
9205 }
9206 self.generate_index_specific_modifiers(modifiers);
9208 }
9209
9210 fn generate_index_specific_modifiers(&mut self, modifiers: &ConstraintModifiers) {
9212 if let Some(ref comment) = modifiers.comment {
9213 self.write_space();
9214 self.write_keyword("COMMENT");
9215 self.write(" '");
9216 self.write(comment);
9217 self.write("'");
9218 }
9219 if let Some(visible) = modifiers.visible {
9220 self.write_space();
9221 if visible {
9222 self.write_keyword("VISIBLE");
9223 } else {
9224 self.write_keyword("INVISIBLE");
9225 }
9226 }
9227 if let Some(ref attr) = modifiers.engine_attribute {
9228 self.write_space();
9229 self.write_keyword("ENGINE_ATTRIBUTE");
9230 self.write(" = '");
9231 self.write(attr);
9232 self.write("'");
9233 }
9234 if let Some(ref parser) = modifiers.with_parser {
9235 self.write_space();
9236 self.write_keyword("WITH PARSER");
9237 self.write_space();
9238 self.write(parser);
9239 }
9240 }
9241
9242 fn generate_referential_actions(&mut self, fk_ref: &ForeignKeyRef) -> Result<()> {
9243 if !fk_ref.match_after_actions {
9245 if let Some(ref match_type) = fk_ref.match_type {
9246 self.write_space();
9247 self.write_keyword("MATCH");
9248 self.write_space();
9249 match match_type {
9250 MatchType::Full => self.write_keyword("FULL"),
9251 MatchType::Partial => self.write_keyword("PARTIAL"),
9252 MatchType::Simple => self.write_keyword("SIMPLE"),
9253 }
9254 }
9255 }
9256
9257 if fk_ref.on_update_first {
9259 if let Some(ref action) = fk_ref.on_update {
9260 self.write_space();
9261 self.write_keyword("ON UPDATE");
9262 self.write_space();
9263 self.generate_referential_action(action);
9264 }
9265 if let Some(ref action) = fk_ref.on_delete {
9266 self.write_space();
9267 self.write_keyword("ON DELETE");
9268 self.write_space();
9269 self.generate_referential_action(action);
9270 }
9271 } else {
9272 if let Some(ref action) = fk_ref.on_delete {
9273 self.write_space();
9274 self.write_keyword("ON DELETE");
9275 self.write_space();
9276 self.generate_referential_action(action);
9277 }
9278 if let Some(ref action) = fk_ref.on_update {
9279 self.write_space();
9280 self.write_keyword("ON UPDATE");
9281 self.write_space();
9282 self.generate_referential_action(action);
9283 }
9284 }
9285
9286 if fk_ref.match_after_actions {
9288 if let Some(ref match_type) = fk_ref.match_type {
9289 self.write_space();
9290 self.write_keyword("MATCH");
9291 self.write_space();
9292 match match_type {
9293 MatchType::Full => self.write_keyword("FULL"),
9294 MatchType::Partial => self.write_keyword("PARTIAL"),
9295 MatchType::Simple => self.write_keyword("SIMPLE"),
9296 }
9297 }
9298 }
9299
9300 if let Some(deferrable) = fk_ref.deferrable {
9302 self.write_space();
9303 if deferrable {
9304 self.write_keyword("DEFERRABLE");
9305 } else {
9306 self.write_keyword("NOT DEFERRABLE");
9307 }
9308 }
9309
9310 Ok(())
9311 }
9312
9313 fn generate_referential_action(&mut self, action: &ReferentialAction) {
9314 match action {
9315 ReferentialAction::Cascade => self.write_keyword("CASCADE"),
9316 ReferentialAction::SetNull => self.write_keyword("SET NULL"),
9317 ReferentialAction::SetDefault => self.write_keyword("SET DEFAULT"),
9318 ReferentialAction::Restrict => self.write_keyword("RESTRICT"),
9319 ReferentialAction::NoAction => self.write_keyword("NO ACTION"),
9320 }
9321 }
9322
9323 fn generate_drop_table(&mut self, dt: &DropTable) -> Result<()> {
9324 let saved_athena_hive_context = self.athena_hive_context;
9326 if matches!(
9327 self.config.dialect,
9328 Some(crate::dialects::DialectType::Athena)
9329 ) {
9330 self.athena_hive_context = true;
9331 }
9332
9333 for comment in &dt.leading_comments {
9335 self.write_formatted_comment(comment);
9336 self.write_space();
9337 }
9338 self.write_keyword("DROP TABLE");
9339
9340 if dt.if_exists {
9341 self.write_space();
9342 self.write_keyword("IF EXISTS");
9343 }
9344
9345 self.write_space();
9346 for (i, table) in dt.names.iter().enumerate() {
9347 if i > 0 {
9348 self.write(", ");
9349 }
9350 self.generate_table(table)?;
9351 }
9352
9353 if dt.cascade_constraints {
9354 self.write_space();
9355 self.write_keyword("CASCADE CONSTRAINTS");
9356 } else if dt.cascade {
9357 self.write_space();
9358 self.write_keyword("CASCADE");
9359 }
9360
9361 if dt.purge {
9362 self.write_space();
9363 self.write_keyword("PURGE");
9364 }
9365
9366 self.athena_hive_context = saved_athena_hive_context;
9368
9369 Ok(())
9370 }
9371
9372 fn generate_alter_table(&mut self, at: &AlterTable) -> Result<()> {
9373 let saved_athena_hive_context = self.athena_hive_context;
9375 if matches!(
9376 self.config.dialect,
9377 Some(crate::dialects::DialectType::Athena)
9378 ) {
9379 self.athena_hive_context = true;
9380 }
9381
9382 self.write_keyword("ALTER TABLE");
9383 if at.if_exists {
9384 self.write_space();
9385 self.write_keyword("IF EXISTS");
9386 }
9387 self.write_space();
9388 self.generate_table(&at.name)?;
9389
9390 if let Some(ref on_cluster) = at.on_cluster {
9392 self.write_space();
9393 self.generate_on_cluster(on_cluster)?;
9394 }
9395
9396 if let Some(ref partition) = at.partition {
9398 self.write_space();
9399 self.write_keyword("PARTITION");
9400 self.write("(");
9401 for (i, (key, value)) in partition.iter().enumerate() {
9402 if i > 0 {
9403 self.write(", ");
9404 }
9405 self.generate_identifier(key)?;
9406 self.write(" = ");
9407 self.generate_expression(value)?;
9408 }
9409 self.write(")");
9410 }
9411
9412 if let Some(ref with_check) = at.with_check {
9414 self.write_space();
9415 self.write_keyword(with_check);
9416 }
9417
9418 if self.config.pretty {
9419 self.write_newline();
9421 self.indent_level += 1;
9422 for (i, action) in at.actions.iter().enumerate() {
9423 let is_continuation = i > 0
9425 && matches!(
9426 (&at.actions[i - 1], action),
9427 (
9428 AlterTableAction::AddColumn { .. },
9429 AlterTableAction::AddColumn { .. }
9430 ) | (
9431 AlterTableAction::AddConstraint(_),
9432 AlterTableAction::AddConstraint(_)
9433 )
9434 );
9435 if i > 0 {
9436 self.write(",");
9437 self.write_newline();
9438 }
9439 self.write_indent();
9440 self.generate_alter_action_with_continuation(action, is_continuation)?;
9441 }
9442 self.indent_level -= 1;
9443 } else {
9444 for (i, action) in at.actions.iter().enumerate() {
9445 let is_continuation = i > 0
9447 && matches!(
9448 (&at.actions[i - 1], action),
9449 (
9450 AlterTableAction::AddColumn { .. },
9451 AlterTableAction::AddColumn { .. }
9452 ) | (
9453 AlterTableAction::AddConstraint(_),
9454 AlterTableAction::AddConstraint(_)
9455 )
9456 );
9457 if i > 0 {
9458 self.write(",");
9459 }
9460 self.write_space();
9461 self.generate_alter_action_with_continuation(action, is_continuation)?;
9462 }
9463 }
9464
9465 if let Some(ref algorithm) = at.algorithm {
9467 self.write(", ");
9468 self.write_keyword("ALGORITHM");
9469 self.write("=");
9470 self.write_keyword(algorithm);
9471 }
9472 if let Some(ref lock) = at.lock {
9473 self.write(", ");
9474 self.write_keyword("LOCK");
9475 self.write("=");
9476 self.write_keyword(lock);
9477 }
9478
9479 self.athena_hive_context = saved_athena_hive_context;
9481
9482 Ok(())
9483 }
9484
9485 fn generate_alter_action_with_continuation(
9486 &mut self,
9487 action: &AlterTableAction,
9488 is_continuation: bool,
9489 ) -> Result<()> {
9490 match action {
9491 AlterTableAction::AddColumn {
9492 column,
9493 if_not_exists,
9494 position,
9495 } => {
9496 use crate::dialects::DialectType;
9497 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
9501 let is_tsql_like = matches!(
9502 self.config.dialect,
9503 Some(DialectType::TSQL) | Some(DialectType::Fabric)
9504 );
9505 let is_athena = matches!(self.config.dialect, Some(DialectType::Athena));
9507
9508 if is_continuation && (is_snowflake || is_tsql_like) {
9509 } else if is_snowflake {
9511 self.write_keyword("ADD");
9512 self.write_space();
9513 } else if is_athena {
9514 self.write_keyword("ADD COLUMNS");
9516 self.write(" (");
9517 } else if self.config.alter_table_include_column_keyword {
9518 self.write_keyword("ADD COLUMN");
9519 self.write_space();
9520 } else {
9521 self.write_keyword("ADD");
9523 self.write_space();
9524 }
9525
9526 if *if_not_exists {
9527 self.write_keyword("IF NOT EXISTS");
9528 self.write_space();
9529 }
9530 self.generate_column_def(column)?;
9531
9532 if is_athena {
9534 self.write(")");
9535 }
9536
9537 if let Some(pos) = position {
9539 self.write_space();
9540 match pos {
9541 ColumnPosition::First => self.write_keyword("FIRST"),
9542 ColumnPosition::After(col_name) => {
9543 self.write_keyword("AFTER");
9544 self.write_space();
9545 self.generate_identifier(col_name)?;
9546 }
9547 }
9548 }
9549 }
9550 AlterTableAction::DropColumn {
9551 name,
9552 if_exists,
9553 cascade,
9554 } => {
9555 self.write_keyword("DROP COLUMN");
9556 if *if_exists {
9557 self.write_space();
9558 self.write_keyword("IF EXISTS");
9559 }
9560 self.write_space();
9561 self.generate_identifier(name)?;
9562 if *cascade {
9563 self.write_space();
9564 self.write_keyword("CASCADE");
9565 }
9566 }
9567 AlterTableAction::DropColumns { names } => {
9568 self.write_keyword("DROP COLUMNS");
9569 self.write(" (");
9570 for (i, name) in names.iter().enumerate() {
9571 if i > 0 {
9572 self.write(", ");
9573 }
9574 self.generate_identifier(name)?;
9575 }
9576 self.write(")");
9577 }
9578 AlterTableAction::RenameColumn {
9579 old_name,
9580 new_name,
9581 if_exists,
9582 } => {
9583 self.write_keyword("RENAME COLUMN");
9584 if *if_exists {
9585 self.write_space();
9586 self.write_keyword("IF EXISTS");
9587 }
9588 self.write_space();
9589 self.generate_identifier(old_name)?;
9590 self.write_space();
9591 self.write_keyword("TO");
9592 self.write_space();
9593 self.generate_identifier(new_name)?;
9594 }
9595 AlterTableAction::AlterColumn {
9596 name,
9597 action,
9598 use_modify_keyword,
9599 } => {
9600 use crate::dialects::DialectType;
9601 let use_modify = *use_modify_keyword
9604 || (matches!(self.config.dialect, Some(DialectType::MySQL))
9605 && matches!(action, AlterColumnAction::SetDataType { .. }));
9606 if use_modify {
9607 self.write_keyword("MODIFY COLUMN");
9608 self.write_space();
9609 self.generate_identifier(name)?;
9610 if let AlterColumnAction::SetDataType {
9612 data_type,
9613 using: _,
9614 collate,
9615 } = action
9616 {
9617 self.write_space();
9618 self.generate_data_type(data_type)?;
9619 if let Some(collate_name) = collate {
9621 self.write_space();
9622 self.write_keyword("COLLATE");
9623 self.write_space();
9624 self.write(&format!("'{}'", collate_name));
9626 }
9627 } else {
9628 self.write_space();
9629 self.generate_alter_column_action(action)?;
9630 }
9631 } else if matches!(self.config.dialect, Some(DialectType::Hive))
9632 && matches!(action, AlterColumnAction::SetDataType { .. })
9633 {
9634 self.write_keyword("CHANGE COLUMN");
9636 self.write_space();
9637 self.generate_identifier(name)?;
9638 self.write_space();
9639 self.generate_identifier(name)?;
9640 if let AlterColumnAction::SetDataType { data_type, .. } = action {
9641 self.write_space();
9642 self.generate_data_type(data_type)?;
9643 }
9644 } else {
9645 self.write_keyword("ALTER COLUMN");
9646 self.write_space();
9647 self.generate_identifier(name)?;
9648 self.write_space();
9649 self.generate_alter_column_action(action)?;
9650 }
9651 }
9652 AlterTableAction::RenameTable(new_name) => {
9653 let mysql_like = matches!(
9655 self.config.dialect,
9656 Some(DialectType::MySQL)
9657 | Some(DialectType::Doris)
9658 | Some(DialectType::StarRocks)
9659 | Some(DialectType::SingleStore)
9660 );
9661 if mysql_like {
9662 self.write_keyword("RENAME");
9663 } else {
9664 self.write_keyword("RENAME TO");
9665 }
9666 self.write_space();
9667 let rename_table_with_db = !matches!(
9669 self.config.dialect,
9670 Some(DialectType::Doris)
9671 | Some(DialectType::DuckDB)
9672 | Some(DialectType::BigQuery)
9673 | Some(DialectType::PostgreSQL)
9674 );
9675 if !rename_table_with_db {
9676 let mut stripped = new_name.clone();
9677 stripped.schema = None;
9678 stripped.catalog = None;
9679 self.generate_table(&stripped)?;
9680 } else {
9681 self.generate_table(new_name)?;
9682 }
9683 }
9684 AlterTableAction::AddConstraint(constraint) => {
9685 if !is_continuation {
9688 self.write_keyword("ADD");
9689 self.write_space();
9690 }
9691 self.generate_table_constraint(constraint)?;
9692 }
9693 AlterTableAction::DropConstraint { name, if_exists } => {
9694 self.write_keyword("DROP CONSTRAINT");
9695 if *if_exists {
9696 self.write_space();
9697 self.write_keyword("IF EXISTS");
9698 }
9699 self.write_space();
9700 self.generate_identifier(name)?;
9701 }
9702 AlterTableAction::DropForeignKey { name } => {
9703 self.write_keyword("DROP FOREIGN KEY");
9704 self.write_space();
9705 self.generate_identifier(name)?;
9706 }
9707 AlterTableAction::DropPartition {
9708 partitions,
9709 if_exists,
9710 } => {
9711 self.write_keyword("DROP");
9712 if *if_exists {
9713 self.write_space();
9714 self.write_keyword("IF EXISTS");
9715 }
9716 for (i, partition) in partitions.iter().enumerate() {
9717 if i > 0 {
9718 self.write(",");
9719 }
9720 self.write_space();
9721 self.write_keyword("PARTITION");
9722 if partition.len() == 1 && partition[0].0.name == "__expr__" {
9724 self.write_space();
9726 self.generate_expression(&partition[0].1)?;
9727 } else if partition.len() == 1 && partition[0].0.name == "ALL" {
9728 self.write_space();
9730 self.write_keyword("ALL");
9731 } else if partition.len() == 1 && partition[0].0.name == "ID" {
9732 self.write_space();
9734 self.write_keyword("ID");
9735 self.write_space();
9736 self.generate_expression(&partition[0].1)?;
9737 } else {
9738 self.write("(");
9740 for (j, (key, value)) in partition.iter().enumerate() {
9741 if j > 0 {
9742 self.write(", ");
9743 }
9744 self.generate_identifier(key)?;
9745 self.write(" = ");
9746 self.generate_expression(value)?;
9747 }
9748 self.write(")");
9749 }
9750 }
9751 }
9752 AlterTableAction::Delete { where_clause } => {
9753 self.write_keyword("DELETE");
9754 self.write_space();
9755 self.write_keyword("WHERE");
9756 self.write_space();
9757 self.generate_expression(where_clause)?;
9758 }
9759 AlterTableAction::SwapWith(target) => {
9760 self.write_keyword("SWAP WITH");
9761 self.write_space();
9762 self.generate_table(target)?;
9763 }
9764 AlterTableAction::SetProperty { properties } => {
9765 use crate::dialects::DialectType;
9766 self.write_keyword("SET");
9767 let is_trino_presto = matches!(
9769 self.config.dialect,
9770 Some(DialectType::Trino) | Some(DialectType::Presto)
9771 );
9772 if is_trino_presto {
9773 self.write_space();
9774 self.write_keyword("PROPERTIES");
9775 }
9776 let eq = if is_trino_presto { " = " } else { "=" };
9777 for (i, (key, value)) in properties.iter().enumerate() {
9778 if i > 0 {
9779 self.write(",");
9780 }
9781 self.write_space();
9782 if key.contains(' ') {
9784 self.generate_string_literal(key)?;
9785 } else {
9786 self.write(key);
9787 }
9788 self.write(eq);
9789 self.generate_expression(value)?;
9790 }
9791 }
9792 AlterTableAction::UnsetProperty { properties } => {
9793 self.write_keyword("UNSET");
9794 for (i, name) in properties.iter().enumerate() {
9795 if i > 0 {
9796 self.write(",");
9797 }
9798 self.write_space();
9799 self.write(name);
9800 }
9801 }
9802 AlterTableAction::ClusterBy { expressions } => {
9803 self.write_keyword("CLUSTER BY");
9804 self.write(" (");
9805 for (i, expr) in expressions.iter().enumerate() {
9806 if i > 0 {
9807 self.write(", ");
9808 }
9809 self.generate_expression(expr)?;
9810 }
9811 self.write(")");
9812 }
9813 AlterTableAction::SetTag { expressions } => {
9814 self.write_keyword("SET TAG");
9815 for (i, (key, value)) in expressions.iter().enumerate() {
9816 if i > 0 {
9817 self.write(",");
9818 }
9819 self.write_space();
9820 self.write(key);
9821 self.write(" = ");
9822 self.generate_expression(value)?;
9823 }
9824 }
9825 AlterTableAction::UnsetTag { names } => {
9826 self.write_keyword("UNSET TAG");
9827 for (i, name) in names.iter().enumerate() {
9828 if i > 0 {
9829 self.write(",");
9830 }
9831 self.write_space();
9832 self.write(name);
9833 }
9834 }
9835 AlterTableAction::SetOptions { expressions } => {
9836 self.write_keyword("SET");
9837 self.write(" (");
9838 for (i, expr) in expressions.iter().enumerate() {
9839 if i > 0 {
9840 self.write(", ");
9841 }
9842 self.generate_expression(expr)?;
9843 }
9844 self.write(")");
9845 }
9846 AlterTableAction::AlterIndex { name, visible } => {
9847 self.write_keyword("ALTER INDEX");
9848 self.write_space();
9849 self.generate_identifier(name)?;
9850 self.write_space();
9851 if *visible {
9852 self.write_keyword("VISIBLE");
9853 } else {
9854 self.write_keyword("INVISIBLE");
9855 }
9856 }
9857 AlterTableAction::SetAttribute { attribute } => {
9858 self.write_keyword("SET");
9859 self.write_space();
9860 self.write_keyword(attribute);
9861 }
9862 AlterTableAction::SetStageFileFormat { options } => {
9863 self.write_keyword("SET");
9864 self.write_space();
9865 self.write_keyword("STAGE_FILE_FORMAT");
9866 self.write(" = (");
9867 if let Some(opts) = options {
9868 self.generate_space_separated_properties(opts)?;
9869 }
9870 self.write(")");
9871 }
9872 AlterTableAction::SetStageCopyOptions { options } => {
9873 self.write_keyword("SET");
9874 self.write_space();
9875 self.write_keyword("STAGE_COPY_OPTIONS");
9876 self.write(" = (");
9877 if let Some(opts) = options {
9878 self.generate_space_separated_properties(opts)?;
9879 }
9880 self.write(")");
9881 }
9882 AlterTableAction::AddColumns { columns, cascade } => {
9883 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
9886 if is_oracle {
9887 self.write_keyword("ADD");
9888 } else {
9889 self.write_keyword("ADD COLUMNS");
9890 }
9891 self.write(" (");
9892 for (i, col) in columns.iter().enumerate() {
9893 if i > 0 {
9894 self.write(", ");
9895 }
9896 self.generate_column_def(col)?;
9897 }
9898 self.write(")");
9899 if *cascade {
9900 self.write_space();
9901 self.write_keyword("CASCADE");
9902 }
9903 }
9904 AlterTableAction::ChangeColumn {
9905 old_name,
9906 new_name,
9907 data_type,
9908 comment,
9909 cascade,
9910 } => {
9911 use crate::dialects::DialectType;
9912 let is_spark = matches!(
9913 self.config.dialect,
9914 Some(DialectType::Spark) | Some(DialectType::Databricks)
9915 );
9916 let is_rename = old_name.name != new_name.name;
9917
9918 if is_spark {
9919 if is_rename {
9920 self.write_keyword("RENAME COLUMN");
9922 self.write_space();
9923 self.generate_identifier(old_name)?;
9924 self.write_space();
9925 self.write_keyword("TO");
9926 self.write_space();
9927 self.generate_identifier(new_name)?;
9928 } else if comment.is_some() {
9929 self.write_keyword("ALTER COLUMN");
9931 self.write_space();
9932 self.generate_identifier(old_name)?;
9933 self.write_space();
9934 self.write_keyword("COMMENT");
9935 self.write_space();
9936 self.write("'");
9937 self.write(comment.as_ref().unwrap());
9938 self.write("'");
9939 } else if data_type.is_some() {
9940 self.write_keyword("ALTER COLUMN");
9942 self.write_space();
9943 self.generate_identifier(old_name)?;
9944 self.write_space();
9945 self.write_keyword("TYPE");
9946 self.write_space();
9947 self.generate_data_type(data_type.as_ref().unwrap())?;
9948 } else {
9949 self.write_keyword("CHANGE COLUMN");
9951 self.write_space();
9952 self.generate_identifier(old_name)?;
9953 self.write_space();
9954 self.generate_identifier(new_name)?;
9955 }
9956 } else {
9957 if data_type.is_some() {
9959 self.write_keyword("CHANGE COLUMN");
9960 } else {
9961 self.write_keyword("CHANGE");
9962 }
9963 self.write_space();
9964 self.generate_identifier(old_name)?;
9965 self.write_space();
9966 self.generate_identifier(new_name)?;
9967 if let Some(ref dt) = data_type {
9968 self.write_space();
9969 self.generate_data_type(dt)?;
9970 }
9971 if let Some(ref c) = comment {
9972 self.write_space();
9973 self.write_keyword("COMMENT");
9974 self.write_space();
9975 self.write("'");
9976 self.write(c);
9977 self.write("'");
9978 }
9979 if *cascade {
9980 self.write_space();
9981 self.write_keyword("CASCADE");
9982 }
9983 }
9984 }
9985 AlterTableAction::AddPartition {
9986 partition,
9987 if_not_exists,
9988 location,
9989 } => {
9990 self.write_keyword("ADD");
9991 self.write_space();
9992 if *if_not_exists {
9993 self.write_keyword("IF NOT EXISTS");
9994 self.write_space();
9995 }
9996 self.generate_expression(partition)?;
9997 if let Some(ref loc) = location {
9998 self.write_space();
9999 self.write_keyword("LOCATION");
10000 self.write_space();
10001 self.generate_expression(loc)?;
10002 }
10003 }
10004 AlterTableAction::AlterSortKey {
10005 this,
10006 expressions,
10007 compound,
10008 } => {
10009 self.write_keyword("ALTER");
10011 if *compound {
10012 self.write_space();
10013 self.write_keyword("COMPOUND");
10014 }
10015 self.write_space();
10016 self.write_keyword("SORTKEY");
10017 self.write_space();
10018 if let Some(style) = this {
10019 self.write_keyword(style);
10020 } else if !expressions.is_empty() {
10021 self.write("(");
10022 for (i, expr) in expressions.iter().enumerate() {
10023 if i > 0 {
10024 self.write(", ");
10025 }
10026 self.generate_expression(expr)?;
10027 }
10028 self.write(")");
10029 }
10030 }
10031 AlterTableAction::AlterDistStyle { style, distkey } => {
10032 self.write_keyword("ALTER");
10034 self.write_space();
10035 self.write_keyword("DISTSTYLE");
10036 self.write_space();
10037 self.write_keyword(style);
10038 if let Some(col) = distkey {
10039 self.write_space();
10040 self.write_keyword("DISTKEY");
10041 self.write_space();
10042 self.generate_identifier(col)?;
10043 }
10044 }
10045 AlterTableAction::SetTableProperties { properties } => {
10046 self.write_keyword("SET TABLE PROPERTIES");
10048 self.write(" (");
10049 for (i, (key, value)) in properties.iter().enumerate() {
10050 if i > 0 {
10051 self.write(", ");
10052 }
10053 self.generate_expression(key)?;
10054 self.write(" = ");
10055 self.generate_expression(value)?;
10056 }
10057 self.write(")");
10058 }
10059 AlterTableAction::SetLocation { location } => {
10060 self.write_keyword("SET LOCATION");
10062 self.write_space();
10063 self.write("'");
10064 self.write(location);
10065 self.write("'");
10066 }
10067 AlterTableAction::SetFileFormat { format } => {
10068 self.write_keyword("SET FILE FORMAT");
10070 self.write_space();
10071 self.write_keyword(format);
10072 }
10073 AlterTableAction::ReplacePartition { partition, source } => {
10074 self.write_keyword("REPLACE PARTITION");
10076 self.write_space();
10077 self.generate_expression(partition)?;
10078 if let Some(src) = source {
10079 self.write_space();
10080 self.write_keyword("FROM");
10081 self.write_space();
10082 self.generate_expression(src)?;
10083 }
10084 }
10085 AlterTableAction::Raw { sql } => {
10086 self.write(sql);
10087 }
10088 }
10089 Ok(())
10090 }
10091
10092 fn generate_alter_column_action(&mut self, action: &AlterColumnAction) -> Result<()> {
10093 match action {
10094 AlterColumnAction::SetDataType {
10095 data_type,
10096 using,
10097 collate,
10098 } => {
10099 use crate::dialects::DialectType;
10100 let is_no_prefix = matches!(
10105 self.config.dialect,
10106 Some(DialectType::TSQL) | Some(DialectType::Fabric) | Some(DialectType::Hive)
10107 );
10108 let is_type_only = matches!(
10109 self.config.dialect,
10110 Some(DialectType::Redshift)
10111 | Some(DialectType::Spark)
10112 | Some(DialectType::Databricks)
10113 );
10114 if is_type_only {
10115 self.write_keyword("TYPE");
10116 self.write_space();
10117 } else if !is_no_prefix {
10118 self.write_keyword("SET DATA TYPE");
10119 self.write_space();
10120 }
10121 self.generate_data_type(data_type)?;
10122 if let Some(ref collation) = collate {
10123 self.write_space();
10124 self.write_keyword("COLLATE");
10125 self.write_space();
10126 self.write(collation);
10127 }
10128 if let Some(ref using_expr) = using {
10129 self.write_space();
10130 self.write_keyword("USING");
10131 self.write_space();
10132 self.generate_expression(using_expr)?;
10133 }
10134 }
10135 AlterColumnAction::SetDefault(expr) => {
10136 self.write_keyword("SET DEFAULT");
10137 self.write_space();
10138 self.generate_expression(expr)?;
10139 }
10140 AlterColumnAction::DropDefault => {
10141 self.write_keyword("DROP DEFAULT");
10142 }
10143 AlterColumnAction::SetNotNull => {
10144 self.write_keyword("SET NOT NULL");
10145 }
10146 AlterColumnAction::DropNotNull => {
10147 self.write_keyword("DROP NOT NULL");
10148 }
10149 AlterColumnAction::Comment(comment) => {
10150 self.write_keyword("COMMENT");
10151 self.write_space();
10152 self.generate_string_literal(comment)?;
10153 }
10154 AlterColumnAction::SetVisible => {
10155 self.write_keyword("SET VISIBLE");
10156 }
10157 AlterColumnAction::SetInvisible => {
10158 self.write_keyword("SET INVISIBLE");
10159 }
10160 }
10161 Ok(())
10162 }
10163
10164 fn generate_create_index(&mut self, ci: &CreateIndex) -> Result<()> {
10165 self.write_keyword("CREATE");
10166
10167 if ci.unique {
10168 self.write_space();
10169 self.write_keyword("UNIQUE");
10170 }
10171
10172 if let Some(ref clustered) = ci.clustered {
10174 self.write_space();
10175 self.write_keyword(clustered);
10176 }
10177
10178 self.write_space();
10179 self.write_keyword("INDEX");
10180
10181 if ci.concurrently {
10183 self.write_space();
10184 self.write_keyword("CONCURRENTLY");
10185 }
10186
10187 if ci.if_not_exists {
10188 self.write_space();
10189 self.write_keyword("IF NOT EXISTS");
10190 }
10191
10192 if !ci.name.name.is_empty() {
10194 self.write_space();
10195 self.generate_identifier(&ci.name)?;
10196 }
10197 self.write_space();
10198 self.write_keyword("ON");
10199 if matches!(self.config.dialect, Some(DialectType::Hive)) {
10201 self.write_space();
10202 self.write_keyword("TABLE");
10203 }
10204 self.write_space();
10205 self.generate_table(&ci.table)?;
10206
10207 if !ci.columns.is_empty() || ci.using.is_some() {
10210 let space_before_paren = false;
10211
10212 if let Some(ref using) = ci.using {
10213 self.write_space();
10214 self.write_keyword("USING");
10215 self.write_space();
10216 self.write(using);
10217 if space_before_paren {
10218 self.write(" (");
10219 } else {
10220 self.write("(");
10221 }
10222 } else {
10223 if space_before_paren {
10224 self.write(" (");
10225 } else {
10226 self.write("(");
10227 }
10228 }
10229 for (i, col) in ci.columns.iter().enumerate() {
10230 if i > 0 {
10231 self.write(", ");
10232 }
10233 self.generate_identifier(&col.column)?;
10234 if let Some(ref opclass) = col.opclass {
10235 self.write_space();
10236 self.write(opclass);
10237 }
10238 if col.desc {
10239 self.write_space();
10240 self.write_keyword("DESC");
10241 } else if col.asc {
10242 self.write_space();
10243 self.write_keyword("ASC");
10244 }
10245 if let Some(nulls_first) = col.nulls_first {
10246 self.write_space();
10247 self.write_keyword("NULLS");
10248 self.write_space();
10249 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
10250 }
10251 }
10252 self.write(")");
10253 }
10254
10255 if !ci.include_columns.is_empty() {
10257 self.write_space();
10258 self.write_keyword("INCLUDE");
10259 self.write(" (");
10260 for (i, col) in ci.include_columns.iter().enumerate() {
10261 if i > 0 {
10262 self.write(", ");
10263 }
10264 self.generate_identifier(col)?;
10265 }
10266 self.write(")");
10267 }
10268
10269 if !ci.with_options.is_empty() {
10271 self.write_space();
10272 self.write_keyword("WITH");
10273 self.write(" (");
10274 for (i, (key, value)) in ci.with_options.iter().enumerate() {
10275 if i > 0 {
10276 self.write(", ");
10277 }
10278 self.write(key);
10279 self.write("=");
10280 self.write(value);
10281 }
10282 self.write(")");
10283 }
10284
10285 if let Some(ref where_clause) = ci.where_clause {
10287 self.write_space();
10288 self.write_keyword("WHERE");
10289 self.write_space();
10290 self.generate_expression(where_clause)?;
10291 }
10292
10293 if let Some(ref on_fg) = ci.on_filegroup {
10295 self.write_space();
10296 self.write_keyword("ON");
10297 self.write_space();
10298 self.write(on_fg);
10299 }
10300
10301 Ok(())
10302 }
10303
10304 fn generate_drop_index(&mut self, di: &DropIndex) -> Result<()> {
10305 self.write_keyword("DROP INDEX");
10306
10307 if di.concurrently {
10308 self.write_space();
10309 self.write_keyword("CONCURRENTLY");
10310 }
10311
10312 if di.if_exists {
10313 self.write_space();
10314 self.write_keyword("IF EXISTS");
10315 }
10316
10317 self.write_space();
10318 self.generate_identifier(&di.name)?;
10319
10320 if let Some(ref table) = di.table {
10321 self.write_space();
10322 self.write_keyword("ON");
10323 self.write_space();
10324 self.generate_table(table)?;
10325 }
10326
10327 Ok(())
10328 }
10329
10330 fn generate_create_view(&mut self, cv: &CreateView) -> Result<()> {
10331 self.write_keyword("CREATE");
10332
10333 if let Some(ref algorithm) = cv.algorithm {
10335 self.write_space();
10336 self.write_keyword("ALGORITHM");
10337 self.write("=");
10338 self.write_keyword(algorithm);
10339 }
10340
10341 if let Some(ref definer) = cv.definer {
10343 self.write_space();
10344 self.write_keyword("DEFINER");
10345 self.write("=");
10346 self.write(definer);
10347 }
10348
10349 if cv.security_sql_style {
10351 if let Some(ref security) = cv.security {
10352 self.write_space();
10353 self.write_keyword("SQL SECURITY");
10354 self.write_space();
10355 match security {
10356 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
10357 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
10358 FunctionSecurity::None => self.write_keyword("NONE"),
10359 }
10360 }
10361 }
10362
10363 if cv.or_replace {
10364 self.write_space();
10365 self.write_keyword("OR REPLACE");
10366 }
10367
10368 if cv.temporary {
10369 self.write_space();
10370 self.write_keyword("TEMPORARY");
10371 }
10372
10373 if cv.materialized {
10374 self.write_space();
10375 self.write_keyword("MATERIALIZED");
10376 }
10377
10378 if cv.secure {
10380 self.write_space();
10381 self.write_keyword("SECURE");
10382 }
10383
10384 self.write_space();
10385 self.write_keyword("VIEW");
10386
10387 if cv.if_not_exists {
10388 self.write_space();
10389 self.write_keyword("IF NOT EXISTS");
10390 }
10391
10392 self.write_space();
10393 self.generate_table(&cv.name)?;
10394
10395 if let Some(ref on_cluster) = cv.on_cluster {
10397 self.write_space();
10398 self.generate_on_cluster(on_cluster)?;
10399 }
10400
10401 if let Some(ref to_table) = cv.to_table {
10403 self.write_space();
10404 self.write_keyword("TO");
10405 self.write_space();
10406 self.generate_table(to_table)?;
10407 }
10408
10409 if !cv.materialized {
10412 if !cv.columns.is_empty() {
10414 self.write(" (");
10415 for (i, col) in cv.columns.iter().enumerate() {
10416 if i > 0 {
10417 self.write(", ");
10418 }
10419 self.generate_identifier(&col.name)?;
10420 if !col.options.is_empty() {
10422 self.write_space();
10423 self.generate_options_clause(&col.options)?;
10424 }
10425 if let Some(ref comment) = col.comment {
10426 self.write_space();
10427 self.write_keyword("COMMENT");
10428 self.write_space();
10429 self.generate_string_literal(comment)?;
10430 }
10431 }
10432 self.write(")");
10433 }
10434
10435 if !cv.security_sql_style {
10437 if let Some(ref security) = cv.security {
10438 self.write_space();
10439 self.write_keyword("SECURITY");
10440 self.write_space();
10441 match security {
10442 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
10443 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
10444 FunctionSecurity::None => self.write_keyword("NONE"),
10445 }
10446 }
10447 }
10448
10449 if cv.copy_grants {
10451 self.write_space();
10452 self.write_keyword("COPY GRANTS");
10453 }
10454 } else {
10455 if cv.copy_grants {
10457 self.write_space();
10458 self.write_keyword("COPY GRANTS");
10459 }
10460
10461 if let Some(ref schema) = cv.schema {
10463 self.write(" (");
10464 for (i, expr) in schema.expressions.iter().enumerate() {
10465 if i > 0 {
10466 self.write(", ");
10467 }
10468 self.generate_expression(expr)?;
10469 }
10470 self.write(")");
10471 } else if !cv.columns.is_empty() {
10472 self.write(" (");
10474 for (i, col) in cv.columns.iter().enumerate() {
10475 if i > 0 {
10476 self.write(", ");
10477 }
10478 self.generate_identifier(&col.name)?;
10479 if !col.options.is_empty() {
10481 self.write_space();
10482 self.generate_options_clause(&col.options)?;
10483 }
10484 if let Some(ref comment) = col.comment {
10485 self.write_space();
10486 self.write_keyword("COMMENT");
10487 self.write_space();
10488 self.generate_string_literal(comment)?;
10489 }
10490 }
10491 self.write(")");
10492 }
10493
10494 if let Some(ref unique_key) = cv.unique_key {
10496 self.write_space();
10497 self.write_keyword("KEY");
10498 self.write(" (");
10499 for (i, expr) in unique_key.expressions.iter().enumerate() {
10500 if i > 0 {
10501 self.write(", ");
10502 }
10503 self.generate_expression(expr)?;
10504 }
10505 self.write(")");
10506 }
10507 }
10508
10509 if let Some(ref comment) = cv.comment {
10511 self.write_space();
10512 self.write_keyword("COMMENT");
10513 self.write("=");
10514 self.generate_string_literal(comment)?;
10515 }
10516
10517 if !cv.tags.is_empty() {
10519 self.write_space();
10520 self.write_keyword("TAG");
10521 self.write(" (");
10522 for (i, (name, value)) in cv.tags.iter().enumerate() {
10523 if i > 0 {
10524 self.write(", ");
10525 }
10526 self.write(name);
10527 self.write("='");
10528 self.write(value);
10529 self.write("'");
10530 }
10531 self.write(")");
10532 }
10533
10534 if !cv.options.is_empty() {
10536 self.write_space();
10537 self.generate_options_clause(&cv.options)?;
10538 }
10539
10540 if let Some(ref build) = cv.build {
10542 self.write_space();
10543 self.write_keyword("BUILD");
10544 self.write_space();
10545 self.write_keyword(build);
10546 }
10547
10548 if let Some(ref refresh) = cv.refresh {
10550 self.write_space();
10551 self.generate_refresh_trigger_property(refresh)?;
10552 }
10553
10554 if let Some(auto_refresh) = cv.auto_refresh {
10556 self.write_space();
10557 self.write_keyword("AUTO REFRESH");
10558 self.write_space();
10559 if auto_refresh {
10560 self.write_keyword("YES");
10561 } else {
10562 self.write_keyword("NO");
10563 }
10564 }
10565
10566 for prop in &cv.table_properties {
10568 self.write_space();
10569 self.generate_expression(prop)?;
10570 }
10571
10572 if !matches!(&cv.query, Expression::Null(_)) {
10574 self.write_space();
10575 self.write_keyword("AS");
10576 self.write_space();
10577
10578 if let Some(ref mode) = cv.locking_mode {
10580 self.write_keyword("LOCKING");
10581 self.write_space();
10582 self.write_keyword(mode);
10583 if let Some(ref access) = cv.locking_access {
10584 self.write_space();
10585 self.write_keyword("FOR");
10586 self.write_space();
10587 self.write_keyword(access);
10588 }
10589 self.write_space();
10590 }
10591
10592 if cv.query_parenthesized {
10593 self.write("(");
10594 }
10595 self.generate_expression(&cv.query)?;
10596 if cv.query_parenthesized {
10597 self.write(")");
10598 }
10599 }
10600
10601 if cv.no_schema_binding {
10603 self.write_space();
10604 self.write_keyword("WITH NO SCHEMA BINDING");
10605 }
10606
10607 Ok(())
10608 }
10609
10610 fn generate_drop_view(&mut self, dv: &DropView) -> Result<()> {
10611 self.write_keyword("DROP");
10612
10613 if dv.materialized {
10614 self.write_space();
10615 self.write_keyword("MATERIALIZED");
10616 }
10617
10618 self.write_space();
10619 self.write_keyword("VIEW");
10620
10621 if dv.if_exists {
10622 self.write_space();
10623 self.write_keyword("IF EXISTS");
10624 }
10625
10626 self.write_space();
10627 self.generate_table(&dv.name)?;
10628
10629 Ok(())
10630 }
10631
10632 fn generate_truncate(&mut self, tr: &Truncate) -> Result<()> {
10633 match tr.target {
10634 TruncateTarget::Database => self.write_keyword("TRUNCATE DATABASE"),
10635 TruncateTarget::Table => self.write_keyword("TRUNCATE TABLE"),
10636 }
10637 if tr.if_exists {
10638 self.write_space();
10639 self.write_keyword("IF EXISTS");
10640 }
10641 self.write_space();
10642 self.generate_table(&tr.table)?;
10643
10644 if let Some(ref on_cluster) = tr.on_cluster {
10646 self.write_space();
10647 self.generate_on_cluster(on_cluster)?;
10648 }
10649
10650 if !tr.extra_tables.is_empty() {
10652 let skip_first = if let Some(first) = tr.extra_tables.first() {
10654 first.table.name == tr.table.name && first.star
10655 } else {
10656 false
10657 };
10658
10659 let strip_star = matches!(
10661 self.config.dialect,
10662 Some(crate::dialects::DialectType::PostgreSQL)
10663 | Some(crate::dialects::DialectType::Redshift)
10664 );
10665 if skip_first && !strip_star {
10666 self.write("*");
10667 }
10668
10669 for (i, entry) in tr.extra_tables.iter().enumerate() {
10671 if i == 0 && skip_first {
10672 continue; }
10674 self.write(", ");
10675 self.generate_table(&entry.table)?;
10676 if entry.star && !strip_star {
10677 self.write("*");
10678 }
10679 }
10680 }
10681
10682 if let Some(identity) = &tr.identity {
10684 self.write_space();
10685 match identity {
10686 TruncateIdentity::Restart => self.write_keyword("RESTART IDENTITY"),
10687 TruncateIdentity::Continue => self.write_keyword("CONTINUE IDENTITY"),
10688 }
10689 }
10690
10691 if tr.cascade {
10692 self.write_space();
10693 self.write_keyword("CASCADE");
10694 }
10695
10696 if tr.restrict {
10697 self.write_space();
10698 self.write_keyword("RESTRICT");
10699 }
10700
10701 if let Some(ref partition) = tr.partition {
10703 self.write_space();
10704 self.generate_expression(partition)?;
10705 }
10706
10707 Ok(())
10708 }
10709
10710 fn generate_use(&mut self, u: &Use) -> Result<()> {
10711 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
10713 self.write_keyword("DATABASE");
10714 self.write_space();
10715 self.generate_identifier(&u.this)?;
10716 return Ok(());
10717 }
10718
10719 self.write_keyword("USE");
10720
10721 if let Some(kind) = &u.kind {
10722 self.write_space();
10723 match kind {
10724 UseKind::Database => self.write_keyword("DATABASE"),
10725 UseKind::Schema => self.write_keyword("SCHEMA"),
10726 UseKind::Role => self.write_keyword("ROLE"),
10727 UseKind::Warehouse => self.write_keyword("WAREHOUSE"),
10728 UseKind::Catalog => self.write_keyword("CATALOG"),
10729 UseKind::SecondaryRoles => self.write_keyword("SECONDARY ROLES"),
10730 }
10731 }
10732
10733 self.write_space();
10734 if matches!(&u.kind, Some(UseKind::SecondaryRoles)) {
10737 self.write(&u.this.name);
10738 } else {
10739 self.generate_identifier(&u.this)?;
10740 }
10741 Ok(())
10742 }
10743
10744 fn generate_cache(&mut self, c: &Cache) -> Result<()> {
10745 self.write_keyword("CACHE");
10746 if c.lazy {
10747 self.write_space();
10748 self.write_keyword("LAZY");
10749 }
10750 self.write_space();
10751 self.write_keyword("TABLE");
10752 self.write_space();
10753 self.generate_identifier(&c.table)?;
10754
10755 if !c.options.is_empty() {
10757 self.write_space();
10758 self.write_keyword("OPTIONS");
10759 self.write("(");
10760 for (i, (key, value)) in c.options.iter().enumerate() {
10761 if i > 0 {
10762 self.write(", ");
10763 }
10764 self.generate_expression(key)?;
10765 self.write(" = ");
10766 self.generate_expression(value)?;
10767 }
10768 self.write(")");
10769 }
10770
10771 if let Some(query) = &c.query {
10773 self.write_space();
10774 self.write_keyword("AS");
10775 self.write_space();
10776 self.generate_expression(query)?;
10777 }
10778
10779 Ok(())
10780 }
10781
10782 fn generate_uncache(&mut self, u: &Uncache) -> Result<()> {
10783 self.write_keyword("UNCACHE TABLE");
10784 if u.if_exists {
10785 self.write_space();
10786 self.write_keyword("IF EXISTS");
10787 }
10788 self.write_space();
10789 self.generate_identifier(&u.table)?;
10790 Ok(())
10791 }
10792
10793 fn generate_load_data(&mut self, l: &LoadData) -> Result<()> {
10794 self.write_keyword("LOAD DATA");
10795 if l.local {
10796 self.write_space();
10797 self.write_keyword("LOCAL");
10798 }
10799 self.write_space();
10800 self.write_keyword("INPATH");
10801 self.write_space();
10802 self.write("'");
10803 self.write(&l.inpath);
10804 self.write("'");
10805
10806 if l.overwrite {
10807 self.write_space();
10808 self.write_keyword("OVERWRITE");
10809 }
10810
10811 self.write_space();
10812 self.write_keyword("INTO TABLE");
10813 self.write_space();
10814 self.generate_expression(&l.table)?;
10815
10816 if !l.partition.is_empty() {
10818 self.write_space();
10819 self.write_keyword("PARTITION");
10820 self.write("(");
10821 for (i, (col, val)) in l.partition.iter().enumerate() {
10822 if i > 0 {
10823 self.write(", ");
10824 }
10825 self.generate_identifier(col)?;
10826 self.write(" = ");
10827 self.generate_expression(val)?;
10828 }
10829 self.write(")");
10830 }
10831
10832 if let Some(fmt) = &l.input_format {
10834 self.write_space();
10835 self.write_keyword("INPUTFORMAT");
10836 self.write_space();
10837 self.write("'");
10838 self.write(fmt);
10839 self.write("'");
10840 }
10841
10842 if let Some(serde) = &l.serde {
10844 self.write_space();
10845 self.write_keyword("SERDE");
10846 self.write_space();
10847 self.write("'");
10848 self.write(serde);
10849 self.write("'");
10850 }
10851
10852 Ok(())
10853 }
10854
10855 fn generate_pragma(&mut self, p: &Pragma) -> Result<()> {
10856 self.write_keyword("PRAGMA");
10857 self.write_space();
10858
10859 if let Some(schema) = &p.schema {
10861 self.generate_identifier(schema)?;
10862 self.write(".");
10863 }
10864
10865 self.generate_identifier(&p.name)?;
10867
10868 if let Some(value) = &p.value {
10870 self.write(" = ");
10871 self.generate_expression(value)?;
10872 } else if !p.args.is_empty() {
10873 self.write("(");
10874 for (i, arg) in p.args.iter().enumerate() {
10875 if i > 0 {
10876 self.write(", ");
10877 }
10878 self.generate_expression(arg)?;
10879 }
10880 self.write(")");
10881 }
10882
10883 Ok(())
10884 }
10885
10886 fn generate_grant(&mut self, g: &Grant) -> Result<()> {
10887 self.write_keyword("GRANT");
10888 self.write_space();
10889
10890 for (i, privilege) in g.privileges.iter().enumerate() {
10892 if i > 0 {
10893 self.write(", ");
10894 }
10895 self.write_keyword(&privilege.name);
10896 if !privilege.columns.is_empty() {
10898 self.write("(");
10899 for (j, col) in privilege.columns.iter().enumerate() {
10900 if j > 0 {
10901 self.write(", ");
10902 }
10903 self.write(col);
10904 }
10905 self.write(")");
10906 }
10907 }
10908
10909 self.write_space();
10910 self.write_keyword("ON");
10911 self.write_space();
10912
10913 if let Some(kind) = &g.kind {
10915 self.write_keyword(kind);
10916 self.write_space();
10917 }
10918
10919 {
10921 use crate::dialects::DialectType;
10922 let should_upper = matches!(
10923 self.config.dialect,
10924 Some(DialectType::PostgreSQL)
10925 | Some(DialectType::CockroachDB)
10926 | Some(DialectType::Materialize)
10927 | Some(DialectType::RisingWave)
10928 ) && (g.kind.as_deref() == Some("FUNCTION")
10929 || g.kind.as_deref() == Some("PROCEDURE"));
10930 if should_upper {
10931 use crate::expressions::Identifier;
10932 let upper_id = Identifier {
10933 name: g.securable.name.to_uppercase(),
10934 quoted: g.securable.quoted,
10935 ..g.securable.clone()
10936 };
10937 self.generate_identifier(&upper_id)?;
10938 } else {
10939 self.generate_identifier(&g.securable)?;
10940 }
10941 }
10942
10943 if !g.function_params.is_empty() {
10945 self.write("(");
10946 for (i, param) in g.function_params.iter().enumerate() {
10947 if i > 0 {
10948 self.write(", ");
10949 }
10950 self.write(param);
10951 }
10952 self.write(")");
10953 }
10954
10955 self.write_space();
10956 self.write_keyword("TO");
10957 self.write_space();
10958
10959 for (i, principal) in g.principals.iter().enumerate() {
10961 if i > 0 {
10962 self.write(", ");
10963 }
10964 if principal.is_role {
10965 self.write_keyword("ROLE");
10966 self.write_space();
10967 } else if principal.is_group {
10968 self.write_keyword("GROUP");
10969 self.write_space();
10970 }
10971 self.generate_identifier(&principal.name)?;
10972 }
10973
10974 if g.grant_option {
10976 self.write_space();
10977 self.write_keyword("WITH GRANT OPTION");
10978 }
10979
10980 if let Some(ref principal) = g.as_principal {
10982 self.write_space();
10983 self.write_keyword("AS");
10984 self.write_space();
10985 self.generate_identifier(principal)?;
10986 }
10987
10988 Ok(())
10989 }
10990
10991 fn generate_revoke(&mut self, r: &Revoke) -> Result<()> {
10992 self.write_keyword("REVOKE");
10993 self.write_space();
10994
10995 if r.grant_option {
10997 self.write_keyword("GRANT OPTION FOR");
10998 self.write_space();
10999 }
11000
11001 for (i, privilege) in r.privileges.iter().enumerate() {
11003 if i > 0 {
11004 self.write(", ");
11005 }
11006 self.write_keyword(&privilege.name);
11007 if !privilege.columns.is_empty() {
11009 self.write("(");
11010 for (j, col) in privilege.columns.iter().enumerate() {
11011 if j > 0 {
11012 self.write(", ");
11013 }
11014 self.write(col);
11015 }
11016 self.write(")");
11017 }
11018 }
11019
11020 self.write_space();
11021 self.write_keyword("ON");
11022 self.write_space();
11023
11024 if let Some(kind) = &r.kind {
11026 self.write_keyword(kind);
11027 self.write_space();
11028 }
11029
11030 {
11032 use crate::dialects::DialectType;
11033 let should_upper = matches!(
11034 self.config.dialect,
11035 Some(DialectType::PostgreSQL)
11036 | Some(DialectType::CockroachDB)
11037 | Some(DialectType::Materialize)
11038 | Some(DialectType::RisingWave)
11039 ) && (r.kind.as_deref() == Some("FUNCTION")
11040 || r.kind.as_deref() == Some("PROCEDURE"));
11041 if should_upper {
11042 use crate::expressions::Identifier;
11043 let upper_id = Identifier {
11044 name: r.securable.name.to_uppercase(),
11045 quoted: r.securable.quoted,
11046 ..r.securable.clone()
11047 };
11048 self.generate_identifier(&upper_id)?;
11049 } else {
11050 self.generate_identifier(&r.securable)?;
11051 }
11052 }
11053
11054 if !r.function_params.is_empty() {
11056 self.write("(");
11057 for (i, param) in r.function_params.iter().enumerate() {
11058 if i > 0 {
11059 self.write(", ");
11060 }
11061 self.write(param);
11062 }
11063 self.write(")");
11064 }
11065
11066 self.write_space();
11067 self.write_keyword("FROM");
11068 self.write_space();
11069
11070 for (i, principal) in r.principals.iter().enumerate() {
11072 if i > 0 {
11073 self.write(", ");
11074 }
11075 if principal.is_role {
11076 self.write_keyword("ROLE");
11077 self.write_space();
11078 } else if principal.is_group {
11079 self.write_keyword("GROUP");
11080 self.write_space();
11081 }
11082 self.generate_identifier(&principal.name)?;
11083 }
11084
11085 if r.cascade {
11087 self.write_space();
11088 self.write_keyword("CASCADE");
11089 } else if r.restrict {
11090 self.write_space();
11091 self.write_keyword("RESTRICT");
11092 }
11093
11094 Ok(())
11095 }
11096
11097 fn generate_comment(&mut self, c: &Comment) -> Result<()> {
11098 self.write_keyword("COMMENT");
11099
11100 if c.exists {
11102 self.write_space();
11103 self.write_keyword("IF EXISTS");
11104 }
11105
11106 self.write_space();
11107 self.write_keyword("ON");
11108
11109 if c.materialized {
11111 self.write_space();
11112 self.write_keyword("MATERIALIZED");
11113 }
11114
11115 self.write_space();
11116 self.write_keyword(&c.kind);
11117 self.write_space();
11118
11119 self.generate_expression(&c.this)?;
11121
11122 self.write_space();
11123 self.write_keyword("IS");
11124 self.write_space();
11125
11126 self.generate_expression(&c.expression)?;
11128
11129 Ok(())
11130 }
11131
11132 fn generate_set_statement(&mut self, s: &SetStatement) -> Result<()> {
11133 self.write_keyword("SET");
11134
11135 for (i, item) in s.items.iter().enumerate() {
11136 if i > 0 {
11137 self.write(",");
11138 }
11139 self.write_space();
11140
11141 if let Some(ref kind) = item.kind {
11143 self.write_keyword(kind);
11144 self.write_space();
11145 }
11146
11147 let name_str = match &item.name {
11149 Expression::Identifier(id) => Some(id.name.as_str()),
11150 _ => None,
11151 };
11152
11153 let is_transaction = name_str == Some("TRANSACTION");
11154 let is_character_set = name_str == Some("CHARACTER SET");
11155 let is_names = name_str == Some("NAMES");
11156 let is_collate = name_str == Some("COLLATE");
11157 let has_variable_kind = item.kind.as_deref() == Some("VARIABLE");
11158 let name_has_variable_prefix = name_str.map_or(false, |n| n.starts_with("VARIABLE "));
11159 let is_variable = has_variable_kind || name_has_variable_prefix;
11160 let is_value_only =
11161 matches!(&item.value, Expression::Identifier(id) if id.name.is_empty());
11162
11163 if is_transaction {
11164 self.write_keyword("TRANSACTION");
11166 if let Expression::Identifier(id) = &item.value {
11167 if !id.name.is_empty() {
11168 self.write_space();
11169 self.write(&id.name);
11170 }
11171 }
11172 } else if is_character_set {
11173 self.write_keyword("CHARACTER SET");
11175 self.write_space();
11176 self.generate_set_value(&item.value)?;
11177 } else if is_names {
11178 self.write_keyword("NAMES");
11180 self.write_space();
11181 self.generate_set_value(&item.value)?;
11182 } else if is_collate {
11183 self.write_keyword("COLLATE");
11185 self.write_space();
11186 self.generate_set_value(&item.value)?;
11187 } else if is_variable {
11188 if name_has_variable_prefix && !has_variable_kind {
11192 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
11193 self.write_keyword("VARIABLE");
11194 self.write_space();
11195 }
11196 }
11197 if let Some(ns) = name_str {
11199 let var_name = if name_has_variable_prefix {
11200 &ns["VARIABLE ".len()..]
11201 } else {
11202 ns
11203 };
11204 self.write(var_name);
11205 } else {
11206 self.generate_expression(&item.name)?;
11207 }
11208 self.write(" = ");
11209 self.generate_set_value(&item.value)?;
11210 } else if is_value_only {
11211 self.generate_expression(&item.name)?;
11213 } else if item.no_equals && matches!(self.config.dialect, Some(DialectType::TSQL)) {
11214 self.generate_expression(&item.name)?;
11216 self.write_space();
11217 self.generate_set_value(&item.value)?;
11218 } else {
11219 match &item.name {
11222 Expression::Identifier(id) => {
11223 self.write(&id.name);
11224 }
11225 _ => {
11226 self.generate_expression(&item.name)?;
11227 }
11228 }
11229 self.write(" = ");
11230 self.generate_set_value(&item.value)?;
11231 }
11232 }
11233
11234 Ok(())
11235 }
11236
11237 fn generate_set_value(&mut self, value: &Expression) -> Result<()> {
11240 if let Expression::Identifier(id) = value {
11241 match id.name.as_str() {
11242 "DEFAULT" | "ON" | "OFF" => {
11243 self.write_keyword(&id.name);
11244 return Ok(());
11245 }
11246 _ => {}
11247 }
11248 }
11249 self.generate_expression(value)
11250 }
11251
11252 fn generate_alter_view(&mut self, av: &AlterView) -> Result<()> {
11255 self.write_keyword("ALTER");
11256 if let Some(ref algorithm) = av.algorithm {
11258 self.write_space();
11259 self.write_keyword("ALGORITHM");
11260 self.write(" = ");
11261 self.write_keyword(algorithm);
11262 }
11263 if let Some(ref definer) = av.definer {
11264 self.write_space();
11265 self.write_keyword("DEFINER");
11266 self.write(" = ");
11267 self.write(definer);
11268 }
11269 if let Some(ref sql_security) = av.sql_security {
11270 self.write_space();
11271 self.write_keyword("SQL SECURITY");
11272 self.write(" = ");
11273 self.write_keyword(sql_security);
11274 }
11275 self.write_space();
11276 self.write_keyword("VIEW");
11277 self.write_space();
11278 self.generate_table(&av.name)?;
11279
11280 if !av.columns.is_empty() {
11282 self.write(" (");
11283 for (i, col) in av.columns.iter().enumerate() {
11284 if i > 0 {
11285 self.write(", ");
11286 }
11287 self.generate_identifier(&col.name)?;
11288 if let Some(ref comment) = col.comment {
11289 self.write_space();
11290 self.write_keyword("COMMENT");
11291 self.write(" ");
11292 self.generate_string_literal(comment)?;
11293 }
11294 }
11295 self.write(")");
11296 }
11297
11298 if let Some(ref opt) = av.with_option {
11300 self.write_space();
11301 self.write_keyword("WITH");
11302 self.write_space();
11303 self.write_keyword(opt);
11304 }
11305
11306 for action in &av.actions {
11307 self.write_space();
11308 match action {
11309 AlterViewAction::Rename(new_name) => {
11310 self.write_keyword("RENAME TO");
11311 self.write_space();
11312 self.generate_table(new_name)?;
11313 }
11314 AlterViewAction::OwnerTo(owner) => {
11315 self.write_keyword("OWNER TO");
11316 self.write_space();
11317 self.generate_identifier(owner)?;
11318 }
11319 AlterViewAction::SetSchema(schema) => {
11320 self.write_keyword("SET SCHEMA");
11321 self.write_space();
11322 self.generate_identifier(schema)?;
11323 }
11324 AlterViewAction::SetAuthorization(auth) => {
11325 self.write_keyword("SET AUTHORIZATION");
11326 self.write_space();
11327 self.write(auth);
11328 }
11329 AlterViewAction::AlterColumn { name, action } => {
11330 self.write_keyword("ALTER COLUMN");
11331 self.write_space();
11332 self.generate_identifier(name)?;
11333 self.write_space();
11334 self.generate_alter_column_action(action)?;
11335 }
11336 AlterViewAction::AsSelect(query) => {
11337 self.write_keyword("AS");
11338 self.write_space();
11339 self.generate_expression(query)?;
11340 }
11341 AlterViewAction::SetTblproperties(props) => {
11342 self.write_keyword("SET TBLPROPERTIES");
11343 self.write(" (");
11344 for (i, (key, value)) in props.iter().enumerate() {
11345 if i > 0 {
11346 self.write(", ");
11347 }
11348 self.generate_string_literal(key)?;
11349 self.write("=");
11350 self.generate_string_literal(value)?;
11351 }
11352 self.write(")");
11353 }
11354 AlterViewAction::UnsetTblproperties(keys) => {
11355 self.write_keyword("UNSET TBLPROPERTIES");
11356 self.write(" (");
11357 for (i, key) in keys.iter().enumerate() {
11358 if i > 0 {
11359 self.write(", ");
11360 }
11361 self.generate_string_literal(key)?;
11362 }
11363 self.write(")");
11364 }
11365 }
11366 }
11367
11368 Ok(())
11369 }
11370
11371 fn generate_alter_index(&mut self, ai: &AlterIndex) -> Result<()> {
11372 self.write_keyword("ALTER INDEX");
11373 self.write_space();
11374 self.generate_identifier(&ai.name)?;
11375
11376 if let Some(table) = &ai.table {
11377 self.write_space();
11378 self.write_keyword("ON");
11379 self.write_space();
11380 self.generate_table(table)?;
11381 }
11382
11383 for action in &ai.actions {
11384 self.write_space();
11385 match action {
11386 AlterIndexAction::Rename(new_name) => {
11387 self.write_keyword("RENAME TO");
11388 self.write_space();
11389 self.generate_identifier(new_name)?;
11390 }
11391 AlterIndexAction::SetTablespace(tablespace) => {
11392 self.write_keyword("SET TABLESPACE");
11393 self.write_space();
11394 self.generate_identifier(tablespace)?;
11395 }
11396 AlterIndexAction::Visible(visible) => {
11397 if *visible {
11398 self.write_keyword("VISIBLE");
11399 } else {
11400 self.write_keyword("INVISIBLE");
11401 }
11402 }
11403 }
11404 }
11405
11406 Ok(())
11407 }
11408
11409 fn generate_create_schema(&mut self, cs: &CreateSchema) -> Result<()> {
11410 for comment in &cs.leading_comments {
11412 self.write_formatted_comment(comment);
11413 self.write_space();
11414 }
11415
11416 let saved_athena_hive_context = self.athena_hive_context;
11418 if matches!(
11419 self.config.dialect,
11420 Some(crate::dialects::DialectType::Athena)
11421 ) {
11422 self.athena_hive_context = true;
11423 }
11424
11425 self.write_keyword("CREATE SCHEMA");
11426
11427 if cs.if_not_exists {
11428 self.write_space();
11429 self.write_keyword("IF NOT EXISTS");
11430 }
11431
11432 self.write_space();
11433 self.generate_identifier(&cs.name)?;
11434
11435 if let Some(ref clone_src) = cs.clone_from {
11436 self.write_keyword(" CLONE ");
11437 self.generate_identifier(clone_src)?;
11438 }
11439
11440 if let Some(ref at_clause) = cs.at_clause {
11441 self.write_space();
11442 self.generate_expression(at_clause)?;
11443 }
11444
11445 if let Some(auth) = &cs.authorization {
11446 self.write_space();
11447 self.write_keyword("AUTHORIZATION");
11448 self.write_space();
11449 self.generate_identifier(auth)?;
11450 }
11451
11452 let with_properties: Vec<_> = cs
11455 .properties
11456 .iter()
11457 .filter(|p| matches!(p, Expression::Property(_)))
11458 .collect();
11459 let other_properties: Vec<_> = cs
11460 .properties
11461 .iter()
11462 .filter(|p| !matches!(p, Expression::Property(_)))
11463 .collect();
11464
11465 if !with_properties.is_empty() {
11467 self.write_space();
11468 self.write_keyword("WITH");
11469 self.write(" (");
11470 for (i, prop) in with_properties.iter().enumerate() {
11471 if i > 0 {
11472 self.write(", ");
11473 }
11474 self.generate_expression(prop)?;
11475 }
11476 self.write(")");
11477 }
11478
11479 for prop in other_properties {
11481 self.write_space();
11482 self.generate_expression(prop)?;
11483 }
11484
11485 self.athena_hive_context = saved_athena_hive_context;
11487
11488 Ok(())
11489 }
11490
11491 fn generate_drop_schema(&mut self, ds: &DropSchema) -> Result<()> {
11492 self.write_keyword("DROP SCHEMA");
11493
11494 if ds.if_exists {
11495 self.write_space();
11496 self.write_keyword("IF EXISTS");
11497 }
11498
11499 self.write_space();
11500 self.generate_identifier(&ds.name)?;
11501
11502 if ds.cascade {
11503 self.write_space();
11504 self.write_keyword("CASCADE");
11505 }
11506
11507 Ok(())
11508 }
11509
11510 fn generate_drop_namespace(&mut self, dn: &DropNamespace) -> Result<()> {
11511 self.write_keyword("DROP NAMESPACE");
11512
11513 if dn.if_exists {
11514 self.write_space();
11515 self.write_keyword("IF EXISTS");
11516 }
11517
11518 self.write_space();
11519 self.generate_identifier(&dn.name)?;
11520
11521 if dn.cascade {
11522 self.write_space();
11523 self.write_keyword("CASCADE");
11524 }
11525
11526 Ok(())
11527 }
11528
11529 fn generate_create_database(&mut self, cd: &CreateDatabase) -> Result<()> {
11530 self.write_keyword("CREATE DATABASE");
11531
11532 if cd.if_not_exists {
11533 self.write_space();
11534 self.write_keyword("IF NOT EXISTS");
11535 }
11536
11537 self.write_space();
11538 self.generate_identifier(&cd.name)?;
11539
11540 if let Some(ref clone_src) = cd.clone_from {
11541 self.write_keyword(" CLONE ");
11542 self.generate_identifier(clone_src)?;
11543 }
11544
11545 if let Some(ref at_clause) = cd.at_clause {
11547 self.write_space();
11548 self.generate_expression(at_clause)?;
11549 }
11550
11551 for option in &cd.options {
11552 self.write_space();
11553 match option {
11554 DatabaseOption::CharacterSet(charset) => {
11555 self.write_keyword("CHARACTER SET");
11556 self.write(" = ");
11557 self.write(&format!("'{}'", charset));
11558 }
11559 DatabaseOption::Collate(collate) => {
11560 self.write_keyword("COLLATE");
11561 self.write(" = ");
11562 self.write(&format!("'{}'", collate));
11563 }
11564 DatabaseOption::Owner(owner) => {
11565 self.write_keyword("OWNER");
11566 self.write(" = ");
11567 self.generate_identifier(owner)?;
11568 }
11569 DatabaseOption::Template(template) => {
11570 self.write_keyword("TEMPLATE");
11571 self.write(" = ");
11572 self.generate_identifier(template)?;
11573 }
11574 DatabaseOption::Encoding(encoding) => {
11575 self.write_keyword("ENCODING");
11576 self.write(" = ");
11577 self.write(&format!("'{}'", encoding));
11578 }
11579 DatabaseOption::Location(location) => {
11580 self.write_keyword("LOCATION");
11581 self.write(" = ");
11582 self.write(&format!("'{}'", location));
11583 }
11584 }
11585 }
11586
11587 Ok(())
11588 }
11589
11590 fn generate_drop_database(&mut self, dd: &DropDatabase) -> Result<()> {
11591 self.write_keyword("DROP DATABASE");
11592
11593 if dd.if_exists {
11594 self.write_space();
11595 self.write_keyword("IF EXISTS");
11596 }
11597
11598 self.write_space();
11599 self.generate_identifier(&dd.name)?;
11600
11601 Ok(())
11602 }
11603
11604 fn generate_create_function(&mut self, cf: &CreateFunction) -> Result<()> {
11605 self.write_keyword("CREATE");
11606
11607 if cf.or_replace {
11608 self.write_space();
11609 self.write_keyword("OR REPLACE");
11610 }
11611
11612 if cf.temporary {
11613 self.write_space();
11614 self.write_keyword("TEMPORARY");
11615 }
11616
11617 self.write_space();
11618 if cf.is_table_function {
11619 self.write_keyword("TABLE FUNCTION");
11620 } else {
11621 self.write_keyword("FUNCTION");
11622 }
11623
11624 if cf.if_not_exists {
11625 self.write_space();
11626 self.write_keyword("IF NOT EXISTS");
11627 }
11628
11629 self.write_space();
11630 self.generate_table(&cf.name)?;
11631 if cf.has_parens {
11632 let func_multiline = self.config.pretty
11633 && matches!(
11634 self.config.dialect,
11635 Some(crate::dialects::DialectType::TSQL)
11636 | Some(crate::dialects::DialectType::Fabric)
11637 )
11638 && !cf.parameters.is_empty();
11639 if func_multiline {
11640 self.write("(\n");
11641 self.indent_level += 2;
11642 self.write_indent();
11643 self.generate_function_parameters(&cf.parameters)?;
11644 self.write("\n");
11645 self.indent_level -= 2;
11646 self.write(")");
11647 } else {
11648 self.write("(");
11649 self.generate_function_parameters(&cf.parameters)?;
11650 self.write(")");
11651 }
11652 }
11653
11654 let use_multiline = self.config.pretty
11657 && matches!(
11658 self.config.dialect,
11659 Some(crate::dialects::DialectType::BigQuery)
11660 | Some(crate::dialects::DialectType::TSQL)
11661 | Some(crate::dialects::DialectType::Fabric)
11662 );
11663
11664 if cf.language_first {
11665 if let Some(lang) = &cf.language {
11667 if use_multiline {
11668 self.write_newline();
11669 } else {
11670 self.write_space();
11671 }
11672 self.write_keyword("LANGUAGE");
11673 self.write_space();
11674 self.write(lang);
11675 }
11676
11677 if let Some(sql_data) = &cf.sql_data_access {
11679 self.write_space();
11680 match sql_data {
11681 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
11682 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
11683 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
11684 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
11685 }
11686 }
11687
11688 if let Some(ref rtb) = cf.returns_table_body {
11689 if use_multiline {
11690 self.write_newline();
11691 } else {
11692 self.write_space();
11693 }
11694 self.write_keyword("RETURNS");
11695 self.write_space();
11696 self.write(rtb);
11697 } else if let Some(return_type) = &cf.return_type {
11698 if use_multiline {
11699 self.write_newline();
11700 } else {
11701 self.write_space();
11702 }
11703 self.write_keyword("RETURNS");
11704 self.write_space();
11705 self.generate_data_type(return_type)?;
11706 }
11707 } else {
11708 let is_duckdb = matches!(
11711 self.config.dialect,
11712 Some(crate::dialects::DialectType::DuckDB)
11713 );
11714 if let Some(ref rtb) = cf.returns_table_body {
11715 if !(is_duckdb && rtb.is_empty()) {
11716 if use_multiline {
11717 self.write_newline();
11718 } else {
11719 self.write_space();
11720 }
11721 self.write_keyword("RETURNS");
11722 self.write_space();
11723 self.write(rtb);
11724 }
11725 } else if let Some(return_type) = &cf.return_type {
11726 if use_multiline {
11727 self.write_newline();
11728 } else {
11729 self.write_space();
11730 }
11731 self.write_keyword("RETURNS");
11732 self.write_space();
11733 self.generate_data_type(return_type)?;
11734 }
11735 }
11736
11737 if !cf.property_order.is_empty() {
11739 let is_bigquery = matches!(
11741 self.config.dialect,
11742 Some(crate::dialects::DialectType::BigQuery)
11743 );
11744 let property_order = if is_bigquery {
11745 let mut reordered = Vec::new();
11747 let mut has_as = false;
11748 let mut has_options = false;
11749 for prop in &cf.property_order {
11750 match prop {
11751 FunctionPropertyKind::As => has_as = true,
11752 FunctionPropertyKind::Options => has_options = true,
11753 _ => {}
11754 }
11755 }
11756 if has_as && has_options {
11757 for prop in &cf.property_order {
11759 if *prop != FunctionPropertyKind::As
11760 && *prop != FunctionPropertyKind::Options
11761 {
11762 reordered.push(*prop);
11763 }
11764 }
11765 reordered.push(FunctionPropertyKind::Options);
11766 reordered.push(FunctionPropertyKind::As);
11767 reordered
11768 } else {
11769 cf.property_order.clone()
11770 }
11771 } else {
11772 cf.property_order.clone()
11773 };
11774
11775 for prop in &property_order {
11776 match prop {
11777 FunctionPropertyKind::Set => {
11778 self.generate_function_set_options(cf)?;
11779 }
11780 FunctionPropertyKind::As => {
11781 self.generate_function_body(cf)?;
11782 }
11783 FunctionPropertyKind::Language => {
11784 if !cf.language_first {
11785 if let Some(lang) = &cf.language {
11787 let use_multiline = self.config.pretty
11789 && matches!(
11790 self.config.dialect,
11791 Some(crate::dialects::DialectType::BigQuery)
11792 );
11793 if use_multiline {
11794 self.write_newline();
11795 } else {
11796 self.write_space();
11797 }
11798 self.write_keyword("LANGUAGE");
11799 self.write_space();
11800 self.write(lang);
11801 }
11802 }
11803 }
11804 FunctionPropertyKind::Determinism => {
11805 self.generate_function_determinism(cf)?;
11806 }
11807 FunctionPropertyKind::NullInput => {
11808 self.generate_function_null_input(cf)?;
11809 }
11810 FunctionPropertyKind::Security => {
11811 self.generate_function_security(cf)?;
11812 }
11813 FunctionPropertyKind::SqlDataAccess => {
11814 if !cf.language_first {
11815 self.generate_function_sql_data_access(cf)?;
11817 }
11818 }
11819 FunctionPropertyKind::Options => {
11820 if !cf.options.is_empty() {
11821 self.write_space();
11822 self.generate_options_clause(&cf.options)?;
11823 }
11824 }
11825 FunctionPropertyKind::Environment => {
11826 if !cf.environment.is_empty() {
11827 self.write_space();
11828 self.generate_environment_clause(&cf.environment)?;
11829 }
11830 }
11831 }
11832 }
11833
11834 if !cf.options.is_empty() && !cf.property_order.contains(&FunctionPropertyKind::Options)
11836 {
11837 self.write_space();
11838 self.generate_options_clause(&cf.options)?;
11839 }
11840
11841 if !cf.environment.is_empty()
11843 && !cf
11844 .property_order
11845 .contains(&FunctionPropertyKind::Environment)
11846 {
11847 self.write_space();
11848 self.generate_environment_clause(&cf.environment)?;
11849 }
11850 } else {
11851 if matches!(
11854 self.config.dialect,
11855 Some(crate::dialects::DialectType::BigQuery)
11856 ) {
11857 self.generate_function_determinism(cf)?;
11858 }
11859
11860 let use_multiline = self.config.pretty
11862 && matches!(
11863 self.config.dialect,
11864 Some(crate::dialects::DialectType::BigQuery)
11865 );
11866
11867 if !cf.language_first {
11868 if let Some(lang) = &cf.language {
11869 if use_multiline {
11870 self.write_newline();
11871 } else {
11872 self.write_space();
11873 }
11874 self.write_keyword("LANGUAGE");
11875 self.write_space();
11876 self.write(lang);
11877 }
11878
11879 self.generate_function_sql_data_access(cf)?;
11881 }
11882
11883 if !matches!(
11885 self.config.dialect,
11886 Some(crate::dialects::DialectType::BigQuery)
11887 ) {
11888 self.generate_function_determinism(cf)?;
11889 }
11890
11891 self.generate_function_null_input(cf)?;
11892 self.generate_function_security(cf)?;
11893 self.generate_function_set_options(cf)?;
11894
11895 if !cf.options.is_empty() {
11897 self.write_space();
11898 self.generate_options_clause(&cf.options)?;
11899 }
11900
11901 if !cf.environment.is_empty() {
11903 self.write_space();
11904 self.generate_environment_clause(&cf.environment)?;
11905 }
11906
11907 self.generate_function_body(cf)?;
11908 }
11909
11910 Ok(())
11911 }
11912
11913 fn generate_function_set_options(&mut self, cf: &CreateFunction) -> Result<()> {
11915 for opt in &cf.set_options {
11916 self.write_space();
11917 self.write_keyword("SET");
11918 self.write_space();
11919 self.write(&opt.name);
11920 match &opt.value {
11921 FunctionSetValue::Value { value, use_to } => {
11922 if *use_to {
11923 self.write(" TO ");
11924 } else {
11925 self.write(" = ");
11926 }
11927 self.write(value);
11928 }
11929 FunctionSetValue::FromCurrent => {
11930 self.write_space();
11931 self.write_keyword("FROM CURRENT");
11932 }
11933 }
11934 }
11935 Ok(())
11936 }
11937
11938 fn generate_function_body(&mut self, cf: &CreateFunction) -> Result<()> {
11940 if let Some(body) = &cf.body {
11941 self.write_space();
11943 let use_multiline = self.config.pretty
11945 && matches!(
11946 self.config.dialect,
11947 Some(crate::dialects::DialectType::BigQuery)
11948 );
11949 match body {
11950 FunctionBody::Block(block) => {
11951 self.write_keyword("AS");
11952 if matches!(
11953 self.config.dialect,
11954 Some(crate::dialects::DialectType::TSQL)
11955 ) {
11956 self.write(" BEGIN ");
11957 self.write(block);
11958 self.write(" END");
11959 } else if matches!(
11960 self.config.dialect,
11961 Some(crate::dialects::DialectType::PostgreSQL)
11962 ) {
11963 self.write(" $$");
11964 self.write(block);
11965 self.write("$$");
11966 } else {
11967 let escaped = self.escape_block_for_single_quote(block);
11969 if use_multiline {
11971 self.write_newline();
11972 } else {
11973 self.write(" ");
11974 }
11975 self.write("'");
11976 self.write(&escaped);
11977 self.write("'");
11978 }
11979 }
11980 FunctionBody::StringLiteral(s) => {
11981 self.write_keyword("AS");
11982 if use_multiline {
11984 self.write_newline();
11985 } else {
11986 self.write(" ");
11987 }
11988 self.write("'");
11989 self.write(s);
11990 self.write("'");
11991 }
11992 FunctionBody::Expression(expr) => {
11993 self.write_keyword("AS");
11994 self.write_space();
11995 self.generate_expression(expr)?;
11996 }
11997 FunctionBody::External(name) => {
11998 self.write_keyword("EXTERNAL NAME");
11999 self.write(" '");
12000 self.write(name);
12001 self.write("'");
12002 }
12003 FunctionBody::Return(expr) => {
12004 if matches!(
12005 self.config.dialect,
12006 Some(crate::dialects::DialectType::DuckDB)
12007 ) {
12008 self.write_keyword("AS");
12010 self.write_space();
12011 if cf.returns_table_body.is_some() {
12013 self.write_keyword("TABLE");
12014 self.write_space();
12015 }
12016 self.generate_expression(expr)?;
12017 } else {
12018 if self.config.create_function_return_as {
12019 self.write_keyword("AS");
12020 if self.config.pretty
12022 && matches!(
12023 self.config.dialect,
12024 Some(crate::dialects::DialectType::TSQL)
12025 | Some(crate::dialects::DialectType::Fabric)
12026 )
12027 {
12028 self.write_newline();
12029 } else {
12030 self.write_space();
12031 }
12032 }
12033 self.write_keyword("RETURN");
12034 self.write_space();
12035 self.generate_expression(expr)?;
12036 }
12037 }
12038 FunctionBody::Statements(stmts) => {
12039 self.write_keyword("AS");
12040 self.write(" BEGIN ");
12041 for (i, stmt) in stmts.iter().enumerate() {
12042 if i > 0 {
12043 self.write(" ");
12044 }
12045 self.generate_expression(stmt)?;
12046 }
12047 self.write(" END");
12048 }
12049 FunctionBody::DollarQuoted { content, tag } => {
12050 self.write_keyword("AS");
12051 self.write(" ");
12052 let supports_dollar_quoting = matches!(
12054 self.config.dialect,
12055 Some(crate::dialects::DialectType::PostgreSQL)
12056 | Some(crate::dialects::DialectType::Databricks)
12057 | Some(crate::dialects::DialectType::Redshift)
12058 | Some(crate::dialects::DialectType::DuckDB)
12059 );
12060 if supports_dollar_quoting {
12061 self.write("$");
12063 if let Some(t) = tag {
12064 self.write(t);
12065 }
12066 self.write("$");
12067 self.write(content);
12068 self.write("$");
12069 if let Some(t) = tag {
12070 self.write(t);
12071 }
12072 self.write("$");
12073 } else {
12074 let escaped = self.escape_block_for_single_quote(content);
12076 self.write("'");
12077 self.write(&escaped);
12078 self.write("'");
12079 }
12080 }
12081 }
12082 }
12083 Ok(())
12084 }
12085
12086 fn generate_function_determinism(&mut self, cf: &CreateFunction) -> Result<()> {
12088 if let Some(det) = cf.deterministic {
12089 self.write_space();
12090 if matches!(
12091 self.config.dialect,
12092 Some(crate::dialects::DialectType::BigQuery)
12093 ) {
12094 if det {
12096 self.write_keyword("DETERMINISTIC");
12097 } else {
12098 self.write_keyword("NOT DETERMINISTIC");
12099 }
12100 } else {
12101 if det {
12103 self.write_keyword("IMMUTABLE");
12104 } else {
12105 self.write_keyword("VOLATILE");
12106 }
12107 }
12108 }
12109 Ok(())
12110 }
12111
12112 fn generate_function_null_input(&mut self, cf: &CreateFunction) -> Result<()> {
12114 if let Some(returns_null) = cf.returns_null_on_null_input {
12115 self.write_space();
12116 if returns_null {
12117 if cf.strict {
12118 self.write_keyword("STRICT");
12119 } else {
12120 self.write_keyword("RETURNS NULL ON NULL INPUT");
12121 }
12122 } else {
12123 self.write_keyword("CALLED ON NULL INPUT");
12124 }
12125 }
12126 Ok(())
12127 }
12128
12129 fn generate_function_security(&mut self, cf: &CreateFunction) -> Result<()> {
12131 if let Some(security) = &cf.security {
12132 self.write_space();
12133 self.write_keyword("SECURITY");
12134 self.write_space();
12135 match security {
12136 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
12137 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
12138 FunctionSecurity::None => self.write_keyword("NONE"),
12139 }
12140 }
12141 Ok(())
12142 }
12143
12144 fn generate_function_sql_data_access(&mut self, cf: &CreateFunction) -> Result<()> {
12146 if let Some(sql_data) = &cf.sql_data_access {
12147 self.write_space();
12148 match sql_data {
12149 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
12150 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
12151 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
12152 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
12153 }
12154 }
12155 Ok(())
12156 }
12157
12158 fn generate_function_parameters(&mut self, params: &[FunctionParameter]) -> Result<()> {
12159 for (i, param) in params.iter().enumerate() {
12160 if i > 0 {
12161 self.write(", ");
12162 }
12163
12164 if let Some(mode) = ¶m.mode {
12165 if let Some(text) = ¶m.mode_text {
12166 self.write(text);
12167 } else {
12168 match mode {
12169 ParameterMode::In => self.write_keyword("IN"),
12170 ParameterMode::Out => self.write_keyword("OUT"),
12171 ParameterMode::InOut => self.write_keyword("INOUT"),
12172 ParameterMode::Variadic => self.write_keyword("VARIADIC"),
12173 }
12174 }
12175 self.write_space();
12176 }
12177
12178 if let Some(name) = ¶m.name {
12179 self.generate_identifier(name)?;
12180 let skip_type =
12182 matches!(¶m.data_type, DataType::Custom { name } if name.is_empty());
12183 if !skip_type {
12184 self.write_space();
12185 self.generate_data_type(¶m.data_type)?;
12186 }
12187 } else {
12188 self.generate_data_type(¶m.data_type)?;
12189 }
12190
12191 if let Some(default) = ¶m.default {
12192 if self.config.parameter_default_equals {
12193 self.write(" = ");
12194 } else {
12195 self.write(" DEFAULT ");
12196 }
12197 self.generate_expression(default)?;
12198 }
12199 }
12200
12201 Ok(())
12202 }
12203
12204 fn generate_drop_function(&mut self, df: &DropFunction) -> Result<()> {
12205 self.write_keyword("DROP FUNCTION");
12206
12207 if df.if_exists {
12208 self.write_space();
12209 self.write_keyword("IF EXISTS");
12210 }
12211
12212 self.write_space();
12213 self.generate_table(&df.name)?;
12214
12215 if let Some(params) = &df.parameters {
12216 self.write(" (");
12217 for (i, dt) in params.iter().enumerate() {
12218 if i > 0 {
12219 self.write(", ");
12220 }
12221 self.generate_data_type(dt)?;
12222 }
12223 self.write(")");
12224 }
12225
12226 if df.cascade {
12227 self.write_space();
12228 self.write_keyword("CASCADE");
12229 }
12230
12231 Ok(())
12232 }
12233
12234 fn generate_create_procedure(&mut self, cp: &CreateProcedure) -> Result<()> {
12235 self.write_keyword("CREATE");
12236
12237 if cp.or_replace {
12238 self.write_space();
12239 self.write_keyword("OR REPLACE");
12240 }
12241
12242 self.write_space();
12243 if cp.use_proc_keyword {
12244 self.write_keyword("PROC");
12245 } else {
12246 self.write_keyword("PROCEDURE");
12247 }
12248
12249 if cp.if_not_exists {
12250 self.write_space();
12251 self.write_keyword("IF NOT EXISTS");
12252 }
12253
12254 self.write_space();
12255 self.generate_table(&cp.name)?;
12256 if cp.has_parens {
12257 self.write("(");
12258 self.generate_function_parameters(&cp.parameters)?;
12259 self.write(")");
12260 } else if !cp.parameters.is_empty() {
12261 self.write_space();
12263 self.generate_function_parameters(&cp.parameters)?;
12264 }
12265
12266 if let Some(return_type) = &cp.return_type {
12268 self.write_space();
12269 self.write_keyword("RETURNS");
12270 self.write_space();
12271 self.generate_data_type(return_type)?;
12272 }
12273
12274 if let Some(execute_as) = &cp.execute_as {
12276 self.write_space();
12277 self.write_keyword("EXECUTE AS");
12278 self.write_space();
12279 self.write_keyword(execute_as);
12280 }
12281
12282 if let Some(lang) = &cp.language {
12283 self.write_space();
12284 self.write_keyword("LANGUAGE");
12285 self.write_space();
12286 self.write(lang);
12287 }
12288
12289 if let Some(security) = &cp.security {
12290 self.write_space();
12291 self.write_keyword("SECURITY");
12292 self.write_space();
12293 match security {
12294 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
12295 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
12296 FunctionSecurity::None => self.write_keyword("NONE"),
12297 }
12298 }
12299
12300 if !cp.with_options.is_empty() {
12302 self.write_space();
12303 self.write_keyword("WITH");
12304 self.write_space();
12305 for (i, opt) in cp.with_options.iter().enumerate() {
12306 if i > 0 {
12307 self.write(", ");
12308 }
12309 self.write(opt);
12310 }
12311 }
12312
12313 if let Some(body) = &cp.body {
12314 self.write_space();
12315 match body {
12316 FunctionBody::Block(block) => {
12317 self.write_keyword("AS");
12318 if matches!(
12319 self.config.dialect,
12320 Some(crate::dialects::DialectType::TSQL)
12321 ) {
12322 self.write(" BEGIN ");
12323 self.write(block);
12324 self.write(" END");
12325 } else if matches!(
12326 self.config.dialect,
12327 Some(crate::dialects::DialectType::PostgreSQL)
12328 ) {
12329 self.write(" $$");
12330 self.write(block);
12331 self.write("$$");
12332 } else {
12333 let escaped = self.escape_block_for_single_quote(block);
12335 self.write(" '");
12336 self.write(&escaped);
12337 self.write("'");
12338 }
12339 }
12340 FunctionBody::StringLiteral(s) => {
12341 self.write_keyword("AS");
12342 self.write(" '");
12343 self.write(s);
12344 self.write("'");
12345 }
12346 FunctionBody::Expression(expr) => {
12347 self.write_keyword("AS");
12348 self.write_space();
12349 self.generate_expression(expr)?;
12350 }
12351 FunctionBody::External(name) => {
12352 self.write_keyword("EXTERNAL NAME");
12353 self.write(" '");
12354 self.write(name);
12355 self.write("'");
12356 }
12357 FunctionBody::Return(expr) => {
12358 self.write_keyword("RETURN");
12359 self.write_space();
12360 self.generate_expression(expr)?;
12361 }
12362 FunctionBody::Statements(stmts) => {
12363 self.write_keyword("AS");
12364 self.write(" BEGIN ");
12365 for (i, stmt) in stmts.iter().enumerate() {
12366 if i > 0 {
12367 self.write(" ");
12368 }
12369 self.generate_expression(stmt)?;
12370 }
12371 self.write(" END");
12372 }
12373 FunctionBody::DollarQuoted { content, tag } => {
12374 self.write_keyword("AS");
12375 self.write(" ");
12376 let supports_dollar_quoting = matches!(
12378 self.config.dialect,
12379 Some(crate::dialects::DialectType::PostgreSQL)
12380 | Some(crate::dialects::DialectType::Databricks)
12381 | Some(crate::dialects::DialectType::Redshift)
12382 | Some(crate::dialects::DialectType::DuckDB)
12383 );
12384 if supports_dollar_quoting {
12385 self.write("$");
12387 if let Some(t) = tag {
12388 self.write(t);
12389 }
12390 self.write("$");
12391 self.write(content);
12392 self.write("$");
12393 if let Some(t) = tag {
12394 self.write(t);
12395 }
12396 self.write("$");
12397 } else {
12398 let escaped = self.escape_block_for_single_quote(content);
12400 self.write("'");
12401 self.write(&escaped);
12402 self.write("'");
12403 }
12404 }
12405 }
12406 }
12407
12408 Ok(())
12409 }
12410
12411 fn generate_drop_procedure(&mut self, dp: &DropProcedure) -> Result<()> {
12412 self.write_keyword("DROP PROCEDURE");
12413
12414 if dp.if_exists {
12415 self.write_space();
12416 self.write_keyword("IF EXISTS");
12417 }
12418
12419 self.write_space();
12420 self.generate_table(&dp.name)?;
12421
12422 if let Some(params) = &dp.parameters {
12423 self.write(" (");
12424 for (i, dt) in params.iter().enumerate() {
12425 if i > 0 {
12426 self.write(", ");
12427 }
12428 self.generate_data_type(dt)?;
12429 }
12430 self.write(")");
12431 }
12432
12433 if dp.cascade {
12434 self.write_space();
12435 self.write_keyword("CASCADE");
12436 }
12437
12438 Ok(())
12439 }
12440
12441 fn generate_create_sequence(&mut self, cs: &CreateSequence) -> Result<()> {
12442 self.write_keyword("CREATE");
12443
12444 if cs.or_replace {
12445 self.write_space();
12446 self.write_keyword("OR REPLACE");
12447 }
12448
12449 if cs.temporary {
12450 self.write_space();
12451 self.write_keyword("TEMPORARY");
12452 }
12453
12454 self.write_space();
12455 self.write_keyword("SEQUENCE");
12456
12457 if cs.if_not_exists {
12458 self.write_space();
12459 self.write_keyword("IF NOT EXISTS");
12460 }
12461
12462 self.write_space();
12463 self.generate_table(&cs.name)?;
12464
12465 if let Some(as_type) = &cs.as_type {
12467 self.write_space();
12468 self.write_keyword("AS");
12469 self.write_space();
12470 self.generate_data_type(as_type)?;
12471 }
12472
12473 if let Some(comment) = &cs.comment {
12475 self.write_space();
12476 self.write_keyword("COMMENT");
12477 self.write("=");
12478 self.generate_string_literal(comment)?;
12479 }
12480
12481 if !cs.property_order.is_empty() {
12483 for prop in &cs.property_order {
12484 match prop {
12485 SeqPropKind::Start => {
12486 if let Some(start) = cs.start {
12487 self.write_space();
12488 self.write_keyword("START WITH");
12489 self.write(&format!(" {}", start));
12490 }
12491 }
12492 SeqPropKind::Increment => {
12493 if let Some(inc) = cs.increment {
12494 self.write_space();
12495 self.write_keyword("INCREMENT BY");
12496 self.write(&format!(" {}", inc));
12497 }
12498 }
12499 SeqPropKind::Minvalue => {
12500 if let Some(min) = &cs.minvalue {
12501 self.write_space();
12502 match min {
12503 SequenceBound::Value(v) => {
12504 self.write_keyword("MINVALUE");
12505 self.write(&format!(" {}", v));
12506 }
12507 SequenceBound::None => {
12508 self.write_keyword("NO MINVALUE");
12509 }
12510 }
12511 }
12512 }
12513 SeqPropKind::Maxvalue => {
12514 if let Some(max) = &cs.maxvalue {
12515 self.write_space();
12516 match max {
12517 SequenceBound::Value(v) => {
12518 self.write_keyword("MAXVALUE");
12519 self.write(&format!(" {}", v));
12520 }
12521 SequenceBound::None => {
12522 self.write_keyword("NO MAXVALUE");
12523 }
12524 }
12525 }
12526 }
12527 SeqPropKind::Cache => {
12528 if let Some(cache) = cs.cache {
12529 self.write_space();
12530 self.write_keyword("CACHE");
12531 self.write(&format!(" {}", cache));
12532 }
12533 }
12534 SeqPropKind::NoCache => {
12535 self.write_space();
12536 self.write_keyword("NO CACHE");
12537 }
12538 SeqPropKind::NoCacheWord => {
12539 self.write_space();
12540 self.write_keyword("NOCACHE");
12541 }
12542 SeqPropKind::Cycle => {
12543 self.write_space();
12544 self.write_keyword("CYCLE");
12545 }
12546 SeqPropKind::NoCycle => {
12547 self.write_space();
12548 self.write_keyword("NO CYCLE");
12549 }
12550 SeqPropKind::NoCycleWord => {
12551 self.write_space();
12552 self.write_keyword("NOCYCLE");
12553 }
12554 SeqPropKind::OwnedBy => {
12555 if !cs.owned_by_none {
12557 if let Some(owned) = &cs.owned_by {
12558 self.write_space();
12559 self.write_keyword("OWNED BY");
12560 self.write_space();
12561 self.generate_table(owned)?;
12562 }
12563 }
12564 }
12565 SeqPropKind::Order => {
12566 self.write_space();
12567 self.write_keyword("ORDER");
12568 }
12569 SeqPropKind::NoOrder => {
12570 self.write_space();
12571 self.write_keyword("NOORDER");
12572 }
12573 SeqPropKind::Comment => {
12574 }
12576 SeqPropKind::Sharing => {
12577 if let Some(val) = &cs.sharing {
12578 self.write_space();
12579 self.write(&format!("SHARING={}", val));
12580 }
12581 }
12582 SeqPropKind::Keep => {
12583 self.write_space();
12584 self.write_keyword("KEEP");
12585 }
12586 SeqPropKind::NoKeep => {
12587 self.write_space();
12588 self.write_keyword("NOKEEP");
12589 }
12590 SeqPropKind::Scale => {
12591 self.write_space();
12592 self.write_keyword("SCALE");
12593 if let Some(modifier) = &cs.scale_modifier {
12594 if !modifier.is_empty() {
12595 self.write_space();
12596 self.write_keyword(modifier);
12597 }
12598 }
12599 }
12600 SeqPropKind::NoScale => {
12601 self.write_space();
12602 self.write_keyword("NOSCALE");
12603 }
12604 SeqPropKind::Shard => {
12605 self.write_space();
12606 self.write_keyword("SHARD");
12607 if let Some(modifier) = &cs.shard_modifier {
12608 if !modifier.is_empty() {
12609 self.write_space();
12610 self.write_keyword(modifier);
12611 }
12612 }
12613 }
12614 SeqPropKind::NoShard => {
12615 self.write_space();
12616 self.write_keyword("NOSHARD");
12617 }
12618 SeqPropKind::Session => {
12619 self.write_space();
12620 self.write_keyword("SESSION");
12621 }
12622 SeqPropKind::Global => {
12623 self.write_space();
12624 self.write_keyword("GLOBAL");
12625 }
12626 SeqPropKind::NoMinvalueWord => {
12627 self.write_space();
12628 self.write_keyword("NOMINVALUE");
12629 }
12630 SeqPropKind::NoMaxvalueWord => {
12631 self.write_space();
12632 self.write_keyword("NOMAXVALUE");
12633 }
12634 }
12635 }
12636 } else {
12637 if let Some(inc) = cs.increment {
12639 self.write_space();
12640 self.write_keyword("INCREMENT BY");
12641 self.write(&format!(" {}", inc));
12642 }
12643
12644 if let Some(min) = &cs.minvalue {
12645 self.write_space();
12646 match min {
12647 SequenceBound::Value(v) => {
12648 self.write_keyword("MINVALUE");
12649 self.write(&format!(" {}", v));
12650 }
12651 SequenceBound::None => {
12652 self.write_keyword("NO MINVALUE");
12653 }
12654 }
12655 }
12656
12657 if let Some(max) = &cs.maxvalue {
12658 self.write_space();
12659 match max {
12660 SequenceBound::Value(v) => {
12661 self.write_keyword("MAXVALUE");
12662 self.write(&format!(" {}", v));
12663 }
12664 SequenceBound::None => {
12665 self.write_keyword("NO MAXVALUE");
12666 }
12667 }
12668 }
12669
12670 if let Some(start) = cs.start {
12671 self.write_space();
12672 self.write_keyword("START WITH");
12673 self.write(&format!(" {}", start));
12674 }
12675
12676 if let Some(cache) = cs.cache {
12677 self.write_space();
12678 self.write_keyword("CACHE");
12679 self.write(&format!(" {}", cache));
12680 }
12681
12682 if cs.cycle {
12683 self.write_space();
12684 self.write_keyword("CYCLE");
12685 }
12686
12687 if let Some(owned) = &cs.owned_by {
12688 self.write_space();
12689 self.write_keyword("OWNED BY");
12690 self.write_space();
12691 self.generate_table(owned)?;
12692 }
12693 }
12694
12695 Ok(())
12696 }
12697
12698 fn generate_drop_sequence(&mut self, ds: &DropSequence) -> Result<()> {
12699 self.write_keyword("DROP SEQUENCE");
12700
12701 if ds.if_exists {
12702 self.write_space();
12703 self.write_keyword("IF EXISTS");
12704 }
12705
12706 self.write_space();
12707 self.generate_table(&ds.name)?;
12708
12709 if ds.cascade {
12710 self.write_space();
12711 self.write_keyword("CASCADE");
12712 }
12713
12714 Ok(())
12715 }
12716
12717 fn generate_alter_sequence(&mut self, als: &AlterSequence) -> Result<()> {
12718 self.write_keyword("ALTER SEQUENCE");
12719
12720 if als.if_exists {
12721 self.write_space();
12722 self.write_keyword("IF EXISTS");
12723 }
12724
12725 self.write_space();
12726 self.generate_table(&als.name)?;
12727
12728 if let Some(inc) = als.increment {
12729 self.write_space();
12730 self.write_keyword("INCREMENT BY");
12731 self.write(&format!(" {}", inc));
12732 }
12733
12734 if let Some(min) = &als.minvalue {
12735 self.write_space();
12736 match min {
12737 SequenceBound::Value(v) => {
12738 self.write_keyword("MINVALUE");
12739 self.write(&format!(" {}", v));
12740 }
12741 SequenceBound::None => {
12742 self.write_keyword("NO MINVALUE");
12743 }
12744 }
12745 }
12746
12747 if let Some(max) = &als.maxvalue {
12748 self.write_space();
12749 match max {
12750 SequenceBound::Value(v) => {
12751 self.write_keyword("MAXVALUE");
12752 self.write(&format!(" {}", v));
12753 }
12754 SequenceBound::None => {
12755 self.write_keyword("NO MAXVALUE");
12756 }
12757 }
12758 }
12759
12760 if let Some(start) = als.start {
12761 self.write_space();
12762 self.write_keyword("START WITH");
12763 self.write(&format!(" {}", start));
12764 }
12765
12766 if let Some(restart) = &als.restart {
12767 self.write_space();
12768 self.write_keyword("RESTART");
12769 if let Some(val) = restart {
12770 self.write_keyword(" WITH");
12771 self.write(&format!(" {}", val));
12772 }
12773 }
12774
12775 if let Some(cache) = als.cache {
12776 self.write_space();
12777 self.write_keyword("CACHE");
12778 self.write(&format!(" {}", cache));
12779 }
12780
12781 if let Some(cycle) = als.cycle {
12782 self.write_space();
12783 if cycle {
12784 self.write_keyword("CYCLE");
12785 } else {
12786 self.write_keyword("NO CYCLE");
12787 }
12788 }
12789
12790 if let Some(owned) = &als.owned_by {
12791 self.write_space();
12792 self.write_keyword("OWNED BY");
12793 self.write_space();
12794 if let Some(table) = owned {
12795 self.generate_table(table)?;
12796 } else {
12797 self.write_keyword("NONE");
12798 }
12799 }
12800
12801 Ok(())
12802 }
12803
12804 fn generate_create_trigger(&mut self, ct: &CreateTrigger) -> Result<()> {
12805 self.write_keyword("CREATE");
12806
12807 if ct.or_replace {
12808 self.write_space();
12809 self.write_keyword("OR REPLACE");
12810 }
12811
12812 if ct.constraint {
12813 self.write_space();
12814 self.write_keyword("CONSTRAINT");
12815 }
12816
12817 self.write_space();
12818 self.write_keyword("TRIGGER");
12819 self.write_space();
12820 self.generate_identifier(&ct.name)?;
12821
12822 self.write_space();
12823 match ct.timing {
12824 TriggerTiming::Before => self.write_keyword("BEFORE"),
12825 TriggerTiming::After => self.write_keyword("AFTER"),
12826 TriggerTiming::InsteadOf => self.write_keyword("INSTEAD OF"),
12827 }
12828
12829 for (i, event) in ct.events.iter().enumerate() {
12831 if i > 0 {
12832 self.write_keyword(" OR");
12833 }
12834 self.write_space();
12835 match event {
12836 TriggerEvent::Insert => self.write_keyword("INSERT"),
12837 TriggerEvent::Update(cols) => {
12838 self.write_keyword("UPDATE");
12839 if let Some(cols) = cols {
12840 self.write_space();
12841 self.write_keyword("OF");
12842 for (j, col) in cols.iter().enumerate() {
12843 if j > 0 {
12844 self.write(",");
12845 }
12846 self.write_space();
12847 self.generate_identifier(col)?;
12848 }
12849 }
12850 }
12851 TriggerEvent::Delete => self.write_keyword("DELETE"),
12852 TriggerEvent::Truncate => self.write_keyword("TRUNCATE"),
12853 }
12854 }
12855
12856 self.write_space();
12857 self.write_keyword("ON");
12858 self.write_space();
12859 self.generate_table(&ct.table)?;
12860
12861 if let Some(ref_clause) = &ct.referencing {
12863 self.write_space();
12864 self.write_keyword("REFERENCING");
12865 if let Some(old_table) = &ref_clause.old_table {
12866 self.write_space();
12867 self.write_keyword("OLD TABLE AS");
12868 self.write_space();
12869 self.generate_identifier(old_table)?;
12870 }
12871 if let Some(new_table) = &ref_clause.new_table {
12872 self.write_space();
12873 self.write_keyword("NEW TABLE AS");
12874 self.write_space();
12875 self.generate_identifier(new_table)?;
12876 }
12877 if let Some(old_row) = &ref_clause.old_row {
12878 self.write_space();
12879 self.write_keyword("OLD ROW AS");
12880 self.write_space();
12881 self.generate_identifier(old_row)?;
12882 }
12883 if let Some(new_row) = &ref_clause.new_row {
12884 self.write_space();
12885 self.write_keyword("NEW ROW AS");
12886 self.write_space();
12887 self.generate_identifier(new_row)?;
12888 }
12889 }
12890
12891 if let Some(deferrable) = ct.deferrable {
12893 self.write_space();
12894 if deferrable {
12895 self.write_keyword("DEFERRABLE");
12896 } else {
12897 self.write_keyword("NOT DEFERRABLE");
12898 }
12899 }
12900
12901 if let Some(initially) = ct.initially_deferred {
12902 self.write_space();
12903 self.write_keyword("INITIALLY");
12904 self.write_space();
12905 if initially {
12906 self.write_keyword("DEFERRED");
12907 } else {
12908 self.write_keyword("IMMEDIATE");
12909 }
12910 }
12911
12912 self.write_space();
12913 self.write_keyword("FOR EACH");
12914 self.write_space();
12915 match ct.for_each {
12916 TriggerForEach::Row => self.write_keyword("ROW"),
12917 TriggerForEach::Statement => self.write_keyword("STATEMENT"),
12918 }
12919
12920 if let Some(when) = &ct.when {
12922 self.write_space();
12923 self.write_keyword("WHEN");
12924 self.write(" (");
12925 self.generate_expression(when)?;
12926 self.write(")");
12927 }
12928
12929 self.write_space();
12931 match &ct.body {
12932 TriggerBody::Execute { function, args } => {
12933 self.write_keyword("EXECUTE FUNCTION");
12934 self.write_space();
12935 self.generate_table(function)?;
12936 self.write("(");
12937 for (i, arg) in args.iter().enumerate() {
12938 if i > 0 {
12939 self.write(", ");
12940 }
12941 self.generate_expression(arg)?;
12942 }
12943 self.write(")");
12944 }
12945 TriggerBody::Block(block) => {
12946 self.write_keyword("BEGIN");
12947 self.write_space();
12948 self.write(block);
12949 self.write_space();
12950 self.write_keyword("END");
12951 }
12952 }
12953
12954 Ok(())
12955 }
12956
12957 fn generate_drop_trigger(&mut self, dt: &DropTrigger) -> Result<()> {
12958 self.write_keyword("DROP TRIGGER");
12959
12960 if dt.if_exists {
12961 self.write_space();
12962 self.write_keyword("IF EXISTS");
12963 }
12964
12965 self.write_space();
12966 self.generate_identifier(&dt.name)?;
12967
12968 if let Some(table) = &dt.table {
12969 self.write_space();
12970 self.write_keyword("ON");
12971 self.write_space();
12972 self.generate_table(table)?;
12973 }
12974
12975 if dt.cascade {
12976 self.write_space();
12977 self.write_keyword("CASCADE");
12978 }
12979
12980 Ok(())
12981 }
12982
12983 fn generate_create_type(&mut self, ct: &CreateType) -> Result<()> {
12984 self.write_keyword("CREATE TYPE");
12985
12986 if ct.if_not_exists {
12987 self.write_space();
12988 self.write_keyword("IF NOT EXISTS");
12989 }
12990
12991 self.write_space();
12992 self.generate_table(&ct.name)?;
12993
12994 self.write_space();
12995 self.write_keyword("AS");
12996 self.write_space();
12997
12998 match &ct.definition {
12999 TypeDefinition::Enum(values) => {
13000 self.write_keyword("ENUM");
13001 self.write(" (");
13002 for (i, val) in values.iter().enumerate() {
13003 if i > 0 {
13004 self.write(", ");
13005 }
13006 self.write(&format!("'{}'", val));
13007 }
13008 self.write(")");
13009 }
13010 TypeDefinition::Composite(attrs) => {
13011 self.write("(");
13012 for (i, attr) in attrs.iter().enumerate() {
13013 if i > 0 {
13014 self.write(", ");
13015 }
13016 self.generate_identifier(&attr.name)?;
13017 self.write_space();
13018 self.generate_data_type(&attr.data_type)?;
13019 if let Some(collate) = &attr.collate {
13020 self.write_space();
13021 self.write_keyword("COLLATE");
13022 self.write_space();
13023 self.generate_identifier(collate)?;
13024 }
13025 }
13026 self.write(")");
13027 }
13028 TypeDefinition::Range {
13029 subtype,
13030 subtype_diff,
13031 canonical,
13032 } => {
13033 self.write_keyword("RANGE");
13034 self.write(" (");
13035 self.write_keyword("SUBTYPE");
13036 self.write(" = ");
13037 self.generate_data_type(subtype)?;
13038 if let Some(diff) = subtype_diff {
13039 self.write(", ");
13040 self.write_keyword("SUBTYPE_DIFF");
13041 self.write(" = ");
13042 self.write(diff);
13043 }
13044 if let Some(canon) = canonical {
13045 self.write(", ");
13046 self.write_keyword("CANONICAL");
13047 self.write(" = ");
13048 self.write(canon);
13049 }
13050 self.write(")");
13051 }
13052 TypeDefinition::Base {
13053 input,
13054 output,
13055 internallength,
13056 } => {
13057 self.write("(");
13058 self.write_keyword("INPUT");
13059 self.write(" = ");
13060 self.write(input);
13061 self.write(", ");
13062 self.write_keyword("OUTPUT");
13063 self.write(" = ");
13064 self.write(output);
13065 if let Some(len) = internallength {
13066 self.write(", ");
13067 self.write_keyword("INTERNALLENGTH");
13068 self.write(" = ");
13069 self.write(&len.to_string());
13070 }
13071 self.write(")");
13072 }
13073 TypeDefinition::Domain {
13074 base_type,
13075 default,
13076 constraints,
13077 } => {
13078 self.generate_data_type(base_type)?;
13079 if let Some(def) = default {
13080 self.write_space();
13081 self.write_keyword("DEFAULT");
13082 self.write_space();
13083 self.generate_expression(def)?;
13084 }
13085 for constr in constraints {
13086 self.write_space();
13087 if let Some(name) = &constr.name {
13088 self.write_keyword("CONSTRAINT");
13089 self.write_space();
13090 self.generate_identifier(name)?;
13091 self.write_space();
13092 }
13093 self.write_keyword("CHECK");
13094 self.write(" (");
13095 self.generate_expression(&constr.check)?;
13096 self.write(")");
13097 }
13098 }
13099 }
13100
13101 Ok(())
13102 }
13103
13104 fn generate_drop_type(&mut self, dt: &DropType) -> Result<()> {
13105 self.write_keyword("DROP TYPE");
13106
13107 if dt.if_exists {
13108 self.write_space();
13109 self.write_keyword("IF EXISTS");
13110 }
13111
13112 self.write_space();
13113 self.generate_table(&dt.name)?;
13114
13115 if dt.cascade {
13116 self.write_space();
13117 self.write_keyword("CASCADE");
13118 }
13119
13120 Ok(())
13121 }
13122
13123 fn generate_describe(&mut self, d: &Describe) -> Result<()> {
13124 let saved_athena_hive_context = self.athena_hive_context;
13126 if matches!(
13127 self.config.dialect,
13128 Some(crate::dialects::DialectType::Athena)
13129 ) {
13130 self.athena_hive_context = true;
13131 }
13132
13133 for comment in &d.leading_comments {
13135 self.write_formatted_comment(comment);
13136 self.write(" ");
13137 }
13138
13139 self.write_keyword("DESCRIBE");
13140
13141 if d.extended {
13142 self.write_space();
13143 self.write_keyword("EXTENDED");
13144 } else if d.formatted {
13145 self.write_space();
13146 self.write_keyword("FORMATTED");
13147 }
13148
13149 if let Some(ref style) = d.style {
13151 self.write_space();
13152 self.write_keyword(style);
13153 }
13154
13155 let should_output_kind = match self.config.dialect {
13157 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
13159 false
13160 }
13161 Some(DialectType::Snowflake) => true,
13163 _ => d.kind.is_some(),
13164 };
13165 if should_output_kind {
13166 if let Some(ref kind) = d.kind {
13167 self.write_space();
13168 self.write_keyword(kind);
13169 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
13170 self.write_space();
13171 self.write_keyword("TABLE");
13172 }
13173 }
13174
13175 self.write_space();
13176 self.generate_expression(&d.target)?;
13177
13178 if let Some(ref partition) = d.partition {
13180 self.write_space();
13181 self.generate_expression(partition)?;
13182 }
13183
13184 if d.as_json {
13186 self.write_space();
13187 self.write_keyword("AS JSON");
13188 }
13189
13190 for (name, value) in &d.properties {
13192 self.write_space();
13193 self.write(name);
13194 self.write("=");
13195 self.write(value);
13196 }
13197
13198 self.athena_hive_context = saved_athena_hive_context;
13200
13201 Ok(())
13202 }
13203
13204 fn generate_show(&mut self, s: &Show) -> Result<()> {
13207 self.write_keyword("SHOW");
13208 self.write_space();
13209
13210 let show_terse = s.terse
13213 && !matches!(
13214 s.this.as_str(),
13215 "PRIMARY KEYS" | "UNIQUE KEYS" | "IMPORTED KEYS"
13216 );
13217 if show_terse {
13218 self.write_keyword("TERSE");
13219 self.write_space();
13220 }
13221
13222 self.write_keyword(&s.this);
13224
13225 if let Some(ref target_expr) = s.target {
13227 self.write_space();
13228 self.generate_expression(target_expr)?;
13229 }
13230
13231 if s.history {
13233 self.write_space();
13234 self.write_keyword("HISTORY");
13235 }
13236
13237 if let Some(ref for_target) = s.for_target {
13239 self.write_space();
13240 self.write_keyword("FOR");
13241 self.write_space();
13242 self.generate_expression(for_target)?;
13243 }
13244
13245 use crate::dialects::DialectType;
13249 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
13250
13251 if !is_snowflake && s.from.is_some() {
13252 if let Some(ref scope_kind) = s.scope_kind {
13256 self.write_space();
13257 self.write_keyword("IN");
13258 self.write_space();
13259 self.write_keyword(scope_kind);
13260 if let Some(ref scope) = s.scope {
13261 self.write_space();
13262 self.generate_expression(scope)?;
13263 }
13264 } else if let Some(ref scope) = s.scope {
13265 self.write_space();
13266 self.write_keyword("IN");
13267 self.write_space();
13268 self.generate_expression(scope)?;
13269 }
13270
13271 if let Some(ref from) = s.from {
13273 self.write_space();
13274 self.write_keyword("FROM");
13275 self.write_space();
13276 self.generate_expression(from)?;
13277 }
13278
13279 if let Some(ref db) = s.db {
13281 self.write_space();
13282 self.write_keyword("FROM");
13283 self.write_space();
13284 self.generate_expression(db)?;
13285 }
13286
13287 if let Some(ref like) = s.like {
13289 self.write_space();
13290 self.write_keyword("LIKE");
13291 self.write_space();
13292 self.generate_expression(like)?;
13293 }
13294 } else {
13295 if let Some(ref like) = s.like {
13299 self.write_space();
13300 self.write_keyword("LIKE");
13301 self.write_space();
13302 self.generate_expression(like)?;
13303 }
13304
13305 if let Some(ref scope_kind) = s.scope_kind {
13307 self.write_space();
13308 self.write_keyword("IN");
13309 self.write_space();
13310 self.write_keyword(scope_kind);
13311 if let Some(ref scope) = s.scope {
13312 self.write_space();
13313 self.generate_expression(scope)?;
13314 }
13315 } else if let Some(ref scope) = s.scope {
13316 self.write_space();
13317 self.write_keyword("IN");
13318 self.write_space();
13319 self.generate_expression(scope)?;
13320 }
13321 }
13322
13323 if let Some(ref starts_with) = s.starts_with {
13325 self.write_space();
13326 self.write_keyword("STARTS WITH");
13327 self.write_space();
13328 self.generate_expression(starts_with)?;
13329 }
13330
13331 if let Some(ref limit) = s.limit {
13333 self.write_space();
13334 self.generate_limit(limit)?;
13335 }
13336
13337 if is_snowflake {
13339 if let Some(ref from) = s.from {
13340 self.write_space();
13341 self.write_keyword("FROM");
13342 self.write_space();
13343 self.generate_expression(from)?;
13344 }
13345 }
13346
13347 if let Some(ref where_clause) = s.where_clause {
13349 self.write_space();
13350 self.write_keyword("WHERE");
13351 self.write_space();
13352 self.generate_expression(where_clause)?;
13353 }
13354
13355 if let Some(is_mutex) = s.mutex {
13357 self.write_space();
13358 if is_mutex {
13359 self.write_keyword("MUTEX");
13360 } else {
13361 self.write_keyword("STATUS");
13362 }
13363 }
13364
13365 if !s.privileges.is_empty() {
13367 self.write_space();
13368 self.write_keyword("WITH PRIVILEGES");
13369 self.write_space();
13370 for (i, priv_name) in s.privileges.iter().enumerate() {
13371 if i > 0 {
13372 self.write(", ");
13373 }
13374 self.write_keyword(priv_name);
13375 }
13376 }
13377
13378 Ok(())
13379 }
13380
13381 fn generate_literal(&mut self, lit: &Literal) -> Result<()> {
13384 use crate::dialects::DialectType;
13385 match lit {
13386 Literal::String(s) => {
13387 self.generate_string_literal(s)?;
13388 }
13389 Literal::Number(n) => {
13390 if matches!(self.config.dialect, Some(DialectType::MySQL))
13391 && n.len() > 2
13392 && (n.starts_with("0x") || n.starts_with("0X"))
13393 && !n[2..].chars().all(|c| c.is_ascii_hexdigit())
13394 {
13395 return self.generate_identifier(&Identifier {
13396 name: n.clone(),
13397 quoted: true,
13398 trailing_comments: Vec::new(),
13399 span: None,
13400 });
13401 }
13402 let n = if n.contains('_')
13406 && !matches!(
13407 self.config.dialect,
13408 Some(DialectType::ClickHouse)
13409 | Some(DialectType::DuckDB)
13410 | Some(DialectType::PostgreSQL)
13411 | Some(DialectType::Hive)
13412 | Some(DialectType::Spark)
13413 | Some(DialectType::Databricks)
13414 ) {
13415 std::borrow::Cow::Owned(n.replace('_', ""))
13416 } else {
13417 std::borrow::Cow::Borrowed(n.as_str())
13418 };
13419 if n.starts_with('.') {
13422 self.write("0");
13423 self.write(&n);
13424 } else if n.starts_with("-.") {
13425 self.write("-0");
13427 self.write(&n[1..]);
13428 } else {
13429 self.write(&n);
13430 }
13431 }
13432 Literal::HexString(h) => {
13433 match self.config.dialect {
13435 Some(DialectType::Spark)
13436 | Some(DialectType::Databricks)
13437 | Some(DialectType::Teradata) => self.write("X'"),
13438 _ => self.write("x'"),
13439 }
13440 self.write(h);
13441 self.write("'");
13442 }
13443 Literal::HexNumber(h) => {
13444 match self.config.dialect {
13448 Some(DialectType::BigQuery)
13449 | Some(DialectType::TSQL)
13450 | Some(DialectType::Fabric) => {
13451 self.write("0x");
13452 self.write(h);
13453 }
13454 _ => {
13455 if let Ok(val) = u64::from_str_radix(h, 16) {
13457 self.write(&val.to_string());
13458 } else {
13459 self.write("0x");
13461 self.write(h);
13462 }
13463 }
13464 }
13465 }
13466 Literal::BitString(b) => {
13467 self.write("B'");
13469 self.write(b);
13470 self.write("'");
13471 }
13472 Literal::ByteString(b) => {
13473 self.write("b'");
13475 self.write_escaped_byte_string(b);
13477 self.write("'");
13478 }
13479 Literal::NationalString(s) => {
13480 let keep_n_prefix = matches!(
13483 self.config.dialect,
13484 Some(DialectType::TSQL)
13485 | Some(DialectType::Oracle)
13486 | Some(DialectType::MySQL)
13487 | None
13488 );
13489 if keep_n_prefix {
13490 self.write("N'");
13491 } else {
13492 self.write("'");
13493 }
13494 self.write(s);
13495 self.write("'");
13496 }
13497 Literal::Date(d) => {
13498 self.generate_date_literal(d)?;
13499 }
13500 Literal::Time(t) => {
13501 self.generate_time_literal(t)?;
13502 }
13503 Literal::Timestamp(ts) => {
13504 self.generate_timestamp_literal(ts)?;
13505 }
13506 Literal::Datetime(dt) => {
13507 self.generate_datetime_literal(dt)?;
13508 }
13509 Literal::TripleQuotedString(s, _quote_char) => {
13510 if matches!(
13512 self.config.dialect,
13513 Some(crate::dialects::DialectType::BigQuery)
13514 | Some(crate::dialects::DialectType::DuckDB)
13515 | Some(crate::dialects::DialectType::Snowflake)
13516 | Some(crate::dialects::DialectType::Spark)
13517 | Some(crate::dialects::DialectType::Hive)
13518 | Some(crate::dialects::DialectType::Presto)
13519 | Some(crate::dialects::DialectType::Trino)
13520 | Some(crate::dialects::DialectType::PostgreSQL)
13521 | Some(crate::dialects::DialectType::MySQL)
13522 | Some(crate::dialects::DialectType::Redshift)
13523 | Some(crate::dialects::DialectType::TSQL)
13524 | Some(crate::dialects::DialectType::Oracle)
13525 | Some(crate::dialects::DialectType::ClickHouse)
13526 | Some(crate::dialects::DialectType::Databricks)
13527 | Some(crate::dialects::DialectType::SQLite)
13528 ) {
13529 self.generate_string_literal(s)?;
13530 } else {
13531 let quotes = format!("{0}{0}{0}", _quote_char);
13533 self.write("es);
13534 self.write(s);
13535 self.write("es);
13536 }
13537 }
13538 Literal::EscapeString(s) => {
13539 use crate::dialects::DialectType;
13543 let content = if let Some(c) = s.strip_prefix("e:") {
13544 c
13545 } else if let Some(c) = s.strip_prefix("E:") {
13546 c
13547 } else {
13548 s.as_str()
13549 };
13550
13551 if matches!(
13553 self.config.dialect,
13554 Some(DialectType::MySQL) | Some(DialectType::TiDB)
13555 ) {
13556 self.write(content);
13557 } else {
13558 let prefix = if matches!(
13560 self.config.dialect,
13561 Some(DialectType::SingleStore)
13562 | Some(DialectType::DuckDB)
13563 | Some(DialectType::PostgreSQL)
13564 | Some(DialectType::CockroachDB)
13565 | Some(DialectType::Materialize)
13566 | Some(DialectType::RisingWave)
13567 ) {
13568 "e'"
13569 } else {
13570 "E'"
13571 };
13572
13573 let normalized = content.replace("\\'", "''");
13575 self.write(prefix);
13576 self.write(&normalized);
13577 self.write("'");
13578 }
13579 }
13580 Literal::DollarString(s) => {
13581 use crate::dialects::DialectType;
13584 let (_tag, content) = crate::tokens::parse_dollar_string_token(s);
13586 let escape_backslash = matches!(self.config.dialect, Some(DialectType::Snowflake));
13588 let use_backslash_quote =
13592 matches!(self.config.dialect, Some(DialectType::Snowflake));
13593
13594 let mut escaped = String::with_capacity(content.len() + 4);
13595 for ch in content.chars() {
13596 if escape_backslash && ch == '\\' {
13597 escaped.push('\\');
13599 escaped.push('\\');
13600 } else if ch == '\'' {
13601 if use_backslash_quote {
13602 escaped.push('\\');
13603 escaped.push('\'');
13604 } else {
13605 escaped.push('\'');
13606 escaped.push('\'');
13607 }
13608 } else {
13609 escaped.push(ch);
13610 }
13611 }
13612 self.write("'");
13613 self.write(&escaped);
13614 self.write("'");
13615 }
13616 Literal::RawString(s) => {
13617 use crate::dialects::DialectType;
13623
13624 let escape_backslash = matches!(
13626 self.config.dialect,
13627 Some(DialectType::BigQuery)
13628 | Some(DialectType::MySQL)
13629 | Some(DialectType::SingleStore)
13630 | Some(DialectType::TiDB)
13631 | Some(DialectType::Hive)
13632 | Some(DialectType::Spark)
13633 | Some(DialectType::Databricks)
13634 | Some(DialectType::Drill)
13635 | Some(DialectType::Snowflake)
13636 | Some(DialectType::Redshift)
13637 | Some(DialectType::ClickHouse)
13638 );
13639
13640 let backslash_escapes_quote = matches!(
13643 self.config.dialect,
13644 Some(DialectType::BigQuery)
13645 | Some(DialectType::Hive)
13646 | Some(DialectType::Spark)
13647 | Some(DialectType::Databricks)
13648 | Some(DialectType::Drill)
13649 | Some(DialectType::Snowflake)
13650 | Some(DialectType::Redshift)
13651 );
13652
13653 let supports_escape_sequences = escape_backslash;
13656
13657 let mut escaped = String::with_capacity(s.len() + 4);
13658 for ch in s.chars() {
13659 if escape_backslash && ch == '\\' {
13660 escaped.push('\\');
13662 escaped.push('\\');
13663 } else if ch == '\'' {
13664 if backslash_escapes_quote {
13665 escaped.push('\\');
13667 escaped.push('\'');
13668 } else {
13669 escaped.push('\'');
13671 escaped.push('\'');
13672 }
13673 } else if supports_escape_sequences {
13674 match ch {
13677 '\n' => {
13678 escaped.push('\\');
13679 escaped.push('n');
13680 }
13681 '\r' => {
13682 escaped.push('\\');
13683 escaped.push('r');
13684 }
13685 '\t' => {
13686 escaped.push('\\');
13687 escaped.push('t');
13688 }
13689 '\x07' => {
13690 escaped.push('\\');
13691 escaped.push('a');
13692 }
13693 '\x08' => {
13694 escaped.push('\\');
13695 escaped.push('b');
13696 }
13697 '\x0C' => {
13698 escaped.push('\\');
13699 escaped.push('f');
13700 }
13701 '\x0B' => {
13702 escaped.push('\\');
13703 escaped.push('v');
13704 }
13705 _ => escaped.push(ch),
13706 }
13707 } else {
13708 escaped.push(ch);
13709 }
13710 }
13711 self.write("'");
13712 self.write(&escaped);
13713 self.write("'");
13714 }
13715 }
13716 Ok(())
13717 }
13718
13719 fn generate_date_literal(&mut self, d: &str) -> Result<()> {
13721 use crate::dialects::DialectType;
13722
13723 match self.config.dialect {
13724 Some(DialectType::TSQL) => {
13726 self.write("CAST('");
13727 self.write(d);
13728 self.write("' AS DATE)");
13729 }
13730 Some(DialectType::BigQuery) => {
13733 self.write("CAST('");
13734 self.write(d);
13735 self.write("' AS DATE)");
13736 }
13737 Some(DialectType::Exasol) => {
13740 self.write("CAST('");
13741 self.write(d);
13742 self.write("' AS DATE)");
13743 }
13744 Some(DialectType::Snowflake) => {
13747 self.write("CAST('");
13748 self.write(d);
13749 self.write("' AS DATE)");
13750 }
13751 Some(DialectType::PostgreSQL)
13753 | Some(DialectType::MySQL)
13754 | Some(DialectType::SingleStore)
13755 | Some(DialectType::TiDB)
13756 | Some(DialectType::Redshift) => {
13757 self.write("CAST('");
13758 self.write(d);
13759 self.write("' AS DATE)");
13760 }
13761 Some(DialectType::DuckDB)
13763 | Some(DialectType::Presto)
13764 | Some(DialectType::Trino)
13765 | Some(DialectType::Athena)
13766 | Some(DialectType::Spark)
13767 | Some(DialectType::Databricks)
13768 | Some(DialectType::Hive) => {
13769 self.write("CAST('");
13770 self.write(d);
13771 self.write("' AS DATE)");
13772 }
13773 Some(DialectType::Oracle) => {
13775 self.write("TO_DATE('");
13776 self.write(d);
13777 self.write("', 'YYYY-MM-DD')");
13778 }
13779 _ => {
13781 self.write_keyword("DATE");
13782 self.write(" '");
13783 self.write(d);
13784 self.write("'");
13785 }
13786 }
13787 Ok(())
13788 }
13789
13790 fn generate_time_literal(&mut self, t: &str) -> Result<()> {
13792 use crate::dialects::DialectType;
13793
13794 match self.config.dialect {
13795 Some(DialectType::TSQL) => {
13797 self.write("CAST('");
13798 self.write(t);
13799 self.write("' AS TIME)");
13800 }
13801 _ => {
13803 self.write_keyword("TIME");
13804 self.write(" '");
13805 self.write(t);
13806 self.write("'");
13807 }
13808 }
13809 Ok(())
13810 }
13811
13812 fn generate_dremio_date_expression(&mut self, expr: &Expression) -> Result<()> {
13814 use crate::expressions::Literal;
13815
13816 match expr {
13817 Expression::Literal(Literal::Date(d)) => {
13818 self.write("CAST('");
13820 self.write(d);
13821 self.write("' AS DATE)");
13822 }
13823 _ => {
13824 self.generate_expression(expr)?;
13826 }
13827 }
13828 Ok(())
13829 }
13830
13831 fn generate_timestamp_literal(&mut self, ts: &str) -> Result<()> {
13833 use crate::dialects::DialectType;
13834
13835 match self.config.dialect {
13836 Some(DialectType::TSQL) => {
13838 self.write("CAST('");
13839 self.write(ts);
13840 self.write("' AS DATETIME2)");
13841 }
13842 Some(DialectType::BigQuery) => {
13845 self.write("CAST('");
13846 self.write(ts);
13847 self.write("' AS TIMESTAMP)");
13848 }
13849 Some(DialectType::Snowflake) => {
13852 self.write("CAST('");
13853 self.write(ts);
13854 self.write("' AS TIMESTAMP)");
13855 }
13856 Some(DialectType::Dremio) => {
13859 self.write("CAST('");
13860 self.write(ts);
13861 self.write("' AS TIMESTAMP)");
13862 }
13863 Some(DialectType::Exasol) => {
13866 self.write("CAST('");
13867 self.write(ts);
13868 self.write("' AS TIMESTAMP)");
13869 }
13870 Some(DialectType::Oracle) => {
13873 self.write("TO_TIMESTAMP('");
13874 self.write(ts);
13875 self.write("', 'YYYY-MM-DD HH24:MI:SS.FF6')");
13876 }
13877 Some(DialectType::Presto) | Some(DialectType::Trino) => {
13879 if Self::timestamp_has_timezone(ts) {
13880 self.write("CAST('");
13881 self.write(ts);
13882 self.write("' AS TIMESTAMP WITH TIME ZONE)");
13883 } else {
13884 self.write("CAST('");
13885 self.write(ts);
13886 self.write("' AS TIMESTAMP)");
13887 }
13888 }
13889 Some(DialectType::ClickHouse) => {
13891 self.write("CAST('");
13892 self.write(ts);
13893 self.write("' AS Nullable(DateTime))");
13894 }
13895 Some(DialectType::Spark) => {
13897 self.write("CAST('");
13898 self.write(ts);
13899 self.write("' AS TIMESTAMP)");
13900 }
13901 Some(DialectType::Redshift) => {
13904 if ts == "epoch" {
13905 self.write_keyword("TIMESTAMP");
13906 self.write(" '");
13907 self.write(ts);
13908 self.write("'");
13909 } else {
13910 self.write("CAST('");
13911 self.write(ts);
13912 self.write("' AS TIMESTAMP)");
13913 }
13914 }
13915 Some(DialectType::PostgreSQL)
13917 | Some(DialectType::Hive)
13918 | Some(DialectType::SQLite)
13919 | Some(DialectType::DuckDB)
13920 | Some(DialectType::Athena)
13921 | Some(DialectType::Drill)
13922 | Some(DialectType::Teradata) => {
13923 self.write("CAST('");
13924 self.write(ts);
13925 self.write("' AS TIMESTAMP)");
13926 }
13927 Some(DialectType::MySQL) | Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
13929 self.write("CAST('");
13930 self.write(ts);
13931 self.write("' AS DATETIME)");
13932 }
13933 Some(DialectType::Databricks) => {
13935 self.write("CAST('");
13936 self.write(ts);
13937 self.write("' AS TIMESTAMP_NTZ)");
13938 }
13939 _ => {
13941 self.write_keyword("TIMESTAMP");
13942 self.write(" '");
13943 self.write(ts);
13944 self.write("'");
13945 }
13946 }
13947 Ok(())
13948 }
13949
13950 fn timestamp_has_timezone(ts: &str) -> bool {
13953 let ts_lower = ts.to_lowercase();
13957
13958 let continent_prefixes = [
13960 "africa/",
13961 "america/",
13962 "antarctica/",
13963 "arctic/",
13964 "asia/",
13965 "atlantic/",
13966 "australia/",
13967 "europe/",
13968 "indian/",
13969 "pacific/",
13970 "etc/",
13971 "brazil/",
13972 "canada/",
13973 "chile/",
13974 "mexico/",
13975 "us/",
13976 ];
13977
13978 for prefix in &continent_prefixes {
13979 if ts_lower.contains(prefix) {
13980 return true;
13981 }
13982 }
13983
13984 let tz_abbrevs = [
13987 " utc", " gmt", " cet", " cest", " eet", " eest", " wet", " west", " est", " edt",
13988 " cst", " cdt", " mst", " mdt", " pst", " pdt", " ist", " bst", " jst", " kst", " hkt",
13989 " sgt", " aest", " aedt", " acst", " acdt", " awst",
13990 ];
13991
13992 for abbrev in &tz_abbrevs {
13993 if ts_lower.ends_with(abbrev) {
13994 return true;
13995 }
13996 }
13997
13998 let trimmed = ts.trim();
14002 if let Some(last_space) = trimmed.rfind(' ') {
14003 let suffix = &trimmed[last_space + 1..];
14004 if (suffix.starts_with('+') || suffix.starts_with('-')) && suffix.len() > 1 {
14005 let rest = &suffix[1..];
14007 if rest.chars().all(|c| c.is_ascii_digit() || c == ':') {
14008 return true;
14009 }
14010 }
14011 }
14012
14013 false
14014 }
14015
14016 fn generate_datetime_literal(&mut self, dt: &str) -> Result<()> {
14018 use crate::dialects::DialectType;
14019
14020 match self.config.dialect {
14021 Some(DialectType::BigQuery) => {
14024 self.write("CAST('");
14025 self.write(dt);
14026 self.write("' AS DATETIME)");
14027 }
14028 Some(DialectType::DuckDB) => {
14030 self.write("CAST('");
14031 self.write(dt);
14032 self.write("' AS TIMESTAMP)");
14033 }
14034 _ => {
14037 self.write_keyword("DATETIME");
14038 self.write(" '");
14039 self.write(dt);
14040 self.write("'");
14041 }
14042 }
14043 Ok(())
14044 }
14045
14046 fn generate_string_literal(&mut self, s: &str) -> Result<()> {
14048 use crate::dialects::DialectType;
14049
14050 match self.config.dialect {
14051 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
14055 self.write("'");
14057 for c in s.chars() {
14058 match c {
14059 '\'' => self.write("\\'"),
14060 '\\' => self.write("\\\\"),
14061 '\n' => self.write("\\n"),
14062 '\r' => self.write("\\r"),
14063 '\t' => self.write("\\t"),
14064 '\0' => self.write("\\0"),
14065 _ => self.output.push(c),
14066 }
14067 }
14068 self.write("'");
14069 }
14070 Some(DialectType::Drill) => {
14071 self.write("'");
14074 for c in s.chars() {
14075 match c {
14076 '\'' => self.write("''"),
14077 '\\' => self.write("\\\\"),
14078 '\n' => self.write("\\n"),
14079 '\r' => self.write("\\r"),
14080 '\t' => self.write("\\t"),
14081 '\0' => self.write("\\0"),
14082 _ => self.output.push(c),
14083 }
14084 }
14085 self.write("'");
14086 }
14087 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB) => {
14088 self.write("'");
14089 for c in s.chars() {
14090 match c {
14091 '\'' => self.write("''"),
14093 '\\' => self.write("\\\\"),
14094 '\n' => self.write("\\n"),
14095 '\r' => self.write("\\r"),
14096 '\t' => self.write("\\t"),
14097 '\0' => self.output.push('\0'),
14099 _ => self.output.push(c),
14100 }
14101 }
14102 self.write("'");
14103 }
14104 Some(DialectType::BigQuery) => {
14106 self.write("'");
14107 for c in s.chars() {
14108 match c {
14109 '\'' => self.write("\\'"),
14110 '\\' => self.write("\\\\"),
14111 '\n' => self.write("\\n"),
14112 '\r' => self.write("\\r"),
14113 '\t' => self.write("\\t"),
14114 '\0' => self.write("\\0"),
14115 '\x07' => self.write("\\a"),
14116 '\x08' => self.write("\\b"),
14117 '\x0C' => self.write("\\f"),
14118 '\x0B' => self.write("\\v"),
14119 _ => self.output.push(c),
14120 }
14121 }
14122 self.write("'");
14123 }
14124 Some(DialectType::Athena) => {
14128 if self.athena_hive_context {
14129 self.write("'");
14131 for c in s.chars() {
14132 match c {
14133 '\'' => self.write("\\'"),
14134 '\\' => self.write("\\\\"),
14135 '\n' => self.write("\\n"),
14136 '\r' => self.write("\\r"),
14137 '\t' => self.write("\\t"),
14138 '\0' => self.write("\\0"),
14139 _ => self.output.push(c),
14140 }
14141 }
14142 self.write("'");
14143 } else {
14144 self.write("'");
14146 for c in s.chars() {
14147 match c {
14148 '\'' => self.write("''"),
14149 _ => self.output.push(c),
14151 }
14152 }
14153 self.write("'");
14154 }
14155 }
14156 Some(DialectType::Snowflake) => {
14161 self.write("'");
14162 for c in s.chars() {
14163 match c {
14164 '\'' => self.write("\\'"),
14165 '\n' => self.write("\\n"),
14168 '\r' => self.write("\\r"),
14169 '\t' => self.write("\\t"),
14170 _ => self.output.push(c),
14171 }
14172 }
14173 self.write("'");
14174 }
14175 Some(DialectType::PostgreSQL) => {
14177 self.write("'");
14178 for c in s.chars() {
14179 match c {
14180 '\'' => self.write("''"),
14181 _ => self.output.push(c),
14182 }
14183 }
14184 self.write("'");
14185 }
14186 Some(DialectType::Redshift) => {
14188 self.write("'");
14189 for c in s.chars() {
14190 match c {
14191 '\'' => self.write("\\'"),
14192 _ => self.output.push(c),
14193 }
14194 }
14195 self.write("'");
14196 }
14197 Some(DialectType::Oracle) => {
14199 self.write("'");
14200 self.write(&s.replace('\'', "''"));
14201 self.write("'");
14202 }
14203 Some(DialectType::ClickHouse) => {
14206 self.write("'");
14207 for c in s.chars() {
14208 match c {
14209 '\'' => self.write("''"),
14210 '\\' => self.write("\\\\"),
14211 '\n' => self.write("\\n"),
14212 '\r' => self.write("\\r"),
14213 '\t' => self.write("\\t"),
14214 '\0' => self.write("\\0"),
14215 '\x07' => self.write("\\a"),
14216 '\x08' => self.write("\\b"),
14217 '\x0C' => self.write("\\f"),
14218 '\x0B' => self.write("\\v"),
14219 c if c.is_control() || (c as u32) < 0x20 => {
14221 let byte = c as u32;
14222 if byte < 256 {
14223 self.write(&format!("\\x{:02X}", byte));
14224 } else {
14225 self.output.push(c);
14226 }
14227 }
14228 _ => self.output.push(c),
14229 }
14230 }
14231 self.write("'");
14232 }
14233 _ => {
14236 self.write("'");
14237 self.write(&s.replace('\'', "''"));
14238 self.write("'");
14239 }
14240 }
14241 Ok(())
14242 }
14243
14244 fn write_escaped_byte_string(&mut self, s: &str) {
14247 for c in s.chars() {
14248 match c {
14249 '\'' => self.write("\\'"),
14251 '\\' => self.write("\\\\"),
14253 _ if !c.is_control() => self.output.push(c),
14255 _ => {
14257 let byte = c as u32;
14258 if byte < 256 {
14259 self.write(&format!("\\x{:02x}", byte));
14260 } else {
14261 for b in c.to_string().as_bytes() {
14263 self.write(&format!("\\x{:02x}", b));
14264 }
14265 }
14266 }
14267 }
14268 }
14269 }
14270
14271 fn generate_boolean(&mut self, b: &BooleanLiteral) -> Result<()> {
14272 use crate::dialects::DialectType;
14273
14274 match self.config.dialect {
14276 Some(DialectType::TSQL) => {
14279 self.write(if b.value { "1" } else { "0" });
14280 }
14281 Some(DialectType::Oracle) => {
14283 self.write(if b.value { "1" } else { "0" });
14284 }
14285 Some(DialectType::MySQL) => {
14287 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
14288 }
14289 _ => {
14291 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
14292 }
14293 }
14294 Ok(())
14295 }
14296
14297 fn generate_alias_identifier(&mut self, id: &Identifier) -> Result<()> {
14300 let name = &id.name;
14301 let quote_style = &self.config.identifier_quote_style;
14302
14303 let needs_quoting = id.quoted || self.is_reserved_keyword(name);
14307
14308 let output_name = if self.config.normalize_identifiers && !id.quoted {
14310 name.to_lowercase()
14311 } else {
14312 name.to_string()
14313 };
14314
14315 if needs_quoting {
14316 let escaped_name = if quote_style.start == quote_style.end {
14318 output_name.replace(
14319 quote_style.end,
14320 &format!("{}{}", quote_style.end, quote_style.end),
14321 )
14322 } else {
14323 output_name.replace(
14324 quote_style.end,
14325 &format!("{}{}", quote_style.end, quote_style.end),
14326 )
14327 };
14328 self.write(&format!(
14329 "{}{}{}",
14330 quote_style.start, escaped_name, quote_style.end
14331 ));
14332 } else {
14333 self.write(&output_name);
14334 }
14335
14336 for comment in &id.trailing_comments {
14338 self.write(" ");
14339 self.write_formatted_comment(comment);
14340 }
14341 Ok(())
14342 }
14343
14344 fn generate_identifier(&mut self, id: &Identifier) -> Result<()> {
14345 use crate::dialects::DialectType;
14346
14347 let name = &id.name;
14348
14349 let quote_style = if matches!(self.config.dialect, Some(DialectType::Athena))
14351 && self.athena_hive_context
14352 {
14353 &IdentifierQuoteStyle::BACKTICK
14354 } else {
14355 &self.config.identifier_quote_style
14356 };
14357
14358 let starts_with_digit = name.chars().next().map_or(false, |c| c.is_ascii_digit());
14365 let needs_digit_quoting = starts_with_digit
14366 && !self.config.identifiers_can_start_with_digit
14367 && self.config.dialect.is_some();
14368 let mysql_invalid_hex_identifier = matches!(self.config.dialect, Some(DialectType::MySQL))
14369 && name.len() > 2
14370 && (name.starts_with("0x") || name.starts_with("0X"))
14371 && !name[2..].chars().all(|c| c.is_ascii_hexdigit());
14372 let needs_quoting = id.quoted
14373 || self.is_reserved_keyword(name)
14374 || self.config.always_quote_identifiers
14375 || needs_digit_quoting
14376 || mysql_invalid_hex_identifier;
14377
14378 let (base_name, suffix) = if needs_quoting {
14381 if let Some(paren_pos) = name.find('(') {
14383 let base = &name[..paren_pos];
14384 let rest = &name[paren_pos..];
14385 if rest.starts_with('(')
14387 && (rest.ends_with(')') || rest.ends_with(") ASC") || rest.ends_with(") DESC"))
14388 {
14389 let close_paren = rest.find(')').unwrap_or(rest.len());
14391 let inside = &rest[1..close_paren];
14392 if inside.chars().all(|c| c.is_ascii_digit()) {
14393 (base.to_string(), rest.to_string())
14394 } else {
14395 (name.to_string(), String::new())
14396 }
14397 } else {
14398 (name.to_string(), String::new())
14399 }
14400 } else if name.ends_with(" ASC") {
14401 let base = &name[..name.len() - 4];
14402 (base.to_string(), " ASC".to_string())
14403 } else if name.ends_with(" DESC") {
14404 let base = &name[..name.len() - 5];
14405 (base.to_string(), " DESC".to_string())
14406 } else {
14407 (name.to_string(), String::new())
14408 }
14409 } else {
14410 (name.to_string(), String::new())
14411 };
14412
14413 let output_name = if self.config.normalize_identifiers && !id.quoted {
14417 base_name.to_lowercase()
14418 } else if matches!(self.config.dialect, Some(DialectType::Exasol))
14419 && !id.quoted
14420 && self.is_reserved_keyword(name)
14421 {
14422 base_name.to_uppercase()
14425 } else {
14426 base_name
14427 };
14428
14429 if needs_quoting {
14430 let escaped_name = if quote_style.start == quote_style.end {
14432 output_name.replace(
14434 quote_style.end,
14435 &format!("{}{}", quote_style.end, quote_style.end),
14436 )
14437 } else {
14438 output_name.replace(
14440 quote_style.end,
14441 &format!("{}{}", quote_style.end, quote_style.end),
14442 )
14443 };
14444 self.write(&format!(
14445 "{}{}{}{}",
14446 quote_style.start, escaped_name, quote_style.end, suffix
14447 ));
14448 } else {
14449 self.write(&output_name);
14450 }
14451
14452 for comment in &id.trailing_comments {
14454 self.write(" ");
14455 self.write_formatted_comment(comment);
14456 }
14457 Ok(())
14458 }
14459
14460 fn generate_column(&mut self, col: &Column) -> Result<()> {
14461 use crate::dialects::DialectType;
14462
14463 if let Some(table) = &col.table {
14464 let is_exasol_local_prefix = matches!(self.config.dialect, Some(DialectType::Exasol))
14468 && !table.quoted
14469 && table.name.eq_ignore_ascii_case("LOCAL");
14470
14471 if is_exasol_local_prefix {
14472 self.write("LOCAL");
14474 } else {
14475 self.generate_identifier(table)?;
14476 }
14477 self.write(".");
14478 }
14479 self.generate_identifier(&col.name)?;
14480 if col.join_mark && self.config.supports_column_join_marks {
14483 self.write(" (+)");
14484 }
14485 for comment in &col.trailing_comments {
14487 self.write_space();
14488 self.write_formatted_comment(comment);
14489 }
14490 Ok(())
14491 }
14492
14493 fn generate_pseudocolumn(&mut self, pc: &Pseudocolumn) -> Result<()> {
14496 use crate::dialects::DialectType;
14497 use crate::expressions::PseudocolumnType;
14498
14499 if pc.kind == PseudocolumnType::Sysdate
14501 && !matches!(
14502 self.config.dialect,
14503 Some(DialectType::Oracle) | Some(DialectType::Redshift) | None
14504 )
14505 {
14506 self.write_keyword("CURRENT_TIMESTAMP");
14507 if matches!(
14509 self.config.dialect,
14510 Some(DialectType::MySQL)
14511 | Some(DialectType::ClickHouse)
14512 | Some(DialectType::Spark)
14513 | Some(DialectType::Databricks)
14514 | Some(DialectType::Hive)
14515 ) {
14516 self.write("()");
14517 }
14518 } else {
14519 self.write(pc.kind.as_str());
14520 }
14521 Ok(())
14522 }
14523
14524 fn generate_connect(&mut self, connect: &Connect) -> Result<()> {
14526 use crate::dialects::DialectType;
14527
14528 let supports_connect_by = matches!(
14531 self.config.dialect,
14532 Some(DialectType::Oracle) | Some(DialectType::Snowflake)
14533 );
14534
14535 if !supports_connect_by && self.config.dialect.is_some() {
14536 if self.config.pretty {
14538 self.write_newline();
14539 } else {
14540 self.write_space();
14541 }
14542 self.write("/* CONNECT BY requires manual conversion to recursive CTE */");
14543 }
14544
14545 if let Some(start) = &connect.start {
14547 if self.config.pretty {
14548 self.write_newline();
14549 } else {
14550 self.write_space();
14551 }
14552 self.write_keyword("START WITH");
14553 self.write_space();
14554 self.generate_expression(start)?;
14555 }
14556
14557 if self.config.pretty {
14559 self.write_newline();
14560 } else {
14561 self.write_space();
14562 }
14563 self.write_keyword("CONNECT BY");
14564 if connect.nocycle {
14565 self.write_space();
14566 self.write_keyword("NOCYCLE");
14567 }
14568 self.write_space();
14569 self.generate_expression(&connect.connect)?;
14570
14571 Ok(())
14572 }
14573
14574 fn generate_connect_expr(&mut self, connect: &Connect) -> Result<()> {
14576 self.generate_connect(connect)
14577 }
14578
14579 fn generate_prior(&mut self, prior: &Prior) -> Result<()> {
14581 self.write_keyword("PRIOR");
14582 self.write_space();
14583 self.generate_expression(&prior.this)?;
14584 Ok(())
14585 }
14586
14587 fn generate_connect_by_root(&mut self, cbr: &ConnectByRoot) -> Result<()> {
14590 self.write_keyword("CONNECT_BY_ROOT");
14591 self.write_space();
14592 self.generate_expression(&cbr.this)?;
14593 Ok(())
14594 }
14595
14596 fn generate_match_recognize(&mut self, mr: &MatchRecognize) -> Result<()> {
14598 use crate::dialects::DialectType;
14599
14600 let supports_match_recognize = matches!(
14602 self.config.dialect,
14603 Some(DialectType::Oracle)
14604 | Some(DialectType::Snowflake)
14605 | Some(DialectType::Presto)
14606 | Some(DialectType::Trino)
14607 );
14608
14609 if let Some(source) = &mr.this {
14611 self.generate_expression(source)?;
14612 }
14613
14614 if !supports_match_recognize {
14615 self.write("/* MATCH_RECOGNIZE not supported in this dialect */");
14616 return Ok(());
14617 }
14618
14619 if self.config.pretty {
14621 self.write_newline();
14622 } else {
14623 self.write_space();
14624 }
14625
14626 self.write_keyword("MATCH_RECOGNIZE");
14627 self.write(" (");
14628
14629 if self.config.pretty {
14630 self.indent_level += 1;
14631 }
14632
14633 let mut needs_separator = false;
14634
14635 if let Some(partition_by) = &mr.partition_by {
14637 if !partition_by.is_empty() {
14638 if self.config.pretty {
14639 self.write_newline();
14640 self.write_indent();
14641 }
14642 self.write_keyword("PARTITION BY");
14643 self.write_space();
14644 for (i, expr) in partition_by.iter().enumerate() {
14645 if i > 0 {
14646 self.write(", ");
14647 }
14648 self.generate_expression(expr)?;
14649 }
14650 needs_separator = true;
14651 }
14652 }
14653
14654 if let Some(order_by) = &mr.order_by {
14656 if !order_by.is_empty() {
14657 if needs_separator {
14658 if self.config.pretty {
14659 self.write_newline();
14660 self.write_indent();
14661 } else {
14662 self.write_space();
14663 }
14664 } else if self.config.pretty {
14665 self.write_newline();
14666 self.write_indent();
14667 }
14668 self.write_keyword("ORDER BY");
14669 if self.config.pretty {
14671 self.indent_level += 1;
14672 for (i, ordered) in order_by.iter().enumerate() {
14673 if i > 0 {
14674 self.write(",");
14675 }
14676 self.write_newline();
14677 self.write_indent();
14678 self.generate_ordered(ordered)?;
14679 }
14680 self.indent_level -= 1;
14681 } else {
14682 self.write_space();
14683 for (i, ordered) in order_by.iter().enumerate() {
14684 if i > 0 {
14685 self.write(", ");
14686 }
14687 self.generate_ordered(ordered)?;
14688 }
14689 }
14690 needs_separator = true;
14691 }
14692 }
14693
14694 if let Some(measures) = &mr.measures {
14696 if !measures.is_empty() {
14697 if needs_separator {
14698 if self.config.pretty {
14699 self.write_newline();
14700 self.write_indent();
14701 } else {
14702 self.write_space();
14703 }
14704 } else if self.config.pretty {
14705 self.write_newline();
14706 self.write_indent();
14707 }
14708 self.write_keyword("MEASURES");
14709 if self.config.pretty {
14711 self.indent_level += 1;
14712 for (i, measure) in measures.iter().enumerate() {
14713 if i > 0 {
14714 self.write(",");
14715 }
14716 self.write_newline();
14717 self.write_indent();
14718 if let Some(semantics) = &measure.window_frame {
14720 match semantics {
14721 MatchRecognizeSemantics::Running => {
14722 self.write_keyword("RUNNING");
14723 self.write_space();
14724 }
14725 MatchRecognizeSemantics::Final => {
14726 self.write_keyword("FINAL");
14727 self.write_space();
14728 }
14729 }
14730 }
14731 self.generate_expression(&measure.this)?;
14732 }
14733 self.indent_level -= 1;
14734 } else {
14735 self.write_space();
14736 for (i, measure) in measures.iter().enumerate() {
14737 if i > 0 {
14738 self.write(", ");
14739 }
14740 if let Some(semantics) = &measure.window_frame {
14742 match semantics {
14743 MatchRecognizeSemantics::Running => {
14744 self.write_keyword("RUNNING");
14745 self.write_space();
14746 }
14747 MatchRecognizeSemantics::Final => {
14748 self.write_keyword("FINAL");
14749 self.write_space();
14750 }
14751 }
14752 }
14753 self.generate_expression(&measure.this)?;
14754 }
14755 }
14756 needs_separator = true;
14757 }
14758 }
14759
14760 if let Some(rows) = &mr.rows {
14762 if needs_separator {
14763 if self.config.pretty {
14764 self.write_newline();
14765 self.write_indent();
14766 } else {
14767 self.write_space();
14768 }
14769 } else if self.config.pretty {
14770 self.write_newline();
14771 self.write_indent();
14772 }
14773 match rows {
14774 MatchRecognizeRows::OneRowPerMatch => {
14775 self.write_keyword("ONE ROW PER MATCH");
14776 }
14777 MatchRecognizeRows::AllRowsPerMatch => {
14778 self.write_keyword("ALL ROWS PER MATCH");
14779 }
14780 MatchRecognizeRows::AllRowsPerMatchShowEmptyMatches => {
14781 self.write_keyword("ALL ROWS PER MATCH SHOW EMPTY MATCHES");
14782 }
14783 MatchRecognizeRows::AllRowsPerMatchOmitEmptyMatches => {
14784 self.write_keyword("ALL ROWS PER MATCH OMIT EMPTY MATCHES");
14785 }
14786 MatchRecognizeRows::AllRowsPerMatchWithUnmatchedRows => {
14787 self.write_keyword("ALL ROWS PER MATCH WITH UNMATCHED ROWS");
14788 }
14789 }
14790 needs_separator = true;
14791 }
14792
14793 if let Some(after) = &mr.after {
14795 if needs_separator {
14796 if self.config.pretty {
14797 self.write_newline();
14798 self.write_indent();
14799 } else {
14800 self.write_space();
14801 }
14802 } else if self.config.pretty {
14803 self.write_newline();
14804 self.write_indent();
14805 }
14806 match after {
14807 MatchRecognizeAfter::PastLastRow => {
14808 self.write_keyword("AFTER MATCH SKIP PAST LAST ROW");
14809 }
14810 MatchRecognizeAfter::ToNextRow => {
14811 self.write_keyword("AFTER MATCH SKIP TO NEXT ROW");
14812 }
14813 MatchRecognizeAfter::ToFirst(ident) => {
14814 self.write_keyword("AFTER MATCH SKIP TO FIRST");
14815 self.write_space();
14816 self.generate_identifier(ident)?;
14817 }
14818 MatchRecognizeAfter::ToLast(ident) => {
14819 self.write_keyword("AFTER MATCH SKIP TO LAST");
14820 self.write_space();
14821 self.generate_identifier(ident)?;
14822 }
14823 }
14824 needs_separator = true;
14825 }
14826
14827 if let Some(pattern) = &mr.pattern {
14829 if needs_separator {
14830 if self.config.pretty {
14831 self.write_newline();
14832 self.write_indent();
14833 } else {
14834 self.write_space();
14835 }
14836 } else if self.config.pretty {
14837 self.write_newline();
14838 self.write_indent();
14839 }
14840 self.write_keyword("PATTERN");
14841 self.write_space();
14842 self.write("(");
14843 self.write(pattern);
14844 self.write(")");
14845 needs_separator = true;
14846 }
14847
14848 if let Some(define) = &mr.define {
14850 if !define.is_empty() {
14851 if needs_separator {
14852 if self.config.pretty {
14853 self.write_newline();
14854 self.write_indent();
14855 } else {
14856 self.write_space();
14857 }
14858 } else if self.config.pretty {
14859 self.write_newline();
14860 self.write_indent();
14861 }
14862 self.write_keyword("DEFINE");
14863 if self.config.pretty {
14865 self.indent_level += 1;
14866 for (i, (name, expr)) in define.iter().enumerate() {
14867 if i > 0 {
14868 self.write(",");
14869 }
14870 self.write_newline();
14871 self.write_indent();
14872 self.generate_identifier(name)?;
14873 self.write(" AS ");
14874 self.generate_expression(expr)?;
14875 }
14876 self.indent_level -= 1;
14877 } else {
14878 self.write_space();
14879 for (i, (name, expr)) in define.iter().enumerate() {
14880 if i > 0 {
14881 self.write(", ");
14882 }
14883 self.generate_identifier(name)?;
14884 self.write(" AS ");
14885 self.generate_expression(expr)?;
14886 }
14887 }
14888 }
14889 }
14890
14891 if self.config.pretty {
14892 self.indent_level -= 1;
14893 self.write_newline();
14894 }
14895 self.write(")");
14896
14897 if let Some(alias) = &mr.alias {
14899 self.write(" ");
14900 if mr.alias_explicit_as {
14901 self.write_keyword("AS");
14902 self.write(" ");
14903 }
14904 self.generate_identifier(alias)?;
14905 }
14906
14907 Ok(())
14908 }
14909
14910 fn generate_hint(&mut self, hint: &Hint) -> Result<()> {
14912 use crate::dialects::DialectType;
14913
14914 let supports_hints = matches!(
14916 self.config.dialect,
14917 None | Some(DialectType::Oracle) | Some(DialectType::MySQL) |
14919 Some(DialectType::Spark) | Some(DialectType::Hive) |
14920 Some(DialectType::Databricks) | Some(DialectType::PostgreSQL)
14921 );
14922
14923 if !supports_hints || hint.expressions.is_empty() {
14924 return Ok(());
14925 }
14926
14927 let mut hint_strings: Vec<String> = Vec::new();
14930 for expr in &hint.expressions {
14931 match expr {
14932 HintExpression::Raw(text) => {
14933 let parsed = self.parse_raw_hint_text(text);
14935 hint_strings.extend(parsed);
14936 }
14937 _ => {
14938 hint_strings.push(self.hint_expression_to_string(expr)?);
14939 }
14940 }
14941 }
14942
14943 let use_multiline = self.config.pretty && hint_strings.len() > 1;
14947
14948 if use_multiline {
14949 self.write(" /*+ ");
14951 for (i, hint_str) in hint_strings.iter().enumerate() {
14952 if i > 0 {
14953 self.write_newline();
14954 self.write(" "); }
14956 self.write(hint_str);
14957 }
14958 self.write(" */");
14959 } else {
14960 self.write(" /*+ ");
14962 let sep = match self.config.dialect {
14963 Some(DialectType::Spark) | Some(DialectType::Databricks) => ", ",
14964 _ => " ",
14965 };
14966 for (i, hint_str) in hint_strings.iter().enumerate() {
14967 if i > 0 {
14968 self.write(sep);
14969 }
14970 self.write(hint_str);
14971 }
14972 self.write(" */");
14973 }
14974
14975 Ok(())
14976 }
14977
14978 fn parse_raw_hint_text(&self, text: &str) -> Vec<String> {
14982 let mut results = Vec::new();
14983 let mut chars = text.chars().peekable();
14984 let mut current = String::new();
14985 let mut paren_depth = 0;
14986 let mut has_unparseable_content = false;
14987 let mut position_after_last_function = 0;
14988 let mut char_position = 0;
14989
14990 while let Some(c) = chars.next() {
14991 char_position += c.len_utf8();
14992 match c {
14993 '(' => {
14994 paren_depth += 1;
14995 current.push(c);
14996 }
14997 ')' => {
14998 paren_depth -= 1;
14999 current.push(c);
15000 if paren_depth == 0 {
15002 let trimmed = current.trim().to_string();
15003 if !trimmed.is_empty() {
15004 let formatted = self.format_hint_function(&trimmed);
15006 results.push(formatted);
15007 }
15008 current.clear();
15009 position_after_last_function = char_position;
15010 }
15011 }
15012 ' ' | '\t' | '\n' | ',' if paren_depth == 0 => {
15013 }
15015 _ if paren_depth == 0 => {
15016 current.push(c);
15018 }
15019 _ => {
15020 current.push(c);
15021 }
15022 }
15023 }
15024
15025 let remaining_text = text[position_after_last_function..].trim();
15027 if !remaining_text.is_empty() {
15028 let words: Vec<&str> = remaining_text.split_whitespace().collect();
15032 let looks_like_hint_functions = words.iter().all(|word| {
15033 word.contains('(') || (word.chars().all(|c| c.is_ascii_uppercase() || c == '_'))
15035 });
15036
15037 if !looks_like_hint_functions && words.len() > 1 {
15038 has_unparseable_content = true;
15039 }
15040 }
15041
15042 if has_unparseable_content {
15044 return vec![text.trim().to_string()];
15045 }
15046
15047 if results.is_empty() {
15049 results.push(text.trim().to_string());
15050 }
15051
15052 results
15053 }
15054
15055 fn format_hint_function(&self, hint: &str) -> String {
15058 if !self.config.pretty {
15059 return hint.to_string();
15060 }
15061
15062 if let Some(paren_pos) = hint.find('(') {
15064 if hint.ends_with(')') {
15065 let name = &hint[..paren_pos];
15066 let args_str = &hint[paren_pos + 1..hint.len() - 1];
15067
15068 let args: Vec<&str> = args_str.split_whitespace().collect();
15070
15071 let total_args_width: usize =
15073 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() {
15077 let mut result = format!("{}(\n", name);
15078 for arg in &args {
15079 result.push_str(" "); result.push_str(arg);
15081 result.push('\n');
15082 }
15083 result.push_str(" )"); return result;
15085 }
15086 }
15087 }
15088
15089 hint.to_string()
15090 }
15091
15092 fn hint_expression_to_string(&mut self, expr: &HintExpression) -> Result<String> {
15094 match expr {
15095 HintExpression::Function { name, args } => {
15096 let arg_strings: Vec<String> = args
15098 .iter()
15099 .map(|arg| {
15100 let mut gen = Generator::with_config(self.config.clone());
15101 gen.generate_expression(arg)?;
15102 Ok(gen.output)
15103 })
15104 .collect::<Result<Vec<_>>>()?;
15105
15106 let total_args_width: usize = arg_strings.iter().map(|s| s.len()).sum::<usize>()
15108 + arg_strings.len().saturating_sub(1); let args_multiline =
15113 self.config.pretty && total_args_width > self.config.max_text_width;
15114
15115 if args_multiline && !arg_strings.is_empty() {
15116 let mut result = format!("{}(\n", name);
15118 for arg_str in &arg_strings {
15119 result.push_str(" "); result.push_str(arg_str);
15121 result.push('\n');
15122 }
15123 result.push_str(" )"); Ok(result)
15125 } else {
15126 let args_str = arg_strings.join(" ");
15128 Ok(format!("{}({})", name, args_str))
15129 }
15130 }
15131 HintExpression::Identifier(name) => Ok(name.clone()),
15132 HintExpression::Raw(text) => {
15133 if self.config.pretty {
15135 Ok(self.format_hint_function(text))
15136 } else {
15137 Ok(text.clone())
15138 }
15139 }
15140 }
15141 }
15142
15143 fn generate_table(&mut self, table: &TableRef) -> Result<()> {
15144 if table.only {
15146 self.write_keyword("ONLY");
15147 self.write_space();
15148 }
15149
15150 if let Some(ref identifier_func) = table.identifier_func {
15152 self.generate_expression(identifier_func)?;
15153 } else {
15154 if let Some(catalog) = &table.catalog {
15155 self.generate_identifier(catalog)?;
15156 self.write(".");
15157 }
15158 if let Some(schema) = &table.schema {
15159 self.generate_identifier(schema)?;
15160 self.write(".");
15161 }
15162 self.generate_identifier(&table.name)?;
15163 }
15164
15165 if let Some(changes) = &table.changes {
15167 self.write(" ");
15168 self.generate_changes(changes)?;
15169 }
15170
15171 if !table.partitions.is_empty() {
15173 self.write_space();
15174 self.write_keyword("PARTITION");
15175 self.write("(");
15176 for (i, partition) in table.partitions.iter().enumerate() {
15177 if i > 0 {
15178 self.write(", ");
15179 }
15180 self.generate_identifier(partition)?;
15181 }
15182 self.write(")");
15183 }
15184
15185 if table.changes.is_none() {
15188 if let Some(when) = &table.when {
15189 self.write_space();
15190 self.generate_historical_data(when)?;
15191 }
15192 }
15193
15194 if let Some(ref system_time) = table.system_time {
15196 self.write_space();
15197 self.write(system_time);
15198 }
15199
15200 if let Some(ref version) = table.version {
15202 self.write_space();
15203 self.generate_version(version)?;
15204 }
15205
15206 let alias_post_tablesample = self.config.alias_post_tablesample;
15210
15211 if alias_post_tablesample {
15212 self.generate_table_sample_clause(table)?;
15214 }
15215
15216 let is_sqlite_hint = matches!(self.config.dialect, Some(DialectType::SQLite))
15219 && table.hints.iter().any(|h| {
15220 if let Expression::Identifier(id) = h {
15221 id.name.starts_with("INDEXED BY") || id.name == "NOT INDEXED"
15222 } else {
15223 false
15224 }
15225 });
15226 if !table.hints.is_empty() && !is_sqlite_hint {
15227 for hint in &table.hints {
15228 self.write_space();
15229 self.generate_expression(hint)?;
15230 }
15231 }
15232
15233 if let Some(alias) = &table.alias {
15234 self.write_space();
15235 let always_use_as = self.config.dialect.is_none()
15238 || matches!(
15239 self.config.dialect,
15240 Some(DialectType::Generic)
15241 | Some(DialectType::PostgreSQL)
15242 | Some(DialectType::Redshift)
15243 | Some(DialectType::Snowflake)
15244 | Some(DialectType::BigQuery)
15245 | Some(DialectType::Presto)
15246 | Some(DialectType::Trino)
15247 | Some(DialectType::TSQL)
15248 | Some(DialectType::Fabric)
15249 | Some(DialectType::MySQL)
15250 | Some(DialectType::Spark)
15251 | Some(DialectType::Hive)
15252 | Some(DialectType::SQLite)
15253 | Some(DialectType::Drill)
15254 );
15255 let is_stage_ref = table.name.name.starts_with('@');
15256 let suppress_as = matches!(self.config.dialect, Some(DialectType::Oracle));
15258 if !suppress_as && (table.alias_explicit_as || always_use_as || is_stage_ref) {
15259 self.write_keyword("AS");
15260 self.write_space();
15261 }
15262 self.generate_identifier(alias)?;
15263
15264 if !table.column_aliases.is_empty() && self.config.supports_table_alias_columns {
15267 self.write("(");
15268 for (i, col_alias) in table.column_aliases.iter().enumerate() {
15269 if i > 0 {
15270 self.write(", ");
15271 }
15272 self.generate_identifier(col_alias)?;
15273 }
15274 self.write(")");
15275 }
15276 }
15277
15278 if !alias_post_tablesample {
15280 self.generate_table_sample_clause(table)?;
15281 }
15282
15283 if is_sqlite_hint {
15285 for hint in &table.hints {
15286 self.write_space();
15287 self.generate_expression(hint)?;
15288 }
15289 }
15290
15291 if table.final_ && matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
15293 self.write_space();
15294 self.write_keyword("FINAL");
15295 }
15296
15297 for comment in &table.trailing_comments {
15299 self.write_space();
15300 self.write_formatted_comment(comment);
15301 }
15302
15303 Ok(())
15304 }
15305
15306 fn generate_table_sample_clause(&mut self, table: &TableRef) -> Result<()> {
15308 if let Some(ref ts) = table.table_sample {
15309 self.write_space();
15310 if ts.is_using_sample {
15311 self.write_keyword("USING SAMPLE");
15312 } else {
15313 self.write_keyword(self.config.tablesample_keywords);
15315 }
15316 self.generate_sample_body(ts)?;
15317 if let Some(ref seed) = ts.seed {
15319 self.write_space();
15320 self.write_keyword(self.config.tablesample_seed_keyword);
15321 self.write(" (");
15322 self.generate_expression(seed)?;
15323 self.write(")");
15324 }
15325 }
15326 Ok(())
15327 }
15328
15329 fn generate_stage_reference(&mut self, sr: &StageReference) -> Result<()> {
15330 if sr.quoted {
15334 self.write("'");
15335 }
15336
15337 self.write(&sr.name);
15338 if let Some(path) = &sr.path {
15339 self.write(path);
15340 }
15341
15342 if sr.quoted {
15343 self.write("'");
15344 }
15345
15346 let has_options = sr.file_format.is_some() || sr.pattern.is_some();
15348 if has_options {
15349 self.write(" (");
15350 let mut first = true;
15351
15352 if let Some(file_format) = &sr.file_format {
15353 if !first {
15354 self.write(", ");
15355 }
15356 self.write_keyword("FILE_FORMAT");
15357 self.write(" => ");
15358 self.generate_expression(file_format)?;
15359 first = false;
15360 }
15361
15362 if let Some(pattern) = &sr.pattern {
15363 if !first {
15364 self.write(", ");
15365 }
15366 self.write_keyword("PATTERN");
15367 self.write(" => '");
15368 self.write(pattern);
15369 self.write("'");
15370 }
15371
15372 self.write(")");
15373 }
15374 Ok(())
15375 }
15376
15377 fn generate_star(&mut self, star: &Star) -> Result<()> {
15378 use crate::dialects::DialectType;
15379
15380 if let Some(table) = &star.table {
15381 self.generate_identifier(table)?;
15382 self.write(".");
15383 }
15384 self.write("*");
15385
15386 if let Some(except) = &star.except {
15388 if !except.is_empty() {
15389 self.write_space();
15390 match self.config.dialect {
15392 Some(DialectType::BigQuery) => self.write_keyword("EXCEPT"),
15393 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => {
15394 self.write_keyword("EXCLUDE")
15395 }
15396 _ => self.write_keyword("EXCEPT"), }
15398 self.write(" (");
15399 for (i, col) in except.iter().enumerate() {
15400 if i > 0 {
15401 self.write(", ");
15402 }
15403 self.generate_identifier(col)?;
15404 }
15405 self.write(")");
15406 }
15407 }
15408
15409 if let Some(replace) = &star.replace {
15411 if !replace.is_empty() {
15412 self.write_space();
15413 self.write_keyword("REPLACE");
15414 self.write(" (");
15415 for (i, alias) in replace.iter().enumerate() {
15416 if i > 0 {
15417 self.write(", ");
15418 }
15419 self.generate_expression(&alias.this)?;
15420 self.write_space();
15421 self.write_keyword("AS");
15422 self.write_space();
15423 self.generate_identifier(&alias.alias)?;
15424 }
15425 self.write(")");
15426 }
15427 }
15428
15429 if let Some(rename) = &star.rename {
15431 if !rename.is_empty() {
15432 self.write_space();
15433 self.write_keyword("RENAME");
15434 self.write(" (");
15435 for (i, (old_name, new_name)) in rename.iter().enumerate() {
15436 if i > 0 {
15437 self.write(", ");
15438 }
15439 self.generate_identifier(old_name)?;
15440 self.write_space();
15441 self.write_keyword("AS");
15442 self.write_space();
15443 self.generate_identifier(new_name)?;
15444 }
15445 self.write(")");
15446 }
15447 }
15448
15449 for comment in &star.trailing_comments {
15451 self.write_space();
15452 self.write_formatted_comment(comment);
15453 }
15454
15455 Ok(())
15456 }
15457
15458 fn generate_braced_wildcard(&mut self, expr: &Expression) -> Result<()> {
15460 self.write("{");
15461 match expr {
15462 Expression::Star(star) => {
15463 self.generate_star(star)?;
15465 }
15466 Expression::ILike(ilike) => {
15467 self.generate_expression(&ilike.left)?;
15469 self.write_space();
15470 self.write_keyword("ILIKE");
15471 self.write_space();
15472 self.generate_expression(&ilike.right)?;
15473 }
15474 _ => {
15475 self.generate_expression(expr)?;
15476 }
15477 }
15478 self.write("}");
15479 Ok(())
15480 }
15481
15482 fn generate_alias(&mut self, alias: &Alias) -> Result<()> {
15483 match &alias.this {
15487 Expression::Column(col) => {
15488 if let Some(table) = &col.table {
15490 self.generate_identifier(table)?;
15491 self.write(".");
15492 }
15493 self.generate_identifier(&col.name)?;
15494 }
15495 _ => {
15496 self.generate_expression(&alias.this)?;
15497 }
15498 }
15499
15500 if !alias.pre_alias_comments.is_empty() && !alias.trailing_comments.is_empty() {
15504 for comment in &alias.pre_alias_comments {
15505 self.write_space();
15506 self.write_formatted_comment(comment);
15507 }
15508 }
15509
15510 use crate::dialects::DialectType;
15511
15512 let is_table_source = matches!(
15518 &alias.this,
15519 Expression::JSONTable(_)
15520 | Expression::XMLTable(_)
15521 | Expression::TableFromRows(_)
15522 | Expression::Unnest(_)
15523 | Expression::MatchRecognize(_)
15524 | Expression::Select(_)
15525 | Expression::Subquery(_)
15526 | Expression::Paren(_)
15527 );
15528 let dialect_skips_table_alias_as = matches!(self.config.dialect, Some(DialectType::Oracle));
15529 let skip_as = is_table_source && dialect_skips_table_alias_as;
15530
15531 self.write_space();
15532 if !skip_as {
15533 self.write_keyword("AS");
15534 self.write_space();
15535 }
15536
15537 let skip_column_aliases = matches!(self.config.dialect, Some(DialectType::BigQuery));
15539
15540 if alias.alias.is_empty() && !alias.column_aliases.is_empty() && !skip_column_aliases {
15542 self.write("(");
15544 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
15545 if i > 0 {
15546 self.write(", ");
15547 }
15548 self.generate_alias_identifier(col_alias)?;
15549 }
15550 self.write(")");
15551 } else if !alias.column_aliases.is_empty() && !skip_column_aliases {
15552 self.generate_alias_identifier(&alias.alias)?;
15554 self.write("(");
15555 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
15556 if i > 0 {
15557 self.write(", ");
15558 }
15559 self.generate_alias_identifier(col_alias)?;
15560 }
15561 self.write(")");
15562 } else {
15563 self.generate_alias_identifier(&alias.alias)?;
15565 }
15566
15567 for comment in &alias.trailing_comments {
15569 self.write_space();
15570 self.write_formatted_comment(comment);
15571 }
15572
15573 if alias.trailing_comments.is_empty() {
15578 for comment in &alias.pre_alias_comments {
15579 self.write_space();
15580 self.write_formatted_comment(comment);
15581 }
15582 }
15583
15584 Ok(())
15585 }
15586
15587 fn generate_cast(&mut self, cast: &Cast) -> Result<()> {
15588 use crate::dialects::DialectType;
15589
15590 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
15592 self.generate_expression(&cast.this)?;
15593 self.write(" :> ");
15594 self.generate_data_type(&cast.to)?;
15595 return Ok(());
15596 }
15597
15598 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
15600 let is_unknown_type = matches!(cast.to, DataType::Unknown)
15601 || matches!(cast.to, DataType::Custom { ref name } if name.is_empty());
15602 if is_unknown_type {
15603 if let Some(format) = &cast.format {
15604 self.write_keyword("CAST");
15605 self.write("(");
15606 self.generate_expression(&cast.this)?;
15607 self.write_space();
15608 self.write_keyword("AS");
15609 self.write_space();
15610 self.write_keyword("FORMAT");
15611 self.write_space();
15612 self.generate_expression(format)?;
15613 self.write(")");
15614 return Ok(());
15615 }
15616 }
15617 }
15618
15619 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
15622 if let Some(format) = &cast.format {
15623 let is_date = matches!(cast.to, DataType::Date);
15625 let is_timestamp = matches!(cast.to, DataType::Timestamp { .. });
15626
15627 if is_date || is_timestamp {
15628 let func_name = if is_date { "TO_DATE" } else { "TO_TIMESTAMP" };
15629 self.write_keyword(func_name);
15630 self.write("(");
15631 self.generate_expression(&cast.this)?;
15632 self.write(", ");
15633
15634 if let Expression::Literal(Literal::String(fmt_str)) = format.as_ref() {
15637 let normalized = self.normalize_oracle_format(fmt_str);
15638 self.write("'");
15639 self.write(&normalized);
15640 self.write("'");
15641 } else {
15642 self.generate_expression(format)?;
15643 }
15644
15645 self.write(")");
15646 return Ok(());
15647 }
15648 }
15649 }
15650
15651 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
15654 if let Expression::Array(arr) = &cast.this {
15655 self.generate_data_type(&cast.to)?;
15656 self.write("[");
15658 for (i, expr) in arr.expressions.iter().enumerate() {
15659 if i > 0 {
15660 self.write(", ");
15661 }
15662 self.generate_expression(expr)?;
15663 }
15664 self.write("]");
15665 return Ok(());
15666 }
15667 if matches!(&cast.this, Expression::ArrayFunc(_)) {
15668 self.generate_data_type(&cast.to)?;
15669 self.generate_expression(&cast.this)?;
15670 return Ok(());
15671 }
15672 }
15673
15674 if matches!(
15677 self.config.dialect,
15678 Some(DialectType::DuckDB) | Some(DialectType::Presto) | Some(DialectType::Trino)
15679 ) {
15680 if let Expression::Struct(ref s) = cast.this {
15681 let all_unnamed = s.fields.iter().all(|(name, _)| name.is_none());
15682 if all_unnamed && matches!(cast.to, DataType::Struct { .. }) {
15683 self.write_keyword("CAST");
15684 self.write("(");
15685 self.generate_struct_as_row(s)?;
15686 self.write_space();
15687 self.write_keyword("AS");
15688 self.write_space();
15689 self.generate_data_type(&cast.to)?;
15690 self.write(")");
15691 return Ok(());
15692 }
15693 }
15694 }
15695
15696 let use_double_colon = cast.double_colon_syntax && self.dialect_prefers_double_colon();
15699
15700 if use_double_colon {
15701 self.generate_expression(&cast.this)?;
15703 self.write("::");
15704 self.generate_data_type(&cast.to)?;
15705 } else {
15706 self.write_keyword("CAST");
15708 self.write("(");
15709 self.generate_expression(&cast.this)?;
15710 self.write_space();
15711 self.write_keyword("AS");
15712 self.write_space();
15713 if matches!(
15716 self.config.dialect,
15717 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB)
15718 ) {
15719 match &cast.to {
15720 DataType::Custom { ref name } => {
15721 let upper = name.to_uppercase();
15722 match upper.as_str() {
15723 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" | "LONGBLOB" | "MEDIUMBLOB"
15724 | "TINYBLOB" => {
15725 self.write_keyword("CHAR");
15726 }
15727 _ => {
15728 self.generate_data_type(&cast.to)?;
15729 }
15730 }
15731 }
15732 DataType::VarChar { length, .. } => {
15733 self.write_keyword("CHAR");
15735 if let Some(n) = length {
15736 self.write(&format!("({})", n));
15737 }
15738 }
15739 DataType::Text => {
15740 self.write_keyword("CHAR");
15742 }
15743 DataType::Timestamp {
15744 precision,
15745 timezone: false,
15746 } => {
15747 self.write_keyword("DATETIME");
15749 if let Some(p) = precision {
15750 self.write(&format!("({})", p));
15751 }
15752 }
15753 _ => {
15754 self.generate_data_type(&cast.to)?;
15755 }
15756 }
15757 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
15758 match &cast.to {
15760 DataType::String { length } => {
15761 self.write_keyword("VARCHAR");
15762 if let Some(n) = length {
15763 self.write(&format!("({})", n));
15764 }
15765 }
15766 _ => {
15767 self.generate_data_type(&cast.to)?;
15768 }
15769 }
15770 } else {
15771 self.generate_data_type(&cast.to)?;
15772 }
15773
15774 if let Some(default) = &cast.default {
15776 self.write_space();
15777 self.write_keyword("DEFAULT");
15778 self.write_space();
15779 self.generate_expression(default)?;
15780 self.write_space();
15781 self.write_keyword("ON");
15782 self.write_space();
15783 self.write_keyword("CONVERSION");
15784 self.write_space();
15785 self.write_keyword("ERROR");
15786 }
15787
15788 if let Some(format) = &cast.format {
15791 if matches!(
15793 self.config.dialect,
15794 Some(crate::dialects::DialectType::Oracle)
15795 ) {
15796 self.write(", ");
15797 } else {
15798 self.write_space();
15799 self.write_keyword("FORMAT");
15800 self.write_space();
15801 }
15802 self.generate_expression(format)?;
15803 }
15804
15805 self.write(")");
15806 for comment in &cast.trailing_comments {
15808 self.write_space();
15809 self.write_formatted_comment(comment);
15810 }
15811 }
15812 Ok(())
15813 }
15814
15815 fn generate_struct_as_row(&mut self, s: &crate::expressions::Struct) -> Result<()> {
15818 self.write_keyword("ROW");
15819 self.write("(");
15820 for (i, (_, expr)) in s.fields.iter().enumerate() {
15821 if i > 0 {
15822 self.write(", ");
15823 }
15824 if let Expression::Struct(ref inner_s) = expr {
15826 self.generate_struct_as_row(inner_s)?;
15827 } else {
15828 self.generate_expression(expr)?;
15829 }
15830 }
15831 self.write(")");
15832 Ok(())
15833 }
15834
15835 fn normalize_oracle_format(&self, format: &str) -> String {
15838 let mut result = String::new();
15841 let chars: Vec<char> = format.chars().collect();
15842 let mut i = 0;
15843
15844 while i < chars.len() {
15845 if i + 1 < chars.len() && chars[i] == 'H' && chars[i + 1] == 'H' {
15846 if i + 2 < chars.len() {
15848 let next = chars[i + 2];
15849 if next == '1' || next == '2' {
15850 result.push('H');
15852 result.push('H');
15853 i += 2;
15854 continue;
15855 }
15856 }
15857 result.push_str("HH12");
15859 i += 2;
15860 } else {
15861 result.push(chars[i]);
15862 i += 1;
15863 }
15864 }
15865
15866 result
15867 }
15868
15869 fn dialect_prefers_double_colon(&self) -> bool {
15873 false
15876 }
15877
15878 fn generate_mod_func(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
15880 use crate::dialects::DialectType;
15881
15882 let use_percent_operator = matches!(
15884 self.config.dialect,
15885 Some(DialectType::Snowflake)
15886 | Some(DialectType::MySQL)
15887 | Some(DialectType::Presto)
15888 | Some(DialectType::Trino)
15889 | Some(DialectType::PostgreSQL)
15890 | Some(DialectType::DuckDB)
15891 | Some(DialectType::Hive)
15892 | Some(DialectType::Spark)
15893 | Some(DialectType::Databricks)
15894 | Some(DialectType::Athena)
15895 );
15896
15897 if use_percent_operator {
15898 let needs_paren = |e: &Expression| matches!(e, Expression::Add(_) | Expression::Sub(_));
15901 if needs_paren(&f.this) {
15902 self.write("(");
15903 self.generate_expression(&f.this)?;
15904 self.write(")");
15905 } else {
15906 self.generate_expression(&f.this)?;
15907 }
15908 self.write(" % ");
15909 if needs_paren(&f.expression) {
15910 self.write("(");
15911 self.generate_expression(&f.expression)?;
15912 self.write(")");
15913 } else {
15914 self.generate_expression(&f.expression)?;
15915 }
15916 Ok(())
15917 } else {
15918 self.generate_binary_func("MOD", &f.this, &f.expression)
15919 }
15920 }
15921
15922 fn generate_ifnull(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
15924 use crate::dialects::DialectType;
15925
15926 let func_name = match self.config.dialect {
15928 Some(DialectType::Snowflake) => "COALESCE",
15929 _ => "IFNULL",
15930 };
15931
15932 self.generate_binary_func(func_name, &f.this, &f.expression)
15933 }
15934
15935 fn generate_nvl(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
15937 if let Some(ref original_name) = f.original_name {
15939 return self.generate_binary_func(original_name, &f.this, &f.expression);
15940 }
15941
15942 use crate::dialects::DialectType;
15944 let func_name = match self.config.dialect {
15945 Some(DialectType::Snowflake)
15946 | Some(DialectType::ClickHouse)
15947 | Some(DialectType::PostgreSQL)
15948 | Some(DialectType::Presto)
15949 | Some(DialectType::Trino)
15950 | Some(DialectType::Athena)
15951 | Some(DialectType::DuckDB)
15952 | Some(DialectType::BigQuery)
15953 | Some(DialectType::Spark)
15954 | Some(DialectType::Databricks)
15955 | Some(DialectType::Hive) => "COALESCE",
15956 Some(DialectType::MySQL)
15957 | Some(DialectType::Doris)
15958 | Some(DialectType::StarRocks)
15959 | Some(DialectType::SingleStore)
15960 | Some(DialectType::TiDB) => "IFNULL",
15961 _ => "NVL",
15962 };
15963
15964 self.generate_binary_func(func_name, &f.this, &f.expression)
15965 }
15966
15967 fn generate_stddev_samp(&mut self, f: &crate::expressions::AggFunc) -> Result<()> {
15969 use crate::dialects::DialectType;
15970
15971 let func_name = match self.config.dialect {
15973 Some(DialectType::Snowflake) => "STDDEV",
15974 _ => "STDDEV_SAMP",
15975 };
15976
15977 self.generate_agg_func(func_name, f)
15978 }
15979
15980 fn generate_collation(&mut self, coll: &CollationExpr) -> Result<()> {
15981 self.generate_expression(&coll.this)?;
15982 self.write_space();
15983 self.write_keyword("COLLATE");
15984 self.write_space();
15985 if coll.quoted {
15986 self.write("'");
15988 self.write(&coll.collation);
15989 self.write("'");
15990 } else if coll.double_quoted {
15991 self.write("\"");
15993 self.write(&coll.collation);
15994 self.write("\"");
15995 } else {
15996 self.write(&coll.collation);
15998 }
15999 Ok(())
16000 }
16001
16002 fn generate_case(&mut self, case: &Case) -> Result<()> {
16003 let multiline_case = if self.config.pretty {
16005 let mut statements: Vec<String> = Vec::new();
16007 let operand_str = if let Some(operand) = &case.operand {
16008 let s = self.generate_to_string(operand)?;
16009 statements.push(format!("CASE {}", s));
16010 s
16011 } else {
16012 statements.push("CASE".to_string());
16013 String::new()
16014 };
16015 let _ = operand_str;
16016 for (condition, result) in &case.whens {
16017 statements.push(format!("WHEN {}", self.generate_to_string(condition)?));
16018 statements.push(format!("THEN {}", self.generate_to_string(result)?));
16019 }
16020 if let Some(else_) = &case.else_ {
16021 statements.push(format!("ELSE {}", self.generate_to_string(else_)?));
16022 }
16023 statements.push("END".to_string());
16024 self.too_wide(&statements)
16025 } else {
16026 false
16027 };
16028
16029 self.write_keyword("CASE");
16030 if let Some(operand) = &case.operand {
16031 self.write_space();
16032 self.generate_expression(operand)?;
16033 }
16034 if multiline_case {
16035 self.indent_level += 1;
16036 }
16037 for (condition, result) in &case.whens {
16038 if multiline_case {
16039 self.write_newline();
16040 self.write_indent();
16041 } else {
16042 self.write_space();
16043 }
16044 self.write_keyword("WHEN");
16045 self.write_space();
16046 self.generate_expression(condition)?;
16047 if multiline_case {
16048 self.write_newline();
16049 self.write_indent();
16050 } else {
16051 self.write_space();
16052 }
16053 self.write_keyword("THEN");
16054 self.write_space();
16055 self.generate_expression(result)?;
16056 }
16057 if let Some(else_) = &case.else_ {
16058 if multiline_case {
16059 self.write_newline();
16060 self.write_indent();
16061 } else {
16062 self.write_space();
16063 }
16064 self.write_keyword("ELSE");
16065 self.write_space();
16066 self.generate_expression(else_)?;
16067 }
16068 if multiline_case {
16069 self.indent_level -= 1;
16070 self.write_newline();
16071 self.write_indent();
16072 } else {
16073 self.write_space();
16074 }
16075 self.write_keyword("END");
16076 for comment in &case.comments {
16078 self.write(" ");
16079 self.write_formatted_comment(comment);
16080 }
16081 Ok(())
16082 }
16083
16084 fn generate_function(&mut self, func: &Function) -> Result<()> {
16085 let normalized_name = self.normalize_func_name(&func.name);
16087 let upper_name = func.name.to_uppercase();
16088
16089 if matches!(self.config.dialect, Some(DialectType::DuckDB))
16091 && upper_name == "ARRAY_CONSTRUCT_COMPACT"
16092 {
16093 self.write("LIST_FILTER(");
16094 self.write("[");
16095 for (i, arg) in func.args.iter().enumerate() {
16096 if i > 0 {
16097 self.write(", ");
16098 }
16099 self.generate_expression(arg)?;
16100 }
16101 self.write("], _u -> NOT _u IS NULL)");
16102 return Ok(());
16103 }
16104
16105 if upper_name == "STRUCT"
16107 && !matches!(
16108 self.config.dialect,
16109 Some(DialectType::BigQuery)
16110 | Some(DialectType::Spark)
16111 | Some(DialectType::Databricks)
16112 | Some(DialectType::Hive)
16113 | None
16114 )
16115 {
16116 return self.generate_struct_function_cross_dialect(func);
16117 }
16118
16119 if upper_name == "__SS_JSON_PATH_QMARK__" && func.args.len() == 2 {
16122 self.generate_expression(&func.args[0])?;
16123 self.write("::?");
16124 if let Expression::Literal(crate::expressions::Literal::String(key)) = &func.args[1] {
16126 self.write(key);
16127 } else {
16128 self.generate_expression(&func.args[1])?;
16129 }
16130 return Ok(());
16131 }
16132
16133 if upper_name == "__PG_BITWISE_XOR__" && func.args.len() == 2 {
16135 self.generate_expression(&func.args[0])?;
16136 self.write(" # ");
16137 self.generate_expression(&func.args[1])?;
16138 return Ok(());
16139 }
16140
16141 if matches!(
16143 self.config.dialect,
16144 Some(DialectType::Spark | DialectType::Databricks | DialectType::Hive)
16145 ) && upper_name == "TRY"
16146 && func.args.len() == 1
16147 {
16148 self.generate_expression(&func.args[0])?;
16149 return Ok(());
16150 }
16151
16152 if self.config.dialect == Some(DialectType::ClickHouse)
16154 && upper_name == "TOSTARTOFDAY"
16155 && func.args.len() == 1
16156 {
16157 self.write("dateTrunc('DAY', ");
16158 self.generate_expression(&func.args[0])?;
16159 self.write(")");
16160 return Ok(());
16161 }
16162
16163 if self.config.dialect == Some(DialectType::Redshift)
16165 && upper_name == "CONCAT"
16166 && func.args.len() >= 2
16167 {
16168 for (i, arg) in func.args.iter().enumerate() {
16169 if i > 0 {
16170 self.write(" || ");
16171 }
16172 self.generate_expression(arg)?;
16173 }
16174 return Ok(());
16175 }
16176
16177 if self.config.dialect == Some(DialectType::Redshift)
16179 && upper_name == "CONCAT_WS"
16180 && func.args.len() >= 2
16181 {
16182 let sep = &func.args[0];
16183 for (i, arg) in func.args.iter().skip(1).enumerate() {
16184 if i > 0 {
16185 self.write(" || ");
16186 self.generate_expression(sep)?;
16187 self.write(" || ");
16188 }
16189 self.generate_expression(arg)?;
16190 }
16191 return Ok(());
16192 }
16193
16194 if self.config.dialect == Some(DialectType::Redshift)
16197 && (upper_name == "DATEDIFF" || upper_name == "DATE_DIFF")
16198 && func.args.len() == 3
16199 {
16200 self.write_keyword("DATEDIFF");
16201 self.write("(");
16202 self.write_redshift_date_part(&func.args[0]);
16204 self.write(", ");
16205 self.generate_expression(&func.args[1])?;
16206 self.write(", ");
16207 self.generate_expression(&func.args[2])?;
16208 self.write(")");
16209 return Ok(());
16210 }
16211
16212 if self.config.dialect == Some(DialectType::Redshift)
16215 && (upper_name == "DATEADD" || upper_name == "DATE_ADD")
16216 && func.args.len() == 3
16217 {
16218 self.write_keyword("DATEADD");
16219 self.write("(");
16220 self.write_redshift_date_part(&func.args[0]);
16222 self.write(", ");
16223 self.generate_expression(&func.args[1])?;
16224 self.write(", ");
16225 self.generate_expression(&func.args[2])?;
16226 self.write(")");
16227 return Ok(());
16228 }
16229
16230 if upper_name == "UUID_STRING"
16232 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None)
16233 {
16234 let func_name = match self.config.dialect {
16235 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
16236 Some(DialectType::BigQuery) => "GENERATE_UUID",
16237 _ => "UUID",
16238 };
16239 self.write_keyword(func_name);
16240 self.write("()");
16241 return Ok(());
16242 }
16243
16244 if self.config.dialect == Some(DialectType::Redshift)
16247 && upper_name == "DATE_TRUNC"
16248 && func.args.len() == 2
16249 {
16250 self.write_keyword("DATE_TRUNC");
16251 self.write("(");
16252 self.write_redshift_date_part_quoted(&func.args[0]);
16254 self.write(", ");
16255 self.generate_expression(&func.args[1])?;
16256 self.write(")");
16257 return Ok(());
16258 }
16259
16260 if matches!(
16262 self.config.dialect,
16263 Some(DialectType::TSQL) | Some(DialectType::Fabric)
16264 ) && (upper_name == "DATE_PART" || upper_name == "DATEPART")
16265 && func.args.len() == 2
16266 {
16267 self.write_keyword("DATEPART");
16268 self.write("(");
16269 self.generate_expression(&func.args[0])?;
16270 self.write(", ");
16271 self.generate_expression(&func.args[1])?;
16272 self.write(")");
16273 return Ok(());
16274 }
16275
16276 if matches!(
16278 self.config.dialect,
16279 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
16280 ) && (upper_name == "DATE_PART" || upper_name == "DATEPART")
16281 && func.args.len() == 2
16282 {
16283 self.write_keyword("EXTRACT");
16284 self.write("(");
16285 match &func.args[0] {
16287 Expression::Literal(crate::expressions::Literal::String(s)) => {
16288 self.write(&s.to_lowercase());
16289 }
16290 _ => self.generate_expression(&func.args[0])?,
16291 }
16292 self.write_space();
16293 self.write_keyword("FROM");
16294 self.write_space();
16295 self.generate_expression(&func.args[1])?;
16296 self.write(")");
16297 return Ok(());
16298 }
16299
16300 if self.config.dialect == Some(DialectType::Dremio)
16303 && (upper_name == "DATE_PART" || upper_name == "DATEPART")
16304 && func.args.len() == 2
16305 {
16306 self.write_keyword("EXTRACT");
16307 self.write("(");
16308 self.generate_expression(&func.args[0])?;
16309 self.write_space();
16310 self.write_keyword("FROM");
16311 self.write_space();
16312 self.generate_dremio_date_expression(&func.args[1])?;
16314 self.write(")");
16315 return Ok(());
16316 }
16317
16318 if self.config.dialect == Some(DialectType::Dremio)
16320 && upper_name == "CURRENT_DATE_UTC"
16321 && func.args.is_empty()
16322 {
16323 self.write_keyword("CURRENT_DATE_UTC");
16324 return Ok(());
16325 }
16326
16327 if self.config.dialect == Some(DialectType::Dremio)
16331 && upper_name == "DATETYPE"
16332 && func.args.len() == 3
16333 {
16334 fn get_int_literal(expr: &Expression) -> Option<i64> {
16336 if let Expression::Literal(crate::expressions::Literal::Number(s)) = expr {
16337 s.parse::<i64>().ok()
16338 } else {
16339 None
16340 }
16341 }
16342
16343 if let (Some(year), Some(month), Some(day)) = (
16345 get_int_literal(&func.args[0]),
16346 get_int_literal(&func.args[1]),
16347 get_int_literal(&func.args[2]),
16348 ) {
16349 self.write_keyword("DATE");
16351 self.write(&format!("('{:04}-{:02}-{:02}')", year, month, day));
16352 return Ok(());
16353 }
16354
16355 self.write_keyword("CAST");
16357 self.write("(");
16358 self.write_keyword("CONCAT");
16359 self.write("(");
16360 self.generate_expression(&func.args[0])?;
16361 self.write(", '-', ");
16362 self.generate_expression(&func.args[1])?;
16363 self.write(", '-', ");
16364 self.generate_expression(&func.args[2])?;
16365 self.write(")");
16366 self.write_space();
16367 self.write_keyword("AS");
16368 self.write_space();
16369 self.write_keyword("DATE");
16370 self.write(")");
16371 return Ok(());
16372 }
16373
16374 let is_presto_like = matches!(
16377 self.config.dialect,
16378 Some(DialectType::Presto) | Some(DialectType::Trino)
16379 );
16380 if is_presto_like && upper_name == "DATE_ADD" && func.args.len() == 3 {
16381 self.write_keyword("DATE_ADD");
16382 self.write("(");
16383 self.generate_expression(&func.args[0])?;
16385 self.write(", ");
16386 let interval = &func.args[1];
16388 let needs_cast = !self.returns_integer_type(interval);
16389 if needs_cast {
16390 self.write_keyword("CAST");
16391 self.write("(");
16392 }
16393 self.generate_expression(interval)?;
16394 if needs_cast {
16395 self.write_space();
16396 self.write_keyword("AS");
16397 self.write_space();
16398 self.write_keyword("BIGINT");
16399 self.write(")");
16400 }
16401 self.write(", ");
16402 self.generate_expression(&func.args[2])?;
16404 self.write(")");
16405 return Ok(());
16406 }
16407
16408 let use_brackets = func.use_bracket_syntax;
16410
16411 let has_ordinality = upper_name.ends_with(" WITH ORDINALITY");
16416 let output_name = if has_ordinality {
16417 let base_name = &func.name[..func.name.len() - " WITH ORDINALITY".len()];
16418 self.normalize_func_name(base_name)
16419 } else {
16420 normalized_name.clone()
16421 };
16422
16423 if func.name.contains('.') && !has_ordinality {
16426 if func.quoted {
16429 self.write("`");
16430 self.write(&func.name);
16431 self.write("`");
16432 } else {
16433 self.write(&func.name);
16434 }
16435 } else {
16436 self.write(&output_name);
16437 }
16438
16439 let force_parens = func.no_parens && func.args.is_empty() && !func.distinct && {
16442 let needs_parens = match upper_name.as_str() {
16443 "CURRENT_USER" | "SESSION_USER" | "SYSTEM_USER" => matches!(
16444 self.config.dialect,
16445 Some(DialectType::Snowflake)
16446 | Some(DialectType::Spark)
16447 | Some(DialectType::Databricks)
16448 | Some(DialectType::Hive)
16449 ),
16450 _ => false,
16451 };
16452 !needs_parens
16453 };
16454 if force_parens {
16455 for comment in &func.trailing_comments {
16457 self.write_space();
16458 self.write_formatted_comment(comment);
16459 }
16460 return Ok(());
16461 }
16462
16463 if upper_name == "CUBE" || upper_name == "ROLLUP" || upper_name == "GROUPING SETS" {
16465 self.write(" (");
16466 } else if use_brackets {
16467 self.write("[");
16468 } else {
16469 self.write("(");
16470 }
16471 if func.distinct {
16472 self.write_keyword("DISTINCT");
16473 self.write_space();
16474 }
16475
16476 let compact_pretty_func = matches!(self.config.dialect, Some(DialectType::Snowflake))
16478 && (upper_name == "TABLE" || upper_name == "FLATTEN");
16479 let is_grouping_func =
16481 upper_name == "GROUPING SETS" || upper_name == "CUBE" || upper_name == "ROLLUP";
16482 let should_split = if self.config.pretty && !func.args.is_empty() && !compact_pretty_func {
16483 if is_grouping_func {
16484 true
16485 } else {
16486 let mut expr_strings: Vec<String> = Vec::with_capacity(func.args.len());
16488 for arg in &func.args {
16489 let mut temp_gen = Generator::with_config(self.config.clone());
16490 temp_gen.config.pretty = false; temp_gen.generate_expression(arg)?;
16492 expr_strings.push(temp_gen.output);
16493 }
16494 self.too_wide(&expr_strings)
16495 }
16496 } else {
16497 false
16498 };
16499
16500 if should_split {
16501 self.write_newline();
16503 self.indent_level += 1;
16504 for (i, arg) in func.args.iter().enumerate() {
16505 self.write_indent();
16506 self.generate_expression(arg)?;
16507 if i + 1 < func.args.len() {
16508 self.write(",");
16509 }
16510 self.write_newline();
16511 }
16512 self.indent_level -= 1;
16513 self.write_indent();
16514 } else {
16515 for (i, arg) in func.args.iter().enumerate() {
16517 if i > 0 {
16518 self.write(", ");
16519 }
16520 self.generate_expression(arg)?;
16521 }
16522 }
16523
16524 if use_brackets {
16525 self.write("]");
16526 } else {
16527 self.write(")");
16528 }
16529 if has_ordinality {
16531 self.write_space();
16532 self.write_keyword("WITH ORDINALITY");
16533 }
16534 for comment in &func.trailing_comments {
16536 self.write_space();
16537 self.write_formatted_comment(comment);
16538 }
16539 Ok(())
16540 }
16541
16542 fn generate_aggregate_function(&mut self, func: &AggregateFunction) -> Result<()> {
16543 let mut normalized_name = self.normalize_func_name(&func.name);
16545
16546 let upper = normalized_name.to_uppercase();
16548 if upper == "MAX_BY" || upper == "MIN_BY" {
16549 let is_max = upper == "MAX_BY";
16550 match self.config.dialect {
16551 Some(DialectType::ClickHouse) => {
16552 normalized_name = if is_max {
16553 "argMax".to_string()
16554 } else {
16555 "argMin".to_string()
16556 };
16557 }
16558 Some(DialectType::DuckDB) => {
16559 normalized_name = if is_max {
16560 "ARG_MAX".to_string()
16561 } else {
16562 "ARG_MIN".to_string()
16563 };
16564 }
16565 _ => {}
16566 }
16567 }
16568 self.write(&normalized_name);
16569 self.write("(");
16570 if func.distinct {
16571 self.write_keyword("DISTINCT");
16572 self.write_space();
16573 }
16574
16575 let is_count = normalized_name.eq_ignore_ascii_case("COUNT");
16579 let needs_multi_arg_transform =
16580 func.distinct && is_count && func.args.len() > 1 && !self.config.multi_arg_distinct;
16581
16582 if needs_multi_arg_transform {
16583 self.write_keyword("CASE");
16585 for arg in &func.args {
16586 self.write_space();
16587 self.write_keyword("WHEN");
16588 self.write_space();
16589 self.generate_expression(arg)?;
16590 self.write_space();
16591 self.write_keyword("IS NULL THEN NULL");
16592 }
16593 self.write_space();
16594 self.write_keyword("ELSE");
16595 self.write(" (");
16596 for (i, arg) in func.args.iter().enumerate() {
16597 if i > 0 {
16598 self.write(", ");
16599 }
16600 self.generate_expression(arg)?;
16601 }
16602 self.write(")");
16603 self.write_space();
16604 self.write_keyword("END");
16605 } else {
16606 for (i, arg) in func.args.iter().enumerate() {
16607 if i > 0 {
16608 self.write(", ");
16609 }
16610 self.generate_expression(arg)?;
16611 }
16612 }
16613
16614 if self.config.ignore_nulls_in_func
16616 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
16617 {
16618 if let Some(ignore) = func.ignore_nulls {
16619 self.write_space();
16620 if ignore {
16621 self.write_keyword("IGNORE NULLS");
16622 } else {
16623 self.write_keyword("RESPECT NULLS");
16624 }
16625 }
16626 }
16627
16628 if !func.order_by.is_empty() {
16630 self.write_space();
16631 self.write_keyword("ORDER BY");
16632 self.write_space();
16633 for (i, ord) in func.order_by.iter().enumerate() {
16634 if i > 0 {
16635 self.write(", ");
16636 }
16637 self.generate_ordered(ord)?;
16638 }
16639 }
16640
16641 if let Some(limit) = &func.limit {
16643 self.write_space();
16644 self.write_keyword("LIMIT");
16645 self.write_space();
16646 if let Expression::Tuple(t) = limit.as_ref() {
16648 if t.expressions.len() == 2 {
16649 self.generate_expression(&t.expressions[0])?;
16650 self.write(", ");
16651 self.generate_expression(&t.expressions[1])?;
16652 } else {
16653 self.generate_expression(limit)?;
16654 }
16655 } else {
16656 self.generate_expression(limit)?;
16657 }
16658 }
16659
16660 self.write(")");
16661
16662 if !self.config.ignore_nulls_in_func
16664 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
16665 {
16666 if let Some(ignore) = func.ignore_nulls {
16667 self.write_space();
16668 if ignore {
16669 self.write_keyword("IGNORE NULLS");
16670 } else {
16671 self.write_keyword("RESPECT NULLS");
16672 }
16673 }
16674 }
16675
16676 if let Some(filter) = &func.filter {
16677 self.write_space();
16678 self.write_keyword("FILTER");
16679 self.write("(");
16680 self.write_keyword("WHERE");
16681 self.write_space();
16682 self.generate_expression(filter)?;
16683 self.write(")");
16684 }
16685
16686 Ok(())
16687 }
16688
16689 fn generate_window_function(&mut self, wf: &WindowFunction) -> Result<()> {
16690 self.generate_expression(&wf.this)?;
16691
16692 if let Some(keep) = &wf.keep {
16694 self.write_space();
16695 self.write_keyword("KEEP");
16696 self.write(" (");
16697 self.write_keyword("DENSE_RANK");
16698 self.write_space();
16699 if keep.first {
16700 self.write_keyword("FIRST");
16701 } else {
16702 self.write_keyword("LAST");
16703 }
16704 self.write_space();
16705 self.write_keyword("ORDER BY");
16706 self.write_space();
16707 for (i, ord) in keep.order_by.iter().enumerate() {
16708 if i > 0 {
16709 self.write(", ");
16710 }
16711 self.generate_ordered(ord)?;
16712 }
16713 self.write(")");
16714 }
16715
16716 let has_over = !wf.over.partition_by.is_empty()
16718 || !wf.over.order_by.is_empty()
16719 || wf.over.frame.is_some()
16720 || wf.over.window_name.is_some();
16721
16722 if has_over {
16724 self.write_space();
16725 self.write_keyword("OVER");
16726
16727 let has_specs = !wf.over.partition_by.is_empty()
16729 || !wf.over.order_by.is_empty()
16730 || wf.over.frame.is_some();
16731
16732 if wf.over.window_name.is_some() && !has_specs {
16733 self.write_space();
16735 self.write(&wf.over.window_name.as_ref().unwrap().name);
16736 } else {
16737 self.write(" (");
16739 self.generate_over(&wf.over)?;
16740 self.write(")");
16741 }
16742 } else if wf.keep.is_none() {
16743 self.write_space();
16745 self.write_keyword("OVER");
16746 self.write(" ()");
16747 }
16748
16749 Ok(())
16750 }
16751
16752 fn generate_within_group(&mut self, wg: &WithinGroup) -> Result<()> {
16754 self.generate_expression(&wg.this)?;
16755 self.write_space();
16756 self.write_keyword("WITHIN GROUP");
16757 self.write(" (");
16758 self.write_keyword("ORDER BY");
16759 self.write_space();
16760 for (i, ord) in wg.order_by.iter().enumerate() {
16761 if i > 0 {
16762 self.write(", ");
16763 }
16764 self.generate_ordered(ord)?;
16765 }
16766 self.write(")");
16767 Ok(())
16768 }
16769
16770 fn generate_over(&mut self, over: &Over) -> Result<()> {
16772 let mut has_content = false;
16773
16774 if let Some(name) = &over.window_name {
16776 self.write(&name.name);
16777 has_content = true;
16778 }
16779
16780 if !over.partition_by.is_empty() {
16782 if has_content {
16783 self.write_space();
16784 }
16785 self.write_keyword("PARTITION BY");
16786 self.write_space();
16787 for (i, expr) in over.partition_by.iter().enumerate() {
16788 if i > 0 {
16789 self.write(", ");
16790 }
16791 self.generate_expression(expr)?;
16792 }
16793 has_content = true;
16794 }
16795
16796 if !over.order_by.is_empty() {
16798 if has_content {
16799 self.write_space();
16800 }
16801 self.write_keyword("ORDER BY");
16802 self.write_space();
16803 for (i, ordered) in over.order_by.iter().enumerate() {
16804 if i > 0 {
16805 self.write(", ");
16806 }
16807 self.generate_ordered(ordered)?;
16808 }
16809 has_content = true;
16810 }
16811
16812 if let Some(frame) = &over.frame {
16814 if has_content {
16815 self.write_space();
16816 }
16817 self.generate_window_frame(frame)?;
16818 }
16819
16820 Ok(())
16821 }
16822
16823 fn generate_window_frame(&mut self, frame: &WindowFrame) -> Result<()> {
16824 let lowercase_frame = self.config.lowercase_window_frame_keywords;
16826
16827 if !lowercase_frame {
16829 if let Some(kind_text) = &frame.kind_text {
16830 self.write(kind_text);
16831 } else {
16832 match frame.kind {
16833 WindowFrameKind::Rows => self.write_keyword("ROWS"),
16834 WindowFrameKind::Range => self.write_keyword("RANGE"),
16835 WindowFrameKind::Groups => self.write_keyword("GROUPS"),
16836 }
16837 }
16838 } else {
16839 match frame.kind {
16840 WindowFrameKind::Rows => self.write("rows"),
16841 WindowFrameKind::Range => self.write("range"),
16842 WindowFrameKind::Groups => self.write("groups"),
16843 }
16844 }
16845
16846 self.write_space();
16849 let should_normalize = self.config.normalize_window_frame_between
16850 && frame.end.is_none()
16851 && matches!(
16852 frame.start,
16853 WindowFrameBound::Preceding(_)
16854 | WindowFrameBound::Following(_)
16855 | WindowFrameBound::UnboundedPreceding
16856 | WindowFrameBound::UnboundedFollowing
16857 );
16858
16859 if let Some(end) = &frame.end {
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.generate_window_frame_bound(end, frame.end_side_text.as_deref())?;
16868 } else if should_normalize {
16869 self.write_keyword("BETWEEN");
16871 self.write_space();
16872 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
16873 self.write_space();
16874 self.write_keyword("AND");
16875 self.write_space();
16876 self.write_keyword("CURRENT ROW");
16877 } else {
16878 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
16880 }
16881
16882 if let Some(exclude) = &frame.exclude {
16884 self.write_space();
16885 self.write_keyword("EXCLUDE");
16886 self.write_space();
16887 match exclude {
16888 WindowFrameExclude::CurrentRow => self.write_keyword("CURRENT ROW"),
16889 WindowFrameExclude::Group => self.write_keyword("GROUP"),
16890 WindowFrameExclude::Ties => self.write_keyword("TIES"),
16891 WindowFrameExclude::NoOthers => self.write_keyword("NO OTHERS"),
16892 }
16893 }
16894
16895 Ok(())
16896 }
16897
16898 fn generate_window_frame_bound(
16899 &mut self,
16900 bound: &WindowFrameBound,
16901 side_text: Option<&str>,
16902 ) -> Result<()> {
16903 let lowercase_frame = self.config.lowercase_window_frame_keywords;
16905
16906 match bound {
16907 WindowFrameBound::CurrentRow => {
16908 self.write_keyword("CURRENT ROW");
16909 }
16910 WindowFrameBound::UnboundedPreceding => {
16911 self.write_keyword("UNBOUNDED");
16912 self.write_space();
16913 if lowercase_frame {
16914 self.write("preceding");
16915 } else if let Some(text) = side_text {
16916 self.write(text);
16917 } else {
16918 self.write_keyword("PRECEDING");
16919 }
16920 }
16921 WindowFrameBound::UnboundedFollowing => {
16922 self.write_keyword("UNBOUNDED");
16923 self.write_space();
16924 if lowercase_frame {
16925 self.write("following");
16926 } else if let Some(text) = side_text {
16927 self.write(text);
16928 } else {
16929 self.write_keyword("FOLLOWING");
16930 }
16931 }
16932 WindowFrameBound::Preceding(expr) => {
16933 self.generate_expression(expr)?;
16934 self.write_space();
16935 if lowercase_frame {
16936 self.write("preceding");
16937 } else if let Some(text) = side_text {
16938 self.write(text);
16939 } else {
16940 self.write_keyword("PRECEDING");
16941 }
16942 }
16943 WindowFrameBound::Following(expr) => {
16944 self.generate_expression(expr)?;
16945 self.write_space();
16946 if lowercase_frame {
16947 self.write("following");
16948 } else if let Some(text) = side_text {
16949 self.write(text);
16950 } else {
16951 self.write_keyword("FOLLOWING");
16952 }
16953 }
16954 WindowFrameBound::BarePreceding => {
16955 if lowercase_frame {
16956 self.write("preceding");
16957 } else if let Some(text) = side_text {
16958 self.write(text);
16959 } else {
16960 self.write_keyword("PRECEDING");
16961 }
16962 }
16963 WindowFrameBound::BareFollowing => {
16964 if lowercase_frame {
16965 self.write("following");
16966 } else if let Some(text) = side_text {
16967 self.write(text);
16968 } else {
16969 self.write_keyword("FOLLOWING");
16970 }
16971 }
16972 WindowFrameBound::Value(expr) => {
16973 self.generate_expression(expr)?;
16975 }
16976 }
16977 Ok(())
16978 }
16979
16980 fn generate_interval(&mut self, interval: &Interval) -> Result<()> {
16981 let skip_interval_keyword = matches!(self.config.dialect, Some(DialectType::Oracle))
16984 && matches!(&interval.unit, Some(IntervalUnitSpec::ExprSpan(_)))
16985 && !matches!(&interval.this, Some(Expression::Literal(_)));
16986
16987 if self.config.single_string_interval {
16990 if let (
16991 Some(Expression::Literal(Literal::String(ref val))),
16992 Some(IntervalUnitSpec::Simple {
16993 ref unit,
16994 ref use_plural,
16995 }),
16996 ) = (&interval.this, &interval.unit)
16997 {
16998 self.write_keyword("INTERVAL");
16999 self.write_space();
17000 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
17001 let unit_str = self.interval_unit_str(unit, effective_plural);
17002 self.write("'");
17003 self.write(val);
17004 self.write(" ");
17005 self.write(&unit_str);
17006 self.write("'");
17007 return Ok(());
17008 }
17009 }
17010
17011 if !skip_interval_keyword {
17012 self.write_keyword("INTERVAL");
17013 }
17014
17015 if let Some(ref value) = interval.this {
17017 if !skip_interval_keyword {
17018 self.write_space();
17019 }
17020 let needs_parens = interval.unit.is_some()
17024 && matches!(
17025 value,
17026 Expression::Add(_)
17027 | Expression::Sub(_)
17028 | Expression::Mul(_)
17029 | Expression::Div(_)
17030 | Expression::Mod(_)
17031 | Expression::BitwiseAnd(_)
17032 | Expression::BitwiseOr(_)
17033 | Expression::BitwiseXor(_)
17034 );
17035 if needs_parens {
17036 self.write("(");
17037 }
17038 self.generate_expression(value)?;
17039 if needs_parens {
17040 self.write(")");
17041 }
17042 }
17043
17044 if let Some(ref unit_spec) = interval.unit {
17046 self.write_space();
17047 self.write_interval_unit_spec(unit_spec)?;
17048 }
17049
17050 Ok(())
17051 }
17052
17053 fn interval_unit_str(&self, unit: &IntervalUnit, use_plural: bool) -> &'static str {
17055 match (unit, use_plural) {
17056 (IntervalUnit::Year, false) => "YEAR",
17057 (IntervalUnit::Year, true) => "YEARS",
17058 (IntervalUnit::Quarter, false) => "QUARTER",
17059 (IntervalUnit::Quarter, true) => "QUARTERS",
17060 (IntervalUnit::Month, false) => "MONTH",
17061 (IntervalUnit::Month, true) => "MONTHS",
17062 (IntervalUnit::Week, false) => "WEEK",
17063 (IntervalUnit::Week, true) => "WEEKS",
17064 (IntervalUnit::Day, false) => "DAY",
17065 (IntervalUnit::Day, true) => "DAYS",
17066 (IntervalUnit::Hour, false) => "HOUR",
17067 (IntervalUnit::Hour, true) => "HOURS",
17068 (IntervalUnit::Minute, false) => "MINUTE",
17069 (IntervalUnit::Minute, true) => "MINUTES",
17070 (IntervalUnit::Second, false) => "SECOND",
17071 (IntervalUnit::Second, true) => "SECONDS",
17072 (IntervalUnit::Millisecond, false) => "MILLISECOND",
17073 (IntervalUnit::Millisecond, true) => "MILLISECONDS",
17074 (IntervalUnit::Microsecond, false) => "MICROSECOND",
17075 (IntervalUnit::Microsecond, true) => "MICROSECONDS",
17076 (IntervalUnit::Nanosecond, false) => "NANOSECOND",
17077 (IntervalUnit::Nanosecond, true) => "NANOSECONDS",
17078 }
17079 }
17080
17081 fn write_interval_unit_spec(&mut self, unit_spec: &IntervalUnitSpec) -> Result<()> {
17082 match unit_spec {
17083 IntervalUnitSpec::Simple { unit, use_plural } => {
17084 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
17086 self.write_simple_interval_unit(unit, effective_plural);
17087 }
17088 IntervalUnitSpec::Span(span) => {
17089 self.write_simple_interval_unit(&span.this, false);
17090 self.write_space();
17091 self.write_keyword("TO");
17092 self.write_space();
17093 self.write_simple_interval_unit(&span.expression, false);
17094 }
17095 IntervalUnitSpec::ExprSpan(span) => {
17096 self.generate_expression(&span.this)?;
17098 self.write_space();
17099 self.write_keyword("TO");
17100 self.write_space();
17101 self.generate_expression(&span.expression)?;
17102 }
17103 IntervalUnitSpec::Expr(expr) => {
17104 self.generate_expression(expr)?;
17105 }
17106 }
17107 Ok(())
17108 }
17109
17110 fn write_simple_interval_unit(&mut self, unit: &IntervalUnit, use_plural: bool) {
17111 match (unit, use_plural) {
17113 (IntervalUnit::Year, false) => self.write_keyword("YEAR"),
17114 (IntervalUnit::Year, true) => self.write_keyword("YEARS"),
17115 (IntervalUnit::Quarter, false) => self.write_keyword("QUARTER"),
17116 (IntervalUnit::Quarter, true) => self.write_keyword("QUARTERS"),
17117 (IntervalUnit::Month, false) => self.write_keyword("MONTH"),
17118 (IntervalUnit::Month, true) => self.write_keyword("MONTHS"),
17119 (IntervalUnit::Week, false) => self.write_keyword("WEEK"),
17120 (IntervalUnit::Week, true) => self.write_keyword("WEEKS"),
17121 (IntervalUnit::Day, false) => self.write_keyword("DAY"),
17122 (IntervalUnit::Day, true) => self.write_keyword("DAYS"),
17123 (IntervalUnit::Hour, false) => self.write_keyword("HOUR"),
17124 (IntervalUnit::Hour, true) => self.write_keyword("HOURS"),
17125 (IntervalUnit::Minute, false) => self.write_keyword("MINUTE"),
17126 (IntervalUnit::Minute, true) => self.write_keyword("MINUTES"),
17127 (IntervalUnit::Second, false) => self.write_keyword("SECOND"),
17128 (IntervalUnit::Second, true) => self.write_keyword("SECONDS"),
17129 (IntervalUnit::Millisecond, false) => self.write_keyword("MILLISECOND"),
17130 (IntervalUnit::Millisecond, true) => self.write_keyword("MILLISECONDS"),
17131 (IntervalUnit::Microsecond, false) => self.write_keyword("MICROSECOND"),
17132 (IntervalUnit::Microsecond, true) => self.write_keyword("MICROSECONDS"),
17133 (IntervalUnit::Nanosecond, false) => self.write_keyword("NANOSECOND"),
17134 (IntervalUnit::Nanosecond, true) => self.write_keyword("NANOSECONDS"),
17135 }
17136 }
17137
17138 fn write_redshift_date_part(&mut self, expr: &Expression) {
17141 let part_str = self.extract_date_part_string(expr);
17142 if let Some(part) = part_str {
17143 let normalized = self.normalize_date_part(&part);
17144 self.write_keyword(&normalized);
17145 } else {
17146 let _ = self.generate_expression(expr);
17148 }
17149 }
17150
17151 fn write_redshift_date_part_quoted(&mut self, expr: &Expression) {
17154 let part_str = self.extract_date_part_string(expr);
17155 if let Some(part) = part_str {
17156 let normalized = self.normalize_date_part(&part);
17157 self.write("'");
17158 self.write(&normalized);
17159 self.write("'");
17160 } else {
17161 let _ = self.generate_expression(expr);
17163 }
17164 }
17165
17166 fn extract_date_part_string(&self, expr: &Expression) -> Option<String> {
17168 match expr {
17169 Expression::Literal(crate::expressions::Literal::String(s)) => Some(s.clone()),
17170 Expression::Identifier(id) => Some(id.name.clone()),
17171 Expression::Column(col) if col.table.is_none() => {
17172 Some(col.name.name.clone())
17174 }
17175 _ => None,
17176 }
17177 }
17178
17179 fn normalize_date_part(&self, part: &str) -> String {
17182 let lower = part.to_lowercase();
17183 match lower.as_str() {
17184 "day" | "days" | "d" => "DAY".to_string(),
17185 "month" | "months" | "mon" | "mm" => "MONTH".to_string(),
17186 "year" | "years" | "y" | "yy" | "yyyy" => "YEAR".to_string(),
17187 "week" | "weeks" | "w" | "wk" => "WEEK".to_string(),
17188 "hour" | "hours" | "h" | "hh" => "HOUR".to_string(),
17189 "minute" | "minutes" | "m" | "mi" | "n" => "MINUTE".to_string(),
17190 "second" | "seconds" | "s" | "ss" => "SECOND".to_string(),
17191 "millisecond" | "milliseconds" | "ms" => "MILLISECOND".to_string(),
17192 "microsecond" | "microseconds" | "us" => "MICROSECOND".to_string(),
17193 "quarter" | "quarters" | "q" | "qq" => "QUARTER".to_string(),
17194 _ => part.to_uppercase(),
17195 }
17196 }
17197
17198 fn write_datetime_field(&mut self, field: &DateTimeField) {
17199 match field {
17200 DateTimeField::Year => self.write_keyword("YEAR"),
17201 DateTimeField::Month => self.write_keyword("MONTH"),
17202 DateTimeField::Day => self.write_keyword("DAY"),
17203 DateTimeField::Hour => self.write_keyword("HOUR"),
17204 DateTimeField::Minute => self.write_keyword("MINUTE"),
17205 DateTimeField::Second => self.write_keyword("SECOND"),
17206 DateTimeField::Millisecond => self.write_keyword("MILLISECOND"),
17207 DateTimeField::Microsecond => self.write_keyword("MICROSECOND"),
17208 DateTimeField::DayOfWeek => {
17209 let name = match self.config.dialect {
17210 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFWEEK",
17211 _ => "DOW",
17212 };
17213 self.write_keyword(name);
17214 }
17215 DateTimeField::DayOfYear => {
17216 let name = match self.config.dialect {
17217 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFYEAR",
17218 _ => "DOY",
17219 };
17220 self.write_keyword(name);
17221 }
17222 DateTimeField::Week => self.write_keyword("WEEK"),
17223 DateTimeField::WeekWithModifier(modifier) => {
17224 self.write_keyword("WEEK");
17225 self.write("(");
17226 self.write(modifier);
17227 self.write(")");
17228 }
17229 DateTimeField::Quarter => self.write_keyword("QUARTER"),
17230 DateTimeField::Epoch => self.write_keyword("EPOCH"),
17231 DateTimeField::Timezone => self.write_keyword("TIMEZONE"),
17232 DateTimeField::TimezoneHour => self.write_keyword("TIMEZONE_HOUR"),
17233 DateTimeField::TimezoneMinute => self.write_keyword("TIMEZONE_MINUTE"),
17234 DateTimeField::Date => self.write_keyword("DATE"),
17235 DateTimeField::Time => self.write_keyword("TIME"),
17236 DateTimeField::Custom(name) => self.write(name),
17237 }
17238 }
17239
17240 fn write_datetime_field_lower(&mut self, field: &DateTimeField) {
17242 match field {
17243 DateTimeField::Year => self.write("year"),
17244 DateTimeField::Month => self.write("month"),
17245 DateTimeField::Day => self.write("day"),
17246 DateTimeField::Hour => self.write("hour"),
17247 DateTimeField::Minute => self.write("minute"),
17248 DateTimeField::Second => self.write("second"),
17249 DateTimeField::Millisecond => self.write("millisecond"),
17250 DateTimeField::Microsecond => self.write("microsecond"),
17251 DateTimeField::DayOfWeek => self.write("dow"),
17252 DateTimeField::DayOfYear => self.write("doy"),
17253 DateTimeField::Week => self.write("week"),
17254 DateTimeField::WeekWithModifier(modifier) => {
17255 self.write("week(");
17256 self.write(modifier);
17257 self.write(")");
17258 }
17259 DateTimeField::Quarter => self.write("quarter"),
17260 DateTimeField::Epoch => self.write("epoch"),
17261 DateTimeField::Timezone => self.write("timezone"),
17262 DateTimeField::TimezoneHour => self.write("timezone_hour"),
17263 DateTimeField::TimezoneMinute => self.write("timezone_minute"),
17264 DateTimeField::Date => self.write("date"),
17265 DateTimeField::Time => self.write("time"),
17266 DateTimeField::Custom(name) => self.write(name),
17267 }
17268 }
17269
17270 fn generate_simple_func(&mut self, name: &str, arg: &Expression) -> Result<()> {
17273 self.write_keyword(name);
17274 self.write("(");
17275 self.generate_expression(arg)?;
17276 self.write(")");
17277 Ok(())
17278 }
17279
17280 fn generate_unary_func(
17282 &mut self,
17283 default_name: &str,
17284 f: &crate::expressions::UnaryFunc,
17285 ) -> Result<()> {
17286 let name = f.original_name.as_deref().unwrap_or(default_name);
17287 self.write_keyword(name);
17288 self.write("(");
17289 self.generate_expression(&f.this)?;
17290 self.write(")");
17291 Ok(())
17292 }
17293
17294 fn generate_sqrt_cbrt(
17296 &mut self,
17297 f: &crate::expressions::UnaryFunc,
17298 func_name: &str,
17299 _op: &str,
17300 ) -> Result<()> {
17301 self.write_keyword(func_name);
17304 self.write("(");
17305 self.generate_expression(&f.this)?;
17306 self.write(")");
17307 Ok(())
17308 }
17309
17310 fn generate_binary_func(
17311 &mut self,
17312 name: &str,
17313 arg1: &Expression,
17314 arg2: &Expression,
17315 ) -> Result<()> {
17316 self.write_keyword(name);
17317 self.write("(");
17318 self.generate_expression(arg1)?;
17319 self.write(", ");
17320 self.generate_expression(arg2)?;
17321 self.write(")");
17322 Ok(())
17323 }
17324
17325 fn generate_char_func(&mut self, f: &crate::expressions::CharFunc) -> Result<()> {
17329 let func_name = f.name.as_deref().unwrap_or("CHAR");
17331 self.write_keyword(func_name);
17332 self.write("(");
17333 for (i, arg) in f.args.iter().enumerate() {
17334 if i > 0 {
17335 self.write(", ");
17336 }
17337 self.generate_expression(arg)?;
17338 }
17339 if let Some(ref charset) = f.charset {
17340 self.write(" ");
17341 self.write_keyword("USING");
17342 self.write(" ");
17343 self.write(charset);
17344 }
17345 self.write(")");
17346 Ok(())
17347 }
17348
17349 fn generate_power(&mut self, f: &BinaryFunc) -> Result<()> {
17350 use crate::dialects::DialectType;
17351
17352 match self.config.dialect {
17353 Some(DialectType::Teradata) => {
17354 self.generate_expression(&f.this)?;
17356 self.write(" ** ");
17357 self.generate_expression(&f.expression)?;
17358 Ok(())
17359 }
17360 _ => {
17361 self.generate_binary_func("POWER", &f.this, &f.expression)
17363 }
17364 }
17365 }
17366
17367 fn generate_vararg_func(&mut self, name: &str, args: &[Expression]) -> Result<()> {
17368 self.write_func_name(name);
17369 self.write("(");
17370 for (i, arg) in args.iter().enumerate() {
17371 if i > 0 {
17372 self.write(", ");
17373 }
17374 self.generate_expression(arg)?;
17375 }
17376 self.write(")");
17377 Ok(())
17378 }
17379
17380 fn generate_concat_ws(&mut self, f: &ConcatWs) -> Result<()> {
17383 self.write_keyword("CONCAT_WS");
17384 self.write("(");
17385 self.generate_expression(&f.separator)?;
17386 for expr in &f.expressions {
17387 self.write(", ");
17388 self.generate_expression(expr)?;
17389 }
17390 self.write(")");
17391 Ok(())
17392 }
17393
17394 fn collect_concat_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
17395 if let Expression::Concat(op) = expr {
17396 Self::collect_concat_operands(&op.left, out);
17397 Self::collect_concat_operands(&op.right, out);
17398 } else {
17399 out.push(expr);
17400 }
17401 }
17402
17403 fn generate_mysql_concat_from_concat(&mut self, op: &BinaryOp) -> Result<()> {
17404 let mut operands = Vec::new();
17405 Self::collect_concat_operands(&op.left, &mut operands);
17406 Self::collect_concat_operands(&op.right, &mut operands);
17407
17408 self.write_keyword("CONCAT");
17409 self.write("(");
17410 for (i, operand) in operands.iter().enumerate() {
17411 if i > 0 {
17412 self.write(", ");
17413 }
17414 self.generate_expression(operand)?;
17415 }
17416 self.write(")");
17417 Ok(())
17418 }
17419
17420 fn collect_dpipe_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
17421 if let Expression::DPipe(dpipe) = expr {
17422 Self::collect_dpipe_operands(&dpipe.this, out);
17423 Self::collect_dpipe_operands(&dpipe.expression, out);
17424 } else {
17425 out.push(expr);
17426 }
17427 }
17428
17429 fn generate_mysql_concat_from_dpipe(&mut self, e: &DPipe) -> Result<()> {
17430 let mut operands = Vec::new();
17431 Self::collect_dpipe_operands(&e.this, &mut operands);
17432 Self::collect_dpipe_operands(&e.expression, &mut operands);
17433
17434 self.write_keyword("CONCAT");
17435 self.write("(");
17436 for (i, operand) in operands.iter().enumerate() {
17437 if i > 0 {
17438 self.write(", ");
17439 }
17440 self.generate_expression(operand)?;
17441 }
17442 self.write(")");
17443 Ok(())
17444 }
17445
17446 fn generate_substring(&mut self, f: &SubstringFunc) -> Result<()> {
17447 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
17449 if is_oracle {
17450 self.write_keyword("SUBSTR");
17451 } else {
17452 self.write_keyword("SUBSTRING");
17453 }
17454 self.write("(");
17455 self.generate_expression(&f.this)?;
17456 let force_from_for = matches!(self.config.dialect, Some(DialectType::PostgreSQL));
17458 let use_comma_syntax = matches!(
17460 self.config.dialect,
17461 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
17462 );
17463 if (f.from_for_syntax || force_from_for) && !use_comma_syntax {
17464 self.write_space();
17466 self.write_keyword("FROM");
17467 self.write_space();
17468 self.generate_expression(&f.start)?;
17469 if let Some(length) = &f.length {
17470 self.write_space();
17471 self.write_keyword("FOR");
17472 self.write_space();
17473 self.generate_expression(length)?;
17474 }
17475 } else {
17476 self.write(", ");
17478 self.generate_expression(&f.start)?;
17479 if let Some(length) = &f.length {
17480 self.write(", ");
17481 self.generate_expression(length)?;
17482 }
17483 }
17484 self.write(")");
17485 Ok(())
17486 }
17487
17488 fn generate_overlay(&mut self, f: &OverlayFunc) -> Result<()> {
17489 self.write_keyword("OVERLAY");
17490 self.write("(");
17491 self.generate_expression(&f.this)?;
17492 self.write_space();
17493 self.write_keyword("PLACING");
17494 self.write_space();
17495 self.generate_expression(&f.replacement)?;
17496 self.write_space();
17497 self.write_keyword("FROM");
17498 self.write_space();
17499 self.generate_expression(&f.from)?;
17500 if let Some(length) = &f.length {
17501 self.write_space();
17502 self.write_keyword("FOR");
17503 self.write_space();
17504 self.generate_expression(length)?;
17505 }
17506 self.write(")");
17507 Ok(())
17508 }
17509
17510 fn generate_trim(&mut self, f: &TrimFunc) -> Result<()> {
17511 if f.position_explicit && f.characters.is_none() {
17514 match f.position {
17515 TrimPosition::Leading => {
17516 self.write_keyword("LTRIM");
17517 self.write("(");
17518 self.generate_expression(&f.this)?;
17519 self.write(")");
17520 return Ok(());
17521 }
17522 TrimPosition::Trailing => {
17523 self.write_keyword("RTRIM");
17524 self.write("(");
17525 self.generate_expression(&f.this)?;
17526 self.write(")");
17527 return Ok(());
17528 }
17529 TrimPosition::Both => {
17530 }
17533 }
17534 }
17535
17536 self.write_keyword("TRIM");
17537 self.write("(");
17538 let force_standard = f.characters.is_some()
17541 && !f.sql_standard_syntax
17542 && matches!(
17543 self.config.dialect,
17544 Some(DialectType::Hive)
17545 | Some(DialectType::Spark)
17546 | Some(DialectType::Databricks)
17547 | Some(DialectType::ClickHouse)
17548 );
17549 let use_standard = (f.sql_standard_syntax || force_standard)
17550 && !(f.position_explicit
17551 && f.characters.is_none()
17552 && matches!(f.position, TrimPosition::Both));
17553 if use_standard {
17554 if f.position_explicit {
17557 match f.position {
17558 TrimPosition::Both => self.write_keyword("BOTH"),
17559 TrimPosition::Leading => self.write_keyword("LEADING"),
17560 TrimPosition::Trailing => self.write_keyword("TRAILING"),
17561 }
17562 self.write_space();
17563 }
17564 if let Some(chars) = &f.characters {
17565 self.generate_expression(chars)?;
17566 self.write_space();
17567 }
17568 self.write_keyword("FROM");
17569 self.write_space();
17570 self.generate_expression(&f.this)?;
17571 } else {
17572 self.generate_expression(&f.this)?;
17574 if let Some(chars) = &f.characters {
17575 self.write(", ");
17576 self.generate_expression(chars)?;
17577 }
17578 }
17579 self.write(")");
17580 Ok(())
17581 }
17582
17583 fn generate_replace(&mut self, f: &ReplaceFunc) -> Result<()> {
17584 self.write_keyword("REPLACE");
17585 self.write("(");
17586 self.generate_expression(&f.this)?;
17587 self.write(", ");
17588 self.generate_expression(&f.old)?;
17589 self.write(", ");
17590 self.generate_expression(&f.new)?;
17591 self.write(")");
17592 Ok(())
17593 }
17594
17595 fn generate_left_right(&mut self, name: &str, f: &LeftRightFunc) -> Result<()> {
17596 self.write_keyword(name);
17597 self.write("(");
17598 self.generate_expression(&f.this)?;
17599 self.write(", ");
17600 self.generate_expression(&f.length)?;
17601 self.write(")");
17602 Ok(())
17603 }
17604
17605 fn generate_repeat(&mut self, f: &RepeatFunc) -> Result<()> {
17606 self.write_keyword("REPEAT");
17607 self.write("(");
17608 self.generate_expression(&f.this)?;
17609 self.write(", ");
17610 self.generate_expression(&f.times)?;
17611 self.write(")");
17612 Ok(())
17613 }
17614
17615 fn generate_pad(&mut self, name: &str, f: &PadFunc) -> Result<()> {
17616 self.write_keyword(name);
17617 self.write("(");
17618 self.generate_expression(&f.this)?;
17619 self.write(", ");
17620 self.generate_expression(&f.length)?;
17621 if let Some(fill) = &f.fill {
17622 self.write(", ");
17623 self.generate_expression(fill)?;
17624 }
17625 self.write(")");
17626 Ok(())
17627 }
17628
17629 fn generate_split(&mut self, f: &SplitFunc) -> Result<()> {
17630 self.write_keyword("SPLIT");
17631 self.write("(");
17632 self.generate_expression(&f.this)?;
17633 self.write(", ");
17634 self.generate_expression(&f.delimiter)?;
17635 self.write(")");
17636 Ok(())
17637 }
17638
17639 fn generate_regexp_like(&mut self, f: &RegexpFunc) -> Result<()> {
17640 use crate::dialects::DialectType;
17641 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) && f.flags.is_none() {
17643 self.generate_expression(&f.this)?;
17644 self.write(" ~ ");
17645 self.generate_expression(&f.pattern)?;
17646 } else if matches!(
17647 self.config.dialect,
17648 Some(DialectType::SingleStore)
17649 | Some(DialectType::Spark)
17650 | Some(DialectType::Hive)
17651 | Some(DialectType::Databricks)
17652 ) && f.flags.is_none()
17653 {
17654 self.generate_expression(&f.this)?;
17656 self.write_keyword(" RLIKE ");
17657 self.generate_expression(&f.pattern)?;
17658 } else if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
17659 self.write_keyword("REGEXP");
17661 self.write("(");
17662 self.generate_expression(&f.this)?;
17663 self.write(", ");
17664 self.generate_expression(&f.pattern)?;
17665 if let Some(flags) = &f.flags {
17666 self.write(", ");
17667 self.generate_expression(flags)?;
17668 }
17669 self.write(")");
17670 } else {
17671 self.write_keyword("REGEXP_LIKE");
17672 self.write("(");
17673 self.generate_expression(&f.this)?;
17674 self.write(", ");
17675 self.generate_expression(&f.pattern)?;
17676 if let Some(flags) = &f.flags {
17677 self.write(", ");
17678 self.generate_expression(flags)?;
17679 }
17680 self.write(")");
17681 }
17682 Ok(())
17683 }
17684
17685 fn generate_regexp_replace(&mut self, f: &RegexpReplaceFunc) -> Result<()> {
17686 self.write_keyword("REGEXP_REPLACE");
17687 self.write("(");
17688 self.generate_expression(&f.this)?;
17689 self.write(", ");
17690 self.generate_expression(&f.pattern)?;
17691 self.write(", ");
17692 self.generate_expression(&f.replacement)?;
17693 if let Some(flags) = &f.flags {
17694 self.write(", ");
17695 self.generate_expression(flags)?;
17696 }
17697 self.write(")");
17698 Ok(())
17699 }
17700
17701 fn generate_regexp_extract(&mut self, f: &RegexpExtractFunc) -> Result<()> {
17702 self.write_keyword("REGEXP_EXTRACT");
17703 self.write("(");
17704 self.generate_expression(&f.this)?;
17705 self.write(", ");
17706 self.generate_expression(&f.pattern)?;
17707 if let Some(group) = &f.group {
17708 self.write(", ");
17709 self.generate_expression(group)?;
17710 }
17711 self.write(")");
17712 Ok(())
17713 }
17714
17715 fn generate_round(&mut self, f: &RoundFunc) -> Result<()> {
17718 self.write_keyword("ROUND");
17719 self.write("(");
17720 self.generate_expression(&f.this)?;
17721 if let Some(decimals) = &f.decimals {
17722 self.write(", ");
17723 self.generate_expression(decimals)?;
17724 }
17725 self.write(")");
17726 Ok(())
17727 }
17728
17729 fn generate_floor(&mut self, f: &FloorFunc) -> Result<()> {
17730 self.write_keyword("FLOOR");
17731 self.write("(");
17732 self.generate_expression(&f.this)?;
17733 if let Some(to) = &f.to {
17735 self.write(" ");
17736 self.write_keyword("TO");
17737 self.write(" ");
17738 self.generate_expression(to)?;
17739 } else if let Some(scale) = &f.scale {
17740 self.write(", ");
17741 self.generate_expression(scale)?;
17742 }
17743 self.write(")");
17744 Ok(())
17745 }
17746
17747 fn generate_ceil(&mut self, f: &CeilFunc) -> Result<()> {
17748 self.write_keyword("CEIL");
17749 self.write("(");
17750 self.generate_expression(&f.this)?;
17751 if let Some(to) = &f.to {
17753 self.write(" ");
17754 self.write_keyword("TO");
17755 self.write(" ");
17756 self.generate_expression(to)?;
17757 } else if let Some(decimals) = &f.decimals {
17758 self.write(", ");
17759 self.generate_expression(decimals)?;
17760 }
17761 self.write(")");
17762 Ok(())
17763 }
17764
17765 fn generate_log(&mut self, f: &LogFunc) -> Result<()> {
17766 use crate::expressions::Literal;
17767
17768 if let Some(base) = &f.base {
17769 if self.is_log_base_none() {
17772 if matches!(base, Expression::Literal(Literal::Number(s)) if s == "2") {
17773 self.write_func_name("LOG2");
17774 self.write("(");
17775 self.generate_expression(&f.this)?;
17776 self.write(")");
17777 return Ok(());
17778 } else if matches!(base, Expression::Literal(Literal::Number(s)) if s == "10") {
17779 self.write_func_name("LOG10");
17780 self.write("(");
17781 self.generate_expression(&f.this)?;
17782 self.write(")");
17783 return Ok(());
17784 }
17785 }
17787
17788 self.write_func_name("LOG");
17789 self.write("(");
17790 if self.is_log_value_first() {
17791 self.generate_expression(&f.this)?;
17793 self.write(", ");
17794 self.generate_expression(base)?;
17795 } else {
17796 self.generate_expression(base)?;
17798 self.write(", ");
17799 self.generate_expression(&f.this)?;
17800 }
17801 self.write(")");
17802 } else {
17803 self.write_func_name("LOG");
17805 self.write("(");
17806 self.generate_expression(&f.this)?;
17807 self.write(")");
17808 }
17809 Ok(())
17810 }
17811
17812 fn is_log_value_first(&self) -> bool {
17815 use crate::dialects::DialectType;
17816 matches!(
17817 self.config.dialect,
17818 Some(DialectType::BigQuery)
17819 | Some(DialectType::TSQL)
17820 | Some(DialectType::Tableau)
17821 | Some(DialectType::Fabric)
17822 )
17823 }
17824
17825 fn is_log_base_none(&self) -> bool {
17828 use crate::dialects::DialectType;
17829 matches!(
17830 self.config.dialect,
17831 Some(DialectType::Presto)
17832 | Some(DialectType::Trino)
17833 | Some(DialectType::ClickHouse)
17834 | Some(DialectType::Athena)
17835 )
17836 }
17837
17838 fn generate_current_time(&mut self, f: &CurrentTime) -> Result<()> {
17841 self.write_keyword("CURRENT_TIME");
17842 if let Some(precision) = f.precision {
17843 self.write(&format!("({})", precision));
17844 }
17845 Ok(())
17846 }
17847
17848 fn generate_current_timestamp(&mut self, f: &CurrentTimestamp) -> Result<()> {
17849 use crate::dialects::DialectType;
17850
17851 if f.sysdate {
17853 match self.config.dialect {
17854 Some(DialectType::Oracle) | Some(DialectType::Redshift) => {
17855 self.write_keyword("SYSDATE");
17856 return Ok(());
17857 }
17858 Some(DialectType::Snowflake) => {
17859 self.write_keyword("SYSDATE");
17861 self.write("()");
17862 return Ok(());
17863 }
17864 _ => {
17865 }
17867 }
17868 }
17869
17870 self.write_keyword("CURRENT_TIMESTAMP");
17871 if let Some(precision) = f.precision {
17873 self.write(&format!("({})", precision));
17874 } else if matches!(
17875 self.config.dialect,
17876 Some(crate::dialects::DialectType::MySQL)
17877 | Some(crate::dialects::DialectType::SingleStore)
17878 | Some(crate::dialects::DialectType::TiDB)
17879 | Some(crate::dialects::DialectType::Spark)
17880 | Some(crate::dialects::DialectType::Hive)
17881 | Some(crate::dialects::DialectType::Databricks)
17882 | Some(crate::dialects::DialectType::ClickHouse)
17883 | Some(crate::dialects::DialectType::BigQuery)
17884 | Some(crate::dialects::DialectType::Snowflake)
17885 ) {
17886 self.write("()");
17887 }
17888 Ok(())
17889 }
17890
17891 fn generate_at_time_zone(&mut self, f: &AtTimeZone) -> Result<()> {
17892 if self.config.dialect == Some(DialectType::Exasol) {
17894 self.write_keyword("CONVERT_TZ");
17895 self.write("(");
17896 self.generate_expression(&f.this)?;
17897 self.write(", 'UTC', ");
17898 self.generate_expression(&f.zone)?;
17899 self.write(")");
17900 return Ok(());
17901 }
17902
17903 self.generate_expression(&f.this)?;
17904 self.write_space();
17905 self.write_keyword("AT TIME ZONE");
17906 self.write_space();
17907 self.generate_expression(&f.zone)?;
17908 Ok(())
17909 }
17910
17911 fn generate_date_add(&mut self, f: &DateAddFunc, name: &str) -> Result<()> {
17912 use crate::dialects::DialectType;
17913
17914 let is_presto_like = matches!(
17917 self.config.dialect,
17918 Some(DialectType::Presto) | Some(DialectType::Trino)
17919 );
17920
17921 if is_presto_like {
17922 self.write_keyword(name);
17923 self.write("(");
17924 self.write("'");
17926 self.write_simple_interval_unit(&f.unit, false);
17927 self.write("'");
17928 self.write(", ");
17929 let needs_cast = !self.returns_integer_type(&f.interval);
17931 if needs_cast {
17932 self.write_keyword("CAST");
17933 self.write("(");
17934 }
17935 self.generate_expression(&f.interval)?;
17936 if needs_cast {
17937 self.write_space();
17938 self.write_keyword("AS");
17939 self.write_space();
17940 self.write_keyword("BIGINT");
17941 self.write(")");
17942 }
17943 self.write(", ");
17944 self.generate_expression(&f.this)?;
17945 self.write(")");
17946 } else {
17947 self.write_keyword(name);
17948 self.write("(");
17949 self.generate_expression(&f.this)?;
17950 self.write(", ");
17951 self.write_keyword("INTERVAL");
17952 self.write_space();
17953 self.generate_expression(&f.interval)?;
17954 self.write_space();
17955 self.write_simple_interval_unit(&f.unit, false); self.write(")");
17957 }
17958 Ok(())
17959 }
17960
17961 fn returns_integer_type(&self, expr: &Expression) -> bool {
17964 use crate::expressions::{DataType, Literal};
17965 match expr {
17966 Expression::Literal(Literal::Number(n)) => !n.contains('.'),
17968
17969 Expression::Floor(f) => self.returns_integer_type(&f.this),
17971
17972 Expression::Round(f) => {
17974 f.decimals.is_none() && self.returns_integer_type(&f.this)
17976 }
17977
17978 Expression::Sign(f) => self.returns_integer_type(&f.this),
17980
17981 Expression::Abs(f) => self.returns_integer_type(&f.this),
17983
17984 Expression::Mul(op) => {
17986 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
17987 }
17988 Expression::Add(op) => {
17989 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
17990 }
17991 Expression::Sub(op) => {
17992 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
17993 }
17994 Expression::Mod(op) => self.returns_integer_type(&op.left),
17995
17996 Expression::Cast(c) => matches!(
17998 &c.to,
17999 DataType::BigInt { .. }
18000 | DataType::Int { .. }
18001 | DataType::SmallInt { .. }
18002 | DataType::TinyInt { .. }
18003 ),
18004
18005 Expression::Neg(op) => self.returns_integer_type(&op.this),
18007
18008 Expression::Paren(p) => self.returns_integer_type(&p.this),
18010
18011 _ => false,
18014 }
18015 }
18016
18017 fn generate_datediff(&mut self, f: &DateDiffFunc) -> Result<()> {
18018 self.write_keyword("DATEDIFF");
18019 self.write("(");
18020 if let Some(unit) = &f.unit {
18021 self.write_simple_interval_unit(unit, false); self.write(", ");
18023 }
18024 self.generate_expression(&f.this)?;
18025 self.write(", ");
18026 self.generate_expression(&f.expression)?;
18027 self.write(")");
18028 Ok(())
18029 }
18030
18031 fn generate_date_trunc(&mut self, f: &DateTruncFunc) -> Result<()> {
18032 self.write_keyword("DATE_TRUNC");
18033 self.write("('");
18034 self.write_datetime_field(&f.unit);
18035 self.write("', ");
18036 self.generate_expression(&f.this)?;
18037 self.write(")");
18038 Ok(())
18039 }
18040
18041 fn generate_last_day(&mut self, f: &LastDayFunc) -> Result<()> {
18042 use crate::dialects::DialectType;
18043 use crate::expressions::DateTimeField;
18044
18045 self.write_keyword("LAST_DAY");
18046 self.write("(");
18047 self.generate_expression(&f.this)?;
18048 if let Some(unit) = &f.unit {
18049 self.write(", ");
18050 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
18053 if let DateTimeField::WeekWithModifier(_) = unit {
18054 self.write_keyword("WEEK");
18055 } else {
18056 self.write_datetime_field(unit);
18057 }
18058 } else {
18059 self.write_datetime_field(unit);
18060 }
18061 }
18062 self.write(")");
18063 Ok(())
18064 }
18065
18066 fn generate_extract(&mut self, f: &ExtractFunc) -> Result<()> {
18067 if matches!(
18069 self.config.dialect,
18070 Some(DialectType::TSQL) | Some(DialectType::Fabric)
18071 ) {
18072 self.write_keyword("DATEPART");
18073 self.write("(");
18074 self.write_datetime_field(&f.field);
18075 self.write(", ");
18076 self.generate_expression(&f.this)?;
18077 self.write(")");
18078 return Ok(());
18079 }
18080 self.write_keyword("EXTRACT");
18081 self.write("(");
18082 if matches!(
18084 self.config.dialect,
18085 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
18086 ) {
18087 self.write_datetime_field_lower(&f.field);
18088 } else {
18089 self.write_datetime_field(&f.field);
18090 }
18091 self.write_space();
18092 self.write_keyword("FROM");
18093 self.write_space();
18094 self.generate_expression(&f.this)?;
18095 self.write(")");
18096 Ok(())
18097 }
18098
18099 fn generate_to_date(&mut self, f: &ToDateFunc) -> Result<()> {
18100 self.write_keyword("TO_DATE");
18101 self.write("(");
18102 self.generate_expression(&f.this)?;
18103 if let Some(format) = &f.format {
18104 self.write(", ");
18105 self.generate_expression(format)?;
18106 }
18107 self.write(")");
18108 Ok(())
18109 }
18110
18111 fn generate_to_timestamp(&mut self, f: &ToTimestampFunc) -> Result<()> {
18112 self.write_keyword("TO_TIMESTAMP");
18113 self.write("(");
18114 self.generate_expression(&f.this)?;
18115 if let Some(format) = &f.format {
18116 self.write(", ");
18117 self.generate_expression(format)?;
18118 }
18119 self.write(")");
18120 Ok(())
18121 }
18122
18123 fn generate_if_func(&mut self, f: &IfFunc) -> Result<()> {
18126 use crate::dialects::DialectType;
18127
18128 if self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic) {
18130 self.write_keyword("CASE WHEN");
18131 self.write_space();
18132 self.generate_expression(&f.condition)?;
18133 self.write_space();
18134 self.write_keyword("THEN");
18135 self.write_space();
18136 self.generate_expression(&f.true_value)?;
18137 if let Some(false_val) = &f.false_value {
18138 self.write_space();
18139 self.write_keyword("ELSE");
18140 self.write_space();
18141 self.generate_expression(false_val)?;
18142 }
18143 self.write_space();
18144 self.write_keyword("END");
18145 return Ok(());
18146 }
18147
18148 if self.config.dialect == Some(DialectType::Exasol) {
18150 self.write_keyword("IF");
18151 self.write_space();
18152 self.generate_expression(&f.condition)?;
18153 self.write_space();
18154 self.write_keyword("THEN");
18155 self.write_space();
18156 self.generate_expression(&f.true_value)?;
18157 if let Some(false_val) = &f.false_value {
18158 self.write_space();
18159 self.write_keyword("ELSE");
18160 self.write_space();
18161 self.generate_expression(false_val)?;
18162 }
18163 self.write_space();
18164 self.write_keyword("ENDIF");
18165 return Ok(());
18166 }
18167
18168 let func_name = match self.config.dialect {
18170 Some(DialectType::Snowflake) => "IFF",
18171 Some(DialectType::SQLite) | Some(DialectType::TSQL) => "IIF",
18172 Some(DialectType::Drill) => "`IF`",
18173 _ => "IF",
18174 };
18175 self.write(func_name);
18176 self.write("(");
18177 self.generate_expression(&f.condition)?;
18178 self.write(", ");
18179 self.generate_expression(&f.true_value)?;
18180 if let Some(false_val) = &f.false_value {
18181 self.write(", ");
18182 self.generate_expression(false_val)?;
18183 }
18184 self.write(")");
18185 Ok(())
18186 }
18187
18188 fn generate_nvl2(&mut self, f: &Nvl2Func) -> Result<()> {
18189 self.write_keyword("NVL2");
18190 self.write("(");
18191 self.generate_expression(&f.this)?;
18192 self.write(", ");
18193 self.generate_expression(&f.true_value)?;
18194 self.write(", ");
18195 self.generate_expression(&f.false_value)?;
18196 self.write(")");
18197 Ok(())
18198 }
18199
18200 fn generate_count(&mut self, f: &CountFunc) -> Result<()> {
18203 let count_name = match self.config.normalize_functions {
18205 NormalizeFunctions::Upper => "COUNT".to_string(),
18206 NormalizeFunctions::Lower => "count".to_string(),
18207 NormalizeFunctions::None => f
18208 .original_name
18209 .clone()
18210 .unwrap_or_else(|| "COUNT".to_string()),
18211 };
18212 self.write(&count_name);
18213 self.write("(");
18214 if f.distinct {
18215 self.write_keyword("DISTINCT");
18216 self.write_space();
18217 }
18218 if f.star {
18219 self.write("*");
18220 } else if let Some(ref expr) = f.this {
18221 if let Expression::Tuple(tuple) = expr {
18223 let needs_transform =
18227 f.distinct && tuple.expressions.len() > 1 && !self.config.multi_arg_distinct;
18228
18229 if needs_transform {
18230 self.write_keyword("CASE");
18232 for e in &tuple.expressions {
18233 self.write_space();
18234 self.write_keyword("WHEN");
18235 self.write_space();
18236 self.generate_expression(e)?;
18237 self.write_space();
18238 self.write_keyword("IS NULL THEN NULL");
18239 }
18240 self.write_space();
18241 self.write_keyword("ELSE");
18242 self.write(" (");
18243 for (i, e) in tuple.expressions.iter().enumerate() {
18244 if i > 0 {
18245 self.write(", ");
18246 }
18247 self.generate_expression(e)?;
18248 }
18249 self.write(")");
18250 self.write_space();
18251 self.write_keyword("END");
18252 } else {
18253 for (i, e) in tuple.expressions.iter().enumerate() {
18254 if i > 0 {
18255 self.write(", ");
18256 }
18257 self.generate_expression(e)?;
18258 }
18259 }
18260 } else {
18261 self.generate_expression(expr)?;
18262 }
18263 }
18264 if let Some(ignore) = f.ignore_nulls {
18266 self.write_space();
18267 if ignore {
18268 self.write_keyword("IGNORE NULLS");
18269 } else {
18270 self.write_keyword("RESPECT NULLS");
18271 }
18272 }
18273 self.write(")");
18274 if let Some(ref filter) = f.filter {
18275 self.write_space();
18276 self.write_keyword("FILTER");
18277 self.write("(");
18278 self.write_keyword("WHERE");
18279 self.write_space();
18280 self.generate_expression(filter)?;
18281 self.write(")");
18282 }
18283 Ok(())
18284 }
18285
18286 fn generate_agg_func(&mut self, name: &str, f: &AggFunc) -> Result<()> {
18287 let func_name = match self.config.normalize_functions {
18289 NormalizeFunctions::Upper => name.to_uppercase(),
18290 NormalizeFunctions::Lower => name.to_lowercase(),
18291 NormalizeFunctions::None => {
18292 if let Some(ref original) = f.name {
18295 original.clone()
18296 } else {
18297 name.to_lowercase()
18298 }
18299 }
18300 };
18301 self.write(&func_name);
18302 self.write("(");
18303 if f.distinct {
18304 self.write_keyword("DISTINCT");
18305 self.write_space();
18306 }
18307 if !matches!(f.this, Expression::Null(_)) {
18309 self.generate_expression(&f.this)?;
18310 }
18311 if self.config.ignore_nulls_in_func
18314 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
18315 {
18316 match f.ignore_nulls {
18317 Some(true) => {
18318 self.write_space();
18319 self.write_keyword("IGNORE NULLS");
18320 }
18321 Some(false) => {
18322 self.write_space();
18323 self.write_keyword("RESPECT NULLS");
18324 }
18325 None => {}
18326 }
18327 }
18328 if let Some((ref expr, is_max)) = f.having_max {
18331 self.write_space();
18332 self.write_keyword("HAVING");
18333 self.write_space();
18334 if is_max {
18335 self.write_keyword("MAX");
18336 } else {
18337 self.write_keyword("MIN");
18338 }
18339 self.write_space();
18340 self.generate_expression(expr)?;
18341 }
18342 if !f.order_by.is_empty() {
18344 self.write_space();
18345 self.write_keyword("ORDER BY");
18346 self.write_space();
18347 for (i, ord) in f.order_by.iter().enumerate() {
18348 if i > 0 {
18349 self.write(", ");
18350 }
18351 self.generate_ordered(ord)?;
18352 }
18353 }
18354 if let Some(ref limit) = f.limit {
18356 self.write_space();
18357 self.write_keyword("LIMIT");
18358 self.write_space();
18359 if let Expression::Tuple(t) = limit.as_ref() {
18361 if t.expressions.len() == 2 {
18362 self.generate_expression(&t.expressions[0])?;
18363 self.write(", ");
18364 self.generate_expression(&t.expressions[1])?;
18365 } else {
18366 self.generate_expression(limit)?;
18367 }
18368 } else {
18369 self.generate_expression(limit)?;
18370 }
18371 }
18372 self.write(")");
18373 if !self.config.ignore_nulls_in_func
18376 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
18377 {
18378 match f.ignore_nulls {
18379 Some(true) => {
18380 self.write_space();
18381 self.write_keyword("IGNORE NULLS");
18382 }
18383 Some(false) => {
18384 self.write_space();
18385 self.write_keyword("RESPECT NULLS");
18386 }
18387 None => {}
18388 }
18389 }
18390 if let Some(ref filter) = f.filter {
18391 self.write_space();
18392 self.write_keyword("FILTER");
18393 self.write("(");
18394 self.write_keyword("WHERE");
18395 self.write_space();
18396 self.generate_expression(filter)?;
18397 self.write(")");
18398 }
18399 Ok(())
18400 }
18401
18402 fn generate_group_concat(&mut self, f: &GroupConcatFunc) -> Result<()> {
18403 self.write_keyword("GROUP_CONCAT");
18404 self.write("(");
18405 if f.distinct {
18406 self.write_keyword("DISTINCT");
18407 self.write_space();
18408 }
18409 self.generate_expression(&f.this)?;
18410 if let Some(ref order_by) = f.order_by {
18411 self.write_space();
18412 self.write_keyword("ORDER BY");
18413 self.write_space();
18414 for (i, ord) in order_by.iter().enumerate() {
18415 if i > 0 {
18416 self.write(", ");
18417 }
18418 self.generate_ordered(ord)?;
18419 }
18420 }
18421 if let Some(ref sep) = f.separator {
18422 if matches!(
18425 self.config.dialect,
18426 Some(crate::dialects::DialectType::SQLite)
18427 ) {
18428 self.write(", ");
18429 self.generate_expression(sep)?;
18430 } else {
18431 self.write_space();
18432 self.write_keyword("SEPARATOR");
18433 self.write_space();
18434 self.generate_expression(sep)?;
18435 }
18436 }
18437 self.write(")");
18438 if let Some(ref filter) = f.filter {
18439 self.write_space();
18440 self.write_keyword("FILTER");
18441 self.write("(");
18442 self.write_keyword("WHERE");
18443 self.write_space();
18444 self.generate_expression(filter)?;
18445 self.write(")");
18446 }
18447 Ok(())
18448 }
18449
18450 fn generate_string_agg(&mut self, f: &StringAggFunc) -> Result<()> {
18451 let is_tsql = matches!(
18452 self.config.dialect,
18453 Some(crate::dialects::DialectType::TSQL)
18454 );
18455 self.write_keyword("STRING_AGG");
18456 self.write("(");
18457 if f.distinct {
18458 self.write_keyword("DISTINCT");
18459 self.write_space();
18460 }
18461 self.generate_expression(&f.this)?;
18462 if let Some(ref separator) = f.separator {
18463 self.write(", ");
18464 self.generate_expression(separator)?;
18465 }
18466 if !is_tsql {
18468 if let Some(ref order_by) = f.order_by {
18469 self.write_space();
18470 self.write_keyword("ORDER BY");
18471 self.write_space();
18472 for (i, ord) in order_by.iter().enumerate() {
18473 if i > 0 {
18474 self.write(", ");
18475 }
18476 self.generate_ordered(ord)?;
18477 }
18478 }
18479 }
18480 if let Some(ref limit) = f.limit {
18481 self.write_space();
18482 self.write_keyword("LIMIT");
18483 self.write_space();
18484 self.generate_expression(limit)?;
18485 }
18486 self.write(")");
18487 if is_tsql {
18489 if let Some(ref order_by) = f.order_by {
18490 self.write_space();
18491 self.write_keyword("WITHIN GROUP");
18492 self.write(" (");
18493 self.write_keyword("ORDER BY");
18494 self.write_space();
18495 for (i, ord) in order_by.iter().enumerate() {
18496 if i > 0 {
18497 self.write(", ");
18498 }
18499 self.generate_ordered(ord)?;
18500 }
18501 self.write(")");
18502 }
18503 }
18504 if let Some(ref filter) = f.filter {
18505 self.write_space();
18506 self.write_keyword("FILTER");
18507 self.write("(");
18508 self.write_keyword("WHERE");
18509 self.write_space();
18510 self.generate_expression(filter)?;
18511 self.write(")");
18512 }
18513 Ok(())
18514 }
18515
18516 fn generate_listagg(&mut self, f: &ListAggFunc) -> Result<()> {
18517 use crate::dialects::DialectType;
18518 self.write_keyword("LISTAGG");
18519 self.write("(");
18520 if f.distinct {
18521 self.write_keyword("DISTINCT");
18522 self.write_space();
18523 }
18524 self.generate_expression(&f.this)?;
18525 if let Some(ref sep) = f.separator {
18526 self.write(", ");
18527 self.generate_expression(sep)?;
18528 } else if matches!(
18529 self.config.dialect,
18530 Some(DialectType::Trino) | Some(DialectType::Presto)
18531 ) {
18532 self.write(", ','");
18534 }
18535 if let Some(ref overflow) = f.on_overflow {
18536 self.write_space();
18537 self.write_keyword("ON OVERFLOW");
18538 self.write_space();
18539 match overflow {
18540 ListAggOverflow::Error => self.write_keyword("ERROR"),
18541 ListAggOverflow::Truncate { filler, with_count } => {
18542 self.write_keyword("TRUNCATE");
18543 if let Some(ref fill) = filler {
18544 self.write_space();
18545 self.generate_expression(fill)?;
18546 }
18547 if *with_count {
18548 self.write_space();
18549 self.write_keyword("WITH COUNT");
18550 } else {
18551 self.write_space();
18552 self.write_keyword("WITHOUT COUNT");
18553 }
18554 }
18555 }
18556 }
18557 self.write(")");
18558 if let Some(ref order_by) = f.order_by {
18559 self.write_space();
18560 self.write_keyword("WITHIN GROUP");
18561 self.write(" (");
18562 self.write_keyword("ORDER BY");
18563 self.write_space();
18564 for (i, ord) in order_by.iter().enumerate() {
18565 if i > 0 {
18566 self.write(", ");
18567 }
18568 self.generate_ordered(ord)?;
18569 }
18570 self.write(")");
18571 }
18572 if let Some(ref filter) = f.filter {
18573 self.write_space();
18574 self.write_keyword("FILTER");
18575 self.write("(");
18576 self.write_keyword("WHERE");
18577 self.write_space();
18578 self.generate_expression(filter)?;
18579 self.write(")");
18580 }
18581 Ok(())
18582 }
18583
18584 fn generate_sum_if(&mut self, f: &SumIfFunc) -> Result<()> {
18585 self.write_keyword("SUM_IF");
18586 self.write("(");
18587 self.generate_expression(&f.this)?;
18588 self.write(", ");
18589 self.generate_expression(&f.condition)?;
18590 self.write(")");
18591 if let Some(ref filter) = f.filter {
18592 self.write_space();
18593 self.write_keyword("FILTER");
18594 self.write("(");
18595 self.write_keyword("WHERE");
18596 self.write_space();
18597 self.generate_expression(filter)?;
18598 self.write(")");
18599 }
18600 Ok(())
18601 }
18602
18603 fn generate_approx_percentile(&mut self, f: &ApproxPercentileFunc) -> Result<()> {
18604 self.write_keyword("APPROX_PERCENTILE");
18605 self.write("(");
18606 self.generate_expression(&f.this)?;
18607 self.write(", ");
18608 self.generate_expression(&f.percentile)?;
18609 if let Some(ref acc) = f.accuracy {
18610 self.write(", ");
18611 self.generate_expression(acc)?;
18612 }
18613 self.write(")");
18614 if let Some(ref filter) = f.filter {
18615 self.write_space();
18616 self.write_keyword("FILTER");
18617 self.write("(");
18618 self.write_keyword("WHERE");
18619 self.write_space();
18620 self.generate_expression(filter)?;
18621 self.write(")");
18622 }
18623 Ok(())
18624 }
18625
18626 fn generate_percentile(&mut self, name: &str, f: &PercentileFunc) -> Result<()> {
18627 self.write_keyword(name);
18628 self.write("(");
18629 self.generate_expression(&f.percentile)?;
18630 self.write(")");
18631 if let Some(ref order_by) = f.order_by {
18632 self.write_space();
18633 self.write_keyword("WITHIN GROUP");
18634 self.write(" (");
18635 self.write_keyword("ORDER BY");
18636 self.write_space();
18637 self.generate_expression(&f.this)?;
18638 for ord in order_by.iter() {
18639 if ord.desc {
18640 self.write_space();
18641 self.write_keyword("DESC");
18642 }
18643 }
18644 self.write(")");
18645 }
18646 if let Some(ref filter) = f.filter {
18647 self.write_space();
18648 self.write_keyword("FILTER");
18649 self.write("(");
18650 self.write_keyword("WHERE");
18651 self.write_space();
18652 self.generate_expression(filter)?;
18653 self.write(")");
18654 }
18655 Ok(())
18656 }
18657
18658 fn generate_ntile(&mut self, f: &NTileFunc) -> Result<()> {
18661 self.write_keyword("NTILE");
18662 self.write("(");
18663 if let Some(num_buckets) = &f.num_buckets {
18664 self.generate_expression(num_buckets)?;
18665 }
18666 if let Some(order_by) = &f.order_by {
18667 self.write_keyword(" ORDER BY ");
18668 for (i, ob) in order_by.iter().enumerate() {
18669 if i > 0 {
18670 self.write(", ");
18671 }
18672 self.generate_ordered(ob)?;
18673 }
18674 }
18675 self.write(")");
18676 Ok(())
18677 }
18678
18679 fn generate_lead_lag(&mut self, name: &str, f: &LeadLagFunc) -> Result<()> {
18680 self.write_keyword(name);
18681 self.write("(");
18682 self.generate_expression(&f.this)?;
18683 if let Some(ref offset) = f.offset {
18684 self.write(", ");
18685 self.generate_expression(offset)?;
18686 if let Some(ref default) = f.default {
18687 self.write(", ");
18688 self.generate_expression(default)?;
18689 }
18690 }
18691 if f.ignore_nulls && self.config.ignore_nulls_in_func {
18693 self.write_space();
18694 self.write_keyword("IGNORE NULLS");
18695 }
18696 self.write(")");
18697 if f.ignore_nulls && !self.config.ignore_nulls_in_func {
18699 self.write_space();
18700 self.write_keyword("IGNORE NULLS");
18701 }
18702 Ok(())
18703 }
18704
18705 fn generate_value_func(&mut self, name: &str, f: &ValueFunc) -> Result<()> {
18706 self.write_keyword(name);
18707 self.write("(");
18708 self.generate_expression(&f.this)?;
18709 if self.config.ignore_nulls_in_func {
18711 match f.ignore_nulls {
18712 Some(true) => {
18713 self.write_space();
18714 self.write_keyword("IGNORE NULLS");
18715 }
18716 Some(false) => {
18717 self.write_space();
18718 self.write_keyword("RESPECT NULLS");
18719 }
18720 None => {}
18721 }
18722 }
18723 self.write(")");
18724 if !self.config.ignore_nulls_in_func {
18726 match f.ignore_nulls {
18727 Some(true) => {
18728 self.write_space();
18729 self.write_keyword("IGNORE NULLS");
18730 }
18731 Some(false) => {
18732 self.write_space();
18733 self.write_keyword("RESPECT NULLS");
18734 }
18735 None => {}
18736 }
18737 }
18738 Ok(())
18739 }
18740
18741 fn generate_nth_value(&mut self, f: &NthValueFunc) -> Result<()> {
18742 self.write_keyword("NTH_VALUE");
18743 self.write("(");
18744 self.generate_expression(&f.this)?;
18745 self.write(", ");
18746 self.generate_expression(&f.offset)?;
18747 if self.config.ignore_nulls_in_func {
18749 match f.ignore_nulls {
18750 Some(true) => {
18751 self.write_space();
18752 self.write_keyword("IGNORE NULLS");
18753 }
18754 Some(false) => {
18755 self.write_space();
18756 self.write_keyword("RESPECT NULLS");
18757 }
18758 None => {}
18759 }
18760 }
18761 self.write(")");
18762 if matches!(
18764 self.config.dialect,
18765 Some(crate::dialects::DialectType::Snowflake)
18766 ) {
18767 match f.from_first {
18768 Some(true) => {
18769 self.write_space();
18770 self.write_keyword("FROM FIRST");
18771 }
18772 Some(false) => {
18773 self.write_space();
18774 self.write_keyword("FROM LAST");
18775 }
18776 None => {}
18777 }
18778 }
18779 if !self.config.ignore_nulls_in_func {
18781 match f.ignore_nulls {
18782 Some(true) => {
18783 self.write_space();
18784 self.write_keyword("IGNORE NULLS");
18785 }
18786 Some(false) => {
18787 self.write_space();
18788 self.write_keyword("RESPECT NULLS");
18789 }
18790 None => {}
18791 }
18792 }
18793 Ok(())
18794 }
18795
18796 fn generate_position(&mut self, f: &PositionFunc) -> Result<()> {
18799 if matches!(
18802 self.config.dialect,
18803 Some(crate::dialects::DialectType::ClickHouse)
18804 ) {
18805 self.write_keyword("POSITION");
18806 self.write("(");
18807 self.generate_expression(&f.string)?;
18808 self.write(", ");
18809 self.generate_expression(&f.substring)?;
18810 if let Some(ref start) = f.start {
18811 self.write(", ");
18812 self.generate_expression(start)?;
18813 }
18814 self.write(")");
18815 return Ok(());
18816 }
18817
18818 self.write_keyword("POSITION");
18819 self.write("(");
18820 self.generate_expression(&f.substring)?;
18821 self.write_space();
18822 self.write_keyword("IN");
18823 self.write_space();
18824 self.generate_expression(&f.string)?;
18825 if let Some(ref start) = f.start {
18826 self.write(", ");
18827 self.generate_expression(start)?;
18828 }
18829 self.write(")");
18830 Ok(())
18831 }
18832
18833 fn generate_rand(&mut self, f: &Rand) -> Result<()> {
18836 if f.lower.is_some() || f.upper.is_some() {
18838 self.write_keyword("RANDOM");
18839 self.write("(");
18840 if let Some(ref lower) = f.lower {
18841 self.generate_expression(lower)?;
18842 }
18843 if let Some(ref upper) = f.upper {
18844 self.write(", ");
18845 self.generate_expression(upper)?;
18846 }
18847 self.write(")");
18848 return Ok(());
18849 }
18850 let func_name = match self.config.dialect {
18852 Some(crate::dialects::DialectType::Snowflake)
18853 | Some(crate::dialects::DialectType::DuckDB) => "RANDOM",
18854 _ => "RAND",
18855 };
18856 self.write_keyword(func_name);
18857 self.write("(");
18858 if !matches!(
18860 self.config.dialect,
18861 Some(crate::dialects::DialectType::DuckDB)
18862 ) {
18863 if let Some(ref seed) = f.seed {
18864 self.generate_expression(seed)?;
18865 }
18866 }
18867 self.write(")");
18868 Ok(())
18869 }
18870
18871 fn generate_truncate_func(&mut self, f: &TruncateFunc) -> Result<()> {
18872 self.write_keyword("TRUNCATE");
18873 self.write("(");
18874 self.generate_expression(&f.this)?;
18875 if let Some(ref decimals) = f.decimals {
18876 self.write(", ");
18877 self.generate_expression(decimals)?;
18878 }
18879 self.write(")");
18880 Ok(())
18881 }
18882
18883 fn generate_decode(&mut self, f: &DecodeFunc) -> Result<()> {
18886 self.write_keyword("DECODE");
18887 self.write("(");
18888 self.generate_expression(&f.this)?;
18889 for (search, result) in &f.search_results {
18890 self.write(", ");
18891 self.generate_expression(search)?;
18892 self.write(", ");
18893 self.generate_expression(result)?;
18894 }
18895 if let Some(ref default) = f.default {
18896 self.write(", ");
18897 self.generate_expression(default)?;
18898 }
18899 self.write(")");
18900 Ok(())
18901 }
18902
18903 fn generate_date_format(&mut self, name: &str, f: &DateFormatFunc) -> Result<()> {
18906 self.write_keyword(name);
18907 self.write("(");
18908 self.generate_expression(&f.this)?;
18909 self.write(", ");
18910 self.generate_expression(&f.format)?;
18911 self.write(")");
18912 Ok(())
18913 }
18914
18915 fn generate_from_unixtime(&mut self, f: &FromUnixtimeFunc) -> Result<()> {
18916 self.write_keyword("FROM_UNIXTIME");
18917 self.write("(");
18918 self.generate_expression(&f.this)?;
18919 if let Some(ref format) = f.format {
18920 self.write(", ");
18921 self.generate_expression(format)?;
18922 }
18923 self.write(")");
18924 Ok(())
18925 }
18926
18927 fn generate_unix_timestamp(&mut self, f: &UnixTimestampFunc) -> Result<()> {
18928 self.write_keyword("UNIX_TIMESTAMP");
18929 self.write("(");
18930 if let Some(ref expr) = f.this {
18931 self.generate_expression(expr)?;
18932 if let Some(ref format) = f.format {
18933 self.write(", ");
18934 self.generate_expression(format)?;
18935 }
18936 } else if matches!(
18937 self.config.dialect,
18938 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
18939 ) {
18940 self.write_keyword("CURRENT_TIMESTAMP");
18942 self.write("()");
18943 }
18944 self.write(")");
18945 Ok(())
18946 }
18947
18948 fn generate_make_date(&mut self, f: &MakeDateFunc) -> Result<()> {
18949 self.write_keyword("MAKE_DATE");
18950 self.write("(");
18951 self.generate_expression(&f.year)?;
18952 self.write(", ");
18953 self.generate_expression(&f.month)?;
18954 self.write(", ");
18955 self.generate_expression(&f.day)?;
18956 self.write(")");
18957 Ok(())
18958 }
18959
18960 fn generate_make_timestamp(&mut self, f: &MakeTimestampFunc) -> Result<()> {
18961 self.write_keyword("MAKE_TIMESTAMP");
18962 self.write("(");
18963 self.generate_expression(&f.year)?;
18964 self.write(", ");
18965 self.generate_expression(&f.month)?;
18966 self.write(", ");
18967 self.generate_expression(&f.day)?;
18968 self.write(", ");
18969 self.generate_expression(&f.hour)?;
18970 self.write(", ");
18971 self.generate_expression(&f.minute)?;
18972 self.write(", ");
18973 self.generate_expression(&f.second)?;
18974 if let Some(ref tz) = f.timezone {
18975 self.write(", ");
18976 self.generate_expression(tz)?;
18977 }
18978 self.write(")");
18979 Ok(())
18980 }
18981
18982 fn extract_struct_field_names(expr: &Expression) -> Option<Vec<String>> {
18984 match expr {
18985 Expression::Struct(s) => {
18986 if s.fields.iter().all(|(name, _)| name.is_some()) {
18987 Some(
18988 s.fields
18989 .iter()
18990 .map(|(name, _)| name.as_deref().unwrap_or("").to_string())
18991 .collect(),
18992 )
18993 } else {
18994 None
18995 }
18996 }
18997 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => {
18998 if f.args.iter().all(|a| matches!(a, Expression::Alias(_))) {
19000 Some(
19001 f.args
19002 .iter()
19003 .filter_map(|a| {
19004 if let Expression::Alias(alias) = a {
19005 Some(alias.alias.name.clone())
19006 } else {
19007 None
19008 }
19009 })
19010 .collect(),
19011 )
19012 } else {
19013 None
19014 }
19015 }
19016 _ => None,
19017 }
19018 }
19019
19020 fn struct_has_unnamed_fields(expr: &Expression) -> bool {
19022 match expr {
19023 Expression::Struct(s) => s.fields.iter().any(|(name, _)| name.is_none()),
19024 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => {
19025 f.args.iter().any(|a| !matches!(a, Expression::Alias(_)))
19026 }
19027 _ => false,
19028 }
19029 }
19030
19031 fn struct_field_count(expr: &Expression) -> usize {
19033 match expr {
19034 Expression::Struct(s) => s.fields.len(),
19035 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => f.args.len(),
19036 _ => 0,
19037 }
19038 }
19039
19040 fn apply_struct_field_names(expr: &Expression, field_names: &[String]) -> Expression {
19042 match expr {
19043 Expression::Struct(s) => {
19044 let mut new_fields = Vec::with_capacity(s.fields.len());
19045 for (i, (name, value)) in s.fields.iter().enumerate() {
19046 if name.is_none() && i < field_names.len() {
19047 new_fields.push((Some(field_names[i].clone()), value.clone()));
19048 } else {
19049 new_fields.push((name.clone(), value.clone()));
19050 }
19051 }
19052 Expression::Struct(Box::new(crate::expressions::Struct { fields: new_fields }))
19053 }
19054 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => {
19055 let mut new_args = Vec::with_capacity(f.args.len());
19056 for (i, arg) in f.args.iter().enumerate() {
19057 if !matches!(arg, Expression::Alias(_)) && i < field_names.len() {
19058 new_args.push(Expression::Alias(Box::new(crate::expressions::Alias {
19060 this: arg.clone(),
19061 alias: crate::expressions::Identifier::new(field_names[i].clone()),
19062 column_aliases: Vec::new(),
19063 pre_alias_comments: Vec::new(),
19064 trailing_comments: Vec::new(),
19065 inferred_type: None,
19066 })));
19067 } else {
19068 new_args.push(arg.clone());
19069 }
19070 }
19071 Expression::Function(Box::new(crate::expressions::Function {
19072 name: f.name.clone(),
19073 args: new_args,
19074 distinct: f.distinct,
19075 trailing_comments: f.trailing_comments.clone(),
19076 use_bracket_syntax: f.use_bracket_syntax,
19077 no_parens: f.no_parens,
19078 quoted: f.quoted,
19079 span: None,
19080 inferred_type: None,
19081 }))
19082 }
19083 _ => expr.clone(),
19084 }
19085 }
19086
19087 fn inherit_struct_field_names(expressions: &[Expression]) -> Vec<Expression> {
19091 let first = match expressions.first() {
19092 Some(e) => e,
19093 None => return expressions.to_vec(),
19094 };
19095
19096 let field_names = match Self::extract_struct_field_names(first) {
19097 Some(names) if !names.is_empty() => names,
19098 _ => return expressions.to_vec(),
19099 };
19100
19101 let mut result = Vec::with_capacity(expressions.len());
19102 for (idx, expr) in expressions.iter().enumerate() {
19103 if idx == 0 {
19104 result.push(expr.clone());
19105 continue;
19106 }
19107 if Self::struct_field_count(expr) == field_names.len()
19109 && Self::struct_has_unnamed_fields(expr)
19110 {
19111 result.push(Self::apply_struct_field_names(expr, &field_names));
19112 } else {
19113 result.push(expr.clone());
19114 }
19115 }
19116 result
19117 }
19118
19119 fn generate_array_constructor(&mut self, f: &ArrayConstructor) -> Result<()> {
19122 let needs_inheritance = matches!(
19125 self.config.dialect,
19126 Some(DialectType::DuckDB)
19127 | Some(DialectType::Spark)
19128 | Some(DialectType::Databricks)
19129 | Some(DialectType::Hive)
19130 | Some(DialectType::Snowflake)
19131 | Some(DialectType::Presto)
19132 | Some(DialectType::Trino)
19133 );
19134 let propagated: Vec<Expression>;
19135 let expressions = if needs_inheritance && f.expressions.len() > 1 {
19136 propagated = Self::inherit_struct_field_names(&f.expressions);
19137 &propagated
19138 } else {
19139 &f.expressions
19140 };
19141
19142 let should_split = if self.config.pretty && !expressions.is_empty() {
19144 let mut expr_strings: Vec<String> = Vec::with_capacity(expressions.len());
19145 for expr in expressions {
19146 let mut temp_gen = Generator::with_config(self.config.clone());
19147 temp_gen.config.pretty = false;
19148 temp_gen.generate_expression(expr)?;
19149 expr_strings.push(temp_gen.output);
19150 }
19151 self.too_wide(&expr_strings)
19152 } else {
19153 false
19154 };
19155
19156 if f.bracket_notation {
19157 let (open, close) = match self.config.dialect {
19161 None
19162 | Some(DialectType::Generic)
19163 | Some(DialectType::Spark)
19164 | Some(DialectType::Databricks)
19165 | Some(DialectType::Hive) => {
19166 self.write_keyword("ARRAY");
19167 ("(", ")")
19168 }
19169 Some(DialectType::Presto)
19170 | Some(DialectType::Trino)
19171 | Some(DialectType::PostgreSQL)
19172 | Some(DialectType::Redshift)
19173 | Some(DialectType::Materialize)
19174 | Some(DialectType::RisingWave)
19175 | Some(DialectType::CockroachDB) => {
19176 self.write_keyword("ARRAY");
19177 ("[", "]")
19178 }
19179 _ => ("[", "]"),
19180 };
19181 self.write(open);
19182 if should_split {
19183 self.write_newline();
19184 self.indent_level += 1;
19185 for (i, expr) in expressions.iter().enumerate() {
19186 self.write_indent();
19187 self.generate_expression(expr)?;
19188 if i + 1 < expressions.len() {
19189 self.write(",");
19190 }
19191 self.write_newline();
19192 }
19193 self.indent_level -= 1;
19194 self.write_indent();
19195 } else {
19196 for (i, expr) in expressions.iter().enumerate() {
19197 if i > 0 {
19198 self.write(", ");
19199 }
19200 self.generate_expression(expr)?;
19201 }
19202 }
19203 self.write(close);
19204 } else {
19205 if f.use_list_keyword {
19207 self.write_keyword("LIST");
19208 } else {
19209 self.write_keyword("ARRAY");
19210 }
19211 let has_subquery = expressions
19214 .iter()
19215 .any(|e| matches!(e, Expression::Select(_)));
19216 let (open, close) = if matches!(
19217 self.config.dialect,
19218 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive)
19219 ) || (matches!(self.config.dialect, Some(DialectType::BigQuery))
19220 && has_subquery)
19221 {
19222 ("(", ")")
19223 } else {
19224 ("[", "]")
19225 };
19226 self.write(open);
19227 if should_split {
19228 self.write_newline();
19229 self.indent_level += 1;
19230 for (i, expr) in expressions.iter().enumerate() {
19231 self.write_indent();
19232 self.generate_expression(expr)?;
19233 if i + 1 < expressions.len() {
19234 self.write(",");
19235 }
19236 self.write_newline();
19237 }
19238 self.indent_level -= 1;
19239 self.write_indent();
19240 } else {
19241 for (i, expr) in expressions.iter().enumerate() {
19242 if i > 0 {
19243 self.write(", ");
19244 }
19245 self.generate_expression(expr)?;
19246 }
19247 }
19248 self.write(close);
19249 }
19250 Ok(())
19251 }
19252
19253 fn generate_array_sort(&mut self, f: &ArraySortFunc) -> Result<()> {
19254 self.write_keyword("ARRAY_SORT");
19255 self.write("(");
19256 self.generate_expression(&f.this)?;
19257 if let Some(ref comp) = f.comparator {
19258 self.write(", ");
19259 self.generate_expression(comp)?;
19260 }
19261 self.write(")");
19262 Ok(())
19263 }
19264
19265 fn generate_array_join(&mut self, name: &str, f: &ArrayJoinFunc) -> Result<()> {
19266 self.write_keyword(name);
19267 self.write("(");
19268 self.generate_expression(&f.this)?;
19269 self.write(", ");
19270 self.generate_expression(&f.separator)?;
19271 if let Some(ref null_rep) = f.null_replacement {
19272 self.write(", ");
19273 self.generate_expression(null_rep)?;
19274 }
19275 self.write(")");
19276 Ok(())
19277 }
19278
19279 fn generate_unnest(&mut self, f: &UnnestFunc) -> Result<()> {
19280 self.write_keyword("UNNEST");
19281 self.write("(");
19282 self.generate_expression(&f.this)?;
19283 for extra in &f.expressions {
19284 self.write(", ");
19285 self.generate_expression(extra)?;
19286 }
19287 self.write(")");
19288 if f.with_ordinality {
19289 self.write_space();
19290 if self.config.unnest_with_ordinality {
19291 self.write_keyword("WITH ORDINALITY");
19293 } else if f.offset_alias.is_some() {
19294 if let Some(ref alias) = f.alias {
19297 self.write_keyword("AS");
19298 self.write_space();
19299 self.generate_identifier(alias)?;
19300 self.write_space();
19301 }
19302 self.write_keyword("WITH OFFSET");
19303 if let Some(ref offset_alias) = f.offset_alias {
19304 self.write_space();
19305 self.write_keyword("AS");
19306 self.write_space();
19307 self.generate_identifier(offset_alias)?;
19308 }
19309 } else {
19310 self.write_keyword("WITH OFFSET");
19312 if f.alias.is_none() {
19313 self.write(" AS offset");
19314 }
19315 }
19316 }
19317 if let Some(ref alias) = f.alias {
19318 let should_add_alias = if !f.with_ordinality {
19320 true
19321 } else if self.config.unnest_with_ordinality {
19322 true
19324 } else if f.offset_alias.is_some() {
19325 false
19327 } else {
19328 true
19330 };
19331 if should_add_alias {
19332 self.write_space();
19333 self.write_keyword("AS");
19334 self.write_space();
19335 self.generate_identifier(alias)?;
19336 }
19337 }
19338 Ok(())
19339 }
19340
19341 fn generate_array_filter(&mut self, f: &ArrayFilterFunc) -> Result<()> {
19342 self.write_keyword("FILTER");
19343 self.write("(");
19344 self.generate_expression(&f.this)?;
19345 self.write(", ");
19346 self.generate_expression(&f.filter)?;
19347 self.write(")");
19348 Ok(())
19349 }
19350
19351 fn generate_array_transform(&mut self, f: &ArrayTransformFunc) -> Result<()> {
19352 self.write_keyword("TRANSFORM");
19353 self.write("(");
19354 self.generate_expression(&f.this)?;
19355 self.write(", ");
19356 self.generate_expression(&f.transform)?;
19357 self.write(")");
19358 Ok(())
19359 }
19360
19361 fn generate_sequence(&mut self, name: &str, f: &SequenceFunc) -> Result<()> {
19362 self.write_keyword(name);
19363 self.write("(");
19364 self.generate_expression(&f.start)?;
19365 self.write(", ");
19366 self.generate_expression(&f.stop)?;
19367 if let Some(ref step) = f.step {
19368 self.write(", ");
19369 self.generate_expression(step)?;
19370 }
19371 self.write(")");
19372 Ok(())
19373 }
19374
19375 fn generate_struct_constructor(&mut self, f: &StructConstructor) -> Result<()> {
19378 self.write_keyword("STRUCT");
19379 self.write("(");
19380 for (i, (name, expr)) in f.fields.iter().enumerate() {
19381 if i > 0 {
19382 self.write(", ");
19383 }
19384 if let Some(ref id) = name {
19385 self.generate_identifier(id)?;
19386 self.write(" ");
19387 self.write_keyword("AS");
19388 self.write(" ");
19389 }
19390 self.generate_expression(expr)?;
19391 }
19392 self.write(")");
19393 Ok(())
19394 }
19395
19396 fn generate_struct_function_cross_dialect(&mut self, func: &Function) -> Result<()> {
19398 let mut names: Vec<Option<String>> = Vec::new();
19401 let mut values: Vec<&Expression> = Vec::new();
19402 let mut all_named = true;
19403
19404 for arg in &func.args {
19405 match arg {
19406 Expression::Alias(a) => {
19407 names.push(Some(a.alias.name.clone()));
19408 values.push(&a.this);
19409 }
19410 _ => {
19411 names.push(None);
19412 values.push(arg);
19413 all_named = false;
19414 }
19415 }
19416 }
19417
19418 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
19419 self.write("{");
19421 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
19422 if i > 0 {
19423 self.write(", ");
19424 }
19425 if let Some(n) = name {
19426 self.write("'");
19427 self.write(n);
19428 self.write("'");
19429 } else {
19430 self.write("'_");
19431 self.write(&i.to_string());
19432 self.write("'");
19433 }
19434 self.write(": ");
19435 self.generate_expression(value)?;
19436 }
19437 self.write("}");
19438 return Ok(());
19439 }
19440
19441 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
19442 self.write_keyword("OBJECT_CONSTRUCT");
19444 self.write("(");
19445 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
19446 if i > 0 {
19447 self.write(", ");
19448 }
19449 if let Some(n) = name {
19450 self.write("'");
19451 self.write(n);
19452 self.write("'");
19453 } else {
19454 self.write("'_");
19455 self.write(&i.to_string());
19456 self.write("'");
19457 }
19458 self.write(", ");
19459 self.generate_expression(value)?;
19460 }
19461 self.write(")");
19462 return Ok(());
19463 }
19464
19465 if matches!(
19466 self.config.dialect,
19467 Some(DialectType::Presto) | Some(DialectType::Trino)
19468 ) {
19469 if all_named && !names.is_empty() {
19470 self.write_keyword("CAST");
19473 self.write("(");
19474 self.write_keyword("ROW");
19475 self.write("(");
19476 for (i, value) in values.iter().enumerate() {
19477 if i > 0 {
19478 self.write(", ");
19479 }
19480 self.generate_expression(value)?;
19481 }
19482 self.write(")");
19483 self.write(" ");
19484 self.write_keyword("AS");
19485 self.write(" ");
19486 self.write_keyword("ROW");
19487 self.write("(");
19488 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
19489 if i > 0 {
19490 self.write(", ");
19491 }
19492 if let Some(n) = name {
19493 self.write(n);
19494 }
19495 self.write(" ");
19496 let type_str = Self::infer_sql_type_for_presto(value);
19497 self.write_keyword(&type_str);
19498 }
19499 self.write(")");
19500 self.write(")");
19501 } else {
19502 self.write_keyword("ROW");
19504 self.write("(");
19505 for (i, value) in values.iter().enumerate() {
19506 if i > 0 {
19507 self.write(", ");
19508 }
19509 self.generate_expression(value)?;
19510 }
19511 self.write(")");
19512 }
19513 return Ok(());
19514 }
19515
19516 self.write_keyword("ROW");
19518 self.write("(");
19519 for (i, value) in values.iter().enumerate() {
19520 if i > 0 {
19521 self.write(", ");
19522 }
19523 self.generate_expression(value)?;
19524 }
19525 self.write(")");
19526 Ok(())
19527 }
19528
19529 fn infer_sql_type_for_presto(expr: &Expression) -> String {
19531 match expr {
19532 Expression::Literal(crate::expressions::Literal::String(_)) => "VARCHAR".to_string(),
19533 Expression::Literal(crate::expressions::Literal::Number(n)) => {
19534 if n.contains('.') {
19535 "DOUBLE".to_string()
19536 } else {
19537 "INTEGER".to_string()
19538 }
19539 }
19540 Expression::Boolean(_) => "BOOLEAN".to_string(),
19541 Expression::Literal(crate::expressions::Literal::Date(_)) => "DATE".to_string(),
19542 Expression::Literal(crate::expressions::Literal::Timestamp(_)) => {
19543 "TIMESTAMP".to_string()
19544 }
19545 Expression::Literal(crate::expressions::Literal::Datetime(_)) => {
19546 "TIMESTAMP".to_string()
19547 }
19548 Expression::Array(_) | Expression::ArrayFunc(_) => {
19549 "ARRAY(VARCHAR)".to_string()
19551 }
19552 Expression::Struct(_) | Expression::StructFunc(_) => "ROW".to_string(),
19554 Expression::Function(f) => {
19555 let up = f.name.to_uppercase();
19556 if up == "STRUCT" {
19557 "ROW".to_string()
19558 } else if up == "CURRENT_DATE" {
19559 "DATE".to_string()
19560 } else if up == "CURRENT_TIMESTAMP" || up == "NOW" {
19561 "TIMESTAMP".to_string()
19562 } else {
19563 "VARCHAR".to_string()
19564 }
19565 }
19566 _ => "VARCHAR".to_string(),
19567 }
19568 }
19569
19570 fn generate_struct_extract(&mut self, f: &StructExtractFunc) -> Result<()> {
19571 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
19573 self.write_keyword("STRUCT_EXTRACT");
19574 self.write("(");
19575 self.generate_expression(&f.this)?;
19576 self.write(", ");
19577 self.write("'");
19579 self.write(&f.field.name);
19580 self.write("'");
19581 self.write(")");
19582 return Ok(());
19583 }
19584 self.generate_expression(&f.this)?;
19585 self.write(".");
19586 self.generate_identifier(&f.field)
19587 }
19588
19589 fn generate_named_struct(&mut self, f: &NamedStructFunc) -> Result<()> {
19590 self.write_keyword("NAMED_STRUCT");
19591 self.write("(");
19592 for (i, (name, value)) in f.pairs.iter().enumerate() {
19593 if i > 0 {
19594 self.write(", ");
19595 }
19596 self.generate_expression(name)?;
19597 self.write(", ");
19598 self.generate_expression(value)?;
19599 }
19600 self.write(")");
19601 Ok(())
19602 }
19603
19604 fn generate_map_constructor(&mut self, f: &MapConstructor) -> Result<()> {
19607 if f.curly_brace_syntax {
19608 if f.with_map_keyword {
19610 self.write_keyword("MAP");
19611 self.write(" ");
19612 }
19613 self.write("{");
19614 for (i, (key, val)) in f.keys.iter().zip(f.values.iter()).enumerate() {
19615 if i > 0 {
19616 self.write(", ");
19617 }
19618 self.generate_expression(key)?;
19619 self.write(": ");
19620 self.generate_expression(val)?;
19621 }
19622 self.write("}");
19623 } else {
19624 self.write_keyword("MAP");
19626 self.write("(");
19627 self.write_keyword("ARRAY");
19628 self.write("[");
19629 for (i, key) in f.keys.iter().enumerate() {
19630 if i > 0 {
19631 self.write(", ");
19632 }
19633 self.generate_expression(key)?;
19634 }
19635 self.write("], ");
19636 self.write_keyword("ARRAY");
19637 self.write("[");
19638 for (i, val) in f.values.iter().enumerate() {
19639 if i > 0 {
19640 self.write(", ");
19641 }
19642 self.generate_expression(val)?;
19643 }
19644 self.write("])");
19645 }
19646 Ok(())
19647 }
19648
19649 fn generate_transform_func(&mut self, name: &str, f: &TransformFunc) -> Result<()> {
19650 self.write_keyword(name);
19651 self.write("(");
19652 self.generate_expression(&f.this)?;
19653 self.write(", ");
19654 self.generate_expression(&f.transform)?;
19655 self.write(")");
19656 Ok(())
19657 }
19658
19659 fn generate_json_extract(&mut self, name: &str, f: &JsonExtractFunc) -> Result<()> {
19662 use crate::dialects::DialectType;
19663
19664 let use_arrow = f.arrow_syntax && self.dialect_supports_json_arrow();
19666
19667 if use_arrow {
19668 self.generate_expression(&f.this)?;
19670 if name == "JSON_EXTRACT_SCALAR" || name == "JSON_EXTRACT_PATH_TEXT" {
19671 self.write(" ->> ");
19672 } else {
19673 self.write(" -> ");
19674 }
19675 self.generate_expression(&f.path)?;
19676 return Ok(());
19677 }
19678
19679 if f.hash_arrow_syntax
19681 && matches!(
19682 self.config.dialect,
19683 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
19684 )
19685 {
19686 self.generate_expression(&f.this)?;
19687 self.write(" #>> ");
19688 self.generate_expression(&f.path)?;
19689 return Ok(());
19690 }
19691
19692 let func_name = if matches!(self.config.dialect, Some(DialectType::Redshift)) {
19695 match name {
19696 "JSON_EXTRACT_SCALAR"
19697 | "JSON_EXTRACT_PATH_TEXT"
19698 | "JSON_EXTRACT"
19699 | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH_TEXT",
19700 _ => name,
19701 }
19702 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
19703 match name {
19704 "JSON_EXTRACT_SCALAR" | "JSON_EXTRACT_PATH_TEXT" => "JSON_EXTRACT_PATH_TEXT",
19705 "JSON_EXTRACT" | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH",
19706 _ => name,
19707 }
19708 } else {
19709 name
19710 };
19711
19712 self.write_keyword(func_name);
19713 self.write("(");
19714 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
19716 if let Expression::Cast(ref cast) = f.this {
19717 if matches!(cast.to, crate::expressions::DataType::Json) {
19718 self.generate_expression(&cast.this)?;
19719 } else {
19720 self.generate_expression(&f.this)?;
19721 }
19722 } else {
19723 self.generate_expression(&f.this)?;
19724 }
19725 } else {
19726 self.generate_expression(&f.this)?;
19727 }
19728 if matches!(
19731 self.config.dialect,
19732 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
19733 ) && (func_name == "JSON_EXTRACT_PATH" || func_name == "JSON_EXTRACT_PATH_TEXT")
19734 {
19735 if let Expression::Literal(Literal::String(ref s)) = f.path {
19736 let parts = Self::decompose_json_path(s);
19737 for part in &parts {
19738 self.write(", '");
19739 self.write(part);
19740 self.write("'");
19741 }
19742 } else {
19743 self.write(", ");
19744 self.generate_expression(&f.path)?;
19745 }
19746 } else {
19747 self.write(", ");
19748 self.generate_expression(&f.path)?;
19749 }
19750
19751 if let Some(ref wrapper) = f.wrapper_option {
19754 self.write_space();
19755 self.write_keyword(wrapper);
19756 }
19757 if let Some(ref quotes) = f.quotes_option {
19758 self.write_space();
19759 self.write_keyword(quotes);
19760 if f.on_scalar_string {
19761 self.write_space();
19762 self.write_keyword("ON SCALAR STRING");
19763 }
19764 }
19765 if let Some(ref on_err) = f.on_error {
19766 self.write_space();
19767 self.write_keyword(on_err);
19768 }
19769 if let Some(ref ret_type) = f.returning {
19770 self.write_space();
19771 self.write_keyword("RETURNING");
19772 self.write_space();
19773 self.generate_data_type(ret_type)?;
19774 }
19775
19776 self.write(")");
19777 Ok(())
19778 }
19779
19780 fn dialect_supports_json_arrow(&self) -> bool {
19782 use crate::dialects::DialectType;
19783 match self.config.dialect {
19784 Some(DialectType::PostgreSQL) => true,
19786 Some(DialectType::MySQL) => true,
19787 Some(DialectType::DuckDB) => true,
19788 Some(DialectType::CockroachDB) => true,
19789 Some(DialectType::StarRocks) => true,
19790 Some(DialectType::SQLite) => true,
19791 _ => false,
19793 }
19794 }
19795
19796 fn generate_json_path(&mut self, name: &str, f: &JsonPathFunc) -> Result<()> {
19797 use crate::dialects::DialectType;
19798
19799 if matches!(
19801 self.config.dialect,
19802 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
19803 ) && name == "JSON_EXTRACT_PATH"
19804 {
19805 self.generate_expression(&f.this)?;
19806 self.write(" #> ");
19807 if f.paths.len() == 1 {
19808 self.generate_expression(&f.paths[0])?;
19809 } else {
19810 self.write_keyword("ARRAY");
19812 self.write("[");
19813 for (i, path) in f.paths.iter().enumerate() {
19814 if i > 0 {
19815 self.write(", ");
19816 }
19817 self.generate_expression(path)?;
19818 }
19819 self.write("]");
19820 }
19821 return Ok(());
19822 }
19823
19824 self.write_keyword(name);
19825 self.write("(");
19826 self.generate_expression(&f.this)?;
19827 for path in &f.paths {
19828 self.write(", ");
19829 self.generate_expression(path)?;
19830 }
19831 self.write(")");
19832 Ok(())
19833 }
19834
19835 fn generate_json_object(&mut self, f: &JsonObjectFunc) -> Result<()> {
19836 use crate::dialects::DialectType;
19837
19838 self.write_keyword("JSON_OBJECT");
19839 self.write("(");
19840 if f.star {
19841 self.write("*");
19842 } else {
19843 let use_comma_syntax = self.config.json_key_value_pair_sep == ","
19847 || matches!(
19848 self.config.dialect,
19849 Some(DialectType::BigQuery)
19850 | Some(DialectType::MySQL)
19851 | Some(DialectType::SQLite)
19852 );
19853
19854 for (i, (key, value)) in f.pairs.iter().enumerate() {
19855 if i > 0 {
19856 self.write(", ");
19857 }
19858 self.generate_expression(key)?;
19859 if use_comma_syntax {
19860 self.write(", ");
19861 } else {
19862 self.write(": ");
19863 }
19864 self.generate_expression(value)?;
19865 }
19866 }
19867 if let Some(null_handling) = f.null_handling {
19868 self.write_space();
19869 match null_handling {
19870 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
19871 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
19872 }
19873 }
19874 if f.with_unique_keys {
19875 self.write_space();
19876 self.write_keyword("WITH UNIQUE KEYS");
19877 }
19878 if let Some(ref ret_type) = f.returning_type {
19879 self.write_space();
19880 self.write_keyword("RETURNING");
19881 self.write_space();
19882 self.generate_data_type(ret_type)?;
19883 if f.format_json {
19884 self.write_space();
19885 self.write_keyword("FORMAT JSON");
19886 }
19887 if let Some(ref enc) = f.encoding {
19888 self.write_space();
19889 self.write_keyword("ENCODING");
19890 self.write_space();
19891 self.write(enc);
19892 }
19893 }
19894 self.write(")");
19895 Ok(())
19896 }
19897
19898 fn generate_json_modify(&mut self, name: &str, f: &JsonModifyFunc) -> Result<()> {
19899 self.write_keyword(name);
19900 self.write("(");
19901 self.generate_expression(&f.this)?;
19902 for (path, value) in &f.path_values {
19903 self.write(", ");
19904 self.generate_expression(path)?;
19905 self.write(", ");
19906 self.generate_expression(value)?;
19907 }
19908 self.write(")");
19909 Ok(())
19910 }
19911
19912 fn generate_json_array_agg(&mut self, f: &JsonArrayAggFunc) -> Result<()> {
19913 self.write_keyword("JSON_ARRAYAGG");
19914 self.write("(");
19915 self.generate_expression(&f.this)?;
19916 if let Some(ref order_by) = f.order_by {
19917 self.write_space();
19918 self.write_keyword("ORDER BY");
19919 self.write_space();
19920 for (i, ord) in order_by.iter().enumerate() {
19921 if i > 0 {
19922 self.write(", ");
19923 }
19924 self.generate_ordered(ord)?;
19925 }
19926 }
19927 if let Some(null_handling) = f.null_handling {
19928 self.write_space();
19929 match null_handling {
19930 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
19931 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
19932 }
19933 }
19934 self.write(")");
19935 if let Some(ref filter) = f.filter {
19936 self.write_space();
19937 self.write_keyword("FILTER");
19938 self.write("(");
19939 self.write_keyword("WHERE");
19940 self.write_space();
19941 self.generate_expression(filter)?;
19942 self.write(")");
19943 }
19944 Ok(())
19945 }
19946
19947 fn generate_json_object_agg(&mut self, f: &JsonObjectAggFunc) -> Result<()> {
19948 self.write_keyword("JSON_OBJECTAGG");
19949 self.write("(");
19950 self.generate_expression(&f.key)?;
19951 self.write(": ");
19952 self.generate_expression(&f.value)?;
19953 if let Some(null_handling) = f.null_handling {
19954 self.write_space();
19955 match null_handling {
19956 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
19957 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
19958 }
19959 }
19960 self.write(")");
19961 if let Some(ref filter) = f.filter {
19962 self.write_space();
19963 self.write_keyword("FILTER");
19964 self.write("(");
19965 self.write_keyword("WHERE");
19966 self.write_space();
19967 self.generate_expression(filter)?;
19968 self.write(")");
19969 }
19970 Ok(())
19971 }
19972
19973 fn generate_convert(&mut self, f: &ConvertFunc) -> Result<()> {
19976 use crate::dialects::DialectType;
19977
19978 if self.config.dialect == Some(DialectType::Redshift) {
19980 self.write_keyword("CAST");
19981 self.write("(");
19982 self.generate_expression(&f.this)?;
19983 self.write_space();
19984 self.write_keyword("AS");
19985 self.write_space();
19986 self.generate_data_type(&f.to)?;
19987 self.write(")");
19988 return Ok(());
19989 }
19990
19991 self.write_keyword("CONVERT");
19992 self.write("(");
19993 self.generate_data_type(&f.to)?;
19994 self.write(", ");
19995 self.generate_expression(&f.this)?;
19996 if let Some(ref style) = f.style {
19997 self.write(", ");
19998 self.generate_expression(style)?;
19999 }
20000 self.write(")");
20001 Ok(())
20002 }
20003
20004 fn generate_lambda(&mut self, f: &LambdaExpr) -> Result<()> {
20007 if f.colon {
20008 self.write_keyword("LAMBDA");
20010 self.write_space();
20011 for (i, param) in f.parameters.iter().enumerate() {
20012 if i > 0 {
20013 self.write(", ");
20014 }
20015 self.generate_identifier(param)?;
20016 }
20017 self.write(" : ");
20018 } else {
20019 if f.parameters.len() == 1 {
20021 self.generate_identifier(&f.parameters[0])?;
20022 } else {
20023 self.write("(");
20024 for (i, param) in f.parameters.iter().enumerate() {
20025 if i > 0 {
20026 self.write(", ");
20027 }
20028 self.generate_identifier(param)?;
20029 }
20030 self.write(")");
20031 }
20032 self.write(" -> ");
20033 }
20034 self.generate_expression(&f.body)
20035 }
20036
20037 fn generate_named_argument(&mut self, f: &NamedArgument) -> Result<()> {
20038 self.generate_identifier(&f.name)?;
20039 match f.separator {
20040 NamedArgSeparator::DArrow => self.write(" => "),
20041 NamedArgSeparator::ColonEq => self.write(" := "),
20042 NamedArgSeparator::Eq => self.write(" = "),
20043 }
20044 self.generate_expression(&f.value)
20045 }
20046
20047 fn generate_table_argument(&mut self, f: &TableArgument) -> Result<()> {
20048 self.write_keyword(&f.prefix);
20049 self.write(" ");
20050 self.generate_expression(&f.this)
20051 }
20052
20053 fn generate_parameter(&mut self, f: &Parameter) -> Result<()> {
20054 match f.style {
20055 ParameterStyle::Question => self.write("?"),
20056 ParameterStyle::Dollar => {
20057 self.write("$");
20058 if let Some(idx) = f.index {
20059 self.write(&idx.to_string());
20060 } else if let Some(ref name) = f.name {
20061 self.write(name);
20063 }
20064 }
20065 ParameterStyle::DollarBrace => {
20066 self.write("${");
20068 if let Some(ref name) = f.name {
20069 self.write(name);
20070 }
20071 if let Some(ref expr) = f.expression {
20072 self.write(":");
20073 self.write(expr);
20074 }
20075 self.write("}");
20076 }
20077 ParameterStyle::Colon => {
20078 self.write(":");
20079 if let Some(idx) = f.index {
20080 self.write(&idx.to_string());
20081 } else if let Some(ref name) = f.name {
20082 self.write(name);
20083 }
20084 }
20085 ParameterStyle::At => {
20086 self.write("@");
20087 if let Some(ref name) = f.name {
20088 if f.string_quoted {
20089 self.write("'");
20090 self.write(name);
20091 self.write("'");
20092 } else if f.quoted {
20093 self.write("\"");
20094 self.write(name);
20095 self.write("\"");
20096 } else {
20097 self.write(name);
20098 }
20099 }
20100 }
20101 ParameterStyle::DoubleAt => {
20102 self.write("@@");
20103 if let Some(ref name) = f.name {
20104 self.write(name);
20105 }
20106 }
20107 ParameterStyle::DoubleDollar => {
20108 self.write("$$");
20109 if let Some(ref name) = f.name {
20110 self.write(name);
20111 }
20112 }
20113 ParameterStyle::Percent => {
20114 if let Some(ref name) = f.name {
20115 self.write("%(");
20117 self.write(name);
20118 self.write(")s");
20119 } else {
20120 self.write("%s");
20122 }
20123 }
20124 ParameterStyle::Brace => {
20125 self.write("{");
20128 if let Some(ref name) = f.name {
20129 self.write(name);
20130 }
20131 if let Some(ref expr) = f.expression {
20132 self.write(": ");
20133 self.write(expr);
20134 }
20135 self.write("}");
20136 }
20137 }
20138 Ok(())
20139 }
20140
20141 fn generate_placeholder(&mut self, f: &Placeholder) -> Result<()> {
20142 self.write("?");
20143 if let Some(idx) = f.index {
20144 self.write(&idx.to_string());
20145 }
20146 Ok(())
20147 }
20148
20149 fn generate_sql_comment(&mut self, f: &SqlComment) -> Result<()> {
20150 if f.is_block {
20151 self.write("/*");
20152 self.write(&f.text);
20153 self.write("*/");
20154 } else {
20155 self.write("--");
20156 self.write(&f.text);
20157 }
20158 Ok(())
20159 }
20160
20161 fn generate_similar_to(&mut self, f: &SimilarToExpr) -> Result<()> {
20164 self.generate_expression(&f.this)?;
20165 if f.not {
20166 self.write_space();
20167 self.write_keyword("NOT");
20168 }
20169 self.write_space();
20170 self.write_keyword("SIMILAR TO");
20171 self.write_space();
20172 self.generate_expression(&f.pattern)?;
20173 if let Some(ref escape) = f.escape {
20174 self.write_space();
20175 self.write_keyword("ESCAPE");
20176 self.write_space();
20177 self.generate_expression(escape)?;
20178 }
20179 Ok(())
20180 }
20181
20182 fn generate_quantified(&mut self, name: &str, f: &QuantifiedExpr) -> Result<()> {
20183 self.generate_expression(&f.this)?;
20184 self.write_space();
20185 if let Some(op) = &f.op {
20187 match op {
20188 QuantifiedOp::Eq => self.write("="),
20189 QuantifiedOp::Neq => self.write("<>"),
20190 QuantifiedOp::Lt => self.write("<"),
20191 QuantifiedOp::Lte => self.write("<="),
20192 QuantifiedOp::Gt => self.write(">"),
20193 QuantifiedOp::Gte => self.write(">="),
20194 }
20195 self.write_space();
20196 }
20197 self.write_keyword(name);
20198
20199 if matches!(&f.subquery, Expression::Subquery(_)) {
20201 self.write_space();
20202 self.generate_expression(&f.subquery)?;
20203 } else {
20204 self.write("(");
20205
20206 let is_statement = matches!(
20207 &f.subquery,
20208 Expression::Select(_)
20209 | Expression::Union(_)
20210 | Expression::Intersect(_)
20211 | Expression::Except(_)
20212 );
20213
20214 if self.config.pretty && is_statement {
20215 self.write_newline();
20216 self.indent_level += 1;
20217 self.write_indent();
20218 }
20219 self.generate_expression(&f.subquery)?;
20220 if self.config.pretty && is_statement {
20221 self.write_newline();
20222 self.indent_level -= 1;
20223 self.write_indent();
20224 }
20225 self.write(")");
20226 }
20227 Ok(())
20228 }
20229
20230 fn generate_overlaps(&mut self, f: &OverlapsExpr) -> Result<()> {
20231 if let (Some(this), Some(expr)) = (&f.this, &f.expression) {
20233 self.generate_expression(this)?;
20234 self.write_space();
20235 self.write_keyword("OVERLAPS");
20236 self.write_space();
20237 self.generate_expression(expr)?;
20238 } else if let (Some(ls), Some(le), Some(rs), Some(re)) =
20239 (&f.left_start, &f.left_end, &f.right_start, &f.right_end)
20240 {
20241 self.write("(");
20243 self.generate_expression(ls)?;
20244 self.write(", ");
20245 self.generate_expression(le)?;
20246 self.write(")");
20247 self.write_space();
20248 self.write_keyword("OVERLAPS");
20249 self.write_space();
20250 self.write("(");
20251 self.generate_expression(rs)?;
20252 self.write(", ");
20253 self.generate_expression(re)?;
20254 self.write(")");
20255 }
20256 Ok(())
20257 }
20258
20259 fn generate_try_cast(&mut self, cast: &Cast) -> Result<()> {
20262 use crate::dialects::DialectType;
20263
20264 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
20266 self.generate_expression(&cast.this)?;
20267 self.write(" !:> ");
20268 self.generate_data_type(&cast.to)?;
20269 return Ok(());
20270 }
20271
20272 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
20274 self.write_keyword("TRYCAST");
20275 self.write("(");
20276 self.generate_expression(&cast.this)?;
20277 self.write_space();
20278 self.write_keyword("AS");
20279 self.write_space();
20280 self.generate_data_type(&cast.to)?;
20281 self.write(")");
20282 return Ok(());
20283 }
20284
20285 let keyword = if matches!(
20287 self.config.dialect,
20288 Some(DialectType::Hive)
20289 | Some(DialectType::MySQL)
20290 | Some(DialectType::SQLite)
20291 | Some(DialectType::Oracle)
20292 | Some(DialectType::ClickHouse)
20293 | Some(DialectType::Redshift)
20294 | Some(DialectType::PostgreSQL)
20295 | Some(DialectType::StarRocks)
20296 | Some(DialectType::Doris)
20297 ) {
20298 "CAST"
20299 } else {
20300 "TRY_CAST"
20301 };
20302
20303 self.write_keyword(keyword);
20304 self.write("(");
20305 self.generate_expression(&cast.this)?;
20306 self.write_space();
20307 self.write_keyword("AS");
20308 self.write_space();
20309 self.generate_data_type(&cast.to)?;
20310
20311 if let Some(format) = &cast.format {
20313 self.write_space();
20314 self.write_keyword("FORMAT");
20315 self.write_space();
20316 self.generate_expression(format)?;
20317 }
20318
20319 self.write(")");
20320 Ok(())
20321 }
20322
20323 fn generate_safe_cast(&mut self, cast: &Cast) -> Result<()> {
20324 self.write_keyword("SAFE_CAST");
20325 self.write("(");
20326 self.generate_expression(&cast.this)?;
20327 self.write_space();
20328 self.write_keyword("AS");
20329 self.write_space();
20330 self.generate_data_type(&cast.to)?;
20331
20332 if let Some(format) = &cast.format {
20334 self.write_space();
20335 self.write_keyword("FORMAT");
20336 self.write_space();
20337 self.generate_expression(format)?;
20338 }
20339
20340 self.write(")");
20341 Ok(())
20342 }
20343
20344 fn generate_subscript(&mut self, s: &Subscript) -> Result<()> {
20347 self.generate_expression(&s.this)?;
20348 self.write("[");
20349 self.generate_expression(&s.index)?;
20350 self.write("]");
20351 Ok(())
20352 }
20353
20354 fn generate_dot_access(&mut self, d: &DotAccess) -> Result<()> {
20355 self.generate_expression(&d.this)?;
20356 let use_colon = matches!(self.config.dialect, Some(DialectType::Snowflake))
20359 && matches!(
20360 &d.this,
20361 Expression::Cast(_) | Expression::SafeCast(_) | Expression::TryCast(_)
20362 );
20363 if use_colon {
20364 self.write(":");
20365 } else {
20366 self.write(".");
20367 }
20368 self.generate_identifier(&d.field)
20369 }
20370
20371 fn generate_method_call(&mut self, m: &MethodCall) -> Result<()> {
20372 self.generate_expression(&m.this)?;
20373 self.write(".");
20374 if m.method.quoted {
20377 let q = self.config.identifier_quote;
20378 self.write(&format!("{}{}{}", q, m.method.name, q));
20379 } else {
20380 self.write(&m.method.name);
20381 }
20382 self.write("(");
20383 for (i, arg) in m.args.iter().enumerate() {
20384 if i > 0 {
20385 self.write(", ");
20386 }
20387 self.generate_expression(arg)?;
20388 }
20389 self.write(")");
20390 Ok(())
20391 }
20392
20393 fn generate_array_slice(&mut self, s: &ArraySlice) -> Result<()> {
20394 let needs_parens = matches!(
20397 &s.this,
20398 Expression::JsonExtract(f) if f.arrow_syntax
20399 ) || matches!(
20400 &s.this,
20401 Expression::JsonExtractScalar(f) if f.arrow_syntax
20402 );
20403
20404 if needs_parens {
20405 self.write("(");
20406 }
20407 self.generate_expression(&s.this)?;
20408 if needs_parens {
20409 self.write(")");
20410 }
20411 self.write("[");
20412 if let Some(start) = &s.start {
20413 self.generate_expression(start)?;
20414 }
20415 self.write(":");
20416 if let Some(end) = &s.end {
20417 self.generate_expression(end)?;
20418 }
20419 self.write("]");
20420 Ok(())
20421 }
20422
20423 fn generate_binary_op(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
20424 match &op.left {
20428 Expression::Column(col) => {
20429 if let Some(table) = &col.table {
20432 self.generate_identifier(table)?;
20433 self.write(".");
20434 }
20435 self.generate_identifier(&col.name)?;
20436 if col.join_mark && self.config.supports_column_join_marks {
20438 self.write(" (+)");
20439 }
20440 if op.left_comments.is_empty() {
20442 for comment in &col.trailing_comments {
20443 self.write_space();
20444 self.write_formatted_comment(comment);
20445 }
20446 }
20447 }
20448 Expression::Add(inner_op)
20449 | Expression::Sub(inner_op)
20450 | Expression::Mul(inner_op)
20451 | Expression::Div(inner_op)
20452 | Expression::Concat(inner_op) => {
20453 self.generate_binary_op_no_trailing(inner_op, match &op.left {
20455 Expression::Add(_) => "+",
20456 Expression::Sub(_) => "-",
20457 Expression::Mul(_) => "*",
20458 Expression::Div(_) => "/",
20459 Expression::Concat(_) => "||",
20460 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
20461 })?;
20462 }
20463 _ => {
20464 self.generate_expression(&op.left)?;
20465 }
20466 }
20467 for comment in &op.left_comments {
20469 self.write_space();
20470 self.write_formatted_comment(comment);
20471 }
20472 if self.config.pretty
20473 && matches!(self.config.dialect, Some(DialectType::Snowflake))
20474 && (operator == "AND" || operator == "OR")
20475 {
20476 self.write_newline();
20477 self.write_indent();
20478 self.write_keyword(operator);
20479 } else {
20480 self.write_space();
20481 if operator.chars().all(|c| c.is_alphabetic()) {
20482 self.write_keyword(operator);
20483 } else {
20484 self.write(operator);
20485 }
20486 }
20487 for comment in &op.operator_comments {
20489 self.write_space();
20490 self.write_formatted_comment(comment);
20491 }
20492 self.write_space();
20493 self.generate_expression(&op.right)?;
20494 for comment in &op.trailing_comments {
20496 self.write_space();
20497 self.write_formatted_comment(comment);
20498 }
20499 Ok(())
20500 }
20501
20502 fn generate_connector_op(&mut self, op: &BinaryOp, connector: ConnectorOperator) -> Result<()> {
20503 let keyword = connector.keyword();
20504 let Some(terms) = self.flatten_connector_terms(op, connector) else {
20505 return self.generate_binary_op(op, keyword);
20506 };
20507
20508 self.generate_expression(terms[0])?;
20509 for term in terms.iter().skip(1) {
20510 if self.config.pretty && matches!(self.config.dialect, Some(DialectType::Snowflake)) {
20511 self.write_newline();
20512 self.write_indent();
20513 self.write_keyword(keyword);
20514 } else {
20515 self.write_space();
20516 self.write_keyword(keyword);
20517 }
20518 self.write_space();
20519 self.generate_expression(term)?;
20520 }
20521
20522 Ok(())
20523 }
20524
20525 fn flatten_connector_terms<'a>(
20526 &self,
20527 root: &'a BinaryOp,
20528 connector: ConnectorOperator,
20529 ) -> Option<Vec<&'a Expression>> {
20530 if !root.left_comments.is_empty()
20531 || !root.operator_comments.is_empty()
20532 || !root.trailing_comments.is_empty()
20533 {
20534 return None;
20535 }
20536
20537 let mut terms = Vec::new();
20538 let mut stack: Vec<&Expression> = vec![&root.right, &root.left];
20539
20540 while let Some(expr) = stack.pop() {
20541 match (connector, expr) {
20542 (ConnectorOperator::And, Expression::And(inner))
20543 if inner.left_comments.is_empty()
20544 && inner.operator_comments.is_empty()
20545 && inner.trailing_comments.is_empty() =>
20546 {
20547 stack.push(&inner.right);
20548 stack.push(&inner.left);
20549 }
20550 (ConnectorOperator::Or, Expression::Or(inner))
20551 if inner.left_comments.is_empty()
20552 && inner.operator_comments.is_empty()
20553 && inner.trailing_comments.is_empty() =>
20554 {
20555 stack.push(&inner.right);
20556 stack.push(&inner.left);
20557 }
20558 _ => terms.push(expr),
20559 }
20560 }
20561
20562 if terms.len() > 1 {
20563 Some(terms)
20564 } else {
20565 None
20566 }
20567 }
20568
20569 fn generate_like_op(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
20571 self.generate_expression(&op.left)?;
20572 self.write_space();
20573 if operator == "ILIKE" && matches!(self.config.dialect, Some(DialectType::Drill)) {
20575 self.write("`ILIKE`");
20576 } else {
20577 self.write_keyword(operator);
20578 }
20579 if let Some(quantifier) = &op.quantifier {
20580 self.write_space();
20581 self.write_keyword(quantifier);
20582 }
20583 self.write_space();
20584 self.generate_expression(&op.right)?;
20585 if let Some(escape) = &op.escape {
20586 self.write_space();
20587 self.write_keyword("ESCAPE");
20588 self.write_space();
20589 self.generate_expression(escape)?;
20590 }
20591 Ok(())
20592 }
20593
20594 fn generate_null_safe_eq(&mut self, op: &BinaryOp) -> Result<()> {
20597 use crate::dialects::DialectType;
20598 self.generate_expression(&op.left)?;
20599 self.write_space();
20600 if matches!(self.config.dialect, Some(DialectType::MySQL)) {
20601 self.write("<=>");
20602 } else {
20603 self.write_keyword("IS NOT DISTINCT FROM");
20604 }
20605 self.write_space();
20606 self.generate_expression(&op.right)?;
20607 Ok(())
20608 }
20609
20610 fn generate_null_safe_neq(&mut self, op: &BinaryOp) -> Result<()> {
20612 self.generate_expression(&op.left)?;
20613 self.write_space();
20614 self.write_keyword("IS DISTINCT FROM");
20615 self.write_space();
20616 self.generate_expression(&op.right)?;
20617 Ok(())
20618 }
20619
20620 fn generate_binary_op_no_trailing(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
20622 match &op.left {
20624 Expression::Column(col) => {
20625 if let Some(table) = &col.table {
20626 self.generate_identifier(table)?;
20627 self.write(".");
20628 }
20629 self.generate_identifier(&col.name)?;
20630 if col.join_mark && self.config.supports_column_join_marks {
20632 self.write(" (+)");
20633 }
20634 }
20635 Expression::Add(inner_op)
20636 | Expression::Sub(inner_op)
20637 | Expression::Mul(inner_op)
20638 | Expression::Div(inner_op)
20639 | Expression::Concat(inner_op) => {
20640 self.generate_binary_op_no_trailing(inner_op, match &op.left {
20641 Expression::Add(_) => "+",
20642 Expression::Sub(_) => "-",
20643 Expression::Mul(_) => "*",
20644 Expression::Div(_) => "/",
20645 Expression::Concat(_) => "||",
20646 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
20647 })?;
20648 }
20649 _ => {
20650 self.generate_expression(&op.left)?;
20651 }
20652 }
20653 for comment in &op.left_comments {
20655 self.write_space();
20656 self.write_formatted_comment(comment);
20657 }
20658 self.write_space();
20659 if operator.chars().all(|c| c.is_alphabetic()) {
20660 self.write_keyword(operator);
20661 } else {
20662 self.write(operator);
20663 }
20664 for comment in &op.operator_comments {
20666 self.write_space();
20667 self.write_formatted_comment(comment);
20668 }
20669 self.write_space();
20670 match &op.right {
20673 Expression::Column(col) => {
20674 if let Some(table) = &col.table {
20675 self.generate_identifier(table)?;
20676 self.write(".");
20677 }
20678 self.generate_identifier(&col.name)?;
20679 if col.join_mark && self.config.supports_column_join_marks {
20681 self.write(" (+)");
20682 }
20683 }
20684 _ => {
20685 self.generate_expression(&op.right)?;
20686 }
20687 }
20688 Ok(())
20690 }
20691
20692 fn generate_unary_op(&mut self, op: &UnaryOp, operator: &str) -> Result<()> {
20693 if operator.chars().all(|c| c.is_alphabetic()) {
20694 self.write_keyword(operator);
20695 self.write_space();
20696 } else {
20697 self.write(operator);
20698 if matches!(&op.this, Expression::Neg(_) | Expression::BitwiseNot(_)) {
20700 self.write_space();
20701 }
20702 }
20703 self.generate_expression(&op.this)
20704 }
20705
20706 fn generate_in(&mut self, in_expr: &In) -> Result<()> {
20707 let is_generic =
20711 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
20712 let use_prefix_not =
20713 in_expr.not && is_generic && self.config.not_in_style == NotInStyle::Prefix;
20714 if use_prefix_not {
20715 self.write_keyword("NOT");
20716 self.write_space();
20717 }
20718 self.generate_expression(&in_expr.this)?;
20719 if in_expr.global {
20720 self.write_space();
20721 self.write_keyword("GLOBAL");
20722 }
20723 if in_expr.not && !use_prefix_not {
20724 self.write_space();
20725 self.write_keyword("NOT");
20726 }
20727 self.write_space();
20728 self.write_keyword("IN");
20729
20730 if let Some(unnest_expr) = &in_expr.unnest {
20732 self.write_space();
20733 self.write_keyword("UNNEST");
20734 self.write("(");
20735 self.generate_expression(unnest_expr)?;
20736 self.write(")");
20737 return Ok(());
20738 }
20739
20740 if let Some(query) = &in_expr.query {
20741 let is_bare = in_expr.expressions.is_empty()
20744 && !matches!(
20745 query,
20746 Expression::Select(_)
20747 | Expression::Union(_)
20748 | Expression::Intersect(_)
20749 | Expression::Except(_)
20750 | Expression::Subquery(_)
20751 );
20752 if is_bare {
20753 self.write_space();
20755 self.generate_expression(query)?;
20756 } else {
20757 self.write(" (");
20759 let is_statement = matches!(
20760 query,
20761 Expression::Select(_)
20762 | Expression::Union(_)
20763 | Expression::Intersect(_)
20764 | Expression::Except(_)
20765 | Expression::Subquery(_)
20766 );
20767 if self.config.pretty && is_statement {
20768 self.write_newline();
20769 self.indent_level += 1;
20770 self.write_indent();
20771 }
20772 self.generate_expression(query)?;
20773 if self.config.pretty && is_statement {
20774 self.write_newline();
20775 self.indent_level -= 1;
20776 self.write_indent();
20777 }
20778 self.write(")");
20779 }
20780 } else {
20781 let is_duckdb = matches!(
20785 self.config.dialect,
20786 Some(crate::dialects::DialectType::DuckDB)
20787 );
20788 let is_clickhouse = matches!(
20789 self.config.dialect,
20790 Some(crate::dialects::DialectType::ClickHouse)
20791 );
20792 let single_expr = in_expr.expressions.len() == 1;
20793 if is_clickhouse && single_expr {
20794 if let Expression::Array(arr) = &in_expr.expressions[0] {
20795 self.write(" (");
20797 for (i, expr) in arr.expressions.iter().enumerate() {
20798 if i > 0 {
20799 self.write(", ");
20800 }
20801 self.generate_expression(expr)?;
20802 }
20803 self.write(")");
20804 } else {
20805 self.write_space();
20806 self.generate_expression(&in_expr.expressions[0])?;
20807 }
20808 } else {
20809 let is_bare_ref = single_expr
20810 && matches!(
20811 &in_expr.expressions[0],
20812 Expression::Column(_) | Expression::Identifier(_) | Expression::Dot(_)
20813 );
20814 if (is_duckdb && is_bare_ref) || (in_expr.is_field && single_expr) {
20815 self.write_space();
20818 self.generate_expression(&in_expr.expressions[0])?;
20819 } else {
20820 self.write(" (");
20822 for (i, expr) in in_expr.expressions.iter().enumerate() {
20823 if i > 0 {
20824 self.write(", ");
20825 }
20826 self.generate_expression(expr)?;
20827 }
20828 self.write(")");
20829 }
20830 }
20831 }
20832
20833 Ok(())
20834 }
20835
20836 fn generate_between(&mut self, between: &Between) -> Result<()> {
20837 let use_prefix_not = between.not
20839 && (self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic));
20840 if use_prefix_not {
20841 self.write_keyword("NOT");
20842 self.write_space();
20843 }
20844 self.generate_expression(&between.this)?;
20845 if between.not && !use_prefix_not {
20846 self.write_space();
20847 self.write_keyword("NOT");
20848 }
20849 self.write_space();
20850 self.write_keyword("BETWEEN");
20851 if let Some(sym) = between.symmetric {
20853 if sym {
20854 self.write(" SYMMETRIC");
20855 } else {
20856 self.write(" ASYMMETRIC");
20857 }
20858 }
20859 self.write_space();
20860 self.generate_expression(&between.low)?;
20861 self.write_space();
20862 self.write_keyword("AND");
20863 self.write_space();
20864 self.generate_expression(&between.high)
20865 }
20866
20867 fn generate_is_null(&mut self, is_null: &IsNull) -> Result<()> {
20868 let use_prefix_not = is_null.not
20870 && (self.config.dialect.is_none()
20871 || self.config.dialect == Some(DialectType::Generic)
20872 || is_null.postfix_form);
20873 if use_prefix_not {
20874 self.write_keyword("NOT");
20876 self.write_space();
20877 self.generate_expression(&is_null.this)?;
20878 self.write_space();
20879 self.write_keyword("IS");
20880 self.write_space();
20881 self.write_keyword("NULL");
20882 } else {
20883 self.generate_expression(&is_null.this)?;
20884 self.write_space();
20885 self.write_keyword("IS");
20886 if is_null.not {
20887 self.write_space();
20888 self.write_keyword("NOT");
20889 }
20890 self.write_space();
20891 self.write_keyword("NULL");
20892 }
20893 Ok(())
20894 }
20895
20896 fn generate_is_true(&mut self, is_true: &IsTrueFalse) -> Result<()> {
20897 self.generate_expression(&is_true.this)?;
20898 self.write_space();
20899 self.write_keyword("IS");
20900 if is_true.not {
20901 self.write_space();
20902 self.write_keyword("NOT");
20903 }
20904 self.write_space();
20905 self.write_keyword("TRUE");
20906 Ok(())
20907 }
20908
20909 fn generate_is_false(&mut self, is_false: &IsTrueFalse) -> Result<()> {
20910 self.generate_expression(&is_false.this)?;
20911 self.write_space();
20912 self.write_keyword("IS");
20913 if is_false.not {
20914 self.write_space();
20915 self.write_keyword("NOT");
20916 }
20917 self.write_space();
20918 self.write_keyword("FALSE");
20919 Ok(())
20920 }
20921
20922 fn generate_is_json(&mut self, is_json: &IsJson) -> Result<()> {
20923 self.generate_expression(&is_json.this)?;
20924 self.write_space();
20925 self.write_keyword("IS");
20926 if is_json.negated {
20927 self.write_space();
20928 self.write_keyword("NOT");
20929 }
20930 self.write_space();
20931 self.write_keyword("JSON");
20932
20933 if let Some(ref json_type) = is_json.json_type {
20935 self.write_space();
20936 self.write_keyword(json_type);
20937 }
20938
20939 match &is_json.unique_keys {
20941 Some(JsonUniqueKeys::With) => {
20942 self.write_space();
20943 self.write_keyword("WITH UNIQUE KEYS");
20944 }
20945 Some(JsonUniqueKeys::Without) => {
20946 self.write_space();
20947 self.write_keyword("WITHOUT UNIQUE KEYS");
20948 }
20949 Some(JsonUniqueKeys::Shorthand) => {
20950 self.write_space();
20951 self.write_keyword("UNIQUE KEYS");
20952 }
20953 None => {}
20954 }
20955
20956 Ok(())
20957 }
20958
20959 fn generate_is(&mut self, is_expr: &BinaryOp) -> Result<()> {
20960 self.generate_expression(&is_expr.left)?;
20961 self.write_space();
20962 self.write_keyword("IS");
20963 self.write_space();
20964 self.generate_expression(&is_expr.right)
20965 }
20966
20967 fn generate_exists(&mut self, exists: &Exists) -> Result<()> {
20968 if exists.not {
20969 self.write_keyword("NOT");
20970 self.write_space();
20971 }
20972 self.write_keyword("EXISTS");
20973 self.write("(");
20974 let is_statement = matches!(
20975 &exists.this,
20976 Expression::Select(_)
20977 | Expression::Union(_)
20978 | Expression::Intersect(_)
20979 | Expression::Except(_)
20980 );
20981 if self.config.pretty && is_statement {
20982 self.write_newline();
20983 self.indent_level += 1;
20984 self.write_indent();
20985 self.generate_expression(&exists.this)?;
20986 self.write_newline();
20987 self.indent_level -= 1;
20988 self.write_indent();
20989 self.write(")");
20990 } else {
20991 self.generate_expression(&exists.this)?;
20992 self.write(")");
20993 }
20994 Ok(())
20995 }
20996
20997 fn generate_member_of(&mut self, op: &BinaryOp) -> Result<()> {
20998 self.generate_expression(&op.left)?;
20999 self.write_space();
21000 self.write_keyword("MEMBER OF");
21001 self.write("(");
21002 self.generate_expression(&op.right)?;
21003 self.write(")");
21004 Ok(())
21005 }
21006
21007 fn generate_subquery(&mut self, subquery: &Subquery) -> Result<()> {
21008 if subquery.lateral {
21009 self.write_keyword("LATERAL");
21010 self.write_space();
21011 }
21012
21013 let skip_outer_parens = if let Expression::Paren(ref p) = &subquery.this {
21017 matches!(
21018 &p.this,
21019 Expression::Select(_)
21020 | Expression::Union(_)
21021 | Expression::Intersect(_)
21022 | Expression::Except(_)
21023 | Expression::Subquery(_)
21024 )
21025 } else {
21026 false
21027 };
21028
21029 let is_statement = matches!(
21031 &subquery.this,
21032 Expression::Select(_)
21033 | Expression::Union(_)
21034 | Expression::Intersect(_)
21035 | Expression::Except(_)
21036 | Expression::Merge(_)
21037 );
21038
21039 if !skip_outer_parens {
21040 self.write("(");
21041 if self.config.pretty && is_statement {
21042 self.write_newline();
21043 self.indent_level += 1;
21044 self.write_indent();
21045 }
21046 }
21047 self.generate_expression(&subquery.this)?;
21048
21049 if subquery.modifiers_inside {
21051 if let Some(order_by) = &subquery.order_by {
21053 self.write_space();
21054 self.write_keyword("ORDER BY");
21055 self.write_space();
21056 for (i, ord) in order_by.expressions.iter().enumerate() {
21057 if i > 0 {
21058 self.write(", ");
21059 }
21060 self.generate_ordered(ord)?;
21061 }
21062 }
21063
21064 if let Some(limit) = &subquery.limit {
21065 self.write_space();
21066 self.write_keyword("LIMIT");
21067 self.write_space();
21068 self.generate_expression(&limit.this)?;
21069 if limit.percent {
21070 self.write_space();
21071 self.write_keyword("PERCENT");
21072 }
21073 }
21074
21075 if let Some(offset) = &subquery.offset {
21076 self.write_space();
21077 self.write_keyword("OFFSET");
21078 self.write_space();
21079 self.generate_expression(&offset.this)?;
21080 }
21081 }
21082
21083 if !skip_outer_parens {
21084 if self.config.pretty && is_statement {
21085 self.write_newline();
21086 self.indent_level -= 1;
21087 self.write_indent();
21088 }
21089 self.write(")");
21090 }
21091
21092 if !subquery.modifiers_inside {
21094 if let Some(order_by) = &subquery.order_by {
21095 self.write_space();
21096 self.write_keyword("ORDER BY");
21097 self.write_space();
21098 for (i, ord) in order_by.expressions.iter().enumerate() {
21099 if i > 0 {
21100 self.write(", ");
21101 }
21102 self.generate_ordered(ord)?;
21103 }
21104 }
21105
21106 if let Some(limit) = &subquery.limit {
21107 self.write_space();
21108 self.write_keyword("LIMIT");
21109 self.write_space();
21110 self.generate_expression(&limit.this)?;
21111 if limit.percent {
21112 self.write_space();
21113 self.write_keyword("PERCENT");
21114 }
21115 }
21116
21117 if let Some(offset) = &subquery.offset {
21118 self.write_space();
21119 self.write_keyword("OFFSET");
21120 self.write_space();
21121 self.generate_expression(&offset.this)?;
21122 }
21123
21124 if let Some(distribute_by) = &subquery.distribute_by {
21126 self.write_space();
21127 self.write_keyword("DISTRIBUTE BY");
21128 self.write_space();
21129 for (i, expr) in distribute_by.expressions.iter().enumerate() {
21130 if i > 0 {
21131 self.write(", ");
21132 }
21133 self.generate_expression(expr)?;
21134 }
21135 }
21136
21137 if let Some(sort_by) = &subquery.sort_by {
21139 self.write_space();
21140 self.write_keyword("SORT BY");
21141 self.write_space();
21142 for (i, ord) in sort_by.expressions.iter().enumerate() {
21143 if i > 0 {
21144 self.write(", ");
21145 }
21146 self.generate_ordered(ord)?;
21147 }
21148 }
21149
21150 if let Some(cluster_by) = &subquery.cluster_by {
21152 self.write_space();
21153 self.write_keyword("CLUSTER BY");
21154 self.write_space();
21155 for (i, ord) in cluster_by.expressions.iter().enumerate() {
21156 if i > 0 {
21157 self.write(", ");
21158 }
21159 self.generate_ordered(ord)?;
21160 }
21161 }
21162 }
21163
21164 if let Some(alias) = &subquery.alias {
21165 self.write_space();
21166 let skip_as = matches!(
21168 self.config.dialect,
21169 Some(crate::dialects::DialectType::Oracle)
21170 );
21171 if !skip_as {
21172 self.write_keyword("AS");
21173 self.write_space();
21174 }
21175 self.generate_identifier(alias)?;
21176 if !subquery.column_aliases.is_empty() {
21177 self.write("(");
21178 for (i, col) in subquery.column_aliases.iter().enumerate() {
21179 if i > 0 {
21180 self.write(", ");
21181 }
21182 self.generate_identifier(col)?;
21183 }
21184 self.write(")");
21185 }
21186 }
21187 for comment in &subquery.trailing_comments {
21189 self.write(" ");
21190 self.write_formatted_comment(comment);
21191 }
21192 Ok(())
21193 }
21194
21195 fn generate_pivot(&mut self, pivot: &Pivot) -> Result<()> {
21196 if let Some(ref with) = pivot.with {
21198 self.generate_with(with)?;
21199 self.write_space();
21200 }
21201
21202 let direction = if pivot.unpivot { "UNPIVOT" } else { "PIVOT" };
21203
21204 let is_redshift_unpivot = pivot.unpivot
21208 && pivot.expressions.is_empty()
21209 && pivot.fields.is_empty()
21210 && pivot.using.is_empty()
21211 && pivot.into.is_none()
21212 && !matches!(&pivot.this, Expression::Null(_));
21213
21214 if is_redshift_unpivot {
21215 self.write_keyword("UNPIVOT");
21217 self.write_space();
21218 self.generate_expression(&pivot.this)?;
21219 if let Some(alias) = &pivot.alias {
21221 self.write_space();
21222 self.write_keyword("AS");
21223 self.write_space();
21224 self.write(&alias.name);
21226 }
21227 return Ok(());
21228 }
21229
21230 let is_simplified = !pivot.using.is_empty()
21232 || pivot.into.is_some()
21233 || (pivot.fields.is_empty()
21234 && !pivot.expressions.is_empty()
21235 && !matches!(&pivot.this, Expression::Null(_)));
21236
21237 if is_simplified {
21238 self.write_keyword(direction);
21242 self.write_space();
21243 self.generate_expression(&pivot.this)?;
21244
21245 if !pivot.expressions.is_empty() {
21246 self.write_space();
21247 self.write_keyword("ON");
21248 self.write_space();
21249 for (i, expr) in pivot.expressions.iter().enumerate() {
21250 if i > 0 {
21251 self.write(", ");
21252 }
21253 self.generate_expression(expr)?;
21254 }
21255 }
21256
21257 if let Some(into) = &pivot.into {
21259 self.write_space();
21260 self.write_keyword("INTO");
21261 self.write_space();
21262 self.generate_expression(into)?;
21263 }
21264
21265 if !pivot.using.is_empty() {
21267 self.write_space();
21268 self.write_keyword("USING");
21269 self.write_space();
21270 for (i, expr) in pivot.using.iter().enumerate() {
21271 if i > 0 {
21272 self.write(", ");
21273 }
21274 self.generate_expression(expr)?;
21275 }
21276 }
21277
21278 if let Some(group) = &pivot.group {
21280 self.write_space();
21281 self.generate_expression(group)?;
21282 }
21283 } else {
21284 if !matches!(&pivot.this, Expression::Null(_)) {
21289 self.generate_expression(&pivot.this)?;
21290 self.write_space();
21291 }
21292 self.write_keyword(direction);
21293 self.write("(");
21294
21295 for (i, expr) in pivot.expressions.iter().enumerate() {
21297 if i > 0 {
21298 self.write(", ");
21299 }
21300 self.generate_expression(expr)?;
21301 }
21302
21303 if !pivot.fields.is_empty() {
21305 if !pivot.expressions.is_empty() {
21306 self.write_space();
21307 }
21308 self.write_keyword("FOR");
21309 self.write_space();
21310 for (i, field) in pivot.fields.iter().enumerate() {
21311 if i > 0 {
21312 self.write_space();
21313 }
21314 self.generate_expression(field)?;
21316 }
21317 }
21318
21319 if let Some(default_val) = &pivot.default_on_null {
21321 self.write_space();
21322 self.write_keyword("DEFAULT ON NULL");
21323 self.write(" (");
21324 self.generate_expression(default_val)?;
21325 self.write(")");
21326 }
21327
21328 if let Some(group) = &pivot.group {
21330 self.write_space();
21331 self.generate_expression(group)?;
21332 }
21333
21334 self.write(")");
21335 }
21336
21337 if let Some(alias) = &pivot.alias {
21339 self.write_space();
21340 self.write_keyword("AS");
21341 self.write_space();
21342 self.generate_identifier(alias)?;
21343 }
21344
21345 Ok(())
21346 }
21347
21348 fn generate_unpivot(&mut self, unpivot: &Unpivot) -> Result<()> {
21349 self.generate_expression(&unpivot.this)?;
21350 self.write_space();
21351 self.write_keyword("UNPIVOT");
21352 if let Some(include) = unpivot.include_nulls {
21354 self.write_space();
21355 if include {
21356 self.write_keyword("INCLUDE NULLS");
21357 } else {
21358 self.write_keyword("EXCLUDE NULLS");
21359 }
21360 self.write_space();
21361 }
21362 self.write("(");
21363 if unpivot.value_column_parenthesized {
21364 self.write("(");
21365 }
21366 self.generate_identifier(&unpivot.value_column)?;
21367 for extra_col in &unpivot.extra_value_columns {
21369 self.write(", ");
21370 self.generate_identifier(extra_col)?;
21371 }
21372 if unpivot.value_column_parenthesized {
21373 self.write(")");
21374 }
21375 self.write_space();
21376 self.write_keyword("FOR");
21377 self.write_space();
21378 self.generate_identifier(&unpivot.name_column)?;
21379 self.write_space();
21380 self.write_keyword("IN");
21381 self.write(" (");
21382 for (i, col) in unpivot.columns.iter().enumerate() {
21383 if i > 0 {
21384 self.write(", ");
21385 }
21386 self.generate_expression(col)?;
21387 }
21388 self.write("))");
21389 if let Some(alias) = &unpivot.alias {
21390 self.write_space();
21391 self.write_keyword("AS");
21392 self.write_space();
21393 self.generate_identifier(alias)?;
21394 }
21395 Ok(())
21396 }
21397
21398 fn generate_values(&mut self, values: &Values) -> Result<()> {
21399 self.write_keyword("VALUES");
21400 for (i, row) in values.expressions.iter().enumerate() {
21401 if i > 0 {
21402 self.write(",");
21403 }
21404 self.write(" (");
21405 for (j, expr) in row.expressions.iter().enumerate() {
21406 if j > 0 {
21407 self.write(", ");
21408 }
21409 self.generate_expression(expr)?;
21410 }
21411 self.write(")");
21412 }
21413 if let Some(alias) = &values.alias {
21414 self.write_space();
21415 self.write_keyword("AS");
21416 self.write_space();
21417 self.generate_identifier(alias)?;
21418 if !values.column_aliases.is_empty() {
21419 self.write("(");
21420 for (i, col) in values.column_aliases.iter().enumerate() {
21421 if i > 0 {
21422 self.write(", ");
21423 }
21424 self.generate_identifier(col)?;
21425 }
21426 self.write(")");
21427 }
21428 }
21429 Ok(())
21430 }
21431
21432 fn generate_array(&mut self, arr: &Array) -> Result<()> {
21433 let needs_inheritance = matches!(
21435 self.config.dialect,
21436 Some(DialectType::DuckDB)
21437 | Some(DialectType::Spark)
21438 | Some(DialectType::Databricks)
21439 | Some(DialectType::Hive)
21440 | Some(DialectType::Snowflake)
21441 | Some(DialectType::Presto)
21442 | Some(DialectType::Trino)
21443 );
21444 let propagated: Vec<Expression>;
21445 let expressions = if needs_inheritance && arr.expressions.len() > 1 {
21446 propagated = Self::inherit_struct_field_names(&arr.expressions);
21447 &propagated
21448 } else {
21449 &arr.expressions
21450 };
21451
21452 let use_parens =
21455 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
21456 if !self.config.array_bracket_only {
21457 self.write_keyword("ARRAY");
21458 }
21459 if use_parens {
21460 self.write("(");
21461 } else {
21462 self.write("[");
21463 }
21464 for (i, expr) in expressions.iter().enumerate() {
21465 if i > 0 {
21466 self.write(", ");
21467 }
21468 self.generate_expression(expr)?;
21469 }
21470 if use_parens {
21471 self.write(")");
21472 } else {
21473 self.write("]");
21474 }
21475 Ok(())
21476 }
21477
21478 fn generate_tuple(&mut self, tuple: &Tuple) -> Result<()> {
21479 if tuple.expressions.len() == 2 {
21482 if let Expression::TableAlias(_) = &tuple.expressions[1] {
21483 self.generate_expression(&tuple.expressions[0])?;
21485 self.write_space();
21486 self.write_keyword("AS");
21487 self.write_space();
21488 self.generate_expression(&tuple.expressions[1])?;
21489 return Ok(());
21490 }
21491 }
21492
21493 let expand_tuple = if self.config.pretty && tuple.expressions.len() > 1 {
21496 let mut expr_strings: Vec<String> = Vec::with_capacity(tuple.expressions.len());
21497 for expr in &tuple.expressions {
21498 expr_strings.push(self.generate_to_string(expr)?);
21499 }
21500 self.too_wide(&expr_strings)
21501 } else {
21502 false
21503 };
21504
21505 if expand_tuple {
21506 self.write("(");
21507 self.write_newline();
21508 self.indent_level += 1;
21509 for (i, expr) in tuple.expressions.iter().enumerate() {
21510 if i > 0 {
21511 self.write(",");
21512 self.write_newline();
21513 }
21514 self.write_indent();
21515 self.generate_expression(expr)?;
21516 }
21517 self.indent_level -= 1;
21518 self.write_newline();
21519 self.write_indent();
21520 self.write(")");
21521 } else {
21522 self.write("(");
21523 for (i, expr) in tuple.expressions.iter().enumerate() {
21524 if i > 0 {
21525 self.write(", ");
21526 }
21527 self.generate_expression(expr)?;
21528 }
21529 self.write(")");
21530 }
21531 Ok(())
21532 }
21533
21534 fn generate_pipe_operator(&mut self, pipe: &PipeOperator) -> Result<()> {
21535 self.generate_expression(&pipe.this)?;
21536 self.write(" |> ");
21537 self.generate_expression(&pipe.expression)?;
21538 Ok(())
21539 }
21540
21541 fn generate_ordered(&mut self, ordered: &Ordered) -> Result<()> {
21542 self.generate_expression(&ordered.this)?;
21543 if ordered.desc {
21544 self.write_space();
21545 self.write_keyword("DESC");
21546 } else if ordered.explicit_asc {
21547 self.write_space();
21548 self.write_keyword("ASC");
21549 }
21550 if let Some(nulls_first) = ordered.nulls_first {
21551 let is_asc = !ordered.desc;
21565 let is_nulls_are_large = matches!(
21566 self.config.dialect,
21567 Some(DialectType::Oracle)
21568 | Some(DialectType::PostgreSQL)
21569 | Some(DialectType::Redshift)
21570 | Some(DialectType::Snowflake)
21571 );
21572 let is_nulls_are_last = matches!(
21573 self.config.dialect,
21574 Some(DialectType::Dremio)
21575 | Some(DialectType::DuckDB)
21576 | Some(DialectType::Presto)
21577 | Some(DialectType::Trino)
21578 | Some(DialectType::Athena)
21579 | Some(DialectType::ClickHouse)
21580 | Some(DialectType::Drill)
21581 | Some(DialectType::Exasol)
21582 );
21583
21584 let is_default_nulls = if is_nulls_are_large {
21586 (is_asc && !nulls_first) || (!is_asc && nulls_first)
21588 } else if is_nulls_are_last {
21589 !nulls_first
21591 } else {
21592 false
21593 };
21594
21595 if !is_default_nulls {
21596 self.write_space();
21597 self.write_keyword("NULLS");
21598 self.write_space();
21599 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
21600 }
21601 }
21602 if let Some(ref with_fill) = ordered.with_fill {
21604 self.write_space();
21605 self.generate_with_fill(with_fill)?;
21606 }
21607 Ok(())
21608 }
21609
21610 fn write_clickhouse_type(&mut self, type_str: &str) {
21612 if self.clickhouse_nullable_depth < 0 {
21613 self.write(type_str);
21615 } else {
21616 self.write(&format!("Nullable({})", type_str));
21617 }
21618 }
21619
21620 fn generate_data_type(&mut self, dt: &DataType) -> Result<()> {
21621 use crate::dialects::DialectType;
21622
21623 match dt {
21624 DataType::Boolean => {
21625 match self.config.dialect {
21627 Some(DialectType::TSQL) => self.write_keyword("BIT"),
21628 Some(DialectType::MySQL) => self.write_keyword("BOOLEAN"), Some(DialectType::Oracle) => {
21630 self.write_keyword("NUMBER(1)")
21632 }
21633 Some(DialectType::ClickHouse) => self.write("Bool"), _ => self.write_keyword("BOOLEAN"),
21635 }
21636 }
21637 DataType::TinyInt { length } => {
21638 match self.config.dialect {
21642 Some(DialectType::PostgreSQL)
21643 | Some(DialectType::Redshift)
21644 | Some(DialectType::Oracle)
21645 | Some(DialectType::Exasol) => {
21646 self.write_keyword("SMALLINT");
21647 }
21648 Some(DialectType::Teradata) => {
21649 self.write_keyword("BYTEINT");
21651 }
21652 Some(DialectType::Dremio) => {
21653 self.write_keyword("INT");
21655 }
21656 Some(DialectType::ClickHouse) => {
21657 self.write_clickhouse_type("Int8");
21658 }
21659 _ => {
21660 self.write_keyword("TINYINT");
21661 }
21662 }
21663 if let Some(n) = length {
21664 if !matches!(
21665 self.config.dialect,
21666 Some(DialectType::Dremio) | Some(DialectType::ClickHouse)
21667 ) {
21668 self.write(&format!("({})", n));
21669 }
21670 }
21671 }
21672 DataType::SmallInt { length } => {
21673 match self.config.dialect {
21675 Some(DialectType::Dremio) => {
21676 self.write_keyword("INT");
21677 }
21678 Some(DialectType::SQLite) | Some(DialectType::Drill) => {
21679 self.write_keyword("INTEGER");
21680 }
21681 Some(DialectType::BigQuery) => {
21682 self.write_keyword("INT64");
21683 }
21684 Some(DialectType::ClickHouse) => {
21685 self.write_clickhouse_type("Int16");
21686 }
21687 _ => {
21688 self.write_keyword("SMALLINT");
21689 if let Some(n) = length {
21690 self.write(&format!("({})", n));
21691 }
21692 }
21693 }
21694 }
21695 DataType::Int {
21696 length,
21697 integer_spelling,
21698 } => {
21699 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
21701 self.write_keyword("INT64");
21702 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
21703 self.write_clickhouse_type("Int32");
21704 } else {
21705 let use_integer = match self.config.dialect {
21707 Some(DialectType::TSQL)
21708 | Some(DialectType::Fabric)
21709 | Some(DialectType::Presto)
21710 | Some(DialectType::Trino)
21711 | Some(DialectType::SQLite)
21712 | Some(DialectType::Redshift) => true,
21713 Some(DialectType::Databricks) => *integer_spelling,
21715 _ => false,
21716 };
21717 if use_integer {
21718 self.write_keyword("INTEGER");
21719 } else {
21720 self.write_keyword("INT");
21721 }
21722 if let Some(n) = length {
21723 self.write(&format!("({})", n));
21724 }
21725 }
21726 }
21727 DataType::BigInt { length } => {
21728 match self.config.dialect {
21730 Some(DialectType::Oracle) => {
21731 self.write_keyword("INT");
21733 }
21734 Some(DialectType::ClickHouse) => {
21735 self.write_clickhouse_type("Int64");
21736 }
21737 _ => {
21738 self.write_keyword("BIGINT");
21739 if let Some(n) = length {
21740 self.write(&format!("({})", n));
21741 }
21742 }
21743 }
21744 }
21745 DataType::Float {
21746 precision,
21747 scale,
21748 real_spelling,
21749 } => {
21750 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
21754 self.write_clickhouse_type("Float32");
21755 } else if *real_spelling
21756 && !matches!(
21757 self.config.dialect,
21758 Some(DialectType::Spark)
21759 | Some(DialectType::Databricks)
21760 | Some(DialectType::Hive)
21761 | Some(DialectType::Snowflake)
21762 | Some(DialectType::MySQL)
21763 | Some(DialectType::BigQuery)
21764 )
21765 {
21766 self.write_keyword("REAL")
21767 } else {
21768 match self.config.dialect {
21769 Some(DialectType::PostgreSQL) => self.write_keyword("REAL"),
21770 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
21771 _ => self.write_keyword("FLOAT"),
21772 }
21773 }
21774 if !matches!(
21777 self.config.dialect,
21778 Some(DialectType::Spark)
21779 | Some(DialectType::Databricks)
21780 | Some(DialectType::Hive)
21781 | Some(DialectType::Presto)
21782 | Some(DialectType::Trino)
21783 ) {
21784 if let Some(p) = precision {
21785 self.write(&format!("({}", p));
21786 if let Some(s) = scale {
21787 self.write(&format!(", {})", s));
21788 } else {
21789 self.write(")");
21790 }
21791 }
21792 }
21793 }
21794 DataType::Double { precision, scale } => {
21795 match self.config.dialect {
21797 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
21798 self.write_keyword("FLOAT")
21799 } Some(DialectType::Oracle) => self.write_keyword("DOUBLE PRECISION"),
21801 Some(DialectType::ClickHouse) => self.write_clickhouse_type("Float64"),
21802 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
21803 Some(DialectType::SQLite) => self.write_keyword("REAL"),
21804 Some(DialectType::PostgreSQL)
21805 | Some(DialectType::Redshift)
21806 | Some(DialectType::Teradata)
21807 | Some(DialectType::Materialize) => self.write_keyword("DOUBLE PRECISION"),
21808 _ => self.write_keyword("DOUBLE"),
21809 }
21810 if let Some(p) = precision {
21812 self.write(&format!("({}", p));
21813 if let Some(s) = scale {
21814 self.write(&format!(", {})", s));
21815 } else {
21816 self.write(")");
21817 }
21818 }
21819 }
21820 DataType::Decimal { precision, scale } => {
21821 match self.config.dialect {
21823 Some(DialectType::ClickHouse) => {
21824 self.write("Decimal");
21825 if let Some(p) = precision {
21826 self.write(&format!("({}", p));
21827 if let Some(s) = scale {
21828 self.write(&format!(", {}", s));
21829 }
21830 self.write(")");
21831 }
21832 }
21833 Some(DialectType::Oracle) => {
21834 self.write_keyword("NUMBER");
21836 if let Some(p) = precision {
21837 self.write(&format!("({}", p));
21838 if let Some(s) = scale {
21839 self.write(&format!(", {}", s));
21840 }
21841 self.write(")");
21842 }
21843 }
21844 Some(DialectType::BigQuery) => {
21845 self.write_keyword("NUMERIC");
21847 if let Some(p) = precision {
21848 self.write(&format!("({}", p));
21849 if let Some(s) = scale {
21850 self.write(&format!(", {}", s));
21851 }
21852 self.write(")");
21853 }
21854 }
21855 _ => {
21856 self.write_keyword("DECIMAL");
21857 if let Some(p) = precision {
21858 self.write(&format!("({}", p));
21859 if let Some(s) = scale {
21860 self.write(&format!(", {}", s));
21861 }
21862 self.write(")");
21863 }
21864 }
21865 }
21866 }
21867 DataType::Char { length } => {
21868 match self.config.dialect {
21870 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
21871 self.write_keyword("TEXT");
21873 }
21874 Some(DialectType::Hive)
21875 | Some(DialectType::Spark)
21876 | Some(DialectType::Databricks) => {
21877 if length.is_some()
21880 && !matches!(self.config.dialect, Some(DialectType::Hive))
21881 {
21882 self.write_keyword("CHAR");
21883 if let Some(n) = length {
21884 self.write(&format!("({})", n));
21885 }
21886 } else {
21887 self.write_keyword("STRING");
21888 }
21889 }
21890 Some(DialectType::Dremio) => {
21891 self.write_keyword("VARCHAR");
21893 if let Some(n) = length {
21894 self.write(&format!("({})", n));
21895 }
21896 }
21897 _ => {
21898 self.write_keyword("CHAR");
21899 if let Some(n) = length {
21900 self.write(&format!("({})", n));
21901 }
21902 }
21903 }
21904 }
21905 DataType::VarChar {
21906 length,
21907 parenthesized_length,
21908 } => {
21909 match self.config.dialect {
21911 Some(DialectType::Oracle) => {
21912 self.write_keyword("VARCHAR2");
21913 if let Some(n) = length {
21914 self.write(&format!("({})", n));
21915 }
21916 }
21917 Some(DialectType::DuckDB) => {
21918 self.write_keyword("TEXT");
21920 if let Some(n) = length {
21921 self.write(&format!("({})", n));
21922 }
21923 }
21924 Some(DialectType::SQLite) => {
21925 self.write_keyword("TEXT");
21927 if let Some(n) = length {
21928 self.write(&format!("({})", n));
21929 }
21930 }
21931 Some(DialectType::MySQL) if length.is_none() => {
21932 self.write_keyword("TEXT");
21934 }
21935 Some(DialectType::Hive)
21936 | Some(DialectType::Spark)
21937 | Some(DialectType::Databricks)
21938 if length.is_none() =>
21939 {
21940 self.write_keyword("STRING");
21942 }
21943 _ => {
21944 self.write_keyword("VARCHAR");
21945 if let Some(n) = length {
21946 if *parenthesized_length {
21948 self.write(&format!("(({}))", n));
21949 } else {
21950 self.write(&format!("({})", n));
21951 }
21952 }
21953 }
21954 }
21955 }
21956 DataType::Text => {
21957 match self.config.dialect {
21959 Some(DialectType::Oracle) => self.write_keyword("CLOB"),
21960 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
21961 self.write_keyword("VARCHAR(MAX)")
21962 }
21963 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
21964 Some(DialectType::Snowflake)
21965 | Some(DialectType::Dremio)
21966 | Some(DialectType::Drill) => self.write_keyword("VARCHAR"),
21967 Some(DialectType::Exasol) => self.write_keyword("LONG VARCHAR"),
21968 Some(DialectType::Presto)
21969 | Some(DialectType::Trino)
21970 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
21971 Some(DialectType::Spark)
21972 | Some(DialectType::Databricks)
21973 | Some(DialectType::Hive) => self.write_keyword("STRING"),
21974 Some(DialectType::Redshift) => self.write_keyword("VARCHAR(MAX)"),
21975 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
21976 self.write_keyword("STRING")
21977 }
21978 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
21979 _ => self.write_keyword("TEXT"),
21980 }
21981 }
21982 DataType::TextWithLength { length } => {
21983 match self.config.dialect {
21985 Some(DialectType::Oracle) => self.write(&format!("CLOB({})", length)),
21986 Some(DialectType::Hive)
21987 | Some(DialectType::Spark)
21988 | Some(DialectType::Databricks) => {
21989 self.write(&format!("VARCHAR({})", length));
21990 }
21991 Some(DialectType::Redshift) => self.write(&format!("VARCHAR({})", length)),
21992 Some(DialectType::BigQuery) => self.write(&format!("STRING({})", length)),
21993 Some(DialectType::Snowflake)
21994 | Some(DialectType::Presto)
21995 | Some(DialectType::Trino)
21996 | Some(DialectType::Athena)
21997 | Some(DialectType::Drill)
21998 | Some(DialectType::Dremio) => {
21999 self.write(&format!("VARCHAR({})", length));
22000 }
22001 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
22002 self.write(&format!("VARCHAR({})", length))
22003 }
22004 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
22005 self.write(&format!("STRING({})", length))
22006 }
22007 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
22008 _ => self.write(&format!("TEXT({})", length)),
22009 }
22010 }
22011 DataType::String { length } => {
22012 match self.config.dialect {
22014 Some(DialectType::ClickHouse) => {
22015 self.write("String");
22017 if let Some(n) = length {
22018 self.write(&format!("({})", n));
22019 }
22020 }
22021 Some(DialectType::BigQuery)
22022 | Some(DialectType::Hive)
22023 | Some(DialectType::Spark)
22024 | Some(DialectType::Databricks)
22025 | Some(DialectType::StarRocks)
22026 | Some(DialectType::Doris) => {
22027 self.write_keyword("STRING");
22028 if let Some(n) = length {
22029 self.write(&format!("({})", n));
22030 }
22031 }
22032 Some(DialectType::PostgreSQL) => {
22033 if let Some(n) = length {
22035 self.write_keyword("VARCHAR");
22036 self.write(&format!("({})", n));
22037 } else {
22038 self.write_keyword("TEXT");
22039 }
22040 }
22041 Some(DialectType::Redshift) => {
22042 if let Some(n) = length {
22044 self.write_keyword("VARCHAR");
22045 self.write(&format!("({})", n));
22046 } else {
22047 self.write_keyword("VARCHAR(MAX)");
22048 }
22049 }
22050 Some(DialectType::MySQL) => {
22051 if let Some(n) = length {
22053 self.write_keyword("VARCHAR");
22054 self.write(&format!("({})", n));
22055 } else {
22056 self.write_keyword("TEXT");
22057 }
22058 }
22059 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
22060 if let Some(n) = length {
22062 self.write_keyword("VARCHAR");
22063 self.write(&format!("({})", n));
22064 } else {
22065 self.write_keyword("VARCHAR(MAX)");
22066 }
22067 }
22068 Some(DialectType::Oracle) => {
22069 self.write_keyword("CLOB");
22071 }
22072 Some(DialectType::DuckDB) | Some(DialectType::Materialize) => {
22073 self.write_keyword("TEXT");
22075 if let Some(n) = length {
22076 self.write(&format!("({})", n));
22077 }
22078 }
22079 Some(DialectType::Presto)
22080 | Some(DialectType::Trino)
22081 | Some(DialectType::Drill)
22082 | Some(DialectType::Dremio) => {
22083 self.write_keyword("VARCHAR");
22085 if let Some(n) = length {
22086 self.write(&format!("({})", n));
22087 }
22088 }
22089 Some(DialectType::Snowflake) => {
22090 self.write_keyword("STRING");
22093 if let Some(n) = length {
22094 self.write(&format!("({})", n));
22095 }
22096 }
22097 _ => {
22098 self.write_keyword("STRING");
22100 if let Some(n) = length {
22101 self.write(&format!("({})", n));
22102 }
22103 }
22104 }
22105 }
22106 DataType::Binary { length } => {
22107 match self.config.dialect {
22109 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
22110 self.write_keyword("BYTEA");
22111 if let Some(n) = length {
22112 self.write(&format!("({})", n));
22113 }
22114 }
22115 Some(DialectType::Redshift) => {
22116 self.write_keyword("VARBYTE");
22117 if let Some(n) = length {
22118 self.write(&format!("({})", n));
22119 }
22120 }
22121 Some(DialectType::DuckDB)
22122 | Some(DialectType::SQLite)
22123 | Some(DialectType::Oracle) => {
22124 self.write_keyword("BLOB");
22126 if let Some(n) = length {
22127 self.write(&format!("({})", n));
22128 }
22129 }
22130 Some(DialectType::Presto)
22131 | Some(DialectType::Trino)
22132 | Some(DialectType::Athena)
22133 | Some(DialectType::Drill)
22134 | Some(DialectType::Dremio) => {
22135 self.write_keyword("VARBINARY");
22137 if let Some(n) = length {
22138 self.write(&format!("({})", n));
22139 }
22140 }
22141 Some(DialectType::ClickHouse) => {
22142 if self.clickhouse_nullable_depth < 0 {
22144 self.write("BINARY");
22145 } else {
22146 self.write("Nullable(BINARY");
22147 }
22148 if let Some(n) = length {
22149 self.write(&format!("({})", n));
22150 }
22151 if self.clickhouse_nullable_depth >= 0 {
22152 self.write(")");
22153 }
22154 }
22155 _ => {
22156 self.write_keyword("BINARY");
22157 if let Some(n) = length {
22158 self.write(&format!("({})", n));
22159 }
22160 }
22161 }
22162 }
22163 DataType::VarBinary { length } => {
22164 match self.config.dialect {
22166 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
22167 self.write_keyword("BYTEA");
22168 if let Some(n) = length {
22169 self.write(&format!("({})", n));
22170 }
22171 }
22172 Some(DialectType::Redshift) => {
22173 self.write_keyword("VARBYTE");
22174 if let Some(n) = length {
22175 self.write(&format!("({})", n));
22176 }
22177 }
22178 Some(DialectType::DuckDB)
22179 | Some(DialectType::SQLite)
22180 | Some(DialectType::Oracle) => {
22181 self.write_keyword("BLOB");
22183 if let Some(n) = length {
22184 self.write(&format!("({})", n));
22185 }
22186 }
22187 Some(DialectType::Exasol) => {
22188 self.write_keyword("VARCHAR");
22190 }
22191 Some(DialectType::Spark)
22192 | Some(DialectType::Hive)
22193 | Some(DialectType::Databricks) => {
22194 self.write_keyword("BINARY");
22196 if let Some(n) = length {
22197 self.write(&format!("({})", n));
22198 }
22199 }
22200 Some(DialectType::ClickHouse) => {
22201 self.write_clickhouse_type("String");
22203 }
22204 _ => {
22205 self.write_keyword("VARBINARY");
22206 if let Some(n) = length {
22207 self.write(&format!("({})", n));
22208 }
22209 }
22210 }
22211 }
22212 DataType::Blob => {
22213 match self.config.dialect {
22215 Some(DialectType::PostgreSQL) => self.write_keyword("BYTEA"),
22216 Some(DialectType::Redshift) => self.write_keyword("VARBYTE"),
22217 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
22218 self.write_keyword("VARBINARY")
22219 }
22220 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
22221 Some(DialectType::Exasol) => self.write_keyword("VARCHAR"),
22222 Some(DialectType::Presto)
22223 | Some(DialectType::Trino)
22224 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
22225 Some(DialectType::DuckDB) => {
22226 self.write_keyword("VARBINARY");
22229 }
22230 Some(DialectType::Spark)
22231 | Some(DialectType::Databricks)
22232 | Some(DialectType::Hive) => self.write_keyword("BINARY"),
22233 Some(DialectType::ClickHouse) => {
22234 self.write("Nullable(String)");
22238 }
22239 _ => self.write_keyword("BLOB"),
22240 }
22241 }
22242 DataType::Bit { length } => {
22243 match self.config.dialect {
22245 Some(DialectType::Dremio)
22246 | Some(DialectType::Spark)
22247 | Some(DialectType::Databricks)
22248 | Some(DialectType::Hive)
22249 | Some(DialectType::Snowflake)
22250 | Some(DialectType::BigQuery)
22251 | Some(DialectType::Presto)
22252 | Some(DialectType::Trino)
22253 | Some(DialectType::ClickHouse)
22254 | Some(DialectType::Redshift) => {
22255 self.write_keyword("BOOLEAN");
22257 }
22258 _ => {
22259 self.write_keyword("BIT");
22260 if let Some(n) = length {
22261 self.write(&format!("({})", n));
22262 }
22263 }
22264 }
22265 }
22266 DataType::VarBit { length } => {
22267 self.write_keyword("VARBIT");
22268 if let Some(n) = length {
22269 self.write(&format!("({})", n));
22270 }
22271 }
22272 DataType::Date => self.write_keyword("DATE"),
22273 DataType::Time {
22274 precision,
22275 timezone,
22276 } => {
22277 if *timezone {
22278 match self.config.dialect {
22280 Some(DialectType::DuckDB) => {
22281 self.write_keyword("TIMETZ");
22283 }
22284 Some(DialectType::PostgreSQL) => {
22285 self.write_keyword("TIMETZ");
22287 if let Some(p) = precision {
22288 self.write(&format!("({})", p));
22289 }
22290 }
22291 _ => {
22292 self.write_keyword("TIME");
22294 if let Some(p) = precision {
22295 self.write(&format!("({})", p));
22296 }
22297 self.write_keyword(" WITH TIME ZONE");
22298 }
22299 }
22300 } else {
22301 if matches!(
22303 self.config.dialect,
22304 Some(DialectType::Spark)
22305 | Some(DialectType::Databricks)
22306 | Some(DialectType::Hive)
22307 ) {
22308 self.write_keyword("TIMESTAMP");
22309 } else {
22310 self.write_keyword("TIME");
22311 if let Some(p) = precision {
22312 self.write(&format!("({})", p));
22313 }
22314 }
22315 }
22316 }
22317 DataType::Timestamp {
22318 precision,
22319 timezone,
22320 } => {
22321 match self.config.dialect {
22323 Some(DialectType::ClickHouse) => {
22324 self.write("DateTime");
22325 if let Some(p) = precision {
22326 self.write(&format!("({})", p));
22327 }
22328 }
22329 Some(DialectType::TSQL) => {
22330 if *timezone {
22331 self.write_keyword("DATETIMEOFFSET");
22332 } else {
22333 self.write_keyword("DATETIME2");
22334 }
22335 if let Some(p) = precision {
22336 self.write(&format!("({})", p));
22337 }
22338 }
22339 Some(DialectType::MySQL) => {
22340 self.write_keyword("TIMESTAMP");
22342 if let Some(p) = precision {
22343 self.write(&format!("({})", p));
22344 }
22345 }
22346 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
22347 self.write_keyword("DATETIME");
22349 if let Some(p) = precision {
22350 self.write(&format!("({})", p));
22351 }
22352 }
22353 Some(DialectType::BigQuery) => {
22354 if *timezone {
22356 self.write_keyword("TIMESTAMP");
22357 } else {
22358 self.write_keyword("DATETIME");
22359 }
22360 }
22361 Some(DialectType::DuckDB) => {
22362 if *timezone {
22364 self.write_keyword("TIMESTAMPTZ");
22365 } else {
22366 self.write_keyword("TIMESTAMP");
22367 if let Some(p) = precision {
22368 self.write(&format!("({})", p));
22369 }
22370 }
22371 }
22372 _ => {
22373 if *timezone && !self.config.tz_to_with_time_zone {
22374 self.write_keyword("TIMESTAMPTZ");
22376 if let Some(p) = precision {
22377 self.write(&format!("({})", p));
22378 }
22379 } else {
22380 self.write_keyword("TIMESTAMP");
22381 if let Some(p) = precision {
22382 self.write(&format!("({})", p));
22383 }
22384 if *timezone {
22385 self.write_space();
22386 self.write_keyword("WITH TIME ZONE");
22387 }
22388 }
22389 }
22390 }
22391 }
22392 DataType::Interval { unit, to } => {
22393 self.write_keyword("INTERVAL");
22394 if let Some(u) = unit {
22395 self.write_space();
22396 self.write_keyword(u);
22397 }
22398 if let Some(t) = to {
22400 self.write_space();
22401 self.write_keyword("TO");
22402 self.write_space();
22403 self.write_keyword(t);
22404 }
22405 }
22406 DataType::Json => {
22407 match self.config.dialect {
22409 Some(DialectType::Oracle) => self.write_keyword("JSON"), Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"), Some(DialectType::MySQL) => self.write_keyword("JSON"),
22412 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
22413 _ => self.write_keyword("JSON"),
22414 }
22415 }
22416 DataType::JsonB => {
22417 match self.config.dialect {
22419 Some(DialectType::PostgreSQL) => self.write_keyword("JSONB"),
22420 Some(DialectType::Doris) => self.write_keyword("JSONB"),
22421 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
22422 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
22423 Some(DialectType::DuckDB) => self.write_keyword("JSON"), _ => self.write_keyword("JSON"), }
22426 }
22427 DataType::Uuid => {
22428 match self.config.dialect {
22430 Some(DialectType::TSQL) => self.write_keyword("UNIQUEIDENTIFIER"),
22431 Some(DialectType::MySQL) => self.write_keyword("CHAR(36)"),
22432 Some(DialectType::Oracle) => self.write_keyword("RAW(16)"),
22433 Some(DialectType::BigQuery)
22434 | Some(DialectType::Spark)
22435 | Some(DialectType::Databricks) => self.write_keyword("STRING"),
22436 _ => self.write_keyword("UUID"),
22437 }
22438 }
22439 DataType::Array {
22440 element_type,
22441 dimension,
22442 } => {
22443 match self.config.dialect {
22445 Some(DialectType::PostgreSQL)
22446 | Some(DialectType::Redshift)
22447 | Some(DialectType::DuckDB) => {
22448 self.generate_data_type(element_type)?;
22450 if let Some(dim) = dimension {
22451 self.write(&format!("[{}]", dim));
22452 } else {
22453 self.write("[]");
22454 }
22455 }
22456 Some(DialectType::BigQuery) => {
22457 self.write_keyword("ARRAY<");
22458 self.generate_data_type(element_type)?;
22459 self.write(">");
22460 }
22461 Some(DialectType::Snowflake)
22462 | Some(DialectType::Presto)
22463 | Some(DialectType::Trino)
22464 | Some(DialectType::ClickHouse) => {
22465 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
22467 self.write("Array(");
22468 } else {
22469 self.write_keyword("ARRAY(");
22470 }
22471 self.generate_data_type(element_type)?;
22472 self.write(")");
22473 }
22474 Some(DialectType::TSQL)
22475 | Some(DialectType::MySQL)
22476 | Some(DialectType::Oracle) => {
22477 match self.config.dialect {
22480 Some(DialectType::MySQL) => self.write_keyword("JSON"),
22481 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
22482 _ => self.write_keyword("JSON"),
22483 }
22484 }
22485 _ => {
22486 self.write_keyword("ARRAY<");
22488 self.generate_data_type(element_type)?;
22489 self.write(">");
22490 }
22491 }
22492 }
22493 DataType::List { element_type } => {
22494 self.generate_data_type(element_type)?;
22496 self.write_keyword(" LIST");
22497 }
22498 DataType::Map {
22499 key_type,
22500 value_type,
22501 } => {
22502 match self.config.dialect {
22504 Some(DialectType::Materialize) => {
22505 self.write_keyword("MAP[");
22507 self.generate_data_type(key_type)?;
22508 self.write(" => ");
22509 self.generate_data_type(value_type)?;
22510 self.write("]");
22511 }
22512 Some(DialectType::Snowflake)
22513 | Some(DialectType::RisingWave)
22514 | Some(DialectType::DuckDB)
22515 | Some(DialectType::Presto)
22516 | Some(DialectType::Trino)
22517 | Some(DialectType::Athena) => {
22518 self.write_keyword("MAP(");
22519 self.generate_data_type(key_type)?;
22520 self.write(", ");
22521 self.generate_data_type(value_type)?;
22522 self.write(")");
22523 }
22524 Some(DialectType::ClickHouse) => {
22525 self.write("Map(");
22528 self.clickhouse_nullable_depth = -1; self.generate_data_type(key_type)?;
22530 self.clickhouse_nullable_depth = 0;
22531 self.write(", ");
22532 self.generate_data_type(value_type)?;
22533 self.write(")");
22534 }
22535 _ => {
22536 self.write_keyword("MAP<");
22537 self.generate_data_type(key_type)?;
22538 self.write(", ");
22539 self.generate_data_type(value_type)?;
22540 self.write(">");
22541 }
22542 }
22543 }
22544 DataType::Vector {
22545 element_type,
22546 dimension,
22547 } => {
22548 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
22549 self.write_keyword("VECTOR(");
22551 if let Some(dim) = dimension {
22552 self.write(&dim.to_string());
22553 }
22554 let type_alias = element_type.as_ref().and_then(|et| match et.as_ref() {
22556 DataType::TinyInt { .. } => Some("I8"),
22557 DataType::SmallInt { .. } => Some("I16"),
22558 DataType::Int { .. } => Some("I32"),
22559 DataType::BigInt { .. } => Some("I64"),
22560 DataType::Float { .. } => Some("F32"),
22561 DataType::Double { .. } => Some("F64"),
22562 _ => None,
22563 });
22564 if let Some(alias) = type_alias {
22565 if dimension.is_some() {
22566 self.write(", ");
22567 }
22568 self.write(alias);
22569 }
22570 self.write(")");
22571 } else {
22572 self.write_keyword("VECTOR(");
22574 if let Some(ref et) = element_type {
22575 self.generate_data_type(et)?;
22576 if dimension.is_some() {
22577 self.write(", ");
22578 }
22579 }
22580 if let Some(dim) = dimension {
22581 self.write(&dim.to_string());
22582 }
22583 self.write(")");
22584 }
22585 }
22586 DataType::Object { fields, modifier } => {
22587 self.write_keyword("OBJECT(");
22588 for (i, (name, dt, not_null)) in fields.iter().enumerate() {
22589 if i > 0 {
22590 self.write(", ");
22591 }
22592 self.write(name);
22593 self.write(" ");
22594 self.generate_data_type(dt)?;
22595 if *not_null {
22596 self.write_keyword(" NOT NULL");
22597 }
22598 }
22599 self.write(")");
22600 if let Some(mod_str) = modifier {
22601 self.write(" ");
22602 self.write_keyword(mod_str);
22603 }
22604 }
22605 DataType::Struct { fields, nested } => {
22606 match self.config.dialect {
22608 Some(DialectType::Snowflake) => {
22609 self.write_keyword("OBJECT(");
22611 for (i, field) in fields.iter().enumerate() {
22612 if i > 0 {
22613 self.write(", ");
22614 }
22615 if !field.name.is_empty() {
22616 self.write(&field.name);
22617 self.write(" ");
22618 }
22619 self.generate_data_type(&field.data_type)?;
22620 }
22621 self.write(")");
22622 }
22623 Some(DialectType::Presto) | Some(DialectType::Trino) => {
22624 self.write_keyword("ROW(");
22626 for (i, field) in fields.iter().enumerate() {
22627 if i > 0 {
22628 self.write(", ");
22629 }
22630 if !field.name.is_empty() {
22631 self.write(&field.name);
22632 self.write(" ");
22633 }
22634 self.generate_data_type(&field.data_type)?;
22635 }
22636 self.write(")");
22637 }
22638 Some(DialectType::DuckDB) => {
22639 self.write_keyword("STRUCT(");
22641 for (i, field) in fields.iter().enumerate() {
22642 if i > 0 {
22643 self.write(", ");
22644 }
22645 if !field.name.is_empty() {
22646 self.write(&field.name);
22647 self.write(" ");
22648 }
22649 self.generate_data_type(&field.data_type)?;
22650 }
22651 self.write(")");
22652 }
22653 Some(DialectType::ClickHouse) => {
22654 self.write("Tuple(");
22656 for (i, field) in fields.iter().enumerate() {
22657 if i > 0 {
22658 self.write(", ");
22659 }
22660 if !field.name.is_empty() {
22661 self.write(&field.name);
22662 self.write(" ");
22663 }
22664 self.generate_data_type(&field.data_type)?;
22665 }
22666 self.write(")");
22667 }
22668 Some(DialectType::SingleStore) => {
22669 self.write_keyword("RECORD(");
22671 for (i, field) in fields.iter().enumerate() {
22672 if i > 0 {
22673 self.write(", ");
22674 }
22675 if !field.name.is_empty() {
22676 self.write(&field.name);
22677 self.write(" ");
22678 }
22679 self.generate_data_type(&field.data_type)?;
22680 }
22681 self.write(")");
22682 }
22683 _ => {
22684 let force_angle_brackets = matches!(
22686 self.config.dialect,
22687 Some(DialectType::Hive)
22688 | Some(DialectType::Spark)
22689 | Some(DialectType::Databricks)
22690 );
22691 if *nested && !force_angle_brackets {
22692 self.write_keyword("STRUCT(");
22693 for (i, field) in fields.iter().enumerate() {
22694 if i > 0 {
22695 self.write(", ");
22696 }
22697 if !field.name.is_empty() {
22698 self.write(&field.name);
22699 self.write(" ");
22700 }
22701 self.generate_data_type(&field.data_type)?;
22702 }
22703 self.write(")");
22704 } else {
22705 self.write_keyword("STRUCT<");
22706 for (i, field) in fields.iter().enumerate() {
22707 if i > 0 {
22708 self.write(", ");
22709 }
22710 if !field.name.is_empty() {
22711 self.write(&field.name);
22713 self.write(self.config.struct_field_sep);
22714 }
22715 self.generate_data_type(&field.data_type)?;
22717 if let Some(comment) = &field.comment {
22719 self.write(" COMMENT '");
22720 self.write(comment);
22721 self.write("'");
22722 }
22723 if !field.options.is_empty() {
22725 self.write(" ");
22726 self.generate_options_clause(&field.options)?;
22727 }
22728 }
22729 self.write(">");
22730 }
22731 }
22732 }
22733 }
22734 DataType::Enum {
22735 values,
22736 assignments,
22737 } => {
22738 if self.config.dialect == Some(DialectType::ClickHouse) {
22741 self.write("Enum(");
22742 } else {
22743 self.write_keyword("ENUM(");
22744 }
22745 for (i, val) in values.iter().enumerate() {
22746 if i > 0 {
22747 self.write(", ");
22748 }
22749 self.write("'");
22750 self.write(val);
22751 self.write("'");
22752 if let Some(Some(assignment)) = assignments.get(i) {
22753 self.write(" = ");
22754 self.write(assignment);
22755 }
22756 }
22757 self.write(")");
22758 }
22759 DataType::Set { values } => {
22760 self.write_keyword("SET(");
22762 for (i, val) in values.iter().enumerate() {
22763 if i > 0 {
22764 self.write(", ");
22765 }
22766 self.write("'");
22767 self.write(val);
22768 self.write("'");
22769 }
22770 self.write(")");
22771 }
22772 DataType::Union { fields } => {
22773 self.write_keyword("UNION(");
22775 for (i, (name, dt)) in fields.iter().enumerate() {
22776 if i > 0 {
22777 self.write(", ");
22778 }
22779 if !name.is_empty() {
22780 self.write(name);
22781 self.write(" ");
22782 }
22783 self.generate_data_type(dt)?;
22784 }
22785 self.write(")");
22786 }
22787 DataType::Nullable { inner } => {
22788 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
22790 self.write("Nullable(");
22791 let saved_depth = self.clickhouse_nullable_depth;
22793 self.clickhouse_nullable_depth = -1;
22794 self.generate_data_type(inner)?;
22795 self.clickhouse_nullable_depth = saved_depth;
22796 self.write(")");
22797 } else {
22798 match inner.as_ref() {
22800 DataType::Custom { name } if name.to_uppercase() == "DATETIME" => {
22801 self.generate_data_type(&DataType::Timestamp {
22802 precision: None,
22803 timezone: false,
22804 })?;
22805 }
22806 _ => {
22807 self.generate_data_type(inner)?;
22808 }
22809 }
22810 }
22811 }
22812 DataType::Custom { name } => {
22813 let name_upper = name.to_uppercase();
22815 match self.config.dialect {
22816 Some(DialectType::ClickHouse) => {
22817 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
22818 (name_upper[..idx].to_string(), &name[idx..])
22819 } else {
22820 (name_upper.clone(), "")
22821 };
22822 let mapped = match base_upper.as_str() {
22823 "DATETIME" | "TIMESTAMPTZ" | "TIMESTAMP" | "TIMESTAMPNTZ"
22824 | "SMALLDATETIME" | "DATETIME2" => "DateTime",
22825 "DATETIME64" => "DateTime64",
22826 "DATE32" => "Date32",
22827 "INT" => "Int32",
22828 "MEDIUMINT" => "Int32",
22829 "INT8" => "Int8",
22830 "INT16" => "Int16",
22831 "INT32" => "Int32",
22832 "INT64" => "Int64",
22833 "INT128" => "Int128",
22834 "INT256" => "Int256",
22835 "UINT8" => "UInt8",
22836 "UINT16" => "UInt16",
22837 "UINT32" => "UInt32",
22838 "UINT64" => "UInt64",
22839 "UINT128" => "UInt128",
22840 "UINT256" => "UInt256",
22841 "FLOAT32" => "Float32",
22842 "FLOAT64" => "Float64",
22843 "DECIMAL32" => "Decimal32",
22844 "DECIMAL64" => "Decimal64",
22845 "DECIMAL128" => "Decimal128",
22846 "DECIMAL256" => "Decimal256",
22847 "ENUM" => "Enum",
22848 "ENUM8" => "Enum8",
22849 "ENUM16" => "Enum16",
22850 "FIXEDSTRING" => "FixedString",
22851 "NESTED" => "Nested",
22852 "LOWCARDINALITY" => "LowCardinality",
22853 "NULLABLE" => "Nullable",
22854 "IPV4" => "IPv4",
22855 "IPV6" => "IPv6",
22856 "POINT" => "Point",
22857 "RING" => "Ring",
22858 "LINESTRING" => "LineString",
22859 "MULTILINESTRING" => "MultiLineString",
22860 "POLYGON" => "Polygon",
22861 "MULTIPOLYGON" => "MultiPolygon",
22862 "AGGREGATEFUNCTION" => "AggregateFunction",
22863 "SIMPLEAGGREGATEFUNCTION" => "SimpleAggregateFunction",
22864 "DYNAMIC" => "Dynamic",
22865 _ => "",
22866 };
22867 if mapped.is_empty() {
22868 self.write(name);
22869 } else {
22870 self.write(mapped);
22871 self.write(suffix);
22872 }
22873 }
22874 Some(DialectType::MySQL)
22875 if name_upper == "TIMESTAMPTZ" || name_upper == "TIMESTAMPLTZ" =>
22876 {
22877 self.write_keyword("TIMESTAMP");
22879 }
22880 Some(DialectType::TSQL) if name_upper == "VARIANT" => {
22881 self.write_keyword("SQL_VARIANT");
22882 }
22883 Some(DialectType::DuckDB) if name_upper == "DECFLOAT" => {
22884 self.write_keyword("DECIMAL(38, 5)");
22885 }
22886 Some(DialectType::Exasol) => {
22887 match name_upper.as_str() {
22889 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => self.write_keyword("VARCHAR"),
22891 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => self.write_keyword("VARCHAR"),
22893 "MEDIUMINT" => self.write_keyword("INT"),
22895 "DECIMAL32" | "DECIMAL64" | "DECIMAL128" | "DECIMAL256" => {
22897 self.write_keyword("DECIMAL")
22898 }
22899 "DATETIME" => self.write_keyword("TIMESTAMP"),
22901 "TIMESTAMPLTZ" => self.write_keyword("TIMESTAMP WITH LOCAL TIME ZONE"),
22902 _ => self.write(name),
22903 }
22904 }
22905 Some(DialectType::Dremio) => {
22906 match name_upper.as_str() {
22908 "TIMESTAMPNTZ" | "DATETIME" => self.write_keyword("TIMESTAMP"),
22909 "ARRAY" => self.write_keyword("LIST"),
22910 "NCHAR" => self.write_keyword("VARCHAR"),
22911 _ => self.write(name),
22912 }
22913 }
22914 _ => {
22916 let (base_upper, _args_str) = if let Some(idx) = name_upper.find('(') {
22918 (name_upper[..idx].to_string(), Some(&name[idx..]))
22919 } else {
22920 (name_upper.clone(), None)
22921 };
22922
22923 match base_upper.as_str() {
22924 "INT64"
22925 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
22926 {
22927 self.write_keyword("BIGINT");
22928 }
22929 "FLOAT64"
22930 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
22931 {
22932 self.write_keyword("DOUBLE");
22933 }
22934 "BOOL"
22935 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
22936 {
22937 self.write_keyword("BOOLEAN");
22938 }
22939 "BYTES"
22940 if matches!(
22941 self.config.dialect,
22942 Some(DialectType::Spark)
22943 | Some(DialectType::Hive)
22944 | Some(DialectType::Databricks)
22945 ) =>
22946 {
22947 self.write_keyword("BINARY");
22948 }
22949 "BYTES"
22950 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
22951 {
22952 self.write_keyword("VARBINARY");
22953 }
22954 "DATETIME2" | "SMALLDATETIME"
22956 if !matches!(
22957 self.config.dialect,
22958 Some(DialectType::TSQL) | Some(DialectType::Fabric)
22959 ) =>
22960 {
22961 if matches!(
22963 self.config.dialect,
22964 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
22965 ) {
22966 self.write_keyword("TIMESTAMP");
22967 if let Some(args) = _args_str {
22968 self.write(args);
22969 }
22970 } else {
22971 self.write_keyword("TIMESTAMP");
22972 }
22973 }
22974 "DATETIMEOFFSET"
22976 if !matches!(
22977 self.config.dialect,
22978 Some(DialectType::TSQL) | Some(DialectType::Fabric)
22979 ) =>
22980 {
22981 if matches!(
22982 self.config.dialect,
22983 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
22984 ) {
22985 self.write_keyword("TIMESTAMPTZ");
22986 if let Some(args) = _args_str {
22987 self.write(args);
22988 }
22989 } else {
22990 self.write_keyword("TIMESTAMPTZ");
22991 }
22992 }
22993 "UNIQUEIDENTIFIER"
22995 if !matches!(
22996 self.config.dialect,
22997 Some(DialectType::TSQL) | Some(DialectType::Fabric)
22998 ) =>
22999 {
23000 match self.config.dialect {
23001 Some(DialectType::Spark)
23002 | Some(DialectType::Databricks)
23003 | Some(DialectType::Hive) => self.write_keyword("STRING"),
23004 _ => self.write_keyword("UUID"),
23005 }
23006 }
23007 "BIT"
23009 if !matches!(
23010 self.config.dialect,
23011 Some(DialectType::TSQL)
23012 | Some(DialectType::Fabric)
23013 | Some(DialectType::PostgreSQL)
23014 | Some(DialectType::MySQL)
23015 | Some(DialectType::DuckDB)
23016 ) =>
23017 {
23018 self.write_keyword("BOOLEAN");
23019 }
23020 "NVARCHAR"
23022 if !matches!(
23023 self.config.dialect,
23024 Some(DialectType::TSQL) | Some(DialectType::Fabric)
23025 ) =>
23026 {
23027 match self.config.dialect {
23028 Some(DialectType::Oracle) => {
23029 self.write_keyword("NVARCHAR2");
23031 if let Some(args) = _args_str {
23032 self.write(args);
23033 }
23034 }
23035 Some(DialectType::BigQuery) => {
23036 self.write_keyword("STRING");
23038 }
23039 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
23040 self.write_keyword("TEXT");
23041 if let Some(args) = _args_str {
23042 self.write(args);
23043 }
23044 }
23045 Some(DialectType::Hive) => {
23046 self.write_keyword("STRING");
23048 }
23049 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
23050 if _args_str.is_some() {
23051 self.write_keyword("VARCHAR");
23052 self.write(_args_str.unwrap());
23053 } else {
23054 self.write_keyword("STRING");
23055 }
23056 }
23057 _ => {
23058 self.write_keyword("VARCHAR");
23059 if let Some(args) = _args_str {
23060 self.write(args);
23061 }
23062 }
23063 }
23064 }
23065 "NCHAR"
23067 if !matches!(
23068 self.config.dialect,
23069 Some(DialectType::TSQL) | Some(DialectType::Fabric)
23070 ) =>
23071 {
23072 match self.config.dialect {
23073 Some(DialectType::Oracle) => {
23074 self.write_keyword("NCHAR");
23076 if let Some(args) = _args_str {
23077 self.write(args);
23078 }
23079 }
23080 Some(DialectType::BigQuery) => {
23081 self.write_keyword("STRING");
23083 }
23084 Some(DialectType::Hive) => {
23085 self.write_keyword("STRING");
23087 }
23088 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
23089 self.write_keyword("TEXT");
23090 if let Some(args) = _args_str {
23091 self.write(args);
23092 }
23093 }
23094 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
23095 if _args_str.is_some() {
23096 self.write_keyword("CHAR");
23097 self.write(_args_str.unwrap());
23098 } else {
23099 self.write_keyword("STRING");
23100 }
23101 }
23102 _ => {
23103 self.write_keyword("CHAR");
23104 if let Some(args) = _args_str {
23105 self.write(args);
23106 }
23107 }
23108 }
23109 }
23110 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => match self.config.dialect {
23113 Some(DialectType::MySQL)
23114 | Some(DialectType::SingleStore)
23115 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
23116 Some(DialectType::Spark)
23117 | Some(DialectType::Databricks)
23118 | Some(DialectType::Hive) => self.write_keyword("TEXT"),
23119 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
23120 Some(DialectType::Presto)
23121 | Some(DialectType::Trino)
23122 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
23123 Some(DialectType::Snowflake)
23124 | Some(DialectType::Redshift)
23125 | Some(DialectType::Dremio) => self.write_keyword("VARCHAR"),
23126 _ => self.write_keyword("TEXT"),
23127 },
23128 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => match self.config.dialect {
23131 Some(DialectType::MySQL)
23132 | Some(DialectType::SingleStore)
23133 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
23134 Some(DialectType::Spark)
23135 | Some(DialectType::Databricks)
23136 | Some(DialectType::Hive) => self.write_keyword("BLOB"),
23137 Some(DialectType::DuckDB) => self.write_keyword("VARBINARY"),
23138 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
23139 Some(DialectType::Presto)
23140 | Some(DialectType::Trino)
23141 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
23142 Some(DialectType::Snowflake)
23143 | Some(DialectType::Redshift)
23144 | Some(DialectType::Dremio) => self.write_keyword("VARBINARY"),
23145 _ => self.write_keyword("BLOB"),
23146 },
23147 "LONGVARCHAR" => match self.config.dialect {
23149 Some(DialectType::SQLite) => self.write_keyword("TEXT"),
23150 _ => self.write_keyword("VARCHAR"),
23151 },
23152 "DATETIME" => {
23154 match self.config.dialect {
23155 Some(DialectType::MySQL)
23156 | Some(DialectType::Doris)
23157 | Some(DialectType::StarRocks)
23158 | Some(DialectType::TSQL)
23159 | Some(DialectType::Fabric)
23160 | Some(DialectType::BigQuery)
23161 | Some(DialectType::SQLite)
23162 | Some(DialectType::Snowflake) => {
23163 self.write_keyword("DATETIME");
23164 if let Some(args) = _args_str {
23165 self.write(args);
23166 }
23167 }
23168 Some(_) => {
23169 self.write_keyword("TIMESTAMP");
23171 if let Some(args) = _args_str {
23172 self.write(args);
23173 }
23174 }
23175 None => {
23176 self.write(name);
23178 }
23179 }
23180 }
23181 "VARCHAR2"
23183 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
23184 {
23185 match self.config.dialect {
23186 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
23187 self.write_keyword("TEXT");
23188 }
23189 Some(DialectType::Hive)
23190 | Some(DialectType::Spark)
23191 | Some(DialectType::Databricks)
23192 | Some(DialectType::BigQuery)
23193 | Some(DialectType::ClickHouse)
23194 | Some(DialectType::StarRocks)
23195 | Some(DialectType::Doris) => {
23196 self.write_keyword("STRING");
23197 }
23198 _ => {
23199 self.write_keyword("VARCHAR");
23200 if let Some(args) = _args_str {
23201 self.write(args);
23202 }
23203 }
23204 }
23205 }
23206 "NVARCHAR2"
23207 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
23208 {
23209 match self.config.dialect {
23210 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
23211 self.write_keyword("TEXT");
23212 }
23213 Some(DialectType::Hive)
23214 | Some(DialectType::Spark)
23215 | Some(DialectType::Databricks)
23216 | Some(DialectType::BigQuery)
23217 | Some(DialectType::ClickHouse)
23218 | Some(DialectType::StarRocks)
23219 | Some(DialectType::Doris) => {
23220 self.write_keyword("STRING");
23221 }
23222 _ => {
23223 self.write_keyword("VARCHAR");
23224 if let Some(args) = _args_str {
23225 self.write(args);
23226 }
23227 }
23228 }
23229 }
23230 _ => self.write(name),
23231 }
23232 }
23233 }
23234 }
23235 DataType::Geometry { subtype, srid } => {
23236 match self.config.dialect {
23238 Some(DialectType::MySQL) => {
23239 if let Some(sub) = subtype {
23241 self.write_keyword(sub);
23242 if let Some(s) = srid {
23243 self.write(" SRID ");
23244 self.write(&s.to_string());
23245 }
23246 } else {
23247 self.write_keyword("GEOMETRY");
23248 }
23249 }
23250 Some(DialectType::BigQuery) => {
23251 self.write_keyword("GEOGRAPHY");
23253 }
23254 Some(DialectType::Teradata) => {
23255 self.write_keyword("ST_GEOMETRY");
23257 if subtype.is_some() || srid.is_some() {
23258 self.write("(");
23259 if let Some(sub) = subtype {
23260 self.write_keyword(sub);
23261 }
23262 if let Some(s) = srid {
23263 if subtype.is_some() {
23264 self.write(", ");
23265 }
23266 self.write(&s.to_string());
23267 }
23268 self.write(")");
23269 }
23270 }
23271 _ => {
23272 self.write_keyword("GEOMETRY");
23274 if subtype.is_some() || srid.is_some() {
23275 self.write("(");
23276 if let Some(sub) = subtype {
23277 self.write_keyword(sub);
23278 }
23279 if let Some(s) = srid {
23280 if subtype.is_some() {
23281 self.write(", ");
23282 }
23283 self.write(&s.to_string());
23284 }
23285 self.write(")");
23286 }
23287 }
23288 }
23289 }
23290 DataType::Geography { subtype, srid } => {
23291 match self.config.dialect {
23293 Some(DialectType::MySQL) => {
23294 if let Some(sub) = subtype {
23296 self.write_keyword(sub);
23297 } else {
23298 self.write_keyword("GEOMETRY");
23299 }
23300 let effective_srid = srid.unwrap_or(4326);
23302 self.write(" SRID ");
23303 self.write(&effective_srid.to_string());
23304 }
23305 Some(DialectType::BigQuery) => {
23306 self.write_keyword("GEOGRAPHY");
23308 }
23309 Some(DialectType::Snowflake) => {
23310 self.write_keyword("GEOGRAPHY");
23312 }
23313 _ => {
23314 self.write_keyword("GEOGRAPHY");
23316 if subtype.is_some() || srid.is_some() {
23317 self.write("(");
23318 if let Some(sub) = subtype {
23319 self.write_keyword(sub);
23320 }
23321 if let Some(s) = srid {
23322 if subtype.is_some() {
23323 self.write(", ");
23324 }
23325 self.write(&s.to_string());
23326 }
23327 self.write(")");
23328 }
23329 }
23330 }
23331 }
23332 DataType::CharacterSet { name } => {
23333 self.write_keyword("CHAR CHARACTER SET ");
23335 self.write(name);
23336 }
23337 _ => self.write("UNKNOWN"),
23338 }
23339 Ok(())
23340 }
23341
23342 fn write(&mut self, s: &str) {
23345 self.output.push_str(s);
23346 }
23347
23348 fn write_space(&mut self) {
23349 self.output.push(' ');
23350 }
23351
23352 fn write_keyword(&mut self, keyword: &str) {
23353 if self.config.uppercase_keywords {
23354 self.output.push_str(keyword);
23355 } else {
23356 self.output.push_str(&keyword.to_lowercase());
23357 }
23358 }
23359
23360 fn write_func_name(&mut self, name: &str) {
23362 let normalized = self.normalize_func_name(name);
23363 self.output.push_str(&normalized);
23364 }
23365
23366 fn convert_strptime_to_exasol_format(format: &str) -> String {
23370 let mut result = String::new();
23371 let chars: Vec<char> = format.chars().collect();
23372 let mut i = 0;
23373 while i < chars.len() {
23374 if chars[i] == '%' && i + 1 < chars.len() {
23375 let spec = chars[i + 1];
23376 let exasol_spec = match spec {
23377 'Y' => "YYYY",
23378 'y' => "YY",
23379 'm' => "MM",
23380 'd' => "DD",
23381 'H' => "HH",
23382 'M' => "MI",
23383 'S' => "SS",
23384 'a' => "DY", 'A' => "DAY", 'b' => "MON", 'B' => "MONTH", 'I' => "H12", 'u' => "ID", 'V' => "IW", 'G' => "IYYY", 'W' => "UW", 'U' => "UW", 'z' => "Z", _ => {
23396 result.push('%');
23398 result.push(spec);
23399 i += 2;
23400 continue;
23401 }
23402 };
23403 result.push_str(exasol_spec);
23404 i += 2;
23405 } else {
23406 result.push(chars[i]);
23407 i += 1;
23408 }
23409 }
23410 result
23411 }
23412
23413 fn convert_strptime_to_postgres_format(format: &str) -> String {
23417 let mut result = String::new();
23418 let chars: Vec<char> = format.chars().collect();
23419 let mut i = 0;
23420 while i < chars.len() {
23421 if chars[i] == '%' && i + 1 < chars.len() {
23422 if chars[i + 1] == '-' && i + 2 < chars.len() {
23424 let spec = chars[i + 2];
23425 let pg_spec = match spec {
23426 'd' => "FMDD",
23427 'm' => "FMMM",
23428 'H' => "FMHH24",
23429 'M' => "FMMI",
23430 'S' => "FMSS",
23431 _ => {
23432 result.push('%');
23433 result.push('-');
23434 result.push(spec);
23435 i += 3;
23436 continue;
23437 }
23438 };
23439 result.push_str(pg_spec);
23440 i += 3;
23441 continue;
23442 }
23443 let spec = chars[i + 1];
23444 let pg_spec = match spec {
23445 'Y' => "YYYY",
23446 'y' => "YY",
23447 'm' => "MM",
23448 'd' => "DD",
23449 'H' => "HH24",
23450 'I' => "HH12",
23451 'M' => "MI",
23452 'S' => "SS",
23453 'f' => "US", 'u' => "D", 'j' => "DDD", 'z' => "OF", 'Z' => "TZ", 'A' => "TMDay", 'a' => "TMDy", 'b' => "TMMon", 'B' => "TMMonth", 'U' => "WW", _ => {
23464 result.push('%');
23466 result.push(spec);
23467 i += 2;
23468 continue;
23469 }
23470 };
23471 result.push_str(pg_spec);
23472 i += 2;
23473 } else {
23474 result.push(chars[i]);
23475 i += 1;
23476 }
23477 }
23478 result
23479 }
23480
23481 fn write_limit_expr(&mut self, expr: &Expression) -> Result<()> {
23483 if self.config.limit_only_literals {
23484 if let Some(value) = Self::try_evaluate_constant(expr) {
23485 self.write(&value.to_string());
23486 return Ok(());
23487 }
23488 }
23489 self.generate_expression(expr)
23490 }
23491
23492 fn write_formatted_comment(&mut self, comment: &str) {
23496 let content = if comment.starts_with("/*") && comment.ends_with("*/") {
23499 &comment[2..comment.len() - 2]
23502 } else if comment.starts_with("--") {
23503 &comment[2..]
23506 } else {
23507 comment
23509 };
23510 if content.trim().is_empty() {
23512 return;
23513 }
23514 self.output.push_str("/*");
23516 if !content.starts_with(' ') {
23517 self.output.push(' ');
23518 }
23519 self.output.push_str(content);
23520 if !content.ends_with(' ') {
23521 self.output.push(' ');
23522 }
23523 self.output.push_str("*/");
23524 }
23525
23526 fn escape_block_for_single_quote(&self, block: &str) -> String {
23529 let escape_backslash = matches!(
23530 self.config.dialect,
23531 Some(crate::dialects::DialectType::Snowflake)
23532 );
23533 let mut escaped = String::with_capacity(block.len() + 4);
23534 for ch in block.chars() {
23535 if ch == '\'' {
23536 escaped.push('\\');
23537 escaped.push('\'');
23538 } else if escape_backslash && ch == '\\' {
23539 escaped.push('\\');
23540 escaped.push('\\');
23541 } else {
23542 escaped.push(ch);
23543 }
23544 }
23545 escaped
23546 }
23547
23548 fn write_newline(&mut self) {
23549 self.output.push('\n');
23550 }
23551
23552 fn write_indent(&mut self) {
23553 for _ in 0..self.indent_level {
23554 self.output.push_str(&self.config.indent);
23555 }
23556 }
23557
23558 fn too_wide(&self, args: &[String]) -> bool {
23564 args.iter().map(|s| s.len()).sum::<usize>() > self.config.max_text_width
23565 }
23566
23567 fn generate_to_string(&self, expr: &Expression) -> Result<String> {
23570 let config = GeneratorConfig {
23571 pretty: false,
23572 dialect: self.config.dialect,
23573 ..Default::default()
23574 };
23575 let mut gen = Generator::with_config(config);
23576 gen.generate_expression(expr)?;
23577 Ok(gen.output)
23578 }
23579
23580 fn write_clause_condition(&mut self, keyword: &str, condition: &Expression) -> Result<()> {
23583 if self.config.pretty {
23584 self.write_newline();
23585 self.write_indent();
23586 self.write_keyword(keyword);
23587 self.write_newline();
23588 self.indent_level += 1;
23589 self.write_indent();
23590 self.generate_expression(condition)?;
23591 self.indent_level -= 1;
23592 } else {
23593 self.write_space();
23594 self.write_keyword(keyword);
23595 self.write_space();
23596 self.generate_expression(condition)?;
23597 }
23598 Ok(())
23599 }
23600
23601 fn write_clause_expressions(&mut self, keyword: &str, exprs: &[Expression]) -> Result<()> {
23604 if exprs.is_empty() {
23605 return Ok(());
23606 }
23607
23608 if self.config.pretty {
23609 self.write_newline();
23610 self.write_indent();
23611 self.write_keyword(keyword);
23612 self.write_newline();
23613 self.indent_level += 1;
23614 for (i, expr) in exprs.iter().enumerate() {
23615 if i > 0 {
23616 self.write(",");
23617 self.write_newline();
23618 }
23619 self.write_indent();
23620 self.generate_expression(expr)?;
23621 }
23622 self.indent_level -= 1;
23623 } else {
23624 self.write_space();
23625 self.write_keyword(keyword);
23626 self.write_space();
23627 for (i, expr) in exprs.iter().enumerate() {
23628 if i > 0 {
23629 self.write(", ");
23630 }
23631 self.generate_expression(expr)?;
23632 }
23633 }
23634 Ok(())
23635 }
23636
23637 fn write_order_clause(&mut self, keyword: &str, orderings: &[Ordered]) -> Result<()> {
23639 if orderings.is_empty() {
23640 return Ok(());
23641 }
23642
23643 if self.config.pretty {
23644 self.write_newline();
23645 self.write_indent();
23646 self.write_keyword(keyword);
23647 self.write_newline();
23648 self.indent_level += 1;
23649 for (i, ordered) in orderings.iter().enumerate() {
23650 if i > 0 {
23651 self.write(",");
23652 self.write_newline();
23653 }
23654 self.write_indent();
23655 self.generate_ordered(ordered)?;
23656 }
23657 self.indent_level -= 1;
23658 } else {
23659 self.write_space();
23660 self.write_keyword(keyword);
23661 self.write_space();
23662 for (i, ordered) in orderings.iter().enumerate() {
23663 if i > 0 {
23664 self.write(", ");
23665 }
23666 self.generate_ordered(ordered)?;
23667 }
23668 }
23669 Ok(())
23670 }
23671
23672 fn write_window_clause(&mut self, windows: &[NamedWindow]) -> Result<()> {
23674 if windows.is_empty() {
23675 return Ok(());
23676 }
23677
23678 if self.config.pretty {
23679 self.write_newline();
23680 self.write_indent();
23681 self.write_keyword("WINDOW");
23682 self.write_newline();
23683 self.indent_level += 1;
23684 for (i, named_window) in windows.iter().enumerate() {
23685 if i > 0 {
23686 self.write(",");
23687 self.write_newline();
23688 }
23689 self.write_indent();
23690 self.generate_identifier(&named_window.name)?;
23691 self.write_space();
23692 self.write_keyword("AS");
23693 self.write(" (");
23694 self.generate_over(&named_window.spec)?;
23695 self.write(")");
23696 }
23697 self.indent_level -= 1;
23698 } else {
23699 self.write_space();
23700 self.write_keyword("WINDOW");
23701 self.write_space();
23702 for (i, named_window) in windows.iter().enumerate() {
23703 if i > 0 {
23704 self.write(", ");
23705 }
23706 self.generate_identifier(&named_window.name)?;
23707 self.write_space();
23708 self.write_keyword("AS");
23709 self.write(" (");
23710 self.generate_over(&named_window.spec)?;
23711 self.write(")");
23712 }
23713 }
23714 Ok(())
23715 }
23716
23717 fn generate_ai_agg(&mut self, e: &AIAgg) -> Result<()> {
23719 self.write_keyword("AI_AGG");
23721 self.write("(");
23722 self.generate_expression(&e.this)?;
23723 self.write(", ");
23724 self.generate_expression(&e.expression)?;
23725 self.write(")");
23726 Ok(())
23727 }
23728
23729 fn generate_ai_classify(&mut self, e: &AIClassify) -> Result<()> {
23730 self.write_keyword("AI_CLASSIFY");
23732 self.write("(");
23733 self.generate_expression(&e.this)?;
23734 if let Some(categories) = &e.categories {
23735 self.write(", ");
23736 self.generate_expression(categories)?;
23737 }
23738 if let Some(config) = &e.config {
23739 self.write(", ");
23740 self.generate_expression(config)?;
23741 }
23742 self.write(")");
23743 Ok(())
23744 }
23745
23746 fn generate_add_partition(&mut self, e: &AddPartition) -> Result<()> {
23747 self.write_keyword("ADD");
23749 self.write_space();
23750 if e.exists {
23751 self.write_keyword("IF NOT EXISTS");
23752 self.write_space();
23753 }
23754 self.generate_expression(&e.this)?;
23755 if let Some(location) = &e.location {
23756 self.write_space();
23757 self.generate_expression(location)?;
23758 }
23759 Ok(())
23760 }
23761
23762 fn generate_algorithm_property(&mut self, e: &AlgorithmProperty) -> Result<()> {
23763 self.write_keyword("ALGORITHM");
23765 self.write("=");
23766 self.generate_expression(&e.this)?;
23767 Ok(())
23768 }
23769
23770 fn generate_aliases(&mut self, e: &Aliases) -> Result<()> {
23771 self.generate_expression(&e.this)?;
23773 self.write_space();
23774 self.write_keyword("AS");
23775 self.write(" (");
23776 for (i, expr) in e.expressions.iter().enumerate() {
23777 if i > 0 {
23778 self.write(", ");
23779 }
23780 self.generate_expression(expr)?;
23781 }
23782 self.write(")");
23783 Ok(())
23784 }
23785
23786 fn generate_allowed_values_property(&mut self, e: &AllowedValuesProperty) -> Result<()> {
23787 self.write_keyword("ALLOWED_VALUES");
23789 self.write_space();
23790 for (i, expr) in e.expressions.iter().enumerate() {
23791 if i > 0 {
23792 self.write(", ");
23793 }
23794 self.generate_expression(expr)?;
23795 }
23796 Ok(())
23797 }
23798
23799 fn generate_alter_column(&mut self, e: &AlterColumn) -> Result<()> {
23800 self.write_keyword("ALTER COLUMN");
23802 self.write_space();
23803 self.generate_expression(&e.this)?;
23804
23805 if let Some(dtype) = &e.dtype {
23806 self.write_space();
23807 self.write_keyword("SET DATA TYPE");
23808 self.write_space();
23809 self.generate_expression(dtype)?;
23810 if let Some(collate) = &e.collate {
23811 self.write_space();
23812 self.write_keyword("COLLATE");
23813 self.write_space();
23814 self.generate_expression(collate)?;
23815 }
23816 if let Some(using) = &e.using {
23817 self.write_space();
23818 self.write_keyword("USING");
23819 self.write_space();
23820 self.generate_expression(using)?;
23821 }
23822 } else if let Some(default) = &e.default {
23823 self.write_space();
23824 self.write_keyword("SET DEFAULT");
23825 self.write_space();
23826 self.generate_expression(default)?;
23827 } else if let Some(comment) = &e.comment {
23828 self.write_space();
23829 self.write_keyword("COMMENT");
23830 self.write_space();
23831 self.generate_expression(comment)?;
23832 } else if let Some(drop) = &e.drop {
23833 self.write_space();
23834 self.write_keyword("DROP");
23835 self.write_space();
23836 self.generate_expression(drop)?;
23837 } else if let Some(visible) = &e.visible {
23838 self.write_space();
23839 self.generate_expression(visible)?;
23840 } else if let Some(rename_to) = &e.rename_to {
23841 self.write_space();
23842 self.write_keyword("RENAME TO");
23843 self.write_space();
23844 self.generate_expression(rename_to)?;
23845 } else if let Some(allow_null) = &e.allow_null {
23846 self.write_space();
23847 self.generate_expression(allow_null)?;
23848 }
23849 Ok(())
23850 }
23851
23852 fn generate_alter_session(&mut self, e: &AlterSession) -> Result<()> {
23853 self.write_keyword("ALTER SESSION");
23855 self.write_space();
23856 if e.unset.is_some() {
23857 self.write_keyword("UNSET");
23858 } else {
23859 self.write_keyword("SET");
23860 }
23861 self.write_space();
23862 for (i, expr) in e.expressions.iter().enumerate() {
23863 if i > 0 {
23864 self.write(", ");
23865 }
23866 self.generate_expression(expr)?;
23867 }
23868 Ok(())
23869 }
23870
23871 fn generate_alter_set(&mut self, e: &AlterSet) -> Result<()> {
23872 self.write_keyword("SET");
23874
23875 if let Some(opt) = &e.option {
23877 self.write_space();
23878 self.generate_expression(opt)?;
23879 }
23880
23881 if !e.expressions.is_empty() {
23884 let is_properties = e
23886 .expressions
23887 .iter()
23888 .any(|expr| matches!(expr, Expression::Eq(_)));
23889 if is_properties && e.option.is_none() {
23890 self.write_space();
23891 self.write_keyword("PROPERTIES");
23892 }
23893 self.write_space();
23894 for (i, expr) in e.expressions.iter().enumerate() {
23895 if i > 0 {
23896 self.write(", ");
23897 }
23898 self.generate_expression(expr)?;
23899 }
23900 }
23901
23902 if let Some(file_format) = &e.file_format {
23904 self.write(" ");
23905 self.write_keyword("STAGE_FILE_FORMAT");
23906 self.write(" = (");
23907 self.generate_space_separated_properties(file_format)?;
23908 self.write(")");
23909 }
23910
23911 if let Some(copy_options) = &e.copy_options {
23913 self.write(" ");
23914 self.write_keyword("STAGE_COPY_OPTIONS");
23915 self.write(" = (");
23916 self.generate_space_separated_properties(copy_options)?;
23917 self.write(")");
23918 }
23919
23920 if let Some(tag) = &e.tag {
23922 self.write(" ");
23923 self.write_keyword("TAG");
23924 self.write(" ");
23925 self.generate_expression(tag)?;
23926 }
23927
23928 Ok(())
23929 }
23930
23931 fn generate_space_separated_properties(&mut self, expr: &Expression) -> Result<()> {
23933 match expr {
23934 Expression::Tuple(t) => {
23935 for (i, prop) in t.expressions.iter().enumerate() {
23936 if i > 0 {
23937 self.write(" ");
23938 }
23939 self.generate_expression(prop)?;
23940 }
23941 }
23942 _ => {
23943 self.generate_expression(expr)?;
23944 }
23945 }
23946 Ok(())
23947 }
23948
23949 fn generate_alter_sort_key(&mut self, e: &AlterSortKey) -> Result<()> {
23950 self.write_keyword("ALTER");
23952 if e.compound.is_some() {
23953 self.write_space();
23954 self.write_keyword("COMPOUND");
23955 }
23956 self.write_space();
23957 self.write_keyword("SORTKEY");
23958 self.write_space();
23959 if let Some(this) = &e.this {
23960 self.generate_expression(this)?;
23961 } else if !e.expressions.is_empty() {
23962 self.write("(");
23963 for (i, expr) in e.expressions.iter().enumerate() {
23964 if i > 0 {
23965 self.write(", ");
23966 }
23967 self.generate_expression(expr)?;
23968 }
23969 self.write(")");
23970 }
23971 Ok(())
23972 }
23973
23974 fn generate_analyze(&mut self, e: &Analyze) -> Result<()> {
23975 self.write_keyword("ANALYZE");
23977 if !e.options.is_empty() {
23978 self.write_space();
23979 for (i, opt) in e.options.iter().enumerate() {
23980 if i > 0 {
23981 self.write_space();
23982 }
23983 if let Expression::Identifier(id) = opt {
23985 self.write_keyword(&id.name);
23986 } else {
23987 self.generate_expression(opt)?;
23988 }
23989 }
23990 }
23991 if let Some(kind) = &e.kind {
23992 self.write_space();
23993 self.write_keyword(kind);
23994 }
23995 if let Some(this) = &e.this {
23996 self.write_space();
23997 self.generate_expression(this)?;
23998 }
23999 if !e.columns.is_empty() {
24001 self.write("(");
24002 for (i, col) in e.columns.iter().enumerate() {
24003 if i > 0 {
24004 self.write(", ");
24005 }
24006 self.write(col);
24007 }
24008 self.write(")");
24009 }
24010 if let Some(partition) = &e.partition {
24011 self.write_space();
24012 self.generate_expression(partition)?;
24013 }
24014 if let Some(mode) = &e.mode {
24015 self.write_space();
24016 self.generate_expression(mode)?;
24017 }
24018 if let Some(expression) = &e.expression {
24019 self.write_space();
24020 self.generate_expression(expression)?;
24021 }
24022 if !e.properties.is_empty() {
24023 self.write_space();
24024 self.write_keyword(self.config.with_properties_prefix);
24025 self.write(" (");
24026 for (i, prop) in e.properties.iter().enumerate() {
24027 if i > 0 {
24028 self.write(", ");
24029 }
24030 self.generate_expression(prop)?;
24031 }
24032 self.write(")");
24033 }
24034 Ok(())
24035 }
24036
24037 fn generate_analyze_delete(&mut self, e: &AnalyzeDelete) -> Result<()> {
24038 self.write_keyword("DELETE");
24040 if let Some(kind) = &e.kind {
24041 self.write_space();
24042 self.write_keyword(kind);
24043 }
24044 self.write_space();
24045 self.write_keyword("STATISTICS");
24046 Ok(())
24047 }
24048
24049 fn generate_analyze_histogram(&mut self, e: &AnalyzeHistogram) -> Result<()> {
24050 if let Expression::Identifier(id) = e.this.as_ref() {
24053 self.write_keyword(&id.name);
24054 } else {
24055 self.generate_expression(&e.this)?;
24056 }
24057 self.write_space();
24058 self.write_keyword("HISTOGRAM ON");
24059 self.write_space();
24060 for (i, expr) in e.expressions.iter().enumerate() {
24061 if i > 0 {
24062 self.write(", ");
24063 }
24064 self.generate_expression(expr)?;
24065 }
24066 if let Some(expression) = &e.expression {
24067 self.write_space();
24068 self.generate_expression(expression)?;
24069 }
24070 if let Some(update_options) = &e.update_options {
24071 self.write_space();
24072 self.generate_expression(update_options)?;
24073 self.write_space();
24074 self.write_keyword("UPDATE");
24075 }
24076 Ok(())
24077 }
24078
24079 fn generate_analyze_list_chained_rows(&mut self, e: &AnalyzeListChainedRows) -> Result<()> {
24080 self.write_keyword("LIST CHAINED ROWS");
24082 if let Some(expression) = &e.expression {
24083 self.write_space();
24084 self.write_keyword("INTO");
24085 self.write_space();
24086 self.generate_expression(expression)?;
24087 }
24088 Ok(())
24089 }
24090
24091 fn generate_analyze_sample(&mut self, e: &AnalyzeSample) -> Result<()> {
24092 self.write_keyword("SAMPLE");
24094 self.write_space();
24095 if let Some(sample) = &e.sample {
24096 self.generate_expression(sample)?;
24097 self.write_space();
24098 }
24099 self.write_keyword(&e.kind);
24100 Ok(())
24101 }
24102
24103 fn generate_analyze_statistics(&mut self, e: &AnalyzeStatistics) -> Result<()> {
24104 self.write_keyword(&e.kind);
24106 if let Some(option) = &e.option {
24107 self.write_space();
24108 self.generate_expression(option)?;
24109 }
24110 self.write_space();
24111 self.write_keyword("STATISTICS");
24112 if let Some(this) = &e.this {
24113 self.write_space();
24114 self.generate_expression(this)?;
24115 }
24116 if !e.expressions.is_empty() {
24117 self.write_space();
24118 for (i, expr) in e.expressions.iter().enumerate() {
24119 if i > 0 {
24120 self.write(", ");
24121 }
24122 self.generate_expression(expr)?;
24123 }
24124 }
24125 Ok(())
24126 }
24127
24128 fn generate_analyze_validate(&mut self, e: &AnalyzeValidate) -> Result<()> {
24129 self.write_keyword("VALIDATE");
24131 self.write_space();
24132 self.write_keyword(&e.kind);
24133 if let Some(this) = &e.this {
24134 self.write_space();
24135 if let Expression::Identifier(id) = this.as_ref() {
24137 self.write_keyword(&id.name);
24138 } else {
24139 self.generate_expression(this)?;
24140 }
24141 }
24142 if let Some(expression) = &e.expression {
24143 self.write_space();
24144 self.write_keyword("INTO");
24145 self.write_space();
24146 self.generate_expression(expression)?;
24147 }
24148 Ok(())
24149 }
24150
24151 fn generate_analyze_with(&mut self, e: &AnalyzeWith) -> Result<()> {
24152 self.write_keyword("WITH");
24154 self.write_space();
24155 for (i, expr) in e.expressions.iter().enumerate() {
24156 if i > 0 {
24157 self.write(", ");
24158 }
24159 self.generate_expression(expr)?;
24160 }
24161 Ok(())
24162 }
24163
24164 fn generate_anonymous(&mut self, e: &Anonymous) -> Result<()> {
24165 self.generate_expression(&e.this)?;
24168 self.write("(");
24169 for (i, arg) in e.expressions.iter().enumerate() {
24170 if i > 0 {
24171 self.write(", ");
24172 }
24173 self.generate_expression(arg)?;
24174 }
24175 self.write(")");
24176 Ok(())
24177 }
24178
24179 fn generate_anonymous_agg_func(&mut self, e: &AnonymousAggFunc) -> Result<()> {
24180 self.generate_expression(&e.this)?;
24182 self.write("(");
24183 for (i, arg) in e.expressions.iter().enumerate() {
24184 if i > 0 {
24185 self.write(", ");
24186 }
24187 self.generate_expression(arg)?;
24188 }
24189 self.write(")");
24190 Ok(())
24191 }
24192
24193 fn generate_apply(&mut self, e: &Apply) -> Result<()> {
24194 self.generate_expression(&e.this)?;
24196 self.write_space();
24197 self.write_keyword("APPLY");
24198 self.write("(");
24199 self.generate_expression(&e.expression)?;
24200 self.write(")");
24201 Ok(())
24202 }
24203
24204 fn generate_approx_percentile_estimate(&mut self, e: &ApproxPercentileEstimate) -> Result<()> {
24205 self.write_keyword("APPROX_PERCENTILE_ESTIMATE");
24207 self.write("(");
24208 self.generate_expression(&e.this)?;
24209 if let Some(percentile) = &e.percentile {
24210 self.write(", ");
24211 self.generate_expression(percentile)?;
24212 }
24213 self.write(")");
24214 Ok(())
24215 }
24216
24217 fn generate_approx_quantile(&mut self, e: &ApproxQuantile) -> Result<()> {
24218 self.write_keyword("APPROX_QUANTILE");
24220 self.write("(");
24221 self.generate_expression(&e.this)?;
24222 if let Some(quantile) = &e.quantile {
24223 self.write(", ");
24224 self.generate_expression(quantile)?;
24225 }
24226 if let Some(accuracy) = &e.accuracy {
24227 self.write(", ");
24228 self.generate_expression(accuracy)?;
24229 }
24230 if let Some(weight) = &e.weight {
24231 self.write(", ");
24232 self.generate_expression(weight)?;
24233 }
24234 self.write(")");
24235 Ok(())
24236 }
24237
24238 fn generate_approx_quantiles(&mut self, e: &ApproxQuantiles) -> Result<()> {
24239 self.write_keyword("APPROX_QUANTILES");
24241 self.write("(");
24242 self.generate_expression(&e.this)?;
24243 if let Some(expression) = &e.expression {
24244 self.write(", ");
24245 self.generate_expression(expression)?;
24246 }
24247 self.write(")");
24248 Ok(())
24249 }
24250
24251 fn generate_approx_top_k(&mut self, e: &ApproxTopK) -> Result<()> {
24252 self.write_keyword("APPROX_TOP_K");
24254 self.write("(");
24255 self.generate_expression(&e.this)?;
24256 if let Some(expression) = &e.expression {
24257 self.write(", ");
24258 self.generate_expression(expression)?;
24259 }
24260 if let Some(counters) = &e.counters {
24261 self.write(", ");
24262 self.generate_expression(counters)?;
24263 }
24264 self.write(")");
24265 Ok(())
24266 }
24267
24268 fn generate_approx_top_k_accumulate(&mut self, e: &ApproxTopKAccumulate) -> Result<()> {
24269 self.write_keyword("APPROX_TOP_K_ACCUMULATE");
24271 self.write("(");
24272 self.generate_expression(&e.this)?;
24273 if let Some(expression) = &e.expression {
24274 self.write(", ");
24275 self.generate_expression(expression)?;
24276 }
24277 self.write(")");
24278 Ok(())
24279 }
24280
24281 fn generate_approx_top_k_combine(&mut self, e: &ApproxTopKCombine) -> Result<()> {
24282 self.write_keyword("APPROX_TOP_K_COMBINE");
24284 self.write("(");
24285 self.generate_expression(&e.this)?;
24286 if let Some(expression) = &e.expression {
24287 self.write(", ");
24288 self.generate_expression(expression)?;
24289 }
24290 self.write(")");
24291 Ok(())
24292 }
24293
24294 fn generate_approx_top_k_estimate(&mut self, e: &ApproxTopKEstimate) -> Result<()> {
24295 self.write_keyword("APPROX_TOP_K_ESTIMATE");
24297 self.write("(");
24298 self.generate_expression(&e.this)?;
24299 if let Some(expression) = &e.expression {
24300 self.write(", ");
24301 self.generate_expression(expression)?;
24302 }
24303 self.write(")");
24304 Ok(())
24305 }
24306
24307 fn generate_approx_top_sum(&mut self, e: &ApproxTopSum) -> Result<()> {
24308 self.write_keyword("APPROX_TOP_SUM");
24310 self.write("(");
24311 self.generate_expression(&e.this)?;
24312 self.write(", ");
24313 self.generate_expression(&e.expression)?;
24314 if let Some(count) = &e.count {
24315 self.write(", ");
24316 self.generate_expression(count)?;
24317 }
24318 self.write(")");
24319 Ok(())
24320 }
24321
24322 fn generate_arg_max(&mut self, e: &ArgMax) -> Result<()> {
24323 self.write_keyword("ARG_MAX");
24325 self.write("(");
24326 self.generate_expression(&e.this)?;
24327 self.write(", ");
24328 self.generate_expression(&e.expression)?;
24329 if let Some(count) = &e.count {
24330 self.write(", ");
24331 self.generate_expression(count)?;
24332 }
24333 self.write(")");
24334 Ok(())
24335 }
24336
24337 fn generate_arg_min(&mut self, e: &ArgMin) -> Result<()> {
24338 self.write_keyword("ARG_MIN");
24340 self.write("(");
24341 self.generate_expression(&e.this)?;
24342 self.write(", ");
24343 self.generate_expression(&e.expression)?;
24344 if let Some(count) = &e.count {
24345 self.write(", ");
24346 self.generate_expression(count)?;
24347 }
24348 self.write(")");
24349 Ok(())
24350 }
24351
24352 fn generate_array_all(&mut self, e: &ArrayAll) -> Result<()> {
24353 self.write_keyword("ARRAY_ALL");
24355 self.write("(");
24356 self.generate_expression(&e.this)?;
24357 self.write(", ");
24358 self.generate_expression(&e.expression)?;
24359 self.write(")");
24360 Ok(())
24361 }
24362
24363 fn generate_array_any(&mut self, e: &ArrayAny) -> Result<()> {
24364 self.write_keyword("ARRAY_ANY");
24366 self.write("(");
24367 self.generate_expression(&e.this)?;
24368 self.write(", ");
24369 self.generate_expression(&e.expression)?;
24370 self.write(")");
24371 Ok(())
24372 }
24373
24374 fn generate_array_construct_compact(&mut self, e: &ArrayConstructCompact) -> Result<()> {
24375 self.write_keyword("ARRAY_CONSTRUCT_COMPACT");
24377 self.write("(");
24378 for (i, expr) in e.expressions.iter().enumerate() {
24379 if i > 0 {
24380 self.write(", ");
24381 }
24382 self.generate_expression(expr)?;
24383 }
24384 self.write(")");
24385 Ok(())
24386 }
24387
24388 fn generate_array_sum(&mut self, e: &ArraySum) -> Result<()> {
24389 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
24391 self.write("arraySum");
24392 } else {
24393 self.write_keyword("ARRAY_SUM");
24394 }
24395 self.write("(");
24396 self.generate_expression(&e.this)?;
24397 if let Some(expression) = &e.expression {
24398 self.write(", ");
24399 self.generate_expression(expression)?;
24400 }
24401 self.write(")");
24402 Ok(())
24403 }
24404
24405 fn generate_at_index(&mut self, e: &AtIndex) -> Result<()> {
24406 self.generate_expression(&e.this)?;
24408 self.write_space();
24409 self.write_keyword("AT");
24410 self.write_space();
24411 self.generate_expression(&e.expression)?;
24412 Ok(())
24413 }
24414
24415 fn generate_attach(&mut self, e: &Attach) -> Result<()> {
24416 self.write_keyword("ATTACH");
24418 if e.exists {
24419 self.write_space();
24420 self.write_keyword("IF NOT EXISTS");
24421 }
24422 self.write_space();
24423 self.generate_expression(&e.this)?;
24424 if !e.expressions.is_empty() {
24425 self.write(" (");
24426 for (i, expr) in e.expressions.iter().enumerate() {
24427 if i > 0 {
24428 self.write(", ");
24429 }
24430 self.generate_expression(expr)?;
24431 }
24432 self.write(")");
24433 }
24434 Ok(())
24435 }
24436
24437 fn generate_attach_option(&mut self, e: &AttachOption) -> Result<()> {
24438 self.generate_expression(&e.this)?;
24441 if let Some(expression) = &e.expression {
24442 self.write_space();
24443 self.generate_expression(expression)?;
24444 }
24445 Ok(())
24446 }
24447
24448 fn generate_auto_increment_keyword(
24452 &mut self,
24453 col: &crate::expressions::ColumnDef,
24454 ) -> Result<()> {
24455 use crate::dialects::DialectType;
24456 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
24457 self.write_keyword("IDENTITY");
24458 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
24459 self.write("(");
24460 if let Some(ref start) = col.auto_increment_start {
24461 self.generate_expression(start)?;
24462 } else {
24463 self.write("0");
24464 }
24465 self.write(", ");
24466 if let Some(ref inc) = col.auto_increment_increment {
24467 self.generate_expression(inc)?;
24468 } else {
24469 self.write("1");
24470 }
24471 self.write(")");
24472 }
24473 } else if matches!(
24474 self.config.dialect,
24475 Some(DialectType::Snowflake) | Some(DialectType::SQLite)
24476 ) {
24477 self.write_keyword("AUTOINCREMENT");
24478 if let Some(ref start) = col.auto_increment_start {
24479 self.write_space();
24480 self.write_keyword("START");
24481 self.write_space();
24482 self.generate_expression(start)?;
24483 }
24484 if let Some(ref inc) = col.auto_increment_increment {
24485 self.write_space();
24486 self.write_keyword("INCREMENT");
24487 self.write_space();
24488 self.generate_expression(inc)?;
24489 }
24490 if let Some(order) = col.auto_increment_order {
24491 self.write_space();
24492 if order {
24493 self.write_keyword("ORDER");
24494 } else {
24495 self.write_keyword("NOORDER");
24496 }
24497 }
24498 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
24499 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
24500 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
24501 self.write(" (");
24502 let mut first = true;
24503 if let Some(ref start) = col.auto_increment_start {
24504 self.write_keyword("START WITH");
24505 self.write_space();
24506 self.generate_expression(start)?;
24507 first = false;
24508 }
24509 if let Some(ref inc) = col.auto_increment_increment {
24510 if !first {
24511 self.write_space();
24512 }
24513 self.write_keyword("INCREMENT BY");
24514 self.write_space();
24515 self.generate_expression(inc)?;
24516 }
24517 self.write(")");
24518 }
24519 } else if matches!(self.config.dialect, Some(DialectType::Databricks)) {
24520 self.write_keyword("GENERATED ALWAYS AS IDENTITY");
24521 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
24522 self.write(" (");
24523 let mut first = true;
24524 if let Some(ref start) = col.auto_increment_start {
24525 self.write_keyword("START WITH");
24526 self.write_space();
24527 self.generate_expression(start)?;
24528 first = false;
24529 }
24530 if let Some(ref inc) = col.auto_increment_increment {
24531 if !first {
24532 self.write_space();
24533 }
24534 self.write_keyword("INCREMENT BY");
24535 self.write_space();
24536 self.generate_expression(inc)?;
24537 }
24538 self.write(")");
24539 }
24540 } else if matches!(
24541 self.config.dialect,
24542 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24543 ) {
24544 self.write_keyword("IDENTITY");
24545 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
24546 self.write("(");
24547 if let Some(ref start) = col.auto_increment_start {
24548 self.generate_expression(start)?;
24549 } else {
24550 self.write("0");
24551 }
24552 self.write(", ");
24553 if let Some(ref inc) = col.auto_increment_increment {
24554 self.generate_expression(inc)?;
24555 } else {
24556 self.write("1");
24557 }
24558 self.write(")");
24559 }
24560 } else {
24561 self.write_keyword("AUTO_INCREMENT");
24562 if let Some(ref start) = col.auto_increment_start {
24563 self.write_space();
24564 self.write_keyword("START");
24565 self.write_space();
24566 self.generate_expression(start)?;
24567 }
24568 if let Some(ref inc) = col.auto_increment_increment {
24569 self.write_space();
24570 self.write_keyword("INCREMENT");
24571 self.write_space();
24572 self.generate_expression(inc)?;
24573 }
24574 if let Some(order) = col.auto_increment_order {
24575 self.write_space();
24576 if order {
24577 self.write_keyword("ORDER");
24578 } else {
24579 self.write_keyword("NOORDER");
24580 }
24581 }
24582 }
24583 Ok(())
24584 }
24585
24586 fn generate_auto_increment_property(&mut self, e: &AutoIncrementProperty) -> Result<()> {
24587 self.write_keyword("AUTO_INCREMENT");
24589 self.write("=");
24590 self.generate_expression(&e.this)?;
24591 Ok(())
24592 }
24593
24594 fn generate_auto_refresh_property(&mut self, e: &AutoRefreshProperty) -> Result<()> {
24595 self.write_keyword("AUTO_REFRESH");
24597 self.write("=");
24598 self.generate_expression(&e.this)?;
24599 Ok(())
24600 }
24601
24602 fn generate_backup_property(&mut self, e: &BackupProperty) -> Result<()> {
24603 self.write_keyword("BACKUP");
24605 self.write_space();
24606 self.generate_expression(&e.this)?;
24607 Ok(())
24608 }
24609
24610 fn generate_base64_decode_binary(&mut self, e: &Base64DecodeBinary) -> Result<()> {
24611 self.write_keyword("BASE64_DECODE_BINARY");
24613 self.write("(");
24614 self.generate_expression(&e.this)?;
24615 if let Some(alphabet) = &e.alphabet {
24616 self.write(", ");
24617 self.generate_expression(alphabet)?;
24618 }
24619 self.write(")");
24620 Ok(())
24621 }
24622
24623 fn generate_base64_decode_string(&mut self, e: &Base64DecodeString) -> Result<()> {
24624 self.write_keyword("BASE64_DECODE_STRING");
24626 self.write("(");
24627 self.generate_expression(&e.this)?;
24628 if let Some(alphabet) = &e.alphabet {
24629 self.write(", ");
24630 self.generate_expression(alphabet)?;
24631 }
24632 self.write(")");
24633 Ok(())
24634 }
24635
24636 fn generate_base64_encode(&mut self, e: &Base64Encode) -> Result<()> {
24637 self.write_keyword("BASE64_ENCODE");
24639 self.write("(");
24640 self.generate_expression(&e.this)?;
24641 if let Some(max_line_length) = &e.max_line_length {
24642 self.write(", ");
24643 self.generate_expression(max_line_length)?;
24644 }
24645 if let Some(alphabet) = &e.alphabet {
24646 self.write(", ");
24647 self.generate_expression(alphabet)?;
24648 }
24649 self.write(")");
24650 Ok(())
24651 }
24652
24653 fn generate_block_compression_property(&mut self, e: &BlockCompressionProperty) -> Result<()> {
24654 self.write_keyword("BLOCKCOMPRESSION");
24656 self.write("=");
24657 if let Some(autotemp) = &e.autotemp {
24658 self.write_keyword("AUTOTEMP");
24659 self.write("(");
24660 self.generate_expression(autotemp)?;
24661 self.write(")");
24662 }
24663 if let Some(always) = &e.always {
24664 self.generate_expression(always)?;
24665 }
24666 if let Some(default) = &e.default {
24667 self.generate_expression(default)?;
24668 }
24669 if let Some(manual) = &e.manual {
24670 self.generate_expression(manual)?;
24671 }
24672 if let Some(never) = &e.never {
24673 self.generate_expression(never)?;
24674 }
24675 Ok(())
24676 }
24677
24678 fn generate_booland(&mut self, e: &Booland) -> Result<()> {
24679 self.write("((");
24681 self.generate_expression(&e.this)?;
24682 self.write(") ");
24683 self.write_keyword("AND");
24684 self.write(" (");
24685 self.generate_expression(&e.expression)?;
24686 self.write("))");
24687 Ok(())
24688 }
24689
24690 fn generate_boolor(&mut self, e: &Boolor) -> Result<()> {
24691 self.write("((");
24693 self.generate_expression(&e.this)?;
24694 self.write(") ");
24695 self.write_keyword("OR");
24696 self.write(" (");
24697 self.generate_expression(&e.expression)?;
24698 self.write("))");
24699 Ok(())
24700 }
24701
24702 fn generate_build_property(&mut self, e: &BuildProperty) -> Result<()> {
24703 self.write_keyword("BUILD");
24705 self.write_space();
24706 self.generate_expression(&e.this)?;
24707 Ok(())
24708 }
24709
24710 fn generate_byte_string(&mut self, e: &ByteString) -> Result<()> {
24711 self.generate_expression(&e.this)?;
24713 Ok(())
24714 }
24715
24716 fn generate_case_specific_column_constraint(
24717 &mut self,
24718 e: &CaseSpecificColumnConstraint,
24719 ) -> Result<()> {
24720 if e.not_.is_some() {
24722 self.write_keyword("NOT");
24723 self.write_space();
24724 }
24725 self.write_keyword("CASESPECIFIC");
24726 Ok(())
24727 }
24728
24729 fn generate_cast_to_str_type(&mut self, e: &CastToStrType) -> Result<()> {
24730 self.write_keyword("CAST");
24732 self.write("(");
24733 self.generate_expression(&e.this)?;
24734 if self.config.dialect == Some(DialectType::ClickHouse) {
24735 self.write(", ");
24737 } else {
24738 self.write_space();
24739 self.write_keyword("AS");
24740 self.write_space();
24741 }
24742 if let Some(to) = &e.to {
24743 self.generate_expression(to)?;
24744 }
24745 self.write(")");
24746 Ok(())
24747 }
24748
24749 fn generate_changes(&mut self, e: &Changes) -> Result<()> {
24750 self.write_keyword("CHANGES");
24753 self.write(" (");
24754 if let Some(information) = &e.information {
24755 self.write_keyword("INFORMATION");
24756 self.write(" => ");
24757 self.generate_expression(information)?;
24758 }
24759 self.write(")");
24760 if let Some(at_before) = &e.at_before {
24762 self.write(" ");
24763 self.generate_expression(at_before)?;
24764 }
24765 if let Some(end) = &e.end {
24766 self.write(" ");
24767 self.generate_expression(end)?;
24768 }
24769 Ok(())
24770 }
24771
24772 fn generate_character_set_column_constraint(
24773 &mut self,
24774 e: &CharacterSetColumnConstraint,
24775 ) -> Result<()> {
24776 self.write_keyword("CHARACTER SET");
24778 self.write_space();
24779 self.generate_expression(&e.this)?;
24780 Ok(())
24781 }
24782
24783 fn generate_character_set_property(&mut self, e: &CharacterSetProperty) -> Result<()> {
24784 if e.default.is_some() {
24786 self.write_keyword("DEFAULT");
24787 self.write_space();
24788 }
24789 self.write_keyword("CHARACTER SET");
24790 self.write("=");
24791 self.generate_expression(&e.this)?;
24792 Ok(())
24793 }
24794
24795 fn generate_check_column_constraint(&mut self, e: &CheckColumnConstraint) -> Result<()> {
24796 self.write_keyword("CHECK");
24798 self.write(" (");
24799 self.generate_expression(&e.this)?;
24800 self.write(")");
24801 if e.enforced.is_some() {
24802 self.write_space();
24803 self.write_keyword("ENFORCED");
24804 }
24805 Ok(())
24806 }
24807
24808 fn generate_check_json(&mut self, e: &CheckJson) -> Result<()> {
24809 self.write_keyword("CHECK_JSON");
24811 self.write("(");
24812 self.generate_expression(&e.this)?;
24813 self.write(")");
24814 Ok(())
24815 }
24816
24817 fn generate_check_xml(&mut self, e: &CheckXml) -> Result<()> {
24818 self.write_keyword("CHECK_XML");
24820 self.write("(");
24821 self.generate_expression(&e.this)?;
24822 self.write(")");
24823 Ok(())
24824 }
24825
24826 fn generate_checksum_property(&mut self, e: &ChecksumProperty) -> Result<()> {
24827 self.write_keyword("CHECKSUM");
24829 self.write("=");
24830 if e.on.is_some() {
24831 self.write_keyword("ON");
24832 } else if e.default.is_some() {
24833 self.write_keyword("DEFAULT");
24834 } else {
24835 self.write_keyword("OFF");
24836 }
24837 Ok(())
24838 }
24839
24840 fn generate_clone(&mut self, e: &Clone) -> Result<()> {
24841 if e.shallow.is_some() {
24843 self.write_keyword("SHALLOW");
24844 self.write_space();
24845 }
24846 if e.copy.is_some() {
24847 self.write_keyword("COPY");
24848 } else {
24849 self.write_keyword("CLONE");
24850 }
24851 self.write_space();
24852 self.generate_expression(&e.this)?;
24853 Ok(())
24854 }
24855
24856 fn generate_cluster_by(&mut self, e: &ClusterBy) -> Result<()> {
24857 self.write_keyword("CLUSTER BY");
24859 self.write(" (");
24860 for (i, ord) in e.expressions.iter().enumerate() {
24861 if i > 0 {
24862 self.write(", ");
24863 }
24864 self.generate_ordered(ord)?;
24865 }
24866 self.write(")");
24867 Ok(())
24868 }
24869
24870 fn generate_cluster_by_columns_property(&mut self, e: &ClusterByColumnsProperty) -> Result<()> {
24871 self.write_keyword("CLUSTER BY");
24873 self.write_space();
24874 for (i, col) in e.columns.iter().enumerate() {
24875 if i > 0 {
24876 self.write(", ");
24877 }
24878 self.generate_identifier(col)?;
24879 }
24880 Ok(())
24881 }
24882
24883 fn generate_clustered_by_property(&mut self, e: &ClusteredByProperty) -> Result<()> {
24884 self.write_keyword("CLUSTERED BY");
24886 self.write(" (");
24887 for (i, expr) in e.expressions.iter().enumerate() {
24888 if i > 0 {
24889 self.write(", ");
24890 }
24891 self.generate_expression(expr)?;
24892 }
24893 self.write(")");
24894 if let Some(sorted_by) = &e.sorted_by {
24895 self.write_space();
24896 self.write_keyword("SORTED BY");
24897 self.write(" (");
24898 if let Expression::Tuple(t) = sorted_by.as_ref() {
24900 for (i, expr) in t.expressions.iter().enumerate() {
24901 if i > 0 {
24902 self.write(", ");
24903 }
24904 self.generate_expression(expr)?;
24905 }
24906 } else {
24907 self.generate_expression(sorted_by)?;
24908 }
24909 self.write(")");
24910 }
24911 if let Some(buckets) = &e.buckets {
24912 self.write_space();
24913 self.write_keyword("INTO");
24914 self.write_space();
24915 self.generate_expression(buckets)?;
24916 self.write_space();
24917 self.write_keyword("BUCKETS");
24918 }
24919 Ok(())
24920 }
24921
24922 fn generate_collate_property(&mut self, e: &CollateProperty) -> Result<()> {
24923 if e.default.is_some() {
24927 self.write_keyword("DEFAULT");
24928 self.write_space();
24929 }
24930 self.write_keyword("COLLATE");
24931 match self.config.dialect {
24933 Some(DialectType::BigQuery) => self.write_space(),
24934 _ => self.write("="),
24935 }
24936 self.generate_expression(&e.this)?;
24937 Ok(())
24938 }
24939
24940 fn generate_column_constraint(&mut self, e: &ColumnConstraint) -> Result<()> {
24941 match e {
24943 ColumnConstraint::NotNull => {
24944 self.write_keyword("NOT NULL");
24945 }
24946 ColumnConstraint::Null => {
24947 self.write_keyword("NULL");
24948 }
24949 ColumnConstraint::Unique => {
24950 self.write_keyword("UNIQUE");
24951 }
24952 ColumnConstraint::PrimaryKey => {
24953 self.write_keyword("PRIMARY KEY");
24954 }
24955 ColumnConstraint::Default(expr) => {
24956 self.write_keyword("DEFAULT");
24957 self.write_space();
24958 self.generate_expression(expr)?;
24959 }
24960 ColumnConstraint::Check(expr) => {
24961 self.write_keyword("CHECK");
24962 self.write(" (");
24963 self.generate_expression(expr)?;
24964 self.write(")");
24965 }
24966 ColumnConstraint::References(fk_ref) => {
24967 if fk_ref.has_foreign_key_keywords {
24968 self.write_keyword("FOREIGN KEY");
24969 self.write_space();
24970 }
24971 self.write_keyword("REFERENCES");
24972 self.write_space();
24973 self.generate_table(&fk_ref.table)?;
24974 if !fk_ref.columns.is_empty() {
24975 self.write(" (");
24976 for (i, col) in fk_ref.columns.iter().enumerate() {
24977 if i > 0 {
24978 self.write(", ");
24979 }
24980 self.generate_identifier(col)?;
24981 }
24982 self.write(")");
24983 }
24984 }
24985 ColumnConstraint::GeneratedAsIdentity(gen) => {
24986 self.write_keyword("GENERATED");
24987 self.write_space();
24988 if gen.always {
24989 self.write_keyword("ALWAYS");
24990 } else {
24991 self.write_keyword("BY DEFAULT");
24992 if gen.on_null {
24993 self.write_space();
24994 self.write_keyword("ON NULL");
24995 }
24996 }
24997 self.write_space();
24998 self.write_keyword("AS IDENTITY");
24999 }
25000 ColumnConstraint::Collate(collation) => {
25001 self.write_keyword("COLLATE");
25002 self.write_space();
25003 self.generate_identifier(collation)?;
25004 }
25005 ColumnConstraint::Comment(comment) => {
25006 self.write_keyword("COMMENT");
25007 self.write(" '");
25008 self.write(comment);
25009 self.write("'");
25010 }
25011 ColumnConstraint::ComputedColumn(cc) => {
25012 self.generate_computed_column_inline(cc)?;
25013 }
25014 ColumnConstraint::GeneratedAsRow(gar) => {
25015 self.generate_generated_as_row_inline(gar)?;
25016 }
25017 ColumnConstraint::Tags(tags) => {
25018 self.write_keyword("TAG");
25019 self.write(" (");
25020 for (i, expr) in tags.expressions.iter().enumerate() {
25021 if i > 0 {
25022 self.write(", ");
25023 }
25024 self.generate_expression(expr)?;
25025 }
25026 self.write(")");
25027 }
25028 ColumnConstraint::Path(path_expr) => {
25029 self.write_keyword("PATH");
25030 self.write_space();
25031 self.generate_expression(path_expr)?;
25032 }
25033 }
25034 Ok(())
25035 }
25036
25037 fn generate_column_position(&mut self, e: &ColumnPosition) -> Result<()> {
25038 match e {
25040 ColumnPosition::First => {
25041 self.write_keyword("FIRST");
25042 }
25043 ColumnPosition::After(ident) => {
25044 self.write_keyword("AFTER");
25045 self.write_space();
25046 self.generate_identifier(ident)?;
25047 }
25048 }
25049 Ok(())
25050 }
25051
25052 fn generate_column_prefix(&mut self, e: &ColumnPrefix) -> Result<()> {
25053 self.generate_expression(&e.this)?;
25055 self.write("(");
25056 self.generate_expression(&e.expression)?;
25057 self.write(")");
25058 Ok(())
25059 }
25060
25061 fn generate_columns(&mut self, e: &Columns) -> Result<()> {
25062 if let Some(ref unpack) = e.unpack {
25065 if let Expression::Boolean(b) = unpack.as_ref() {
25066 if b.value {
25067 self.write("*");
25068 }
25069 }
25070 }
25071 self.write_keyword("COLUMNS");
25072 self.write("(");
25073 self.generate_expression(&e.this)?;
25074 self.write(")");
25075 Ok(())
25076 }
25077
25078 fn generate_combined_agg_func(&mut self, e: &CombinedAggFunc) -> Result<()> {
25079 self.generate_expression(&e.this)?;
25081 self.write("(");
25082 for (i, expr) in e.expressions.iter().enumerate() {
25083 if i > 0 {
25084 self.write(", ");
25085 }
25086 self.generate_expression(expr)?;
25087 }
25088 self.write(")");
25089 Ok(())
25090 }
25091
25092 fn generate_combined_parameterized_agg(&mut self, e: &CombinedParameterizedAgg) -> Result<()> {
25093 self.generate_expression(&e.this)?;
25095 self.write("(");
25096 for (i, param) in e.params.iter().enumerate() {
25097 if i > 0 {
25098 self.write(", ");
25099 }
25100 self.generate_expression(param)?;
25101 }
25102 self.write(")(");
25103 for (i, expr) in e.expressions.iter().enumerate() {
25104 if i > 0 {
25105 self.write(", ");
25106 }
25107 self.generate_expression(expr)?;
25108 }
25109 self.write(")");
25110 Ok(())
25111 }
25112
25113 fn generate_commit(&mut self, e: &Commit) -> Result<()> {
25114 self.write_keyword("COMMIT");
25116
25117 if e.this.is_none()
25119 && matches!(
25120 self.config.dialect,
25121 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25122 )
25123 {
25124 self.write_space();
25125 self.write_keyword("TRANSACTION");
25126 }
25127
25128 if let Some(this) = &e.this {
25130 let is_transaction_marker = matches!(
25132 this.as_ref(),
25133 Expression::Identifier(id) if id.name == "TRANSACTION"
25134 );
25135
25136 self.write_space();
25137 self.write_keyword("TRANSACTION");
25138
25139 if !is_transaction_marker {
25141 self.write_space();
25142 self.generate_expression(this)?;
25143 }
25144 }
25145
25146 if let Some(durability) = &e.durability {
25148 self.write_space();
25149 self.write_keyword("WITH");
25150 self.write(" (");
25151 self.write_keyword("DELAYED_DURABILITY");
25152 self.write(" = ");
25153 if let Expression::Boolean(BooleanLiteral { value: true }) = durability.as_ref() {
25154 self.write_keyword("ON");
25155 } else {
25156 self.write_keyword("OFF");
25157 }
25158 self.write(")");
25159 }
25160
25161 if let Some(chain) = &e.chain {
25163 self.write_space();
25164 if let Expression::Boolean(BooleanLiteral { value: false }) = chain.as_ref() {
25165 self.write_keyword("AND NO CHAIN");
25166 } else {
25167 self.write_keyword("AND CHAIN");
25168 }
25169 }
25170 Ok(())
25171 }
25172
25173 fn generate_comprehension(&mut self, e: &Comprehension) -> Result<()> {
25174 self.write("[");
25176 self.generate_expression(&e.this)?;
25177 self.write_space();
25178 self.write_keyword("FOR");
25179 self.write_space();
25180 self.generate_expression(&e.expression)?;
25181 if let Some(pos) = &e.position {
25183 self.write(", ");
25184 self.generate_expression(pos)?;
25185 }
25186 if let Some(iterator) = &e.iterator {
25187 self.write_space();
25188 self.write_keyword("IN");
25189 self.write_space();
25190 self.generate_expression(iterator)?;
25191 }
25192 if let Some(condition) = &e.condition {
25193 self.write_space();
25194 self.write_keyword("IF");
25195 self.write_space();
25196 self.generate_expression(condition)?;
25197 }
25198 self.write("]");
25199 Ok(())
25200 }
25201
25202 fn generate_compress(&mut self, e: &Compress) -> Result<()> {
25203 self.write_keyword("COMPRESS");
25205 self.write("(");
25206 self.generate_expression(&e.this)?;
25207 if let Some(method) = &e.method {
25208 self.write(", '");
25209 self.write(method);
25210 self.write("'");
25211 }
25212 self.write(")");
25213 Ok(())
25214 }
25215
25216 fn generate_compress_column_constraint(&mut self, e: &CompressColumnConstraint) -> Result<()> {
25217 self.write_keyword("COMPRESS");
25219 if let Some(this) = &e.this {
25220 self.write_space();
25221 self.generate_expression(this)?;
25222 }
25223 Ok(())
25224 }
25225
25226 fn generate_computed_column_constraint(&mut self, e: &ComputedColumnConstraint) -> Result<()> {
25227 self.write_keyword("AS");
25229 self.write_space();
25230 self.generate_expression(&e.this)?;
25231 if e.not_null.is_some() {
25232 self.write_space();
25233 self.write_keyword("PERSISTED NOT NULL");
25234 } else if e.persisted.is_some() {
25235 self.write_space();
25236 self.write_keyword("PERSISTED");
25237 }
25238 Ok(())
25239 }
25240
25241 fn generate_computed_column_inline(&mut self, cc: &ComputedColumn) -> Result<()> {
25245 let computed_expr = if matches!(
25246 self.config.dialect,
25247 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25248 ) {
25249 match &*cc.expression {
25250 Expression::Year(y) if !matches!(&y.this, Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
25251 {
25252 let wrapped = Expression::Cast(Box::new(Cast {
25253 this: y.this.clone(),
25254 to: DataType::Date,
25255 trailing_comments: Vec::new(),
25256 double_colon_syntax: false,
25257 format: None,
25258 default: None,
25259 inferred_type: None,
25260 }));
25261 Expression::Year(Box::new(UnaryFunc::new(wrapped)))
25262 }
25263 Expression::Function(f)
25264 if f.name.eq_ignore_ascii_case("YEAR")
25265 && f.args.len() == 1
25266 && !matches!(&f.args[0], Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
25267 {
25268 let wrapped = Expression::Cast(Box::new(Cast {
25269 this: f.args[0].clone(),
25270 to: DataType::Date,
25271 trailing_comments: Vec::new(),
25272 double_colon_syntax: false,
25273 format: None,
25274 default: None,
25275 inferred_type: None,
25276 }));
25277 Expression::Function(Box::new(Function::new("YEAR".to_string(), vec![wrapped])))
25278 }
25279 _ => *cc.expression.clone(),
25280 }
25281 } else {
25282 *cc.expression.clone()
25283 };
25284
25285 match cc.persistence_kind.as_deref() {
25286 Some("STORED") | Some("VIRTUAL") => {
25287 self.write_keyword("GENERATED ALWAYS AS");
25289 self.write(" (");
25290 self.generate_expression(&computed_expr)?;
25291 self.write(")");
25292 self.write_space();
25293 if cc.persisted {
25294 self.write_keyword("STORED");
25295 } else {
25296 self.write_keyword("VIRTUAL");
25297 }
25298 }
25299 Some("PERSISTED") => {
25300 self.write_keyword("AS");
25302 self.write(" (");
25303 self.generate_expression(&computed_expr)?;
25304 self.write(")");
25305 self.write_space();
25306 self.write_keyword("PERSISTED");
25307 if let Some(ref dt) = cc.data_type {
25309 self.write_space();
25310 self.generate_data_type(dt)?;
25311 }
25312 if cc.not_null {
25313 self.write_space();
25314 self.write_keyword("NOT NULL");
25315 }
25316 }
25317 _ => {
25318 if matches!(
25321 self.config.dialect,
25322 Some(DialectType::Spark)
25323 | Some(DialectType::Databricks)
25324 | Some(DialectType::Hive)
25325 ) {
25326 self.write_keyword("GENERATED ALWAYS AS");
25327 self.write(" (");
25328 self.generate_expression(&computed_expr)?;
25329 self.write(")");
25330 } else if matches!(
25331 self.config.dialect,
25332 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25333 ) {
25334 self.write_keyword("AS");
25335 let omit_parens = matches!(computed_expr, Expression::Year(_))
25336 || matches!(&computed_expr, Expression::Function(f) if f.name.eq_ignore_ascii_case("YEAR"));
25337 if omit_parens {
25338 self.write_space();
25339 self.generate_expression(&computed_expr)?;
25340 } else {
25341 self.write(" (");
25342 self.generate_expression(&computed_expr)?;
25343 self.write(")");
25344 }
25345 } else {
25346 self.write_keyword("AS");
25347 self.write(" (");
25348 self.generate_expression(&computed_expr)?;
25349 self.write(")");
25350 }
25351 }
25352 }
25353 Ok(())
25354 }
25355
25356 fn generate_generated_as_row_inline(&mut self, gar: &GeneratedAsRow) -> Result<()> {
25359 self.write_keyword("GENERATED ALWAYS AS ROW ");
25360 if gar.start {
25361 self.write_keyword("START");
25362 } else {
25363 self.write_keyword("END");
25364 }
25365 if gar.hidden {
25366 self.write_space();
25367 self.write_keyword("HIDDEN");
25368 }
25369 Ok(())
25370 }
25371
25372 fn generate_system_versioning_content(
25374 &mut self,
25375 e: &WithSystemVersioningProperty,
25376 ) -> Result<()> {
25377 let mut parts = Vec::new();
25378
25379 if let Some(this) = &e.this {
25380 let mut s = String::from("HISTORY_TABLE=");
25381 let mut gen = Generator::new();
25382 gen.config = self.config.clone();
25383 gen.generate_expression(this)?;
25384 s.push_str(&gen.output);
25385 parts.push(s);
25386 }
25387
25388 if let Some(data_consistency) = &e.data_consistency {
25389 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
25390 let mut gen = Generator::new();
25391 gen.config = self.config.clone();
25392 gen.generate_expression(data_consistency)?;
25393 s.push_str(&gen.output);
25394 parts.push(s);
25395 }
25396
25397 if let Some(retention_period) = &e.retention_period {
25398 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
25399 let mut gen = Generator::new();
25400 gen.config = self.config.clone();
25401 gen.generate_expression(retention_period)?;
25402 s.push_str(&gen.output);
25403 parts.push(s);
25404 }
25405
25406 self.write_keyword("SYSTEM_VERSIONING");
25407 self.write("=");
25408
25409 if !parts.is_empty() {
25410 self.write_keyword("ON");
25411 self.write("(");
25412 self.write(&parts.join(", "));
25413 self.write(")");
25414 } else if e.on.is_some() {
25415 self.write_keyword("ON");
25416 } else {
25417 self.write_keyword("OFF");
25418 }
25419
25420 Ok(())
25421 }
25422
25423 fn generate_conditional_insert(&mut self, e: &ConditionalInsert) -> Result<()> {
25424 if e.else_.is_some() {
25427 self.write_keyword("ELSE");
25428 self.write_space();
25429 } else if let Some(expression) = &e.expression {
25430 self.write_keyword("WHEN");
25431 self.write_space();
25432 self.generate_expression(expression)?;
25433 self.write_space();
25434 self.write_keyword("THEN");
25435 self.write_space();
25436 }
25437
25438 if let Expression::Insert(insert) = e.this.as_ref() {
25441 self.write_keyword("INTO");
25442 self.write_space();
25443 self.generate_table(&insert.table)?;
25444
25445 if !insert.columns.is_empty() {
25447 self.write(" (");
25448 for (i, col) in insert.columns.iter().enumerate() {
25449 if i > 0 {
25450 self.write(", ");
25451 }
25452 self.generate_identifier(col)?;
25453 }
25454 self.write(")");
25455 }
25456
25457 if !insert.values.is_empty() {
25459 self.write_space();
25460 self.write_keyword("VALUES");
25461 for (row_idx, row) in insert.values.iter().enumerate() {
25462 if row_idx > 0 {
25463 self.write(", ");
25464 }
25465 self.write(" (");
25466 for (i, val) in row.iter().enumerate() {
25467 if i > 0 {
25468 self.write(", ");
25469 }
25470 self.generate_expression(val)?;
25471 }
25472 self.write(")");
25473 }
25474 }
25475 } else {
25476 self.generate_expression(&e.this)?;
25478 }
25479 Ok(())
25480 }
25481
25482 fn generate_constraint(&mut self, e: &Constraint) -> Result<()> {
25483 self.write_keyword("CONSTRAINT");
25485 self.write_space();
25486 self.generate_expression(&e.this)?;
25487 if !e.expressions.is_empty() {
25488 self.write_space();
25489 for (i, expr) in e.expressions.iter().enumerate() {
25490 if i > 0 {
25491 self.write_space();
25492 }
25493 self.generate_expression(expr)?;
25494 }
25495 }
25496 Ok(())
25497 }
25498
25499 fn generate_convert_timezone(&mut self, e: &ConvertTimezone) -> Result<()> {
25500 self.write_keyword("CONVERT_TIMEZONE");
25502 self.write("(");
25503 let mut first = true;
25504 if let Some(source_tz) = &e.source_tz {
25505 self.generate_expression(source_tz)?;
25506 first = false;
25507 }
25508 if let Some(target_tz) = &e.target_tz {
25509 if !first {
25510 self.write(", ");
25511 }
25512 self.generate_expression(target_tz)?;
25513 first = false;
25514 }
25515 if let Some(timestamp) = &e.timestamp {
25516 if !first {
25517 self.write(", ");
25518 }
25519 self.generate_expression(timestamp)?;
25520 }
25521 self.write(")");
25522 Ok(())
25523 }
25524
25525 fn generate_convert_to_charset(&mut self, e: &ConvertToCharset) -> Result<()> {
25526 self.write_keyword("CONVERT");
25528 self.write("(");
25529 self.generate_expression(&e.this)?;
25530 if let Some(dest) = &e.dest {
25531 self.write_space();
25532 self.write_keyword("USING");
25533 self.write_space();
25534 self.generate_expression(dest)?;
25535 }
25536 self.write(")");
25537 Ok(())
25538 }
25539
25540 fn generate_copy(&mut self, e: &CopyStmt) -> Result<()> {
25541 self.write_keyword("COPY");
25542 if e.is_into {
25543 self.write_space();
25544 self.write_keyword("INTO");
25545 }
25546 self.write_space();
25547
25548 if let Expression::Literal(Literal::String(s)) = &e.this {
25550 if s.starts_with('@') {
25551 self.write(s);
25552 } else {
25553 self.generate_expression(&e.this)?;
25554 }
25555 } else {
25556 self.generate_expression(&e.this)?;
25557 }
25558
25559 if e.kind {
25561 if self.config.pretty {
25563 self.write_newline();
25564 } else {
25565 self.write_space();
25566 }
25567 self.write_keyword("FROM");
25568 self.write_space();
25569 } else if !e.files.is_empty() {
25570 if self.config.pretty {
25572 self.write_newline();
25573 } else {
25574 self.write_space();
25575 }
25576 self.write_keyword("TO");
25577 self.write_space();
25578 }
25579
25580 for (i, file) in e.files.iter().enumerate() {
25582 if i > 0 {
25583 self.write_space();
25584 }
25585 if let Expression::Literal(Literal::String(s)) = file {
25587 if s.starts_with('@') {
25588 self.write(s);
25589 } else {
25590 self.generate_expression(file)?;
25591 }
25592 } else if let Expression::Identifier(id) = file {
25593 if id.quoted {
25595 self.write("`");
25596 self.write(&id.name);
25597 self.write("`");
25598 } else {
25599 self.generate_expression(file)?;
25600 }
25601 } else {
25602 self.generate_expression(file)?;
25603 }
25604 }
25605
25606 if !e.with_wrapped {
25608 if let Some(ref creds) = e.credentials {
25609 if let Some(ref storage) = creds.storage {
25610 if self.config.pretty {
25611 self.write_newline();
25612 } else {
25613 self.write_space();
25614 }
25615 self.write_keyword("STORAGE_INTEGRATION");
25616 self.write(" = ");
25617 self.write(storage);
25618 }
25619 if creds.credentials.is_empty() {
25620 if self.config.pretty {
25622 self.write_newline();
25623 } else {
25624 self.write_space();
25625 }
25626 self.write_keyword("CREDENTIALS");
25627 self.write(" = ()");
25628 } else {
25629 if self.config.pretty {
25630 self.write_newline();
25631 } else {
25632 self.write_space();
25633 }
25634 self.write_keyword("CREDENTIALS");
25635 if creds.credentials.len() == 1 && creds.credentials[0].0.is_empty() {
25638 self.write(" '");
25640 self.write(&creds.credentials[0].1);
25641 self.write("'");
25642 } else {
25643 self.write(" = (");
25645 for (i, (k, v)) in creds.credentials.iter().enumerate() {
25646 if i > 0 {
25647 self.write_space();
25648 }
25649 self.write(k);
25650 self.write("='");
25651 self.write(v);
25652 self.write("'");
25653 }
25654 self.write(")");
25655 }
25656 }
25657 if let Some(ref encryption) = creds.encryption {
25658 self.write_space();
25659 self.write_keyword("ENCRYPTION");
25660 self.write(" = ");
25661 self.write(encryption);
25662 }
25663 }
25664 }
25665
25666 if !e.params.is_empty() {
25668 if e.with_wrapped {
25669 self.write_space();
25671 self.write_keyword("WITH");
25672 self.write(" (");
25673 for (i, param) in e.params.iter().enumerate() {
25674 if i > 0 {
25675 self.write(", ");
25676 }
25677 self.generate_copy_param_with_format(param)?;
25678 }
25679 self.write(")");
25680 } else {
25681 for param in &e.params {
25685 if self.config.pretty {
25686 self.write_newline();
25687 } else {
25688 self.write_space();
25689 }
25690 self.write(¶m.name);
25692 if let Some(ref value) = param.value {
25693 if param.eq {
25695 self.write(" = ");
25696 } else {
25697 self.write(" ");
25698 }
25699 if !param.values.is_empty() {
25700 self.write("(");
25701 for (i, v) in param.values.iter().enumerate() {
25702 if i > 0 {
25703 self.write_space();
25704 }
25705 self.generate_copy_nested_param(v)?;
25706 }
25707 self.write(")");
25708 } else {
25709 self.generate_copy_param_value(value)?;
25711 }
25712 } else if !param.values.is_empty() {
25713 if param.eq {
25715 self.write(" = (");
25716 } else {
25717 self.write(" (");
25718 }
25719 let is_key_value_pairs = param
25724 .values
25725 .first()
25726 .map_or(false, |v| matches!(v, Expression::Eq(_)));
25727 let sep = if is_key_value_pairs && param.eq {
25728 " "
25729 } else {
25730 ", "
25731 };
25732 for (i, v) in param.values.iter().enumerate() {
25733 if i > 0 {
25734 self.write(sep);
25735 }
25736 self.generate_copy_nested_param(v)?;
25737 }
25738 self.write(")");
25739 }
25740 }
25741 }
25742 }
25743
25744 Ok(())
25745 }
25746
25747 fn generate_copy_param_with_format(&mut self, param: &CopyParameter) -> Result<()> {
25750 self.write_keyword(¶m.name);
25751 if !param.values.is_empty() {
25752 self.write(" = (");
25754 for (i, v) in param.values.iter().enumerate() {
25755 if i > 0 {
25756 self.write(", ");
25757 }
25758 self.generate_copy_nested_param(v)?;
25759 }
25760 self.write(")");
25761 } else if let Some(ref value) = param.value {
25762 if param.eq {
25763 self.write(" = ");
25764 } else {
25765 self.write(" ");
25766 }
25767 self.generate_expression(value)?;
25768 }
25769 Ok(())
25770 }
25771
25772 fn generate_copy_nested_param(&mut self, expr: &Expression) -> Result<()> {
25774 match expr {
25775 Expression::Eq(eq) => {
25776 match &eq.left {
25778 Expression::Column(c) => self.write(&c.name.name),
25779 _ => self.generate_expression(&eq.left)?,
25780 }
25781 self.write("=");
25782 match &eq.right {
25784 Expression::Literal(Literal::String(s)) => {
25785 self.write("'");
25786 self.write(s);
25787 self.write("'");
25788 }
25789 Expression::Tuple(t) => {
25790 self.write("(");
25792 if self.config.pretty {
25793 self.write_newline();
25794 self.indent_level += 1;
25795 for (i, item) in t.expressions.iter().enumerate() {
25796 if i > 0 {
25797 self.write(", ");
25798 }
25799 self.write_indent();
25800 self.generate_expression(item)?;
25801 }
25802 self.write_newline();
25803 self.indent_level -= 1;
25804 } else {
25805 for (i, item) in t.expressions.iter().enumerate() {
25806 if i > 0 {
25807 self.write(", ");
25808 }
25809 self.generate_expression(item)?;
25810 }
25811 }
25812 self.write(")");
25813 }
25814 _ => self.generate_expression(&eq.right)?,
25815 }
25816 Ok(())
25817 }
25818 Expression::Column(c) => {
25819 self.write(&c.name.name);
25821 Ok(())
25822 }
25823 _ => self.generate_expression(expr),
25824 }
25825 }
25826
25827 fn generate_copy_param_value(&mut self, expr: &Expression) -> Result<()> {
25830 match expr {
25831 Expression::Column(c) => {
25832 if c.name.quoted {
25834 self.write("\"");
25835 self.write(&c.name.name);
25836 self.write("\"");
25837 } else {
25838 self.write(&c.name.name);
25839 }
25840 Ok(())
25841 }
25842 Expression::Identifier(id) => {
25843 if id.quoted {
25845 self.write("\"");
25846 self.write(&id.name);
25847 self.write("\"");
25848 } else {
25849 self.write(&id.name);
25850 }
25851 Ok(())
25852 }
25853 Expression::Literal(Literal::String(s)) => {
25854 self.write("'");
25856 self.write(s);
25857 self.write("'");
25858 Ok(())
25859 }
25860 _ => self.generate_expression(expr),
25861 }
25862 }
25863
25864 fn generate_copy_parameter(&mut self, e: &CopyParameter) -> Result<()> {
25865 self.write_keyword(&e.name);
25866 if let Some(ref value) = e.value {
25867 if e.eq {
25868 self.write(" = ");
25869 } else {
25870 self.write(" ");
25871 }
25872 self.generate_expression(value)?;
25873 }
25874 if !e.values.is_empty() {
25875 if e.eq {
25876 self.write(" = ");
25877 } else {
25878 self.write(" ");
25879 }
25880 self.write("(");
25881 for (i, v) in e.values.iter().enumerate() {
25882 if i > 0 {
25883 self.write(", ");
25884 }
25885 self.generate_expression(v)?;
25886 }
25887 self.write(")");
25888 }
25889 Ok(())
25890 }
25891
25892 fn generate_corr(&mut self, e: &Corr) -> Result<()> {
25893 self.write_keyword("CORR");
25895 self.write("(");
25896 self.generate_expression(&e.this)?;
25897 self.write(", ");
25898 self.generate_expression(&e.expression)?;
25899 self.write(")");
25900 Ok(())
25901 }
25902
25903 fn generate_cosine_distance(&mut self, e: &CosineDistance) -> Result<()> {
25904 self.write_keyword("COSINE_DISTANCE");
25906 self.write("(");
25907 self.generate_expression(&e.this)?;
25908 self.write(", ");
25909 self.generate_expression(&e.expression)?;
25910 self.write(")");
25911 Ok(())
25912 }
25913
25914 fn generate_covar_pop(&mut self, e: &CovarPop) -> Result<()> {
25915 self.write_keyword("COVAR_POP");
25917 self.write("(");
25918 self.generate_expression(&e.this)?;
25919 self.write(", ");
25920 self.generate_expression(&e.expression)?;
25921 self.write(")");
25922 Ok(())
25923 }
25924
25925 fn generate_covar_samp(&mut self, e: &CovarSamp) -> Result<()> {
25926 self.write_keyword("COVAR_SAMP");
25928 self.write("(");
25929 self.generate_expression(&e.this)?;
25930 self.write(", ");
25931 self.generate_expression(&e.expression)?;
25932 self.write(")");
25933 Ok(())
25934 }
25935
25936 fn generate_credentials(&mut self, e: &Credentials) -> Result<()> {
25937 self.write_keyword("CREDENTIALS");
25939 self.write(" (");
25940 for (i, (key, value)) in e.credentials.iter().enumerate() {
25941 if i > 0 {
25942 self.write(", ");
25943 }
25944 self.write(key);
25945 self.write("='");
25946 self.write(value);
25947 self.write("'");
25948 }
25949 self.write(")");
25950 Ok(())
25951 }
25952
25953 fn generate_credentials_property(&mut self, e: &CredentialsProperty) -> Result<()> {
25954 self.write_keyword("CREDENTIALS");
25956 self.write("=(");
25957 for (i, expr) in e.expressions.iter().enumerate() {
25958 if i > 0 {
25959 self.write(", ");
25960 }
25961 self.generate_expression(expr)?;
25962 }
25963 self.write(")");
25964 Ok(())
25965 }
25966
25967 fn generate_cte(&mut self, e: &Cte) -> Result<()> {
25968 use crate::dialects::DialectType;
25969
25970 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !e.alias_first {
25973 self.generate_expression(&e.this)?;
25974 self.write_space();
25975 self.write_keyword("AS");
25976 self.write_space();
25977 self.generate_identifier(&e.alias)?;
25978 return Ok(());
25979 }
25980 self.write(&e.alias.name);
25981
25982 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
25984
25985 if !e.columns.is_empty() && !skip_cte_columns {
25986 self.write("(");
25987 for (i, col) in e.columns.iter().enumerate() {
25988 if i > 0 {
25989 self.write(", ");
25990 }
25991 self.write(&col.name);
25992 }
25993 self.write(")");
25994 }
25995 if !e.key_expressions.is_empty() {
25997 self.write_space();
25998 self.write_keyword("USING KEY");
25999 self.write(" (");
26000 for (i, key) in e.key_expressions.iter().enumerate() {
26001 if i > 0 {
26002 self.write(", ");
26003 }
26004 self.write(&key.name);
26005 }
26006 self.write(")");
26007 }
26008 self.write_space();
26009 self.write_keyword("AS");
26010 self.write_space();
26011 if let Some(materialized) = e.materialized {
26012 if materialized {
26013 self.write_keyword("MATERIALIZED");
26014 } else {
26015 self.write_keyword("NOT MATERIALIZED");
26016 }
26017 self.write_space();
26018 }
26019 self.write("(");
26020 self.generate_expression(&e.this)?;
26021 self.write(")");
26022 Ok(())
26023 }
26024
26025 fn generate_cube(&mut self, e: &Cube) -> Result<()> {
26026 if e.expressions.is_empty() {
26028 self.write_keyword("WITH CUBE");
26029 } else {
26030 self.write_keyword("CUBE");
26031 self.write("(");
26032 for (i, expr) in e.expressions.iter().enumerate() {
26033 if i > 0 {
26034 self.write(", ");
26035 }
26036 self.generate_expression(expr)?;
26037 }
26038 self.write(")");
26039 }
26040 Ok(())
26041 }
26042
26043 fn generate_current_datetime(&mut self, e: &CurrentDatetime) -> Result<()> {
26044 self.write_keyword("CURRENT_DATETIME");
26046 if let Some(this) = &e.this {
26047 self.write("(");
26048 self.generate_expression(this)?;
26049 self.write(")");
26050 }
26051 Ok(())
26052 }
26053
26054 fn generate_current_schema(&mut self, _e: &CurrentSchema) -> Result<()> {
26055 self.write_keyword("CURRENT_SCHEMA");
26057 Ok(())
26058 }
26059
26060 fn generate_current_schemas(&mut self, e: &CurrentSchemas) -> Result<()> {
26061 self.write_keyword("CURRENT_SCHEMAS");
26063 self.write("(");
26064 if let Some(this) = &e.this {
26065 self.generate_expression(this)?;
26066 }
26067 self.write(")");
26068 Ok(())
26069 }
26070
26071 fn generate_current_user(&mut self, e: &CurrentUser) -> Result<()> {
26072 self.write_keyword("CURRENT_USER");
26074 let needs_parens = e.this.is_some()
26076 || matches!(
26077 self.config.dialect,
26078 Some(DialectType::Snowflake)
26079 | Some(DialectType::Spark)
26080 | Some(DialectType::Hive)
26081 | Some(DialectType::DuckDB)
26082 | Some(DialectType::BigQuery)
26083 | Some(DialectType::MySQL)
26084 | Some(DialectType::Databricks)
26085 );
26086 if needs_parens {
26087 self.write("()");
26088 }
26089 Ok(())
26090 }
26091
26092 fn generate_d_pipe(&mut self, e: &DPipe) -> Result<()> {
26093 if self.config.dialect == Some(DialectType::Solr) {
26095 self.generate_expression(&e.this)?;
26096 self.write(" ");
26097 self.write_keyword("OR");
26098 self.write(" ");
26099 self.generate_expression(&e.expression)?;
26100 } else if self.config.dialect == Some(DialectType::MySQL) {
26101 self.generate_mysql_concat_from_dpipe(e)?;
26102 } else {
26103 self.generate_expression(&e.this)?;
26105 self.write(" || ");
26106 self.generate_expression(&e.expression)?;
26107 }
26108 Ok(())
26109 }
26110
26111 fn generate_data_blocksize_property(&mut self, e: &DataBlocksizeProperty) -> Result<()> {
26112 self.write_keyword("DATABLOCKSIZE");
26114 self.write("=");
26115 if let Some(size) = e.size {
26116 self.write(&size.to_string());
26117 if let Some(units) = &e.units {
26118 self.write_space();
26119 self.generate_expression(units)?;
26120 }
26121 } else if e.minimum.is_some() {
26122 self.write_keyword("MINIMUM");
26123 } else if e.maximum.is_some() {
26124 self.write_keyword("MAXIMUM");
26125 } else if e.default.is_some() {
26126 self.write_keyword("DEFAULT");
26127 }
26128 Ok(())
26129 }
26130
26131 fn generate_data_deletion_property(&mut self, e: &DataDeletionProperty) -> Result<()> {
26132 self.write_keyword("DATA_DELETION");
26134 self.write("=");
26135
26136 let is_on = matches!(&*e.on, Expression::Boolean(BooleanLiteral { value: true }));
26137 let has_options = e.filter_column.is_some() || e.retention_period.is_some();
26138
26139 if is_on {
26140 self.write_keyword("ON");
26141 if has_options {
26142 self.write("(");
26143 let mut first = true;
26144 if let Some(filter_column) = &e.filter_column {
26145 self.write_keyword("FILTER_COLUMN");
26146 self.write("=");
26147 self.generate_expression(filter_column)?;
26148 first = false;
26149 }
26150 if let Some(retention_period) = &e.retention_period {
26151 if !first {
26152 self.write(", ");
26153 }
26154 self.write_keyword("RETENTION_PERIOD");
26155 self.write("=");
26156 self.generate_expression(retention_period)?;
26157 }
26158 self.write(")");
26159 }
26160 } else {
26161 self.write_keyword("OFF");
26162 }
26163 Ok(())
26164 }
26165
26166 fn generate_date_func(&mut self, e: &UnaryFunc) -> Result<()> {
26170 use crate::dialects::DialectType;
26171 use crate::expressions::Literal;
26172
26173 match self.config.dialect {
26174 Some(DialectType::Exasol) => {
26176 self.write_keyword("TO_DATE");
26177 self.write("(");
26178 match &e.this {
26180 Expression::Literal(Literal::String(s)) => {
26181 self.write("'");
26182 self.write(s);
26183 self.write("'");
26184 }
26185 _ => {
26186 self.generate_expression(&e.this)?;
26187 }
26188 }
26189 self.write(")");
26190 }
26191 _ => {
26193 self.write_keyword("DATE");
26194 self.write("(");
26195 self.generate_expression(&e.this)?;
26196 self.write(")");
26197 }
26198 }
26199 Ok(())
26200 }
26201
26202 fn generate_date_bin(&mut self, e: &DateBin) -> Result<()> {
26203 self.write_keyword("DATE_BIN");
26205 self.write("(");
26206 self.generate_expression(&e.this)?;
26207 self.write(", ");
26208 self.generate_expression(&e.expression)?;
26209 if let Some(origin) = &e.origin {
26210 self.write(", ");
26211 self.generate_expression(origin)?;
26212 }
26213 self.write(")");
26214 Ok(())
26215 }
26216
26217 fn generate_date_format_column_constraint(
26218 &mut self,
26219 e: &DateFormatColumnConstraint,
26220 ) -> Result<()> {
26221 self.write_keyword("FORMAT");
26223 self.write_space();
26224 self.generate_expression(&e.this)?;
26225 Ok(())
26226 }
26227
26228 fn generate_date_from_parts(&mut self, e: &DateFromParts) -> Result<()> {
26229 self.write_keyword("DATE_FROM_PARTS");
26231 self.write("(");
26232 let mut first = true;
26233 if let Some(year) = &e.year {
26234 self.generate_expression(year)?;
26235 first = false;
26236 }
26237 if let Some(month) = &e.month {
26238 if !first {
26239 self.write(", ");
26240 }
26241 self.generate_expression(month)?;
26242 first = false;
26243 }
26244 if let Some(day) = &e.day {
26245 if !first {
26246 self.write(", ");
26247 }
26248 self.generate_expression(day)?;
26249 }
26250 self.write(")");
26251 Ok(())
26252 }
26253
26254 fn generate_datetime(&mut self, e: &Datetime) -> Result<()> {
26255 self.write_keyword("DATETIME");
26257 self.write("(");
26258 self.generate_expression(&e.this)?;
26259 if let Some(expr) = &e.expression {
26260 self.write(", ");
26261 self.generate_expression(expr)?;
26262 }
26263 self.write(")");
26264 Ok(())
26265 }
26266
26267 fn generate_datetime_add(&mut self, e: &DatetimeAdd) -> Result<()> {
26268 self.write_keyword("DATETIME_ADD");
26270 self.write("(");
26271 self.generate_expression(&e.this)?;
26272 self.write(", ");
26273 self.generate_expression(&e.expression)?;
26274 if let Some(unit) = &e.unit {
26275 self.write(", ");
26276 self.write_keyword(unit);
26277 }
26278 self.write(")");
26279 Ok(())
26280 }
26281
26282 fn generate_datetime_diff(&mut self, e: &DatetimeDiff) -> Result<()> {
26283 self.write_keyword("DATETIME_DIFF");
26285 self.write("(");
26286 self.generate_expression(&e.this)?;
26287 self.write(", ");
26288 self.generate_expression(&e.expression)?;
26289 if let Some(unit) = &e.unit {
26290 self.write(", ");
26291 self.write_keyword(unit);
26292 }
26293 self.write(")");
26294 Ok(())
26295 }
26296
26297 fn generate_datetime_sub(&mut self, e: &DatetimeSub) -> Result<()> {
26298 self.write_keyword("DATETIME_SUB");
26300 self.write("(");
26301 self.generate_expression(&e.this)?;
26302 self.write(", ");
26303 self.generate_expression(&e.expression)?;
26304 if let Some(unit) = &e.unit {
26305 self.write(", ");
26306 self.write_keyword(unit);
26307 }
26308 self.write(")");
26309 Ok(())
26310 }
26311
26312 fn generate_datetime_trunc(&mut self, e: &DatetimeTrunc) -> Result<()> {
26313 self.write_keyword("DATETIME_TRUNC");
26315 self.write("(");
26316 self.generate_expression(&e.this)?;
26317 self.write(", ");
26318 self.write_keyword(&e.unit);
26319 if let Some(zone) = &e.zone {
26320 self.write(", ");
26321 self.generate_expression(zone)?;
26322 }
26323 self.write(")");
26324 Ok(())
26325 }
26326
26327 fn generate_dayname(&mut self, e: &Dayname) -> Result<()> {
26328 self.write_keyword("DAYNAME");
26330 self.write("(");
26331 self.generate_expression(&e.this)?;
26332 self.write(")");
26333 Ok(())
26334 }
26335
26336 fn generate_declare(&mut self, e: &Declare) -> Result<()> {
26337 self.write_keyword("DECLARE");
26339 self.write_space();
26340 for (i, expr) in e.expressions.iter().enumerate() {
26341 if i > 0 {
26342 self.write(", ");
26343 }
26344 self.generate_expression(expr)?;
26345 }
26346 Ok(())
26347 }
26348
26349 fn generate_declare_item(&mut self, e: &DeclareItem) -> Result<()> {
26350 use crate::dialects::DialectType;
26351
26352 self.generate_expression(&e.this)?;
26354 for name in &e.additional_names {
26356 self.write(", ");
26357 self.generate_expression(name)?;
26358 }
26359 if let Some(kind) = &e.kind {
26360 self.write_space();
26361 match self.config.dialect {
26365 Some(DialectType::BigQuery) => {
26366 self.write(kind);
26367 }
26368 Some(DialectType::TSQL) => {
26369 let is_complex_table = kind.starts_with("TABLE")
26373 && (kind.contains("CLUSTERED") || kind.contains("INDEX"));
26374
26375 if is_complex_table {
26376 self.write(kind);
26378 } else {
26379 if !kind.starts_with("CURSOR") {
26381 self.write_keyword("AS");
26382 self.write_space();
26383 }
26384 if kind == "INT" {
26386 self.write("INTEGER");
26387 } else if kind.starts_with("TABLE") {
26388 let normalized = kind
26390 .replace(" INT ", " INTEGER ")
26391 .replace(" INT,", " INTEGER,")
26392 .replace(" INT)", " INTEGER)")
26393 .replace("(INT ", "(INTEGER ");
26394 self.write(&normalized);
26395 } else {
26396 self.write(kind);
26397 }
26398 }
26399 }
26400 _ => {
26401 if e.has_as {
26402 self.write_keyword("AS");
26403 self.write_space();
26404 }
26405 self.write(kind);
26406 }
26407 }
26408 }
26409 if let Some(default) = &e.default {
26410 match self.config.dialect {
26412 Some(DialectType::BigQuery) => {
26413 self.write_space();
26414 self.write_keyword("DEFAULT");
26415 self.write_space();
26416 }
26417 _ => {
26418 self.write(" = ");
26419 }
26420 }
26421 self.generate_expression(default)?;
26422 }
26423 Ok(())
26424 }
26425
26426 fn generate_decode_case(&mut self, e: &DecodeCase) -> Result<()> {
26427 self.write_keyword("DECODE");
26429 self.write("(");
26430 for (i, expr) in e.expressions.iter().enumerate() {
26431 if i > 0 {
26432 self.write(", ");
26433 }
26434 self.generate_expression(expr)?;
26435 }
26436 self.write(")");
26437 Ok(())
26438 }
26439
26440 fn generate_decompress_binary(&mut self, e: &DecompressBinary) -> Result<()> {
26441 self.write_keyword("DECOMPRESS");
26443 self.write("(");
26444 self.generate_expression(&e.this)?;
26445 self.write(", '");
26446 self.write(&e.method);
26447 self.write("')");
26448 Ok(())
26449 }
26450
26451 fn generate_decompress_string(&mut self, e: &DecompressString) -> Result<()> {
26452 self.write_keyword("DECOMPRESS");
26454 self.write("(");
26455 self.generate_expression(&e.this)?;
26456 self.write(", '");
26457 self.write(&e.method);
26458 self.write("')");
26459 Ok(())
26460 }
26461
26462 fn generate_decrypt(&mut self, e: &Decrypt) -> Result<()> {
26463 self.write_keyword("DECRYPT");
26465 self.write("(");
26466 self.generate_expression(&e.this)?;
26467 if let Some(passphrase) = &e.passphrase {
26468 self.write(", ");
26469 self.generate_expression(passphrase)?;
26470 }
26471 if let Some(aad) = &e.aad {
26472 self.write(", ");
26473 self.generate_expression(aad)?;
26474 }
26475 if let Some(method) = &e.encryption_method {
26476 self.write(", ");
26477 self.generate_expression(method)?;
26478 }
26479 self.write(")");
26480 Ok(())
26481 }
26482
26483 fn generate_decrypt_raw(&mut self, e: &DecryptRaw) -> Result<()> {
26484 self.write_keyword("DECRYPT_RAW");
26486 self.write("(");
26487 self.generate_expression(&e.this)?;
26488 if let Some(key) = &e.key {
26489 self.write(", ");
26490 self.generate_expression(key)?;
26491 }
26492 if let Some(iv) = &e.iv {
26493 self.write(", ");
26494 self.generate_expression(iv)?;
26495 }
26496 if let Some(aad) = &e.aad {
26497 self.write(", ");
26498 self.generate_expression(aad)?;
26499 }
26500 if let Some(method) = &e.encryption_method {
26501 self.write(", ");
26502 self.generate_expression(method)?;
26503 }
26504 self.write(")");
26505 Ok(())
26506 }
26507
26508 fn generate_definer_property(&mut self, e: &DefinerProperty) -> Result<()> {
26509 self.write_keyword("DEFINER");
26511 self.write(" = ");
26512 self.generate_expression(&e.this)?;
26513 Ok(())
26514 }
26515
26516 fn generate_detach(&mut self, e: &Detach) -> Result<()> {
26517 self.write_keyword("DETACH");
26519 if e.exists {
26520 self.write_keyword(" DATABASE IF EXISTS");
26521 }
26522 self.write_space();
26523 self.generate_expression(&e.this)?;
26524 Ok(())
26525 }
26526
26527 fn generate_dict_property(&mut self, e: &DictProperty) -> Result<()> {
26528 let property_name = match e.this.as_ref() {
26529 Expression::Identifier(id) => id.name.as_str(),
26530 Expression::Var(v) => v.this.as_str(),
26531 _ => "DICTIONARY",
26532 };
26533 self.write_keyword(property_name);
26534 self.write("(");
26535 self.write(&e.kind);
26536 if let Some(settings) = &e.settings {
26537 self.write("(");
26538 if let Expression::Tuple(t) = settings.as_ref() {
26539 if self.config.pretty && !t.expressions.is_empty() {
26540 self.write_newline();
26541 self.indent_level += 1;
26542 for (i, pair) in t.expressions.iter().enumerate() {
26543 if i > 0 {
26544 self.write(",");
26545 self.write_newline();
26546 }
26547 self.write_indent();
26548 if let Expression::Tuple(pair_tuple) = pair {
26549 if let Some(k) = pair_tuple.expressions.first() {
26550 self.generate_expression(k)?;
26551 }
26552 if let Some(v) = pair_tuple.expressions.get(1) {
26553 self.write(" ");
26554 self.generate_expression(v)?;
26555 }
26556 } else {
26557 self.generate_expression(pair)?;
26558 }
26559 }
26560 self.indent_level -= 1;
26561 self.write_newline();
26562 self.write_indent();
26563 } else {
26564 for (i, pair) in t.expressions.iter().enumerate() {
26565 if i > 0 {
26566 self.write(", ");
26567 }
26568 if let Expression::Tuple(pair_tuple) = pair {
26569 if let Some(k) = pair_tuple.expressions.first() {
26570 self.generate_expression(k)?;
26571 }
26572 if let Some(v) = pair_tuple.expressions.get(1) {
26573 self.write(" ");
26574 self.generate_expression(v)?;
26575 }
26576 } else {
26577 self.generate_expression(pair)?;
26578 }
26579 }
26580 }
26581 } else {
26582 self.generate_expression(settings)?;
26583 }
26584 self.write(")");
26585 } else if property_name.eq_ignore_ascii_case("LAYOUT") {
26586 self.write("()");
26587 }
26588 self.write(")");
26589 Ok(())
26590 }
26591
26592 fn generate_dict_range(&mut self, e: &DictRange) -> Result<()> {
26593 let property_name = match e.this.as_ref() {
26594 Expression::Identifier(id) => id.name.as_str(),
26595 Expression::Var(v) => v.this.as_str(),
26596 _ => "RANGE",
26597 };
26598 self.write_keyword(property_name);
26599 self.write("(");
26600 if let Some(min) = &e.min {
26601 self.write_keyword("MIN");
26602 self.write_space();
26603 self.generate_expression(min)?;
26604 }
26605 if let Some(max) = &e.max {
26606 self.write_space();
26607 self.write_keyword("MAX");
26608 self.write_space();
26609 self.generate_expression(max)?;
26610 }
26611 self.write(")");
26612 Ok(())
26613 }
26614
26615 fn generate_directory(&mut self, e: &Directory) -> Result<()> {
26616 if e.local.is_some() {
26618 self.write_keyword("LOCAL ");
26619 }
26620 self.write_keyword("DIRECTORY");
26621 self.write_space();
26622 self.generate_expression(&e.this)?;
26623 if let Some(row_format) = &e.row_format {
26624 self.write_space();
26625 self.generate_expression(row_format)?;
26626 }
26627 Ok(())
26628 }
26629
26630 fn generate_dist_key_property(&mut self, e: &DistKeyProperty) -> Result<()> {
26631 self.write_keyword("DISTKEY");
26633 self.write("(");
26634 self.generate_expression(&e.this)?;
26635 self.write(")");
26636 Ok(())
26637 }
26638
26639 fn generate_dist_style_property(&mut self, e: &DistStyleProperty) -> Result<()> {
26640 self.write_keyword("DISTSTYLE");
26642 self.write_space();
26643 self.generate_expression(&e.this)?;
26644 Ok(())
26645 }
26646
26647 fn generate_distribute_by(&mut self, e: &DistributeBy) -> Result<()> {
26648 self.write_keyword("DISTRIBUTE BY");
26650 self.write_space();
26651 for (i, expr) in e.expressions.iter().enumerate() {
26652 if i > 0 {
26653 self.write(", ");
26654 }
26655 self.generate_expression(expr)?;
26656 }
26657 Ok(())
26658 }
26659
26660 fn generate_distributed_by_property(&mut self, e: &DistributedByProperty) -> Result<()> {
26661 self.write_keyword("DISTRIBUTED BY");
26663 self.write_space();
26664 self.write(&e.kind);
26665 if !e.expressions.is_empty() {
26666 self.write(" (");
26667 for (i, expr) in e.expressions.iter().enumerate() {
26668 if i > 0 {
26669 self.write(", ");
26670 }
26671 self.generate_expression(expr)?;
26672 }
26673 self.write(")");
26674 }
26675 if let Some(buckets) = &e.buckets {
26676 self.write_space();
26677 self.write_keyword("BUCKETS");
26678 self.write_space();
26679 self.generate_expression(buckets)?;
26680 }
26681 if let Some(order) = &e.order {
26682 self.write_space();
26683 self.generate_expression(order)?;
26684 }
26685 Ok(())
26686 }
26687
26688 fn generate_dot_product(&mut self, e: &DotProduct) -> Result<()> {
26689 self.write_keyword("DOT_PRODUCT");
26691 self.write("(");
26692 self.generate_expression(&e.this)?;
26693 self.write(", ");
26694 self.generate_expression(&e.expression)?;
26695 self.write(")");
26696 Ok(())
26697 }
26698
26699 fn generate_drop_partition(&mut self, e: &DropPartition) -> Result<()> {
26700 self.write_keyword("DROP");
26702 if e.exists {
26703 self.write_keyword(" IF EXISTS ");
26704 } else {
26705 self.write_space();
26706 }
26707 for (i, expr) in e.expressions.iter().enumerate() {
26708 if i > 0 {
26709 self.write(", ");
26710 }
26711 self.generate_expression(expr)?;
26712 }
26713 Ok(())
26714 }
26715
26716 fn generate_duplicate_key_property(&mut self, e: &DuplicateKeyProperty) -> Result<()> {
26717 self.write_keyword("DUPLICATE KEY");
26719 self.write(" (");
26720 for (i, expr) in e.expressions.iter().enumerate() {
26721 if i > 0 {
26722 self.write(", ");
26723 }
26724 self.generate_expression(expr)?;
26725 }
26726 self.write(")");
26727 Ok(())
26728 }
26729
26730 fn generate_elt(&mut self, e: &Elt) -> Result<()> {
26731 self.write_keyword("ELT");
26733 self.write("(");
26734 self.generate_expression(&e.this)?;
26735 for expr in &e.expressions {
26736 self.write(", ");
26737 self.generate_expression(expr)?;
26738 }
26739 self.write(")");
26740 Ok(())
26741 }
26742
26743 fn generate_encode(&mut self, e: &Encode) -> Result<()> {
26744 self.write_keyword("ENCODE");
26746 self.write("(");
26747 self.generate_expression(&e.this)?;
26748 if let Some(charset) = &e.charset {
26749 self.write(", ");
26750 self.generate_expression(charset)?;
26751 }
26752 self.write(")");
26753 Ok(())
26754 }
26755
26756 fn generate_encode_property(&mut self, e: &EncodeProperty) -> Result<()> {
26757 if e.key.is_some() {
26759 self.write_keyword("KEY ");
26760 }
26761 self.write_keyword("ENCODE");
26762 self.write_space();
26763 self.generate_expression(&e.this)?;
26764 if !e.properties.is_empty() {
26765 self.write(" (");
26766 for (i, prop) in e.properties.iter().enumerate() {
26767 if i > 0 {
26768 self.write(", ");
26769 }
26770 self.generate_expression(prop)?;
26771 }
26772 self.write(")");
26773 }
26774 Ok(())
26775 }
26776
26777 fn generate_encrypt(&mut self, e: &Encrypt) -> Result<()> {
26778 self.write_keyword("ENCRYPT");
26780 self.write("(");
26781 self.generate_expression(&e.this)?;
26782 if let Some(passphrase) = &e.passphrase {
26783 self.write(", ");
26784 self.generate_expression(passphrase)?;
26785 }
26786 if let Some(aad) = &e.aad {
26787 self.write(", ");
26788 self.generate_expression(aad)?;
26789 }
26790 if let Some(method) = &e.encryption_method {
26791 self.write(", ");
26792 self.generate_expression(method)?;
26793 }
26794 self.write(")");
26795 Ok(())
26796 }
26797
26798 fn generate_encrypt_raw(&mut self, e: &EncryptRaw) -> Result<()> {
26799 self.write_keyword("ENCRYPT_RAW");
26801 self.write("(");
26802 self.generate_expression(&e.this)?;
26803 if let Some(key) = &e.key {
26804 self.write(", ");
26805 self.generate_expression(key)?;
26806 }
26807 if let Some(iv) = &e.iv {
26808 self.write(", ");
26809 self.generate_expression(iv)?;
26810 }
26811 if let Some(aad) = &e.aad {
26812 self.write(", ");
26813 self.generate_expression(aad)?;
26814 }
26815 if let Some(method) = &e.encryption_method {
26816 self.write(", ");
26817 self.generate_expression(method)?;
26818 }
26819 self.write(")");
26820 Ok(())
26821 }
26822
26823 fn generate_engine_property(&mut self, e: &EngineProperty) -> Result<()> {
26824 self.write_keyword("ENGINE");
26826 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
26827 self.write("=");
26828 } else {
26829 self.write(" = ");
26830 }
26831 self.generate_expression(&e.this)?;
26832 Ok(())
26833 }
26834
26835 fn generate_enviroment_property(&mut self, e: &EnviromentProperty) -> Result<()> {
26836 self.write_keyword("ENVIRONMENT");
26838 self.write(" (");
26839 for (i, expr) in e.expressions.iter().enumerate() {
26840 if i > 0 {
26841 self.write(", ");
26842 }
26843 self.generate_expression(expr)?;
26844 }
26845 self.write(")");
26846 Ok(())
26847 }
26848
26849 fn generate_ephemeral_column_constraint(
26850 &mut self,
26851 e: &EphemeralColumnConstraint,
26852 ) -> Result<()> {
26853 self.write_keyword("EPHEMERAL");
26855 if let Some(this) = &e.this {
26856 self.write_space();
26857 self.generate_expression(this)?;
26858 }
26859 Ok(())
26860 }
26861
26862 fn generate_equal_null(&mut self, e: &EqualNull) -> Result<()> {
26863 self.write_keyword("EQUAL_NULL");
26865 self.write("(");
26866 self.generate_expression(&e.this)?;
26867 self.write(", ");
26868 self.generate_expression(&e.expression)?;
26869 self.write(")");
26870 Ok(())
26871 }
26872
26873 fn generate_euclidean_distance(&mut self, e: &EuclideanDistance) -> Result<()> {
26874 use crate::dialects::DialectType;
26875
26876 match self.config.dialect {
26878 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
26879 self.generate_expression(&e.this)?;
26880 self.write(" <-> ");
26881 self.generate_expression(&e.expression)?;
26882 }
26883 _ => {
26884 self.write_keyword("EUCLIDEAN_DISTANCE");
26886 self.write("(");
26887 self.generate_expression(&e.this)?;
26888 self.write(", ");
26889 self.generate_expression(&e.expression)?;
26890 self.write(")");
26891 }
26892 }
26893 Ok(())
26894 }
26895
26896 fn generate_execute_as_property(&mut self, e: &ExecuteAsProperty) -> Result<()> {
26897 self.write_keyword("EXECUTE AS");
26899 self.write_space();
26900 self.generate_expression(&e.this)?;
26901 Ok(())
26902 }
26903
26904 fn generate_export(&mut self, e: &Export) -> Result<()> {
26905 self.write_keyword("EXPORT DATA");
26907 if let Some(connection) = &e.connection {
26908 self.write_space();
26909 self.write_keyword("WITH CONNECTION");
26910 self.write_space();
26911 self.generate_expression(connection)?;
26912 }
26913 if !e.options.is_empty() {
26914 self.write_space();
26915 self.generate_options_clause(&e.options)?;
26916 }
26917 self.write_space();
26918 self.write_keyword("AS");
26919 self.write_space();
26920 self.generate_expression(&e.this)?;
26921 Ok(())
26922 }
26923
26924 fn generate_external_property(&mut self, e: &ExternalProperty) -> Result<()> {
26925 self.write_keyword("EXTERNAL");
26927 if let Some(this) = &e.this {
26928 self.write_space();
26929 self.generate_expression(this)?;
26930 }
26931 Ok(())
26932 }
26933
26934 fn generate_fallback_property(&mut self, e: &FallbackProperty) -> Result<()> {
26935 if e.no.is_some() {
26937 self.write_keyword("NO ");
26938 }
26939 self.write_keyword("FALLBACK");
26940 if e.protection.is_some() {
26941 self.write_keyword(" PROTECTION");
26942 }
26943 Ok(())
26944 }
26945
26946 fn generate_farm_fingerprint(&mut self, e: &FarmFingerprint) -> Result<()> {
26947 self.write_keyword("FARM_FINGERPRINT");
26949 self.write("(");
26950 for (i, expr) in e.expressions.iter().enumerate() {
26951 if i > 0 {
26952 self.write(", ");
26953 }
26954 self.generate_expression(expr)?;
26955 }
26956 self.write(")");
26957 Ok(())
26958 }
26959
26960 fn generate_features_at_time(&mut self, e: &FeaturesAtTime) -> Result<()> {
26961 self.write_keyword("FEATURES_AT_TIME");
26963 self.write("(");
26964 self.generate_expression(&e.this)?;
26965 if let Some(time) = &e.time {
26966 self.write(", ");
26967 self.generate_expression(time)?;
26968 }
26969 if let Some(num_rows) = &e.num_rows {
26970 self.write(", ");
26971 self.generate_expression(num_rows)?;
26972 }
26973 if let Some(ignore_nulls) = &e.ignore_feature_nulls {
26974 self.write(", ");
26975 self.generate_expression(ignore_nulls)?;
26976 }
26977 self.write(")");
26978 Ok(())
26979 }
26980
26981 fn generate_fetch(&mut self, e: &Fetch) -> Result<()> {
26982 let use_limit = !e.percent
26984 && !e.with_ties
26985 && e.count.is_some()
26986 && matches!(
26987 self.config.dialect,
26988 Some(DialectType::Spark)
26989 | Some(DialectType::Hive)
26990 | Some(DialectType::DuckDB)
26991 | Some(DialectType::SQLite)
26992 | Some(DialectType::MySQL)
26993 | Some(DialectType::BigQuery)
26994 | Some(DialectType::Databricks)
26995 | Some(DialectType::StarRocks)
26996 | Some(DialectType::Doris)
26997 | Some(DialectType::Athena)
26998 | Some(DialectType::ClickHouse)
26999 );
27000
27001 if use_limit {
27002 self.write_keyword("LIMIT");
27003 self.write_space();
27004 self.generate_expression(e.count.as_ref().unwrap())?;
27005 return Ok(());
27006 }
27007
27008 self.write_keyword("FETCH");
27010 if !e.direction.is_empty() {
27011 self.write_space();
27012 self.write_keyword(&e.direction);
27013 }
27014 if let Some(count) = &e.count {
27015 self.write_space();
27016 self.generate_expression(count)?;
27017 }
27018 if e.percent {
27020 self.write_keyword(" PERCENT");
27021 }
27022 if e.rows {
27023 self.write_keyword(" ROWS");
27024 }
27025 if e.with_ties {
27026 self.write_keyword(" WITH TIES");
27027 } else if e.rows {
27028 self.write_keyword(" ONLY");
27029 } else {
27030 self.write_keyword(" ROWS ONLY");
27031 }
27032 Ok(())
27033 }
27034
27035 fn generate_file_format_property(&mut self, e: &FileFormatProperty) -> Result<()> {
27036 if e.hive_format.is_some() {
27040 self.write_keyword("STORED AS");
27042 self.write_space();
27043 if let Some(this) = &e.this {
27044 if let Expression::Identifier(id) = this.as_ref() {
27046 self.write_keyword(&id.name.to_uppercase());
27047 } else {
27048 self.generate_expression(this)?;
27049 }
27050 }
27051 } else if matches!(self.config.dialect, Some(DialectType::Hive)) {
27052 self.write_keyword("STORED AS");
27054 self.write_space();
27055 if let Some(this) = &e.this {
27056 if let Expression::Identifier(id) = this.as_ref() {
27057 self.write_keyword(&id.name.to_uppercase());
27058 } else {
27059 self.generate_expression(this)?;
27060 }
27061 }
27062 } else if matches!(
27063 self.config.dialect,
27064 Some(DialectType::Spark) | Some(DialectType::Databricks)
27065 ) {
27066 self.write_keyword("USING");
27068 self.write_space();
27069 if let Some(this) = &e.this {
27070 self.generate_expression(this)?;
27071 }
27072 } else {
27073 self.write_keyword("FILE_FORMAT");
27075 self.write(" = ");
27076 if let Some(this) = &e.this {
27077 self.generate_expression(this)?;
27078 } else if !e.expressions.is_empty() {
27079 self.write("(");
27080 for (i, expr) in e.expressions.iter().enumerate() {
27081 if i > 0 {
27082 self.write(", ");
27083 }
27084 self.generate_expression(expr)?;
27085 }
27086 self.write(")");
27087 }
27088 }
27089 Ok(())
27090 }
27091
27092 fn generate_filter(&mut self, e: &Filter) -> Result<()> {
27093 self.generate_expression(&e.this)?;
27095 self.write_space();
27096 self.write_keyword("FILTER");
27097 self.write("(");
27098 self.write_keyword("WHERE");
27099 self.write_space();
27100 self.generate_expression(&e.expression)?;
27101 self.write(")");
27102 Ok(())
27103 }
27104
27105 fn generate_float64(&mut self, e: &Float64) -> Result<()> {
27106 self.write_keyword("FLOAT64");
27108 self.write("(");
27109 self.generate_expression(&e.this)?;
27110 if let Some(expr) = &e.expression {
27111 self.write(", ");
27112 self.generate_expression(expr)?;
27113 }
27114 self.write(")");
27115 Ok(())
27116 }
27117
27118 fn generate_for_in(&mut self, e: &ForIn) -> Result<()> {
27119 self.write_keyword("FOR");
27121 self.write_space();
27122 self.generate_expression(&e.this)?;
27123 self.write_space();
27124 self.write_keyword("DO");
27125 self.write_space();
27126 self.generate_expression(&e.expression)?;
27127 Ok(())
27128 }
27129
27130 fn generate_foreign_key(&mut self, e: &ForeignKey) -> Result<()> {
27131 self.write_keyword("FOREIGN KEY");
27133 if !e.expressions.is_empty() {
27134 self.write(" (");
27135 for (i, expr) in e.expressions.iter().enumerate() {
27136 if i > 0 {
27137 self.write(", ");
27138 }
27139 self.generate_expression(expr)?;
27140 }
27141 self.write(")");
27142 }
27143 if let Some(reference) = &e.reference {
27144 self.write_space();
27145 self.generate_expression(reference)?;
27146 }
27147 if let Some(delete) = &e.delete {
27148 self.write_space();
27149 self.write_keyword("ON DELETE");
27150 self.write_space();
27151 self.generate_expression(delete)?;
27152 }
27153 if let Some(update) = &e.update {
27154 self.write_space();
27155 self.write_keyword("ON UPDATE");
27156 self.write_space();
27157 self.generate_expression(update)?;
27158 }
27159 if !e.options.is_empty() {
27160 self.write_space();
27161 for (i, opt) in e.options.iter().enumerate() {
27162 if i > 0 {
27163 self.write_space();
27164 }
27165 self.generate_expression(opt)?;
27166 }
27167 }
27168 Ok(())
27169 }
27170
27171 fn generate_format(&mut self, e: &Format) -> Result<()> {
27172 self.write_keyword("FORMAT");
27174 self.write("(");
27175 self.generate_expression(&e.this)?;
27176 for expr in &e.expressions {
27177 self.write(", ");
27178 self.generate_expression(expr)?;
27179 }
27180 self.write(")");
27181 Ok(())
27182 }
27183
27184 fn generate_format_phrase(&mut self, e: &FormatPhrase) -> Result<()> {
27185 self.generate_expression(&e.this)?;
27187 self.write(" (");
27188 self.write_keyword("FORMAT");
27189 self.write(" '");
27190 self.write(&e.format);
27191 self.write("')");
27192 Ok(())
27193 }
27194
27195 fn generate_freespace_property(&mut self, e: &FreespaceProperty) -> Result<()> {
27196 self.write_keyword("FREESPACE");
27198 self.write("=");
27199 self.generate_expression(&e.this)?;
27200 if e.percent.is_some() {
27201 self.write_keyword(" PERCENT");
27202 }
27203 Ok(())
27204 }
27205
27206 fn generate_from(&mut self, e: &From) -> Result<()> {
27207 self.write_keyword("FROM");
27209 self.write_space();
27210
27211 use crate::dialects::DialectType;
27215 let has_tablesample = e
27216 .expressions
27217 .iter()
27218 .any(|expr| matches!(expr, Expression::TableSample(_)));
27219 let is_cross_join_dialect = matches!(
27220 self.config.dialect,
27221 Some(DialectType::BigQuery)
27222 | Some(DialectType::Hive)
27223 | Some(DialectType::Spark)
27224 | Some(DialectType::Databricks)
27225 | Some(DialectType::SQLite)
27226 | Some(DialectType::ClickHouse)
27227 );
27228 let source_is_same_as_target2 = self.config.source_dialect.is_some()
27229 && self.config.source_dialect == self.config.dialect;
27230 let source_is_cross_join_dialect2 = matches!(
27231 self.config.source_dialect,
27232 Some(DialectType::BigQuery)
27233 | Some(DialectType::Hive)
27234 | Some(DialectType::Spark)
27235 | Some(DialectType::Databricks)
27236 | Some(DialectType::SQLite)
27237 | Some(DialectType::ClickHouse)
27238 );
27239 let use_cross_join = !has_tablesample
27240 && is_cross_join_dialect
27241 && (source_is_same_as_target2
27242 || source_is_cross_join_dialect2
27243 || self.config.source_dialect.is_none());
27244
27245 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
27247
27248 for (i, expr) in e.expressions.iter().enumerate() {
27249 if i > 0 {
27250 if use_cross_join {
27251 self.write(" CROSS JOIN ");
27252 } else {
27253 self.write(", ");
27254 }
27255 }
27256 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
27257 self.write("(");
27258 self.generate_expression(expr)?;
27259 self.write(")");
27260 } else {
27261 self.generate_expression(expr)?;
27262 }
27263 }
27264 Ok(())
27265 }
27266
27267 fn generate_from_base(&mut self, e: &FromBase) -> Result<()> {
27268 self.write_keyword("FROM_BASE");
27270 self.write("(");
27271 self.generate_expression(&e.this)?;
27272 self.write(", ");
27273 self.generate_expression(&e.expression)?;
27274 self.write(")");
27275 Ok(())
27276 }
27277
27278 fn generate_from_time_zone(&mut self, e: &FromTimeZone) -> Result<()> {
27279 self.generate_expression(&e.this)?;
27281 if let Some(zone) = &e.zone {
27282 self.write_space();
27283 self.write_keyword("AT TIME ZONE");
27284 self.write_space();
27285 self.generate_expression(zone)?;
27286 self.write_space();
27287 self.write_keyword("AT TIME ZONE");
27288 self.write(" 'UTC'");
27289 }
27290 Ok(())
27291 }
27292
27293 fn generate_gap_fill(&mut self, e: &GapFill) -> Result<()> {
27294 self.write_keyword("GAP_FILL");
27296 self.write("(");
27297 self.generate_expression(&e.this)?;
27298 if let Some(ts_column) = &e.ts_column {
27299 self.write(", ");
27300 self.generate_expression(ts_column)?;
27301 }
27302 if let Some(bucket_width) = &e.bucket_width {
27303 self.write(", ");
27304 self.generate_expression(bucket_width)?;
27305 }
27306 if let Some(partitioning_columns) = &e.partitioning_columns {
27307 self.write(", ");
27308 self.generate_expression(partitioning_columns)?;
27309 }
27310 if let Some(value_columns) = &e.value_columns {
27311 self.write(", ");
27312 self.generate_expression(value_columns)?;
27313 }
27314 self.write(")");
27315 Ok(())
27316 }
27317
27318 fn generate_generate_date_array(&mut self, e: &GenerateDateArray) -> Result<()> {
27319 self.write_keyword("GENERATE_DATE_ARRAY");
27321 self.write("(");
27322 let mut first = true;
27323 if let Some(start) = &e.start {
27324 self.generate_expression(start)?;
27325 first = false;
27326 }
27327 if let Some(end) = &e.end {
27328 if !first {
27329 self.write(", ");
27330 }
27331 self.generate_expression(end)?;
27332 first = false;
27333 }
27334 if let Some(step) = &e.step {
27335 if !first {
27336 self.write(", ");
27337 }
27338 self.generate_expression(step)?;
27339 }
27340 self.write(")");
27341 Ok(())
27342 }
27343
27344 fn generate_generate_embedding(&mut self, e: &GenerateEmbedding) -> Result<()> {
27345 self.write_keyword("ML.GENERATE_EMBEDDING");
27347 self.write("(");
27348 self.generate_expression(&e.this)?;
27349 self.write(", ");
27350 self.generate_expression(&e.expression)?;
27351 if let Some(params) = &e.params_struct {
27352 self.write(", ");
27353 self.generate_expression(params)?;
27354 }
27355 self.write(")");
27356 Ok(())
27357 }
27358
27359 fn generate_generate_series(&mut self, e: &GenerateSeries) -> Result<()> {
27360 let fn_name = match self.config.dialect {
27362 Some(DialectType::Presto)
27363 | Some(DialectType::Trino)
27364 | Some(DialectType::Athena)
27365 | Some(DialectType::Spark)
27366 | Some(DialectType::Databricks)
27367 | Some(DialectType::Hive) => "SEQUENCE",
27368 _ => "GENERATE_SERIES",
27369 };
27370 self.write_keyword(fn_name);
27371 self.write("(");
27372 let mut first = true;
27373 if let Some(start) = &e.start {
27374 self.generate_expression(start)?;
27375 first = false;
27376 }
27377 if let Some(end) = &e.end {
27378 if !first {
27379 self.write(", ");
27380 }
27381 self.generate_expression(end)?;
27382 first = false;
27383 }
27384 if let Some(step) = &e.step {
27385 if !first {
27386 self.write(", ");
27387 }
27388 if matches!(
27391 self.config.dialect,
27392 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
27393 ) {
27394 if let Some(converted) = self.convert_week_interval_to_day(step) {
27395 self.generate_expression(&converted)?;
27396 } else {
27397 self.generate_expression(step)?;
27398 }
27399 } else {
27400 self.generate_expression(step)?;
27401 }
27402 }
27403 self.write(")");
27404 Ok(())
27405 }
27406
27407 fn convert_week_interval_to_day(&self, expr: &Expression) -> Option<Expression> {
27410 use crate::expressions::*;
27411 if let Expression::Interval(ref iv) = expr {
27412 let (is_week, count_str) = if let Some(IntervalUnitSpec::Simple {
27414 unit: IntervalUnit::Week,
27415 ..
27416 }) = &iv.unit
27417 {
27418 let count = match &iv.this {
27420 Some(Expression::Literal(Literal::String(s))) => s.clone(),
27421 Some(Expression::Literal(Literal::Number(s))) => s.clone(),
27422 _ => return None,
27423 };
27424 (true, count)
27425 } else if iv.unit.is_none() {
27426 if let Some(Expression::Literal(Literal::String(s))) = &iv.this {
27428 let parts: Vec<&str> = s.trim().splitn(2, char::is_whitespace).collect();
27429 if parts.len() == 2 && parts[1].eq_ignore_ascii_case("WEEK") {
27430 (true, parts[0].to_string())
27431 } else {
27432 (false, String::new())
27433 }
27434 } else {
27435 (false, String::new())
27436 }
27437 } else {
27438 (false, String::new())
27439 };
27440
27441 if is_week {
27442 let count_expr = Expression::Literal(Literal::Number(count_str));
27444 let day_interval = Expression::Interval(Box::new(Interval {
27445 this: Some(Expression::Literal(Literal::String("7".to_string()))),
27446 unit: Some(IntervalUnitSpec::Simple {
27447 unit: IntervalUnit::Day,
27448 use_plural: false,
27449 }),
27450 }));
27451 let mul = Expression::Mul(Box::new(BinaryOp {
27452 left: count_expr,
27453 right: day_interval,
27454 left_comments: vec![],
27455 operator_comments: vec![],
27456 trailing_comments: vec![],
27457 inferred_type: None,
27458 }));
27459 return Some(Expression::Paren(Box::new(Paren {
27460 this: mul,
27461 trailing_comments: vec![],
27462 })));
27463 }
27464 }
27465 None
27466 }
27467
27468 fn generate_generate_timestamp_array(&mut self, e: &GenerateTimestampArray) -> Result<()> {
27469 self.write_keyword("GENERATE_TIMESTAMP_ARRAY");
27471 self.write("(");
27472 let mut first = true;
27473 if let Some(start) = &e.start {
27474 self.generate_expression(start)?;
27475 first = false;
27476 }
27477 if let Some(end) = &e.end {
27478 if !first {
27479 self.write(", ");
27480 }
27481 self.generate_expression(end)?;
27482 first = false;
27483 }
27484 if let Some(step) = &e.step {
27485 if !first {
27486 self.write(", ");
27487 }
27488 self.generate_expression(step)?;
27489 }
27490 self.write(")");
27491 Ok(())
27492 }
27493
27494 fn generate_generated_as_identity_column_constraint(
27495 &mut self,
27496 e: &GeneratedAsIdentityColumnConstraint,
27497 ) -> Result<()> {
27498 use crate::dialects::DialectType;
27499
27500 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
27502 self.write_keyword("AUTOINCREMENT");
27503 if let Some(start) = &e.start {
27504 self.write_keyword(" START ");
27505 self.generate_expression(start)?;
27506 }
27507 if let Some(increment) = &e.increment {
27508 self.write_keyword(" INCREMENT ");
27509 self.generate_expression(increment)?;
27510 }
27511 return Ok(());
27512 }
27513
27514 self.write_keyword("GENERATED");
27516 if let Some(this) = &e.this {
27517 if let Expression::Boolean(b) = this.as_ref() {
27519 if b.value {
27520 self.write_keyword(" ALWAYS");
27521 } else {
27522 self.write_keyword(" BY DEFAULT");
27523 if e.on_null.is_some() {
27524 self.write_keyword(" ON NULL");
27525 }
27526 }
27527 } else {
27528 self.write_keyword(" ALWAYS");
27529 }
27530 }
27531 self.write_keyword(" AS IDENTITY");
27532 let has_options = e.start.is_some()
27534 || e.increment.is_some()
27535 || e.minvalue.is_some()
27536 || e.maxvalue.is_some();
27537 if has_options {
27538 self.write(" (");
27539 let mut first = true;
27540 if let Some(start) = &e.start {
27541 self.write_keyword("START WITH ");
27542 self.generate_expression(start)?;
27543 first = false;
27544 }
27545 if let Some(increment) = &e.increment {
27546 if !first {
27547 self.write(" ");
27548 }
27549 self.write_keyword("INCREMENT BY ");
27550 self.generate_expression(increment)?;
27551 first = false;
27552 }
27553 if let Some(minvalue) = &e.minvalue {
27554 if !first {
27555 self.write(" ");
27556 }
27557 self.write_keyword("MINVALUE ");
27558 self.generate_expression(minvalue)?;
27559 first = false;
27560 }
27561 if let Some(maxvalue) = &e.maxvalue {
27562 if !first {
27563 self.write(" ");
27564 }
27565 self.write_keyword("MAXVALUE ");
27566 self.generate_expression(maxvalue)?;
27567 }
27568 self.write(")");
27569 }
27570 Ok(())
27571 }
27572
27573 fn generate_generated_as_row_column_constraint(
27574 &mut self,
27575 e: &GeneratedAsRowColumnConstraint,
27576 ) -> Result<()> {
27577 self.write_keyword("GENERATED ALWAYS AS ROW ");
27579 if e.start.is_some() {
27580 self.write_keyword("START");
27581 } else {
27582 self.write_keyword("END");
27583 }
27584 if e.hidden.is_some() {
27585 self.write_keyword(" HIDDEN");
27586 }
27587 Ok(())
27588 }
27589
27590 fn generate_get(&mut self, e: &Get) -> Result<()> {
27591 self.write_keyword("GET");
27593 self.write_space();
27594 self.generate_expression(&e.this)?;
27595 if let Some(target) = &e.target {
27596 self.write_space();
27597 self.generate_expression(target)?;
27598 }
27599 for prop in &e.properties {
27600 self.write_space();
27601 self.generate_expression(prop)?;
27602 }
27603 Ok(())
27604 }
27605
27606 fn generate_get_extract(&mut self, e: &GetExtract) -> Result<()> {
27607 self.generate_expression(&e.this)?;
27609 self.write("[");
27610 self.generate_expression(&e.expression)?;
27611 self.write("]");
27612 Ok(())
27613 }
27614
27615 fn generate_getbit(&mut self, e: &Getbit) -> Result<()> {
27616 self.write_keyword("GETBIT");
27618 self.write("(");
27619 self.generate_expression(&e.this)?;
27620 self.write(", ");
27621 self.generate_expression(&e.expression)?;
27622 self.write(")");
27623 Ok(())
27624 }
27625
27626 fn generate_grant_principal(&mut self, e: &GrantPrincipal) -> Result<()> {
27627 if e.is_role {
27629 self.write_keyword("ROLE");
27630 self.write_space();
27631 } else if e.is_group {
27632 self.write_keyword("GROUP");
27633 self.write_space();
27634 }
27635 self.write(&e.name.name);
27636 Ok(())
27637 }
27638
27639 fn generate_grant_privilege(&mut self, e: &GrantPrivilege) -> Result<()> {
27640 self.generate_expression(&e.this)?;
27642 if !e.expressions.is_empty() {
27643 self.write("(");
27644 for (i, expr) in e.expressions.iter().enumerate() {
27645 if i > 0 {
27646 self.write(", ");
27647 }
27648 self.generate_expression(expr)?;
27649 }
27650 self.write(")");
27651 }
27652 Ok(())
27653 }
27654
27655 fn generate_group(&mut self, e: &Group) -> Result<()> {
27656 self.write_keyword("GROUP BY");
27658 match e.all {
27660 Some(true) => {
27661 self.write_space();
27662 self.write_keyword("ALL");
27663 }
27664 Some(false) => {
27665 self.write_space();
27666 self.write_keyword("DISTINCT");
27667 }
27668 None => {}
27669 }
27670 if !e.expressions.is_empty() {
27671 self.write_space();
27672 for (i, expr) in e.expressions.iter().enumerate() {
27673 if i > 0 {
27674 self.write(", ");
27675 }
27676 self.generate_expression(expr)?;
27677 }
27678 }
27679 if let Some(cube) = &e.cube {
27681 if !e.expressions.is_empty() {
27682 self.write(", ");
27683 } else {
27684 self.write_space();
27685 }
27686 self.generate_expression(cube)?;
27687 }
27688 if let Some(rollup) = &e.rollup {
27689 if !e.expressions.is_empty() || e.cube.is_some() {
27690 self.write(", ");
27691 } else {
27692 self.write_space();
27693 }
27694 self.generate_expression(rollup)?;
27695 }
27696 if let Some(grouping_sets) = &e.grouping_sets {
27697 if !e.expressions.is_empty() || e.cube.is_some() || e.rollup.is_some() {
27698 self.write(", ");
27699 } else {
27700 self.write_space();
27701 }
27702 self.generate_expression(grouping_sets)?;
27703 }
27704 if let Some(totals) = &e.totals {
27705 self.write_space();
27706 self.write_keyword("WITH TOTALS");
27707 self.generate_expression(totals)?;
27708 }
27709 Ok(())
27710 }
27711
27712 fn generate_group_by(&mut self, e: &GroupBy) -> Result<()> {
27713 self.write_keyword("GROUP BY");
27715 match e.all {
27717 Some(true) => {
27718 self.write_space();
27719 self.write_keyword("ALL");
27720 }
27721 Some(false) => {
27722 self.write_space();
27723 self.write_keyword("DISTINCT");
27724 }
27725 None => {}
27726 }
27727
27728 let mut trailing_cube = false;
27731 let mut trailing_rollup = false;
27732 let mut regular_expressions: Vec<&Expression> = Vec::new();
27733
27734 for expr in &e.expressions {
27735 match expr {
27736 Expression::Cube(c) if c.expressions.is_empty() => {
27737 trailing_cube = true;
27738 }
27739 Expression::Rollup(r) if r.expressions.is_empty() => {
27740 trailing_rollup = true;
27741 }
27742 _ => {
27743 regular_expressions.push(expr);
27744 }
27745 }
27746 }
27747
27748 if self.config.pretty {
27750 self.write_newline();
27751 self.indent_level += 1;
27752 for (i, expr) in regular_expressions.iter().enumerate() {
27753 if i > 0 {
27754 self.write(",");
27755 self.write_newline();
27756 }
27757 self.write_indent();
27758 self.generate_expression(expr)?;
27759 }
27760 self.indent_level -= 1;
27761 } else {
27762 self.write_space();
27763 for (i, expr) in regular_expressions.iter().enumerate() {
27764 if i > 0 {
27765 self.write(", ");
27766 }
27767 self.generate_expression(expr)?;
27768 }
27769 }
27770
27771 if trailing_cube {
27773 self.write_space();
27774 self.write_keyword("WITH CUBE");
27775 } else if trailing_rollup {
27776 self.write_space();
27777 self.write_keyword("WITH ROLLUP");
27778 }
27779
27780 if e.totals {
27782 self.write_space();
27783 self.write_keyword("WITH TOTALS");
27784 }
27785
27786 Ok(())
27787 }
27788
27789 fn generate_grouping(&mut self, e: &Grouping) -> Result<()> {
27790 self.write_keyword("GROUPING");
27792 self.write("(");
27793 for (i, expr) in e.expressions.iter().enumerate() {
27794 if i > 0 {
27795 self.write(", ");
27796 }
27797 self.generate_expression(expr)?;
27798 }
27799 self.write(")");
27800 Ok(())
27801 }
27802
27803 fn generate_grouping_id(&mut self, e: &GroupingId) -> Result<()> {
27804 self.write_keyword("GROUPING_ID");
27806 self.write("(");
27807 for (i, expr) in e.expressions.iter().enumerate() {
27808 if i > 0 {
27809 self.write(", ");
27810 }
27811 self.generate_expression(expr)?;
27812 }
27813 self.write(")");
27814 Ok(())
27815 }
27816
27817 fn generate_grouping_sets(&mut self, e: &GroupingSets) -> Result<()> {
27818 self.write_keyword("GROUPING SETS");
27820 self.write(" (");
27821 for (i, expr) in e.expressions.iter().enumerate() {
27822 if i > 0 {
27823 self.write(", ");
27824 }
27825 self.generate_expression(expr)?;
27826 }
27827 self.write(")");
27828 Ok(())
27829 }
27830
27831 fn generate_hash_agg(&mut self, e: &HashAgg) -> Result<()> {
27832 self.write_keyword("HASH_AGG");
27834 self.write("(");
27835 self.generate_expression(&e.this)?;
27836 for expr in &e.expressions {
27837 self.write(", ");
27838 self.generate_expression(expr)?;
27839 }
27840 self.write(")");
27841 Ok(())
27842 }
27843
27844 fn generate_having(&mut self, e: &Having) -> Result<()> {
27845 self.write_keyword("HAVING");
27847 self.write_space();
27848 self.generate_expression(&e.this)?;
27849 Ok(())
27850 }
27851
27852 fn generate_having_max(&mut self, e: &HavingMax) -> Result<()> {
27853 self.generate_expression(&e.this)?;
27855 self.write_space();
27856 self.write_keyword("HAVING");
27857 self.write_space();
27858 if e.max.is_some() {
27859 self.write_keyword("MAX");
27860 } else {
27861 self.write_keyword("MIN");
27862 }
27863 self.write_space();
27864 self.generate_expression(&e.expression)?;
27865 Ok(())
27866 }
27867
27868 fn generate_heredoc(&mut self, e: &Heredoc) -> Result<()> {
27869 use crate::dialects::DialectType;
27870 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
27872 if let Expression::Literal(Literal::String(ref s)) = *e.this {
27874 return self.generate_string_literal(s);
27875 }
27876 }
27877 if matches!(
27879 self.config.dialect,
27880 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
27881 ) {
27882 self.write("$");
27883 if let Some(tag) = &e.tag {
27884 self.generate_expression(tag)?;
27885 }
27886 self.write("$");
27887 self.generate_expression(&e.this)?;
27888 self.write("$");
27889 if let Some(tag) = &e.tag {
27890 self.generate_expression(tag)?;
27891 }
27892 self.write("$");
27893 return Ok(());
27894 }
27895 self.write("$");
27897 if let Some(tag) = &e.tag {
27898 self.generate_expression(tag)?;
27899 }
27900 self.write("$");
27901 self.generate_expression(&e.this)?;
27902 self.write("$");
27903 if let Some(tag) = &e.tag {
27904 self.generate_expression(tag)?;
27905 }
27906 self.write("$");
27907 Ok(())
27908 }
27909
27910 fn generate_hex_encode(&mut self, e: &HexEncode) -> Result<()> {
27911 self.write_keyword("HEX_ENCODE");
27913 self.write("(");
27914 self.generate_expression(&e.this)?;
27915 self.write(")");
27916 Ok(())
27917 }
27918
27919 fn generate_historical_data(&mut self, e: &HistoricalData) -> Result<()> {
27920 match e.this.as_ref() {
27923 Expression::Identifier(id) => self.write(&id.name),
27924 other => self.generate_expression(other)?,
27925 }
27926 self.write(" (");
27927 self.write(&e.kind);
27928 self.write(" => ");
27929 self.generate_expression(&e.expression)?;
27930 self.write(")");
27931 Ok(())
27932 }
27933
27934 fn generate_hll(&mut self, e: &Hll) -> Result<()> {
27935 self.write_keyword("HLL");
27937 self.write("(");
27938 self.generate_expression(&e.this)?;
27939 for expr in &e.expressions {
27940 self.write(", ");
27941 self.generate_expression(expr)?;
27942 }
27943 self.write(")");
27944 Ok(())
27945 }
27946
27947 fn generate_in_out_column_constraint(&mut self, e: &InOutColumnConstraint) -> Result<()> {
27948 if e.input_.is_some() && e.output.is_some() {
27950 self.write_keyword("IN OUT");
27951 } else if e.input_.is_some() {
27952 self.write_keyword("IN");
27953 } else if e.output.is_some() {
27954 self.write_keyword("OUT");
27955 }
27956 Ok(())
27957 }
27958
27959 fn generate_include_property(&mut self, e: &IncludeProperty) -> Result<()> {
27960 self.write_keyword("INCLUDE");
27962 self.write_space();
27963 self.generate_expression(&e.this)?;
27964 if let Some(column_def) = &e.column_def {
27965 self.write_space();
27966 self.generate_expression(column_def)?;
27967 }
27968 if let Some(alias) = &e.alias {
27969 self.write_space();
27970 self.write_keyword("AS");
27971 self.write_space();
27972 self.write(alias);
27973 }
27974 Ok(())
27975 }
27976
27977 fn generate_index(&mut self, e: &Index) -> Result<()> {
27978 if e.unique {
27980 self.write_keyword("UNIQUE");
27981 self.write_space();
27982 }
27983 if e.primary.is_some() {
27984 self.write_keyword("PRIMARY");
27985 self.write_space();
27986 }
27987 if e.amp.is_some() {
27988 self.write_keyword("AMP");
27989 self.write_space();
27990 }
27991 if e.table.is_none() {
27992 self.write_keyword("INDEX");
27993 self.write_space();
27994 }
27995 if let Some(name) = &e.this {
27996 self.generate_expression(name)?;
27997 self.write_space();
27998 }
27999 if let Some(table) = &e.table {
28000 self.write_keyword("ON");
28001 self.write_space();
28002 self.generate_expression(table)?;
28003 }
28004 if !e.params.is_empty() {
28005 self.write("(");
28006 for (i, param) in e.params.iter().enumerate() {
28007 if i > 0 {
28008 self.write(", ");
28009 }
28010 self.generate_expression(param)?;
28011 }
28012 self.write(")");
28013 }
28014 Ok(())
28015 }
28016
28017 fn generate_index_column_constraint(&mut self, e: &IndexColumnConstraint) -> Result<()> {
28018 if let Some(kind) = &e.kind {
28020 self.write(kind);
28021 self.write_space();
28022 }
28023 self.write_keyword("INDEX");
28024 if let Some(this) = &e.this {
28025 self.write_space();
28026 self.generate_expression(this)?;
28027 }
28028 if let Some(index_type) = &e.index_type {
28029 self.write_space();
28030 self.write_keyword("USING");
28031 self.write_space();
28032 self.generate_expression(index_type)?;
28033 }
28034 if !e.expressions.is_empty() {
28035 self.write(" (");
28036 for (i, expr) in e.expressions.iter().enumerate() {
28037 if i > 0 {
28038 self.write(", ");
28039 }
28040 self.generate_expression(expr)?;
28041 }
28042 self.write(")");
28043 }
28044 for opt in &e.options {
28045 self.write_space();
28046 self.generate_expression(opt)?;
28047 }
28048 Ok(())
28049 }
28050
28051 fn generate_index_constraint_option(&mut self, e: &IndexConstraintOption) -> Result<()> {
28052 if let Some(key_block_size) = &e.key_block_size {
28054 self.write_keyword("KEY_BLOCK_SIZE");
28055 self.write(" = ");
28056 self.generate_expression(key_block_size)?;
28057 } else if let Some(using) = &e.using {
28058 self.write_keyword("USING");
28059 self.write_space();
28060 self.generate_expression(using)?;
28061 } else if let Some(parser) = &e.parser {
28062 self.write_keyword("WITH PARSER");
28063 self.write_space();
28064 self.generate_expression(parser)?;
28065 } else if let Some(comment) = &e.comment {
28066 self.write_keyword("COMMENT");
28067 self.write_space();
28068 self.generate_expression(comment)?;
28069 } else if let Some(visible) = &e.visible {
28070 self.generate_expression(visible)?;
28071 } else if let Some(engine_attr) = &e.engine_attr {
28072 self.write_keyword("ENGINE_ATTRIBUTE");
28073 self.write(" = ");
28074 self.generate_expression(engine_attr)?;
28075 } else if let Some(secondary_engine_attr) = &e.secondary_engine_attr {
28076 self.write_keyword("SECONDARY_ENGINE_ATTRIBUTE");
28077 self.write(" = ");
28078 self.generate_expression(secondary_engine_attr)?;
28079 }
28080 Ok(())
28081 }
28082
28083 fn generate_index_parameters(&mut self, e: &IndexParameters) -> Result<()> {
28084 if let Some(using) = &e.using {
28086 self.write_keyword("USING");
28087 self.write_space();
28088 self.generate_expression(using)?;
28089 }
28090 if !e.columns.is_empty() {
28091 self.write("(");
28092 for (i, col) in e.columns.iter().enumerate() {
28093 if i > 0 {
28094 self.write(", ");
28095 }
28096 self.generate_expression(col)?;
28097 }
28098 self.write(")");
28099 }
28100 if let Some(partition_by) = &e.partition_by {
28101 self.write_space();
28102 self.write_keyword("PARTITION BY");
28103 self.write_space();
28104 self.generate_expression(partition_by)?;
28105 }
28106 if let Some(where_) = &e.where_ {
28107 self.write_space();
28108 self.generate_expression(where_)?;
28109 }
28110 if let Some(include) = &e.include {
28111 self.write_space();
28112 self.write_keyword("INCLUDE");
28113 self.write(" (");
28114 self.generate_expression(include)?;
28115 self.write(")");
28116 }
28117 if let Some(with_storage) = &e.with_storage {
28118 self.write_space();
28119 self.write_keyword("WITH");
28120 self.write(" (");
28121 self.generate_expression(with_storage)?;
28122 self.write(")");
28123 }
28124 if let Some(tablespace) = &e.tablespace {
28125 self.write_space();
28126 self.write_keyword("USING INDEX TABLESPACE");
28127 self.write_space();
28128 self.generate_expression(tablespace)?;
28129 }
28130 Ok(())
28131 }
28132
28133 fn generate_index_table_hint(&mut self, e: &IndexTableHint) -> Result<()> {
28134 if let Expression::Identifier(id) = &*e.this {
28138 self.write_keyword(&id.name);
28139 } else {
28140 self.generate_expression(&e.this)?;
28141 }
28142 self.write_space();
28143 self.write_keyword("INDEX");
28144 if let Some(target) = &e.target {
28145 self.write_space();
28146 self.write_keyword("FOR");
28147 self.write_space();
28148 if let Expression::Identifier(id) = &**target {
28149 self.write_keyword(&id.name);
28150 } else {
28151 self.generate_expression(target)?;
28152 }
28153 }
28154 self.write(" (");
28156 for (i, expr) in e.expressions.iter().enumerate() {
28157 if i > 0 {
28158 self.write(", ");
28159 }
28160 self.generate_expression(expr)?;
28161 }
28162 self.write(")");
28163 Ok(())
28164 }
28165
28166 fn generate_inherits_property(&mut self, e: &InheritsProperty) -> Result<()> {
28167 self.write_keyword("INHERITS");
28169 self.write(" (");
28170 for (i, expr) in e.expressions.iter().enumerate() {
28171 if i > 0 {
28172 self.write(", ");
28173 }
28174 self.generate_expression(expr)?;
28175 }
28176 self.write(")");
28177 Ok(())
28178 }
28179
28180 fn generate_input_model_property(&mut self, e: &InputModelProperty) -> Result<()> {
28181 self.write_keyword("INPUT");
28183 self.write("(");
28184 self.generate_expression(&e.this)?;
28185 self.write(")");
28186 Ok(())
28187 }
28188
28189 fn generate_input_output_format(&mut self, e: &InputOutputFormat) -> Result<()> {
28190 if let Some(input_format) = &e.input_format {
28192 self.write_keyword("INPUTFORMAT");
28193 self.write_space();
28194 self.generate_expression(input_format)?;
28195 }
28196 if let Some(output_format) = &e.output_format {
28197 if e.input_format.is_some() {
28198 self.write(" ");
28199 }
28200 self.write_keyword("OUTPUTFORMAT");
28201 self.write_space();
28202 self.generate_expression(output_format)?;
28203 }
28204 Ok(())
28205 }
28206
28207 fn generate_install(&mut self, e: &Install) -> Result<()> {
28208 if e.force.is_some() {
28210 self.write_keyword("FORCE");
28211 self.write_space();
28212 }
28213 self.write_keyword("INSTALL");
28214 self.write_space();
28215 self.generate_expression(&e.this)?;
28216 if let Some(from) = &e.from_ {
28217 self.write_space();
28218 self.write_keyword("FROM");
28219 self.write_space();
28220 self.generate_expression(from)?;
28221 }
28222 Ok(())
28223 }
28224
28225 fn generate_interval_op(&mut self, e: &IntervalOp) -> Result<()> {
28226 self.write_keyword("INTERVAL");
28228 self.write_space();
28229 self.generate_expression(&e.expression)?;
28231 if let Some(unit) = &e.unit {
28232 self.write_space();
28233 self.write(unit);
28234 }
28235 Ok(())
28236 }
28237
28238 fn generate_interval_span(&mut self, e: &IntervalSpan) -> Result<()> {
28239 self.write(&format!("{:?}", e.this).to_uppercase());
28241 self.write_space();
28242 self.write_keyword("TO");
28243 self.write_space();
28244 self.write(&format!("{:?}", e.expression).to_uppercase());
28245 Ok(())
28246 }
28247
28248 fn generate_into_clause(&mut self, e: &IntoClause) -> Result<()> {
28249 self.write_keyword("INTO");
28251 if e.temporary {
28252 self.write_keyword(" TEMPORARY");
28253 }
28254 if e.unlogged.is_some() {
28255 self.write_keyword(" UNLOGGED");
28256 }
28257 if let Some(this) = &e.this {
28258 self.write_space();
28259 self.generate_expression(this)?;
28260 }
28261 if !e.expressions.is_empty() {
28262 self.write(" (");
28263 for (i, expr) in e.expressions.iter().enumerate() {
28264 if i > 0 {
28265 self.write(", ");
28266 }
28267 self.generate_expression(expr)?;
28268 }
28269 self.write(")");
28270 }
28271 Ok(())
28272 }
28273
28274 fn generate_introducer(&mut self, e: &Introducer) -> Result<()> {
28275 self.generate_expression(&e.this)?;
28277 self.write_space();
28278 self.generate_expression(&e.expression)?;
28279 Ok(())
28280 }
28281
28282 fn generate_isolated_loading_property(&mut self, e: &IsolatedLoadingProperty) -> Result<()> {
28283 self.write_keyword("WITH");
28285 if e.no.is_some() {
28286 self.write_keyword(" NO");
28287 }
28288 if e.concurrent.is_some() {
28289 self.write_keyword(" CONCURRENT");
28290 }
28291 self.write_keyword(" ISOLATED LOADING");
28292 if let Some(target) = &e.target {
28293 self.write_space();
28294 self.generate_expression(target)?;
28295 }
28296 Ok(())
28297 }
28298
28299 fn generate_json(&mut self, e: &JSON) -> Result<()> {
28300 self.write_keyword("JSON");
28302 if let Some(this) = &e.this {
28303 self.write_space();
28304 self.generate_expression(this)?;
28305 }
28306 if let Some(with_) = &e.with_ {
28307 if let Expression::Boolean(b) = with_.as_ref() {
28309 if b.value {
28310 self.write_keyword(" WITH");
28311 } else {
28312 self.write_keyword(" WITHOUT");
28313 }
28314 }
28315 }
28316 if e.unique {
28317 self.write_keyword(" UNIQUE KEYS");
28318 }
28319 Ok(())
28320 }
28321
28322 fn generate_json_array(&mut self, e: &JSONArray) -> Result<()> {
28323 self.write_keyword("JSON_ARRAY");
28325 self.write("(");
28326 for (i, expr) in e.expressions.iter().enumerate() {
28327 if i > 0 {
28328 self.write(", ");
28329 }
28330 self.generate_expression(expr)?;
28331 }
28332 if let Some(null_handling) = &e.null_handling {
28333 self.write_space();
28334 self.generate_expression(null_handling)?;
28335 }
28336 if let Some(return_type) = &e.return_type {
28337 self.write_space();
28338 self.write_keyword("RETURNING");
28339 self.write_space();
28340 self.generate_expression(return_type)?;
28341 }
28342 if e.strict.is_some() {
28343 self.write_space();
28344 self.write_keyword("STRICT");
28345 }
28346 self.write(")");
28347 Ok(())
28348 }
28349
28350 fn generate_json_array_agg_struct(&mut self, e: &JSONArrayAgg) -> Result<()> {
28351 self.write_keyword("JSON_ARRAYAGG");
28353 self.write("(");
28354 self.generate_expression(&e.this)?;
28355 if let Some(order) = &e.order {
28356 self.write_space();
28357 if let Expression::OrderBy(ob) = order.as_ref() {
28359 self.write_keyword("ORDER BY");
28360 self.write_space();
28361 for (i, ord) in ob.expressions.iter().enumerate() {
28362 if i > 0 {
28363 self.write(", ");
28364 }
28365 self.generate_ordered(ord)?;
28366 }
28367 } else {
28368 self.generate_expression(order)?;
28370 }
28371 }
28372 if let Some(null_handling) = &e.null_handling {
28373 self.write_space();
28374 self.generate_expression(null_handling)?;
28375 }
28376 if let Some(return_type) = &e.return_type {
28377 self.write_space();
28378 self.write_keyword("RETURNING");
28379 self.write_space();
28380 self.generate_expression(return_type)?;
28381 }
28382 if e.strict.is_some() {
28383 self.write_space();
28384 self.write_keyword("STRICT");
28385 }
28386 self.write(")");
28387 Ok(())
28388 }
28389
28390 fn generate_json_object_agg_struct(&mut self, e: &JSONObjectAgg) -> Result<()> {
28391 self.write_keyword("JSON_OBJECTAGG");
28393 self.write("(");
28394 for (i, expr) in e.expressions.iter().enumerate() {
28395 if i > 0 {
28396 self.write(", ");
28397 }
28398 self.generate_expression(expr)?;
28399 }
28400 if let Some(null_handling) = &e.null_handling {
28401 self.write_space();
28402 self.generate_expression(null_handling)?;
28403 }
28404 if let Some(unique_keys) = &e.unique_keys {
28405 self.write_space();
28406 if let Expression::Boolean(b) = unique_keys.as_ref() {
28407 if b.value {
28408 self.write_keyword("WITH UNIQUE KEYS");
28409 } else {
28410 self.write_keyword("WITHOUT UNIQUE KEYS");
28411 }
28412 }
28413 }
28414 if let Some(return_type) = &e.return_type {
28415 self.write_space();
28416 self.write_keyword("RETURNING");
28417 self.write_space();
28418 self.generate_expression(return_type)?;
28419 }
28420 self.write(")");
28421 Ok(())
28422 }
28423
28424 fn generate_json_array_append(&mut self, e: &JSONArrayAppend) -> Result<()> {
28425 self.write_keyword("JSON_ARRAY_APPEND");
28427 self.write("(");
28428 self.generate_expression(&e.this)?;
28429 for expr in &e.expressions {
28430 self.write(", ");
28431 self.generate_expression(expr)?;
28432 }
28433 self.write(")");
28434 Ok(())
28435 }
28436
28437 fn generate_json_array_contains(&mut self, e: &JSONArrayContains) -> Result<()> {
28438 self.write_keyword("JSON_ARRAY_CONTAINS");
28440 self.write("(");
28441 self.generate_expression(&e.this)?;
28442 self.write(", ");
28443 self.generate_expression(&e.expression)?;
28444 self.write(")");
28445 Ok(())
28446 }
28447
28448 fn generate_json_array_insert(&mut self, e: &JSONArrayInsert) -> Result<()> {
28449 self.write_keyword("JSON_ARRAY_INSERT");
28451 self.write("(");
28452 self.generate_expression(&e.this)?;
28453 for expr in &e.expressions {
28454 self.write(", ");
28455 self.generate_expression(expr)?;
28456 }
28457 self.write(")");
28458 Ok(())
28459 }
28460
28461 fn generate_jsonb_exists(&mut self, e: &JSONBExists) -> Result<()> {
28462 self.write_keyword("JSONB_EXISTS");
28464 self.write("(");
28465 self.generate_expression(&e.this)?;
28466 if let Some(path) = &e.path {
28467 self.write(", ");
28468 self.generate_expression(path)?;
28469 }
28470 self.write(")");
28471 Ok(())
28472 }
28473
28474 fn generate_jsonb_extract_scalar(&mut self, e: &JSONBExtractScalar) -> Result<()> {
28475 self.write_keyword("JSONB_EXTRACT_SCALAR");
28477 self.write("(");
28478 self.generate_expression(&e.this)?;
28479 self.write(", ");
28480 self.generate_expression(&e.expression)?;
28481 self.write(")");
28482 Ok(())
28483 }
28484
28485 fn generate_jsonb_object_agg(&mut self, e: &JSONBObjectAgg) -> Result<()> {
28486 self.write_keyword("JSONB_OBJECT_AGG");
28488 self.write("(");
28489 self.generate_expression(&e.this)?;
28490 self.write(", ");
28491 self.generate_expression(&e.expression)?;
28492 self.write(")");
28493 Ok(())
28494 }
28495
28496 fn generate_json_column_def(&mut self, e: &JSONColumnDef) -> Result<()> {
28497 if let Some(nested_schema) = &e.nested_schema {
28499 self.write_keyword("NESTED");
28500 if let Some(path) = &e.path {
28501 self.write_space();
28502 self.write_keyword("PATH");
28503 self.write_space();
28504 self.generate_expression(path)?;
28505 }
28506 self.write_space();
28507 self.generate_expression(nested_schema)?;
28508 } else {
28509 if let Some(this) = &e.this {
28510 self.generate_expression(this)?;
28511 }
28512 if let Some(kind) = &e.kind {
28513 self.write_space();
28514 self.write(kind);
28515 }
28516 if let Some(path) = &e.path {
28517 self.write_space();
28518 self.write_keyword("PATH");
28519 self.write_space();
28520 self.generate_expression(path)?;
28521 }
28522 if e.ordinality.is_some() {
28523 self.write_keyword(" FOR ORDINALITY");
28524 }
28525 }
28526 Ok(())
28527 }
28528
28529 fn generate_json_exists(&mut self, e: &JSONExists) -> Result<()> {
28530 self.write_keyword("JSON_EXISTS");
28532 self.write("(");
28533 self.generate_expression(&e.this)?;
28534 if let Some(path) = &e.path {
28535 self.write(", ");
28536 self.generate_expression(path)?;
28537 }
28538 if let Some(passing) = &e.passing {
28539 self.write_space();
28540 self.write_keyword("PASSING");
28541 self.write_space();
28542 self.generate_expression(passing)?;
28543 }
28544 if let Some(on_condition) = &e.on_condition {
28545 self.write_space();
28546 self.generate_expression(on_condition)?;
28547 }
28548 self.write(")");
28549 Ok(())
28550 }
28551
28552 fn generate_json_cast(&mut self, e: &JSONCast) -> Result<()> {
28553 self.generate_expression(&e.this)?;
28554 self.write(".:");
28555 self.generate_data_type(&e.to)?;
28556 Ok(())
28557 }
28558
28559 fn generate_json_extract_array(&mut self, e: &JSONExtractArray) -> Result<()> {
28560 self.write_keyword("JSON_EXTRACT_ARRAY");
28562 self.write("(");
28563 self.generate_expression(&e.this)?;
28564 if let Some(expr) = &e.expression {
28565 self.write(", ");
28566 self.generate_expression(expr)?;
28567 }
28568 self.write(")");
28569 Ok(())
28570 }
28571
28572 fn generate_json_extract_quote(&mut self, e: &JSONExtractQuote) -> Result<()> {
28573 if let Some(option) = &e.option {
28575 self.generate_expression(option)?;
28576 self.write_space();
28577 }
28578 self.write_keyword("QUOTES");
28579 if e.scalar.is_some() {
28580 self.write_keyword(" SCALAR_ONLY");
28581 }
28582 Ok(())
28583 }
28584
28585 fn generate_json_extract_scalar(&mut self, e: &JSONExtractScalar) -> Result<()> {
28586 self.write_keyword("JSON_EXTRACT_SCALAR");
28588 self.write("(");
28589 self.generate_expression(&e.this)?;
28590 self.write(", ");
28591 self.generate_expression(&e.expression)?;
28592 self.write(")");
28593 Ok(())
28594 }
28595
28596 fn generate_json_extract_path(&mut self, e: &JSONExtract) -> Result<()> {
28597 if e.variant_extract.is_some() {
28601 use crate::dialects::DialectType;
28602 if matches!(self.config.dialect, Some(DialectType::Databricks)) {
28603 self.generate_expression(&e.this)?;
28605 self.write(":");
28606 match e.expression.as_ref() {
28609 Expression::Literal(Literal::String(s)) => {
28610 self.write(s);
28611 }
28612 _ => {
28613 self.generate_expression(&e.expression)?;
28615 }
28616 }
28617 } else {
28618 self.write_keyword("GET_PATH");
28620 self.write("(");
28621 self.generate_expression(&e.this)?;
28622 self.write(", ");
28623 self.generate_expression(&e.expression)?;
28624 self.write(")");
28625 }
28626 } else {
28627 self.write_keyword("JSON_EXTRACT");
28628 self.write("(");
28629 self.generate_expression(&e.this)?;
28630 self.write(", ");
28631 self.generate_expression(&e.expression)?;
28632 for expr in &e.expressions {
28633 self.write(", ");
28634 self.generate_expression(expr)?;
28635 }
28636 self.write(")");
28637 }
28638 Ok(())
28639 }
28640
28641 fn generate_json_format(&mut self, e: &JSONFormat) -> Result<()> {
28642 if let Some(this) = &e.this {
28645 self.generate_expression(this)?;
28646 self.write_space();
28647 }
28648 self.write_keyword("FORMAT JSON");
28649 Ok(())
28650 }
28651
28652 fn generate_json_key_value(&mut self, e: &JSONKeyValue) -> Result<()> {
28653 self.generate_expression(&e.this)?;
28655 self.write(": ");
28656 self.generate_expression(&e.expression)?;
28657 Ok(())
28658 }
28659
28660 fn generate_json_keys(&mut self, e: &JSONKeys) -> Result<()> {
28661 self.write_keyword("JSON_KEYS");
28663 self.write("(");
28664 self.generate_expression(&e.this)?;
28665 if let Some(expr) = &e.expression {
28666 self.write(", ");
28667 self.generate_expression(expr)?;
28668 }
28669 for expr in &e.expressions {
28670 self.write(", ");
28671 self.generate_expression(expr)?;
28672 }
28673 self.write(")");
28674 Ok(())
28675 }
28676
28677 fn generate_json_keys_at_depth(&mut self, e: &JSONKeysAtDepth) -> Result<()> {
28678 self.write_keyword("JSON_KEYS");
28680 self.write("(");
28681 self.generate_expression(&e.this)?;
28682 if let Some(expr) = &e.expression {
28683 self.write(", ");
28684 self.generate_expression(expr)?;
28685 }
28686 self.write(")");
28687 Ok(())
28688 }
28689
28690 fn generate_json_path_expr(&mut self, e: &JSONPath) -> Result<()> {
28691 let mut path_str = String::new();
28694 for expr in &e.expressions {
28695 match expr {
28696 Expression::JSONPathRoot(_) => {
28697 path_str.push('$');
28698 }
28699 Expression::JSONPathKey(k) => {
28700 if let Expression::Literal(crate::expressions::Literal::String(s)) =
28702 k.this.as_ref()
28703 {
28704 path_str.push('.');
28705 let needs_quoting = s.chars().any(|c| !c.is_alphanumeric() && c != '_');
28707 if needs_quoting {
28708 path_str.push('"');
28709 path_str.push_str(s);
28710 path_str.push('"');
28711 } else {
28712 path_str.push_str(s);
28713 }
28714 }
28715 }
28716 Expression::JSONPathSubscript(s) => {
28717 if let Expression::Literal(crate::expressions::Literal::Number(n)) =
28719 s.this.as_ref()
28720 {
28721 path_str.push('[');
28722 path_str.push_str(n);
28723 path_str.push(']');
28724 }
28725 }
28726 _ => {
28727 let mut temp_gen = Self::with_config(self.config.clone());
28729 temp_gen.generate_expression(expr)?;
28730 path_str.push_str(&temp_gen.output);
28731 }
28732 }
28733 }
28734 self.write("'");
28736 self.write(&path_str);
28737 self.write("'");
28738 Ok(())
28739 }
28740
28741 fn generate_json_path_filter(&mut self, e: &JSONPathFilter) -> Result<()> {
28742 self.write("?(");
28744 self.generate_expression(&e.this)?;
28745 self.write(")");
28746 Ok(())
28747 }
28748
28749 fn generate_json_path_key(&mut self, e: &JSONPathKey) -> Result<()> {
28750 self.write(".");
28752 self.generate_expression(&e.this)?;
28753 Ok(())
28754 }
28755
28756 fn generate_json_path_recursive(&mut self, e: &JSONPathRecursive) -> Result<()> {
28757 self.write("..");
28759 if let Some(this) = &e.this {
28760 self.generate_expression(this)?;
28761 }
28762 Ok(())
28763 }
28764
28765 fn generate_json_path_root(&mut self) -> Result<()> {
28766 self.write("$");
28768 Ok(())
28769 }
28770
28771 fn generate_json_path_script(&mut self, e: &JSONPathScript) -> Result<()> {
28772 self.write("(");
28774 self.generate_expression(&e.this)?;
28775 self.write(")");
28776 Ok(())
28777 }
28778
28779 fn generate_json_path_selector(&mut self, e: &JSONPathSelector) -> Result<()> {
28780 self.generate_expression(&e.this)?;
28782 Ok(())
28783 }
28784
28785 fn generate_json_path_slice(&mut self, e: &JSONPathSlice) -> Result<()> {
28786 self.write("[");
28788 if let Some(start) = &e.start {
28789 self.generate_expression(start)?;
28790 }
28791 self.write(":");
28792 if let Some(end) = &e.end {
28793 self.generate_expression(end)?;
28794 }
28795 if let Some(step) = &e.step {
28796 self.write(":");
28797 self.generate_expression(step)?;
28798 }
28799 self.write("]");
28800 Ok(())
28801 }
28802
28803 fn generate_json_path_subscript(&mut self, e: &JSONPathSubscript) -> Result<()> {
28804 self.write("[");
28806 self.generate_expression(&e.this)?;
28807 self.write("]");
28808 Ok(())
28809 }
28810
28811 fn generate_json_path_union(&mut self, e: &JSONPathUnion) -> Result<()> {
28812 self.write("[");
28814 for (i, expr) in e.expressions.iter().enumerate() {
28815 if i > 0 {
28816 self.write(", ");
28817 }
28818 self.generate_expression(expr)?;
28819 }
28820 self.write("]");
28821 Ok(())
28822 }
28823
28824 fn generate_json_remove(&mut self, e: &JSONRemove) -> Result<()> {
28825 self.write_keyword("JSON_REMOVE");
28827 self.write("(");
28828 self.generate_expression(&e.this)?;
28829 for expr in &e.expressions {
28830 self.write(", ");
28831 self.generate_expression(expr)?;
28832 }
28833 self.write(")");
28834 Ok(())
28835 }
28836
28837 fn generate_json_schema(&mut self, e: &JSONSchema) -> Result<()> {
28838 self.write_keyword("COLUMNS");
28841 self.write("(");
28842
28843 if self.config.pretty && !e.expressions.is_empty() {
28844 let mut expr_strings: Vec<String> = Vec::with_capacity(e.expressions.len());
28846 for expr in &e.expressions {
28847 let mut temp_gen = Generator::with_config(self.config.clone());
28848 temp_gen.generate_expression(expr)?;
28849 expr_strings.push(temp_gen.output);
28850 }
28851
28852 if self.too_wide(&expr_strings) {
28854 self.write_newline();
28856 self.indent_level += 1;
28857 for (i, expr_str) in expr_strings.iter().enumerate() {
28858 if i > 0 {
28859 self.write(",");
28860 self.write_newline();
28861 }
28862 self.write_indent();
28863 self.write(expr_str);
28864 }
28865 self.write_newline();
28866 self.indent_level -= 1;
28867 self.write_indent();
28868 } else {
28869 for (i, expr_str) in expr_strings.iter().enumerate() {
28871 if i > 0 {
28872 self.write(", ");
28873 }
28874 self.write(expr_str);
28875 }
28876 }
28877 } else {
28878 for (i, expr) in e.expressions.iter().enumerate() {
28880 if i > 0 {
28881 self.write(", ");
28882 }
28883 self.generate_expression(expr)?;
28884 }
28885 }
28886 self.write(")");
28887 Ok(())
28888 }
28889
28890 fn generate_json_set(&mut self, e: &JSONSet) -> Result<()> {
28891 self.write_keyword("JSON_SET");
28893 self.write("(");
28894 self.generate_expression(&e.this)?;
28895 for expr in &e.expressions {
28896 self.write(", ");
28897 self.generate_expression(expr)?;
28898 }
28899 self.write(")");
28900 Ok(())
28901 }
28902
28903 fn generate_json_strip_nulls(&mut self, e: &JSONStripNulls) -> Result<()> {
28904 self.write_keyword("JSON_STRIP_NULLS");
28906 self.write("(");
28907 self.generate_expression(&e.this)?;
28908 if let Some(expr) = &e.expression {
28909 self.write(", ");
28910 self.generate_expression(expr)?;
28911 }
28912 self.write(")");
28913 Ok(())
28914 }
28915
28916 fn generate_json_table(&mut self, e: &JSONTable) -> Result<()> {
28917 self.write_keyword("JSON_TABLE");
28919 self.write("(");
28920 self.generate_expression(&e.this)?;
28921 if let Some(path) = &e.path {
28922 self.write(", ");
28923 self.generate_expression(path)?;
28924 }
28925 if let Some(error_handling) = &e.error_handling {
28926 self.write_space();
28927 self.generate_expression(error_handling)?;
28928 }
28929 if let Some(empty_handling) = &e.empty_handling {
28930 self.write_space();
28931 self.generate_expression(empty_handling)?;
28932 }
28933 if let Some(schema) = &e.schema {
28934 self.write_space();
28935 self.generate_expression(schema)?;
28936 }
28937 self.write(")");
28938 Ok(())
28939 }
28940
28941 fn generate_json_type(&mut self, e: &JSONType) -> Result<()> {
28942 self.write_keyword("JSON_TYPE");
28944 self.write("(");
28945 self.generate_expression(&e.this)?;
28946 self.write(")");
28947 Ok(())
28948 }
28949
28950 fn generate_json_value(&mut self, e: &JSONValue) -> Result<()> {
28951 self.write_keyword("JSON_VALUE");
28953 self.write("(");
28954 self.generate_expression(&e.this)?;
28955 if let Some(path) = &e.path {
28956 self.write(", ");
28957 self.generate_expression(path)?;
28958 }
28959 if let Some(returning) = &e.returning {
28960 self.write_space();
28961 self.write_keyword("RETURNING");
28962 self.write_space();
28963 self.generate_expression(returning)?;
28964 }
28965 if let Some(on_condition) = &e.on_condition {
28966 self.write_space();
28967 self.generate_expression(on_condition)?;
28968 }
28969 self.write(")");
28970 Ok(())
28971 }
28972
28973 fn generate_json_value_array(&mut self, e: &JSONValueArray) -> Result<()> {
28974 self.write_keyword("JSON_VALUE_ARRAY");
28976 self.write("(");
28977 self.generate_expression(&e.this)?;
28978 self.write(")");
28979 Ok(())
28980 }
28981
28982 fn generate_jarowinkler_similarity(&mut self, e: &JarowinklerSimilarity) -> Result<()> {
28983 self.write_keyword("JAROWINKLER_SIMILARITY");
28985 self.write("(");
28986 self.generate_expression(&e.this)?;
28987 self.write(", ");
28988 self.generate_expression(&e.expression)?;
28989 self.write(")");
28990 Ok(())
28991 }
28992
28993 fn generate_join_hint(&mut self, e: &JoinHint) -> Result<()> {
28994 self.generate_expression(&e.this)?;
28996 self.write("(");
28997 for (i, expr) in e.expressions.iter().enumerate() {
28998 if i > 0 {
28999 self.write(", ");
29000 }
29001 self.generate_expression(expr)?;
29002 }
29003 self.write(")");
29004 Ok(())
29005 }
29006
29007 fn generate_journal_property(&mut self, e: &JournalProperty) -> Result<()> {
29008 if e.no.is_some() {
29010 self.write_keyword("NO ");
29011 }
29012 if let Some(local) = &e.local {
29013 self.generate_expression(local)?;
29014 self.write_space();
29015 }
29016 if e.dual.is_some() {
29017 self.write_keyword("DUAL ");
29018 }
29019 if e.before.is_some() {
29020 self.write_keyword("BEFORE ");
29021 }
29022 if e.after.is_some() {
29023 self.write_keyword("AFTER ");
29024 }
29025 self.write_keyword("JOURNAL");
29026 Ok(())
29027 }
29028
29029 fn generate_language_property(&mut self, e: &LanguageProperty) -> Result<()> {
29030 self.write_keyword("LANGUAGE");
29032 self.write_space();
29033 self.generate_expression(&e.this)?;
29034 Ok(())
29035 }
29036
29037 fn generate_lateral(&mut self, e: &Lateral) -> Result<()> {
29038 if e.view.is_some() {
29040 self.write_keyword("LATERAL VIEW");
29042 if e.outer.is_some() {
29043 self.write_space();
29044 self.write_keyword("OUTER");
29045 }
29046 self.write_space();
29047 self.generate_expression(&e.this)?;
29048 if let Some(alias) = &e.alias {
29049 self.write_space();
29050 self.write(alias);
29051 }
29052 } else {
29053 self.write_keyword("LATERAL");
29055 self.write_space();
29056 self.generate_expression(&e.this)?;
29057 if e.ordinality.is_some() {
29058 self.write_space();
29059 self.write_keyword("WITH ORDINALITY");
29060 }
29061 if let Some(alias) = &e.alias {
29062 self.write_space();
29063 self.write_keyword("AS");
29064 self.write_space();
29065 self.write(alias);
29066 if !e.column_aliases.is_empty() {
29067 self.write("(");
29068 for (i, col) in e.column_aliases.iter().enumerate() {
29069 if i > 0 {
29070 self.write(", ");
29071 }
29072 self.write(col);
29073 }
29074 self.write(")");
29075 }
29076 }
29077 }
29078 Ok(())
29079 }
29080
29081 fn generate_like_property(&mut self, e: &LikeProperty) -> Result<()> {
29082 self.write_keyword("LIKE");
29084 self.write_space();
29085 self.generate_expression(&e.this)?;
29086 for expr in &e.expressions {
29087 self.write_space();
29088 self.generate_expression(expr)?;
29089 }
29090 Ok(())
29091 }
29092
29093 fn generate_limit(&mut self, e: &Limit) -> Result<()> {
29094 self.write_keyword("LIMIT");
29095 self.write_space();
29096 self.write_limit_expr(&e.this)?;
29097 if e.percent {
29098 self.write_space();
29099 self.write_keyword("PERCENT");
29100 }
29101 for comment in &e.comments {
29103 self.write(" ");
29104 self.write_formatted_comment(comment);
29105 }
29106 Ok(())
29107 }
29108
29109 fn generate_limit_options(&mut self, e: &LimitOptions) -> Result<()> {
29110 if e.percent.is_some() {
29112 self.write_keyword(" PERCENT");
29113 }
29114 if e.rows.is_some() {
29115 self.write_keyword(" ROWS");
29116 }
29117 if e.with_ties.is_some() {
29118 self.write_keyword(" WITH TIES");
29119 } else if e.rows.is_some() {
29120 self.write_keyword(" ONLY");
29121 }
29122 Ok(())
29123 }
29124
29125 fn generate_list(&mut self, e: &List) -> Result<()> {
29126 use crate::dialects::DialectType;
29127 let is_materialize = matches!(self.config.dialect, Some(DialectType::Materialize));
29128
29129 if e.expressions.len() == 1 {
29131 if let Expression::Select(_) = &e.expressions[0] {
29132 self.write_keyword("LIST");
29133 self.write("(");
29134 self.generate_expression(&e.expressions[0])?;
29135 self.write(")");
29136 return Ok(());
29137 }
29138 }
29139
29140 if is_materialize {
29142 self.write_keyword("LIST");
29143 self.write("[");
29144 for (i, expr) in e.expressions.iter().enumerate() {
29145 if i > 0 {
29146 self.write(", ");
29147 }
29148 self.generate_expression(expr)?;
29149 }
29150 self.write("]");
29151 } else {
29152 self.write_keyword("LIST");
29154 self.write("(");
29155 for (i, expr) in e.expressions.iter().enumerate() {
29156 if i > 0 {
29157 self.write(", ");
29158 }
29159 self.generate_expression(expr)?;
29160 }
29161 self.write(")");
29162 }
29163 Ok(())
29164 }
29165
29166 fn generate_tomap(&mut self, e: &ToMap) -> Result<()> {
29167 if let Expression::Select(_) = &*e.this {
29169 self.write_keyword("MAP");
29170 self.write("(");
29171 self.generate_expression(&e.this)?;
29172 self.write(")");
29173 return Ok(());
29174 }
29175
29176 let is_duckdb = matches!(self.config.dialect, Some(DialectType::DuckDB));
29177
29178 self.write_keyword("MAP");
29180 if is_duckdb {
29181 self.write(" {");
29182 } else {
29183 self.write("[");
29184 }
29185 if let Expression::Struct(s) = &*e.this {
29186 for (i, (_, expr)) in s.fields.iter().enumerate() {
29187 if i > 0 {
29188 self.write(", ");
29189 }
29190 if let Expression::PropertyEQ(op) = expr {
29191 self.generate_expression(&op.left)?;
29192 if is_duckdb {
29193 self.write(": ");
29194 } else {
29195 self.write(" => ");
29196 }
29197 self.generate_expression(&op.right)?;
29198 } else {
29199 self.generate_expression(expr)?;
29200 }
29201 }
29202 }
29203 if is_duckdb {
29204 self.write("}");
29205 } else {
29206 self.write("]");
29207 }
29208 Ok(())
29209 }
29210
29211 fn generate_localtime(&mut self, e: &Localtime) -> Result<()> {
29212 self.write_keyword("LOCALTIME");
29214 if let Some(precision) = &e.this {
29215 self.write("(");
29216 self.generate_expression(precision)?;
29217 self.write(")");
29218 }
29219 Ok(())
29220 }
29221
29222 fn generate_localtimestamp(&mut self, e: &Localtimestamp) -> Result<()> {
29223 self.write_keyword("LOCALTIMESTAMP");
29225 if let Some(precision) = &e.this {
29226 self.write("(");
29227 self.generate_expression(precision)?;
29228 self.write(")");
29229 }
29230 Ok(())
29231 }
29232
29233 fn generate_location_property(&mut self, e: &LocationProperty) -> Result<()> {
29234 self.write_keyword("LOCATION");
29236 self.write_space();
29237 self.generate_expression(&e.this)?;
29238 Ok(())
29239 }
29240
29241 fn generate_lock(&mut self, e: &Lock) -> Result<()> {
29242 if e.update.is_some() {
29244 if e.key.is_some() {
29245 self.write_keyword("FOR NO KEY UPDATE");
29246 } else {
29247 self.write_keyword("FOR UPDATE");
29248 }
29249 } else {
29250 if e.key.is_some() {
29251 self.write_keyword("FOR KEY SHARE");
29252 } else {
29253 self.write_keyword("FOR SHARE");
29254 }
29255 }
29256 if !e.expressions.is_empty() {
29257 self.write_keyword(" OF ");
29258 for (i, expr) in e.expressions.iter().enumerate() {
29259 if i > 0 {
29260 self.write(", ");
29261 }
29262 self.generate_expression(expr)?;
29263 }
29264 }
29265 if let Some(wait) = &e.wait {
29270 match wait.as_ref() {
29271 Expression::Boolean(b) => {
29272 if b.value {
29273 self.write_keyword(" NOWAIT");
29274 } else {
29275 self.write_keyword(" SKIP LOCKED");
29276 }
29277 }
29278 _ => {
29279 self.write_keyword(" WAIT ");
29281 self.generate_expression(wait)?;
29282 }
29283 }
29284 }
29285 Ok(())
29286 }
29287
29288 fn generate_lock_property(&mut self, e: &LockProperty) -> Result<()> {
29289 self.write_keyword("LOCK");
29291 self.write_space();
29292 self.generate_expression(&e.this)?;
29293 Ok(())
29294 }
29295
29296 fn generate_locking_property(&mut self, e: &LockingProperty) -> Result<()> {
29297 self.write_keyword("LOCKING");
29299 self.write_space();
29300 self.write(&e.kind);
29301 if let Some(this) = &e.this {
29302 self.write_space();
29303 self.generate_expression(this)?;
29304 }
29305 if let Some(for_or_in) = &e.for_or_in {
29306 self.write_space();
29307 self.generate_expression(for_or_in)?;
29308 }
29309 if let Some(lock_type) = &e.lock_type {
29310 self.write_space();
29311 self.generate_expression(lock_type)?;
29312 }
29313 if e.override_.is_some() {
29314 self.write_keyword(" OVERRIDE");
29315 }
29316 Ok(())
29317 }
29318
29319 fn generate_locking_statement(&mut self, e: &LockingStatement) -> Result<()> {
29320 self.generate_expression(&e.this)?;
29322 self.write_space();
29323 self.generate_expression(&e.expression)?;
29324 Ok(())
29325 }
29326
29327 fn generate_log_property(&mut self, e: &LogProperty) -> Result<()> {
29328 if e.no.is_some() {
29330 self.write_keyword("NO ");
29331 }
29332 self.write_keyword("LOG");
29333 Ok(())
29334 }
29335
29336 fn generate_md5_digest(&mut self, e: &MD5Digest) -> Result<()> {
29337 self.write_keyword("MD5");
29339 self.write("(");
29340 self.generate_expression(&e.this)?;
29341 for expr in &e.expressions {
29342 self.write(", ");
29343 self.generate_expression(expr)?;
29344 }
29345 self.write(")");
29346 Ok(())
29347 }
29348
29349 fn generate_ml_forecast(&mut self, e: &MLForecast) -> Result<()> {
29350 self.write_keyword("ML.FORECAST");
29352 self.write("(");
29353 self.generate_expression(&e.this)?;
29354 if let Some(expression) = &e.expression {
29355 self.write(", ");
29356 self.generate_expression(expression)?;
29357 }
29358 if let Some(params) = &e.params_struct {
29359 self.write(", ");
29360 self.generate_expression(params)?;
29361 }
29362 self.write(")");
29363 Ok(())
29364 }
29365
29366 fn generate_ml_translate(&mut self, e: &MLTranslate) -> Result<()> {
29367 self.write_keyword("ML.TRANSLATE");
29369 self.write("(");
29370 self.generate_expression(&e.this)?;
29371 self.write(", ");
29372 self.generate_expression(&e.expression)?;
29373 if let Some(params) = &e.params_struct {
29374 self.write(", ");
29375 self.generate_expression(params)?;
29376 }
29377 self.write(")");
29378 Ok(())
29379 }
29380
29381 fn generate_make_interval(&mut self, e: &MakeInterval) -> Result<()> {
29382 self.write_keyword("MAKE_INTERVAL");
29384 self.write("(");
29385 let mut first = true;
29386 if let Some(year) = &e.year {
29387 self.write("years => ");
29388 self.generate_expression(year)?;
29389 first = false;
29390 }
29391 if let Some(month) = &e.month {
29392 if !first {
29393 self.write(", ");
29394 }
29395 self.write("months => ");
29396 self.generate_expression(month)?;
29397 first = false;
29398 }
29399 if let Some(week) = &e.week {
29400 if !first {
29401 self.write(", ");
29402 }
29403 self.write("weeks => ");
29404 self.generate_expression(week)?;
29405 first = false;
29406 }
29407 if let Some(day) = &e.day {
29408 if !first {
29409 self.write(", ");
29410 }
29411 self.write("days => ");
29412 self.generate_expression(day)?;
29413 first = false;
29414 }
29415 if let Some(hour) = &e.hour {
29416 if !first {
29417 self.write(", ");
29418 }
29419 self.write("hours => ");
29420 self.generate_expression(hour)?;
29421 first = false;
29422 }
29423 if let Some(minute) = &e.minute {
29424 if !first {
29425 self.write(", ");
29426 }
29427 self.write("mins => ");
29428 self.generate_expression(minute)?;
29429 first = false;
29430 }
29431 if let Some(second) = &e.second {
29432 if !first {
29433 self.write(", ");
29434 }
29435 self.write("secs => ");
29436 self.generate_expression(second)?;
29437 }
29438 self.write(")");
29439 Ok(())
29440 }
29441
29442 fn generate_manhattan_distance(&mut self, e: &ManhattanDistance) -> Result<()> {
29443 self.write_keyword("MANHATTAN_DISTANCE");
29445 self.write("(");
29446 self.generate_expression(&e.this)?;
29447 self.write(", ");
29448 self.generate_expression(&e.expression)?;
29449 self.write(")");
29450 Ok(())
29451 }
29452
29453 fn generate_map(&mut self, e: &Map) -> Result<()> {
29454 self.write_keyword("MAP");
29456 self.write("(");
29457 for (i, (key, value)) in e.keys.iter().zip(e.values.iter()).enumerate() {
29458 if i > 0 {
29459 self.write(", ");
29460 }
29461 self.generate_expression(key)?;
29462 self.write(", ");
29463 self.generate_expression(value)?;
29464 }
29465 self.write(")");
29466 Ok(())
29467 }
29468
29469 fn generate_map_cat(&mut self, e: &MapCat) -> Result<()> {
29470 self.write_keyword("MAP_CAT");
29472 self.write("(");
29473 self.generate_expression(&e.this)?;
29474 self.write(", ");
29475 self.generate_expression(&e.expression)?;
29476 self.write(")");
29477 Ok(())
29478 }
29479
29480 fn generate_map_delete(&mut self, e: &MapDelete) -> Result<()> {
29481 self.write_keyword("MAP_DELETE");
29483 self.write("(");
29484 self.generate_expression(&e.this)?;
29485 for expr in &e.expressions {
29486 self.write(", ");
29487 self.generate_expression(expr)?;
29488 }
29489 self.write(")");
29490 Ok(())
29491 }
29492
29493 fn generate_map_insert(&mut self, e: &MapInsert) -> Result<()> {
29494 self.write_keyword("MAP_INSERT");
29496 self.write("(");
29497 self.generate_expression(&e.this)?;
29498 if let Some(key) = &e.key {
29499 self.write(", ");
29500 self.generate_expression(key)?;
29501 }
29502 if let Some(value) = &e.value {
29503 self.write(", ");
29504 self.generate_expression(value)?;
29505 }
29506 if let Some(update_flag) = &e.update_flag {
29507 self.write(", ");
29508 self.generate_expression(update_flag)?;
29509 }
29510 self.write(")");
29511 Ok(())
29512 }
29513
29514 fn generate_map_pick(&mut self, e: &MapPick) -> Result<()> {
29515 self.write_keyword("MAP_PICK");
29517 self.write("(");
29518 self.generate_expression(&e.this)?;
29519 for expr in &e.expressions {
29520 self.write(", ");
29521 self.generate_expression(expr)?;
29522 }
29523 self.write(")");
29524 Ok(())
29525 }
29526
29527 fn generate_masking_policy_column_constraint(
29528 &mut self,
29529 e: &MaskingPolicyColumnConstraint,
29530 ) -> Result<()> {
29531 self.write_keyword("MASKING POLICY");
29533 self.write_space();
29534 self.generate_expression(&e.this)?;
29535 if !e.expressions.is_empty() {
29536 self.write_keyword(" USING");
29537 self.write(" (");
29538 for (i, expr) in e.expressions.iter().enumerate() {
29539 if i > 0 {
29540 self.write(", ");
29541 }
29542 self.generate_expression(expr)?;
29543 }
29544 self.write(")");
29545 }
29546 Ok(())
29547 }
29548
29549 fn generate_match_against(&mut self, e: &MatchAgainst) -> Result<()> {
29550 if matches!(
29551 self.config.dialect,
29552 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
29553 ) {
29554 if e.expressions.len() > 1 {
29555 self.write("(");
29556 }
29557 for (i, expr) in e.expressions.iter().enumerate() {
29558 if i > 0 {
29559 self.write_keyword(" OR ");
29560 }
29561 self.generate_expression(expr)?;
29562 self.write_space();
29563 self.write("@@");
29564 self.write_space();
29565 self.generate_expression(&e.this)?;
29566 }
29567 if e.expressions.len() > 1 {
29568 self.write(")");
29569 }
29570 return Ok(());
29571 }
29572
29573 self.write_keyword("MATCH");
29575 self.write("(");
29576 for (i, expr) in e.expressions.iter().enumerate() {
29577 if i > 0 {
29578 self.write(", ");
29579 }
29580 self.generate_expression(expr)?;
29581 }
29582 self.write(")");
29583 self.write_keyword(" AGAINST");
29584 self.write("(");
29585 self.generate_expression(&e.this)?;
29586 if let Some(modifier) = &e.modifier {
29587 self.write_space();
29588 self.generate_expression(modifier)?;
29589 }
29590 self.write(")");
29591 Ok(())
29592 }
29593
29594 fn generate_match_recognize_measure(&mut self, e: &MatchRecognizeMeasure) -> Result<()> {
29595 if let Some(window_frame) = &e.window_frame {
29597 self.write(&format!("{:?}", window_frame).to_uppercase());
29598 self.write_space();
29599 }
29600 self.generate_expression(&e.this)?;
29601 Ok(())
29602 }
29603
29604 fn generate_materialized_property(&mut self, e: &MaterializedProperty) -> Result<()> {
29605 self.write_keyword("MATERIALIZED");
29607 if let Some(this) = &e.this {
29608 self.write_space();
29609 self.generate_expression(this)?;
29610 }
29611 Ok(())
29612 }
29613
29614 fn generate_merge(&mut self, e: &Merge) -> Result<()> {
29615 if let Some(with_) = &e.with_ {
29618 self.generate_expression(with_)?;
29619 self.write_space();
29620 }
29621 self.write_keyword("MERGE INTO");
29622 self.write_space();
29623 self.generate_expression(&e.this)?;
29624
29625 if self.config.pretty {
29627 self.write_newline();
29628 self.write_indent();
29629 } else {
29630 self.write_space();
29631 }
29632 self.write_keyword("USING");
29633 self.write_space();
29634 self.generate_expression(&e.using)?;
29635
29636 if let Some(on) = &e.on {
29638 if self.config.pretty {
29639 self.write_newline();
29640 self.write_indent();
29641 } else {
29642 self.write_space();
29643 }
29644 self.write_keyword("ON");
29645 self.write_space();
29646 self.generate_expression(on)?;
29647 }
29648 if let Some(using_cond) = &e.using_cond {
29650 self.write_space();
29651 self.write_keyword("USING");
29652 self.write_space();
29653 self.write("(");
29654 if let Expression::Tuple(tuple) = using_cond.as_ref() {
29656 for (i, col) in tuple.expressions.iter().enumerate() {
29657 if i > 0 {
29658 self.write(", ");
29659 }
29660 self.generate_expression(col)?;
29661 }
29662 } else {
29663 self.generate_expression(using_cond)?;
29664 }
29665 self.write(")");
29666 }
29667 let saved_merge_strip = std::mem::take(&mut self.merge_strip_qualifiers);
29669 if matches!(
29670 self.config.dialect,
29671 Some(crate::DialectType::PostgreSQL)
29672 | Some(crate::DialectType::Redshift)
29673 | Some(crate::DialectType::Trino)
29674 | Some(crate::DialectType::Presto)
29675 | Some(crate::DialectType::Athena)
29676 ) {
29677 let mut names = Vec::new();
29678 match e.this.as_ref() {
29679 Expression::Alias(a) => {
29680 if let Expression::Table(t) = &a.this {
29682 names.push(t.name.name.clone());
29683 } else if let Expression::Identifier(id) = &a.this {
29684 names.push(id.name.clone());
29685 }
29686 names.push(a.alias.name.clone());
29687 }
29688 Expression::Table(t) => {
29689 names.push(t.name.name.clone());
29690 }
29691 Expression::Identifier(id) => {
29692 names.push(id.name.clone());
29693 }
29694 _ => {}
29695 }
29696 self.merge_strip_qualifiers = names;
29697 }
29698
29699 if let Some(whens) = &e.whens {
29701 if self.config.pretty {
29702 self.write_newline();
29703 self.write_indent();
29704 } else {
29705 self.write_space();
29706 }
29707 self.generate_expression(whens)?;
29708 }
29709
29710 self.merge_strip_qualifiers = saved_merge_strip;
29712
29713 if let Some(returning) = &e.returning {
29715 if self.config.pretty {
29716 self.write_newline();
29717 self.write_indent();
29718 } else {
29719 self.write_space();
29720 }
29721 self.generate_expression(returning)?;
29722 }
29723 Ok(())
29724 }
29725
29726 fn generate_merge_block_ratio_property(&mut self, e: &MergeBlockRatioProperty) -> Result<()> {
29727 if e.no.is_some() {
29729 self.write_keyword("NO MERGEBLOCKRATIO");
29730 } else if e.default.is_some() {
29731 self.write_keyword("DEFAULT MERGEBLOCKRATIO");
29732 } else {
29733 self.write_keyword("MERGEBLOCKRATIO");
29734 self.write("=");
29735 if let Some(this) = &e.this {
29736 self.generate_expression(this)?;
29737 }
29738 if e.percent.is_some() {
29739 self.write_keyword(" PERCENT");
29740 }
29741 }
29742 Ok(())
29743 }
29744
29745 fn generate_merge_tree_ttl(&mut self, e: &MergeTreeTTL) -> Result<()> {
29746 self.write_keyword("TTL");
29748 let pretty_clickhouse = self.config.pretty
29749 && matches!(
29750 self.config.dialect,
29751 Some(crate::dialects::DialectType::ClickHouse)
29752 );
29753
29754 if pretty_clickhouse {
29755 self.write_newline();
29756 self.indent_level += 1;
29757 for (i, expr) in e.expressions.iter().enumerate() {
29758 if i > 0 {
29759 self.write(",");
29760 self.write_newline();
29761 }
29762 self.write_indent();
29763 self.generate_expression(expr)?;
29764 }
29765 self.indent_level -= 1;
29766 } else {
29767 self.write_space();
29768 for (i, expr) in e.expressions.iter().enumerate() {
29769 if i > 0 {
29770 self.write(", ");
29771 }
29772 self.generate_expression(expr)?;
29773 }
29774 }
29775
29776 if let Some(where_) = &e.where_ {
29777 if pretty_clickhouse {
29778 self.write_newline();
29779 if let Expression::Where(w) = where_.as_ref() {
29780 self.write_indent();
29781 self.write_keyword("WHERE");
29782 self.write_newline();
29783 self.indent_level += 1;
29784 self.write_indent();
29785 self.generate_expression(&w.this)?;
29786 self.indent_level -= 1;
29787 } else {
29788 self.write_indent();
29789 self.generate_expression(where_)?;
29790 }
29791 } else {
29792 self.write_space();
29793 self.generate_expression(where_)?;
29794 }
29795 }
29796 if let Some(group) = &e.group {
29797 if pretty_clickhouse {
29798 self.write_newline();
29799 if let Expression::Group(g) = group.as_ref() {
29800 self.write_indent();
29801 self.write_keyword("GROUP BY");
29802 self.write_newline();
29803 self.indent_level += 1;
29804 for (i, expr) in g.expressions.iter().enumerate() {
29805 if i > 0 {
29806 self.write(",");
29807 self.write_newline();
29808 }
29809 self.write_indent();
29810 self.generate_expression(expr)?;
29811 }
29812 self.indent_level -= 1;
29813 } else {
29814 self.write_indent();
29815 self.generate_expression(group)?;
29816 }
29817 } else {
29818 self.write_space();
29819 self.generate_expression(group)?;
29820 }
29821 }
29822 if let Some(aggregates) = &e.aggregates {
29823 if pretty_clickhouse {
29824 self.write_newline();
29825 self.write_indent();
29826 self.write_keyword("SET");
29827 self.write_newline();
29828 self.indent_level += 1;
29829 if let Expression::Tuple(t) = aggregates.as_ref() {
29830 for (i, agg) in t.expressions.iter().enumerate() {
29831 if i > 0 {
29832 self.write(",");
29833 self.write_newline();
29834 }
29835 self.write_indent();
29836 self.generate_expression(agg)?;
29837 }
29838 } else {
29839 self.write_indent();
29840 self.generate_expression(aggregates)?;
29841 }
29842 self.indent_level -= 1;
29843 } else {
29844 self.write_space();
29845 self.write_keyword("SET");
29846 self.write_space();
29847 self.generate_expression(aggregates)?;
29848 }
29849 }
29850 Ok(())
29851 }
29852
29853 fn generate_merge_tree_ttl_action(&mut self, e: &MergeTreeTTLAction) -> Result<()> {
29854 self.generate_expression(&e.this)?;
29856 if e.delete.is_some() {
29857 self.write_keyword(" DELETE");
29858 }
29859 if let Some(recompress) = &e.recompress {
29860 self.write_keyword(" RECOMPRESS ");
29861 self.generate_expression(recompress)?;
29862 }
29863 if let Some(to_disk) = &e.to_disk {
29864 self.write_keyword(" TO DISK ");
29865 self.generate_expression(to_disk)?;
29866 }
29867 if let Some(to_volume) = &e.to_volume {
29868 self.write_keyword(" TO VOLUME ");
29869 self.generate_expression(to_volume)?;
29870 }
29871 Ok(())
29872 }
29873
29874 fn generate_minhash(&mut self, e: &Minhash) -> Result<()> {
29875 self.write_keyword("MINHASH");
29877 self.write("(");
29878 self.generate_expression(&e.this)?;
29879 for expr in &e.expressions {
29880 self.write(", ");
29881 self.generate_expression(expr)?;
29882 }
29883 self.write(")");
29884 Ok(())
29885 }
29886
29887 fn generate_model_attribute(&mut self, e: &ModelAttribute) -> Result<()> {
29888 self.generate_expression(&e.this)?;
29890 self.write("!");
29891 self.generate_expression(&e.expression)?;
29892 Ok(())
29893 }
29894
29895 fn generate_monthname(&mut self, e: &Monthname) -> Result<()> {
29896 self.write_keyword("MONTHNAME");
29898 self.write("(");
29899 self.generate_expression(&e.this)?;
29900 self.write(")");
29901 Ok(())
29902 }
29903
29904 fn generate_multitable_inserts(&mut self, e: &MultitableInserts) -> Result<()> {
29905 for comment in &e.leading_comments {
29907 self.write_formatted_comment(comment);
29908 if self.config.pretty {
29909 self.write_newline();
29910 self.write_indent();
29911 } else {
29912 self.write_space();
29913 }
29914 }
29915 self.write_keyword("INSERT");
29917 self.write_space();
29918 self.write(&e.kind);
29919 if self.config.pretty {
29920 self.indent_level += 1;
29921 for expr in &e.expressions {
29922 self.write_newline();
29923 self.write_indent();
29924 self.generate_expression(expr)?;
29925 }
29926 self.indent_level -= 1;
29927 } else {
29928 for expr in &e.expressions {
29929 self.write_space();
29930 self.generate_expression(expr)?;
29931 }
29932 }
29933 if let Some(source) = &e.source {
29934 if self.config.pretty {
29935 self.write_newline();
29936 self.write_indent();
29937 } else {
29938 self.write_space();
29939 }
29940 self.generate_expression(source)?;
29941 }
29942 Ok(())
29943 }
29944
29945 fn generate_next_value_for(&mut self, e: &NextValueFor) -> Result<()> {
29946 self.write_keyword("NEXT VALUE FOR");
29948 self.write_space();
29949 self.generate_expression(&e.this)?;
29950 if let Some(order) = &e.order {
29951 self.write_space();
29952 self.write_keyword("OVER");
29953 self.write(" (");
29954 self.generate_expression(order)?;
29955 self.write(")");
29956 }
29957 Ok(())
29958 }
29959
29960 fn generate_normal(&mut self, e: &Normal) -> Result<()> {
29961 self.write_keyword("NORMAL");
29963 self.write("(");
29964 self.generate_expression(&e.this)?;
29965 if let Some(stddev) = &e.stddev {
29966 self.write(", ");
29967 self.generate_expression(stddev)?;
29968 }
29969 if let Some(gen) = &e.gen {
29970 self.write(", ");
29971 self.generate_expression(gen)?;
29972 }
29973 self.write(")");
29974 Ok(())
29975 }
29976
29977 fn generate_normalize(&mut self, e: &Normalize) -> Result<()> {
29978 if e.is_casefold.is_some() {
29980 self.write_keyword("NORMALIZE_AND_CASEFOLD");
29981 } else {
29982 self.write_keyword("NORMALIZE");
29983 }
29984 self.write("(");
29985 self.generate_expression(&e.this)?;
29986 if let Some(form) = &e.form {
29987 self.write(", ");
29988 self.generate_expression(form)?;
29989 }
29990 self.write(")");
29991 Ok(())
29992 }
29993
29994 fn generate_not_null_column_constraint(&mut self, e: &NotNullColumnConstraint) -> Result<()> {
29995 if e.allow_null.is_none() {
29997 self.write_keyword("NOT ");
29998 }
29999 self.write_keyword("NULL");
30000 Ok(())
30001 }
30002
30003 fn generate_nullif(&mut self, e: &Nullif) -> Result<()> {
30004 self.write_keyword("NULLIF");
30006 self.write("(");
30007 self.generate_expression(&e.this)?;
30008 self.write(", ");
30009 self.generate_expression(&e.expression)?;
30010 self.write(")");
30011 Ok(())
30012 }
30013
30014 fn generate_number_to_str(&mut self, e: &NumberToStr) -> Result<()> {
30015 self.write_keyword("FORMAT");
30017 self.write("(");
30018 self.generate_expression(&e.this)?;
30019 self.write(", '");
30020 self.write(&e.format);
30021 self.write("'");
30022 if let Some(culture) = &e.culture {
30023 self.write(", ");
30024 self.generate_expression(culture)?;
30025 }
30026 self.write(")");
30027 Ok(())
30028 }
30029
30030 fn generate_object_agg(&mut self, e: &ObjectAgg) -> Result<()> {
30031 self.write_keyword("OBJECT_AGG");
30033 self.write("(");
30034 self.generate_expression(&e.this)?;
30035 self.write(", ");
30036 self.generate_expression(&e.expression)?;
30037 self.write(")");
30038 Ok(())
30039 }
30040
30041 fn generate_object_identifier(&mut self, e: &ObjectIdentifier) -> Result<()> {
30042 self.generate_expression(&e.this)?;
30044 Ok(())
30045 }
30046
30047 fn generate_object_insert(&mut self, e: &ObjectInsert) -> Result<()> {
30048 self.write_keyword("OBJECT_INSERT");
30050 self.write("(");
30051 self.generate_expression(&e.this)?;
30052 if let Some(key) = &e.key {
30053 self.write(", ");
30054 self.generate_expression(key)?;
30055 }
30056 if let Some(value) = &e.value {
30057 self.write(", ");
30058 self.generate_expression(value)?;
30059 }
30060 if let Some(update_flag) = &e.update_flag {
30061 self.write(", ");
30062 self.generate_expression(update_flag)?;
30063 }
30064 self.write(")");
30065 Ok(())
30066 }
30067
30068 fn generate_offset(&mut self, e: &Offset) -> Result<()> {
30069 self.write_keyword("OFFSET");
30071 self.write_space();
30072 self.generate_expression(&e.this)?;
30073 if e.rows == Some(true)
30075 && matches!(
30076 self.config.dialect,
30077 Some(crate::dialects::DialectType::TSQL)
30078 | Some(crate::dialects::DialectType::Oracle)
30079 )
30080 {
30081 self.write_space();
30082 self.write_keyword("ROWS");
30083 }
30084 Ok(())
30085 }
30086
30087 fn generate_qualify(&mut self, e: &Qualify) -> Result<()> {
30088 self.write_keyword("QUALIFY");
30090 self.write_space();
30091 self.generate_expression(&e.this)?;
30092 Ok(())
30093 }
30094
30095 fn generate_on_cluster(&mut self, e: &OnCluster) -> Result<()> {
30096 self.write_keyword("ON CLUSTER");
30098 self.write_space();
30099 self.generate_expression(&e.this)?;
30100 Ok(())
30101 }
30102
30103 fn generate_on_commit_property(&mut self, e: &OnCommitProperty) -> Result<()> {
30104 self.write_keyword("ON COMMIT");
30106 if e.delete.is_some() {
30107 self.write_keyword(" DELETE ROWS");
30108 } else {
30109 self.write_keyword(" PRESERVE ROWS");
30110 }
30111 Ok(())
30112 }
30113
30114 fn generate_on_condition(&mut self, e: &OnCondition) -> Result<()> {
30115 if let Some(empty) = &e.empty {
30117 self.generate_expression(empty)?;
30118 self.write_keyword(" ON EMPTY");
30119 }
30120 if let Some(error) = &e.error {
30121 if e.empty.is_some() {
30122 self.write_space();
30123 }
30124 self.generate_expression(error)?;
30125 self.write_keyword(" ON ERROR");
30126 }
30127 if let Some(null) = &e.null {
30128 if e.empty.is_some() || e.error.is_some() {
30129 self.write_space();
30130 }
30131 self.generate_expression(null)?;
30132 self.write_keyword(" ON NULL");
30133 }
30134 Ok(())
30135 }
30136
30137 fn generate_on_conflict(&mut self, e: &OnConflict) -> Result<()> {
30138 if matches!(self.config.dialect, Some(DialectType::Materialize)) {
30140 return Ok(());
30141 }
30142 if e.duplicate.is_some() {
30144 self.write_keyword("ON DUPLICATE KEY UPDATE");
30146 for (i, expr) in e.expressions.iter().enumerate() {
30147 if i > 0 {
30148 self.write(",");
30149 }
30150 self.write_space();
30151 self.generate_expression(expr)?;
30152 }
30153 return Ok(());
30154 } else {
30155 self.write_keyword("ON CONFLICT");
30156 }
30157 if let Some(constraint) = &e.constraint {
30158 self.write_keyword(" ON CONSTRAINT ");
30159 self.generate_expression(constraint)?;
30160 }
30161 if let Some(conflict_keys) = &e.conflict_keys {
30162 if let Expression::Tuple(t) = conflict_keys.as_ref() {
30164 self.write("(");
30165 for (i, expr) in t.expressions.iter().enumerate() {
30166 if i > 0 {
30167 self.write(", ");
30168 }
30169 self.generate_expression(expr)?;
30170 }
30171 self.write(")");
30172 } else {
30173 self.write("(");
30174 self.generate_expression(conflict_keys)?;
30175 self.write(")");
30176 }
30177 }
30178 if let Some(index_predicate) = &e.index_predicate {
30179 self.write_keyword(" WHERE ");
30180 self.generate_expression(index_predicate)?;
30181 }
30182 if let Some(action) = &e.action {
30183 if let Expression::Identifier(id) = action.as_ref() {
30185 if id.name == "NOTHING" || id.name.to_uppercase() == "NOTHING" {
30186 self.write_keyword(" DO NOTHING");
30187 } else {
30188 self.write_keyword(" DO ");
30189 self.generate_expression(action)?;
30190 }
30191 } else if let Expression::Tuple(t) = action.as_ref() {
30192 self.write_keyword(" DO UPDATE SET ");
30194 for (i, expr) in t.expressions.iter().enumerate() {
30195 if i > 0 {
30196 self.write(", ");
30197 }
30198 self.generate_expression(expr)?;
30199 }
30200 } else {
30201 self.write_keyword(" DO ");
30202 self.generate_expression(action)?;
30203 }
30204 }
30205 if let Some(where_) = &e.where_ {
30207 self.write_keyword(" WHERE ");
30208 self.generate_expression(where_)?;
30209 }
30210 Ok(())
30211 }
30212
30213 fn generate_on_property(&mut self, e: &OnProperty) -> Result<()> {
30214 self.write_keyword("ON");
30216 self.write_space();
30217 self.generate_expression(&e.this)?;
30218 Ok(())
30219 }
30220
30221 fn generate_opclass(&mut self, e: &Opclass) -> Result<()> {
30222 self.generate_expression(&e.this)?;
30224 self.write_space();
30225 self.generate_expression(&e.expression)?;
30226 Ok(())
30227 }
30228
30229 fn generate_open_json(&mut self, e: &OpenJSON) -> Result<()> {
30230 self.write_keyword("OPENJSON");
30232 self.write("(");
30233 self.generate_expression(&e.this)?;
30234 if let Some(path) = &e.path {
30235 self.write(", ");
30236 self.generate_expression(path)?;
30237 }
30238 self.write(")");
30239 if !e.expressions.is_empty() {
30240 self.write_keyword(" WITH");
30241 if self.config.pretty {
30242 self.write(" (\n");
30243 self.indent_level += 2;
30244 for (i, expr) in e.expressions.iter().enumerate() {
30245 if i > 0 {
30246 self.write(",\n");
30247 }
30248 self.write_indent();
30249 self.generate_expression(expr)?;
30250 }
30251 self.write("\n");
30252 self.indent_level -= 2;
30253 self.write(")");
30254 } else {
30255 self.write(" (");
30256 for (i, expr) in e.expressions.iter().enumerate() {
30257 if i > 0 {
30258 self.write(", ");
30259 }
30260 self.generate_expression(expr)?;
30261 }
30262 self.write(")");
30263 }
30264 }
30265 Ok(())
30266 }
30267
30268 fn generate_open_json_column_def(&mut self, e: &OpenJSONColumnDef) -> Result<()> {
30269 self.generate_expression(&e.this)?;
30271 self.write_space();
30272 if let Some(ref dt) = e.data_type {
30274 self.generate_data_type(dt)?;
30275 } else if !e.kind.is_empty() {
30276 self.write(&e.kind);
30277 }
30278 if let Some(path) = &e.path {
30279 self.write_space();
30280 self.generate_expression(path)?;
30281 }
30282 if e.as_json.is_some() {
30283 self.write_keyword(" AS JSON");
30284 }
30285 Ok(())
30286 }
30287
30288 fn generate_operator(&mut self, e: &Operator) -> Result<()> {
30289 self.generate_expression(&e.this)?;
30291 self.write_space();
30292 if let Some(op) = &e.operator {
30293 self.write_keyword("OPERATOR");
30294 self.write("(");
30295 self.generate_expression(op)?;
30296 self.write(")");
30297 }
30298 for comment in &e.comments {
30300 self.write_space();
30301 self.write_formatted_comment(comment);
30302 }
30303 self.write_space();
30304 self.generate_expression(&e.expression)?;
30305 Ok(())
30306 }
30307
30308 fn generate_order_by(&mut self, e: &OrderBy) -> Result<()> {
30309 self.write_keyword("ORDER BY");
30311 let pretty_clickhouse_single_paren = self.config.pretty
30312 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
30313 && e.expressions.len() == 1
30314 && matches!(e.expressions[0].this, Expression::Paren(ref p) if !matches!(p.this, Expression::Tuple(_)));
30315 let clickhouse_single_tuple = matches!(self.config.dialect, Some(DialectType::ClickHouse))
30316 && e.expressions.len() == 1
30317 && matches!(e.expressions[0].this, Expression::Tuple(_))
30318 && !e.expressions[0].desc
30319 && e.expressions[0].nulls_first.is_none();
30320
30321 if pretty_clickhouse_single_paren {
30322 self.write_space();
30323 if let Expression::Paren(p) = &e.expressions[0].this {
30324 self.write("(");
30325 self.write_newline();
30326 self.indent_level += 1;
30327 self.write_indent();
30328 self.generate_expression(&p.this)?;
30329 self.indent_level -= 1;
30330 self.write_newline();
30331 self.write(")");
30332 }
30333 return Ok(());
30334 }
30335
30336 if clickhouse_single_tuple {
30337 self.write_space();
30338 if let Expression::Tuple(t) = &e.expressions[0].this {
30339 self.write("(");
30340 for (i, expr) in t.expressions.iter().enumerate() {
30341 if i > 0 {
30342 self.write(", ");
30343 }
30344 self.generate_expression(expr)?;
30345 }
30346 self.write(")");
30347 }
30348 return Ok(());
30349 }
30350
30351 self.write_space();
30352 for (i, ordered) in e.expressions.iter().enumerate() {
30353 if i > 0 {
30354 self.write(", ");
30355 }
30356 self.generate_expression(&ordered.this)?;
30357 if ordered.desc {
30358 self.write_space();
30359 self.write_keyword("DESC");
30360 } else if ordered.explicit_asc {
30361 self.write_space();
30362 self.write_keyword("ASC");
30363 }
30364 if let Some(nulls_first) = ordered.nulls_first {
30365 let skip_nulls_last =
30367 !nulls_first && matches!(self.config.dialect, Some(DialectType::Dremio));
30368 if !skip_nulls_last {
30369 self.write_space();
30370 self.write_keyword("NULLS");
30371 self.write_space();
30372 if nulls_first {
30373 self.write_keyword("FIRST");
30374 } else {
30375 self.write_keyword("LAST");
30376 }
30377 }
30378 }
30379 }
30380 Ok(())
30381 }
30382
30383 fn generate_output_model_property(&mut self, e: &OutputModelProperty) -> Result<()> {
30384 self.write_keyword("OUTPUT");
30386 self.write("(");
30387 if self.config.pretty {
30388 self.indent_level += 1;
30389 self.write_newline();
30390 self.write_indent();
30391 self.generate_expression(&e.this)?;
30392 self.indent_level -= 1;
30393 self.write_newline();
30394 } else {
30395 self.generate_expression(&e.this)?;
30396 }
30397 self.write(")");
30398 Ok(())
30399 }
30400
30401 fn generate_overflow_truncate_behavior(&mut self, e: &OverflowTruncateBehavior) -> Result<()> {
30402 self.write_keyword("TRUNCATE");
30404 if let Some(this) = &e.this {
30405 self.write_space();
30406 self.generate_expression(this)?;
30407 }
30408 if e.with_count.is_some() {
30409 self.write_keyword(" WITH COUNT");
30410 } else {
30411 self.write_keyword(" WITHOUT COUNT");
30412 }
30413 Ok(())
30414 }
30415
30416 fn generate_parameterized_agg(&mut self, e: &ParameterizedAgg) -> Result<()> {
30417 self.generate_expression(&e.this)?;
30419 self.write("(");
30420 for (i, expr) in e.expressions.iter().enumerate() {
30421 if i > 0 {
30422 self.write(", ");
30423 }
30424 self.generate_expression(expr)?;
30425 }
30426 self.write(")(");
30427 for (i, param) in e.params.iter().enumerate() {
30428 if i > 0 {
30429 self.write(", ");
30430 }
30431 self.generate_expression(param)?;
30432 }
30433 self.write(")");
30434 Ok(())
30435 }
30436
30437 fn generate_parse_datetime(&mut self, e: &ParseDatetime) -> Result<()> {
30438 self.write_keyword("PARSE_DATETIME");
30440 self.write("(");
30441 if let Some(format) = &e.format {
30442 self.write("'");
30443 self.write(format);
30444 self.write("', ");
30445 }
30446 self.generate_expression(&e.this)?;
30447 if let Some(zone) = &e.zone {
30448 self.write(", ");
30449 self.generate_expression(zone)?;
30450 }
30451 self.write(")");
30452 Ok(())
30453 }
30454
30455 fn generate_parse_ip(&mut self, e: &ParseIp) -> Result<()> {
30456 self.write_keyword("PARSE_IP");
30458 self.write("(");
30459 self.generate_expression(&e.this)?;
30460 if let Some(type_) = &e.type_ {
30461 self.write(", ");
30462 self.generate_expression(type_)?;
30463 }
30464 if let Some(permissive) = &e.permissive {
30465 self.write(", ");
30466 self.generate_expression(permissive)?;
30467 }
30468 self.write(")");
30469 Ok(())
30470 }
30471
30472 fn generate_parse_json(&mut self, e: &ParseJSON) -> Result<()> {
30473 self.write_keyword("PARSE_JSON");
30475 self.write("(");
30476 self.generate_expression(&e.this)?;
30477 if let Some(expression) = &e.expression {
30478 self.write(", ");
30479 self.generate_expression(expression)?;
30480 }
30481 self.write(")");
30482 Ok(())
30483 }
30484
30485 fn generate_parse_time(&mut self, e: &ParseTime) -> Result<()> {
30486 self.write_keyword("PARSE_TIME");
30488 self.write("(");
30489 self.write(&format!("'{}'", e.format));
30490 self.write(", ");
30491 self.generate_expression(&e.this)?;
30492 self.write(")");
30493 Ok(())
30494 }
30495
30496 fn generate_parse_url(&mut self, e: &ParseUrl) -> Result<()> {
30497 self.write_keyword("PARSE_URL");
30499 self.write("(");
30500 self.generate_expression(&e.this)?;
30501 if let Some(part) = &e.part_to_extract {
30502 self.write(", ");
30503 self.generate_expression(part)?;
30504 }
30505 if let Some(key) = &e.key {
30506 self.write(", ");
30507 self.generate_expression(key)?;
30508 }
30509 if let Some(permissive) = &e.permissive {
30510 self.write(", ");
30511 self.generate_expression(permissive)?;
30512 }
30513 self.write(")");
30514 Ok(())
30515 }
30516
30517 fn generate_partition_expr(&mut self, e: &Partition) -> Result<()> {
30518 if e.subpartition {
30520 self.write_keyword("SUBPARTITION");
30521 } else {
30522 self.write_keyword("PARTITION");
30523 }
30524 self.write("(");
30525 for (i, expr) in e.expressions.iter().enumerate() {
30526 if i > 0 {
30527 self.write(", ");
30528 }
30529 self.generate_expression(expr)?;
30530 }
30531 self.write(")");
30532 Ok(())
30533 }
30534
30535 fn generate_partition_bound_spec(&mut self, e: &PartitionBoundSpec) -> Result<()> {
30536 if let Some(this) = &e.this {
30538 if let Some(expression) = &e.expression {
30539 self.write_keyword("WITH");
30541 self.write(" (");
30542 self.write_keyword("MODULUS");
30543 self.write_space();
30544 self.generate_expression(this)?;
30545 self.write(", ");
30546 self.write_keyword("REMAINDER");
30547 self.write_space();
30548 self.generate_expression(expression)?;
30549 self.write(")");
30550 } else {
30551 self.write_keyword("IN");
30553 self.write(" (");
30554 self.generate_partition_bound_values(this)?;
30555 self.write(")");
30556 }
30557 } else if let (Some(from), Some(to)) = (&e.from_expressions, &e.to_expressions) {
30558 self.write_keyword("FROM");
30560 self.write(" (");
30561 self.generate_partition_bound_values(from)?;
30562 self.write(") ");
30563 self.write_keyword("TO");
30564 self.write(" (");
30565 self.generate_partition_bound_values(to)?;
30566 self.write(")");
30567 }
30568 Ok(())
30569 }
30570
30571 fn generate_partition_bound_values(&mut self, expr: &Expression) -> Result<()> {
30574 if let Expression::Tuple(t) = expr {
30575 for (i, e) in t.expressions.iter().enumerate() {
30576 if i > 0 {
30577 self.write(", ");
30578 }
30579 self.generate_expression(e)?;
30580 }
30581 Ok(())
30582 } else {
30583 self.generate_expression(expr)
30584 }
30585 }
30586
30587 fn generate_partition_by_list_property(&mut self, e: &PartitionByListProperty) -> Result<()> {
30588 self.write_keyword("PARTITION BY LIST");
30590 if let Some(partition_exprs) = &e.partition_expressions {
30591 self.write(" (");
30592 self.generate_doris_partition_expressions(partition_exprs)?;
30594 self.write(")");
30595 }
30596 if let Some(create_exprs) = &e.create_expressions {
30597 self.write(" (");
30598 self.generate_doris_partition_definitions(create_exprs)?;
30600 self.write(")");
30601 }
30602 Ok(())
30603 }
30604
30605 fn generate_partition_by_range_property(&mut self, e: &PartitionByRangeProperty) -> Result<()> {
30606 self.write_keyword("PARTITION BY RANGE");
30608 if let Some(partition_exprs) = &e.partition_expressions {
30609 self.write(" (");
30610 self.generate_doris_partition_expressions(partition_exprs)?;
30612 self.write(")");
30613 }
30614 if let Some(create_exprs) = &e.create_expressions {
30615 self.write(" (");
30616 self.generate_doris_partition_definitions(create_exprs)?;
30618 self.write(")");
30619 }
30620 Ok(())
30621 }
30622
30623 fn generate_doris_partition_expressions(&mut self, expr: &Expression) -> Result<()> {
30625 if let Expression::Tuple(t) = expr {
30626 for (i, e) in t.expressions.iter().enumerate() {
30627 if i > 0 {
30628 self.write(", ");
30629 }
30630 self.generate_expression(e)?;
30631 }
30632 } else {
30633 self.generate_expression(expr)?;
30634 }
30635 Ok(())
30636 }
30637
30638 fn generate_doris_partition_definitions(&mut self, expr: &Expression) -> Result<()> {
30640 match expr {
30641 Expression::Tuple(t) => {
30642 for (i, part) in t.expressions.iter().enumerate() {
30644 if i > 0 {
30645 self.write(", ");
30646 }
30647 if let Expression::Partition(p) = part {
30649 for (j, inner) in p.expressions.iter().enumerate() {
30650 if j > 0 {
30651 self.write(", ");
30652 }
30653 self.generate_expression(inner)?;
30654 }
30655 } else {
30656 self.generate_expression(part)?;
30657 }
30658 }
30659 }
30660 Expression::PartitionByRangePropertyDynamic(_) => {
30661 self.generate_expression(expr)?;
30663 }
30664 _ => {
30665 self.generate_expression(expr)?;
30666 }
30667 }
30668 Ok(())
30669 }
30670
30671 fn generate_partition_by_range_property_dynamic(
30672 &mut self,
30673 e: &PartitionByRangePropertyDynamic,
30674 ) -> Result<()> {
30675 if e.use_start_end {
30676 if let Some(start) = &e.start {
30678 self.write_keyword("START");
30679 self.write(" (");
30680 self.generate_expression(start)?;
30681 self.write(")");
30682 }
30683 if let Some(end) = &e.end {
30684 self.write_space();
30685 self.write_keyword("END");
30686 self.write(" (");
30687 self.generate_expression(end)?;
30688 self.write(")");
30689 }
30690 if let Some(every) = &e.every {
30691 self.write_space();
30692 self.write_keyword("EVERY");
30693 self.write(" (");
30694 self.generate_doris_interval(every)?;
30696 self.write(")");
30697 }
30698 } else {
30699 if let Some(start) = &e.start {
30701 self.write_keyword("FROM");
30702 self.write(" (");
30703 self.generate_expression(start)?;
30704 self.write(")");
30705 }
30706 if let Some(end) = &e.end {
30707 self.write_space();
30708 self.write_keyword("TO");
30709 self.write(" (");
30710 self.generate_expression(end)?;
30711 self.write(")");
30712 }
30713 if let Some(every) = &e.every {
30714 self.write_space();
30715 self.generate_doris_interval(every)?;
30717 }
30718 }
30719 Ok(())
30720 }
30721
30722 fn generate_doris_interval(&mut self, expr: &Expression) -> Result<()> {
30724 if let Expression::Interval(interval) = expr {
30725 self.write_keyword("INTERVAL");
30726 if let Some(ref value) = interval.this {
30727 self.write_space();
30728 match value {
30732 Expression::Literal(Literal::String(s))
30733 if s.chars()
30734 .all(|c| c.is_ascii_digit() || c == '.' || c == '-')
30735 && !s.is_empty() =>
30736 {
30737 self.write(s);
30738 }
30739 _ => {
30740 self.generate_expression(value)?;
30741 }
30742 }
30743 }
30744 if let Some(ref unit_spec) = interval.unit {
30745 self.write_space();
30746 self.write_interval_unit_spec(unit_spec)?;
30747 }
30748 Ok(())
30749 } else {
30750 self.generate_expression(expr)
30751 }
30752 }
30753
30754 fn generate_partition_by_truncate(&mut self, e: &PartitionByTruncate) -> Result<()> {
30755 self.write_keyword("TRUNCATE");
30757 self.write("(");
30758 self.generate_expression(&e.expression)?;
30759 self.write(", ");
30760 self.generate_expression(&e.this)?;
30761 self.write(")");
30762 Ok(())
30763 }
30764
30765 fn generate_partition_list(&mut self, e: &PartitionList) -> Result<()> {
30766 self.write_keyword("PARTITION");
30768 self.write_space();
30769 self.generate_expression(&e.this)?;
30770 self.write_space();
30771 self.write_keyword("VALUES IN");
30772 self.write(" (");
30773 for (i, expr) in e.expressions.iter().enumerate() {
30774 if i > 0 {
30775 self.write(", ");
30776 }
30777 self.generate_expression(expr)?;
30778 }
30779 self.write(")");
30780 Ok(())
30781 }
30782
30783 fn generate_partition_range(&mut self, e: &PartitionRange) -> Result<()> {
30784 if e.expressions.is_empty() && e.expression.is_some() {
30787 self.generate_expression(&e.this)?;
30789 self.write_space();
30790 self.write_keyword("TO");
30791 self.write_space();
30792 self.generate_expression(e.expression.as_ref().unwrap())?;
30793 return Ok(());
30794 }
30795
30796 self.write_keyword("PARTITION");
30798 self.write_space();
30799 self.generate_expression(&e.this)?;
30800 self.write_space();
30801
30802 if e.expressions.len() == 1 {
30804 self.write_keyword("VALUES LESS THAN");
30806 self.write(" (");
30807 self.generate_expression(&e.expressions[0])?;
30808 self.write(")");
30809 } else if !e.expressions.is_empty() {
30810 self.write_keyword("VALUES");
30812 self.write(" [");
30813 for (i, expr) in e.expressions.iter().enumerate() {
30814 if i > 0 {
30815 self.write(", ");
30816 }
30817 if let Expression::Tuple(t) = expr {
30819 self.write("(");
30820 for (j, inner) in t.expressions.iter().enumerate() {
30821 if j > 0 {
30822 self.write(", ");
30823 }
30824 self.generate_expression(inner)?;
30825 }
30826 self.write(")");
30827 } else {
30828 self.write("(");
30829 self.generate_expression(expr)?;
30830 self.write(")");
30831 }
30832 }
30833 self.write(")");
30834 }
30835 Ok(())
30836 }
30837
30838 fn generate_partitioned_by_bucket(&mut self, e: &PartitionedByBucket) -> Result<()> {
30839 self.write_keyword("BUCKET");
30841 self.write("(");
30842 self.generate_expression(&e.this)?;
30843 self.write(", ");
30844 self.generate_expression(&e.expression)?;
30845 self.write(")");
30846 Ok(())
30847 }
30848
30849 fn generate_partition_by_property(&mut self, e: &PartitionByProperty) -> Result<()> {
30850 self.write_keyword("PARTITION BY");
30852 self.write_space();
30853 for (i, expr) in e.expressions.iter().enumerate() {
30854 if i > 0 {
30855 self.write(", ");
30856 }
30857 self.generate_expression(expr)?;
30858 }
30859 Ok(())
30860 }
30861
30862 fn generate_partitioned_by_property(&mut self, e: &PartitionedByProperty) -> Result<()> {
30863 if matches!(
30865 self.config.dialect,
30866 Some(crate::dialects::DialectType::Teradata)
30867 | Some(crate::dialects::DialectType::ClickHouse)
30868 ) {
30869 self.write_keyword("PARTITION BY");
30870 } else {
30871 self.write_keyword("PARTITIONED BY");
30872 }
30873 self.write_space();
30874 if self.config.pretty {
30876 if let Expression::Tuple(ref tuple) = *e.this {
30877 self.write("(");
30878 self.write_newline();
30879 self.indent_level += 1;
30880 for (i, expr) in tuple.expressions.iter().enumerate() {
30881 if i > 0 {
30882 self.write(",");
30883 self.write_newline();
30884 }
30885 self.write_indent();
30886 self.generate_expression(expr)?;
30887 }
30888 self.indent_level -= 1;
30889 self.write_newline();
30890 self.write(")");
30891 } else {
30892 self.generate_expression(&e.this)?;
30893 }
30894 } else {
30895 self.generate_expression(&e.this)?;
30896 }
30897 Ok(())
30898 }
30899
30900 fn generate_partitioned_of_property(&mut self, e: &PartitionedOfProperty) -> Result<()> {
30901 self.write_keyword("PARTITION OF");
30903 self.write_space();
30904 self.generate_expression(&e.this)?;
30905 if let Expression::PartitionBoundSpec(_) = e.expression.as_ref() {
30907 self.write_space();
30908 self.write_keyword("FOR VALUES");
30909 self.write_space();
30910 self.generate_expression(&e.expression)?;
30911 } else {
30912 self.write_space();
30913 self.write_keyword("DEFAULT");
30914 }
30915 Ok(())
30916 }
30917
30918 fn generate_period_for_system_time_constraint(
30919 &mut self,
30920 e: &PeriodForSystemTimeConstraint,
30921 ) -> Result<()> {
30922 self.write_keyword("PERIOD FOR SYSTEM_TIME");
30924 self.write(" (");
30925 self.generate_expression(&e.this)?;
30926 self.write(", ");
30927 self.generate_expression(&e.expression)?;
30928 self.write(")");
30929 Ok(())
30930 }
30931
30932 fn generate_pivot_alias(&mut self, e: &PivotAlias) -> Result<()> {
30933 self.generate_expression(&e.this)?;
30936 self.write_space();
30937 self.write_keyword("AS");
30938 self.write_space();
30939 if self.config.unpivot_aliases_are_identifiers {
30941 match &e.alias {
30942 Expression::Literal(Literal::String(s)) => {
30943 self.generate_identifier(&Identifier::new(s.clone()))?;
30945 }
30946 Expression::Literal(Literal::Number(n)) => {
30947 let mut id = Identifier::new(n.clone());
30949 id.quoted = true;
30950 self.generate_identifier(&id)?;
30951 }
30952 other => {
30953 self.generate_expression(other)?;
30954 }
30955 }
30956 } else {
30957 self.generate_expression(&e.alias)?;
30958 }
30959 Ok(())
30960 }
30961
30962 fn generate_pivot_any(&mut self, e: &PivotAny) -> Result<()> {
30963 self.write_keyword("ANY");
30965 if let Some(this) = &e.this {
30966 self.write_space();
30967 self.generate_expression(this)?;
30968 }
30969 Ok(())
30970 }
30971
30972 fn generate_predict(&mut self, e: &Predict) -> Result<()> {
30973 self.write_keyword("ML.PREDICT");
30975 self.write("(");
30976 self.write_keyword("MODEL");
30977 self.write_space();
30978 self.generate_expression(&e.this)?;
30979 self.write(", ");
30980 self.generate_expression(&e.expression)?;
30981 if let Some(params) = &e.params_struct {
30982 self.write(", ");
30983 self.generate_expression(params)?;
30984 }
30985 self.write(")");
30986 Ok(())
30987 }
30988
30989 fn generate_previous_day(&mut self, e: &PreviousDay) -> Result<()> {
30990 self.write_keyword("PREVIOUS_DAY");
30992 self.write("(");
30993 self.generate_expression(&e.this)?;
30994 self.write(", ");
30995 self.generate_expression(&e.expression)?;
30996 self.write(")");
30997 Ok(())
30998 }
30999
31000 fn generate_primary_key(&mut self, e: &PrimaryKey) -> Result<()> {
31001 self.write_keyword("PRIMARY KEY");
31003 if let Some(name) = &e.this {
31004 self.write_space();
31005 self.generate_expression(name)?;
31006 }
31007 if !e.expressions.is_empty() {
31008 self.write(" (");
31009 for (i, expr) in e.expressions.iter().enumerate() {
31010 if i > 0 {
31011 self.write(", ");
31012 }
31013 self.generate_expression(expr)?;
31014 }
31015 self.write(")");
31016 }
31017 if let Some(include) = &e.include {
31018 self.write_space();
31019 self.generate_expression(include)?;
31020 }
31021 if !e.options.is_empty() {
31022 self.write_space();
31023 for (i, opt) in e.options.iter().enumerate() {
31024 if i > 0 {
31025 self.write_space();
31026 }
31027 self.generate_expression(opt)?;
31028 }
31029 }
31030 Ok(())
31031 }
31032
31033 fn generate_primary_key_column_constraint(
31034 &mut self,
31035 _e: &PrimaryKeyColumnConstraint,
31036 ) -> Result<()> {
31037 self.write_keyword("PRIMARY KEY");
31039 Ok(())
31040 }
31041
31042 fn generate_path_column_constraint(&mut self, e: &PathColumnConstraint) -> Result<()> {
31043 self.write_keyword("PATH");
31045 self.write_space();
31046 self.generate_expression(&e.this)?;
31047 Ok(())
31048 }
31049
31050 fn generate_projection_def(&mut self, e: &ProjectionDef) -> Result<()> {
31051 self.write_keyword("PROJECTION");
31053 self.write_space();
31054 self.generate_expression(&e.this)?;
31055 self.write(" (");
31056 self.generate_expression(&e.expression)?;
31057 self.write(")");
31058 Ok(())
31059 }
31060
31061 fn generate_properties(&mut self, e: &Properties) -> Result<()> {
31062 for (i, prop) in e.expressions.iter().enumerate() {
31064 if i > 0 {
31065 self.write(", ");
31066 }
31067 self.generate_expression(prop)?;
31068 }
31069 Ok(())
31070 }
31071
31072 fn generate_property(&mut self, e: &Property) -> Result<()> {
31073 self.generate_expression(&e.this)?;
31075 if let Some(value) = &e.value {
31076 self.write("=");
31077 self.generate_expression(value)?;
31078 }
31079 Ok(())
31080 }
31081
31082 fn generate_options_property(&mut self, e: &OptionsProperty) -> Result<()> {
31083 self.write_keyword("OPTIONS");
31084 if e.entries.is_empty() {
31085 self.write(" ()");
31086 return Ok(());
31087 }
31088
31089 if self.config.pretty {
31090 self.write(" (");
31091 self.write_newline();
31092 self.indent_level += 1;
31093 for (i, entry) in e.entries.iter().enumerate() {
31094 if i > 0 {
31095 self.write(",");
31096 self.write_newline();
31097 }
31098 self.write_indent();
31099 self.generate_identifier(&entry.key)?;
31100 self.write("=");
31101 self.generate_expression(&entry.value)?;
31102 }
31103 self.indent_level -= 1;
31104 self.write_newline();
31105 self.write(")");
31106 } else {
31107 self.write(" (");
31108 for (i, entry) in e.entries.iter().enumerate() {
31109 if i > 0 {
31110 self.write(", ");
31111 }
31112 self.generate_identifier(&entry.key)?;
31113 self.write("=");
31114 self.generate_expression(&entry.value)?;
31115 }
31116 self.write(")");
31117 }
31118 Ok(())
31119 }
31120
31121 fn generate_options_clause(&mut self, options: &[Expression]) -> Result<()> {
31123 self.write_keyword("OPTIONS");
31124 self.write(" (");
31125 for (i, opt) in options.iter().enumerate() {
31126 if i > 0 {
31127 self.write(", ");
31128 }
31129 self.generate_option_expression(opt)?;
31130 }
31131 self.write(")");
31132 Ok(())
31133 }
31134
31135 fn generate_properties_clause(&mut self, properties: &[Expression]) -> Result<()> {
31137 self.write_keyword("PROPERTIES");
31138 self.write(" (");
31139 for (i, prop) in properties.iter().enumerate() {
31140 if i > 0 {
31141 self.write(", ");
31142 }
31143 self.generate_option_expression(prop)?;
31144 }
31145 self.write(")");
31146 Ok(())
31147 }
31148
31149 fn generate_environment_clause(&mut self, environment: &[Expression]) -> Result<()> {
31151 self.write_keyword("ENVIRONMENT");
31152 self.write(" (");
31153 for (i, env_item) in environment.iter().enumerate() {
31154 if i > 0 {
31155 self.write(", ");
31156 }
31157 self.generate_environment_expression(env_item)?;
31158 }
31159 self.write(")");
31160 Ok(())
31161 }
31162
31163 fn generate_environment_expression(&mut self, expr: &Expression) -> Result<()> {
31165 match expr {
31166 Expression::Eq(eq) => {
31167 self.generate_expression(&eq.left)?;
31169 self.write(" = ");
31170 self.generate_expression(&eq.right)?;
31171 Ok(())
31172 }
31173 _ => self.generate_expression(expr),
31174 }
31175 }
31176
31177 fn generate_tblproperties_clause(&mut self, options: &[Expression]) -> Result<()> {
31179 self.write_keyword("TBLPROPERTIES");
31180 if self.config.pretty {
31181 self.write(" (");
31182 self.write_newline();
31183 self.indent_level += 1;
31184 for (i, opt) in options.iter().enumerate() {
31185 if i > 0 {
31186 self.write(",");
31187 self.write_newline();
31188 }
31189 self.write_indent();
31190 self.generate_option_expression(opt)?;
31191 }
31192 self.indent_level -= 1;
31193 self.write_newline();
31194 self.write(")");
31195 } else {
31196 self.write(" (");
31197 for (i, opt) in options.iter().enumerate() {
31198 if i > 0 {
31199 self.write(", ");
31200 }
31201 self.generate_option_expression(opt)?;
31202 }
31203 self.write(")");
31204 }
31205 Ok(())
31206 }
31207
31208 fn generate_option_expression(&mut self, expr: &Expression) -> Result<()> {
31210 match expr {
31211 Expression::Eq(eq) => {
31212 self.generate_expression(&eq.left)?;
31214 self.write("=");
31215 self.generate_expression(&eq.right)?;
31216 Ok(())
31217 }
31218 _ => self.generate_expression(expr),
31219 }
31220 }
31221
31222 fn generate_pseudo_type(&mut self, e: &PseudoType) -> Result<()> {
31223 self.generate_expression(&e.this)?;
31225 Ok(())
31226 }
31227
31228 fn generate_put(&mut self, e: &PutStmt) -> Result<()> {
31229 self.write_keyword("PUT");
31231 self.write_space();
31232
31233 if e.source_quoted {
31235 self.write("'");
31236 self.write(&e.source);
31237 self.write("'");
31238 } else {
31239 self.write(&e.source);
31240 }
31241
31242 self.write_space();
31243
31244 if let Expression::Literal(Literal::String(s)) = &e.target {
31246 self.write(s);
31247 } else {
31248 self.generate_expression(&e.target)?;
31249 }
31250
31251 for param in &e.params {
31253 self.write_space();
31254 self.write(¶m.name);
31255 if let Some(ref value) = param.value {
31256 self.write("=");
31257 self.generate_expression(value)?;
31258 }
31259 }
31260
31261 Ok(())
31262 }
31263
31264 fn generate_quantile(&mut self, e: &Quantile) -> Result<()> {
31265 self.write_keyword("QUANTILE");
31267 self.write("(");
31268 self.generate_expression(&e.this)?;
31269 if let Some(quantile) = &e.quantile {
31270 self.write(", ");
31271 self.generate_expression(quantile)?;
31272 }
31273 self.write(")");
31274 Ok(())
31275 }
31276
31277 fn generate_query_band(&mut self, e: &QueryBand) -> Result<()> {
31278 if matches!(
31280 self.config.dialect,
31281 Some(crate::dialects::DialectType::Teradata)
31282 ) {
31283 self.write_keyword("SET");
31284 self.write_space();
31285 }
31286 self.write_keyword("QUERY_BAND");
31287 self.write(" = ");
31288 self.generate_expression(&e.this)?;
31289 if e.update.is_some() {
31290 self.write_space();
31291 self.write_keyword("UPDATE");
31292 }
31293 if let Some(scope) = &e.scope {
31294 self.write_space();
31295 self.write_keyword("FOR");
31296 self.write_space();
31297 self.generate_expression(scope)?;
31298 }
31299 Ok(())
31300 }
31301
31302 fn generate_query_option(&mut self, e: &QueryOption) -> Result<()> {
31303 self.generate_expression(&e.this)?;
31305 if let Some(expression) = &e.expression {
31306 self.write(" = ");
31307 self.generate_expression(expression)?;
31308 }
31309 Ok(())
31310 }
31311
31312 fn generate_query_transform(&mut self, e: &QueryTransform) -> Result<()> {
31313 self.write_keyword("TRANSFORM");
31315 self.write("(");
31316 for (i, expr) in e.expressions.iter().enumerate() {
31317 if i > 0 {
31318 self.write(", ");
31319 }
31320 self.generate_expression(expr)?;
31321 }
31322 self.write(")");
31323 if let Some(row_format_before) = &e.row_format_before {
31324 self.write_space();
31325 self.generate_expression(row_format_before)?;
31326 }
31327 if let Some(record_writer) = &e.record_writer {
31328 self.write_space();
31329 self.write_keyword("RECORDWRITER");
31330 self.write_space();
31331 self.generate_expression(record_writer)?;
31332 }
31333 if let Some(command_script) = &e.command_script {
31334 self.write_space();
31335 self.write_keyword("USING");
31336 self.write_space();
31337 self.generate_expression(command_script)?;
31338 }
31339 if let Some(schema) = &e.schema {
31340 self.write_space();
31341 self.write_keyword("AS");
31342 self.write_space();
31343 self.generate_expression(schema)?;
31344 }
31345 if let Some(row_format_after) = &e.row_format_after {
31346 self.write_space();
31347 self.generate_expression(row_format_after)?;
31348 }
31349 if let Some(record_reader) = &e.record_reader {
31350 self.write_space();
31351 self.write_keyword("RECORDREADER");
31352 self.write_space();
31353 self.generate_expression(record_reader)?;
31354 }
31355 Ok(())
31356 }
31357
31358 fn generate_randn(&mut self, e: &Randn) -> Result<()> {
31359 self.write_keyword("RANDN");
31361 self.write("(");
31362 if let Some(this) = &e.this {
31363 self.generate_expression(this)?;
31364 }
31365 self.write(")");
31366 Ok(())
31367 }
31368
31369 fn generate_randstr(&mut self, e: &Randstr) -> Result<()> {
31370 self.write_keyword("RANDSTR");
31372 self.write("(");
31373 self.generate_expression(&e.this)?;
31374 if let Some(generator) = &e.generator {
31375 self.write(", ");
31376 self.generate_expression(generator)?;
31377 }
31378 self.write(")");
31379 Ok(())
31380 }
31381
31382 fn generate_range_bucket(&mut self, e: &RangeBucket) -> Result<()> {
31383 self.write_keyword("RANGE_BUCKET");
31385 self.write("(");
31386 self.generate_expression(&e.this)?;
31387 self.write(", ");
31388 self.generate_expression(&e.expression)?;
31389 self.write(")");
31390 Ok(())
31391 }
31392
31393 fn generate_range_n(&mut self, e: &RangeN) -> Result<()> {
31394 self.write_keyword("RANGE_N");
31396 self.write("(");
31397 self.generate_expression(&e.this)?;
31398 self.write_space();
31399 self.write_keyword("BETWEEN");
31400 self.write_space();
31401 for (i, expr) in e.expressions.iter().enumerate() {
31402 if i > 0 {
31403 self.write(", ");
31404 }
31405 self.generate_expression(expr)?;
31406 }
31407 if let Some(each) = &e.each {
31408 self.write_space();
31409 self.write_keyword("EACH");
31410 self.write_space();
31411 self.generate_expression(each)?;
31412 }
31413 self.write(")");
31414 Ok(())
31415 }
31416
31417 fn generate_read_csv(&mut self, e: &ReadCSV) -> Result<()> {
31418 self.write_keyword("READ_CSV");
31420 self.write("(");
31421 self.generate_expression(&e.this)?;
31422 for expr in &e.expressions {
31423 self.write(", ");
31424 self.generate_expression(expr)?;
31425 }
31426 self.write(")");
31427 Ok(())
31428 }
31429
31430 fn generate_read_parquet(&mut self, e: &ReadParquet) -> Result<()> {
31431 self.write_keyword("READ_PARQUET");
31433 self.write("(");
31434 for (i, expr) in e.expressions.iter().enumerate() {
31435 if i > 0 {
31436 self.write(", ");
31437 }
31438 self.generate_expression(expr)?;
31439 }
31440 self.write(")");
31441 Ok(())
31442 }
31443
31444 fn generate_recursive_with_search(&mut self, e: &RecursiveWithSearch) -> Result<()> {
31445 if e.kind == "CYCLE" {
31448 self.write_keyword("CYCLE");
31449 } else {
31450 self.write_keyword("SEARCH");
31451 self.write_space();
31452 self.write(&e.kind);
31453 self.write_space();
31454 self.write_keyword("FIRST BY");
31455 }
31456 self.write_space();
31457 self.generate_expression(&e.this)?;
31458 self.write_space();
31459 self.write_keyword("SET");
31460 self.write_space();
31461 self.generate_expression(&e.expression)?;
31462 if let Some(using) = &e.using {
31463 self.write_space();
31464 self.write_keyword("USING");
31465 self.write_space();
31466 self.generate_expression(using)?;
31467 }
31468 Ok(())
31469 }
31470
31471 fn generate_reduce(&mut self, e: &Reduce) -> Result<()> {
31472 self.write_keyword("REDUCE");
31474 self.write("(");
31475 self.generate_expression(&e.this)?;
31476 if let Some(initial) = &e.initial {
31477 self.write(", ");
31478 self.generate_expression(initial)?;
31479 }
31480 if let Some(merge) = &e.merge {
31481 self.write(", ");
31482 self.generate_expression(merge)?;
31483 }
31484 if let Some(finish) = &e.finish {
31485 self.write(", ");
31486 self.generate_expression(finish)?;
31487 }
31488 self.write(")");
31489 Ok(())
31490 }
31491
31492 fn generate_reference(&mut self, e: &Reference) -> Result<()> {
31493 self.write_keyword("REFERENCES");
31495 self.write_space();
31496 self.generate_expression(&e.this)?;
31497 if !e.expressions.is_empty() {
31498 self.write(" (");
31499 for (i, expr) in e.expressions.iter().enumerate() {
31500 if i > 0 {
31501 self.write(", ");
31502 }
31503 self.generate_expression(expr)?;
31504 }
31505 self.write(")");
31506 }
31507 for opt in &e.options {
31508 self.write_space();
31509 self.generate_expression(opt)?;
31510 }
31511 Ok(())
31512 }
31513
31514 fn generate_refresh(&mut self, e: &Refresh) -> Result<()> {
31515 self.write_keyword("REFRESH");
31517 if !e.kind.is_empty() {
31518 self.write_space();
31519 self.write_keyword(&e.kind);
31520 }
31521 self.write_space();
31522 self.generate_expression(&e.this)?;
31523 Ok(())
31524 }
31525
31526 fn generate_refresh_trigger_property(&mut self, e: &RefreshTriggerProperty) -> Result<()> {
31527 self.write_keyword("REFRESH");
31529 self.write_space();
31530 self.write_keyword(&e.method);
31531
31532 if let Some(ref kind) = e.kind {
31533 self.write_space();
31534 self.write_keyword("ON");
31535 self.write_space();
31536 self.write_keyword(kind);
31537
31538 if let Some(ref every) = e.every {
31540 self.write_space();
31541 self.write_keyword("EVERY");
31542 self.write_space();
31543 self.generate_expression(every)?;
31544 if let Some(ref unit) = e.unit {
31545 self.write_space();
31546 self.write_keyword(unit);
31547 }
31548 }
31549
31550 if let Some(ref starts) = e.starts {
31552 self.write_space();
31553 self.write_keyword("STARTS");
31554 self.write_space();
31555 self.generate_expression(starts)?;
31556 }
31557 }
31558 Ok(())
31559 }
31560
31561 fn generate_regexp_count(&mut self, e: &RegexpCount) -> Result<()> {
31562 self.write_keyword("REGEXP_COUNT");
31564 self.write("(");
31565 self.generate_expression(&e.this)?;
31566 self.write(", ");
31567 self.generate_expression(&e.expression)?;
31568 if let Some(position) = &e.position {
31569 self.write(", ");
31570 self.generate_expression(position)?;
31571 }
31572 if let Some(parameters) = &e.parameters {
31573 self.write(", ");
31574 self.generate_expression(parameters)?;
31575 }
31576 self.write(")");
31577 Ok(())
31578 }
31579
31580 fn generate_regexp_extract_all(&mut self, e: &RegexpExtractAll) -> Result<()> {
31581 self.write_keyword("REGEXP_EXTRACT_ALL");
31583 self.write("(");
31584 self.generate_expression(&e.this)?;
31585 self.write(", ");
31586 self.generate_expression(&e.expression)?;
31587 if let Some(group) = &e.group {
31588 self.write(", ");
31589 self.generate_expression(group)?;
31590 }
31591 self.write(")");
31592 Ok(())
31593 }
31594
31595 fn generate_regexp_full_match(&mut self, e: &RegexpFullMatch) -> Result<()> {
31596 self.write_keyword("REGEXP_FULL_MATCH");
31598 self.write("(");
31599 self.generate_expression(&e.this)?;
31600 self.write(", ");
31601 self.generate_expression(&e.expression)?;
31602 self.write(")");
31603 Ok(())
31604 }
31605
31606 fn generate_regexp_i_like(&mut self, e: &RegexpILike) -> Result<()> {
31607 use crate::dialects::DialectType;
31608 if matches!(
31610 self.config.dialect,
31611 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
31612 ) && e.flag.is_none()
31613 {
31614 self.generate_expression(&e.this)?;
31615 self.write(" ~* ");
31616 self.generate_expression(&e.expression)?;
31617 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
31618 self.write_keyword("REGEXP_LIKE");
31620 self.write("(");
31621 self.generate_expression(&e.this)?;
31622 self.write(", ");
31623 self.generate_expression(&e.expression)?;
31624 self.write(", ");
31625 if let Some(flag) = &e.flag {
31626 self.generate_expression(flag)?;
31627 } else {
31628 self.write("'i'");
31629 }
31630 self.write(")");
31631 } else {
31632 self.generate_expression(&e.this)?;
31634 self.write_space();
31635 self.write_keyword("REGEXP_ILIKE");
31636 self.write_space();
31637 self.generate_expression(&e.expression)?;
31638 if let Some(flag) = &e.flag {
31639 self.write(", ");
31640 self.generate_expression(flag)?;
31641 }
31642 }
31643 Ok(())
31644 }
31645
31646 fn generate_regexp_instr(&mut self, e: &RegexpInstr) -> Result<()> {
31647 self.write_keyword("REGEXP_INSTR");
31649 self.write("(");
31650 self.generate_expression(&e.this)?;
31651 self.write(", ");
31652 self.generate_expression(&e.expression)?;
31653 if let Some(position) = &e.position {
31654 self.write(", ");
31655 self.generate_expression(position)?;
31656 }
31657 if let Some(occurrence) = &e.occurrence {
31658 self.write(", ");
31659 self.generate_expression(occurrence)?;
31660 }
31661 if let Some(option) = &e.option {
31662 self.write(", ");
31663 self.generate_expression(option)?;
31664 }
31665 if let Some(parameters) = &e.parameters {
31666 self.write(", ");
31667 self.generate_expression(parameters)?;
31668 }
31669 if let Some(group) = &e.group {
31670 self.write(", ");
31671 self.generate_expression(group)?;
31672 }
31673 self.write(")");
31674 Ok(())
31675 }
31676
31677 fn generate_regexp_split(&mut self, e: &RegexpSplit) -> Result<()> {
31678 self.write_keyword("REGEXP_SPLIT");
31680 self.write("(");
31681 self.generate_expression(&e.this)?;
31682 self.write(", ");
31683 self.generate_expression(&e.expression)?;
31684 if let Some(limit) = &e.limit {
31685 self.write(", ");
31686 self.generate_expression(limit)?;
31687 }
31688 self.write(")");
31689 Ok(())
31690 }
31691
31692 fn generate_regr_avgx(&mut self, e: &RegrAvgx) -> Result<()> {
31693 self.write_keyword("REGR_AVGX");
31695 self.write("(");
31696 self.generate_expression(&e.this)?;
31697 self.write(", ");
31698 self.generate_expression(&e.expression)?;
31699 self.write(")");
31700 Ok(())
31701 }
31702
31703 fn generate_regr_avgy(&mut self, e: &RegrAvgy) -> Result<()> {
31704 self.write_keyword("REGR_AVGY");
31706 self.write("(");
31707 self.generate_expression(&e.this)?;
31708 self.write(", ");
31709 self.generate_expression(&e.expression)?;
31710 self.write(")");
31711 Ok(())
31712 }
31713
31714 fn generate_regr_count(&mut self, e: &RegrCount) -> Result<()> {
31715 self.write_keyword("REGR_COUNT");
31717 self.write("(");
31718 self.generate_expression(&e.this)?;
31719 self.write(", ");
31720 self.generate_expression(&e.expression)?;
31721 self.write(")");
31722 Ok(())
31723 }
31724
31725 fn generate_regr_intercept(&mut self, e: &RegrIntercept) -> Result<()> {
31726 self.write_keyword("REGR_INTERCEPT");
31728 self.write("(");
31729 self.generate_expression(&e.this)?;
31730 self.write(", ");
31731 self.generate_expression(&e.expression)?;
31732 self.write(")");
31733 Ok(())
31734 }
31735
31736 fn generate_regr_r2(&mut self, e: &RegrR2) -> Result<()> {
31737 self.write_keyword("REGR_R2");
31739 self.write("(");
31740 self.generate_expression(&e.this)?;
31741 self.write(", ");
31742 self.generate_expression(&e.expression)?;
31743 self.write(")");
31744 Ok(())
31745 }
31746
31747 fn generate_regr_slope(&mut self, e: &RegrSlope) -> Result<()> {
31748 self.write_keyword("REGR_SLOPE");
31750 self.write("(");
31751 self.generate_expression(&e.this)?;
31752 self.write(", ");
31753 self.generate_expression(&e.expression)?;
31754 self.write(")");
31755 Ok(())
31756 }
31757
31758 fn generate_regr_sxx(&mut self, e: &RegrSxx) -> Result<()> {
31759 self.write_keyword("REGR_SXX");
31761 self.write("(");
31762 self.generate_expression(&e.this)?;
31763 self.write(", ");
31764 self.generate_expression(&e.expression)?;
31765 self.write(")");
31766 Ok(())
31767 }
31768
31769 fn generate_regr_sxy(&mut self, e: &RegrSxy) -> Result<()> {
31770 self.write_keyword("REGR_SXY");
31772 self.write("(");
31773 self.generate_expression(&e.this)?;
31774 self.write(", ");
31775 self.generate_expression(&e.expression)?;
31776 self.write(")");
31777 Ok(())
31778 }
31779
31780 fn generate_regr_syy(&mut self, e: &RegrSyy) -> Result<()> {
31781 self.write_keyword("REGR_SYY");
31783 self.write("(");
31784 self.generate_expression(&e.this)?;
31785 self.write(", ");
31786 self.generate_expression(&e.expression)?;
31787 self.write(")");
31788 Ok(())
31789 }
31790
31791 fn generate_regr_valx(&mut self, e: &RegrValx) -> Result<()> {
31792 self.write_keyword("REGR_VALX");
31794 self.write("(");
31795 self.generate_expression(&e.this)?;
31796 self.write(", ");
31797 self.generate_expression(&e.expression)?;
31798 self.write(")");
31799 Ok(())
31800 }
31801
31802 fn generate_regr_valy(&mut self, e: &RegrValy) -> Result<()> {
31803 self.write_keyword("REGR_VALY");
31805 self.write("(");
31806 self.generate_expression(&e.this)?;
31807 self.write(", ");
31808 self.generate_expression(&e.expression)?;
31809 self.write(")");
31810 Ok(())
31811 }
31812
31813 fn generate_remote_with_connection_model_property(
31814 &mut self,
31815 e: &RemoteWithConnectionModelProperty,
31816 ) -> Result<()> {
31817 self.write_keyword("REMOTE WITH CONNECTION");
31819 self.write_space();
31820 self.generate_expression(&e.this)?;
31821 Ok(())
31822 }
31823
31824 fn generate_rename_column(&mut self, e: &RenameColumn) -> Result<()> {
31825 self.write_keyword("RENAME COLUMN");
31827 if e.exists {
31828 self.write_space();
31829 self.write_keyword("IF EXISTS");
31830 }
31831 self.write_space();
31832 self.generate_expression(&e.this)?;
31833 if let Some(to) = &e.to {
31834 self.write_space();
31835 self.write_keyword("TO");
31836 self.write_space();
31837 self.generate_expression(to)?;
31838 }
31839 Ok(())
31840 }
31841
31842 fn generate_replace_partition(&mut self, e: &ReplacePartition) -> Result<()> {
31843 self.write_keyword("REPLACE PARTITION");
31845 self.write_space();
31846 self.generate_expression(&e.expression)?;
31847 if let Some(source) = &e.source {
31848 self.write_space();
31849 self.write_keyword("FROM");
31850 self.write_space();
31851 self.generate_expression(source)?;
31852 }
31853 Ok(())
31854 }
31855
31856 fn generate_returning(&mut self, e: &Returning) -> Result<()> {
31857 let keyword = match self.config.dialect {
31860 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "OUTPUT",
31861 _ => "RETURNING",
31862 };
31863 self.write_keyword(keyword);
31864 self.write_space();
31865 for (i, expr) in e.expressions.iter().enumerate() {
31866 if i > 0 {
31867 self.write(", ");
31868 }
31869 self.generate_expression(expr)?;
31870 }
31871 if let Some(into) = &e.into {
31872 self.write_space();
31873 self.write_keyword("INTO");
31874 self.write_space();
31875 self.generate_expression(into)?;
31876 }
31877 Ok(())
31878 }
31879
31880 fn generate_output_clause(&mut self, output: &OutputClause) -> Result<()> {
31881 self.write_space();
31883 self.write_keyword("OUTPUT");
31884 self.write_space();
31885 for (i, expr) in output.columns.iter().enumerate() {
31886 if i > 0 {
31887 self.write(", ");
31888 }
31889 self.generate_expression(expr)?;
31890 }
31891 if let Some(into_table) = &output.into_table {
31892 self.write_space();
31893 self.write_keyword("INTO");
31894 self.write_space();
31895 self.generate_expression(into_table)?;
31896 }
31897 Ok(())
31898 }
31899
31900 fn generate_returns_property(&mut self, e: &ReturnsProperty) -> Result<()> {
31901 self.write_keyword("RETURNS");
31903 if e.is_table.is_some() {
31904 self.write_space();
31905 self.write_keyword("TABLE");
31906 }
31907 if let Some(table) = &e.table {
31908 self.write_space();
31909 self.generate_expression(table)?;
31910 } else if let Some(this) = &e.this {
31911 self.write_space();
31912 self.generate_expression(this)?;
31913 }
31914 if e.null.is_some() {
31915 self.write_space();
31916 self.write_keyword("NULL ON NULL INPUT");
31917 }
31918 Ok(())
31919 }
31920
31921 fn generate_rollback(&mut self, e: &Rollback) -> Result<()> {
31922 self.write_keyword("ROLLBACK");
31924
31925 if e.this.is_none()
31927 && matches!(
31928 self.config.dialect,
31929 Some(DialectType::TSQL) | Some(DialectType::Fabric)
31930 )
31931 {
31932 self.write_space();
31933 self.write_keyword("TRANSACTION");
31934 }
31935
31936 if let Some(this) = &e.this {
31938 let is_transaction_marker = matches!(
31940 this.as_ref(),
31941 Expression::Identifier(id) if id.name == "TRANSACTION"
31942 );
31943
31944 self.write_space();
31945 self.write_keyword("TRANSACTION");
31946
31947 if !is_transaction_marker {
31949 self.write_space();
31950 self.generate_expression(this)?;
31951 }
31952 }
31953
31954 if let Some(savepoint) = &e.savepoint {
31956 self.write_space();
31957 self.write_keyword("TO");
31958 self.write_space();
31959 self.generate_expression(savepoint)?;
31960 }
31961 Ok(())
31962 }
31963
31964 fn generate_rollup(&mut self, e: &Rollup) -> Result<()> {
31965 if e.expressions.is_empty() {
31967 self.write_keyword("WITH ROLLUP");
31968 } else {
31969 self.write_keyword("ROLLUP");
31970 self.write("(");
31971 for (i, expr) in e.expressions.iter().enumerate() {
31972 if i > 0 {
31973 self.write(", ");
31974 }
31975 self.generate_expression(expr)?;
31976 }
31977 self.write(")");
31978 }
31979 Ok(())
31980 }
31981
31982 fn generate_row_format_delimited_property(
31983 &mut self,
31984 e: &RowFormatDelimitedProperty,
31985 ) -> Result<()> {
31986 self.write_keyword("ROW FORMAT DELIMITED");
31988 if let Some(fields) = &e.fields {
31989 self.write_space();
31990 self.write_keyword("FIELDS TERMINATED BY");
31991 self.write_space();
31992 self.generate_expression(fields)?;
31993 }
31994 if let Some(escaped) = &e.escaped {
31995 self.write_space();
31996 self.write_keyword("ESCAPED BY");
31997 self.write_space();
31998 self.generate_expression(escaped)?;
31999 }
32000 if let Some(items) = &e.collection_items {
32001 self.write_space();
32002 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
32003 self.write_space();
32004 self.generate_expression(items)?;
32005 }
32006 if let Some(keys) = &e.map_keys {
32007 self.write_space();
32008 self.write_keyword("MAP KEYS TERMINATED BY");
32009 self.write_space();
32010 self.generate_expression(keys)?;
32011 }
32012 if let Some(lines) = &e.lines {
32013 self.write_space();
32014 self.write_keyword("LINES TERMINATED BY");
32015 self.write_space();
32016 self.generate_expression(lines)?;
32017 }
32018 if let Some(null) = &e.null {
32019 self.write_space();
32020 self.write_keyword("NULL DEFINED AS");
32021 self.write_space();
32022 self.generate_expression(null)?;
32023 }
32024 if let Some(serde) = &e.serde {
32025 self.write_space();
32026 self.generate_expression(serde)?;
32027 }
32028 Ok(())
32029 }
32030
32031 fn generate_row_format_property(&mut self, e: &RowFormatProperty) -> Result<()> {
32032 self.write_keyword("ROW FORMAT");
32034 self.write_space();
32035 self.generate_expression(&e.this)?;
32036 Ok(())
32037 }
32038
32039 fn generate_row_format_serde_property(&mut self, e: &RowFormatSerdeProperty) -> Result<()> {
32040 self.write_keyword("ROW FORMAT SERDE");
32042 self.write_space();
32043 self.generate_expression(&e.this)?;
32044 if let Some(props) = &e.serde_properties {
32045 self.write_space();
32046 self.generate_expression(props)?;
32048 }
32049 Ok(())
32050 }
32051
32052 fn generate_sha2(&mut self, e: &SHA2) -> Result<()> {
32053 self.write_keyword("SHA2");
32055 self.write("(");
32056 self.generate_expression(&e.this)?;
32057 if let Some(length) = e.length {
32058 self.write(", ");
32059 self.write(&length.to_string());
32060 }
32061 self.write(")");
32062 Ok(())
32063 }
32064
32065 fn generate_sha2_digest(&mut self, e: &SHA2Digest) -> Result<()> {
32066 self.write_keyword("SHA2_DIGEST");
32068 self.write("(");
32069 self.generate_expression(&e.this)?;
32070 if let Some(length) = e.length {
32071 self.write(", ");
32072 self.write(&length.to_string());
32073 }
32074 self.write(")");
32075 Ok(())
32076 }
32077
32078 fn generate_safe_add(&mut self, e: &SafeAdd) -> Result<()> {
32079 let name = if matches!(
32080 self.config.dialect,
32081 Some(crate::dialects::DialectType::Spark)
32082 | Some(crate::dialects::DialectType::Databricks)
32083 ) {
32084 "TRY_ADD"
32085 } else {
32086 "SAFE_ADD"
32087 };
32088 self.write_keyword(name);
32089 self.write("(");
32090 self.generate_expression(&e.this)?;
32091 self.write(", ");
32092 self.generate_expression(&e.expression)?;
32093 self.write(")");
32094 Ok(())
32095 }
32096
32097 fn generate_safe_divide(&mut self, e: &SafeDivide) -> Result<()> {
32098 self.write_keyword("SAFE_DIVIDE");
32100 self.write("(");
32101 self.generate_expression(&e.this)?;
32102 self.write(", ");
32103 self.generate_expression(&e.expression)?;
32104 self.write(")");
32105 Ok(())
32106 }
32107
32108 fn generate_safe_multiply(&mut self, e: &SafeMultiply) -> Result<()> {
32109 let name = if matches!(
32110 self.config.dialect,
32111 Some(crate::dialects::DialectType::Spark)
32112 | Some(crate::dialects::DialectType::Databricks)
32113 ) {
32114 "TRY_MULTIPLY"
32115 } else {
32116 "SAFE_MULTIPLY"
32117 };
32118 self.write_keyword(name);
32119 self.write("(");
32120 self.generate_expression(&e.this)?;
32121 self.write(", ");
32122 self.generate_expression(&e.expression)?;
32123 self.write(")");
32124 Ok(())
32125 }
32126
32127 fn generate_safe_subtract(&mut self, e: &SafeSubtract) -> Result<()> {
32128 let name = if matches!(
32129 self.config.dialect,
32130 Some(crate::dialects::DialectType::Spark)
32131 | Some(crate::dialects::DialectType::Databricks)
32132 ) {
32133 "TRY_SUBTRACT"
32134 } else {
32135 "SAFE_SUBTRACT"
32136 };
32137 self.write_keyword(name);
32138 self.write("(");
32139 self.generate_expression(&e.this)?;
32140 self.write(", ");
32141 self.generate_expression(&e.expression)?;
32142 self.write(")");
32143 Ok(())
32144 }
32145
32146 fn generate_sample_body(&mut self, sample: &Sample) -> Result<()> {
32149 if matches!(sample.method, SampleMethod::Bucket) {
32151 self.write(" (");
32152 self.write_keyword("BUCKET");
32153 self.write_space();
32154 if let Some(ref num) = sample.bucket_numerator {
32155 self.generate_expression(num)?;
32156 }
32157 self.write_space();
32158 self.write_keyword("OUT OF");
32159 self.write_space();
32160 if let Some(ref denom) = sample.bucket_denominator {
32161 self.generate_expression(denom)?;
32162 }
32163 if let Some(ref field) = sample.bucket_field {
32164 self.write_space();
32165 self.write_keyword("ON");
32166 self.write_space();
32167 self.generate_expression(field)?;
32168 }
32169 self.write(")");
32170 return Ok(());
32171 }
32172
32173 let is_snowflake = matches!(
32175 self.config.dialect,
32176 Some(crate::dialects::DialectType::Snowflake)
32177 );
32178 let is_postgres = matches!(
32179 self.config.dialect,
32180 Some(crate::dialects::DialectType::PostgreSQL)
32181 | Some(crate::dialects::DialectType::Redshift)
32182 );
32183 let is_databricks = matches!(
32185 self.config.dialect,
32186 Some(crate::dialects::DialectType::Databricks)
32187 );
32188 let is_spark = matches!(
32189 self.config.dialect,
32190 Some(crate::dialects::DialectType::Spark)
32191 );
32192 let suppress_method = is_databricks || is_spark || sample.suppress_method_output;
32193 let force_method = is_postgres && matches!(sample.method, SampleMethod::Bernoulli);
32195 if !suppress_method && (sample.explicit_method || is_snowflake || force_method) {
32196 self.write_space();
32197 if !sample.explicit_method && (is_snowflake || force_method) {
32198 self.write_keyword("BERNOULLI");
32200 } else {
32201 match sample.method {
32202 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
32203 SampleMethod::System => self.write_keyword("SYSTEM"),
32204 SampleMethod::Block => self.write_keyword("BLOCK"),
32205 SampleMethod::Row => self.write_keyword("ROW"),
32206 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
32207 SampleMethod::Percent => self.write_keyword("SYSTEM"),
32208 SampleMethod::Bucket => {} }
32210 }
32211 }
32212
32213 let emit_size_no_parens = !self.config.tablesample_requires_parens;
32215 if emit_size_no_parens {
32216 self.write_space();
32217 match &sample.size {
32218 Expression::Tuple(tuple) => {
32219 for (i, expr) in tuple.expressions.iter().enumerate() {
32220 if i > 0 {
32221 self.write(", ");
32222 }
32223 self.generate_expression(expr)?;
32224 }
32225 }
32226 expr => self.generate_expression(expr)?,
32227 }
32228 } else {
32229 self.write(" (");
32230 self.generate_expression(&sample.size)?;
32231 }
32232
32233 let is_rows_method = matches!(
32235 sample.method,
32236 SampleMethod::Reservoir | SampleMethod::Row | SampleMethod::Bucket
32237 );
32238 let is_percent = matches!(
32239 sample.method,
32240 SampleMethod::Percent
32241 | SampleMethod::System
32242 | SampleMethod::Bernoulli
32243 | SampleMethod::Block
32244 );
32245
32246 let is_presto = matches!(
32250 self.config.dialect,
32251 Some(crate::dialects::DialectType::Presto)
32252 | Some(crate::dialects::DialectType::Trino)
32253 | Some(crate::dialects::DialectType::Athena)
32254 );
32255 let should_output_unit = if is_databricks || is_spark {
32256 is_percent || is_rows_method || sample.unit_after_size
32258 } else if is_snowflake || is_postgres || is_presto {
32259 sample.unit_after_size
32260 } else {
32261 sample.unit_after_size || (sample.explicit_method && (is_rows_method || is_percent))
32262 };
32263
32264 if should_output_unit {
32265 self.write_space();
32266 if sample.is_percent {
32267 self.write_keyword("PERCENT");
32268 } else if is_rows_method && !sample.unit_after_size {
32269 self.write_keyword("ROWS");
32270 } else if sample.unit_after_size {
32271 match sample.method {
32272 SampleMethod::Percent
32273 | SampleMethod::System
32274 | SampleMethod::Bernoulli
32275 | SampleMethod::Block => {
32276 self.write_keyword("PERCENT");
32277 }
32278 SampleMethod::Row | SampleMethod::Reservoir => {
32279 self.write_keyword("ROWS");
32280 }
32281 _ => self.write_keyword("ROWS"),
32282 }
32283 } else {
32284 self.write_keyword("PERCENT");
32285 }
32286 }
32287
32288 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
32289 if let Some(ref offset) = sample.offset {
32290 self.write_space();
32291 self.write_keyword("OFFSET");
32292 self.write_space();
32293 self.generate_expression(offset)?;
32294 }
32295 }
32296 if !emit_size_no_parens {
32297 self.write(")");
32298 }
32299
32300 Ok(())
32301 }
32302
32303 fn generate_sample_property(&mut self, e: &SampleProperty) -> Result<()> {
32304 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
32306 self.write_keyword("SAMPLE BY");
32307 } else {
32308 self.write_keyword("SAMPLE");
32309 }
32310 self.write_space();
32311 self.generate_expression(&e.this)?;
32312 Ok(())
32313 }
32314
32315 fn generate_schema(&mut self, e: &Schema) -> Result<()> {
32316 if let Some(this) = &e.this {
32318 self.generate_expression(this)?;
32319 }
32320 if !e.expressions.is_empty() {
32321 if e.this.is_some() {
32323 self.write_space();
32324 }
32325 self.write("(");
32326 for (i, expr) in e.expressions.iter().enumerate() {
32327 if i > 0 {
32328 self.write(", ");
32329 }
32330 self.generate_expression(expr)?;
32331 }
32332 self.write(")");
32333 }
32334 Ok(())
32335 }
32336
32337 fn generate_schema_comment_property(&mut self, e: &SchemaCommentProperty) -> Result<()> {
32338 self.write_keyword("COMMENT");
32340 self.write_space();
32341 self.generate_expression(&e.this)?;
32342 Ok(())
32343 }
32344
32345 fn generate_scope_resolution(&mut self, e: &ScopeResolution) -> Result<()> {
32346 if let Some(this) = &e.this {
32348 self.generate_expression(this)?;
32349 self.write("::");
32350 }
32351 self.generate_expression(&e.expression)?;
32352 Ok(())
32353 }
32354
32355 fn generate_search(&mut self, e: &Search) -> Result<()> {
32356 self.write_keyword("SEARCH");
32358 self.write("(");
32359 self.generate_expression(&e.this)?;
32360 self.write(", ");
32361 self.generate_expression(&e.expression)?;
32362 if let Some(json_scope) = &e.json_scope {
32363 self.write(", ");
32364 self.generate_expression(json_scope)?;
32365 }
32366 if let Some(analyzer) = &e.analyzer {
32367 self.write(", ");
32368 self.generate_expression(analyzer)?;
32369 }
32370 if let Some(analyzer_options) = &e.analyzer_options {
32371 self.write(", ");
32372 self.generate_expression(analyzer_options)?;
32373 }
32374 if let Some(search_mode) = &e.search_mode {
32375 self.write(", ");
32376 self.generate_expression(search_mode)?;
32377 }
32378 self.write(")");
32379 Ok(())
32380 }
32381
32382 fn generate_search_ip(&mut self, e: &SearchIp) -> Result<()> {
32383 self.write_keyword("SEARCH_IP");
32385 self.write("(");
32386 self.generate_expression(&e.this)?;
32387 self.write(", ");
32388 self.generate_expression(&e.expression)?;
32389 self.write(")");
32390 Ok(())
32391 }
32392
32393 fn generate_security_property(&mut self, e: &SecurityProperty) -> Result<()> {
32394 self.write_keyword("SECURITY");
32396 self.write_space();
32397 self.generate_expression(&e.this)?;
32398 Ok(())
32399 }
32400
32401 fn generate_semantic_view(&mut self, e: &SemanticView) -> Result<()> {
32402 self.write("SEMANTIC_VIEW(");
32404
32405 if self.config.pretty {
32406 self.write_newline();
32408 self.indent_level += 1;
32409 self.write_indent();
32410 self.generate_expression(&e.this)?;
32411
32412 if let Some(metrics) = &e.metrics {
32413 self.write_newline();
32414 self.write_indent();
32415 self.write_keyword("METRICS");
32416 self.write_space();
32417 self.generate_semantic_view_tuple(metrics)?;
32418 }
32419 if let Some(dimensions) = &e.dimensions {
32420 self.write_newline();
32421 self.write_indent();
32422 self.write_keyword("DIMENSIONS");
32423 self.write_space();
32424 self.generate_semantic_view_tuple(dimensions)?;
32425 }
32426 if let Some(facts) = &e.facts {
32427 self.write_newline();
32428 self.write_indent();
32429 self.write_keyword("FACTS");
32430 self.write_space();
32431 self.generate_semantic_view_tuple(facts)?;
32432 }
32433 if let Some(where_) = &e.where_ {
32434 self.write_newline();
32435 self.write_indent();
32436 self.write_keyword("WHERE");
32437 self.write_space();
32438 self.generate_expression(where_)?;
32439 }
32440 self.write_newline();
32441 self.indent_level -= 1;
32442 self.write_indent();
32443 } else {
32444 self.generate_expression(&e.this)?;
32446 if let Some(metrics) = &e.metrics {
32447 self.write_space();
32448 self.write_keyword("METRICS");
32449 self.write_space();
32450 self.generate_semantic_view_tuple(metrics)?;
32451 }
32452 if let Some(dimensions) = &e.dimensions {
32453 self.write_space();
32454 self.write_keyword("DIMENSIONS");
32455 self.write_space();
32456 self.generate_semantic_view_tuple(dimensions)?;
32457 }
32458 if let Some(facts) = &e.facts {
32459 self.write_space();
32460 self.write_keyword("FACTS");
32461 self.write_space();
32462 self.generate_semantic_view_tuple(facts)?;
32463 }
32464 if let Some(where_) = &e.where_ {
32465 self.write_space();
32466 self.write_keyword("WHERE");
32467 self.write_space();
32468 self.generate_expression(where_)?;
32469 }
32470 }
32471 self.write(")");
32472 Ok(())
32473 }
32474
32475 fn generate_semantic_view_tuple(&mut self, expr: &Expression) -> Result<()> {
32477 if let Expression::Tuple(t) = expr {
32478 for (i, e) in t.expressions.iter().enumerate() {
32479 if i > 0 {
32480 self.write(", ");
32481 }
32482 self.generate_expression(e)?;
32483 }
32484 } else {
32485 self.generate_expression(expr)?;
32486 }
32487 Ok(())
32488 }
32489
32490 fn generate_sequence_properties(&mut self, e: &SequenceProperties) -> Result<()> {
32491 if let Some(start) = &e.start {
32493 self.write_keyword("START WITH");
32494 self.write_space();
32495 self.generate_expression(start)?;
32496 }
32497 if let Some(increment) = &e.increment {
32498 self.write_space();
32499 self.write_keyword("INCREMENT BY");
32500 self.write_space();
32501 self.generate_expression(increment)?;
32502 }
32503 if let Some(minvalue) = &e.minvalue {
32504 self.write_space();
32505 self.write_keyword("MINVALUE");
32506 self.write_space();
32507 self.generate_expression(minvalue)?;
32508 }
32509 if let Some(maxvalue) = &e.maxvalue {
32510 self.write_space();
32511 self.write_keyword("MAXVALUE");
32512 self.write_space();
32513 self.generate_expression(maxvalue)?;
32514 }
32515 if let Some(cache) = &e.cache {
32516 self.write_space();
32517 self.write_keyword("CACHE");
32518 self.write_space();
32519 self.generate_expression(cache)?;
32520 }
32521 if let Some(owned) = &e.owned {
32522 self.write_space();
32523 self.write_keyword("OWNED BY");
32524 self.write_space();
32525 self.generate_expression(owned)?;
32526 }
32527 for opt in &e.options {
32528 self.write_space();
32529 self.generate_expression(opt)?;
32530 }
32531 Ok(())
32532 }
32533
32534 fn generate_serde_properties(&mut self, e: &SerdeProperties) -> Result<()> {
32535 if e.with_.is_some() {
32537 self.write_keyword("WITH");
32538 self.write_space();
32539 }
32540 self.write_keyword("SERDEPROPERTIES");
32541 self.write(" (");
32542 for (i, expr) in e.expressions.iter().enumerate() {
32543 if i > 0 {
32544 self.write(", ");
32545 }
32546 match expr {
32548 Expression::Eq(eq) => {
32549 self.generate_expression(&eq.left)?;
32550 self.write("=");
32551 self.generate_expression(&eq.right)?;
32552 }
32553 _ => self.generate_expression(expr)?,
32554 }
32555 }
32556 self.write(")");
32557 Ok(())
32558 }
32559
32560 fn generate_session_parameter(&mut self, e: &SessionParameter) -> Result<()> {
32561 self.write("@@");
32563 if let Some(kind) = &e.kind {
32564 self.write(kind);
32565 self.write(".");
32566 }
32567 self.generate_expression(&e.this)?;
32568 Ok(())
32569 }
32570
32571 fn generate_set(&mut self, e: &Set) -> Result<()> {
32572 if e.unset.is_some() {
32574 self.write_keyword("UNSET");
32575 } else {
32576 self.write_keyword("SET");
32577 }
32578 if e.tag.is_some() {
32579 self.write_space();
32580 self.write_keyword("TAG");
32581 }
32582 if !e.expressions.is_empty() {
32583 self.write_space();
32584 for (i, expr) in e.expressions.iter().enumerate() {
32585 if i > 0 {
32586 self.write(", ");
32587 }
32588 self.generate_expression(expr)?;
32589 }
32590 }
32591 Ok(())
32592 }
32593
32594 fn generate_set_config_property(&mut self, e: &SetConfigProperty) -> Result<()> {
32595 self.write_keyword("SET");
32597 self.write_space();
32598 self.generate_expression(&e.this)?;
32599 Ok(())
32600 }
32601
32602 fn generate_set_item(&mut self, e: &SetItem) -> Result<()> {
32603 if let Some(kind) = &e.kind {
32605 self.write_keyword(kind);
32606 self.write_space();
32607 }
32608 self.generate_expression(&e.name)?;
32609 self.write(" = ");
32610 self.generate_expression(&e.value)?;
32611 Ok(())
32612 }
32613
32614 fn generate_set_operation(&mut self, e: &SetOperation) -> Result<()> {
32615 if let Some(with_) = &e.with_ {
32617 self.generate_expression(with_)?;
32618 self.write_space();
32619 }
32620 self.generate_expression(&e.this)?;
32621 self.write_space();
32622 if let Some(kind) = &e.kind {
32624 self.write_keyword(kind);
32625 }
32626 if e.distinct {
32627 self.write_space();
32628 self.write_keyword("DISTINCT");
32629 } else {
32630 self.write_space();
32631 self.write_keyword("ALL");
32632 }
32633 if e.by_name.is_some() {
32634 self.write_space();
32635 self.write_keyword("BY NAME");
32636 }
32637 self.write_space();
32638 self.generate_expression(&e.expression)?;
32639 Ok(())
32640 }
32641
32642 fn generate_set_property(&mut self, e: &SetProperty) -> Result<()> {
32643 if e.multi.is_some() {
32645 self.write_keyword("MULTISET");
32646 } else {
32647 self.write_keyword("SET");
32648 }
32649 Ok(())
32650 }
32651
32652 fn generate_settings_property(&mut self, e: &SettingsProperty) -> Result<()> {
32653 self.write_keyword("SETTINGS");
32655 if self.config.pretty && e.expressions.len() > 1 {
32656 self.indent_level += 1;
32658 for (i, expr) in e.expressions.iter().enumerate() {
32659 if i > 0 {
32660 self.write(",");
32661 }
32662 self.write_newline();
32663 self.write_indent();
32664 self.generate_expression(expr)?;
32665 }
32666 self.indent_level -= 1;
32667 } else {
32668 self.write_space();
32669 for (i, expr) in e.expressions.iter().enumerate() {
32670 if i > 0 {
32671 self.write(", ");
32672 }
32673 self.generate_expression(expr)?;
32674 }
32675 }
32676 Ok(())
32677 }
32678
32679 fn generate_sharing_property(&mut self, e: &SharingProperty) -> Result<()> {
32680 self.write_keyword("SHARING");
32682 if let Some(this) = &e.this {
32683 self.write(" = ");
32684 self.generate_expression(this)?;
32685 }
32686 Ok(())
32687 }
32688
32689 fn generate_slice(&mut self, e: &Slice) -> Result<()> {
32690 if let Some(begin) = &e.this {
32692 self.generate_expression(begin)?;
32693 }
32694 self.write(":");
32695 if let Some(end) = &e.expression {
32696 self.generate_expression(end)?;
32697 }
32698 if let Some(step) = &e.step {
32699 self.write(":");
32700 self.generate_expression(step)?;
32701 }
32702 Ok(())
32703 }
32704
32705 fn generate_sort_array(&mut self, e: &SortArray) -> Result<()> {
32706 self.write_keyword("SORT_ARRAY");
32708 self.write("(");
32709 self.generate_expression(&e.this)?;
32710 if let Some(asc) = &e.asc {
32711 self.write(", ");
32712 self.generate_expression(asc)?;
32713 }
32714 self.write(")");
32715 Ok(())
32716 }
32717
32718 fn generate_sort_by(&mut self, e: &SortBy) -> Result<()> {
32719 self.write_keyword("SORT BY");
32721 self.write_space();
32722 for (i, expr) in e.expressions.iter().enumerate() {
32723 if i > 0 {
32724 self.write(", ");
32725 }
32726 self.generate_ordered(expr)?;
32727 }
32728 Ok(())
32729 }
32730
32731 fn generate_sort_key_property(&mut self, e: &SortKeyProperty) -> Result<()> {
32732 if e.compound.is_some() {
32734 self.write_keyword("COMPOUND");
32735 self.write_space();
32736 }
32737 self.write_keyword("SORTKEY");
32738 self.write("(");
32739 if let Expression::Tuple(t) = e.this.as_ref() {
32741 for (i, expr) in t.expressions.iter().enumerate() {
32742 if i > 0 {
32743 self.write(", ");
32744 }
32745 self.generate_expression(expr)?;
32746 }
32747 } else {
32748 self.generate_expression(&e.this)?;
32749 }
32750 self.write(")");
32751 Ok(())
32752 }
32753
32754 fn generate_split_part(&mut self, e: &SplitPart) -> Result<()> {
32755 self.write_keyword("SPLIT_PART");
32757 self.write("(");
32758 self.generate_expression(&e.this)?;
32759 if let Some(delimiter) = &e.delimiter {
32760 self.write(", ");
32761 self.generate_expression(delimiter)?;
32762 }
32763 if let Some(part_index) = &e.part_index {
32764 self.write(", ");
32765 self.generate_expression(part_index)?;
32766 }
32767 self.write(")");
32768 Ok(())
32769 }
32770
32771 fn generate_sql_read_write_property(&mut self, e: &SqlReadWriteProperty) -> Result<()> {
32772 self.generate_expression(&e.this)?;
32774 Ok(())
32775 }
32776
32777 fn generate_sql_security_property(&mut self, e: &SqlSecurityProperty) -> Result<()> {
32778 self.write_keyword("SQL SECURITY");
32780 self.write_space();
32781 self.generate_expression(&e.this)?;
32782 Ok(())
32783 }
32784
32785 fn generate_st_distance(&mut self, e: &StDistance) -> Result<()> {
32786 self.write_keyword("ST_DISTANCE");
32788 self.write("(");
32789 self.generate_expression(&e.this)?;
32790 self.write(", ");
32791 self.generate_expression(&e.expression)?;
32792 if let Some(use_spheroid) = &e.use_spheroid {
32793 self.write(", ");
32794 self.generate_expression(use_spheroid)?;
32795 }
32796 self.write(")");
32797 Ok(())
32798 }
32799
32800 fn generate_st_point(&mut self, e: &StPoint) -> Result<()> {
32801 self.write_keyword("ST_POINT");
32803 self.write("(");
32804 self.generate_expression(&e.this)?;
32805 self.write(", ");
32806 self.generate_expression(&e.expression)?;
32807 self.write(")");
32808 Ok(())
32809 }
32810
32811 fn generate_stability_property(&mut self, e: &StabilityProperty) -> Result<()> {
32812 self.generate_expression(&e.this)?;
32814 Ok(())
32815 }
32816
32817 fn generate_standard_hash(&mut self, e: &StandardHash) -> Result<()> {
32818 self.write_keyword("STANDARD_HASH");
32820 self.write("(");
32821 self.generate_expression(&e.this)?;
32822 if let Some(expression) = &e.expression {
32823 self.write(", ");
32824 self.generate_expression(expression)?;
32825 }
32826 self.write(")");
32827 Ok(())
32828 }
32829
32830 fn generate_storage_handler_property(&mut self, e: &StorageHandlerProperty) -> Result<()> {
32831 self.write_keyword("STORED BY");
32833 self.write_space();
32834 self.generate_expression(&e.this)?;
32835 Ok(())
32836 }
32837
32838 fn generate_str_position(&mut self, e: &StrPosition) -> Result<()> {
32839 use crate::dialects::DialectType;
32842 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
32843 self.write_keyword("CHARINDEX");
32845 self.write("(");
32846 if let Some(substr) = &e.substr {
32847 self.generate_expression(substr)?;
32848 self.write(", ");
32849 }
32850 self.generate_expression(&e.this)?;
32851 if let Some(position) = &e.position {
32852 self.write(", ");
32853 self.generate_expression(position)?;
32854 }
32855 self.write(")");
32856 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
32857 self.write_keyword("POSITION");
32858 self.write("(");
32859 self.generate_expression(&e.this)?;
32860 if let Some(substr) = &e.substr {
32861 self.write(", ");
32862 self.generate_expression(substr)?;
32863 }
32864 if let Some(position) = &e.position {
32865 self.write(", ");
32866 self.generate_expression(position)?;
32867 }
32868 if let Some(occurrence) = &e.occurrence {
32869 self.write(", ");
32870 self.generate_expression(occurrence)?;
32871 }
32872 self.write(")");
32873 } else if matches!(
32874 self.config.dialect,
32875 Some(DialectType::SQLite)
32876 | Some(DialectType::Oracle)
32877 | Some(DialectType::BigQuery)
32878 | Some(DialectType::Teradata)
32879 ) {
32880 self.write_keyword("INSTR");
32881 self.write("(");
32882 self.generate_expression(&e.this)?;
32883 if let Some(substr) = &e.substr {
32884 self.write(", ");
32885 self.generate_expression(substr)?;
32886 }
32887 if let Some(position) = &e.position {
32888 self.write(", ");
32889 self.generate_expression(position)?;
32890 } else if e.occurrence.is_some() {
32891 self.write(", 1");
32894 }
32895 if let Some(occurrence) = &e.occurrence {
32896 self.write(", ");
32897 self.generate_expression(occurrence)?;
32898 }
32899 self.write(")");
32900 } else if matches!(
32901 self.config.dialect,
32902 Some(DialectType::MySQL)
32903 | Some(DialectType::SingleStore)
32904 | Some(DialectType::Doris)
32905 | Some(DialectType::StarRocks)
32906 | Some(DialectType::Hive)
32907 | Some(DialectType::Spark)
32908 | Some(DialectType::Databricks)
32909 ) {
32910 self.write_keyword("LOCATE");
32912 self.write("(");
32913 if let Some(substr) = &e.substr {
32914 self.generate_expression(substr)?;
32915 self.write(", ");
32916 }
32917 self.generate_expression(&e.this)?;
32918 if let Some(position) = &e.position {
32919 self.write(", ");
32920 self.generate_expression(position)?;
32921 }
32922 self.write(")");
32923 } else if matches!(self.config.dialect, Some(DialectType::TSQL)) {
32924 self.write_keyword("CHARINDEX");
32926 self.write("(");
32927 if let Some(substr) = &e.substr {
32928 self.generate_expression(substr)?;
32929 self.write(", ");
32930 }
32931 self.generate_expression(&e.this)?;
32932 if let Some(position) = &e.position {
32933 self.write(", ");
32934 self.generate_expression(position)?;
32935 }
32936 self.write(")");
32937 } else if matches!(
32938 self.config.dialect,
32939 Some(DialectType::PostgreSQL)
32940 | Some(DialectType::Materialize)
32941 | Some(DialectType::RisingWave)
32942 | Some(DialectType::Redshift)
32943 ) {
32944 self.write_keyword("POSITION");
32946 self.write("(");
32947 if let Some(substr) = &e.substr {
32948 self.generate_expression(substr)?;
32949 self.write(" IN ");
32950 }
32951 self.generate_expression(&e.this)?;
32952 self.write(")");
32953 } else {
32954 self.write_keyword("STRPOS");
32955 self.write("(");
32956 self.generate_expression(&e.this)?;
32957 if let Some(substr) = &e.substr {
32958 self.write(", ");
32959 self.generate_expression(substr)?;
32960 }
32961 if let Some(position) = &e.position {
32962 self.write(", ");
32963 self.generate_expression(position)?;
32964 }
32965 if let Some(occurrence) = &e.occurrence {
32966 self.write(", ");
32967 self.generate_expression(occurrence)?;
32968 }
32969 self.write(")");
32970 }
32971 Ok(())
32972 }
32973
32974 fn generate_str_to_date(&mut self, e: &StrToDate) -> Result<()> {
32975 match self.config.dialect {
32976 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
32977 self.write_keyword("TO_DATE");
32979 self.write("(");
32980 self.generate_expression(&e.this)?;
32981 if let Some(format) = &e.format {
32982 self.write(", '");
32983 self.write(&Self::strftime_to_java_format(format));
32984 self.write("'");
32985 }
32986 self.write(")");
32987 }
32988 Some(DialectType::DuckDB) => {
32989 self.write_keyword("CAST");
32991 self.write("(");
32992 self.write_keyword("STRPTIME");
32993 self.write("(");
32994 self.generate_expression(&e.this)?;
32995 if let Some(format) = &e.format {
32996 self.write(", '");
32997 self.write(format);
32998 self.write("'");
32999 }
33000 self.write(")");
33001 self.write_keyword(" AS ");
33002 self.write_keyword("DATE");
33003 self.write(")");
33004 }
33005 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
33006 self.write_keyword("TO_DATE");
33008 self.write("(");
33009 self.generate_expression(&e.this)?;
33010 if let Some(format) = &e.format {
33011 self.write(", '");
33012 self.write(&Self::strftime_to_postgres_format(format));
33013 self.write("'");
33014 }
33015 self.write(")");
33016 }
33017 Some(DialectType::BigQuery) => {
33018 self.write_keyword("PARSE_DATE");
33020 self.write("(");
33021 if let Some(format) = &e.format {
33022 self.write("'");
33023 self.write(format);
33024 self.write("'");
33025 self.write(", ");
33026 }
33027 self.generate_expression(&e.this)?;
33028 self.write(")");
33029 }
33030 Some(DialectType::Teradata) => {
33031 self.write_keyword("CAST");
33033 self.write("(");
33034 self.generate_expression(&e.this)?;
33035 self.write_keyword(" AS ");
33036 self.write_keyword("DATE");
33037 if let Some(format) = &e.format {
33038 self.write_keyword(" FORMAT ");
33039 self.write("'");
33040 self.write(&Self::strftime_to_teradata_format(format));
33041 self.write("'");
33042 }
33043 self.write(")");
33044 }
33045 _ => {
33046 self.write_keyword("STR_TO_DATE");
33048 self.write("(");
33049 self.generate_expression(&e.this)?;
33050 if let Some(format) = &e.format {
33051 self.write(", '");
33052 self.write(format);
33053 self.write("'");
33054 }
33055 self.write(")");
33056 }
33057 }
33058 Ok(())
33059 }
33060
33061 fn strftime_to_teradata_format(fmt: &str) -> String {
33063 let mut result = fmt.to_string();
33064 result = result.replace("%Y", "YYYY");
33065 result = result.replace("%y", "YY");
33066 result = result.replace("%m", "MM");
33067 result = result.replace("%B", "MMMM");
33068 result = result.replace("%b", "MMM");
33069 result = result.replace("%d", "DD");
33070 result = result.replace("%j", "DDD");
33071 result = result.replace("%H", "HH");
33072 result = result.replace("%M", "MI");
33073 result = result.replace("%S", "SS");
33074 result = result.replace("%f", "SSSSSS");
33075 result = result.replace("%A", "EEEE");
33076 result = result.replace("%a", "EEE");
33077 result
33078 }
33079
33080 pub fn strftime_to_java_format_static(fmt: &str) -> String {
33083 Self::strftime_to_java_format(fmt)
33084 }
33085
33086 fn strftime_to_java_format(fmt: &str) -> String {
33088 let mut result = fmt.to_string();
33089 result = result.replace("%-d", "d");
33091 result = result.replace("%-m", "M");
33092 result = result.replace("%-H", "H");
33093 result = result.replace("%-M", "m");
33094 result = result.replace("%-S", "s");
33095 result = result.replace("%Y", "yyyy");
33096 result = result.replace("%y", "yy");
33097 result = result.replace("%m", "MM");
33098 result = result.replace("%B", "MMMM");
33099 result = result.replace("%b", "MMM");
33100 result = result.replace("%d", "dd");
33101 result = result.replace("%j", "DDD");
33102 result = result.replace("%H", "HH");
33103 result = result.replace("%M", "mm");
33104 result = result.replace("%S", "ss");
33105 result = result.replace("%f", "SSSSSS");
33106 result = result.replace("%A", "EEEE");
33107 result = result.replace("%a", "EEE");
33108 result
33109 }
33110
33111 fn strftime_to_tsql_format(fmt: &str) -> String {
33114 let mut result = fmt.to_string();
33115 result = result.replace("%-d", "d");
33117 result = result.replace("%-m", "M");
33118 result = result.replace("%-H", "H");
33119 result = result.replace("%-M", "m");
33120 result = result.replace("%-S", "s");
33121 result = result.replace("%Y", "yyyy");
33122 result = result.replace("%y", "yy");
33123 result = result.replace("%m", "MM");
33124 result = result.replace("%B", "MMMM");
33125 result = result.replace("%b", "MMM");
33126 result = result.replace("%d", "dd");
33127 result = result.replace("%j", "DDD");
33128 result = result.replace("%H", "HH");
33129 result = result.replace("%M", "mm");
33130 result = result.replace("%S", "ss");
33131 result = result.replace("%f", "ffffff");
33132 result = result.replace("%A", "dddd");
33133 result = result.replace("%a", "ddd");
33134 result
33135 }
33136
33137 fn decompose_json_path(path: &str) -> Vec<String> {
33140 let mut parts = Vec::new();
33141 let path = if path.starts_with("$.") {
33143 &path[2..]
33144 } else if path.starts_with('$') {
33145 &path[1..]
33146 } else {
33147 path
33148 };
33149 if path.is_empty() {
33150 return parts;
33151 }
33152 let mut current = String::new();
33153 let chars: Vec<char> = path.chars().collect();
33154 let mut i = 0;
33155 while i < chars.len() {
33156 match chars[i] {
33157 '.' => {
33158 if !current.is_empty() {
33159 parts.push(current.clone());
33160 current.clear();
33161 }
33162 i += 1;
33163 }
33164 '[' => {
33165 if !current.is_empty() {
33166 parts.push(current.clone());
33167 current.clear();
33168 }
33169 i += 1;
33170 let mut bracket_content = String::new();
33172 while i < chars.len() && chars[i] != ']' {
33173 if chars[i] == '"' || chars[i] == '\'' {
33175 let quote = chars[i];
33176 i += 1;
33177 while i < chars.len() && chars[i] != quote {
33178 bracket_content.push(chars[i]);
33179 i += 1;
33180 }
33181 if i < chars.len() {
33182 i += 1;
33183 } } else {
33185 bracket_content.push(chars[i]);
33186 i += 1;
33187 }
33188 }
33189 if i < chars.len() {
33190 i += 1;
33191 } if bracket_content != "*" {
33194 parts.push(bracket_content);
33195 }
33196 }
33197 _ => {
33198 current.push(chars[i]);
33199 i += 1;
33200 }
33201 }
33202 }
33203 if !current.is_empty() {
33204 parts.push(current);
33205 }
33206 parts
33207 }
33208
33209 fn strftime_to_postgres_format(fmt: &str) -> String {
33211 let mut result = fmt.to_string();
33212 result = result.replace("%-d", "FMDD");
33214 result = result.replace("%-m", "FMMM");
33215 result = result.replace("%-H", "FMHH24");
33216 result = result.replace("%-M", "FMMI");
33217 result = result.replace("%-S", "FMSS");
33218 result = result.replace("%Y", "YYYY");
33219 result = result.replace("%y", "YY");
33220 result = result.replace("%m", "MM");
33221 result = result.replace("%B", "Month");
33222 result = result.replace("%b", "Mon");
33223 result = result.replace("%d", "DD");
33224 result = result.replace("%j", "DDD");
33225 result = result.replace("%H", "HH24");
33226 result = result.replace("%M", "MI");
33227 result = result.replace("%S", "SS");
33228 result = result.replace("%f", "US");
33229 result = result.replace("%A", "Day");
33230 result = result.replace("%a", "Dy");
33231 result
33232 }
33233
33234 fn strftime_to_snowflake_format(fmt: &str) -> String {
33236 let mut result = fmt.to_string();
33237 result = result.replace("%-d", "dd");
33239 result = result.replace("%-m", "mm"); result = result.replace("%Y", "yyyy");
33241 result = result.replace("%y", "yy");
33242 result = result.replace("%m", "mm");
33243 result = result.replace("%d", "DD");
33244 result = result.replace("%H", "hh24");
33245 result = result.replace("%M", "mi");
33246 result = result.replace("%S", "ss");
33247 result = result.replace("%f", "ff");
33248 result
33249 }
33250
33251 fn generate_str_to_map(&mut self, e: &StrToMap) -> Result<()> {
33252 self.write_keyword("STR_TO_MAP");
33254 self.write("(");
33255 self.generate_expression(&e.this)?;
33256 let needs_defaults = matches!(
33258 self.config.dialect,
33259 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
33260 );
33261 if let Some(pair_delim) = &e.pair_delim {
33262 self.write(", ");
33263 self.generate_expression(pair_delim)?;
33264 } else if needs_defaults {
33265 self.write(", ','");
33266 }
33267 if let Some(key_value_delim) = &e.key_value_delim {
33268 self.write(", ");
33269 self.generate_expression(key_value_delim)?;
33270 } else if needs_defaults {
33271 self.write(", ':'");
33272 }
33273 self.write(")");
33274 Ok(())
33275 }
33276
33277 fn generate_str_to_time(&mut self, e: &StrToTime) -> Result<()> {
33278 let is_strftime = e.format.contains('%');
33280 let to_strftime = |f: &str| -> String {
33282 if is_strftime {
33283 f.to_string()
33284 } else {
33285 Self::snowflake_format_to_strftime(f)
33286 }
33287 };
33288 let to_java = |f: &str| -> String {
33290 if is_strftime {
33291 Self::strftime_to_java_format(f)
33292 } else {
33293 Self::snowflake_format_to_spark(f)
33294 }
33295 };
33296 let to_pg = |f: &str| -> String {
33298 if is_strftime {
33299 Self::strftime_to_postgres_format(f)
33300 } else {
33301 Self::convert_strptime_to_postgres_format(f)
33302 }
33303 };
33304
33305 match self.config.dialect {
33306 Some(DialectType::Exasol) => {
33307 self.write_keyword("TO_DATE");
33308 self.write("(");
33309 self.generate_expression(&e.this)?;
33310 self.write(", '");
33311 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
33312 self.write("'");
33313 self.write(")");
33314 }
33315 Some(DialectType::BigQuery) => {
33316 let fmt = to_strftime(&e.format);
33318 let fmt = fmt.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
33320 self.write_keyword("PARSE_TIMESTAMP");
33321 self.write("('");
33322 self.write(&fmt);
33323 self.write("', ");
33324 self.generate_expression(&e.this)?;
33325 self.write(")");
33326 }
33327 Some(DialectType::Hive) => {
33328 let java_fmt = to_java(&e.format);
33331 if java_fmt == "yyyy-MM-dd HH:mm:ss"
33332 || java_fmt == "yyyy-MM-dd"
33333 || e.format == "yyyy-MM-dd HH:mm:ss"
33334 || e.format == "yyyy-MM-dd"
33335 {
33336 self.write_keyword("CAST");
33337 self.write("(");
33338 self.generate_expression(&e.this)?;
33339 self.write(" ");
33340 self.write_keyword("AS TIMESTAMP");
33341 self.write(")");
33342 } else {
33343 self.write_keyword("CAST");
33345 self.write("(");
33346 self.write_keyword("FROM_UNIXTIME");
33347 self.write("(");
33348 self.write_keyword("UNIX_TIMESTAMP");
33349 self.write("(");
33350 self.generate_expression(&e.this)?;
33351 self.write(", '");
33352 self.write(&java_fmt);
33353 self.write("')");
33354 self.write(") ");
33355 self.write_keyword("AS TIMESTAMP");
33356 self.write(")");
33357 }
33358 }
33359 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
33360 let java_fmt = to_java(&e.format);
33362 self.write_keyword("TO_TIMESTAMP");
33363 self.write("(");
33364 self.generate_expression(&e.this)?;
33365 self.write(", '");
33366 self.write(&java_fmt);
33367 self.write("')");
33368 }
33369 Some(DialectType::MySQL) => {
33370 let mut fmt = to_strftime(&e.format);
33372 fmt = fmt.replace("%-d", "%e");
33374 fmt = fmt.replace("%-m", "%c");
33375 fmt = fmt.replace("%H:%M:%S", "%T");
33376 self.write_keyword("STR_TO_DATE");
33377 self.write("(");
33378 self.generate_expression(&e.this)?;
33379 self.write(", '");
33380 self.write(&fmt);
33381 self.write("')");
33382 }
33383 Some(DialectType::Drill) => {
33384 let java_fmt = to_java(&e.format);
33386 let java_fmt = java_fmt.replace('T', "''T''");
33388 self.write_keyword("TO_TIMESTAMP");
33389 self.write("(");
33390 self.generate_expression(&e.this)?;
33391 self.write(", '");
33392 self.write(&java_fmt);
33393 self.write("')");
33394 }
33395 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
33396 let mut fmt = to_strftime(&e.format);
33398 fmt = fmt.replace("%-d", "%e");
33400 fmt = fmt.replace("%-m", "%c");
33401 fmt = fmt.replace("%H:%M:%S", "%T");
33402 self.write_keyword("DATE_PARSE");
33403 self.write("(");
33404 self.generate_expression(&e.this)?;
33405 self.write(", '");
33406 self.write(&fmt);
33407 self.write("')");
33408 }
33409 Some(DialectType::DuckDB) => {
33410 let fmt = to_strftime(&e.format);
33412 self.write_keyword("STRPTIME");
33413 self.write("(");
33414 self.generate_expression(&e.this)?;
33415 self.write(", '");
33416 self.write(&fmt);
33417 self.write("')");
33418 }
33419 Some(DialectType::PostgreSQL)
33420 | Some(DialectType::Redshift)
33421 | Some(DialectType::Materialize) => {
33422 let pg_fmt = to_pg(&e.format);
33424 self.write_keyword("TO_TIMESTAMP");
33425 self.write("(");
33426 self.generate_expression(&e.this)?;
33427 self.write(", '");
33428 self.write(&pg_fmt);
33429 self.write("')");
33430 }
33431 Some(DialectType::Oracle) => {
33432 let pg_fmt = to_pg(&e.format);
33434 self.write_keyword("TO_TIMESTAMP");
33435 self.write("(");
33436 self.generate_expression(&e.this)?;
33437 self.write(", '");
33438 self.write(&pg_fmt);
33439 self.write("')");
33440 }
33441 Some(DialectType::Snowflake) => {
33442 self.write_keyword("TO_TIMESTAMP");
33444 self.write("(");
33445 self.generate_expression(&e.this)?;
33446 self.write(", '");
33447 self.write(&e.format);
33448 self.write("')");
33449 }
33450 _ => {
33451 self.write_keyword("STR_TO_TIME");
33453 self.write("(");
33454 self.generate_expression(&e.this)?;
33455 self.write(", '");
33456 self.write(&e.format);
33457 self.write("'");
33458 self.write(")");
33459 }
33460 }
33461 Ok(())
33462 }
33463
33464 fn snowflake_format_to_strftime(format: &str) -> String {
33466 let mut result = String::new();
33467 let chars: Vec<char> = format.chars().collect();
33468 let mut i = 0;
33469 while i < chars.len() {
33470 let remaining = &format[i..];
33471 if remaining.starts_with("yyyy") {
33472 result.push_str("%Y");
33473 i += 4;
33474 } else if remaining.starts_with("yy") {
33475 result.push_str("%y");
33476 i += 2;
33477 } else if remaining.starts_with("mmmm") {
33478 result.push_str("%B"); i += 4;
33480 } else if remaining.starts_with("mon") {
33481 result.push_str("%b"); i += 3;
33483 } else if remaining.starts_with("mm") {
33484 result.push_str("%m");
33485 i += 2;
33486 } else if remaining.starts_with("DD") {
33487 result.push_str("%d");
33488 i += 2;
33489 } else if remaining.starts_with("dy") {
33490 result.push_str("%a"); i += 2;
33492 } else if remaining.starts_with("hh24") {
33493 result.push_str("%H");
33494 i += 4;
33495 } else if remaining.starts_with("hh12") {
33496 result.push_str("%I");
33497 i += 4;
33498 } else if remaining.starts_with("hh") {
33499 result.push_str("%H");
33500 i += 2;
33501 } else if remaining.starts_with("mi") {
33502 result.push_str("%M");
33503 i += 2;
33504 } else if remaining.starts_with("ss") {
33505 result.push_str("%S");
33506 i += 2;
33507 } else if remaining.starts_with("ff") {
33508 result.push_str("%f");
33510 i += 2;
33511 while i < chars.len() && chars[i].is_ascii_digit() {
33513 i += 1;
33514 }
33515 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
33516 result.push_str("%p");
33517 i += 2;
33518 } else if remaining.starts_with("tz") {
33519 result.push_str("%Z");
33520 i += 2;
33521 } else {
33522 result.push(chars[i]);
33523 i += 1;
33524 }
33525 }
33526 result
33527 }
33528
33529 fn snowflake_format_to_spark(format: &str) -> String {
33531 let mut result = String::new();
33532 let chars: Vec<char> = format.chars().collect();
33533 let mut i = 0;
33534 while i < chars.len() {
33535 let remaining = &format[i..];
33536 if remaining.starts_with("yyyy") {
33537 result.push_str("yyyy");
33538 i += 4;
33539 } else if remaining.starts_with("yy") {
33540 result.push_str("yy");
33541 i += 2;
33542 } else if remaining.starts_with("mmmm") {
33543 result.push_str("MMMM"); i += 4;
33545 } else if remaining.starts_with("mon") {
33546 result.push_str("MMM"); i += 3;
33548 } else if remaining.starts_with("mm") {
33549 result.push_str("MM");
33550 i += 2;
33551 } else if remaining.starts_with("DD") {
33552 result.push_str("dd");
33553 i += 2;
33554 } else if remaining.starts_with("dy") {
33555 result.push_str("EEE"); i += 2;
33557 } else if remaining.starts_with("hh24") {
33558 result.push_str("HH");
33559 i += 4;
33560 } else if remaining.starts_with("hh12") {
33561 result.push_str("hh");
33562 i += 4;
33563 } else if remaining.starts_with("hh") {
33564 result.push_str("HH");
33565 i += 2;
33566 } else if remaining.starts_with("mi") {
33567 result.push_str("mm");
33568 i += 2;
33569 } else if remaining.starts_with("ss") {
33570 result.push_str("ss");
33571 i += 2;
33572 } else if remaining.starts_with("ff") {
33573 result.push_str("SSS"); i += 2;
33575 while i < chars.len() && chars[i].is_ascii_digit() {
33577 i += 1;
33578 }
33579 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
33580 result.push_str("a");
33581 i += 2;
33582 } else if remaining.starts_with("tz") {
33583 result.push_str("z");
33584 i += 2;
33585 } else {
33586 result.push(chars[i]);
33587 i += 1;
33588 }
33589 }
33590 result
33591 }
33592
33593 fn generate_str_to_unix(&mut self, e: &StrToUnix) -> Result<()> {
33594 match self.config.dialect {
33595 Some(DialectType::DuckDB) => {
33596 self.write_keyword("EPOCH");
33598 self.write("(");
33599 self.write_keyword("STRPTIME");
33600 self.write("(");
33601 if let Some(this) = &e.this {
33602 self.generate_expression(this)?;
33603 }
33604 if let Some(format) = &e.format {
33605 self.write(", '");
33606 self.write(format);
33607 self.write("'");
33608 }
33609 self.write("))");
33610 }
33611 Some(DialectType::Hive) => {
33612 self.write_keyword("UNIX_TIMESTAMP");
33614 self.write("(");
33615 if let Some(this) = &e.this {
33616 self.generate_expression(this)?;
33617 }
33618 if let Some(format) = &e.format {
33619 let java_fmt = Self::strftime_to_java_format(format);
33620 if java_fmt != "yyyy-MM-dd HH:mm:ss" {
33621 self.write(", '");
33622 self.write(&java_fmt);
33623 self.write("'");
33624 }
33625 }
33626 self.write(")");
33627 }
33628 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
33629 self.write_keyword("UNIX_TIMESTAMP");
33631 self.write("(");
33632 if let Some(this) = &e.this {
33633 self.generate_expression(this)?;
33634 }
33635 if let Some(format) = &e.format {
33636 self.write(", '");
33637 self.write(format);
33638 self.write("'");
33639 }
33640 self.write(")");
33641 }
33642 Some(DialectType::Presto) | Some(DialectType::Trino) => {
33643 let c_fmt = e.format.as_deref().unwrap_or("%Y-%m-%d %T");
33646 let java_fmt = Self::strftime_to_java_format(c_fmt);
33647 self.write_keyword("TO_UNIXTIME");
33648 self.write("(");
33649 self.write_keyword("COALESCE");
33650 self.write("(");
33651 self.write_keyword("TRY");
33652 self.write("(");
33653 self.write_keyword("DATE_PARSE");
33654 self.write("(");
33655 self.write_keyword("CAST");
33656 self.write("(");
33657 if let Some(this) = &e.this {
33658 self.generate_expression(this)?;
33659 }
33660 self.write(" ");
33661 self.write_keyword("AS VARCHAR");
33662 self.write("), '");
33663 self.write(c_fmt);
33664 self.write("')), ");
33665 self.write_keyword("PARSE_DATETIME");
33666 self.write("(");
33667 self.write_keyword("DATE_FORMAT");
33668 self.write("(");
33669 self.write_keyword("CAST");
33670 self.write("(");
33671 if let Some(this) = &e.this {
33672 self.generate_expression(this)?;
33673 }
33674 self.write(" ");
33675 self.write_keyword("AS TIMESTAMP");
33676 self.write("), '");
33677 self.write(c_fmt);
33678 self.write("'), '");
33679 self.write(&java_fmt);
33680 self.write("')))");
33681 }
33682 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
33683 self.write_keyword("UNIX_TIMESTAMP");
33685 self.write("(");
33686 if let Some(this) = &e.this {
33687 self.generate_expression(this)?;
33688 }
33689 if let Some(format) = &e.format {
33690 let java_fmt = Self::strftime_to_java_format(format);
33691 self.write(", '");
33692 self.write(&java_fmt);
33693 self.write("'");
33694 }
33695 self.write(")");
33696 }
33697 _ => {
33698 self.write_keyword("STR_TO_UNIX");
33700 self.write("(");
33701 if let Some(this) = &e.this {
33702 self.generate_expression(this)?;
33703 }
33704 if let Some(format) = &e.format {
33705 self.write(", '");
33706 self.write(format);
33707 self.write("'");
33708 }
33709 self.write(")");
33710 }
33711 }
33712 Ok(())
33713 }
33714
33715 fn generate_string_to_array(&mut self, e: &StringToArray) -> Result<()> {
33716 self.write_keyword("STRING_TO_ARRAY");
33718 self.write("(");
33719 self.generate_expression(&e.this)?;
33720 if let Some(expression) = &e.expression {
33721 self.write(", ");
33722 self.generate_expression(expression)?;
33723 }
33724 if let Some(null_val) = &e.null {
33725 self.write(", ");
33726 self.generate_expression(null_val)?;
33727 }
33728 self.write(")");
33729 Ok(())
33730 }
33731
33732 fn generate_struct(&mut self, e: &Struct) -> Result<()> {
33733 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
33734 self.write_keyword("OBJECT_CONSTRUCT");
33736 self.write("(");
33737 for (i, (name, expr)) in e.fields.iter().enumerate() {
33738 if i > 0 {
33739 self.write(", ");
33740 }
33741 if let Some(name) = name {
33742 self.write("'");
33743 self.write(name);
33744 self.write("'");
33745 self.write(", ");
33746 } else {
33747 self.write("'_");
33748 self.write(&i.to_string());
33749 self.write("'");
33750 self.write(", ");
33751 }
33752 self.generate_expression(expr)?;
33753 }
33754 self.write(")");
33755 } else if self.config.struct_curly_brace_notation {
33756 self.write("{");
33758 for (i, (name, expr)) in e.fields.iter().enumerate() {
33759 if i > 0 {
33760 self.write(", ");
33761 }
33762 if let Some(name) = name {
33763 self.write("'");
33765 self.write(name);
33766 self.write("'");
33767 self.write(": ");
33768 } else {
33769 self.write("'_");
33771 self.write(&i.to_string());
33772 self.write("'");
33773 self.write(": ");
33774 }
33775 self.generate_expression(expr)?;
33776 }
33777 self.write("}");
33778 } else {
33779 let value_as_name = matches!(
33783 self.config.dialect,
33784 Some(DialectType::BigQuery)
33785 | Some(DialectType::Spark)
33786 | Some(DialectType::Databricks)
33787 | Some(DialectType::Hive)
33788 );
33789 self.write_keyword("STRUCT");
33790 self.write("(");
33791 for (i, (name, expr)) in e.fields.iter().enumerate() {
33792 if i > 0 {
33793 self.write(", ");
33794 }
33795 if let Some(name) = name {
33796 if value_as_name {
33797 self.generate_expression(expr)?;
33799 self.write_space();
33800 self.write_keyword("AS");
33801 self.write_space();
33802 let needs_quoting = name.contains(' ') || name.contains('-');
33804 if needs_quoting {
33805 if matches!(
33806 self.config.dialect,
33807 Some(DialectType::Spark)
33808 | Some(DialectType::Databricks)
33809 | Some(DialectType::Hive)
33810 ) {
33811 self.write("`");
33812 self.write(name);
33813 self.write("`");
33814 } else {
33815 self.write(name);
33816 }
33817 } else {
33818 self.write(name);
33819 }
33820 } else {
33821 self.write(name);
33823 self.write_space();
33824 self.write_keyword("AS");
33825 self.write_space();
33826 self.generate_expression(expr)?;
33827 }
33828 } else {
33829 self.generate_expression(expr)?;
33830 }
33831 }
33832 self.write(")");
33833 }
33834 Ok(())
33835 }
33836
33837 fn generate_stuff(&mut self, e: &Stuff) -> Result<()> {
33838 self.write_keyword("STUFF");
33840 self.write("(");
33841 self.generate_expression(&e.this)?;
33842 if let Some(start) = &e.start {
33843 self.write(", ");
33844 self.generate_expression(start)?;
33845 }
33846 if let Some(length) = e.length {
33847 self.write(", ");
33848 self.write(&length.to_string());
33849 }
33850 self.write(", ");
33851 self.generate_expression(&e.expression)?;
33852 self.write(")");
33853 Ok(())
33854 }
33855
33856 fn generate_substring_index(&mut self, e: &SubstringIndex) -> Result<()> {
33857 self.write_keyword("SUBSTRING_INDEX");
33859 self.write("(");
33860 self.generate_expression(&e.this)?;
33861 if let Some(delimiter) = &e.delimiter {
33862 self.write(", ");
33863 self.generate_expression(delimiter)?;
33864 }
33865 if let Some(count) = &e.count {
33866 self.write(", ");
33867 self.generate_expression(count)?;
33868 }
33869 self.write(")");
33870 Ok(())
33871 }
33872
33873 fn generate_summarize(&mut self, e: &Summarize) -> Result<()> {
33874 self.write_keyword("SUMMARIZE");
33876 if e.table.is_some() {
33877 self.write_space();
33878 self.write_keyword("TABLE");
33879 }
33880 self.write_space();
33881 self.generate_expression(&e.this)?;
33882 Ok(())
33883 }
33884
33885 fn generate_systimestamp(&mut self, _e: &Systimestamp) -> Result<()> {
33886 self.write_keyword("SYSTIMESTAMP");
33888 Ok(())
33889 }
33890
33891 fn generate_table_alias(&mut self, e: &TableAlias) -> Result<()> {
33892 if let Some(this) = &e.this {
33894 self.generate_expression(this)?;
33895 }
33896 if !e.columns.is_empty() {
33897 self.write("(");
33898 for (i, col) in e.columns.iter().enumerate() {
33899 if i > 0 {
33900 self.write(", ");
33901 }
33902 self.generate_expression(col)?;
33903 }
33904 self.write(")");
33905 }
33906 Ok(())
33907 }
33908
33909 fn generate_table_from_rows(&mut self, e: &TableFromRows) -> Result<()> {
33910 self.write_keyword("TABLE");
33912 self.write("(");
33913 self.generate_expression(&e.this)?;
33914 self.write(")");
33915 if let Some(alias) = &e.alias {
33916 self.write_space();
33917 self.write_keyword("AS");
33918 self.write_space();
33919 self.write(alias);
33920 }
33921 Ok(())
33922 }
33923
33924 fn generate_rows_from(&mut self, e: &RowsFrom) -> Result<()> {
33925 self.write_keyword("ROWS FROM");
33927 self.write(" (");
33928 for (i, expr) in e.expressions.iter().enumerate() {
33929 if i > 0 {
33930 self.write(", ");
33931 }
33932 match expr {
33936 Expression::Tuple(tuple) if tuple.expressions.len() == 2 => {
33937 self.generate_expression(&tuple.expressions[0])?;
33939 self.write_space();
33940 self.write_keyword("AS");
33941 self.write_space();
33942 self.generate_expression(&tuple.expressions[1])?;
33943 }
33944 _ => {
33945 self.generate_expression(expr)?;
33946 }
33947 }
33948 }
33949 self.write(")");
33950 if e.ordinality {
33951 self.write_space();
33952 self.write_keyword("WITH ORDINALITY");
33953 }
33954 if let Some(alias) = &e.alias {
33955 self.write_space();
33956 self.write_keyword("AS");
33957 self.write_space();
33958 self.generate_expression(alias)?;
33959 }
33960 Ok(())
33961 }
33962
33963 fn generate_table_sample(&mut self, e: &TableSample) -> Result<()> {
33964 use crate::dialects::DialectType;
33965
33966 if let (Some(this), Some(sample)) = (&e.this, &e.sample) {
33968 if self.config.alias_post_tablesample {
33970 if let Expression::Subquery(ref s) = **this {
33972 if let Some(ref alias) = s.alias {
33973 let mut subquery_no_alias = (**s).clone();
33975 subquery_no_alias.alias = None;
33976 subquery_no_alias.column_aliases = Vec::new();
33977 self.generate_expression(&Expression::Subquery(Box::new(
33978 subquery_no_alias,
33979 )))?;
33980 self.write_space();
33981 self.write_keyword("TABLESAMPLE");
33982 self.generate_sample_body(sample)?;
33983 if let Some(ref seed) = sample.seed {
33984 self.write_space();
33985 let use_seed = sample.use_seed_keyword
33986 && !matches!(
33987 self.config.dialect,
33988 Some(crate::dialects::DialectType::Databricks)
33989 | Some(crate::dialects::DialectType::Spark)
33990 );
33991 if use_seed {
33992 self.write_keyword("SEED");
33993 } else {
33994 self.write_keyword("REPEATABLE");
33995 }
33996 self.write(" (");
33997 self.generate_expression(seed)?;
33998 self.write(")");
33999 }
34000 self.write_space();
34001 self.write_keyword("AS");
34002 self.write_space();
34003 self.generate_identifier(alias)?;
34004 return Ok(());
34005 }
34006 } else if let Expression::Alias(ref a) = **this {
34007 self.generate_expression(&a.this)?;
34009 self.write_space();
34010 self.write_keyword("TABLESAMPLE");
34011 self.generate_sample_body(sample)?;
34012 if let Some(ref seed) = sample.seed {
34013 self.write_space();
34014 let use_seed = sample.use_seed_keyword
34015 && !matches!(
34016 self.config.dialect,
34017 Some(crate::dialects::DialectType::Databricks)
34018 | Some(crate::dialects::DialectType::Spark)
34019 );
34020 if use_seed {
34021 self.write_keyword("SEED");
34022 } else {
34023 self.write_keyword("REPEATABLE");
34024 }
34025 self.write(" (");
34026 self.generate_expression(seed)?;
34027 self.write(")");
34028 }
34029 self.write_space();
34031 self.write_keyword("AS");
34032 self.write_space();
34033 self.generate_identifier(&a.alias)?;
34034 return Ok(());
34035 }
34036 }
34037 self.generate_expression(this)?;
34039 self.write_space();
34040 self.write_keyword("TABLESAMPLE");
34041 self.generate_sample_body(sample)?;
34042 if let Some(ref seed) = sample.seed {
34044 self.write_space();
34045 let use_seed = sample.use_seed_keyword
34047 && !matches!(
34048 self.config.dialect,
34049 Some(crate::dialects::DialectType::Databricks)
34050 | Some(crate::dialects::DialectType::Spark)
34051 );
34052 if use_seed {
34053 self.write_keyword("SEED");
34054 } else {
34055 self.write_keyword("REPEATABLE");
34056 }
34057 self.write(" (");
34058 self.generate_expression(seed)?;
34059 self.write(")");
34060 }
34061 return Ok(());
34062 }
34063
34064 self.write_keyword("TABLESAMPLE");
34066 if let Some(method) = &e.method {
34067 self.write_space();
34068 self.write_keyword(method);
34069 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
34070 self.write_space();
34072 self.write_keyword("BERNOULLI");
34073 }
34074 if let (Some(numerator), Some(denominator)) = (&e.bucket_numerator, &e.bucket_denominator) {
34075 self.write_space();
34076 self.write_keyword("BUCKET");
34077 self.write_space();
34078 self.generate_expression(numerator)?;
34079 self.write_space();
34080 self.write_keyword("OUT OF");
34081 self.write_space();
34082 self.generate_expression(denominator)?;
34083 if let Some(field) = &e.bucket_field {
34084 self.write_space();
34085 self.write_keyword("ON");
34086 self.write_space();
34087 self.generate_expression(field)?;
34088 }
34089 } else if !e.expressions.is_empty() {
34090 self.write(" (");
34091 for (i, expr) in e.expressions.iter().enumerate() {
34092 if i > 0 {
34093 self.write(", ");
34094 }
34095 self.generate_expression(expr)?;
34096 }
34097 self.write(")");
34098 } else if let Some(percent) = &e.percent {
34099 self.write(" (");
34100 self.generate_expression(percent)?;
34101 self.write_space();
34102 self.write_keyword("PERCENT");
34103 self.write(")");
34104 }
34105 Ok(())
34106 }
34107
34108 fn generate_tag(&mut self, e: &Tag) -> Result<()> {
34109 if let Some(prefix) = &e.prefix {
34111 self.generate_expression(prefix)?;
34112 }
34113 if let Some(this) = &e.this {
34114 self.generate_expression(this)?;
34115 }
34116 if let Some(postfix) = &e.postfix {
34117 self.generate_expression(postfix)?;
34118 }
34119 Ok(())
34120 }
34121
34122 fn generate_tags(&mut self, e: &Tags) -> Result<()> {
34123 self.write_keyword("TAG");
34125 self.write(" (");
34126 for (i, expr) in e.expressions.iter().enumerate() {
34127 if i > 0 {
34128 self.write(", ");
34129 }
34130 self.generate_expression(expr)?;
34131 }
34132 self.write(")");
34133 Ok(())
34134 }
34135
34136 fn generate_temporary_property(&mut self, e: &TemporaryProperty) -> Result<()> {
34137 if let Some(this) = &e.this {
34139 self.generate_expression(this)?;
34140 self.write_space();
34141 }
34142 self.write_keyword("TEMPORARY");
34143 Ok(())
34144 }
34145
34146 fn generate_time_func(&mut self, e: &UnaryFunc) -> Result<()> {
34149 self.write_keyword("TIME");
34151 self.write("(");
34152 self.generate_expression(&e.this)?;
34153 self.write(")");
34154 Ok(())
34155 }
34156
34157 fn generate_time_add(&mut self, e: &TimeAdd) -> Result<()> {
34158 self.write_keyword("TIME_ADD");
34160 self.write("(");
34161 self.generate_expression(&e.this)?;
34162 self.write(", ");
34163 self.generate_expression(&e.expression)?;
34164 if let Some(unit) = &e.unit {
34165 self.write(", ");
34166 self.write_keyword(unit);
34167 }
34168 self.write(")");
34169 Ok(())
34170 }
34171
34172 fn generate_time_diff(&mut self, e: &TimeDiff) -> Result<()> {
34173 self.write_keyword("TIME_DIFF");
34175 self.write("(");
34176 self.generate_expression(&e.this)?;
34177 self.write(", ");
34178 self.generate_expression(&e.expression)?;
34179 if let Some(unit) = &e.unit {
34180 self.write(", ");
34181 self.write_keyword(unit);
34182 }
34183 self.write(")");
34184 Ok(())
34185 }
34186
34187 fn generate_time_from_parts(&mut self, e: &TimeFromParts) -> Result<()> {
34188 self.write_keyword("TIME_FROM_PARTS");
34190 self.write("(");
34191 let mut first = true;
34192 if let Some(hour) = &e.hour {
34193 self.generate_expression(hour)?;
34194 first = false;
34195 }
34196 if let Some(minute) = &e.min {
34197 if !first {
34198 self.write(", ");
34199 }
34200 self.generate_expression(minute)?;
34201 first = false;
34202 }
34203 if let Some(second) = &e.sec {
34204 if !first {
34205 self.write(", ");
34206 }
34207 self.generate_expression(second)?;
34208 first = false;
34209 }
34210 if let Some(ns) = &e.nano {
34211 if !first {
34212 self.write(", ");
34213 }
34214 self.generate_expression(ns)?;
34215 }
34216 self.write(")");
34217 Ok(())
34218 }
34219
34220 fn generate_time_slice(&mut self, e: &TimeSlice) -> Result<()> {
34221 self.write_keyword("TIME_SLICE");
34223 self.write("(");
34224 self.generate_expression(&e.this)?;
34225 self.write(", ");
34226 self.generate_expression(&e.expression)?;
34227 self.write(", ");
34228 self.write_keyword(&e.unit);
34229 self.write(")");
34230 Ok(())
34231 }
34232
34233 fn generate_time_str_to_time(&mut self, e: &TimeStrToTime) -> Result<()> {
34234 self.write_keyword("TIME_STR_TO_TIME");
34236 self.write("(");
34237 self.generate_expression(&e.this)?;
34238 self.write(")");
34239 Ok(())
34240 }
34241
34242 fn generate_time_sub(&mut self, e: &TimeSub) -> Result<()> {
34243 self.write_keyword("TIME_SUB");
34245 self.write("(");
34246 self.generate_expression(&e.this)?;
34247 self.write(", ");
34248 self.generate_expression(&e.expression)?;
34249 if let Some(unit) = &e.unit {
34250 self.write(", ");
34251 self.write_keyword(unit);
34252 }
34253 self.write(")");
34254 Ok(())
34255 }
34256
34257 fn generate_time_to_str(&mut self, e: &TimeToStr) -> Result<()> {
34258 match self.config.dialect {
34259 Some(DialectType::Exasol) => {
34260 self.write_keyword("TO_CHAR");
34262 self.write("(");
34263 self.generate_expression(&e.this)?;
34264 self.write(", '");
34265 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
34266 self.write("'");
34267 self.write(")");
34268 }
34269 Some(DialectType::PostgreSQL)
34270 | Some(DialectType::Redshift)
34271 | Some(DialectType::Materialize) => {
34272 self.write_keyword("TO_CHAR");
34274 self.write("(");
34275 self.generate_expression(&e.this)?;
34276 self.write(", '");
34277 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
34278 self.write("'");
34279 self.write(")");
34280 }
34281 Some(DialectType::Oracle) => {
34282 self.write_keyword("TO_CHAR");
34284 self.write("(");
34285 self.generate_expression(&e.this)?;
34286 self.write(", '");
34287 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
34288 self.write("'");
34289 self.write(")");
34290 }
34291 Some(DialectType::Drill) => {
34292 self.write_keyword("TO_CHAR");
34294 self.write("(");
34295 self.generate_expression(&e.this)?;
34296 self.write(", '");
34297 self.write(&Self::strftime_to_java_format(&e.format));
34298 self.write("'");
34299 self.write(")");
34300 }
34301 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
34302 self.write_keyword("FORMAT");
34304 self.write("(");
34305 self.generate_expression(&e.this)?;
34306 self.write(", '");
34307 self.write(&Self::strftime_to_tsql_format(&e.format));
34308 self.write("'");
34309 self.write(")");
34310 }
34311 Some(DialectType::DuckDB) => {
34312 self.write_keyword("STRFTIME");
34314 self.write("(");
34315 self.generate_expression(&e.this)?;
34316 self.write(", '");
34317 self.write(&e.format);
34318 self.write("'");
34319 self.write(")");
34320 }
34321 Some(DialectType::BigQuery) => {
34322 let fmt = e.format.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
34325 self.write_keyword("FORMAT_DATE");
34326 self.write("('");
34327 self.write(&fmt);
34328 self.write("', ");
34329 self.generate_expression(&e.this)?;
34330 self.write(")");
34331 }
34332 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
34333 self.write_keyword("DATE_FORMAT");
34335 self.write("(");
34336 self.generate_expression(&e.this)?;
34337 self.write(", '");
34338 self.write(&Self::strftime_to_java_format(&e.format));
34339 self.write("'");
34340 self.write(")");
34341 }
34342 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
34343 self.write_keyword("DATE_FORMAT");
34345 self.write("(");
34346 self.generate_expression(&e.this)?;
34347 self.write(", '");
34348 self.write(&e.format);
34349 self.write("'");
34350 self.write(")");
34351 }
34352 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
34353 self.write_keyword("DATE_FORMAT");
34355 self.write("(");
34356 self.generate_expression(&e.this)?;
34357 self.write(", '");
34358 self.write(&e.format);
34359 self.write("'");
34360 self.write(")");
34361 }
34362 _ => {
34363 self.write_keyword("TIME_TO_STR");
34365 self.write("(");
34366 self.generate_expression(&e.this)?;
34367 self.write(", '");
34368 self.write(&e.format);
34369 self.write("'");
34370 self.write(")");
34371 }
34372 }
34373 Ok(())
34374 }
34375
34376 fn generate_time_to_unix(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
34377 match self.config.dialect {
34378 Some(DialectType::DuckDB) => {
34379 self.write_keyword("EPOCH");
34381 self.write("(");
34382 self.generate_expression(&e.this)?;
34383 self.write(")");
34384 }
34385 Some(DialectType::Hive)
34386 | Some(DialectType::Spark)
34387 | Some(DialectType::Databricks)
34388 | Some(DialectType::Doris)
34389 | Some(DialectType::StarRocks)
34390 | Some(DialectType::Drill) => {
34391 self.write_keyword("UNIX_TIMESTAMP");
34393 self.write("(");
34394 self.generate_expression(&e.this)?;
34395 self.write(")");
34396 }
34397 Some(DialectType::Presto) | Some(DialectType::Trino) => {
34398 self.write_keyword("TO_UNIXTIME");
34400 self.write("(");
34401 self.generate_expression(&e.this)?;
34402 self.write(")");
34403 }
34404 _ => {
34405 self.write_keyword("TIME_TO_UNIX");
34407 self.write("(");
34408 self.generate_expression(&e.this)?;
34409 self.write(")");
34410 }
34411 }
34412 Ok(())
34413 }
34414
34415 fn generate_time_str_to_date(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
34416 match self.config.dialect {
34417 Some(DialectType::Hive) => {
34418 self.write_keyword("TO_DATE");
34420 self.write("(");
34421 self.generate_expression(&e.this)?;
34422 self.write(")");
34423 }
34424 _ => {
34425 self.write_keyword("TIME_STR_TO_DATE");
34427 self.write("(");
34428 self.generate_expression(&e.this)?;
34429 self.write(")");
34430 }
34431 }
34432 Ok(())
34433 }
34434
34435 fn generate_time_trunc(&mut self, e: &TimeTrunc) -> Result<()> {
34436 self.write_keyword("TIME_TRUNC");
34438 self.write("(");
34439 self.generate_expression(&e.this)?;
34440 self.write(", ");
34441 self.write_keyword(&e.unit);
34442 self.write(")");
34443 Ok(())
34444 }
34445
34446 fn generate_time_unit(&mut self, e: &TimeUnit) -> Result<()> {
34447 if let Some(unit) = &e.unit {
34449 self.write_keyword(unit);
34450 }
34451 Ok(())
34452 }
34453
34454 fn generate_timestamp_func(&mut self, e: &TimestampFunc) -> Result<()> {
34458 use crate::dialects::DialectType;
34459 use crate::expressions::Literal;
34460
34461 match self.config.dialect {
34462 Some(DialectType::Exasol) => {
34464 self.write_keyword("TO_TIMESTAMP");
34465 self.write("(");
34466 if let Some(this) = &e.this {
34468 match this.as_ref() {
34469 Expression::Literal(Literal::String(s)) => {
34470 self.write("'");
34471 self.write(s);
34472 self.write("'");
34473 }
34474 _ => {
34475 self.generate_expression(this)?;
34476 }
34477 }
34478 }
34479 self.write(")");
34480 }
34481 _ => {
34483 self.write_keyword("TIMESTAMP");
34484 self.write("(");
34485 if let Some(this) = &e.this {
34486 self.generate_expression(this)?;
34487 }
34488 if let Some(zone) = &e.zone {
34489 self.write(", ");
34490 self.generate_expression(zone)?;
34491 }
34492 self.write(")");
34493 }
34494 }
34495 Ok(())
34496 }
34497
34498 fn generate_timestamp_add(&mut self, e: &TimestampAdd) -> Result<()> {
34499 self.write_keyword("TIMESTAMP_ADD");
34501 self.write("(");
34502 self.generate_expression(&e.this)?;
34503 self.write(", ");
34504 self.generate_expression(&e.expression)?;
34505 if let Some(unit) = &e.unit {
34506 self.write(", ");
34507 self.write_keyword(unit);
34508 }
34509 self.write(")");
34510 Ok(())
34511 }
34512
34513 fn generate_timestamp_diff(&mut self, e: &TimestampDiff) -> Result<()> {
34514 self.write_keyword("TIMESTAMP_DIFF");
34516 self.write("(");
34517 self.generate_expression(&e.this)?;
34518 self.write(", ");
34519 self.generate_expression(&e.expression)?;
34520 if let Some(unit) = &e.unit {
34521 self.write(", ");
34522 self.write_keyword(unit);
34523 }
34524 self.write(")");
34525 Ok(())
34526 }
34527
34528 fn generate_timestamp_from_parts(&mut self, e: &TimestampFromParts) -> Result<()> {
34529 self.write_keyword("TIMESTAMP_FROM_PARTS");
34531 self.write("(");
34532 if let Some(this) = &e.this {
34533 self.generate_expression(this)?;
34534 }
34535 if let Some(expression) = &e.expression {
34536 self.write(", ");
34537 self.generate_expression(expression)?;
34538 }
34539 if let Some(zone) = &e.zone {
34540 self.write(", ");
34541 self.generate_expression(zone)?;
34542 }
34543 if let Some(milli) = &e.milli {
34544 self.write(", ");
34545 self.generate_expression(milli)?;
34546 }
34547 self.write(")");
34548 Ok(())
34549 }
34550
34551 fn generate_timestamp_sub(&mut self, e: &TimestampSub) -> Result<()> {
34552 self.write_keyword("TIMESTAMP_SUB");
34554 self.write("(");
34555 self.generate_expression(&e.this)?;
34556 self.write(", ");
34557 self.write_keyword("INTERVAL");
34558 self.write_space();
34559 self.generate_expression(&e.expression)?;
34560 if let Some(unit) = &e.unit {
34561 self.write_space();
34562 self.write_keyword(unit);
34563 }
34564 self.write(")");
34565 Ok(())
34566 }
34567
34568 fn generate_timestamp_tz_from_parts(&mut self, e: &TimestampTzFromParts) -> Result<()> {
34569 self.write_keyword("TIMESTAMP_TZ_FROM_PARTS");
34571 self.write("(");
34572 if let Some(zone) = &e.zone {
34573 self.generate_expression(zone)?;
34574 }
34575 self.write(")");
34576 Ok(())
34577 }
34578
34579 fn generate_to_binary(&mut self, e: &ToBinary) -> Result<()> {
34580 self.write_keyword("TO_BINARY");
34582 self.write("(");
34583 self.generate_expression(&e.this)?;
34584 if let Some(format) = &e.format {
34585 self.write(", '");
34586 self.write(format);
34587 self.write("'");
34588 }
34589 self.write(")");
34590 Ok(())
34591 }
34592
34593 fn generate_to_boolean(&mut self, e: &ToBoolean) -> Result<()> {
34594 self.write_keyword("TO_BOOLEAN");
34596 self.write("(");
34597 self.generate_expression(&e.this)?;
34598 self.write(")");
34599 Ok(())
34600 }
34601
34602 fn generate_to_char(&mut self, e: &ToChar) -> Result<()> {
34603 self.write_keyword("TO_CHAR");
34605 self.write("(");
34606 self.generate_expression(&e.this)?;
34607 if let Some(format) = &e.format {
34608 self.write(", '");
34609 self.write(format);
34610 self.write("'");
34611 }
34612 if let Some(nlsparam) = &e.nlsparam {
34613 self.write(", ");
34614 self.generate_expression(nlsparam)?;
34615 }
34616 self.write(")");
34617 Ok(())
34618 }
34619
34620 fn generate_to_decfloat(&mut self, e: &ToDecfloat) -> Result<()> {
34621 self.write_keyword("TO_DECFLOAT");
34623 self.write("(");
34624 self.generate_expression(&e.this)?;
34625 if let Some(format) = &e.format {
34626 self.write(", '");
34627 self.write(format);
34628 self.write("'");
34629 }
34630 self.write(")");
34631 Ok(())
34632 }
34633
34634 fn generate_to_double(&mut self, e: &ToDouble) -> Result<()> {
34635 self.write_keyword("TO_DOUBLE");
34637 self.write("(");
34638 self.generate_expression(&e.this)?;
34639 if let Some(format) = &e.format {
34640 self.write(", '");
34641 self.write(format);
34642 self.write("'");
34643 }
34644 self.write(")");
34645 Ok(())
34646 }
34647
34648 fn generate_to_file(&mut self, e: &ToFile) -> Result<()> {
34649 self.write_keyword("TO_FILE");
34651 self.write("(");
34652 self.generate_expression(&e.this)?;
34653 if let Some(path) = &e.path {
34654 self.write(", ");
34655 self.generate_expression(path)?;
34656 }
34657 self.write(")");
34658 Ok(())
34659 }
34660
34661 fn generate_to_number(&mut self, e: &ToNumber) -> Result<()> {
34662 let is_safe = e.safe.is_some();
34665 if is_safe {
34666 self.write_keyword("TRY_TO_NUMBER");
34667 } else {
34668 self.write_keyword("TO_NUMBER");
34669 }
34670 self.write("(");
34671 self.generate_expression(&e.this)?;
34672 if let Some(format) = &e.format {
34673 self.write(", ");
34674 self.generate_expression(format)?;
34675 }
34676 if let Some(nlsparam) = &e.nlsparam {
34677 self.write(", ");
34678 self.generate_expression(nlsparam)?;
34679 }
34680 if let Some(precision) = &e.precision {
34681 self.write(", ");
34682 self.generate_expression(precision)?;
34683 }
34684 if let Some(scale) = &e.scale {
34685 self.write(", ");
34686 self.generate_expression(scale)?;
34687 }
34688 self.write(")");
34689 Ok(())
34690 }
34691
34692 fn generate_to_table_property(&mut self, e: &ToTableProperty) -> Result<()> {
34693 self.write_keyword("TO_TABLE");
34695 self.write_space();
34696 self.generate_expression(&e.this)?;
34697 Ok(())
34698 }
34699
34700 fn generate_transaction(&mut self, e: &Transaction) -> Result<()> {
34701 let mark_text = e.mark.as_ref().map(|m| match m.as_ref() {
34703 Expression::Identifier(id) => id.name.clone(),
34704 Expression::Literal(Literal::String(s)) => s.clone(),
34705 _ => String::new(),
34706 });
34707
34708 let is_start = mark_text.as_ref().map_or(false, |s| s == "START");
34709 let has_transaction_keyword = mark_text.as_ref().map_or(false, |s| s == "TRANSACTION");
34710 let has_with_mark = e.mark.as_ref().map_or(false, |m| {
34711 matches!(m.as_ref(), Expression::Literal(Literal::String(_)))
34712 });
34713
34714 let use_start_transaction = matches!(
34716 self.config.dialect,
34717 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
34718 );
34719 let strip_transaction = matches!(
34721 self.config.dialect,
34722 Some(DialectType::Snowflake)
34723 | Some(DialectType::PostgreSQL)
34724 | Some(DialectType::Redshift)
34725 | Some(DialectType::MySQL)
34726 | Some(DialectType::Hive)
34727 | Some(DialectType::Spark)
34728 | Some(DialectType::Databricks)
34729 | Some(DialectType::DuckDB)
34730 | Some(DialectType::Oracle)
34731 | Some(DialectType::Doris)
34732 | Some(DialectType::StarRocks)
34733 | Some(DialectType::Materialize)
34734 | Some(DialectType::ClickHouse)
34735 );
34736
34737 if is_start || use_start_transaction {
34738 self.write_keyword("START TRANSACTION");
34740 if let Some(modes) = &e.modes {
34741 self.write_space();
34742 self.generate_expression(modes)?;
34743 }
34744 } else {
34745 self.write_keyword("BEGIN");
34747
34748 let is_kind = e.this.as_ref().map_or(false, |t| {
34750 if let Expression::Identifier(id) = t.as_ref() {
34751 matches!(
34752 id.name.to_uppercase().as_str(),
34753 "DEFERRED" | "IMMEDIATE" | "EXCLUSIVE"
34754 )
34755 } else {
34756 false
34757 }
34758 });
34759
34760 if is_kind {
34762 if let Some(this) = &e.this {
34763 self.write_space();
34764 if let Expression::Identifier(id) = this.as_ref() {
34765 self.write_keyword(&id.name);
34766 }
34767 }
34768 }
34769
34770 if (has_transaction_keyword || has_with_mark) && !strip_transaction {
34772 self.write_space();
34773 self.write_keyword("TRANSACTION");
34774 }
34775
34776 if !is_kind {
34778 if let Some(this) = &e.this {
34779 self.write_space();
34780 self.generate_expression(this)?;
34781 }
34782 }
34783
34784 if has_with_mark {
34786 self.write_space();
34787 self.write_keyword("WITH MARK");
34788 if let Some(Expression::Literal(Literal::String(desc))) = e.mark.as_deref() {
34789 if !desc.is_empty() {
34790 self.write_space();
34791 self.write(&format!("'{}'", desc));
34792 }
34793 }
34794 }
34795
34796 if let Some(modes) = &e.modes {
34798 self.write_space();
34799 self.generate_expression(modes)?;
34800 }
34801 }
34802 Ok(())
34803 }
34804
34805 fn generate_transform(&mut self, e: &Transform) -> Result<()> {
34806 self.write_keyword("TRANSFORM");
34808 self.write("(");
34809 self.generate_expression(&e.this)?;
34810 self.write(", ");
34811 self.generate_expression(&e.expression)?;
34812 self.write(")");
34813 Ok(())
34814 }
34815
34816 fn generate_transform_model_property(&mut self, e: &TransformModelProperty) -> Result<()> {
34817 self.write_keyword("TRANSFORM");
34819 self.write("(");
34820 if self.config.pretty && !e.expressions.is_empty() {
34821 self.indent_level += 1;
34822 for (i, expr) in e.expressions.iter().enumerate() {
34823 if i > 0 {
34824 self.write(",");
34825 }
34826 self.write_newline();
34827 self.write_indent();
34828 self.generate_expression(expr)?;
34829 }
34830 self.indent_level -= 1;
34831 self.write_newline();
34832 self.write(")");
34833 } else {
34834 for (i, expr) in e.expressions.iter().enumerate() {
34835 if i > 0 {
34836 self.write(", ");
34837 }
34838 self.generate_expression(expr)?;
34839 }
34840 self.write(")");
34841 }
34842 Ok(())
34843 }
34844
34845 fn generate_transient_property(&mut self, e: &TransientProperty) -> Result<()> {
34846 use crate::dialects::DialectType;
34847 if let Some(this) = &e.this {
34849 self.generate_expression(this)?;
34850 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
34851 self.write_space();
34852 }
34853 }
34854 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
34855 self.write_keyword("TRANSIENT");
34856 }
34857 Ok(())
34858 }
34859
34860 fn generate_translate(&mut self, e: &Translate) -> Result<()> {
34861 self.write_keyword("TRANSLATE");
34863 self.write("(");
34864 self.generate_expression(&e.this)?;
34865 if let Some(from) = &e.from_ {
34866 self.write(", ");
34867 self.generate_expression(from)?;
34868 }
34869 if let Some(to) = &e.to {
34870 self.write(", ");
34871 self.generate_expression(to)?;
34872 }
34873 self.write(")");
34874 Ok(())
34875 }
34876
34877 fn generate_translate_characters(&mut self, e: &TranslateCharacters) -> Result<()> {
34878 self.write_keyword("TRANSLATE");
34880 self.write("(");
34881 self.generate_expression(&e.this)?;
34882 self.write_space();
34883 self.write_keyword("USING");
34884 self.write_space();
34885 self.generate_expression(&e.expression)?;
34886 if e.with_error.is_some() {
34887 self.write_space();
34888 self.write_keyword("WITH ERROR");
34889 }
34890 self.write(")");
34891 Ok(())
34892 }
34893
34894 fn generate_truncate_table(&mut self, e: &TruncateTable) -> Result<()> {
34895 self.write_keyword("TRUNCATE TABLE");
34897 self.write_space();
34898 for (i, expr) in e.expressions.iter().enumerate() {
34899 if i > 0 {
34900 self.write(", ");
34901 }
34902 self.generate_expression(expr)?;
34903 }
34904 Ok(())
34905 }
34906
34907 fn generate_try_base64_decode_binary(&mut self, e: &TryBase64DecodeBinary) -> Result<()> {
34908 self.write_keyword("TRY_BASE64_DECODE_BINARY");
34910 self.write("(");
34911 self.generate_expression(&e.this)?;
34912 if let Some(alphabet) = &e.alphabet {
34913 self.write(", ");
34914 self.generate_expression(alphabet)?;
34915 }
34916 self.write(")");
34917 Ok(())
34918 }
34919
34920 fn generate_try_base64_decode_string(&mut self, e: &TryBase64DecodeString) -> Result<()> {
34921 self.write_keyword("TRY_BASE64_DECODE_STRING");
34923 self.write("(");
34924 self.generate_expression(&e.this)?;
34925 if let Some(alphabet) = &e.alphabet {
34926 self.write(", ");
34927 self.generate_expression(alphabet)?;
34928 }
34929 self.write(")");
34930 Ok(())
34931 }
34932
34933 fn generate_try_to_decfloat(&mut self, e: &TryToDecfloat) -> Result<()> {
34934 self.write_keyword("TRY_TO_DECFLOAT");
34936 self.write("(");
34937 self.generate_expression(&e.this)?;
34938 if let Some(format) = &e.format {
34939 self.write(", '");
34940 self.write(format);
34941 self.write("'");
34942 }
34943 self.write(")");
34944 Ok(())
34945 }
34946
34947 fn generate_ts_or_ds_add(&mut self, e: &TsOrDsAdd) -> Result<()> {
34948 self.write_keyword("TS_OR_DS_ADD");
34950 self.write("(");
34951 self.generate_expression(&e.this)?;
34952 self.write(", ");
34953 self.generate_expression(&e.expression)?;
34954 if let Some(unit) = &e.unit {
34955 self.write(", ");
34956 self.write_keyword(unit);
34957 }
34958 if let Some(return_type) = &e.return_type {
34959 self.write(", ");
34960 self.generate_expression(return_type)?;
34961 }
34962 self.write(")");
34963 Ok(())
34964 }
34965
34966 fn generate_ts_or_ds_diff(&mut self, e: &TsOrDsDiff) -> Result<()> {
34967 self.write_keyword("TS_OR_DS_DIFF");
34969 self.write("(");
34970 self.generate_expression(&e.this)?;
34971 self.write(", ");
34972 self.generate_expression(&e.expression)?;
34973 if let Some(unit) = &e.unit {
34974 self.write(", ");
34975 self.write_keyword(unit);
34976 }
34977 self.write(")");
34978 Ok(())
34979 }
34980
34981 fn generate_ts_or_ds_to_date(&mut self, e: &TsOrDsToDate) -> Result<()> {
34982 let default_time_format = "%Y-%m-%d %H:%M:%S";
34983 let default_date_format = "%Y-%m-%d";
34984 let has_non_default_format = e.format.as_ref().map_or(false, |f| {
34985 f != default_time_format && f != default_date_format
34986 });
34987
34988 if has_non_default_format {
34989 let fmt = e.format.as_ref().unwrap();
34991 match self.config.dialect {
34992 Some(DialectType::MySQL) | Some(DialectType::StarRocks) => {
34993 let str_to_time = crate::expressions::StrToTime {
34996 this: Box::new((*e.this).clone()),
34997 format: fmt.clone(),
34998 zone: None,
34999 safe: None,
35000 target_type: None,
35001 };
35002 self.generate_str_to_time(&str_to_time)?;
35003 }
35004 Some(DialectType::Hive)
35005 | Some(DialectType::Spark)
35006 | Some(DialectType::Databricks) => {
35007 self.write_keyword("TO_DATE");
35009 self.write("(");
35010 self.generate_expression(&e.this)?;
35011 self.write(", '");
35012 self.write(&Self::strftime_to_java_format(fmt));
35013 self.write("')");
35014 }
35015 Some(DialectType::Snowflake) => {
35016 self.write_keyword("TO_DATE");
35018 self.write("(");
35019 self.generate_expression(&e.this)?;
35020 self.write(", '");
35021 self.write(&Self::strftime_to_snowflake_format(fmt));
35022 self.write("')");
35023 }
35024 Some(DialectType::Doris) => {
35025 self.write_keyword("TO_DATE");
35027 self.write("(");
35028 self.generate_expression(&e.this)?;
35029 self.write(")");
35030 }
35031 _ => {
35032 self.write_keyword("CAST");
35034 self.write("(");
35035 let str_to_time = crate::expressions::StrToTime {
35036 this: Box::new((*e.this).clone()),
35037 format: fmt.clone(),
35038 zone: None,
35039 safe: None,
35040 target_type: None,
35041 };
35042 self.generate_str_to_time(&str_to_time)?;
35043 self.write_keyword(" AS ");
35044 self.write_keyword("DATE");
35045 self.write(")");
35046 }
35047 }
35048 } else {
35049 match self.config.dialect {
35051 Some(DialectType::MySQL)
35052 | Some(DialectType::SQLite)
35053 | Some(DialectType::StarRocks) => {
35054 self.write_keyword("DATE");
35056 self.write("(");
35057 self.generate_expression(&e.this)?;
35058 self.write(")");
35059 }
35060 Some(DialectType::Hive)
35061 | Some(DialectType::Spark)
35062 | Some(DialectType::Databricks)
35063 | Some(DialectType::Snowflake)
35064 | Some(DialectType::Doris) => {
35065 self.write_keyword("TO_DATE");
35067 self.write("(");
35068 self.generate_expression(&e.this)?;
35069 self.write(")");
35070 }
35071 Some(DialectType::Presto)
35072 | Some(DialectType::Trino)
35073 | Some(DialectType::Athena) => {
35074 self.write_keyword("CAST");
35076 self.write("(");
35077 self.write_keyword("CAST");
35078 self.write("(");
35079 self.generate_expression(&e.this)?;
35080 self.write_keyword(" AS ");
35081 self.write_keyword("TIMESTAMP");
35082 self.write(")");
35083 self.write_keyword(" AS ");
35084 self.write_keyword("DATE");
35085 self.write(")");
35086 }
35087 Some(DialectType::ClickHouse) => {
35088 self.write_keyword("CAST");
35090 self.write("(");
35091 self.generate_expression(&e.this)?;
35092 self.write_keyword(" AS ");
35093 self.write("Nullable(DATE)");
35094 self.write(")");
35095 }
35096 _ => {
35097 self.write_keyword("CAST");
35099 self.write("(");
35100 self.generate_expression(&e.this)?;
35101 self.write_keyword(" AS ");
35102 self.write_keyword("DATE");
35103 self.write(")");
35104 }
35105 }
35106 }
35107 Ok(())
35108 }
35109
35110 fn generate_ts_or_ds_to_time(&mut self, e: &TsOrDsToTime) -> Result<()> {
35111 self.write_keyword("TS_OR_DS_TO_TIME");
35113 self.write("(");
35114 self.generate_expression(&e.this)?;
35115 if let Some(format) = &e.format {
35116 self.write(", '");
35117 self.write(format);
35118 self.write("'");
35119 }
35120 self.write(")");
35121 Ok(())
35122 }
35123
35124 fn generate_unhex(&mut self, e: &Unhex) -> Result<()> {
35125 self.write_keyword("UNHEX");
35127 self.write("(");
35128 self.generate_expression(&e.this)?;
35129 if let Some(expression) = &e.expression {
35130 self.write(", ");
35131 self.generate_expression(expression)?;
35132 }
35133 self.write(")");
35134 Ok(())
35135 }
35136
35137 fn generate_unicode_string(&mut self, e: &UnicodeString) -> Result<()> {
35138 self.write("U&");
35140 self.generate_expression(&e.this)?;
35141 if let Some(escape) = &e.escape {
35142 self.write_space();
35143 self.write_keyword("UESCAPE");
35144 self.write_space();
35145 self.generate_expression(escape)?;
35146 }
35147 Ok(())
35148 }
35149
35150 fn generate_uniform(&mut self, e: &Uniform) -> Result<()> {
35151 self.write_keyword("UNIFORM");
35153 self.write("(");
35154 self.generate_expression(&e.this)?;
35155 self.write(", ");
35156 self.generate_expression(&e.expression)?;
35157 if let Some(gen) = &e.gen {
35158 self.write(", ");
35159 self.generate_expression(gen)?;
35160 }
35161 if let Some(seed) = &e.seed {
35162 self.write(", ");
35163 self.generate_expression(seed)?;
35164 }
35165 self.write(")");
35166 Ok(())
35167 }
35168
35169 fn generate_unique_column_constraint(&mut self, e: &UniqueColumnConstraint) -> Result<()> {
35170 self.write_keyword("UNIQUE");
35172 if e.nulls.is_some() {
35174 self.write(" NULLS NOT DISTINCT");
35175 }
35176 if let Some(this) = &e.this {
35177 self.write_space();
35178 self.generate_expression(this)?;
35179 }
35180 if let Some(index_type) = &e.index_type {
35181 self.write(" USING ");
35182 self.generate_expression(index_type)?;
35183 }
35184 if let Some(on_conflict) = &e.on_conflict {
35185 self.write_space();
35186 self.generate_expression(on_conflict)?;
35187 }
35188 for opt in &e.options {
35189 self.write_space();
35190 self.generate_expression(opt)?;
35191 }
35192 Ok(())
35193 }
35194
35195 fn generate_unique_key_property(&mut self, e: &UniqueKeyProperty) -> Result<()> {
35196 self.write_keyword("UNIQUE KEY");
35198 self.write(" (");
35199 for (i, expr) in e.expressions.iter().enumerate() {
35200 if i > 0 {
35201 self.write(", ");
35202 }
35203 self.generate_expression(expr)?;
35204 }
35205 self.write(")");
35206 Ok(())
35207 }
35208
35209 fn generate_rollup_property(&mut self, e: &RollupProperty) -> Result<()> {
35210 self.write_keyword("ROLLUP");
35212 self.write(" (");
35213 for (i, index) in e.expressions.iter().enumerate() {
35214 if i > 0 {
35215 self.write(", ");
35216 }
35217 self.generate_identifier(&index.name)?;
35218 self.write("(");
35219 for (j, col) in index.expressions.iter().enumerate() {
35220 if j > 0 {
35221 self.write(", ");
35222 }
35223 self.generate_identifier(col)?;
35224 }
35225 self.write(")");
35226 }
35227 self.write(")");
35228 Ok(())
35229 }
35230
35231 fn generate_unix_to_str(&mut self, e: &UnixToStr) -> Result<()> {
35232 match self.config.dialect {
35233 Some(DialectType::DuckDB) => {
35234 self.write_keyword("STRFTIME");
35236 self.write("(");
35237 self.write_keyword("TO_TIMESTAMP");
35238 self.write("(");
35239 self.generate_expression(&e.this)?;
35240 self.write("), '");
35241 if let Some(format) = &e.format {
35242 self.write(format);
35243 }
35244 self.write("')");
35245 }
35246 Some(DialectType::Hive) => {
35247 self.write_keyword("FROM_UNIXTIME");
35249 self.write("(");
35250 self.generate_expression(&e.this)?;
35251 if let Some(format) = &e.format {
35252 if format != "yyyy-MM-dd HH:mm:ss" {
35253 self.write(", '");
35254 self.write(format);
35255 self.write("'");
35256 }
35257 }
35258 self.write(")");
35259 }
35260 Some(DialectType::Presto) | Some(DialectType::Trino) => {
35261 self.write_keyword("DATE_FORMAT");
35263 self.write("(");
35264 self.write_keyword("FROM_UNIXTIME");
35265 self.write("(");
35266 self.generate_expression(&e.this)?;
35267 self.write("), '");
35268 if let Some(format) = &e.format {
35269 self.write(format);
35270 }
35271 self.write("')");
35272 }
35273 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
35274 self.write_keyword("FROM_UNIXTIME");
35276 self.write("(");
35277 self.generate_expression(&e.this)?;
35278 if let Some(format) = &e.format {
35279 self.write(", '");
35280 self.write(format);
35281 self.write("'");
35282 }
35283 self.write(")");
35284 }
35285 _ => {
35286 self.write_keyword("UNIX_TO_STR");
35288 self.write("(");
35289 self.generate_expression(&e.this)?;
35290 if let Some(format) = &e.format {
35291 self.write(", '");
35292 self.write(format);
35293 self.write("'");
35294 }
35295 self.write(")");
35296 }
35297 }
35298 Ok(())
35299 }
35300
35301 fn generate_unix_to_time(&mut self, e: &UnixToTime) -> Result<()> {
35302 use crate::dialects::DialectType;
35303 let scale = e.scale.unwrap_or(0); match self.config.dialect {
35306 Some(DialectType::Snowflake) => {
35307 self.write_keyword("TO_TIMESTAMP");
35309 self.write("(");
35310 self.generate_expression(&e.this)?;
35311 if let Some(s) = e.scale {
35312 if s > 0 {
35313 self.write(", ");
35314 self.write(&s.to_string());
35315 }
35316 }
35317 self.write(")");
35318 }
35319 Some(DialectType::BigQuery) => {
35320 match scale {
35323 0 => {
35324 self.write_keyword("TIMESTAMP_SECONDS");
35325 self.write("(");
35326 self.generate_expression(&e.this)?;
35327 self.write(")");
35328 }
35329 3 => {
35330 self.write_keyword("TIMESTAMP_MILLIS");
35331 self.write("(");
35332 self.generate_expression(&e.this)?;
35333 self.write(")");
35334 }
35335 6 => {
35336 self.write_keyword("TIMESTAMP_MICROS");
35337 self.write("(");
35338 self.generate_expression(&e.this)?;
35339 self.write(")");
35340 }
35341 _ => {
35342 self.write_keyword("TIMESTAMP_SECONDS");
35344 self.write("(CAST(");
35345 self.generate_expression(&e.this)?;
35346 self.write(&format!(" / POWER(10, {}) AS INT64))", scale));
35347 }
35348 }
35349 }
35350 Some(DialectType::Spark) => {
35351 match scale {
35356 0 => {
35357 self.write_keyword("CAST");
35358 self.write("(");
35359 self.write_keyword("FROM_UNIXTIME");
35360 self.write("(");
35361 self.generate_expression(&e.this)?;
35362 self.write(") ");
35363 self.write_keyword("AS TIMESTAMP");
35364 self.write(")");
35365 }
35366 3 => {
35367 self.write_keyword("TIMESTAMP_MILLIS");
35368 self.write("(");
35369 self.generate_expression(&e.this)?;
35370 self.write(")");
35371 }
35372 6 => {
35373 self.write_keyword("TIMESTAMP_MICROS");
35374 self.write("(");
35375 self.generate_expression(&e.this)?;
35376 self.write(")");
35377 }
35378 _ => {
35379 self.write_keyword("TIMESTAMP_SECONDS");
35380 self.write("(");
35381 self.generate_expression(&e.this)?;
35382 self.write(&format!(" / POWER(10, {}))", scale));
35383 }
35384 }
35385 }
35386 Some(DialectType::Databricks) => {
35387 match scale {
35391 0 => {
35392 self.write_keyword("CAST");
35393 self.write("(");
35394 self.write_keyword("FROM_UNIXTIME");
35395 self.write("(");
35396 self.generate_expression(&e.this)?;
35397 self.write(") ");
35398 self.write_keyword("AS TIMESTAMP");
35399 self.write(")");
35400 }
35401 3 => {
35402 self.write_keyword("TIMESTAMP_MILLIS");
35403 self.write("(");
35404 self.generate_expression(&e.this)?;
35405 self.write(")");
35406 }
35407 6 => {
35408 self.write_keyword("TIMESTAMP_MICROS");
35409 self.write("(");
35410 self.generate_expression(&e.this)?;
35411 self.write(")");
35412 }
35413 _ => {
35414 self.write_keyword("TIMESTAMP_SECONDS");
35415 self.write("(");
35416 self.generate_expression(&e.this)?;
35417 self.write(&format!(" / POWER(10, {}))", scale));
35418 }
35419 }
35420 }
35421 Some(DialectType::Hive) => {
35422 if scale == 0 {
35424 self.write_keyword("FROM_UNIXTIME");
35425 self.write("(");
35426 self.generate_expression(&e.this)?;
35427 self.write(")");
35428 } else {
35429 self.write_keyword("FROM_UNIXTIME");
35430 self.write("(");
35431 self.generate_expression(&e.this)?;
35432 self.write(&format!(" / POWER(10, {})", scale));
35433 self.write(")");
35434 }
35435 }
35436 Some(DialectType::Presto) | Some(DialectType::Trino) => {
35437 if scale == 0 {
35440 self.write_keyword("FROM_UNIXTIME");
35441 self.write("(");
35442 self.generate_expression(&e.this)?;
35443 self.write(")");
35444 } else {
35445 self.write_keyword("FROM_UNIXTIME");
35446 self.write("(CAST(");
35447 self.generate_expression(&e.this)?;
35448 self.write(&format!(" AS DOUBLE) / POW(10, {}))", scale));
35449 }
35450 }
35451 Some(DialectType::DuckDB) => {
35452 match scale {
35456 0 => {
35457 self.write_keyword("TO_TIMESTAMP");
35458 self.write("(");
35459 self.generate_expression(&e.this)?;
35460 self.write(")");
35461 }
35462 3 => {
35463 self.write_keyword("EPOCH_MS");
35464 self.write("(");
35465 self.generate_expression(&e.this)?;
35466 self.write(")");
35467 }
35468 6 => {
35469 self.write_keyword("MAKE_TIMESTAMP");
35470 self.write("(");
35471 self.generate_expression(&e.this)?;
35472 self.write(")");
35473 }
35474 _ => {
35475 self.write_keyword("TO_TIMESTAMP");
35476 self.write("(");
35477 self.generate_expression(&e.this)?;
35478 self.write(&format!(" / POWER(10, {}))", scale));
35479 self.write_keyword(" AT TIME ZONE");
35480 self.write(" 'UTC'");
35481 }
35482 }
35483 }
35484 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
35485 self.write_keyword("FROM_UNIXTIME");
35487 self.write("(");
35488 self.generate_expression(&e.this)?;
35489 self.write(")");
35490 }
35491 Some(DialectType::Oracle) => {
35492 self.write("TO_DATE('1970-01-01', 'YYYY-MM-DD') + (");
35494 self.generate_expression(&e.this)?;
35495 self.write(" / 86400)");
35496 }
35497 Some(DialectType::Redshift) => {
35498 self.write("(TIMESTAMP 'epoch' + ");
35501 if scale == 0 {
35502 self.generate_expression(&e.this)?;
35503 } else {
35504 self.write("(");
35505 self.generate_expression(&e.this)?;
35506 self.write(&format!(" / POWER(10, {}))", scale));
35507 }
35508 self.write(" * INTERVAL '1 SECOND')");
35509 }
35510 _ => {
35511 self.write_keyword("TO_TIMESTAMP");
35513 self.write("(");
35514 self.generate_expression(&e.this)?;
35515 if let Some(s) = e.scale {
35516 self.write(", ");
35517 self.write(&s.to_string());
35518 }
35519 self.write(")");
35520 }
35521 }
35522 Ok(())
35523 }
35524
35525 fn generate_unpivot_columns(&mut self, e: &UnpivotColumns) -> Result<()> {
35526 if !matches!(&*e.this, Expression::Null(_)) {
35528 self.write_keyword("NAME");
35529 self.write_space();
35530 self.generate_expression(&e.this)?;
35531 }
35532 if !e.expressions.is_empty() {
35533 self.write_space();
35534 self.write_keyword("VALUE");
35535 self.write_space();
35536 for (i, expr) in e.expressions.iter().enumerate() {
35537 if i > 0 {
35538 self.write(", ");
35539 }
35540 self.generate_expression(expr)?;
35541 }
35542 }
35543 Ok(())
35544 }
35545
35546 fn generate_user_defined_function(&mut self, e: &UserDefinedFunction) -> Result<()> {
35547 if e.wrapped.is_some() {
35549 self.write("(");
35550 }
35551 self.generate_expression(&e.this)?;
35552 if e.wrapped.is_some() {
35553 self.write(")");
35554 }
35555 self.write("(");
35556 for (i, expr) in e.expressions.iter().enumerate() {
35557 if i > 0 {
35558 self.write(", ");
35559 }
35560 self.generate_expression(expr)?;
35561 }
35562 self.write(")");
35563 Ok(())
35564 }
35565
35566 fn generate_using_template_property(&mut self, e: &UsingTemplateProperty) -> Result<()> {
35567 self.write_keyword("USING TEMPLATE");
35569 self.write_space();
35570 self.generate_expression(&e.this)?;
35571 Ok(())
35572 }
35573
35574 fn generate_utc_time(&mut self, _e: &UtcTime) -> Result<()> {
35575 self.write_keyword("UTC_TIME");
35577 Ok(())
35578 }
35579
35580 fn generate_utc_timestamp(&mut self, _e: &UtcTimestamp) -> Result<()> {
35581 self.write_keyword("UTC_TIMESTAMP");
35583 Ok(())
35584 }
35585
35586 fn generate_uuid(&mut self, e: &Uuid) -> Result<()> {
35587 use crate::dialects::DialectType;
35588 let func_name = match self.config.dialect {
35590 Some(DialectType::Snowflake) => "UUID_STRING",
35591 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
35592 Some(DialectType::BigQuery) => "GENERATE_UUID",
35593 _ => {
35594 if let Some(name) = &e.name {
35595 name.as_str()
35596 } else {
35597 "UUID"
35598 }
35599 }
35600 };
35601 self.write_keyword(func_name);
35602 self.write("(");
35603 if let Some(this) = &e.this {
35604 self.generate_expression(this)?;
35605 }
35606 self.write(")");
35607 Ok(())
35608 }
35609
35610 fn generate_var_map(&mut self, e: &VarMap) -> Result<()> {
35611 self.write_keyword("MAP");
35613 self.write("(");
35614 let mut first = true;
35615 for (k, v) in e.keys.iter().zip(e.values.iter()) {
35616 if !first {
35617 self.write(", ");
35618 }
35619 self.generate_expression(k)?;
35620 self.write(", ");
35621 self.generate_expression(v)?;
35622 first = false;
35623 }
35624 self.write(")");
35625 Ok(())
35626 }
35627
35628 fn generate_vector_search(&mut self, e: &VectorSearch) -> Result<()> {
35629 self.write_keyword("VECTOR_SEARCH");
35631 self.write("(");
35632 self.generate_expression(&e.this)?;
35633 if let Some(col) = &e.column_to_search {
35634 self.write(", ");
35635 self.generate_expression(col)?;
35636 }
35637 if let Some(query_table) = &e.query_table {
35638 self.write(", ");
35639 self.generate_expression(query_table)?;
35640 }
35641 if let Some(query_col) = &e.query_column_to_search {
35642 self.write(", ");
35643 self.generate_expression(query_col)?;
35644 }
35645 if let Some(top_k) = &e.top_k {
35646 self.write(", ");
35647 self.generate_expression(top_k)?;
35648 }
35649 if let Some(dist_type) = &e.distance_type {
35650 self.write(", ");
35651 self.generate_expression(dist_type)?;
35652 }
35653 self.write(")");
35654 Ok(())
35655 }
35656
35657 fn generate_version(&mut self, e: &Version) -> Result<()> {
35658 use crate::dialects::DialectType;
35664 let skip_for = matches!(
35665 self.config.dialect,
35666 Some(DialectType::Hive) | Some(DialectType::Spark)
35667 );
35668 if !skip_for {
35669 self.write_keyword("FOR");
35670 self.write_space();
35671 }
35672 match e.this.as_ref() {
35674 Expression::Identifier(ident) => {
35675 self.write_keyword(&ident.name);
35676 }
35677 _ => {
35678 self.generate_expression(&e.this)?;
35679 }
35680 }
35681 self.write_space();
35682 self.write_keyword(&e.kind);
35683 if let Some(expression) = &e.expression {
35684 self.write_space();
35685 self.generate_expression(expression)?;
35686 }
35687 Ok(())
35688 }
35689
35690 fn generate_view_attribute_property(&mut self, e: &ViewAttributeProperty) -> Result<()> {
35691 self.generate_expression(&e.this)?;
35693 Ok(())
35694 }
35695
35696 fn generate_volatile_property(&mut self, e: &VolatileProperty) -> Result<()> {
35697 if e.this.is_some() {
35699 self.write_keyword("NOT VOLATILE");
35700 } else {
35701 self.write_keyword("VOLATILE");
35702 }
35703 Ok(())
35704 }
35705
35706 fn generate_watermark_column_constraint(
35707 &mut self,
35708 e: &WatermarkColumnConstraint,
35709 ) -> Result<()> {
35710 self.write_keyword("WATERMARK FOR");
35712 self.write_space();
35713 self.generate_expression(&e.this)?;
35714 self.write_space();
35715 self.write_keyword("AS");
35716 self.write_space();
35717 self.generate_expression(&e.expression)?;
35718 Ok(())
35719 }
35720
35721 fn generate_week(&mut self, e: &Week) -> Result<()> {
35722 self.write_keyword("WEEK");
35724 self.write("(");
35725 self.generate_expression(&e.this)?;
35726 if let Some(mode) = &e.mode {
35727 self.write(", ");
35728 self.generate_expression(mode)?;
35729 }
35730 self.write(")");
35731 Ok(())
35732 }
35733
35734 fn generate_when(&mut self, e: &When) -> Result<()> {
35735 self.write_keyword("WHEN");
35739 self.write_space();
35740
35741 if let Some(matched) = &e.matched {
35743 match matched.as_ref() {
35745 Expression::Boolean(b) if b.value => {
35746 self.write_keyword("MATCHED");
35747 }
35748 _ => {
35749 self.write_keyword("NOT MATCHED");
35750 }
35751 }
35752 } else {
35753 self.write_keyword("NOT MATCHED");
35754 }
35755
35756 if self.config.matched_by_source {
35761 if let Some(source) = &e.source {
35762 if let Expression::Boolean(b) = source.as_ref() {
35763 if b.value {
35764 self.write_space();
35766 self.write_keyword("BY SOURCE");
35767 }
35768 } else {
35770 self.write_space();
35772 self.write_keyword("BY SOURCE");
35773 }
35774 }
35775 }
35776
35777 if let Some(condition) = &e.condition {
35779 self.write_space();
35780 self.write_keyword("AND");
35781 self.write_space();
35782 self.generate_expression(condition)?;
35783 }
35784
35785 self.write_space();
35786 self.write_keyword("THEN");
35787 self.write_space();
35788
35789 self.generate_merge_action(&e.then)?;
35792
35793 Ok(())
35794 }
35795
35796 fn generate_merge_action(&mut self, action: &Expression) -> Result<()> {
35797 match action {
35798 Expression::Tuple(tuple) => {
35799 let elements = &tuple.expressions;
35800 if elements.is_empty() {
35801 return self.generate_expression(action);
35802 }
35803 match &elements[0] {
35805 Expression::Var(v) if v.this == "INSERT" => {
35806 self.write_keyword("INSERT");
35807 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
35809 self.write(" *");
35810 } else {
35811 let mut values_idx = 1;
35812 if elements.len() > 1 {
35814 if let Expression::Tuple(cols) = &elements[1] {
35815 if elements.len() > 2 {
35817 self.write(" (");
35819 for (i, col) in cols.expressions.iter().enumerate() {
35820 if i > 0 {
35821 self.write(", ");
35822 }
35823 if !self.merge_strip_qualifiers.is_empty() {
35825 let stripped = self.strip_merge_qualifier(col);
35826 self.generate_expression(&stripped)?;
35827 } else {
35828 self.generate_expression(col)?;
35829 }
35830 }
35831 self.write(")");
35832 values_idx = 2;
35833 } else {
35834 values_idx = 1;
35836 }
35837 }
35838 }
35839 if values_idx < elements.len() {
35841 let is_row = matches!(&elements[values_idx], Expression::Var(v) if v.this == "ROW");
35843 if !is_row {
35844 self.write_space();
35845 self.write_keyword("VALUES");
35846 }
35847 self.write(" ");
35848 if let Expression::Tuple(vals) = &elements[values_idx] {
35849 self.write("(");
35850 for (i, val) in vals.expressions.iter().enumerate() {
35851 if i > 0 {
35852 self.write(", ");
35853 }
35854 self.generate_expression(val)?;
35855 }
35856 self.write(")");
35857 } else {
35858 self.generate_expression(&elements[values_idx])?;
35859 }
35860 }
35861 } }
35863 Expression::Var(v) if v.this == "UPDATE" => {
35864 self.write_keyword("UPDATE");
35865 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
35867 self.write(" *");
35868 } else if elements.len() > 1 {
35869 self.write_space();
35870 self.write_keyword("SET");
35871 if self.config.pretty {
35873 self.write_newline();
35874 self.indent_level += 1;
35875 self.write_indent();
35876 } else {
35877 self.write_space();
35878 }
35879 if let Expression::Tuple(assignments) = &elements[1] {
35880 for (i, assignment) in assignments.expressions.iter().enumerate() {
35881 if i > 0 {
35882 if self.config.pretty {
35883 self.write(",");
35884 self.write_newline();
35885 self.write_indent();
35886 } else {
35887 self.write(", ");
35888 }
35889 }
35890 if !self.merge_strip_qualifiers.is_empty() {
35892 self.generate_merge_set_assignment(assignment)?;
35893 } else {
35894 self.generate_expression(assignment)?;
35895 }
35896 }
35897 } else {
35898 self.generate_expression(&elements[1])?;
35899 }
35900 if self.config.pretty {
35901 self.indent_level -= 1;
35902 }
35903 }
35904 }
35905 _ => {
35906 self.generate_expression(action)?;
35908 }
35909 }
35910 }
35911 Expression::Var(v)
35912 if v.this == "INSERT"
35913 || v.this == "UPDATE"
35914 || v.this == "DELETE"
35915 || v.this == "DO NOTHING" =>
35916 {
35917 self.write_keyword(&v.this);
35918 }
35919 _ => {
35920 self.generate_expression(action)?;
35921 }
35922 }
35923 Ok(())
35924 }
35925
35926 fn generate_merge_set_assignment(&mut self, assignment: &Expression) -> Result<()> {
35928 match assignment {
35929 Expression::Eq(eq) => {
35930 let stripped_left = self.strip_merge_qualifier(&eq.left);
35932 self.generate_expression(&stripped_left)?;
35933 self.write(" = ");
35934 self.generate_expression(&eq.right)?;
35935 Ok(())
35936 }
35937 other => self.generate_expression(other),
35938 }
35939 }
35940
35941 fn strip_merge_qualifier(&self, expr: &Expression) -> Expression {
35943 match expr {
35944 Expression::Column(col) => {
35945 if let Some(ref table_ident) = col.table {
35946 if self
35947 .merge_strip_qualifiers
35948 .iter()
35949 .any(|n| n.eq_ignore_ascii_case(&table_ident.name))
35950 {
35951 let mut col = col.clone();
35953 col.table = None;
35954 return Expression::Column(col);
35955 }
35956 }
35957 expr.clone()
35958 }
35959 Expression::Dot(dot) => {
35960 if let Expression::Identifier(id) = &dot.this {
35962 if self
35963 .merge_strip_qualifiers
35964 .iter()
35965 .any(|n| n.eq_ignore_ascii_case(&id.name))
35966 {
35967 return Expression::Identifier(dot.field.clone());
35968 }
35969 }
35970 expr.clone()
35971 }
35972 _ => expr.clone(),
35973 }
35974 }
35975
35976 fn generate_whens(&mut self, e: &Whens) -> Result<()> {
35977 for (i, expr) in e.expressions.iter().enumerate() {
35979 if i > 0 {
35980 if self.config.pretty {
35982 self.write_newline();
35983 self.write_indent();
35984 } else {
35985 self.write_space();
35986 }
35987 }
35988 self.generate_expression(expr)?;
35989 }
35990 Ok(())
35991 }
35992
35993 fn generate_where(&mut self, e: &Where) -> Result<()> {
35994 self.write_keyword("WHERE");
35996 self.write_space();
35997 self.generate_expression(&e.this)?;
35998 Ok(())
35999 }
36000
36001 fn generate_width_bucket(&mut self, e: &WidthBucket) -> Result<()> {
36002 self.write_keyword("WIDTH_BUCKET");
36004 self.write("(");
36005 self.generate_expression(&e.this)?;
36006 if let Some(min_value) = &e.min_value {
36007 self.write(", ");
36008 self.generate_expression(min_value)?;
36009 }
36010 if let Some(max_value) = &e.max_value {
36011 self.write(", ");
36012 self.generate_expression(max_value)?;
36013 }
36014 if let Some(num_buckets) = &e.num_buckets {
36015 self.write(", ");
36016 self.generate_expression(num_buckets)?;
36017 }
36018 self.write(")");
36019 Ok(())
36020 }
36021
36022 fn generate_window(&mut self, e: &WindowSpec) -> Result<()> {
36023 self.generate_window_spec(e)
36025 }
36026
36027 fn generate_window_spec(&mut self, e: &WindowSpec) -> Result<()> {
36028 let mut has_content = false;
36030
36031 if !e.partition_by.is_empty() {
36033 self.write_keyword("PARTITION BY");
36034 self.write_space();
36035 for (i, expr) in e.partition_by.iter().enumerate() {
36036 if i > 0 {
36037 self.write(", ");
36038 }
36039 self.generate_expression(expr)?;
36040 }
36041 has_content = true;
36042 }
36043
36044 if !e.order_by.is_empty() {
36046 if has_content {
36047 self.write_space();
36048 }
36049 self.write_keyword("ORDER BY");
36050 self.write_space();
36051 for (i, ordered) in e.order_by.iter().enumerate() {
36052 if i > 0 {
36053 self.write(", ");
36054 }
36055 self.generate_expression(&ordered.this)?;
36056 if ordered.desc {
36057 self.write_space();
36058 self.write_keyword("DESC");
36059 } else if ordered.explicit_asc {
36060 self.write_space();
36061 self.write_keyword("ASC");
36062 }
36063 if let Some(nulls_first) = ordered.nulls_first {
36064 self.write_space();
36065 self.write_keyword("NULLS");
36066 self.write_space();
36067 if nulls_first {
36068 self.write_keyword("FIRST");
36069 } else {
36070 self.write_keyword("LAST");
36071 }
36072 }
36073 }
36074 has_content = true;
36075 }
36076
36077 if let Some(frame) = &e.frame {
36079 if has_content {
36080 self.write_space();
36081 }
36082 self.generate_window_frame(frame)?;
36083 }
36084
36085 Ok(())
36086 }
36087
36088 fn generate_with_data_property(&mut self, e: &WithDataProperty) -> Result<()> {
36089 self.write_keyword("WITH");
36091 self.write_space();
36092 if e.no.is_some() {
36093 self.write_keyword("NO");
36094 self.write_space();
36095 }
36096 self.write_keyword("DATA");
36097
36098 if let Some(statistics) = &e.statistics {
36100 self.write_space();
36101 self.write_keyword("AND");
36102 self.write_space();
36103 match statistics.as_ref() {
36105 Expression::Boolean(b) if !b.value => {
36106 self.write_keyword("NO");
36107 self.write_space();
36108 }
36109 _ => {}
36110 }
36111 self.write_keyword("STATISTICS");
36112 }
36113 Ok(())
36114 }
36115
36116 fn generate_with_fill(&mut self, e: &WithFill) -> Result<()> {
36117 self.write_keyword("WITH FILL");
36119
36120 if let Some(from_) = &e.from_ {
36121 self.write_space();
36122 self.write_keyword("FROM");
36123 self.write_space();
36124 self.generate_expression(from_)?;
36125 }
36126
36127 if let Some(to) = &e.to {
36128 self.write_space();
36129 self.write_keyword("TO");
36130 self.write_space();
36131 self.generate_expression(to)?;
36132 }
36133
36134 if let Some(step) = &e.step {
36135 self.write_space();
36136 self.write_keyword("STEP");
36137 self.write_space();
36138 self.generate_expression(step)?;
36139 }
36140
36141 if let Some(staleness) = &e.staleness {
36142 self.write_space();
36143 self.write_keyword("STALENESS");
36144 self.write_space();
36145 self.generate_expression(staleness)?;
36146 }
36147
36148 if let Some(interpolate) = &e.interpolate {
36149 self.write_space();
36150 self.write_keyword("INTERPOLATE");
36151 self.write(" (");
36152 self.generate_interpolate_item(interpolate)?;
36154 self.write(")");
36155 }
36156
36157 Ok(())
36158 }
36159
36160 fn generate_interpolate_item(&mut self, expr: &Expression) -> Result<()> {
36162 match expr {
36163 Expression::Alias(alias) => {
36164 self.generate_identifier(&alias.alias)?;
36166 self.write_space();
36167 self.write_keyword("AS");
36168 self.write_space();
36169 self.generate_expression(&alias.this)?;
36170 }
36171 Expression::Tuple(tuple) => {
36172 for (i, item) in tuple.expressions.iter().enumerate() {
36173 if i > 0 {
36174 self.write(", ");
36175 }
36176 self.generate_interpolate_item(item)?;
36177 }
36178 }
36179 other => {
36180 self.generate_expression(other)?;
36181 }
36182 }
36183 Ok(())
36184 }
36185
36186 fn generate_with_journal_table_property(&mut self, e: &WithJournalTableProperty) -> Result<()> {
36187 self.write_keyword("WITH JOURNAL TABLE");
36189 self.write("=");
36190 self.generate_expression(&e.this)?;
36191 Ok(())
36192 }
36193
36194 fn generate_with_operator(&mut self, e: &WithOperator) -> Result<()> {
36195 self.generate_expression(&e.this)?;
36197 self.write_space();
36198 self.write_keyword("WITH");
36199 self.write_space();
36200 self.write_keyword(&e.op);
36201 Ok(())
36202 }
36203
36204 fn generate_with_procedure_options(&mut self, e: &WithProcedureOptions) -> Result<()> {
36205 self.write_keyword("WITH");
36207 self.write_space();
36208 for (i, expr) in e.expressions.iter().enumerate() {
36209 if i > 0 {
36210 self.write(", ");
36211 }
36212 self.generate_expression(expr)?;
36213 }
36214 Ok(())
36215 }
36216
36217 fn generate_with_schema_binding_property(
36218 &mut self,
36219 e: &WithSchemaBindingProperty,
36220 ) -> Result<()> {
36221 self.write_keyword("WITH");
36223 self.write_space();
36224 self.generate_expression(&e.this)?;
36225 Ok(())
36226 }
36227
36228 fn generate_with_system_versioning_property(
36229 &mut self,
36230 e: &WithSystemVersioningProperty,
36231 ) -> Result<()> {
36232 let mut parts = Vec::new();
36238
36239 if let Some(this) = &e.this {
36240 let mut s = String::from("HISTORY_TABLE=");
36242 let mut gen = Generator::new();
36243 gen.generate_expression(this)?;
36244 s.push_str(&gen.output);
36245 parts.push(s);
36246 }
36247
36248 if let Some(data_consistency) = &e.data_consistency {
36249 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
36250 let mut gen = Generator::new();
36251 gen.generate_expression(data_consistency)?;
36252 s.push_str(&gen.output);
36253 parts.push(s);
36254 }
36255
36256 if let Some(retention_period) = &e.retention_period {
36257 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
36258 let mut gen = Generator::new();
36259 gen.generate_expression(retention_period)?;
36260 s.push_str(&gen.output);
36261 parts.push(s);
36262 }
36263
36264 self.write_keyword("SYSTEM_VERSIONING");
36265 self.write("=");
36266
36267 if !parts.is_empty() {
36268 self.write_keyword("ON");
36269 self.write("(");
36270 self.write(&parts.join(", "));
36271 self.write(")");
36272 } else if e.on.is_some() {
36273 self.write_keyword("ON");
36274 } else {
36275 self.write_keyword("OFF");
36276 }
36277
36278 if e.with_.is_some() {
36280 let inner = self.output.clone();
36281 self.output.clear();
36282 self.write("WITH(");
36283 self.write(&inner);
36284 self.write(")");
36285 }
36286
36287 Ok(())
36288 }
36289
36290 fn generate_with_table_hint(&mut self, e: &WithTableHint) -> Result<()> {
36291 self.write_keyword("WITH");
36293 self.write(" (");
36294 for (i, expr) in e.expressions.iter().enumerate() {
36295 if i > 0 {
36296 self.write(", ");
36297 }
36298 self.generate_expression(expr)?;
36299 }
36300 self.write(")");
36301 Ok(())
36302 }
36303
36304 fn generate_xml_element(&mut self, e: &XMLElement) -> Result<()> {
36305 self.write_keyword("XMLELEMENT");
36308 self.write("(");
36309
36310 if e.evalname.is_some() {
36311 self.write_keyword("EVALNAME");
36312 } else {
36313 self.write_keyword("NAME");
36314 }
36315 self.write_space();
36316 self.generate_expression(&e.this)?;
36317
36318 for expr in &e.expressions {
36319 self.write(", ");
36320 self.generate_expression(expr)?;
36321 }
36322 self.write(")");
36323 Ok(())
36324 }
36325
36326 fn generate_xml_get(&mut self, e: &XMLGet) -> Result<()> {
36327 self.write_keyword("XMLGET");
36329 self.write("(");
36330 self.generate_expression(&e.this)?;
36331 self.write(", ");
36332 self.generate_expression(&e.expression)?;
36333 if let Some(instance) = &e.instance {
36334 self.write(", ");
36335 self.generate_expression(instance)?;
36336 }
36337 self.write(")");
36338 Ok(())
36339 }
36340
36341 fn generate_xml_key_value_option(&mut self, e: &XMLKeyValueOption) -> Result<()> {
36342 self.generate_expression(&e.this)?;
36344 if let Some(expression) = &e.expression {
36345 self.write("(");
36346 self.generate_expression(expression)?;
36347 self.write(")");
36348 }
36349 Ok(())
36350 }
36351
36352 fn generate_xml_table(&mut self, e: &XMLTable) -> Result<()> {
36353 self.write_keyword("XMLTABLE");
36355 self.write("(");
36356
36357 if self.config.pretty {
36358 self.indent_level += 1;
36359 self.write_newline();
36360 self.write_indent();
36361 self.generate_expression(&e.this)?;
36362
36363 if let Some(passing) = &e.passing {
36364 self.write_newline();
36365 self.write_indent();
36366 self.write_keyword("PASSING");
36367 if let Expression::Tuple(tuple) = passing.as_ref() {
36368 for expr in &tuple.expressions {
36369 self.write_newline();
36370 self.indent_level += 1;
36371 self.write_indent();
36372 self.generate_expression(expr)?;
36373 self.indent_level -= 1;
36374 }
36375 } else {
36376 self.write_newline();
36377 self.indent_level += 1;
36378 self.write_indent();
36379 self.generate_expression(passing)?;
36380 self.indent_level -= 1;
36381 }
36382 }
36383
36384 if e.by_ref.is_some() {
36385 self.write_newline();
36386 self.write_indent();
36387 self.write_keyword("RETURNING SEQUENCE BY REF");
36388 }
36389
36390 if !e.columns.is_empty() {
36391 self.write_newline();
36392 self.write_indent();
36393 self.write_keyword("COLUMNS");
36394 for (i, col) in e.columns.iter().enumerate() {
36395 self.write_newline();
36396 self.indent_level += 1;
36397 self.write_indent();
36398 self.generate_expression(col)?;
36399 self.indent_level -= 1;
36400 if i < e.columns.len() - 1 {
36401 self.write(",");
36402 }
36403 }
36404 }
36405
36406 self.indent_level -= 1;
36407 self.write_newline();
36408 self.write_indent();
36409 self.write(")");
36410 return Ok(());
36411 }
36412
36413 if let Some(namespaces) = &e.namespaces {
36415 self.write_keyword("XMLNAMESPACES");
36416 self.write("(");
36417 if let Expression::Tuple(tuple) = namespaces.as_ref() {
36419 for (i, expr) in tuple.expressions.iter().enumerate() {
36420 if i > 0 {
36421 self.write(", ");
36422 }
36423 if !matches!(expr, Expression::Alias(_)) {
36426 self.write_keyword("DEFAULT");
36427 self.write_space();
36428 }
36429 self.generate_expression(expr)?;
36430 }
36431 } else {
36432 if !matches!(namespaces.as_ref(), Expression::Alias(_)) {
36434 self.write_keyword("DEFAULT");
36435 self.write_space();
36436 }
36437 self.generate_expression(namespaces)?;
36438 }
36439 self.write("), ");
36440 }
36441
36442 self.generate_expression(&e.this)?;
36444
36445 if let Some(passing) = &e.passing {
36447 self.write_space();
36448 self.write_keyword("PASSING");
36449 self.write_space();
36450 if let Expression::Tuple(tuple) = passing.as_ref() {
36452 for (i, expr) in tuple.expressions.iter().enumerate() {
36453 if i > 0 {
36454 self.write(", ");
36455 }
36456 self.generate_expression(expr)?;
36457 }
36458 } else {
36459 self.generate_expression(passing)?;
36460 }
36461 }
36462
36463 if e.by_ref.is_some() {
36465 self.write_space();
36466 self.write_keyword("RETURNING SEQUENCE BY REF");
36467 }
36468
36469 if !e.columns.is_empty() {
36471 self.write_space();
36472 self.write_keyword("COLUMNS");
36473 self.write_space();
36474 for (i, col) in e.columns.iter().enumerate() {
36475 if i > 0 {
36476 self.write(", ");
36477 }
36478 self.generate_expression(col)?;
36479 }
36480 }
36481
36482 self.write(")");
36483 Ok(())
36484 }
36485
36486 fn generate_xor(&mut self, e: &Xor) -> Result<()> {
36487 if let Some(this) = &e.this {
36490 self.generate_expression(this)?;
36491 if let Some(expression) = &e.expression {
36492 self.write_space();
36493 self.write_keyword("XOR");
36494 self.write_space();
36495 self.generate_expression(expression)?;
36496 }
36497 }
36498
36499 for (i, expr) in e.expressions.iter().enumerate() {
36501 if i > 0 || e.this.is_some() {
36502 self.write_space();
36503 self.write_keyword("XOR");
36504 self.write_space();
36505 }
36506 self.generate_expression(expr)?;
36507 }
36508 Ok(())
36509 }
36510
36511 fn generate_zipf(&mut self, e: &Zipf) -> Result<()> {
36512 self.write_keyword("ZIPF");
36514 self.write("(");
36515 self.generate_expression(&e.this)?;
36516 if let Some(elementcount) = &e.elementcount {
36517 self.write(", ");
36518 self.generate_expression(elementcount)?;
36519 }
36520 if let Some(gen) = &e.gen {
36521 self.write(", ");
36522 self.generate_expression(gen)?;
36523 }
36524 self.write(")");
36525 Ok(())
36526 }
36527}
36528
36529impl Default for Generator {
36530 fn default() -> Self {
36531 Self::new()
36532 }
36533}
36534
36535#[cfg(test)]
36536mod tests {
36537 use super::*;
36538 use crate::parser::Parser;
36539
36540 fn roundtrip(sql: &str) -> String {
36541 let ast = Parser::parse_sql(sql).unwrap();
36542 Generator::sql(&ast[0]).unwrap()
36543 }
36544
36545 #[test]
36546 fn test_simple_select() {
36547 let result = roundtrip("SELECT 1");
36548 assert_eq!(result, "SELECT 1");
36549 }
36550
36551 #[test]
36552 fn test_select_from() {
36553 let result = roundtrip("SELECT a, b FROM t");
36554 assert_eq!(result, "SELECT a, b FROM t");
36555 }
36556
36557 #[test]
36558 fn test_select_where() {
36559 let result = roundtrip("SELECT * FROM t WHERE x = 1");
36560 assert_eq!(result, "SELECT * FROM t WHERE x = 1");
36561 }
36562
36563 #[test]
36564 fn test_select_join() {
36565 let result = roundtrip("SELECT * FROM a JOIN b ON a.id = b.id");
36566 assert_eq!(result, "SELECT * FROM a JOIN b ON a.id = b.id");
36567 }
36568
36569 #[test]
36570 fn test_insert() {
36571 let result = roundtrip("INSERT INTO t (a, b) VALUES (1, 2)");
36572 assert_eq!(result, "INSERT INTO t (a, b) VALUES (1, 2)");
36573 }
36574
36575 #[test]
36576 fn test_pretty_print() {
36577 let ast = Parser::parse_sql("SELECT a, b FROM t WHERE x = 1").unwrap();
36578 let result = Generator::pretty_sql(&ast[0]).unwrap();
36579 assert!(result.contains('\n'));
36580 }
36581
36582 #[test]
36583 fn test_window_function() {
36584 let result = roundtrip("SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)");
36585 assert_eq!(
36586 result,
36587 "SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)"
36588 );
36589 }
36590
36591 #[test]
36592 fn test_window_function_with_frame() {
36593 let result = roundtrip("SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
36594 assert_eq!(result, "SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
36595 }
36596
36597 #[test]
36598 fn test_aggregate_with_filter() {
36599 let result = roundtrip("SELECT COUNT(*) FILTER (WHERE status = 1) FROM orders");
36600 assert_eq!(
36601 result,
36602 "SELECT COUNT(*) FILTER(WHERE status = 1) FROM orders"
36603 );
36604 }
36605
36606 #[test]
36607 fn test_subscript() {
36608 let result = roundtrip("SELECT arr[0]");
36609 assert_eq!(result, "SELECT arr[0]");
36610 }
36611
36612 #[test]
36614 fn test_create_table() {
36615 let result = roundtrip("CREATE TABLE users (id INT, name VARCHAR(100))");
36616 assert_eq!(result, "CREATE TABLE users (id INT, name VARCHAR(100))");
36617 }
36618
36619 #[test]
36620 fn test_create_table_with_constraints() {
36621 let result = roundtrip(
36622 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)",
36623 );
36624 assert_eq!(
36625 result,
36626 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)"
36627 );
36628 }
36629
36630 #[test]
36631 fn test_create_table_if_not_exists() {
36632 let result = roundtrip("CREATE TABLE IF NOT EXISTS t (id INT)");
36633 assert_eq!(result, "CREATE TABLE IF NOT EXISTS t (id INT)");
36634 }
36635
36636 #[test]
36637 fn test_drop_table() {
36638 let result = roundtrip("DROP TABLE users");
36639 assert_eq!(result, "DROP TABLE users");
36640 }
36641
36642 #[test]
36643 fn test_drop_table_if_exists_cascade() {
36644 let result = roundtrip("DROP TABLE IF EXISTS users CASCADE");
36645 assert_eq!(result, "DROP TABLE IF EXISTS users CASCADE");
36646 }
36647
36648 #[test]
36649 fn test_alter_table_add_column() {
36650 let result = roundtrip("ALTER TABLE users ADD COLUMN email VARCHAR(255)");
36651 assert_eq!(result, "ALTER TABLE users ADD COLUMN email VARCHAR(255)");
36652 }
36653
36654 #[test]
36655 fn test_alter_table_drop_column() {
36656 let result = roundtrip("ALTER TABLE users DROP COLUMN email");
36657 assert_eq!(result, "ALTER TABLE users DROP COLUMN email");
36658 }
36659
36660 #[test]
36661 fn test_create_index() {
36662 let result = roundtrip("CREATE INDEX idx_name ON users(name)");
36663 assert_eq!(result, "CREATE INDEX idx_name ON users(name)");
36664 }
36665
36666 #[test]
36667 fn test_create_unique_index() {
36668 let result = roundtrip("CREATE UNIQUE INDEX idx_email ON users(email)");
36669 assert_eq!(result, "CREATE UNIQUE INDEX idx_email ON users(email)");
36670 }
36671
36672 #[test]
36673 fn test_drop_index() {
36674 let result = roundtrip("DROP INDEX idx_name");
36675 assert_eq!(result, "DROP INDEX idx_name");
36676 }
36677
36678 #[test]
36679 fn test_create_view() {
36680 let result = roundtrip("CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1");
36681 assert_eq!(
36682 result,
36683 "CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1"
36684 );
36685 }
36686
36687 #[test]
36688 fn test_drop_view() {
36689 let result = roundtrip("DROP VIEW active_users");
36690 assert_eq!(result, "DROP VIEW active_users");
36691 }
36692
36693 #[test]
36694 fn test_truncate() {
36695 let result = roundtrip("TRUNCATE TABLE users");
36696 assert_eq!(result, "TRUNCATE TABLE users");
36697 }
36698
36699 #[test]
36700 fn test_string_literal_escaping_default() {
36701 let result = roundtrip("SELECT 'hello'");
36703 assert_eq!(result, "SELECT 'hello'");
36704
36705 let result = roundtrip("SELECT 'it''s a test'");
36707 assert_eq!(result, "SELECT 'it''s a test'");
36708 }
36709
36710 #[test]
36711 fn test_not_in_style_prefix_default_generic() {
36712 let result = roundtrip("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')");
36713 assert_eq!(
36714 result,
36715 "SELECT id FROM users WHERE NOT status IN ('deleted', 'banned')"
36716 );
36717 }
36718
36719 #[test]
36720 fn test_not_in_style_infix_generic_override() {
36721 let ast =
36722 Parser::parse_sql("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')")
36723 .unwrap();
36724 let config = GeneratorConfig {
36725 not_in_style: NotInStyle::Infix,
36726 ..Default::default()
36727 };
36728 let mut gen = Generator::with_config(config);
36729 let result = gen.generate(&ast[0]).unwrap();
36730 assert_eq!(
36731 result,
36732 "SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')"
36733 );
36734 }
36735
36736 #[test]
36737 fn test_string_literal_escaping_mysql() {
36738 use crate::dialects::DialectType;
36739
36740 let config = GeneratorConfig {
36741 dialect: Some(DialectType::MySQL),
36742 ..Default::default()
36743 };
36744
36745 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
36746 let mut gen = Generator::with_config(config.clone());
36747 let result = gen.generate(&ast[0]).unwrap();
36748 assert_eq!(result, "SELECT 'hello'");
36749
36750 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
36752 let mut gen = Generator::with_config(config.clone());
36753 let result = gen.generate(&ast[0]).unwrap();
36754 assert_eq!(result, "SELECT 'it''s'");
36755 }
36756
36757 #[test]
36758 fn test_string_literal_escaping_postgres() {
36759 use crate::dialects::DialectType;
36760
36761 let config = GeneratorConfig {
36762 dialect: Some(DialectType::PostgreSQL),
36763 ..Default::default()
36764 };
36765
36766 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
36767 let mut gen = Generator::with_config(config.clone());
36768 let result = gen.generate(&ast[0]).unwrap();
36769 assert_eq!(result, "SELECT 'hello'");
36770
36771 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
36773 let mut gen = Generator::with_config(config.clone());
36774 let result = gen.generate(&ast[0]).unwrap();
36775 assert_eq!(result, "SELECT 'it''s'");
36776 }
36777
36778 #[test]
36779 fn test_string_literal_escaping_bigquery() {
36780 use crate::dialects::DialectType;
36781
36782 let config = GeneratorConfig {
36783 dialect: Some(DialectType::BigQuery),
36784 ..Default::default()
36785 };
36786
36787 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
36788 let mut gen = Generator::with_config(config.clone());
36789 let result = gen.generate(&ast[0]).unwrap();
36790 assert_eq!(result, "SELECT 'hello'");
36791
36792 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
36794 let mut gen = Generator::with_config(config.clone());
36795 let result = gen.generate(&ast[0]).unwrap();
36796 assert_eq!(result, "SELECT 'it\\'s'");
36797 }
36798
36799 #[test]
36800 fn test_generate_deep_and_chain_without_stack_growth() {
36801 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
36802 Expression::column("c0"),
36803 Expression::number(0),
36804 )));
36805
36806 for i in 1..2500 {
36807 let predicate = Expression::Eq(Box::new(BinaryOp::new(
36808 Expression::column(format!("c{i}")),
36809 Expression::number(i as i64),
36810 )));
36811 expr = Expression::And(Box::new(BinaryOp::new(expr, predicate)));
36812 }
36813
36814 let sql = Generator::sql(&expr).expect("deep AND chain should generate");
36815 assert!(sql.contains("c2499 = 2499"), "{}", sql);
36816 }
36817
36818 #[test]
36819 fn test_generate_deep_or_chain_without_stack_growth() {
36820 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
36821 Expression::column("c0"),
36822 Expression::number(0),
36823 )));
36824
36825 for i in 1..2500 {
36826 let predicate = Expression::Eq(Box::new(BinaryOp::new(
36827 Expression::column(format!("c{i}")),
36828 Expression::number(i as i64),
36829 )));
36830 expr = Expression::Or(Box::new(BinaryOp::new(expr, predicate)));
36831 }
36832
36833 let sql = Generator::sql(&expr).expect("deep OR chain should generate");
36834 assert!(sql.contains("c2499 = 2499"), "{}", sql);
36835 }
36836}