1use crate::error::Result;
14use crate::expressions::*;
15use crate::DialectType;
16
17pub struct Generator {
42 config: GeneratorConfig,
43 output: String,
44 indent_level: usize,
45 athena_hive_context: bool,
48 sqlite_inline_pk_columns: std::collections::HashSet<String>,
50 merge_strip_qualifiers: Vec<String>,
52 clickhouse_nullable_depth: i32,
57}
58
59#[derive(Debug, Clone, Copy, PartialEq, Default)]
65pub enum NormalizeFunctions {
66 #[default]
68 Upper,
69 Lower,
71 None,
73}
74
75#[derive(Debug, Clone, Copy, PartialEq, Default)]
77pub enum LimitFetchStyle {
78 #[default]
80 Limit,
81 Top,
83 FetchFirst,
85}
86
87#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
89pub enum NotInStyle {
90 #[default]
92 Prefix,
93 Infix,
95}
96
97#[derive(Debug, Clone, Copy, PartialEq, Eq)]
98enum ConnectorOperator {
99 And,
100 Or,
101}
102
103impl ConnectorOperator {
104 fn keyword(self) -> &'static str {
105 match self {
106 Self::And => "AND",
107 Self::Or => "OR",
108 }
109 }
110}
111
112#[derive(Debug, Clone, Copy, PartialEq)]
114pub struct IdentifierQuoteStyle {
115 pub start: char,
117 pub end: char,
119}
120
121impl Default for IdentifierQuoteStyle {
122 fn default() -> Self {
123 Self {
124 start: '"',
125 end: '"',
126 }
127 }
128}
129
130impl IdentifierQuoteStyle {
131 pub const DOUBLE_QUOTE: Self = Self {
133 start: '"',
134 end: '"',
135 };
136 pub const BACKTICK: Self = Self {
138 start: '`',
139 end: '`',
140 };
141 pub const BRACKET: Self = Self {
143 start: '[',
144 end: ']',
145 };
146}
147
148#[derive(Debug, Clone)]
170pub struct GeneratorConfig {
171 pub pretty: bool,
174 pub indent: String,
176 pub max_text_width: usize,
178 pub identifier_quote: char,
180 pub identifier_quote_style: IdentifierQuoteStyle,
182 pub uppercase_keywords: bool,
184 pub normalize_identifiers: bool,
186 pub dialect: Option<crate::dialects::DialectType>,
188 pub source_dialect: Option<crate::dialects::DialectType>,
190 pub normalize_functions: NormalizeFunctions,
192 pub string_escape: char,
194 pub case_sensitive_identifiers: bool,
196 pub identifiers_can_start_with_digit: bool,
198 pub always_quote_identifiers: bool,
201 pub not_in_style: NotInStyle,
203
204 pub null_ordering_supported: bool,
208 pub ignore_nulls_in_func: bool,
211 pub nvl2_supported: bool,
213
214 pub limit_fetch_style: LimitFetchStyle,
217 pub limit_is_top: bool,
219 pub limit_only_literals: bool,
221
222 pub single_string_interval: bool,
225 pub interval_allows_plural_form: bool,
227
228 pub cte_recursive_keyword_required: bool,
231
232 pub values_as_table: bool,
235 pub wrap_derived_values: bool,
237
238 pub tablesample_seed_keyword: &'static str,
241 pub tablesample_requires_parens: bool,
243 pub tablesample_size_is_rows: bool,
245 pub tablesample_keywords: &'static str,
247 pub tablesample_with_method: bool,
249 pub alias_post_tablesample: bool,
251
252 pub aggregate_filter_supported: bool,
255 pub multi_arg_distinct: bool,
257 pub quantified_no_paren_space: bool,
259 pub supports_median: bool,
261
262 pub supports_select_into: bool,
265 pub locking_reads_supported: bool,
267
268 pub rename_table_with_db: bool,
271 pub semi_anti_join_with_side: bool,
273 pub supports_table_alias_columns: bool,
275 pub join_hints: bool,
277 pub table_hints: bool,
279 pub query_hints: bool,
281 pub query_hint_sep: &'static str,
283 pub supports_column_join_marks: bool,
285
286 pub index_using_no_space: bool,
290 pub supports_unlogged_tables: bool,
292 pub supports_create_table_like: bool,
294 pub like_property_inside_schema: bool,
296 pub alter_table_include_column_keyword: bool,
298 pub supports_table_copy: bool,
300 pub alter_set_type: &'static str,
302 pub alter_set_wrapped: bool,
304
305 pub tz_to_with_time_zone: bool,
308 pub supports_convert_timezone: bool,
310
311 pub json_type_required_for_extraction: bool,
314 pub json_path_bracketed_key_supported: bool,
316 pub json_path_single_quote_escape: bool,
318 pub quote_json_path: bool,
320 pub json_key_value_pair_sep: &'static str,
322
323 pub copy_params_are_wrapped: bool,
326 pub copy_params_eq_required: bool,
328 pub copy_has_into_keyword: bool,
330
331 pub supports_window_exclude: bool,
334 pub unnest_with_ordinality: bool,
336 pub lowercase_window_frame_keywords: bool,
339 pub normalize_window_frame_between: bool,
342
343 pub array_concat_is_var_len: bool,
346 pub array_size_dim_required: Option<bool>,
349 pub can_implement_array_any: bool,
351 pub array_size_name: &'static str,
353
354 pub supports_between_flags: bool,
357
358 pub is_bool_allowed: bool,
361 pub ensure_bools: bool,
363
364 pub extract_allows_quotes: bool,
367 pub normalize_extract_date_parts: bool,
369
370 pub try_supported: bool,
373 pub supports_uescape: bool,
375 pub supports_to_number: bool,
377 pub supports_single_arg_concat: bool,
379 pub last_day_supports_date_part: bool,
381 pub supports_exploding_projections: bool,
383 pub supports_unix_seconds: bool,
385 pub supports_like_quantifiers: bool,
387 pub supports_decode_case: bool,
389 pub set_op_modifiers: bool,
391 pub update_statement_supports_from: bool,
393
394 pub collate_is_func: bool,
397
398 pub duplicate_key_update_with_set: bool,
401 pub insert_overwrite: &'static str,
403
404 pub returning_end: bool,
407
408 pub matched_by_source: bool,
411
412 pub create_function_return_as: bool,
415 pub parameter_default_equals: bool,
417
418 pub computed_column_with_type: bool,
421
422 pub unpivot_aliases_are_identifiers: bool,
425
426 pub star_except: &'static str,
429
430 pub hex_func: &'static str,
433
434 pub with_properties_prefix: &'static str,
437
438 pub pad_fill_pattern_is_required: bool,
441
442 pub index_on: &'static str,
445
446 pub groupings_sep: &'static str,
449
450 pub struct_delimiter: (&'static str, &'static str),
453 pub struct_curly_brace_notation: bool,
455 pub array_bracket_only: bool,
457 pub struct_field_sep: &'static str,
459
460 pub except_intersect_support_all_clause: bool,
463
464 pub parameter_token: &'static str,
467 pub named_placeholder_token: &'static str,
469
470 pub data_type_specifiers_allowed: bool,
473
474 pub schema_comment_with_eq: bool,
478}
479
480impl Default for GeneratorConfig {
481 fn default() -> Self {
482 Self {
483 pretty: false,
485 indent: " ".to_string(),
486 max_text_width: 80,
487 identifier_quote: '"',
488 identifier_quote_style: IdentifierQuoteStyle::DOUBLE_QUOTE,
489 uppercase_keywords: true,
490 normalize_identifiers: false,
491 dialect: None,
492 source_dialect: None,
493 normalize_functions: NormalizeFunctions::Upper,
494 string_escape: '\'',
495 case_sensitive_identifiers: false,
496 identifiers_can_start_with_digit: false,
497 always_quote_identifiers: false,
498 not_in_style: NotInStyle::Prefix,
499
500 null_ordering_supported: true,
502 ignore_nulls_in_func: false,
503 nvl2_supported: true,
504
505 limit_fetch_style: LimitFetchStyle::Limit,
507 limit_is_top: false,
508 limit_only_literals: false,
509
510 single_string_interval: false,
512 interval_allows_plural_form: true,
513
514 cte_recursive_keyword_required: true,
516
517 values_as_table: true,
519 wrap_derived_values: true,
520
521 tablesample_seed_keyword: "SEED",
523 tablesample_requires_parens: true,
524 tablesample_size_is_rows: true,
525 tablesample_keywords: "TABLESAMPLE",
526 tablesample_with_method: true,
527 alias_post_tablesample: false,
528
529 aggregate_filter_supported: true,
531 multi_arg_distinct: true,
532 quantified_no_paren_space: false,
533 supports_median: true,
534
535 supports_select_into: false,
537 locking_reads_supported: true,
538
539 rename_table_with_db: true,
541 semi_anti_join_with_side: true,
542 supports_table_alias_columns: true,
543 join_hints: true,
544 table_hints: true,
545 query_hints: true,
546 query_hint_sep: ", ",
547 supports_column_join_marks: false,
548
549 index_using_no_space: false,
551 supports_unlogged_tables: false,
552 supports_create_table_like: true,
553 like_property_inside_schema: false,
554 alter_table_include_column_keyword: true,
555 supports_table_copy: true,
556 alter_set_type: "SET DATA TYPE",
557 alter_set_wrapped: false,
558
559 tz_to_with_time_zone: false,
561 supports_convert_timezone: false,
562
563 json_type_required_for_extraction: false,
565 json_path_bracketed_key_supported: true,
566 json_path_single_quote_escape: false,
567 quote_json_path: true,
568 json_key_value_pair_sep: ":",
569
570 copy_params_are_wrapped: true,
572 copy_params_eq_required: false,
573 copy_has_into_keyword: true,
574
575 supports_window_exclude: false,
577 unnest_with_ordinality: true,
578 lowercase_window_frame_keywords: false,
579 normalize_window_frame_between: false,
580
581 array_concat_is_var_len: true,
583 array_size_dim_required: None,
584 can_implement_array_any: false,
585 array_size_name: "ARRAY_LENGTH",
586
587 supports_between_flags: false,
589
590 is_bool_allowed: true,
592 ensure_bools: false,
593
594 extract_allows_quotes: true,
596 normalize_extract_date_parts: false,
597
598 try_supported: true,
600 supports_uescape: true,
601 supports_to_number: true,
602 supports_single_arg_concat: true,
603 last_day_supports_date_part: true,
604 supports_exploding_projections: true,
605 supports_unix_seconds: false,
606 supports_like_quantifiers: true,
607 supports_decode_case: true,
608 set_op_modifiers: true,
609 update_statement_supports_from: true,
610
611 collate_is_func: false,
613
614 duplicate_key_update_with_set: true,
616 insert_overwrite: " OVERWRITE TABLE",
617
618 returning_end: true,
620
621 matched_by_source: true,
623
624 create_function_return_as: true,
626 parameter_default_equals: false,
627
628 computed_column_with_type: true,
630
631 unpivot_aliases_are_identifiers: true,
633
634 star_except: "EXCEPT",
636
637 hex_func: "HEX",
639
640 with_properties_prefix: "WITH",
642
643 pad_fill_pattern_is_required: false,
645
646 index_on: "ON",
648
649 groupings_sep: ",",
651
652 struct_delimiter: ("<", ">"),
654 struct_curly_brace_notation: false,
655 array_bracket_only: false,
656 struct_field_sep: " ",
657
658 except_intersect_support_all_clause: true,
660
661 parameter_token: "@",
663 named_placeholder_token: ":",
664
665 data_type_specifiers_allowed: false,
667
668 schema_comment_with_eq: true,
670 }
671 }
672}
673
674mod reserved_keywords {
677 use std::collections::HashSet;
678 use std::sync::LazyLock;
679
680 pub static SQL_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
682 [
683 "all",
684 "alter",
685 "and",
686 "any",
687 "array",
688 "as",
689 "asc",
690 "at",
691 "authorization",
692 "begin",
693 "between",
694 "both",
695 "by",
696 "case",
697 "cast",
698 "check",
699 "collate",
700 "column",
701 "commit",
702 "constraint",
703 "create",
704 "cross",
705 "cube",
706 "current",
707 "current_date",
708 "current_time",
709 "current_timestamp",
710 "current_user",
711 "default",
712 "delete",
713 "desc",
714 "distinct",
715 "drop",
716 "else",
717 "end",
718 "escape",
719 "except",
720 "execute",
721 "exists",
722 "external",
723 "false",
724 "fetch",
725 "filter",
726 "for",
727 "foreign",
728 "from",
729 "full",
730 "function",
731 "grant",
732 "group",
733 "grouping",
734 "having",
735 "if",
736 "in",
737 "index",
738 "inner",
739 "insert",
740 "intersect",
741 "interval",
742 "into",
743 "is",
744 "join",
745 "key",
746 "leading",
747 "left",
748 "like",
749 "limit",
750 "local",
751 "localtime",
752 "localtimestamp",
753 "match",
754 "merge",
755 "natural",
756 "no",
757 "not",
758 "null",
759 "of",
760 "offset",
761 "on",
762 "only",
763 "or",
764 "order",
765 "outer",
766 "over",
767 "partition",
768 "primary",
769 "procedure",
770 "range",
771 "references",
772 "right",
773 "rollback",
774 "rollup",
775 "row",
776 "rows",
777 "select",
778 "session_user",
779 "set",
780 "some",
781 "table",
782 "tablesample",
783 "then",
784 "to",
785 "trailing",
786 "true",
787 "truncate",
788 "union",
789 "unique",
790 "unknown",
791 "update",
792 "user",
793 "using",
794 "values",
795 "view",
796 "when",
797 "where",
798 "window",
799 "with",
800 ]
801 .into_iter()
802 .collect()
803 });
804
805 pub static BIGQUERY_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
808 let mut set = SQL_RESERVED.clone();
809 set.extend([
810 "assert_rows_modified",
811 "at",
812 "contains",
813 "cube",
814 "current",
815 "define",
816 "enum",
817 "escape",
818 "exclude",
819 "following",
820 "for",
821 "groups",
822 "hash",
823 "ignore",
824 "lateral",
825 "lookup",
826 "new",
827 "no",
828 "nulls",
829 "of",
830 "over",
831 "preceding",
832 "proto",
833 "qualify",
834 "recursive",
835 "respect",
836 "struct",
837 "tablesample",
838 "treat",
839 "unbounded",
840 "unnest",
841 "window",
842 "within",
843 ]);
844 set.remove("grant");
846 set.remove("key");
847 set.remove("index");
848 set.remove("values");
849 set.remove("table");
850 set
851 });
852
853 pub static MYSQL_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
855 let mut set = SQL_RESERVED.clone();
856 set.extend([
857 "accessible",
858 "add",
859 "analyze",
860 "asensitive",
861 "before",
862 "bigint",
863 "binary",
864 "blob",
865 "call",
866 "cascade",
867 "change",
868 "char",
869 "character",
870 "condition",
871 "continue",
872 "convert",
873 "current_date",
874 "current_time",
875 "current_timestamp",
876 "current_user",
877 "cursor",
878 "database",
879 "databases",
880 "day_hour",
881 "day_microsecond",
882 "day_minute",
883 "day_second",
884 "dec",
885 "decimal",
886 "declare",
887 "delayed",
888 "describe",
889 "deterministic",
890 "distinctrow",
891 "div",
892 "double",
893 "dual",
894 "each",
895 "elseif",
896 "enclosed",
897 "escaped",
898 "exit",
899 "explain",
900 "float",
901 "float4",
902 "float8",
903 "force",
904 "get",
905 "high_priority",
906 "hour_microsecond",
907 "hour_minute",
908 "hour_second",
909 "ignore",
910 "infile",
911 "inout",
912 "insensitive",
913 "int",
914 "int1",
915 "int2",
916 "int3",
917 "int4",
918 "int8",
919 "integer",
920 "iterate",
921 "keys",
922 "kill",
923 "leave",
924 "linear",
925 "lines",
926 "load",
927 "lock",
928 "long",
929 "longblob",
930 "longtext",
931 "loop",
932 "low_priority",
933 "master_ssl_verify_server_cert",
934 "maxvalue",
935 "mediumblob",
936 "mediumint",
937 "mediumtext",
938 "middleint",
939 "minute_microsecond",
940 "minute_second",
941 "mod",
942 "modifies",
943 "no_write_to_binlog",
944 "numeric",
945 "optimize",
946 "option",
947 "optionally",
948 "out",
949 "outfile",
950 "precision",
951 "purge",
952 "read",
953 "reads",
954 "real",
955 "regexp",
956 "release",
957 "rename",
958 "repeat",
959 "replace",
960 "require",
961 "resignal",
962 "restrict",
963 "return",
964 "revoke",
965 "rlike",
966 "schema",
967 "schemas",
968 "second_microsecond",
969 "sensitive",
970 "separator",
971 "show",
972 "signal",
973 "smallint",
974 "spatial",
975 "specific",
976 "sql",
977 "sql_big_result",
978 "sql_calc_found_rows",
979 "sql_small_result",
980 "sqlexception",
981 "sqlstate",
982 "sqlwarning",
983 "ssl",
984 "starting",
985 "straight_join",
986 "terminated",
987 "text",
988 "tinyblob",
989 "tinyint",
990 "tinytext",
991 "trigger",
992 "undo",
993 "unlock",
994 "unsigned",
995 "usage",
996 "utc_date",
997 "utc_time",
998 "utc_timestamp",
999 "varbinary",
1000 "varchar",
1001 "varcharacter",
1002 "varying",
1003 "while",
1004 "write",
1005 "xor",
1006 "year_month",
1007 "zerofill",
1008 ]);
1009 set.remove("table");
1010 set
1011 });
1012
1013 pub static DORIS_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1016 let mut set = MYSQL_RESERVED.clone();
1017 set.extend([
1018 "aggregate",
1019 "anti",
1020 "array",
1021 "backend",
1022 "backup",
1023 "begin",
1024 "bitmap",
1025 "boolean",
1026 "broker",
1027 "buckets",
1028 "cached",
1029 "cancel",
1030 "cast",
1031 "catalog",
1032 "charset",
1033 "cluster",
1034 "collation",
1035 "columns",
1036 "comment",
1037 "commit",
1038 "config",
1039 "connection",
1040 "count",
1041 "current",
1042 "data",
1043 "date",
1044 "datetime",
1045 "day",
1046 "deferred",
1047 "distributed",
1048 "dynamic",
1049 "enable",
1050 "end",
1051 "events",
1052 "export",
1053 "external",
1054 "fields",
1055 "first",
1056 "follower",
1057 "format",
1058 "free",
1059 "frontend",
1060 "full",
1061 "functions",
1062 "global",
1063 "grants",
1064 "hash",
1065 "help",
1066 "hour",
1067 "install",
1068 "intermediate",
1069 "json",
1070 "label",
1071 "last",
1072 "less",
1073 "level",
1074 "link",
1075 "local",
1076 "location",
1077 "max",
1078 "merge",
1079 "min",
1080 "minute",
1081 "modify",
1082 "month",
1083 "name",
1084 "names",
1085 "negative",
1086 "nulls",
1087 "observer",
1088 "offset",
1089 "only",
1090 "open",
1091 "overwrite",
1092 "password",
1093 "path",
1094 "plan",
1095 "plugin",
1096 "plugins",
1097 "policy",
1098 "process",
1099 "properties",
1100 "property",
1101 "query",
1102 "quota",
1103 "recover",
1104 "refresh",
1105 "repair",
1106 "replica",
1107 "repository",
1108 "resource",
1109 "restore",
1110 "resume",
1111 "role",
1112 "roles",
1113 "rollback",
1114 "rollup",
1115 "routine",
1116 "sample",
1117 "second",
1118 "semi",
1119 "session",
1120 "signed",
1121 "snapshot",
1122 "start",
1123 "stats",
1124 "status",
1125 "stop",
1126 "stream",
1127 "string",
1128 "sum",
1129 "tables",
1130 "tablet",
1131 "temporary",
1132 "text",
1133 "timestamp",
1134 "transaction",
1135 "trash",
1136 "trim",
1137 "truncate",
1138 "type",
1139 "user",
1140 "value",
1141 "variables",
1142 "verbose",
1143 "version",
1144 "view",
1145 "warnings",
1146 "week",
1147 "work",
1148 "year",
1149 ]);
1150 set
1151 });
1152
1153 pub static POSTGRES_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1155 let mut set = SQL_RESERVED.clone();
1156 set.extend([
1157 "analyse",
1158 "analyze",
1159 "asymmetric",
1160 "binary",
1161 "collation",
1162 "concurrently",
1163 "current_catalog",
1164 "current_role",
1165 "current_schema",
1166 "deferrable",
1167 "do",
1168 "freeze",
1169 "ilike",
1170 "initially",
1171 "isnull",
1172 "lateral",
1173 "notnull",
1174 "placing",
1175 "returning",
1176 "similar",
1177 "symmetric",
1178 "variadic",
1179 "verbose",
1180 ]);
1181 set.remove("default");
1183 set.remove("interval");
1184 set.remove("match");
1185 set.remove("offset");
1186 set.remove("table");
1187 set
1188 });
1189
1190 pub static REDSHIFT_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1194 [
1195 "aes128",
1196 "aes256",
1197 "all",
1198 "allowoverwrite",
1199 "analyse",
1200 "analyze",
1201 "and",
1202 "any",
1203 "array",
1204 "as",
1205 "asc",
1206 "authorization",
1207 "az64",
1208 "backup",
1209 "between",
1210 "binary",
1211 "blanksasnull",
1212 "both",
1213 "bytedict",
1214 "bzip2",
1215 "case",
1216 "cast",
1217 "check",
1218 "collate",
1219 "column",
1220 "constraint",
1221 "create",
1222 "credentials",
1223 "cross",
1224 "current_date",
1225 "current_time",
1226 "current_timestamp",
1227 "current_user",
1228 "current_user_id",
1229 "default",
1230 "deferrable",
1231 "deflate",
1232 "defrag",
1233 "delta",
1234 "delta32k",
1235 "desc",
1236 "disable",
1237 "distinct",
1238 "do",
1239 "else",
1240 "emptyasnull",
1241 "enable",
1242 "encode",
1243 "encrypt",
1244 "encryption",
1245 "end",
1246 "except",
1247 "explicit",
1248 "false",
1249 "for",
1250 "foreign",
1251 "freeze",
1252 "from",
1253 "full",
1254 "globaldict256",
1255 "globaldict64k",
1256 "grant",
1257 "group",
1258 "gzip",
1259 "having",
1260 "identity",
1261 "ignore",
1262 "ilike",
1263 "in",
1264 "initially",
1265 "inner",
1266 "intersect",
1267 "interval",
1268 "into",
1269 "is",
1270 "isnull",
1271 "join",
1272 "leading",
1273 "left",
1274 "like",
1275 "limit",
1276 "localtime",
1277 "localtimestamp",
1278 "lun",
1279 "luns",
1280 "lzo",
1281 "lzop",
1282 "minus",
1283 "mostly16",
1284 "mostly32",
1285 "mostly8",
1286 "natural",
1287 "new",
1288 "not",
1289 "notnull",
1290 "null",
1291 "nulls",
1292 "off",
1293 "offline",
1294 "offset",
1295 "oid",
1296 "old",
1297 "on",
1298 "only",
1299 "open",
1300 "or",
1301 "order",
1302 "outer",
1303 "overlaps",
1304 "parallel",
1305 "partition",
1306 "percent",
1307 "permissions",
1308 "pivot",
1309 "placing",
1310 "primary",
1311 "raw",
1312 "readratio",
1313 "recover",
1314 "references",
1315 "rejectlog",
1316 "resort",
1317 "respect",
1318 "restore",
1319 "right",
1320 "select",
1321 "session_user",
1322 "similar",
1323 "snapshot",
1324 "some",
1325 "sysdate",
1326 "system",
1327 "table",
1328 "tag",
1329 "tdes",
1330 "text255",
1331 "text32k",
1332 "then",
1333 "timestamp",
1334 "to",
1335 "top",
1336 "trailing",
1337 "true",
1338 "truncatecolumns",
1339 "type",
1340 "union",
1341 "unique",
1342 "unnest",
1343 "unpivot",
1344 "user",
1345 "using",
1346 "verbose",
1347 "wallet",
1348 "when",
1349 "where",
1350 "with",
1351 "without",
1352 ]
1353 .into_iter()
1354 .collect()
1355 });
1356
1357 pub static DUCKDB_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1359 let mut set = POSTGRES_RESERVED.clone();
1360 set.extend([
1361 "anti",
1362 "asof",
1363 "columns",
1364 "describe",
1365 "groups",
1366 "macro",
1367 "pivot",
1368 "pivot_longer",
1369 "pivot_wider",
1370 "qualify",
1371 "replace",
1372 "respect",
1373 "semi",
1374 "show",
1375 "table",
1376 "unpivot",
1377 ]);
1378 set.remove("at");
1379 set.remove("key");
1380 set.remove("row");
1381 set
1382 });
1383
1384 pub static PRESTO_TRINO_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1386 let mut set = SQL_RESERVED.clone();
1387 set.extend([
1388 "alter",
1389 "and",
1390 "as",
1391 "between",
1392 "by",
1393 "case",
1394 "cast",
1395 "constraint",
1396 "create",
1397 "cross",
1398 "cube",
1399 "current_catalog",
1400 "current_date",
1401 "current_path",
1402 "current_role",
1403 "current_schema",
1404 "current_time",
1405 "current_timestamp",
1406 "current_user",
1407 "deallocate",
1408 "delete",
1409 "describe",
1410 "distinct",
1411 "drop",
1412 "else",
1413 "end",
1414 "escape",
1415 "except",
1416 "execute",
1417 "exists",
1418 "extract",
1419 "false",
1420 "for",
1421 "from",
1422 "full",
1423 "group",
1424 "grouping",
1425 "having",
1426 "in",
1427 "inner",
1428 "insert",
1429 "intersect",
1430 "into",
1431 "is",
1432 "join",
1433 "json_array",
1434 "json_exists",
1435 "json_object",
1436 "json_query",
1437 "json_table",
1438 "json_value",
1439 "left",
1440 "like",
1441 "listagg",
1442 "localtime",
1443 "localtimestamp",
1444 "natural",
1445 "normalize",
1446 "not",
1447 "null",
1448 "on",
1449 "or",
1450 "order",
1451 "outer",
1452 "prepare",
1453 "recursive",
1454 "right",
1455 "rollup",
1456 "select",
1457 "skip",
1458 "table",
1459 "then",
1460 "trim",
1461 "true",
1462 "uescape",
1463 "union",
1464 "unnest",
1465 "using",
1466 "values",
1467 "when",
1468 "where",
1469 "with",
1470 ]);
1471 set.remove("key");
1473 set
1474 });
1475
1476 pub static STARROCKS_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1479 [
1480 "add",
1481 "all",
1482 "alter",
1483 "analyze",
1484 "and",
1485 "array",
1486 "as",
1487 "asc",
1488 "between",
1489 "bigint",
1490 "bitmap",
1491 "both",
1492 "by",
1493 "case",
1494 "char",
1495 "character",
1496 "check",
1497 "collate",
1498 "column",
1499 "compaction",
1500 "convert",
1501 "create",
1502 "cross",
1503 "cube",
1504 "current_date",
1505 "current_role",
1506 "current_time",
1507 "current_timestamp",
1508 "current_user",
1509 "database",
1510 "databases",
1511 "decimal",
1512 "decimalv2",
1513 "decimal32",
1514 "decimal64",
1515 "decimal128",
1516 "default",
1517 "deferred",
1518 "delete",
1519 "dense_rank",
1520 "desc",
1521 "describe",
1522 "distinct",
1523 "double",
1524 "drop",
1525 "dual",
1526 "else",
1527 "except",
1528 "exists",
1529 "explain",
1530 "false",
1531 "first_value",
1532 "float",
1533 "for",
1534 "force",
1535 "from",
1536 "full",
1537 "function",
1538 "grant",
1539 "group",
1540 "grouping",
1541 "grouping_id",
1542 "groups",
1543 "having",
1544 "hll",
1545 "host",
1546 "if",
1547 "ignore",
1548 "immediate",
1549 "in",
1550 "index",
1551 "infile",
1552 "inner",
1553 "insert",
1554 "int",
1555 "integer",
1556 "intersect",
1557 "into",
1558 "is",
1559 "join",
1560 "json",
1561 "key",
1562 "keys",
1563 "kill",
1564 "lag",
1565 "largeint",
1566 "last_value",
1567 "lateral",
1568 "lead",
1569 "left",
1570 "like",
1571 "limit",
1572 "load",
1573 "localtime",
1574 "localtimestamp",
1575 "maxvalue",
1576 "minus",
1577 "mod",
1578 "not",
1579 "ntile",
1580 "null",
1581 "on",
1582 "or",
1583 "order",
1584 "outer",
1585 "outfile",
1586 "over",
1587 "partition",
1588 "percentile",
1589 "primary",
1590 "procedure",
1591 "qualify",
1592 "range",
1593 "rank",
1594 "read",
1595 "regexp",
1596 "release",
1597 "rename",
1598 "replace",
1599 "revoke",
1600 "right",
1601 "rlike",
1602 "row",
1603 "row_number",
1604 "rows",
1605 "schema",
1606 "schemas",
1607 "select",
1608 "set",
1609 "set_var",
1610 "show",
1611 "smallint",
1612 "system",
1613 "table",
1614 "terminated",
1615 "text",
1616 "then",
1617 "tinyint",
1618 "to",
1619 "true",
1620 "union",
1621 "unique",
1622 "unsigned",
1623 "update",
1624 "use",
1625 "using",
1626 "values",
1627 "varchar",
1628 "when",
1629 "where",
1630 "with",
1631 ]
1632 .into_iter()
1633 .collect()
1634 });
1635
1636 pub static SINGLESTORE_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1639 let mut set = MYSQL_RESERVED.clone();
1640 set.extend([
1641 "abs",
1644 "account",
1645 "acos",
1646 "adddate",
1647 "addtime",
1648 "admin",
1649 "aes_decrypt",
1650 "aes_encrypt",
1651 "aggregate",
1652 "aggregates",
1653 "aggregator",
1654 "anti_join",
1655 "any_value",
1656 "approx_count_distinct",
1657 "approx_percentile",
1658 "arrange",
1659 "arrangement",
1660 "asin",
1661 "atan",
1662 "atan2",
1663 "attach",
1664 "autostats",
1665 "avro",
1666 "background",
1667 "backup",
1668 "batch",
1669 "batches",
1670 "boot_strapping",
1671 "ceil",
1672 "ceiling",
1673 "coercibility",
1674 "columnar",
1675 "columnstore",
1676 "compile",
1677 "concurrent",
1678 "connection_id",
1679 "cos",
1680 "cot",
1681 "current_security_groups",
1682 "current_security_roles",
1683 "dayname",
1684 "dayofmonth",
1685 "dayofweek",
1686 "dayofyear",
1687 "degrees",
1688 "dot_product",
1689 "dump",
1690 "durability",
1691 "earliest",
1692 "echo",
1693 "election",
1694 "euclidean_distance",
1695 "exp",
1696 "extractor",
1697 "extractors",
1698 "floor",
1699 "foreground",
1700 "found_rows",
1701 "from_base64",
1702 "from_days",
1703 "from_unixtime",
1704 "fs",
1705 "fulltext",
1706 "gc",
1707 "gcs",
1708 "geography",
1709 "geography_area",
1710 "geography_contains",
1711 "geography_distance",
1712 "geography_intersects",
1713 "geography_latitude",
1714 "geography_length",
1715 "geography_longitude",
1716 "geographypoint",
1717 "geography_point",
1718 "geography_within_distance",
1719 "geometry",
1720 "geometry_area",
1721 "geometry_contains",
1722 "geometry_distance",
1723 "geometry_filter",
1724 "geometry_intersects",
1725 "geometry_length",
1726 "geometrypoint",
1727 "geometry_point",
1728 "geometry_within_distance",
1729 "geometry_x",
1730 "geometry_y",
1731 "greatest",
1732 "groups",
1733 "group_concat",
1734 "gzip",
1735 "hdfs",
1736 "hex",
1737 "highlight",
1738 "ifnull",
1739 "ilike",
1740 "inet_aton",
1741 "inet_ntoa",
1742 "inet6_aton",
1743 "inet6_ntoa",
1744 "initcap",
1745 "instr",
1746 "interpreter_mode",
1747 "isnull",
1748 "json",
1749 "json_agg",
1750 "json_array_contains_double",
1751 "json_array_contains_json",
1752 "json_array_contains_string",
1753 "json_delete_key",
1754 "json_extract_double",
1755 "json_extract_json",
1756 "json_extract_string",
1757 "json_extract_bigint",
1758 "json_get_type",
1759 "json_length",
1760 "json_set_double",
1761 "json_set_json",
1762 "json_set_string",
1763 "kafka",
1764 "lag",
1765 "last_day",
1766 "last_insert_id",
1767 "latest",
1768 "lcase",
1769 "lead",
1770 "leaf",
1771 "least",
1772 "leaves",
1773 "length",
1774 "license",
1775 "links",
1776 "llvm",
1777 "ln",
1778 "load",
1779 "locate",
1780 "log",
1781 "log10",
1782 "log2",
1783 "lpad",
1784 "lz4",
1785 "management",
1786 "match",
1787 "mbc",
1788 "md5",
1789 "median",
1790 "memsql",
1791 "memsql_deserialize",
1792 "memsql_serialize",
1793 "metadata",
1794 "microsecond",
1795 "minute",
1796 "model",
1797 "monthname",
1798 "months_between",
1799 "mpl",
1800 "namespace",
1801 "node",
1802 "noparam",
1803 "now",
1804 "nth_value",
1805 "ntile",
1806 "nullcols",
1807 "nullif",
1808 "object",
1809 "octet_length",
1810 "offsets",
1811 "online",
1812 "optimizer",
1813 "orphan",
1814 "parquet",
1815 "partitions",
1816 "pause",
1817 "percentile_cont",
1818 "percentile_disc",
1819 "periodic",
1820 "persisted",
1821 "pi",
1822 "pipeline",
1823 "pipelines",
1824 "plancache",
1825 "plugins",
1826 "pool",
1827 "pools",
1828 "pow",
1829 "power",
1830 "process",
1831 "processlist",
1832 "profile",
1833 "profiles",
1834 "quarter",
1835 "queries",
1836 "query",
1837 "radians",
1838 "rand",
1839 "record",
1840 "reduce",
1841 "redundancy",
1842 "regexp_match",
1843 "regexp_substr",
1844 "remote",
1845 "replication",
1846 "resource",
1847 "resource_pool",
1848 "restore",
1849 "retry",
1850 "role",
1851 "roles",
1852 "round",
1853 "rpad",
1854 "rtrim",
1855 "running",
1856 "s3",
1857 "scalar",
1858 "sec_to_time",
1859 "second",
1860 "security_lists_intersect",
1861 "semi_join",
1862 "sha",
1863 "sha1",
1864 "sha2",
1865 "shard",
1866 "sharded",
1867 "sharded_id",
1868 "sigmoid",
1869 "sign",
1870 "sin",
1871 "skip",
1872 "sleep",
1873 "snapshot",
1874 "soname",
1875 "sparse",
1876 "spatial_check_index",
1877 "split",
1878 "sqrt",
1879 "standalone",
1880 "std",
1881 "stddev",
1882 "stddev_pop",
1883 "stddev_samp",
1884 "stop",
1885 "str_to_date",
1886 "subdate",
1887 "substr",
1888 "substring_index",
1889 "success",
1890 "synchronize",
1891 "table_checksum",
1892 "tan",
1893 "task",
1894 "timediff",
1895 "time_bucket",
1896 "time_format",
1897 "time_to_sec",
1898 "timestampadd",
1899 "timestampdiff",
1900 "to_base64",
1901 "to_char",
1902 "to_date",
1903 "to_days",
1904 "to_json",
1905 "to_number",
1906 "to_seconds",
1907 "to_timestamp",
1908 "tracelogs",
1909 "transform",
1910 "trim",
1911 "trunc",
1912 "truncate",
1913 "ucase",
1914 "unhex",
1915 "unix_timestamp",
1916 "utc_date",
1917 "utc_time",
1918 "utc_timestamp",
1919 "vacuum",
1920 "variance",
1921 "var_pop",
1922 "var_samp",
1923 "vector_sub",
1924 "voting",
1925 "week",
1926 "weekday",
1927 "weekofyear",
1928 "workload",
1929 "year",
1930 ]);
1931 set.remove("all");
1933 set
1934 });
1935
1936 pub static SQLITE_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1940 [
1942 "abort",
1943 "action",
1944 "add",
1945 "after",
1946 "all",
1947 "alter",
1948 "always",
1949 "analyze",
1950 "and",
1951 "as",
1952 "asc",
1953 "attach",
1954 "autoincrement",
1955 "before",
1956 "begin",
1957 "between",
1958 "by",
1959 "cascade",
1960 "case",
1961 "cast",
1962 "check",
1963 "collate",
1964 "column",
1965 "commit",
1966 "conflict",
1967 "constraint",
1968 "create",
1969 "cross",
1970 "current",
1971 "current_date",
1972 "current_time",
1973 "current_timestamp",
1974 "database",
1975 "default",
1976 "deferrable",
1977 "deferred",
1978 "delete",
1979 "desc",
1980 "detach",
1981 "distinct",
1982 "do",
1983 "drop",
1984 "each",
1985 "else",
1986 "end",
1987 "escape",
1988 "except",
1989 "exclude",
1990 "exclusive",
1991 "exists",
1992 "explain",
1993 "fail",
1994 "filter",
1995 "first",
1996 "following",
1997 "for",
1998 "foreign",
1999 "from",
2000 "full",
2001 "generated",
2002 "glob",
2003 "group",
2004 "groups",
2005 "having",
2006 "if",
2007 "ignore",
2008 "immediate",
2009 "in",
2010 "index",
2011 "indexed",
2012 "initially",
2013 "inner",
2014 "insert",
2015 "instead",
2016 "intersect",
2017 "into",
2018 "is",
2019 "isnull",
2020 "join",
2021 "key",
2022 "last",
2023 "left",
2024 "like",
2025 "limit",
2026 "natural",
2027 "no",
2028 "not",
2029 "nothing",
2030 "notnull",
2031 "null",
2032 "nulls",
2033 "of",
2034 "offset",
2035 "on",
2036 "or",
2037 "order",
2038 "others",
2039 "outer",
2040 "partition",
2041 "plan",
2042 "pragma",
2043 "preceding",
2044 "primary",
2045 "query",
2046 "raise",
2047 "range",
2048 "recursive",
2049 "references",
2050 "regexp",
2051 "reindex",
2052 "release",
2053 "rename",
2054 "replace",
2055 "restrict",
2056 "returning",
2057 "right",
2058 "rollback",
2059 "row",
2060 "rows",
2061 "savepoint",
2062 "select",
2063 "set",
2064 "table",
2065 "temp",
2066 "temporary",
2067 "then",
2068 "ties",
2069 "to",
2070 "transaction",
2071 "trigger",
2072 "unbounded",
2073 "union",
2074 "unique",
2075 "update",
2076 "using",
2077 "vacuum",
2078 "values",
2079 "view",
2080 "virtual",
2081 "when",
2082 "where",
2083 "window",
2084 "with",
2085 "without",
2086 ]
2087 .into_iter()
2088 .collect()
2089 });
2090}
2091
2092impl Generator {
2093 pub fn new() -> Self {
2099 Self::with_config(GeneratorConfig::default())
2100 }
2101
2102 pub fn with_config(config: GeneratorConfig) -> Self {
2107 Self {
2108 config,
2109 output: String::new(),
2110 indent_level: 0,
2111 athena_hive_context: false,
2112 sqlite_inline_pk_columns: std::collections::HashSet::new(),
2113 merge_strip_qualifiers: Vec::new(),
2114 clickhouse_nullable_depth: 0,
2115 }
2116 }
2117
2118 fn add_column_aliases_to_query(expr: Expression) -> Expression {
2122 match expr {
2123 Expression::Select(mut select) => {
2124 select.expressions = select
2126 .expressions
2127 .into_iter()
2128 .map(|e| Self::add_alias_to_expression(e))
2129 .collect();
2130
2131 if let Some(ref mut from) = select.from {
2133 from.expressions = from
2134 .expressions
2135 .iter()
2136 .cloned()
2137 .map(|e| Self::add_column_aliases_to_query(e))
2138 .collect();
2139 }
2140
2141 Expression::Select(select)
2142 }
2143 Expression::Subquery(mut sq) => {
2144 sq.this = Self::add_column_aliases_to_query(sq.this);
2145 Expression::Subquery(sq)
2146 }
2147 Expression::Paren(mut p) => {
2148 p.this = Self::add_column_aliases_to_query(p.this);
2149 Expression::Paren(p)
2150 }
2151 other => other,
2153 }
2154 }
2155
2156 fn add_alias_to_expression(expr: Expression) -> Expression {
2159 use crate::expressions::Alias;
2160
2161 match &expr {
2162 Expression::Alias(_) => expr,
2164
2165 Expression::Column(col) => Expression::Alias(Box::new(Alias {
2167 this: expr.clone(),
2168 alias: col.name.clone(),
2169 column_aliases: Vec::new(),
2170 pre_alias_comments: Vec::new(),
2171 trailing_comments: Vec::new(),
2172 })),
2173
2174 Expression::Identifier(ident) => Expression::Alias(Box::new(Alias {
2176 this: expr.clone(),
2177 alias: ident.clone(),
2178 column_aliases: Vec::new(),
2179 pre_alias_comments: Vec::new(),
2180 trailing_comments: Vec::new(),
2181 })),
2182
2183 Expression::Subquery(sq) => {
2185 let processed = Self::add_column_aliases_to_query(Expression::Subquery(sq.clone()));
2186 if sq.alias.is_some() {
2188 processed
2189 } else {
2190 processed
2192 }
2193 }
2194
2195 Expression::Star(_) => expr,
2197
2198 _ => expr,
2201 }
2202 }
2203
2204 fn try_evaluate_constant(expr: &Expression) -> Option<i64> {
2208 match expr {
2209 Expression::Literal(Literal::Number(n)) => n.parse::<i64>().ok(),
2210 Expression::Add(op) => {
2211 let left = Self::try_evaluate_constant(&op.left)?;
2212 let right = Self::try_evaluate_constant(&op.right)?;
2213 Some(left + right)
2214 }
2215 Expression::Sub(op) => {
2216 let left = Self::try_evaluate_constant(&op.left)?;
2217 let right = Self::try_evaluate_constant(&op.right)?;
2218 Some(left - right)
2219 }
2220 Expression::Mul(op) => {
2221 let left = Self::try_evaluate_constant(&op.left)?;
2222 let right = Self::try_evaluate_constant(&op.right)?;
2223 Some(left * right)
2224 }
2225 Expression::Div(op) => {
2226 let left = Self::try_evaluate_constant(&op.left)?;
2227 let right = Self::try_evaluate_constant(&op.right)?;
2228 if right != 0 {
2229 Some(left / right)
2230 } else {
2231 None
2232 }
2233 }
2234 Expression::Paren(p) => Self::try_evaluate_constant(&p.this),
2235 _ => None,
2236 }
2237 }
2238
2239 fn is_reserved_keyword(&self, name: &str) -> bool {
2241 use crate::dialects::DialectType;
2242 let lower = name.to_lowercase();
2243 let lower_ref = lower.as_str();
2244
2245 match self.config.dialect {
2246 Some(DialectType::BigQuery) => reserved_keywords::BIGQUERY_RESERVED.contains(lower_ref),
2247 Some(DialectType::MySQL) | Some(DialectType::TiDB) => {
2248 reserved_keywords::MYSQL_RESERVED.contains(lower_ref)
2249 }
2250 Some(DialectType::Doris) => reserved_keywords::DORIS_RESERVED.contains(lower_ref),
2251 Some(DialectType::SingleStore) => {
2252 reserved_keywords::SINGLESTORE_RESERVED.contains(lower_ref)
2253 }
2254 Some(DialectType::StarRocks) => {
2255 reserved_keywords::STARROCKS_RESERVED.contains(lower_ref)
2256 }
2257 Some(DialectType::PostgreSQL)
2258 | Some(DialectType::CockroachDB)
2259 | Some(DialectType::Materialize)
2260 | Some(DialectType::RisingWave) => {
2261 reserved_keywords::POSTGRES_RESERVED.contains(lower_ref)
2262 }
2263 Some(DialectType::Redshift) => reserved_keywords::REDSHIFT_RESERVED.contains(lower_ref),
2264 Some(DialectType::Snowflake) => false,
2267 Some(DialectType::ClickHouse) => false,
2269 Some(DialectType::DuckDB) => reserved_keywords::DUCKDB_RESERVED.contains(lower_ref),
2270 Some(DialectType::Teradata) => false,
2272 Some(DialectType::TSQL)
2274 | Some(DialectType::Fabric)
2275 | Some(DialectType::Oracle)
2276 | Some(DialectType::Spark)
2277 | Some(DialectType::Databricks)
2278 | Some(DialectType::Hive)
2279 | Some(DialectType::Solr) => false,
2280 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
2281 reserved_keywords::PRESTO_TRINO_RESERVED.contains(lower_ref)
2282 }
2283 Some(DialectType::SQLite) => reserved_keywords::SQLITE_RESERVED.contains(lower_ref),
2284 Some(DialectType::Generic) | None => false,
2286 _ => reserved_keywords::SQL_RESERVED.contains(lower_ref),
2288 }
2289 }
2290
2291 fn normalize_func_name(&self, name: &str) -> String {
2293 match self.config.normalize_functions {
2294 NormalizeFunctions::Upper => name.to_uppercase(),
2295 NormalizeFunctions::Lower => name.to_lowercase(),
2296 NormalizeFunctions::None => name.to_string(),
2297 }
2298 }
2299
2300 pub fn generate(&mut self, expr: &Expression) -> Result<String> {
2309 self.output.clear();
2310 self.generate_expression(expr)?;
2311 Ok(std::mem::take(&mut self.output))
2312 }
2313
2314 pub fn sql(expr: &Expression) -> Result<String> {
2320 let mut gen = Generator::new();
2321 gen.generate(expr)
2322 }
2323
2324 pub fn pretty_sql(expr: &Expression) -> Result<String> {
2329 let config = GeneratorConfig {
2330 pretty: true,
2331 ..Default::default()
2332 };
2333 let mut gen = Generator::with_config(config);
2334 let mut sql = gen.generate(expr)?;
2335 if !sql.ends_with(';') {
2337 sql.push(';');
2338 }
2339 Ok(sql)
2340 }
2341
2342 fn generate_expression(&mut self, expr: &Expression) -> Result<()> {
2343 match expr {
2344 Expression::Select(select) => self.generate_select(select),
2345 Expression::Union(union) => self.generate_union(union),
2346 Expression::Intersect(intersect) => self.generate_intersect(intersect),
2347 Expression::Except(except) => self.generate_except(except),
2348 Expression::Insert(insert) => self.generate_insert(insert),
2349 Expression::Update(update) => self.generate_update(update),
2350 Expression::Delete(delete) => self.generate_delete(delete),
2351 Expression::Literal(lit) => self.generate_literal(lit),
2352 Expression::Boolean(b) => self.generate_boolean(b),
2353 Expression::Null(_) => {
2354 self.write_keyword("NULL");
2355 Ok(())
2356 }
2357 Expression::Identifier(id) => self.generate_identifier(id),
2358 Expression::Column(col) => self.generate_column(col),
2359 Expression::Pseudocolumn(pc) => self.generate_pseudocolumn(pc),
2360 Expression::Connect(c) => self.generate_connect_expr(c),
2361 Expression::Prior(p) => self.generate_prior(p),
2362 Expression::ConnectByRoot(cbr) => self.generate_connect_by_root(cbr),
2363 Expression::MatchRecognize(mr) => self.generate_match_recognize(mr),
2364 Expression::Table(table) => self.generate_table(table),
2365 Expression::StageReference(sr) => self.generate_stage_reference(sr),
2366 Expression::HistoricalData(hd) => self.generate_historical_data(hd),
2367 Expression::JoinedTable(jt) => self.generate_joined_table(jt),
2368 Expression::Star(star) => self.generate_star(star),
2369 Expression::BracedWildcard(expr) => self.generate_braced_wildcard(expr),
2370 Expression::Alias(alias) => self.generate_alias(alias),
2371 Expression::Cast(cast) => self.generate_cast(cast),
2372 Expression::Collation(coll) => self.generate_collation(coll),
2373 Expression::Case(case) => self.generate_case(case),
2374 Expression::Function(func) => self.generate_function(func),
2375 Expression::AggregateFunction(func) => self.generate_aggregate_function(func),
2376 Expression::WindowFunction(wf) => self.generate_window_function(wf),
2377 Expression::WithinGroup(wg) => self.generate_within_group(wg),
2378 Expression::Interval(interval) => self.generate_interval(interval),
2379
2380 Expression::ConcatWs(f) => self.generate_concat_ws(f),
2382 Expression::Substring(f) => self.generate_substring(f),
2383 Expression::Upper(f) => self.generate_unary_func("UPPER", f),
2384 Expression::Lower(f) => self.generate_unary_func("LOWER", f),
2385 Expression::Length(f) => self.generate_unary_func("LENGTH", f),
2386 Expression::Trim(f) => self.generate_trim(f),
2387 Expression::LTrim(f) => self.generate_simple_func("LTRIM", &f.this),
2388 Expression::RTrim(f) => self.generate_simple_func("RTRIM", &f.this),
2389 Expression::Replace(f) => self.generate_replace(f),
2390 Expression::Reverse(f) => self.generate_simple_func("REVERSE", &f.this),
2391 Expression::Left(f) => self.generate_left_right("LEFT", f),
2392 Expression::Right(f) => self.generate_left_right("RIGHT", f),
2393 Expression::Repeat(f) => self.generate_repeat(f),
2394 Expression::Lpad(f) => self.generate_pad("LPAD", f),
2395 Expression::Rpad(f) => self.generate_pad("RPAD", f),
2396 Expression::Split(f) => self.generate_split(f),
2397 Expression::RegexpLike(f) => self.generate_regexp_like(f),
2398 Expression::RegexpReplace(f) => self.generate_regexp_replace(f),
2399 Expression::RegexpExtract(f) => self.generate_regexp_extract(f),
2400 Expression::Overlay(f) => self.generate_overlay(f),
2401
2402 Expression::Abs(f) => self.generate_simple_func("ABS", &f.this),
2404 Expression::Round(f) => self.generate_round(f),
2405 Expression::Floor(f) => self.generate_floor(f),
2406 Expression::Ceil(f) => self.generate_ceil(f),
2407 Expression::Power(f) => self.generate_power(f),
2408 Expression::Sqrt(f) => self.generate_sqrt_cbrt(f, "SQRT", "|/"),
2409 Expression::Cbrt(f) => self.generate_sqrt_cbrt(f, "CBRT", "||/"),
2410 Expression::Ln(f) => self.generate_simple_func("LN", &f.this),
2411 Expression::Log(f) => self.generate_log(f),
2412 Expression::Exp(f) => self.generate_simple_func("EXP", &f.this),
2413 Expression::Sign(f) => self.generate_simple_func("SIGN", &f.this),
2414 Expression::Greatest(f) => self.generate_vararg_func("GREATEST", &f.expressions),
2415 Expression::Least(f) => self.generate_vararg_func("LEAST", &f.expressions),
2416
2417 Expression::CurrentDate(_) => {
2419 self.write_keyword("CURRENT_DATE");
2420 Ok(())
2421 }
2422 Expression::CurrentTime(f) => self.generate_current_time(f),
2423 Expression::CurrentTimestamp(f) => self.generate_current_timestamp(f),
2424 Expression::AtTimeZone(f) => self.generate_at_time_zone(f),
2425 Expression::DateAdd(f) => self.generate_date_add(f, "DATE_ADD"),
2426 Expression::DateSub(f) => self.generate_date_add(f, "DATE_SUB"),
2427 Expression::DateDiff(f) => self.generate_datediff(f),
2428 Expression::DateTrunc(f) => self.generate_date_trunc(f),
2429 Expression::Extract(f) => self.generate_extract(f),
2430 Expression::ToDate(f) => self.generate_to_date(f),
2431 Expression::ToTimestamp(f) => self.generate_to_timestamp(f),
2432
2433 Expression::Coalesce(f) => {
2435 let func_name = f.original_name.as_deref().unwrap_or("COALESCE");
2437 self.generate_vararg_func(func_name, &f.expressions)
2438 }
2439 Expression::NullIf(f) => self.generate_binary_func("NULLIF", &f.this, &f.expression),
2440 Expression::IfFunc(f) => self.generate_if_func(f),
2441 Expression::IfNull(f) => self.generate_ifnull(f),
2442 Expression::Nvl(f) => self.generate_nvl(f),
2443 Expression::Nvl2(f) => self.generate_nvl2(f),
2444
2445 Expression::TryCast(cast) => self.generate_try_cast(cast),
2447 Expression::SafeCast(cast) => self.generate_safe_cast(cast),
2448
2449 Expression::Count(f) => self.generate_count(f),
2451 Expression::Sum(f) => self.generate_agg_func("SUM", f),
2452 Expression::Avg(f) => self.generate_agg_func("AVG", f),
2453 Expression::Min(f) => self.generate_agg_func("MIN", f),
2454 Expression::Max(f) => self.generate_agg_func("MAX", f),
2455 Expression::GroupConcat(f) => self.generate_group_concat(f),
2456 Expression::StringAgg(f) => self.generate_string_agg(f),
2457 Expression::ListAgg(f) => self.generate_listagg(f),
2458 Expression::ArrayAgg(f) => {
2459 let override_name = f
2462 .name
2463 .as_ref()
2464 .filter(|n| n.to_uppercase() != "ARRAY_AGG")
2465 .map(|n| n.to_uppercase());
2466 match override_name {
2467 Some(name) => self.generate_agg_func(&name, f),
2468 None => self.generate_agg_func("ARRAY_AGG", f),
2469 }
2470 }
2471 Expression::ArrayConcatAgg(f) => self.generate_agg_func("ARRAY_CONCAT_AGG", f),
2472 Expression::CountIf(f) => self.generate_agg_func("COUNT_IF", f),
2473 Expression::SumIf(f) => self.generate_sum_if(f),
2474 Expression::Stddev(f) => self.generate_agg_func("STDDEV", f),
2475 Expression::StddevPop(f) => self.generate_agg_func("STDDEV_POP", f),
2476 Expression::StddevSamp(f) => self.generate_stddev_samp(f),
2477 Expression::Variance(f) => self.generate_agg_func("VARIANCE", f),
2478 Expression::VarPop(f) => {
2479 let name = if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
2480 "VARIANCE_POP"
2481 } else {
2482 "VAR_POP"
2483 };
2484 self.generate_agg_func(name, f)
2485 }
2486 Expression::VarSamp(f) => self.generate_agg_func("VAR_SAMP", f),
2487 Expression::Skewness(f) => {
2488 let name = match self.config.dialect {
2489 Some(DialectType::Snowflake) => "SKEW",
2490 _ => "SKEWNESS",
2491 };
2492 self.generate_agg_func(name, f)
2493 }
2494 Expression::Median(f) => self.generate_agg_func("MEDIAN", f),
2495 Expression::Mode(f) => self.generate_agg_func("MODE", f),
2496 Expression::First(f) => self.generate_agg_func("FIRST", f),
2497 Expression::Last(f) => self.generate_agg_func("LAST", f),
2498 Expression::AnyValue(f) => self.generate_agg_func("ANY_VALUE", f),
2499 Expression::ApproxDistinct(f) => {
2500 match self.config.dialect {
2501 Some(DialectType::Hive)
2502 | Some(DialectType::Spark)
2503 | Some(DialectType::Databricks)
2504 | Some(DialectType::BigQuery) => {
2505 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2507 }
2508 Some(DialectType::Redshift) => {
2509 self.write_keyword("APPROXIMATE COUNT");
2511 self.write("(");
2512 self.write_keyword("DISTINCT");
2513 self.write(" ");
2514 self.generate_expression(&f.this)?;
2515 self.write(")");
2516 Ok(())
2517 }
2518 _ => self.generate_agg_func("APPROX_DISTINCT", f),
2519 }
2520 }
2521 Expression::ApproxCountDistinct(f) => {
2522 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2523 }
2524 Expression::ApproxPercentile(f) => self.generate_approx_percentile(f),
2525 Expression::Percentile(f) => self.generate_percentile("PERCENTILE", f),
2526 Expression::LogicalAnd(f) => {
2527 let name = match self.config.dialect {
2528 Some(DialectType::Snowflake) => "BOOLAND_AGG",
2529 Some(DialectType::Spark)
2530 | Some(DialectType::Databricks)
2531 | Some(DialectType::PostgreSQL)
2532 | Some(DialectType::DuckDB)
2533 | Some(DialectType::Redshift) => "BOOL_AND",
2534 Some(DialectType::Oracle)
2535 | Some(DialectType::SQLite)
2536 | Some(DialectType::MySQL) => "MIN",
2537 _ => "BOOL_AND",
2538 };
2539 self.generate_agg_func(name, f)
2540 }
2541 Expression::LogicalOr(f) => {
2542 let name = match self.config.dialect {
2543 Some(DialectType::Snowflake) => "BOOLOR_AGG",
2544 Some(DialectType::Spark)
2545 | Some(DialectType::Databricks)
2546 | Some(DialectType::PostgreSQL)
2547 | Some(DialectType::DuckDB)
2548 | Some(DialectType::Redshift) => "BOOL_OR",
2549 Some(DialectType::Oracle)
2550 | Some(DialectType::SQLite)
2551 | Some(DialectType::MySQL) => "MAX",
2552 _ => "BOOL_OR",
2553 };
2554 self.generate_agg_func(name, f)
2555 }
2556
2557 Expression::RowNumber(_) => {
2559 if self.config.dialect == Some(DialectType::ClickHouse) {
2560 self.write("row_number");
2561 } else {
2562 self.write_keyword("ROW_NUMBER");
2563 }
2564 self.write("()");
2565 Ok(())
2566 }
2567 Expression::Rank(r) => {
2568 self.write_keyword("RANK");
2569 self.write("(");
2570 if !r.args.is_empty() {
2572 for (i, arg) in r.args.iter().enumerate() {
2573 if i > 0 {
2574 self.write(", ");
2575 }
2576 self.generate_expression(arg)?;
2577 }
2578 } else if let Some(order_by) = &r.order_by {
2579 self.write_keyword(" ORDER BY ");
2581 for (i, ob) in order_by.iter().enumerate() {
2582 if i > 0 {
2583 self.write(", ");
2584 }
2585 self.generate_ordered(ob)?;
2586 }
2587 }
2588 self.write(")");
2589 Ok(())
2590 }
2591 Expression::DenseRank(dr) => {
2592 self.write_keyword("DENSE_RANK");
2593 self.write("(");
2594 for (i, arg) in dr.args.iter().enumerate() {
2596 if i > 0 {
2597 self.write(", ");
2598 }
2599 self.generate_expression(arg)?;
2600 }
2601 self.write(")");
2602 Ok(())
2603 }
2604 Expression::NTile(f) => self.generate_ntile(f),
2605 Expression::Lead(f) => self.generate_lead_lag("LEAD", f),
2606 Expression::Lag(f) => self.generate_lead_lag("LAG", f),
2607 Expression::FirstValue(f) => self.generate_value_func("FIRST_VALUE", f),
2608 Expression::LastValue(f) => self.generate_value_func("LAST_VALUE", f),
2609 Expression::NthValue(f) => self.generate_nth_value(f),
2610 Expression::PercentRank(pr) => {
2611 self.write_keyword("PERCENT_RANK");
2612 self.write("(");
2613 if !pr.args.is_empty() {
2615 for (i, arg) in pr.args.iter().enumerate() {
2616 if i > 0 {
2617 self.write(", ");
2618 }
2619 self.generate_expression(arg)?;
2620 }
2621 } else if let Some(order_by) = &pr.order_by {
2622 self.write_keyword(" ORDER BY ");
2624 for (i, ob) in order_by.iter().enumerate() {
2625 if i > 0 {
2626 self.write(", ");
2627 }
2628 self.generate_ordered(ob)?;
2629 }
2630 }
2631 self.write(")");
2632 Ok(())
2633 }
2634 Expression::CumeDist(cd) => {
2635 self.write_keyword("CUME_DIST");
2636 self.write("(");
2637 if !cd.args.is_empty() {
2639 for (i, arg) in cd.args.iter().enumerate() {
2640 if i > 0 {
2641 self.write(", ");
2642 }
2643 self.generate_expression(arg)?;
2644 }
2645 } else if let Some(order_by) = &cd.order_by {
2646 self.write_keyword(" ORDER BY ");
2648 for (i, ob) in order_by.iter().enumerate() {
2649 if i > 0 {
2650 self.write(", ");
2651 }
2652 self.generate_ordered(ob)?;
2653 }
2654 }
2655 self.write(")");
2656 Ok(())
2657 }
2658 Expression::PercentileCont(f) => self.generate_percentile("PERCENTILE_CONT", f),
2659 Expression::PercentileDisc(f) => self.generate_percentile("PERCENTILE_DISC", f),
2660
2661 Expression::Contains(f) => {
2663 self.generate_binary_func("CONTAINS", &f.this, &f.expression)
2664 }
2665 Expression::StartsWith(f) => {
2666 let name = match self.config.dialect {
2667 Some(DialectType::Spark) | Some(DialectType::Databricks) => "STARTSWITH",
2668 _ => "STARTS_WITH",
2669 };
2670 self.generate_binary_func(name, &f.this, &f.expression)
2671 }
2672 Expression::EndsWith(f) => {
2673 let name = match self.config.dialect {
2674 Some(DialectType::Snowflake) => "ENDSWITH",
2675 Some(DialectType::Spark) | Some(DialectType::Databricks) => "ENDSWITH",
2676 Some(DialectType::ClickHouse) => "endsWith",
2677 _ => "ENDS_WITH",
2678 };
2679 self.generate_binary_func(name, &f.this, &f.expression)
2680 }
2681 Expression::Position(f) => self.generate_position(f),
2682 Expression::Initcap(f) => match self.config.dialect {
2683 Some(DialectType::Presto)
2684 | Some(DialectType::Trino)
2685 | Some(DialectType::Athena) => {
2686 self.write_keyword("REGEXP_REPLACE");
2687 self.write("(");
2688 self.generate_expression(&f.this)?;
2689 self.write(", '(\\w)(\\w*)', x -> UPPER(x[1]) || LOWER(x[2]))");
2690 Ok(())
2691 }
2692 _ => self.generate_simple_func("INITCAP", &f.this),
2693 },
2694 Expression::Ascii(f) => self.generate_simple_func("ASCII", &f.this),
2695 Expression::Chr(f) => self.generate_simple_func("CHR", &f.this),
2696 Expression::CharFunc(f) => self.generate_char_func(f),
2697 Expression::Soundex(f) => self.generate_simple_func("SOUNDEX", &f.this),
2698 Expression::Levenshtein(f) => {
2699 self.generate_binary_func("LEVENSHTEIN", &f.this, &f.expression)
2700 }
2701
2702 Expression::ModFunc(f) => self.generate_mod_func(f),
2704 Expression::Random(_) => {
2705 self.write_keyword("RANDOM");
2706 self.write("()");
2707 Ok(())
2708 }
2709 Expression::Rand(f) => self.generate_rand(f),
2710 Expression::TruncFunc(f) => self.generate_truncate_func(f),
2711 Expression::Pi(_) => {
2712 self.write_keyword("PI");
2713 self.write("()");
2714 Ok(())
2715 }
2716 Expression::Radians(f) => self.generate_simple_func("RADIANS", &f.this),
2717 Expression::Degrees(f) => self.generate_simple_func("DEGREES", &f.this),
2718 Expression::Sin(f) => self.generate_simple_func("SIN", &f.this),
2719 Expression::Cos(f) => self.generate_simple_func("COS", &f.this),
2720 Expression::Tan(f) => self.generate_simple_func("TAN", &f.this),
2721 Expression::Asin(f) => self.generate_simple_func("ASIN", &f.this),
2722 Expression::Acos(f) => self.generate_simple_func("ACOS", &f.this),
2723 Expression::Atan(f) => self.generate_simple_func("ATAN", &f.this),
2724 Expression::Atan2(f) => {
2725 let name = f.original_name.as_deref().unwrap_or("ATAN2");
2726 self.generate_binary_func(name, &f.this, &f.expression)
2727 }
2728
2729 Expression::Decode(f) => self.generate_decode(f),
2731
2732 Expression::DateFormat(f) => self.generate_date_format("DATE_FORMAT", f),
2734 Expression::FormatDate(f) => self.generate_date_format("FORMAT_DATE", f),
2735 Expression::Year(f) => self.generate_simple_func("YEAR", &f.this),
2736 Expression::Month(f) => self.generate_simple_func("MONTH", &f.this),
2737 Expression::Day(f) => self.generate_simple_func("DAY", &f.this),
2738 Expression::Hour(f) => self.generate_simple_func("HOUR", &f.this),
2739 Expression::Minute(f) => self.generate_simple_func("MINUTE", &f.this),
2740 Expression::Second(f) => self.generate_simple_func("SECOND", &f.this),
2741 Expression::DayOfWeek(f) => {
2742 let name = match self.config.dialect {
2743 Some(DialectType::Presto)
2744 | Some(DialectType::Trino)
2745 | Some(DialectType::Athena) => "DAY_OF_WEEK",
2746 Some(DialectType::DuckDB) => "ISODOW",
2747 _ => "DAYOFWEEK",
2748 };
2749 self.generate_simple_func(name, &f.this)
2750 }
2751 Expression::DayOfMonth(f) => {
2752 let name = match self.config.dialect {
2753 Some(DialectType::Presto)
2754 | Some(DialectType::Trino)
2755 | Some(DialectType::Athena) => "DAY_OF_MONTH",
2756 _ => "DAYOFMONTH",
2757 };
2758 self.generate_simple_func(name, &f.this)
2759 }
2760 Expression::DayOfYear(f) => {
2761 let name = match self.config.dialect {
2762 Some(DialectType::Presto)
2763 | Some(DialectType::Trino)
2764 | Some(DialectType::Athena) => "DAY_OF_YEAR",
2765 _ => "DAYOFYEAR",
2766 };
2767 self.generate_simple_func(name, &f.this)
2768 }
2769 Expression::WeekOfYear(f) => {
2770 let name = match self.config.dialect {
2772 Some(DialectType::Hive)
2773 | Some(DialectType::DuckDB)
2774 | Some(DialectType::Spark)
2775 | Some(DialectType::Databricks)
2776 | Some(DialectType::MySQL) => "WEEKOFYEAR",
2777 _ => "WEEK_OF_YEAR",
2778 };
2779 self.generate_simple_func(name, &f.this)
2780 }
2781 Expression::Quarter(f) => self.generate_simple_func("QUARTER", &f.this),
2782 Expression::AddMonths(f) => {
2783 self.generate_binary_func("ADD_MONTHS", &f.this, &f.expression)
2784 }
2785 Expression::MonthsBetween(f) => {
2786 self.generate_binary_func("MONTHS_BETWEEN", &f.this, &f.expression)
2787 }
2788 Expression::LastDay(f) => self.generate_last_day(f),
2789 Expression::NextDay(f) => self.generate_binary_func("NEXT_DAY", &f.this, &f.expression),
2790 Expression::Epoch(f) => self.generate_simple_func("EPOCH", &f.this),
2791 Expression::EpochMs(f) => self.generate_simple_func("EPOCH_MS", &f.this),
2792 Expression::FromUnixtime(f) => self.generate_from_unixtime(f),
2793 Expression::UnixTimestamp(f) => self.generate_unix_timestamp(f),
2794 Expression::MakeDate(f) => self.generate_make_date(f),
2795 Expression::MakeTimestamp(f) => self.generate_make_timestamp(f),
2796 Expression::TimestampTrunc(f) => self.generate_date_trunc(f),
2797
2798 Expression::ArrayFunc(f) => self.generate_array_constructor(f),
2800 Expression::ArrayLength(f) => self.generate_simple_func("ARRAY_LENGTH", &f.this),
2801 Expression::ArraySize(f) => self.generate_simple_func("ARRAY_SIZE", &f.this),
2802 Expression::Cardinality(f) => self.generate_simple_func("CARDINALITY", &f.this),
2803 Expression::ArrayContains(f) => {
2804 self.generate_binary_func("ARRAY_CONTAINS", &f.this, &f.expression)
2805 }
2806 Expression::ArrayPosition(f) => {
2807 self.generate_binary_func("ARRAY_POSITION", &f.this, &f.expression)
2808 }
2809 Expression::ArrayAppend(f) => {
2810 self.generate_binary_func("ARRAY_APPEND", &f.this, &f.expression)
2811 }
2812 Expression::ArrayPrepend(f) => {
2813 self.generate_binary_func("ARRAY_PREPEND", &f.this, &f.expression)
2814 }
2815 Expression::ArrayConcat(f) => self.generate_vararg_func("ARRAY_CONCAT", &f.expressions),
2816 Expression::ArraySort(f) => self.generate_array_sort(f),
2817 Expression::ArrayReverse(f) => self.generate_simple_func("ARRAY_REVERSE", &f.this),
2818 Expression::ArrayDistinct(f) => self.generate_simple_func("ARRAY_DISTINCT", &f.this),
2819 Expression::ArrayJoin(f) => self.generate_array_join("ARRAY_JOIN", f),
2820 Expression::ArrayToString(f) => self.generate_array_join("ARRAY_TO_STRING", f),
2821 Expression::Unnest(f) => self.generate_unnest(f),
2822 Expression::Explode(f) => self.generate_simple_func("EXPLODE", &f.this),
2823 Expression::ExplodeOuter(f) => self.generate_simple_func("EXPLODE_OUTER", &f.this),
2824 Expression::ArrayFilter(f) => self.generate_array_filter(f),
2825 Expression::ArrayTransform(f) => self.generate_array_transform(f),
2826 Expression::ArrayFlatten(f) => self.generate_simple_func("FLATTEN", &f.this),
2827 Expression::ArrayCompact(f) => {
2828 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
2829 self.write("LIST_FILTER(");
2831 self.generate_expression(&f.this)?;
2832 self.write(", _u -> NOT _u IS NULL)");
2833 Ok(())
2834 } else {
2835 self.generate_simple_func("ARRAY_COMPACT", &f.this)
2836 }
2837 }
2838 Expression::ArrayIntersect(f) => {
2839 let func_name = f.original_name.as_deref().unwrap_or("ARRAY_INTERSECT");
2840 self.generate_vararg_func(func_name, &f.expressions)
2841 }
2842 Expression::ArrayUnion(f) => {
2843 self.generate_binary_func("ARRAY_UNION", &f.this, &f.expression)
2844 }
2845 Expression::ArrayExcept(f) => {
2846 self.generate_binary_func("ARRAY_EXCEPT", &f.this, &f.expression)
2847 }
2848 Expression::ArrayRemove(f) => {
2849 self.generate_binary_func("ARRAY_REMOVE", &f.this, &f.expression)
2850 }
2851 Expression::ArrayZip(f) => self.generate_vararg_func("ARRAYS_ZIP", &f.expressions),
2852 Expression::Sequence(f) => self.generate_sequence("SEQUENCE", f),
2853 Expression::Generate(f) => self.generate_sequence("GENERATE_SERIES", f),
2854
2855 Expression::StructFunc(f) => self.generate_struct_constructor(f),
2857 Expression::StructExtract(f) => self.generate_struct_extract(f),
2858 Expression::NamedStruct(f) => self.generate_named_struct(f),
2859
2860 Expression::MapFunc(f) => self.generate_map_constructor(f),
2862 Expression::MapFromEntries(f) => self.generate_simple_func("MAP_FROM_ENTRIES", &f.this),
2863 Expression::MapFromArrays(f) => {
2864 self.generate_binary_func("MAP_FROM_ARRAYS", &f.this, &f.expression)
2865 }
2866 Expression::MapKeys(f) => self.generate_simple_func("MAP_KEYS", &f.this),
2867 Expression::MapValues(f) => self.generate_simple_func("MAP_VALUES", &f.this),
2868 Expression::MapContainsKey(f) => {
2869 self.generate_binary_func("MAP_CONTAINS_KEY", &f.this, &f.expression)
2870 }
2871 Expression::MapConcat(f) => self.generate_vararg_func("MAP_CONCAT", &f.expressions),
2872 Expression::ElementAt(f) => {
2873 self.generate_binary_func("ELEMENT_AT", &f.this, &f.expression)
2874 }
2875 Expression::TransformKeys(f) => self.generate_transform_func("TRANSFORM_KEYS", f),
2876 Expression::TransformValues(f) => self.generate_transform_func("TRANSFORM_VALUES", f),
2877
2878 Expression::JsonExtract(f) => self.generate_json_extract("JSON_EXTRACT", f),
2880 Expression::JsonExtractScalar(f) => {
2881 self.generate_json_extract("JSON_EXTRACT_SCALAR", f)
2882 }
2883 Expression::JsonExtractPath(f) => self.generate_json_path("JSON_EXTRACT_PATH", f),
2884 Expression::JsonArray(f) => self.generate_vararg_func("JSON_ARRAY", &f.expressions),
2885 Expression::JsonObject(f) => self.generate_json_object(f),
2886 Expression::JsonQuery(f) => self.generate_json_extract("JSON_QUERY", f),
2887 Expression::JsonValue(f) => self.generate_json_extract("JSON_VALUE", f),
2888 Expression::JsonArrayLength(f) => {
2889 self.generate_simple_func("JSON_ARRAY_LENGTH", &f.this)
2890 }
2891 Expression::JsonKeys(f) => self.generate_simple_func("JSON_KEYS", &f.this),
2892 Expression::JsonType(f) => self.generate_simple_func("JSON_TYPE", &f.this),
2893 Expression::ParseJson(f) => {
2894 let name = match self.config.dialect {
2895 Some(DialectType::Presto)
2896 | Some(DialectType::Trino)
2897 | Some(DialectType::Athena) => "JSON_PARSE",
2898 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
2899 self.write_keyword("CAST");
2901 self.write("(");
2902 self.generate_expression(&f.this)?;
2903 self.write_keyword(" AS ");
2904 self.write_keyword("JSON");
2905 self.write(")");
2906 return Ok(());
2907 }
2908 Some(DialectType::Hive)
2909 | Some(DialectType::Spark)
2910 | Some(DialectType::MySQL)
2911 | Some(DialectType::SingleStore)
2912 | Some(DialectType::TiDB)
2913 | Some(DialectType::TSQL) => {
2914 self.generate_expression(&f.this)?;
2916 return Ok(());
2917 }
2918 Some(DialectType::DuckDB) => "JSON",
2919 _ => "PARSE_JSON",
2920 };
2921 self.generate_simple_func(name, &f.this)
2922 }
2923 Expression::ToJson(f) => self.generate_simple_func("TO_JSON", &f.this),
2924 Expression::JsonSet(f) => self.generate_json_modify("JSON_SET", f),
2925 Expression::JsonInsert(f) => self.generate_json_modify("JSON_INSERT", f),
2926 Expression::JsonRemove(f) => self.generate_json_path("JSON_REMOVE", f),
2927 Expression::JsonMergePatch(f) => {
2928 self.generate_binary_func("JSON_MERGE_PATCH", &f.this, &f.expression)
2929 }
2930 Expression::JsonArrayAgg(f) => self.generate_json_array_agg(f),
2931 Expression::JsonObjectAgg(f) => self.generate_json_object_agg(f),
2932
2933 Expression::Convert(f) => self.generate_convert(f),
2935 Expression::Typeof(f) => self.generate_simple_func("TYPEOF", &f.this),
2936
2937 Expression::Lambda(f) => self.generate_lambda(f),
2939 Expression::Parameter(f) => self.generate_parameter(f),
2940 Expression::Placeholder(f) => self.generate_placeholder(f),
2941 Expression::NamedArgument(f) => self.generate_named_argument(f),
2942 Expression::TableArgument(f) => self.generate_table_argument(f),
2943 Expression::SqlComment(f) => self.generate_sql_comment(f),
2944
2945 Expression::NullSafeEq(op) => self.generate_null_safe_eq(op),
2947 Expression::NullSafeNeq(op) => self.generate_null_safe_neq(op),
2948 Expression::Glob(op) => self.generate_binary_op(op, "GLOB"),
2949 Expression::SimilarTo(f) => self.generate_similar_to(f),
2950 Expression::Any(f) => self.generate_quantified("ANY", f),
2951 Expression::All(f) => self.generate_quantified("ALL", f),
2952 Expression::Overlaps(f) => self.generate_overlaps(f),
2953
2954 Expression::BitwiseLeftShift(op) => {
2956 if matches!(
2957 self.config.dialect,
2958 Some(DialectType::Presto) | Some(DialectType::Trino)
2959 ) {
2960 self.write_keyword("BITWISE_ARITHMETIC_SHIFT_LEFT");
2961 self.write("(");
2962 self.generate_expression(&op.left)?;
2963 self.write(", ");
2964 self.generate_expression(&op.right)?;
2965 self.write(")");
2966 Ok(())
2967 } else if matches!(
2968 self.config.dialect,
2969 Some(DialectType::Spark) | Some(DialectType::Databricks)
2970 ) {
2971 self.write_keyword("SHIFTLEFT");
2972 self.write("(");
2973 self.generate_expression(&op.left)?;
2974 self.write(", ");
2975 self.generate_expression(&op.right)?;
2976 self.write(")");
2977 Ok(())
2978 } else {
2979 self.generate_binary_op(op, "<<")
2980 }
2981 }
2982 Expression::BitwiseRightShift(op) => {
2983 if matches!(
2984 self.config.dialect,
2985 Some(DialectType::Presto) | Some(DialectType::Trino)
2986 ) {
2987 self.write_keyword("BITWISE_ARITHMETIC_SHIFT_RIGHT");
2988 self.write("(");
2989 self.generate_expression(&op.left)?;
2990 self.write(", ");
2991 self.generate_expression(&op.right)?;
2992 self.write(")");
2993 Ok(())
2994 } else if matches!(
2995 self.config.dialect,
2996 Some(DialectType::Spark) | Some(DialectType::Databricks)
2997 ) {
2998 self.write_keyword("SHIFTRIGHT");
2999 self.write("(");
3000 self.generate_expression(&op.left)?;
3001 self.write(", ");
3002 self.generate_expression(&op.right)?;
3003 self.write(")");
3004 Ok(())
3005 } else {
3006 self.generate_binary_op(op, ">>")
3007 }
3008 }
3009 Expression::BitwiseAndAgg(f) => self.generate_agg_func("BIT_AND", f),
3010 Expression::BitwiseOrAgg(f) => self.generate_agg_func("BIT_OR", f),
3011 Expression::BitwiseXorAgg(f) => self.generate_agg_func("BIT_XOR", f),
3012
3013 Expression::Subscript(s) => self.generate_subscript(s),
3015 Expression::Dot(d) => self.generate_dot_access(d),
3016 Expression::MethodCall(m) => self.generate_method_call(m),
3017 Expression::ArraySlice(s) => self.generate_array_slice(s),
3018
3019 Expression::And(op) => self.generate_connector_op(op, ConnectorOperator::And),
3020 Expression::Or(op) => self.generate_connector_op(op, ConnectorOperator::Or),
3021 Expression::Add(op) => self.generate_binary_op(op, "+"),
3022 Expression::Sub(op) => self.generate_binary_op(op, "-"),
3023 Expression::Mul(op) => self.generate_binary_op(op, "*"),
3024 Expression::Div(op) => self.generate_binary_op(op, "/"),
3025 Expression::IntDiv(f) => {
3026 use crate::dialects::DialectType;
3027 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
3028 self.generate_expression(&f.this)?;
3030 self.write(" // ");
3031 self.generate_expression(&f.expression)?;
3032 Ok(())
3033 } else if matches!(
3034 self.config.dialect,
3035 Some(DialectType::Hive | DialectType::Spark | DialectType::Databricks)
3036 ) {
3037 self.generate_expression(&f.this)?;
3039 self.write(" ");
3040 self.write_keyword("DIV");
3041 self.write(" ");
3042 self.generate_expression(&f.expression)?;
3043 Ok(())
3044 } else {
3045 self.write_keyword("DIV");
3047 self.write("(");
3048 self.generate_expression(&f.this)?;
3049 self.write(", ");
3050 self.generate_expression(&f.expression)?;
3051 self.write(")");
3052 Ok(())
3053 }
3054 }
3055 Expression::Mod(op) => {
3056 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
3057 self.generate_binary_op(op, "MOD")
3058 } else {
3059 self.generate_binary_op(op, "%")
3060 }
3061 }
3062 Expression::Eq(op) => self.generate_binary_op(op, "="),
3063 Expression::Neq(op) => self.generate_binary_op(op, "<>"),
3064 Expression::Lt(op) => self.generate_binary_op(op, "<"),
3065 Expression::Lte(op) => self.generate_binary_op(op, "<="),
3066 Expression::Gt(op) => self.generate_binary_op(op, ">"),
3067 Expression::Gte(op) => self.generate_binary_op(op, ">="),
3068 Expression::Like(op) => self.generate_like_op(op, "LIKE"),
3069 Expression::ILike(op) => self.generate_like_op(op, "ILIKE"),
3070 Expression::Match(op) => self.generate_binary_op(op, "MATCH"),
3071 Expression::Concat(op) => {
3072 if self.config.dialect == Some(DialectType::Solr) {
3074 self.generate_binary_op(op, "OR")
3075 } else if self.config.dialect == Some(DialectType::MySQL) {
3076 self.generate_mysql_concat_from_concat(op)
3077 } else {
3078 self.generate_binary_op(op, "||")
3079 }
3080 }
3081 Expression::BitwiseAnd(op) => {
3082 if matches!(
3084 self.config.dialect,
3085 Some(DialectType::Presto) | Some(DialectType::Trino)
3086 ) {
3087 self.write_keyword("BITWISE_AND");
3088 self.write("(");
3089 self.generate_expression(&op.left)?;
3090 self.write(", ");
3091 self.generate_expression(&op.right)?;
3092 self.write(")");
3093 Ok(())
3094 } else {
3095 self.generate_binary_op(op, "&")
3096 }
3097 }
3098 Expression::BitwiseOr(op) => {
3099 if matches!(
3101 self.config.dialect,
3102 Some(DialectType::Presto) | Some(DialectType::Trino)
3103 ) {
3104 self.write_keyword("BITWISE_OR");
3105 self.write("(");
3106 self.generate_expression(&op.left)?;
3107 self.write(", ");
3108 self.generate_expression(&op.right)?;
3109 self.write(")");
3110 Ok(())
3111 } else {
3112 self.generate_binary_op(op, "|")
3113 }
3114 }
3115 Expression::BitwiseXor(op) => {
3116 if matches!(
3118 self.config.dialect,
3119 Some(DialectType::Presto) | Some(DialectType::Trino)
3120 ) {
3121 self.write_keyword("BITWISE_XOR");
3122 self.write("(");
3123 self.generate_expression(&op.left)?;
3124 self.write(", ");
3125 self.generate_expression(&op.right)?;
3126 self.write(")");
3127 Ok(())
3128 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
3129 self.generate_binary_op(op, "#")
3130 } else {
3131 self.generate_binary_op(op, "^")
3132 }
3133 }
3134 Expression::Adjacent(op) => self.generate_binary_op(op, "-|-"),
3135 Expression::TsMatch(op) => self.generate_binary_op(op, "@@"),
3136 Expression::PropertyEQ(op) => self.generate_binary_op(op, ":="),
3137 Expression::ArrayContainsAll(op) => self.generate_binary_op(op, "@>"),
3138 Expression::ArrayContainedBy(op) => self.generate_binary_op(op, "<@"),
3139 Expression::ArrayOverlaps(op) => self.generate_binary_op(op, "&&"),
3140 Expression::JSONBContainsAllTopKeys(op) => self.generate_binary_op(op, "?&"),
3141 Expression::JSONBContainsAnyTopKeys(op) => self.generate_binary_op(op, "?|"),
3142 Expression::JSONBContains(f) => {
3143 self.generate_expression(&f.this)?;
3145 self.write_space();
3146 self.write("?");
3147 self.write_space();
3148 self.generate_expression(&f.expression)
3149 }
3150 Expression::JSONBDeleteAtPath(op) => self.generate_binary_op(op, "#-"),
3151 Expression::ExtendsLeft(op) => self.generate_binary_op(op, "&<"),
3152 Expression::ExtendsRight(op) => self.generate_binary_op(op, "&>"),
3153 Expression::Not(op) => self.generate_unary_op(op, "NOT"),
3154 Expression::Neg(op) => self.generate_unary_op(op, "-"),
3155 Expression::BitwiseNot(op) => {
3156 if matches!(
3158 self.config.dialect,
3159 Some(DialectType::Presto) | Some(DialectType::Trino)
3160 ) {
3161 self.write_keyword("BITWISE_NOT");
3162 self.write("(");
3163 self.generate_expression(&op.this)?;
3164 self.write(")");
3165 Ok(())
3166 } else {
3167 self.generate_unary_op(op, "~")
3168 }
3169 }
3170 Expression::In(in_expr) => self.generate_in(in_expr),
3171 Expression::Between(between) => self.generate_between(between),
3172 Expression::IsNull(is_null) => self.generate_is_null(is_null),
3173 Expression::IsTrue(is_true) => self.generate_is_true(is_true),
3174 Expression::IsFalse(is_false) => self.generate_is_false(is_false),
3175 Expression::IsJson(is_json) => self.generate_is_json(is_json),
3176 Expression::Is(is_expr) => self.generate_is(is_expr),
3177 Expression::Exists(exists) => self.generate_exists(exists),
3178 Expression::MemberOf(member_of) => self.generate_member_of(member_of),
3179 Expression::Subquery(subquery) => self.generate_subquery(subquery),
3180 Expression::Paren(paren) => {
3181 let skip_parens = matches!(&paren.this, Expression::JoinedTable(_));
3183
3184 if !skip_parens {
3185 self.write("(");
3186 if self.config.pretty {
3187 self.write_newline();
3188 self.indent_level += 1;
3189 self.write_indent();
3190 }
3191 }
3192 self.generate_expression(&paren.this)?;
3193 if !skip_parens {
3194 if self.config.pretty {
3195 self.write_newline();
3196 self.indent_level -= 1;
3197 self.write_indent();
3198 }
3199 self.write(")");
3200 }
3201 for comment in &paren.trailing_comments {
3203 self.write(" ");
3204 self.write_formatted_comment(comment);
3205 }
3206 Ok(())
3207 }
3208 Expression::Array(arr) => self.generate_array(arr),
3209 Expression::Tuple(tuple) => self.generate_tuple(tuple),
3210 Expression::PipeOperator(pipe) => self.generate_pipe_operator(pipe),
3211 Expression::Ordered(ordered) => self.generate_ordered(ordered),
3212 Expression::DataType(dt) => self.generate_data_type(dt),
3213 Expression::Raw(raw) => {
3214 self.write(&raw.sql);
3215 Ok(())
3216 }
3217 Expression::Command(cmd) => {
3218 self.write(&cmd.this);
3219 Ok(())
3220 }
3221 Expression::Kill(kill) => {
3222 self.write_keyword("KILL");
3223 if let Some(kind) = &kill.kind {
3224 self.write_space();
3225 self.write_keyword(kind);
3226 }
3227 self.write_space();
3228 self.generate_expression(&kill.this)?;
3229 Ok(())
3230 }
3231 Expression::Execute(exec) => {
3232 self.write_keyword("EXEC");
3233 self.write_space();
3234 self.generate_expression(&exec.this)?;
3235 for (i, param) in exec.parameters.iter().enumerate() {
3236 if i == 0 {
3237 self.write_space();
3238 } else {
3239 self.write(", ");
3240 }
3241 self.write(¶m.name);
3242 self.write("=");
3243 self.generate_expression(¶m.value)?;
3244 }
3245 Ok(())
3246 }
3247 Expression::Annotated(annotated) => {
3248 self.generate_expression(&annotated.this)?;
3249 for comment in &annotated.trailing_comments {
3250 self.write(" ");
3251 self.write_formatted_comment(comment);
3252 }
3253 Ok(())
3254 }
3255
3256 Expression::CreateTable(ct) => self.generate_create_table(ct),
3258 Expression::DropTable(dt) => self.generate_drop_table(dt),
3259 Expression::AlterTable(at) => self.generate_alter_table(at),
3260 Expression::CreateIndex(ci) => self.generate_create_index(ci),
3261 Expression::DropIndex(di) => self.generate_drop_index(di),
3262 Expression::CreateView(cv) => self.generate_create_view(cv),
3263 Expression::DropView(dv) => self.generate_drop_view(dv),
3264 Expression::AlterView(av) => self.generate_alter_view(av),
3265 Expression::AlterIndex(ai) => self.generate_alter_index(ai),
3266 Expression::Truncate(tr) => self.generate_truncate(tr),
3267 Expression::Use(u) => self.generate_use(u),
3268 Expression::CreateSchema(cs) => self.generate_create_schema(cs),
3270 Expression::DropSchema(ds) => self.generate_drop_schema(ds),
3271 Expression::DropNamespace(dn) => self.generate_drop_namespace(dn),
3272 Expression::CreateDatabase(cd) => self.generate_create_database(cd),
3273 Expression::DropDatabase(dd) => self.generate_drop_database(dd),
3274 Expression::CreateFunction(cf) => self.generate_create_function(cf),
3275 Expression::DropFunction(df) => self.generate_drop_function(df),
3276 Expression::CreateProcedure(cp) => self.generate_create_procedure(cp),
3277 Expression::DropProcedure(dp) => self.generate_drop_procedure(dp),
3278 Expression::CreateSequence(cs) => self.generate_create_sequence(cs),
3279 Expression::DropSequence(ds) => self.generate_drop_sequence(ds),
3280 Expression::AlterSequence(als) => self.generate_alter_sequence(als),
3281 Expression::CreateTrigger(ct) => self.generate_create_trigger(ct),
3282 Expression::DropTrigger(dt) => self.generate_drop_trigger(dt),
3283 Expression::CreateType(ct) => self.generate_create_type(ct),
3284 Expression::DropType(dt) => self.generate_drop_type(dt),
3285 Expression::Describe(d) => self.generate_describe(d),
3286 Expression::Show(s) => self.generate_show(s),
3287
3288 Expression::Cache(c) => self.generate_cache(c),
3290 Expression::Uncache(u) => self.generate_uncache(u),
3291 Expression::LoadData(l) => self.generate_load_data(l),
3292 Expression::Pragma(p) => self.generate_pragma(p),
3293 Expression::Grant(g) => self.generate_grant(g),
3294 Expression::Revoke(r) => self.generate_revoke(r),
3295 Expression::Comment(c) => self.generate_comment(c),
3296 Expression::SetStatement(s) => self.generate_set_statement(s),
3297
3298 Expression::Pivot(pivot) => self.generate_pivot(pivot),
3300 Expression::Unpivot(unpivot) => self.generate_unpivot(unpivot),
3301
3302 Expression::Values(values) => self.generate_values(values),
3304
3305 Expression::AIAgg(e) => self.generate_ai_agg(e),
3307 Expression::AIClassify(e) => self.generate_ai_classify(e),
3308 Expression::AddPartition(e) => self.generate_add_partition(e),
3309 Expression::AlgorithmProperty(e) => self.generate_algorithm_property(e),
3310 Expression::Aliases(e) => self.generate_aliases(e),
3311 Expression::AllowedValuesProperty(e) => self.generate_allowed_values_property(e),
3312 Expression::AlterColumn(e) => self.generate_alter_column(e),
3313 Expression::AlterSession(e) => self.generate_alter_session(e),
3314 Expression::AlterSet(e) => self.generate_alter_set(e),
3315 Expression::AlterSortKey(e) => self.generate_alter_sort_key(e),
3316 Expression::Analyze(e) => self.generate_analyze(e),
3317 Expression::AnalyzeDelete(e) => self.generate_analyze_delete(e),
3318 Expression::AnalyzeHistogram(e) => self.generate_analyze_histogram(e),
3319 Expression::AnalyzeListChainedRows(e) => self.generate_analyze_list_chained_rows(e),
3320 Expression::AnalyzeSample(e) => self.generate_analyze_sample(e),
3321 Expression::AnalyzeStatistics(e) => self.generate_analyze_statistics(e),
3322 Expression::AnalyzeValidate(e) => self.generate_analyze_validate(e),
3323 Expression::AnalyzeWith(e) => self.generate_analyze_with(e),
3324 Expression::Anonymous(e) => self.generate_anonymous(e),
3325 Expression::AnonymousAggFunc(e) => self.generate_anonymous_agg_func(e),
3326 Expression::Apply(e) => self.generate_apply(e),
3327 Expression::ApproxPercentileEstimate(e) => self.generate_approx_percentile_estimate(e),
3328 Expression::ApproxQuantile(e) => self.generate_approx_quantile(e),
3329 Expression::ApproxQuantiles(e) => self.generate_approx_quantiles(e),
3330 Expression::ApproxTopK(e) => self.generate_approx_top_k(e),
3331 Expression::ApproxTopKAccumulate(e) => self.generate_approx_top_k_accumulate(e),
3332 Expression::ApproxTopKCombine(e) => self.generate_approx_top_k_combine(e),
3333 Expression::ApproxTopKEstimate(e) => self.generate_approx_top_k_estimate(e),
3334 Expression::ApproxTopSum(e) => self.generate_approx_top_sum(e),
3335 Expression::ArgMax(e) => self.generate_arg_max(e),
3336 Expression::ArgMin(e) => self.generate_arg_min(e),
3337 Expression::ArrayAll(e) => self.generate_array_all(e),
3338 Expression::ArrayAny(e) => self.generate_array_any(e),
3339 Expression::ArrayConstructCompact(e) => self.generate_array_construct_compact(e),
3340 Expression::ArraySum(e) => self.generate_array_sum(e),
3341 Expression::AtIndex(e) => self.generate_at_index(e),
3342 Expression::Attach(e) => self.generate_attach(e),
3343 Expression::AttachOption(e) => self.generate_attach_option(e),
3344 Expression::AutoIncrementProperty(e) => self.generate_auto_increment_property(e),
3345 Expression::AutoRefreshProperty(e) => self.generate_auto_refresh_property(e),
3346 Expression::BackupProperty(e) => self.generate_backup_property(e),
3347 Expression::Base64DecodeBinary(e) => self.generate_base64_decode_binary(e),
3348 Expression::Base64DecodeString(e) => self.generate_base64_decode_string(e),
3349 Expression::Base64Encode(e) => self.generate_base64_encode(e),
3350 Expression::BlockCompressionProperty(e) => self.generate_block_compression_property(e),
3351 Expression::Booland(e) => self.generate_booland(e),
3352 Expression::Boolor(e) => self.generate_boolor(e),
3353 Expression::BuildProperty(e) => self.generate_build_property(e),
3354 Expression::ByteString(e) => self.generate_byte_string(e),
3355 Expression::CaseSpecificColumnConstraint(e) => {
3356 self.generate_case_specific_column_constraint(e)
3357 }
3358 Expression::CastToStrType(e) => self.generate_cast_to_str_type(e),
3359 Expression::Changes(e) => self.generate_changes(e),
3360 Expression::CharacterSetColumnConstraint(e) => {
3361 self.generate_character_set_column_constraint(e)
3362 }
3363 Expression::CharacterSetProperty(e) => self.generate_character_set_property(e),
3364 Expression::CheckColumnConstraint(e) => self.generate_check_column_constraint(e),
3365 Expression::CheckJson(e) => self.generate_check_json(e),
3366 Expression::CheckXml(e) => self.generate_check_xml(e),
3367 Expression::ChecksumProperty(e) => self.generate_checksum_property(e),
3368 Expression::Clone(e) => self.generate_clone(e),
3369 Expression::ClusterBy(e) => self.generate_cluster_by(e),
3370 Expression::ClusterByColumnsProperty(e) => self.generate_cluster_by_columns_property(e),
3371 Expression::ClusteredByProperty(e) => self.generate_clustered_by_property(e),
3372 Expression::CollateProperty(e) => self.generate_collate_property(e),
3373 Expression::ColumnConstraint(e) => self.generate_column_constraint(e),
3374 Expression::ColumnDef(e) => self.generate_column_def_expr(e),
3375 Expression::ColumnPosition(e) => self.generate_column_position(e),
3376 Expression::ColumnPrefix(e) => self.generate_column_prefix(e),
3377 Expression::Columns(e) => self.generate_columns(e),
3378 Expression::CombinedAggFunc(e) => self.generate_combined_agg_func(e),
3379 Expression::CombinedParameterizedAgg(e) => self.generate_combined_parameterized_agg(e),
3380 Expression::Commit(e) => self.generate_commit(e),
3381 Expression::Comprehension(e) => self.generate_comprehension(e),
3382 Expression::Compress(e) => self.generate_compress(e),
3383 Expression::CompressColumnConstraint(e) => self.generate_compress_column_constraint(e),
3384 Expression::ComputedColumnConstraint(e) => self.generate_computed_column_constraint(e),
3385 Expression::ConditionalInsert(e) => self.generate_conditional_insert(e),
3386 Expression::Constraint(e) => self.generate_constraint(e),
3387 Expression::ConvertTimezone(e) => self.generate_convert_timezone(e),
3388 Expression::ConvertToCharset(e) => self.generate_convert_to_charset(e),
3389 Expression::Copy(e) => self.generate_copy(e),
3390 Expression::CopyParameter(e) => self.generate_copy_parameter(e),
3391 Expression::Corr(e) => self.generate_corr(e),
3392 Expression::CosineDistance(e) => self.generate_cosine_distance(e),
3393 Expression::CovarPop(e) => self.generate_covar_pop(e),
3394 Expression::CovarSamp(e) => self.generate_covar_samp(e),
3395 Expression::Credentials(e) => self.generate_credentials(e),
3396 Expression::CredentialsProperty(e) => self.generate_credentials_property(e),
3397 Expression::Cte(e) => self.generate_cte(e),
3398 Expression::Cube(e) => self.generate_cube(e),
3399 Expression::CurrentDatetime(e) => self.generate_current_datetime(e),
3400 Expression::CurrentSchema(e) => self.generate_current_schema(e),
3401 Expression::CurrentSchemas(e) => self.generate_current_schemas(e),
3402 Expression::CurrentUser(e) => self.generate_current_user(e),
3403 Expression::DPipe(e) => self.generate_d_pipe(e),
3404 Expression::DataBlocksizeProperty(e) => self.generate_data_blocksize_property(e),
3405 Expression::DataDeletionProperty(e) => self.generate_data_deletion_property(e),
3406 Expression::Date(e) => self.generate_date_func(e),
3407 Expression::DateBin(e) => self.generate_date_bin(e),
3408 Expression::DateFormatColumnConstraint(e) => {
3409 self.generate_date_format_column_constraint(e)
3410 }
3411 Expression::DateFromParts(e) => self.generate_date_from_parts(e),
3412 Expression::Datetime(e) => self.generate_datetime(e),
3413 Expression::DatetimeAdd(e) => self.generate_datetime_add(e),
3414 Expression::DatetimeDiff(e) => self.generate_datetime_diff(e),
3415 Expression::DatetimeSub(e) => self.generate_datetime_sub(e),
3416 Expression::DatetimeTrunc(e) => self.generate_datetime_trunc(e),
3417 Expression::Dayname(e) => self.generate_dayname(e),
3418 Expression::Declare(e) => self.generate_declare(e),
3419 Expression::DeclareItem(e) => self.generate_declare_item(e),
3420 Expression::DecodeCase(e) => self.generate_decode_case(e),
3421 Expression::DecompressBinary(e) => self.generate_decompress_binary(e),
3422 Expression::DecompressString(e) => self.generate_decompress_string(e),
3423 Expression::Decrypt(e) => self.generate_decrypt(e),
3424 Expression::DecryptRaw(e) => self.generate_decrypt_raw(e),
3425 Expression::DefinerProperty(e) => self.generate_definer_property(e),
3426 Expression::Detach(e) => self.generate_detach(e),
3427 Expression::DictProperty(e) => self.generate_dict_property(e),
3428 Expression::DictRange(e) => self.generate_dict_range(e),
3429 Expression::Directory(e) => self.generate_directory(e),
3430 Expression::DistKeyProperty(e) => self.generate_dist_key_property(e),
3431 Expression::DistStyleProperty(e) => self.generate_dist_style_property(e),
3432 Expression::DistributeBy(e) => self.generate_distribute_by(e),
3433 Expression::DistributedByProperty(e) => self.generate_distributed_by_property(e),
3434 Expression::DotProduct(e) => self.generate_dot_product(e),
3435 Expression::DropPartition(e) => self.generate_drop_partition(e),
3436 Expression::DuplicateKeyProperty(e) => self.generate_duplicate_key_property(e),
3437 Expression::Elt(e) => self.generate_elt(e),
3438 Expression::Encode(e) => self.generate_encode(e),
3439 Expression::EncodeProperty(e) => self.generate_encode_property(e),
3440 Expression::Encrypt(e) => self.generate_encrypt(e),
3441 Expression::EncryptRaw(e) => self.generate_encrypt_raw(e),
3442 Expression::EngineProperty(e) => self.generate_engine_property(e),
3443 Expression::EnviromentProperty(e) => self.generate_enviroment_property(e),
3444 Expression::EphemeralColumnConstraint(e) => {
3445 self.generate_ephemeral_column_constraint(e)
3446 }
3447 Expression::EqualNull(e) => self.generate_equal_null(e),
3448 Expression::EuclideanDistance(e) => self.generate_euclidean_distance(e),
3449 Expression::ExecuteAsProperty(e) => self.generate_execute_as_property(e),
3450 Expression::Export(e) => self.generate_export(e),
3451 Expression::ExternalProperty(e) => self.generate_external_property(e),
3452 Expression::FallbackProperty(e) => self.generate_fallback_property(e),
3453 Expression::FarmFingerprint(e) => self.generate_farm_fingerprint(e),
3454 Expression::FeaturesAtTime(e) => self.generate_features_at_time(e),
3455 Expression::Fetch(e) => self.generate_fetch(e),
3456 Expression::FileFormatProperty(e) => self.generate_file_format_property(e),
3457 Expression::Filter(e) => self.generate_filter(e),
3458 Expression::Float64(e) => self.generate_float64(e),
3459 Expression::ForIn(e) => self.generate_for_in(e),
3460 Expression::ForeignKey(e) => self.generate_foreign_key(e),
3461 Expression::Format(e) => self.generate_format(e),
3462 Expression::FormatPhrase(e) => self.generate_format_phrase(e),
3463 Expression::FreespaceProperty(e) => self.generate_freespace_property(e),
3464 Expression::From(e) => self.generate_from(e),
3465 Expression::FromBase(e) => self.generate_from_base(e),
3466 Expression::FromTimeZone(e) => self.generate_from_time_zone(e),
3467 Expression::GapFill(e) => self.generate_gap_fill(e),
3468 Expression::GenerateDateArray(e) => self.generate_generate_date_array(e),
3469 Expression::GenerateEmbedding(e) => self.generate_generate_embedding(e),
3470 Expression::GenerateSeries(e) => self.generate_generate_series(e),
3471 Expression::GenerateTimestampArray(e) => self.generate_generate_timestamp_array(e),
3472 Expression::GeneratedAsIdentityColumnConstraint(e) => {
3473 self.generate_generated_as_identity_column_constraint(e)
3474 }
3475 Expression::GeneratedAsRowColumnConstraint(e) => {
3476 self.generate_generated_as_row_column_constraint(e)
3477 }
3478 Expression::Get(e) => self.generate_get(e),
3479 Expression::GetExtract(e) => self.generate_get_extract(e),
3480 Expression::Getbit(e) => self.generate_getbit(e),
3481 Expression::GrantPrincipal(e) => self.generate_grant_principal(e),
3482 Expression::GrantPrivilege(e) => self.generate_grant_privilege(e),
3483 Expression::Group(e) => self.generate_group(e),
3484 Expression::GroupBy(e) => self.generate_group_by(e),
3485 Expression::Grouping(e) => self.generate_grouping(e),
3486 Expression::GroupingId(e) => self.generate_grouping_id(e),
3487 Expression::GroupingSets(e) => self.generate_grouping_sets(e),
3488 Expression::HashAgg(e) => self.generate_hash_agg(e),
3489 Expression::Having(e) => self.generate_having(e),
3490 Expression::HavingMax(e) => self.generate_having_max(e),
3491 Expression::Heredoc(e) => self.generate_heredoc(e),
3492 Expression::HexEncode(e) => self.generate_hex_encode(e),
3493 Expression::Hll(e) => self.generate_hll(e),
3494 Expression::InOutColumnConstraint(e) => self.generate_in_out_column_constraint(e),
3495 Expression::IncludeProperty(e) => self.generate_include_property(e),
3496 Expression::Index(e) => self.generate_index(e),
3497 Expression::IndexColumnConstraint(e) => self.generate_index_column_constraint(e),
3498 Expression::IndexConstraintOption(e) => self.generate_index_constraint_option(e),
3499 Expression::IndexParameters(e) => self.generate_index_parameters(e),
3500 Expression::IndexTableHint(e) => self.generate_index_table_hint(e),
3501 Expression::InheritsProperty(e) => self.generate_inherits_property(e),
3502 Expression::InputModelProperty(e) => self.generate_input_model_property(e),
3503 Expression::InputOutputFormat(e) => self.generate_input_output_format(e),
3504 Expression::Install(e) => self.generate_install(e),
3505 Expression::IntervalOp(e) => self.generate_interval_op(e),
3506 Expression::IntervalSpan(e) => self.generate_interval_span(e),
3507 Expression::IntoClause(e) => self.generate_into_clause(e),
3508 Expression::Introducer(e) => self.generate_introducer(e),
3509 Expression::IsolatedLoadingProperty(e) => self.generate_isolated_loading_property(e),
3510 Expression::JSON(e) => self.generate_json(e),
3511 Expression::JSONArray(e) => self.generate_json_array(e),
3512 Expression::JSONArrayAgg(e) => self.generate_json_array_agg_struct(e),
3513 Expression::JSONArrayAppend(e) => self.generate_json_array_append(e),
3514 Expression::JSONArrayContains(e) => self.generate_json_array_contains(e),
3515 Expression::JSONArrayInsert(e) => self.generate_json_array_insert(e),
3516 Expression::JSONBExists(e) => self.generate_jsonb_exists(e),
3517 Expression::JSONBExtractScalar(e) => self.generate_jsonb_extract_scalar(e),
3518 Expression::JSONBObjectAgg(e) => self.generate_jsonb_object_agg(e),
3519 Expression::JSONObjectAgg(e) => self.generate_json_object_agg_struct(e),
3520 Expression::JSONColumnDef(e) => self.generate_json_column_def(e),
3521 Expression::JSONExists(e) => self.generate_json_exists(e),
3522 Expression::JSONCast(e) => self.generate_json_cast(e),
3523 Expression::JSONExtract(e) => self.generate_json_extract_path(e),
3524 Expression::JSONExtractArray(e) => self.generate_json_extract_array(e),
3525 Expression::JSONExtractQuote(e) => self.generate_json_extract_quote(e),
3526 Expression::JSONExtractScalar(e) => self.generate_json_extract_scalar(e),
3527 Expression::JSONFormat(e) => self.generate_json_format(e),
3528 Expression::JSONKeyValue(e) => self.generate_json_key_value(e),
3529 Expression::JSONKeys(e) => self.generate_json_keys(e),
3530 Expression::JSONKeysAtDepth(e) => self.generate_json_keys_at_depth(e),
3531 Expression::JSONPath(e) => self.generate_json_path_expr(e),
3532 Expression::JSONPathFilter(e) => self.generate_json_path_filter(e),
3533 Expression::JSONPathKey(e) => self.generate_json_path_key(e),
3534 Expression::JSONPathRecursive(e) => self.generate_json_path_recursive(e),
3535 Expression::JSONPathRoot(_) => self.generate_json_path_root(),
3536 Expression::JSONPathScript(e) => self.generate_json_path_script(e),
3537 Expression::JSONPathSelector(e) => self.generate_json_path_selector(e),
3538 Expression::JSONPathSlice(e) => self.generate_json_path_slice(e),
3539 Expression::JSONPathSubscript(e) => self.generate_json_path_subscript(e),
3540 Expression::JSONPathUnion(e) => self.generate_json_path_union(e),
3541 Expression::JSONRemove(e) => self.generate_json_remove(e),
3542 Expression::JSONSchema(e) => self.generate_json_schema(e),
3543 Expression::JSONSet(e) => self.generate_json_set(e),
3544 Expression::JSONStripNulls(e) => self.generate_json_strip_nulls(e),
3545 Expression::JSONTable(e) => self.generate_json_table(e),
3546 Expression::JSONType(e) => self.generate_json_type(e),
3547 Expression::JSONValue(e) => self.generate_json_value(e),
3548 Expression::JSONValueArray(e) => self.generate_json_value_array(e),
3549 Expression::JarowinklerSimilarity(e) => self.generate_jarowinkler_similarity(e),
3550 Expression::JoinHint(e) => self.generate_join_hint(e),
3551 Expression::JournalProperty(e) => self.generate_journal_property(e),
3552 Expression::LanguageProperty(e) => self.generate_language_property(e),
3553 Expression::Lateral(e) => self.generate_lateral(e),
3554 Expression::LikeProperty(e) => self.generate_like_property(e),
3555 Expression::Limit(e) => self.generate_limit(e),
3556 Expression::LimitOptions(e) => self.generate_limit_options(e),
3557 Expression::List(e) => self.generate_list(e),
3558 Expression::ToMap(e) => self.generate_tomap(e),
3559 Expression::Localtime(e) => self.generate_localtime(e),
3560 Expression::Localtimestamp(e) => self.generate_localtimestamp(e),
3561 Expression::LocationProperty(e) => self.generate_location_property(e),
3562 Expression::Lock(e) => self.generate_lock(e),
3563 Expression::LockProperty(e) => self.generate_lock_property(e),
3564 Expression::LockingProperty(e) => self.generate_locking_property(e),
3565 Expression::LockingStatement(e) => self.generate_locking_statement(e),
3566 Expression::LogProperty(e) => self.generate_log_property(e),
3567 Expression::MD5Digest(e) => self.generate_md5_digest(e),
3568 Expression::MLForecast(e) => self.generate_ml_forecast(e),
3569 Expression::MLTranslate(e) => self.generate_ml_translate(e),
3570 Expression::MakeInterval(e) => self.generate_make_interval(e),
3571 Expression::ManhattanDistance(e) => self.generate_manhattan_distance(e),
3572 Expression::Map(e) => self.generate_map(e),
3573 Expression::MapCat(e) => self.generate_map_cat(e),
3574 Expression::MapDelete(e) => self.generate_map_delete(e),
3575 Expression::MapInsert(e) => self.generate_map_insert(e),
3576 Expression::MapPick(e) => self.generate_map_pick(e),
3577 Expression::MaskingPolicyColumnConstraint(e) => {
3578 self.generate_masking_policy_column_constraint(e)
3579 }
3580 Expression::MatchAgainst(e) => self.generate_match_against(e),
3581 Expression::MatchRecognizeMeasure(e) => self.generate_match_recognize_measure(e),
3582 Expression::MaterializedProperty(e) => self.generate_materialized_property(e),
3583 Expression::Merge(e) => self.generate_merge(e),
3584 Expression::MergeBlockRatioProperty(e) => self.generate_merge_block_ratio_property(e),
3585 Expression::MergeTreeTTL(e) => self.generate_merge_tree_ttl(e),
3586 Expression::MergeTreeTTLAction(e) => self.generate_merge_tree_ttl_action(e),
3587 Expression::Minhash(e) => self.generate_minhash(e),
3588 Expression::ModelAttribute(e) => self.generate_model_attribute(e),
3589 Expression::Monthname(e) => self.generate_monthname(e),
3590 Expression::MultitableInserts(e) => self.generate_multitable_inserts(e),
3591 Expression::NextValueFor(e) => self.generate_next_value_for(e),
3592 Expression::Normal(e) => self.generate_normal(e),
3593 Expression::Normalize(e) => self.generate_normalize(e),
3594 Expression::NotNullColumnConstraint(e) => self.generate_not_null_column_constraint(e),
3595 Expression::Nullif(e) => self.generate_nullif(e),
3596 Expression::NumberToStr(e) => self.generate_number_to_str(e),
3597 Expression::ObjectAgg(e) => self.generate_object_agg(e),
3598 Expression::ObjectIdentifier(e) => self.generate_object_identifier(e),
3599 Expression::ObjectInsert(e) => self.generate_object_insert(e),
3600 Expression::Offset(e) => self.generate_offset(e),
3601 Expression::Qualify(e) => self.generate_qualify(e),
3602 Expression::OnCluster(e) => self.generate_on_cluster(e),
3603 Expression::OnCommitProperty(e) => self.generate_on_commit_property(e),
3604 Expression::OnCondition(e) => self.generate_on_condition(e),
3605 Expression::OnConflict(e) => self.generate_on_conflict(e),
3606 Expression::OnProperty(e) => self.generate_on_property(e),
3607 Expression::Opclass(e) => self.generate_opclass(e),
3608 Expression::OpenJSON(e) => self.generate_open_json(e),
3609 Expression::OpenJSONColumnDef(e) => self.generate_open_json_column_def(e),
3610 Expression::Operator(e) => self.generate_operator(e),
3611 Expression::OrderBy(e) => self.generate_order_by(e),
3612 Expression::OutputModelProperty(e) => self.generate_output_model_property(e),
3613 Expression::OverflowTruncateBehavior(e) => self.generate_overflow_truncate_behavior(e),
3614 Expression::ParameterizedAgg(e) => self.generate_parameterized_agg(e),
3615 Expression::ParseDatetime(e) => self.generate_parse_datetime(e),
3616 Expression::ParseIp(e) => self.generate_parse_ip(e),
3617 Expression::ParseJSON(e) => self.generate_parse_json(e),
3618 Expression::ParseTime(e) => self.generate_parse_time(e),
3619 Expression::ParseUrl(e) => self.generate_parse_url(e),
3620 Expression::Partition(e) => self.generate_partition_expr(e),
3621 Expression::PartitionBoundSpec(e) => self.generate_partition_bound_spec(e),
3622 Expression::PartitionByListProperty(e) => self.generate_partition_by_list_property(e),
3623 Expression::PartitionByRangeProperty(e) => self.generate_partition_by_range_property(e),
3624 Expression::PartitionByRangePropertyDynamic(e) => {
3625 self.generate_partition_by_range_property_dynamic(e)
3626 }
3627 Expression::PartitionByTruncate(e) => self.generate_partition_by_truncate(e),
3628 Expression::PartitionList(e) => self.generate_partition_list(e),
3629 Expression::PartitionRange(e) => self.generate_partition_range(e),
3630 Expression::PartitionByProperty(e) => self.generate_partition_by_property(e),
3631 Expression::PartitionedByBucket(e) => self.generate_partitioned_by_bucket(e),
3632 Expression::PartitionedByProperty(e) => self.generate_partitioned_by_property(e),
3633 Expression::PartitionedOfProperty(e) => self.generate_partitioned_of_property(e),
3634 Expression::PeriodForSystemTimeConstraint(e) => {
3635 self.generate_period_for_system_time_constraint(e)
3636 }
3637 Expression::PivotAlias(e) => self.generate_pivot_alias(e),
3638 Expression::PivotAny(e) => self.generate_pivot_any(e),
3639 Expression::Predict(e) => self.generate_predict(e),
3640 Expression::PreviousDay(e) => self.generate_previous_day(e),
3641 Expression::PrimaryKey(e) => self.generate_primary_key(e),
3642 Expression::PrimaryKeyColumnConstraint(e) => {
3643 self.generate_primary_key_column_constraint(e)
3644 }
3645 Expression::PathColumnConstraint(e) => self.generate_path_column_constraint(e),
3646 Expression::ProjectionDef(e) => self.generate_projection_def(e),
3647 Expression::OptionsProperty(e) => self.generate_options_property(e),
3648 Expression::Properties(e) => self.generate_properties(e),
3649 Expression::Property(e) => self.generate_property(e),
3650 Expression::PseudoType(e) => self.generate_pseudo_type(e),
3651 Expression::Put(e) => self.generate_put(e),
3652 Expression::Quantile(e) => self.generate_quantile(e),
3653 Expression::QueryBand(e) => self.generate_query_band(e),
3654 Expression::QueryOption(e) => self.generate_query_option(e),
3655 Expression::QueryTransform(e) => self.generate_query_transform(e),
3656 Expression::Randn(e) => self.generate_randn(e),
3657 Expression::Randstr(e) => self.generate_randstr(e),
3658 Expression::RangeBucket(e) => self.generate_range_bucket(e),
3659 Expression::RangeN(e) => self.generate_range_n(e),
3660 Expression::ReadCSV(e) => self.generate_read_csv(e),
3661 Expression::ReadParquet(e) => self.generate_read_parquet(e),
3662 Expression::RecursiveWithSearch(e) => self.generate_recursive_with_search(e),
3663 Expression::Reduce(e) => self.generate_reduce(e),
3664 Expression::Reference(e) => self.generate_reference(e),
3665 Expression::Refresh(e) => self.generate_refresh(e),
3666 Expression::RefreshTriggerProperty(e) => self.generate_refresh_trigger_property(e),
3667 Expression::RegexpCount(e) => self.generate_regexp_count(e),
3668 Expression::RegexpExtractAll(e) => self.generate_regexp_extract_all(e),
3669 Expression::RegexpFullMatch(e) => self.generate_regexp_full_match(e),
3670 Expression::RegexpILike(e) => self.generate_regexp_i_like(e),
3671 Expression::RegexpInstr(e) => self.generate_regexp_instr(e),
3672 Expression::RegexpSplit(e) => self.generate_regexp_split(e),
3673 Expression::RegrAvgx(e) => self.generate_regr_avgx(e),
3674 Expression::RegrAvgy(e) => self.generate_regr_avgy(e),
3675 Expression::RegrCount(e) => self.generate_regr_count(e),
3676 Expression::RegrIntercept(e) => self.generate_regr_intercept(e),
3677 Expression::RegrR2(e) => self.generate_regr_r2(e),
3678 Expression::RegrSlope(e) => self.generate_regr_slope(e),
3679 Expression::RegrSxx(e) => self.generate_regr_sxx(e),
3680 Expression::RegrSxy(e) => self.generate_regr_sxy(e),
3681 Expression::RegrSyy(e) => self.generate_regr_syy(e),
3682 Expression::RegrValx(e) => self.generate_regr_valx(e),
3683 Expression::RegrValy(e) => self.generate_regr_valy(e),
3684 Expression::RemoteWithConnectionModelProperty(e) => {
3685 self.generate_remote_with_connection_model_property(e)
3686 }
3687 Expression::RenameColumn(e) => self.generate_rename_column(e),
3688 Expression::ReplacePartition(e) => self.generate_replace_partition(e),
3689 Expression::Returning(e) => self.generate_returning(e),
3690 Expression::ReturnsProperty(e) => self.generate_returns_property(e),
3691 Expression::Rollback(e) => self.generate_rollback(e),
3692 Expression::Rollup(e) => self.generate_rollup(e),
3693 Expression::RowFormatDelimitedProperty(e) => {
3694 self.generate_row_format_delimited_property(e)
3695 }
3696 Expression::RowFormatProperty(e) => self.generate_row_format_property(e),
3697 Expression::RowFormatSerdeProperty(e) => self.generate_row_format_serde_property(e),
3698 Expression::SHA2(e) => self.generate_sha2(e),
3699 Expression::SHA2Digest(e) => self.generate_sha2_digest(e),
3700 Expression::SafeAdd(e) => self.generate_safe_add(e),
3701 Expression::SafeDivide(e) => self.generate_safe_divide(e),
3702 Expression::SafeMultiply(e) => self.generate_safe_multiply(e),
3703 Expression::SafeSubtract(e) => self.generate_safe_subtract(e),
3704 Expression::SampleProperty(e) => self.generate_sample_property(e),
3705 Expression::Schema(e) => self.generate_schema(e),
3706 Expression::SchemaCommentProperty(e) => self.generate_schema_comment_property(e),
3707 Expression::ScopeResolution(e) => self.generate_scope_resolution(e),
3708 Expression::Search(e) => self.generate_search(e),
3709 Expression::SearchIp(e) => self.generate_search_ip(e),
3710 Expression::SecurityProperty(e) => self.generate_security_property(e),
3711 Expression::SemanticView(e) => self.generate_semantic_view(e),
3712 Expression::SequenceProperties(e) => self.generate_sequence_properties(e),
3713 Expression::SerdeProperties(e) => self.generate_serde_properties(e),
3714 Expression::SessionParameter(e) => self.generate_session_parameter(e),
3715 Expression::Set(e) => self.generate_set(e),
3716 Expression::SetConfigProperty(e) => self.generate_set_config_property(e),
3717 Expression::SetItem(e) => self.generate_set_item(e),
3718 Expression::SetOperation(e) => self.generate_set_operation(e),
3719 Expression::SetProperty(e) => self.generate_set_property(e),
3720 Expression::SettingsProperty(e) => self.generate_settings_property(e),
3721 Expression::SharingProperty(e) => self.generate_sharing_property(e),
3722 Expression::Slice(e) => self.generate_slice(e),
3723 Expression::SortArray(e) => self.generate_sort_array(e),
3724 Expression::SortBy(e) => self.generate_sort_by(e),
3725 Expression::SortKeyProperty(e) => self.generate_sort_key_property(e),
3726 Expression::SplitPart(e) => self.generate_split_part(e),
3727 Expression::SqlReadWriteProperty(e) => self.generate_sql_read_write_property(e),
3728 Expression::SqlSecurityProperty(e) => self.generate_sql_security_property(e),
3729 Expression::StDistance(e) => self.generate_st_distance(e),
3730 Expression::StPoint(e) => self.generate_st_point(e),
3731 Expression::StabilityProperty(e) => self.generate_stability_property(e),
3732 Expression::StandardHash(e) => self.generate_standard_hash(e),
3733 Expression::StorageHandlerProperty(e) => self.generate_storage_handler_property(e),
3734 Expression::StrPosition(e) => self.generate_str_position(e),
3735 Expression::StrToDate(e) => self.generate_str_to_date(e),
3736 Expression::DateStrToDate(f) => self.generate_simple_func("DATE_STR_TO_DATE", &f.this),
3737 Expression::DateToDateStr(f) => self.generate_simple_func("DATE_TO_DATE_STR", &f.this),
3738 Expression::StrToMap(e) => self.generate_str_to_map(e),
3739 Expression::StrToTime(e) => self.generate_str_to_time(e),
3740 Expression::StrToUnix(e) => self.generate_str_to_unix(e),
3741 Expression::StringToArray(e) => self.generate_string_to_array(e),
3742 Expression::Struct(e) => self.generate_struct(e),
3743 Expression::Stuff(e) => self.generate_stuff(e),
3744 Expression::SubstringIndex(e) => self.generate_substring_index(e),
3745 Expression::Summarize(e) => self.generate_summarize(e),
3746 Expression::Systimestamp(e) => self.generate_systimestamp(e),
3747 Expression::TableAlias(e) => self.generate_table_alias(e),
3748 Expression::TableFromRows(e) => self.generate_table_from_rows(e),
3749 Expression::RowsFrom(e) => self.generate_rows_from(e),
3750 Expression::TableSample(e) => self.generate_table_sample(e),
3751 Expression::Tag(e) => self.generate_tag(e),
3752 Expression::Tags(e) => self.generate_tags(e),
3753 Expression::TemporaryProperty(e) => self.generate_temporary_property(e),
3754 Expression::Time(e) => self.generate_time_func(e),
3755 Expression::TimeAdd(e) => self.generate_time_add(e),
3756 Expression::TimeDiff(e) => self.generate_time_diff(e),
3757 Expression::TimeFromParts(e) => self.generate_time_from_parts(e),
3758 Expression::TimeSlice(e) => self.generate_time_slice(e),
3759 Expression::TimeStrToDate(e) => self.generate_time_str_to_date(e),
3760 Expression::TimeStrToTime(e) => self.generate_time_str_to_time(e),
3761 Expression::TimeSub(e) => self.generate_time_sub(e),
3762 Expression::TimeToStr(e) => self.generate_time_to_str(e),
3763 Expression::TimeToUnix(e) => self.generate_time_to_unix(e),
3764 Expression::TimeTrunc(e) => self.generate_time_trunc(e),
3765 Expression::TimeUnit(e) => self.generate_time_unit(e),
3766 Expression::Timestamp(e) => self.generate_timestamp_func(e),
3767 Expression::TimestampAdd(e) => self.generate_timestamp_add(e),
3768 Expression::TimestampDiff(e) => self.generate_timestamp_diff(e),
3769 Expression::TimestampFromParts(e) => self.generate_timestamp_from_parts(e),
3770 Expression::TimestampSub(e) => self.generate_timestamp_sub(e),
3771 Expression::TimestampTzFromParts(e) => self.generate_timestamp_tz_from_parts(e),
3772 Expression::ToBinary(e) => self.generate_to_binary(e),
3773 Expression::ToBoolean(e) => self.generate_to_boolean(e),
3774 Expression::ToChar(e) => self.generate_to_char(e),
3775 Expression::ToDecfloat(e) => self.generate_to_decfloat(e),
3776 Expression::ToDouble(e) => self.generate_to_double(e),
3777 Expression::ToFile(e) => self.generate_to_file(e),
3778 Expression::ToNumber(e) => self.generate_to_number(e),
3779 Expression::ToTableProperty(e) => self.generate_to_table_property(e),
3780 Expression::Transaction(e) => self.generate_transaction(e),
3781 Expression::Transform(e) => self.generate_transform(e),
3782 Expression::TransformModelProperty(e) => self.generate_transform_model_property(e),
3783 Expression::TransientProperty(e) => self.generate_transient_property(e),
3784 Expression::Translate(e) => self.generate_translate(e),
3785 Expression::TranslateCharacters(e) => self.generate_translate_characters(e),
3786 Expression::TruncateTable(e) => self.generate_truncate_table(e),
3787 Expression::TryBase64DecodeBinary(e) => self.generate_try_base64_decode_binary(e),
3788 Expression::TryBase64DecodeString(e) => self.generate_try_base64_decode_string(e),
3789 Expression::TryToDecfloat(e) => self.generate_try_to_decfloat(e),
3790 Expression::TsOrDsAdd(e) => self.generate_ts_or_ds_add(e),
3791 Expression::TsOrDsDiff(e) => self.generate_ts_or_ds_diff(e),
3792 Expression::TsOrDsToDate(e) => self.generate_ts_or_ds_to_date(e),
3793 Expression::TsOrDsToTime(e) => self.generate_ts_or_ds_to_time(e),
3794 Expression::Unhex(e) => self.generate_unhex(e),
3795 Expression::UnicodeString(e) => self.generate_unicode_string(e),
3796 Expression::Uniform(e) => self.generate_uniform(e),
3797 Expression::UniqueColumnConstraint(e) => self.generate_unique_column_constraint(e),
3798 Expression::UniqueKeyProperty(e) => self.generate_unique_key_property(e),
3799 Expression::RollupProperty(e) => self.generate_rollup_property(e),
3800 Expression::UnixToStr(e) => self.generate_unix_to_str(e),
3801 Expression::UnixToTime(e) => self.generate_unix_to_time(e),
3802 Expression::UnpivotColumns(e) => self.generate_unpivot_columns(e),
3803 Expression::UserDefinedFunction(e) => self.generate_user_defined_function(e),
3804 Expression::UsingTemplateProperty(e) => self.generate_using_template_property(e),
3805 Expression::UtcTime(e) => self.generate_utc_time(e),
3806 Expression::UtcTimestamp(e) => self.generate_utc_timestamp(e),
3807 Expression::Uuid(e) => self.generate_uuid(e),
3808 Expression::Var(v) => {
3809 if matches!(self.config.dialect, Some(DialectType::MySQL))
3810 && v.this.len() > 2
3811 && (v.this.starts_with("0x") || v.this.starts_with("0X"))
3812 && !v.this[2..].chars().all(|c| c.is_ascii_hexdigit())
3813 {
3814 return self.generate_identifier(&Identifier {
3815 name: v.this.clone(),
3816 quoted: true,
3817 trailing_comments: Vec::new(),
3818 span: None,
3819 });
3820 }
3821 self.write(&v.this);
3822 Ok(())
3823 }
3824 Expression::Variadic(e) => {
3825 self.write_keyword("VARIADIC");
3826 self.write_space();
3827 self.generate_expression(&e.this)?;
3828 Ok(())
3829 }
3830 Expression::VarMap(e) => self.generate_var_map(e),
3831 Expression::VectorSearch(e) => self.generate_vector_search(e),
3832 Expression::Version(e) => self.generate_version(e),
3833 Expression::ViewAttributeProperty(e) => self.generate_view_attribute_property(e),
3834 Expression::VolatileProperty(e) => self.generate_volatile_property(e),
3835 Expression::WatermarkColumnConstraint(e) => {
3836 self.generate_watermark_column_constraint(e)
3837 }
3838 Expression::Week(e) => self.generate_week(e),
3839 Expression::When(e) => self.generate_when(e),
3840 Expression::Whens(e) => self.generate_whens(e),
3841 Expression::Where(e) => self.generate_where(e),
3842 Expression::WidthBucket(e) => self.generate_width_bucket(e),
3843 Expression::Window(e) => self.generate_window(e),
3844 Expression::WindowSpec(e) => self.generate_window_spec(e),
3845 Expression::WithDataProperty(e) => self.generate_with_data_property(e),
3846 Expression::WithFill(e) => self.generate_with_fill(e),
3847 Expression::WithJournalTableProperty(e) => self.generate_with_journal_table_property(e),
3848 Expression::WithOperator(e) => self.generate_with_operator(e),
3849 Expression::WithProcedureOptions(e) => self.generate_with_procedure_options(e),
3850 Expression::WithSchemaBindingProperty(e) => {
3851 self.generate_with_schema_binding_property(e)
3852 }
3853 Expression::WithSystemVersioningProperty(e) => {
3854 self.generate_with_system_versioning_property(e)
3855 }
3856 Expression::WithTableHint(e) => self.generate_with_table_hint(e),
3857 Expression::XMLElement(e) => self.generate_xml_element(e),
3858 Expression::XMLGet(e) => self.generate_xml_get(e),
3859 Expression::XMLKeyValueOption(e) => self.generate_xml_key_value_option(e),
3860 Expression::XMLTable(e) => self.generate_xml_table(e),
3861 Expression::Xor(e) => self.generate_xor(e),
3862 Expression::Zipf(e) => self.generate_zipf(e),
3863 _ => {
3864 self.write(&format!("/* unimplemented: {:?} */", expr));
3866 Ok(())
3867 }
3868 }
3869 }
3870
3871 fn generate_select(&mut self, select: &Select) -> Result<()> {
3872 use crate::dialects::DialectType;
3873
3874 for comment in &select.leading_comments {
3876 self.write_formatted_comment(comment);
3877 self.write(" ");
3878 }
3879
3880 if let Some(with) = &select.with {
3882 self.generate_with(with)?;
3883 if self.config.pretty {
3884 self.write_newline();
3885 self.write_indent();
3886 } else {
3887 self.write_space();
3888 }
3889 }
3890
3891 for comment in &select.post_select_comments {
3894 self.write_formatted_comment(comment);
3895 self.write(" ");
3896 }
3897
3898 self.write_keyword("SELECT");
3899
3900 if let Some(hint) = &select.hint {
3902 self.generate_hint(hint)?;
3903 }
3904
3905 let use_top_from_limit = matches!(self.config.dialect, Some(DialectType::TSQL))
3909 && select.top.is_none()
3910 && select.limit.is_some()
3911 && select.offset.is_none(); let is_top_dialect = matches!(
3916 self.config.dialect,
3917 Some(DialectType::TSQL) | Some(DialectType::Teradata) | Some(DialectType::Fabric)
3918 );
3919 let keep_top_verbatim = !is_top_dialect
3920 && select.limit.is_none()
3921 && select
3922 .top
3923 .as_ref()
3924 .map_or(false, |top| top.percent || top.with_ties);
3925
3926 if select.distinct && (is_top_dialect || select.top.is_some()) {
3927 self.write_space();
3928 self.write_keyword("DISTINCT");
3929 }
3930
3931 if is_top_dialect || keep_top_verbatim {
3932 if let Some(top) = &select.top {
3933 self.write_space();
3934 self.write_keyword("TOP");
3935 if top.parenthesized {
3936 self.write(" (");
3937 self.generate_expression(&top.this)?;
3938 self.write(")");
3939 } else {
3940 self.write_space();
3941 self.generate_expression(&top.this)?;
3942 }
3943 if top.percent {
3944 self.write_space();
3945 self.write_keyword("PERCENT");
3946 }
3947 if top.with_ties {
3948 self.write_space();
3949 self.write_keyword("WITH TIES");
3950 }
3951 } else if use_top_from_limit {
3952 if let Some(limit) = &select.limit {
3954 self.write_space();
3955 self.write_keyword("TOP");
3956 let is_simple_literal =
3958 matches!(&limit.this, Expression::Literal(Literal::Number(_)));
3959 if is_simple_literal {
3960 self.write_space();
3961 self.generate_expression(&limit.this)?;
3962 } else {
3963 self.write(" (");
3964 self.generate_expression(&limit.this)?;
3965 self.write(")");
3966 }
3967 }
3968 }
3969 }
3970
3971 if select.distinct && !is_top_dialect && select.top.is_none() {
3972 self.write_space();
3973 self.write_keyword("DISTINCT");
3974 }
3975
3976 if let Some(distinct_on) = &select.distinct_on {
3978 self.write_space();
3979 self.write_keyword("ON");
3980 self.write(" (");
3981 for (i, expr) in distinct_on.iter().enumerate() {
3982 if i > 0 {
3983 self.write(", ");
3984 }
3985 self.generate_expression(expr)?;
3986 }
3987 self.write(")");
3988 }
3989
3990 for modifier in &select.operation_modifiers {
3992 self.write_space();
3993 self.write_keyword(modifier);
3994 }
3995
3996 if let Some(kind) = &select.kind {
3998 self.write_space();
3999 self.write_keyword("AS");
4000 self.write_space();
4001 self.write_keyword(kind);
4002 }
4003
4004 if !select.expressions.is_empty() {
4006 if self.config.pretty {
4007 self.write_newline();
4008 self.indent_level += 1;
4009 } else {
4010 self.write_space();
4011 }
4012 }
4013
4014 for (i, expr) in select.expressions.iter().enumerate() {
4015 if i > 0 {
4016 self.write(",");
4017 if self.config.pretty {
4018 self.write_newline();
4019 } else {
4020 self.write_space();
4021 }
4022 }
4023 if self.config.pretty {
4024 self.write_indent();
4025 }
4026 self.generate_expression(expr)?;
4027 }
4028
4029 if self.config.pretty && !select.expressions.is_empty() {
4030 self.indent_level -= 1;
4031 }
4032
4033 if let Some(into) = &select.into {
4036 if self.config.pretty {
4037 self.write_newline();
4038 self.write_indent();
4039 } else {
4040 self.write_space();
4041 }
4042 if into.bulk_collect {
4043 self.write_keyword("BULK COLLECT INTO");
4044 } else {
4045 self.write_keyword("INTO");
4046 }
4047 if into.temporary {
4048 self.write_space();
4049 self.write_keyword("TEMPORARY");
4050 }
4051 if into.unlogged {
4052 self.write_space();
4053 self.write_keyword("UNLOGGED");
4054 }
4055 self.write_space();
4056 if !into.expressions.is_empty() {
4058 for (i, expr) in into.expressions.iter().enumerate() {
4059 if i > 0 {
4060 self.write(", ");
4061 }
4062 self.generate_expression(expr)?;
4063 }
4064 } else {
4065 self.generate_expression(&into.this)?;
4066 }
4067 }
4068
4069 if let Some(from) = &select.from {
4071 if self.config.pretty {
4072 self.write_newline();
4073 self.write_indent();
4074 } else {
4075 self.write_space();
4076 }
4077 self.write_keyword("FROM");
4078 self.write_space();
4079
4080 let has_tablesample = from
4085 .expressions
4086 .iter()
4087 .any(|e| matches!(e, Expression::TableSample(_)));
4088 let is_cross_join_dialect = matches!(
4089 self.config.dialect,
4090 Some(DialectType::BigQuery)
4091 | Some(DialectType::Hive)
4092 | Some(DialectType::Spark)
4093 | Some(DialectType::Databricks)
4094 | Some(DialectType::SQLite)
4095 | Some(DialectType::ClickHouse)
4096 );
4097 let source_is_same_as_target = self.config.source_dialect.is_some()
4100 && self.config.source_dialect == self.config.dialect;
4101 let source_is_cross_join_dialect = matches!(
4102 self.config.source_dialect,
4103 Some(DialectType::BigQuery)
4104 | Some(DialectType::Hive)
4105 | Some(DialectType::Spark)
4106 | Some(DialectType::Databricks)
4107 | Some(DialectType::SQLite)
4108 | Some(DialectType::ClickHouse)
4109 );
4110 let use_cross_join = !has_tablesample
4111 && is_cross_join_dialect
4112 && (source_is_same_as_target
4113 || source_is_cross_join_dialect
4114 || self.config.source_dialect.is_none());
4115
4116 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
4118
4119 for (i, expr) in from.expressions.iter().enumerate() {
4120 if i > 0 {
4121 if use_cross_join {
4122 self.write(" CROSS JOIN ");
4123 } else {
4124 self.write(", ");
4125 }
4126 }
4127 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
4128 self.write("(");
4129 self.generate_expression(expr)?;
4130 self.write(")");
4131 } else {
4132 self.generate_expression(expr)?;
4133 }
4134 }
4135 }
4136
4137 if self.config.pretty {
4141 self.generate_joins_with_nesting(&select.joins)?;
4142 } else {
4143 for join in &select.joins {
4144 self.generate_join(join)?;
4145 }
4146 for join in select.joins.iter().rev() {
4148 if join.deferred_condition {
4149 self.generate_join_condition(join)?;
4150 }
4151 }
4152 }
4153
4154 for lateral_view in &select.lateral_views {
4156 self.generate_lateral_view(lateral_view)?;
4157 }
4158
4159 if let Some(prewhere) = &select.prewhere {
4161 self.write_clause_condition("PREWHERE", prewhere)?;
4162 }
4163
4164 if let Some(where_clause) = &select.where_clause {
4166 self.write_clause_condition("WHERE", &where_clause.this)?;
4167 }
4168
4169 if let Some(connect) = &select.connect {
4171 self.generate_connect(connect)?;
4172 }
4173
4174 if let Some(group_by) = &select.group_by {
4176 if self.config.pretty {
4177 for comment in &group_by.comments {
4179 self.write_newline();
4180 self.write_indent();
4181 self.write_formatted_comment(comment);
4182 }
4183 self.write_newline();
4184 self.write_indent();
4185 } else {
4186 self.write_space();
4187 for comment in &group_by.comments {
4189 self.write_formatted_comment(comment);
4190 self.write_space();
4191 }
4192 }
4193 self.write_keyword("GROUP BY");
4194 match group_by.all {
4196 Some(true) => {
4197 self.write_space();
4198 self.write_keyword("ALL");
4199 }
4200 Some(false) => {
4201 self.write_space();
4202 self.write_keyword("DISTINCT");
4203 }
4204 None => {}
4205 }
4206 if !group_by.expressions.is_empty() {
4207 let mut trailing_cube = false;
4210 let mut trailing_rollup = false;
4211 let mut plain_expressions: Vec<&Expression> = Vec::new();
4212 let mut grouping_sets_expressions: Vec<&Expression> = Vec::new();
4213 let mut cube_expressions: Vec<&Expression> = Vec::new();
4214 let mut rollup_expressions: Vec<&Expression> = Vec::new();
4215
4216 for expr in &group_by.expressions {
4217 match expr {
4218 Expression::Cube(c) if c.expressions.is_empty() => {
4219 trailing_cube = true;
4220 }
4221 Expression::Rollup(r) if r.expressions.is_empty() => {
4222 trailing_rollup = true;
4223 }
4224 Expression::Function(f) if f.name == "CUBE" => {
4225 cube_expressions.push(expr);
4226 }
4227 Expression::Function(f) if f.name == "ROLLUP" => {
4228 rollup_expressions.push(expr);
4229 }
4230 Expression::Function(f) if f.name == "GROUPING SETS" => {
4231 grouping_sets_expressions.push(expr);
4232 }
4233 _ => {
4234 plain_expressions.push(expr);
4235 }
4236 }
4237 }
4238
4239 let mut regular_expressions: Vec<&Expression> = Vec::new();
4241 regular_expressions.extend(plain_expressions);
4242 regular_expressions.extend(grouping_sets_expressions);
4243 regular_expressions.extend(cube_expressions);
4244 regular_expressions.extend(rollup_expressions);
4245
4246 if self.config.pretty {
4247 self.write_newline();
4248 self.indent_level += 1;
4249 self.write_indent();
4250 } else {
4251 self.write_space();
4252 }
4253
4254 for (i, expr) in regular_expressions.iter().enumerate() {
4255 if i > 0 {
4256 if self.config.pretty {
4257 self.write(",");
4258 self.write_newline();
4259 self.write_indent();
4260 } else {
4261 self.write(", ");
4262 }
4263 }
4264 self.generate_expression(expr)?;
4265 }
4266
4267 if self.config.pretty {
4268 self.indent_level -= 1;
4269 }
4270
4271 if trailing_cube {
4273 self.write_space();
4274 self.write_keyword("WITH CUBE");
4275 } else if trailing_rollup {
4276 self.write_space();
4277 self.write_keyword("WITH ROLLUP");
4278 }
4279 }
4280
4281 if group_by.totals {
4283 self.write_space();
4284 self.write_keyword("WITH TOTALS");
4285 }
4286 }
4287
4288 if let Some(having) = &select.having {
4290 if self.config.pretty {
4291 for comment in &having.comments {
4293 self.write_newline();
4294 self.write_indent();
4295 self.write_formatted_comment(comment);
4296 }
4297 } else {
4298 for comment in &having.comments {
4299 self.write_space();
4300 self.write_formatted_comment(comment);
4301 }
4302 }
4303 self.write_clause_condition("HAVING", &having.this)?;
4304 }
4305
4306 if select.qualify_after_window {
4308 if let Some(windows) = &select.windows {
4310 self.write_window_clause(windows)?;
4311 }
4312 if let Some(qualify) = &select.qualify {
4313 self.write_clause_condition("QUALIFY", &qualify.this)?;
4314 }
4315 } else {
4316 if let Some(qualify) = &select.qualify {
4318 self.write_clause_condition("QUALIFY", &qualify.this)?;
4319 }
4320 if let Some(windows) = &select.windows {
4321 self.write_window_clause(windows)?;
4322 }
4323 }
4324
4325 if let Some(distribute_by) = &select.distribute_by {
4327 self.write_clause_expressions("DISTRIBUTE BY", &distribute_by.expressions)?;
4328 }
4329
4330 if let Some(cluster_by) = &select.cluster_by {
4332 self.write_order_clause("CLUSTER BY", &cluster_by.expressions)?;
4333 }
4334
4335 if let Some(sort_by) = &select.sort_by {
4337 self.write_order_clause("SORT BY", &sort_by.expressions)?;
4338 }
4339
4340 if let Some(order_by) = &select.order_by {
4342 if self.config.pretty {
4343 for comment in &order_by.comments {
4345 self.write_newline();
4346 self.write_indent();
4347 self.write_formatted_comment(comment);
4348 }
4349 } else {
4350 for comment in &order_by.comments {
4351 self.write_space();
4352 self.write_formatted_comment(comment);
4353 }
4354 }
4355 let keyword = if order_by.siblings {
4356 "ORDER SIBLINGS BY"
4357 } else {
4358 "ORDER BY"
4359 };
4360 self.write_order_clause(keyword, &order_by.expressions)?;
4361 }
4362
4363 if select.order_by.is_none()
4365 && select.fetch.is_some()
4366 && matches!(
4367 self.config.dialect,
4368 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4369 )
4370 {
4371 if self.config.pretty {
4372 self.write_newline();
4373 self.write_indent();
4374 } else {
4375 self.write_space();
4376 }
4377 self.write_keyword("ORDER BY (SELECT NULL) OFFSET 0 ROWS");
4378 }
4379
4380 let is_presto_like = matches!(
4385 self.config.dialect,
4386 Some(DialectType::Presto) | Some(DialectType::Trino)
4387 );
4388
4389 if is_presto_like && select.offset.is_some() {
4390 if let Some(offset) = &select.offset {
4392 if self.config.pretty {
4393 self.write_newline();
4394 self.write_indent();
4395 } else {
4396 self.write_space();
4397 }
4398 self.write_keyword("OFFSET");
4399 self.write_space();
4400 self.write_limit_expr(&offset.this)?;
4401 if offset.rows == Some(true) {
4402 self.write_space();
4403 self.write_keyword("ROWS");
4404 }
4405 }
4406 if let Some(limit) = &select.limit {
4407 if self.config.pretty {
4408 self.write_newline();
4409 self.write_indent();
4410 } else {
4411 self.write_space();
4412 }
4413 self.write_keyword("LIMIT");
4414 self.write_space();
4415 self.write_limit_expr(&limit.this)?;
4416 if limit.percent {
4417 self.write_space();
4418 self.write_keyword("PERCENT");
4419 }
4420 for comment in &limit.comments {
4422 self.write(" ");
4423 self.write_formatted_comment(comment);
4424 }
4425 }
4426 } else {
4427 let fetch_as_limit = select.fetch.as_ref().map_or(false, |fetch| {
4429 !fetch.percent
4430 && !fetch.with_ties
4431 && fetch.count.is_some()
4432 && matches!(
4433 self.config.dialect,
4434 Some(DialectType::Spark)
4435 | Some(DialectType::Hive)
4436 | Some(DialectType::DuckDB)
4437 | Some(DialectType::SQLite)
4438 | Some(DialectType::MySQL)
4439 | Some(DialectType::BigQuery)
4440 | Some(DialectType::Databricks)
4441 | Some(DialectType::StarRocks)
4442 | Some(DialectType::Doris)
4443 | Some(DialectType::Athena)
4444 | Some(DialectType::ClickHouse)
4445 | Some(DialectType::Redshift)
4446 )
4447 });
4448
4449 if let Some(limit) = &select.limit {
4451 if !matches!(self.config.dialect, Some(DialectType::TSQL)) {
4453 if self.config.pretty {
4454 self.write_newline();
4455 self.write_indent();
4456 } else {
4457 self.write_space();
4458 }
4459 self.write_keyword("LIMIT");
4460 self.write_space();
4461 self.write_limit_expr(&limit.this)?;
4462 if limit.percent {
4463 self.write_space();
4464 self.write_keyword("PERCENT");
4465 }
4466 for comment in &limit.comments {
4468 self.write(" ");
4469 self.write_formatted_comment(comment);
4470 }
4471 }
4472 }
4473
4474 if select.top.is_some() && !is_top_dialect && select.limit.is_none() {
4476 if let Some(top) = &select.top {
4477 if !top.percent && !top.with_ties {
4478 if self.config.pretty {
4479 self.write_newline();
4480 self.write_indent();
4481 } else {
4482 self.write_space();
4483 }
4484 self.write_keyword("LIMIT");
4485 self.write_space();
4486 self.generate_expression(&top.this)?;
4487 }
4488 }
4489 }
4490
4491 if fetch_as_limit && select.offset.is_some() {
4494 if let Some(fetch) = &select.fetch {
4495 if self.config.pretty {
4496 self.write_newline();
4497 self.write_indent();
4498 } else {
4499 self.write_space();
4500 }
4501 self.write_keyword("LIMIT");
4502 self.write_space();
4503 self.generate_expression(fetch.count.as_ref().unwrap())?;
4504 }
4505 }
4506
4507 if let Some(offset) = &select.offset {
4511 if self.config.pretty {
4512 self.write_newline();
4513 self.write_indent();
4514 } else {
4515 self.write_space();
4516 }
4517 if matches!(self.config.dialect, Some(DialectType::TSQL)) {
4518 self.write_keyword("OFFSET");
4520 self.write_space();
4521 self.write_limit_expr(&offset.this)?;
4522 self.write_space();
4523 self.write_keyword("ROWS");
4524 if let Some(limit) = &select.limit {
4526 self.write_space();
4527 self.write_keyword("FETCH NEXT");
4528 self.write_space();
4529 self.write_limit_expr(&limit.this)?;
4530 self.write_space();
4531 self.write_keyword("ROWS ONLY");
4532 }
4533 } else {
4534 self.write_keyword("OFFSET");
4535 self.write_space();
4536 self.write_limit_expr(&offset.this)?;
4537 if offset.rows == Some(true) {
4539 self.write_space();
4540 self.write_keyword("ROWS");
4541 }
4542 }
4543 }
4544 }
4545
4546 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4548 if let Some(limit_by) = &select.limit_by {
4549 if !limit_by.is_empty() {
4550 self.write_space();
4551 self.write_keyword("BY");
4552 self.write_space();
4553 for (i, expr) in limit_by.iter().enumerate() {
4554 if i > 0 {
4555 self.write(", ");
4556 }
4557 self.generate_expression(expr)?;
4558 }
4559 }
4560 }
4561 }
4562
4563 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4565 if let Some(settings) = &select.settings {
4566 if self.config.pretty {
4567 self.write_newline();
4568 self.write_indent();
4569 } else {
4570 self.write_space();
4571 }
4572 self.write_keyword("SETTINGS");
4573 self.write_space();
4574 for (i, expr) in settings.iter().enumerate() {
4575 if i > 0 {
4576 self.write(", ");
4577 }
4578 self.generate_expression(expr)?;
4579 }
4580 }
4581
4582 if let Some(format_expr) = &select.format {
4583 if self.config.pretty {
4584 self.write_newline();
4585 self.write_indent();
4586 } else {
4587 self.write_space();
4588 }
4589 self.write_keyword("FORMAT");
4590 self.write_space();
4591 self.generate_expression(format_expr)?;
4592 }
4593 }
4594
4595 if let Some(fetch) = &select.fetch {
4597 let fetch_already_as_limit = select.offset.is_some()
4599 && !fetch.percent
4600 && !fetch.with_ties
4601 && fetch.count.is_some()
4602 && matches!(
4603 self.config.dialect,
4604 Some(DialectType::Spark)
4605 | Some(DialectType::Hive)
4606 | Some(DialectType::DuckDB)
4607 | Some(DialectType::SQLite)
4608 | Some(DialectType::MySQL)
4609 | Some(DialectType::BigQuery)
4610 | Some(DialectType::Databricks)
4611 | Some(DialectType::StarRocks)
4612 | Some(DialectType::Doris)
4613 | Some(DialectType::Athena)
4614 | Some(DialectType::ClickHouse)
4615 | Some(DialectType::Redshift)
4616 );
4617
4618 if fetch_already_as_limit {
4619 } else {
4621 if self.config.pretty {
4622 self.write_newline();
4623 self.write_indent();
4624 } else {
4625 self.write_space();
4626 }
4627
4628 let use_limit = !fetch.percent
4630 && !fetch.with_ties
4631 && fetch.count.is_some()
4632 && matches!(
4633 self.config.dialect,
4634 Some(DialectType::Spark)
4635 | Some(DialectType::Hive)
4636 | Some(DialectType::DuckDB)
4637 | Some(DialectType::SQLite)
4638 | Some(DialectType::MySQL)
4639 | Some(DialectType::BigQuery)
4640 | Some(DialectType::Databricks)
4641 | Some(DialectType::StarRocks)
4642 | Some(DialectType::Doris)
4643 | Some(DialectType::Athena)
4644 | Some(DialectType::ClickHouse)
4645 | Some(DialectType::Redshift)
4646 );
4647
4648 if use_limit {
4649 self.write_keyword("LIMIT");
4650 self.write_space();
4651 self.generate_expression(fetch.count.as_ref().unwrap())?;
4652 } else {
4653 self.write_keyword("FETCH");
4654 self.write_space();
4655 self.write_keyword(&fetch.direction);
4656 if let Some(ref count) = fetch.count {
4657 self.write_space();
4658 self.generate_expression(count)?;
4659 }
4660 if fetch.percent {
4661 self.write_space();
4662 self.write_keyword("PERCENT");
4663 }
4664 if fetch.rows {
4665 self.write_space();
4666 self.write_keyword("ROWS");
4667 }
4668 if fetch.with_ties {
4669 self.write_space();
4670 self.write_keyword("WITH TIES");
4671 } else {
4672 self.write_space();
4673 self.write_keyword("ONLY");
4674 }
4675 }
4676 } }
4678
4679 if let Some(sample) = &select.sample {
4681 use crate::dialects::DialectType;
4682 if self.config.pretty {
4683 self.write_newline();
4684 } else {
4685 self.write_space();
4686 }
4687
4688 if sample.is_using_sample {
4689 self.write_keyword("USING SAMPLE");
4691 self.generate_sample_body(sample)?;
4692 } else {
4693 self.write_keyword("TABLESAMPLE");
4694
4695 let snowflake_bernoulli =
4697 matches!(self.config.dialect, Some(DialectType::Snowflake))
4698 && !sample.explicit_method;
4699 if snowflake_bernoulli {
4700 self.write_space();
4701 self.write_keyword("BERNOULLI");
4702 }
4703
4704 if matches!(sample.method, SampleMethod::Bucket) {
4706 self.write_space();
4707 self.write("(");
4708 self.write_keyword("BUCKET");
4709 self.write_space();
4710 if let Some(ref num) = sample.bucket_numerator {
4711 self.generate_expression(num)?;
4712 }
4713 self.write_space();
4714 self.write_keyword("OUT OF");
4715 self.write_space();
4716 if let Some(ref denom) = sample.bucket_denominator {
4717 self.generate_expression(denom)?;
4718 }
4719 if let Some(ref field) = sample.bucket_field {
4720 self.write_space();
4721 self.write_keyword("ON");
4722 self.write_space();
4723 self.generate_expression(field)?;
4724 }
4725 self.write(")");
4726 } else if sample.unit_after_size {
4727 if sample.explicit_method && sample.method_before_size {
4729 self.write_space();
4730 match sample.method {
4731 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
4732 SampleMethod::System => self.write_keyword("SYSTEM"),
4733 SampleMethod::Block => self.write_keyword("BLOCK"),
4734 SampleMethod::Row => self.write_keyword("ROW"),
4735 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
4736 _ => {}
4737 }
4738 }
4739 self.write(" (");
4740 self.generate_expression(&sample.size)?;
4741 self.write_space();
4742 match sample.method {
4743 SampleMethod::Percent => self.write_keyword("PERCENT"),
4744 SampleMethod::Row => self.write_keyword("ROWS"),
4745 SampleMethod::Reservoir => self.write_keyword("ROWS"),
4746 _ => {
4747 self.write_keyword("PERCENT");
4748 }
4749 }
4750 self.write(")");
4751 } else {
4752 self.write_space();
4754 match sample.method {
4755 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
4756 SampleMethod::System => self.write_keyword("SYSTEM"),
4757 SampleMethod::Block => self.write_keyword("BLOCK"),
4758 SampleMethod::Row => self.write_keyword("ROW"),
4759 SampleMethod::Percent => self.write_keyword("BERNOULLI"),
4760 SampleMethod::Bucket => {}
4761 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
4762 }
4763 self.write(" (");
4764 self.generate_expression(&sample.size)?;
4765 if matches!(sample.method, SampleMethod::Percent) {
4766 self.write_space();
4767 self.write_keyword("PERCENT");
4768 }
4769 self.write(")");
4770 }
4771 }
4772
4773 if let Some(seed) = &sample.seed {
4774 self.write_space();
4775 let use_seed = sample.use_seed_keyword
4777 && !matches!(
4778 self.config.dialect,
4779 Some(crate::dialects::DialectType::Databricks)
4780 | Some(crate::dialects::DialectType::Spark)
4781 );
4782 if use_seed {
4783 self.write_keyword("SEED");
4784 } else {
4785 self.write_keyword("REPEATABLE");
4786 }
4787 self.write(" (");
4788 self.generate_expression(seed)?;
4789 self.write(")");
4790 }
4791 }
4792
4793 if self.config.locking_reads_supported {
4796 for lock in &select.locks {
4797 if self.config.pretty {
4798 self.write_newline();
4799 self.write_indent();
4800 } else {
4801 self.write_space();
4802 }
4803 self.generate_lock(lock)?;
4804 }
4805 }
4806
4807 if !select.for_xml.is_empty() {
4809 if self.config.pretty {
4810 self.write_newline();
4811 self.write_indent();
4812 } else {
4813 self.write_space();
4814 }
4815 self.write_keyword("FOR XML");
4816 for (i, opt) in select.for_xml.iter().enumerate() {
4817 if self.config.pretty {
4818 if i > 0 {
4819 self.write(",");
4820 }
4821 self.write_newline();
4822 self.write_indent();
4823 self.write(" "); } else {
4825 if i > 0 {
4826 self.write(",");
4827 }
4828 self.write_space();
4829 }
4830 self.generate_for_xml_option(opt)?;
4831 }
4832 }
4833
4834 if let Some(ref option) = select.option {
4836 if matches!(
4837 self.config.dialect,
4838 Some(crate::dialects::DialectType::TSQL)
4839 | Some(crate::dialects::DialectType::Fabric)
4840 ) {
4841 self.write_space();
4842 self.write(option);
4843 }
4844 }
4845
4846 Ok(())
4847 }
4848
4849 fn generate_for_xml_option(&mut self, opt: &Expression) -> Result<()> {
4851 match opt {
4852 Expression::QueryOption(qo) => {
4853 if let Expression::Var(var) = &*qo.this {
4855 self.write(&var.this);
4856 } else {
4857 self.generate_expression(&qo.this)?;
4858 }
4859 if let Some(expr) = &qo.expression {
4861 self.write("(");
4862 self.generate_expression(expr)?;
4863 self.write(")");
4864 }
4865 }
4866 _ => {
4867 self.generate_expression(opt)?;
4868 }
4869 }
4870 Ok(())
4871 }
4872
4873 fn generate_with(&mut self, with: &With) -> Result<()> {
4874 use crate::dialects::DialectType;
4875
4876 for comment in &with.leading_comments {
4878 self.write_formatted_comment(comment);
4879 self.write(" ");
4880 }
4881 self.write_keyword("WITH");
4882 if with.recursive && self.config.cte_recursive_keyword_required {
4883 self.write_space();
4884 self.write_keyword("RECURSIVE");
4885 }
4886 self.write_space();
4887
4888 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
4890
4891 for (i, cte) in with.ctes.iter().enumerate() {
4892 if i > 0 {
4893 self.write(",");
4894 if self.config.pretty {
4895 self.write_space();
4896 } else {
4897 self.write(" ");
4898 }
4899 }
4900 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !cte.alias_first {
4901 self.generate_expression(&cte.this)?;
4902 self.write_space();
4903 self.write_keyword("AS");
4904 self.write_space();
4905 self.generate_identifier(&cte.alias)?;
4906 continue;
4907 }
4908 self.generate_identifier(&cte.alias)?;
4909 for comment in &cte.comments {
4911 self.write_space();
4912 self.write_formatted_comment(comment);
4913 }
4914 if !cte.columns.is_empty() && !skip_cte_columns {
4915 self.write("(");
4916 for (j, col) in cte.columns.iter().enumerate() {
4917 if j > 0 {
4918 self.write(", ");
4919 }
4920 self.generate_identifier(col)?;
4921 }
4922 self.write(")");
4923 }
4924 if !cte.key_expressions.is_empty() {
4926 self.write_space();
4927 self.write_keyword("USING KEY");
4928 self.write(" (");
4929 for (i, key) in cte.key_expressions.iter().enumerate() {
4930 if i > 0 {
4931 self.write(", ");
4932 }
4933 self.generate_identifier(key)?;
4934 }
4935 self.write(")");
4936 }
4937 self.write_space();
4938 self.write_keyword("AS");
4939 if let Some(materialized) = cte.materialized {
4941 self.write_space();
4942 if materialized {
4943 self.write_keyword("MATERIALIZED");
4944 } else {
4945 self.write_keyword("NOT MATERIALIZED");
4946 }
4947 }
4948 self.write(" (");
4949 if self.config.pretty {
4950 self.write_newline();
4951 self.indent_level += 1;
4952 self.write_indent();
4953 }
4954 let wrap_values_in_select = matches!(
4957 self.config.dialect,
4958 Some(DialectType::Spark) | Some(DialectType::Databricks)
4959 ) && matches!(&cte.this, Expression::Values(_));
4960
4961 if wrap_values_in_select {
4962 self.write_keyword("SELECT");
4963 self.write(" * ");
4964 self.write_keyword("FROM");
4965 self.write_space();
4966 }
4967 self.generate_expression(&cte.this)?;
4968 if self.config.pretty {
4969 self.write_newline();
4970 self.indent_level -= 1;
4971 self.write_indent();
4972 }
4973 self.write(")");
4974 }
4975
4976 if let Some(search) = &with.search {
4978 self.write_space();
4979 self.generate_expression(search)?;
4980 }
4981
4982 Ok(())
4983 }
4984
4985 fn generate_joins_with_nesting(&mut self, joins: &[Join]) -> Result<()> {
4989 let mut i = 0;
4990 while i < joins.len() {
4991 if joins[i].deferred_condition {
4992 let parent_group = joins[i].nesting_group;
4993
4994 self.generate_join_without_condition(&joins[i])?;
4997
4998 let child_start = i + 1;
5000 let mut child_end = child_start;
5001 while child_end < joins.len()
5002 && !joins[child_end].deferred_condition
5003 && joins[child_end].nesting_group == parent_group
5004 {
5005 child_end += 1;
5006 }
5007
5008 if child_start < child_end {
5010 self.indent_level += 1;
5011 for j in child_start..child_end {
5012 self.generate_join(&joins[j])?;
5013 }
5014 self.indent_level -= 1;
5015 }
5016
5017 self.generate_join_condition(&joins[i])?;
5019
5020 i = child_end;
5021 } else {
5022 self.generate_join(&joins[i])?;
5024 i += 1;
5025 }
5026 }
5027 Ok(())
5028 }
5029
5030 fn generate_join_without_condition(&mut self, join: &Join) -> Result<()> {
5033 let mut join_copy = join.clone();
5036 join_copy.on = None;
5037 join_copy.using = Vec::new();
5038 join_copy.deferred_condition = false;
5039 self.generate_join(&join_copy)
5040 }
5041
5042 fn generate_join(&mut self, join: &Join) -> Result<()> {
5043 if join.kind == JoinKind::Implicit {
5045 self.write(",");
5046 if self.config.pretty {
5047 self.write_newline();
5048 self.write_indent();
5049 } else {
5050 self.write_space();
5051 }
5052 self.generate_expression(&join.this)?;
5053 return Ok(());
5054 }
5055
5056 if self.config.pretty {
5057 self.write_newline();
5058 self.write_indent();
5059 } else {
5060 self.write_space();
5061 }
5062
5063 let hint_str = if self.config.join_hints {
5066 join.join_hint
5067 .as_ref()
5068 .map(|h| format!(" {}", h))
5069 .unwrap_or_default()
5070 } else {
5071 String::new()
5072 };
5073
5074 let clickhouse_join_keyword =
5075 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
5076 if let Some(hint) = &join.join_hint {
5077 let mut global = false;
5078 let mut strictness: Option<&'static str> = None;
5079 for part in hint.split_whitespace() {
5080 match part.to_uppercase().as_str() {
5081 "GLOBAL" => global = true,
5082 "ANY" => strictness = Some("ANY"),
5083 "ASOF" => strictness = Some("ASOF"),
5084 "SEMI" => strictness = Some("SEMI"),
5085 "ANTI" => strictness = Some("ANTI"),
5086 _ => {}
5087 }
5088 }
5089
5090 if global || strictness.is_some() {
5091 let join_type = match join.kind {
5092 JoinKind::Left => {
5093 if join.use_outer_keyword {
5094 "LEFT OUTER"
5095 } else if join.use_inner_keyword {
5096 "LEFT INNER"
5097 } else {
5098 "LEFT"
5099 }
5100 }
5101 JoinKind::Right => {
5102 if join.use_outer_keyword {
5103 "RIGHT OUTER"
5104 } else if join.use_inner_keyword {
5105 "RIGHT INNER"
5106 } else {
5107 "RIGHT"
5108 }
5109 }
5110 JoinKind::Full => {
5111 if join.use_outer_keyword {
5112 "FULL OUTER"
5113 } else {
5114 "FULL"
5115 }
5116 }
5117 JoinKind::Inner => {
5118 if join.use_inner_keyword {
5119 "INNER"
5120 } else {
5121 ""
5122 }
5123 }
5124 _ => "",
5125 };
5126
5127 let mut parts = Vec::new();
5128 if global {
5129 parts.push("GLOBAL");
5130 }
5131 if !join_type.is_empty() {
5132 parts.push(join_type);
5133 }
5134 if let Some(strict) = strictness {
5135 parts.push(strict);
5136 }
5137 parts.push("JOIN");
5138 Some(parts.join(" "))
5139 } else {
5140 None
5141 }
5142 } else {
5143 None
5144 }
5145 } else {
5146 None
5147 };
5148
5149 if !join.comments.is_empty() {
5153 if self.config.pretty {
5154 let trimmed = self.output.trim_end().len();
5159 self.output.truncate(trimmed);
5160 for comment in &join.comments {
5161 self.write_newline();
5162 self.write_indent();
5163 self.write_formatted_comment(comment);
5164 }
5165 self.write_newline();
5166 self.write_indent();
5167 } else {
5168 for comment in &join.comments {
5169 self.write_formatted_comment(comment);
5170 self.write_space();
5171 }
5172 }
5173 }
5174
5175 let directed_str = if join.directed { " DIRECTED" } else { "" };
5176
5177 if let Some(keyword) = clickhouse_join_keyword {
5178 self.write_keyword(&keyword);
5179 } else {
5180 match join.kind {
5181 JoinKind::Inner => {
5182 if join.use_inner_keyword {
5183 self.write_keyword(&format!("INNER{}{} JOIN", hint_str, directed_str));
5184 } else {
5185 self.write_keyword(&format!(
5186 "{}{}JOIN",
5187 if hint_str.is_empty() {
5188 String::new()
5189 } else {
5190 format!("{} ", hint_str.trim())
5191 },
5192 if directed_str.is_empty() {
5193 ""
5194 } else {
5195 "DIRECTED "
5196 }
5197 ));
5198 }
5199 }
5200 JoinKind::Left => {
5201 if join.use_outer_keyword {
5202 self.write_keyword(&format!("LEFT OUTER{}{} JOIN", hint_str, directed_str));
5203 } else if join.use_inner_keyword {
5204 self.write_keyword(&format!("LEFT INNER{}{} JOIN", hint_str, directed_str));
5205 } else {
5206 self.write_keyword(&format!("LEFT{}{} JOIN", hint_str, directed_str));
5207 }
5208 }
5209 JoinKind::Right => {
5210 if join.use_outer_keyword {
5211 self.write_keyword(&format!(
5212 "RIGHT OUTER{}{} JOIN",
5213 hint_str, directed_str
5214 ));
5215 } else if join.use_inner_keyword {
5216 self.write_keyword(&format!(
5217 "RIGHT INNER{}{} JOIN",
5218 hint_str, directed_str
5219 ));
5220 } else {
5221 self.write_keyword(&format!("RIGHT{}{} JOIN", hint_str, directed_str));
5222 }
5223 }
5224 JoinKind::Full => {
5225 if join.use_outer_keyword {
5226 self.write_keyword(&format!("FULL OUTER{}{} JOIN", hint_str, directed_str));
5227 } else {
5228 self.write_keyword(&format!("FULL{}{} JOIN", hint_str, directed_str));
5229 }
5230 }
5231 JoinKind::Outer => self.write_keyword(&format!("OUTER{} JOIN", directed_str)),
5232 JoinKind::Cross => self.write_keyword(&format!("CROSS{} JOIN", directed_str)),
5233 JoinKind::Natural => {
5234 if join.use_inner_keyword {
5235 self.write_keyword(&format!("NATURAL INNER{} JOIN", directed_str));
5236 } else {
5237 self.write_keyword(&format!("NATURAL{} JOIN", directed_str));
5238 }
5239 }
5240 JoinKind::NaturalLeft => {
5241 if join.use_outer_keyword {
5242 self.write_keyword(&format!("NATURAL LEFT OUTER{} JOIN", directed_str));
5243 } else {
5244 self.write_keyword(&format!("NATURAL LEFT{} JOIN", directed_str));
5245 }
5246 }
5247 JoinKind::NaturalRight => {
5248 if join.use_outer_keyword {
5249 self.write_keyword(&format!("NATURAL RIGHT OUTER{} JOIN", directed_str));
5250 } else {
5251 self.write_keyword(&format!("NATURAL RIGHT{} JOIN", directed_str));
5252 }
5253 }
5254 JoinKind::NaturalFull => {
5255 if join.use_outer_keyword {
5256 self.write_keyword(&format!("NATURAL FULL OUTER{} JOIN", directed_str));
5257 } else {
5258 self.write_keyword(&format!("NATURAL FULL{} JOIN", directed_str));
5259 }
5260 }
5261 JoinKind::Semi => self.write_keyword("SEMI JOIN"),
5262 JoinKind::Anti => self.write_keyword("ANTI JOIN"),
5263 JoinKind::LeftSemi => self.write_keyword("LEFT SEMI JOIN"),
5264 JoinKind::LeftAnti => self.write_keyword("LEFT ANTI JOIN"),
5265 JoinKind::RightSemi => self.write_keyword("RIGHT SEMI JOIN"),
5266 JoinKind::RightAnti => self.write_keyword("RIGHT ANTI JOIN"),
5267 JoinKind::CrossApply => {
5268 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
5270 self.write_keyword("CROSS APPLY");
5271 } else {
5272 self.write_keyword("INNER JOIN LATERAL");
5273 }
5274 }
5275 JoinKind::OuterApply => {
5276 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
5278 self.write_keyword("OUTER APPLY");
5279 } else {
5280 self.write_keyword("LEFT JOIN LATERAL");
5281 }
5282 }
5283 JoinKind::AsOf => self.write_keyword("ASOF JOIN"),
5284 JoinKind::AsOfLeft => {
5285 if join.use_outer_keyword {
5286 self.write_keyword("ASOF LEFT OUTER JOIN");
5287 } else {
5288 self.write_keyword("ASOF LEFT JOIN");
5289 }
5290 }
5291 JoinKind::AsOfRight => {
5292 if join.use_outer_keyword {
5293 self.write_keyword("ASOF RIGHT OUTER JOIN");
5294 } else {
5295 self.write_keyword("ASOF RIGHT JOIN");
5296 }
5297 }
5298 JoinKind::Lateral => self.write_keyword("LATERAL JOIN"),
5299 JoinKind::LeftLateral => {
5300 if join.use_outer_keyword {
5301 self.write_keyword("LEFT OUTER LATERAL JOIN");
5302 } else {
5303 self.write_keyword("LEFT LATERAL JOIN");
5304 }
5305 }
5306 JoinKind::Straight => self.write_keyword("STRAIGHT_JOIN"),
5307 JoinKind::Implicit => {
5308 use crate::dialects::DialectType;
5312 let is_cj_dialect = matches!(
5313 self.config.dialect,
5314 Some(DialectType::BigQuery)
5315 | Some(DialectType::Hive)
5316 | Some(DialectType::Spark)
5317 | Some(DialectType::Databricks)
5318 );
5319 let source_is_same = self.config.source_dialect.is_some()
5320 && self.config.source_dialect == self.config.dialect;
5321 let source_is_cj = matches!(
5322 self.config.source_dialect,
5323 Some(DialectType::BigQuery)
5324 | Some(DialectType::Hive)
5325 | Some(DialectType::Spark)
5326 | Some(DialectType::Databricks)
5327 );
5328 if is_cj_dialect
5329 && (source_is_same || source_is_cj || self.config.source_dialect.is_none())
5330 {
5331 self.write_keyword("CROSS JOIN");
5332 } else {
5333 self.output.truncate(self.output.trim_end().len());
5337 self.write(",");
5338 }
5339 }
5340 JoinKind::Array => self.write_keyword("ARRAY JOIN"),
5341 JoinKind::LeftArray => self.write_keyword("LEFT ARRAY JOIN"),
5342 JoinKind::Paste => self.write_keyword("PASTE JOIN"),
5343 }
5344 }
5345
5346 if matches!(join.kind, JoinKind::Array | JoinKind::LeftArray) {
5348 self.write_space();
5349 match &join.this {
5350 Expression::Tuple(t) => {
5351 for (i, item) in t.expressions.iter().enumerate() {
5352 if i > 0 {
5353 self.write(", ");
5354 }
5355 self.generate_expression(item)?;
5356 }
5357 }
5358 other => {
5359 self.generate_expression(other)?;
5360 }
5361 }
5362 } else {
5363 self.write_space();
5364 self.generate_expression(&join.this)?;
5365 }
5366
5367 if !join.deferred_condition {
5369 if let Some(match_cond) = &join.match_condition {
5371 self.write_space();
5372 self.write_keyword("MATCH_CONDITION");
5373 self.write(" (");
5374 self.generate_expression(match_cond)?;
5375 self.write(")");
5376 }
5377
5378 if let Some(on) = &join.on {
5379 if self.config.pretty {
5380 self.write_newline();
5381 self.indent_level += 1;
5382 self.write_indent();
5383 self.write_keyword("ON");
5384 self.write_space();
5385 self.generate_join_on_condition(on)?;
5386 self.indent_level -= 1;
5387 } else {
5388 self.write_space();
5389 self.write_keyword("ON");
5390 self.write_space();
5391 self.generate_expression(on)?;
5392 }
5393 }
5394
5395 if !join.using.is_empty() {
5396 if self.config.pretty {
5397 self.write_newline();
5398 self.indent_level += 1;
5399 self.write_indent();
5400 self.write_keyword("USING");
5401 self.write(" (");
5402 for (i, col) in join.using.iter().enumerate() {
5403 if i > 0 {
5404 self.write(", ");
5405 }
5406 self.generate_identifier(col)?;
5407 }
5408 self.write(")");
5409 self.indent_level -= 1;
5410 } else {
5411 self.write_space();
5412 self.write_keyword("USING");
5413 self.write(" (");
5414 for (i, col) in join.using.iter().enumerate() {
5415 if i > 0 {
5416 self.write(", ");
5417 }
5418 self.generate_identifier(col)?;
5419 }
5420 self.write(")");
5421 }
5422 }
5423 }
5424
5425 for pivot in &join.pivots {
5427 self.write_space();
5428 self.generate_expression(pivot)?;
5429 }
5430
5431 Ok(())
5432 }
5433
5434 fn generate_join_condition(&mut self, join: &Join) -> Result<()> {
5436 if let Some(match_cond) = &join.match_condition {
5438 self.write_space();
5439 self.write_keyword("MATCH_CONDITION");
5440 self.write(" (");
5441 self.generate_expression(match_cond)?;
5442 self.write(")");
5443 }
5444
5445 if let Some(on) = &join.on {
5446 if self.config.pretty {
5447 self.write_newline();
5448 self.indent_level += 1;
5449 self.write_indent();
5450 self.write_keyword("ON");
5451 self.write_space();
5452 self.generate_join_on_condition(on)?;
5454 self.indent_level -= 1;
5455 } else {
5456 self.write_space();
5457 self.write_keyword("ON");
5458 self.write_space();
5459 self.generate_expression(on)?;
5460 }
5461 }
5462
5463 if !join.using.is_empty() {
5464 if self.config.pretty {
5465 self.write_newline();
5466 self.indent_level += 1;
5467 self.write_indent();
5468 self.write_keyword("USING");
5469 self.write(" (");
5470 for (i, col) in join.using.iter().enumerate() {
5471 if i > 0 {
5472 self.write(", ");
5473 }
5474 self.generate_identifier(col)?;
5475 }
5476 self.write(")");
5477 self.indent_level -= 1;
5478 } else {
5479 self.write_space();
5480 self.write_keyword("USING");
5481 self.write(" (");
5482 for (i, col) in join.using.iter().enumerate() {
5483 if i > 0 {
5484 self.write(", ");
5485 }
5486 self.generate_identifier(col)?;
5487 }
5488 self.write(")");
5489 }
5490 }
5491
5492 for pivot in &join.pivots {
5494 self.write_space();
5495 self.generate_expression(pivot)?;
5496 }
5497
5498 Ok(())
5499 }
5500
5501 fn generate_join_on_condition(&mut self, expr: &Expression) -> Result<()> {
5503 if let Expression::And(and_op) = expr {
5504 if let Some(conditions) = self.flatten_connector_terms(and_op, ConnectorOperator::And) {
5505 self.generate_expression(conditions[0])?;
5506 for condition in conditions.iter().skip(1) {
5507 self.write_newline();
5508 self.write_indent();
5509 self.write_keyword("AND");
5510 self.write_space();
5511 self.generate_expression(condition)?;
5512 }
5513 return Ok(());
5514 }
5515 }
5516
5517 self.generate_expression(expr)
5518 }
5519
5520 fn generate_joined_table(&mut self, jt: &JoinedTable) -> Result<()> {
5521 self.write("(");
5523 self.generate_expression(&jt.left)?;
5524
5525 for join in &jt.joins {
5527 self.generate_join(join)?;
5528 }
5529
5530 for lv in &jt.lateral_views {
5532 self.generate_lateral_view(lv)?;
5533 }
5534
5535 self.write(")");
5536
5537 if let Some(alias) = &jt.alias {
5539 self.write_space();
5540 self.write_keyword("AS");
5541 self.write_space();
5542 self.generate_identifier(alias)?;
5543 }
5544
5545 Ok(())
5546 }
5547
5548 fn generate_lateral_view(&mut self, lv: &LateralView) -> Result<()> {
5549 use crate::dialects::DialectType;
5550
5551 if self.config.pretty {
5552 self.write_newline();
5553 self.write_indent();
5554 } else {
5555 self.write_space();
5556 }
5557
5558 let use_lateral_join = matches!(
5561 self.config.dialect,
5562 Some(DialectType::PostgreSQL)
5563 | Some(DialectType::DuckDB)
5564 | Some(DialectType::Snowflake)
5565 | Some(DialectType::TSQL)
5566 | Some(DialectType::Presto)
5567 | Some(DialectType::Trino)
5568 | Some(DialectType::Athena)
5569 );
5570
5571 let use_unnest = matches!(
5573 self.config.dialect,
5574 Some(DialectType::DuckDB)
5575 | Some(DialectType::Presto)
5576 | Some(DialectType::Trino)
5577 | Some(DialectType::Athena)
5578 );
5579
5580 let (is_posexplode, func_args) = match &lv.this {
5582 Expression::Explode(uf) => {
5583 (false, vec![uf.this.clone()])
5585 }
5586 Expression::Unnest(uf) => {
5587 let mut args = vec![uf.this.clone()];
5588 args.extend(uf.expressions.clone());
5589 (false, args)
5590 }
5591 Expression::Function(func) => {
5592 let name = func.name.to_uppercase();
5593 if name == "POSEXPLODE" || name == "POSEXPLODE_OUTER" {
5594 (true, func.args.clone())
5595 } else if name == "EXPLODE" || name == "EXPLODE_OUTER" || name == "INLINE" {
5596 (false, func.args.clone())
5597 } else {
5598 (false, vec![])
5599 }
5600 }
5601 _ => (false, vec![]),
5602 };
5603
5604 if use_lateral_join {
5605 if lv.outer {
5607 self.write_keyword("LEFT JOIN LATERAL");
5608 } else {
5609 self.write_keyword("CROSS JOIN");
5610 }
5611 self.write_space();
5612
5613 if use_unnest && !func_args.is_empty() {
5614 let unnest_args = if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
5617 func_args
5619 .iter()
5620 .map(|a| {
5621 if let Expression::Function(ref f) = a {
5622 if f.name.to_uppercase() == "ARRAY" && f.args.len() == 1 {
5623 return Expression::ArrayFunc(Box::new(
5624 crate::expressions::ArrayConstructor {
5625 expressions: f.args.clone(),
5626 bracket_notation: true,
5627 use_list_keyword: false,
5628 },
5629 ));
5630 }
5631 }
5632 a.clone()
5633 })
5634 .collect::<Vec<_>>()
5635 } else if matches!(
5636 self.config.dialect,
5637 Some(DialectType::Presto)
5638 | Some(DialectType::Trino)
5639 | Some(DialectType::Athena)
5640 ) {
5641 func_args
5643 .iter()
5644 .map(|a| {
5645 if let Expression::Function(ref f) = a {
5646 if f.name.to_uppercase() == "ARRAY" && f.args.len() >= 1 {
5647 return Expression::ArrayFunc(Box::new(
5648 crate::expressions::ArrayConstructor {
5649 expressions: f.args.clone(),
5650 bracket_notation: true,
5651 use_list_keyword: false,
5652 },
5653 ));
5654 }
5655 }
5656 a.clone()
5657 })
5658 .collect::<Vec<_>>()
5659 } else {
5660 func_args
5661 };
5662
5663 if is_posexplode {
5665 self.write_keyword("LATERAL");
5666 self.write(" (");
5667 self.write_keyword("SELECT");
5668 self.write_space();
5669
5670 let pos_alias = if !lv.column_aliases.is_empty() {
5673 lv.column_aliases[0].clone()
5674 } else {
5675 Identifier::new("pos")
5676 };
5677 let data_aliases: Vec<Identifier> = if lv.column_aliases.len() > 1 {
5678 lv.column_aliases[1..].to_vec()
5679 } else {
5680 vec![Identifier::new("col")]
5681 };
5682
5683 self.generate_identifier(&pos_alias)?;
5685 self.write(" - 1");
5686 self.write_space();
5687 self.write_keyword("AS");
5688 self.write_space();
5689 self.generate_identifier(&pos_alias)?;
5690
5691 for data_col in &data_aliases {
5693 self.write(", ");
5694 self.generate_identifier(data_col)?;
5695 }
5696
5697 self.write_space();
5698 self.write_keyword("FROM");
5699 self.write_space();
5700 self.write_keyword("UNNEST");
5701 self.write("(");
5702 for (i, arg) in unnest_args.iter().enumerate() {
5703 if i > 0 {
5704 self.write(", ");
5705 }
5706 self.generate_expression(arg)?;
5707 }
5708 self.write(")");
5709 self.write_space();
5710 self.write_keyword("WITH ORDINALITY");
5711 self.write_space();
5712 self.write_keyword("AS");
5713 self.write_space();
5714
5715 let table_alias_ident = lv
5717 .table_alias
5718 .clone()
5719 .unwrap_or_else(|| Identifier::new("t"));
5720 self.generate_identifier(&table_alias_ident)?;
5721 self.write("(");
5722 for (i, data_col) in data_aliases.iter().enumerate() {
5723 if i > 0 {
5724 self.write(", ");
5725 }
5726 self.generate_identifier(data_col)?;
5727 }
5728 self.write(", ");
5729 self.generate_identifier(&pos_alias)?;
5730 self.write("))");
5731 } else {
5732 self.write_keyword("UNNEST");
5733 self.write("(");
5734 for (i, arg) in unnest_args.iter().enumerate() {
5735 if i > 0 {
5736 self.write(", ");
5737 }
5738 self.generate_expression(arg)?;
5739 }
5740 self.write(")");
5741
5742 if let Some(alias) = &lv.table_alias {
5744 self.write_space();
5745 self.write_keyword("AS");
5746 self.write_space();
5747 self.generate_identifier(alias)?;
5748 if !lv.column_aliases.is_empty() {
5749 self.write("(");
5750 for (i, col) in lv.column_aliases.iter().enumerate() {
5751 if i > 0 {
5752 self.write(", ");
5753 }
5754 self.generate_identifier(col)?;
5755 }
5756 self.write(")");
5757 }
5758 } else if !lv.column_aliases.is_empty() {
5759 self.write_space();
5760 self.write_keyword("AS");
5761 self.write(" t(");
5762 for (i, col) in lv.column_aliases.iter().enumerate() {
5763 if i > 0 {
5764 self.write(", ");
5765 }
5766 self.generate_identifier(col)?;
5767 }
5768 self.write(")");
5769 }
5770 }
5771 } else {
5772 if !lv.outer {
5774 self.write_keyword("LATERAL");
5775 self.write_space();
5776 }
5777 self.generate_expression(&lv.this)?;
5778
5779 if let Some(alias) = &lv.table_alias {
5781 self.write_space();
5782 self.write_keyword("AS");
5783 self.write_space();
5784 self.generate_identifier(alias)?;
5785 if !lv.column_aliases.is_empty() {
5786 self.write("(");
5787 for (i, col) in lv.column_aliases.iter().enumerate() {
5788 if i > 0 {
5789 self.write(", ");
5790 }
5791 self.generate_identifier(col)?;
5792 }
5793 self.write(")");
5794 }
5795 } else if !lv.column_aliases.is_empty() {
5796 self.write_space();
5797 self.write_keyword("AS");
5798 self.write(" t(");
5799 for (i, col) in lv.column_aliases.iter().enumerate() {
5800 if i > 0 {
5801 self.write(", ");
5802 }
5803 self.generate_identifier(col)?;
5804 }
5805 self.write(")");
5806 }
5807 }
5808
5809 if lv.outer {
5811 self.write_space();
5812 self.write_keyword("ON TRUE");
5813 }
5814 } else {
5815 self.write_keyword("LATERAL VIEW");
5817 if lv.outer {
5818 self.write_space();
5819 self.write_keyword("OUTER");
5820 }
5821 if self.config.pretty {
5822 self.write_newline();
5823 self.write_indent();
5824 } else {
5825 self.write_space();
5826 }
5827 self.generate_expression(&lv.this)?;
5828
5829 if let Some(alias) = &lv.table_alias {
5831 self.write_space();
5832 self.generate_identifier(alias)?;
5833 }
5834
5835 if !lv.column_aliases.is_empty() {
5837 self.write_space();
5838 self.write_keyword("AS");
5839 self.write_space();
5840 for (i, col) in lv.column_aliases.iter().enumerate() {
5841 if i > 0 {
5842 self.write(", ");
5843 }
5844 self.generate_identifier(col)?;
5845 }
5846 }
5847 }
5848
5849 Ok(())
5850 }
5851
5852 fn generate_union(&mut self, union: &Union) -> Result<()> {
5853 if let Some(with) = &union.with {
5855 self.generate_with(with)?;
5856 self.write_space();
5857 }
5858 self.generate_expression(&union.left)?;
5859 if self.config.pretty {
5860 self.write_newline();
5861 self.write_indent();
5862 } else {
5863 self.write_space();
5864 }
5865
5866 if let Some(side) = &union.side {
5868 self.write_keyword(side);
5869 self.write_space();
5870 }
5871 if let Some(kind) = &union.kind {
5872 self.write_keyword(kind);
5873 self.write_space();
5874 }
5875
5876 self.write_keyword("UNION");
5877 if union.all {
5878 self.write_space();
5879 self.write_keyword("ALL");
5880 } else if union.distinct {
5881 self.write_space();
5882 self.write_keyword("DISTINCT");
5883 }
5884
5885 if union.corresponding || union.by_name {
5888 self.write_space();
5889 self.write_keyword("BY NAME");
5890 }
5891 if !union.on_columns.is_empty() {
5892 self.write_space();
5893 self.write_keyword("ON");
5894 self.write(" (");
5895 for (i, col) in union.on_columns.iter().enumerate() {
5896 if i > 0 {
5897 self.write(", ");
5898 }
5899 self.generate_expression(col)?;
5900 }
5901 self.write(")");
5902 }
5903
5904 if self.config.pretty {
5905 self.write_newline();
5906 self.write_indent();
5907 } else {
5908 self.write_space();
5909 }
5910 self.generate_expression(&union.right)?;
5911 if let Some(order_by) = &union.order_by {
5913 if self.config.pretty {
5914 self.write_newline();
5915 } else {
5916 self.write_space();
5917 }
5918 self.write_keyword("ORDER BY");
5919 self.write_space();
5920 for (i, ordered) in order_by.expressions.iter().enumerate() {
5921 if i > 0 {
5922 self.write(", ");
5923 }
5924 self.generate_ordered(ordered)?;
5925 }
5926 }
5927 if let Some(limit) = &union.limit {
5928 if self.config.pretty {
5929 self.write_newline();
5930 } else {
5931 self.write_space();
5932 }
5933 self.write_keyword("LIMIT");
5934 self.write_space();
5935 self.generate_expression(limit)?;
5936 }
5937 if let Some(offset) = &union.offset {
5938 if self.config.pretty {
5939 self.write_newline();
5940 } else {
5941 self.write_space();
5942 }
5943 self.write_keyword("OFFSET");
5944 self.write_space();
5945 self.generate_expression(offset)?;
5946 }
5947 if let Some(distribute_by) = &union.distribute_by {
5949 self.write_space();
5950 self.write_keyword("DISTRIBUTE BY");
5951 self.write_space();
5952 for (i, expr) in distribute_by.expressions.iter().enumerate() {
5953 if i > 0 {
5954 self.write(", ");
5955 }
5956 self.generate_expression(expr)?;
5957 }
5958 }
5959 if let Some(sort_by) = &union.sort_by {
5961 self.write_space();
5962 self.write_keyword("SORT BY");
5963 self.write_space();
5964 for (i, ord) in sort_by.expressions.iter().enumerate() {
5965 if i > 0 {
5966 self.write(", ");
5967 }
5968 self.generate_ordered(ord)?;
5969 }
5970 }
5971 if let Some(cluster_by) = &union.cluster_by {
5973 self.write_space();
5974 self.write_keyword("CLUSTER BY");
5975 self.write_space();
5976 for (i, ord) in cluster_by.expressions.iter().enumerate() {
5977 if i > 0 {
5978 self.write(", ");
5979 }
5980 self.generate_ordered(ord)?;
5981 }
5982 }
5983 Ok(())
5984 }
5985
5986 fn generate_intersect(&mut self, intersect: &Intersect) -> Result<()> {
5987 if let Some(with) = &intersect.with {
5989 self.generate_with(with)?;
5990 self.write_space();
5991 }
5992 self.generate_expression(&intersect.left)?;
5993 if self.config.pretty {
5994 self.write_newline();
5995 self.write_indent();
5996 } else {
5997 self.write_space();
5998 }
5999
6000 if let Some(side) = &intersect.side {
6002 self.write_keyword(side);
6003 self.write_space();
6004 }
6005 if let Some(kind) = &intersect.kind {
6006 self.write_keyword(kind);
6007 self.write_space();
6008 }
6009
6010 self.write_keyword("INTERSECT");
6011 if intersect.all {
6012 self.write_space();
6013 self.write_keyword("ALL");
6014 } else if intersect.distinct {
6015 self.write_space();
6016 self.write_keyword("DISTINCT");
6017 }
6018
6019 if intersect.corresponding || intersect.by_name {
6022 self.write_space();
6023 self.write_keyword("BY NAME");
6024 }
6025 if !intersect.on_columns.is_empty() {
6026 self.write_space();
6027 self.write_keyword("ON");
6028 self.write(" (");
6029 for (i, col) in intersect.on_columns.iter().enumerate() {
6030 if i > 0 {
6031 self.write(", ");
6032 }
6033 self.generate_expression(col)?;
6034 }
6035 self.write(")");
6036 }
6037
6038 if self.config.pretty {
6039 self.write_newline();
6040 self.write_indent();
6041 } else {
6042 self.write_space();
6043 }
6044 self.generate_expression(&intersect.right)?;
6045 if let Some(order_by) = &intersect.order_by {
6047 if self.config.pretty {
6048 self.write_newline();
6049 } else {
6050 self.write_space();
6051 }
6052 self.write_keyword("ORDER BY");
6053 self.write_space();
6054 for (i, ordered) in order_by.expressions.iter().enumerate() {
6055 if i > 0 {
6056 self.write(", ");
6057 }
6058 self.generate_ordered(ordered)?;
6059 }
6060 }
6061 if let Some(limit) = &intersect.limit {
6062 if self.config.pretty {
6063 self.write_newline();
6064 } else {
6065 self.write_space();
6066 }
6067 self.write_keyword("LIMIT");
6068 self.write_space();
6069 self.generate_expression(limit)?;
6070 }
6071 if let Some(offset) = &intersect.offset {
6072 if self.config.pretty {
6073 self.write_newline();
6074 } else {
6075 self.write_space();
6076 }
6077 self.write_keyword("OFFSET");
6078 self.write_space();
6079 self.generate_expression(offset)?;
6080 }
6081 if let Some(distribute_by) = &intersect.distribute_by {
6083 self.write_space();
6084 self.write_keyword("DISTRIBUTE BY");
6085 self.write_space();
6086 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6087 if i > 0 {
6088 self.write(", ");
6089 }
6090 self.generate_expression(expr)?;
6091 }
6092 }
6093 if let Some(sort_by) = &intersect.sort_by {
6095 self.write_space();
6096 self.write_keyword("SORT BY");
6097 self.write_space();
6098 for (i, ord) in sort_by.expressions.iter().enumerate() {
6099 if i > 0 {
6100 self.write(", ");
6101 }
6102 self.generate_ordered(ord)?;
6103 }
6104 }
6105 if let Some(cluster_by) = &intersect.cluster_by {
6107 self.write_space();
6108 self.write_keyword("CLUSTER BY");
6109 self.write_space();
6110 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6111 if i > 0 {
6112 self.write(", ");
6113 }
6114 self.generate_ordered(ord)?;
6115 }
6116 }
6117 Ok(())
6118 }
6119
6120 fn generate_except(&mut self, except: &Except) -> Result<()> {
6121 use crate::dialects::DialectType;
6122
6123 if let Some(with) = &except.with {
6125 self.generate_with(with)?;
6126 self.write_space();
6127 }
6128
6129 self.generate_expression(&except.left)?;
6130 if self.config.pretty {
6131 self.write_newline();
6132 self.write_indent();
6133 } else {
6134 self.write_space();
6135 }
6136
6137 if let Some(side) = &except.side {
6139 self.write_keyword(side);
6140 self.write_space();
6141 }
6142 if let Some(kind) = &except.kind {
6143 self.write_keyword(kind);
6144 self.write_space();
6145 }
6146
6147 match self.config.dialect {
6149 Some(DialectType::Oracle) if !except.all => {
6150 self.write_keyword("MINUS");
6151 }
6152 Some(DialectType::ClickHouse) => {
6153 self.write_keyword("EXCEPT");
6155 if except.distinct {
6156 self.write_space();
6157 self.write_keyword("DISTINCT");
6158 }
6159 }
6160 Some(DialectType::BigQuery) => {
6161 self.write_keyword("EXCEPT");
6163 if except.all {
6164 self.write_space();
6165 self.write_keyword("ALL");
6166 } else {
6167 self.write_space();
6168 self.write_keyword("DISTINCT");
6169 }
6170 }
6171 _ => {
6172 self.write_keyword("EXCEPT");
6173 if except.all {
6174 self.write_space();
6175 self.write_keyword("ALL");
6176 } else if except.distinct {
6177 self.write_space();
6178 self.write_keyword("DISTINCT");
6179 }
6180 }
6181 }
6182
6183 if except.corresponding || except.by_name {
6186 self.write_space();
6187 self.write_keyword("BY NAME");
6188 }
6189 if !except.on_columns.is_empty() {
6190 self.write_space();
6191 self.write_keyword("ON");
6192 self.write(" (");
6193 for (i, col) in except.on_columns.iter().enumerate() {
6194 if i > 0 {
6195 self.write(", ");
6196 }
6197 self.generate_expression(col)?;
6198 }
6199 self.write(")");
6200 }
6201
6202 if self.config.pretty {
6203 self.write_newline();
6204 self.write_indent();
6205 } else {
6206 self.write_space();
6207 }
6208 self.generate_expression(&except.right)?;
6209 if let Some(order_by) = &except.order_by {
6211 if self.config.pretty {
6212 self.write_newline();
6213 } else {
6214 self.write_space();
6215 }
6216 self.write_keyword("ORDER BY");
6217 self.write_space();
6218 for (i, ordered) in order_by.expressions.iter().enumerate() {
6219 if i > 0 {
6220 self.write(", ");
6221 }
6222 self.generate_ordered(ordered)?;
6223 }
6224 }
6225 if let Some(limit) = &except.limit {
6226 if self.config.pretty {
6227 self.write_newline();
6228 } else {
6229 self.write_space();
6230 }
6231 self.write_keyword("LIMIT");
6232 self.write_space();
6233 self.generate_expression(limit)?;
6234 }
6235 if let Some(offset) = &except.offset {
6236 if self.config.pretty {
6237 self.write_newline();
6238 } else {
6239 self.write_space();
6240 }
6241 self.write_keyword("OFFSET");
6242 self.write_space();
6243 self.generate_expression(offset)?;
6244 }
6245 if let Some(distribute_by) = &except.distribute_by {
6247 self.write_space();
6248 self.write_keyword("DISTRIBUTE BY");
6249 self.write_space();
6250 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6251 if i > 0 {
6252 self.write(", ");
6253 }
6254 self.generate_expression(expr)?;
6255 }
6256 }
6257 if let Some(sort_by) = &except.sort_by {
6259 self.write_space();
6260 self.write_keyword("SORT BY");
6261 self.write_space();
6262 for (i, ord) in sort_by.expressions.iter().enumerate() {
6263 if i > 0 {
6264 self.write(", ");
6265 }
6266 self.generate_ordered(ord)?;
6267 }
6268 }
6269 if let Some(cluster_by) = &except.cluster_by {
6271 self.write_space();
6272 self.write_keyword("CLUSTER BY");
6273 self.write_space();
6274 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6275 if i > 0 {
6276 self.write(", ");
6277 }
6278 self.generate_ordered(ord)?;
6279 }
6280 }
6281 Ok(())
6282 }
6283
6284 fn generate_insert(&mut self, insert: &Insert) -> Result<()> {
6285 let prepend_query_cte = if insert.with.is_none() {
6287 use crate::dialects::DialectType;
6288 let should_prepend = matches!(
6289 self.config.dialect,
6290 Some(DialectType::TSQL)
6291 | Some(DialectType::Fabric)
6292 | Some(DialectType::Spark)
6293 | Some(DialectType::Databricks)
6294 | Some(DialectType::Hive)
6295 );
6296 if should_prepend {
6297 if let Some(Expression::Select(select)) = &insert.query {
6298 select.with.clone()
6299 } else {
6300 None
6301 }
6302 } else {
6303 None
6304 }
6305 } else {
6306 None
6307 };
6308
6309 if let Some(with) = &insert.with {
6311 self.generate_with(with)?;
6312 self.write_space();
6313 } else if let Some(with) = &prepend_query_cte {
6314 self.generate_with(with)?;
6315 self.write_space();
6316 }
6317
6318 for comment in &insert.leading_comments {
6320 self.write_formatted_comment(comment);
6321 self.write(" ");
6322 }
6323
6324 if let Some(dir) = &insert.directory {
6326 self.write_keyword("INSERT OVERWRITE");
6327 if dir.local {
6328 self.write_space();
6329 self.write_keyword("LOCAL");
6330 }
6331 self.write_space();
6332 self.write_keyword("DIRECTORY");
6333 self.write_space();
6334 self.write("'");
6335 self.write(&dir.path);
6336 self.write("'");
6337
6338 if let Some(row_format) = &dir.row_format {
6340 self.write_space();
6341 self.write_keyword("ROW FORMAT");
6342 if row_format.delimited {
6343 self.write_space();
6344 self.write_keyword("DELIMITED");
6345 }
6346 if let Some(val) = &row_format.fields_terminated_by {
6347 self.write_space();
6348 self.write_keyword("FIELDS TERMINATED BY");
6349 self.write_space();
6350 self.write("'");
6351 self.write(val);
6352 self.write("'");
6353 }
6354 if let Some(val) = &row_format.collection_items_terminated_by {
6355 self.write_space();
6356 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
6357 self.write_space();
6358 self.write("'");
6359 self.write(val);
6360 self.write("'");
6361 }
6362 if let Some(val) = &row_format.map_keys_terminated_by {
6363 self.write_space();
6364 self.write_keyword("MAP KEYS TERMINATED BY");
6365 self.write_space();
6366 self.write("'");
6367 self.write(val);
6368 self.write("'");
6369 }
6370 if let Some(val) = &row_format.lines_terminated_by {
6371 self.write_space();
6372 self.write_keyword("LINES TERMINATED BY");
6373 self.write_space();
6374 self.write("'");
6375 self.write(val);
6376 self.write("'");
6377 }
6378 if let Some(val) = &row_format.null_defined_as {
6379 self.write_space();
6380 self.write_keyword("NULL DEFINED AS");
6381 self.write_space();
6382 self.write("'");
6383 self.write(val);
6384 self.write("'");
6385 }
6386 }
6387
6388 if let Some(format) = &dir.stored_as {
6390 self.write_space();
6391 self.write_keyword("STORED AS");
6392 self.write_space();
6393 self.write_keyword(format);
6394 }
6395
6396 if let Some(query) = &insert.query {
6398 self.write_space();
6399 self.generate_expression(query)?;
6400 }
6401
6402 return Ok(());
6403 }
6404
6405 if insert.is_replace {
6406 self.write_keyword("REPLACE INTO");
6408 } else if insert.overwrite {
6409 self.write_keyword("INSERT");
6411 if let Some(ref hint) = insert.hint {
6413 self.generate_hint(hint)?;
6414 }
6415 self.write(&self.config.insert_overwrite.to_uppercase());
6416 } else if let Some(ref action) = insert.conflict_action {
6417 self.write_keyword("INSERT OR");
6419 self.write_space();
6420 self.write_keyword(action);
6421 self.write_space();
6422 self.write_keyword("INTO");
6423 } else if insert.ignore {
6424 self.write_keyword("INSERT IGNORE INTO");
6426 } else {
6427 self.write_keyword("INSERT");
6428 if let Some(ref hint) = insert.hint {
6430 self.generate_hint(hint)?;
6431 }
6432 self.write_space();
6433 self.write_keyword("INTO");
6434 }
6435 if let Some(ref func) = insert.function_target {
6437 self.write_space();
6438 self.write_keyword("FUNCTION");
6439 self.write_space();
6440 self.generate_expression(func)?;
6441 } else {
6442 self.write_space();
6443 self.generate_table(&insert.table)?;
6444 }
6445
6446 if let Some(ref alias) = insert.alias {
6448 self.write_space();
6449 if insert.alias_explicit_as {
6450 self.write_keyword("AS");
6451 self.write_space();
6452 }
6453 self.generate_identifier(alias)?;
6454 }
6455
6456 if insert.if_exists {
6458 self.write_space();
6459 self.write_keyword("IF EXISTS");
6460 }
6461
6462 if let Some(ref replace_where) = insert.replace_where {
6464 if self.config.pretty {
6465 self.write_newline();
6466 self.write_indent();
6467 } else {
6468 self.write_space();
6469 }
6470 self.write_keyword("REPLACE WHERE");
6471 self.write_space();
6472 self.generate_expression(replace_where)?;
6473 }
6474
6475 if !insert.partition.is_empty() {
6477 self.write_space();
6478 self.write_keyword("PARTITION");
6479 self.write("(");
6480 for (i, (col, val)) in insert.partition.iter().enumerate() {
6481 if i > 0 {
6482 self.write(", ");
6483 }
6484 self.generate_identifier(col)?;
6485 if let Some(v) = val {
6486 self.write(" = ");
6487 self.generate_expression(v)?;
6488 }
6489 }
6490 self.write(")");
6491 }
6492
6493 if let Some(ref partition_by) = insert.partition_by {
6495 self.write_space();
6496 self.write_keyword("PARTITION BY");
6497 self.write_space();
6498 self.generate_expression(partition_by)?;
6499 }
6500
6501 if !insert.settings.is_empty() {
6503 self.write_space();
6504 self.write_keyword("SETTINGS");
6505 self.write_space();
6506 for (i, setting) in insert.settings.iter().enumerate() {
6507 if i > 0 {
6508 self.write(", ");
6509 }
6510 self.generate_expression(setting)?;
6511 }
6512 }
6513
6514 if !insert.columns.is_empty() {
6515 if insert.alias.is_some() && insert.alias_explicit_as {
6516 self.write("(");
6518 } else {
6519 self.write(" (");
6521 }
6522 for (i, col) in insert.columns.iter().enumerate() {
6523 if i > 0 {
6524 self.write(", ");
6525 }
6526 self.generate_identifier(col)?;
6527 }
6528 self.write(")");
6529 }
6530
6531 if let Some(ref output) = insert.output {
6533 self.generate_output_clause(output)?;
6534 }
6535
6536 if insert.by_name {
6538 self.write_space();
6539 self.write_keyword("BY NAME");
6540 }
6541
6542 if insert.default_values {
6543 self.write_space();
6544 self.write_keyword("DEFAULT VALUES");
6545 } else if let Some(query) = &insert.query {
6546 if self.config.pretty {
6547 self.write_newline();
6548 } else {
6549 self.write_space();
6550 }
6551 if prepend_query_cte.is_some() {
6553 if let Expression::Select(select) = query {
6554 let mut select_no_with = select.clone();
6555 select_no_with.with = None;
6556 self.generate_select(&select_no_with)?;
6557 } else {
6558 self.generate_expression(query)?;
6559 }
6560 } else {
6561 self.generate_expression(query)?;
6562 }
6563 } else if !insert.values.is_empty() {
6564 if self.config.pretty {
6565 self.write_newline();
6567 self.write_keyword("VALUES");
6568 self.write_newline();
6569 self.indent_level += 1;
6570 for (i, row) in insert.values.iter().enumerate() {
6571 if i > 0 {
6572 self.write(",");
6573 self.write_newline();
6574 }
6575 self.write_indent();
6576 self.write("(");
6577 for (j, val) in row.iter().enumerate() {
6578 if j > 0 {
6579 self.write(", ");
6580 }
6581 self.generate_expression(val)?;
6582 }
6583 self.write(")");
6584 }
6585 self.indent_level -= 1;
6586 } else {
6587 self.write_space();
6589 self.write_keyword("VALUES");
6590 for (i, row) in insert.values.iter().enumerate() {
6591 if i > 0 {
6592 self.write(",");
6593 }
6594 self.write(" (");
6595 for (j, val) in row.iter().enumerate() {
6596 if j > 0 {
6597 self.write(", ");
6598 }
6599 self.generate_expression(val)?;
6600 }
6601 self.write(")");
6602 }
6603 }
6604 }
6605
6606 if let Some(ref source) = insert.source {
6608 self.write_space();
6609 self.write_keyword("TABLE");
6610 self.write_space();
6611 self.generate_expression(source)?;
6612 }
6613
6614 if let Some(alias) = &insert.source_alias {
6616 self.write_space();
6617 self.write_keyword("AS");
6618 self.write_space();
6619 self.generate_identifier(alias)?;
6620 }
6621
6622 if let Some(on_conflict) = &insert.on_conflict {
6624 if !matches!(self.config.dialect, Some(DialectType::Materialize)) {
6625 self.write_space();
6626 self.generate_expression(on_conflict)?;
6627 }
6628 }
6629
6630 if !insert.returning.is_empty() {
6632 self.write_space();
6633 self.write_keyword("RETURNING");
6634 self.write_space();
6635 for (i, expr) in insert.returning.iter().enumerate() {
6636 if i > 0 {
6637 self.write(", ");
6638 }
6639 self.generate_expression(expr)?;
6640 }
6641 }
6642
6643 Ok(())
6644 }
6645
6646 fn generate_update(&mut self, update: &Update) -> Result<()> {
6647 for comment in &update.leading_comments {
6649 self.write_formatted_comment(comment);
6650 self.write(" ");
6651 }
6652
6653 if let Some(ref with) = update.with {
6655 self.generate_with(with)?;
6656 self.write_space();
6657 }
6658
6659 self.write_keyword("UPDATE");
6660 self.write_space();
6661 self.generate_table(&update.table)?;
6662
6663 let mysql_like_update_from = matches!(
6664 self.config.dialect,
6665 Some(DialectType::MySQL) | Some(DialectType::SingleStore)
6666 ) && update.from_clause.is_some();
6667
6668 let mut set_pairs = update.set.clone();
6669
6670 let mut pre_set_joins = update.table_joins.clone();
6672 if mysql_like_update_from {
6673 let target_name = update
6674 .table
6675 .alias
6676 .as_ref()
6677 .map(|a| a.name.clone())
6678 .unwrap_or_else(|| update.table.name.name.clone());
6679
6680 for (col, _) in &mut set_pairs {
6681 if !col.name.contains('.') {
6682 col.name = format!("{}.{}", target_name, col.name);
6683 }
6684 }
6685
6686 if let Some(from_clause) = &update.from_clause {
6687 for table_expr in &from_clause.expressions {
6688 pre_set_joins.push(crate::expressions::Join {
6689 this: table_expr.clone(),
6690 on: Some(Expression::Boolean(crate::expressions::BooleanLiteral {
6691 value: true,
6692 })),
6693 using: Vec::new(),
6694 kind: crate::expressions::JoinKind::Inner,
6695 use_inner_keyword: false,
6696 use_outer_keyword: false,
6697 deferred_condition: false,
6698 join_hint: None,
6699 match_condition: None,
6700 pivots: Vec::new(),
6701 comments: Vec::new(),
6702 nesting_group: 0,
6703 directed: false,
6704 });
6705 }
6706 }
6707 for join in &update.from_joins {
6708 let mut join = join.clone();
6709 if join.on.is_none() && join.using.is_empty() {
6710 join.on = Some(Expression::Boolean(crate::expressions::BooleanLiteral {
6711 value: true,
6712 }));
6713 }
6714 pre_set_joins.push(join);
6715 }
6716 }
6717
6718 for extra_table in &update.extra_tables {
6720 self.write(", ");
6721 self.generate_table(extra_table)?;
6722 }
6723
6724 for join in &pre_set_joins {
6726 self.generate_join(join)?;
6728 }
6729
6730 let teradata_from_before_set = matches!(self.config.dialect, Some(DialectType::Teradata));
6732 if teradata_from_before_set && !mysql_like_update_from {
6733 if let Some(ref from_clause) = update.from_clause {
6734 self.write_space();
6735 self.write_keyword("FROM");
6736 self.write_space();
6737 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
6738 if i > 0 {
6739 self.write(", ");
6740 }
6741 self.generate_expression(table_expr)?;
6742 }
6743 }
6744 for join in &update.from_joins {
6745 self.generate_join(join)?;
6746 }
6747 }
6748
6749 self.write_space();
6750 self.write_keyword("SET");
6751 self.write_space();
6752
6753 for (i, (col, val)) in set_pairs.iter().enumerate() {
6754 if i > 0 {
6755 self.write(", ");
6756 }
6757 self.generate_identifier(col)?;
6758 self.write(" = ");
6759 self.generate_expression(val)?;
6760 }
6761
6762 if let Some(ref output) = update.output {
6764 self.generate_output_clause(output)?;
6765 }
6766
6767 if !mysql_like_update_from && !teradata_from_before_set {
6769 if let Some(ref from_clause) = update.from_clause {
6770 self.write_space();
6771 self.write_keyword("FROM");
6772 self.write_space();
6773 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
6775 if i > 0 {
6776 self.write(", ");
6777 }
6778 self.generate_expression(table_expr)?;
6779 }
6780 }
6781 }
6782
6783 if !mysql_like_update_from && !teradata_from_before_set {
6784 for join in &update.from_joins {
6786 self.generate_join(join)?;
6787 }
6788 }
6789
6790 if let Some(where_clause) = &update.where_clause {
6791 self.write_space();
6792 self.write_keyword("WHERE");
6793 self.write_space();
6794 self.generate_expression(&where_clause.this)?;
6795 }
6796
6797 if !update.returning.is_empty() {
6799 self.write_space();
6800 self.write_keyword("RETURNING");
6801 self.write_space();
6802 for (i, expr) in update.returning.iter().enumerate() {
6803 if i > 0 {
6804 self.write(", ");
6805 }
6806 self.generate_expression(expr)?;
6807 }
6808 }
6809
6810 if let Some(ref order_by) = update.order_by {
6812 self.write_space();
6813 self.generate_order_by(order_by)?;
6814 }
6815
6816 if let Some(ref limit) = update.limit {
6818 self.write_space();
6819 self.write_keyword("LIMIT");
6820 self.write_space();
6821 self.generate_expression(limit)?;
6822 }
6823
6824 Ok(())
6825 }
6826
6827 fn generate_delete(&mut self, delete: &Delete) -> Result<()> {
6828 if let Some(with) = &delete.with {
6830 self.generate_with(with)?;
6831 self.write_space();
6832 }
6833
6834 for comment in &delete.leading_comments {
6836 self.write_formatted_comment(comment);
6837 self.write(" ");
6838 }
6839
6840 if !delete.tables.is_empty() && !delete.tables_from_using {
6842 self.write_keyword("DELETE");
6844 self.write_space();
6845 for (i, tbl) in delete.tables.iter().enumerate() {
6846 if i > 0 {
6847 self.write(", ");
6848 }
6849 self.generate_table(tbl)?;
6850 }
6851 if let Some(ref output) = delete.output {
6853 self.generate_output_clause(output)?;
6854 }
6855 self.write_space();
6856 self.write_keyword("FROM");
6857 self.write_space();
6858 self.generate_table(&delete.table)?;
6859 } else if !delete.tables.is_empty() && delete.tables_from_using {
6860 self.write_keyword("DELETE FROM");
6862 self.write_space();
6863 for (i, tbl) in delete.tables.iter().enumerate() {
6864 if i > 0 {
6865 self.write(", ");
6866 }
6867 self.generate_table(tbl)?;
6868 }
6869 } else if delete.no_from && matches!(self.config.dialect, Some(DialectType::BigQuery)) {
6870 self.write_keyword("DELETE");
6872 self.write_space();
6873 self.generate_table(&delete.table)?;
6874 } else {
6875 self.write_keyword("DELETE FROM");
6876 self.write_space();
6877 self.generate_table(&delete.table)?;
6878 }
6879
6880 if let Some(ref on_cluster) = delete.on_cluster {
6882 self.write_space();
6883 self.generate_on_cluster(on_cluster)?;
6884 }
6885
6886 if let Some(ref idx) = delete.force_index {
6888 self.write_space();
6889 self.write_keyword("FORCE INDEX");
6890 self.write(" (");
6891 self.write(idx);
6892 self.write(")");
6893 }
6894
6895 if let Some(ref alias) = delete.alias {
6897 self.write_space();
6898 if delete.alias_explicit_as
6899 || matches!(self.config.dialect, Some(DialectType::BigQuery))
6900 {
6901 self.write_keyword("AS");
6902 self.write_space();
6903 }
6904 self.generate_identifier(alias)?;
6905 }
6906
6907 if !delete.tables_from_using {
6909 for join in &delete.joins {
6910 self.generate_join(join)?;
6911 }
6912 }
6913
6914 if !delete.using.is_empty() {
6916 self.write_space();
6917 self.write_keyword("USING");
6918 for (i, table) in delete.using.iter().enumerate() {
6919 if i > 0 {
6920 self.write(",");
6921 }
6922 self.write_space();
6923 if !table.hints.is_empty() && table.name.is_empty() {
6925 self.generate_expression(&table.hints[0])?;
6927 if let Some(ref alias) = table.alias {
6928 self.write_space();
6929 if table.alias_explicit_as {
6930 self.write_keyword("AS");
6931 self.write_space();
6932 }
6933 self.generate_identifier(alias)?;
6934 if !table.column_aliases.is_empty() {
6935 self.write("(");
6936 for (j, col_alias) in table.column_aliases.iter().enumerate() {
6937 if j > 0 {
6938 self.write(", ");
6939 }
6940 self.generate_identifier(col_alias)?;
6941 }
6942 self.write(")");
6943 }
6944 }
6945 } else {
6946 self.generate_table(table)?;
6947 }
6948 }
6949 }
6950
6951 if delete.tables_from_using {
6953 for join in &delete.joins {
6954 self.generate_join(join)?;
6955 }
6956 }
6957
6958 let output_already_emitted =
6960 !delete.tables.is_empty() && !delete.tables_from_using && delete.output.is_some();
6961 if !output_already_emitted {
6962 if let Some(ref output) = delete.output {
6963 self.generate_output_clause(output)?;
6964 }
6965 }
6966
6967 if let Some(where_clause) = &delete.where_clause {
6968 self.write_space();
6969 self.write_keyword("WHERE");
6970 self.write_space();
6971 self.generate_expression(&where_clause.this)?;
6972 }
6973
6974 if let Some(ref order_by) = delete.order_by {
6976 self.write_space();
6977 self.generate_order_by(order_by)?;
6978 }
6979
6980 if let Some(ref limit) = delete.limit {
6982 self.write_space();
6983 self.write_keyword("LIMIT");
6984 self.write_space();
6985 self.generate_expression(limit)?;
6986 }
6987
6988 if !delete.returning.is_empty() {
6990 self.write_space();
6991 self.write_keyword("RETURNING");
6992 self.write_space();
6993 for (i, expr) in delete.returning.iter().enumerate() {
6994 if i > 0 {
6995 self.write(", ");
6996 }
6997 self.generate_expression(expr)?;
6998 }
6999 }
7000
7001 Ok(())
7002 }
7003
7004 fn generate_create_table(&mut self, ct: &CreateTable) -> Result<()> {
7007 let saved_athena_hive_context = self.athena_hive_context;
7011 let is_clickhouse = matches!(self.config.dialect, Some(DialectType::ClickHouse));
7012 if matches!(
7013 self.config.dialect,
7014 Some(crate::dialects::DialectType::Athena)
7015 ) {
7016 let is_external = ct
7020 .table_modifier
7021 .as_ref()
7022 .map(|m| m.eq_ignore_ascii_case("EXTERNAL"))
7023 .unwrap_or(false);
7024 let has_as_select = ct.as_select.is_some();
7025 self.athena_hive_context = is_external || !has_as_select;
7026 }
7027
7028 if matches!(
7030 self.config.dialect,
7031 Some(crate::dialects::DialectType::TSQL)
7032 ) {
7033 if let Some(ref query) = ct.as_select {
7034 if let Some(with_cte) = &ct.with_cte {
7036 self.generate_with(with_cte)?;
7037 self.write_space();
7038 }
7039
7040 self.write_keyword("SELECT");
7042 self.write(" * ");
7043 self.write_keyword("INTO");
7044 self.write_space();
7045
7046 if ct.temporary {
7048 self.write("#");
7049 }
7050 self.generate_table(&ct.name)?;
7051
7052 self.write_space();
7053 self.write_keyword("FROM");
7054 self.write(" (");
7055 let aliased_query = Self::add_column_aliases_to_query(query.clone());
7057 self.generate_expression(&aliased_query)?;
7058 self.write(") ");
7059 self.write_keyword("AS");
7060 self.write(" temp");
7061 return Ok(());
7062 }
7063 }
7064
7065 if let Some(with_cte) = &ct.with_cte {
7067 self.generate_with(with_cte)?;
7068 self.write_space();
7069 }
7070
7071 for comment in &ct.leading_comments {
7073 self.write_formatted_comment(comment);
7074 self.write(" ");
7075 }
7076 self.write_keyword("CREATE");
7077
7078 if ct.or_replace {
7079 self.write_space();
7080 self.write_keyword("OR REPLACE");
7081 }
7082
7083 if ct.temporary {
7084 self.write_space();
7085 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
7087 self.write_keyword("GLOBAL TEMPORARY");
7088 } else {
7089 self.write_keyword("TEMPORARY");
7090 }
7091 }
7092
7093 let is_dictionary = ct
7095 .table_modifier
7096 .as_ref()
7097 .map(|m| m.eq_ignore_ascii_case("DICTIONARY"))
7098 .unwrap_or(false);
7099 if let Some(ref modifier) = ct.table_modifier {
7100 let skip_transient = modifier.eq_ignore_ascii_case("TRANSIENT")
7102 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None);
7103 let is_teradata_modifier = modifier.eq_ignore_ascii_case("VOLATILE")
7105 || modifier.eq_ignore_ascii_case("SET")
7106 || modifier.eq_ignore_ascii_case("MULTISET")
7107 || modifier.to_uppercase().contains("VOLATILE")
7108 || modifier.to_uppercase().starts_with("SET ")
7109 || modifier.to_uppercase().starts_with("MULTISET ");
7110 let skip_teradata =
7111 is_teradata_modifier && !matches!(self.config.dialect, Some(DialectType::Teradata));
7112 if !skip_transient && !skip_teradata {
7113 self.write_space();
7114 self.write_keyword(modifier);
7115 }
7116 }
7117
7118 if !is_dictionary {
7119 self.write_space();
7120 self.write_keyword("TABLE");
7121 }
7122
7123 if ct.if_not_exists {
7124 self.write_space();
7125 self.write_keyword("IF NOT EXISTS");
7126 }
7127
7128 self.write_space();
7129 self.generate_table(&ct.name)?;
7130
7131 if let Some(ref on_cluster) = ct.on_cluster {
7133 self.write_space();
7134 self.generate_on_cluster(on_cluster)?;
7135 }
7136
7137 if matches!(
7139 self.config.dialect,
7140 Some(crate::dialects::DialectType::Teradata)
7141 ) && !ct.teradata_post_name_options.is_empty()
7142 {
7143 for opt in &ct.teradata_post_name_options {
7144 self.write(", ");
7145 self.write(opt);
7146 }
7147 }
7148
7149 if ct.copy_grants {
7151 self.write_space();
7152 self.write_keyword("COPY GRANTS");
7153 }
7154
7155 if let Some(ref using_template) = ct.using_template {
7157 self.write_space();
7158 self.write_keyword("USING TEMPLATE");
7159 self.write_space();
7160 self.generate_expression(using_template)?;
7161 return Ok(());
7162 }
7163
7164 if let Some(ref clone_source) = ct.clone_source {
7166 self.write_space();
7167 if ct.is_copy && self.config.supports_table_copy {
7168 self.write_keyword("COPY");
7170 } else if ct.shallow_clone {
7171 self.write_keyword("SHALLOW CLONE");
7172 } else {
7173 self.write_keyword("CLONE");
7174 }
7175 self.write_space();
7176 self.generate_table(clone_source)?;
7177 if let Some(ref at_clause) = ct.clone_at_clause {
7179 self.write_space();
7180 self.generate_expression(at_clause)?;
7181 }
7182 return Ok(());
7183 }
7184
7185 if let Some(ref partition_of) = ct.partition_of {
7189 self.write_space();
7190
7191 if let Expression::PartitionedOfProperty(ref pop) = partition_of {
7193 self.write_keyword("PARTITION OF");
7195 self.write_space();
7196 self.generate_expression(&pop.this)?;
7197
7198 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
7200 self.write(" (");
7201 let mut first = true;
7202 for col in &ct.columns {
7203 if !first {
7204 self.write(", ");
7205 }
7206 first = false;
7207 self.generate_column_def(col)?;
7208 }
7209 for constraint in &ct.constraints {
7210 if !first {
7211 self.write(", ");
7212 }
7213 first = false;
7214 self.generate_table_constraint(constraint)?;
7215 }
7216 self.write(")");
7217 }
7218
7219 if let Expression::PartitionBoundSpec(_) = pop.expression.as_ref() {
7221 self.write_space();
7222 self.write_keyword("FOR VALUES");
7223 self.write_space();
7224 self.generate_expression(&pop.expression)?;
7225 } else {
7226 self.write_space();
7227 self.write_keyword("DEFAULT");
7228 }
7229 } else {
7230 self.generate_expression(partition_of)?;
7232
7233 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
7235 self.write(" (");
7236 let mut first = true;
7237 for col in &ct.columns {
7238 if !first {
7239 self.write(", ");
7240 }
7241 first = false;
7242 self.generate_column_def(col)?;
7243 }
7244 for constraint in &ct.constraints {
7245 if !first {
7246 self.write(", ");
7247 }
7248 first = false;
7249 self.generate_table_constraint(constraint)?;
7250 }
7251 self.write(")");
7252 }
7253 }
7254
7255 for prop in &ct.properties {
7257 self.write_space();
7258 self.generate_expression(prop)?;
7259 }
7260
7261 return Ok(());
7262 }
7263
7264 self.sqlite_inline_pk_columns.clear();
7267 if matches!(
7268 self.config.dialect,
7269 Some(crate::dialects::DialectType::SQLite)
7270 ) {
7271 for constraint in &ct.constraints {
7272 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7273 if columns.len() == 1 && name.is_none() {
7275 let pk_col_name = columns[0].name.to_lowercase();
7276 if ct
7278 .columns
7279 .iter()
7280 .any(|c| c.name.name.to_lowercase() == pk_col_name)
7281 {
7282 self.sqlite_inline_pk_columns.insert(pk_col_name);
7283 }
7284 }
7285 }
7286 }
7287 }
7288
7289 if !ct.columns.is_empty() {
7291 if self.config.pretty {
7292 self.write(" (");
7294 self.write_newline();
7295 self.indent_level += 1;
7296 for (i, col) in ct.columns.iter().enumerate() {
7297 if i > 0 {
7298 self.write(",");
7299 self.write_newline();
7300 }
7301 self.write_indent();
7302 self.generate_column_def(col)?;
7303 }
7304 for constraint in &ct.constraints {
7306 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7308 if columns.len() == 1
7309 && name.is_none()
7310 && self
7311 .sqlite_inline_pk_columns
7312 .contains(&columns[0].name.to_lowercase())
7313 {
7314 continue;
7315 }
7316 }
7317 self.write(",");
7318 self.write_newline();
7319 self.write_indent();
7320 self.generate_table_constraint(constraint)?;
7321 }
7322 self.indent_level -= 1;
7323 self.write_newline();
7324 self.write(")");
7325 } else {
7326 self.write(" (");
7327 for (i, col) in ct.columns.iter().enumerate() {
7328 if i > 0 {
7329 self.write(", ");
7330 }
7331 self.generate_column_def(col)?;
7332 }
7333 let mut first_constraint = true;
7335 for constraint in &ct.constraints {
7336 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7338 if columns.len() == 1
7339 && name.is_none()
7340 && self
7341 .sqlite_inline_pk_columns
7342 .contains(&columns[0].name.to_lowercase())
7343 {
7344 continue;
7345 }
7346 }
7347 if first_constraint {
7348 self.write(", ");
7349 first_constraint = false;
7350 } else {
7351 self.write(", ");
7352 }
7353 self.generate_table_constraint(constraint)?;
7354 }
7355 self.write(")");
7356 }
7357 } else if !ct.constraints.is_empty() {
7358 let has_like_only = ct
7360 .constraints
7361 .iter()
7362 .all(|c| matches!(c, TableConstraint::Like { .. }));
7363 let has_tags_only = ct
7364 .constraints
7365 .iter()
7366 .all(|c| matches!(c, TableConstraint::Tags(_)));
7367 let is_pg_like = matches!(
7371 self.config.dialect,
7372 Some(crate::dialects::DialectType::PostgreSQL)
7373 | Some(crate::dialects::DialectType::CockroachDB)
7374 | Some(crate::dialects::DialectType::Materialize)
7375 | Some(crate::dialects::DialectType::RisingWave)
7376 | Some(crate::dialects::DialectType::Redshift)
7377 | Some(crate::dialects::DialectType::Presto)
7378 | Some(crate::dialects::DialectType::Trino)
7379 | Some(crate::dialects::DialectType::Athena)
7380 );
7381 let use_parens = if has_like_only {
7382 is_pg_like
7383 } else {
7384 !has_tags_only
7385 };
7386 if self.config.pretty && use_parens {
7387 self.write(" (");
7388 self.write_newline();
7389 self.indent_level += 1;
7390 for (i, constraint) in ct.constraints.iter().enumerate() {
7391 if i > 0 {
7392 self.write(",");
7393 self.write_newline();
7394 }
7395 self.write_indent();
7396 self.generate_table_constraint(constraint)?;
7397 }
7398 self.indent_level -= 1;
7399 self.write_newline();
7400 self.write(")");
7401 } else {
7402 if use_parens {
7403 self.write(" (");
7404 } else {
7405 self.write_space();
7406 }
7407 for (i, constraint) in ct.constraints.iter().enumerate() {
7408 if i > 0 {
7409 self.write(", ");
7410 }
7411 self.generate_table_constraint(constraint)?;
7412 }
7413 if use_parens {
7414 self.write(")");
7415 }
7416 }
7417 }
7418
7419 if let Some(ref on_prop) = ct.on_property {
7421 self.write(" ");
7422 self.write_keyword("ON");
7423 self.write(" ");
7424 self.generate_expression(&on_prop.this)?;
7425 }
7426
7427 if !is_clickhouse {
7430 for prop in &ct.properties {
7431 if let Expression::SchemaCommentProperty(_) = prop {
7432 if self.config.pretty {
7433 self.write_newline();
7434 } else {
7435 self.write_space();
7436 }
7437 self.generate_expression(prop)?;
7438 }
7439 }
7440 }
7441
7442 if !ct.with_properties.is_empty() {
7444 let is_snowflake_special_table = matches!(
7446 self.config.dialect,
7447 Some(crate::dialects::DialectType::Snowflake)
7448 ) && (ct.table_modifier.as_deref() == Some("ICEBERG")
7449 || ct.table_modifier.as_deref() == Some("DYNAMIC"));
7450 if is_snowflake_special_table {
7451 for (key, value) in &ct.with_properties {
7452 self.write_space();
7453 self.write(key);
7454 self.write("=");
7455 self.write(value);
7456 }
7457 } else if self.config.pretty {
7458 self.write_newline();
7459 self.write_keyword("WITH");
7460 self.write(" (");
7461 self.write_newline();
7462 self.indent_level += 1;
7463 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
7464 if i > 0 {
7465 self.write(",");
7466 self.write_newline();
7467 }
7468 self.write_indent();
7469 self.write(key);
7470 self.write("=");
7471 self.write(value);
7472 }
7473 self.indent_level -= 1;
7474 self.write_newline();
7475 self.write(")");
7476 } else {
7477 self.write_space();
7478 self.write_keyword("WITH");
7479 self.write(" (");
7480 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
7481 if i > 0 {
7482 self.write(", ");
7483 }
7484 self.write(key);
7485 self.write("=");
7486 self.write(value);
7487 }
7488 self.write(")");
7489 }
7490 }
7491
7492 let (pre_as_properties, post_as_properties): (Vec<&Expression>, Vec<&Expression>) =
7493 if is_clickhouse && ct.as_select.is_some() {
7494 let mut pre = Vec::new();
7495 let mut post = Vec::new();
7496 for prop in &ct.properties {
7497 if matches!(prop, Expression::SchemaCommentProperty(_)) {
7498 post.push(prop);
7499 } else {
7500 pre.push(prop);
7501 }
7502 }
7503 (pre, post)
7504 } else {
7505 (ct.properties.iter().collect(), Vec::new())
7506 };
7507
7508 for prop in pre_as_properties {
7510 if !is_clickhouse && matches!(prop, Expression::SchemaCommentProperty(_)) {
7512 continue;
7513 }
7514 if self.config.pretty {
7515 self.write_newline();
7516 } else {
7517 self.write_space();
7518 }
7519 if let Expression::Properties(props) = prop {
7523 let is_hive_dialect = matches!(
7524 self.config.dialect,
7525 Some(crate::dialects::DialectType::Hive)
7526 | Some(crate::dialects::DialectType::Spark)
7527 | Some(crate::dialects::DialectType::Databricks)
7528 | Some(crate::dialects::DialectType::Athena)
7529 );
7530 let is_doris_starrocks = matches!(
7531 self.config.dialect,
7532 Some(crate::dialects::DialectType::Doris)
7533 | Some(crate::dialects::DialectType::StarRocks)
7534 );
7535 if is_hive_dialect {
7536 self.generate_tblproperties_clause(&props.expressions)?;
7537 } else if is_doris_starrocks {
7538 self.generate_properties_clause(&props.expressions)?;
7539 } else {
7540 self.generate_options_clause(&props.expressions)?;
7541 }
7542 } else {
7543 self.generate_expression(prop)?;
7544 }
7545 }
7546
7547 for prop in &ct.post_table_properties {
7549 if let Expression::WithSystemVersioningProperty(ref svp) = prop {
7550 self.write(" WITH(");
7551 self.generate_system_versioning_content(svp)?;
7552 self.write(")");
7553 } else if let Expression::Properties(props) = prop {
7554 let is_doris_starrocks = matches!(
7556 self.config.dialect,
7557 Some(crate::dialects::DialectType::Doris)
7558 | Some(crate::dialects::DialectType::StarRocks)
7559 );
7560 self.write_space();
7561 if is_doris_starrocks {
7562 self.generate_properties_clause(&props.expressions)?;
7563 } else {
7564 self.generate_options_clause(&props.expressions)?;
7565 }
7566 } else {
7567 self.write_space();
7568 self.generate_expression(prop)?;
7569 }
7570 }
7571
7572 if let Some(ref rollup) = ct.rollup {
7575 if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
7576 self.write_space();
7577 self.generate_rollup_property(rollup)?;
7578 }
7579 }
7580
7581 let is_mysql_compatible = matches!(
7585 self.config.dialect,
7586 Some(DialectType::MySQL)
7587 | Some(DialectType::SingleStore)
7588 | Some(DialectType::Doris)
7589 | Some(DialectType::StarRocks)
7590 | None
7591 );
7592 let is_hive_compatible = matches!(
7593 self.config.dialect,
7594 Some(DialectType::Hive)
7595 | Some(DialectType::Spark)
7596 | Some(DialectType::Databricks)
7597 | Some(DialectType::Athena)
7598 );
7599 let mysql_pretty_options =
7600 self.config.pretty && matches!(self.config.dialect, Some(DialectType::MySQL));
7601 for (key, value) in &ct.mysql_table_options {
7602 let should_output = if is_mysql_compatible {
7604 true
7605 } else if is_hive_compatible && key == "COMMENT" {
7606 true } else {
7608 false
7609 };
7610 if should_output {
7611 if mysql_pretty_options {
7612 self.write_newline();
7613 self.write_indent();
7614 } else {
7615 self.write_space();
7616 }
7617 self.write_keyword(key);
7618 if key == "COMMENT" && !self.config.schema_comment_with_eq {
7620 self.write_space();
7621 } else {
7622 self.write("=");
7623 }
7624 self.write(value);
7625 }
7626 }
7627
7628 if ct.temporary
7630 && matches!(
7631 self.config.dialect,
7632 Some(DialectType::Spark) | Some(DialectType::Databricks)
7633 )
7634 && ct.as_select.is_none()
7635 {
7636 self.write_space();
7637 self.write_keyword("USING PARQUET");
7638 }
7639
7640 if !ct.inherits.is_empty() {
7642 self.write_space();
7643 self.write_keyword("INHERITS");
7644 self.write(" (");
7645 for (i, parent) in ct.inherits.iter().enumerate() {
7646 if i > 0 {
7647 self.write(", ");
7648 }
7649 self.generate_table(parent)?;
7650 }
7651 self.write(")");
7652 }
7653
7654 if let Some(ref query) = ct.as_select {
7656 self.write_space();
7657 self.write_keyword("AS");
7658 self.write_space();
7659 if ct.as_select_parenthesized {
7660 self.write("(");
7661 }
7662 self.generate_expression(query)?;
7663 if ct.as_select_parenthesized {
7664 self.write(")");
7665 }
7666
7667 if let Some(with_data) = ct.with_data {
7669 self.write_space();
7670 self.write_keyword("WITH");
7671 if !with_data {
7672 self.write_space();
7673 self.write_keyword("NO");
7674 }
7675 self.write_space();
7676 self.write_keyword("DATA");
7677 }
7678
7679 if let Some(with_statistics) = ct.with_statistics {
7681 self.write_space();
7682 self.write_keyword("AND");
7683 if !with_statistics {
7684 self.write_space();
7685 self.write_keyword("NO");
7686 }
7687 self.write_space();
7688 self.write_keyword("STATISTICS");
7689 }
7690
7691 for index in &ct.teradata_indexes {
7693 self.write_space();
7694 match index.kind {
7695 TeradataIndexKind::NoPrimary => {
7696 self.write_keyword("NO PRIMARY INDEX");
7697 }
7698 TeradataIndexKind::Primary => {
7699 self.write_keyword("PRIMARY INDEX");
7700 }
7701 TeradataIndexKind::PrimaryAmp => {
7702 self.write_keyword("PRIMARY AMP INDEX");
7703 }
7704 TeradataIndexKind::Unique => {
7705 self.write_keyword("UNIQUE INDEX");
7706 }
7707 TeradataIndexKind::UniquePrimary => {
7708 self.write_keyword("UNIQUE PRIMARY INDEX");
7709 }
7710 TeradataIndexKind::Secondary => {
7711 self.write_keyword("INDEX");
7712 }
7713 }
7714 if let Some(ref name) = index.name {
7716 self.write_space();
7717 self.write(name);
7718 }
7719 if !index.columns.is_empty() {
7721 self.write(" (");
7722 for (i, col) in index.columns.iter().enumerate() {
7723 if i > 0 {
7724 self.write(", ");
7725 }
7726 self.write(col);
7727 }
7728 self.write(")");
7729 }
7730 }
7731
7732 if let Some(ref on_commit) = ct.on_commit {
7734 self.write_space();
7735 self.write_keyword("ON COMMIT");
7736 self.write_space();
7737 match on_commit {
7738 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
7739 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
7740 }
7741 }
7742
7743 if !post_as_properties.is_empty() {
7744 for prop in post_as_properties {
7745 self.write_space();
7746 self.generate_expression(prop)?;
7747 }
7748 }
7749
7750 self.athena_hive_context = saved_athena_hive_context;
7752 return Ok(());
7753 }
7754
7755 if let Some(ref on_commit) = ct.on_commit {
7757 self.write_space();
7758 self.write_keyword("ON COMMIT");
7759 self.write_space();
7760 match on_commit {
7761 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
7762 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
7763 }
7764 }
7765
7766 self.athena_hive_context = saved_athena_hive_context;
7768
7769 Ok(())
7770 }
7771
7772 fn generate_column_def_expr(&mut self, col: &ColumnDef) -> Result<()> {
7775 self.generate_identifier(&col.name)?;
7777 if !matches!(col.data_type, DataType::Unknown) {
7779 self.write_space();
7780 self.generate_data_type(&col.data_type)?;
7781 }
7782 for constraint in &col.constraints {
7784 if let ColumnConstraint::Path(path_expr) = constraint {
7785 self.write_space();
7786 self.write_keyword("PATH");
7787 self.write_space();
7788 self.generate_expression(path_expr)?;
7789 }
7790 }
7791 Ok(())
7792 }
7793
7794 fn generate_column_def(&mut self, col: &ColumnDef) -> Result<()> {
7795 let has_computed_no_type = matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
7797 && col
7798 .constraints
7799 .iter()
7800 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
7801 let omit_computed_type = !self.config.computed_column_with_type
7803 && col
7804 .constraints
7805 .iter()
7806 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
7807
7808 let is_partition_column_spec = matches!(col.data_type, DataType::Unknown);
7811
7812 let has_no_type = col.no_type
7815 || (matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
7816 && col.constraints.is_empty());
7817
7818 self.generate_identifier(&col.name)?;
7819
7820 let serial_expansion = if matches!(
7822 self.config.dialect,
7823 Some(DialectType::Materialize) | Some(DialectType::PostgreSQL)
7824 ) {
7825 if let DataType::Custom { ref name } = col.data_type {
7826 match name.to_uppercase().as_str() {
7827 "SERIAL" => Some("INT"),
7828 "BIGSERIAL" => Some("BIGINT"),
7829 "SMALLSERIAL" => Some("SMALLINT"),
7830 _ => None,
7831 }
7832 } else {
7833 None
7834 }
7835 } else {
7836 None
7837 };
7838
7839 if !has_computed_no_type && !omit_computed_type && !is_partition_column_spec && !has_no_type
7840 {
7841 self.write_space();
7842 let saved_nullable_depth = self.clickhouse_nullable_depth;
7845 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
7846 self.clickhouse_nullable_depth = -1;
7847 }
7848 if let Some(int_type) = serial_expansion {
7849 self.write_keyword(int_type);
7851 } else if col.unsigned && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
7852 let unsigned_type = match &col.data_type {
7854 DataType::Int { .. } => Some("UINTEGER"),
7855 DataType::BigInt { .. } => Some("UBIGINT"),
7856 DataType::SmallInt { .. } => Some("USMALLINT"),
7857 DataType::TinyInt { .. } => Some("UTINYINT"),
7858 _ => None,
7859 };
7860 if let Some(utype) = unsigned_type {
7861 self.write_keyword(utype);
7862 } else {
7863 self.generate_data_type(&col.data_type)?;
7864 }
7865 } else {
7866 self.generate_data_type(&col.data_type)?;
7867 }
7868 self.clickhouse_nullable_depth = saved_nullable_depth;
7869 }
7870
7871 if col.unsigned && !matches!(self.config.dialect, Some(DialectType::DuckDB)) {
7874 self.write_space();
7875 self.write_keyword("UNSIGNED");
7876 }
7877 if col.zerofill {
7878 self.write_space();
7879 self.write_keyword("ZEROFILL");
7880 }
7881
7882 if let Some(ref charset) = col.character_set {
7886 self.write_space();
7887 self.write_keyword("CHARACTER SET");
7888 self.write_space();
7889 self.write(charset);
7890 }
7891
7892 if col.uppercase {
7893 self.write_space();
7894 self.write_keyword("UPPERCASE");
7895 }
7896
7897 if let Some(casespecific) = col.casespecific {
7898 self.write_space();
7899 if casespecific {
7900 self.write_keyword("CASESPECIFIC");
7901 } else {
7902 self.write_keyword("NOT CASESPECIFIC");
7903 }
7904 }
7905
7906 if let Some(ref format) = col.format {
7907 self.write_space();
7908 self.write_keyword("FORMAT");
7909 self.write(" '");
7910 self.write(format);
7911 self.write("'");
7912 }
7913
7914 if let Some(ref title) = col.title {
7915 self.write_space();
7916 self.write_keyword("TITLE");
7917 self.write(" '");
7918 self.write(title);
7919 self.write("'");
7920 }
7921
7922 if let Some(length) = col.inline_length {
7923 self.write_space();
7924 self.write_keyword("INLINE LENGTH");
7925 self.write(" ");
7926 self.write(&length.to_string());
7927 }
7928
7929 if let Some(ref compress) = col.compress {
7930 self.write_space();
7931 self.write_keyword("COMPRESS");
7932 if !compress.is_empty() {
7933 if compress.len() == 1 {
7935 if let Expression::Literal(Literal::String(_)) = &compress[0] {
7936 self.write_space();
7937 self.generate_expression(&compress[0])?;
7938 } else {
7939 self.write(" (");
7940 self.generate_expression(&compress[0])?;
7941 self.write(")");
7942 }
7943 } else {
7944 self.write(" (");
7945 for (i, val) in compress.iter().enumerate() {
7946 if i > 0 {
7947 self.write(", ");
7948 }
7949 self.generate_expression(val)?;
7950 }
7951 self.write(")");
7952 }
7953 }
7954 }
7955
7956 if !col.constraint_order.is_empty() {
7959 let mut references_idx = 0;
7962 let mut check_idx = 0;
7963 let mut generated_idx = 0;
7964 let mut collate_idx = 0;
7965 let mut comment_idx = 0;
7966 let defer_not_null_after_identity = false;
7969 let mut pending_not_null_after_identity = false;
7970
7971 for constraint_type in &col.constraint_order {
7972 match constraint_type {
7973 ConstraintType::PrimaryKey => {
7974 if col.primary_key
7976 && !matches!(self.config.dialect, Some(DialectType::Materialize))
7977 {
7978 if let Some(ref cname) = col.primary_key_constraint_name {
7979 self.write_space();
7980 self.write_keyword("CONSTRAINT");
7981 self.write_space();
7982 self.write(cname);
7983 }
7984 self.write_space();
7985 self.write_keyword("PRIMARY KEY");
7986 if let Some(ref order) = col.primary_key_order {
7987 self.write_space();
7988 match order {
7989 SortOrder::Asc => self.write_keyword("ASC"),
7990 SortOrder::Desc => self.write_keyword("DESC"),
7991 }
7992 }
7993 }
7994 }
7995 ConstraintType::Unique => {
7996 if col.unique {
7997 if let Some(ref cname) = col.unique_constraint_name {
7998 self.write_space();
7999 self.write_keyword("CONSTRAINT");
8000 self.write_space();
8001 self.write(cname);
8002 }
8003 self.write_space();
8004 self.write_keyword("UNIQUE");
8005 if col.unique_nulls_not_distinct {
8007 self.write(" NULLS NOT DISTINCT");
8008 }
8009 }
8010 }
8011 ConstraintType::NotNull => {
8012 if col.nullable == Some(false) {
8013 if defer_not_null_after_identity {
8014 pending_not_null_after_identity = true;
8015 continue;
8016 }
8017 if let Some(ref cname) = col.not_null_constraint_name {
8018 self.write_space();
8019 self.write_keyword("CONSTRAINT");
8020 self.write_space();
8021 self.write(cname);
8022 }
8023 self.write_space();
8024 self.write_keyword("NOT NULL");
8025 }
8026 }
8027 ConstraintType::Null => {
8028 if col.nullable == Some(true) {
8029 self.write_space();
8030 self.write_keyword("NULL");
8031 }
8032 }
8033 ConstraintType::Default => {
8034 if let Some(ref default) = col.default {
8035 self.write_space();
8036 self.write_keyword("DEFAULT");
8037 self.write_space();
8038 self.generate_expression(default)?;
8039 }
8040 }
8041 ConstraintType::AutoIncrement => {
8042 if col.auto_increment {
8043 if matches!(
8045 self.config.dialect,
8046 Some(crate::dialects::DialectType::DuckDB)
8047 ) {
8048 } else if matches!(
8050 self.config.dialect,
8051 Some(crate::dialects::DialectType::Materialize)
8052 ) {
8053 if !matches!(col.nullable, Some(false)) {
8055 self.write_space();
8056 self.write_keyword("NOT NULL");
8057 }
8058 } else if matches!(
8059 self.config.dialect,
8060 Some(crate::dialects::DialectType::PostgreSQL)
8061 ) {
8062 self.write_space();
8064 self.generate_auto_increment_keyword(col)?;
8065 } else {
8066 self.write_space();
8067 self.generate_auto_increment_keyword(col)?;
8068 if pending_not_null_after_identity {
8069 self.write_space();
8070 self.write_keyword("NOT NULL");
8071 pending_not_null_after_identity = false;
8072 }
8073 }
8074 } }
8076 ConstraintType::References => {
8077 while references_idx < col.constraints.len() {
8079 if let ColumnConstraint::References(fk_ref) =
8080 &col.constraints[references_idx]
8081 {
8082 if let Some(ref name) = fk_ref.constraint_name {
8084 self.write_space();
8085 self.write_keyword("CONSTRAINT");
8086 self.write_space();
8087 self.write(name);
8088 }
8089 self.write_space();
8090 if fk_ref.has_foreign_key_keywords {
8091 self.write_keyword("FOREIGN KEY");
8092 self.write_space();
8093 }
8094 self.write_keyword("REFERENCES");
8095 self.write_space();
8096 self.generate_table(&fk_ref.table)?;
8097 if !fk_ref.columns.is_empty() {
8098 self.write(" (");
8099 for (i, c) in fk_ref.columns.iter().enumerate() {
8100 if i > 0 {
8101 self.write(", ");
8102 }
8103 self.generate_identifier(c)?;
8104 }
8105 self.write(")");
8106 }
8107 self.generate_referential_actions(fk_ref)?;
8108 references_idx += 1;
8109 break;
8110 }
8111 references_idx += 1;
8112 }
8113 }
8114 ConstraintType::Check => {
8115 while check_idx < col.constraints.len() {
8117 if let ColumnConstraint::Check(expr) = &col.constraints[check_idx] {
8118 if check_idx == 0 {
8120 if let Some(ref cname) = col.check_constraint_name {
8121 self.write_space();
8122 self.write_keyword("CONSTRAINT");
8123 self.write_space();
8124 self.write(cname);
8125 }
8126 }
8127 self.write_space();
8128 self.write_keyword("CHECK");
8129 self.write(" (");
8130 self.generate_expression(expr)?;
8131 self.write(")");
8132 check_idx += 1;
8133 break;
8134 }
8135 check_idx += 1;
8136 }
8137 }
8138 ConstraintType::GeneratedAsIdentity => {
8139 while generated_idx < col.constraints.len() {
8141 if let ColumnConstraint::GeneratedAsIdentity(gen) =
8142 &col.constraints[generated_idx]
8143 {
8144 self.write_space();
8145 if matches!(
8147 self.config.dialect,
8148 Some(crate::dialects::DialectType::Redshift)
8149 ) {
8150 self.write_keyword("IDENTITY");
8151 self.write("(");
8152 if let Some(ref start) = gen.start {
8153 self.generate_expression(start)?;
8154 } else {
8155 self.write("0");
8156 }
8157 self.write(", ");
8158 if let Some(ref incr) = gen.increment {
8159 self.generate_expression(incr)?;
8160 } else {
8161 self.write("1");
8162 }
8163 self.write(")");
8164 } else {
8165 self.write_keyword("GENERATED");
8166 if gen.always {
8167 self.write_space();
8168 self.write_keyword("ALWAYS");
8169 } else {
8170 self.write_space();
8171 self.write_keyword("BY DEFAULT");
8172 if gen.on_null {
8173 self.write_space();
8174 self.write_keyword("ON NULL");
8175 }
8176 }
8177 self.write_space();
8178 self.write_keyword("AS IDENTITY");
8179
8180 let has_options = gen.start.is_some()
8181 || gen.increment.is_some()
8182 || gen.minvalue.is_some()
8183 || gen.maxvalue.is_some()
8184 || gen.cycle.is_some();
8185 if has_options {
8186 self.write(" (");
8187 let mut first = true;
8188 if let Some(ref start) = gen.start {
8189 if !first {
8190 self.write(" ");
8191 }
8192 first = false;
8193 self.write_keyword("START WITH");
8194 self.write_space();
8195 self.generate_expression(start)?;
8196 }
8197 if let Some(ref incr) = gen.increment {
8198 if !first {
8199 self.write(" ");
8200 }
8201 first = false;
8202 self.write_keyword("INCREMENT BY");
8203 self.write_space();
8204 self.generate_expression(incr)?;
8205 }
8206 if let Some(ref minv) = gen.minvalue {
8207 if !first {
8208 self.write(" ");
8209 }
8210 first = false;
8211 self.write_keyword("MINVALUE");
8212 self.write_space();
8213 self.generate_expression(minv)?;
8214 }
8215 if let Some(ref maxv) = gen.maxvalue {
8216 if !first {
8217 self.write(" ");
8218 }
8219 first = false;
8220 self.write_keyword("MAXVALUE");
8221 self.write_space();
8222 self.generate_expression(maxv)?;
8223 }
8224 if let Some(cycle) = gen.cycle {
8225 if !first {
8226 self.write(" ");
8227 }
8228 if cycle {
8229 self.write_keyword("CYCLE");
8230 } else {
8231 self.write_keyword("NO CYCLE");
8232 }
8233 }
8234 self.write(")");
8235 }
8236 }
8237 generated_idx += 1;
8238 break;
8239 }
8240 generated_idx += 1;
8241 }
8242 }
8243 ConstraintType::Collate => {
8244 while collate_idx < col.constraints.len() {
8246 if let ColumnConstraint::Collate(collation) =
8247 &col.constraints[collate_idx]
8248 {
8249 self.write_space();
8250 self.write_keyword("COLLATE");
8251 self.write_space();
8252 self.generate_identifier(collation)?;
8253 collate_idx += 1;
8254 break;
8255 }
8256 collate_idx += 1;
8257 }
8258 }
8259 ConstraintType::Comment => {
8260 while comment_idx < col.constraints.len() {
8262 if let ColumnConstraint::Comment(comment) =
8263 &col.constraints[comment_idx]
8264 {
8265 self.write_space();
8266 self.write_keyword("COMMENT");
8267 self.write_space();
8268 self.generate_string_literal(comment)?;
8269 comment_idx += 1;
8270 break;
8271 }
8272 comment_idx += 1;
8273 }
8274 }
8275 ConstraintType::Tags => {
8276 for constraint in &col.constraints {
8278 if let ColumnConstraint::Tags(tags) = constraint {
8279 self.write_space();
8280 self.write_keyword("TAG");
8281 self.write(" (");
8282 for (i, expr) in tags.expressions.iter().enumerate() {
8283 if i > 0 {
8284 self.write(", ");
8285 }
8286 self.generate_expression(expr)?;
8287 }
8288 self.write(")");
8289 break;
8290 }
8291 }
8292 }
8293 ConstraintType::ComputedColumn => {
8294 for constraint in &col.constraints {
8296 if let ColumnConstraint::ComputedColumn(cc) = constraint {
8297 self.write_space();
8298 self.generate_computed_column_inline(cc)?;
8299 break;
8300 }
8301 }
8302 }
8303 ConstraintType::GeneratedAsRow => {
8304 for constraint in &col.constraints {
8306 if let ColumnConstraint::GeneratedAsRow(gar) = constraint {
8307 self.write_space();
8308 self.generate_generated_as_row_inline(gar)?;
8309 break;
8310 }
8311 }
8312 }
8313 ConstraintType::OnUpdate => {
8314 if let Some(ref expr) = col.on_update {
8315 self.write_space();
8316 self.write_keyword("ON UPDATE");
8317 self.write_space();
8318 self.generate_expression(expr)?;
8319 }
8320 }
8321 ConstraintType::Encode => {
8322 if let Some(ref encoding) = col.encoding {
8323 self.write_space();
8324 self.write_keyword("ENCODE");
8325 self.write_space();
8326 self.write(encoding);
8327 }
8328 }
8329 ConstraintType::Path => {
8330 for constraint in &col.constraints {
8332 if let ColumnConstraint::Path(path_expr) = constraint {
8333 self.write_space();
8334 self.write_keyword("PATH");
8335 self.write_space();
8336 self.generate_expression(path_expr)?;
8337 break;
8338 }
8339 }
8340 }
8341 }
8342 }
8343 if pending_not_null_after_identity {
8344 self.write_space();
8345 self.write_keyword("NOT NULL");
8346 }
8347 } else {
8348 if col.primary_key {
8350 self.write_space();
8351 self.write_keyword("PRIMARY KEY");
8352 if let Some(ref order) = col.primary_key_order {
8353 self.write_space();
8354 match order {
8355 SortOrder::Asc => self.write_keyword("ASC"),
8356 SortOrder::Desc => self.write_keyword("DESC"),
8357 }
8358 }
8359 }
8360
8361 if col.unique {
8362 self.write_space();
8363 self.write_keyword("UNIQUE");
8364 if col.unique_nulls_not_distinct {
8366 self.write(" NULLS NOT DISTINCT");
8367 }
8368 }
8369
8370 match col.nullable {
8371 Some(false) => {
8372 self.write_space();
8373 self.write_keyword("NOT NULL");
8374 }
8375 Some(true) => {
8376 self.write_space();
8377 self.write_keyword("NULL");
8378 }
8379 None => {}
8380 }
8381
8382 if let Some(ref default) = col.default {
8383 self.write_space();
8384 self.write_keyword("DEFAULT");
8385 self.write_space();
8386 self.generate_expression(default)?;
8387 }
8388
8389 if col.auto_increment {
8390 self.write_space();
8391 self.generate_auto_increment_keyword(col)?;
8392 }
8393
8394 for constraint in &col.constraints {
8396 match constraint {
8397 ColumnConstraint::References(fk_ref) => {
8398 self.write_space();
8399 if fk_ref.has_foreign_key_keywords {
8400 self.write_keyword("FOREIGN KEY");
8401 self.write_space();
8402 }
8403 self.write_keyword("REFERENCES");
8404 self.write_space();
8405 self.generate_table(&fk_ref.table)?;
8406 if !fk_ref.columns.is_empty() {
8407 self.write(" (");
8408 for (i, c) in fk_ref.columns.iter().enumerate() {
8409 if i > 0 {
8410 self.write(", ");
8411 }
8412 self.generate_identifier(c)?;
8413 }
8414 self.write(")");
8415 }
8416 self.generate_referential_actions(fk_ref)?;
8417 }
8418 ColumnConstraint::Check(expr) => {
8419 self.write_space();
8420 self.write_keyword("CHECK");
8421 self.write(" (");
8422 self.generate_expression(expr)?;
8423 self.write(")");
8424 }
8425 ColumnConstraint::GeneratedAsIdentity(gen) => {
8426 self.write_space();
8427 if matches!(
8429 self.config.dialect,
8430 Some(crate::dialects::DialectType::Redshift)
8431 ) {
8432 self.write_keyword("IDENTITY");
8433 self.write("(");
8434 if let Some(ref start) = gen.start {
8435 self.generate_expression(start)?;
8436 } else {
8437 self.write("0");
8438 }
8439 self.write(", ");
8440 if let Some(ref incr) = gen.increment {
8441 self.generate_expression(incr)?;
8442 } else {
8443 self.write("1");
8444 }
8445 self.write(")");
8446 } else {
8447 self.write_keyword("GENERATED");
8448 if gen.always {
8449 self.write_space();
8450 self.write_keyword("ALWAYS");
8451 } else {
8452 self.write_space();
8453 self.write_keyword("BY DEFAULT");
8454 if gen.on_null {
8455 self.write_space();
8456 self.write_keyword("ON NULL");
8457 }
8458 }
8459 self.write_space();
8460 self.write_keyword("AS IDENTITY");
8461
8462 let has_options = gen.start.is_some()
8463 || gen.increment.is_some()
8464 || gen.minvalue.is_some()
8465 || gen.maxvalue.is_some()
8466 || gen.cycle.is_some();
8467 if has_options {
8468 self.write(" (");
8469 let mut first = true;
8470 if let Some(ref start) = gen.start {
8471 if !first {
8472 self.write(" ");
8473 }
8474 first = false;
8475 self.write_keyword("START WITH");
8476 self.write_space();
8477 self.generate_expression(start)?;
8478 }
8479 if let Some(ref incr) = gen.increment {
8480 if !first {
8481 self.write(" ");
8482 }
8483 first = false;
8484 self.write_keyword("INCREMENT BY");
8485 self.write_space();
8486 self.generate_expression(incr)?;
8487 }
8488 if let Some(ref minv) = gen.minvalue {
8489 if !first {
8490 self.write(" ");
8491 }
8492 first = false;
8493 self.write_keyword("MINVALUE");
8494 self.write_space();
8495 self.generate_expression(minv)?;
8496 }
8497 if let Some(ref maxv) = gen.maxvalue {
8498 if !first {
8499 self.write(" ");
8500 }
8501 first = false;
8502 self.write_keyword("MAXVALUE");
8503 self.write_space();
8504 self.generate_expression(maxv)?;
8505 }
8506 if let Some(cycle) = gen.cycle {
8507 if !first {
8508 self.write(" ");
8509 }
8510 if cycle {
8511 self.write_keyword("CYCLE");
8512 } else {
8513 self.write_keyword("NO CYCLE");
8514 }
8515 }
8516 self.write(")");
8517 }
8518 }
8519 }
8520 ColumnConstraint::Collate(collation) => {
8521 self.write_space();
8522 self.write_keyword("COLLATE");
8523 self.write_space();
8524 self.generate_identifier(collation)?;
8525 }
8526 ColumnConstraint::Comment(comment) => {
8527 self.write_space();
8528 self.write_keyword("COMMENT");
8529 self.write_space();
8530 self.generate_string_literal(comment)?;
8531 }
8532 ColumnConstraint::Path(path_expr) => {
8533 self.write_space();
8534 self.write_keyword("PATH");
8535 self.write_space();
8536 self.generate_expression(path_expr)?;
8537 }
8538 _ => {} }
8540 }
8541
8542 if let Some(ref encoding) = col.encoding {
8544 self.write_space();
8545 self.write_keyword("ENCODE");
8546 self.write_space();
8547 self.write(encoding);
8548 }
8549 }
8550
8551 if let Some(ref codec) = col.codec {
8553 self.write_space();
8554 self.write_keyword("CODEC");
8555 self.write("(");
8556 self.write(codec);
8557 self.write(")");
8558 }
8559
8560 if let Some(ref ephemeral) = col.ephemeral {
8562 self.write_space();
8563 self.write_keyword("EPHEMERAL");
8564 if let Some(ref expr) = ephemeral {
8565 self.write_space();
8566 self.generate_expression(expr)?;
8567 }
8568 }
8569
8570 if let Some(ref mat_expr) = col.materialized_expr {
8572 self.write_space();
8573 self.write_keyword("MATERIALIZED");
8574 self.write_space();
8575 self.generate_expression(mat_expr)?;
8576 }
8577
8578 if let Some(ref alias_expr) = col.alias_expr {
8580 self.write_space();
8581 self.write_keyword("ALIAS");
8582 self.write_space();
8583 self.generate_expression(alias_expr)?;
8584 }
8585
8586 if let Some(ref ttl_expr) = col.ttl_expr {
8588 self.write_space();
8589 self.write_keyword("TTL");
8590 self.write_space();
8591 self.generate_expression(ttl_expr)?;
8592 }
8593
8594 if col.not_for_replication
8596 && matches!(
8597 self.config.dialect,
8598 Some(crate::dialects::DialectType::TSQL)
8599 | Some(crate::dialects::DialectType::Fabric)
8600 )
8601 {
8602 self.write_space();
8603 self.write_keyword("NOT FOR REPLICATION");
8604 }
8605
8606 if !col.options.is_empty() {
8608 self.write_space();
8609 self.generate_options_clause(&col.options)?;
8610 }
8611
8612 if !col.primary_key
8615 && self
8616 .sqlite_inline_pk_columns
8617 .contains(&col.name.name.to_lowercase())
8618 {
8619 self.write_space();
8620 self.write_keyword("PRIMARY KEY");
8621 }
8622
8623 if serial_expansion.is_some() {
8626 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
8627 self.write_space();
8628 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY NOT NULL");
8629 } else if matches!(self.config.dialect, Some(DialectType::Materialize)) {
8630 self.write_space();
8631 self.write_keyword("NOT NULL");
8632 }
8633 }
8634
8635 Ok(())
8636 }
8637
8638 fn generate_table_constraint(&mut self, constraint: &TableConstraint) -> Result<()> {
8639 match constraint {
8640 TableConstraint::PrimaryKey {
8641 name,
8642 columns,
8643 include_columns,
8644 modifiers,
8645 has_constraint_keyword,
8646 } => {
8647 if let Some(ref n) = name {
8648 if *has_constraint_keyword {
8649 self.write_keyword("CONSTRAINT");
8650 self.write_space();
8651 self.generate_identifier(n)?;
8652 self.write_space();
8653 }
8654 }
8655 self.write_keyword("PRIMARY KEY");
8656 if let Some(ref clustered) = modifiers.clustered {
8658 self.write_space();
8659 self.write_keyword(clustered);
8660 }
8661 if let Some(ref n) = name {
8663 if !*has_constraint_keyword {
8664 self.write_space();
8665 self.generate_identifier(n)?;
8666 }
8667 }
8668 self.write(" (");
8669 for (i, col) in columns.iter().enumerate() {
8670 if i > 0 {
8671 self.write(", ");
8672 }
8673 self.generate_identifier(col)?;
8674 }
8675 self.write(")");
8676 if !include_columns.is_empty() {
8677 self.write_space();
8678 self.write_keyword("INCLUDE");
8679 self.write(" (");
8680 for (i, col) in include_columns.iter().enumerate() {
8681 if i > 0 {
8682 self.write(", ");
8683 }
8684 self.generate_identifier(col)?;
8685 }
8686 self.write(")");
8687 }
8688 self.generate_constraint_modifiers(modifiers);
8689 }
8690 TableConstraint::Unique {
8691 name,
8692 columns,
8693 columns_parenthesized,
8694 modifiers,
8695 has_constraint_keyword,
8696 nulls_not_distinct,
8697 } => {
8698 if let Some(ref n) = name {
8699 if *has_constraint_keyword {
8700 self.write_keyword("CONSTRAINT");
8701 self.write_space();
8702 self.generate_identifier(n)?;
8703 self.write_space();
8704 }
8705 }
8706 self.write_keyword("UNIQUE");
8707 if let Some(ref clustered) = modifiers.clustered {
8709 self.write_space();
8710 self.write_keyword(clustered);
8711 }
8712 if *nulls_not_distinct {
8714 self.write(" NULLS NOT DISTINCT");
8715 }
8716 if let Some(ref n) = name {
8718 if !*has_constraint_keyword {
8719 self.write_space();
8720 self.generate_identifier(n)?;
8721 }
8722 }
8723 if *columns_parenthesized {
8724 self.write(" (");
8725 for (i, col) in columns.iter().enumerate() {
8726 if i > 0 {
8727 self.write(", ");
8728 }
8729 self.generate_identifier(col)?;
8730 }
8731 self.write(")");
8732 } else {
8733 for col in columns.iter() {
8735 self.write_space();
8736 self.generate_identifier(col)?;
8737 }
8738 }
8739 self.generate_constraint_modifiers(modifiers);
8740 }
8741 TableConstraint::ForeignKey {
8742 name,
8743 columns,
8744 references,
8745 on_delete,
8746 on_update,
8747 modifiers,
8748 } => {
8749 if let Some(ref n) = name {
8750 self.write_keyword("CONSTRAINT");
8751 self.write_space();
8752 self.generate_identifier(n)?;
8753 self.write_space();
8754 }
8755 self.write_keyword("FOREIGN KEY");
8756 self.write(" (");
8757 for (i, col) in columns.iter().enumerate() {
8758 if i > 0 {
8759 self.write(", ");
8760 }
8761 self.generate_identifier(col)?;
8762 }
8763 self.write(")");
8764 if let Some(ref refs) = references {
8765 self.write(" ");
8766 self.write_keyword("REFERENCES");
8767 self.write_space();
8768 self.generate_table(&refs.table)?;
8769 if !refs.columns.is_empty() {
8770 if self.config.pretty {
8771 self.write(" (");
8772 self.write_newline();
8773 self.indent_level += 1;
8774 for (i, col) in refs.columns.iter().enumerate() {
8775 if i > 0 {
8776 self.write(",");
8777 self.write_newline();
8778 }
8779 self.write_indent();
8780 self.generate_identifier(col)?;
8781 }
8782 self.indent_level -= 1;
8783 self.write_newline();
8784 self.write_indent();
8785 self.write(")");
8786 } else {
8787 self.write(" (");
8788 for (i, col) in refs.columns.iter().enumerate() {
8789 if i > 0 {
8790 self.write(", ");
8791 }
8792 self.generate_identifier(col)?;
8793 }
8794 self.write(")");
8795 }
8796 }
8797 self.generate_referential_actions(refs)?;
8798 } else {
8799 if let Some(ref action) = on_delete {
8801 self.write_space();
8802 self.write_keyword("ON DELETE");
8803 self.write_space();
8804 self.generate_referential_action(action);
8805 }
8806 if let Some(ref action) = on_update {
8807 self.write_space();
8808 self.write_keyword("ON UPDATE");
8809 self.write_space();
8810 self.generate_referential_action(action);
8811 }
8812 }
8813 self.generate_constraint_modifiers(modifiers);
8814 }
8815 TableConstraint::Check {
8816 name,
8817 expression,
8818 modifiers,
8819 } => {
8820 if let Some(ref n) = name {
8821 self.write_keyword("CONSTRAINT");
8822 self.write_space();
8823 self.generate_identifier(n)?;
8824 self.write_space();
8825 }
8826 self.write_keyword("CHECK");
8827 self.write(" (");
8828 self.generate_expression(expression)?;
8829 self.write(")");
8830 self.generate_constraint_modifiers(modifiers);
8831 }
8832 TableConstraint::Index {
8833 name,
8834 columns,
8835 kind,
8836 modifiers,
8837 use_key_keyword,
8838 expression,
8839 index_type,
8840 granularity,
8841 } => {
8842 if expression.is_some() {
8844 self.write_keyword("INDEX");
8845 if let Some(ref n) = name {
8846 self.write_space();
8847 self.generate_identifier(n)?;
8848 }
8849 if let Some(ref expr) = expression {
8850 self.write_space();
8851 self.generate_expression(expr)?;
8852 }
8853 if let Some(ref idx_type) = index_type {
8854 self.write_space();
8855 self.write_keyword("TYPE");
8856 self.write_space();
8857 self.generate_expression(idx_type)?;
8858 }
8859 if let Some(ref gran) = granularity {
8860 self.write_space();
8861 self.write_keyword("GRANULARITY");
8862 self.write_space();
8863 self.generate_expression(gran)?;
8864 }
8865 } else {
8866 use crate::dialects::DialectType;
8870 let index_keyword = if *use_key_keyword
8871 && !matches!(self.config.dialect, Some(DialectType::MySQL))
8872 {
8873 "KEY"
8874 } else {
8875 "INDEX"
8876 };
8877
8878 if let Some(ref k) = kind {
8880 self.write_keyword(k);
8881 if k != "UNIQUE" {
8883 self.write_space();
8884 self.write_keyword(index_keyword);
8885 }
8886 } else {
8887 self.write_keyword(index_keyword);
8888 }
8889
8890 if modifiers.using_before_columns && name.is_none() {
8892 if let Some(ref using) = modifiers.using {
8893 self.write_space();
8894 self.write_keyword("USING");
8895 self.write_space();
8896 self.write_keyword(using);
8897 }
8898 }
8899
8900 if let Some(ref n) = name {
8902 self.write_space();
8903 self.generate_identifier(n)?;
8904 }
8905
8906 if modifiers.using_before_columns && name.is_some() {
8908 if let Some(ref using) = modifiers.using {
8909 self.write_space();
8910 self.write_keyword("USING");
8911 self.write_space();
8912 self.write_keyword(using);
8913 }
8914 }
8915
8916 self.write(" (");
8918 for (i, col) in columns.iter().enumerate() {
8919 if i > 0 {
8920 self.write(", ");
8921 }
8922 self.generate_identifier(col)?;
8923 }
8924 self.write(")");
8925
8926 if !modifiers.using_before_columns {
8928 if let Some(ref using) = modifiers.using {
8929 self.write_space();
8930 self.write_keyword("USING");
8931 self.write_space();
8932 self.write_keyword(using);
8933 }
8934 }
8935
8936 self.generate_constraint_modifiers_without_using(modifiers);
8938 }
8939 }
8940 TableConstraint::Projection { name, expression } => {
8941 self.write_keyword("PROJECTION");
8943 self.write_space();
8944 self.generate_identifier(name)?;
8945 self.write(" (");
8946 self.generate_expression(expression)?;
8947 self.write(")");
8948 }
8949 TableConstraint::Like { source, options } => {
8950 self.write_keyword("LIKE");
8951 self.write_space();
8952 self.generate_table(source)?;
8953 for (action, prop) in options {
8954 self.write_space();
8955 match action {
8956 LikeOptionAction::Including => self.write_keyword("INCLUDING"),
8957 LikeOptionAction::Excluding => self.write_keyword("EXCLUDING"),
8958 }
8959 self.write_space();
8960 self.write_keyword(prop);
8961 }
8962 }
8963 TableConstraint::PeriodForSystemTime { start_col, end_col } => {
8964 self.write_keyword("PERIOD FOR SYSTEM_TIME");
8965 self.write(" (");
8966 self.generate_identifier(start_col)?;
8967 self.write(", ");
8968 self.generate_identifier(end_col)?;
8969 self.write(")");
8970 }
8971 TableConstraint::Exclude {
8972 name,
8973 using,
8974 elements,
8975 include_columns,
8976 where_clause,
8977 with_params,
8978 using_index_tablespace,
8979 modifiers: _,
8980 } => {
8981 if let Some(ref n) = name {
8982 self.write_keyword("CONSTRAINT");
8983 self.write_space();
8984 self.generate_identifier(n)?;
8985 self.write_space();
8986 }
8987 self.write_keyword("EXCLUDE");
8988 if let Some(ref method) = using {
8989 self.write_space();
8990 self.write_keyword("USING");
8991 self.write_space();
8992 self.write(method);
8993 self.write("(");
8994 } else {
8995 self.write(" (");
8996 }
8997 for (i, elem) in elements.iter().enumerate() {
8998 if i > 0 {
8999 self.write(", ");
9000 }
9001 self.write(&elem.expression);
9002 self.write_space();
9003 self.write_keyword("WITH");
9004 self.write_space();
9005 self.write(&elem.operator);
9006 }
9007 self.write(")");
9008 if !include_columns.is_empty() {
9009 self.write_space();
9010 self.write_keyword("INCLUDE");
9011 self.write(" (");
9012 for (i, col) in include_columns.iter().enumerate() {
9013 if i > 0 {
9014 self.write(", ");
9015 }
9016 self.generate_identifier(col)?;
9017 }
9018 self.write(")");
9019 }
9020 if !with_params.is_empty() {
9021 self.write_space();
9022 self.write_keyword("WITH");
9023 self.write(" (");
9024 for (i, (key, val)) in with_params.iter().enumerate() {
9025 if i > 0 {
9026 self.write(", ");
9027 }
9028 self.write(key);
9029 self.write("=");
9030 self.write(val);
9031 }
9032 self.write(")");
9033 }
9034 if let Some(ref tablespace) = using_index_tablespace {
9035 self.write_space();
9036 self.write_keyword("USING INDEX TABLESPACE");
9037 self.write_space();
9038 self.write(tablespace);
9039 }
9040 if let Some(ref where_expr) = where_clause {
9041 self.write_space();
9042 self.write_keyword("WHERE");
9043 self.write(" (");
9044 self.generate_expression(where_expr)?;
9045 self.write(")");
9046 }
9047 }
9048 TableConstraint::Tags(tags) => {
9049 self.write_keyword("TAG");
9050 self.write(" (");
9051 for (i, expr) in tags.expressions.iter().enumerate() {
9052 if i > 0 {
9053 self.write(", ");
9054 }
9055 self.generate_expression(expr)?;
9056 }
9057 self.write(")");
9058 }
9059 TableConstraint::InitiallyDeferred { deferred } => {
9060 self.write_keyword("INITIALLY");
9061 self.write_space();
9062 if *deferred {
9063 self.write_keyword("DEFERRED");
9064 } else {
9065 self.write_keyword("IMMEDIATE");
9066 }
9067 }
9068 }
9069 Ok(())
9070 }
9071
9072 fn generate_constraint_modifiers(&mut self, modifiers: &ConstraintModifiers) {
9073 if let Some(using) = &modifiers.using {
9075 self.write_space();
9076 self.write_keyword("USING");
9077 self.write_space();
9078 self.write_keyword(using);
9079 }
9080 if let Some(enforced) = modifiers.enforced {
9082 self.write_space();
9083 if enforced {
9084 self.write_keyword("ENFORCED");
9085 } else {
9086 self.write_keyword("NOT ENFORCED");
9087 }
9088 }
9089 if let Some(deferrable) = modifiers.deferrable {
9091 self.write_space();
9092 if deferrable {
9093 self.write_keyword("DEFERRABLE");
9094 } else {
9095 self.write_keyword("NOT DEFERRABLE");
9096 }
9097 }
9098 if let Some(initially_deferred) = modifiers.initially_deferred {
9100 self.write_space();
9101 if initially_deferred {
9102 self.write_keyword("INITIALLY DEFERRED");
9103 } else {
9104 self.write_keyword("INITIALLY IMMEDIATE");
9105 }
9106 }
9107 if modifiers.norely {
9109 self.write_space();
9110 self.write_keyword("NORELY");
9111 }
9112 if modifiers.rely {
9114 self.write_space();
9115 self.write_keyword("RELY");
9116 }
9117 if modifiers.not_valid {
9119 self.write_space();
9120 self.write_keyword("NOT VALID");
9121 }
9122 if let Some(on_conflict) = &modifiers.on_conflict {
9124 self.write_space();
9125 self.write_keyword("ON CONFLICT");
9126 self.write_space();
9127 self.write_keyword(on_conflict);
9128 }
9129 if !modifiers.with_options.is_empty() {
9131 self.write_space();
9132 self.write_keyword("WITH");
9133 self.write(" (");
9134 for (i, (key, value)) in modifiers.with_options.iter().enumerate() {
9135 if i > 0 {
9136 self.write(", ");
9137 }
9138 self.write(key);
9139 self.write("=");
9140 self.write(value);
9141 }
9142 self.write(")");
9143 }
9144 if let Some(ref fg) = modifiers.on_filegroup {
9146 self.write_space();
9147 self.write_keyword("ON");
9148 self.write_space();
9149 let _ = self.generate_identifier(fg);
9150 }
9151 }
9152
9153 fn generate_constraint_modifiers_without_using(&mut self, modifiers: &ConstraintModifiers) {
9155 if let Some(enforced) = modifiers.enforced {
9157 self.write_space();
9158 if enforced {
9159 self.write_keyword("ENFORCED");
9160 } else {
9161 self.write_keyword("NOT ENFORCED");
9162 }
9163 }
9164 if let Some(deferrable) = modifiers.deferrable {
9166 self.write_space();
9167 if deferrable {
9168 self.write_keyword("DEFERRABLE");
9169 } else {
9170 self.write_keyword("NOT DEFERRABLE");
9171 }
9172 }
9173 if let Some(initially_deferred) = modifiers.initially_deferred {
9175 self.write_space();
9176 if initially_deferred {
9177 self.write_keyword("INITIALLY DEFERRED");
9178 } else {
9179 self.write_keyword("INITIALLY IMMEDIATE");
9180 }
9181 }
9182 if modifiers.norely {
9184 self.write_space();
9185 self.write_keyword("NORELY");
9186 }
9187 if modifiers.rely {
9189 self.write_space();
9190 self.write_keyword("RELY");
9191 }
9192 if modifiers.not_valid {
9194 self.write_space();
9195 self.write_keyword("NOT VALID");
9196 }
9197 if let Some(on_conflict) = &modifiers.on_conflict {
9199 self.write_space();
9200 self.write_keyword("ON CONFLICT");
9201 self.write_space();
9202 self.write_keyword(on_conflict);
9203 }
9204 self.generate_index_specific_modifiers(modifiers);
9206 }
9207
9208 fn generate_index_specific_modifiers(&mut self, modifiers: &ConstraintModifiers) {
9210 if let Some(ref comment) = modifiers.comment {
9211 self.write_space();
9212 self.write_keyword("COMMENT");
9213 self.write(" '");
9214 self.write(comment);
9215 self.write("'");
9216 }
9217 if let Some(visible) = modifiers.visible {
9218 self.write_space();
9219 if visible {
9220 self.write_keyword("VISIBLE");
9221 } else {
9222 self.write_keyword("INVISIBLE");
9223 }
9224 }
9225 if let Some(ref attr) = modifiers.engine_attribute {
9226 self.write_space();
9227 self.write_keyword("ENGINE_ATTRIBUTE");
9228 self.write(" = '");
9229 self.write(attr);
9230 self.write("'");
9231 }
9232 if let Some(ref parser) = modifiers.with_parser {
9233 self.write_space();
9234 self.write_keyword("WITH PARSER");
9235 self.write_space();
9236 self.write(parser);
9237 }
9238 }
9239
9240 fn generate_referential_actions(&mut self, fk_ref: &ForeignKeyRef) -> Result<()> {
9241 if !fk_ref.match_after_actions {
9243 if let Some(ref match_type) = fk_ref.match_type {
9244 self.write_space();
9245 self.write_keyword("MATCH");
9246 self.write_space();
9247 match match_type {
9248 MatchType::Full => self.write_keyword("FULL"),
9249 MatchType::Partial => self.write_keyword("PARTIAL"),
9250 MatchType::Simple => self.write_keyword("SIMPLE"),
9251 }
9252 }
9253 }
9254
9255 if fk_ref.on_update_first {
9257 if let Some(ref action) = fk_ref.on_update {
9258 self.write_space();
9259 self.write_keyword("ON UPDATE");
9260 self.write_space();
9261 self.generate_referential_action(action);
9262 }
9263 if let Some(ref action) = fk_ref.on_delete {
9264 self.write_space();
9265 self.write_keyword("ON DELETE");
9266 self.write_space();
9267 self.generate_referential_action(action);
9268 }
9269 } else {
9270 if let Some(ref action) = fk_ref.on_delete {
9271 self.write_space();
9272 self.write_keyword("ON DELETE");
9273 self.write_space();
9274 self.generate_referential_action(action);
9275 }
9276 if let Some(ref action) = fk_ref.on_update {
9277 self.write_space();
9278 self.write_keyword("ON UPDATE");
9279 self.write_space();
9280 self.generate_referential_action(action);
9281 }
9282 }
9283
9284 if fk_ref.match_after_actions {
9286 if let Some(ref match_type) = fk_ref.match_type {
9287 self.write_space();
9288 self.write_keyword("MATCH");
9289 self.write_space();
9290 match match_type {
9291 MatchType::Full => self.write_keyword("FULL"),
9292 MatchType::Partial => self.write_keyword("PARTIAL"),
9293 MatchType::Simple => self.write_keyword("SIMPLE"),
9294 }
9295 }
9296 }
9297
9298 if let Some(deferrable) = fk_ref.deferrable {
9300 self.write_space();
9301 if deferrable {
9302 self.write_keyword("DEFERRABLE");
9303 } else {
9304 self.write_keyword("NOT DEFERRABLE");
9305 }
9306 }
9307
9308 Ok(())
9309 }
9310
9311 fn generate_referential_action(&mut self, action: &ReferentialAction) {
9312 match action {
9313 ReferentialAction::Cascade => self.write_keyword("CASCADE"),
9314 ReferentialAction::SetNull => self.write_keyword("SET NULL"),
9315 ReferentialAction::SetDefault => self.write_keyword("SET DEFAULT"),
9316 ReferentialAction::Restrict => self.write_keyword("RESTRICT"),
9317 ReferentialAction::NoAction => self.write_keyword("NO ACTION"),
9318 }
9319 }
9320
9321 fn generate_drop_table(&mut self, dt: &DropTable) -> Result<()> {
9322 let saved_athena_hive_context = self.athena_hive_context;
9324 if matches!(
9325 self.config.dialect,
9326 Some(crate::dialects::DialectType::Athena)
9327 ) {
9328 self.athena_hive_context = true;
9329 }
9330
9331 for comment in &dt.leading_comments {
9333 self.write_formatted_comment(comment);
9334 self.write_space();
9335 }
9336 self.write_keyword("DROP TABLE");
9337
9338 if dt.if_exists {
9339 self.write_space();
9340 self.write_keyword("IF EXISTS");
9341 }
9342
9343 self.write_space();
9344 for (i, table) in dt.names.iter().enumerate() {
9345 if i > 0 {
9346 self.write(", ");
9347 }
9348 self.generate_table(table)?;
9349 }
9350
9351 if dt.cascade_constraints {
9352 self.write_space();
9353 self.write_keyword("CASCADE CONSTRAINTS");
9354 } else if dt.cascade {
9355 self.write_space();
9356 self.write_keyword("CASCADE");
9357 }
9358
9359 if dt.purge {
9360 self.write_space();
9361 self.write_keyword("PURGE");
9362 }
9363
9364 self.athena_hive_context = saved_athena_hive_context;
9366
9367 Ok(())
9368 }
9369
9370 fn generate_alter_table(&mut self, at: &AlterTable) -> Result<()> {
9371 let saved_athena_hive_context = self.athena_hive_context;
9373 if matches!(
9374 self.config.dialect,
9375 Some(crate::dialects::DialectType::Athena)
9376 ) {
9377 self.athena_hive_context = true;
9378 }
9379
9380 self.write_keyword("ALTER TABLE");
9381 if at.if_exists {
9382 self.write_space();
9383 self.write_keyword("IF EXISTS");
9384 }
9385 self.write_space();
9386 self.generate_table(&at.name)?;
9387
9388 if let Some(ref on_cluster) = at.on_cluster {
9390 self.write_space();
9391 self.generate_on_cluster(on_cluster)?;
9392 }
9393
9394 if let Some(ref partition) = at.partition {
9396 self.write_space();
9397 self.write_keyword("PARTITION");
9398 self.write("(");
9399 for (i, (key, value)) in partition.iter().enumerate() {
9400 if i > 0 {
9401 self.write(", ");
9402 }
9403 self.generate_identifier(key)?;
9404 self.write(" = ");
9405 self.generate_expression(value)?;
9406 }
9407 self.write(")");
9408 }
9409
9410 if let Some(ref with_check) = at.with_check {
9412 self.write_space();
9413 self.write_keyword(with_check);
9414 }
9415
9416 if self.config.pretty {
9417 self.write_newline();
9419 self.indent_level += 1;
9420 for (i, action) in at.actions.iter().enumerate() {
9421 let is_continuation = i > 0
9423 && matches!(
9424 (&at.actions[i - 1], action),
9425 (
9426 AlterTableAction::AddColumn { .. },
9427 AlterTableAction::AddColumn { .. }
9428 ) | (
9429 AlterTableAction::AddConstraint(_),
9430 AlterTableAction::AddConstraint(_)
9431 )
9432 );
9433 if i > 0 {
9434 self.write(",");
9435 self.write_newline();
9436 }
9437 self.write_indent();
9438 self.generate_alter_action_with_continuation(action, is_continuation)?;
9439 }
9440 self.indent_level -= 1;
9441 } else {
9442 for (i, action) in at.actions.iter().enumerate() {
9443 let is_continuation = i > 0
9445 && matches!(
9446 (&at.actions[i - 1], action),
9447 (
9448 AlterTableAction::AddColumn { .. },
9449 AlterTableAction::AddColumn { .. }
9450 ) | (
9451 AlterTableAction::AddConstraint(_),
9452 AlterTableAction::AddConstraint(_)
9453 )
9454 );
9455 if i > 0 {
9456 self.write(",");
9457 }
9458 self.write_space();
9459 self.generate_alter_action_with_continuation(action, is_continuation)?;
9460 }
9461 }
9462
9463 if let Some(ref algorithm) = at.algorithm {
9465 self.write(", ");
9466 self.write_keyword("ALGORITHM");
9467 self.write("=");
9468 self.write_keyword(algorithm);
9469 }
9470 if let Some(ref lock) = at.lock {
9471 self.write(", ");
9472 self.write_keyword("LOCK");
9473 self.write("=");
9474 self.write_keyword(lock);
9475 }
9476
9477 self.athena_hive_context = saved_athena_hive_context;
9479
9480 Ok(())
9481 }
9482
9483 fn generate_alter_action_with_continuation(
9484 &mut self,
9485 action: &AlterTableAction,
9486 is_continuation: bool,
9487 ) -> Result<()> {
9488 match action {
9489 AlterTableAction::AddColumn {
9490 column,
9491 if_not_exists,
9492 position,
9493 } => {
9494 use crate::dialects::DialectType;
9495 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
9499 let is_tsql_like = matches!(
9500 self.config.dialect,
9501 Some(DialectType::TSQL) | Some(DialectType::Fabric)
9502 );
9503 let is_athena = matches!(self.config.dialect, Some(DialectType::Athena));
9505
9506 if is_continuation && (is_snowflake || is_tsql_like) {
9507 } else if is_snowflake {
9509 self.write_keyword("ADD");
9510 self.write_space();
9511 } else if is_athena {
9512 self.write_keyword("ADD COLUMNS");
9514 self.write(" (");
9515 } else if self.config.alter_table_include_column_keyword {
9516 self.write_keyword("ADD COLUMN");
9517 self.write_space();
9518 } else {
9519 self.write_keyword("ADD");
9521 self.write_space();
9522 }
9523
9524 if *if_not_exists {
9525 self.write_keyword("IF NOT EXISTS");
9526 self.write_space();
9527 }
9528 self.generate_column_def(column)?;
9529
9530 if is_athena {
9532 self.write(")");
9533 }
9534
9535 if let Some(pos) = position {
9537 self.write_space();
9538 match pos {
9539 ColumnPosition::First => self.write_keyword("FIRST"),
9540 ColumnPosition::After(col_name) => {
9541 self.write_keyword("AFTER");
9542 self.write_space();
9543 self.generate_identifier(col_name)?;
9544 }
9545 }
9546 }
9547 }
9548 AlterTableAction::DropColumn {
9549 name,
9550 if_exists,
9551 cascade,
9552 } => {
9553 self.write_keyword("DROP COLUMN");
9554 if *if_exists {
9555 self.write_space();
9556 self.write_keyword("IF EXISTS");
9557 }
9558 self.write_space();
9559 self.generate_identifier(name)?;
9560 if *cascade {
9561 self.write_space();
9562 self.write_keyword("CASCADE");
9563 }
9564 }
9565 AlterTableAction::DropColumns { names } => {
9566 self.write_keyword("DROP COLUMNS");
9567 self.write(" (");
9568 for (i, name) in names.iter().enumerate() {
9569 if i > 0 {
9570 self.write(", ");
9571 }
9572 self.generate_identifier(name)?;
9573 }
9574 self.write(")");
9575 }
9576 AlterTableAction::RenameColumn {
9577 old_name,
9578 new_name,
9579 if_exists,
9580 } => {
9581 self.write_keyword("RENAME COLUMN");
9582 if *if_exists {
9583 self.write_space();
9584 self.write_keyword("IF EXISTS");
9585 }
9586 self.write_space();
9587 self.generate_identifier(old_name)?;
9588 self.write_space();
9589 self.write_keyword("TO");
9590 self.write_space();
9591 self.generate_identifier(new_name)?;
9592 }
9593 AlterTableAction::AlterColumn {
9594 name,
9595 action,
9596 use_modify_keyword,
9597 } => {
9598 use crate::dialects::DialectType;
9599 let use_modify = *use_modify_keyword
9602 || (matches!(self.config.dialect, Some(DialectType::MySQL))
9603 && matches!(action, AlterColumnAction::SetDataType { .. }));
9604 if use_modify {
9605 self.write_keyword("MODIFY COLUMN");
9606 self.write_space();
9607 self.generate_identifier(name)?;
9608 if let AlterColumnAction::SetDataType {
9610 data_type,
9611 using: _,
9612 collate,
9613 } = action
9614 {
9615 self.write_space();
9616 self.generate_data_type(data_type)?;
9617 if let Some(collate_name) = collate {
9619 self.write_space();
9620 self.write_keyword("COLLATE");
9621 self.write_space();
9622 self.write(&format!("'{}'", collate_name));
9624 }
9625 } else {
9626 self.write_space();
9627 self.generate_alter_column_action(action)?;
9628 }
9629 } else if matches!(self.config.dialect, Some(DialectType::Hive))
9630 && matches!(action, AlterColumnAction::SetDataType { .. })
9631 {
9632 self.write_keyword("CHANGE COLUMN");
9634 self.write_space();
9635 self.generate_identifier(name)?;
9636 self.write_space();
9637 self.generate_identifier(name)?;
9638 if let AlterColumnAction::SetDataType { data_type, .. } = action {
9639 self.write_space();
9640 self.generate_data_type(data_type)?;
9641 }
9642 } else {
9643 self.write_keyword("ALTER COLUMN");
9644 self.write_space();
9645 self.generate_identifier(name)?;
9646 self.write_space();
9647 self.generate_alter_column_action(action)?;
9648 }
9649 }
9650 AlterTableAction::RenameTable(new_name) => {
9651 let mysql_like = matches!(
9653 self.config.dialect,
9654 Some(DialectType::MySQL)
9655 | Some(DialectType::Doris)
9656 | Some(DialectType::StarRocks)
9657 | Some(DialectType::SingleStore)
9658 );
9659 if mysql_like {
9660 self.write_keyword("RENAME");
9661 } else {
9662 self.write_keyword("RENAME TO");
9663 }
9664 self.write_space();
9665 let rename_table_with_db = !matches!(
9667 self.config.dialect,
9668 Some(DialectType::Doris)
9669 | Some(DialectType::DuckDB)
9670 | Some(DialectType::BigQuery)
9671 | Some(DialectType::PostgreSQL)
9672 );
9673 if !rename_table_with_db {
9674 let mut stripped = new_name.clone();
9675 stripped.schema = None;
9676 stripped.catalog = None;
9677 self.generate_table(&stripped)?;
9678 } else {
9679 self.generate_table(new_name)?;
9680 }
9681 }
9682 AlterTableAction::AddConstraint(constraint) => {
9683 if !is_continuation {
9686 self.write_keyword("ADD");
9687 self.write_space();
9688 }
9689 self.generate_table_constraint(constraint)?;
9690 }
9691 AlterTableAction::DropConstraint { name, if_exists } => {
9692 self.write_keyword("DROP CONSTRAINT");
9693 if *if_exists {
9694 self.write_space();
9695 self.write_keyword("IF EXISTS");
9696 }
9697 self.write_space();
9698 self.generate_identifier(name)?;
9699 }
9700 AlterTableAction::DropForeignKey { name } => {
9701 self.write_keyword("DROP FOREIGN KEY");
9702 self.write_space();
9703 self.generate_identifier(name)?;
9704 }
9705 AlterTableAction::DropPartition {
9706 partitions,
9707 if_exists,
9708 } => {
9709 self.write_keyword("DROP");
9710 if *if_exists {
9711 self.write_space();
9712 self.write_keyword("IF EXISTS");
9713 }
9714 for (i, partition) in partitions.iter().enumerate() {
9715 if i > 0 {
9716 self.write(",");
9717 }
9718 self.write_space();
9719 self.write_keyword("PARTITION");
9720 if partition.len() == 1 && partition[0].0.name == "__expr__" {
9722 self.write_space();
9724 self.generate_expression(&partition[0].1)?;
9725 } else if partition.len() == 1 && partition[0].0.name == "ALL" {
9726 self.write_space();
9728 self.write_keyword("ALL");
9729 } else if partition.len() == 1 && partition[0].0.name == "ID" {
9730 self.write_space();
9732 self.write_keyword("ID");
9733 self.write_space();
9734 self.generate_expression(&partition[0].1)?;
9735 } else {
9736 self.write("(");
9738 for (j, (key, value)) in partition.iter().enumerate() {
9739 if j > 0 {
9740 self.write(", ");
9741 }
9742 self.generate_identifier(key)?;
9743 self.write(" = ");
9744 self.generate_expression(value)?;
9745 }
9746 self.write(")");
9747 }
9748 }
9749 }
9750 AlterTableAction::Delete { where_clause } => {
9751 self.write_keyword("DELETE");
9752 self.write_space();
9753 self.write_keyword("WHERE");
9754 self.write_space();
9755 self.generate_expression(where_clause)?;
9756 }
9757 AlterTableAction::SwapWith(target) => {
9758 self.write_keyword("SWAP WITH");
9759 self.write_space();
9760 self.generate_table(target)?;
9761 }
9762 AlterTableAction::SetProperty { properties } => {
9763 use crate::dialects::DialectType;
9764 self.write_keyword("SET");
9765 let is_trino_presto = matches!(
9767 self.config.dialect,
9768 Some(DialectType::Trino) | Some(DialectType::Presto)
9769 );
9770 if is_trino_presto {
9771 self.write_space();
9772 self.write_keyword("PROPERTIES");
9773 }
9774 let eq = if is_trino_presto { " = " } else { "=" };
9775 for (i, (key, value)) in properties.iter().enumerate() {
9776 if i > 0 {
9777 self.write(",");
9778 }
9779 self.write_space();
9780 if key.contains(' ') {
9782 self.generate_string_literal(key)?;
9783 } else {
9784 self.write(key);
9785 }
9786 self.write(eq);
9787 self.generate_expression(value)?;
9788 }
9789 }
9790 AlterTableAction::UnsetProperty { properties } => {
9791 self.write_keyword("UNSET");
9792 for (i, name) in properties.iter().enumerate() {
9793 if i > 0 {
9794 self.write(",");
9795 }
9796 self.write_space();
9797 self.write(name);
9798 }
9799 }
9800 AlterTableAction::ClusterBy { expressions } => {
9801 self.write_keyword("CLUSTER BY");
9802 self.write(" (");
9803 for (i, expr) in expressions.iter().enumerate() {
9804 if i > 0 {
9805 self.write(", ");
9806 }
9807 self.generate_expression(expr)?;
9808 }
9809 self.write(")");
9810 }
9811 AlterTableAction::SetTag { expressions } => {
9812 self.write_keyword("SET TAG");
9813 for (i, (key, value)) in expressions.iter().enumerate() {
9814 if i > 0 {
9815 self.write(",");
9816 }
9817 self.write_space();
9818 self.write(key);
9819 self.write(" = ");
9820 self.generate_expression(value)?;
9821 }
9822 }
9823 AlterTableAction::UnsetTag { names } => {
9824 self.write_keyword("UNSET TAG");
9825 for (i, name) in names.iter().enumerate() {
9826 if i > 0 {
9827 self.write(",");
9828 }
9829 self.write_space();
9830 self.write(name);
9831 }
9832 }
9833 AlterTableAction::SetOptions { expressions } => {
9834 self.write_keyword("SET");
9835 self.write(" (");
9836 for (i, expr) in expressions.iter().enumerate() {
9837 if i > 0 {
9838 self.write(", ");
9839 }
9840 self.generate_expression(expr)?;
9841 }
9842 self.write(")");
9843 }
9844 AlterTableAction::AlterIndex { name, visible } => {
9845 self.write_keyword("ALTER INDEX");
9846 self.write_space();
9847 self.generate_identifier(name)?;
9848 self.write_space();
9849 if *visible {
9850 self.write_keyword("VISIBLE");
9851 } else {
9852 self.write_keyword("INVISIBLE");
9853 }
9854 }
9855 AlterTableAction::SetAttribute { attribute } => {
9856 self.write_keyword("SET");
9857 self.write_space();
9858 self.write_keyword(attribute);
9859 }
9860 AlterTableAction::SetStageFileFormat { options } => {
9861 self.write_keyword("SET");
9862 self.write_space();
9863 self.write_keyword("STAGE_FILE_FORMAT");
9864 self.write(" = (");
9865 if let Some(opts) = options {
9866 self.generate_space_separated_properties(opts)?;
9867 }
9868 self.write(")");
9869 }
9870 AlterTableAction::SetStageCopyOptions { options } => {
9871 self.write_keyword("SET");
9872 self.write_space();
9873 self.write_keyword("STAGE_COPY_OPTIONS");
9874 self.write(" = (");
9875 if let Some(opts) = options {
9876 self.generate_space_separated_properties(opts)?;
9877 }
9878 self.write(")");
9879 }
9880 AlterTableAction::AddColumns { columns, cascade } => {
9881 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
9884 if is_oracle {
9885 self.write_keyword("ADD");
9886 } else {
9887 self.write_keyword("ADD COLUMNS");
9888 }
9889 self.write(" (");
9890 for (i, col) in columns.iter().enumerate() {
9891 if i > 0 {
9892 self.write(", ");
9893 }
9894 self.generate_column_def(col)?;
9895 }
9896 self.write(")");
9897 if *cascade {
9898 self.write_space();
9899 self.write_keyword("CASCADE");
9900 }
9901 }
9902 AlterTableAction::ChangeColumn {
9903 old_name,
9904 new_name,
9905 data_type,
9906 comment,
9907 cascade,
9908 } => {
9909 use crate::dialects::DialectType;
9910 let is_spark = matches!(
9911 self.config.dialect,
9912 Some(DialectType::Spark) | Some(DialectType::Databricks)
9913 );
9914 let is_rename = old_name.name != new_name.name;
9915
9916 if is_spark {
9917 if is_rename {
9918 self.write_keyword("RENAME COLUMN");
9920 self.write_space();
9921 self.generate_identifier(old_name)?;
9922 self.write_space();
9923 self.write_keyword("TO");
9924 self.write_space();
9925 self.generate_identifier(new_name)?;
9926 } else if comment.is_some() {
9927 self.write_keyword("ALTER COLUMN");
9929 self.write_space();
9930 self.generate_identifier(old_name)?;
9931 self.write_space();
9932 self.write_keyword("COMMENT");
9933 self.write_space();
9934 self.write("'");
9935 self.write(comment.as_ref().unwrap());
9936 self.write("'");
9937 } else if data_type.is_some() {
9938 self.write_keyword("ALTER COLUMN");
9940 self.write_space();
9941 self.generate_identifier(old_name)?;
9942 self.write_space();
9943 self.write_keyword("TYPE");
9944 self.write_space();
9945 self.generate_data_type(data_type.as_ref().unwrap())?;
9946 } else {
9947 self.write_keyword("CHANGE COLUMN");
9949 self.write_space();
9950 self.generate_identifier(old_name)?;
9951 self.write_space();
9952 self.generate_identifier(new_name)?;
9953 }
9954 } else {
9955 if data_type.is_some() {
9957 self.write_keyword("CHANGE COLUMN");
9958 } else {
9959 self.write_keyword("CHANGE");
9960 }
9961 self.write_space();
9962 self.generate_identifier(old_name)?;
9963 self.write_space();
9964 self.generate_identifier(new_name)?;
9965 if let Some(ref dt) = data_type {
9966 self.write_space();
9967 self.generate_data_type(dt)?;
9968 }
9969 if let Some(ref c) = comment {
9970 self.write_space();
9971 self.write_keyword("COMMENT");
9972 self.write_space();
9973 self.write("'");
9974 self.write(c);
9975 self.write("'");
9976 }
9977 if *cascade {
9978 self.write_space();
9979 self.write_keyword("CASCADE");
9980 }
9981 }
9982 }
9983 AlterTableAction::AddPartition {
9984 partition,
9985 if_not_exists,
9986 location,
9987 } => {
9988 self.write_keyword("ADD");
9989 self.write_space();
9990 if *if_not_exists {
9991 self.write_keyword("IF NOT EXISTS");
9992 self.write_space();
9993 }
9994 self.generate_expression(partition)?;
9995 if let Some(ref loc) = location {
9996 self.write_space();
9997 self.write_keyword("LOCATION");
9998 self.write_space();
9999 self.generate_expression(loc)?;
10000 }
10001 }
10002 AlterTableAction::AlterSortKey {
10003 this,
10004 expressions,
10005 compound,
10006 } => {
10007 self.write_keyword("ALTER");
10009 if *compound {
10010 self.write_space();
10011 self.write_keyword("COMPOUND");
10012 }
10013 self.write_space();
10014 self.write_keyword("SORTKEY");
10015 self.write_space();
10016 if let Some(style) = this {
10017 self.write_keyword(style);
10018 } else if !expressions.is_empty() {
10019 self.write("(");
10020 for (i, expr) in expressions.iter().enumerate() {
10021 if i > 0 {
10022 self.write(", ");
10023 }
10024 self.generate_expression(expr)?;
10025 }
10026 self.write(")");
10027 }
10028 }
10029 AlterTableAction::AlterDistStyle { style, distkey } => {
10030 self.write_keyword("ALTER");
10032 self.write_space();
10033 self.write_keyword("DISTSTYLE");
10034 self.write_space();
10035 self.write_keyword(style);
10036 if let Some(col) = distkey {
10037 self.write_space();
10038 self.write_keyword("DISTKEY");
10039 self.write_space();
10040 self.generate_identifier(col)?;
10041 }
10042 }
10043 AlterTableAction::SetTableProperties { properties } => {
10044 self.write_keyword("SET TABLE PROPERTIES");
10046 self.write(" (");
10047 for (i, (key, value)) in properties.iter().enumerate() {
10048 if i > 0 {
10049 self.write(", ");
10050 }
10051 self.generate_expression(key)?;
10052 self.write(" = ");
10053 self.generate_expression(value)?;
10054 }
10055 self.write(")");
10056 }
10057 AlterTableAction::SetLocation { location } => {
10058 self.write_keyword("SET LOCATION");
10060 self.write_space();
10061 self.write("'");
10062 self.write(location);
10063 self.write("'");
10064 }
10065 AlterTableAction::SetFileFormat { format } => {
10066 self.write_keyword("SET FILE FORMAT");
10068 self.write_space();
10069 self.write_keyword(format);
10070 }
10071 AlterTableAction::ReplacePartition { partition, source } => {
10072 self.write_keyword("REPLACE PARTITION");
10074 self.write_space();
10075 self.generate_expression(partition)?;
10076 if let Some(src) = source {
10077 self.write_space();
10078 self.write_keyword("FROM");
10079 self.write_space();
10080 self.generate_expression(src)?;
10081 }
10082 }
10083 AlterTableAction::Raw { sql } => {
10084 self.write(sql);
10085 }
10086 }
10087 Ok(())
10088 }
10089
10090 fn generate_alter_column_action(&mut self, action: &AlterColumnAction) -> Result<()> {
10091 match action {
10092 AlterColumnAction::SetDataType {
10093 data_type,
10094 using,
10095 collate,
10096 } => {
10097 use crate::dialects::DialectType;
10098 let is_no_prefix = matches!(
10103 self.config.dialect,
10104 Some(DialectType::TSQL) | Some(DialectType::Fabric) | Some(DialectType::Hive)
10105 );
10106 let is_type_only = matches!(
10107 self.config.dialect,
10108 Some(DialectType::Redshift)
10109 | Some(DialectType::Spark)
10110 | Some(DialectType::Databricks)
10111 );
10112 if is_type_only {
10113 self.write_keyword("TYPE");
10114 self.write_space();
10115 } else if !is_no_prefix {
10116 self.write_keyword("SET DATA TYPE");
10117 self.write_space();
10118 }
10119 self.generate_data_type(data_type)?;
10120 if let Some(ref collation) = collate {
10121 self.write_space();
10122 self.write_keyword("COLLATE");
10123 self.write_space();
10124 self.write(collation);
10125 }
10126 if let Some(ref using_expr) = using {
10127 self.write_space();
10128 self.write_keyword("USING");
10129 self.write_space();
10130 self.generate_expression(using_expr)?;
10131 }
10132 }
10133 AlterColumnAction::SetDefault(expr) => {
10134 self.write_keyword("SET DEFAULT");
10135 self.write_space();
10136 self.generate_expression(expr)?;
10137 }
10138 AlterColumnAction::DropDefault => {
10139 self.write_keyword("DROP DEFAULT");
10140 }
10141 AlterColumnAction::SetNotNull => {
10142 self.write_keyword("SET NOT NULL");
10143 }
10144 AlterColumnAction::DropNotNull => {
10145 self.write_keyword("DROP NOT NULL");
10146 }
10147 AlterColumnAction::Comment(comment) => {
10148 self.write_keyword("COMMENT");
10149 self.write_space();
10150 self.generate_string_literal(comment)?;
10151 }
10152 AlterColumnAction::SetVisible => {
10153 self.write_keyword("SET VISIBLE");
10154 }
10155 AlterColumnAction::SetInvisible => {
10156 self.write_keyword("SET INVISIBLE");
10157 }
10158 }
10159 Ok(())
10160 }
10161
10162 fn generate_create_index(&mut self, ci: &CreateIndex) -> Result<()> {
10163 self.write_keyword("CREATE");
10164
10165 if ci.unique {
10166 self.write_space();
10167 self.write_keyword("UNIQUE");
10168 }
10169
10170 if let Some(ref clustered) = ci.clustered {
10172 self.write_space();
10173 self.write_keyword(clustered);
10174 }
10175
10176 self.write_space();
10177 self.write_keyword("INDEX");
10178
10179 if ci.concurrently {
10181 self.write_space();
10182 self.write_keyword("CONCURRENTLY");
10183 }
10184
10185 if ci.if_not_exists {
10186 self.write_space();
10187 self.write_keyword("IF NOT EXISTS");
10188 }
10189
10190 if !ci.name.name.is_empty() {
10192 self.write_space();
10193 self.generate_identifier(&ci.name)?;
10194 }
10195 self.write_space();
10196 self.write_keyword("ON");
10197 if matches!(self.config.dialect, Some(DialectType::Hive)) {
10199 self.write_space();
10200 self.write_keyword("TABLE");
10201 }
10202 self.write_space();
10203 self.generate_table(&ci.table)?;
10204
10205 if !ci.columns.is_empty() || ci.using.is_some() {
10208 let space_before_paren = false;
10209
10210 if let Some(ref using) = ci.using {
10211 self.write_space();
10212 self.write_keyword("USING");
10213 self.write_space();
10214 self.write(using);
10215 if space_before_paren {
10216 self.write(" (");
10217 } else {
10218 self.write("(");
10219 }
10220 } else {
10221 if space_before_paren {
10222 self.write(" (");
10223 } else {
10224 self.write("(");
10225 }
10226 }
10227 for (i, col) in ci.columns.iter().enumerate() {
10228 if i > 0 {
10229 self.write(", ");
10230 }
10231 self.generate_identifier(&col.column)?;
10232 if let Some(ref opclass) = col.opclass {
10233 self.write_space();
10234 self.write(opclass);
10235 }
10236 if col.desc {
10237 self.write_space();
10238 self.write_keyword("DESC");
10239 } else if col.asc {
10240 self.write_space();
10241 self.write_keyword("ASC");
10242 }
10243 if let Some(nulls_first) = col.nulls_first {
10244 self.write_space();
10245 self.write_keyword("NULLS");
10246 self.write_space();
10247 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
10248 }
10249 }
10250 self.write(")");
10251 }
10252
10253 if !ci.include_columns.is_empty() {
10255 self.write_space();
10256 self.write_keyword("INCLUDE");
10257 self.write(" (");
10258 for (i, col) in ci.include_columns.iter().enumerate() {
10259 if i > 0 {
10260 self.write(", ");
10261 }
10262 self.generate_identifier(col)?;
10263 }
10264 self.write(")");
10265 }
10266
10267 if !ci.with_options.is_empty() {
10269 self.write_space();
10270 self.write_keyword("WITH");
10271 self.write(" (");
10272 for (i, (key, value)) in ci.with_options.iter().enumerate() {
10273 if i > 0 {
10274 self.write(", ");
10275 }
10276 self.write(key);
10277 self.write("=");
10278 self.write(value);
10279 }
10280 self.write(")");
10281 }
10282
10283 if let Some(ref where_clause) = ci.where_clause {
10285 self.write_space();
10286 self.write_keyword("WHERE");
10287 self.write_space();
10288 self.generate_expression(where_clause)?;
10289 }
10290
10291 if let Some(ref on_fg) = ci.on_filegroup {
10293 self.write_space();
10294 self.write_keyword("ON");
10295 self.write_space();
10296 self.write(on_fg);
10297 }
10298
10299 Ok(())
10300 }
10301
10302 fn generate_drop_index(&mut self, di: &DropIndex) -> Result<()> {
10303 self.write_keyword("DROP INDEX");
10304
10305 if di.concurrently {
10306 self.write_space();
10307 self.write_keyword("CONCURRENTLY");
10308 }
10309
10310 if di.if_exists {
10311 self.write_space();
10312 self.write_keyword("IF EXISTS");
10313 }
10314
10315 self.write_space();
10316 self.generate_identifier(&di.name)?;
10317
10318 if let Some(ref table) = di.table {
10319 self.write_space();
10320 self.write_keyword("ON");
10321 self.write_space();
10322 self.generate_table(table)?;
10323 }
10324
10325 Ok(())
10326 }
10327
10328 fn generate_create_view(&mut self, cv: &CreateView) -> Result<()> {
10329 self.write_keyword("CREATE");
10330
10331 if let Some(ref algorithm) = cv.algorithm {
10333 self.write_space();
10334 self.write_keyword("ALGORITHM");
10335 self.write("=");
10336 self.write_keyword(algorithm);
10337 }
10338
10339 if let Some(ref definer) = cv.definer {
10341 self.write_space();
10342 self.write_keyword("DEFINER");
10343 self.write("=");
10344 self.write(definer);
10345 }
10346
10347 if cv.security_sql_style {
10349 if let Some(ref security) = cv.security {
10350 self.write_space();
10351 self.write_keyword("SQL SECURITY");
10352 self.write_space();
10353 match security {
10354 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
10355 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
10356 FunctionSecurity::None => self.write_keyword("NONE"),
10357 }
10358 }
10359 }
10360
10361 if cv.or_replace {
10362 self.write_space();
10363 self.write_keyword("OR REPLACE");
10364 }
10365
10366 if cv.temporary {
10367 self.write_space();
10368 self.write_keyword("TEMPORARY");
10369 }
10370
10371 if cv.materialized {
10372 self.write_space();
10373 self.write_keyword("MATERIALIZED");
10374 }
10375
10376 if cv.secure {
10378 self.write_space();
10379 self.write_keyword("SECURE");
10380 }
10381
10382 self.write_space();
10383 self.write_keyword("VIEW");
10384
10385 if cv.if_not_exists {
10386 self.write_space();
10387 self.write_keyword("IF NOT EXISTS");
10388 }
10389
10390 self.write_space();
10391 self.generate_table(&cv.name)?;
10392
10393 if let Some(ref on_cluster) = cv.on_cluster {
10395 self.write_space();
10396 self.generate_on_cluster(on_cluster)?;
10397 }
10398
10399 if let Some(ref to_table) = cv.to_table {
10401 self.write_space();
10402 self.write_keyword("TO");
10403 self.write_space();
10404 self.generate_table(to_table)?;
10405 }
10406
10407 if !cv.materialized {
10410 if !cv.columns.is_empty() {
10412 self.write(" (");
10413 for (i, col) in cv.columns.iter().enumerate() {
10414 if i > 0 {
10415 self.write(", ");
10416 }
10417 self.generate_identifier(&col.name)?;
10418 if !col.options.is_empty() {
10420 self.write_space();
10421 self.generate_options_clause(&col.options)?;
10422 }
10423 if let Some(ref comment) = col.comment {
10424 self.write_space();
10425 self.write_keyword("COMMENT");
10426 self.write_space();
10427 self.generate_string_literal(comment)?;
10428 }
10429 }
10430 self.write(")");
10431 }
10432
10433 if !cv.security_sql_style {
10435 if let Some(ref security) = cv.security {
10436 self.write_space();
10437 self.write_keyword("SECURITY");
10438 self.write_space();
10439 match security {
10440 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
10441 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
10442 FunctionSecurity::None => self.write_keyword("NONE"),
10443 }
10444 }
10445 }
10446
10447 if cv.copy_grants {
10449 self.write_space();
10450 self.write_keyword("COPY GRANTS");
10451 }
10452 } else {
10453 if cv.copy_grants {
10455 self.write_space();
10456 self.write_keyword("COPY GRANTS");
10457 }
10458
10459 if let Some(ref schema) = cv.schema {
10461 self.write(" (");
10462 for (i, expr) in schema.expressions.iter().enumerate() {
10463 if i > 0 {
10464 self.write(", ");
10465 }
10466 self.generate_expression(expr)?;
10467 }
10468 self.write(")");
10469 } else if !cv.columns.is_empty() {
10470 self.write(" (");
10472 for (i, col) in cv.columns.iter().enumerate() {
10473 if i > 0 {
10474 self.write(", ");
10475 }
10476 self.generate_identifier(&col.name)?;
10477 if !col.options.is_empty() {
10479 self.write_space();
10480 self.generate_options_clause(&col.options)?;
10481 }
10482 if let Some(ref comment) = col.comment {
10483 self.write_space();
10484 self.write_keyword("COMMENT");
10485 self.write_space();
10486 self.generate_string_literal(comment)?;
10487 }
10488 }
10489 self.write(")");
10490 }
10491
10492 if let Some(ref unique_key) = cv.unique_key {
10494 self.write_space();
10495 self.write_keyword("KEY");
10496 self.write(" (");
10497 for (i, expr) in unique_key.expressions.iter().enumerate() {
10498 if i > 0 {
10499 self.write(", ");
10500 }
10501 self.generate_expression(expr)?;
10502 }
10503 self.write(")");
10504 }
10505 }
10506
10507 if let Some(ref comment) = cv.comment {
10509 self.write_space();
10510 self.write_keyword("COMMENT");
10511 self.write("=");
10512 self.generate_string_literal(comment)?;
10513 }
10514
10515 if !cv.tags.is_empty() {
10517 self.write_space();
10518 self.write_keyword("TAG");
10519 self.write(" (");
10520 for (i, (name, value)) in cv.tags.iter().enumerate() {
10521 if i > 0 {
10522 self.write(", ");
10523 }
10524 self.write(name);
10525 self.write("='");
10526 self.write(value);
10527 self.write("'");
10528 }
10529 self.write(")");
10530 }
10531
10532 if !cv.options.is_empty() {
10534 self.write_space();
10535 self.generate_options_clause(&cv.options)?;
10536 }
10537
10538 if let Some(ref build) = cv.build {
10540 self.write_space();
10541 self.write_keyword("BUILD");
10542 self.write_space();
10543 self.write_keyword(build);
10544 }
10545
10546 if let Some(ref refresh) = cv.refresh {
10548 self.write_space();
10549 self.generate_refresh_trigger_property(refresh)?;
10550 }
10551
10552 if let Some(auto_refresh) = cv.auto_refresh {
10554 self.write_space();
10555 self.write_keyword("AUTO REFRESH");
10556 self.write_space();
10557 if auto_refresh {
10558 self.write_keyword("YES");
10559 } else {
10560 self.write_keyword("NO");
10561 }
10562 }
10563
10564 for prop in &cv.table_properties {
10566 self.write_space();
10567 self.generate_expression(prop)?;
10568 }
10569
10570 if !matches!(&cv.query, Expression::Null(_)) {
10572 self.write_space();
10573 self.write_keyword("AS");
10574 self.write_space();
10575
10576 if let Some(ref mode) = cv.locking_mode {
10578 self.write_keyword("LOCKING");
10579 self.write_space();
10580 self.write_keyword(mode);
10581 if let Some(ref access) = cv.locking_access {
10582 self.write_space();
10583 self.write_keyword("FOR");
10584 self.write_space();
10585 self.write_keyword(access);
10586 }
10587 self.write_space();
10588 }
10589
10590 if cv.query_parenthesized {
10591 self.write("(");
10592 }
10593 self.generate_expression(&cv.query)?;
10594 if cv.query_parenthesized {
10595 self.write(")");
10596 }
10597 }
10598
10599 if cv.no_schema_binding {
10601 self.write_space();
10602 self.write_keyword("WITH NO SCHEMA BINDING");
10603 }
10604
10605 Ok(())
10606 }
10607
10608 fn generate_drop_view(&mut self, dv: &DropView) -> Result<()> {
10609 self.write_keyword("DROP");
10610
10611 if dv.materialized {
10612 self.write_space();
10613 self.write_keyword("MATERIALIZED");
10614 }
10615
10616 self.write_space();
10617 self.write_keyword("VIEW");
10618
10619 if dv.if_exists {
10620 self.write_space();
10621 self.write_keyword("IF EXISTS");
10622 }
10623
10624 self.write_space();
10625 self.generate_table(&dv.name)?;
10626
10627 Ok(())
10628 }
10629
10630 fn generate_truncate(&mut self, tr: &Truncate) -> Result<()> {
10631 match tr.target {
10632 TruncateTarget::Database => self.write_keyword("TRUNCATE DATABASE"),
10633 TruncateTarget::Table => self.write_keyword("TRUNCATE TABLE"),
10634 }
10635 if tr.if_exists {
10636 self.write_space();
10637 self.write_keyword("IF EXISTS");
10638 }
10639 self.write_space();
10640 self.generate_table(&tr.table)?;
10641
10642 if let Some(ref on_cluster) = tr.on_cluster {
10644 self.write_space();
10645 self.generate_on_cluster(on_cluster)?;
10646 }
10647
10648 if !tr.extra_tables.is_empty() {
10650 let skip_first = if let Some(first) = tr.extra_tables.first() {
10652 first.table.name == tr.table.name && first.star
10653 } else {
10654 false
10655 };
10656
10657 let strip_star = matches!(
10659 self.config.dialect,
10660 Some(crate::dialects::DialectType::PostgreSQL)
10661 | Some(crate::dialects::DialectType::Redshift)
10662 );
10663 if skip_first && !strip_star {
10664 self.write("*");
10665 }
10666
10667 for (i, entry) in tr.extra_tables.iter().enumerate() {
10669 if i == 0 && skip_first {
10670 continue; }
10672 self.write(", ");
10673 self.generate_table(&entry.table)?;
10674 if entry.star && !strip_star {
10675 self.write("*");
10676 }
10677 }
10678 }
10679
10680 if let Some(identity) = &tr.identity {
10682 self.write_space();
10683 match identity {
10684 TruncateIdentity::Restart => self.write_keyword("RESTART IDENTITY"),
10685 TruncateIdentity::Continue => self.write_keyword("CONTINUE IDENTITY"),
10686 }
10687 }
10688
10689 if tr.cascade {
10690 self.write_space();
10691 self.write_keyword("CASCADE");
10692 }
10693
10694 if tr.restrict {
10695 self.write_space();
10696 self.write_keyword("RESTRICT");
10697 }
10698
10699 if let Some(ref partition) = tr.partition {
10701 self.write_space();
10702 self.generate_expression(partition)?;
10703 }
10704
10705 Ok(())
10706 }
10707
10708 fn generate_use(&mut self, u: &Use) -> Result<()> {
10709 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
10711 self.write_keyword("DATABASE");
10712 self.write_space();
10713 self.generate_identifier(&u.this)?;
10714 return Ok(());
10715 }
10716
10717 self.write_keyword("USE");
10718
10719 if let Some(kind) = &u.kind {
10720 self.write_space();
10721 match kind {
10722 UseKind::Database => self.write_keyword("DATABASE"),
10723 UseKind::Schema => self.write_keyword("SCHEMA"),
10724 UseKind::Role => self.write_keyword("ROLE"),
10725 UseKind::Warehouse => self.write_keyword("WAREHOUSE"),
10726 UseKind::Catalog => self.write_keyword("CATALOG"),
10727 UseKind::SecondaryRoles => self.write_keyword("SECONDARY ROLES"),
10728 }
10729 }
10730
10731 self.write_space();
10732 if matches!(&u.kind, Some(UseKind::SecondaryRoles)) {
10735 self.write(&u.this.name);
10736 } else {
10737 self.generate_identifier(&u.this)?;
10738 }
10739 Ok(())
10740 }
10741
10742 fn generate_cache(&mut self, c: &Cache) -> Result<()> {
10743 self.write_keyword("CACHE");
10744 if c.lazy {
10745 self.write_space();
10746 self.write_keyword("LAZY");
10747 }
10748 self.write_space();
10749 self.write_keyword("TABLE");
10750 self.write_space();
10751 self.generate_identifier(&c.table)?;
10752
10753 if !c.options.is_empty() {
10755 self.write_space();
10756 self.write_keyword("OPTIONS");
10757 self.write("(");
10758 for (i, (key, value)) in c.options.iter().enumerate() {
10759 if i > 0 {
10760 self.write(", ");
10761 }
10762 self.generate_expression(key)?;
10763 self.write(" = ");
10764 self.generate_expression(value)?;
10765 }
10766 self.write(")");
10767 }
10768
10769 if let Some(query) = &c.query {
10771 self.write_space();
10772 self.write_keyword("AS");
10773 self.write_space();
10774 self.generate_expression(query)?;
10775 }
10776
10777 Ok(())
10778 }
10779
10780 fn generate_uncache(&mut self, u: &Uncache) -> Result<()> {
10781 self.write_keyword("UNCACHE TABLE");
10782 if u.if_exists {
10783 self.write_space();
10784 self.write_keyword("IF EXISTS");
10785 }
10786 self.write_space();
10787 self.generate_identifier(&u.table)?;
10788 Ok(())
10789 }
10790
10791 fn generate_load_data(&mut self, l: &LoadData) -> Result<()> {
10792 self.write_keyword("LOAD DATA");
10793 if l.local {
10794 self.write_space();
10795 self.write_keyword("LOCAL");
10796 }
10797 self.write_space();
10798 self.write_keyword("INPATH");
10799 self.write_space();
10800 self.write("'");
10801 self.write(&l.inpath);
10802 self.write("'");
10803
10804 if l.overwrite {
10805 self.write_space();
10806 self.write_keyword("OVERWRITE");
10807 }
10808
10809 self.write_space();
10810 self.write_keyword("INTO TABLE");
10811 self.write_space();
10812 self.generate_expression(&l.table)?;
10813
10814 if !l.partition.is_empty() {
10816 self.write_space();
10817 self.write_keyword("PARTITION");
10818 self.write("(");
10819 for (i, (col, val)) in l.partition.iter().enumerate() {
10820 if i > 0 {
10821 self.write(", ");
10822 }
10823 self.generate_identifier(col)?;
10824 self.write(" = ");
10825 self.generate_expression(val)?;
10826 }
10827 self.write(")");
10828 }
10829
10830 if let Some(fmt) = &l.input_format {
10832 self.write_space();
10833 self.write_keyword("INPUTFORMAT");
10834 self.write_space();
10835 self.write("'");
10836 self.write(fmt);
10837 self.write("'");
10838 }
10839
10840 if let Some(serde) = &l.serde {
10842 self.write_space();
10843 self.write_keyword("SERDE");
10844 self.write_space();
10845 self.write("'");
10846 self.write(serde);
10847 self.write("'");
10848 }
10849
10850 Ok(())
10851 }
10852
10853 fn generate_pragma(&mut self, p: &Pragma) -> Result<()> {
10854 self.write_keyword("PRAGMA");
10855 self.write_space();
10856
10857 if let Some(schema) = &p.schema {
10859 self.generate_identifier(schema)?;
10860 self.write(".");
10861 }
10862
10863 self.generate_identifier(&p.name)?;
10865
10866 if let Some(value) = &p.value {
10868 self.write(" = ");
10869 self.generate_expression(value)?;
10870 } else if !p.args.is_empty() {
10871 self.write("(");
10872 for (i, arg) in p.args.iter().enumerate() {
10873 if i > 0 {
10874 self.write(", ");
10875 }
10876 self.generate_expression(arg)?;
10877 }
10878 self.write(")");
10879 }
10880
10881 Ok(())
10882 }
10883
10884 fn generate_grant(&mut self, g: &Grant) -> Result<()> {
10885 self.write_keyword("GRANT");
10886 self.write_space();
10887
10888 for (i, privilege) in g.privileges.iter().enumerate() {
10890 if i > 0 {
10891 self.write(", ");
10892 }
10893 self.write_keyword(&privilege.name);
10894 if !privilege.columns.is_empty() {
10896 self.write("(");
10897 for (j, col) in privilege.columns.iter().enumerate() {
10898 if j > 0 {
10899 self.write(", ");
10900 }
10901 self.write(col);
10902 }
10903 self.write(")");
10904 }
10905 }
10906
10907 self.write_space();
10908 self.write_keyword("ON");
10909 self.write_space();
10910
10911 if let Some(kind) = &g.kind {
10913 self.write_keyword(kind);
10914 self.write_space();
10915 }
10916
10917 {
10919 use crate::dialects::DialectType;
10920 let should_upper = matches!(
10921 self.config.dialect,
10922 Some(DialectType::PostgreSQL)
10923 | Some(DialectType::CockroachDB)
10924 | Some(DialectType::Materialize)
10925 | Some(DialectType::RisingWave)
10926 ) && (g.kind.as_deref() == Some("FUNCTION")
10927 || g.kind.as_deref() == Some("PROCEDURE"));
10928 if should_upper {
10929 use crate::expressions::Identifier;
10930 let upper_id = Identifier {
10931 name: g.securable.name.to_uppercase(),
10932 quoted: g.securable.quoted,
10933 ..g.securable.clone()
10934 };
10935 self.generate_identifier(&upper_id)?;
10936 } else {
10937 self.generate_identifier(&g.securable)?;
10938 }
10939 }
10940
10941 if !g.function_params.is_empty() {
10943 self.write("(");
10944 for (i, param) in g.function_params.iter().enumerate() {
10945 if i > 0 {
10946 self.write(", ");
10947 }
10948 self.write(param);
10949 }
10950 self.write(")");
10951 }
10952
10953 self.write_space();
10954 self.write_keyword("TO");
10955 self.write_space();
10956
10957 for (i, principal) in g.principals.iter().enumerate() {
10959 if i > 0 {
10960 self.write(", ");
10961 }
10962 if principal.is_role {
10963 self.write_keyword("ROLE");
10964 self.write_space();
10965 } else if principal.is_group {
10966 self.write_keyword("GROUP");
10967 self.write_space();
10968 }
10969 self.generate_identifier(&principal.name)?;
10970 }
10971
10972 if g.grant_option {
10974 self.write_space();
10975 self.write_keyword("WITH GRANT OPTION");
10976 }
10977
10978 if let Some(ref principal) = g.as_principal {
10980 self.write_space();
10981 self.write_keyword("AS");
10982 self.write_space();
10983 self.generate_identifier(principal)?;
10984 }
10985
10986 Ok(())
10987 }
10988
10989 fn generate_revoke(&mut self, r: &Revoke) -> Result<()> {
10990 self.write_keyword("REVOKE");
10991 self.write_space();
10992
10993 if r.grant_option {
10995 self.write_keyword("GRANT OPTION FOR");
10996 self.write_space();
10997 }
10998
10999 for (i, privilege) in r.privileges.iter().enumerate() {
11001 if i > 0 {
11002 self.write(", ");
11003 }
11004 self.write_keyword(&privilege.name);
11005 if !privilege.columns.is_empty() {
11007 self.write("(");
11008 for (j, col) in privilege.columns.iter().enumerate() {
11009 if j > 0 {
11010 self.write(", ");
11011 }
11012 self.write(col);
11013 }
11014 self.write(")");
11015 }
11016 }
11017
11018 self.write_space();
11019 self.write_keyword("ON");
11020 self.write_space();
11021
11022 if let Some(kind) = &r.kind {
11024 self.write_keyword(kind);
11025 self.write_space();
11026 }
11027
11028 {
11030 use crate::dialects::DialectType;
11031 let should_upper = matches!(
11032 self.config.dialect,
11033 Some(DialectType::PostgreSQL)
11034 | Some(DialectType::CockroachDB)
11035 | Some(DialectType::Materialize)
11036 | Some(DialectType::RisingWave)
11037 ) && (r.kind.as_deref() == Some("FUNCTION")
11038 || r.kind.as_deref() == Some("PROCEDURE"));
11039 if should_upper {
11040 use crate::expressions::Identifier;
11041 let upper_id = Identifier {
11042 name: r.securable.name.to_uppercase(),
11043 quoted: r.securable.quoted,
11044 ..r.securable.clone()
11045 };
11046 self.generate_identifier(&upper_id)?;
11047 } else {
11048 self.generate_identifier(&r.securable)?;
11049 }
11050 }
11051
11052 if !r.function_params.is_empty() {
11054 self.write("(");
11055 for (i, param) in r.function_params.iter().enumerate() {
11056 if i > 0 {
11057 self.write(", ");
11058 }
11059 self.write(param);
11060 }
11061 self.write(")");
11062 }
11063
11064 self.write_space();
11065 self.write_keyword("FROM");
11066 self.write_space();
11067
11068 for (i, principal) in r.principals.iter().enumerate() {
11070 if i > 0 {
11071 self.write(", ");
11072 }
11073 if principal.is_role {
11074 self.write_keyword("ROLE");
11075 self.write_space();
11076 } else if principal.is_group {
11077 self.write_keyword("GROUP");
11078 self.write_space();
11079 }
11080 self.generate_identifier(&principal.name)?;
11081 }
11082
11083 if r.cascade {
11085 self.write_space();
11086 self.write_keyword("CASCADE");
11087 } else if r.restrict {
11088 self.write_space();
11089 self.write_keyword("RESTRICT");
11090 }
11091
11092 Ok(())
11093 }
11094
11095 fn generate_comment(&mut self, c: &Comment) -> Result<()> {
11096 self.write_keyword("COMMENT");
11097
11098 if c.exists {
11100 self.write_space();
11101 self.write_keyword("IF EXISTS");
11102 }
11103
11104 self.write_space();
11105 self.write_keyword("ON");
11106
11107 if c.materialized {
11109 self.write_space();
11110 self.write_keyword("MATERIALIZED");
11111 }
11112
11113 self.write_space();
11114 self.write_keyword(&c.kind);
11115 self.write_space();
11116
11117 self.generate_expression(&c.this)?;
11119
11120 self.write_space();
11121 self.write_keyword("IS");
11122 self.write_space();
11123
11124 self.generate_expression(&c.expression)?;
11126
11127 Ok(())
11128 }
11129
11130 fn generate_set_statement(&mut self, s: &SetStatement) -> Result<()> {
11131 self.write_keyword("SET");
11132
11133 for (i, item) in s.items.iter().enumerate() {
11134 if i > 0 {
11135 self.write(",");
11136 }
11137 self.write_space();
11138
11139 if let Some(ref kind) = item.kind {
11141 self.write_keyword(kind);
11142 self.write_space();
11143 }
11144
11145 let name_str = match &item.name {
11147 Expression::Identifier(id) => Some(id.name.as_str()),
11148 _ => None,
11149 };
11150
11151 let is_transaction = name_str == Some("TRANSACTION");
11152 let is_character_set = name_str == Some("CHARACTER SET");
11153 let is_names = name_str == Some("NAMES");
11154 let is_collate = name_str == Some("COLLATE");
11155 let has_variable_kind = item.kind.as_deref() == Some("VARIABLE");
11156 let name_has_variable_prefix = name_str.map_or(false, |n| n.starts_with("VARIABLE "));
11157 let is_variable = has_variable_kind || name_has_variable_prefix;
11158 let is_value_only =
11159 matches!(&item.value, Expression::Identifier(id) if id.name.is_empty());
11160
11161 if is_transaction {
11162 self.write_keyword("TRANSACTION");
11164 if let Expression::Identifier(id) = &item.value {
11165 if !id.name.is_empty() {
11166 self.write_space();
11167 self.write(&id.name);
11168 }
11169 }
11170 } else if is_character_set {
11171 self.write_keyword("CHARACTER SET");
11173 self.write_space();
11174 self.generate_set_value(&item.value)?;
11175 } else if is_names {
11176 self.write_keyword("NAMES");
11178 self.write_space();
11179 self.generate_set_value(&item.value)?;
11180 } else if is_collate {
11181 self.write_keyword("COLLATE");
11183 self.write_space();
11184 self.generate_set_value(&item.value)?;
11185 } else if is_variable {
11186 if name_has_variable_prefix && !has_variable_kind {
11190 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
11191 self.write_keyword("VARIABLE");
11192 self.write_space();
11193 }
11194 }
11195 if let Some(ns) = name_str {
11197 let var_name = if name_has_variable_prefix {
11198 &ns["VARIABLE ".len()..]
11199 } else {
11200 ns
11201 };
11202 self.write(var_name);
11203 } else {
11204 self.generate_expression(&item.name)?;
11205 }
11206 self.write(" = ");
11207 self.generate_set_value(&item.value)?;
11208 } else if is_value_only {
11209 self.generate_expression(&item.name)?;
11211 } else if item.no_equals && matches!(self.config.dialect, Some(DialectType::TSQL)) {
11212 self.generate_expression(&item.name)?;
11214 self.write_space();
11215 self.generate_set_value(&item.value)?;
11216 } else {
11217 match &item.name {
11220 Expression::Identifier(id) => {
11221 self.write(&id.name);
11222 }
11223 _ => {
11224 self.generate_expression(&item.name)?;
11225 }
11226 }
11227 self.write(" = ");
11228 self.generate_set_value(&item.value)?;
11229 }
11230 }
11231
11232 Ok(())
11233 }
11234
11235 fn generate_set_value(&mut self, value: &Expression) -> Result<()> {
11238 if let Expression::Identifier(id) = value {
11239 match id.name.as_str() {
11240 "DEFAULT" | "ON" | "OFF" => {
11241 self.write_keyword(&id.name);
11242 return Ok(());
11243 }
11244 _ => {}
11245 }
11246 }
11247 self.generate_expression(value)
11248 }
11249
11250 fn generate_alter_view(&mut self, av: &AlterView) -> Result<()> {
11253 self.write_keyword("ALTER");
11254 if let Some(ref algorithm) = av.algorithm {
11256 self.write_space();
11257 self.write_keyword("ALGORITHM");
11258 self.write(" = ");
11259 self.write_keyword(algorithm);
11260 }
11261 if let Some(ref definer) = av.definer {
11262 self.write_space();
11263 self.write_keyword("DEFINER");
11264 self.write(" = ");
11265 self.write(definer);
11266 }
11267 if let Some(ref sql_security) = av.sql_security {
11268 self.write_space();
11269 self.write_keyword("SQL SECURITY");
11270 self.write(" = ");
11271 self.write_keyword(sql_security);
11272 }
11273 self.write_space();
11274 self.write_keyword("VIEW");
11275 self.write_space();
11276 self.generate_table(&av.name)?;
11277
11278 if !av.columns.is_empty() {
11280 self.write(" (");
11281 for (i, col) in av.columns.iter().enumerate() {
11282 if i > 0 {
11283 self.write(", ");
11284 }
11285 self.generate_identifier(&col.name)?;
11286 if let Some(ref comment) = col.comment {
11287 self.write_space();
11288 self.write_keyword("COMMENT");
11289 self.write(" ");
11290 self.generate_string_literal(comment)?;
11291 }
11292 }
11293 self.write(")");
11294 }
11295
11296 if let Some(ref opt) = av.with_option {
11298 self.write_space();
11299 self.write_keyword("WITH");
11300 self.write_space();
11301 self.write_keyword(opt);
11302 }
11303
11304 for action in &av.actions {
11305 self.write_space();
11306 match action {
11307 AlterViewAction::Rename(new_name) => {
11308 self.write_keyword("RENAME TO");
11309 self.write_space();
11310 self.generate_table(new_name)?;
11311 }
11312 AlterViewAction::OwnerTo(owner) => {
11313 self.write_keyword("OWNER TO");
11314 self.write_space();
11315 self.generate_identifier(owner)?;
11316 }
11317 AlterViewAction::SetSchema(schema) => {
11318 self.write_keyword("SET SCHEMA");
11319 self.write_space();
11320 self.generate_identifier(schema)?;
11321 }
11322 AlterViewAction::SetAuthorization(auth) => {
11323 self.write_keyword("SET AUTHORIZATION");
11324 self.write_space();
11325 self.write(auth);
11326 }
11327 AlterViewAction::AlterColumn { name, action } => {
11328 self.write_keyword("ALTER COLUMN");
11329 self.write_space();
11330 self.generate_identifier(name)?;
11331 self.write_space();
11332 self.generate_alter_column_action(action)?;
11333 }
11334 AlterViewAction::AsSelect(query) => {
11335 self.write_keyword("AS");
11336 self.write_space();
11337 self.generate_expression(query)?;
11338 }
11339 AlterViewAction::SetTblproperties(props) => {
11340 self.write_keyword("SET TBLPROPERTIES");
11341 self.write(" (");
11342 for (i, (key, value)) in props.iter().enumerate() {
11343 if i > 0 {
11344 self.write(", ");
11345 }
11346 self.generate_string_literal(key)?;
11347 self.write("=");
11348 self.generate_string_literal(value)?;
11349 }
11350 self.write(")");
11351 }
11352 AlterViewAction::UnsetTblproperties(keys) => {
11353 self.write_keyword("UNSET TBLPROPERTIES");
11354 self.write(" (");
11355 for (i, key) in keys.iter().enumerate() {
11356 if i > 0 {
11357 self.write(", ");
11358 }
11359 self.generate_string_literal(key)?;
11360 }
11361 self.write(")");
11362 }
11363 }
11364 }
11365
11366 Ok(())
11367 }
11368
11369 fn generate_alter_index(&mut self, ai: &AlterIndex) -> Result<()> {
11370 self.write_keyword("ALTER INDEX");
11371 self.write_space();
11372 self.generate_identifier(&ai.name)?;
11373
11374 if let Some(table) = &ai.table {
11375 self.write_space();
11376 self.write_keyword("ON");
11377 self.write_space();
11378 self.generate_table(table)?;
11379 }
11380
11381 for action in &ai.actions {
11382 self.write_space();
11383 match action {
11384 AlterIndexAction::Rename(new_name) => {
11385 self.write_keyword("RENAME TO");
11386 self.write_space();
11387 self.generate_identifier(new_name)?;
11388 }
11389 AlterIndexAction::SetTablespace(tablespace) => {
11390 self.write_keyword("SET TABLESPACE");
11391 self.write_space();
11392 self.generate_identifier(tablespace)?;
11393 }
11394 AlterIndexAction::Visible(visible) => {
11395 if *visible {
11396 self.write_keyword("VISIBLE");
11397 } else {
11398 self.write_keyword("INVISIBLE");
11399 }
11400 }
11401 }
11402 }
11403
11404 Ok(())
11405 }
11406
11407 fn generate_create_schema(&mut self, cs: &CreateSchema) -> Result<()> {
11408 for comment in &cs.leading_comments {
11410 self.write_formatted_comment(comment);
11411 self.write_space();
11412 }
11413
11414 let saved_athena_hive_context = self.athena_hive_context;
11416 if matches!(
11417 self.config.dialect,
11418 Some(crate::dialects::DialectType::Athena)
11419 ) {
11420 self.athena_hive_context = true;
11421 }
11422
11423 self.write_keyword("CREATE SCHEMA");
11424
11425 if cs.if_not_exists {
11426 self.write_space();
11427 self.write_keyword("IF NOT EXISTS");
11428 }
11429
11430 self.write_space();
11431 self.generate_identifier(&cs.name)?;
11432
11433 if let Some(ref clone_src) = cs.clone_from {
11434 self.write_keyword(" CLONE ");
11435 self.generate_identifier(clone_src)?;
11436 }
11437
11438 if let Some(ref at_clause) = cs.at_clause {
11439 self.write_space();
11440 self.generate_expression(at_clause)?;
11441 }
11442
11443 if let Some(auth) = &cs.authorization {
11444 self.write_space();
11445 self.write_keyword("AUTHORIZATION");
11446 self.write_space();
11447 self.generate_identifier(auth)?;
11448 }
11449
11450 let with_properties: Vec<_> = cs
11453 .properties
11454 .iter()
11455 .filter(|p| matches!(p, Expression::Property(_)))
11456 .collect();
11457 let other_properties: Vec<_> = cs
11458 .properties
11459 .iter()
11460 .filter(|p| !matches!(p, Expression::Property(_)))
11461 .collect();
11462
11463 if !with_properties.is_empty() {
11465 self.write_space();
11466 self.write_keyword("WITH");
11467 self.write(" (");
11468 for (i, prop) in with_properties.iter().enumerate() {
11469 if i > 0 {
11470 self.write(", ");
11471 }
11472 self.generate_expression(prop)?;
11473 }
11474 self.write(")");
11475 }
11476
11477 for prop in other_properties {
11479 self.write_space();
11480 self.generate_expression(prop)?;
11481 }
11482
11483 self.athena_hive_context = saved_athena_hive_context;
11485
11486 Ok(())
11487 }
11488
11489 fn generate_drop_schema(&mut self, ds: &DropSchema) -> Result<()> {
11490 self.write_keyword("DROP SCHEMA");
11491
11492 if ds.if_exists {
11493 self.write_space();
11494 self.write_keyword("IF EXISTS");
11495 }
11496
11497 self.write_space();
11498 self.generate_identifier(&ds.name)?;
11499
11500 if ds.cascade {
11501 self.write_space();
11502 self.write_keyword("CASCADE");
11503 }
11504
11505 Ok(())
11506 }
11507
11508 fn generate_drop_namespace(&mut self, dn: &DropNamespace) -> Result<()> {
11509 self.write_keyword("DROP NAMESPACE");
11510
11511 if dn.if_exists {
11512 self.write_space();
11513 self.write_keyword("IF EXISTS");
11514 }
11515
11516 self.write_space();
11517 self.generate_identifier(&dn.name)?;
11518
11519 if dn.cascade {
11520 self.write_space();
11521 self.write_keyword("CASCADE");
11522 }
11523
11524 Ok(())
11525 }
11526
11527 fn generate_create_database(&mut self, cd: &CreateDatabase) -> Result<()> {
11528 self.write_keyword("CREATE DATABASE");
11529
11530 if cd.if_not_exists {
11531 self.write_space();
11532 self.write_keyword("IF NOT EXISTS");
11533 }
11534
11535 self.write_space();
11536 self.generate_identifier(&cd.name)?;
11537
11538 if let Some(ref clone_src) = cd.clone_from {
11539 self.write_keyword(" CLONE ");
11540 self.generate_identifier(clone_src)?;
11541 }
11542
11543 if let Some(ref at_clause) = cd.at_clause {
11545 self.write_space();
11546 self.generate_expression(at_clause)?;
11547 }
11548
11549 for option in &cd.options {
11550 self.write_space();
11551 match option {
11552 DatabaseOption::CharacterSet(charset) => {
11553 self.write_keyword("CHARACTER SET");
11554 self.write(" = ");
11555 self.write(&format!("'{}'", charset));
11556 }
11557 DatabaseOption::Collate(collate) => {
11558 self.write_keyword("COLLATE");
11559 self.write(" = ");
11560 self.write(&format!("'{}'", collate));
11561 }
11562 DatabaseOption::Owner(owner) => {
11563 self.write_keyword("OWNER");
11564 self.write(" = ");
11565 self.generate_identifier(owner)?;
11566 }
11567 DatabaseOption::Template(template) => {
11568 self.write_keyword("TEMPLATE");
11569 self.write(" = ");
11570 self.generate_identifier(template)?;
11571 }
11572 DatabaseOption::Encoding(encoding) => {
11573 self.write_keyword("ENCODING");
11574 self.write(" = ");
11575 self.write(&format!("'{}'", encoding));
11576 }
11577 DatabaseOption::Location(location) => {
11578 self.write_keyword("LOCATION");
11579 self.write(" = ");
11580 self.write(&format!("'{}'", location));
11581 }
11582 }
11583 }
11584
11585 Ok(())
11586 }
11587
11588 fn generate_drop_database(&mut self, dd: &DropDatabase) -> Result<()> {
11589 self.write_keyword("DROP DATABASE");
11590
11591 if dd.if_exists {
11592 self.write_space();
11593 self.write_keyword("IF EXISTS");
11594 }
11595
11596 self.write_space();
11597 self.generate_identifier(&dd.name)?;
11598
11599 Ok(())
11600 }
11601
11602 fn generate_create_function(&mut self, cf: &CreateFunction) -> Result<()> {
11603 self.write_keyword("CREATE");
11604
11605 if cf.or_replace {
11606 self.write_space();
11607 self.write_keyword("OR REPLACE");
11608 }
11609
11610 if cf.temporary {
11611 self.write_space();
11612 self.write_keyword("TEMPORARY");
11613 }
11614
11615 self.write_space();
11616 if cf.is_table_function {
11617 self.write_keyword("TABLE FUNCTION");
11618 } else {
11619 self.write_keyword("FUNCTION");
11620 }
11621
11622 if cf.if_not_exists {
11623 self.write_space();
11624 self.write_keyword("IF NOT EXISTS");
11625 }
11626
11627 self.write_space();
11628 self.generate_table(&cf.name)?;
11629 if cf.has_parens {
11630 let func_multiline = self.config.pretty
11631 && matches!(
11632 self.config.dialect,
11633 Some(crate::dialects::DialectType::TSQL)
11634 | Some(crate::dialects::DialectType::Fabric)
11635 )
11636 && !cf.parameters.is_empty();
11637 if func_multiline {
11638 self.write("(\n");
11639 self.indent_level += 2;
11640 self.write_indent();
11641 self.generate_function_parameters(&cf.parameters)?;
11642 self.write("\n");
11643 self.indent_level -= 2;
11644 self.write(")");
11645 } else {
11646 self.write("(");
11647 self.generate_function_parameters(&cf.parameters)?;
11648 self.write(")");
11649 }
11650 }
11651
11652 let use_multiline = self.config.pretty
11655 && matches!(
11656 self.config.dialect,
11657 Some(crate::dialects::DialectType::BigQuery)
11658 | Some(crate::dialects::DialectType::TSQL)
11659 | Some(crate::dialects::DialectType::Fabric)
11660 );
11661
11662 if cf.language_first {
11663 if let Some(lang) = &cf.language {
11665 if use_multiline {
11666 self.write_newline();
11667 } else {
11668 self.write_space();
11669 }
11670 self.write_keyword("LANGUAGE");
11671 self.write_space();
11672 self.write(lang);
11673 }
11674
11675 if let Some(sql_data) = &cf.sql_data_access {
11677 self.write_space();
11678 match sql_data {
11679 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
11680 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
11681 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
11682 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
11683 }
11684 }
11685
11686 if let Some(ref rtb) = cf.returns_table_body {
11687 if use_multiline {
11688 self.write_newline();
11689 } else {
11690 self.write_space();
11691 }
11692 self.write_keyword("RETURNS");
11693 self.write_space();
11694 self.write(rtb);
11695 } else if let Some(return_type) = &cf.return_type {
11696 if use_multiline {
11697 self.write_newline();
11698 } else {
11699 self.write_space();
11700 }
11701 self.write_keyword("RETURNS");
11702 self.write_space();
11703 self.generate_data_type(return_type)?;
11704 }
11705 } else {
11706 let is_duckdb = matches!(
11709 self.config.dialect,
11710 Some(crate::dialects::DialectType::DuckDB)
11711 );
11712 if let Some(ref rtb) = cf.returns_table_body {
11713 if !(is_duckdb && rtb.is_empty()) {
11714 if use_multiline {
11715 self.write_newline();
11716 } else {
11717 self.write_space();
11718 }
11719 self.write_keyword("RETURNS");
11720 self.write_space();
11721 self.write(rtb);
11722 }
11723 } else if let Some(return_type) = &cf.return_type {
11724 if use_multiline {
11725 self.write_newline();
11726 } else {
11727 self.write_space();
11728 }
11729 self.write_keyword("RETURNS");
11730 self.write_space();
11731 self.generate_data_type(return_type)?;
11732 }
11733 }
11734
11735 if !cf.property_order.is_empty() {
11737 let is_bigquery = matches!(
11739 self.config.dialect,
11740 Some(crate::dialects::DialectType::BigQuery)
11741 );
11742 let property_order = if is_bigquery {
11743 let mut reordered = Vec::new();
11745 let mut has_as = false;
11746 let mut has_options = false;
11747 for prop in &cf.property_order {
11748 match prop {
11749 FunctionPropertyKind::As => has_as = true,
11750 FunctionPropertyKind::Options => has_options = true,
11751 _ => {}
11752 }
11753 }
11754 if has_as && has_options {
11755 for prop in &cf.property_order {
11757 if *prop != FunctionPropertyKind::As
11758 && *prop != FunctionPropertyKind::Options
11759 {
11760 reordered.push(*prop);
11761 }
11762 }
11763 reordered.push(FunctionPropertyKind::Options);
11764 reordered.push(FunctionPropertyKind::As);
11765 reordered
11766 } else {
11767 cf.property_order.clone()
11768 }
11769 } else {
11770 cf.property_order.clone()
11771 };
11772
11773 for prop in &property_order {
11774 match prop {
11775 FunctionPropertyKind::Set => {
11776 self.generate_function_set_options(cf)?;
11777 }
11778 FunctionPropertyKind::As => {
11779 self.generate_function_body(cf)?;
11780 }
11781 FunctionPropertyKind::Language => {
11782 if !cf.language_first {
11783 if let Some(lang) = &cf.language {
11785 let use_multiline = self.config.pretty
11787 && matches!(
11788 self.config.dialect,
11789 Some(crate::dialects::DialectType::BigQuery)
11790 );
11791 if use_multiline {
11792 self.write_newline();
11793 } else {
11794 self.write_space();
11795 }
11796 self.write_keyword("LANGUAGE");
11797 self.write_space();
11798 self.write(lang);
11799 }
11800 }
11801 }
11802 FunctionPropertyKind::Determinism => {
11803 self.generate_function_determinism(cf)?;
11804 }
11805 FunctionPropertyKind::NullInput => {
11806 self.generate_function_null_input(cf)?;
11807 }
11808 FunctionPropertyKind::Security => {
11809 self.generate_function_security(cf)?;
11810 }
11811 FunctionPropertyKind::SqlDataAccess => {
11812 if !cf.language_first {
11813 self.generate_function_sql_data_access(cf)?;
11815 }
11816 }
11817 FunctionPropertyKind::Options => {
11818 if !cf.options.is_empty() {
11819 self.write_space();
11820 self.generate_options_clause(&cf.options)?;
11821 }
11822 }
11823 FunctionPropertyKind::Environment => {
11824 if !cf.environment.is_empty() {
11825 self.write_space();
11826 self.generate_environment_clause(&cf.environment)?;
11827 }
11828 }
11829 }
11830 }
11831
11832 if !cf.options.is_empty() && !cf.property_order.contains(&FunctionPropertyKind::Options)
11834 {
11835 self.write_space();
11836 self.generate_options_clause(&cf.options)?;
11837 }
11838
11839 if !cf.environment.is_empty()
11841 && !cf
11842 .property_order
11843 .contains(&FunctionPropertyKind::Environment)
11844 {
11845 self.write_space();
11846 self.generate_environment_clause(&cf.environment)?;
11847 }
11848 } else {
11849 if matches!(
11852 self.config.dialect,
11853 Some(crate::dialects::DialectType::BigQuery)
11854 ) {
11855 self.generate_function_determinism(cf)?;
11856 }
11857
11858 let use_multiline = self.config.pretty
11860 && matches!(
11861 self.config.dialect,
11862 Some(crate::dialects::DialectType::BigQuery)
11863 );
11864
11865 if !cf.language_first {
11866 if let Some(lang) = &cf.language {
11867 if use_multiline {
11868 self.write_newline();
11869 } else {
11870 self.write_space();
11871 }
11872 self.write_keyword("LANGUAGE");
11873 self.write_space();
11874 self.write(lang);
11875 }
11876
11877 self.generate_function_sql_data_access(cf)?;
11879 }
11880
11881 if !matches!(
11883 self.config.dialect,
11884 Some(crate::dialects::DialectType::BigQuery)
11885 ) {
11886 self.generate_function_determinism(cf)?;
11887 }
11888
11889 self.generate_function_null_input(cf)?;
11890 self.generate_function_security(cf)?;
11891 self.generate_function_set_options(cf)?;
11892
11893 if !cf.options.is_empty() {
11895 self.write_space();
11896 self.generate_options_clause(&cf.options)?;
11897 }
11898
11899 if !cf.environment.is_empty() {
11901 self.write_space();
11902 self.generate_environment_clause(&cf.environment)?;
11903 }
11904
11905 self.generate_function_body(cf)?;
11906 }
11907
11908 Ok(())
11909 }
11910
11911 fn generate_function_set_options(&mut self, cf: &CreateFunction) -> Result<()> {
11913 for opt in &cf.set_options {
11914 self.write_space();
11915 self.write_keyword("SET");
11916 self.write_space();
11917 self.write(&opt.name);
11918 match &opt.value {
11919 FunctionSetValue::Value { value, use_to } => {
11920 if *use_to {
11921 self.write(" TO ");
11922 } else {
11923 self.write(" = ");
11924 }
11925 self.write(value);
11926 }
11927 FunctionSetValue::FromCurrent => {
11928 self.write_space();
11929 self.write_keyword("FROM CURRENT");
11930 }
11931 }
11932 }
11933 Ok(())
11934 }
11935
11936 fn generate_function_body(&mut self, cf: &CreateFunction) -> Result<()> {
11938 if let Some(body) = &cf.body {
11939 self.write_space();
11941 let use_multiline = self.config.pretty
11943 && matches!(
11944 self.config.dialect,
11945 Some(crate::dialects::DialectType::BigQuery)
11946 );
11947 match body {
11948 FunctionBody::Block(block) => {
11949 self.write_keyword("AS");
11950 if matches!(
11951 self.config.dialect,
11952 Some(crate::dialects::DialectType::TSQL)
11953 ) {
11954 self.write(" BEGIN ");
11955 self.write(block);
11956 self.write(" END");
11957 } else if matches!(
11958 self.config.dialect,
11959 Some(crate::dialects::DialectType::PostgreSQL)
11960 ) {
11961 self.write(" $$");
11962 self.write(block);
11963 self.write("$$");
11964 } else {
11965 let escaped = self.escape_block_for_single_quote(block);
11967 if use_multiline {
11969 self.write_newline();
11970 } else {
11971 self.write(" ");
11972 }
11973 self.write("'");
11974 self.write(&escaped);
11975 self.write("'");
11976 }
11977 }
11978 FunctionBody::StringLiteral(s) => {
11979 self.write_keyword("AS");
11980 if use_multiline {
11982 self.write_newline();
11983 } else {
11984 self.write(" ");
11985 }
11986 self.write("'");
11987 self.write(s);
11988 self.write("'");
11989 }
11990 FunctionBody::Expression(expr) => {
11991 self.write_keyword("AS");
11992 self.write_space();
11993 self.generate_expression(expr)?;
11994 }
11995 FunctionBody::External(name) => {
11996 self.write_keyword("EXTERNAL NAME");
11997 self.write(" '");
11998 self.write(name);
11999 self.write("'");
12000 }
12001 FunctionBody::Return(expr) => {
12002 if matches!(
12003 self.config.dialect,
12004 Some(crate::dialects::DialectType::DuckDB)
12005 ) {
12006 self.write_keyword("AS");
12008 self.write_space();
12009 if cf.returns_table_body.is_some() {
12011 self.write_keyword("TABLE");
12012 self.write_space();
12013 }
12014 self.generate_expression(expr)?;
12015 } else {
12016 if self.config.create_function_return_as {
12017 self.write_keyword("AS");
12018 if self.config.pretty
12020 && matches!(
12021 self.config.dialect,
12022 Some(crate::dialects::DialectType::TSQL)
12023 | Some(crate::dialects::DialectType::Fabric)
12024 )
12025 {
12026 self.write_newline();
12027 } else {
12028 self.write_space();
12029 }
12030 }
12031 self.write_keyword("RETURN");
12032 self.write_space();
12033 self.generate_expression(expr)?;
12034 }
12035 }
12036 FunctionBody::Statements(stmts) => {
12037 self.write_keyword("AS");
12038 self.write(" BEGIN ");
12039 for (i, stmt) in stmts.iter().enumerate() {
12040 if i > 0 {
12041 self.write(" ");
12042 }
12043 self.generate_expression(stmt)?;
12044 }
12045 self.write(" END");
12046 }
12047 FunctionBody::DollarQuoted { content, tag } => {
12048 self.write_keyword("AS");
12049 self.write(" ");
12050 let supports_dollar_quoting = matches!(
12052 self.config.dialect,
12053 Some(crate::dialects::DialectType::PostgreSQL)
12054 | Some(crate::dialects::DialectType::Databricks)
12055 | Some(crate::dialects::DialectType::Redshift)
12056 | Some(crate::dialects::DialectType::DuckDB)
12057 );
12058 if supports_dollar_quoting {
12059 self.write("$");
12061 if let Some(t) = tag {
12062 self.write(t);
12063 }
12064 self.write("$");
12065 self.write(content);
12066 self.write("$");
12067 if let Some(t) = tag {
12068 self.write(t);
12069 }
12070 self.write("$");
12071 } else {
12072 let escaped = self.escape_block_for_single_quote(content);
12074 self.write("'");
12075 self.write(&escaped);
12076 self.write("'");
12077 }
12078 }
12079 }
12080 }
12081 Ok(())
12082 }
12083
12084 fn generate_function_determinism(&mut self, cf: &CreateFunction) -> Result<()> {
12086 if let Some(det) = cf.deterministic {
12087 self.write_space();
12088 if matches!(
12089 self.config.dialect,
12090 Some(crate::dialects::DialectType::BigQuery)
12091 ) {
12092 if det {
12094 self.write_keyword("DETERMINISTIC");
12095 } else {
12096 self.write_keyword("NOT DETERMINISTIC");
12097 }
12098 } else {
12099 if det {
12101 self.write_keyword("IMMUTABLE");
12102 } else {
12103 self.write_keyword("VOLATILE");
12104 }
12105 }
12106 }
12107 Ok(())
12108 }
12109
12110 fn generate_function_null_input(&mut self, cf: &CreateFunction) -> Result<()> {
12112 if let Some(returns_null) = cf.returns_null_on_null_input {
12113 self.write_space();
12114 if returns_null {
12115 if cf.strict {
12116 self.write_keyword("STRICT");
12117 } else {
12118 self.write_keyword("RETURNS NULL ON NULL INPUT");
12119 }
12120 } else {
12121 self.write_keyword("CALLED ON NULL INPUT");
12122 }
12123 }
12124 Ok(())
12125 }
12126
12127 fn generate_function_security(&mut self, cf: &CreateFunction) -> Result<()> {
12129 if let Some(security) = &cf.security {
12130 self.write_space();
12131 self.write_keyword("SECURITY");
12132 self.write_space();
12133 match security {
12134 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
12135 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
12136 FunctionSecurity::None => self.write_keyword("NONE"),
12137 }
12138 }
12139 Ok(())
12140 }
12141
12142 fn generate_function_sql_data_access(&mut self, cf: &CreateFunction) -> Result<()> {
12144 if let Some(sql_data) = &cf.sql_data_access {
12145 self.write_space();
12146 match sql_data {
12147 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
12148 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
12149 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
12150 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
12151 }
12152 }
12153 Ok(())
12154 }
12155
12156 fn generate_function_parameters(&mut self, params: &[FunctionParameter]) -> Result<()> {
12157 for (i, param) in params.iter().enumerate() {
12158 if i > 0 {
12159 self.write(", ");
12160 }
12161
12162 if let Some(mode) = ¶m.mode {
12163 if let Some(text) = ¶m.mode_text {
12164 self.write(text);
12165 } else {
12166 match mode {
12167 ParameterMode::In => self.write_keyword("IN"),
12168 ParameterMode::Out => self.write_keyword("OUT"),
12169 ParameterMode::InOut => self.write_keyword("INOUT"),
12170 ParameterMode::Variadic => self.write_keyword("VARIADIC"),
12171 }
12172 }
12173 self.write_space();
12174 }
12175
12176 if let Some(name) = ¶m.name {
12177 self.generate_identifier(name)?;
12178 let skip_type =
12180 matches!(¶m.data_type, DataType::Custom { name } if name.is_empty());
12181 if !skip_type {
12182 self.write_space();
12183 self.generate_data_type(¶m.data_type)?;
12184 }
12185 } else {
12186 self.generate_data_type(¶m.data_type)?;
12187 }
12188
12189 if let Some(default) = ¶m.default {
12190 if self.config.parameter_default_equals {
12191 self.write(" = ");
12192 } else {
12193 self.write(" DEFAULT ");
12194 }
12195 self.generate_expression(default)?;
12196 }
12197 }
12198
12199 Ok(())
12200 }
12201
12202 fn generate_drop_function(&mut self, df: &DropFunction) -> Result<()> {
12203 self.write_keyword("DROP FUNCTION");
12204
12205 if df.if_exists {
12206 self.write_space();
12207 self.write_keyword("IF EXISTS");
12208 }
12209
12210 self.write_space();
12211 self.generate_table(&df.name)?;
12212
12213 if let Some(params) = &df.parameters {
12214 self.write(" (");
12215 for (i, dt) in params.iter().enumerate() {
12216 if i > 0 {
12217 self.write(", ");
12218 }
12219 self.generate_data_type(dt)?;
12220 }
12221 self.write(")");
12222 }
12223
12224 if df.cascade {
12225 self.write_space();
12226 self.write_keyword("CASCADE");
12227 }
12228
12229 Ok(())
12230 }
12231
12232 fn generate_create_procedure(&mut self, cp: &CreateProcedure) -> Result<()> {
12233 self.write_keyword("CREATE");
12234
12235 if cp.or_replace {
12236 self.write_space();
12237 self.write_keyword("OR REPLACE");
12238 }
12239
12240 self.write_space();
12241 if cp.use_proc_keyword {
12242 self.write_keyword("PROC");
12243 } else {
12244 self.write_keyword("PROCEDURE");
12245 }
12246
12247 if cp.if_not_exists {
12248 self.write_space();
12249 self.write_keyword("IF NOT EXISTS");
12250 }
12251
12252 self.write_space();
12253 self.generate_table(&cp.name)?;
12254 if cp.has_parens {
12255 self.write("(");
12256 self.generate_function_parameters(&cp.parameters)?;
12257 self.write(")");
12258 } else if !cp.parameters.is_empty() {
12259 self.write_space();
12261 self.generate_function_parameters(&cp.parameters)?;
12262 }
12263
12264 if let Some(return_type) = &cp.return_type {
12266 self.write_space();
12267 self.write_keyword("RETURNS");
12268 self.write_space();
12269 self.generate_data_type(return_type)?;
12270 }
12271
12272 if let Some(execute_as) = &cp.execute_as {
12274 self.write_space();
12275 self.write_keyword("EXECUTE AS");
12276 self.write_space();
12277 self.write_keyword(execute_as);
12278 }
12279
12280 if let Some(lang) = &cp.language {
12281 self.write_space();
12282 self.write_keyword("LANGUAGE");
12283 self.write_space();
12284 self.write(lang);
12285 }
12286
12287 if let Some(security) = &cp.security {
12288 self.write_space();
12289 self.write_keyword("SECURITY");
12290 self.write_space();
12291 match security {
12292 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
12293 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
12294 FunctionSecurity::None => self.write_keyword("NONE"),
12295 }
12296 }
12297
12298 if !cp.with_options.is_empty() {
12300 self.write_space();
12301 self.write_keyword("WITH");
12302 self.write_space();
12303 for (i, opt) in cp.with_options.iter().enumerate() {
12304 if i > 0 {
12305 self.write(", ");
12306 }
12307 self.write(opt);
12308 }
12309 }
12310
12311 if let Some(body) = &cp.body {
12312 self.write_space();
12313 match body {
12314 FunctionBody::Block(block) => {
12315 self.write_keyword("AS");
12316 if matches!(
12317 self.config.dialect,
12318 Some(crate::dialects::DialectType::TSQL)
12319 ) {
12320 self.write(" BEGIN ");
12321 self.write(block);
12322 self.write(" END");
12323 } else if matches!(
12324 self.config.dialect,
12325 Some(crate::dialects::DialectType::PostgreSQL)
12326 ) {
12327 self.write(" $$");
12328 self.write(block);
12329 self.write("$$");
12330 } else {
12331 let escaped = self.escape_block_for_single_quote(block);
12333 self.write(" '");
12334 self.write(&escaped);
12335 self.write("'");
12336 }
12337 }
12338 FunctionBody::StringLiteral(s) => {
12339 self.write_keyword("AS");
12340 self.write(" '");
12341 self.write(s);
12342 self.write("'");
12343 }
12344 FunctionBody::Expression(expr) => {
12345 self.write_keyword("AS");
12346 self.write_space();
12347 self.generate_expression(expr)?;
12348 }
12349 FunctionBody::External(name) => {
12350 self.write_keyword("EXTERNAL NAME");
12351 self.write(" '");
12352 self.write(name);
12353 self.write("'");
12354 }
12355 FunctionBody::Return(expr) => {
12356 self.write_keyword("RETURN");
12357 self.write_space();
12358 self.generate_expression(expr)?;
12359 }
12360 FunctionBody::Statements(stmts) => {
12361 self.write_keyword("AS");
12362 self.write(" BEGIN ");
12363 for (i, stmt) in stmts.iter().enumerate() {
12364 if i > 0 {
12365 self.write(" ");
12366 }
12367 self.generate_expression(stmt)?;
12368 }
12369 self.write(" END");
12370 }
12371 FunctionBody::DollarQuoted { content, tag } => {
12372 self.write_keyword("AS");
12373 self.write(" ");
12374 let supports_dollar_quoting = matches!(
12376 self.config.dialect,
12377 Some(crate::dialects::DialectType::PostgreSQL)
12378 | Some(crate::dialects::DialectType::Databricks)
12379 | Some(crate::dialects::DialectType::Redshift)
12380 | Some(crate::dialects::DialectType::DuckDB)
12381 );
12382 if supports_dollar_quoting {
12383 self.write("$");
12385 if let Some(t) = tag {
12386 self.write(t);
12387 }
12388 self.write("$");
12389 self.write(content);
12390 self.write("$");
12391 if let Some(t) = tag {
12392 self.write(t);
12393 }
12394 self.write("$");
12395 } else {
12396 let escaped = self.escape_block_for_single_quote(content);
12398 self.write("'");
12399 self.write(&escaped);
12400 self.write("'");
12401 }
12402 }
12403 }
12404 }
12405
12406 Ok(())
12407 }
12408
12409 fn generate_drop_procedure(&mut self, dp: &DropProcedure) -> Result<()> {
12410 self.write_keyword("DROP PROCEDURE");
12411
12412 if dp.if_exists {
12413 self.write_space();
12414 self.write_keyword("IF EXISTS");
12415 }
12416
12417 self.write_space();
12418 self.generate_table(&dp.name)?;
12419
12420 if let Some(params) = &dp.parameters {
12421 self.write(" (");
12422 for (i, dt) in params.iter().enumerate() {
12423 if i > 0 {
12424 self.write(", ");
12425 }
12426 self.generate_data_type(dt)?;
12427 }
12428 self.write(")");
12429 }
12430
12431 if dp.cascade {
12432 self.write_space();
12433 self.write_keyword("CASCADE");
12434 }
12435
12436 Ok(())
12437 }
12438
12439 fn generate_create_sequence(&mut self, cs: &CreateSequence) -> Result<()> {
12440 self.write_keyword("CREATE");
12441
12442 if cs.or_replace {
12443 self.write_space();
12444 self.write_keyword("OR REPLACE");
12445 }
12446
12447 if cs.temporary {
12448 self.write_space();
12449 self.write_keyword("TEMPORARY");
12450 }
12451
12452 self.write_space();
12453 self.write_keyword("SEQUENCE");
12454
12455 if cs.if_not_exists {
12456 self.write_space();
12457 self.write_keyword("IF NOT EXISTS");
12458 }
12459
12460 self.write_space();
12461 self.generate_table(&cs.name)?;
12462
12463 if let Some(as_type) = &cs.as_type {
12465 self.write_space();
12466 self.write_keyword("AS");
12467 self.write_space();
12468 self.generate_data_type(as_type)?;
12469 }
12470
12471 if let Some(comment) = &cs.comment {
12473 self.write_space();
12474 self.write_keyword("COMMENT");
12475 self.write("=");
12476 self.generate_string_literal(comment)?;
12477 }
12478
12479 if !cs.property_order.is_empty() {
12481 for prop in &cs.property_order {
12482 match prop {
12483 SeqPropKind::Start => {
12484 if let Some(start) = cs.start {
12485 self.write_space();
12486 self.write_keyword("START WITH");
12487 self.write(&format!(" {}", start));
12488 }
12489 }
12490 SeqPropKind::Increment => {
12491 if let Some(inc) = cs.increment {
12492 self.write_space();
12493 self.write_keyword("INCREMENT BY");
12494 self.write(&format!(" {}", inc));
12495 }
12496 }
12497 SeqPropKind::Minvalue => {
12498 if let Some(min) = &cs.minvalue {
12499 self.write_space();
12500 match min {
12501 SequenceBound::Value(v) => {
12502 self.write_keyword("MINVALUE");
12503 self.write(&format!(" {}", v));
12504 }
12505 SequenceBound::None => {
12506 self.write_keyword("NO MINVALUE");
12507 }
12508 }
12509 }
12510 }
12511 SeqPropKind::Maxvalue => {
12512 if let Some(max) = &cs.maxvalue {
12513 self.write_space();
12514 match max {
12515 SequenceBound::Value(v) => {
12516 self.write_keyword("MAXVALUE");
12517 self.write(&format!(" {}", v));
12518 }
12519 SequenceBound::None => {
12520 self.write_keyword("NO MAXVALUE");
12521 }
12522 }
12523 }
12524 }
12525 SeqPropKind::Cache => {
12526 if let Some(cache) = cs.cache {
12527 self.write_space();
12528 self.write_keyword("CACHE");
12529 self.write(&format!(" {}", cache));
12530 }
12531 }
12532 SeqPropKind::NoCache => {
12533 self.write_space();
12534 self.write_keyword("NO CACHE");
12535 }
12536 SeqPropKind::NoCacheWord => {
12537 self.write_space();
12538 self.write_keyword("NOCACHE");
12539 }
12540 SeqPropKind::Cycle => {
12541 self.write_space();
12542 self.write_keyword("CYCLE");
12543 }
12544 SeqPropKind::NoCycle => {
12545 self.write_space();
12546 self.write_keyword("NO CYCLE");
12547 }
12548 SeqPropKind::NoCycleWord => {
12549 self.write_space();
12550 self.write_keyword("NOCYCLE");
12551 }
12552 SeqPropKind::OwnedBy => {
12553 if !cs.owned_by_none {
12555 if let Some(owned) = &cs.owned_by {
12556 self.write_space();
12557 self.write_keyword("OWNED BY");
12558 self.write_space();
12559 self.generate_table(owned)?;
12560 }
12561 }
12562 }
12563 SeqPropKind::Order => {
12564 self.write_space();
12565 self.write_keyword("ORDER");
12566 }
12567 SeqPropKind::NoOrder => {
12568 self.write_space();
12569 self.write_keyword("NOORDER");
12570 }
12571 SeqPropKind::Comment => {
12572 }
12574 SeqPropKind::Sharing => {
12575 if let Some(val) = &cs.sharing {
12576 self.write_space();
12577 self.write(&format!("SHARING={}", val));
12578 }
12579 }
12580 SeqPropKind::Keep => {
12581 self.write_space();
12582 self.write_keyword("KEEP");
12583 }
12584 SeqPropKind::NoKeep => {
12585 self.write_space();
12586 self.write_keyword("NOKEEP");
12587 }
12588 SeqPropKind::Scale => {
12589 self.write_space();
12590 self.write_keyword("SCALE");
12591 if let Some(modifier) = &cs.scale_modifier {
12592 if !modifier.is_empty() {
12593 self.write_space();
12594 self.write_keyword(modifier);
12595 }
12596 }
12597 }
12598 SeqPropKind::NoScale => {
12599 self.write_space();
12600 self.write_keyword("NOSCALE");
12601 }
12602 SeqPropKind::Shard => {
12603 self.write_space();
12604 self.write_keyword("SHARD");
12605 if let Some(modifier) = &cs.shard_modifier {
12606 if !modifier.is_empty() {
12607 self.write_space();
12608 self.write_keyword(modifier);
12609 }
12610 }
12611 }
12612 SeqPropKind::NoShard => {
12613 self.write_space();
12614 self.write_keyword("NOSHARD");
12615 }
12616 SeqPropKind::Session => {
12617 self.write_space();
12618 self.write_keyword("SESSION");
12619 }
12620 SeqPropKind::Global => {
12621 self.write_space();
12622 self.write_keyword("GLOBAL");
12623 }
12624 SeqPropKind::NoMinvalueWord => {
12625 self.write_space();
12626 self.write_keyword("NOMINVALUE");
12627 }
12628 SeqPropKind::NoMaxvalueWord => {
12629 self.write_space();
12630 self.write_keyword("NOMAXVALUE");
12631 }
12632 }
12633 }
12634 } else {
12635 if let Some(inc) = cs.increment {
12637 self.write_space();
12638 self.write_keyword("INCREMENT BY");
12639 self.write(&format!(" {}", inc));
12640 }
12641
12642 if let Some(min) = &cs.minvalue {
12643 self.write_space();
12644 match min {
12645 SequenceBound::Value(v) => {
12646 self.write_keyword("MINVALUE");
12647 self.write(&format!(" {}", v));
12648 }
12649 SequenceBound::None => {
12650 self.write_keyword("NO MINVALUE");
12651 }
12652 }
12653 }
12654
12655 if let Some(max) = &cs.maxvalue {
12656 self.write_space();
12657 match max {
12658 SequenceBound::Value(v) => {
12659 self.write_keyword("MAXVALUE");
12660 self.write(&format!(" {}", v));
12661 }
12662 SequenceBound::None => {
12663 self.write_keyword("NO MAXVALUE");
12664 }
12665 }
12666 }
12667
12668 if let Some(start) = cs.start {
12669 self.write_space();
12670 self.write_keyword("START WITH");
12671 self.write(&format!(" {}", start));
12672 }
12673
12674 if let Some(cache) = cs.cache {
12675 self.write_space();
12676 self.write_keyword("CACHE");
12677 self.write(&format!(" {}", cache));
12678 }
12679
12680 if cs.cycle {
12681 self.write_space();
12682 self.write_keyword("CYCLE");
12683 }
12684
12685 if let Some(owned) = &cs.owned_by {
12686 self.write_space();
12687 self.write_keyword("OWNED BY");
12688 self.write_space();
12689 self.generate_table(owned)?;
12690 }
12691 }
12692
12693 Ok(())
12694 }
12695
12696 fn generate_drop_sequence(&mut self, ds: &DropSequence) -> Result<()> {
12697 self.write_keyword("DROP SEQUENCE");
12698
12699 if ds.if_exists {
12700 self.write_space();
12701 self.write_keyword("IF EXISTS");
12702 }
12703
12704 self.write_space();
12705 self.generate_table(&ds.name)?;
12706
12707 if ds.cascade {
12708 self.write_space();
12709 self.write_keyword("CASCADE");
12710 }
12711
12712 Ok(())
12713 }
12714
12715 fn generate_alter_sequence(&mut self, als: &AlterSequence) -> Result<()> {
12716 self.write_keyword("ALTER SEQUENCE");
12717
12718 if als.if_exists {
12719 self.write_space();
12720 self.write_keyword("IF EXISTS");
12721 }
12722
12723 self.write_space();
12724 self.generate_table(&als.name)?;
12725
12726 if let Some(inc) = als.increment {
12727 self.write_space();
12728 self.write_keyword("INCREMENT BY");
12729 self.write(&format!(" {}", inc));
12730 }
12731
12732 if let Some(min) = &als.minvalue {
12733 self.write_space();
12734 match min {
12735 SequenceBound::Value(v) => {
12736 self.write_keyword("MINVALUE");
12737 self.write(&format!(" {}", v));
12738 }
12739 SequenceBound::None => {
12740 self.write_keyword("NO MINVALUE");
12741 }
12742 }
12743 }
12744
12745 if let Some(max) = &als.maxvalue {
12746 self.write_space();
12747 match max {
12748 SequenceBound::Value(v) => {
12749 self.write_keyword("MAXVALUE");
12750 self.write(&format!(" {}", v));
12751 }
12752 SequenceBound::None => {
12753 self.write_keyword("NO MAXVALUE");
12754 }
12755 }
12756 }
12757
12758 if let Some(start) = als.start {
12759 self.write_space();
12760 self.write_keyword("START WITH");
12761 self.write(&format!(" {}", start));
12762 }
12763
12764 if let Some(restart) = &als.restart {
12765 self.write_space();
12766 self.write_keyword("RESTART");
12767 if let Some(val) = restart {
12768 self.write_keyword(" WITH");
12769 self.write(&format!(" {}", val));
12770 }
12771 }
12772
12773 if let Some(cache) = als.cache {
12774 self.write_space();
12775 self.write_keyword("CACHE");
12776 self.write(&format!(" {}", cache));
12777 }
12778
12779 if let Some(cycle) = als.cycle {
12780 self.write_space();
12781 if cycle {
12782 self.write_keyword("CYCLE");
12783 } else {
12784 self.write_keyword("NO CYCLE");
12785 }
12786 }
12787
12788 if let Some(owned) = &als.owned_by {
12789 self.write_space();
12790 self.write_keyword("OWNED BY");
12791 self.write_space();
12792 if let Some(table) = owned {
12793 self.generate_table(table)?;
12794 } else {
12795 self.write_keyword("NONE");
12796 }
12797 }
12798
12799 Ok(())
12800 }
12801
12802 fn generate_create_trigger(&mut self, ct: &CreateTrigger) -> Result<()> {
12803 self.write_keyword("CREATE");
12804
12805 if ct.or_replace {
12806 self.write_space();
12807 self.write_keyword("OR REPLACE");
12808 }
12809
12810 if ct.constraint {
12811 self.write_space();
12812 self.write_keyword("CONSTRAINT");
12813 }
12814
12815 self.write_space();
12816 self.write_keyword("TRIGGER");
12817 self.write_space();
12818 self.generate_identifier(&ct.name)?;
12819
12820 self.write_space();
12821 match ct.timing {
12822 TriggerTiming::Before => self.write_keyword("BEFORE"),
12823 TriggerTiming::After => self.write_keyword("AFTER"),
12824 TriggerTiming::InsteadOf => self.write_keyword("INSTEAD OF"),
12825 }
12826
12827 for (i, event) in ct.events.iter().enumerate() {
12829 if i > 0 {
12830 self.write_keyword(" OR");
12831 }
12832 self.write_space();
12833 match event {
12834 TriggerEvent::Insert => self.write_keyword("INSERT"),
12835 TriggerEvent::Update(cols) => {
12836 self.write_keyword("UPDATE");
12837 if let Some(cols) = cols {
12838 self.write_space();
12839 self.write_keyword("OF");
12840 for (j, col) in cols.iter().enumerate() {
12841 if j > 0 {
12842 self.write(",");
12843 }
12844 self.write_space();
12845 self.generate_identifier(col)?;
12846 }
12847 }
12848 }
12849 TriggerEvent::Delete => self.write_keyword("DELETE"),
12850 TriggerEvent::Truncate => self.write_keyword("TRUNCATE"),
12851 }
12852 }
12853
12854 self.write_space();
12855 self.write_keyword("ON");
12856 self.write_space();
12857 self.generate_table(&ct.table)?;
12858
12859 if let Some(ref_clause) = &ct.referencing {
12861 self.write_space();
12862 self.write_keyword("REFERENCING");
12863 if let Some(old_table) = &ref_clause.old_table {
12864 self.write_space();
12865 self.write_keyword("OLD TABLE AS");
12866 self.write_space();
12867 self.generate_identifier(old_table)?;
12868 }
12869 if let Some(new_table) = &ref_clause.new_table {
12870 self.write_space();
12871 self.write_keyword("NEW TABLE AS");
12872 self.write_space();
12873 self.generate_identifier(new_table)?;
12874 }
12875 if let Some(old_row) = &ref_clause.old_row {
12876 self.write_space();
12877 self.write_keyword("OLD ROW AS");
12878 self.write_space();
12879 self.generate_identifier(old_row)?;
12880 }
12881 if let Some(new_row) = &ref_clause.new_row {
12882 self.write_space();
12883 self.write_keyword("NEW ROW AS");
12884 self.write_space();
12885 self.generate_identifier(new_row)?;
12886 }
12887 }
12888
12889 if let Some(deferrable) = ct.deferrable {
12891 self.write_space();
12892 if deferrable {
12893 self.write_keyword("DEFERRABLE");
12894 } else {
12895 self.write_keyword("NOT DEFERRABLE");
12896 }
12897 }
12898
12899 if let Some(initially) = ct.initially_deferred {
12900 self.write_space();
12901 self.write_keyword("INITIALLY");
12902 self.write_space();
12903 if initially {
12904 self.write_keyword("DEFERRED");
12905 } else {
12906 self.write_keyword("IMMEDIATE");
12907 }
12908 }
12909
12910 self.write_space();
12911 self.write_keyword("FOR EACH");
12912 self.write_space();
12913 match ct.for_each {
12914 TriggerForEach::Row => self.write_keyword("ROW"),
12915 TriggerForEach::Statement => self.write_keyword("STATEMENT"),
12916 }
12917
12918 if let Some(when) = &ct.when {
12920 self.write_space();
12921 self.write_keyword("WHEN");
12922 self.write(" (");
12923 self.generate_expression(when)?;
12924 self.write(")");
12925 }
12926
12927 self.write_space();
12929 match &ct.body {
12930 TriggerBody::Execute { function, args } => {
12931 self.write_keyword("EXECUTE FUNCTION");
12932 self.write_space();
12933 self.generate_table(function)?;
12934 self.write("(");
12935 for (i, arg) in args.iter().enumerate() {
12936 if i > 0 {
12937 self.write(", ");
12938 }
12939 self.generate_expression(arg)?;
12940 }
12941 self.write(")");
12942 }
12943 TriggerBody::Block(block) => {
12944 self.write_keyword("BEGIN");
12945 self.write_space();
12946 self.write(block);
12947 self.write_space();
12948 self.write_keyword("END");
12949 }
12950 }
12951
12952 Ok(())
12953 }
12954
12955 fn generate_drop_trigger(&mut self, dt: &DropTrigger) -> Result<()> {
12956 self.write_keyword("DROP TRIGGER");
12957
12958 if dt.if_exists {
12959 self.write_space();
12960 self.write_keyword("IF EXISTS");
12961 }
12962
12963 self.write_space();
12964 self.generate_identifier(&dt.name)?;
12965
12966 if let Some(table) = &dt.table {
12967 self.write_space();
12968 self.write_keyword("ON");
12969 self.write_space();
12970 self.generate_table(table)?;
12971 }
12972
12973 if dt.cascade {
12974 self.write_space();
12975 self.write_keyword("CASCADE");
12976 }
12977
12978 Ok(())
12979 }
12980
12981 fn generate_create_type(&mut self, ct: &CreateType) -> Result<()> {
12982 self.write_keyword("CREATE TYPE");
12983
12984 if ct.if_not_exists {
12985 self.write_space();
12986 self.write_keyword("IF NOT EXISTS");
12987 }
12988
12989 self.write_space();
12990 self.generate_table(&ct.name)?;
12991
12992 self.write_space();
12993 self.write_keyword("AS");
12994 self.write_space();
12995
12996 match &ct.definition {
12997 TypeDefinition::Enum(values) => {
12998 self.write_keyword("ENUM");
12999 self.write(" (");
13000 for (i, val) in values.iter().enumerate() {
13001 if i > 0 {
13002 self.write(", ");
13003 }
13004 self.write(&format!("'{}'", val));
13005 }
13006 self.write(")");
13007 }
13008 TypeDefinition::Composite(attrs) => {
13009 self.write("(");
13010 for (i, attr) in attrs.iter().enumerate() {
13011 if i > 0 {
13012 self.write(", ");
13013 }
13014 self.generate_identifier(&attr.name)?;
13015 self.write_space();
13016 self.generate_data_type(&attr.data_type)?;
13017 if let Some(collate) = &attr.collate {
13018 self.write_space();
13019 self.write_keyword("COLLATE");
13020 self.write_space();
13021 self.generate_identifier(collate)?;
13022 }
13023 }
13024 self.write(")");
13025 }
13026 TypeDefinition::Range {
13027 subtype,
13028 subtype_diff,
13029 canonical,
13030 } => {
13031 self.write_keyword("RANGE");
13032 self.write(" (");
13033 self.write_keyword("SUBTYPE");
13034 self.write(" = ");
13035 self.generate_data_type(subtype)?;
13036 if let Some(diff) = subtype_diff {
13037 self.write(", ");
13038 self.write_keyword("SUBTYPE_DIFF");
13039 self.write(" = ");
13040 self.write(diff);
13041 }
13042 if let Some(canon) = canonical {
13043 self.write(", ");
13044 self.write_keyword("CANONICAL");
13045 self.write(" = ");
13046 self.write(canon);
13047 }
13048 self.write(")");
13049 }
13050 TypeDefinition::Base {
13051 input,
13052 output,
13053 internallength,
13054 } => {
13055 self.write("(");
13056 self.write_keyword("INPUT");
13057 self.write(" = ");
13058 self.write(input);
13059 self.write(", ");
13060 self.write_keyword("OUTPUT");
13061 self.write(" = ");
13062 self.write(output);
13063 if let Some(len) = internallength {
13064 self.write(", ");
13065 self.write_keyword("INTERNALLENGTH");
13066 self.write(" = ");
13067 self.write(&len.to_string());
13068 }
13069 self.write(")");
13070 }
13071 TypeDefinition::Domain {
13072 base_type,
13073 default,
13074 constraints,
13075 } => {
13076 self.generate_data_type(base_type)?;
13077 if let Some(def) = default {
13078 self.write_space();
13079 self.write_keyword("DEFAULT");
13080 self.write_space();
13081 self.generate_expression(def)?;
13082 }
13083 for constr in constraints {
13084 self.write_space();
13085 if let Some(name) = &constr.name {
13086 self.write_keyword("CONSTRAINT");
13087 self.write_space();
13088 self.generate_identifier(name)?;
13089 self.write_space();
13090 }
13091 self.write_keyword("CHECK");
13092 self.write(" (");
13093 self.generate_expression(&constr.check)?;
13094 self.write(")");
13095 }
13096 }
13097 }
13098
13099 Ok(())
13100 }
13101
13102 fn generate_drop_type(&mut self, dt: &DropType) -> Result<()> {
13103 self.write_keyword("DROP TYPE");
13104
13105 if dt.if_exists {
13106 self.write_space();
13107 self.write_keyword("IF EXISTS");
13108 }
13109
13110 self.write_space();
13111 self.generate_table(&dt.name)?;
13112
13113 if dt.cascade {
13114 self.write_space();
13115 self.write_keyword("CASCADE");
13116 }
13117
13118 Ok(())
13119 }
13120
13121 fn generate_describe(&mut self, d: &Describe) -> Result<()> {
13122 let saved_athena_hive_context = self.athena_hive_context;
13124 if matches!(
13125 self.config.dialect,
13126 Some(crate::dialects::DialectType::Athena)
13127 ) {
13128 self.athena_hive_context = true;
13129 }
13130
13131 for comment in &d.leading_comments {
13133 self.write_formatted_comment(comment);
13134 self.write(" ");
13135 }
13136
13137 self.write_keyword("DESCRIBE");
13138
13139 if d.extended {
13140 self.write_space();
13141 self.write_keyword("EXTENDED");
13142 } else if d.formatted {
13143 self.write_space();
13144 self.write_keyword("FORMATTED");
13145 }
13146
13147 if let Some(ref style) = d.style {
13149 self.write_space();
13150 self.write_keyword(style);
13151 }
13152
13153 let should_output_kind = match self.config.dialect {
13155 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
13157 false
13158 }
13159 Some(DialectType::Snowflake) => true,
13161 _ => d.kind.is_some(),
13162 };
13163 if should_output_kind {
13164 if let Some(ref kind) = d.kind {
13165 self.write_space();
13166 self.write_keyword(kind);
13167 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
13168 self.write_space();
13169 self.write_keyword("TABLE");
13170 }
13171 }
13172
13173 self.write_space();
13174 self.generate_expression(&d.target)?;
13175
13176 if let Some(ref partition) = d.partition {
13178 self.write_space();
13179 self.generate_expression(partition)?;
13180 }
13181
13182 if d.as_json {
13184 self.write_space();
13185 self.write_keyword("AS JSON");
13186 }
13187
13188 for (name, value) in &d.properties {
13190 self.write_space();
13191 self.write(name);
13192 self.write("=");
13193 self.write(value);
13194 }
13195
13196 self.athena_hive_context = saved_athena_hive_context;
13198
13199 Ok(())
13200 }
13201
13202 fn generate_show(&mut self, s: &Show) -> Result<()> {
13205 self.write_keyword("SHOW");
13206 self.write_space();
13207
13208 let show_terse = s.terse
13211 && !matches!(
13212 s.this.as_str(),
13213 "PRIMARY KEYS" | "UNIQUE KEYS" | "IMPORTED KEYS"
13214 );
13215 if show_terse {
13216 self.write_keyword("TERSE");
13217 self.write_space();
13218 }
13219
13220 self.write_keyword(&s.this);
13222
13223 if let Some(ref target_expr) = s.target {
13225 self.write_space();
13226 self.generate_expression(target_expr)?;
13227 }
13228
13229 if s.history {
13231 self.write_space();
13232 self.write_keyword("HISTORY");
13233 }
13234
13235 if let Some(ref for_target) = s.for_target {
13237 self.write_space();
13238 self.write_keyword("FOR");
13239 self.write_space();
13240 self.generate_expression(for_target)?;
13241 }
13242
13243 use crate::dialects::DialectType;
13247 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
13248
13249 if !is_snowflake && s.from.is_some() {
13250 if let Some(ref scope_kind) = s.scope_kind {
13254 self.write_space();
13255 self.write_keyword("IN");
13256 self.write_space();
13257 self.write_keyword(scope_kind);
13258 if let Some(ref scope) = s.scope {
13259 self.write_space();
13260 self.generate_expression(scope)?;
13261 }
13262 } else if let Some(ref scope) = s.scope {
13263 self.write_space();
13264 self.write_keyword("IN");
13265 self.write_space();
13266 self.generate_expression(scope)?;
13267 }
13268
13269 if let Some(ref from) = s.from {
13271 self.write_space();
13272 self.write_keyword("FROM");
13273 self.write_space();
13274 self.generate_expression(from)?;
13275 }
13276
13277 if let Some(ref db) = s.db {
13279 self.write_space();
13280 self.write_keyword("FROM");
13281 self.write_space();
13282 self.generate_expression(db)?;
13283 }
13284
13285 if let Some(ref like) = s.like {
13287 self.write_space();
13288 self.write_keyword("LIKE");
13289 self.write_space();
13290 self.generate_expression(like)?;
13291 }
13292 } else {
13293 if let Some(ref like) = s.like {
13297 self.write_space();
13298 self.write_keyword("LIKE");
13299 self.write_space();
13300 self.generate_expression(like)?;
13301 }
13302
13303 if let Some(ref scope_kind) = s.scope_kind {
13305 self.write_space();
13306 self.write_keyword("IN");
13307 self.write_space();
13308 self.write_keyword(scope_kind);
13309 if let Some(ref scope) = s.scope {
13310 self.write_space();
13311 self.generate_expression(scope)?;
13312 }
13313 } else if let Some(ref scope) = s.scope {
13314 self.write_space();
13315 self.write_keyword("IN");
13316 self.write_space();
13317 self.generate_expression(scope)?;
13318 }
13319 }
13320
13321 if let Some(ref starts_with) = s.starts_with {
13323 self.write_space();
13324 self.write_keyword("STARTS WITH");
13325 self.write_space();
13326 self.generate_expression(starts_with)?;
13327 }
13328
13329 if let Some(ref limit) = s.limit {
13331 self.write_space();
13332 self.generate_limit(limit)?;
13333 }
13334
13335 if is_snowflake {
13337 if let Some(ref from) = s.from {
13338 self.write_space();
13339 self.write_keyword("FROM");
13340 self.write_space();
13341 self.generate_expression(from)?;
13342 }
13343 }
13344
13345 if let Some(ref where_clause) = s.where_clause {
13347 self.write_space();
13348 self.write_keyword("WHERE");
13349 self.write_space();
13350 self.generate_expression(where_clause)?;
13351 }
13352
13353 if let Some(is_mutex) = s.mutex {
13355 self.write_space();
13356 if is_mutex {
13357 self.write_keyword("MUTEX");
13358 } else {
13359 self.write_keyword("STATUS");
13360 }
13361 }
13362
13363 if !s.privileges.is_empty() {
13365 self.write_space();
13366 self.write_keyword("WITH PRIVILEGES");
13367 self.write_space();
13368 for (i, priv_name) in s.privileges.iter().enumerate() {
13369 if i > 0 {
13370 self.write(", ");
13371 }
13372 self.write_keyword(priv_name);
13373 }
13374 }
13375
13376 Ok(())
13377 }
13378
13379 fn generate_literal(&mut self, lit: &Literal) -> Result<()> {
13382 use crate::dialects::DialectType;
13383 match lit {
13384 Literal::String(s) => {
13385 self.generate_string_literal(s)?;
13386 }
13387 Literal::Number(n) => {
13388 if matches!(self.config.dialect, Some(DialectType::MySQL))
13389 && n.len() > 2
13390 && (n.starts_with("0x") || n.starts_with("0X"))
13391 && !n[2..].chars().all(|c| c.is_ascii_hexdigit())
13392 {
13393 return self.generate_identifier(&Identifier {
13394 name: n.clone(),
13395 quoted: true,
13396 trailing_comments: Vec::new(),
13397 span: None,
13398 });
13399 }
13400 let n = if n.contains('_')
13404 && !matches!(
13405 self.config.dialect,
13406 Some(DialectType::ClickHouse)
13407 | Some(DialectType::DuckDB)
13408 | Some(DialectType::PostgreSQL)
13409 | Some(DialectType::Hive)
13410 | Some(DialectType::Spark)
13411 | Some(DialectType::Databricks)
13412 ) {
13413 std::borrow::Cow::Owned(n.replace('_', ""))
13414 } else {
13415 std::borrow::Cow::Borrowed(n.as_str())
13416 };
13417 if n.starts_with('.') {
13420 self.write("0");
13421 self.write(&n);
13422 } else if n.starts_with("-.") {
13423 self.write("-0");
13425 self.write(&n[1..]);
13426 } else {
13427 self.write(&n);
13428 }
13429 }
13430 Literal::HexString(h) => {
13431 match self.config.dialect {
13433 Some(DialectType::Spark)
13434 | Some(DialectType::Databricks)
13435 | Some(DialectType::Teradata) => self.write("X'"),
13436 _ => self.write("x'"),
13437 }
13438 self.write(h);
13439 self.write("'");
13440 }
13441 Literal::HexNumber(h) => {
13442 match self.config.dialect {
13446 Some(DialectType::BigQuery)
13447 | Some(DialectType::TSQL)
13448 | Some(DialectType::Fabric) => {
13449 self.write("0x");
13450 self.write(h);
13451 }
13452 _ => {
13453 if let Ok(val) = u64::from_str_radix(h, 16) {
13455 self.write(&val.to_string());
13456 } else {
13457 self.write("0x");
13459 self.write(h);
13460 }
13461 }
13462 }
13463 }
13464 Literal::BitString(b) => {
13465 self.write("B'");
13467 self.write(b);
13468 self.write("'");
13469 }
13470 Literal::ByteString(b) => {
13471 self.write("b'");
13473 self.write_escaped_byte_string(b);
13475 self.write("'");
13476 }
13477 Literal::NationalString(s) => {
13478 let keep_n_prefix = matches!(
13481 self.config.dialect,
13482 Some(DialectType::TSQL)
13483 | Some(DialectType::Oracle)
13484 | Some(DialectType::MySQL)
13485 | None
13486 );
13487 if keep_n_prefix {
13488 self.write("N'");
13489 } else {
13490 self.write("'");
13491 }
13492 self.write(s);
13493 self.write("'");
13494 }
13495 Literal::Date(d) => {
13496 self.generate_date_literal(d)?;
13497 }
13498 Literal::Time(t) => {
13499 self.generate_time_literal(t)?;
13500 }
13501 Literal::Timestamp(ts) => {
13502 self.generate_timestamp_literal(ts)?;
13503 }
13504 Literal::Datetime(dt) => {
13505 self.generate_datetime_literal(dt)?;
13506 }
13507 Literal::TripleQuotedString(s, _quote_char) => {
13508 if matches!(
13510 self.config.dialect,
13511 Some(crate::dialects::DialectType::BigQuery)
13512 | Some(crate::dialects::DialectType::DuckDB)
13513 | Some(crate::dialects::DialectType::Snowflake)
13514 | Some(crate::dialects::DialectType::Spark)
13515 | Some(crate::dialects::DialectType::Hive)
13516 | Some(crate::dialects::DialectType::Presto)
13517 | Some(crate::dialects::DialectType::Trino)
13518 | Some(crate::dialects::DialectType::PostgreSQL)
13519 | Some(crate::dialects::DialectType::MySQL)
13520 | Some(crate::dialects::DialectType::Redshift)
13521 | Some(crate::dialects::DialectType::TSQL)
13522 | Some(crate::dialects::DialectType::Oracle)
13523 | Some(crate::dialects::DialectType::ClickHouse)
13524 | Some(crate::dialects::DialectType::Databricks)
13525 | Some(crate::dialects::DialectType::SQLite)
13526 ) {
13527 self.generate_string_literal(s)?;
13528 } else {
13529 let quotes = format!("{0}{0}{0}", _quote_char);
13531 self.write("es);
13532 self.write(s);
13533 self.write("es);
13534 }
13535 }
13536 Literal::EscapeString(s) => {
13537 use crate::dialects::DialectType;
13541 let content = if let Some(c) = s.strip_prefix("e:") {
13542 c
13543 } else if let Some(c) = s.strip_prefix("E:") {
13544 c
13545 } else {
13546 s.as_str()
13547 };
13548
13549 if matches!(
13551 self.config.dialect,
13552 Some(DialectType::MySQL) | Some(DialectType::TiDB)
13553 ) {
13554 self.write(content);
13555 } else {
13556 let prefix = if matches!(
13558 self.config.dialect,
13559 Some(DialectType::SingleStore)
13560 | Some(DialectType::DuckDB)
13561 | Some(DialectType::PostgreSQL)
13562 | Some(DialectType::CockroachDB)
13563 | Some(DialectType::Materialize)
13564 | Some(DialectType::RisingWave)
13565 ) {
13566 "e'"
13567 } else {
13568 "E'"
13569 };
13570
13571 let normalized = content.replace("\\'", "''");
13573 self.write(prefix);
13574 self.write(&normalized);
13575 self.write("'");
13576 }
13577 }
13578 Literal::DollarString(s) => {
13579 use crate::dialects::DialectType;
13582 let (_tag, content) = crate::tokens::parse_dollar_string_token(s);
13584 let escape_backslash = matches!(self.config.dialect, Some(DialectType::Snowflake));
13586 let use_backslash_quote =
13590 matches!(self.config.dialect, Some(DialectType::Snowflake));
13591
13592 let mut escaped = String::with_capacity(content.len() + 4);
13593 for ch in content.chars() {
13594 if escape_backslash && ch == '\\' {
13595 escaped.push('\\');
13597 escaped.push('\\');
13598 } else if ch == '\'' {
13599 if use_backslash_quote {
13600 escaped.push('\\');
13601 escaped.push('\'');
13602 } else {
13603 escaped.push('\'');
13604 escaped.push('\'');
13605 }
13606 } else {
13607 escaped.push(ch);
13608 }
13609 }
13610 self.write("'");
13611 self.write(&escaped);
13612 self.write("'");
13613 }
13614 Literal::RawString(s) => {
13615 use crate::dialects::DialectType;
13621
13622 let escape_backslash = matches!(
13624 self.config.dialect,
13625 Some(DialectType::BigQuery)
13626 | Some(DialectType::MySQL)
13627 | Some(DialectType::SingleStore)
13628 | Some(DialectType::TiDB)
13629 | Some(DialectType::Hive)
13630 | Some(DialectType::Spark)
13631 | Some(DialectType::Databricks)
13632 | Some(DialectType::Drill)
13633 | Some(DialectType::Snowflake)
13634 | Some(DialectType::Redshift)
13635 | Some(DialectType::ClickHouse)
13636 );
13637
13638 let backslash_escapes_quote = matches!(
13641 self.config.dialect,
13642 Some(DialectType::BigQuery)
13643 | Some(DialectType::Hive)
13644 | Some(DialectType::Spark)
13645 | Some(DialectType::Databricks)
13646 | Some(DialectType::Drill)
13647 | Some(DialectType::Snowflake)
13648 | Some(DialectType::Redshift)
13649 );
13650
13651 let supports_escape_sequences = escape_backslash;
13654
13655 let mut escaped = String::with_capacity(s.len() + 4);
13656 for ch in s.chars() {
13657 if escape_backslash && ch == '\\' {
13658 escaped.push('\\');
13660 escaped.push('\\');
13661 } else if ch == '\'' {
13662 if backslash_escapes_quote {
13663 escaped.push('\\');
13665 escaped.push('\'');
13666 } else {
13667 escaped.push('\'');
13669 escaped.push('\'');
13670 }
13671 } else if supports_escape_sequences {
13672 match ch {
13675 '\n' => {
13676 escaped.push('\\');
13677 escaped.push('n');
13678 }
13679 '\r' => {
13680 escaped.push('\\');
13681 escaped.push('r');
13682 }
13683 '\t' => {
13684 escaped.push('\\');
13685 escaped.push('t');
13686 }
13687 '\x07' => {
13688 escaped.push('\\');
13689 escaped.push('a');
13690 }
13691 '\x08' => {
13692 escaped.push('\\');
13693 escaped.push('b');
13694 }
13695 '\x0C' => {
13696 escaped.push('\\');
13697 escaped.push('f');
13698 }
13699 '\x0B' => {
13700 escaped.push('\\');
13701 escaped.push('v');
13702 }
13703 _ => escaped.push(ch),
13704 }
13705 } else {
13706 escaped.push(ch);
13707 }
13708 }
13709 self.write("'");
13710 self.write(&escaped);
13711 self.write("'");
13712 }
13713 }
13714 Ok(())
13715 }
13716
13717 fn generate_date_literal(&mut self, d: &str) -> Result<()> {
13719 use crate::dialects::DialectType;
13720
13721 match self.config.dialect {
13722 Some(DialectType::TSQL) => {
13724 self.write("CAST('");
13725 self.write(d);
13726 self.write("' AS DATE)");
13727 }
13728 Some(DialectType::BigQuery) => {
13731 self.write("CAST('");
13732 self.write(d);
13733 self.write("' AS DATE)");
13734 }
13735 Some(DialectType::Exasol) => {
13738 self.write("CAST('");
13739 self.write(d);
13740 self.write("' AS DATE)");
13741 }
13742 Some(DialectType::Snowflake) => {
13745 self.write("CAST('");
13746 self.write(d);
13747 self.write("' AS DATE)");
13748 }
13749 Some(DialectType::PostgreSQL)
13751 | Some(DialectType::MySQL)
13752 | Some(DialectType::SingleStore)
13753 | Some(DialectType::TiDB)
13754 | Some(DialectType::Redshift) => {
13755 self.write("CAST('");
13756 self.write(d);
13757 self.write("' AS DATE)");
13758 }
13759 Some(DialectType::DuckDB)
13761 | Some(DialectType::Presto)
13762 | Some(DialectType::Trino)
13763 | Some(DialectType::Athena)
13764 | Some(DialectType::Spark)
13765 | Some(DialectType::Databricks)
13766 | Some(DialectType::Hive) => {
13767 self.write("CAST('");
13768 self.write(d);
13769 self.write("' AS DATE)");
13770 }
13771 Some(DialectType::Oracle) => {
13773 self.write("TO_DATE('");
13774 self.write(d);
13775 self.write("', 'YYYY-MM-DD')");
13776 }
13777 _ => {
13779 self.write_keyword("DATE");
13780 self.write(" '");
13781 self.write(d);
13782 self.write("'");
13783 }
13784 }
13785 Ok(())
13786 }
13787
13788 fn generate_time_literal(&mut self, t: &str) -> Result<()> {
13790 use crate::dialects::DialectType;
13791
13792 match self.config.dialect {
13793 Some(DialectType::TSQL) => {
13795 self.write("CAST('");
13796 self.write(t);
13797 self.write("' AS TIME)");
13798 }
13799 _ => {
13801 self.write_keyword("TIME");
13802 self.write(" '");
13803 self.write(t);
13804 self.write("'");
13805 }
13806 }
13807 Ok(())
13808 }
13809
13810 fn generate_dremio_date_expression(&mut self, expr: &Expression) -> Result<()> {
13812 use crate::expressions::Literal;
13813
13814 match expr {
13815 Expression::Literal(Literal::Date(d)) => {
13816 self.write("CAST('");
13818 self.write(d);
13819 self.write("' AS DATE)");
13820 }
13821 _ => {
13822 self.generate_expression(expr)?;
13824 }
13825 }
13826 Ok(())
13827 }
13828
13829 fn generate_timestamp_literal(&mut self, ts: &str) -> Result<()> {
13831 use crate::dialects::DialectType;
13832
13833 match self.config.dialect {
13834 Some(DialectType::TSQL) => {
13836 self.write("CAST('");
13837 self.write(ts);
13838 self.write("' AS DATETIME2)");
13839 }
13840 Some(DialectType::BigQuery) => {
13843 self.write("CAST('");
13844 self.write(ts);
13845 self.write("' AS TIMESTAMP)");
13846 }
13847 Some(DialectType::Snowflake) => {
13850 self.write("CAST('");
13851 self.write(ts);
13852 self.write("' AS TIMESTAMP)");
13853 }
13854 Some(DialectType::Dremio) => {
13857 self.write("CAST('");
13858 self.write(ts);
13859 self.write("' AS TIMESTAMP)");
13860 }
13861 Some(DialectType::Exasol) => {
13864 self.write("CAST('");
13865 self.write(ts);
13866 self.write("' AS TIMESTAMP)");
13867 }
13868 Some(DialectType::Oracle) => {
13871 self.write("TO_TIMESTAMP('");
13872 self.write(ts);
13873 self.write("', 'YYYY-MM-DD HH24:MI:SS.FF6')");
13874 }
13875 Some(DialectType::Presto) | Some(DialectType::Trino) => {
13877 if Self::timestamp_has_timezone(ts) {
13878 self.write("CAST('");
13879 self.write(ts);
13880 self.write("' AS TIMESTAMP WITH TIME ZONE)");
13881 } else {
13882 self.write("CAST('");
13883 self.write(ts);
13884 self.write("' AS TIMESTAMP)");
13885 }
13886 }
13887 Some(DialectType::ClickHouse) => {
13889 self.write("CAST('");
13890 self.write(ts);
13891 self.write("' AS Nullable(DateTime))");
13892 }
13893 Some(DialectType::Spark) => {
13895 self.write("CAST('");
13896 self.write(ts);
13897 self.write("' AS TIMESTAMP)");
13898 }
13899 Some(DialectType::Redshift) => {
13902 if ts == "epoch" {
13903 self.write_keyword("TIMESTAMP");
13904 self.write(" '");
13905 self.write(ts);
13906 self.write("'");
13907 } else {
13908 self.write("CAST('");
13909 self.write(ts);
13910 self.write("' AS TIMESTAMP)");
13911 }
13912 }
13913 Some(DialectType::PostgreSQL)
13915 | Some(DialectType::Hive)
13916 | Some(DialectType::SQLite)
13917 | Some(DialectType::DuckDB)
13918 | Some(DialectType::Athena)
13919 | Some(DialectType::Drill)
13920 | Some(DialectType::Teradata) => {
13921 self.write("CAST('");
13922 self.write(ts);
13923 self.write("' AS TIMESTAMP)");
13924 }
13925 Some(DialectType::MySQL) | Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
13927 self.write("CAST('");
13928 self.write(ts);
13929 self.write("' AS DATETIME)");
13930 }
13931 Some(DialectType::Databricks) => {
13933 self.write("CAST('");
13934 self.write(ts);
13935 self.write("' AS TIMESTAMP_NTZ)");
13936 }
13937 _ => {
13939 self.write_keyword("TIMESTAMP");
13940 self.write(" '");
13941 self.write(ts);
13942 self.write("'");
13943 }
13944 }
13945 Ok(())
13946 }
13947
13948 fn timestamp_has_timezone(ts: &str) -> bool {
13951 let ts_lower = ts.to_lowercase();
13955
13956 let continent_prefixes = [
13958 "africa/",
13959 "america/",
13960 "antarctica/",
13961 "arctic/",
13962 "asia/",
13963 "atlantic/",
13964 "australia/",
13965 "europe/",
13966 "indian/",
13967 "pacific/",
13968 "etc/",
13969 "brazil/",
13970 "canada/",
13971 "chile/",
13972 "mexico/",
13973 "us/",
13974 ];
13975
13976 for prefix in &continent_prefixes {
13977 if ts_lower.contains(prefix) {
13978 return true;
13979 }
13980 }
13981
13982 let tz_abbrevs = [
13985 " utc", " gmt", " cet", " cest", " eet", " eest", " wet", " west", " est", " edt",
13986 " cst", " cdt", " mst", " mdt", " pst", " pdt", " ist", " bst", " jst", " kst", " hkt",
13987 " sgt", " aest", " aedt", " acst", " acdt", " awst",
13988 ];
13989
13990 for abbrev in &tz_abbrevs {
13991 if ts_lower.ends_with(abbrev) {
13992 return true;
13993 }
13994 }
13995
13996 let trimmed = ts.trim();
14000 if let Some(last_space) = trimmed.rfind(' ') {
14001 let suffix = &trimmed[last_space + 1..];
14002 if (suffix.starts_with('+') || suffix.starts_with('-')) && suffix.len() > 1 {
14003 let rest = &suffix[1..];
14005 if rest.chars().all(|c| c.is_ascii_digit() || c == ':') {
14006 return true;
14007 }
14008 }
14009 }
14010
14011 false
14012 }
14013
14014 fn generate_datetime_literal(&mut self, dt: &str) -> Result<()> {
14016 use crate::dialects::DialectType;
14017
14018 match self.config.dialect {
14019 Some(DialectType::BigQuery) => {
14022 self.write("CAST('");
14023 self.write(dt);
14024 self.write("' AS DATETIME)");
14025 }
14026 Some(DialectType::DuckDB) => {
14028 self.write("CAST('");
14029 self.write(dt);
14030 self.write("' AS TIMESTAMP)");
14031 }
14032 _ => {
14035 self.write_keyword("DATETIME");
14036 self.write(" '");
14037 self.write(dt);
14038 self.write("'");
14039 }
14040 }
14041 Ok(())
14042 }
14043
14044 fn generate_string_literal(&mut self, s: &str) -> Result<()> {
14046 use crate::dialects::DialectType;
14047
14048 match self.config.dialect {
14049 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
14053 self.write("'");
14055 for c in s.chars() {
14056 match c {
14057 '\'' => self.write("\\'"),
14058 '\\' => self.write("\\\\"),
14059 '\n' => self.write("\\n"),
14060 '\r' => self.write("\\r"),
14061 '\t' => self.write("\\t"),
14062 '\0' => self.write("\\0"),
14063 _ => self.output.push(c),
14064 }
14065 }
14066 self.write("'");
14067 }
14068 Some(DialectType::Drill) => {
14069 self.write("'");
14072 for c in s.chars() {
14073 match c {
14074 '\'' => self.write("''"),
14075 '\\' => self.write("\\\\"),
14076 '\n' => self.write("\\n"),
14077 '\r' => self.write("\\r"),
14078 '\t' => self.write("\\t"),
14079 '\0' => self.write("\\0"),
14080 _ => self.output.push(c),
14081 }
14082 }
14083 self.write("'");
14084 }
14085 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB) => {
14086 self.write("'");
14087 for c in s.chars() {
14088 match c {
14089 '\'' => self.write("''"),
14091 '\\' => self.write("\\\\"),
14092 '\n' => self.write("\\n"),
14093 '\r' => self.write("\\r"),
14094 '\t' => self.write("\\t"),
14095 '\0' => self.output.push('\0'),
14097 _ => self.output.push(c),
14098 }
14099 }
14100 self.write("'");
14101 }
14102 Some(DialectType::BigQuery) => {
14104 self.write("'");
14105 for c in s.chars() {
14106 match c {
14107 '\'' => self.write("\\'"),
14108 '\\' => self.write("\\\\"),
14109 '\n' => self.write("\\n"),
14110 '\r' => self.write("\\r"),
14111 '\t' => self.write("\\t"),
14112 '\0' => self.write("\\0"),
14113 '\x07' => self.write("\\a"),
14114 '\x08' => self.write("\\b"),
14115 '\x0C' => self.write("\\f"),
14116 '\x0B' => self.write("\\v"),
14117 _ => self.output.push(c),
14118 }
14119 }
14120 self.write("'");
14121 }
14122 Some(DialectType::Athena) => {
14126 if self.athena_hive_context {
14127 self.write("'");
14129 for c in s.chars() {
14130 match c {
14131 '\'' => self.write("\\'"),
14132 '\\' => self.write("\\\\"),
14133 '\n' => self.write("\\n"),
14134 '\r' => self.write("\\r"),
14135 '\t' => self.write("\\t"),
14136 '\0' => self.write("\\0"),
14137 _ => self.output.push(c),
14138 }
14139 }
14140 self.write("'");
14141 } else {
14142 self.write("'");
14144 for c in s.chars() {
14145 match c {
14146 '\'' => self.write("''"),
14147 _ => self.output.push(c),
14149 }
14150 }
14151 self.write("'");
14152 }
14153 }
14154 Some(DialectType::Snowflake) => {
14159 self.write("'");
14160 for c in s.chars() {
14161 match c {
14162 '\'' => self.write("\\'"),
14163 '\n' => self.write("\\n"),
14166 '\r' => self.write("\\r"),
14167 '\t' => self.write("\\t"),
14168 _ => self.output.push(c),
14169 }
14170 }
14171 self.write("'");
14172 }
14173 Some(DialectType::PostgreSQL) => {
14175 self.write("'");
14176 for c in s.chars() {
14177 match c {
14178 '\'' => self.write("''"),
14179 _ => self.output.push(c),
14180 }
14181 }
14182 self.write("'");
14183 }
14184 Some(DialectType::Redshift) => {
14186 self.write("'");
14187 for c in s.chars() {
14188 match c {
14189 '\'' => self.write("\\'"),
14190 _ => self.output.push(c),
14191 }
14192 }
14193 self.write("'");
14194 }
14195 Some(DialectType::Oracle) => {
14197 self.write("'");
14198 self.write(&s.replace('\'', "''"));
14199 self.write("'");
14200 }
14201 Some(DialectType::ClickHouse) => {
14204 self.write("'");
14205 for c in s.chars() {
14206 match c {
14207 '\'' => self.write("''"),
14208 '\\' => self.write("\\\\"),
14209 '\n' => self.write("\\n"),
14210 '\r' => self.write("\\r"),
14211 '\t' => self.write("\\t"),
14212 '\0' => self.write("\\0"),
14213 '\x07' => self.write("\\a"),
14214 '\x08' => self.write("\\b"),
14215 '\x0C' => self.write("\\f"),
14216 '\x0B' => self.write("\\v"),
14217 c if c.is_control() || (c as u32) < 0x20 => {
14219 let byte = c as u32;
14220 if byte < 256 {
14221 self.write(&format!("\\x{:02X}", byte));
14222 } else {
14223 self.output.push(c);
14224 }
14225 }
14226 _ => self.output.push(c),
14227 }
14228 }
14229 self.write("'");
14230 }
14231 _ => {
14234 self.write("'");
14235 self.write(&s.replace('\'', "''"));
14236 self.write("'");
14237 }
14238 }
14239 Ok(())
14240 }
14241
14242 fn write_escaped_byte_string(&mut self, s: &str) {
14245 for c in s.chars() {
14246 match c {
14247 '\'' => self.write("\\'"),
14249 '\\' => self.write("\\\\"),
14251 _ if !c.is_control() => self.output.push(c),
14253 _ => {
14255 let byte = c as u32;
14256 if byte < 256 {
14257 self.write(&format!("\\x{:02x}", byte));
14258 } else {
14259 for b in c.to_string().as_bytes() {
14261 self.write(&format!("\\x{:02x}", b));
14262 }
14263 }
14264 }
14265 }
14266 }
14267 }
14268
14269 fn generate_boolean(&mut self, b: &BooleanLiteral) -> Result<()> {
14270 use crate::dialects::DialectType;
14271
14272 match self.config.dialect {
14274 Some(DialectType::TSQL) => {
14277 self.write(if b.value { "1" } else { "0" });
14278 }
14279 Some(DialectType::Oracle) => {
14281 self.write(if b.value { "1" } else { "0" });
14282 }
14283 Some(DialectType::MySQL) => {
14285 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
14286 }
14287 _ => {
14289 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
14290 }
14291 }
14292 Ok(())
14293 }
14294
14295 fn generate_alias_identifier(&mut self, id: &Identifier) -> Result<()> {
14298 let name = &id.name;
14299 let quote_style = &self.config.identifier_quote_style;
14300
14301 let needs_quoting = id.quoted || self.is_reserved_keyword(name);
14305
14306 let output_name = if self.config.normalize_identifiers && !id.quoted {
14308 name.to_lowercase()
14309 } else {
14310 name.to_string()
14311 };
14312
14313 if needs_quoting {
14314 let escaped_name = if quote_style.start == quote_style.end {
14316 output_name.replace(
14317 quote_style.end,
14318 &format!("{}{}", quote_style.end, quote_style.end),
14319 )
14320 } else {
14321 output_name.replace(
14322 quote_style.end,
14323 &format!("{}{}", quote_style.end, quote_style.end),
14324 )
14325 };
14326 self.write(&format!(
14327 "{}{}{}",
14328 quote_style.start, escaped_name, quote_style.end
14329 ));
14330 } else {
14331 self.write(&output_name);
14332 }
14333
14334 for comment in &id.trailing_comments {
14336 self.write(" ");
14337 self.write_formatted_comment(comment);
14338 }
14339 Ok(())
14340 }
14341
14342 fn generate_identifier(&mut self, id: &Identifier) -> Result<()> {
14343 use crate::dialects::DialectType;
14344
14345 let name = &id.name;
14346
14347 let quote_style = if matches!(self.config.dialect, Some(DialectType::Athena))
14349 && self.athena_hive_context
14350 {
14351 &IdentifierQuoteStyle::BACKTICK
14352 } else {
14353 &self.config.identifier_quote_style
14354 };
14355
14356 let starts_with_digit = name.chars().next().map_or(false, |c| c.is_ascii_digit());
14363 let needs_digit_quoting = starts_with_digit
14364 && !self.config.identifiers_can_start_with_digit
14365 && self.config.dialect.is_some();
14366 let mysql_invalid_hex_identifier = matches!(self.config.dialect, Some(DialectType::MySQL))
14367 && name.len() > 2
14368 && (name.starts_with("0x") || name.starts_with("0X"))
14369 && !name[2..].chars().all(|c| c.is_ascii_hexdigit());
14370 let needs_quoting = id.quoted
14371 || self.is_reserved_keyword(name)
14372 || self.config.always_quote_identifiers
14373 || needs_digit_quoting
14374 || mysql_invalid_hex_identifier;
14375
14376 let (base_name, suffix) = if needs_quoting {
14379 if let Some(paren_pos) = name.find('(') {
14381 let base = &name[..paren_pos];
14382 let rest = &name[paren_pos..];
14383 if rest.starts_with('(')
14385 && (rest.ends_with(')') || rest.ends_with(") ASC") || rest.ends_with(") DESC"))
14386 {
14387 let close_paren = rest.find(')').unwrap_or(rest.len());
14389 let inside = &rest[1..close_paren];
14390 if inside.chars().all(|c| c.is_ascii_digit()) {
14391 (base.to_string(), rest.to_string())
14392 } else {
14393 (name.to_string(), String::new())
14394 }
14395 } else {
14396 (name.to_string(), String::new())
14397 }
14398 } else if name.ends_with(" ASC") {
14399 let base = &name[..name.len() - 4];
14400 (base.to_string(), " ASC".to_string())
14401 } else if name.ends_with(" DESC") {
14402 let base = &name[..name.len() - 5];
14403 (base.to_string(), " DESC".to_string())
14404 } else {
14405 (name.to_string(), String::new())
14406 }
14407 } else {
14408 (name.to_string(), String::new())
14409 };
14410
14411 let output_name = if self.config.normalize_identifiers && !id.quoted {
14415 base_name.to_lowercase()
14416 } else if matches!(self.config.dialect, Some(DialectType::Exasol))
14417 && !id.quoted
14418 && self.is_reserved_keyword(name)
14419 {
14420 base_name.to_uppercase()
14423 } else {
14424 base_name
14425 };
14426
14427 if needs_quoting {
14428 let escaped_name = if quote_style.start == quote_style.end {
14430 output_name.replace(
14432 quote_style.end,
14433 &format!("{}{}", quote_style.end, quote_style.end),
14434 )
14435 } else {
14436 output_name.replace(
14438 quote_style.end,
14439 &format!("{}{}", quote_style.end, quote_style.end),
14440 )
14441 };
14442 self.write(&format!(
14443 "{}{}{}{}",
14444 quote_style.start, escaped_name, quote_style.end, suffix
14445 ));
14446 } else {
14447 self.write(&output_name);
14448 }
14449
14450 for comment in &id.trailing_comments {
14452 self.write(" ");
14453 self.write_formatted_comment(comment);
14454 }
14455 Ok(())
14456 }
14457
14458 fn generate_column(&mut self, col: &Column) -> Result<()> {
14459 use crate::dialects::DialectType;
14460
14461 if let Some(table) = &col.table {
14462 let is_exasol_local_prefix = matches!(self.config.dialect, Some(DialectType::Exasol))
14466 && !table.quoted
14467 && table.name.eq_ignore_ascii_case("LOCAL");
14468
14469 if is_exasol_local_prefix {
14470 self.write("LOCAL");
14472 } else {
14473 self.generate_identifier(table)?;
14474 }
14475 self.write(".");
14476 }
14477 self.generate_identifier(&col.name)?;
14478 if col.join_mark && self.config.supports_column_join_marks {
14481 self.write(" (+)");
14482 }
14483 for comment in &col.trailing_comments {
14485 self.write_space();
14486 self.write_formatted_comment(comment);
14487 }
14488 Ok(())
14489 }
14490
14491 fn generate_pseudocolumn(&mut self, pc: &Pseudocolumn) -> Result<()> {
14494 use crate::dialects::DialectType;
14495 use crate::expressions::PseudocolumnType;
14496
14497 if pc.kind == PseudocolumnType::Sysdate
14499 && !matches!(
14500 self.config.dialect,
14501 Some(DialectType::Oracle) | Some(DialectType::Redshift) | None
14502 )
14503 {
14504 self.write_keyword("CURRENT_TIMESTAMP");
14505 if matches!(
14507 self.config.dialect,
14508 Some(DialectType::MySQL)
14509 | Some(DialectType::ClickHouse)
14510 | Some(DialectType::Spark)
14511 | Some(DialectType::Databricks)
14512 | Some(DialectType::Hive)
14513 ) {
14514 self.write("()");
14515 }
14516 } else {
14517 self.write(pc.kind.as_str());
14518 }
14519 Ok(())
14520 }
14521
14522 fn generate_connect(&mut self, connect: &Connect) -> Result<()> {
14524 use crate::dialects::DialectType;
14525
14526 let supports_connect_by = matches!(
14529 self.config.dialect,
14530 Some(DialectType::Oracle) | Some(DialectType::Snowflake)
14531 );
14532
14533 if !supports_connect_by && self.config.dialect.is_some() {
14534 if self.config.pretty {
14536 self.write_newline();
14537 } else {
14538 self.write_space();
14539 }
14540 self.write("/* CONNECT BY requires manual conversion to recursive CTE */");
14541 }
14542
14543 if let Some(start) = &connect.start {
14545 if self.config.pretty {
14546 self.write_newline();
14547 } else {
14548 self.write_space();
14549 }
14550 self.write_keyword("START WITH");
14551 self.write_space();
14552 self.generate_expression(start)?;
14553 }
14554
14555 if self.config.pretty {
14557 self.write_newline();
14558 } else {
14559 self.write_space();
14560 }
14561 self.write_keyword("CONNECT BY");
14562 if connect.nocycle {
14563 self.write_space();
14564 self.write_keyword("NOCYCLE");
14565 }
14566 self.write_space();
14567 self.generate_expression(&connect.connect)?;
14568
14569 Ok(())
14570 }
14571
14572 fn generate_connect_expr(&mut self, connect: &Connect) -> Result<()> {
14574 self.generate_connect(connect)
14575 }
14576
14577 fn generate_prior(&mut self, prior: &Prior) -> Result<()> {
14579 self.write_keyword("PRIOR");
14580 self.write_space();
14581 self.generate_expression(&prior.this)?;
14582 Ok(())
14583 }
14584
14585 fn generate_connect_by_root(&mut self, cbr: &ConnectByRoot) -> Result<()> {
14588 self.write_keyword("CONNECT_BY_ROOT");
14589 self.write_space();
14590 self.generate_expression(&cbr.this)?;
14591 Ok(())
14592 }
14593
14594 fn generate_match_recognize(&mut self, mr: &MatchRecognize) -> Result<()> {
14596 use crate::dialects::DialectType;
14597
14598 let supports_match_recognize = matches!(
14600 self.config.dialect,
14601 Some(DialectType::Oracle)
14602 | Some(DialectType::Snowflake)
14603 | Some(DialectType::Presto)
14604 | Some(DialectType::Trino)
14605 );
14606
14607 if let Some(source) = &mr.this {
14609 self.generate_expression(source)?;
14610 }
14611
14612 if !supports_match_recognize {
14613 self.write("/* MATCH_RECOGNIZE not supported in this dialect */");
14614 return Ok(());
14615 }
14616
14617 if self.config.pretty {
14619 self.write_newline();
14620 } else {
14621 self.write_space();
14622 }
14623
14624 self.write_keyword("MATCH_RECOGNIZE");
14625 self.write(" (");
14626
14627 if self.config.pretty {
14628 self.indent_level += 1;
14629 }
14630
14631 let mut needs_separator = false;
14632
14633 if let Some(partition_by) = &mr.partition_by {
14635 if !partition_by.is_empty() {
14636 if self.config.pretty {
14637 self.write_newline();
14638 self.write_indent();
14639 }
14640 self.write_keyword("PARTITION BY");
14641 self.write_space();
14642 for (i, expr) in partition_by.iter().enumerate() {
14643 if i > 0 {
14644 self.write(", ");
14645 }
14646 self.generate_expression(expr)?;
14647 }
14648 needs_separator = true;
14649 }
14650 }
14651
14652 if let Some(order_by) = &mr.order_by {
14654 if !order_by.is_empty() {
14655 if needs_separator {
14656 if self.config.pretty {
14657 self.write_newline();
14658 self.write_indent();
14659 } else {
14660 self.write_space();
14661 }
14662 } else if self.config.pretty {
14663 self.write_newline();
14664 self.write_indent();
14665 }
14666 self.write_keyword("ORDER BY");
14667 if self.config.pretty {
14669 self.indent_level += 1;
14670 for (i, ordered) in order_by.iter().enumerate() {
14671 if i > 0 {
14672 self.write(",");
14673 }
14674 self.write_newline();
14675 self.write_indent();
14676 self.generate_ordered(ordered)?;
14677 }
14678 self.indent_level -= 1;
14679 } else {
14680 self.write_space();
14681 for (i, ordered) in order_by.iter().enumerate() {
14682 if i > 0 {
14683 self.write(", ");
14684 }
14685 self.generate_ordered(ordered)?;
14686 }
14687 }
14688 needs_separator = true;
14689 }
14690 }
14691
14692 if let Some(measures) = &mr.measures {
14694 if !measures.is_empty() {
14695 if needs_separator {
14696 if self.config.pretty {
14697 self.write_newline();
14698 self.write_indent();
14699 } else {
14700 self.write_space();
14701 }
14702 } else if self.config.pretty {
14703 self.write_newline();
14704 self.write_indent();
14705 }
14706 self.write_keyword("MEASURES");
14707 if self.config.pretty {
14709 self.indent_level += 1;
14710 for (i, measure) in measures.iter().enumerate() {
14711 if i > 0 {
14712 self.write(",");
14713 }
14714 self.write_newline();
14715 self.write_indent();
14716 if let Some(semantics) = &measure.window_frame {
14718 match semantics {
14719 MatchRecognizeSemantics::Running => {
14720 self.write_keyword("RUNNING");
14721 self.write_space();
14722 }
14723 MatchRecognizeSemantics::Final => {
14724 self.write_keyword("FINAL");
14725 self.write_space();
14726 }
14727 }
14728 }
14729 self.generate_expression(&measure.this)?;
14730 }
14731 self.indent_level -= 1;
14732 } else {
14733 self.write_space();
14734 for (i, measure) in measures.iter().enumerate() {
14735 if i > 0 {
14736 self.write(", ");
14737 }
14738 if let Some(semantics) = &measure.window_frame {
14740 match semantics {
14741 MatchRecognizeSemantics::Running => {
14742 self.write_keyword("RUNNING");
14743 self.write_space();
14744 }
14745 MatchRecognizeSemantics::Final => {
14746 self.write_keyword("FINAL");
14747 self.write_space();
14748 }
14749 }
14750 }
14751 self.generate_expression(&measure.this)?;
14752 }
14753 }
14754 needs_separator = true;
14755 }
14756 }
14757
14758 if let Some(rows) = &mr.rows {
14760 if needs_separator {
14761 if self.config.pretty {
14762 self.write_newline();
14763 self.write_indent();
14764 } else {
14765 self.write_space();
14766 }
14767 } else if self.config.pretty {
14768 self.write_newline();
14769 self.write_indent();
14770 }
14771 match rows {
14772 MatchRecognizeRows::OneRowPerMatch => {
14773 self.write_keyword("ONE ROW PER MATCH");
14774 }
14775 MatchRecognizeRows::AllRowsPerMatch => {
14776 self.write_keyword("ALL ROWS PER MATCH");
14777 }
14778 MatchRecognizeRows::AllRowsPerMatchShowEmptyMatches => {
14779 self.write_keyword("ALL ROWS PER MATCH SHOW EMPTY MATCHES");
14780 }
14781 MatchRecognizeRows::AllRowsPerMatchOmitEmptyMatches => {
14782 self.write_keyword("ALL ROWS PER MATCH OMIT EMPTY MATCHES");
14783 }
14784 MatchRecognizeRows::AllRowsPerMatchWithUnmatchedRows => {
14785 self.write_keyword("ALL ROWS PER MATCH WITH UNMATCHED ROWS");
14786 }
14787 }
14788 needs_separator = true;
14789 }
14790
14791 if let Some(after) = &mr.after {
14793 if needs_separator {
14794 if self.config.pretty {
14795 self.write_newline();
14796 self.write_indent();
14797 } else {
14798 self.write_space();
14799 }
14800 } else if self.config.pretty {
14801 self.write_newline();
14802 self.write_indent();
14803 }
14804 match after {
14805 MatchRecognizeAfter::PastLastRow => {
14806 self.write_keyword("AFTER MATCH SKIP PAST LAST ROW");
14807 }
14808 MatchRecognizeAfter::ToNextRow => {
14809 self.write_keyword("AFTER MATCH SKIP TO NEXT ROW");
14810 }
14811 MatchRecognizeAfter::ToFirst(ident) => {
14812 self.write_keyword("AFTER MATCH SKIP TO FIRST");
14813 self.write_space();
14814 self.generate_identifier(ident)?;
14815 }
14816 MatchRecognizeAfter::ToLast(ident) => {
14817 self.write_keyword("AFTER MATCH SKIP TO LAST");
14818 self.write_space();
14819 self.generate_identifier(ident)?;
14820 }
14821 }
14822 needs_separator = true;
14823 }
14824
14825 if let Some(pattern) = &mr.pattern {
14827 if needs_separator {
14828 if self.config.pretty {
14829 self.write_newline();
14830 self.write_indent();
14831 } else {
14832 self.write_space();
14833 }
14834 } else if self.config.pretty {
14835 self.write_newline();
14836 self.write_indent();
14837 }
14838 self.write_keyword("PATTERN");
14839 self.write_space();
14840 self.write("(");
14841 self.write(pattern);
14842 self.write(")");
14843 needs_separator = true;
14844 }
14845
14846 if let Some(define) = &mr.define {
14848 if !define.is_empty() {
14849 if needs_separator {
14850 if self.config.pretty {
14851 self.write_newline();
14852 self.write_indent();
14853 } else {
14854 self.write_space();
14855 }
14856 } else if self.config.pretty {
14857 self.write_newline();
14858 self.write_indent();
14859 }
14860 self.write_keyword("DEFINE");
14861 if self.config.pretty {
14863 self.indent_level += 1;
14864 for (i, (name, expr)) in define.iter().enumerate() {
14865 if i > 0 {
14866 self.write(",");
14867 }
14868 self.write_newline();
14869 self.write_indent();
14870 self.generate_identifier(name)?;
14871 self.write(" AS ");
14872 self.generate_expression(expr)?;
14873 }
14874 self.indent_level -= 1;
14875 } else {
14876 self.write_space();
14877 for (i, (name, expr)) in define.iter().enumerate() {
14878 if i > 0 {
14879 self.write(", ");
14880 }
14881 self.generate_identifier(name)?;
14882 self.write(" AS ");
14883 self.generate_expression(expr)?;
14884 }
14885 }
14886 }
14887 }
14888
14889 if self.config.pretty {
14890 self.indent_level -= 1;
14891 self.write_newline();
14892 }
14893 self.write(")");
14894
14895 if let Some(alias) = &mr.alias {
14897 self.write(" ");
14898 if mr.alias_explicit_as {
14899 self.write_keyword("AS");
14900 self.write(" ");
14901 }
14902 self.generate_identifier(alias)?;
14903 }
14904
14905 Ok(())
14906 }
14907
14908 fn generate_hint(&mut self, hint: &Hint) -> Result<()> {
14910 use crate::dialects::DialectType;
14911
14912 let supports_hints = matches!(
14914 self.config.dialect,
14915 None | Some(DialectType::Oracle) | Some(DialectType::MySQL) |
14917 Some(DialectType::Spark) | Some(DialectType::Hive) |
14918 Some(DialectType::Databricks) | Some(DialectType::PostgreSQL)
14919 );
14920
14921 if !supports_hints || hint.expressions.is_empty() {
14922 return Ok(());
14923 }
14924
14925 let mut hint_strings: Vec<String> = Vec::new();
14928 for expr in &hint.expressions {
14929 match expr {
14930 HintExpression::Raw(text) => {
14931 let parsed = self.parse_raw_hint_text(text);
14933 hint_strings.extend(parsed);
14934 }
14935 _ => {
14936 hint_strings.push(self.hint_expression_to_string(expr)?);
14937 }
14938 }
14939 }
14940
14941 let use_multiline = self.config.pretty && hint_strings.len() > 1;
14945
14946 if use_multiline {
14947 self.write(" /*+ ");
14949 for (i, hint_str) in hint_strings.iter().enumerate() {
14950 if i > 0 {
14951 self.write_newline();
14952 self.write(" "); }
14954 self.write(hint_str);
14955 }
14956 self.write(" */");
14957 } else {
14958 self.write(" /*+ ");
14960 let sep = match self.config.dialect {
14961 Some(DialectType::Spark) | Some(DialectType::Databricks) => ", ",
14962 _ => " ",
14963 };
14964 for (i, hint_str) in hint_strings.iter().enumerate() {
14965 if i > 0 {
14966 self.write(sep);
14967 }
14968 self.write(hint_str);
14969 }
14970 self.write(" */");
14971 }
14972
14973 Ok(())
14974 }
14975
14976 fn parse_raw_hint_text(&self, text: &str) -> Vec<String> {
14980 let mut results = Vec::new();
14981 let mut chars = text.chars().peekable();
14982 let mut current = String::new();
14983 let mut paren_depth = 0;
14984 let mut has_unparseable_content = false;
14985 let mut position_after_last_function = 0;
14986 let mut char_position = 0;
14987
14988 while let Some(c) = chars.next() {
14989 char_position += c.len_utf8();
14990 match c {
14991 '(' => {
14992 paren_depth += 1;
14993 current.push(c);
14994 }
14995 ')' => {
14996 paren_depth -= 1;
14997 current.push(c);
14998 if paren_depth == 0 {
15000 let trimmed = current.trim().to_string();
15001 if !trimmed.is_empty() {
15002 let formatted = self.format_hint_function(&trimmed);
15004 results.push(formatted);
15005 }
15006 current.clear();
15007 position_after_last_function = char_position;
15008 }
15009 }
15010 ' ' | '\t' | '\n' | ',' if paren_depth == 0 => {
15011 }
15013 _ if paren_depth == 0 => {
15014 current.push(c);
15016 }
15017 _ => {
15018 current.push(c);
15019 }
15020 }
15021 }
15022
15023 let remaining_text = text[position_after_last_function..].trim();
15025 if !remaining_text.is_empty() {
15026 let words: Vec<&str> = remaining_text.split_whitespace().collect();
15030 let looks_like_hint_functions = words.iter().all(|word| {
15031 word.contains('(') || (word.chars().all(|c| c.is_ascii_uppercase() || c == '_'))
15033 });
15034
15035 if !looks_like_hint_functions && words.len() > 1 {
15036 has_unparseable_content = true;
15037 }
15038 }
15039
15040 if has_unparseable_content {
15042 return vec![text.trim().to_string()];
15043 }
15044
15045 if results.is_empty() {
15047 results.push(text.trim().to_string());
15048 }
15049
15050 results
15051 }
15052
15053 fn format_hint_function(&self, hint: &str) -> String {
15056 if !self.config.pretty {
15057 return hint.to_string();
15058 }
15059
15060 if let Some(paren_pos) = hint.find('(') {
15062 if hint.ends_with(')') {
15063 let name = &hint[..paren_pos];
15064 let args_str = &hint[paren_pos + 1..hint.len() - 1];
15065
15066 let args: Vec<&str> = args_str.split_whitespace().collect();
15068
15069 let total_args_width: usize =
15071 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() {
15075 let mut result = format!("{}(\n", name);
15076 for arg in &args {
15077 result.push_str(" "); result.push_str(arg);
15079 result.push('\n');
15080 }
15081 result.push_str(" )"); return result;
15083 }
15084 }
15085 }
15086
15087 hint.to_string()
15088 }
15089
15090 fn hint_expression_to_string(&mut self, expr: &HintExpression) -> Result<String> {
15092 match expr {
15093 HintExpression::Function { name, args } => {
15094 let arg_strings: Vec<String> = args
15096 .iter()
15097 .map(|arg| {
15098 let mut gen = Generator::with_config(self.config.clone());
15099 gen.generate_expression(arg)?;
15100 Ok(gen.output)
15101 })
15102 .collect::<Result<Vec<_>>>()?;
15103
15104 let total_args_width: usize = arg_strings.iter().map(|s| s.len()).sum::<usize>()
15106 + arg_strings.len().saturating_sub(1); let args_multiline =
15111 self.config.pretty && total_args_width > self.config.max_text_width;
15112
15113 if args_multiline && !arg_strings.is_empty() {
15114 let mut result = format!("{}(\n", name);
15116 for arg_str in &arg_strings {
15117 result.push_str(" "); result.push_str(arg_str);
15119 result.push('\n');
15120 }
15121 result.push_str(" )"); Ok(result)
15123 } else {
15124 let args_str = arg_strings.join(" ");
15126 Ok(format!("{}({})", name, args_str))
15127 }
15128 }
15129 HintExpression::Identifier(name) => Ok(name.clone()),
15130 HintExpression::Raw(text) => {
15131 if self.config.pretty {
15133 Ok(self.format_hint_function(text))
15134 } else {
15135 Ok(text.clone())
15136 }
15137 }
15138 }
15139 }
15140
15141 fn generate_table(&mut self, table: &TableRef) -> Result<()> {
15142 if table.only {
15144 self.write_keyword("ONLY");
15145 self.write_space();
15146 }
15147
15148 if let Some(ref identifier_func) = table.identifier_func {
15150 self.generate_expression(identifier_func)?;
15151 } else {
15152 if let Some(catalog) = &table.catalog {
15153 self.generate_identifier(catalog)?;
15154 self.write(".");
15155 }
15156 if let Some(schema) = &table.schema {
15157 self.generate_identifier(schema)?;
15158 self.write(".");
15159 }
15160 self.generate_identifier(&table.name)?;
15161 }
15162
15163 if let Some(changes) = &table.changes {
15165 self.write(" ");
15166 self.generate_changes(changes)?;
15167 }
15168
15169 if !table.partitions.is_empty() {
15171 self.write_space();
15172 self.write_keyword("PARTITION");
15173 self.write("(");
15174 for (i, partition) in table.partitions.iter().enumerate() {
15175 if i > 0 {
15176 self.write(", ");
15177 }
15178 self.generate_identifier(partition)?;
15179 }
15180 self.write(")");
15181 }
15182
15183 if table.changes.is_none() {
15186 if let Some(when) = &table.when {
15187 self.write_space();
15188 self.generate_historical_data(when)?;
15189 }
15190 }
15191
15192 if let Some(ref system_time) = table.system_time {
15194 self.write_space();
15195 self.write(system_time);
15196 }
15197
15198 if let Some(ref version) = table.version {
15200 self.write_space();
15201 self.generate_version(version)?;
15202 }
15203
15204 let alias_post_tablesample = self.config.alias_post_tablesample;
15208
15209 if alias_post_tablesample {
15210 self.generate_table_sample_clause(table)?;
15212 }
15213
15214 let is_sqlite_hint = matches!(self.config.dialect, Some(DialectType::SQLite))
15217 && table.hints.iter().any(|h| {
15218 if let Expression::Identifier(id) = h {
15219 id.name.starts_with("INDEXED BY") || id.name == "NOT INDEXED"
15220 } else {
15221 false
15222 }
15223 });
15224 if !table.hints.is_empty() && !is_sqlite_hint {
15225 for hint in &table.hints {
15226 self.write_space();
15227 self.generate_expression(hint)?;
15228 }
15229 }
15230
15231 if let Some(alias) = &table.alias {
15232 self.write_space();
15233 let always_use_as = self.config.dialect.is_none()
15236 || matches!(
15237 self.config.dialect,
15238 Some(DialectType::Generic)
15239 | Some(DialectType::PostgreSQL)
15240 | Some(DialectType::Redshift)
15241 | Some(DialectType::Snowflake)
15242 | Some(DialectType::BigQuery)
15243 | Some(DialectType::Presto)
15244 | Some(DialectType::Trino)
15245 | Some(DialectType::TSQL)
15246 | Some(DialectType::Fabric)
15247 | Some(DialectType::MySQL)
15248 | Some(DialectType::Spark)
15249 | Some(DialectType::Hive)
15250 | Some(DialectType::SQLite)
15251 | Some(DialectType::Drill)
15252 );
15253 let is_stage_ref = table.name.name.starts_with('@');
15254 let suppress_as = matches!(self.config.dialect, Some(DialectType::Oracle));
15256 if !suppress_as && (table.alias_explicit_as || always_use_as || is_stage_ref) {
15257 self.write_keyword("AS");
15258 self.write_space();
15259 }
15260 self.generate_identifier(alias)?;
15261
15262 if !table.column_aliases.is_empty() && self.config.supports_table_alias_columns {
15265 self.write("(");
15266 for (i, col_alias) in table.column_aliases.iter().enumerate() {
15267 if i > 0 {
15268 self.write(", ");
15269 }
15270 self.generate_identifier(col_alias)?;
15271 }
15272 self.write(")");
15273 }
15274 }
15275
15276 if !alias_post_tablesample {
15278 self.generate_table_sample_clause(table)?;
15279 }
15280
15281 if is_sqlite_hint {
15283 for hint in &table.hints {
15284 self.write_space();
15285 self.generate_expression(hint)?;
15286 }
15287 }
15288
15289 if table.final_ && matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
15291 self.write_space();
15292 self.write_keyword("FINAL");
15293 }
15294
15295 for comment in &table.trailing_comments {
15297 self.write_space();
15298 self.write_formatted_comment(comment);
15299 }
15300
15301 Ok(())
15302 }
15303
15304 fn generate_table_sample_clause(&mut self, table: &TableRef) -> Result<()> {
15306 if let Some(ref ts) = table.table_sample {
15307 self.write_space();
15308 if ts.is_using_sample {
15309 self.write_keyword("USING SAMPLE");
15310 } else {
15311 self.write_keyword(self.config.tablesample_keywords);
15313 }
15314 self.generate_sample_body(ts)?;
15315 if let Some(ref seed) = ts.seed {
15317 self.write_space();
15318 self.write_keyword(self.config.tablesample_seed_keyword);
15319 self.write(" (");
15320 self.generate_expression(seed)?;
15321 self.write(")");
15322 }
15323 }
15324 Ok(())
15325 }
15326
15327 fn generate_stage_reference(&mut self, sr: &StageReference) -> Result<()> {
15328 if sr.quoted {
15332 self.write("'");
15333 }
15334
15335 self.write(&sr.name);
15336 if let Some(path) = &sr.path {
15337 self.write(path);
15338 }
15339
15340 if sr.quoted {
15341 self.write("'");
15342 }
15343
15344 let has_options = sr.file_format.is_some() || sr.pattern.is_some();
15346 if has_options {
15347 self.write(" (");
15348 let mut first = true;
15349
15350 if let Some(file_format) = &sr.file_format {
15351 if !first {
15352 self.write(", ");
15353 }
15354 self.write_keyword("FILE_FORMAT");
15355 self.write(" => ");
15356 self.generate_expression(file_format)?;
15357 first = false;
15358 }
15359
15360 if let Some(pattern) = &sr.pattern {
15361 if !first {
15362 self.write(", ");
15363 }
15364 self.write_keyword("PATTERN");
15365 self.write(" => '");
15366 self.write(pattern);
15367 self.write("'");
15368 }
15369
15370 self.write(")");
15371 }
15372 Ok(())
15373 }
15374
15375 fn generate_star(&mut self, star: &Star) -> Result<()> {
15376 use crate::dialects::DialectType;
15377
15378 if let Some(table) = &star.table {
15379 self.generate_identifier(table)?;
15380 self.write(".");
15381 }
15382 self.write("*");
15383
15384 if let Some(except) = &star.except {
15386 if !except.is_empty() {
15387 self.write_space();
15388 match self.config.dialect {
15390 Some(DialectType::BigQuery) => self.write_keyword("EXCEPT"),
15391 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => {
15392 self.write_keyword("EXCLUDE")
15393 }
15394 _ => self.write_keyword("EXCEPT"), }
15396 self.write(" (");
15397 for (i, col) in except.iter().enumerate() {
15398 if i > 0 {
15399 self.write(", ");
15400 }
15401 self.generate_identifier(col)?;
15402 }
15403 self.write(")");
15404 }
15405 }
15406
15407 if let Some(replace) = &star.replace {
15409 if !replace.is_empty() {
15410 self.write_space();
15411 self.write_keyword("REPLACE");
15412 self.write(" (");
15413 for (i, alias) in replace.iter().enumerate() {
15414 if i > 0 {
15415 self.write(", ");
15416 }
15417 self.generate_expression(&alias.this)?;
15418 self.write_space();
15419 self.write_keyword("AS");
15420 self.write_space();
15421 self.generate_identifier(&alias.alias)?;
15422 }
15423 self.write(")");
15424 }
15425 }
15426
15427 if let Some(rename) = &star.rename {
15429 if !rename.is_empty() {
15430 self.write_space();
15431 self.write_keyword("RENAME");
15432 self.write(" (");
15433 for (i, (old_name, new_name)) in rename.iter().enumerate() {
15434 if i > 0 {
15435 self.write(", ");
15436 }
15437 self.generate_identifier(old_name)?;
15438 self.write_space();
15439 self.write_keyword("AS");
15440 self.write_space();
15441 self.generate_identifier(new_name)?;
15442 }
15443 self.write(")");
15444 }
15445 }
15446
15447 for comment in &star.trailing_comments {
15449 self.write_space();
15450 self.write_formatted_comment(comment);
15451 }
15452
15453 Ok(())
15454 }
15455
15456 fn generate_braced_wildcard(&mut self, expr: &Expression) -> Result<()> {
15458 self.write("{");
15459 match expr {
15460 Expression::Star(star) => {
15461 self.generate_star(star)?;
15463 }
15464 Expression::ILike(ilike) => {
15465 self.generate_expression(&ilike.left)?;
15467 self.write_space();
15468 self.write_keyword("ILIKE");
15469 self.write_space();
15470 self.generate_expression(&ilike.right)?;
15471 }
15472 _ => {
15473 self.generate_expression(expr)?;
15474 }
15475 }
15476 self.write("}");
15477 Ok(())
15478 }
15479
15480 fn generate_alias(&mut self, alias: &Alias) -> Result<()> {
15481 match &alias.this {
15485 Expression::Column(col) => {
15486 if let Some(table) = &col.table {
15488 self.generate_identifier(table)?;
15489 self.write(".");
15490 }
15491 self.generate_identifier(&col.name)?;
15492 }
15493 _ => {
15494 self.generate_expression(&alias.this)?;
15495 }
15496 }
15497
15498 if !alias.pre_alias_comments.is_empty() && !alias.trailing_comments.is_empty() {
15502 for comment in &alias.pre_alias_comments {
15503 self.write_space();
15504 self.write_formatted_comment(comment);
15505 }
15506 }
15507
15508 use crate::dialects::DialectType;
15509
15510 let is_table_source = matches!(
15516 &alias.this,
15517 Expression::JSONTable(_)
15518 | Expression::XMLTable(_)
15519 | Expression::TableFromRows(_)
15520 | Expression::Unnest(_)
15521 | Expression::MatchRecognize(_)
15522 | Expression::Select(_)
15523 | Expression::Subquery(_)
15524 | Expression::Paren(_)
15525 );
15526 let dialect_skips_table_alias_as = matches!(self.config.dialect, Some(DialectType::Oracle));
15527 let skip_as = is_table_source && dialect_skips_table_alias_as;
15528
15529 self.write_space();
15530 if !skip_as {
15531 self.write_keyword("AS");
15532 self.write_space();
15533 }
15534
15535 let skip_column_aliases = matches!(self.config.dialect, Some(DialectType::BigQuery));
15537
15538 if alias.alias.is_empty() && !alias.column_aliases.is_empty() && !skip_column_aliases {
15540 self.write("(");
15542 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
15543 if i > 0 {
15544 self.write(", ");
15545 }
15546 self.generate_alias_identifier(col_alias)?;
15547 }
15548 self.write(")");
15549 } else if !alias.column_aliases.is_empty() && !skip_column_aliases {
15550 self.generate_alias_identifier(&alias.alias)?;
15552 self.write("(");
15553 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
15554 if i > 0 {
15555 self.write(", ");
15556 }
15557 self.generate_alias_identifier(col_alias)?;
15558 }
15559 self.write(")");
15560 } else {
15561 self.generate_alias_identifier(&alias.alias)?;
15563 }
15564
15565 for comment in &alias.trailing_comments {
15567 self.write_space();
15568 self.write_formatted_comment(comment);
15569 }
15570
15571 if alias.trailing_comments.is_empty() {
15576 for comment in &alias.pre_alias_comments {
15577 self.write_space();
15578 self.write_formatted_comment(comment);
15579 }
15580 }
15581
15582 Ok(())
15583 }
15584
15585 fn generate_cast(&mut self, cast: &Cast) -> Result<()> {
15586 use crate::dialects::DialectType;
15587
15588 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
15590 self.generate_expression(&cast.this)?;
15591 self.write(" :> ");
15592 self.generate_data_type(&cast.to)?;
15593 return Ok(());
15594 }
15595
15596 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
15598 let is_unknown_type = matches!(cast.to, DataType::Unknown)
15599 || matches!(cast.to, DataType::Custom { ref name } if name.is_empty());
15600 if is_unknown_type {
15601 if let Some(format) = &cast.format {
15602 self.write_keyword("CAST");
15603 self.write("(");
15604 self.generate_expression(&cast.this)?;
15605 self.write_space();
15606 self.write_keyword("AS");
15607 self.write_space();
15608 self.write_keyword("FORMAT");
15609 self.write_space();
15610 self.generate_expression(format)?;
15611 self.write(")");
15612 return Ok(());
15613 }
15614 }
15615 }
15616
15617 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
15620 if let Some(format) = &cast.format {
15621 let is_date = matches!(cast.to, DataType::Date);
15623 let is_timestamp = matches!(cast.to, DataType::Timestamp { .. });
15624
15625 if is_date || is_timestamp {
15626 let func_name = if is_date { "TO_DATE" } else { "TO_TIMESTAMP" };
15627 self.write_keyword(func_name);
15628 self.write("(");
15629 self.generate_expression(&cast.this)?;
15630 self.write(", ");
15631
15632 if let Expression::Literal(Literal::String(fmt_str)) = format.as_ref() {
15635 let normalized = self.normalize_oracle_format(fmt_str);
15636 self.write("'");
15637 self.write(&normalized);
15638 self.write("'");
15639 } else {
15640 self.generate_expression(format)?;
15641 }
15642
15643 self.write(")");
15644 return Ok(());
15645 }
15646 }
15647 }
15648
15649 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
15652 if let Expression::Array(arr) = &cast.this {
15653 self.generate_data_type(&cast.to)?;
15654 self.write("[");
15656 for (i, expr) in arr.expressions.iter().enumerate() {
15657 if i > 0 {
15658 self.write(", ");
15659 }
15660 self.generate_expression(expr)?;
15661 }
15662 self.write("]");
15663 return Ok(());
15664 }
15665 if matches!(&cast.this, Expression::ArrayFunc(_)) {
15666 self.generate_data_type(&cast.to)?;
15667 self.generate_expression(&cast.this)?;
15668 return Ok(());
15669 }
15670 }
15671
15672 if matches!(
15675 self.config.dialect,
15676 Some(DialectType::DuckDB) | Some(DialectType::Presto) | Some(DialectType::Trino)
15677 ) {
15678 if let Expression::Struct(ref s) = cast.this {
15679 let all_unnamed = s.fields.iter().all(|(name, _)| name.is_none());
15680 if all_unnamed && matches!(cast.to, DataType::Struct { .. }) {
15681 self.write_keyword("CAST");
15682 self.write("(");
15683 self.generate_struct_as_row(s)?;
15684 self.write_space();
15685 self.write_keyword("AS");
15686 self.write_space();
15687 self.generate_data_type(&cast.to)?;
15688 self.write(")");
15689 return Ok(());
15690 }
15691 }
15692 }
15693
15694 let use_double_colon = cast.double_colon_syntax && self.dialect_prefers_double_colon();
15697
15698 if use_double_colon {
15699 self.generate_expression(&cast.this)?;
15701 self.write("::");
15702 self.generate_data_type(&cast.to)?;
15703 } else {
15704 self.write_keyword("CAST");
15706 self.write("(");
15707 self.generate_expression(&cast.this)?;
15708 self.write_space();
15709 self.write_keyword("AS");
15710 self.write_space();
15711 if matches!(
15714 self.config.dialect,
15715 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB)
15716 ) {
15717 match &cast.to {
15718 DataType::Custom { ref name } => {
15719 let upper = name.to_uppercase();
15720 match upper.as_str() {
15721 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" | "LONGBLOB" | "MEDIUMBLOB"
15722 | "TINYBLOB" => {
15723 self.write_keyword("CHAR");
15724 }
15725 _ => {
15726 self.generate_data_type(&cast.to)?;
15727 }
15728 }
15729 }
15730 DataType::VarChar { length, .. } => {
15731 self.write_keyword("CHAR");
15733 if let Some(n) = length {
15734 self.write(&format!("({})", n));
15735 }
15736 }
15737 DataType::Text => {
15738 self.write_keyword("CHAR");
15740 }
15741 DataType::Timestamp {
15742 precision,
15743 timezone: false,
15744 } => {
15745 self.write_keyword("DATETIME");
15747 if let Some(p) = precision {
15748 self.write(&format!("({})", p));
15749 }
15750 }
15751 _ => {
15752 self.generate_data_type(&cast.to)?;
15753 }
15754 }
15755 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
15756 match &cast.to {
15758 DataType::String { length } => {
15759 self.write_keyword("VARCHAR");
15760 if let Some(n) = length {
15761 self.write(&format!("({})", n));
15762 }
15763 }
15764 _ => {
15765 self.generate_data_type(&cast.to)?;
15766 }
15767 }
15768 } else {
15769 self.generate_data_type(&cast.to)?;
15770 }
15771
15772 if let Some(default) = &cast.default {
15774 self.write_space();
15775 self.write_keyword("DEFAULT");
15776 self.write_space();
15777 self.generate_expression(default)?;
15778 self.write_space();
15779 self.write_keyword("ON");
15780 self.write_space();
15781 self.write_keyword("CONVERSION");
15782 self.write_space();
15783 self.write_keyword("ERROR");
15784 }
15785
15786 if let Some(format) = &cast.format {
15789 if matches!(
15791 self.config.dialect,
15792 Some(crate::dialects::DialectType::Oracle)
15793 ) {
15794 self.write(", ");
15795 } else {
15796 self.write_space();
15797 self.write_keyword("FORMAT");
15798 self.write_space();
15799 }
15800 self.generate_expression(format)?;
15801 }
15802
15803 self.write(")");
15804 for comment in &cast.trailing_comments {
15806 self.write_space();
15807 self.write_formatted_comment(comment);
15808 }
15809 }
15810 Ok(())
15811 }
15812
15813 fn generate_struct_as_row(&mut self, s: &crate::expressions::Struct) -> Result<()> {
15816 self.write_keyword("ROW");
15817 self.write("(");
15818 for (i, (_, expr)) in s.fields.iter().enumerate() {
15819 if i > 0 {
15820 self.write(", ");
15821 }
15822 if let Expression::Struct(ref inner_s) = expr {
15824 self.generate_struct_as_row(inner_s)?;
15825 } else {
15826 self.generate_expression(expr)?;
15827 }
15828 }
15829 self.write(")");
15830 Ok(())
15831 }
15832
15833 fn normalize_oracle_format(&self, format: &str) -> String {
15836 let mut result = String::new();
15839 let chars: Vec<char> = format.chars().collect();
15840 let mut i = 0;
15841
15842 while i < chars.len() {
15843 if i + 1 < chars.len() && chars[i] == 'H' && chars[i + 1] == 'H' {
15844 if i + 2 < chars.len() {
15846 let next = chars[i + 2];
15847 if next == '1' || next == '2' {
15848 result.push('H');
15850 result.push('H');
15851 i += 2;
15852 continue;
15853 }
15854 }
15855 result.push_str("HH12");
15857 i += 2;
15858 } else {
15859 result.push(chars[i]);
15860 i += 1;
15861 }
15862 }
15863
15864 result
15865 }
15866
15867 fn dialect_prefers_double_colon(&self) -> bool {
15871 false
15874 }
15875
15876 fn generate_mod_func(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
15878 use crate::dialects::DialectType;
15879
15880 let use_percent_operator = matches!(
15882 self.config.dialect,
15883 Some(DialectType::Snowflake)
15884 | Some(DialectType::MySQL)
15885 | Some(DialectType::Presto)
15886 | Some(DialectType::Trino)
15887 | Some(DialectType::PostgreSQL)
15888 | Some(DialectType::DuckDB)
15889 | Some(DialectType::Hive)
15890 | Some(DialectType::Spark)
15891 | Some(DialectType::Databricks)
15892 | Some(DialectType::Athena)
15893 );
15894
15895 if use_percent_operator {
15896 let needs_paren = |e: &Expression| matches!(e, Expression::Add(_) | Expression::Sub(_));
15899 if needs_paren(&f.this) {
15900 self.write("(");
15901 self.generate_expression(&f.this)?;
15902 self.write(")");
15903 } else {
15904 self.generate_expression(&f.this)?;
15905 }
15906 self.write(" % ");
15907 if needs_paren(&f.expression) {
15908 self.write("(");
15909 self.generate_expression(&f.expression)?;
15910 self.write(")");
15911 } else {
15912 self.generate_expression(&f.expression)?;
15913 }
15914 Ok(())
15915 } else {
15916 self.generate_binary_func("MOD", &f.this, &f.expression)
15917 }
15918 }
15919
15920 fn generate_ifnull(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
15922 use crate::dialects::DialectType;
15923
15924 let func_name = match self.config.dialect {
15926 Some(DialectType::Snowflake) => "COALESCE",
15927 _ => "IFNULL",
15928 };
15929
15930 self.generate_binary_func(func_name, &f.this, &f.expression)
15931 }
15932
15933 fn generate_nvl(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
15935 if let Some(ref original_name) = f.original_name {
15937 return self.generate_binary_func(original_name, &f.this, &f.expression);
15938 }
15939
15940 use crate::dialects::DialectType;
15942 let func_name = match self.config.dialect {
15943 Some(DialectType::Snowflake)
15944 | Some(DialectType::ClickHouse)
15945 | Some(DialectType::PostgreSQL)
15946 | Some(DialectType::Presto)
15947 | Some(DialectType::Trino)
15948 | Some(DialectType::Athena)
15949 | Some(DialectType::DuckDB)
15950 | Some(DialectType::BigQuery)
15951 | Some(DialectType::Spark)
15952 | Some(DialectType::Databricks)
15953 | Some(DialectType::Hive) => "COALESCE",
15954 Some(DialectType::MySQL)
15955 | Some(DialectType::Doris)
15956 | Some(DialectType::StarRocks)
15957 | Some(DialectType::SingleStore)
15958 | Some(DialectType::TiDB) => "IFNULL",
15959 _ => "NVL",
15960 };
15961
15962 self.generate_binary_func(func_name, &f.this, &f.expression)
15963 }
15964
15965 fn generate_stddev_samp(&mut self, f: &crate::expressions::AggFunc) -> Result<()> {
15967 use crate::dialects::DialectType;
15968
15969 let func_name = match self.config.dialect {
15971 Some(DialectType::Snowflake) => "STDDEV",
15972 _ => "STDDEV_SAMP",
15973 };
15974
15975 self.generate_agg_func(func_name, f)
15976 }
15977
15978 fn generate_collation(&mut self, coll: &CollationExpr) -> Result<()> {
15979 self.generate_expression(&coll.this)?;
15980 self.write_space();
15981 self.write_keyword("COLLATE");
15982 self.write_space();
15983 if coll.quoted {
15984 self.write("'");
15986 self.write(&coll.collation);
15987 self.write("'");
15988 } else if coll.double_quoted {
15989 self.write("\"");
15991 self.write(&coll.collation);
15992 self.write("\"");
15993 } else {
15994 self.write(&coll.collation);
15996 }
15997 Ok(())
15998 }
15999
16000 fn generate_case(&mut self, case: &Case) -> Result<()> {
16001 let multiline_case = if self.config.pretty {
16003 let mut statements: Vec<String> = Vec::new();
16005 let operand_str = if let Some(operand) = &case.operand {
16006 let s = self.generate_to_string(operand)?;
16007 statements.push(format!("CASE {}", s));
16008 s
16009 } else {
16010 statements.push("CASE".to_string());
16011 String::new()
16012 };
16013 let _ = operand_str;
16014 for (condition, result) in &case.whens {
16015 statements.push(format!("WHEN {}", self.generate_to_string(condition)?));
16016 statements.push(format!("THEN {}", self.generate_to_string(result)?));
16017 }
16018 if let Some(else_) = &case.else_ {
16019 statements.push(format!("ELSE {}", self.generate_to_string(else_)?));
16020 }
16021 statements.push("END".to_string());
16022 self.too_wide(&statements)
16023 } else {
16024 false
16025 };
16026
16027 self.write_keyword("CASE");
16028 if let Some(operand) = &case.operand {
16029 self.write_space();
16030 self.generate_expression(operand)?;
16031 }
16032 if multiline_case {
16033 self.indent_level += 1;
16034 }
16035 for (condition, result) in &case.whens {
16036 if multiline_case {
16037 self.write_newline();
16038 self.write_indent();
16039 } else {
16040 self.write_space();
16041 }
16042 self.write_keyword("WHEN");
16043 self.write_space();
16044 self.generate_expression(condition)?;
16045 if multiline_case {
16046 self.write_newline();
16047 self.write_indent();
16048 } else {
16049 self.write_space();
16050 }
16051 self.write_keyword("THEN");
16052 self.write_space();
16053 self.generate_expression(result)?;
16054 }
16055 if let Some(else_) = &case.else_ {
16056 if multiline_case {
16057 self.write_newline();
16058 self.write_indent();
16059 } else {
16060 self.write_space();
16061 }
16062 self.write_keyword("ELSE");
16063 self.write_space();
16064 self.generate_expression(else_)?;
16065 }
16066 if multiline_case {
16067 self.indent_level -= 1;
16068 self.write_newline();
16069 self.write_indent();
16070 } else {
16071 self.write_space();
16072 }
16073 self.write_keyword("END");
16074 for comment in &case.comments {
16076 self.write(" ");
16077 self.write_formatted_comment(comment);
16078 }
16079 Ok(())
16080 }
16081
16082 fn generate_function(&mut self, func: &Function) -> Result<()> {
16083 let normalized_name = self.normalize_func_name(&func.name);
16085 let upper_name = func.name.to_uppercase();
16086
16087 if matches!(self.config.dialect, Some(DialectType::DuckDB))
16089 && upper_name == "ARRAY_CONSTRUCT_COMPACT"
16090 {
16091 self.write("LIST_FILTER(");
16092 self.write("[");
16093 for (i, arg) in func.args.iter().enumerate() {
16094 if i > 0 {
16095 self.write(", ");
16096 }
16097 self.generate_expression(arg)?;
16098 }
16099 self.write("], _u -> NOT _u IS NULL)");
16100 return Ok(());
16101 }
16102
16103 if upper_name == "STRUCT"
16105 && !matches!(
16106 self.config.dialect,
16107 Some(DialectType::BigQuery)
16108 | Some(DialectType::Spark)
16109 | Some(DialectType::Databricks)
16110 | Some(DialectType::Hive)
16111 | None
16112 )
16113 {
16114 return self.generate_struct_function_cross_dialect(func);
16115 }
16116
16117 if upper_name == "__SS_JSON_PATH_QMARK__" && func.args.len() == 2 {
16120 self.generate_expression(&func.args[0])?;
16121 self.write("::?");
16122 if let Expression::Literal(crate::expressions::Literal::String(key)) = &func.args[1] {
16124 self.write(key);
16125 } else {
16126 self.generate_expression(&func.args[1])?;
16127 }
16128 return Ok(());
16129 }
16130
16131 if upper_name == "__PG_BITWISE_XOR__" && func.args.len() == 2 {
16133 self.generate_expression(&func.args[0])?;
16134 self.write(" # ");
16135 self.generate_expression(&func.args[1])?;
16136 return Ok(());
16137 }
16138
16139 if matches!(
16141 self.config.dialect,
16142 Some(DialectType::Spark | DialectType::Databricks | DialectType::Hive)
16143 ) && upper_name == "TRY"
16144 && func.args.len() == 1
16145 {
16146 self.generate_expression(&func.args[0])?;
16147 return Ok(());
16148 }
16149
16150 if self.config.dialect == Some(DialectType::ClickHouse)
16152 && upper_name == "TOSTARTOFDAY"
16153 && func.args.len() == 1
16154 {
16155 self.write("dateTrunc('DAY', ");
16156 self.generate_expression(&func.args[0])?;
16157 self.write(")");
16158 return Ok(());
16159 }
16160
16161 if self.config.dialect == Some(DialectType::Redshift)
16163 && upper_name == "CONCAT"
16164 && func.args.len() >= 2
16165 {
16166 for (i, arg) in func.args.iter().enumerate() {
16167 if i > 0 {
16168 self.write(" || ");
16169 }
16170 self.generate_expression(arg)?;
16171 }
16172 return Ok(());
16173 }
16174
16175 if self.config.dialect == Some(DialectType::Redshift)
16177 && upper_name == "CONCAT_WS"
16178 && func.args.len() >= 2
16179 {
16180 let sep = &func.args[0];
16181 for (i, arg) in func.args.iter().skip(1).enumerate() {
16182 if i > 0 {
16183 self.write(" || ");
16184 self.generate_expression(sep)?;
16185 self.write(" || ");
16186 }
16187 self.generate_expression(arg)?;
16188 }
16189 return Ok(());
16190 }
16191
16192 if self.config.dialect == Some(DialectType::Redshift)
16195 && (upper_name == "DATEDIFF" || upper_name == "DATE_DIFF")
16196 && func.args.len() == 3
16197 {
16198 self.write_keyword("DATEDIFF");
16199 self.write("(");
16200 self.write_redshift_date_part(&func.args[0]);
16202 self.write(", ");
16203 self.generate_expression(&func.args[1])?;
16204 self.write(", ");
16205 self.generate_expression(&func.args[2])?;
16206 self.write(")");
16207 return Ok(());
16208 }
16209
16210 if self.config.dialect == Some(DialectType::Redshift)
16213 && (upper_name == "DATEADD" || upper_name == "DATE_ADD")
16214 && func.args.len() == 3
16215 {
16216 self.write_keyword("DATEADD");
16217 self.write("(");
16218 self.write_redshift_date_part(&func.args[0]);
16220 self.write(", ");
16221 self.generate_expression(&func.args[1])?;
16222 self.write(", ");
16223 self.generate_expression(&func.args[2])?;
16224 self.write(")");
16225 return Ok(());
16226 }
16227
16228 if upper_name == "UUID_STRING"
16230 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None)
16231 {
16232 let func_name = match self.config.dialect {
16233 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
16234 Some(DialectType::BigQuery) => "GENERATE_UUID",
16235 _ => "UUID",
16236 };
16237 self.write_keyword(func_name);
16238 self.write("()");
16239 return Ok(());
16240 }
16241
16242 if self.config.dialect == Some(DialectType::Redshift)
16245 && upper_name == "DATE_TRUNC"
16246 && func.args.len() == 2
16247 {
16248 self.write_keyword("DATE_TRUNC");
16249 self.write("(");
16250 self.write_redshift_date_part_quoted(&func.args[0]);
16252 self.write(", ");
16253 self.generate_expression(&func.args[1])?;
16254 self.write(")");
16255 return Ok(());
16256 }
16257
16258 if matches!(
16260 self.config.dialect,
16261 Some(DialectType::TSQL) | Some(DialectType::Fabric)
16262 ) && (upper_name == "DATE_PART" || upper_name == "DATEPART")
16263 && func.args.len() == 2
16264 {
16265 self.write_keyword("DATEPART");
16266 self.write("(");
16267 self.generate_expression(&func.args[0])?;
16268 self.write(", ");
16269 self.generate_expression(&func.args[1])?;
16270 self.write(")");
16271 return Ok(());
16272 }
16273
16274 if matches!(
16276 self.config.dialect,
16277 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
16278 ) && (upper_name == "DATE_PART" || upper_name == "DATEPART")
16279 && func.args.len() == 2
16280 {
16281 self.write_keyword("EXTRACT");
16282 self.write("(");
16283 match &func.args[0] {
16285 Expression::Literal(crate::expressions::Literal::String(s)) => {
16286 self.write(&s.to_lowercase());
16287 }
16288 _ => self.generate_expression(&func.args[0])?,
16289 }
16290 self.write_space();
16291 self.write_keyword("FROM");
16292 self.write_space();
16293 self.generate_expression(&func.args[1])?;
16294 self.write(")");
16295 return Ok(());
16296 }
16297
16298 if self.config.dialect == Some(DialectType::Dremio)
16301 && (upper_name == "DATE_PART" || upper_name == "DATEPART")
16302 && func.args.len() == 2
16303 {
16304 self.write_keyword("EXTRACT");
16305 self.write("(");
16306 self.generate_expression(&func.args[0])?;
16307 self.write_space();
16308 self.write_keyword("FROM");
16309 self.write_space();
16310 self.generate_dremio_date_expression(&func.args[1])?;
16312 self.write(")");
16313 return Ok(());
16314 }
16315
16316 if self.config.dialect == Some(DialectType::Dremio)
16318 && upper_name == "CURRENT_DATE_UTC"
16319 && func.args.is_empty()
16320 {
16321 self.write_keyword("CURRENT_DATE_UTC");
16322 return Ok(());
16323 }
16324
16325 if self.config.dialect == Some(DialectType::Dremio)
16329 && upper_name == "DATETYPE"
16330 && func.args.len() == 3
16331 {
16332 fn get_int_literal(expr: &Expression) -> Option<i64> {
16334 if let Expression::Literal(crate::expressions::Literal::Number(s)) = expr {
16335 s.parse::<i64>().ok()
16336 } else {
16337 None
16338 }
16339 }
16340
16341 if let (Some(year), Some(month), Some(day)) = (
16343 get_int_literal(&func.args[0]),
16344 get_int_literal(&func.args[1]),
16345 get_int_literal(&func.args[2]),
16346 ) {
16347 self.write_keyword("DATE");
16349 self.write(&format!("('{:04}-{:02}-{:02}')", year, month, day));
16350 return Ok(());
16351 }
16352
16353 self.write_keyword("CAST");
16355 self.write("(");
16356 self.write_keyword("CONCAT");
16357 self.write("(");
16358 self.generate_expression(&func.args[0])?;
16359 self.write(", '-', ");
16360 self.generate_expression(&func.args[1])?;
16361 self.write(", '-', ");
16362 self.generate_expression(&func.args[2])?;
16363 self.write(")");
16364 self.write_space();
16365 self.write_keyword("AS");
16366 self.write_space();
16367 self.write_keyword("DATE");
16368 self.write(")");
16369 return Ok(());
16370 }
16371
16372 let is_presto_like = matches!(
16375 self.config.dialect,
16376 Some(DialectType::Presto) | Some(DialectType::Trino)
16377 );
16378 if is_presto_like && upper_name == "DATE_ADD" && func.args.len() == 3 {
16379 self.write_keyword("DATE_ADD");
16380 self.write("(");
16381 self.generate_expression(&func.args[0])?;
16383 self.write(", ");
16384 let interval = &func.args[1];
16386 let needs_cast = !self.returns_integer_type(interval);
16387 if needs_cast {
16388 self.write_keyword("CAST");
16389 self.write("(");
16390 }
16391 self.generate_expression(interval)?;
16392 if needs_cast {
16393 self.write_space();
16394 self.write_keyword("AS");
16395 self.write_space();
16396 self.write_keyword("BIGINT");
16397 self.write(")");
16398 }
16399 self.write(", ");
16400 self.generate_expression(&func.args[2])?;
16402 self.write(")");
16403 return Ok(());
16404 }
16405
16406 let use_brackets = func.use_bracket_syntax;
16408
16409 let has_ordinality = upper_name.ends_with(" WITH ORDINALITY");
16414 let output_name = if has_ordinality {
16415 let base_name = &func.name[..func.name.len() - " WITH ORDINALITY".len()];
16416 self.normalize_func_name(base_name)
16417 } else {
16418 normalized_name.clone()
16419 };
16420
16421 if func.name.contains('.') && !has_ordinality {
16424 if func.quoted {
16427 self.write("`");
16428 self.write(&func.name);
16429 self.write("`");
16430 } else {
16431 self.write(&func.name);
16432 }
16433 } else {
16434 self.write(&output_name);
16435 }
16436
16437 let force_parens = func.no_parens && func.args.is_empty() && !func.distinct && {
16440 let needs_parens = match upper_name.as_str() {
16441 "CURRENT_USER" | "SESSION_USER" | "SYSTEM_USER" => matches!(
16442 self.config.dialect,
16443 Some(DialectType::Snowflake)
16444 | Some(DialectType::Spark)
16445 | Some(DialectType::Databricks)
16446 | Some(DialectType::Hive)
16447 ),
16448 _ => false,
16449 };
16450 !needs_parens
16451 };
16452 if force_parens {
16453 for comment in &func.trailing_comments {
16455 self.write_space();
16456 self.write_formatted_comment(comment);
16457 }
16458 return Ok(());
16459 }
16460
16461 if upper_name == "CUBE" || upper_name == "ROLLUP" || upper_name == "GROUPING SETS" {
16463 self.write(" (");
16464 } else if use_brackets {
16465 self.write("[");
16466 } else {
16467 self.write("(");
16468 }
16469 if func.distinct {
16470 self.write_keyword("DISTINCT");
16471 self.write_space();
16472 }
16473
16474 let compact_pretty_func = matches!(self.config.dialect, Some(DialectType::Snowflake))
16476 && (upper_name == "TABLE" || upper_name == "FLATTEN");
16477 let is_grouping_func =
16479 upper_name == "GROUPING SETS" || upper_name == "CUBE" || upper_name == "ROLLUP";
16480 let should_split = if self.config.pretty && !func.args.is_empty() && !compact_pretty_func {
16481 if is_grouping_func {
16482 true
16483 } else {
16484 let mut expr_strings: Vec<String> = Vec::with_capacity(func.args.len());
16486 for arg in &func.args {
16487 let mut temp_gen = Generator::with_config(self.config.clone());
16488 temp_gen.config.pretty = false; temp_gen.generate_expression(arg)?;
16490 expr_strings.push(temp_gen.output);
16491 }
16492 self.too_wide(&expr_strings)
16493 }
16494 } else {
16495 false
16496 };
16497
16498 if should_split {
16499 self.write_newline();
16501 self.indent_level += 1;
16502 for (i, arg) in func.args.iter().enumerate() {
16503 self.write_indent();
16504 self.generate_expression(arg)?;
16505 if i + 1 < func.args.len() {
16506 self.write(",");
16507 }
16508 self.write_newline();
16509 }
16510 self.indent_level -= 1;
16511 self.write_indent();
16512 } else {
16513 for (i, arg) in func.args.iter().enumerate() {
16515 if i > 0 {
16516 self.write(", ");
16517 }
16518 self.generate_expression(arg)?;
16519 }
16520 }
16521
16522 if use_brackets {
16523 self.write("]");
16524 } else {
16525 self.write(")");
16526 }
16527 if has_ordinality {
16529 self.write_space();
16530 self.write_keyword("WITH ORDINALITY");
16531 }
16532 for comment in &func.trailing_comments {
16534 self.write_space();
16535 self.write_formatted_comment(comment);
16536 }
16537 Ok(())
16538 }
16539
16540 fn generate_aggregate_function(&mut self, func: &AggregateFunction) -> Result<()> {
16541 let mut normalized_name = self.normalize_func_name(&func.name);
16543
16544 let upper = normalized_name.to_uppercase();
16546 if upper == "MAX_BY" || upper == "MIN_BY" {
16547 let is_max = upper == "MAX_BY";
16548 match self.config.dialect {
16549 Some(DialectType::ClickHouse) => {
16550 normalized_name = if is_max {
16551 "argMax".to_string()
16552 } else {
16553 "argMin".to_string()
16554 };
16555 }
16556 Some(DialectType::DuckDB) => {
16557 normalized_name = if is_max {
16558 "ARG_MAX".to_string()
16559 } else {
16560 "ARG_MIN".to_string()
16561 };
16562 }
16563 _ => {}
16564 }
16565 }
16566 self.write(&normalized_name);
16567 self.write("(");
16568 if func.distinct {
16569 self.write_keyword("DISTINCT");
16570 self.write_space();
16571 }
16572
16573 let is_count = normalized_name.eq_ignore_ascii_case("COUNT");
16577 let needs_multi_arg_transform =
16578 func.distinct && is_count && func.args.len() > 1 && !self.config.multi_arg_distinct;
16579
16580 if needs_multi_arg_transform {
16581 self.write_keyword("CASE");
16583 for arg in &func.args {
16584 self.write_space();
16585 self.write_keyword("WHEN");
16586 self.write_space();
16587 self.generate_expression(arg)?;
16588 self.write_space();
16589 self.write_keyword("IS NULL THEN NULL");
16590 }
16591 self.write_space();
16592 self.write_keyword("ELSE");
16593 self.write(" (");
16594 for (i, arg) in func.args.iter().enumerate() {
16595 if i > 0 {
16596 self.write(", ");
16597 }
16598 self.generate_expression(arg)?;
16599 }
16600 self.write(")");
16601 self.write_space();
16602 self.write_keyword("END");
16603 } else {
16604 for (i, arg) in func.args.iter().enumerate() {
16605 if i > 0 {
16606 self.write(", ");
16607 }
16608 self.generate_expression(arg)?;
16609 }
16610 }
16611
16612 if self.config.ignore_nulls_in_func
16614 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
16615 {
16616 if let Some(ignore) = func.ignore_nulls {
16617 self.write_space();
16618 if ignore {
16619 self.write_keyword("IGNORE NULLS");
16620 } else {
16621 self.write_keyword("RESPECT NULLS");
16622 }
16623 }
16624 }
16625
16626 if !func.order_by.is_empty() {
16628 self.write_space();
16629 self.write_keyword("ORDER BY");
16630 self.write_space();
16631 for (i, ord) in func.order_by.iter().enumerate() {
16632 if i > 0 {
16633 self.write(", ");
16634 }
16635 self.generate_ordered(ord)?;
16636 }
16637 }
16638
16639 if let Some(limit) = &func.limit {
16641 self.write_space();
16642 self.write_keyword("LIMIT");
16643 self.write_space();
16644 if let Expression::Tuple(t) = limit.as_ref() {
16646 if t.expressions.len() == 2 {
16647 self.generate_expression(&t.expressions[0])?;
16648 self.write(", ");
16649 self.generate_expression(&t.expressions[1])?;
16650 } else {
16651 self.generate_expression(limit)?;
16652 }
16653 } else {
16654 self.generate_expression(limit)?;
16655 }
16656 }
16657
16658 self.write(")");
16659
16660 if !self.config.ignore_nulls_in_func
16662 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
16663 {
16664 if let Some(ignore) = func.ignore_nulls {
16665 self.write_space();
16666 if ignore {
16667 self.write_keyword("IGNORE NULLS");
16668 } else {
16669 self.write_keyword("RESPECT NULLS");
16670 }
16671 }
16672 }
16673
16674 if let Some(filter) = &func.filter {
16675 self.write_space();
16676 self.write_keyword("FILTER");
16677 self.write("(");
16678 self.write_keyword("WHERE");
16679 self.write_space();
16680 self.generate_expression(filter)?;
16681 self.write(")");
16682 }
16683
16684 Ok(())
16685 }
16686
16687 fn generate_window_function(&mut self, wf: &WindowFunction) -> Result<()> {
16688 self.generate_expression(&wf.this)?;
16689
16690 if let Some(keep) = &wf.keep {
16692 self.write_space();
16693 self.write_keyword("KEEP");
16694 self.write(" (");
16695 self.write_keyword("DENSE_RANK");
16696 self.write_space();
16697 if keep.first {
16698 self.write_keyword("FIRST");
16699 } else {
16700 self.write_keyword("LAST");
16701 }
16702 self.write_space();
16703 self.write_keyword("ORDER BY");
16704 self.write_space();
16705 for (i, ord) in keep.order_by.iter().enumerate() {
16706 if i > 0 {
16707 self.write(", ");
16708 }
16709 self.generate_ordered(ord)?;
16710 }
16711 self.write(")");
16712 }
16713
16714 let has_over = !wf.over.partition_by.is_empty()
16716 || !wf.over.order_by.is_empty()
16717 || wf.over.frame.is_some()
16718 || wf.over.window_name.is_some();
16719
16720 if has_over {
16722 self.write_space();
16723 self.write_keyword("OVER");
16724
16725 let has_specs = !wf.over.partition_by.is_empty()
16727 || !wf.over.order_by.is_empty()
16728 || wf.over.frame.is_some();
16729
16730 if wf.over.window_name.is_some() && !has_specs {
16731 self.write_space();
16733 self.write(&wf.over.window_name.as_ref().unwrap().name);
16734 } else {
16735 self.write(" (");
16737 self.generate_over(&wf.over)?;
16738 self.write(")");
16739 }
16740 } else if wf.keep.is_none() {
16741 self.write_space();
16743 self.write_keyword("OVER");
16744 self.write(" ()");
16745 }
16746
16747 Ok(())
16748 }
16749
16750 fn generate_within_group(&mut self, wg: &WithinGroup) -> Result<()> {
16752 self.generate_expression(&wg.this)?;
16753 self.write_space();
16754 self.write_keyword("WITHIN GROUP");
16755 self.write(" (");
16756 self.write_keyword("ORDER BY");
16757 self.write_space();
16758 for (i, ord) in wg.order_by.iter().enumerate() {
16759 if i > 0 {
16760 self.write(", ");
16761 }
16762 self.generate_ordered(ord)?;
16763 }
16764 self.write(")");
16765 Ok(())
16766 }
16767
16768 fn generate_over(&mut self, over: &Over) -> Result<()> {
16770 let mut has_content = false;
16771
16772 if let Some(name) = &over.window_name {
16774 self.write(&name.name);
16775 has_content = true;
16776 }
16777
16778 if !over.partition_by.is_empty() {
16780 if has_content {
16781 self.write_space();
16782 }
16783 self.write_keyword("PARTITION BY");
16784 self.write_space();
16785 for (i, expr) in over.partition_by.iter().enumerate() {
16786 if i > 0 {
16787 self.write(", ");
16788 }
16789 self.generate_expression(expr)?;
16790 }
16791 has_content = true;
16792 }
16793
16794 if !over.order_by.is_empty() {
16796 if has_content {
16797 self.write_space();
16798 }
16799 self.write_keyword("ORDER BY");
16800 self.write_space();
16801 for (i, ordered) in over.order_by.iter().enumerate() {
16802 if i > 0 {
16803 self.write(", ");
16804 }
16805 self.generate_ordered(ordered)?;
16806 }
16807 has_content = true;
16808 }
16809
16810 if let Some(frame) = &over.frame {
16812 if has_content {
16813 self.write_space();
16814 }
16815 self.generate_window_frame(frame)?;
16816 }
16817
16818 Ok(())
16819 }
16820
16821 fn generate_window_frame(&mut self, frame: &WindowFrame) -> Result<()> {
16822 let lowercase_frame = self.config.lowercase_window_frame_keywords;
16824
16825 if !lowercase_frame {
16827 if let Some(kind_text) = &frame.kind_text {
16828 self.write(kind_text);
16829 } else {
16830 match frame.kind {
16831 WindowFrameKind::Rows => self.write_keyword("ROWS"),
16832 WindowFrameKind::Range => self.write_keyword("RANGE"),
16833 WindowFrameKind::Groups => self.write_keyword("GROUPS"),
16834 }
16835 }
16836 } else {
16837 match frame.kind {
16838 WindowFrameKind::Rows => self.write("rows"),
16839 WindowFrameKind::Range => self.write("range"),
16840 WindowFrameKind::Groups => self.write("groups"),
16841 }
16842 }
16843
16844 self.write_space();
16847 let should_normalize = self.config.normalize_window_frame_between
16848 && frame.end.is_none()
16849 && matches!(
16850 frame.start,
16851 WindowFrameBound::Preceding(_)
16852 | WindowFrameBound::Following(_)
16853 | WindowFrameBound::UnboundedPreceding
16854 | WindowFrameBound::UnboundedFollowing
16855 );
16856
16857 if let Some(end) = &frame.end {
16858 self.write_keyword("BETWEEN");
16860 self.write_space();
16861 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
16862 self.write_space();
16863 self.write_keyword("AND");
16864 self.write_space();
16865 self.generate_window_frame_bound(end, frame.end_side_text.as_deref())?;
16866 } else if should_normalize {
16867 self.write_keyword("BETWEEN");
16869 self.write_space();
16870 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
16871 self.write_space();
16872 self.write_keyword("AND");
16873 self.write_space();
16874 self.write_keyword("CURRENT ROW");
16875 } else {
16876 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
16878 }
16879
16880 if let Some(exclude) = &frame.exclude {
16882 self.write_space();
16883 self.write_keyword("EXCLUDE");
16884 self.write_space();
16885 match exclude {
16886 WindowFrameExclude::CurrentRow => self.write_keyword("CURRENT ROW"),
16887 WindowFrameExclude::Group => self.write_keyword("GROUP"),
16888 WindowFrameExclude::Ties => self.write_keyword("TIES"),
16889 WindowFrameExclude::NoOthers => self.write_keyword("NO OTHERS"),
16890 }
16891 }
16892
16893 Ok(())
16894 }
16895
16896 fn generate_window_frame_bound(
16897 &mut self,
16898 bound: &WindowFrameBound,
16899 side_text: Option<&str>,
16900 ) -> Result<()> {
16901 let lowercase_frame = self.config.lowercase_window_frame_keywords;
16903
16904 match bound {
16905 WindowFrameBound::CurrentRow => {
16906 self.write_keyword("CURRENT ROW");
16907 }
16908 WindowFrameBound::UnboundedPreceding => {
16909 self.write_keyword("UNBOUNDED");
16910 self.write_space();
16911 if lowercase_frame {
16912 self.write("preceding");
16913 } else if let Some(text) = side_text {
16914 self.write(text);
16915 } else {
16916 self.write_keyword("PRECEDING");
16917 }
16918 }
16919 WindowFrameBound::UnboundedFollowing => {
16920 self.write_keyword("UNBOUNDED");
16921 self.write_space();
16922 if lowercase_frame {
16923 self.write("following");
16924 } else if let Some(text) = side_text {
16925 self.write(text);
16926 } else {
16927 self.write_keyword("FOLLOWING");
16928 }
16929 }
16930 WindowFrameBound::Preceding(expr) => {
16931 self.generate_expression(expr)?;
16932 self.write_space();
16933 if lowercase_frame {
16934 self.write("preceding");
16935 } else if let Some(text) = side_text {
16936 self.write(text);
16937 } else {
16938 self.write_keyword("PRECEDING");
16939 }
16940 }
16941 WindowFrameBound::Following(expr) => {
16942 self.generate_expression(expr)?;
16943 self.write_space();
16944 if lowercase_frame {
16945 self.write("following");
16946 } else if let Some(text) = side_text {
16947 self.write(text);
16948 } else {
16949 self.write_keyword("FOLLOWING");
16950 }
16951 }
16952 WindowFrameBound::BarePreceding => {
16953 if lowercase_frame {
16954 self.write("preceding");
16955 } else if let Some(text) = side_text {
16956 self.write(text);
16957 } else {
16958 self.write_keyword("PRECEDING");
16959 }
16960 }
16961 WindowFrameBound::BareFollowing => {
16962 if lowercase_frame {
16963 self.write("following");
16964 } else if let Some(text) = side_text {
16965 self.write(text);
16966 } else {
16967 self.write_keyword("FOLLOWING");
16968 }
16969 }
16970 WindowFrameBound::Value(expr) => {
16971 self.generate_expression(expr)?;
16973 }
16974 }
16975 Ok(())
16976 }
16977
16978 fn generate_interval(&mut self, interval: &Interval) -> Result<()> {
16979 let skip_interval_keyword = matches!(self.config.dialect, Some(DialectType::Oracle))
16982 && matches!(&interval.unit, Some(IntervalUnitSpec::ExprSpan(_)))
16983 && !matches!(&interval.this, Some(Expression::Literal(_)));
16984
16985 if self.config.single_string_interval {
16988 if let (
16989 Some(Expression::Literal(Literal::String(ref val))),
16990 Some(IntervalUnitSpec::Simple {
16991 ref unit,
16992 ref use_plural,
16993 }),
16994 ) = (&interval.this, &interval.unit)
16995 {
16996 self.write_keyword("INTERVAL");
16997 self.write_space();
16998 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
16999 let unit_str = self.interval_unit_str(unit, effective_plural);
17000 self.write("'");
17001 self.write(val);
17002 self.write(" ");
17003 self.write(&unit_str);
17004 self.write("'");
17005 return Ok(());
17006 }
17007 }
17008
17009 if !skip_interval_keyword {
17010 self.write_keyword("INTERVAL");
17011 }
17012
17013 if let Some(ref value) = interval.this {
17015 if !skip_interval_keyword {
17016 self.write_space();
17017 }
17018 let needs_parens = interval.unit.is_some()
17022 && matches!(
17023 value,
17024 Expression::Add(_)
17025 | Expression::Sub(_)
17026 | Expression::Mul(_)
17027 | Expression::Div(_)
17028 | Expression::Mod(_)
17029 | Expression::BitwiseAnd(_)
17030 | Expression::BitwiseOr(_)
17031 | Expression::BitwiseXor(_)
17032 );
17033 if needs_parens {
17034 self.write("(");
17035 }
17036 self.generate_expression(value)?;
17037 if needs_parens {
17038 self.write(")");
17039 }
17040 }
17041
17042 if let Some(ref unit_spec) = interval.unit {
17044 self.write_space();
17045 self.write_interval_unit_spec(unit_spec)?;
17046 }
17047
17048 Ok(())
17049 }
17050
17051 fn interval_unit_str(&self, unit: &IntervalUnit, use_plural: bool) -> &'static str {
17053 match (unit, use_plural) {
17054 (IntervalUnit::Year, false) => "YEAR",
17055 (IntervalUnit::Year, true) => "YEARS",
17056 (IntervalUnit::Quarter, false) => "QUARTER",
17057 (IntervalUnit::Quarter, true) => "QUARTERS",
17058 (IntervalUnit::Month, false) => "MONTH",
17059 (IntervalUnit::Month, true) => "MONTHS",
17060 (IntervalUnit::Week, false) => "WEEK",
17061 (IntervalUnit::Week, true) => "WEEKS",
17062 (IntervalUnit::Day, false) => "DAY",
17063 (IntervalUnit::Day, true) => "DAYS",
17064 (IntervalUnit::Hour, false) => "HOUR",
17065 (IntervalUnit::Hour, true) => "HOURS",
17066 (IntervalUnit::Minute, false) => "MINUTE",
17067 (IntervalUnit::Minute, true) => "MINUTES",
17068 (IntervalUnit::Second, false) => "SECOND",
17069 (IntervalUnit::Second, true) => "SECONDS",
17070 (IntervalUnit::Millisecond, false) => "MILLISECOND",
17071 (IntervalUnit::Millisecond, true) => "MILLISECONDS",
17072 (IntervalUnit::Microsecond, false) => "MICROSECOND",
17073 (IntervalUnit::Microsecond, true) => "MICROSECONDS",
17074 (IntervalUnit::Nanosecond, false) => "NANOSECOND",
17075 (IntervalUnit::Nanosecond, true) => "NANOSECONDS",
17076 }
17077 }
17078
17079 fn write_interval_unit_spec(&mut self, unit_spec: &IntervalUnitSpec) -> Result<()> {
17080 match unit_spec {
17081 IntervalUnitSpec::Simple { unit, use_plural } => {
17082 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
17084 self.write_simple_interval_unit(unit, effective_plural);
17085 }
17086 IntervalUnitSpec::Span(span) => {
17087 self.write_simple_interval_unit(&span.this, false);
17088 self.write_space();
17089 self.write_keyword("TO");
17090 self.write_space();
17091 self.write_simple_interval_unit(&span.expression, false);
17092 }
17093 IntervalUnitSpec::ExprSpan(span) => {
17094 self.generate_expression(&span.this)?;
17096 self.write_space();
17097 self.write_keyword("TO");
17098 self.write_space();
17099 self.generate_expression(&span.expression)?;
17100 }
17101 IntervalUnitSpec::Expr(expr) => {
17102 self.generate_expression(expr)?;
17103 }
17104 }
17105 Ok(())
17106 }
17107
17108 fn write_simple_interval_unit(&mut self, unit: &IntervalUnit, use_plural: bool) {
17109 match (unit, use_plural) {
17111 (IntervalUnit::Year, false) => self.write_keyword("YEAR"),
17112 (IntervalUnit::Year, true) => self.write_keyword("YEARS"),
17113 (IntervalUnit::Quarter, false) => self.write_keyword("QUARTER"),
17114 (IntervalUnit::Quarter, true) => self.write_keyword("QUARTERS"),
17115 (IntervalUnit::Month, false) => self.write_keyword("MONTH"),
17116 (IntervalUnit::Month, true) => self.write_keyword("MONTHS"),
17117 (IntervalUnit::Week, false) => self.write_keyword("WEEK"),
17118 (IntervalUnit::Week, true) => self.write_keyword("WEEKS"),
17119 (IntervalUnit::Day, false) => self.write_keyword("DAY"),
17120 (IntervalUnit::Day, true) => self.write_keyword("DAYS"),
17121 (IntervalUnit::Hour, false) => self.write_keyword("HOUR"),
17122 (IntervalUnit::Hour, true) => self.write_keyword("HOURS"),
17123 (IntervalUnit::Minute, false) => self.write_keyword("MINUTE"),
17124 (IntervalUnit::Minute, true) => self.write_keyword("MINUTES"),
17125 (IntervalUnit::Second, false) => self.write_keyword("SECOND"),
17126 (IntervalUnit::Second, true) => self.write_keyword("SECONDS"),
17127 (IntervalUnit::Millisecond, false) => self.write_keyword("MILLISECOND"),
17128 (IntervalUnit::Millisecond, true) => self.write_keyword("MILLISECONDS"),
17129 (IntervalUnit::Microsecond, false) => self.write_keyword("MICROSECOND"),
17130 (IntervalUnit::Microsecond, true) => self.write_keyword("MICROSECONDS"),
17131 (IntervalUnit::Nanosecond, false) => self.write_keyword("NANOSECOND"),
17132 (IntervalUnit::Nanosecond, true) => self.write_keyword("NANOSECONDS"),
17133 }
17134 }
17135
17136 fn write_redshift_date_part(&mut self, expr: &Expression) {
17139 let part_str = self.extract_date_part_string(expr);
17140 if let Some(part) = part_str {
17141 let normalized = self.normalize_date_part(&part);
17142 self.write_keyword(&normalized);
17143 } else {
17144 let _ = self.generate_expression(expr);
17146 }
17147 }
17148
17149 fn write_redshift_date_part_quoted(&mut self, expr: &Expression) {
17152 let part_str = self.extract_date_part_string(expr);
17153 if let Some(part) = part_str {
17154 let normalized = self.normalize_date_part(&part);
17155 self.write("'");
17156 self.write(&normalized);
17157 self.write("'");
17158 } else {
17159 let _ = self.generate_expression(expr);
17161 }
17162 }
17163
17164 fn extract_date_part_string(&self, expr: &Expression) -> Option<String> {
17166 match expr {
17167 Expression::Literal(crate::expressions::Literal::String(s)) => Some(s.clone()),
17168 Expression::Identifier(id) => Some(id.name.clone()),
17169 Expression::Column(col) if col.table.is_none() => {
17170 Some(col.name.name.clone())
17172 }
17173 _ => None,
17174 }
17175 }
17176
17177 fn normalize_date_part(&self, part: &str) -> String {
17180 let lower = part.to_lowercase();
17181 match lower.as_str() {
17182 "day" | "days" | "d" => "DAY".to_string(),
17183 "month" | "months" | "mon" | "mm" => "MONTH".to_string(),
17184 "year" | "years" | "y" | "yy" | "yyyy" => "YEAR".to_string(),
17185 "week" | "weeks" | "w" | "wk" => "WEEK".to_string(),
17186 "hour" | "hours" | "h" | "hh" => "HOUR".to_string(),
17187 "minute" | "minutes" | "m" | "mi" | "n" => "MINUTE".to_string(),
17188 "second" | "seconds" | "s" | "ss" => "SECOND".to_string(),
17189 "millisecond" | "milliseconds" | "ms" => "MILLISECOND".to_string(),
17190 "microsecond" | "microseconds" | "us" => "MICROSECOND".to_string(),
17191 "quarter" | "quarters" | "q" | "qq" => "QUARTER".to_string(),
17192 _ => part.to_uppercase(),
17193 }
17194 }
17195
17196 fn write_datetime_field(&mut self, field: &DateTimeField) {
17197 match field {
17198 DateTimeField::Year => self.write_keyword("YEAR"),
17199 DateTimeField::Month => self.write_keyword("MONTH"),
17200 DateTimeField::Day => self.write_keyword("DAY"),
17201 DateTimeField::Hour => self.write_keyword("HOUR"),
17202 DateTimeField::Minute => self.write_keyword("MINUTE"),
17203 DateTimeField::Second => self.write_keyword("SECOND"),
17204 DateTimeField::Millisecond => self.write_keyword("MILLISECOND"),
17205 DateTimeField::Microsecond => self.write_keyword("MICROSECOND"),
17206 DateTimeField::DayOfWeek => {
17207 let name = match self.config.dialect {
17208 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFWEEK",
17209 _ => "DOW",
17210 };
17211 self.write_keyword(name);
17212 }
17213 DateTimeField::DayOfYear => {
17214 let name = match self.config.dialect {
17215 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFYEAR",
17216 _ => "DOY",
17217 };
17218 self.write_keyword(name);
17219 }
17220 DateTimeField::Week => self.write_keyword("WEEK"),
17221 DateTimeField::WeekWithModifier(modifier) => {
17222 self.write_keyword("WEEK");
17223 self.write("(");
17224 self.write(modifier);
17225 self.write(")");
17226 }
17227 DateTimeField::Quarter => self.write_keyword("QUARTER"),
17228 DateTimeField::Epoch => self.write_keyword("EPOCH"),
17229 DateTimeField::Timezone => self.write_keyword("TIMEZONE"),
17230 DateTimeField::TimezoneHour => self.write_keyword("TIMEZONE_HOUR"),
17231 DateTimeField::TimezoneMinute => self.write_keyword("TIMEZONE_MINUTE"),
17232 DateTimeField::Date => self.write_keyword("DATE"),
17233 DateTimeField::Time => self.write_keyword("TIME"),
17234 DateTimeField::Custom(name) => self.write(name),
17235 }
17236 }
17237
17238 fn write_datetime_field_lower(&mut self, field: &DateTimeField) {
17240 match field {
17241 DateTimeField::Year => self.write("year"),
17242 DateTimeField::Month => self.write("month"),
17243 DateTimeField::Day => self.write("day"),
17244 DateTimeField::Hour => self.write("hour"),
17245 DateTimeField::Minute => self.write("minute"),
17246 DateTimeField::Second => self.write("second"),
17247 DateTimeField::Millisecond => self.write("millisecond"),
17248 DateTimeField::Microsecond => self.write("microsecond"),
17249 DateTimeField::DayOfWeek => self.write("dow"),
17250 DateTimeField::DayOfYear => self.write("doy"),
17251 DateTimeField::Week => self.write("week"),
17252 DateTimeField::WeekWithModifier(modifier) => {
17253 self.write("week(");
17254 self.write(modifier);
17255 self.write(")");
17256 }
17257 DateTimeField::Quarter => self.write("quarter"),
17258 DateTimeField::Epoch => self.write("epoch"),
17259 DateTimeField::Timezone => self.write("timezone"),
17260 DateTimeField::TimezoneHour => self.write("timezone_hour"),
17261 DateTimeField::TimezoneMinute => self.write("timezone_minute"),
17262 DateTimeField::Date => self.write("date"),
17263 DateTimeField::Time => self.write("time"),
17264 DateTimeField::Custom(name) => self.write(name),
17265 }
17266 }
17267
17268 fn generate_simple_func(&mut self, name: &str, arg: &Expression) -> Result<()> {
17271 self.write_keyword(name);
17272 self.write("(");
17273 self.generate_expression(arg)?;
17274 self.write(")");
17275 Ok(())
17276 }
17277
17278 fn generate_unary_func(
17280 &mut self,
17281 default_name: &str,
17282 f: &crate::expressions::UnaryFunc,
17283 ) -> Result<()> {
17284 let name = f.original_name.as_deref().unwrap_or(default_name);
17285 self.write_keyword(name);
17286 self.write("(");
17287 self.generate_expression(&f.this)?;
17288 self.write(")");
17289 Ok(())
17290 }
17291
17292 fn generate_sqrt_cbrt(
17294 &mut self,
17295 f: &crate::expressions::UnaryFunc,
17296 func_name: &str,
17297 _op: &str,
17298 ) -> Result<()> {
17299 self.write_keyword(func_name);
17302 self.write("(");
17303 self.generate_expression(&f.this)?;
17304 self.write(")");
17305 Ok(())
17306 }
17307
17308 fn generate_binary_func(
17309 &mut self,
17310 name: &str,
17311 arg1: &Expression,
17312 arg2: &Expression,
17313 ) -> Result<()> {
17314 self.write_keyword(name);
17315 self.write("(");
17316 self.generate_expression(arg1)?;
17317 self.write(", ");
17318 self.generate_expression(arg2)?;
17319 self.write(")");
17320 Ok(())
17321 }
17322
17323 fn generate_char_func(&mut self, f: &crate::expressions::CharFunc) -> Result<()> {
17327 let func_name = f.name.as_deref().unwrap_or("CHAR");
17329 self.write_keyword(func_name);
17330 self.write("(");
17331 for (i, arg) in f.args.iter().enumerate() {
17332 if i > 0 {
17333 self.write(", ");
17334 }
17335 self.generate_expression(arg)?;
17336 }
17337 if let Some(ref charset) = f.charset {
17338 self.write(" ");
17339 self.write_keyword("USING");
17340 self.write(" ");
17341 self.write(charset);
17342 }
17343 self.write(")");
17344 Ok(())
17345 }
17346
17347 fn generate_power(&mut self, f: &BinaryFunc) -> Result<()> {
17348 use crate::dialects::DialectType;
17349
17350 match self.config.dialect {
17351 Some(DialectType::Teradata) => {
17352 self.generate_expression(&f.this)?;
17354 self.write(" ** ");
17355 self.generate_expression(&f.expression)?;
17356 Ok(())
17357 }
17358 _ => {
17359 self.generate_binary_func("POWER", &f.this, &f.expression)
17361 }
17362 }
17363 }
17364
17365 fn generate_vararg_func(&mut self, name: &str, args: &[Expression]) -> Result<()> {
17366 self.write_func_name(name);
17367 self.write("(");
17368 for (i, arg) in args.iter().enumerate() {
17369 if i > 0 {
17370 self.write(", ");
17371 }
17372 self.generate_expression(arg)?;
17373 }
17374 self.write(")");
17375 Ok(())
17376 }
17377
17378 fn generate_concat_ws(&mut self, f: &ConcatWs) -> Result<()> {
17381 self.write_keyword("CONCAT_WS");
17382 self.write("(");
17383 self.generate_expression(&f.separator)?;
17384 for expr in &f.expressions {
17385 self.write(", ");
17386 self.generate_expression(expr)?;
17387 }
17388 self.write(")");
17389 Ok(())
17390 }
17391
17392 fn collect_concat_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
17393 if let Expression::Concat(op) = expr {
17394 Self::collect_concat_operands(&op.left, out);
17395 Self::collect_concat_operands(&op.right, out);
17396 } else {
17397 out.push(expr);
17398 }
17399 }
17400
17401 fn generate_mysql_concat_from_concat(&mut self, op: &BinaryOp) -> Result<()> {
17402 let mut operands = Vec::new();
17403 Self::collect_concat_operands(&op.left, &mut operands);
17404 Self::collect_concat_operands(&op.right, &mut operands);
17405
17406 self.write_keyword("CONCAT");
17407 self.write("(");
17408 for (i, operand) in operands.iter().enumerate() {
17409 if i > 0 {
17410 self.write(", ");
17411 }
17412 self.generate_expression(operand)?;
17413 }
17414 self.write(")");
17415 Ok(())
17416 }
17417
17418 fn collect_dpipe_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
17419 if let Expression::DPipe(dpipe) = expr {
17420 Self::collect_dpipe_operands(&dpipe.this, out);
17421 Self::collect_dpipe_operands(&dpipe.expression, out);
17422 } else {
17423 out.push(expr);
17424 }
17425 }
17426
17427 fn generate_mysql_concat_from_dpipe(&mut self, e: &DPipe) -> Result<()> {
17428 let mut operands = Vec::new();
17429 Self::collect_dpipe_operands(&e.this, &mut operands);
17430 Self::collect_dpipe_operands(&e.expression, &mut operands);
17431
17432 self.write_keyword("CONCAT");
17433 self.write("(");
17434 for (i, operand) in operands.iter().enumerate() {
17435 if i > 0 {
17436 self.write(", ");
17437 }
17438 self.generate_expression(operand)?;
17439 }
17440 self.write(")");
17441 Ok(())
17442 }
17443
17444 fn generate_substring(&mut self, f: &SubstringFunc) -> Result<()> {
17445 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
17447 if is_oracle {
17448 self.write_keyword("SUBSTR");
17449 } else {
17450 self.write_keyword("SUBSTRING");
17451 }
17452 self.write("(");
17453 self.generate_expression(&f.this)?;
17454 let force_from_for = matches!(self.config.dialect, Some(DialectType::PostgreSQL));
17456 let use_comma_syntax = matches!(
17458 self.config.dialect,
17459 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
17460 );
17461 if (f.from_for_syntax || force_from_for) && !use_comma_syntax {
17462 self.write_space();
17464 self.write_keyword("FROM");
17465 self.write_space();
17466 self.generate_expression(&f.start)?;
17467 if let Some(length) = &f.length {
17468 self.write_space();
17469 self.write_keyword("FOR");
17470 self.write_space();
17471 self.generate_expression(length)?;
17472 }
17473 } else {
17474 self.write(", ");
17476 self.generate_expression(&f.start)?;
17477 if let Some(length) = &f.length {
17478 self.write(", ");
17479 self.generate_expression(length)?;
17480 }
17481 }
17482 self.write(")");
17483 Ok(())
17484 }
17485
17486 fn generate_overlay(&mut self, f: &OverlayFunc) -> Result<()> {
17487 self.write_keyword("OVERLAY");
17488 self.write("(");
17489 self.generate_expression(&f.this)?;
17490 self.write_space();
17491 self.write_keyword("PLACING");
17492 self.write_space();
17493 self.generate_expression(&f.replacement)?;
17494 self.write_space();
17495 self.write_keyword("FROM");
17496 self.write_space();
17497 self.generate_expression(&f.from)?;
17498 if let Some(length) = &f.length {
17499 self.write_space();
17500 self.write_keyword("FOR");
17501 self.write_space();
17502 self.generate_expression(length)?;
17503 }
17504 self.write(")");
17505 Ok(())
17506 }
17507
17508 fn generate_trim(&mut self, f: &TrimFunc) -> Result<()> {
17509 if f.position_explicit && f.characters.is_none() {
17512 match f.position {
17513 TrimPosition::Leading => {
17514 self.write_keyword("LTRIM");
17515 self.write("(");
17516 self.generate_expression(&f.this)?;
17517 self.write(")");
17518 return Ok(());
17519 }
17520 TrimPosition::Trailing => {
17521 self.write_keyword("RTRIM");
17522 self.write("(");
17523 self.generate_expression(&f.this)?;
17524 self.write(")");
17525 return Ok(());
17526 }
17527 TrimPosition::Both => {
17528 }
17531 }
17532 }
17533
17534 self.write_keyword("TRIM");
17535 self.write("(");
17536 let force_standard = f.characters.is_some()
17539 && !f.sql_standard_syntax
17540 && matches!(
17541 self.config.dialect,
17542 Some(DialectType::Hive)
17543 | Some(DialectType::Spark)
17544 | Some(DialectType::Databricks)
17545 | Some(DialectType::ClickHouse)
17546 );
17547 let use_standard = (f.sql_standard_syntax || force_standard)
17548 && !(f.position_explicit
17549 && f.characters.is_none()
17550 && matches!(f.position, TrimPosition::Both));
17551 if use_standard {
17552 if f.position_explicit {
17555 match f.position {
17556 TrimPosition::Both => self.write_keyword("BOTH"),
17557 TrimPosition::Leading => self.write_keyword("LEADING"),
17558 TrimPosition::Trailing => self.write_keyword("TRAILING"),
17559 }
17560 self.write_space();
17561 }
17562 if let Some(chars) = &f.characters {
17563 self.generate_expression(chars)?;
17564 self.write_space();
17565 }
17566 self.write_keyword("FROM");
17567 self.write_space();
17568 self.generate_expression(&f.this)?;
17569 } else {
17570 self.generate_expression(&f.this)?;
17572 if let Some(chars) = &f.characters {
17573 self.write(", ");
17574 self.generate_expression(chars)?;
17575 }
17576 }
17577 self.write(")");
17578 Ok(())
17579 }
17580
17581 fn generate_replace(&mut self, f: &ReplaceFunc) -> Result<()> {
17582 self.write_keyword("REPLACE");
17583 self.write("(");
17584 self.generate_expression(&f.this)?;
17585 self.write(", ");
17586 self.generate_expression(&f.old)?;
17587 self.write(", ");
17588 self.generate_expression(&f.new)?;
17589 self.write(")");
17590 Ok(())
17591 }
17592
17593 fn generate_left_right(&mut self, name: &str, f: &LeftRightFunc) -> Result<()> {
17594 self.write_keyword(name);
17595 self.write("(");
17596 self.generate_expression(&f.this)?;
17597 self.write(", ");
17598 self.generate_expression(&f.length)?;
17599 self.write(")");
17600 Ok(())
17601 }
17602
17603 fn generate_repeat(&mut self, f: &RepeatFunc) -> Result<()> {
17604 self.write_keyword("REPEAT");
17605 self.write("(");
17606 self.generate_expression(&f.this)?;
17607 self.write(", ");
17608 self.generate_expression(&f.times)?;
17609 self.write(")");
17610 Ok(())
17611 }
17612
17613 fn generate_pad(&mut self, name: &str, f: &PadFunc) -> Result<()> {
17614 self.write_keyword(name);
17615 self.write("(");
17616 self.generate_expression(&f.this)?;
17617 self.write(", ");
17618 self.generate_expression(&f.length)?;
17619 if let Some(fill) = &f.fill {
17620 self.write(", ");
17621 self.generate_expression(fill)?;
17622 }
17623 self.write(")");
17624 Ok(())
17625 }
17626
17627 fn generate_split(&mut self, f: &SplitFunc) -> Result<()> {
17628 self.write_keyword("SPLIT");
17629 self.write("(");
17630 self.generate_expression(&f.this)?;
17631 self.write(", ");
17632 self.generate_expression(&f.delimiter)?;
17633 self.write(")");
17634 Ok(())
17635 }
17636
17637 fn generate_regexp_like(&mut self, f: &RegexpFunc) -> Result<()> {
17638 use crate::dialects::DialectType;
17639 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) && f.flags.is_none() {
17641 self.generate_expression(&f.this)?;
17642 self.write(" ~ ");
17643 self.generate_expression(&f.pattern)?;
17644 } else if matches!(
17645 self.config.dialect,
17646 Some(DialectType::SingleStore)
17647 | Some(DialectType::Spark)
17648 | Some(DialectType::Hive)
17649 | Some(DialectType::Databricks)
17650 ) && f.flags.is_none()
17651 {
17652 self.generate_expression(&f.this)?;
17654 self.write_keyword(" RLIKE ");
17655 self.generate_expression(&f.pattern)?;
17656 } else if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
17657 self.write_keyword("REGEXP");
17659 self.write("(");
17660 self.generate_expression(&f.this)?;
17661 self.write(", ");
17662 self.generate_expression(&f.pattern)?;
17663 if let Some(flags) = &f.flags {
17664 self.write(", ");
17665 self.generate_expression(flags)?;
17666 }
17667 self.write(")");
17668 } else {
17669 self.write_keyword("REGEXP_LIKE");
17670 self.write("(");
17671 self.generate_expression(&f.this)?;
17672 self.write(", ");
17673 self.generate_expression(&f.pattern)?;
17674 if let Some(flags) = &f.flags {
17675 self.write(", ");
17676 self.generate_expression(flags)?;
17677 }
17678 self.write(")");
17679 }
17680 Ok(())
17681 }
17682
17683 fn generate_regexp_replace(&mut self, f: &RegexpReplaceFunc) -> Result<()> {
17684 self.write_keyword("REGEXP_REPLACE");
17685 self.write("(");
17686 self.generate_expression(&f.this)?;
17687 self.write(", ");
17688 self.generate_expression(&f.pattern)?;
17689 self.write(", ");
17690 self.generate_expression(&f.replacement)?;
17691 if let Some(flags) = &f.flags {
17692 self.write(", ");
17693 self.generate_expression(flags)?;
17694 }
17695 self.write(")");
17696 Ok(())
17697 }
17698
17699 fn generate_regexp_extract(&mut self, f: &RegexpExtractFunc) -> Result<()> {
17700 self.write_keyword("REGEXP_EXTRACT");
17701 self.write("(");
17702 self.generate_expression(&f.this)?;
17703 self.write(", ");
17704 self.generate_expression(&f.pattern)?;
17705 if let Some(group) = &f.group {
17706 self.write(", ");
17707 self.generate_expression(group)?;
17708 }
17709 self.write(")");
17710 Ok(())
17711 }
17712
17713 fn generate_round(&mut self, f: &RoundFunc) -> Result<()> {
17716 self.write_keyword("ROUND");
17717 self.write("(");
17718 self.generate_expression(&f.this)?;
17719 if let Some(decimals) = &f.decimals {
17720 self.write(", ");
17721 self.generate_expression(decimals)?;
17722 }
17723 self.write(")");
17724 Ok(())
17725 }
17726
17727 fn generate_floor(&mut self, f: &FloorFunc) -> Result<()> {
17728 self.write_keyword("FLOOR");
17729 self.write("(");
17730 self.generate_expression(&f.this)?;
17731 if let Some(to) = &f.to {
17733 self.write(" ");
17734 self.write_keyword("TO");
17735 self.write(" ");
17736 self.generate_expression(to)?;
17737 } else if let Some(scale) = &f.scale {
17738 self.write(", ");
17739 self.generate_expression(scale)?;
17740 }
17741 self.write(")");
17742 Ok(())
17743 }
17744
17745 fn generate_ceil(&mut self, f: &CeilFunc) -> Result<()> {
17746 self.write_keyword("CEIL");
17747 self.write("(");
17748 self.generate_expression(&f.this)?;
17749 if let Some(to) = &f.to {
17751 self.write(" ");
17752 self.write_keyword("TO");
17753 self.write(" ");
17754 self.generate_expression(to)?;
17755 } else if let Some(decimals) = &f.decimals {
17756 self.write(", ");
17757 self.generate_expression(decimals)?;
17758 }
17759 self.write(")");
17760 Ok(())
17761 }
17762
17763 fn generate_log(&mut self, f: &LogFunc) -> Result<()> {
17764 use crate::expressions::Literal;
17765
17766 if let Some(base) = &f.base {
17767 if self.is_log_base_none() {
17770 if matches!(base, Expression::Literal(Literal::Number(s)) if s == "2") {
17771 self.write_func_name("LOG2");
17772 self.write("(");
17773 self.generate_expression(&f.this)?;
17774 self.write(")");
17775 return Ok(());
17776 } else if matches!(base, Expression::Literal(Literal::Number(s)) if s == "10") {
17777 self.write_func_name("LOG10");
17778 self.write("(");
17779 self.generate_expression(&f.this)?;
17780 self.write(")");
17781 return Ok(());
17782 }
17783 }
17785
17786 self.write_func_name("LOG");
17787 self.write("(");
17788 if self.is_log_value_first() {
17789 self.generate_expression(&f.this)?;
17791 self.write(", ");
17792 self.generate_expression(base)?;
17793 } else {
17794 self.generate_expression(base)?;
17796 self.write(", ");
17797 self.generate_expression(&f.this)?;
17798 }
17799 self.write(")");
17800 } else {
17801 self.write_func_name("LOG");
17803 self.write("(");
17804 self.generate_expression(&f.this)?;
17805 self.write(")");
17806 }
17807 Ok(())
17808 }
17809
17810 fn is_log_value_first(&self) -> bool {
17813 use crate::dialects::DialectType;
17814 matches!(
17815 self.config.dialect,
17816 Some(DialectType::BigQuery)
17817 | Some(DialectType::TSQL)
17818 | Some(DialectType::Tableau)
17819 | Some(DialectType::Fabric)
17820 )
17821 }
17822
17823 fn is_log_base_none(&self) -> bool {
17826 use crate::dialects::DialectType;
17827 matches!(
17828 self.config.dialect,
17829 Some(DialectType::Presto)
17830 | Some(DialectType::Trino)
17831 | Some(DialectType::ClickHouse)
17832 | Some(DialectType::Athena)
17833 )
17834 }
17835
17836 fn generate_current_time(&mut self, f: &CurrentTime) -> Result<()> {
17839 self.write_keyword("CURRENT_TIME");
17840 if let Some(precision) = f.precision {
17841 self.write(&format!("({})", precision));
17842 }
17843 Ok(())
17844 }
17845
17846 fn generate_current_timestamp(&mut self, f: &CurrentTimestamp) -> Result<()> {
17847 use crate::dialects::DialectType;
17848
17849 if f.sysdate {
17851 match self.config.dialect {
17852 Some(DialectType::Oracle) | Some(DialectType::Redshift) => {
17853 self.write_keyword("SYSDATE");
17854 return Ok(());
17855 }
17856 Some(DialectType::Snowflake) => {
17857 self.write_keyword("SYSDATE");
17859 self.write("()");
17860 return Ok(());
17861 }
17862 _ => {
17863 }
17865 }
17866 }
17867
17868 self.write_keyword("CURRENT_TIMESTAMP");
17869 if let Some(precision) = f.precision {
17871 self.write(&format!("({})", precision));
17872 } else if matches!(
17873 self.config.dialect,
17874 Some(crate::dialects::DialectType::MySQL)
17875 | Some(crate::dialects::DialectType::SingleStore)
17876 | Some(crate::dialects::DialectType::TiDB)
17877 | Some(crate::dialects::DialectType::Spark)
17878 | Some(crate::dialects::DialectType::Hive)
17879 | Some(crate::dialects::DialectType::Databricks)
17880 | Some(crate::dialects::DialectType::ClickHouse)
17881 | Some(crate::dialects::DialectType::BigQuery)
17882 | Some(crate::dialects::DialectType::Snowflake)
17883 ) {
17884 self.write("()");
17885 }
17886 Ok(())
17887 }
17888
17889 fn generate_at_time_zone(&mut self, f: &AtTimeZone) -> Result<()> {
17890 if self.config.dialect == Some(DialectType::Exasol) {
17892 self.write_keyword("CONVERT_TZ");
17893 self.write("(");
17894 self.generate_expression(&f.this)?;
17895 self.write(", 'UTC', ");
17896 self.generate_expression(&f.zone)?;
17897 self.write(")");
17898 return Ok(());
17899 }
17900
17901 self.generate_expression(&f.this)?;
17902 self.write_space();
17903 self.write_keyword("AT TIME ZONE");
17904 self.write_space();
17905 self.generate_expression(&f.zone)?;
17906 Ok(())
17907 }
17908
17909 fn generate_date_add(&mut self, f: &DateAddFunc, name: &str) -> Result<()> {
17910 use crate::dialects::DialectType;
17911
17912 let is_presto_like = matches!(
17915 self.config.dialect,
17916 Some(DialectType::Presto) | Some(DialectType::Trino)
17917 );
17918
17919 if is_presto_like {
17920 self.write_keyword(name);
17921 self.write("(");
17922 self.write("'");
17924 self.write_simple_interval_unit(&f.unit, false);
17925 self.write("'");
17926 self.write(", ");
17927 let needs_cast = !self.returns_integer_type(&f.interval);
17929 if needs_cast {
17930 self.write_keyword("CAST");
17931 self.write("(");
17932 }
17933 self.generate_expression(&f.interval)?;
17934 if needs_cast {
17935 self.write_space();
17936 self.write_keyword("AS");
17937 self.write_space();
17938 self.write_keyword("BIGINT");
17939 self.write(")");
17940 }
17941 self.write(", ");
17942 self.generate_expression(&f.this)?;
17943 self.write(")");
17944 } else {
17945 self.write_keyword(name);
17946 self.write("(");
17947 self.generate_expression(&f.this)?;
17948 self.write(", ");
17949 self.write_keyword("INTERVAL");
17950 self.write_space();
17951 self.generate_expression(&f.interval)?;
17952 self.write_space();
17953 self.write_simple_interval_unit(&f.unit, false); self.write(")");
17955 }
17956 Ok(())
17957 }
17958
17959 fn returns_integer_type(&self, expr: &Expression) -> bool {
17962 use crate::expressions::{DataType, Literal};
17963 match expr {
17964 Expression::Literal(Literal::Number(n)) => !n.contains('.'),
17966
17967 Expression::Floor(f) => self.returns_integer_type(&f.this),
17969
17970 Expression::Round(f) => {
17972 f.decimals.is_none() && self.returns_integer_type(&f.this)
17974 }
17975
17976 Expression::Sign(f) => self.returns_integer_type(&f.this),
17978
17979 Expression::Abs(f) => self.returns_integer_type(&f.this),
17981
17982 Expression::Mul(op) => {
17984 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
17985 }
17986 Expression::Add(op) => {
17987 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
17988 }
17989 Expression::Sub(op) => {
17990 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
17991 }
17992 Expression::Mod(op) => self.returns_integer_type(&op.left),
17993
17994 Expression::Cast(c) => matches!(
17996 &c.to,
17997 DataType::BigInt { .. }
17998 | DataType::Int { .. }
17999 | DataType::SmallInt { .. }
18000 | DataType::TinyInt { .. }
18001 ),
18002
18003 Expression::Neg(op) => self.returns_integer_type(&op.this),
18005
18006 Expression::Paren(p) => self.returns_integer_type(&p.this),
18008
18009 _ => false,
18012 }
18013 }
18014
18015 fn generate_datediff(&mut self, f: &DateDiffFunc) -> Result<()> {
18016 self.write_keyword("DATEDIFF");
18017 self.write("(");
18018 if let Some(unit) = &f.unit {
18019 self.write_simple_interval_unit(unit, false); self.write(", ");
18021 }
18022 self.generate_expression(&f.this)?;
18023 self.write(", ");
18024 self.generate_expression(&f.expression)?;
18025 self.write(")");
18026 Ok(())
18027 }
18028
18029 fn generate_date_trunc(&mut self, f: &DateTruncFunc) -> Result<()> {
18030 self.write_keyword("DATE_TRUNC");
18031 self.write("('");
18032 self.write_datetime_field(&f.unit);
18033 self.write("', ");
18034 self.generate_expression(&f.this)?;
18035 self.write(")");
18036 Ok(())
18037 }
18038
18039 fn generate_last_day(&mut self, f: &LastDayFunc) -> Result<()> {
18040 use crate::dialects::DialectType;
18041 use crate::expressions::DateTimeField;
18042
18043 self.write_keyword("LAST_DAY");
18044 self.write("(");
18045 self.generate_expression(&f.this)?;
18046 if let Some(unit) = &f.unit {
18047 self.write(", ");
18048 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
18051 if let DateTimeField::WeekWithModifier(_) = unit {
18052 self.write_keyword("WEEK");
18053 } else {
18054 self.write_datetime_field(unit);
18055 }
18056 } else {
18057 self.write_datetime_field(unit);
18058 }
18059 }
18060 self.write(")");
18061 Ok(())
18062 }
18063
18064 fn generate_extract(&mut self, f: &ExtractFunc) -> Result<()> {
18065 if matches!(
18067 self.config.dialect,
18068 Some(DialectType::TSQL) | Some(DialectType::Fabric)
18069 ) {
18070 self.write_keyword("DATEPART");
18071 self.write("(");
18072 self.write_datetime_field(&f.field);
18073 self.write(", ");
18074 self.generate_expression(&f.this)?;
18075 self.write(")");
18076 return Ok(());
18077 }
18078 self.write_keyword("EXTRACT");
18079 self.write("(");
18080 if matches!(
18082 self.config.dialect,
18083 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
18084 ) {
18085 self.write_datetime_field_lower(&f.field);
18086 } else {
18087 self.write_datetime_field(&f.field);
18088 }
18089 self.write_space();
18090 self.write_keyword("FROM");
18091 self.write_space();
18092 self.generate_expression(&f.this)?;
18093 self.write(")");
18094 Ok(())
18095 }
18096
18097 fn generate_to_date(&mut self, f: &ToDateFunc) -> Result<()> {
18098 self.write_keyword("TO_DATE");
18099 self.write("(");
18100 self.generate_expression(&f.this)?;
18101 if let Some(format) = &f.format {
18102 self.write(", ");
18103 self.generate_expression(format)?;
18104 }
18105 self.write(")");
18106 Ok(())
18107 }
18108
18109 fn generate_to_timestamp(&mut self, f: &ToTimestampFunc) -> Result<()> {
18110 self.write_keyword("TO_TIMESTAMP");
18111 self.write("(");
18112 self.generate_expression(&f.this)?;
18113 if let Some(format) = &f.format {
18114 self.write(", ");
18115 self.generate_expression(format)?;
18116 }
18117 self.write(")");
18118 Ok(())
18119 }
18120
18121 fn generate_if_func(&mut self, f: &IfFunc) -> Result<()> {
18124 use crate::dialects::DialectType;
18125
18126 if self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic) {
18128 self.write_keyword("CASE WHEN");
18129 self.write_space();
18130 self.generate_expression(&f.condition)?;
18131 self.write_space();
18132 self.write_keyword("THEN");
18133 self.write_space();
18134 self.generate_expression(&f.true_value)?;
18135 if let Some(false_val) = &f.false_value {
18136 self.write_space();
18137 self.write_keyword("ELSE");
18138 self.write_space();
18139 self.generate_expression(false_val)?;
18140 }
18141 self.write_space();
18142 self.write_keyword("END");
18143 return Ok(());
18144 }
18145
18146 if self.config.dialect == Some(DialectType::Exasol) {
18148 self.write_keyword("IF");
18149 self.write_space();
18150 self.generate_expression(&f.condition)?;
18151 self.write_space();
18152 self.write_keyword("THEN");
18153 self.write_space();
18154 self.generate_expression(&f.true_value)?;
18155 if let Some(false_val) = &f.false_value {
18156 self.write_space();
18157 self.write_keyword("ELSE");
18158 self.write_space();
18159 self.generate_expression(false_val)?;
18160 }
18161 self.write_space();
18162 self.write_keyword("ENDIF");
18163 return Ok(());
18164 }
18165
18166 let func_name = match self.config.dialect {
18168 Some(DialectType::Snowflake) => "IFF",
18169 Some(DialectType::SQLite) | Some(DialectType::TSQL) => "IIF",
18170 Some(DialectType::Drill) => "`IF`",
18171 _ => "IF",
18172 };
18173 self.write(func_name);
18174 self.write("(");
18175 self.generate_expression(&f.condition)?;
18176 self.write(", ");
18177 self.generate_expression(&f.true_value)?;
18178 if let Some(false_val) = &f.false_value {
18179 self.write(", ");
18180 self.generate_expression(false_val)?;
18181 }
18182 self.write(")");
18183 Ok(())
18184 }
18185
18186 fn generate_nvl2(&mut self, f: &Nvl2Func) -> Result<()> {
18187 self.write_keyword("NVL2");
18188 self.write("(");
18189 self.generate_expression(&f.this)?;
18190 self.write(", ");
18191 self.generate_expression(&f.true_value)?;
18192 self.write(", ");
18193 self.generate_expression(&f.false_value)?;
18194 self.write(")");
18195 Ok(())
18196 }
18197
18198 fn generate_count(&mut self, f: &CountFunc) -> Result<()> {
18201 let count_name = match self.config.normalize_functions {
18203 NormalizeFunctions::Upper => "COUNT".to_string(),
18204 NormalizeFunctions::Lower => "count".to_string(),
18205 NormalizeFunctions::None => f
18206 .original_name
18207 .clone()
18208 .unwrap_or_else(|| "COUNT".to_string()),
18209 };
18210 self.write(&count_name);
18211 self.write("(");
18212 if f.distinct {
18213 self.write_keyword("DISTINCT");
18214 self.write_space();
18215 }
18216 if f.star {
18217 self.write("*");
18218 } else if let Some(ref expr) = f.this {
18219 if let Expression::Tuple(tuple) = expr {
18221 let needs_transform =
18225 f.distinct && tuple.expressions.len() > 1 && !self.config.multi_arg_distinct;
18226
18227 if needs_transform {
18228 self.write_keyword("CASE");
18230 for e in &tuple.expressions {
18231 self.write_space();
18232 self.write_keyword("WHEN");
18233 self.write_space();
18234 self.generate_expression(e)?;
18235 self.write_space();
18236 self.write_keyword("IS NULL THEN NULL");
18237 }
18238 self.write_space();
18239 self.write_keyword("ELSE");
18240 self.write(" (");
18241 for (i, e) in tuple.expressions.iter().enumerate() {
18242 if i > 0 {
18243 self.write(", ");
18244 }
18245 self.generate_expression(e)?;
18246 }
18247 self.write(")");
18248 self.write_space();
18249 self.write_keyword("END");
18250 } else {
18251 for (i, e) in tuple.expressions.iter().enumerate() {
18252 if i > 0 {
18253 self.write(", ");
18254 }
18255 self.generate_expression(e)?;
18256 }
18257 }
18258 } else {
18259 self.generate_expression(expr)?;
18260 }
18261 }
18262 if let Some(ignore) = f.ignore_nulls {
18264 self.write_space();
18265 if ignore {
18266 self.write_keyword("IGNORE NULLS");
18267 } else {
18268 self.write_keyword("RESPECT NULLS");
18269 }
18270 }
18271 self.write(")");
18272 if let Some(ref filter) = f.filter {
18273 self.write_space();
18274 self.write_keyword("FILTER");
18275 self.write("(");
18276 self.write_keyword("WHERE");
18277 self.write_space();
18278 self.generate_expression(filter)?;
18279 self.write(")");
18280 }
18281 Ok(())
18282 }
18283
18284 fn generate_agg_func(&mut self, name: &str, f: &AggFunc) -> Result<()> {
18285 let func_name = match self.config.normalize_functions {
18287 NormalizeFunctions::Upper => name.to_uppercase(),
18288 NormalizeFunctions::Lower => name.to_lowercase(),
18289 NormalizeFunctions::None => {
18290 if let Some(ref original) = f.name {
18293 original.clone()
18294 } else {
18295 name.to_lowercase()
18296 }
18297 }
18298 };
18299 self.write(&func_name);
18300 self.write("(");
18301 if f.distinct {
18302 self.write_keyword("DISTINCT");
18303 self.write_space();
18304 }
18305 if !matches!(f.this, Expression::Null(_)) {
18307 self.generate_expression(&f.this)?;
18308 }
18309 if self.config.ignore_nulls_in_func
18312 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
18313 {
18314 match f.ignore_nulls {
18315 Some(true) => {
18316 self.write_space();
18317 self.write_keyword("IGNORE NULLS");
18318 }
18319 Some(false) => {
18320 self.write_space();
18321 self.write_keyword("RESPECT NULLS");
18322 }
18323 None => {}
18324 }
18325 }
18326 if let Some((ref expr, is_max)) = f.having_max {
18329 self.write_space();
18330 self.write_keyword("HAVING");
18331 self.write_space();
18332 if is_max {
18333 self.write_keyword("MAX");
18334 } else {
18335 self.write_keyword("MIN");
18336 }
18337 self.write_space();
18338 self.generate_expression(expr)?;
18339 }
18340 if !f.order_by.is_empty() {
18342 self.write_space();
18343 self.write_keyword("ORDER BY");
18344 self.write_space();
18345 for (i, ord) in f.order_by.iter().enumerate() {
18346 if i > 0 {
18347 self.write(", ");
18348 }
18349 self.generate_ordered(ord)?;
18350 }
18351 }
18352 if let Some(ref limit) = f.limit {
18354 self.write_space();
18355 self.write_keyword("LIMIT");
18356 self.write_space();
18357 if let Expression::Tuple(t) = limit.as_ref() {
18359 if t.expressions.len() == 2 {
18360 self.generate_expression(&t.expressions[0])?;
18361 self.write(", ");
18362 self.generate_expression(&t.expressions[1])?;
18363 } else {
18364 self.generate_expression(limit)?;
18365 }
18366 } else {
18367 self.generate_expression(limit)?;
18368 }
18369 }
18370 self.write(")");
18371 if !self.config.ignore_nulls_in_func
18374 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
18375 {
18376 match f.ignore_nulls {
18377 Some(true) => {
18378 self.write_space();
18379 self.write_keyword("IGNORE NULLS");
18380 }
18381 Some(false) => {
18382 self.write_space();
18383 self.write_keyword("RESPECT NULLS");
18384 }
18385 None => {}
18386 }
18387 }
18388 if let Some(ref filter) = f.filter {
18389 self.write_space();
18390 self.write_keyword("FILTER");
18391 self.write("(");
18392 self.write_keyword("WHERE");
18393 self.write_space();
18394 self.generate_expression(filter)?;
18395 self.write(")");
18396 }
18397 Ok(())
18398 }
18399
18400 fn generate_group_concat(&mut self, f: &GroupConcatFunc) -> Result<()> {
18401 self.write_keyword("GROUP_CONCAT");
18402 self.write("(");
18403 if f.distinct {
18404 self.write_keyword("DISTINCT");
18405 self.write_space();
18406 }
18407 self.generate_expression(&f.this)?;
18408 if let Some(ref order_by) = f.order_by {
18409 self.write_space();
18410 self.write_keyword("ORDER BY");
18411 self.write_space();
18412 for (i, ord) in order_by.iter().enumerate() {
18413 if i > 0 {
18414 self.write(", ");
18415 }
18416 self.generate_ordered(ord)?;
18417 }
18418 }
18419 if let Some(ref sep) = f.separator {
18420 if matches!(
18423 self.config.dialect,
18424 Some(crate::dialects::DialectType::SQLite)
18425 ) {
18426 self.write(", ");
18427 self.generate_expression(sep)?;
18428 } else {
18429 self.write_space();
18430 self.write_keyword("SEPARATOR");
18431 self.write_space();
18432 self.generate_expression(sep)?;
18433 }
18434 }
18435 self.write(")");
18436 if let Some(ref filter) = f.filter {
18437 self.write_space();
18438 self.write_keyword("FILTER");
18439 self.write("(");
18440 self.write_keyword("WHERE");
18441 self.write_space();
18442 self.generate_expression(filter)?;
18443 self.write(")");
18444 }
18445 Ok(())
18446 }
18447
18448 fn generate_string_agg(&mut self, f: &StringAggFunc) -> Result<()> {
18449 let is_tsql = matches!(
18450 self.config.dialect,
18451 Some(crate::dialects::DialectType::TSQL)
18452 );
18453 self.write_keyword("STRING_AGG");
18454 self.write("(");
18455 if f.distinct {
18456 self.write_keyword("DISTINCT");
18457 self.write_space();
18458 }
18459 self.generate_expression(&f.this)?;
18460 if let Some(ref separator) = f.separator {
18461 self.write(", ");
18462 self.generate_expression(separator)?;
18463 }
18464 if !is_tsql {
18466 if let Some(ref order_by) = f.order_by {
18467 self.write_space();
18468 self.write_keyword("ORDER BY");
18469 self.write_space();
18470 for (i, ord) in order_by.iter().enumerate() {
18471 if i > 0 {
18472 self.write(", ");
18473 }
18474 self.generate_ordered(ord)?;
18475 }
18476 }
18477 }
18478 if let Some(ref limit) = f.limit {
18479 self.write_space();
18480 self.write_keyword("LIMIT");
18481 self.write_space();
18482 self.generate_expression(limit)?;
18483 }
18484 self.write(")");
18485 if is_tsql {
18487 if let Some(ref order_by) = f.order_by {
18488 self.write_space();
18489 self.write_keyword("WITHIN GROUP");
18490 self.write(" (");
18491 self.write_keyword("ORDER BY");
18492 self.write_space();
18493 for (i, ord) in order_by.iter().enumerate() {
18494 if i > 0 {
18495 self.write(", ");
18496 }
18497 self.generate_ordered(ord)?;
18498 }
18499 self.write(")");
18500 }
18501 }
18502 if let Some(ref filter) = f.filter {
18503 self.write_space();
18504 self.write_keyword("FILTER");
18505 self.write("(");
18506 self.write_keyword("WHERE");
18507 self.write_space();
18508 self.generate_expression(filter)?;
18509 self.write(")");
18510 }
18511 Ok(())
18512 }
18513
18514 fn generate_listagg(&mut self, f: &ListAggFunc) -> Result<()> {
18515 use crate::dialects::DialectType;
18516 self.write_keyword("LISTAGG");
18517 self.write("(");
18518 if f.distinct {
18519 self.write_keyword("DISTINCT");
18520 self.write_space();
18521 }
18522 self.generate_expression(&f.this)?;
18523 if let Some(ref sep) = f.separator {
18524 self.write(", ");
18525 self.generate_expression(sep)?;
18526 } else if matches!(
18527 self.config.dialect,
18528 Some(DialectType::Trino) | Some(DialectType::Presto)
18529 ) {
18530 self.write(", ','");
18532 }
18533 if let Some(ref overflow) = f.on_overflow {
18534 self.write_space();
18535 self.write_keyword("ON OVERFLOW");
18536 self.write_space();
18537 match overflow {
18538 ListAggOverflow::Error => self.write_keyword("ERROR"),
18539 ListAggOverflow::Truncate { filler, with_count } => {
18540 self.write_keyword("TRUNCATE");
18541 if let Some(ref fill) = filler {
18542 self.write_space();
18543 self.generate_expression(fill)?;
18544 }
18545 if *with_count {
18546 self.write_space();
18547 self.write_keyword("WITH COUNT");
18548 } else {
18549 self.write_space();
18550 self.write_keyword("WITHOUT COUNT");
18551 }
18552 }
18553 }
18554 }
18555 self.write(")");
18556 if let Some(ref order_by) = f.order_by {
18557 self.write_space();
18558 self.write_keyword("WITHIN GROUP");
18559 self.write(" (");
18560 self.write_keyword("ORDER BY");
18561 self.write_space();
18562 for (i, ord) in order_by.iter().enumerate() {
18563 if i > 0 {
18564 self.write(", ");
18565 }
18566 self.generate_ordered(ord)?;
18567 }
18568 self.write(")");
18569 }
18570 if let Some(ref filter) = f.filter {
18571 self.write_space();
18572 self.write_keyword("FILTER");
18573 self.write("(");
18574 self.write_keyword("WHERE");
18575 self.write_space();
18576 self.generate_expression(filter)?;
18577 self.write(")");
18578 }
18579 Ok(())
18580 }
18581
18582 fn generate_sum_if(&mut self, f: &SumIfFunc) -> Result<()> {
18583 self.write_keyword("SUM_IF");
18584 self.write("(");
18585 self.generate_expression(&f.this)?;
18586 self.write(", ");
18587 self.generate_expression(&f.condition)?;
18588 self.write(")");
18589 if let Some(ref filter) = f.filter {
18590 self.write_space();
18591 self.write_keyword("FILTER");
18592 self.write("(");
18593 self.write_keyword("WHERE");
18594 self.write_space();
18595 self.generate_expression(filter)?;
18596 self.write(")");
18597 }
18598 Ok(())
18599 }
18600
18601 fn generate_approx_percentile(&mut self, f: &ApproxPercentileFunc) -> Result<()> {
18602 self.write_keyword("APPROX_PERCENTILE");
18603 self.write("(");
18604 self.generate_expression(&f.this)?;
18605 self.write(", ");
18606 self.generate_expression(&f.percentile)?;
18607 if let Some(ref acc) = f.accuracy {
18608 self.write(", ");
18609 self.generate_expression(acc)?;
18610 }
18611 self.write(")");
18612 if let Some(ref filter) = f.filter {
18613 self.write_space();
18614 self.write_keyword("FILTER");
18615 self.write("(");
18616 self.write_keyword("WHERE");
18617 self.write_space();
18618 self.generate_expression(filter)?;
18619 self.write(")");
18620 }
18621 Ok(())
18622 }
18623
18624 fn generate_percentile(&mut self, name: &str, f: &PercentileFunc) -> Result<()> {
18625 self.write_keyword(name);
18626 self.write("(");
18627 self.generate_expression(&f.percentile)?;
18628 self.write(")");
18629 if let Some(ref order_by) = f.order_by {
18630 self.write_space();
18631 self.write_keyword("WITHIN GROUP");
18632 self.write(" (");
18633 self.write_keyword("ORDER BY");
18634 self.write_space();
18635 self.generate_expression(&f.this)?;
18636 for ord in order_by.iter() {
18637 if ord.desc {
18638 self.write_space();
18639 self.write_keyword("DESC");
18640 }
18641 }
18642 self.write(")");
18643 }
18644 if let Some(ref filter) = f.filter {
18645 self.write_space();
18646 self.write_keyword("FILTER");
18647 self.write("(");
18648 self.write_keyword("WHERE");
18649 self.write_space();
18650 self.generate_expression(filter)?;
18651 self.write(")");
18652 }
18653 Ok(())
18654 }
18655
18656 fn generate_ntile(&mut self, f: &NTileFunc) -> Result<()> {
18659 self.write_keyword("NTILE");
18660 self.write("(");
18661 if let Some(num_buckets) = &f.num_buckets {
18662 self.generate_expression(num_buckets)?;
18663 }
18664 if let Some(order_by) = &f.order_by {
18665 self.write_keyword(" ORDER BY ");
18666 for (i, ob) in order_by.iter().enumerate() {
18667 if i > 0 {
18668 self.write(", ");
18669 }
18670 self.generate_ordered(ob)?;
18671 }
18672 }
18673 self.write(")");
18674 Ok(())
18675 }
18676
18677 fn generate_lead_lag(&mut self, name: &str, f: &LeadLagFunc) -> Result<()> {
18678 self.write_keyword(name);
18679 self.write("(");
18680 self.generate_expression(&f.this)?;
18681 if let Some(ref offset) = f.offset {
18682 self.write(", ");
18683 self.generate_expression(offset)?;
18684 if let Some(ref default) = f.default {
18685 self.write(", ");
18686 self.generate_expression(default)?;
18687 }
18688 }
18689 if f.ignore_nulls && self.config.ignore_nulls_in_func {
18691 self.write_space();
18692 self.write_keyword("IGNORE NULLS");
18693 }
18694 self.write(")");
18695 if f.ignore_nulls && !self.config.ignore_nulls_in_func {
18697 self.write_space();
18698 self.write_keyword("IGNORE NULLS");
18699 }
18700 Ok(())
18701 }
18702
18703 fn generate_value_func(&mut self, name: &str, f: &ValueFunc) -> Result<()> {
18704 self.write_keyword(name);
18705 self.write("(");
18706 self.generate_expression(&f.this)?;
18707 if self.config.ignore_nulls_in_func {
18709 match f.ignore_nulls {
18710 Some(true) => {
18711 self.write_space();
18712 self.write_keyword("IGNORE NULLS");
18713 }
18714 Some(false) => {
18715 self.write_space();
18716 self.write_keyword("RESPECT NULLS");
18717 }
18718 None => {}
18719 }
18720 }
18721 self.write(")");
18722 if !self.config.ignore_nulls_in_func {
18724 match f.ignore_nulls {
18725 Some(true) => {
18726 self.write_space();
18727 self.write_keyword("IGNORE NULLS");
18728 }
18729 Some(false) => {
18730 self.write_space();
18731 self.write_keyword("RESPECT NULLS");
18732 }
18733 None => {}
18734 }
18735 }
18736 Ok(())
18737 }
18738
18739 fn generate_nth_value(&mut self, f: &NthValueFunc) -> Result<()> {
18740 self.write_keyword("NTH_VALUE");
18741 self.write("(");
18742 self.generate_expression(&f.this)?;
18743 self.write(", ");
18744 self.generate_expression(&f.offset)?;
18745 if self.config.ignore_nulls_in_func {
18747 match f.ignore_nulls {
18748 Some(true) => {
18749 self.write_space();
18750 self.write_keyword("IGNORE NULLS");
18751 }
18752 Some(false) => {
18753 self.write_space();
18754 self.write_keyword("RESPECT NULLS");
18755 }
18756 None => {}
18757 }
18758 }
18759 self.write(")");
18760 if matches!(
18762 self.config.dialect,
18763 Some(crate::dialects::DialectType::Snowflake)
18764 ) {
18765 match f.from_first {
18766 Some(true) => {
18767 self.write_space();
18768 self.write_keyword("FROM FIRST");
18769 }
18770 Some(false) => {
18771 self.write_space();
18772 self.write_keyword("FROM LAST");
18773 }
18774 None => {}
18775 }
18776 }
18777 if !self.config.ignore_nulls_in_func {
18779 match f.ignore_nulls {
18780 Some(true) => {
18781 self.write_space();
18782 self.write_keyword("IGNORE NULLS");
18783 }
18784 Some(false) => {
18785 self.write_space();
18786 self.write_keyword("RESPECT NULLS");
18787 }
18788 None => {}
18789 }
18790 }
18791 Ok(())
18792 }
18793
18794 fn generate_position(&mut self, f: &PositionFunc) -> Result<()> {
18797 if matches!(
18800 self.config.dialect,
18801 Some(crate::dialects::DialectType::ClickHouse)
18802 ) {
18803 self.write_keyword("POSITION");
18804 self.write("(");
18805 self.generate_expression(&f.string)?;
18806 self.write(", ");
18807 self.generate_expression(&f.substring)?;
18808 if let Some(ref start) = f.start {
18809 self.write(", ");
18810 self.generate_expression(start)?;
18811 }
18812 self.write(")");
18813 return Ok(());
18814 }
18815
18816 self.write_keyword("POSITION");
18817 self.write("(");
18818 self.generate_expression(&f.substring)?;
18819 self.write_space();
18820 self.write_keyword("IN");
18821 self.write_space();
18822 self.generate_expression(&f.string)?;
18823 if let Some(ref start) = f.start {
18824 self.write(", ");
18825 self.generate_expression(start)?;
18826 }
18827 self.write(")");
18828 Ok(())
18829 }
18830
18831 fn generate_rand(&mut self, f: &Rand) -> Result<()> {
18834 if f.lower.is_some() || f.upper.is_some() {
18836 self.write_keyword("RANDOM");
18837 self.write("(");
18838 if let Some(ref lower) = f.lower {
18839 self.generate_expression(lower)?;
18840 }
18841 if let Some(ref upper) = f.upper {
18842 self.write(", ");
18843 self.generate_expression(upper)?;
18844 }
18845 self.write(")");
18846 return Ok(());
18847 }
18848 let func_name = match self.config.dialect {
18850 Some(crate::dialects::DialectType::Snowflake)
18851 | Some(crate::dialects::DialectType::DuckDB) => "RANDOM",
18852 _ => "RAND",
18853 };
18854 self.write_keyword(func_name);
18855 self.write("(");
18856 if !matches!(
18858 self.config.dialect,
18859 Some(crate::dialects::DialectType::DuckDB)
18860 ) {
18861 if let Some(ref seed) = f.seed {
18862 self.generate_expression(seed)?;
18863 }
18864 }
18865 self.write(")");
18866 Ok(())
18867 }
18868
18869 fn generate_truncate_func(&mut self, f: &TruncateFunc) -> Result<()> {
18870 self.write_keyword("TRUNCATE");
18871 self.write("(");
18872 self.generate_expression(&f.this)?;
18873 if let Some(ref decimals) = f.decimals {
18874 self.write(", ");
18875 self.generate_expression(decimals)?;
18876 }
18877 self.write(")");
18878 Ok(())
18879 }
18880
18881 fn generate_decode(&mut self, f: &DecodeFunc) -> Result<()> {
18884 self.write_keyword("DECODE");
18885 self.write("(");
18886 self.generate_expression(&f.this)?;
18887 for (search, result) in &f.search_results {
18888 self.write(", ");
18889 self.generate_expression(search)?;
18890 self.write(", ");
18891 self.generate_expression(result)?;
18892 }
18893 if let Some(ref default) = f.default {
18894 self.write(", ");
18895 self.generate_expression(default)?;
18896 }
18897 self.write(")");
18898 Ok(())
18899 }
18900
18901 fn generate_date_format(&mut self, name: &str, f: &DateFormatFunc) -> Result<()> {
18904 self.write_keyword(name);
18905 self.write("(");
18906 self.generate_expression(&f.this)?;
18907 self.write(", ");
18908 self.generate_expression(&f.format)?;
18909 self.write(")");
18910 Ok(())
18911 }
18912
18913 fn generate_from_unixtime(&mut self, f: &FromUnixtimeFunc) -> Result<()> {
18914 self.write_keyword("FROM_UNIXTIME");
18915 self.write("(");
18916 self.generate_expression(&f.this)?;
18917 if let Some(ref format) = f.format {
18918 self.write(", ");
18919 self.generate_expression(format)?;
18920 }
18921 self.write(")");
18922 Ok(())
18923 }
18924
18925 fn generate_unix_timestamp(&mut self, f: &UnixTimestampFunc) -> Result<()> {
18926 self.write_keyword("UNIX_TIMESTAMP");
18927 self.write("(");
18928 if let Some(ref expr) = f.this {
18929 self.generate_expression(expr)?;
18930 if let Some(ref format) = f.format {
18931 self.write(", ");
18932 self.generate_expression(format)?;
18933 }
18934 } else if matches!(
18935 self.config.dialect,
18936 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
18937 ) {
18938 self.write_keyword("CURRENT_TIMESTAMP");
18940 self.write("()");
18941 }
18942 self.write(")");
18943 Ok(())
18944 }
18945
18946 fn generate_make_date(&mut self, f: &MakeDateFunc) -> Result<()> {
18947 self.write_keyword("MAKE_DATE");
18948 self.write("(");
18949 self.generate_expression(&f.year)?;
18950 self.write(", ");
18951 self.generate_expression(&f.month)?;
18952 self.write(", ");
18953 self.generate_expression(&f.day)?;
18954 self.write(")");
18955 Ok(())
18956 }
18957
18958 fn generate_make_timestamp(&mut self, f: &MakeTimestampFunc) -> Result<()> {
18959 self.write_keyword("MAKE_TIMESTAMP");
18960 self.write("(");
18961 self.generate_expression(&f.year)?;
18962 self.write(", ");
18963 self.generate_expression(&f.month)?;
18964 self.write(", ");
18965 self.generate_expression(&f.day)?;
18966 self.write(", ");
18967 self.generate_expression(&f.hour)?;
18968 self.write(", ");
18969 self.generate_expression(&f.minute)?;
18970 self.write(", ");
18971 self.generate_expression(&f.second)?;
18972 if let Some(ref tz) = f.timezone {
18973 self.write(", ");
18974 self.generate_expression(tz)?;
18975 }
18976 self.write(")");
18977 Ok(())
18978 }
18979
18980 fn extract_struct_field_names(expr: &Expression) -> Option<Vec<String>> {
18982 match expr {
18983 Expression::Struct(s) => {
18984 if s.fields.iter().all(|(name, _)| name.is_some()) {
18985 Some(
18986 s.fields
18987 .iter()
18988 .map(|(name, _)| name.as_deref().unwrap_or("").to_string())
18989 .collect(),
18990 )
18991 } else {
18992 None
18993 }
18994 }
18995 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => {
18996 if f.args.iter().all(|a| matches!(a, Expression::Alias(_))) {
18998 Some(
18999 f.args
19000 .iter()
19001 .filter_map(|a| {
19002 if let Expression::Alias(alias) = a {
19003 Some(alias.alias.name.clone())
19004 } else {
19005 None
19006 }
19007 })
19008 .collect(),
19009 )
19010 } else {
19011 None
19012 }
19013 }
19014 _ => None,
19015 }
19016 }
19017
19018 fn struct_has_unnamed_fields(expr: &Expression) -> bool {
19020 match expr {
19021 Expression::Struct(s) => s.fields.iter().any(|(name, _)| name.is_none()),
19022 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => {
19023 f.args.iter().any(|a| !matches!(a, Expression::Alias(_)))
19024 }
19025 _ => false,
19026 }
19027 }
19028
19029 fn struct_field_count(expr: &Expression) -> usize {
19031 match expr {
19032 Expression::Struct(s) => s.fields.len(),
19033 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => f.args.len(),
19034 _ => 0,
19035 }
19036 }
19037
19038 fn apply_struct_field_names(expr: &Expression, field_names: &[String]) -> Expression {
19040 match expr {
19041 Expression::Struct(s) => {
19042 let mut new_fields = Vec::with_capacity(s.fields.len());
19043 for (i, (name, value)) in s.fields.iter().enumerate() {
19044 if name.is_none() && i < field_names.len() {
19045 new_fields.push((Some(field_names[i].clone()), value.clone()));
19046 } else {
19047 new_fields.push((name.clone(), value.clone()));
19048 }
19049 }
19050 Expression::Struct(Box::new(crate::expressions::Struct { fields: new_fields }))
19051 }
19052 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => {
19053 let mut new_args = Vec::with_capacity(f.args.len());
19054 for (i, arg) in f.args.iter().enumerate() {
19055 if !matches!(arg, Expression::Alias(_)) && i < field_names.len() {
19056 new_args.push(Expression::Alias(Box::new(crate::expressions::Alias {
19058 this: arg.clone(),
19059 alias: crate::expressions::Identifier::new(field_names[i].clone()),
19060 column_aliases: Vec::new(),
19061 pre_alias_comments: Vec::new(),
19062 trailing_comments: Vec::new(),
19063 })));
19064 } else {
19065 new_args.push(arg.clone());
19066 }
19067 }
19068 Expression::Function(Box::new(crate::expressions::Function {
19069 name: f.name.clone(),
19070 args: new_args,
19071 distinct: f.distinct,
19072 trailing_comments: f.trailing_comments.clone(),
19073 use_bracket_syntax: f.use_bracket_syntax,
19074 no_parens: f.no_parens,
19075 quoted: f.quoted,
19076 span: None,
19077 }))
19078 }
19079 _ => expr.clone(),
19080 }
19081 }
19082
19083 fn inherit_struct_field_names(expressions: &[Expression]) -> Vec<Expression> {
19087 let first = match expressions.first() {
19088 Some(e) => e,
19089 None => return expressions.to_vec(),
19090 };
19091
19092 let field_names = match Self::extract_struct_field_names(first) {
19093 Some(names) if !names.is_empty() => names,
19094 _ => return expressions.to_vec(),
19095 };
19096
19097 let mut result = Vec::with_capacity(expressions.len());
19098 for (idx, expr) in expressions.iter().enumerate() {
19099 if idx == 0 {
19100 result.push(expr.clone());
19101 continue;
19102 }
19103 if Self::struct_field_count(expr) == field_names.len()
19105 && Self::struct_has_unnamed_fields(expr)
19106 {
19107 result.push(Self::apply_struct_field_names(expr, &field_names));
19108 } else {
19109 result.push(expr.clone());
19110 }
19111 }
19112 result
19113 }
19114
19115 fn generate_array_constructor(&mut self, f: &ArrayConstructor) -> Result<()> {
19118 let needs_inheritance = matches!(
19121 self.config.dialect,
19122 Some(DialectType::DuckDB)
19123 | Some(DialectType::Spark)
19124 | Some(DialectType::Databricks)
19125 | Some(DialectType::Hive)
19126 | Some(DialectType::Snowflake)
19127 | Some(DialectType::Presto)
19128 | Some(DialectType::Trino)
19129 );
19130 let propagated: Vec<Expression>;
19131 let expressions = if needs_inheritance && f.expressions.len() > 1 {
19132 propagated = Self::inherit_struct_field_names(&f.expressions);
19133 &propagated
19134 } else {
19135 &f.expressions
19136 };
19137
19138 let should_split = if self.config.pretty && !expressions.is_empty() {
19140 let mut expr_strings: Vec<String> = Vec::with_capacity(expressions.len());
19141 for expr in expressions {
19142 let mut temp_gen = Generator::with_config(self.config.clone());
19143 temp_gen.config.pretty = false;
19144 temp_gen.generate_expression(expr)?;
19145 expr_strings.push(temp_gen.output);
19146 }
19147 self.too_wide(&expr_strings)
19148 } else {
19149 false
19150 };
19151
19152 if f.bracket_notation {
19153 let (open, close) = match self.config.dialect {
19157 None
19158 | Some(DialectType::Generic)
19159 | Some(DialectType::Spark)
19160 | Some(DialectType::Databricks)
19161 | Some(DialectType::Hive) => {
19162 self.write_keyword("ARRAY");
19163 ("(", ")")
19164 }
19165 Some(DialectType::Presto)
19166 | Some(DialectType::Trino)
19167 | Some(DialectType::PostgreSQL)
19168 | Some(DialectType::Redshift)
19169 | Some(DialectType::Materialize)
19170 | Some(DialectType::RisingWave)
19171 | Some(DialectType::CockroachDB) => {
19172 self.write_keyword("ARRAY");
19173 ("[", "]")
19174 }
19175 _ => ("[", "]"),
19176 };
19177 self.write(open);
19178 if should_split {
19179 self.write_newline();
19180 self.indent_level += 1;
19181 for (i, expr) in expressions.iter().enumerate() {
19182 self.write_indent();
19183 self.generate_expression(expr)?;
19184 if i + 1 < expressions.len() {
19185 self.write(",");
19186 }
19187 self.write_newline();
19188 }
19189 self.indent_level -= 1;
19190 self.write_indent();
19191 } else {
19192 for (i, expr) in expressions.iter().enumerate() {
19193 if i > 0 {
19194 self.write(", ");
19195 }
19196 self.generate_expression(expr)?;
19197 }
19198 }
19199 self.write(close);
19200 } else {
19201 if f.use_list_keyword {
19203 self.write_keyword("LIST");
19204 } else {
19205 self.write_keyword("ARRAY");
19206 }
19207 let has_subquery = expressions
19210 .iter()
19211 .any(|e| matches!(e, Expression::Select(_)));
19212 let (open, close) = if matches!(
19213 self.config.dialect,
19214 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive)
19215 ) || (matches!(self.config.dialect, Some(DialectType::BigQuery))
19216 && has_subquery)
19217 {
19218 ("(", ")")
19219 } else {
19220 ("[", "]")
19221 };
19222 self.write(open);
19223 if should_split {
19224 self.write_newline();
19225 self.indent_level += 1;
19226 for (i, expr) in expressions.iter().enumerate() {
19227 self.write_indent();
19228 self.generate_expression(expr)?;
19229 if i + 1 < expressions.len() {
19230 self.write(",");
19231 }
19232 self.write_newline();
19233 }
19234 self.indent_level -= 1;
19235 self.write_indent();
19236 } else {
19237 for (i, expr) in expressions.iter().enumerate() {
19238 if i > 0 {
19239 self.write(", ");
19240 }
19241 self.generate_expression(expr)?;
19242 }
19243 }
19244 self.write(close);
19245 }
19246 Ok(())
19247 }
19248
19249 fn generate_array_sort(&mut self, f: &ArraySortFunc) -> Result<()> {
19250 self.write_keyword("ARRAY_SORT");
19251 self.write("(");
19252 self.generate_expression(&f.this)?;
19253 if let Some(ref comp) = f.comparator {
19254 self.write(", ");
19255 self.generate_expression(comp)?;
19256 }
19257 self.write(")");
19258 Ok(())
19259 }
19260
19261 fn generate_array_join(&mut self, name: &str, f: &ArrayJoinFunc) -> Result<()> {
19262 self.write_keyword(name);
19263 self.write("(");
19264 self.generate_expression(&f.this)?;
19265 self.write(", ");
19266 self.generate_expression(&f.separator)?;
19267 if let Some(ref null_rep) = f.null_replacement {
19268 self.write(", ");
19269 self.generate_expression(null_rep)?;
19270 }
19271 self.write(")");
19272 Ok(())
19273 }
19274
19275 fn generate_unnest(&mut self, f: &UnnestFunc) -> Result<()> {
19276 self.write_keyword("UNNEST");
19277 self.write("(");
19278 self.generate_expression(&f.this)?;
19279 for extra in &f.expressions {
19280 self.write(", ");
19281 self.generate_expression(extra)?;
19282 }
19283 self.write(")");
19284 if f.with_ordinality {
19285 self.write_space();
19286 if self.config.unnest_with_ordinality {
19287 self.write_keyword("WITH ORDINALITY");
19289 } else if f.offset_alias.is_some() {
19290 if let Some(ref alias) = f.alias {
19293 self.write_keyword("AS");
19294 self.write_space();
19295 self.generate_identifier(alias)?;
19296 self.write_space();
19297 }
19298 self.write_keyword("WITH OFFSET");
19299 if let Some(ref offset_alias) = f.offset_alias {
19300 self.write_space();
19301 self.write_keyword("AS");
19302 self.write_space();
19303 self.generate_identifier(offset_alias)?;
19304 }
19305 } else {
19306 self.write_keyword("WITH OFFSET");
19308 if f.alias.is_none() {
19309 self.write(" AS offset");
19310 }
19311 }
19312 }
19313 if let Some(ref alias) = f.alias {
19314 let should_add_alias = if !f.with_ordinality {
19316 true
19317 } else if self.config.unnest_with_ordinality {
19318 true
19320 } else if f.offset_alias.is_some() {
19321 false
19323 } else {
19324 true
19326 };
19327 if should_add_alias {
19328 self.write_space();
19329 self.write_keyword("AS");
19330 self.write_space();
19331 self.generate_identifier(alias)?;
19332 }
19333 }
19334 Ok(())
19335 }
19336
19337 fn generate_array_filter(&mut self, f: &ArrayFilterFunc) -> Result<()> {
19338 self.write_keyword("FILTER");
19339 self.write("(");
19340 self.generate_expression(&f.this)?;
19341 self.write(", ");
19342 self.generate_expression(&f.filter)?;
19343 self.write(")");
19344 Ok(())
19345 }
19346
19347 fn generate_array_transform(&mut self, f: &ArrayTransformFunc) -> Result<()> {
19348 self.write_keyword("TRANSFORM");
19349 self.write("(");
19350 self.generate_expression(&f.this)?;
19351 self.write(", ");
19352 self.generate_expression(&f.transform)?;
19353 self.write(")");
19354 Ok(())
19355 }
19356
19357 fn generate_sequence(&mut self, name: &str, f: &SequenceFunc) -> Result<()> {
19358 self.write_keyword(name);
19359 self.write("(");
19360 self.generate_expression(&f.start)?;
19361 self.write(", ");
19362 self.generate_expression(&f.stop)?;
19363 if let Some(ref step) = f.step {
19364 self.write(", ");
19365 self.generate_expression(step)?;
19366 }
19367 self.write(")");
19368 Ok(())
19369 }
19370
19371 fn generate_struct_constructor(&mut self, f: &StructConstructor) -> Result<()> {
19374 self.write_keyword("STRUCT");
19375 self.write("(");
19376 for (i, (name, expr)) in f.fields.iter().enumerate() {
19377 if i > 0 {
19378 self.write(", ");
19379 }
19380 if let Some(ref id) = name {
19381 self.generate_identifier(id)?;
19382 self.write(" ");
19383 self.write_keyword("AS");
19384 self.write(" ");
19385 }
19386 self.generate_expression(expr)?;
19387 }
19388 self.write(")");
19389 Ok(())
19390 }
19391
19392 fn generate_struct_function_cross_dialect(&mut self, func: &Function) -> Result<()> {
19394 let mut names: Vec<Option<String>> = Vec::new();
19397 let mut values: Vec<&Expression> = Vec::new();
19398 let mut all_named = true;
19399
19400 for arg in &func.args {
19401 match arg {
19402 Expression::Alias(a) => {
19403 names.push(Some(a.alias.name.clone()));
19404 values.push(&a.this);
19405 }
19406 _ => {
19407 names.push(None);
19408 values.push(arg);
19409 all_named = false;
19410 }
19411 }
19412 }
19413
19414 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
19415 self.write("{");
19417 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
19418 if i > 0 {
19419 self.write(", ");
19420 }
19421 if let Some(n) = name {
19422 self.write("'");
19423 self.write(n);
19424 self.write("'");
19425 } else {
19426 self.write("'_");
19427 self.write(&i.to_string());
19428 self.write("'");
19429 }
19430 self.write(": ");
19431 self.generate_expression(value)?;
19432 }
19433 self.write("}");
19434 return Ok(());
19435 }
19436
19437 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
19438 self.write_keyword("OBJECT_CONSTRUCT");
19440 self.write("(");
19441 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
19442 if i > 0 {
19443 self.write(", ");
19444 }
19445 if let Some(n) = name {
19446 self.write("'");
19447 self.write(n);
19448 self.write("'");
19449 } else {
19450 self.write("'_");
19451 self.write(&i.to_string());
19452 self.write("'");
19453 }
19454 self.write(", ");
19455 self.generate_expression(value)?;
19456 }
19457 self.write(")");
19458 return Ok(());
19459 }
19460
19461 if matches!(
19462 self.config.dialect,
19463 Some(DialectType::Presto) | Some(DialectType::Trino)
19464 ) {
19465 if all_named && !names.is_empty() {
19466 self.write_keyword("CAST");
19469 self.write("(");
19470 self.write_keyword("ROW");
19471 self.write("(");
19472 for (i, value) in values.iter().enumerate() {
19473 if i > 0 {
19474 self.write(", ");
19475 }
19476 self.generate_expression(value)?;
19477 }
19478 self.write(")");
19479 self.write(" ");
19480 self.write_keyword("AS");
19481 self.write(" ");
19482 self.write_keyword("ROW");
19483 self.write("(");
19484 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
19485 if i > 0 {
19486 self.write(", ");
19487 }
19488 if let Some(n) = name {
19489 self.write(n);
19490 }
19491 self.write(" ");
19492 let type_str = Self::infer_sql_type_for_presto(value);
19493 self.write_keyword(&type_str);
19494 }
19495 self.write(")");
19496 self.write(")");
19497 } else {
19498 self.write_keyword("ROW");
19500 self.write("(");
19501 for (i, value) in values.iter().enumerate() {
19502 if i > 0 {
19503 self.write(", ");
19504 }
19505 self.generate_expression(value)?;
19506 }
19507 self.write(")");
19508 }
19509 return Ok(());
19510 }
19511
19512 self.write_keyword("ROW");
19514 self.write("(");
19515 for (i, value) in values.iter().enumerate() {
19516 if i > 0 {
19517 self.write(", ");
19518 }
19519 self.generate_expression(value)?;
19520 }
19521 self.write(")");
19522 Ok(())
19523 }
19524
19525 fn infer_sql_type_for_presto(expr: &Expression) -> String {
19527 match expr {
19528 Expression::Literal(crate::expressions::Literal::String(_)) => "VARCHAR".to_string(),
19529 Expression::Literal(crate::expressions::Literal::Number(n)) => {
19530 if n.contains('.') {
19531 "DOUBLE".to_string()
19532 } else {
19533 "INTEGER".to_string()
19534 }
19535 }
19536 Expression::Boolean(_) => "BOOLEAN".to_string(),
19537 Expression::Literal(crate::expressions::Literal::Date(_)) => "DATE".to_string(),
19538 Expression::Literal(crate::expressions::Literal::Timestamp(_)) => {
19539 "TIMESTAMP".to_string()
19540 }
19541 Expression::Literal(crate::expressions::Literal::Datetime(_)) => {
19542 "TIMESTAMP".to_string()
19543 }
19544 Expression::Array(_) | Expression::ArrayFunc(_) => {
19545 "ARRAY(VARCHAR)".to_string()
19547 }
19548 Expression::Struct(_) | Expression::StructFunc(_) => "ROW".to_string(),
19550 Expression::Function(f) => {
19551 let up = f.name.to_uppercase();
19552 if up == "STRUCT" {
19553 "ROW".to_string()
19554 } else if up == "CURRENT_DATE" {
19555 "DATE".to_string()
19556 } else if up == "CURRENT_TIMESTAMP" || up == "NOW" {
19557 "TIMESTAMP".to_string()
19558 } else {
19559 "VARCHAR".to_string()
19560 }
19561 }
19562 _ => "VARCHAR".to_string(),
19563 }
19564 }
19565
19566 fn generate_struct_extract(&mut self, f: &StructExtractFunc) -> Result<()> {
19567 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
19569 self.write_keyword("STRUCT_EXTRACT");
19570 self.write("(");
19571 self.generate_expression(&f.this)?;
19572 self.write(", ");
19573 self.write("'");
19575 self.write(&f.field.name);
19576 self.write("'");
19577 self.write(")");
19578 return Ok(());
19579 }
19580 self.generate_expression(&f.this)?;
19581 self.write(".");
19582 self.generate_identifier(&f.field)
19583 }
19584
19585 fn generate_named_struct(&mut self, f: &NamedStructFunc) -> Result<()> {
19586 self.write_keyword("NAMED_STRUCT");
19587 self.write("(");
19588 for (i, (name, value)) in f.pairs.iter().enumerate() {
19589 if i > 0 {
19590 self.write(", ");
19591 }
19592 self.generate_expression(name)?;
19593 self.write(", ");
19594 self.generate_expression(value)?;
19595 }
19596 self.write(")");
19597 Ok(())
19598 }
19599
19600 fn generate_map_constructor(&mut self, f: &MapConstructor) -> Result<()> {
19603 if f.curly_brace_syntax {
19604 if f.with_map_keyword {
19606 self.write_keyword("MAP");
19607 self.write(" ");
19608 }
19609 self.write("{");
19610 for (i, (key, val)) in f.keys.iter().zip(f.values.iter()).enumerate() {
19611 if i > 0 {
19612 self.write(", ");
19613 }
19614 self.generate_expression(key)?;
19615 self.write(": ");
19616 self.generate_expression(val)?;
19617 }
19618 self.write("}");
19619 } else {
19620 self.write_keyword("MAP");
19622 self.write("(");
19623 self.write_keyword("ARRAY");
19624 self.write("[");
19625 for (i, key) in f.keys.iter().enumerate() {
19626 if i > 0 {
19627 self.write(", ");
19628 }
19629 self.generate_expression(key)?;
19630 }
19631 self.write("], ");
19632 self.write_keyword("ARRAY");
19633 self.write("[");
19634 for (i, val) in f.values.iter().enumerate() {
19635 if i > 0 {
19636 self.write(", ");
19637 }
19638 self.generate_expression(val)?;
19639 }
19640 self.write("])");
19641 }
19642 Ok(())
19643 }
19644
19645 fn generate_transform_func(&mut self, name: &str, f: &TransformFunc) -> Result<()> {
19646 self.write_keyword(name);
19647 self.write("(");
19648 self.generate_expression(&f.this)?;
19649 self.write(", ");
19650 self.generate_expression(&f.transform)?;
19651 self.write(")");
19652 Ok(())
19653 }
19654
19655 fn generate_json_extract(&mut self, name: &str, f: &JsonExtractFunc) -> Result<()> {
19658 use crate::dialects::DialectType;
19659
19660 let use_arrow = f.arrow_syntax && self.dialect_supports_json_arrow();
19662
19663 if use_arrow {
19664 self.generate_expression(&f.this)?;
19666 if name == "JSON_EXTRACT_SCALAR" || name == "JSON_EXTRACT_PATH_TEXT" {
19667 self.write(" ->> ");
19668 } else {
19669 self.write(" -> ");
19670 }
19671 self.generate_expression(&f.path)?;
19672 return Ok(());
19673 }
19674
19675 if f.hash_arrow_syntax
19677 && matches!(
19678 self.config.dialect,
19679 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
19680 )
19681 {
19682 self.generate_expression(&f.this)?;
19683 self.write(" #>> ");
19684 self.generate_expression(&f.path)?;
19685 return Ok(());
19686 }
19687
19688 let func_name = if matches!(self.config.dialect, Some(DialectType::Redshift)) {
19691 match name {
19692 "JSON_EXTRACT_SCALAR"
19693 | "JSON_EXTRACT_PATH_TEXT"
19694 | "JSON_EXTRACT"
19695 | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH_TEXT",
19696 _ => name,
19697 }
19698 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
19699 match name {
19700 "JSON_EXTRACT_SCALAR" | "JSON_EXTRACT_PATH_TEXT" => "JSON_EXTRACT_PATH_TEXT",
19701 "JSON_EXTRACT" | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH",
19702 _ => name,
19703 }
19704 } else {
19705 name
19706 };
19707
19708 self.write_keyword(func_name);
19709 self.write("(");
19710 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
19712 if let Expression::Cast(ref cast) = f.this {
19713 if matches!(cast.to, crate::expressions::DataType::Json) {
19714 self.generate_expression(&cast.this)?;
19715 } else {
19716 self.generate_expression(&f.this)?;
19717 }
19718 } else {
19719 self.generate_expression(&f.this)?;
19720 }
19721 } else {
19722 self.generate_expression(&f.this)?;
19723 }
19724 if matches!(
19727 self.config.dialect,
19728 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
19729 ) && (func_name == "JSON_EXTRACT_PATH" || func_name == "JSON_EXTRACT_PATH_TEXT")
19730 {
19731 if let Expression::Literal(Literal::String(ref s)) = f.path {
19732 let parts = Self::decompose_json_path(s);
19733 for part in &parts {
19734 self.write(", '");
19735 self.write(part);
19736 self.write("'");
19737 }
19738 } else {
19739 self.write(", ");
19740 self.generate_expression(&f.path)?;
19741 }
19742 } else {
19743 self.write(", ");
19744 self.generate_expression(&f.path)?;
19745 }
19746
19747 if let Some(ref wrapper) = f.wrapper_option {
19750 self.write_space();
19751 self.write_keyword(wrapper);
19752 }
19753 if let Some(ref quotes) = f.quotes_option {
19754 self.write_space();
19755 self.write_keyword(quotes);
19756 if f.on_scalar_string {
19757 self.write_space();
19758 self.write_keyword("ON SCALAR STRING");
19759 }
19760 }
19761 if let Some(ref on_err) = f.on_error {
19762 self.write_space();
19763 self.write_keyword(on_err);
19764 }
19765 if let Some(ref ret_type) = f.returning {
19766 self.write_space();
19767 self.write_keyword("RETURNING");
19768 self.write_space();
19769 self.generate_data_type(ret_type)?;
19770 }
19771
19772 self.write(")");
19773 Ok(())
19774 }
19775
19776 fn dialect_supports_json_arrow(&self) -> bool {
19778 use crate::dialects::DialectType;
19779 match self.config.dialect {
19780 Some(DialectType::PostgreSQL) => true,
19782 Some(DialectType::MySQL) => true,
19783 Some(DialectType::DuckDB) => true,
19784 Some(DialectType::CockroachDB) => true,
19785 Some(DialectType::StarRocks) => true,
19786 Some(DialectType::SQLite) => true,
19787 _ => false,
19789 }
19790 }
19791
19792 fn generate_json_path(&mut self, name: &str, f: &JsonPathFunc) -> Result<()> {
19793 use crate::dialects::DialectType;
19794
19795 if matches!(
19797 self.config.dialect,
19798 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
19799 ) && name == "JSON_EXTRACT_PATH"
19800 {
19801 self.generate_expression(&f.this)?;
19802 self.write(" #> ");
19803 if f.paths.len() == 1 {
19804 self.generate_expression(&f.paths[0])?;
19805 } else {
19806 self.write_keyword("ARRAY");
19808 self.write("[");
19809 for (i, path) in f.paths.iter().enumerate() {
19810 if i > 0 {
19811 self.write(", ");
19812 }
19813 self.generate_expression(path)?;
19814 }
19815 self.write("]");
19816 }
19817 return Ok(());
19818 }
19819
19820 self.write_keyword(name);
19821 self.write("(");
19822 self.generate_expression(&f.this)?;
19823 for path in &f.paths {
19824 self.write(", ");
19825 self.generate_expression(path)?;
19826 }
19827 self.write(")");
19828 Ok(())
19829 }
19830
19831 fn generate_json_object(&mut self, f: &JsonObjectFunc) -> Result<()> {
19832 use crate::dialects::DialectType;
19833
19834 self.write_keyword("JSON_OBJECT");
19835 self.write("(");
19836 if f.star {
19837 self.write("*");
19838 } else {
19839 let use_comma_syntax = self.config.json_key_value_pair_sep == ","
19843 || matches!(
19844 self.config.dialect,
19845 Some(DialectType::BigQuery)
19846 | Some(DialectType::MySQL)
19847 | Some(DialectType::SQLite)
19848 );
19849
19850 for (i, (key, value)) in f.pairs.iter().enumerate() {
19851 if i > 0 {
19852 self.write(", ");
19853 }
19854 self.generate_expression(key)?;
19855 if use_comma_syntax {
19856 self.write(", ");
19857 } else {
19858 self.write(": ");
19859 }
19860 self.generate_expression(value)?;
19861 }
19862 }
19863 if let Some(null_handling) = f.null_handling {
19864 self.write_space();
19865 match null_handling {
19866 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
19867 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
19868 }
19869 }
19870 if f.with_unique_keys {
19871 self.write_space();
19872 self.write_keyword("WITH UNIQUE KEYS");
19873 }
19874 if let Some(ref ret_type) = f.returning_type {
19875 self.write_space();
19876 self.write_keyword("RETURNING");
19877 self.write_space();
19878 self.generate_data_type(ret_type)?;
19879 if f.format_json {
19880 self.write_space();
19881 self.write_keyword("FORMAT JSON");
19882 }
19883 if let Some(ref enc) = f.encoding {
19884 self.write_space();
19885 self.write_keyword("ENCODING");
19886 self.write_space();
19887 self.write(enc);
19888 }
19889 }
19890 self.write(")");
19891 Ok(())
19892 }
19893
19894 fn generate_json_modify(&mut self, name: &str, f: &JsonModifyFunc) -> Result<()> {
19895 self.write_keyword(name);
19896 self.write("(");
19897 self.generate_expression(&f.this)?;
19898 for (path, value) in &f.path_values {
19899 self.write(", ");
19900 self.generate_expression(path)?;
19901 self.write(", ");
19902 self.generate_expression(value)?;
19903 }
19904 self.write(")");
19905 Ok(())
19906 }
19907
19908 fn generate_json_array_agg(&mut self, f: &JsonArrayAggFunc) -> Result<()> {
19909 self.write_keyword("JSON_ARRAYAGG");
19910 self.write("(");
19911 self.generate_expression(&f.this)?;
19912 if let Some(ref order_by) = f.order_by {
19913 self.write_space();
19914 self.write_keyword("ORDER BY");
19915 self.write_space();
19916 for (i, ord) in order_by.iter().enumerate() {
19917 if i > 0 {
19918 self.write(", ");
19919 }
19920 self.generate_ordered(ord)?;
19921 }
19922 }
19923 if let Some(null_handling) = f.null_handling {
19924 self.write_space();
19925 match null_handling {
19926 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
19927 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
19928 }
19929 }
19930 self.write(")");
19931 if let Some(ref filter) = f.filter {
19932 self.write_space();
19933 self.write_keyword("FILTER");
19934 self.write("(");
19935 self.write_keyword("WHERE");
19936 self.write_space();
19937 self.generate_expression(filter)?;
19938 self.write(")");
19939 }
19940 Ok(())
19941 }
19942
19943 fn generate_json_object_agg(&mut self, f: &JsonObjectAggFunc) -> Result<()> {
19944 self.write_keyword("JSON_OBJECTAGG");
19945 self.write("(");
19946 self.generate_expression(&f.key)?;
19947 self.write(": ");
19948 self.generate_expression(&f.value)?;
19949 if let Some(null_handling) = f.null_handling {
19950 self.write_space();
19951 match null_handling {
19952 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
19953 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
19954 }
19955 }
19956 self.write(")");
19957 if let Some(ref filter) = f.filter {
19958 self.write_space();
19959 self.write_keyword("FILTER");
19960 self.write("(");
19961 self.write_keyword("WHERE");
19962 self.write_space();
19963 self.generate_expression(filter)?;
19964 self.write(")");
19965 }
19966 Ok(())
19967 }
19968
19969 fn generate_convert(&mut self, f: &ConvertFunc) -> Result<()> {
19972 use crate::dialects::DialectType;
19973
19974 if self.config.dialect == Some(DialectType::Redshift) {
19976 self.write_keyword("CAST");
19977 self.write("(");
19978 self.generate_expression(&f.this)?;
19979 self.write_space();
19980 self.write_keyword("AS");
19981 self.write_space();
19982 self.generate_data_type(&f.to)?;
19983 self.write(")");
19984 return Ok(());
19985 }
19986
19987 self.write_keyword("CONVERT");
19988 self.write("(");
19989 self.generate_data_type(&f.to)?;
19990 self.write(", ");
19991 self.generate_expression(&f.this)?;
19992 if let Some(ref style) = f.style {
19993 self.write(", ");
19994 self.generate_expression(style)?;
19995 }
19996 self.write(")");
19997 Ok(())
19998 }
19999
20000 fn generate_lambda(&mut self, f: &LambdaExpr) -> Result<()> {
20003 if f.colon {
20004 self.write_keyword("LAMBDA");
20006 self.write_space();
20007 for (i, param) in f.parameters.iter().enumerate() {
20008 if i > 0 {
20009 self.write(", ");
20010 }
20011 self.generate_identifier(param)?;
20012 }
20013 self.write(" : ");
20014 } else {
20015 if f.parameters.len() == 1 {
20017 self.generate_identifier(&f.parameters[0])?;
20018 } else {
20019 self.write("(");
20020 for (i, param) in f.parameters.iter().enumerate() {
20021 if i > 0 {
20022 self.write(", ");
20023 }
20024 self.generate_identifier(param)?;
20025 }
20026 self.write(")");
20027 }
20028 self.write(" -> ");
20029 }
20030 self.generate_expression(&f.body)
20031 }
20032
20033 fn generate_named_argument(&mut self, f: &NamedArgument) -> Result<()> {
20034 self.generate_identifier(&f.name)?;
20035 match f.separator {
20036 NamedArgSeparator::DArrow => self.write(" => "),
20037 NamedArgSeparator::ColonEq => self.write(" := "),
20038 NamedArgSeparator::Eq => self.write(" = "),
20039 }
20040 self.generate_expression(&f.value)
20041 }
20042
20043 fn generate_table_argument(&mut self, f: &TableArgument) -> Result<()> {
20044 self.write_keyword(&f.prefix);
20045 self.write(" ");
20046 self.generate_expression(&f.this)
20047 }
20048
20049 fn generate_parameter(&mut self, f: &Parameter) -> Result<()> {
20050 match f.style {
20051 ParameterStyle::Question => self.write("?"),
20052 ParameterStyle::Dollar => {
20053 self.write("$");
20054 if let Some(idx) = f.index {
20055 self.write(&idx.to_string());
20056 } else if let Some(ref name) = f.name {
20057 self.write(name);
20059 }
20060 }
20061 ParameterStyle::DollarBrace => {
20062 self.write("${");
20064 if let Some(ref name) = f.name {
20065 self.write(name);
20066 }
20067 if let Some(ref expr) = f.expression {
20068 self.write(":");
20069 self.write(expr);
20070 }
20071 self.write("}");
20072 }
20073 ParameterStyle::Colon => {
20074 self.write(":");
20075 if let Some(idx) = f.index {
20076 self.write(&idx.to_string());
20077 } else if let Some(ref name) = f.name {
20078 self.write(name);
20079 }
20080 }
20081 ParameterStyle::At => {
20082 self.write("@");
20083 if let Some(ref name) = f.name {
20084 if f.string_quoted {
20085 self.write("'");
20086 self.write(name);
20087 self.write("'");
20088 } else if f.quoted {
20089 self.write("\"");
20090 self.write(name);
20091 self.write("\"");
20092 } else {
20093 self.write(name);
20094 }
20095 }
20096 }
20097 ParameterStyle::DoubleAt => {
20098 self.write("@@");
20099 if let Some(ref name) = f.name {
20100 self.write(name);
20101 }
20102 }
20103 ParameterStyle::DoubleDollar => {
20104 self.write("$$");
20105 if let Some(ref name) = f.name {
20106 self.write(name);
20107 }
20108 }
20109 ParameterStyle::Percent => {
20110 if let Some(ref name) = f.name {
20111 self.write("%(");
20113 self.write(name);
20114 self.write(")s");
20115 } else {
20116 self.write("%s");
20118 }
20119 }
20120 ParameterStyle::Brace => {
20121 self.write("{");
20124 if let Some(ref name) = f.name {
20125 self.write(name);
20126 }
20127 if let Some(ref expr) = f.expression {
20128 self.write(": ");
20129 self.write(expr);
20130 }
20131 self.write("}");
20132 }
20133 }
20134 Ok(())
20135 }
20136
20137 fn generate_placeholder(&mut self, f: &Placeholder) -> Result<()> {
20138 self.write("?");
20139 if let Some(idx) = f.index {
20140 self.write(&idx.to_string());
20141 }
20142 Ok(())
20143 }
20144
20145 fn generate_sql_comment(&mut self, f: &SqlComment) -> Result<()> {
20146 if f.is_block {
20147 self.write("/*");
20148 self.write(&f.text);
20149 self.write("*/");
20150 } else {
20151 self.write("--");
20152 self.write(&f.text);
20153 }
20154 Ok(())
20155 }
20156
20157 fn generate_similar_to(&mut self, f: &SimilarToExpr) -> Result<()> {
20160 self.generate_expression(&f.this)?;
20161 if f.not {
20162 self.write_space();
20163 self.write_keyword("NOT");
20164 }
20165 self.write_space();
20166 self.write_keyword("SIMILAR TO");
20167 self.write_space();
20168 self.generate_expression(&f.pattern)?;
20169 if let Some(ref escape) = f.escape {
20170 self.write_space();
20171 self.write_keyword("ESCAPE");
20172 self.write_space();
20173 self.generate_expression(escape)?;
20174 }
20175 Ok(())
20176 }
20177
20178 fn generate_quantified(&mut self, name: &str, f: &QuantifiedExpr) -> Result<()> {
20179 self.generate_expression(&f.this)?;
20180 self.write_space();
20181 if let Some(op) = &f.op {
20183 match op {
20184 QuantifiedOp::Eq => self.write("="),
20185 QuantifiedOp::Neq => self.write("<>"),
20186 QuantifiedOp::Lt => self.write("<"),
20187 QuantifiedOp::Lte => self.write("<="),
20188 QuantifiedOp::Gt => self.write(">"),
20189 QuantifiedOp::Gte => self.write(">="),
20190 }
20191 self.write_space();
20192 }
20193 self.write_keyword(name);
20194
20195 if matches!(&f.subquery, Expression::Subquery(_)) {
20197 self.write_space();
20198 self.generate_expression(&f.subquery)?;
20199 } else {
20200 self.write("(");
20201
20202 let is_statement = matches!(
20203 &f.subquery,
20204 Expression::Select(_)
20205 | Expression::Union(_)
20206 | Expression::Intersect(_)
20207 | Expression::Except(_)
20208 );
20209
20210 if self.config.pretty && is_statement {
20211 self.write_newline();
20212 self.indent_level += 1;
20213 self.write_indent();
20214 }
20215 self.generate_expression(&f.subquery)?;
20216 if self.config.pretty && is_statement {
20217 self.write_newline();
20218 self.indent_level -= 1;
20219 self.write_indent();
20220 }
20221 self.write(")");
20222 }
20223 Ok(())
20224 }
20225
20226 fn generate_overlaps(&mut self, f: &OverlapsExpr) -> Result<()> {
20227 if let (Some(this), Some(expr)) = (&f.this, &f.expression) {
20229 self.generate_expression(this)?;
20230 self.write_space();
20231 self.write_keyword("OVERLAPS");
20232 self.write_space();
20233 self.generate_expression(expr)?;
20234 } else if let (Some(ls), Some(le), Some(rs), Some(re)) =
20235 (&f.left_start, &f.left_end, &f.right_start, &f.right_end)
20236 {
20237 self.write("(");
20239 self.generate_expression(ls)?;
20240 self.write(", ");
20241 self.generate_expression(le)?;
20242 self.write(")");
20243 self.write_space();
20244 self.write_keyword("OVERLAPS");
20245 self.write_space();
20246 self.write("(");
20247 self.generate_expression(rs)?;
20248 self.write(", ");
20249 self.generate_expression(re)?;
20250 self.write(")");
20251 }
20252 Ok(())
20253 }
20254
20255 fn generate_try_cast(&mut self, cast: &Cast) -> Result<()> {
20258 use crate::dialects::DialectType;
20259
20260 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
20262 self.generate_expression(&cast.this)?;
20263 self.write(" !:> ");
20264 self.generate_data_type(&cast.to)?;
20265 return Ok(());
20266 }
20267
20268 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
20270 self.write_keyword("TRYCAST");
20271 self.write("(");
20272 self.generate_expression(&cast.this)?;
20273 self.write_space();
20274 self.write_keyword("AS");
20275 self.write_space();
20276 self.generate_data_type(&cast.to)?;
20277 self.write(")");
20278 return Ok(());
20279 }
20280
20281 let keyword = if matches!(
20283 self.config.dialect,
20284 Some(DialectType::Hive)
20285 | Some(DialectType::MySQL)
20286 | Some(DialectType::SQLite)
20287 | Some(DialectType::Oracle)
20288 | Some(DialectType::ClickHouse)
20289 | Some(DialectType::Redshift)
20290 | Some(DialectType::PostgreSQL)
20291 | Some(DialectType::StarRocks)
20292 | Some(DialectType::Doris)
20293 ) {
20294 "CAST"
20295 } else {
20296 "TRY_CAST"
20297 };
20298
20299 self.write_keyword(keyword);
20300 self.write("(");
20301 self.generate_expression(&cast.this)?;
20302 self.write_space();
20303 self.write_keyword("AS");
20304 self.write_space();
20305 self.generate_data_type(&cast.to)?;
20306
20307 if let Some(format) = &cast.format {
20309 self.write_space();
20310 self.write_keyword("FORMAT");
20311 self.write_space();
20312 self.generate_expression(format)?;
20313 }
20314
20315 self.write(")");
20316 Ok(())
20317 }
20318
20319 fn generate_safe_cast(&mut self, cast: &Cast) -> Result<()> {
20320 self.write_keyword("SAFE_CAST");
20321 self.write("(");
20322 self.generate_expression(&cast.this)?;
20323 self.write_space();
20324 self.write_keyword("AS");
20325 self.write_space();
20326 self.generate_data_type(&cast.to)?;
20327
20328 if let Some(format) = &cast.format {
20330 self.write_space();
20331 self.write_keyword("FORMAT");
20332 self.write_space();
20333 self.generate_expression(format)?;
20334 }
20335
20336 self.write(")");
20337 Ok(())
20338 }
20339
20340 fn generate_subscript(&mut self, s: &Subscript) -> Result<()> {
20343 self.generate_expression(&s.this)?;
20344 self.write("[");
20345 self.generate_expression(&s.index)?;
20346 self.write("]");
20347 Ok(())
20348 }
20349
20350 fn generate_dot_access(&mut self, d: &DotAccess) -> Result<()> {
20351 self.generate_expression(&d.this)?;
20352 let use_colon = matches!(self.config.dialect, Some(DialectType::Snowflake))
20355 && matches!(
20356 &d.this,
20357 Expression::Cast(_) | Expression::SafeCast(_) | Expression::TryCast(_)
20358 );
20359 if use_colon {
20360 self.write(":");
20361 } else {
20362 self.write(".");
20363 }
20364 self.generate_identifier(&d.field)
20365 }
20366
20367 fn generate_method_call(&mut self, m: &MethodCall) -> Result<()> {
20368 self.generate_expression(&m.this)?;
20369 self.write(".");
20370 if m.method.quoted {
20373 let q = self.config.identifier_quote;
20374 self.write(&format!("{}{}{}", q, m.method.name, q));
20375 } else {
20376 self.write(&m.method.name);
20377 }
20378 self.write("(");
20379 for (i, arg) in m.args.iter().enumerate() {
20380 if i > 0 {
20381 self.write(", ");
20382 }
20383 self.generate_expression(arg)?;
20384 }
20385 self.write(")");
20386 Ok(())
20387 }
20388
20389 fn generate_array_slice(&mut self, s: &ArraySlice) -> Result<()> {
20390 let needs_parens = matches!(
20393 &s.this,
20394 Expression::JsonExtract(f) if f.arrow_syntax
20395 ) || matches!(
20396 &s.this,
20397 Expression::JsonExtractScalar(f) if f.arrow_syntax
20398 );
20399
20400 if needs_parens {
20401 self.write("(");
20402 }
20403 self.generate_expression(&s.this)?;
20404 if needs_parens {
20405 self.write(")");
20406 }
20407 self.write("[");
20408 if let Some(start) = &s.start {
20409 self.generate_expression(start)?;
20410 }
20411 self.write(":");
20412 if let Some(end) = &s.end {
20413 self.generate_expression(end)?;
20414 }
20415 self.write("]");
20416 Ok(())
20417 }
20418
20419 fn generate_binary_op(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
20420 match &op.left {
20424 Expression::Column(col) => {
20425 if let Some(table) = &col.table {
20428 self.generate_identifier(table)?;
20429 self.write(".");
20430 }
20431 self.generate_identifier(&col.name)?;
20432 if col.join_mark && self.config.supports_column_join_marks {
20434 self.write(" (+)");
20435 }
20436 if op.left_comments.is_empty() {
20438 for comment in &col.trailing_comments {
20439 self.write_space();
20440 self.write_formatted_comment(comment);
20441 }
20442 }
20443 }
20444 Expression::Add(inner_op)
20445 | Expression::Sub(inner_op)
20446 | Expression::Mul(inner_op)
20447 | Expression::Div(inner_op)
20448 | Expression::Concat(inner_op) => {
20449 self.generate_binary_op_no_trailing(inner_op, match &op.left {
20451 Expression::Add(_) => "+",
20452 Expression::Sub(_) => "-",
20453 Expression::Mul(_) => "*",
20454 Expression::Div(_) => "/",
20455 Expression::Concat(_) => "||",
20456 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
20457 })?;
20458 }
20459 _ => {
20460 self.generate_expression(&op.left)?;
20461 }
20462 }
20463 for comment in &op.left_comments {
20465 self.write_space();
20466 self.write_formatted_comment(comment);
20467 }
20468 if self.config.pretty
20469 && matches!(self.config.dialect, Some(DialectType::Snowflake))
20470 && (operator == "AND" || operator == "OR")
20471 {
20472 self.write_newline();
20473 self.write_indent();
20474 self.write_keyword(operator);
20475 } else {
20476 self.write_space();
20477 if operator.chars().all(|c| c.is_alphabetic()) {
20478 self.write_keyword(operator);
20479 } else {
20480 self.write(operator);
20481 }
20482 }
20483 for comment in &op.operator_comments {
20485 self.write_space();
20486 self.write_formatted_comment(comment);
20487 }
20488 self.write_space();
20489 self.generate_expression(&op.right)?;
20490 for comment in &op.trailing_comments {
20492 self.write_space();
20493 self.write_formatted_comment(comment);
20494 }
20495 Ok(())
20496 }
20497
20498 fn generate_connector_op(&mut self, op: &BinaryOp, connector: ConnectorOperator) -> Result<()> {
20499 let keyword = connector.keyword();
20500 let Some(terms) = self.flatten_connector_terms(op, connector) else {
20501 return self.generate_binary_op(op, keyword);
20502 };
20503
20504 self.generate_expression(terms[0])?;
20505 for term in terms.iter().skip(1) {
20506 if self.config.pretty && matches!(self.config.dialect, Some(DialectType::Snowflake)) {
20507 self.write_newline();
20508 self.write_indent();
20509 self.write_keyword(keyword);
20510 } else {
20511 self.write_space();
20512 self.write_keyword(keyword);
20513 }
20514 self.write_space();
20515 self.generate_expression(term)?;
20516 }
20517
20518 Ok(())
20519 }
20520
20521 fn flatten_connector_terms<'a>(
20522 &self,
20523 root: &'a BinaryOp,
20524 connector: ConnectorOperator,
20525 ) -> Option<Vec<&'a Expression>> {
20526 if !root.left_comments.is_empty()
20527 || !root.operator_comments.is_empty()
20528 || !root.trailing_comments.is_empty()
20529 {
20530 return None;
20531 }
20532
20533 let mut terms = Vec::new();
20534 let mut stack: Vec<&Expression> = vec![&root.right, &root.left];
20535
20536 while let Some(expr) = stack.pop() {
20537 match (connector, expr) {
20538 (ConnectorOperator::And, Expression::And(inner))
20539 if inner.left_comments.is_empty()
20540 && inner.operator_comments.is_empty()
20541 && inner.trailing_comments.is_empty() =>
20542 {
20543 stack.push(&inner.right);
20544 stack.push(&inner.left);
20545 }
20546 (ConnectorOperator::Or, Expression::Or(inner))
20547 if inner.left_comments.is_empty()
20548 && inner.operator_comments.is_empty()
20549 && inner.trailing_comments.is_empty() =>
20550 {
20551 stack.push(&inner.right);
20552 stack.push(&inner.left);
20553 }
20554 _ => terms.push(expr),
20555 }
20556 }
20557
20558 if terms.len() > 1 {
20559 Some(terms)
20560 } else {
20561 None
20562 }
20563 }
20564
20565 fn generate_like_op(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
20567 self.generate_expression(&op.left)?;
20568 self.write_space();
20569 if operator == "ILIKE" && matches!(self.config.dialect, Some(DialectType::Drill)) {
20571 self.write("`ILIKE`");
20572 } else {
20573 self.write_keyword(operator);
20574 }
20575 if let Some(quantifier) = &op.quantifier {
20576 self.write_space();
20577 self.write_keyword(quantifier);
20578 }
20579 self.write_space();
20580 self.generate_expression(&op.right)?;
20581 if let Some(escape) = &op.escape {
20582 self.write_space();
20583 self.write_keyword("ESCAPE");
20584 self.write_space();
20585 self.generate_expression(escape)?;
20586 }
20587 Ok(())
20588 }
20589
20590 fn generate_null_safe_eq(&mut self, op: &BinaryOp) -> Result<()> {
20593 use crate::dialects::DialectType;
20594 self.generate_expression(&op.left)?;
20595 self.write_space();
20596 if matches!(self.config.dialect, Some(DialectType::MySQL)) {
20597 self.write("<=>");
20598 } else {
20599 self.write_keyword("IS NOT DISTINCT FROM");
20600 }
20601 self.write_space();
20602 self.generate_expression(&op.right)?;
20603 Ok(())
20604 }
20605
20606 fn generate_null_safe_neq(&mut self, op: &BinaryOp) -> Result<()> {
20608 self.generate_expression(&op.left)?;
20609 self.write_space();
20610 self.write_keyword("IS DISTINCT FROM");
20611 self.write_space();
20612 self.generate_expression(&op.right)?;
20613 Ok(())
20614 }
20615
20616 fn generate_binary_op_no_trailing(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
20618 match &op.left {
20620 Expression::Column(col) => {
20621 if let Some(table) = &col.table {
20622 self.generate_identifier(table)?;
20623 self.write(".");
20624 }
20625 self.generate_identifier(&col.name)?;
20626 if col.join_mark && self.config.supports_column_join_marks {
20628 self.write(" (+)");
20629 }
20630 }
20631 Expression::Add(inner_op)
20632 | Expression::Sub(inner_op)
20633 | Expression::Mul(inner_op)
20634 | Expression::Div(inner_op)
20635 | Expression::Concat(inner_op) => {
20636 self.generate_binary_op_no_trailing(inner_op, match &op.left {
20637 Expression::Add(_) => "+",
20638 Expression::Sub(_) => "-",
20639 Expression::Mul(_) => "*",
20640 Expression::Div(_) => "/",
20641 Expression::Concat(_) => "||",
20642 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
20643 })?;
20644 }
20645 _ => {
20646 self.generate_expression(&op.left)?;
20647 }
20648 }
20649 for comment in &op.left_comments {
20651 self.write_space();
20652 self.write_formatted_comment(comment);
20653 }
20654 self.write_space();
20655 if operator.chars().all(|c| c.is_alphabetic()) {
20656 self.write_keyword(operator);
20657 } else {
20658 self.write(operator);
20659 }
20660 for comment in &op.operator_comments {
20662 self.write_space();
20663 self.write_formatted_comment(comment);
20664 }
20665 self.write_space();
20666 match &op.right {
20669 Expression::Column(col) => {
20670 if let Some(table) = &col.table {
20671 self.generate_identifier(table)?;
20672 self.write(".");
20673 }
20674 self.generate_identifier(&col.name)?;
20675 if col.join_mark && self.config.supports_column_join_marks {
20677 self.write(" (+)");
20678 }
20679 }
20680 _ => {
20681 self.generate_expression(&op.right)?;
20682 }
20683 }
20684 Ok(())
20686 }
20687
20688 fn generate_unary_op(&mut self, op: &UnaryOp, operator: &str) -> Result<()> {
20689 if operator.chars().all(|c| c.is_alphabetic()) {
20690 self.write_keyword(operator);
20691 self.write_space();
20692 } else {
20693 self.write(operator);
20694 if matches!(&op.this, Expression::Neg(_) | Expression::BitwiseNot(_)) {
20696 self.write_space();
20697 }
20698 }
20699 self.generate_expression(&op.this)
20700 }
20701
20702 fn generate_in(&mut self, in_expr: &In) -> Result<()> {
20703 let is_generic =
20707 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
20708 let use_prefix_not =
20709 in_expr.not && is_generic && self.config.not_in_style == NotInStyle::Prefix;
20710 if use_prefix_not {
20711 self.write_keyword("NOT");
20712 self.write_space();
20713 }
20714 self.generate_expression(&in_expr.this)?;
20715 if in_expr.global {
20716 self.write_space();
20717 self.write_keyword("GLOBAL");
20718 }
20719 if in_expr.not && !use_prefix_not {
20720 self.write_space();
20721 self.write_keyword("NOT");
20722 }
20723 self.write_space();
20724 self.write_keyword("IN");
20725
20726 if let Some(unnest_expr) = &in_expr.unnest {
20728 self.write_space();
20729 self.write_keyword("UNNEST");
20730 self.write("(");
20731 self.generate_expression(unnest_expr)?;
20732 self.write(")");
20733 return Ok(());
20734 }
20735
20736 if let Some(query) = &in_expr.query {
20737 let is_bare = in_expr.expressions.is_empty()
20740 && !matches!(
20741 query,
20742 Expression::Select(_)
20743 | Expression::Union(_)
20744 | Expression::Intersect(_)
20745 | Expression::Except(_)
20746 | Expression::Subquery(_)
20747 );
20748 if is_bare {
20749 self.write_space();
20751 self.generate_expression(query)?;
20752 } else {
20753 self.write(" (");
20755 let is_statement = matches!(
20756 query,
20757 Expression::Select(_)
20758 | Expression::Union(_)
20759 | Expression::Intersect(_)
20760 | Expression::Except(_)
20761 | Expression::Subquery(_)
20762 );
20763 if self.config.pretty && is_statement {
20764 self.write_newline();
20765 self.indent_level += 1;
20766 self.write_indent();
20767 }
20768 self.generate_expression(query)?;
20769 if self.config.pretty && is_statement {
20770 self.write_newline();
20771 self.indent_level -= 1;
20772 self.write_indent();
20773 }
20774 self.write(")");
20775 }
20776 } else {
20777 let is_duckdb = matches!(
20781 self.config.dialect,
20782 Some(crate::dialects::DialectType::DuckDB)
20783 );
20784 let is_clickhouse = matches!(
20785 self.config.dialect,
20786 Some(crate::dialects::DialectType::ClickHouse)
20787 );
20788 let single_expr = in_expr.expressions.len() == 1;
20789 if is_clickhouse && single_expr {
20790 if let Expression::Array(arr) = &in_expr.expressions[0] {
20791 self.write(" (");
20793 for (i, expr) in arr.expressions.iter().enumerate() {
20794 if i > 0 {
20795 self.write(", ");
20796 }
20797 self.generate_expression(expr)?;
20798 }
20799 self.write(")");
20800 } else {
20801 self.write_space();
20802 self.generate_expression(&in_expr.expressions[0])?;
20803 }
20804 } else {
20805 let is_bare_ref = single_expr
20806 && matches!(
20807 &in_expr.expressions[0],
20808 Expression::Column(_) | Expression::Identifier(_) | Expression::Dot(_)
20809 );
20810 if (is_duckdb && is_bare_ref) || (in_expr.is_field && single_expr) {
20811 self.write_space();
20814 self.generate_expression(&in_expr.expressions[0])?;
20815 } else {
20816 self.write(" (");
20818 for (i, expr) in in_expr.expressions.iter().enumerate() {
20819 if i > 0 {
20820 self.write(", ");
20821 }
20822 self.generate_expression(expr)?;
20823 }
20824 self.write(")");
20825 }
20826 }
20827 }
20828
20829 Ok(())
20830 }
20831
20832 fn generate_between(&mut self, between: &Between) -> Result<()> {
20833 let use_prefix_not = between.not
20835 && (self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic));
20836 if use_prefix_not {
20837 self.write_keyword("NOT");
20838 self.write_space();
20839 }
20840 self.generate_expression(&between.this)?;
20841 if between.not && !use_prefix_not {
20842 self.write_space();
20843 self.write_keyword("NOT");
20844 }
20845 self.write_space();
20846 self.write_keyword("BETWEEN");
20847 if let Some(sym) = between.symmetric {
20849 if sym {
20850 self.write(" SYMMETRIC");
20851 } else {
20852 self.write(" ASYMMETRIC");
20853 }
20854 }
20855 self.write_space();
20856 self.generate_expression(&between.low)?;
20857 self.write_space();
20858 self.write_keyword("AND");
20859 self.write_space();
20860 self.generate_expression(&between.high)
20861 }
20862
20863 fn generate_is_null(&mut self, is_null: &IsNull) -> Result<()> {
20864 let use_prefix_not = is_null.not
20866 && (self.config.dialect.is_none()
20867 || self.config.dialect == Some(DialectType::Generic)
20868 || is_null.postfix_form);
20869 if use_prefix_not {
20870 self.write_keyword("NOT");
20872 self.write_space();
20873 self.generate_expression(&is_null.this)?;
20874 self.write_space();
20875 self.write_keyword("IS");
20876 self.write_space();
20877 self.write_keyword("NULL");
20878 } else {
20879 self.generate_expression(&is_null.this)?;
20880 self.write_space();
20881 self.write_keyword("IS");
20882 if is_null.not {
20883 self.write_space();
20884 self.write_keyword("NOT");
20885 }
20886 self.write_space();
20887 self.write_keyword("NULL");
20888 }
20889 Ok(())
20890 }
20891
20892 fn generate_is_true(&mut self, is_true: &IsTrueFalse) -> Result<()> {
20893 self.generate_expression(&is_true.this)?;
20894 self.write_space();
20895 self.write_keyword("IS");
20896 if is_true.not {
20897 self.write_space();
20898 self.write_keyword("NOT");
20899 }
20900 self.write_space();
20901 self.write_keyword("TRUE");
20902 Ok(())
20903 }
20904
20905 fn generate_is_false(&mut self, is_false: &IsTrueFalse) -> Result<()> {
20906 self.generate_expression(&is_false.this)?;
20907 self.write_space();
20908 self.write_keyword("IS");
20909 if is_false.not {
20910 self.write_space();
20911 self.write_keyword("NOT");
20912 }
20913 self.write_space();
20914 self.write_keyword("FALSE");
20915 Ok(())
20916 }
20917
20918 fn generate_is_json(&mut self, is_json: &IsJson) -> Result<()> {
20919 self.generate_expression(&is_json.this)?;
20920 self.write_space();
20921 self.write_keyword("IS");
20922 if is_json.negated {
20923 self.write_space();
20924 self.write_keyword("NOT");
20925 }
20926 self.write_space();
20927 self.write_keyword("JSON");
20928
20929 if let Some(ref json_type) = is_json.json_type {
20931 self.write_space();
20932 self.write_keyword(json_type);
20933 }
20934
20935 match &is_json.unique_keys {
20937 Some(JsonUniqueKeys::With) => {
20938 self.write_space();
20939 self.write_keyword("WITH UNIQUE KEYS");
20940 }
20941 Some(JsonUniqueKeys::Without) => {
20942 self.write_space();
20943 self.write_keyword("WITHOUT UNIQUE KEYS");
20944 }
20945 Some(JsonUniqueKeys::Shorthand) => {
20946 self.write_space();
20947 self.write_keyword("UNIQUE KEYS");
20948 }
20949 None => {}
20950 }
20951
20952 Ok(())
20953 }
20954
20955 fn generate_is(&mut self, is_expr: &BinaryOp) -> Result<()> {
20956 self.generate_expression(&is_expr.left)?;
20957 self.write_space();
20958 self.write_keyword("IS");
20959 self.write_space();
20960 self.generate_expression(&is_expr.right)
20961 }
20962
20963 fn generate_exists(&mut self, exists: &Exists) -> Result<()> {
20964 if exists.not {
20965 self.write_keyword("NOT");
20966 self.write_space();
20967 }
20968 self.write_keyword("EXISTS");
20969 self.write("(");
20970 let is_statement = matches!(
20971 &exists.this,
20972 Expression::Select(_)
20973 | Expression::Union(_)
20974 | Expression::Intersect(_)
20975 | Expression::Except(_)
20976 );
20977 if self.config.pretty && is_statement {
20978 self.write_newline();
20979 self.indent_level += 1;
20980 self.write_indent();
20981 self.generate_expression(&exists.this)?;
20982 self.write_newline();
20983 self.indent_level -= 1;
20984 self.write_indent();
20985 self.write(")");
20986 } else {
20987 self.generate_expression(&exists.this)?;
20988 self.write(")");
20989 }
20990 Ok(())
20991 }
20992
20993 fn generate_member_of(&mut self, op: &BinaryOp) -> Result<()> {
20994 self.generate_expression(&op.left)?;
20995 self.write_space();
20996 self.write_keyword("MEMBER OF");
20997 self.write("(");
20998 self.generate_expression(&op.right)?;
20999 self.write(")");
21000 Ok(())
21001 }
21002
21003 fn generate_subquery(&mut self, subquery: &Subquery) -> Result<()> {
21004 if subquery.lateral {
21005 self.write_keyword("LATERAL");
21006 self.write_space();
21007 }
21008
21009 let skip_outer_parens = if let Expression::Paren(ref p) = &subquery.this {
21013 matches!(
21014 &p.this,
21015 Expression::Select(_)
21016 | Expression::Union(_)
21017 | Expression::Intersect(_)
21018 | Expression::Except(_)
21019 | Expression::Subquery(_)
21020 )
21021 } else {
21022 false
21023 };
21024
21025 let is_statement = matches!(
21027 &subquery.this,
21028 Expression::Select(_)
21029 | Expression::Union(_)
21030 | Expression::Intersect(_)
21031 | Expression::Except(_)
21032 | Expression::Merge(_)
21033 );
21034
21035 if !skip_outer_parens {
21036 self.write("(");
21037 if self.config.pretty && is_statement {
21038 self.write_newline();
21039 self.indent_level += 1;
21040 self.write_indent();
21041 }
21042 }
21043 self.generate_expression(&subquery.this)?;
21044
21045 if subquery.modifiers_inside {
21047 if let Some(order_by) = &subquery.order_by {
21049 self.write_space();
21050 self.write_keyword("ORDER BY");
21051 self.write_space();
21052 for (i, ord) in order_by.expressions.iter().enumerate() {
21053 if i > 0 {
21054 self.write(", ");
21055 }
21056 self.generate_ordered(ord)?;
21057 }
21058 }
21059
21060 if let Some(limit) = &subquery.limit {
21061 self.write_space();
21062 self.write_keyword("LIMIT");
21063 self.write_space();
21064 self.generate_expression(&limit.this)?;
21065 if limit.percent {
21066 self.write_space();
21067 self.write_keyword("PERCENT");
21068 }
21069 }
21070
21071 if let Some(offset) = &subquery.offset {
21072 self.write_space();
21073 self.write_keyword("OFFSET");
21074 self.write_space();
21075 self.generate_expression(&offset.this)?;
21076 }
21077 }
21078
21079 if !skip_outer_parens {
21080 if self.config.pretty && is_statement {
21081 self.write_newline();
21082 self.indent_level -= 1;
21083 self.write_indent();
21084 }
21085 self.write(")");
21086 }
21087
21088 if !subquery.modifiers_inside {
21090 if let Some(order_by) = &subquery.order_by {
21091 self.write_space();
21092 self.write_keyword("ORDER BY");
21093 self.write_space();
21094 for (i, ord) in order_by.expressions.iter().enumerate() {
21095 if i > 0 {
21096 self.write(", ");
21097 }
21098 self.generate_ordered(ord)?;
21099 }
21100 }
21101
21102 if let Some(limit) = &subquery.limit {
21103 self.write_space();
21104 self.write_keyword("LIMIT");
21105 self.write_space();
21106 self.generate_expression(&limit.this)?;
21107 if limit.percent {
21108 self.write_space();
21109 self.write_keyword("PERCENT");
21110 }
21111 }
21112
21113 if let Some(offset) = &subquery.offset {
21114 self.write_space();
21115 self.write_keyword("OFFSET");
21116 self.write_space();
21117 self.generate_expression(&offset.this)?;
21118 }
21119
21120 if let Some(distribute_by) = &subquery.distribute_by {
21122 self.write_space();
21123 self.write_keyword("DISTRIBUTE BY");
21124 self.write_space();
21125 for (i, expr) in distribute_by.expressions.iter().enumerate() {
21126 if i > 0 {
21127 self.write(", ");
21128 }
21129 self.generate_expression(expr)?;
21130 }
21131 }
21132
21133 if let Some(sort_by) = &subquery.sort_by {
21135 self.write_space();
21136 self.write_keyword("SORT BY");
21137 self.write_space();
21138 for (i, ord) in sort_by.expressions.iter().enumerate() {
21139 if i > 0 {
21140 self.write(", ");
21141 }
21142 self.generate_ordered(ord)?;
21143 }
21144 }
21145
21146 if let Some(cluster_by) = &subquery.cluster_by {
21148 self.write_space();
21149 self.write_keyword("CLUSTER BY");
21150 self.write_space();
21151 for (i, ord) in cluster_by.expressions.iter().enumerate() {
21152 if i > 0 {
21153 self.write(", ");
21154 }
21155 self.generate_ordered(ord)?;
21156 }
21157 }
21158 }
21159
21160 if let Some(alias) = &subquery.alias {
21161 self.write_space();
21162 let skip_as = matches!(
21164 self.config.dialect,
21165 Some(crate::dialects::DialectType::Oracle)
21166 );
21167 if !skip_as {
21168 self.write_keyword("AS");
21169 self.write_space();
21170 }
21171 self.generate_identifier(alias)?;
21172 if !subquery.column_aliases.is_empty() {
21173 self.write("(");
21174 for (i, col) in subquery.column_aliases.iter().enumerate() {
21175 if i > 0 {
21176 self.write(", ");
21177 }
21178 self.generate_identifier(col)?;
21179 }
21180 self.write(")");
21181 }
21182 }
21183 for comment in &subquery.trailing_comments {
21185 self.write(" ");
21186 self.write_formatted_comment(comment);
21187 }
21188 Ok(())
21189 }
21190
21191 fn generate_pivot(&mut self, pivot: &Pivot) -> Result<()> {
21192 if let Some(ref with) = pivot.with {
21194 self.generate_with(with)?;
21195 self.write_space();
21196 }
21197
21198 let direction = if pivot.unpivot { "UNPIVOT" } else { "PIVOT" };
21199
21200 let is_redshift_unpivot = pivot.unpivot
21204 && pivot.expressions.is_empty()
21205 && pivot.fields.is_empty()
21206 && pivot.using.is_empty()
21207 && pivot.into.is_none()
21208 && !matches!(&pivot.this, Expression::Null(_));
21209
21210 if is_redshift_unpivot {
21211 self.write_keyword("UNPIVOT");
21213 self.write_space();
21214 self.generate_expression(&pivot.this)?;
21215 if let Some(alias) = &pivot.alias {
21217 self.write_space();
21218 self.write_keyword("AS");
21219 self.write_space();
21220 self.write(&alias.name);
21222 }
21223 return Ok(());
21224 }
21225
21226 let is_simplified = !pivot.using.is_empty()
21228 || pivot.into.is_some()
21229 || (pivot.fields.is_empty()
21230 && !pivot.expressions.is_empty()
21231 && !matches!(&pivot.this, Expression::Null(_)));
21232
21233 if is_simplified {
21234 self.write_keyword(direction);
21238 self.write_space();
21239 self.generate_expression(&pivot.this)?;
21240
21241 if !pivot.expressions.is_empty() {
21242 self.write_space();
21243 self.write_keyword("ON");
21244 self.write_space();
21245 for (i, expr) in pivot.expressions.iter().enumerate() {
21246 if i > 0 {
21247 self.write(", ");
21248 }
21249 self.generate_expression(expr)?;
21250 }
21251 }
21252
21253 if let Some(into) = &pivot.into {
21255 self.write_space();
21256 self.write_keyword("INTO");
21257 self.write_space();
21258 self.generate_expression(into)?;
21259 }
21260
21261 if !pivot.using.is_empty() {
21263 self.write_space();
21264 self.write_keyword("USING");
21265 self.write_space();
21266 for (i, expr) in pivot.using.iter().enumerate() {
21267 if i > 0 {
21268 self.write(", ");
21269 }
21270 self.generate_expression(expr)?;
21271 }
21272 }
21273
21274 if let Some(group) = &pivot.group {
21276 self.write_space();
21277 self.generate_expression(group)?;
21278 }
21279 } else {
21280 if !matches!(&pivot.this, Expression::Null(_)) {
21285 self.generate_expression(&pivot.this)?;
21286 self.write_space();
21287 }
21288 self.write_keyword(direction);
21289 self.write("(");
21290
21291 for (i, expr) in pivot.expressions.iter().enumerate() {
21293 if i > 0 {
21294 self.write(", ");
21295 }
21296 self.generate_expression(expr)?;
21297 }
21298
21299 if !pivot.fields.is_empty() {
21301 if !pivot.expressions.is_empty() {
21302 self.write_space();
21303 }
21304 self.write_keyword("FOR");
21305 self.write_space();
21306 for (i, field) in pivot.fields.iter().enumerate() {
21307 if i > 0 {
21308 self.write_space();
21309 }
21310 self.generate_expression(field)?;
21312 }
21313 }
21314
21315 if let Some(default_val) = &pivot.default_on_null {
21317 self.write_space();
21318 self.write_keyword("DEFAULT ON NULL");
21319 self.write(" (");
21320 self.generate_expression(default_val)?;
21321 self.write(")");
21322 }
21323
21324 if let Some(group) = &pivot.group {
21326 self.write_space();
21327 self.generate_expression(group)?;
21328 }
21329
21330 self.write(")");
21331 }
21332
21333 if let Some(alias) = &pivot.alias {
21335 self.write_space();
21336 self.write_keyword("AS");
21337 self.write_space();
21338 self.generate_identifier(alias)?;
21339 }
21340
21341 Ok(())
21342 }
21343
21344 fn generate_unpivot(&mut self, unpivot: &Unpivot) -> Result<()> {
21345 self.generate_expression(&unpivot.this)?;
21346 self.write_space();
21347 self.write_keyword("UNPIVOT");
21348 if let Some(include) = unpivot.include_nulls {
21350 self.write_space();
21351 if include {
21352 self.write_keyword("INCLUDE NULLS");
21353 } else {
21354 self.write_keyword("EXCLUDE NULLS");
21355 }
21356 self.write_space();
21357 }
21358 self.write("(");
21359 if unpivot.value_column_parenthesized {
21360 self.write("(");
21361 }
21362 self.generate_identifier(&unpivot.value_column)?;
21363 for extra_col in &unpivot.extra_value_columns {
21365 self.write(", ");
21366 self.generate_identifier(extra_col)?;
21367 }
21368 if unpivot.value_column_parenthesized {
21369 self.write(")");
21370 }
21371 self.write_space();
21372 self.write_keyword("FOR");
21373 self.write_space();
21374 self.generate_identifier(&unpivot.name_column)?;
21375 self.write_space();
21376 self.write_keyword("IN");
21377 self.write(" (");
21378 for (i, col) in unpivot.columns.iter().enumerate() {
21379 if i > 0 {
21380 self.write(", ");
21381 }
21382 self.generate_expression(col)?;
21383 }
21384 self.write("))");
21385 if let Some(alias) = &unpivot.alias {
21386 self.write_space();
21387 self.write_keyword("AS");
21388 self.write_space();
21389 self.generate_identifier(alias)?;
21390 }
21391 Ok(())
21392 }
21393
21394 fn generate_values(&mut self, values: &Values) -> Result<()> {
21395 self.write_keyword("VALUES");
21396 for (i, row) in values.expressions.iter().enumerate() {
21397 if i > 0 {
21398 self.write(",");
21399 }
21400 self.write(" (");
21401 for (j, expr) in row.expressions.iter().enumerate() {
21402 if j > 0 {
21403 self.write(", ");
21404 }
21405 self.generate_expression(expr)?;
21406 }
21407 self.write(")");
21408 }
21409 if let Some(alias) = &values.alias {
21410 self.write_space();
21411 self.write_keyword("AS");
21412 self.write_space();
21413 self.generate_identifier(alias)?;
21414 if !values.column_aliases.is_empty() {
21415 self.write("(");
21416 for (i, col) in values.column_aliases.iter().enumerate() {
21417 if i > 0 {
21418 self.write(", ");
21419 }
21420 self.generate_identifier(col)?;
21421 }
21422 self.write(")");
21423 }
21424 }
21425 Ok(())
21426 }
21427
21428 fn generate_array(&mut self, arr: &Array) -> Result<()> {
21429 let needs_inheritance = matches!(
21431 self.config.dialect,
21432 Some(DialectType::DuckDB)
21433 | Some(DialectType::Spark)
21434 | Some(DialectType::Databricks)
21435 | Some(DialectType::Hive)
21436 | Some(DialectType::Snowflake)
21437 | Some(DialectType::Presto)
21438 | Some(DialectType::Trino)
21439 );
21440 let propagated: Vec<Expression>;
21441 let expressions = if needs_inheritance && arr.expressions.len() > 1 {
21442 propagated = Self::inherit_struct_field_names(&arr.expressions);
21443 &propagated
21444 } else {
21445 &arr.expressions
21446 };
21447
21448 let use_parens =
21451 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
21452 if !self.config.array_bracket_only {
21453 self.write_keyword("ARRAY");
21454 }
21455 if use_parens {
21456 self.write("(");
21457 } else {
21458 self.write("[");
21459 }
21460 for (i, expr) in expressions.iter().enumerate() {
21461 if i > 0 {
21462 self.write(", ");
21463 }
21464 self.generate_expression(expr)?;
21465 }
21466 if use_parens {
21467 self.write(")");
21468 } else {
21469 self.write("]");
21470 }
21471 Ok(())
21472 }
21473
21474 fn generate_tuple(&mut self, tuple: &Tuple) -> Result<()> {
21475 if tuple.expressions.len() == 2 {
21478 if let Expression::TableAlias(_) = &tuple.expressions[1] {
21479 self.generate_expression(&tuple.expressions[0])?;
21481 self.write_space();
21482 self.write_keyword("AS");
21483 self.write_space();
21484 self.generate_expression(&tuple.expressions[1])?;
21485 return Ok(());
21486 }
21487 }
21488
21489 let expand_tuple = if self.config.pretty && tuple.expressions.len() > 1 {
21492 let mut expr_strings: Vec<String> = Vec::with_capacity(tuple.expressions.len());
21493 for expr in &tuple.expressions {
21494 expr_strings.push(self.generate_to_string(expr)?);
21495 }
21496 self.too_wide(&expr_strings)
21497 } else {
21498 false
21499 };
21500
21501 if expand_tuple {
21502 self.write("(");
21503 self.write_newline();
21504 self.indent_level += 1;
21505 for (i, expr) in tuple.expressions.iter().enumerate() {
21506 if i > 0 {
21507 self.write(",");
21508 self.write_newline();
21509 }
21510 self.write_indent();
21511 self.generate_expression(expr)?;
21512 }
21513 self.indent_level -= 1;
21514 self.write_newline();
21515 self.write_indent();
21516 self.write(")");
21517 } else {
21518 self.write("(");
21519 for (i, expr) in tuple.expressions.iter().enumerate() {
21520 if i > 0 {
21521 self.write(", ");
21522 }
21523 self.generate_expression(expr)?;
21524 }
21525 self.write(")");
21526 }
21527 Ok(())
21528 }
21529
21530 fn generate_pipe_operator(&mut self, pipe: &PipeOperator) -> Result<()> {
21531 self.generate_expression(&pipe.this)?;
21532 self.write(" |> ");
21533 self.generate_expression(&pipe.expression)?;
21534 Ok(())
21535 }
21536
21537 fn generate_ordered(&mut self, ordered: &Ordered) -> Result<()> {
21538 self.generate_expression(&ordered.this)?;
21539 if ordered.desc {
21540 self.write_space();
21541 self.write_keyword("DESC");
21542 } else if ordered.explicit_asc {
21543 self.write_space();
21544 self.write_keyword("ASC");
21545 }
21546 if let Some(nulls_first) = ordered.nulls_first {
21547 let is_asc = !ordered.desc;
21561 let is_nulls_are_large = matches!(
21562 self.config.dialect,
21563 Some(DialectType::Oracle)
21564 | Some(DialectType::PostgreSQL)
21565 | Some(DialectType::Redshift)
21566 | Some(DialectType::Snowflake)
21567 );
21568 let is_nulls_are_last = matches!(
21569 self.config.dialect,
21570 Some(DialectType::Dremio)
21571 | Some(DialectType::DuckDB)
21572 | Some(DialectType::Presto)
21573 | Some(DialectType::Trino)
21574 | Some(DialectType::Athena)
21575 | Some(DialectType::ClickHouse)
21576 | Some(DialectType::Drill)
21577 | Some(DialectType::Exasol)
21578 );
21579
21580 let is_default_nulls = if is_nulls_are_large {
21582 (is_asc && !nulls_first) || (!is_asc && nulls_first)
21584 } else if is_nulls_are_last {
21585 !nulls_first
21587 } else {
21588 false
21589 };
21590
21591 if !is_default_nulls {
21592 self.write_space();
21593 self.write_keyword("NULLS");
21594 self.write_space();
21595 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
21596 }
21597 }
21598 if let Some(ref with_fill) = ordered.with_fill {
21600 self.write_space();
21601 self.generate_with_fill(with_fill)?;
21602 }
21603 Ok(())
21604 }
21605
21606 fn write_clickhouse_type(&mut self, type_str: &str) {
21608 if self.clickhouse_nullable_depth < 0 {
21609 self.write(type_str);
21611 } else {
21612 self.write(&format!("Nullable({})", type_str));
21613 }
21614 }
21615
21616 fn generate_data_type(&mut self, dt: &DataType) -> Result<()> {
21617 use crate::dialects::DialectType;
21618
21619 match dt {
21620 DataType::Boolean => {
21621 match self.config.dialect {
21623 Some(DialectType::TSQL) => self.write_keyword("BIT"),
21624 Some(DialectType::MySQL) => self.write_keyword("BOOLEAN"), Some(DialectType::Oracle) => {
21626 self.write_keyword("NUMBER(1)")
21628 }
21629 Some(DialectType::ClickHouse) => self.write("Bool"), _ => self.write_keyword("BOOLEAN"),
21631 }
21632 }
21633 DataType::TinyInt { length } => {
21634 match self.config.dialect {
21638 Some(DialectType::PostgreSQL)
21639 | Some(DialectType::Redshift)
21640 | Some(DialectType::Oracle)
21641 | Some(DialectType::Exasol) => {
21642 self.write_keyword("SMALLINT");
21643 }
21644 Some(DialectType::Teradata) => {
21645 self.write_keyword("BYTEINT");
21647 }
21648 Some(DialectType::Dremio) => {
21649 self.write_keyword("INT");
21651 }
21652 Some(DialectType::ClickHouse) => {
21653 self.write_clickhouse_type("Int8");
21654 }
21655 _ => {
21656 self.write_keyword("TINYINT");
21657 }
21658 }
21659 if let Some(n) = length {
21660 if !matches!(
21661 self.config.dialect,
21662 Some(DialectType::Dremio) | Some(DialectType::ClickHouse)
21663 ) {
21664 self.write(&format!("({})", n));
21665 }
21666 }
21667 }
21668 DataType::SmallInt { length } => {
21669 match self.config.dialect {
21671 Some(DialectType::Dremio) => {
21672 self.write_keyword("INT");
21673 }
21674 Some(DialectType::SQLite) | Some(DialectType::Drill) => {
21675 self.write_keyword("INTEGER");
21676 }
21677 Some(DialectType::BigQuery) => {
21678 self.write_keyword("INT64");
21679 }
21680 Some(DialectType::ClickHouse) => {
21681 self.write_clickhouse_type("Int16");
21682 }
21683 _ => {
21684 self.write_keyword("SMALLINT");
21685 if let Some(n) = length {
21686 self.write(&format!("({})", n));
21687 }
21688 }
21689 }
21690 }
21691 DataType::Int {
21692 length,
21693 integer_spelling,
21694 } => {
21695 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
21697 self.write_keyword("INT64");
21698 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
21699 self.write_clickhouse_type("Int32");
21700 } else {
21701 let use_integer = match self.config.dialect {
21703 Some(DialectType::TSQL)
21704 | Some(DialectType::Fabric)
21705 | Some(DialectType::Presto)
21706 | Some(DialectType::Trino)
21707 | Some(DialectType::SQLite)
21708 | Some(DialectType::Redshift) => true,
21709 Some(DialectType::Databricks) => *integer_spelling,
21711 _ => false,
21712 };
21713 if use_integer {
21714 self.write_keyword("INTEGER");
21715 } else {
21716 self.write_keyword("INT");
21717 }
21718 if let Some(n) = length {
21719 self.write(&format!("({})", n));
21720 }
21721 }
21722 }
21723 DataType::BigInt { length } => {
21724 match self.config.dialect {
21726 Some(DialectType::Oracle) => {
21727 self.write_keyword("INT");
21729 }
21730 Some(DialectType::ClickHouse) => {
21731 self.write_clickhouse_type("Int64");
21732 }
21733 _ => {
21734 self.write_keyword("BIGINT");
21735 if let Some(n) = length {
21736 self.write(&format!("({})", n));
21737 }
21738 }
21739 }
21740 }
21741 DataType::Float {
21742 precision,
21743 scale,
21744 real_spelling,
21745 } => {
21746 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
21750 self.write_clickhouse_type("Float32");
21751 } else if *real_spelling
21752 && !matches!(
21753 self.config.dialect,
21754 Some(DialectType::Spark)
21755 | Some(DialectType::Databricks)
21756 | Some(DialectType::Hive)
21757 | Some(DialectType::Snowflake)
21758 | Some(DialectType::MySQL)
21759 | Some(DialectType::BigQuery)
21760 )
21761 {
21762 self.write_keyword("REAL")
21763 } else {
21764 match self.config.dialect {
21765 Some(DialectType::PostgreSQL) => self.write_keyword("REAL"),
21766 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
21767 _ => self.write_keyword("FLOAT"),
21768 }
21769 }
21770 if !matches!(
21773 self.config.dialect,
21774 Some(DialectType::Spark)
21775 | Some(DialectType::Databricks)
21776 | Some(DialectType::Hive)
21777 | Some(DialectType::Presto)
21778 | Some(DialectType::Trino)
21779 ) {
21780 if let Some(p) = precision {
21781 self.write(&format!("({}", p));
21782 if let Some(s) = scale {
21783 self.write(&format!(", {})", s));
21784 } else {
21785 self.write(")");
21786 }
21787 }
21788 }
21789 }
21790 DataType::Double { precision, scale } => {
21791 match self.config.dialect {
21793 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
21794 self.write_keyword("FLOAT")
21795 } Some(DialectType::Oracle) => self.write_keyword("DOUBLE PRECISION"),
21797 Some(DialectType::ClickHouse) => self.write_clickhouse_type("Float64"),
21798 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
21799 Some(DialectType::SQLite) => self.write_keyword("REAL"),
21800 Some(DialectType::PostgreSQL)
21801 | Some(DialectType::Redshift)
21802 | Some(DialectType::Teradata)
21803 | Some(DialectType::Materialize) => self.write_keyword("DOUBLE PRECISION"),
21804 _ => self.write_keyword("DOUBLE"),
21805 }
21806 if let Some(p) = precision {
21808 self.write(&format!("({}", p));
21809 if let Some(s) = scale {
21810 self.write(&format!(", {})", s));
21811 } else {
21812 self.write(")");
21813 }
21814 }
21815 }
21816 DataType::Decimal { precision, scale } => {
21817 match self.config.dialect {
21819 Some(DialectType::ClickHouse) => {
21820 self.write("Decimal");
21821 if let Some(p) = precision {
21822 self.write(&format!("({}", p));
21823 if let Some(s) = scale {
21824 self.write(&format!(", {}", s));
21825 }
21826 self.write(")");
21827 }
21828 }
21829 Some(DialectType::Oracle) => {
21830 self.write_keyword("NUMBER");
21832 if let Some(p) = precision {
21833 self.write(&format!("({}", p));
21834 if let Some(s) = scale {
21835 self.write(&format!(", {}", s));
21836 }
21837 self.write(")");
21838 }
21839 }
21840 Some(DialectType::BigQuery) => {
21841 self.write_keyword("NUMERIC");
21843 if let Some(p) = precision {
21844 self.write(&format!("({}", p));
21845 if let Some(s) = scale {
21846 self.write(&format!(", {}", s));
21847 }
21848 self.write(")");
21849 }
21850 }
21851 _ => {
21852 self.write_keyword("DECIMAL");
21853 if let Some(p) = precision {
21854 self.write(&format!("({}", p));
21855 if let Some(s) = scale {
21856 self.write(&format!(", {}", s));
21857 }
21858 self.write(")");
21859 }
21860 }
21861 }
21862 }
21863 DataType::Char { length } => {
21864 match self.config.dialect {
21866 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
21867 self.write_keyword("TEXT");
21869 }
21870 Some(DialectType::Hive)
21871 | Some(DialectType::Spark)
21872 | Some(DialectType::Databricks) => {
21873 if length.is_some()
21876 && !matches!(self.config.dialect, Some(DialectType::Hive))
21877 {
21878 self.write_keyword("CHAR");
21879 if let Some(n) = length {
21880 self.write(&format!("({})", n));
21881 }
21882 } else {
21883 self.write_keyword("STRING");
21884 }
21885 }
21886 Some(DialectType::Dremio) => {
21887 self.write_keyword("VARCHAR");
21889 if let Some(n) = length {
21890 self.write(&format!("({})", n));
21891 }
21892 }
21893 _ => {
21894 self.write_keyword("CHAR");
21895 if let Some(n) = length {
21896 self.write(&format!("({})", n));
21897 }
21898 }
21899 }
21900 }
21901 DataType::VarChar {
21902 length,
21903 parenthesized_length,
21904 } => {
21905 match self.config.dialect {
21907 Some(DialectType::Oracle) => {
21908 self.write_keyword("VARCHAR2");
21909 if let Some(n) = length {
21910 self.write(&format!("({})", n));
21911 }
21912 }
21913 Some(DialectType::DuckDB) => {
21914 self.write_keyword("TEXT");
21916 if let Some(n) = length {
21917 self.write(&format!("({})", n));
21918 }
21919 }
21920 Some(DialectType::SQLite) => {
21921 self.write_keyword("TEXT");
21923 if let Some(n) = length {
21924 self.write(&format!("({})", n));
21925 }
21926 }
21927 Some(DialectType::MySQL) if length.is_none() => {
21928 self.write_keyword("TEXT");
21930 }
21931 Some(DialectType::Hive)
21932 | Some(DialectType::Spark)
21933 | Some(DialectType::Databricks)
21934 if length.is_none() =>
21935 {
21936 self.write_keyword("STRING");
21938 }
21939 _ => {
21940 self.write_keyword("VARCHAR");
21941 if let Some(n) = length {
21942 if *parenthesized_length {
21944 self.write(&format!("(({}))", n));
21945 } else {
21946 self.write(&format!("({})", n));
21947 }
21948 }
21949 }
21950 }
21951 }
21952 DataType::Text => {
21953 match self.config.dialect {
21955 Some(DialectType::Oracle) => self.write_keyword("CLOB"),
21956 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
21957 self.write_keyword("VARCHAR(MAX)")
21958 }
21959 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
21960 Some(DialectType::Snowflake)
21961 | Some(DialectType::Dremio)
21962 | Some(DialectType::Drill) => self.write_keyword("VARCHAR"),
21963 Some(DialectType::Exasol) => self.write_keyword("LONG VARCHAR"),
21964 Some(DialectType::Presto)
21965 | Some(DialectType::Trino)
21966 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
21967 Some(DialectType::Spark)
21968 | Some(DialectType::Databricks)
21969 | Some(DialectType::Hive) => self.write_keyword("STRING"),
21970 Some(DialectType::Redshift) => self.write_keyword("VARCHAR(MAX)"),
21971 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
21972 self.write_keyword("STRING")
21973 }
21974 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
21975 _ => self.write_keyword("TEXT"),
21976 }
21977 }
21978 DataType::TextWithLength { length } => {
21979 match self.config.dialect {
21981 Some(DialectType::Oracle) => self.write(&format!("CLOB({})", length)),
21982 Some(DialectType::Hive)
21983 | Some(DialectType::Spark)
21984 | Some(DialectType::Databricks) => {
21985 self.write(&format!("VARCHAR({})", length));
21986 }
21987 Some(DialectType::Redshift) => self.write(&format!("VARCHAR({})", length)),
21988 Some(DialectType::BigQuery) => self.write(&format!("STRING({})", length)),
21989 Some(DialectType::Snowflake)
21990 | Some(DialectType::Presto)
21991 | Some(DialectType::Trino)
21992 | Some(DialectType::Athena)
21993 | Some(DialectType::Drill)
21994 | Some(DialectType::Dremio) => {
21995 self.write(&format!("VARCHAR({})", length));
21996 }
21997 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
21998 self.write(&format!("VARCHAR({})", length))
21999 }
22000 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
22001 self.write(&format!("STRING({})", length))
22002 }
22003 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
22004 _ => self.write(&format!("TEXT({})", length)),
22005 }
22006 }
22007 DataType::String { length } => {
22008 match self.config.dialect {
22010 Some(DialectType::ClickHouse) => {
22011 self.write("String");
22013 if let Some(n) = length {
22014 self.write(&format!("({})", n));
22015 }
22016 }
22017 Some(DialectType::BigQuery)
22018 | Some(DialectType::Hive)
22019 | Some(DialectType::Spark)
22020 | Some(DialectType::Databricks)
22021 | Some(DialectType::StarRocks)
22022 | Some(DialectType::Doris) => {
22023 self.write_keyword("STRING");
22024 if let Some(n) = length {
22025 self.write(&format!("({})", n));
22026 }
22027 }
22028 Some(DialectType::PostgreSQL) => {
22029 if let Some(n) = length {
22031 self.write_keyword("VARCHAR");
22032 self.write(&format!("({})", n));
22033 } else {
22034 self.write_keyword("TEXT");
22035 }
22036 }
22037 Some(DialectType::Redshift) => {
22038 if let Some(n) = length {
22040 self.write_keyword("VARCHAR");
22041 self.write(&format!("({})", n));
22042 } else {
22043 self.write_keyword("VARCHAR(MAX)");
22044 }
22045 }
22046 Some(DialectType::MySQL) => {
22047 if let Some(n) = length {
22049 self.write_keyword("VARCHAR");
22050 self.write(&format!("({})", n));
22051 } else {
22052 self.write_keyword("TEXT");
22053 }
22054 }
22055 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
22056 if let Some(n) = length {
22058 self.write_keyword("VARCHAR");
22059 self.write(&format!("({})", n));
22060 } else {
22061 self.write_keyword("VARCHAR(MAX)");
22062 }
22063 }
22064 Some(DialectType::Oracle) => {
22065 self.write_keyword("CLOB");
22067 }
22068 Some(DialectType::DuckDB) | Some(DialectType::Materialize) => {
22069 self.write_keyword("TEXT");
22071 if let Some(n) = length {
22072 self.write(&format!("({})", n));
22073 }
22074 }
22075 Some(DialectType::Presto)
22076 | Some(DialectType::Trino)
22077 | Some(DialectType::Drill)
22078 | Some(DialectType::Dremio) => {
22079 self.write_keyword("VARCHAR");
22081 if let Some(n) = length {
22082 self.write(&format!("({})", n));
22083 }
22084 }
22085 Some(DialectType::Snowflake) => {
22086 self.write_keyword("STRING");
22089 if let Some(n) = length {
22090 self.write(&format!("({})", n));
22091 }
22092 }
22093 _ => {
22094 self.write_keyword("STRING");
22096 if let Some(n) = length {
22097 self.write(&format!("({})", n));
22098 }
22099 }
22100 }
22101 }
22102 DataType::Binary { length } => {
22103 match self.config.dialect {
22105 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
22106 self.write_keyword("BYTEA");
22107 if let Some(n) = length {
22108 self.write(&format!("({})", n));
22109 }
22110 }
22111 Some(DialectType::Redshift) => {
22112 self.write_keyword("VARBYTE");
22113 if let Some(n) = length {
22114 self.write(&format!("({})", n));
22115 }
22116 }
22117 Some(DialectType::DuckDB)
22118 | Some(DialectType::SQLite)
22119 | Some(DialectType::Oracle) => {
22120 self.write_keyword("BLOB");
22122 if let Some(n) = length {
22123 self.write(&format!("({})", n));
22124 }
22125 }
22126 Some(DialectType::Presto)
22127 | Some(DialectType::Trino)
22128 | Some(DialectType::Athena)
22129 | Some(DialectType::Drill)
22130 | Some(DialectType::Dremio) => {
22131 self.write_keyword("VARBINARY");
22133 if let Some(n) = length {
22134 self.write(&format!("({})", n));
22135 }
22136 }
22137 Some(DialectType::ClickHouse) => {
22138 if self.clickhouse_nullable_depth < 0 {
22140 self.write("BINARY");
22141 } else {
22142 self.write("Nullable(BINARY");
22143 }
22144 if let Some(n) = length {
22145 self.write(&format!("({})", n));
22146 }
22147 if self.clickhouse_nullable_depth >= 0 {
22148 self.write(")");
22149 }
22150 }
22151 _ => {
22152 self.write_keyword("BINARY");
22153 if let Some(n) = length {
22154 self.write(&format!("({})", n));
22155 }
22156 }
22157 }
22158 }
22159 DataType::VarBinary { length } => {
22160 match self.config.dialect {
22162 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
22163 self.write_keyword("BYTEA");
22164 if let Some(n) = length {
22165 self.write(&format!("({})", n));
22166 }
22167 }
22168 Some(DialectType::Redshift) => {
22169 self.write_keyword("VARBYTE");
22170 if let Some(n) = length {
22171 self.write(&format!("({})", n));
22172 }
22173 }
22174 Some(DialectType::DuckDB)
22175 | Some(DialectType::SQLite)
22176 | Some(DialectType::Oracle) => {
22177 self.write_keyword("BLOB");
22179 if let Some(n) = length {
22180 self.write(&format!("({})", n));
22181 }
22182 }
22183 Some(DialectType::Exasol) => {
22184 self.write_keyword("VARCHAR");
22186 }
22187 Some(DialectType::Spark)
22188 | Some(DialectType::Hive)
22189 | Some(DialectType::Databricks) => {
22190 self.write_keyword("BINARY");
22192 if let Some(n) = length {
22193 self.write(&format!("({})", n));
22194 }
22195 }
22196 Some(DialectType::ClickHouse) => {
22197 self.write_clickhouse_type("String");
22199 }
22200 _ => {
22201 self.write_keyword("VARBINARY");
22202 if let Some(n) = length {
22203 self.write(&format!("({})", n));
22204 }
22205 }
22206 }
22207 }
22208 DataType::Blob => {
22209 match self.config.dialect {
22211 Some(DialectType::PostgreSQL) => self.write_keyword("BYTEA"),
22212 Some(DialectType::Redshift) => self.write_keyword("VARBYTE"),
22213 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
22214 self.write_keyword("VARBINARY")
22215 }
22216 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
22217 Some(DialectType::Exasol) => self.write_keyword("VARCHAR"),
22218 Some(DialectType::Presto)
22219 | Some(DialectType::Trino)
22220 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
22221 Some(DialectType::DuckDB) => {
22222 self.write_keyword("VARBINARY");
22225 }
22226 Some(DialectType::Spark)
22227 | Some(DialectType::Databricks)
22228 | Some(DialectType::Hive) => self.write_keyword("BINARY"),
22229 Some(DialectType::ClickHouse) => {
22230 self.write("Nullable(String)");
22234 }
22235 _ => self.write_keyword("BLOB"),
22236 }
22237 }
22238 DataType::Bit { length } => {
22239 match self.config.dialect {
22241 Some(DialectType::Dremio)
22242 | Some(DialectType::Spark)
22243 | Some(DialectType::Databricks)
22244 | Some(DialectType::Hive)
22245 | Some(DialectType::Snowflake)
22246 | Some(DialectType::BigQuery)
22247 | Some(DialectType::Presto)
22248 | Some(DialectType::Trino)
22249 | Some(DialectType::ClickHouse)
22250 | Some(DialectType::Redshift) => {
22251 self.write_keyword("BOOLEAN");
22253 }
22254 _ => {
22255 self.write_keyword("BIT");
22256 if let Some(n) = length {
22257 self.write(&format!("({})", n));
22258 }
22259 }
22260 }
22261 }
22262 DataType::VarBit { length } => {
22263 self.write_keyword("VARBIT");
22264 if let Some(n) = length {
22265 self.write(&format!("({})", n));
22266 }
22267 }
22268 DataType::Date => self.write_keyword("DATE"),
22269 DataType::Time {
22270 precision,
22271 timezone,
22272 } => {
22273 if *timezone {
22274 match self.config.dialect {
22276 Some(DialectType::DuckDB) => {
22277 self.write_keyword("TIMETZ");
22279 }
22280 Some(DialectType::PostgreSQL) => {
22281 self.write_keyword("TIMETZ");
22283 if let Some(p) = precision {
22284 self.write(&format!("({})", p));
22285 }
22286 }
22287 _ => {
22288 self.write_keyword("TIME");
22290 if let Some(p) = precision {
22291 self.write(&format!("({})", p));
22292 }
22293 self.write_keyword(" WITH TIME ZONE");
22294 }
22295 }
22296 } else {
22297 if matches!(
22299 self.config.dialect,
22300 Some(DialectType::Spark)
22301 | Some(DialectType::Databricks)
22302 | Some(DialectType::Hive)
22303 ) {
22304 self.write_keyword("TIMESTAMP");
22305 } else {
22306 self.write_keyword("TIME");
22307 if let Some(p) = precision {
22308 self.write(&format!("({})", p));
22309 }
22310 }
22311 }
22312 }
22313 DataType::Timestamp {
22314 precision,
22315 timezone,
22316 } => {
22317 match self.config.dialect {
22319 Some(DialectType::ClickHouse) => {
22320 self.write("DateTime");
22321 if let Some(p) = precision {
22322 self.write(&format!("({})", p));
22323 }
22324 }
22325 Some(DialectType::TSQL) => {
22326 if *timezone {
22327 self.write_keyword("DATETIMEOFFSET");
22328 } else {
22329 self.write_keyword("DATETIME2");
22330 }
22331 if let Some(p) = precision {
22332 self.write(&format!("({})", p));
22333 }
22334 }
22335 Some(DialectType::MySQL) => {
22336 self.write_keyword("TIMESTAMP");
22338 if let Some(p) = precision {
22339 self.write(&format!("({})", p));
22340 }
22341 }
22342 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
22343 self.write_keyword("DATETIME");
22345 if let Some(p) = precision {
22346 self.write(&format!("({})", p));
22347 }
22348 }
22349 Some(DialectType::BigQuery) => {
22350 if *timezone {
22352 self.write_keyword("TIMESTAMP");
22353 } else {
22354 self.write_keyword("DATETIME");
22355 }
22356 }
22357 Some(DialectType::DuckDB) => {
22358 if *timezone {
22360 self.write_keyword("TIMESTAMPTZ");
22361 } else {
22362 self.write_keyword("TIMESTAMP");
22363 if let Some(p) = precision {
22364 self.write(&format!("({})", p));
22365 }
22366 }
22367 }
22368 _ => {
22369 if *timezone && !self.config.tz_to_with_time_zone {
22370 self.write_keyword("TIMESTAMPTZ");
22372 if let Some(p) = precision {
22373 self.write(&format!("({})", p));
22374 }
22375 } else {
22376 self.write_keyword("TIMESTAMP");
22377 if let Some(p) = precision {
22378 self.write(&format!("({})", p));
22379 }
22380 if *timezone {
22381 self.write_space();
22382 self.write_keyword("WITH TIME ZONE");
22383 }
22384 }
22385 }
22386 }
22387 }
22388 DataType::Interval { unit, to } => {
22389 self.write_keyword("INTERVAL");
22390 if let Some(u) = unit {
22391 self.write_space();
22392 self.write_keyword(u);
22393 }
22394 if let Some(t) = to {
22396 self.write_space();
22397 self.write_keyword("TO");
22398 self.write_space();
22399 self.write_keyword(t);
22400 }
22401 }
22402 DataType::Json => {
22403 match self.config.dialect {
22405 Some(DialectType::Oracle) => self.write_keyword("JSON"), Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"), Some(DialectType::MySQL) => self.write_keyword("JSON"),
22408 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
22409 _ => self.write_keyword("JSON"),
22410 }
22411 }
22412 DataType::JsonB => {
22413 match self.config.dialect {
22415 Some(DialectType::PostgreSQL) => self.write_keyword("JSONB"),
22416 Some(DialectType::Doris) => self.write_keyword("JSONB"),
22417 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
22418 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
22419 Some(DialectType::DuckDB) => self.write_keyword("JSON"), _ => self.write_keyword("JSON"), }
22422 }
22423 DataType::Uuid => {
22424 match self.config.dialect {
22426 Some(DialectType::TSQL) => self.write_keyword("UNIQUEIDENTIFIER"),
22427 Some(DialectType::MySQL) => self.write_keyword("CHAR(36)"),
22428 Some(DialectType::Oracle) => self.write_keyword("RAW(16)"),
22429 Some(DialectType::BigQuery)
22430 | Some(DialectType::Spark)
22431 | Some(DialectType::Databricks) => self.write_keyword("STRING"),
22432 _ => self.write_keyword("UUID"),
22433 }
22434 }
22435 DataType::Array {
22436 element_type,
22437 dimension,
22438 } => {
22439 match self.config.dialect {
22441 Some(DialectType::PostgreSQL)
22442 | Some(DialectType::Redshift)
22443 | Some(DialectType::DuckDB) => {
22444 self.generate_data_type(element_type)?;
22446 if let Some(dim) = dimension {
22447 self.write(&format!("[{}]", dim));
22448 } else {
22449 self.write("[]");
22450 }
22451 }
22452 Some(DialectType::BigQuery) => {
22453 self.write_keyword("ARRAY<");
22454 self.generate_data_type(element_type)?;
22455 self.write(">");
22456 }
22457 Some(DialectType::Snowflake)
22458 | Some(DialectType::Presto)
22459 | Some(DialectType::Trino)
22460 | Some(DialectType::ClickHouse) => {
22461 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
22463 self.write("Array(");
22464 } else {
22465 self.write_keyword("ARRAY(");
22466 }
22467 self.generate_data_type(element_type)?;
22468 self.write(")");
22469 }
22470 Some(DialectType::TSQL)
22471 | Some(DialectType::MySQL)
22472 | Some(DialectType::Oracle) => {
22473 match self.config.dialect {
22476 Some(DialectType::MySQL) => self.write_keyword("JSON"),
22477 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
22478 _ => self.write_keyword("JSON"),
22479 }
22480 }
22481 _ => {
22482 self.write_keyword("ARRAY<");
22484 self.generate_data_type(element_type)?;
22485 self.write(">");
22486 }
22487 }
22488 }
22489 DataType::List { element_type } => {
22490 self.generate_data_type(element_type)?;
22492 self.write_keyword(" LIST");
22493 }
22494 DataType::Map {
22495 key_type,
22496 value_type,
22497 } => {
22498 match self.config.dialect {
22500 Some(DialectType::Materialize) => {
22501 self.write_keyword("MAP[");
22503 self.generate_data_type(key_type)?;
22504 self.write(" => ");
22505 self.generate_data_type(value_type)?;
22506 self.write("]");
22507 }
22508 Some(DialectType::Snowflake)
22509 | Some(DialectType::RisingWave)
22510 | Some(DialectType::DuckDB)
22511 | Some(DialectType::Presto)
22512 | Some(DialectType::Trino)
22513 | Some(DialectType::Athena) => {
22514 self.write_keyword("MAP(");
22515 self.generate_data_type(key_type)?;
22516 self.write(", ");
22517 self.generate_data_type(value_type)?;
22518 self.write(")");
22519 }
22520 Some(DialectType::ClickHouse) => {
22521 self.write("Map(");
22524 self.clickhouse_nullable_depth = -1; self.generate_data_type(key_type)?;
22526 self.clickhouse_nullable_depth = 0;
22527 self.write(", ");
22528 self.generate_data_type(value_type)?;
22529 self.write(")");
22530 }
22531 _ => {
22532 self.write_keyword("MAP<");
22533 self.generate_data_type(key_type)?;
22534 self.write(", ");
22535 self.generate_data_type(value_type)?;
22536 self.write(">");
22537 }
22538 }
22539 }
22540 DataType::Vector {
22541 element_type,
22542 dimension,
22543 } => {
22544 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
22545 self.write_keyword("VECTOR(");
22547 if let Some(dim) = dimension {
22548 self.write(&dim.to_string());
22549 }
22550 let type_alias = element_type.as_ref().and_then(|et| match et.as_ref() {
22552 DataType::TinyInt { .. } => Some("I8"),
22553 DataType::SmallInt { .. } => Some("I16"),
22554 DataType::Int { .. } => Some("I32"),
22555 DataType::BigInt { .. } => Some("I64"),
22556 DataType::Float { .. } => Some("F32"),
22557 DataType::Double { .. } => Some("F64"),
22558 _ => None,
22559 });
22560 if let Some(alias) = type_alias {
22561 if dimension.is_some() {
22562 self.write(", ");
22563 }
22564 self.write(alias);
22565 }
22566 self.write(")");
22567 } else {
22568 self.write_keyword("VECTOR(");
22570 if let Some(ref et) = element_type {
22571 self.generate_data_type(et)?;
22572 if dimension.is_some() {
22573 self.write(", ");
22574 }
22575 }
22576 if let Some(dim) = dimension {
22577 self.write(&dim.to_string());
22578 }
22579 self.write(")");
22580 }
22581 }
22582 DataType::Object { fields, modifier } => {
22583 self.write_keyword("OBJECT(");
22584 for (i, (name, dt, not_null)) in fields.iter().enumerate() {
22585 if i > 0 {
22586 self.write(", ");
22587 }
22588 self.write(name);
22589 self.write(" ");
22590 self.generate_data_type(dt)?;
22591 if *not_null {
22592 self.write_keyword(" NOT NULL");
22593 }
22594 }
22595 self.write(")");
22596 if let Some(mod_str) = modifier {
22597 self.write(" ");
22598 self.write_keyword(mod_str);
22599 }
22600 }
22601 DataType::Struct { fields, nested } => {
22602 match self.config.dialect {
22604 Some(DialectType::Snowflake) => {
22605 self.write_keyword("OBJECT(");
22607 for (i, field) in fields.iter().enumerate() {
22608 if i > 0 {
22609 self.write(", ");
22610 }
22611 if !field.name.is_empty() {
22612 self.write(&field.name);
22613 self.write(" ");
22614 }
22615 self.generate_data_type(&field.data_type)?;
22616 }
22617 self.write(")");
22618 }
22619 Some(DialectType::Presto) | Some(DialectType::Trino) => {
22620 self.write_keyword("ROW(");
22622 for (i, field) in fields.iter().enumerate() {
22623 if i > 0 {
22624 self.write(", ");
22625 }
22626 if !field.name.is_empty() {
22627 self.write(&field.name);
22628 self.write(" ");
22629 }
22630 self.generate_data_type(&field.data_type)?;
22631 }
22632 self.write(")");
22633 }
22634 Some(DialectType::DuckDB) => {
22635 self.write_keyword("STRUCT(");
22637 for (i, field) in fields.iter().enumerate() {
22638 if i > 0 {
22639 self.write(", ");
22640 }
22641 if !field.name.is_empty() {
22642 self.write(&field.name);
22643 self.write(" ");
22644 }
22645 self.generate_data_type(&field.data_type)?;
22646 }
22647 self.write(")");
22648 }
22649 Some(DialectType::ClickHouse) => {
22650 self.write("Tuple(");
22652 for (i, field) in fields.iter().enumerate() {
22653 if i > 0 {
22654 self.write(", ");
22655 }
22656 if !field.name.is_empty() {
22657 self.write(&field.name);
22658 self.write(" ");
22659 }
22660 self.generate_data_type(&field.data_type)?;
22661 }
22662 self.write(")");
22663 }
22664 Some(DialectType::SingleStore) => {
22665 self.write_keyword("RECORD(");
22667 for (i, field) in fields.iter().enumerate() {
22668 if i > 0 {
22669 self.write(", ");
22670 }
22671 if !field.name.is_empty() {
22672 self.write(&field.name);
22673 self.write(" ");
22674 }
22675 self.generate_data_type(&field.data_type)?;
22676 }
22677 self.write(")");
22678 }
22679 _ => {
22680 let force_angle_brackets = matches!(
22682 self.config.dialect,
22683 Some(DialectType::Hive)
22684 | Some(DialectType::Spark)
22685 | Some(DialectType::Databricks)
22686 );
22687 if *nested && !force_angle_brackets {
22688 self.write_keyword("STRUCT(");
22689 for (i, field) in fields.iter().enumerate() {
22690 if i > 0 {
22691 self.write(", ");
22692 }
22693 if !field.name.is_empty() {
22694 self.write(&field.name);
22695 self.write(" ");
22696 }
22697 self.generate_data_type(&field.data_type)?;
22698 }
22699 self.write(")");
22700 } else {
22701 self.write_keyword("STRUCT<");
22702 for (i, field) in fields.iter().enumerate() {
22703 if i > 0 {
22704 self.write(", ");
22705 }
22706 if !field.name.is_empty() {
22707 self.write(&field.name);
22709 self.write(self.config.struct_field_sep);
22710 }
22711 self.generate_data_type(&field.data_type)?;
22713 if let Some(comment) = &field.comment {
22715 self.write(" COMMENT '");
22716 self.write(comment);
22717 self.write("'");
22718 }
22719 if !field.options.is_empty() {
22721 self.write(" ");
22722 self.generate_options_clause(&field.options)?;
22723 }
22724 }
22725 self.write(">");
22726 }
22727 }
22728 }
22729 }
22730 DataType::Enum {
22731 values,
22732 assignments,
22733 } => {
22734 if self.config.dialect == Some(DialectType::ClickHouse) {
22737 self.write("Enum(");
22738 } else {
22739 self.write_keyword("ENUM(");
22740 }
22741 for (i, val) in values.iter().enumerate() {
22742 if i > 0 {
22743 self.write(", ");
22744 }
22745 self.write("'");
22746 self.write(val);
22747 self.write("'");
22748 if let Some(Some(assignment)) = assignments.get(i) {
22749 self.write(" = ");
22750 self.write(assignment);
22751 }
22752 }
22753 self.write(")");
22754 }
22755 DataType::Set { values } => {
22756 self.write_keyword("SET(");
22758 for (i, val) in values.iter().enumerate() {
22759 if i > 0 {
22760 self.write(", ");
22761 }
22762 self.write("'");
22763 self.write(val);
22764 self.write("'");
22765 }
22766 self.write(")");
22767 }
22768 DataType::Union { fields } => {
22769 self.write_keyword("UNION(");
22771 for (i, (name, dt)) in fields.iter().enumerate() {
22772 if i > 0 {
22773 self.write(", ");
22774 }
22775 if !name.is_empty() {
22776 self.write(name);
22777 self.write(" ");
22778 }
22779 self.generate_data_type(dt)?;
22780 }
22781 self.write(")");
22782 }
22783 DataType::Nullable { inner } => {
22784 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
22786 self.write("Nullable(");
22787 let saved_depth = self.clickhouse_nullable_depth;
22789 self.clickhouse_nullable_depth = -1;
22790 self.generate_data_type(inner)?;
22791 self.clickhouse_nullable_depth = saved_depth;
22792 self.write(")");
22793 } else {
22794 match inner.as_ref() {
22796 DataType::Custom { name } if name.to_uppercase() == "DATETIME" => {
22797 self.generate_data_type(&DataType::Timestamp {
22798 precision: None,
22799 timezone: false,
22800 })?;
22801 }
22802 _ => {
22803 self.generate_data_type(inner)?;
22804 }
22805 }
22806 }
22807 }
22808 DataType::Custom { name } => {
22809 let name_upper = name.to_uppercase();
22811 match self.config.dialect {
22812 Some(DialectType::ClickHouse) => {
22813 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
22814 (name_upper[..idx].to_string(), &name[idx..])
22815 } else {
22816 (name_upper.clone(), "")
22817 };
22818 let mapped = match base_upper.as_str() {
22819 "DATETIME" | "TIMESTAMPTZ" | "TIMESTAMP" | "TIMESTAMPNTZ"
22820 | "SMALLDATETIME" | "DATETIME2" => "DateTime",
22821 "DATETIME64" => "DateTime64",
22822 "DATE32" => "Date32",
22823 "INT" => "Int32",
22824 "MEDIUMINT" => "Int32",
22825 "INT8" => "Int8",
22826 "INT16" => "Int16",
22827 "INT32" => "Int32",
22828 "INT64" => "Int64",
22829 "INT128" => "Int128",
22830 "INT256" => "Int256",
22831 "UINT8" => "UInt8",
22832 "UINT16" => "UInt16",
22833 "UINT32" => "UInt32",
22834 "UINT64" => "UInt64",
22835 "UINT128" => "UInt128",
22836 "UINT256" => "UInt256",
22837 "FLOAT32" => "Float32",
22838 "FLOAT64" => "Float64",
22839 "DECIMAL32" => "Decimal32",
22840 "DECIMAL64" => "Decimal64",
22841 "DECIMAL128" => "Decimal128",
22842 "DECIMAL256" => "Decimal256",
22843 "ENUM" => "Enum",
22844 "ENUM8" => "Enum8",
22845 "ENUM16" => "Enum16",
22846 "FIXEDSTRING" => "FixedString",
22847 "NESTED" => "Nested",
22848 "LOWCARDINALITY" => "LowCardinality",
22849 "NULLABLE" => "Nullable",
22850 "IPV4" => "IPv4",
22851 "IPV6" => "IPv6",
22852 "POINT" => "Point",
22853 "RING" => "Ring",
22854 "LINESTRING" => "LineString",
22855 "MULTILINESTRING" => "MultiLineString",
22856 "POLYGON" => "Polygon",
22857 "MULTIPOLYGON" => "MultiPolygon",
22858 "AGGREGATEFUNCTION" => "AggregateFunction",
22859 "SIMPLEAGGREGATEFUNCTION" => "SimpleAggregateFunction",
22860 "DYNAMIC" => "Dynamic",
22861 _ => "",
22862 };
22863 if mapped.is_empty() {
22864 self.write(name);
22865 } else {
22866 self.write(mapped);
22867 self.write(suffix);
22868 }
22869 }
22870 Some(DialectType::MySQL)
22871 if name_upper == "TIMESTAMPTZ" || name_upper == "TIMESTAMPLTZ" =>
22872 {
22873 self.write_keyword("TIMESTAMP");
22875 }
22876 Some(DialectType::TSQL) if name_upper == "VARIANT" => {
22877 self.write_keyword("SQL_VARIANT");
22878 }
22879 Some(DialectType::DuckDB) if name_upper == "DECFLOAT" => {
22880 self.write_keyword("DECIMAL(38, 5)");
22881 }
22882 Some(DialectType::Exasol) => {
22883 match name_upper.as_str() {
22885 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => self.write_keyword("VARCHAR"),
22887 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => self.write_keyword("VARCHAR"),
22889 "MEDIUMINT" => self.write_keyword("INT"),
22891 "DECIMAL32" | "DECIMAL64" | "DECIMAL128" | "DECIMAL256" => {
22893 self.write_keyword("DECIMAL")
22894 }
22895 "DATETIME" => self.write_keyword("TIMESTAMP"),
22897 "TIMESTAMPLTZ" => self.write_keyword("TIMESTAMP WITH LOCAL TIME ZONE"),
22898 _ => self.write(name),
22899 }
22900 }
22901 Some(DialectType::Dremio) => {
22902 match name_upper.as_str() {
22904 "TIMESTAMPNTZ" | "DATETIME" => self.write_keyword("TIMESTAMP"),
22905 "ARRAY" => self.write_keyword("LIST"),
22906 "NCHAR" => self.write_keyword("VARCHAR"),
22907 _ => self.write(name),
22908 }
22909 }
22910 _ => {
22912 let (base_upper, _args_str) = if let Some(idx) = name_upper.find('(') {
22914 (name_upper[..idx].to_string(), Some(&name[idx..]))
22915 } else {
22916 (name_upper.clone(), None)
22917 };
22918
22919 match base_upper.as_str() {
22920 "INT64"
22921 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
22922 {
22923 self.write_keyword("BIGINT");
22924 }
22925 "FLOAT64"
22926 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
22927 {
22928 self.write_keyword("DOUBLE");
22929 }
22930 "BOOL"
22931 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
22932 {
22933 self.write_keyword("BOOLEAN");
22934 }
22935 "BYTES"
22936 if matches!(
22937 self.config.dialect,
22938 Some(DialectType::Spark)
22939 | Some(DialectType::Hive)
22940 | Some(DialectType::Databricks)
22941 ) =>
22942 {
22943 self.write_keyword("BINARY");
22944 }
22945 "BYTES"
22946 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
22947 {
22948 self.write_keyword("VARBINARY");
22949 }
22950 "DATETIME2" | "SMALLDATETIME"
22952 if !matches!(
22953 self.config.dialect,
22954 Some(DialectType::TSQL) | Some(DialectType::Fabric)
22955 ) =>
22956 {
22957 if matches!(
22959 self.config.dialect,
22960 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
22961 ) {
22962 self.write_keyword("TIMESTAMP");
22963 if let Some(args) = _args_str {
22964 self.write(args);
22965 }
22966 } else {
22967 self.write_keyword("TIMESTAMP");
22968 }
22969 }
22970 "DATETIMEOFFSET"
22972 if !matches!(
22973 self.config.dialect,
22974 Some(DialectType::TSQL) | Some(DialectType::Fabric)
22975 ) =>
22976 {
22977 if matches!(
22978 self.config.dialect,
22979 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
22980 ) {
22981 self.write_keyword("TIMESTAMPTZ");
22982 if let Some(args) = _args_str {
22983 self.write(args);
22984 }
22985 } else {
22986 self.write_keyword("TIMESTAMPTZ");
22987 }
22988 }
22989 "UNIQUEIDENTIFIER"
22991 if !matches!(
22992 self.config.dialect,
22993 Some(DialectType::TSQL) | Some(DialectType::Fabric)
22994 ) =>
22995 {
22996 match self.config.dialect {
22997 Some(DialectType::Spark)
22998 | Some(DialectType::Databricks)
22999 | Some(DialectType::Hive) => self.write_keyword("STRING"),
23000 _ => self.write_keyword("UUID"),
23001 }
23002 }
23003 "BIT"
23005 if !matches!(
23006 self.config.dialect,
23007 Some(DialectType::TSQL)
23008 | Some(DialectType::Fabric)
23009 | Some(DialectType::PostgreSQL)
23010 | Some(DialectType::MySQL)
23011 | Some(DialectType::DuckDB)
23012 ) =>
23013 {
23014 self.write_keyword("BOOLEAN");
23015 }
23016 "NVARCHAR"
23018 if !matches!(
23019 self.config.dialect,
23020 Some(DialectType::TSQL) | Some(DialectType::Fabric)
23021 ) =>
23022 {
23023 match self.config.dialect {
23024 Some(DialectType::Oracle) => {
23025 self.write_keyword("NVARCHAR2");
23027 if let Some(args) = _args_str {
23028 self.write(args);
23029 }
23030 }
23031 Some(DialectType::BigQuery) => {
23032 self.write_keyword("STRING");
23034 }
23035 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
23036 self.write_keyword("TEXT");
23037 if let Some(args) = _args_str {
23038 self.write(args);
23039 }
23040 }
23041 Some(DialectType::Hive) => {
23042 self.write_keyword("STRING");
23044 }
23045 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
23046 if _args_str.is_some() {
23047 self.write_keyword("VARCHAR");
23048 self.write(_args_str.unwrap());
23049 } else {
23050 self.write_keyword("STRING");
23051 }
23052 }
23053 _ => {
23054 self.write_keyword("VARCHAR");
23055 if let Some(args) = _args_str {
23056 self.write(args);
23057 }
23058 }
23059 }
23060 }
23061 "NCHAR"
23063 if !matches!(
23064 self.config.dialect,
23065 Some(DialectType::TSQL) | Some(DialectType::Fabric)
23066 ) =>
23067 {
23068 match self.config.dialect {
23069 Some(DialectType::Oracle) => {
23070 self.write_keyword("NCHAR");
23072 if let Some(args) = _args_str {
23073 self.write(args);
23074 }
23075 }
23076 Some(DialectType::BigQuery) => {
23077 self.write_keyword("STRING");
23079 }
23080 Some(DialectType::Hive) => {
23081 self.write_keyword("STRING");
23083 }
23084 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
23085 self.write_keyword("TEXT");
23086 if let Some(args) = _args_str {
23087 self.write(args);
23088 }
23089 }
23090 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
23091 if _args_str.is_some() {
23092 self.write_keyword("CHAR");
23093 self.write(_args_str.unwrap());
23094 } else {
23095 self.write_keyword("STRING");
23096 }
23097 }
23098 _ => {
23099 self.write_keyword("CHAR");
23100 if let Some(args) = _args_str {
23101 self.write(args);
23102 }
23103 }
23104 }
23105 }
23106 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => match self.config.dialect {
23109 Some(DialectType::MySQL)
23110 | Some(DialectType::SingleStore)
23111 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
23112 Some(DialectType::Spark)
23113 | Some(DialectType::Databricks)
23114 | Some(DialectType::Hive) => self.write_keyword("TEXT"),
23115 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
23116 Some(DialectType::Presto)
23117 | Some(DialectType::Trino)
23118 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
23119 Some(DialectType::Snowflake)
23120 | Some(DialectType::Redshift)
23121 | Some(DialectType::Dremio) => self.write_keyword("VARCHAR"),
23122 _ => self.write_keyword("TEXT"),
23123 },
23124 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => match self.config.dialect {
23127 Some(DialectType::MySQL)
23128 | Some(DialectType::SingleStore)
23129 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
23130 Some(DialectType::Spark)
23131 | Some(DialectType::Databricks)
23132 | Some(DialectType::Hive) => self.write_keyword("BLOB"),
23133 Some(DialectType::DuckDB) => self.write_keyword("VARBINARY"),
23134 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
23135 Some(DialectType::Presto)
23136 | Some(DialectType::Trino)
23137 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
23138 Some(DialectType::Snowflake)
23139 | Some(DialectType::Redshift)
23140 | Some(DialectType::Dremio) => self.write_keyword("VARBINARY"),
23141 _ => self.write_keyword("BLOB"),
23142 },
23143 "LONGVARCHAR" => match self.config.dialect {
23145 Some(DialectType::SQLite) => self.write_keyword("TEXT"),
23146 _ => self.write_keyword("VARCHAR"),
23147 },
23148 "DATETIME" => {
23150 match self.config.dialect {
23151 Some(DialectType::MySQL)
23152 | Some(DialectType::Doris)
23153 | Some(DialectType::StarRocks)
23154 | Some(DialectType::TSQL)
23155 | Some(DialectType::Fabric)
23156 | Some(DialectType::BigQuery)
23157 | Some(DialectType::SQLite)
23158 | Some(DialectType::Snowflake) => {
23159 self.write_keyword("DATETIME");
23160 if let Some(args) = _args_str {
23161 self.write(args);
23162 }
23163 }
23164 Some(_) => {
23165 self.write_keyword("TIMESTAMP");
23167 if let Some(args) = _args_str {
23168 self.write(args);
23169 }
23170 }
23171 None => {
23172 self.write(name);
23174 }
23175 }
23176 }
23177 "VARCHAR2"
23179 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
23180 {
23181 match self.config.dialect {
23182 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
23183 self.write_keyword("TEXT");
23184 }
23185 Some(DialectType::Hive)
23186 | Some(DialectType::Spark)
23187 | Some(DialectType::Databricks)
23188 | Some(DialectType::BigQuery)
23189 | Some(DialectType::ClickHouse)
23190 | Some(DialectType::StarRocks)
23191 | Some(DialectType::Doris) => {
23192 self.write_keyword("STRING");
23193 }
23194 _ => {
23195 self.write_keyword("VARCHAR");
23196 if let Some(args) = _args_str {
23197 self.write(args);
23198 }
23199 }
23200 }
23201 }
23202 "NVARCHAR2"
23203 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
23204 {
23205 match self.config.dialect {
23206 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
23207 self.write_keyword("TEXT");
23208 }
23209 Some(DialectType::Hive)
23210 | Some(DialectType::Spark)
23211 | Some(DialectType::Databricks)
23212 | Some(DialectType::BigQuery)
23213 | Some(DialectType::ClickHouse)
23214 | Some(DialectType::StarRocks)
23215 | Some(DialectType::Doris) => {
23216 self.write_keyword("STRING");
23217 }
23218 _ => {
23219 self.write_keyword("VARCHAR");
23220 if let Some(args) = _args_str {
23221 self.write(args);
23222 }
23223 }
23224 }
23225 }
23226 _ => self.write(name),
23227 }
23228 }
23229 }
23230 }
23231 DataType::Geometry { subtype, srid } => {
23232 match self.config.dialect {
23234 Some(DialectType::MySQL) => {
23235 if let Some(sub) = subtype {
23237 self.write_keyword(sub);
23238 if let Some(s) = srid {
23239 self.write(" SRID ");
23240 self.write(&s.to_string());
23241 }
23242 } else {
23243 self.write_keyword("GEOMETRY");
23244 }
23245 }
23246 Some(DialectType::BigQuery) => {
23247 self.write_keyword("GEOGRAPHY");
23249 }
23250 Some(DialectType::Teradata) => {
23251 self.write_keyword("ST_GEOMETRY");
23253 if subtype.is_some() || srid.is_some() {
23254 self.write("(");
23255 if let Some(sub) = subtype {
23256 self.write_keyword(sub);
23257 }
23258 if let Some(s) = srid {
23259 if subtype.is_some() {
23260 self.write(", ");
23261 }
23262 self.write(&s.to_string());
23263 }
23264 self.write(")");
23265 }
23266 }
23267 _ => {
23268 self.write_keyword("GEOMETRY");
23270 if subtype.is_some() || srid.is_some() {
23271 self.write("(");
23272 if let Some(sub) = subtype {
23273 self.write_keyword(sub);
23274 }
23275 if let Some(s) = srid {
23276 if subtype.is_some() {
23277 self.write(", ");
23278 }
23279 self.write(&s.to_string());
23280 }
23281 self.write(")");
23282 }
23283 }
23284 }
23285 }
23286 DataType::Geography { subtype, srid } => {
23287 match self.config.dialect {
23289 Some(DialectType::MySQL) => {
23290 if let Some(sub) = subtype {
23292 self.write_keyword(sub);
23293 } else {
23294 self.write_keyword("GEOMETRY");
23295 }
23296 let effective_srid = srid.unwrap_or(4326);
23298 self.write(" SRID ");
23299 self.write(&effective_srid.to_string());
23300 }
23301 Some(DialectType::BigQuery) => {
23302 self.write_keyword("GEOGRAPHY");
23304 }
23305 Some(DialectType::Snowflake) => {
23306 self.write_keyword("GEOGRAPHY");
23308 }
23309 _ => {
23310 self.write_keyword("GEOGRAPHY");
23312 if subtype.is_some() || srid.is_some() {
23313 self.write("(");
23314 if let Some(sub) = subtype {
23315 self.write_keyword(sub);
23316 }
23317 if let Some(s) = srid {
23318 if subtype.is_some() {
23319 self.write(", ");
23320 }
23321 self.write(&s.to_string());
23322 }
23323 self.write(")");
23324 }
23325 }
23326 }
23327 }
23328 DataType::CharacterSet { name } => {
23329 self.write_keyword("CHAR CHARACTER SET ");
23331 self.write(name);
23332 }
23333 _ => self.write("UNKNOWN"),
23334 }
23335 Ok(())
23336 }
23337
23338 fn write(&mut self, s: &str) {
23341 self.output.push_str(s);
23342 }
23343
23344 fn write_space(&mut self) {
23345 self.output.push(' ');
23346 }
23347
23348 fn write_keyword(&mut self, keyword: &str) {
23349 if self.config.uppercase_keywords {
23350 self.output.push_str(keyword);
23351 } else {
23352 self.output.push_str(&keyword.to_lowercase());
23353 }
23354 }
23355
23356 fn write_func_name(&mut self, name: &str) {
23358 let normalized = self.normalize_func_name(name);
23359 self.output.push_str(&normalized);
23360 }
23361
23362 fn convert_strptime_to_exasol_format(format: &str) -> String {
23366 let mut result = String::new();
23367 let chars: Vec<char> = format.chars().collect();
23368 let mut i = 0;
23369 while i < chars.len() {
23370 if chars[i] == '%' && i + 1 < chars.len() {
23371 let spec = chars[i + 1];
23372 let exasol_spec = match spec {
23373 'Y' => "YYYY",
23374 'y' => "YY",
23375 'm' => "MM",
23376 'd' => "DD",
23377 'H' => "HH",
23378 'M' => "MI",
23379 'S' => "SS",
23380 'a' => "DY", 'A' => "DAY", 'b' => "MON", 'B' => "MONTH", 'I' => "H12", 'u' => "ID", 'V' => "IW", 'G' => "IYYY", 'W' => "UW", 'U' => "UW", 'z' => "Z", _ => {
23392 result.push('%');
23394 result.push(spec);
23395 i += 2;
23396 continue;
23397 }
23398 };
23399 result.push_str(exasol_spec);
23400 i += 2;
23401 } else {
23402 result.push(chars[i]);
23403 i += 1;
23404 }
23405 }
23406 result
23407 }
23408
23409 fn convert_strptime_to_postgres_format(format: &str) -> String {
23413 let mut result = String::new();
23414 let chars: Vec<char> = format.chars().collect();
23415 let mut i = 0;
23416 while i < chars.len() {
23417 if chars[i] == '%' && i + 1 < chars.len() {
23418 if chars[i + 1] == '-' && i + 2 < chars.len() {
23420 let spec = chars[i + 2];
23421 let pg_spec = match spec {
23422 'd' => "FMDD",
23423 'm' => "FMMM",
23424 'H' => "FMHH24",
23425 'M' => "FMMI",
23426 'S' => "FMSS",
23427 _ => {
23428 result.push('%');
23429 result.push('-');
23430 result.push(spec);
23431 i += 3;
23432 continue;
23433 }
23434 };
23435 result.push_str(pg_spec);
23436 i += 3;
23437 continue;
23438 }
23439 let spec = chars[i + 1];
23440 let pg_spec = match spec {
23441 'Y' => "YYYY",
23442 'y' => "YY",
23443 'm' => "MM",
23444 'd' => "DD",
23445 'H' => "HH24",
23446 'I' => "HH12",
23447 'M' => "MI",
23448 'S' => "SS",
23449 'f' => "US", 'u' => "D", 'j' => "DDD", 'z' => "OF", 'Z' => "TZ", 'A' => "TMDay", 'a' => "TMDy", 'b' => "TMMon", 'B' => "TMMonth", 'U' => "WW", _ => {
23460 result.push('%');
23462 result.push(spec);
23463 i += 2;
23464 continue;
23465 }
23466 };
23467 result.push_str(pg_spec);
23468 i += 2;
23469 } else {
23470 result.push(chars[i]);
23471 i += 1;
23472 }
23473 }
23474 result
23475 }
23476
23477 fn write_limit_expr(&mut self, expr: &Expression) -> Result<()> {
23479 if self.config.limit_only_literals {
23480 if let Some(value) = Self::try_evaluate_constant(expr) {
23481 self.write(&value.to_string());
23482 return Ok(());
23483 }
23484 }
23485 self.generate_expression(expr)
23486 }
23487
23488 fn write_formatted_comment(&mut self, comment: &str) {
23492 let content = if comment.starts_with("/*") && comment.ends_with("*/") {
23495 &comment[2..comment.len() - 2]
23498 } else if comment.starts_with("--") {
23499 &comment[2..]
23502 } else {
23503 comment
23505 };
23506 if content.trim().is_empty() {
23508 return;
23509 }
23510 self.output.push_str("/*");
23512 if !content.starts_with(' ') {
23513 self.output.push(' ');
23514 }
23515 self.output.push_str(content);
23516 if !content.ends_with(' ') {
23517 self.output.push(' ');
23518 }
23519 self.output.push_str("*/");
23520 }
23521
23522 fn escape_block_for_single_quote(&self, block: &str) -> String {
23525 let escape_backslash = matches!(
23526 self.config.dialect,
23527 Some(crate::dialects::DialectType::Snowflake)
23528 );
23529 let mut escaped = String::with_capacity(block.len() + 4);
23530 for ch in block.chars() {
23531 if ch == '\'' {
23532 escaped.push('\\');
23533 escaped.push('\'');
23534 } else if escape_backslash && ch == '\\' {
23535 escaped.push('\\');
23536 escaped.push('\\');
23537 } else {
23538 escaped.push(ch);
23539 }
23540 }
23541 escaped
23542 }
23543
23544 fn write_newline(&mut self) {
23545 self.output.push('\n');
23546 }
23547
23548 fn write_indent(&mut self) {
23549 for _ in 0..self.indent_level {
23550 self.output.push_str(&self.config.indent);
23551 }
23552 }
23553
23554 fn too_wide(&self, args: &[String]) -> bool {
23560 args.iter().map(|s| s.len()).sum::<usize>() > self.config.max_text_width
23561 }
23562
23563 fn generate_to_string(&self, expr: &Expression) -> Result<String> {
23566 let config = GeneratorConfig {
23567 pretty: false,
23568 dialect: self.config.dialect,
23569 ..Default::default()
23570 };
23571 let mut gen = Generator::with_config(config);
23572 gen.generate_expression(expr)?;
23573 Ok(gen.output)
23574 }
23575
23576 fn write_clause_condition(&mut self, keyword: &str, condition: &Expression) -> Result<()> {
23579 if self.config.pretty {
23580 self.write_newline();
23581 self.write_indent();
23582 self.write_keyword(keyword);
23583 self.write_newline();
23584 self.indent_level += 1;
23585 self.write_indent();
23586 self.generate_expression(condition)?;
23587 self.indent_level -= 1;
23588 } else {
23589 self.write_space();
23590 self.write_keyword(keyword);
23591 self.write_space();
23592 self.generate_expression(condition)?;
23593 }
23594 Ok(())
23595 }
23596
23597 fn write_clause_expressions(&mut self, keyword: &str, exprs: &[Expression]) -> Result<()> {
23600 if exprs.is_empty() {
23601 return Ok(());
23602 }
23603
23604 if self.config.pretty {
23605 self.write_newline();
23606 self.write_indent();
23607 self.write_keyword(keyword);
23608 self.write_newline();
23609 self.indent_level += 1;
23610 for (i, expr) in exprs.iter().enumerate() {
23611 if i > 0 {
23612 self.write(",");
23613 self.write_newline();
23614 }
23615 self.write_indent();
23616 self.generate_expression(expr)?;
23617 }
23618 self.indent_level -= 1;
23619 } else {
23620 self.write_space();
23621 self.write_keyword(keyword);
23622 self.write_space();
23623 for (i, expr) in exprs.iter().enumerate() {
23624 if i > 0 {
23625 self.write(", ");
23626 }
23627 self.generate_expression(expr)?;
23628 }
23629 }
23630 Ok(())
23631 }
23632
23633 fn write_order_clause(&mut self, keyword: &str, orderings: &[Ordered]) -> Result<()> {
23635 if orderings.is_empty() {
23636 return Ok(());
23637 }
23638
23639 if self.config.pretty {
23640 self.write_newline();
23641 self.write_indent();
23642 self.write_keyword(keyword);
23643 self.write_newline();
23644 self.indent_level += 1;
23645 for (i, ordered) in orderings.iter().enumerate() {
23646 if i > 0 {
23647 self.write(",");
23648 self.write_newline();
23649 }
23650 self.write_indent();
23651 self.generate_ordered(ordered)?;
23652 }
23653 self.indent_level -= 1;
23654 } else {
23655 self.write_space();
23656 self.write_keyword(keyword);
23657 self.write_space();
23658 for (i, ordered) in orderings.iter().enumerate() {
23659 if i > 0 {
23660 self.write(", ");
23661 }
23662 self.generate_ordered(ordered)?;
23663 }
23664 }
23665 Ok(())
23666 }
23667
23668 fn write_window_clause(&mut self, windows: &[NamedWindow]) -> Result<()> {
23670 if windows.is_empty() {
23671 return Ok(());
23672 }
23673
23674 if self.config.pretty {
23675 self.write_newline();
23676 self.write_indent();
23677 self.write_keyword("WINDOW");
23678 self.write_newline();
23679 self.indent_level += 1;
23680 for (i, named_window) in windows.iter().enumerate() {
23681 if i > 0 {
23682 self.write(",");
23683 self.write_newline();
23684 }
23685 self.write_indent();
23686 self.generate_identifier(&named_window.name)?;
23687 self.write_space();
23688 self.write_keyword("AS");
23689 self.write(" (");
23690 self.generate_over(&named_window.spec)?;
23691 self.write(")");
23692 }
23693 self.indent_level -= 1;
23694 } else {
23695 self.write_space();
23696 self.write_keyword("WINDOW");
23697 self.write_space();
23698 for (i, named_window) in windows.iter().enumerate() {
23699 if i > 0 {
23700 self.write(", ");
23701 }
23702 self.generate_identifier(&named_window.name)?;
23703 self.write_space();
23704 self.write_keyword("AS");
23705 self.write(" (");
23706 self.generate_over(&named_window.spec)?;
23707 self.write(")");
23708 }
23709 }
23710 Ok(())
23711 }
23712
23713 fn generate_ai_agg(&mut self, e: &AIAgg) -> Result<()> {
23715 self.write_keyword("AI_AGG");
23717 self.write("(");
23718 self.generate_expression(&e.this)?;
23719 self.write(", ");
23720 self.generate_expression(&e.expression)?;
23721 self.write(")");
23722 Ok(())
23723 }
23724
23725 fn generate_ai_classify(&mut self, e: &AIClassify) -> Result<()> {
23726 self.write_keyword("AI_CLASSIFY");
23728 self.write("(");
23729 self.generate_expression(&e.this)?;
23730 if let Some(categories) = &e.categories {
23731 self.write(", ");
23732 self.generate_expression(categories)?;
23733 }
23734 if let Some(config) = &e.config {
23735 self.write(", ");
23736 self.generate_expression(config)?;
23737 }
23738 self.write(")");
23739 Ok(())
23740 }
23741
23742 fn generate_add_partition(&mut self, e: &AddPartition) -> Result<()> {
23743 self.write_keyword("ADD");
23745 self.write_space();
23746 if e.exists {
23747 self.write_keyword("IF NOT EXISTS");
23748 self.write_space();
23749 }
23750 self.generate_expression(&e.this)?;
23751 if let Some(location) = &e.location {
23752 self.write_space();
23753 self.generate_expression(location)?;
23754 }
23755 Ok(())
23756 }
23757
23758 fn generate_algorithm_property(&mut self, e: &AlgorithmProperty) -> Result<()> {
23759 self.write_keyword("ALGORITHM");
23761 self.write("=");
23762 self.generate_expression(&e.this)?;
23763 Ok(())
23764 }
23765
23766 fn generate_aliases(&mut self, e: &Aliases) -> Result<()> {
23767 self.generate_expression(&e.this)?;
23769 self.write_space();
23770 self.write_keyword("AS");
23771 self.write(" (");
23772 for (i, expr) in e.expressions.iter().enumerate() {
23773 if i > 0 {
23774 self.write(", ");
23775 }
23776 self.generate_expression(expr)?;
23777 }
23778 self.write(")");
23779 Ok(())
23780 }
23781
23782 fn generate_allowed_values_property(&mut self, e: &AllowedValuesProperty) -> Result<()> {
23783 self.write_keyword("ALLOWED_VALUES");
23785 self.write_space();
23786 for (i, expr) in e.expressions.iter().enumerate() {
23787 if i > 0 {
23788 self.write(", ");
23789 }
23790 self.generate_expression(expr)?;
23791 }
23792 Ok(())
23793 }
23794
23795 fn generate_alter_column(&mut self, e: &AlterColumn) -> Result<()> {
23796 self.write_keyword("ALTER COLUMN");
23798 self.write_space();
23799 self.generate_expression(&e.this)?;
23800
23801 if let Some(dtype) = &e.dtype {
23802 self.write_space();
23803 self.write_keyword("SET DATA TYPE");
23804 self.write_space();
23805 self.generate_expression(dtype)?;
23806 if let Some(collate) = &e.collate {
23807 self.write_space();
23808 self.write_keyword("COLLATE");
23809 self.write_space();
23810 self.generate_expression(collate)?;
23811 }
23812 if let Some(using) = &e.using {
23813 self.write_space();
23814 self.write_keyword("USING");
23815 self.write_space();
23816 self.generate_expression(using)?;
23817 }
23818 } else if let Some(default) = &e.default {
23819 self.write_space();
23820 self.write_keyword("SET DEFAULT");
23821 self.write_space();
23822 self.generate_expression(default)?;
23823 } else if let Some(comment) = &e.comment {
23824 self.write_space();
23825 self.write_keyword("COMMENT");
23826 self.write_space();
23827 self.generate_expression(comment)?;
23828 } else if let Some(drop) = &e.drop {
23829 self.write_space();
23830 self.write_keyword("DROP");
23831 self.write_space();
23832 self.generate_expression(drop)?;
23833 } else if let Some(visible) = &e.visible {
23834 self.write_space();
23835 self.generate_expression(visible)?;
23836 } else if let Some(rename_to) = &e.rename_to {
23837 self.write_space();
23838 self.write_keyword("RENAME TO");
23839 self.write_space();
23840 self.generate_expression(rename_to)?;
23841 } else if let Some(allow_null) = &e.allow_null {
23842 self.write_space();
23843 self.generate_expression(allow_null)?;
23844 }
23845 Ok(())
23846 }
23847
23848 fn generate_alter_session(&mut self, e: &AlterSession) -> Result<()> {
23849 self.write_keyword("ALTER SESSION");
23851 self.write_space();
23852 if e.unset.is_some() {
23853 self.write_keyword("UNSET");
23854 } else {
23855 self.write_keyword("SET");
23856 }
23857 self.write_space();
23858 for (i, expr) in e.expressions.iter().enumerate() {
23859 if i > 0 {
23860 self.write(", ");
23861 }
23862 self.generate_expression(expr)?;
23863 }
23864 Ok(())
23865 }
23866
23867 fn generate_alter_set(&mut self, e: &AlterSet) -> Result<()> {
23868 self.write_keyword("SET");
23870
23871 if let Some(opt) = &e.option {
23873 self.write_space();
23874 self.generate_expression(opt)?;
23875 }
23876
23877 if !e.expressions.is_empty() {
23880 let is_properties = e
23882 .expressions
23883 .iter()
23884 .any(|expr| matches!(expr, Expression::Eq(_)));
23885 if is_properties && e.option.is_none() {
23886 self.write_space();
23887 self.write_keyword("PROPERTIES");
23888 }
23889 self.write_space();
23890 for (i, expr) in e.expressions.iter().enumerate() {
23891 if i > 0 {
23892 self.write(", ");
23893 }
23894 self.generate_expression(expr)?;
23895 }
23896 }
23897
23898 if let Some(file_format) = &e.file_format {
23900 self.write(" ");
23901 self.write_keyword("STAGE_FILE_FORMAT");
23902 self.write(" = (");
23903 self.generate_space_separated_properties(file_format)?;
23904 self.write(")");
23905 }
23906
23907 if let Some(copy_options) = &e.copy_options {
23909 self.write(" ");
23910 self.write_keyword("STAGE_COPY_OPTIONS");
23911 self.write(" = (");
23912 self.generate_space_separated_properties(copy_options)?;
23913 self.write(")");
23914 }
23915
23916 if let Some(tag) = &e.tag {
23918 self.write(" ");
23919 self.write_keyword("TAG");
23920 self.write(" ");
23921 self.generate_expression(tag)?;
23922 }
23923
23924 Ok(())
23925 }
23926
23927 fn generate_space_separated_properties(&mut self, expr: &Expression) -> Result<()> {
23929 match expr {
23930 Expression::Tuple(t) => {
23931 for (i, prop) in t.expressions.iter().enumerate() {
23932 if i > 0 {
23933 self.write(" ");
23934 }
23935 self.generate_expression(prop)?;
23936 }
23937 }
23938 _ => {
23939 self.generate_expression(expr)?;
23940 }
23941 }
23942 Ok(())
23943 }
23944
23945 fn generate_alter_sort_key(&mut self, e: &AlterSortKey) -> Result<()> {
23946 self.write_keyword("ALTER");
23948 if e.compound.is_some() {
23949 self.write_space();
23950 self.write_keyword("COMPOUND");
23951 }
23952 self.write_space();
23953 self.write_keyword("SORTKEY");
23954 self.write_space();
23955 if let Some(this) = &e.this {
23956 self.generate_expression(this)?;
23957 } else if !e.expressions.is_empty() {
23958 self.write("(");
23959 for (i, expr) in e.expressions.iter().enumerate() {
23960 if i > 0 {
23961 self.write(", ");
23962 }
23963 self.generate_expression(expr)?;
23964 }
23965 self.write(")");
23966 }
23967 Ok(())
23968 }
23969
23970 fn generate_analyze(&mut self, e: &Analyze) -> Result<()> {
23971 self.write_keyword("ANALYZE");
23973 if !e.options.is_empty() {
23974 self.write_space();
23975 for (i, opt) in e.options.iter().enumerate() {
23976 if i > 0 {
23977 self.write_space();
23978 }
23979 if let Expression::Identifier(id) = opt {
23981 self.write_keyword(&id.name);
23982 } else {
23983 self.generate_expression(opt)?;
23984 }
23985 }
23986 }
23987 if let Some(kind) = &e.kind {
23988 self.write_space();
23989 self.write_keyword(kind);
23990 }
23991 if let Some(this) = &e.this {
23992 self.write_space();
23993 self.generate_expression(this)?;
23994 }
23995 if !e.columns.is_empty() {
23997 self.write("(");
23998 for (i, col) in e.columns.iter().enumerate() {
23999 if i > 0 {
24000 self.write(", ");
24001 }
24002 self.write(col);
24003 }
24004 self.write(")");
24005 }
24006 if let Some(partition) = &e.partition {
24007 self.write_space();
24008 self.generate_expression(partition)?;
24009 }
24010 if let Some(mode) = &e.mode {
24011 self.write_space();
24012 self.generate_expression(mode)?;
24013 }
24014 if let Some(expression) = &e.expression {
24015 self.write_space();
24016 self.generate_expression(expression)?;
24017 }
24018 if !e.properties.is_empty() {
24019 self.write_space();
24020 self.write_keyword(self.config.with_properties_prefix);
24021 self.write(" (");
24022 for (i, prop) in e.properties.iter().enumerate() {
24023 if i > 0 {
24024 self.write(", ");
24025 }
24026 self.generate_expression(prop)?;
24027 }
24028 self.write(")");
24029 }
24030 Ok(())
24031 }
24032
24033 fn generate_analyze_delete(&mut self, e: &AnalyzeDelete) -> Result<()> {
24034 self.write_keyword("DELETE");
24036 if let Some(kind) = &e.kind {
24037 self.write_space();
24038 self.write_keyword(kind);
24039 }
24040 self.write_space();
24041 self.write_keyword("STATISTICS");
24042 Ok(())
24043 }
24044
24045 fn generate_analyze_histogram(&mut self, e: &AnalyzeHistogram) -> Result<()> {
24046 if let Expression::Identifier(id) = e.this.as_ref() {
24049 self.write_keyword(&id.name);
24050 } else {
24051 self.generate_expression(&e.this)?;
24052 }
24053 self.write_space();
24054 self.write_keyword("HISTOGRAM ON");
24055 self.write_space();
24056 for (i, expr) in e.expressions.iter().enumerate() {
24057 if i > 0 {
24058 self.write(", ");
24059 }
24060 self.generate_expression(expr)?;
24061 }
24062 if let Some(expression) = &e.expression {
24063 self.write_space();
24064 self.generate_expression(expression)?;
24065 }
24066 if let Some(update_options) = &e.update_options {
24067 self.write_space();
24068 self.generate_expression(update_options)?;
24069 self.write_space();
24070 self.write_keyword("UPDATE");
24071 }
24072 Ok(())
24073 }
24074
24075 fn generate_analyze_list_chained_rows(&mut self, e: &AnalyzeListChainedRows) -> Result<()> {
24076 self.write_keyword("LIST CHAINED ROWS");
24078 if let Some(expression) = &e.expression {
24079 self.write_space();
24080 self.write_keyword("INTO");
24081 self.write_space();
24082 self.generate_expression(expression)?;
24083 }
24084 Ok(())
24085 }
24086
24087 fn generate_analyze_sample(&mut self, e: &AnalyzeSample) -> Result<()> {
24088 self.write_keyword("SAMPLE");
24090 self.write_space();
24091 if let Some(sample) = &e.sample {
24092 self.generate_expression(sample)?;
24093 self.write_space();
24094 }
24095 self.write_keyword(&e.kind);
24096 Ok(())
24097 }
24098
24099 fn generate_analyze_statistics(&mut self, e: &AnalyzeStatistics) -> Result<()> {
24100 self.write_keyword(&e.kind);
24102 if let Some(option) = &e.option {
24103 self.write_space();
24104 self.generate_expression(option)?;
24105 }
24106 self.write_space();
24107 self.write_keyword("STATISTICS");
24108 if let Some(this) = &e.this {
24109 self.write_space();
24110 self.generate_expression(this)?;
24111 }
24112 if !e.expressions.is_empty() {
24113 self.write_space();
24114 for (i, expr) in e.expressions.iter().enumerate() {
24115 if i > 0 {
24116 self.write(", ");
24117 }
24118 self.generate_expression(expr)?;
24119 }
24120 }
24121 Ok(())
24122 }
24123
24124 fn generate_analyze_validate(&mut self, e: &AnalyzeValidate) -> Result<()> {
24125 self.write_keyword("VALIDATE");
24127 self.write_space();
24128 self.write_keyword(&e.kind);
24129 if let Some(this) = &e.this {
24130 self.write_space();
24131 if let Expression::Identifier(id) = this.as_ref() {
24133 self.write_keyword(&id.name);
24134 } else {
24135 self.generate_expression(this)?;
24136 }
24137 }
24138 if let Some(expression) = &e.expression {
24139 self.write_space();
24140 self.write_keyword("INTO");
24141 self.write_space();
24142 self.generate_expression(expression)?;
24143 }
24144 Ok(())
24145 }
24146
24147 fn generate_analyze_with(&mut self, e: &AnalyzeWith) -> Result<()> {
24148 self.write_keyword("WITH");
24150 self.write_space();
24151 for (i, expr) in e.expressions.iter().enumerate() {
24152 if i > 0 {
24153 self.write(", ");
24154 }
24155 self.generate_expression(expr)?;
24156 }
24157 Ok(())
24158 }
24159
24160 fn generate_anonymous(&mut self, e: &Anonymous) -> Result<()> {
24161 self.generate_expression(&e.this)?;
24164 self.write("(");
24165 for (i, arg) in e.expressions.iter().enumerate() {
24166 if i > 0 {
24167 self.write(", ");
24168 }
24169 self.generate_expression(arg)?;
24170 }
24171 self.write(")");
24172 Ok(())
24173 }
24174
24175 fn generate_anonymous_agg_func(&mut self, e: &AnonymousAggFunc) -> Result<()> {
24176 self.generate_expression(&e.this)?;
24178 self.write("(");
24179 for (i, arg) in e.expressions.iter().enumerate() {
24180 if i > 0 {
24181 self.write(", ");
24182 }
24183 self.generate_expression(arg)?;
24184 }
24185 self.write(")");
24186 Ok(())
24187 }
24188
24189 fn generate_apply(&mut self, e: &Apply) -> Result<()> {
24190 self.generate_expression(&e.this)?;
24192 self.write_space();
24193 self.write_keyword("APPLY");
24194 self.write("(");
24195 self.generate_expression(&e.expression)?;
24196 self.write(")");
24197 Ok(())
24198 }
24199
24200 fn generate_approx_percentile_estimate(&mut self, e: &ApproxPercentileEstimate) -> Result<()> {
24201 self.write_keyword("APPROX_PERCENTILE_ESTIMATE");
24203 self.write("(");
24204 self.generate_expression(&e.this)?;
24205 if let Some(percentile) = &e.percentile {
24206 self.write(", ");
24207 self.generate_expression(percentile)?;
24208 }
24209 self.write(")");
24210 Ok(())
24211 }
24212
24213 fn generate_approx_quantile(&mut self, e: &ApproxQuantile) -> Result<()> {
24214 self.write_keyword("APPROX_QUANTILE");
24216 self.write("(");
24217 self.generate_expression(&e.this)?;
24218 if let Some(quantile) = &e.quantile {
24219 self.write(", ");
24220 self.generate_expression(quantile)?;
24221 }
24222 if let Some(accuracy) = &e.accuracy {
24223 self.write(", ");
24224 self.generate_expression(accuracy)?;
24225 }
24226 if let Some(weight) = &e.weight {
24227 self.write(", ");
24228 self.generate_expression(weight)?;
24229 }
24230 self.write(")");
24231 Ok(())
24232 }
24233
24234 fn generate_approx_quantiles(&mut self, e: &ApproxQuantiles) -> Result<()> {
24235 self.write_keyword("APPROX_QUANTILES");
24237 self.write("(");
24238 self.generate_expression(&e.this)?;
24239 if let Some(expression) = &e.expression {
24240 self.write(", ");
24241 self.generate_expression(expression)?;
24242 }
24243 self.write(")");
24244 Ok(())
24245 }
24246
24247 fn generate_approx_top_k(&mut self, e: &ApproxTopK) -> Result<()> {
24248 self.write_keyword("APPROX_TOP_K");
24250 self.write("(");
24251 self.generate_expression(&e.this)?;
24252 if let Some(expression) = &e.expression {
24253 self.write(", ");
24254 self.generate_expression(expression)?;
24255 }
24256 if let Some(counters) = &e.counters {
24257 self.write(", ");
24258 self.generate_expression(counters)?;
24259 }
24260 self.write(")");
24261 Ok(())
24262 }
24263
24264 fn generate_approx_top_k_accumulate(&mut self, e: &ApproxTopKAccumulate) -> Result<()> {
24265 self.write_keyword("APPROX_TOP_K_ACCUMULATE");
24267 self.write("(");
24268 self.generate_expression(&e.this)?;
24269 if let Some(expression) = &e.expression {
24270 self.write(", ");
24271 self.generate_expression(expression)?;
24272 }
24273 self.write(")");
24274 Ok(())
24275 }
24276
24277 fn generate_approx_top_k_combine(&mut self, e: &ApproxTopKCombine) -> Result<()> {
24278 self.write_keyword("APPROX_TOP_K_COMBINE");
24280 self.write("(");
24281 self.generate_expression(&e.this)?;
24282 if let Some(expression) = &e.expression {
24283 self.write(", ");
24284 self.generate_expression(expression)?;
24285 }
24286 self.write(")");
24287 Ok(())
24288 }
24289
24290 fn generate_approx_top_k_estimate(&mut self, e: &ApproxTopKEstimate) -> Result<()> {
24291 self.write_keyword("APPROX_TOP_K_ESTIMATE");
24293 self.write("(");
24294 self.generate_expression(&e.this)?;
24295 if let Some(expression) = &e.expression {
24296 self.write(", ");
24297 self.generate_expression(expression)?;
24298 }
24299 self.write(")");
24300 Ok(())
24301 }
24302
24303 fn generate_approx_top_sum(&mut self, e: &ApproxTopSum) -> Result<()> {
24304 self.write_keyword("APPROX_TOP_SUM");
24306 self.write("(");
24307 self.generate_expression(&e.this)?;
24308 self.write(", ");
24309 self.generate_expression(&e.expression)?;
24310 if let Some(count) = &e.count {
24311 self.write(", ");
24312 self.generate_expression(count)?;
24313 }
24314 self.write(")");
24315 Ok(())
24316 }
24317
24318 fn generate_arg_max(&mut self, e: &ArgMax) -> Result<()> {
24319 self.write_keyword("ARG_MAX");
24321 self.write("(");
24322 self.generate_expression(&e.this)?;
24323 self.write(", ");
24324 self.generate_expression(&e.expression)?;
24325 if let Some(count) = &e.count {
24326 self.write(", ");
24327 self.generate_expression(count)?;
24328 }
24329 self.write(")");
24330 Ok(())
24331 }
24332
24333 fn generate_arg_min(&mut self, e: &ArgMin) -> Result<()> {
24334 self.write_keyword("ARG_MIN");
24336 self.write("(");
24337 self.generate_expression(&e.this)?;
24338 self.write(", ");
24339 self.generate_expression(&e.expression)?;
24340 if let Some(count) = &e.count {
24341 self.write(", ");
24342 self.generate_expression(count)?;
24343 }
24344 self.write(")");
24345 Ok(())
24346 }
24347
24348 fn generate_array_all(&mut self, e: &ArrayAll) -> Result<()> {
24349 self.write_keyword("ARRAY_ALL");
24351 self.write("(");
24352 self.generate_expression(&e.this)?;
24353 self.write(", ");
24354 self.generate_expression(&e.expression)?;
24355 self.write(")");
24356 Ok(())
24357 }
24358
24359 fn generate_array_any(&mut self, e: &ArrayAny) -> Result<()> {
24360 self.write_keyword("ARRAY_ANY");
24362 self.write("(");
24363 self.generate_expression(&e.this)?;
24364 self.write(", ");
24365 self.generate_expression(&e.expression)?;
24366 self.write(")");
24367 Ok(())
24368 }
24369
24370 fn generate_array_construct_compact(&mut self, e: &ArrayConstructCompact) -> Result<()> {
24371 self.write_keyword("ARRAY_CONSTRUCT_COMPACT");
24373 self.write("(");
24374 for (i, expr) in e.expressions.iter().enumerate() {
24375 if i > 0 {
24376 self.write(", ");
24377 }
24378 self.generate_expression(expr)?;
24379 }
24380 self.write(")");
24381 Ok(())
24382 }
24383
24384 fn generate_array_sum(&mut self, e: &ArraySum) -> Result<()> {
24385 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
24387 self.write("arraySum");
24388 } else {
24389 self.write_keyword("ARRAY_SUM");
24390 }
24391 self.write("(");
24392 self.generate_expression(&e.this)?;
24393 if let Some(expression) = &e.expression {
24394 self.write(", ");
24395 self.generate_expression(expression)?;
24396 }
24397 self.write(")");
24398 Ok(())
24399 }
24400
24401 fn generate_at_index(&mut self, e: &AtIndex) -> Result<()> {
24402 self.generate_expression(&e.this)?;
24404 self.write_space();
24405 self.write_keyword("AT");
24406 self.write_space();
24407 self.generate_expression(&e.expression)?;
24408 Ok(())
24409 }
24410
24411 fn generate_attach(&mut self, e: &Attach) -> Result<()> {
24412 self.write_keyword("ATTACH");
24414 if e.exists {
24415 self.write_space();
24416 self.write_keyword("IF NOT EXISTS");
24417 }
24418 self.write_space();
24419 self.generate_expression(&e.this)?;
24420 if !e.expressions.is_empty() {
24421 self.write(" (");
24422 for (i, expr) in e.expressions.iter().enumerate() {
24423 if i > 0 {
24424 self.write(", ");
24425 }
24426 self.generate_expression(expr)?;
24427 }
24428 self.write(")");
24429 }
24430 Ok(())
24431 }
24432
24433 fn generate_attach_option(&mut self, e: &AttachOption) -> Result<()> {
24434 self.generate_expression(&e.this)?;
24437 if let Some(expression) = &e.expression {
24438 self.write_space();
24439 self.generate_expression(expression)?;
24440 }
24441 Ok(())
24442 }
24443
24444 fn generate_auto_increment_keyword(
24448 &mut self,
24449 col: &crate::expressions::ColumnDef,
24450 ) -> Result<()> {
24451 use crate::dialects::DialectType;
24452 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
24453 self.write_keyword("IDENTITY");
24454 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
24455 self.write("(");
24456 if let Some(ref start) = col.auto_increment_start {
24457 self.generate_expression(start)?;
24458 } else {
24459 self.write("0");
24460 }
24461 self.write(", ");
24462 if let Some(ref inc) = col.auto_increment_increment {
24463 self.generate_expression(inc)?;
24464 } else {
24465 self.write("1");
24466 }
24467 self.write(")");
24468 }
24469 } else if matches!(
24470 self.config.dialect,
24471 Some(DialectType::Snowflake) | Some(DialectType::SQLite)
24472 ) {
24473 self.write_keyword("AUTOINCREMENT");
24474 if let Some(ref start) = col.auto_increment_start {
24475 self.write_space();
24476 self.write_keyword("START");
24477 self.write_space();
24478 self.generate_expression(start)?;
24479 }
24480 if let Some(ref inc) = col.auto_increment_increment {
24481 self.write_space();
24482 self.write_keyword("INCREMENT");
24483 self.write_space();
24484 self.generate_expression(inc)?;
24485 }
24486 if let Some(order) = col.auto_increment_order {
24487 self.write_space();
24488 if order {
24489 self.write_keyword("ORDER");
24490 } else {
24491 self.write_keyword("NOORDER");
24492 }
24493 }
24494 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
24495 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
24496 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
24497 self.write(" (");
24498 let mut first = true;
24499 if let Some(ref start) = col.auto_increment_start {
24500 self.write_keyword("START WITH");
24501 self.write_space();
24502 self.generate_expression(start)?;
24503 first = false;
24504 }
24505 if let Some(ref inc) = col.auto_increment_increment {
24506 if !first {
24507 self.write_space();
24508 }
24509 self.write_keyword("INCREMENT BY");
24510 self.write_space();
24511 self.generate_expression(inc)?;
24512 }
24513 self.write(")");
24514 }
24515 } else if matches!(self.config.dialect, Some(DialectType::Databricks)) {
24516 self.write_keyword("GENERATED ALWAYS AS IDENTITY");
24517 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
24518 self.write(" (");
24519 let mut first = true;
24520 if let Some(ref start) = col.auto_increment_start {
24521 self.write_keyword("START WITH");
24522 self.write_space();
24523 self.generate_expression(start)?;
24524 first = false;
24525 }
24526 if let Some(ref inc) = col.auto_increment_increment {
24527 if !first {
24528 self.write_space();
24529 }
24530 self.write_keyword("INCREMENT BY");
24531 self.write_space();
24532 self.generate_expression(inc)?;
24533 }
24534 self.write(")");
24535 }
24536 } else if matches!(
24537 self.config.dialect,
24538 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24539 ) {
24540 self.write_keyword("IDENTITY");
24541 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
24542 self.write("(");
24543 if let Some(ref start) = col.auto_increment_start {
24544 self.generate_expression(start)?;
24545 } else {
24546 self.write("0");
24547 }
24548 self.write(", ");
24549 if let Some(ref inc) = col.auto_increment_increment {
24550 self.generate_expression(inc)?;
24551 } else {
24552 self.write("1");
24553 }
24554 self.write(")");
24555 }
24556 } else {
24557 self.write_keyword("AUTO_INCREMENT");
24558 if let Some(ref start) = col.auto_increment_start {
24559 self.write_space();
24560 self.write_keyword("START");
24561 self.write_space();
24562 self.generate_expression(start)?;
24563 }
24564 if let Some(ref inc) = col.auto_increment_increment {
24565 self.write_space();
24566 self.write_keyword("INCREMENT");
24567 self.write_space();
24568 self.generate_expression(inc)?;
24569 }
24570 if let Some(order) = col.auto_increment_order {
24571 self.write_space();
24572 if order {
24573 self.write_keyword("ORDER");
24574 } else {
24575 self.write_keyword("NOORDER");
24576 }
24577 }
24578 }
24579 Ok(())
24580 }
24581
24582 fn generate_auto_increment_property(&mut self, e: &AutoIncrementProperty) -> Result<()> {
24583 self.write_keyword("AUTO_INCREMENT");
24585 self.write("=");
24586 self.generate_expression(&e.this)?;
24587 Ok(())
24588 }
24589
24590 fn generate_auto_refresh_property(&mut self, e: &AutoRefreshProperty) -> Result<()> {
24591 self.write_keyword("AUTO_REFRESH");
24593 self.write("=");
24594 self.generate_expression(&e.this)?;
24595 Ok(())
24596 }
24597
24598 fn generate_backup_property(&mut self, e: &BackupProperty) -> Result<()> {
24599 self.write_keyword("BACKUP");
24601 self.write_space();
24602 self.generate_expression(&e.this)?;
24603 Ok(())
24604 }
24605
24606 fn generate_base64_decode_binary(&mut self, e: &Base64DecodeBinary) -> Result<()> {
24607 self.write_keyword("BASE64_DECODE_BINARY");
24609 self.write("(");
24610 self.generate_expression(&e.this)?;
24611 if let Some(alphabet) = &e.alphabet {
24612 self.write(", ");
24613 self.generate_expression(alphabet)?;
24614 }
24615 self.write(")");
24616 Ok(())
24617 }
24618
24619 fn generate_base64_decode_string(&mut self, e: &Base64DecodeString) -> Result<()> {
24620 self.write_keyword("BASE64_DECODE_STRING");
24622 self.write("(");
24623 self.generate_expression(&e.this)?;
24624 if let Some(alphabet) = &e.alphabet {
24625 self.write(", ");
24626 self.generate_expression(alphabet)?;
24627 }
24628 self.write(")");
24629 Ok(())
24630 }
24631
24632 fn generate_base64_encode(&mut self, e: &Base64Encode) -> Result<()> {
24633 self.write_keyword("BASE64_ENCODE");
24635 self.write("(");
24636 self.generate_expression(&e.this)?;
24637 if let Some(max_line_length) = &e.max_line_length {
24638 self.write(", ");
24639 self.generate_expression(max_line_length)?;
24640 }
24641 if let Some(alphabet) = &e.alphabet {
24642 self.write(", ");
24643 self.generate_expression(alphabet)?;
24644 }
24645 self.write(")");
24646 Ok(())
24647 }
24648
24649 fn generate_block_compression_property(&mut self, e: &BlockCompressionProperty) -> Result<()> {
24650 self.write_keyword("BLOCKCOMPRESSION");
24652 self.write("=");
24653 if let Some(autotemp) = &e.autotemp {
24654 self.write_keyword("AUTOTEMP");
24655 self.write("(");
24656 self.generate_expression(autotemp)?;
24657 self.write(")");
24658 }
24659 if let Some(always) = &e.always {
24660 self.generate_expression(always)?;
24661 }
24662 if let Some(default) = &e.default {
24663 self.generate_expression(default)?;
24664 }
24665 if let Some(manual) = &e.manual {
24666 self.generate_expression(manual)?;
24667 }
24668 if let Some(never) = &e.never {
24669 self.generate_expression(never)?;
24670 }
24671 Ok(())
24672 }
24673
24674 fn generate_booland(&mut self, e: &Booland) -> Result<()> {
24675 self.write("((");
24677 self.generate_expression(&e.this)?;
24678 self.write(") ");
24679 self.write_keyword("AND");
24680 self.write(" (");
24681 self.generate_expression(&e.expression)?;
24682 self.write("))");
24683 Ok(())
24684 }
24685
24686 fn generate_boolor(&mut self, e: &Boolor) -> Result<()> {
24687 self.write("((");
24689 self.generate_expression(&e.this)?;
24690 self.write(") ");
24691 self.write_keyword("OR");
24692 self.write(" (");
24693 self.generate_expression(&e.expression)?;
24694 self.write("))");
24695 Ok(())
24696 }
24697
24698 fn generate_build_property(&mut self, e: &BuildProperty) -> Result<()> {
24699 self.write_keyword("BUILD");
24701 self.write_space();
24702 self.generate_expression(&e.this)?;
24703 Ok(())
24704 }
24705
24706 fn generate_byte_string(&mut self, e: &ByteString) -> Result<()> {
24707 self.generate_expression(&e.this)?;
24709 Ok(())
24710 }
24711
24712 fn generate_case_specific_column_constraint(
24713 &mut self,
24714 e: &CaseSpecificColumnConstraint,
24715 ) -> Result<()> {
24716 if e.not_.is_some() {
24718 self.write_keyword("NOT");
24719 self.write_space();
24720 }
24721 self.write_keyword("CASESPECIFIC");
24722 Ok(())
24723 }
24724
24725 fn generate_cast_to_str_type(&mut self, e: &CastToStrType) -> Result<()> {
24726 self.write_keyword("CAST");
24728 self.write("(");
24729 self.generate_expression(&e.this)?;
24730 if self.config.dialect == Some(DialectType::ClickHouse) {
24731 self.write(", ");
24733 } else {
24734 self.write_space();
24735 self.write_keyword("AS");
24736 self.write_space();
24737 }
24738 if let Some(to) = &e.to {
24739 self.generate_expression(to)?;
24740 }
24741 self.write(")");
24742 Ok(())
24743 }
24744
24745 fn generate_changes(&mut self, e: &Changes) -> Result<()> {
24746 self.write_keyword("CHANGES");
24749 self.write(" (");
24750 if let Some(information) = &e.information {
24751 self.write_keyword("INFORMATION");
24752 self.write(" => ");
24753 self.generate_expression(information)?;
24754 }
24755 self.write(")");
24756 if let Some(at_before) = &e.at_before {
24758 self.write(" ");
24759 self.generate_expression(at_before)?;
24760 }
24761 if let Some(end) = &e.end {
24762 self.write(" ");
24763 self.generate_expression(end)?;
24764 }
24765 Ok(())
24766 }
24767
24768 fn generate_character_set_column_constraint(
24769 &mut self,
24770 e: &CharacterSetColumnConstraint,
24771 ) -> Result<()> {
24772 self.write_keyword("CHARACTER SET");
24774 self.write_space();
24775 self.generate_expression(&e.this)?;
24776 Ok(())
24777 }
24778
24779 fn generate_character_set_property(&mut self, e: &CharacterSetProperty) -> Result<()> {
24780 if e.default.is_some() {
24782 self.write_keyword("DEFAULT");
24783 self.write_space();
24784 }
24785 self.write_keyword("CHARACTER SET");
24786 self.write("=");
24787 self.generate_expression(&e.this)?;
24788 Ok(())
24789 }
24790
24791 fn generate_check_column_constraint(&mut self, e: &CheckColumnConstraint) -> Result<()> {
24792 self.write_keyword("CHECK");
24794 self.write(" (");
24795 self.generate_expression(&e.this)?;
24796 self.write(")");
24797 if e.enforced.is_some() {
24798 self.write_space();
24799 self.write_keyword("ENFORCED");
24800 }
24801 Ok(())
24802 }
24803
24804 fn generate_check_json(&mut self, e: &CheckJson) -> Result<()> {
24805 self.write_keyword("CHECK_JSON");
24807 self.write("(");
24808 self.generate_expression(&e.this)?;
24809 self.write(")");
24810 Ok(())
24811 }
24812
24813 fn generate_check_xml(&mut self, e: &CheckXml) -> Result<()> {
24814 self.write_keyword("CHECK_XML");
24816 self.write("(");
24817 self.generate_expression(&e.this)?;
24818 self.write(")");
24819 Ok(())
24820 }
24821
24822 fn generate_checksum_property(&mut self, e: &ChecksumProperty) -> Result<()> {
24823 self.write_keyword("CHECKSUM");
24825 self.write("=");
24826 if e.on.is_some() {
24827 self.write_keyword("ON");
24828 } else if e.default.is_some() {
24829 self.write_keyword("DEFAULT");
24830 } else {
24831 self.write_keyword("OFF");
24832 }
24833 Ok(())
24834 }
24835
24836 fn generate_clone(&mut self, e: &Clone) -> Result<()> {
24837 if e.shallow.is_some() {
24839 self.write_keyword("SHALLOW");
24840 self.write_space();
24841 }
24842 if e.copy.is_some() {
24843 self.write_keyword("COPY");
24844 } else {
24845 self.write_keyword("CLONE");
24846 }
24847 self.write_space();
24848 self.generate_expression(&e.this)?;
24849 Ok(())
24850 }
24851
24852 fn generate_cluster_by(&mut self, e: &ClusterBy) -> Result<()> {
24853 self.write_keyword("CLUSTER BY");
24855 self.write(" (");
24856 for (i, ord) in e.expressions.iter().enumerate() {
24857 if i > 0 {
24858 self.write(", ");
24859 }
24860 self.generate_ordered(ord)?;
24861 }
24862 self.write(")");
24863 Ok(())
24864 }
24865
24866 fn generate_cluster_by_columns_property(&mut self, e: &ClusterByColumnsProperty) -> Result<()> {
24867 self.write_keyword("CLUSTER BY");
24869 self.write_space();
24870 for (i, col) in e.columns.iter().enumerate() {
24871 if i > 0 {
24872 self.write(", ");
24873 }
24874 self.generate_identifier(col)?;
24875 }
24876 Ok(())
24877 }
24878
24879 fn generate_clustered_by_property(&mut self, e: &ClusteredByProperty) -> Result<()> {
24880 self.write_keyword("CLUSTERED BY");
24882 self.write(" (");
24883 for (i, expr) in e.expressions.iter().enumerate() {
24884 if i > 0 {
24885 self.write(", ");
24886 }
24887 self.generate_expression(expr)?;
24888 }
24889 self.write(")");
24890 if let Some(sorted_by) = &e.sorted_by {
24891 self.write_space();
24892 self.write_keyword("SORTED BY");
24893 self.write(" (");
24894 if let Expression::Tuple(t) = sorted_by.as_ref() {
24896 for (i, expr) in t.expressions.iter().enumerate() {
24897 if i > 0 {
24898 self.write(", ");
24899 }
24900 self.generate_expression(expr)?;
24901 }
24902 } else {
24903 self.generate_expression(sorted_by)?;
24904 }
24905 self.write(")");
24906 }
24907 if let Some(buckets) = &e.buckets {
24908 self.write_space();
24909 self.write_keyword("INTO");
24910 self.write_space();
24911 self.generate_expression(buckets)?;
24912 self.write_space();
24913 self.write_keyword("BUCKETS");
24914 }
24915 Ok(())
24916 }
24917
24918 fn generate_collate_property(&mut self, e: &CollateProperty) -> Result<()> {
24919 if e.default.is_some() {
24923 self.write_keyword("DEFAULT");
24924 self.write_space();
24925 }
24926 self.write_keyword("COLLATE");
24927 match self.config.dialect {
24929 Some(DialectType::BigQuery) => self.write_space(),
24930 _ => self.write("="),
24931 }
24932 self.generate_expression(&e.this)?;
24933 Ok(())
24934 }
24935
24936 fn generate_column_constraint(&mut self, e: &ColumnConstraint) -> Result<()> {
24937 match e {
24939 ColumnConstraint::NotNull => {
24940 self.write_keyword("NOT NULL");
24941 }
24942 ColumnConstraint::Null => {
24943 self.write_keyword("NULL");
24944 }
24945 ColumnConstraint::Unique => {
24946 self.write_keyword("UNIQUE");
24947 }
24948 ColumnConstraint::PrimaryKey => {
24949 self.write_keyword("PRIMARY KEY");
24950 }
24951 ColumnConstraint::Default(expr) => {
24952 self.write_keyword("DEFAULT");
24953 self.write_space();
24954 self.generate_expression(expr)?;
24955 }
24956 ColumnConstraint::Check(expr) => {
24957 self.write_keyword("CHECK");
24958 self.write(" (");
24959 self.generate_expression(expr)?;
24960 self.write(")");
24961 }
24962 ColumnConstraint::References(fk_ref) => {
24963 if fk_ref.has_foreign_key_keywords {
24964 self.write_keyword("FOREIGN KEY");
24965 self.write_space();
24966 }
24967 self.write_keyword("REFERENCES");
24968 self.write_space();
24969 self.generate_table(&fk_ref.table)?;
24970 if !fk_ref.columns.is_empty() {
24971 self.write(" (");
24972 for (i, col) in fk_ref.columns.iter().enumerate() {
24973 if i > 0 {
24974 self.write(", ");
24975 }
24976 self.generate_identifier(col)?;
24977 }
24978 self.write(")");
24979 }
24980 }
24981 ColumnConstraint::GeneratedAsIdentity(gen) => {
24982 self.write_keyword("GENERATED");
24983 self.write_space();
24984 if gen.always {
24985 self.write_keyword("ALWAYS");
24986 } else {
24987 self.write_keyword("BY DEFAULT");
24988 if gen.on_null {
24989 self.write_space();
24990 self.write_keyword("ON NULL");
24991 }
24992 }
24993 self.write_space();
24994 self.write_keyword("AS IDENTITY");
24995 }
24996 ColumnConstraint::Collate(collation) => {
24997 self.write_keyword("COLLATE");
24998 self.write_space();
24999 self.generate_identifier(collation)?;
25000 }
25001 ColumnConstraint::Comment(comment) => {
25002 self.write_keyword("COMMENT");
25003 self.write(" '");
25004 self.write(comment);
25005 self.write("'");
25006 }
25007 ColumnConstraint::ComputedColumn(cc) => {
25008 self.generate_computed_column_inline(cc)?;
25009 }
25010 ColumnConstraint::GeneratedAsRow(gar) => {
25011 self.generate_generated_as_row_inline(gar)?;
25012 }
25013 ColumnConstraint::Tags(tags) => {
25014 self.write_keyword("TAG");
25015 self.write(" (");
25016 for (i, expr) in tags.expressions.iter().enumerate() {
25017 if i > 0 {
25018 self.write(", ");
25019 }
25020 self.generate_expression(expr)?;
25021 }
25022 self.write(")");
25023 }
25024 ColumnConstraint::Path(path_expr) => {
25025 self.write_keyword("PATH");
25026 self.write_space();
25027 self.generate_expression(path_expr)?;
25028 }
25029 }
25030 Ok(())
25031 }
25032
25033 fn generate_column_position(&mut self, e: &ColumnPosition) -> Result<()> {
25034 match e {
25036 ColumnPosition::First => {
25037 self.write_keyword("FIRST");
25038 }
25039 ColumnPosition::After(ident) => {
25040 self.write_keyword("AFTER");
25041 self.write_space();
25042 self.generate_identifier(ident)?;
25043 }
25044 }
25045 Ok(())
25046 }
25047
25048 fn generate_column_prefix(&mut self, e: &ColumnPrefix) -> Result<()> {
25049 self.generate_expression(&e.this)?;
25051 self.write("(");
25052 self.generate_expression(&e.expression)?;
25053 self.write(")");
25054 Ok(())
25055 }
25056
25057 fn generate_columns(&mut self, e: &Columns) -> Result<()> {
25058 if let Some(ref unpack) = e.unpack {
25061 if let Expression::Boolean(b) = unpack.as_ref() {
25062 if b.value {
25063 self.write("*");
25064 }
25065 }
25066 }
25067 self.write_keyword("COLUMNS");
25068 self.write("(");
25069 self.generate_expression(&e.this)?;
25070 self.write(")");
25071 Ok(())
25072 }
25073
25074 fn generate_combined_agg_func(&mut self, e: &CombinedAggFunc) -> Result<()> {
25075 self.generate_expression(&e.this)?;
25077 self.write("(");
25078 for (i, expr) in e.expressions.iter().enumerate() {
25079 if i > 0 {
25080 self.write(", ");
25081 }
25082 self.generate_expression(expr)?;
25083 }
25084 self.write(")");
25085 Ok(())
25086 }
25087
25088 fn generate_combined_parameterized_agg(&mut self, e: &CombinedParameterizedAgg) -> Result<()> {
25089 self.generate_expression(&e.this)?;
25091 self.write("(");
25092 for (i, param) in e.params.iter().enumerate() {
25093 if i > 0 {
25094 self.write(", ");
25095 }
25096 self.generate_expression(param)?;
25097 }
25098 self.write(")(");
25099 for (i, expr) in e.expressions.iter().enumerate() {
25100 if i > 0 {
25101 self.write(", ");
25102 }
25103 self.generate_expression(expr)?;
25104 }
25105 self.write(")");
25106 Ok(())
25107 }
25108
25109 fn generate_commit(&mut self, e: &Commit) -> Result<()> {
25110 self.write_keyword("COMMIT");
25112
25113 if e.this.is_none()
25115 && matches!(
25116 self.config.dialect,
25117 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25118 )
25119 {
25120 self.write_space();
25121 self.write_keyword("TRANSACTION");
25122 }
25123
25124 if let Some(this) = &e.this {
25126 let is_transaction_marker = matches!(
25128 this.as_ref(),
25129 Expression::Identifier(id) if id.name == "TRANSACTION"
25130 );
25131
25132 self.write_space();
25133 self.write_keyword("TRANSACTION");
25134
25135 if !is_transaction_marker {
25137 self.write_space();
25138 self.generate_expression(this)?;
25139 }
25140 }
25141
25142 if let Some(durability) = &e.durability {
25144 self.write_space();
25145 self.write_keyword("WITH");
25146 self.write(" (");
25147 self.write_keyword("DELAYED_DURABILITY");
25148 self.write(" = ");
25149 if let Expression::Boolean(BooleanLiteral { value: true }) = durability.as_ref() {
25150 self.write_keyword("ON");
25151 } else {
25152 self.write_keyword("OFF");
25153 }
25154 self.write(")");
25155 }
25156
25157 if let Some(chain) = &e.chain {
25159 self.write_space();
25160 if let Expression::Boolean(BooleanLiteral { value: false }) = chain.as_ref() {
25161 self.write_keyword("AND NO CHAIN");
25162 } else {
25163 self.write_keyword("AND CHAIN");
25164 }
25165 }
25166 Ok(())
25167 }
25168
25169 fn generate_comprehension(&mut self, e: &Comprehension) -> Result<()> {
25170 self.write("[");
25172 self.generate_expression(&e.this)?;
25173 self.write_space();
25174 self.write_keyword("FOR");
25175 self.write_space();
25176 self.generate_expression(&e.expression)?;
25177 if let Some(pos) = &e.position {
25179 self.write(", ");
25180 self.generate_expression(pos)?;
25181 }
25182 if let Some(iterator) = &e.iterator {
25183 self.write_space();
25184 self.write_keyword("IN");
25185 self.write_space();
25186 self.generate_expression(iterator)?;
25187 }
25188 if let Some(condition) = &e.condition {
25189 self.write_space();
25190 self.write_keyword("IF");
25191 self.write_space();
25192 self.generate_expression(condition)?;
25193 }
25194 self.write("]");
25195 Ok(())
25196 }
25197
25198 fn generate_compress(&mut self, e: &Compress) -> Result<()> {
25199 self.write_keyword("COMPRESS");
25201 self.write("(");
25202 self.generate_expression(&e.this)?;
25203 if let Some(method) = &e.method {
25204 self.write(", '");
25205 self.write(method);
25206 self.write("'");
25207 }
25208 self.write(")");
25209 Ok(())
25210 }
25211
25212 fn generate_compress_column_constraint(&mut self, e: &CompressColumnConstraint) -> Result<()> {
25213 self.write_keyword("COMPRESS");
25215 if let Some(this) = &e.this {
25216 self.write_space();
25217 self.generate_expression(this)?;
25218 }
25219 Ok(())
25220 }
25221
25222 fn generate_computed_column_constraint(&mut self, e: &ComputedColumnConstraint) -> Result<()> {
25223 self.write_keyword("AS");
25225 self.write_space();
25226 self.generate_expression(&e.this)?;
25227 if e.not_null.is_some() {
25228 self.write_space();
25229 self.write_keyword("PERSISTED NOT NULL");
25230 } else if e.persisted.is_some() {
25231 self.write_space();
25232 self.write_keyword("PERSISTED");
25233 }
25234 Ok(())
25235 }
25236
25237 fn generate_computed_column_inline(&mut self, cc: &ComputedColumn) -> Result<()> {
25241 let computed_expr = if matches!(
25242 self.config.dialect,
25243 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25244 ) {
25245 match &*cc.expression {
25246 Expression::Year(y) if !matches!(&y.this, Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
25247 {
25248 let wrapped = Expression::Cast(Box::new(Cast {
25249 this: y.this.clone(),
25250 to: DataType::Date,
25251 trailing_comments: Vec::new(),
25252 double_colon_syntax: false,
25253 format: None,
25254 default: None,
25255 }));
25256 Expression::Year(Box::new(UnaryFunc::new(wrapped)))
25257 }
25258 Expression::Function(f)
25259 if f.name.eq_ignore_ascii_case("YEAR")
25260 && f.args.len() == 1
25261 && !matches!(&f.args[0], Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
25262 {
25263 let wrapped = Expression::Cast(Box::new(Cast {
25264 this: f.args[0].clone(),
25265 to: DataType::Date,
25266 trailing_comments: Vec::new(),
25267 double_colon_syntax: false,
25268 format: None,
25269 default: None,
25270 }));
25271 Expression::Function(Box::new(Function::new("YEAR".to_string(), vec![wrapped])))
25272 }
25273 _ => *cc.expression.clone(),
25274 }
25275 } else {
25276 *cc.expression.clone()
25277 };
25278
25279 match cc.persistence_kind.as_deref() {
25280 Some("STORED") | Some("VIRTUAL") => {
25281 self.write_keyword("GENERATED ALWAYS AS");
25283 self.write(" (");
25284 self.generate_expression(&computed_expr)?;
25285 self.write(")");
25286 self.write_space();
25287 if cc.persisted {
25288 self.write_keyword("STORED");
25289 } else {
25290 self.write_keyword("VIRTUAL");
25291 }
25292 }
25293 Some("PERSISTED") => {
25294 self.write_keyword("AS");
25296 self.write(" (");
25297 self.generate_expression(&computed_expr)?;
25298 self.write(")");
25299 self.write_space();
25300 self.write_keyword("PERSISTED");
25301 if let Some(ref dt) = cc.data_type {
25303 self.write_space();
25304 self.generate_data_type(dt)?;
25305 }
25306 if cc.not_null {
25307 self.write_space();
25308 self.write_keyword("NOT NULL");
25309 }
25310 }
25311 _ => {
25312 if matches!(
25315 self.config.dialect,
25316 Some(DialectType::Spark)
25317 | Some(DialectType::Databricks)
25318 | Some(DialectType::Hive)
25319 ) {
25320 self.write_keyword("GENERATED ALWAYS AS");
25321 self.write(" (");
25322 self.generate_expression(&computed_expr)?;
25323 self.write(")");
25324 } else if matches!(
25325 self.config.dialect,
25326 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25327 ) {
25328 self.write_keyword("AS");
25329 let omit_parens = matches!(computed_expr, Expression::Year(_))
25330 || matches!(&computed_expr, Expression::Function(f) if f.name.eq_ignore_ascii_case("YEAR"));
25331 if omit_parens {
25332 self.write_space();
25333 self.generate_expression(&computed_expr)?;
25334 } else {
25335 self.write(" (");
25336 self.generate_expression(&computed_expr)?;
25337 self.write(")");
25338 }
25339 } else {
25340 self.write_keyword("AS");
25341 self.write(" (");
25342 self.generate_expression(&computed_expr)?;
25343 self.write(")");
25344 }
25345 }
25346 }
25347 Ok(())
25348 }
25349
25350 fn generate_generated_as_row_inline(&mut self, gar: &GeneratedAsRow) -> Result<()> {
25353 self.write_keyword("GENERATED ALWAYS AS ROW ");
25354 if gar.start {
25355 self.write_keyword("START");
25356 } else {
25357 self.write_keyword("END");
25358 }
25359 if gar.hidden {
25360 self.write_space();
25361 self.write_keyword("HIDDEN");
25362 }
25363 Ok(())
25364 }
25365
25366 fn generate_system_versioning_content(
25368 &mut self,
25369 e: &WithSystemVersioningProperty,
25370 ) -> Result<()> {
25371 let mut parts = Vec::new();
25372
25373 if let Some(this) = &e.this {
25374 let mut s = String::from("HISTORY_TABLE=");
25375 let mut gen = Generator::new();
25376 gen.config = self.config.clone();
25377 gen.generate_expression(this)?;
25378 s.push_str(&gen.output);
25379 parts.push(s);
25380 }
25381
25382 if let Some(data_consistency) = &e.data_consistency {
25383 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
25384 let mut gen = Generator::new();
25385 gen.config = self.config.clone();
25386 gen.generate_expression(data_consistency)?;
25387 s.push_str(&gen.output);
25388 parts.push(s);
25389 }
25390
25391 if let Some(retention_period) = &e.retention_period {
25392 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
25393 let mut gen = Generator::new();
25394 gen.config = self.config.clone();
25395 gen.generate_expression(retention_period)?;
25396 s.push_str(&gen.output);
25397 parts.push(s);
25398 }
25399
25400 self.write_keyword("SYSTEM_VERSIONING");
25401 self.write("=");
25402
25403 if !parts.is_empty() {
25404 self.write_keyword("ON");
25405 self.write("(");
25406 self.write(&parts.join(", "));
25407 self.write(")");
25408 } else if e.on.is_some() {
25409 self.write_keyword("ON");
25410 } else {
25411 self.write_keyword("OFF");
25412 }
25413
25414 Ok(())
25415 }
25416
25417 fn generate_conditional_insert(&mut self, e: &ConditionalInsert) -> Result<()> {
25418 if e.else_.is_some() {
25421 self.write_keyword("ELSE");
25422 self.write_space();
25423 } else if let Some(expression) = &e.expression {
25424 self.write_keyword("WHEN");
25425 self.write_space();
25426 self.generate_expression(expression)?;
25427 self.write_space();
25428 self.write_keyword("THEN");
25429 self.write_space();
25430 }
25431
25432 if let Expression::Insert(insert) = e.this.as_ref() {
25435 self.write_keyword("INTO");
25436 self.write_space();
25437 self.generate_table(&insert.table)?;
25438
25439 if !insert.columns.is_empty() {
25441 self.write(" (");
25442 for (i, col) in insert.columns.iter().enumerate() {
25443 if i > 0 {
25444 self.write(", ");
25445 }
25446 self.generate_identifier(col)?;
25447 }
25448 self.write(")");
25449 }
25450
25451 if !insert.values.is_empty() {
25453 self.write_space();
25454 self.write_keyword("VALUES");
25455 for (row_idx, row) in insert.values.iter().enumerate() {
25456 if row_idx > 0 {
25457 self.write(", ");
25458 }
25459 self.write(" (");
25460 for (i, val) in row.iter().enumerate() {
25461 if i > 0 {
25462 self.write(", ");
25463 }
25464 self.generate_expression(val)?;
25465 }
25466 self.write(")");
25467 }
25468 }
25469 } else {
25470 self.generate_expression(&e.this)?;
25472 }
25473 Ok(())
25474 }
25475
25476 fn generate_constraint(&mut self, e: &Constraint) -> Result<()> {
25477 self.write_keyword("CONSTRAINT");
25479 self.write_space();
25480 self.generate_expression(&e.this)?;
25481 if !e.expressions.is_empty() {
25482 self.write_space();
25483 for (i, expr) in e.expressions.iter().enumerate() {
25484 if i > 0 {
25485 self.write_space();
25486 }
25487 self.generate_expression(expr)?;
25488 }
25489 }
25490 Ok(())
25491 }
25492
25493 fn generate_convert_timezone(&mut self, e: &ConvertTimezone) -> Result<()> {
25494 self.write_keyword("CONVERT_TIMEZONE");
25496 self.write("(");
25497 let mut first = true;
25498 if let Some(source_tz) = &e.source_tz {
25499 self.generate_expression(source_tz)?;
25500 first = false;
25501 }
25502 if let Some(target_tz) = &e.target_tz {
25503 if !first {
25504 self.write(", ");
25505 }
25506 self.generate_expression(target_tz)?;
25507 first = false;
25508 }
25509 if let Some(timestamp) = &e.timestamp {
25510 if !first {
25511 self.write(", ");
25512 }
25513 self.generate_expression(timestamp)?;
25514 }
25515 self.write(")");
25516 Ok(())
25517 }
25518
25519 fn generate_convert_to_charset(&mut self, e: &ConvertToCharset) -> Result<()> {
25520 self.write_keyword("CONVERT");
25522 self.write("(");
25523 self.generate_expression(&e.this)?;
25524 if let Some(dest) = &e.dest {
25525 self.write_space();
25526 self.write_keyword("USING");
25527 self.write_space();
25528 self.generate_expression(dest)?;
25529 }
25530 self.write(")");
25531 Ok(())
25532 }
25533
25534 fn generate_copy(&mut self, e: &CopyStmt) -> Result<()> {
25535 self.write_keyword("COPY");
25536 if e.is_into {
25537 self.write_space();
25538 self.write_keyword("INTO");
25539 }
25540 self.write_space();
25541
25542 if let Expression::Literal(Literal::String(s)) = &e.this {
25544 if s.starts_with('@') {
25545 self.write(s);
25546 } else {
25547 self.generate_expression(&e.this)?;
25548 }
25549 } else {
25550 self.generate_expression(&e.this)?;
25551 }
25552
25553 if e.kind {
25555 if self.config.pretty {
25557 self.write_newline();
25558 } else {
25559 self.write_space();
25560 }
25561 self.write_keyword("FROM");
25562 self.write_space();
25563 } else if !e.files.is_empty() {
25564 if self.config.pretty {
25566 self.write_newline();
25567 } else {
25568 self.write_space();
25569 }
25570 self.write_keyword("TO");
25571 self.write_space();
25572 }
25573
25574 for (i, file) in e.files.iter().enumerate() {
25576 if i > 0 {
25577 self.write_space();
25578 }
25579 if let Expression::Literal(Literal::String(s)) = file {
25581 if s.starts_with('@') {
25582 self.write(s);
25583 } else {
25584 self.generate_expression(file)?;
25585 }
25586 } else if let Expression::Identifier(id) = file {
25587 if id.quoted {
25589 self.write("`");
25590 self.write(&id.name);
25591 self.write("`");
25592 } else {
25593 self.generate_expression(file)?;
25594 }
25595 } else {
25596 self.generate_expression(file)?;
25597 }
25598 }
25599
25600 if !e.with_wrapped {
25602 if let Some(ref creds) = e.credentials {
25603 if let Some(ref storage) = creds.storage {
25604 if self.config.pretty {
25605 self.write_newline();
25606 } else {
25607 self.write_space();
25608 }
25609 self.write_keyword("STORAGE_INTEGRATION");
25610 self.write(" = ");
25611 self.write(storage);
25612 }
25613 if creds.credentials.is_empty() {
25614 if self.config.pretty {
25616 self.write_newline();
25617 } else {
25618 self.write_space();
25619 }
25620 self.write_keyword("CREDENTIALS");
25621 self.write(" = ()");
25622 } else {
25623 if self.config.pretty {
25624 self.write_newline();
25625 } else {
25626 self.write_space();
25627 }
25628 self.write_keyword("CREDENTIALS");
25629 if creds.credentials.len() == 1 && creds.credentials[0].0.is_empty() {
25632 self.write(" '");
25634 self.write(&creds.credentials[0].1);
25635 self.write("'");
25636 } else {
25637 self.write(" = (");
25639 for (i, (k, v)) in creds.credentials.iter().enumerate() {
25640 if i > 0 {
25641 self.write_space();
25642 }
25643 self.write(k);
25644 self.write("='");
25645 self.write(v);
25646 self.write("'");
25647 }
25648 self.write(")");
25649 }
25650 }
25651 if let Some(ref encryption) = creds.encryption {
25652 self.write_space();
25653 self.write_keyword("ENCRYPTION");
25654 self.write(" = ");
25655 self.write(encryption);
25656 }
25657 }
25658 }
25659
25660 if !e.params.is_empty() {
25662 if e.with_wrapped {
25663 self.write_space();
25665 self.write_keyword("WITH");
25666 self.write(" (");
25667 for (i, param) in e.params.iter().enumerate() {
25668 if i > 0 {
25669 self.write(", ");
25670 }
25671 self.generate_copy_param_with_format(param)?;
25672 }
25673 self.write(")");
25674 } else {
25675 for param in &e.params {
25679 if self.config.pretty {
25680 self.write_newline();
25681 } else {
25682 self.write_space();
25683 }
25684 self.write(¶m.name);
25686 if let Some(ref value) = param.value {
25687 if param.eq {
25689 self.write(" = ");
25690 } else {
25691 self.write(" ");
25692 }
25693 if !param.values.is_empty() {
25694 self.write("(");
25695 for (i, v) in param.values.iter().enumerate() {
25696 if i > 0 {
25697 self.write_space();
25698 }
25699 self.generate_copy_nested_param(v)?;
25700 }
25701 self.write(")");
25702 } else {
25703 self.generate_copy_param_value(value)?;
25705 }
25706 } else if !param.values.is_empty() {
25707 if param.eq {
25709 self.write(" = (");
25710 } else {
25711 self.write(" (");
25712 }
25713 let is_key_value_pairs = param
25718 .values
25719 .first()
25720 .map_or(false, |v| matches!(v, Expression::Eq(_)));
25721 let sep = if is_key_value_pairs && param.eq {
25722 " "
25723 } else {
25724 ", "
25725 };
25726 for (i, v) in param.values.iter().enumerate() {
25727 if i > 0 {
25728 self.write(sep);
25729 }
25730 self.generate_copy_nested_param(v)?;
25731 }
25732 self.write(")");
25733 }
25734 }
25735 }
25736 }
25737
25738 Ok(())
25739 }
25740
25741 fn generate_copy_param_with_format(&mut self, param: &CopyParameter) -> Result<()> {
25744 self.write_keyword(¶m.name);
25745 if !param.values.is_empty() {
25746 self.write(" = (");
25748 for (i, v) in param.values.iter().enumerate() {
25749 if i > 0 {
25750 self.write(", ");
25751 }
25752 self.generate_copy_nested_param(v)?;
25753 }
25754 self.write(")");
25755 } else if let Some(ref value) = param.value {
25756 if param.eq {
25757 self.write(" = ");
25758 } else {
25759 self.write(" ");
25760 }
25761 self.generate_expression(value)?;
25762 }
25763 Ok(())
25764 }
25765
25766 fn generate_copy_nested_param(&mut self, expr: &Expression) -> Result<()> {
25768 match expr {
25769 Expression::Eq(eq) => {
25770 match &eq.left {
25772 Expression::Column(c) => self.write(&c.name.name),
25773 _ => self.generate_expression(&eq.left)?,
25774 }
25775 self.write("=");
25776 match &eq.right {
25778 Expression::Literal(Literal::String(s)) => {
25779 self.write("'");
25780 self.write(s);
25781 self.write("'");
25782 }
25783 Expression::Tuple(t) => {
25784 self.write("(");
25786 if self.config.pretty {
25787 self.write_newline();
25788 self.indent_level += 1;
25789 for (i, item) in t.expressions.iter().enumerate() {
25790 if i > 0 {
25791 self.write(", ");
25792 }
25793 self.write_indent();
25794 self.generate_expression(item)?;
25795 }
25796 self.write_newline();
25797 self.indent_level -= 1;
25798 } else {
25799 for (i, item) in t.expressions.iter().enumerate() {
25800 if i > 0 {
25801 self.write(", ");
25802 }
25803 self.generate_expression(item)?;
25804 }
25805 }
25806 self.write(")");
25807 }
25808 _ => self.generate_expression(&eq.right)?,
25809 }
25810 Ok(())
25811 }
25812 Expression::Column(c) => {
25813 self.write(&c.name.name);
25815 Ok(())
25816 }
25817 _ => self.generate_expression(expr),
25818 }
25819 }
25820
25821 fn generate_copy_param_value(&mut self, expr: &Expression) -> Result<()> {
25824 match expr {
25825 Expression::Column(c) => {
25826 if c.name.quoted {
25828 self.write("\"");
25829 self.write(&c.name.name);
25830 self.write("\"");
25831 } else {
25832 self.write(&c.name.name);
25833 }
25834 Ok(())
25835 }
25836 Expression::Identifier(id) => {
25837 if id.quoted {
25839 self.write("\"");
25840 self.write(&id.name);
25841 self.write("\"");
25842 } else {
25843 self.write(&id.name);
25844 }
25845 Ok(())
25846 }
25847 Expression::Literal(Literal::String(s)) => {
25848 self.write("'");
25850 self.write(s);
25851 self.write("'");
25852 Ok(())
25853 }
25854 _ => self.generate_expression(expr),
25855 }
25856 }
25857
25858 fn generate_copy_parameter(&mut self, e: &CopyParameter) -> Result<()> {
25859 self.write_keyword(&e.name);
25860 if let Some(ref value) = e.value {
25861 if e.eq {
25862 self.write(" = ");
25863 } else {
25864 self.write(" ");
25865 }
25866 self.generate_expression(value)?;
25867 }
25868 if !e.values.is_empty() {
25869 if e.eq {
25870 self.write(" = ");
25871 } else {
25872 self.write(" ");
25873 }
25874 self.write("(");
25875 for (i, v) in e.values.iter().enumerate() {
25876 if i > 0 {
25877 self.write(", ");
25878 }
25879 self.generate_expression(v)?;
25880 }
25881 self.write(")");
25882 }
25883 Ok(())
25884 }
25885
25886 fn generate_corr(&mut self, e: &Corr) -> Result<()> {
25887 self.write_keyword("CORR");
25889 self.write("(");
25890 self.generate_expression(&e.this)?;
25891 self.write(", ");
25892 self.generate_expression(&e.expression)?;
25893 self.write(")");
25894 Ok(())
25895 }
25896
25897 fn generate_cosine_distance(&mut self, e: &CosineDistance) -> Result<()> {
25898 self.write_keyword("COSINE_DISTANCE");
25900 self.write("(");
25901 self.generate_expression(&e.this)?;
25902 self.write(", ");
25903 self.generate_expression(&e.expression)?;
25904 self.write(")");
25905 Ok(())
25906 }
25907
25908 fn generate_covar_pop(&mut self, e: &CovarPop) -> Result<()> {
25909 self.write_keyword("COVAR_POP");
25911 self.write("(");
25912 self.generate_expression(&e.this)?;
25913 self.write(", ");
25914 self.generate_expression(&e.expression)?;
25915 self.write(")");
25916 Ok(())
25917 }
25918
25919 fn generate_covar_samp(&mut self, e: &CovarSamp) -> Result<()> {
25920 self.write_keyword("COVAR_SAMP");
25922 self.write("(");
25923 self.generate_expression(&e.this)?;
25924 self.write(", ");
25925 self.generate_expression(&e.expression)?;
25926 self.write(")");
25927 Ok(())
25928 }
25929
25930 fn generate_credentials(&mut self, e: &Credentials) -> Result<()> {
25931 self.write_keyword("CREDENTIALS");
25933 self.write(" (");
25934 for (i, (key, value)) in e.credentials.iter().enumerate() {
25935 if i > 0 {
25936 self.write(", ");
25937 }
25938 self.write(key);
25939 self.write("='");
25940 self.write(value);
25941 self.write("'");
25942 }
25943 self.write(")");
25944 Ok(())
25945 }
25946
25947 fn generate_credentials_property(&mut self, e: &CredentialsProperty) -> Result<()> {
25948 self.write_keyword("CREDENTIALS");
25950 self.write("=(");
25951 for (i, expr) in e.expressions.iter().enumerate() {
25952 if i > 0 {
25953 self.write(", ");
25954 }
25955 self.generate_expression(expr)?;
25956 }
25957 self.write(")");
25958 Ok(())
25959 }
25960
25961 fn generate_cte(&mut self, e: &Cte) -> Result<()> {
25962 use crate::dialects::DialectType;
25963
25964 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !e.alias_first {
25967 self.generate_expression(&e.this)?;
25968 self.write_space();
25969 self.write_keyword("AS");
25970 self.write_space();
25971 self.generate_identifier(&e.alias)?;
25972 return Ok(());
25973 }
25974 self.write(&e.alias.name);
25975
25976 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
25978
25979 if !e.columns.is_empty() && !skip_cte_columns {
25980 self.write("(");
25981 for (i, col) in e.columns.iter().enumerate() {
25982 if i > 0 {
25983 self.write(", ");
25984 }
25985 self.write(&col.name);
25986 }
25987 self.write(")");
25988 }
25989 if !e.key_expressions.is_empty() {
25991 self.write_space();
25992 self.write_keyword("USING KEY");
25993 self.write(" (");
25994 for (i, key) in e.key_expressions.iter().enumerate() {
25995 if i > 0 {
25996 self.write(", ");
25997 }
25998 self.write(&key.name);
25999 }
26000 self.write(")");
26001 }
26002 self.write_space();
26003 self.write_keyword("AS");
26004 self.write_space();
26005 if let Some(materialized) = e.materialized {
26006 if materialized {
26007 self.write_keyword("MATERIALIZED");
26008 } else {
26009 self.write_keyword("NOT MATERIALIZED");
26010 }
26011 self.write_space();
26012 }
26013 self.write("(");
26014 self.generate_expression(&e.this)?;
26015 self.write(")");
26016 Ok(())
26017 }
26018
26019 fn generate_cube(&mut self, e: &Cube) -> Result<()> {
26020 if e.expressions.is_empty() {
26022 self.write_keyword("WITH CUBE");
26023 } else {
26024 self.write_keyword("CUBE");
26025 self.write("(");
26026 for (i, expr) in e.expressions.iter().enumerate() {
26027 if i > 0 {
26028 self.write(", ");
26029 }
26030 self.generate_expression(expr)?;
26031 }
26032 self.write(")");
26033 }
26034 Ok(())
26035 }
26036
26037 fn generate_current_datetime(&mut self, e: &CurrentDatetime) -> Result<()> {
26038 self.write_keyword("CURRENT_DATETIME");
26040 if let Some(this) = &e.this {
26041 self.write("(");
26042 self.generate_expression(this)?;
26043 self.write(")");
26044 }
26045 Ok(())
26046 }
26047
26048 fn generate_current_schema(&mut self, _e: &CurrentSchema) -> Result<()> {
26049 self.write_keyword("CURRENT_SCHEMA");
26051 Ok(())
26052 }
26053
26054 fn generate_current_schemas(&mut self, e: &CurrentSchemas) -> Result<()> {
26055 self.write_keyword("CURRENT_SCHEMAS");
26057 self.write("(");
26058 if let Some(this) = &e.this {
26059 self.generate_expression(this)?;
26060 }
26061 self.write(")");
26062 Ok(())
26063 }
26064
26065 fn generate_current_user(&mut self, e: &CurrentUser) -> Result<()> {
26066 self.write_keyword("CURRENT_USER");
26068 let needs_parens = e.this.is_some()
26070 || matches!(
26071 self.config.dialect,
26072 Some(DialectType::Snowflake)
26073 | Some(DialectType::Spark)
26074 | Some(DialectType::Hive)
26075 | Some(DialectType::DuckDB)
26076 | Some(DialectType::BigQuery)
26077 | Some(DialectType::MySQL)
26078 | Some(DialectType::Databricks)
26079 );
26080 if needs_parens {
26081 self.write("()");
26082 }
26083 Ok(())
26084 }
26085
26086 fn generate_d_pipe(&mut self, e: &DPipe) -> Result<()> {
26087 if self.config.dialect == Some(DialectType::Solr) {
26089 self.generate_expression(&e.this)?;
26090 self.write(" ");
26091 self.write_keyword("OR");
26092 self.write(" ");
26093 self.generate_expression(&e.expression)?;
26094 } else if self.config.dialect == Some(DialectType::MySQL) {
26095 self.generate_mysql_concat_from_dpipe(e)?;
26096 } else {
26097 self.generate_expression(&e.this)?;
26099 self.write(" || ");
26100 self.generate_expression(&e.expression)?;
26101 }
26102 Ok(())
26103 }
26104
26105 fn generate_data_blocksize_property(&mut self, e: &DataBlocksizeProperty) -> Result<()> {
26106 self.write_keyword("DATABLOCKSIZE");
26108 self.write("=");
26109 if let Some(size) = e.size {
26110 self.write(&size.to_string());
26111 if let Some(units) = &e.units {
26112 self.write_space();
26113 self.generate_expression(units)?;
26114 }
26115 } else if e.minimum.is_some() {
26116 self.write_keyword("MINIMUM");
26117 } else if e.maximum.is_some() {
26118 self.write_keyword("MAXIMUM");
26119 } else if e.default.is_some() {
26120 self.write_keyword("DEFAULT");
26121 }
26122 Ok(())
26123 }
26124
26125 fn generate_data_deletion_property(&mut self, e: &DataDeletionProperty) -> Result<()> {
26126 self.write_keyword("DATA_DELETION");
26128 self.write("=");
26129
26130 let is_on = matches!(&*e.on, Expression::Boolean(BooleanLiteral { value: true }));
26131 let has_options = e.filter_column.is_some() || e.retention_period.is_some();
26132
26133 if is_on {
26134 self.write_keyword("ON");
26135 if has_options {
26136 self.write("(");
26137 let mut first = true;
26138 if let Some(filter_column) = &e.filter_column {
26139 self.write_keyword("FILTER_COLUMN");
26140 self.write("=");
26141 self.generate_expression(filter_column)?;
26142 first = false;
26143 }
26144 if let Some(retention_period) = &e.retention_period {
26145 if !first {
26146 self.write(", ");
26147 }
26148 self.write_keyword("RETENTION_PERIOD");
26149 self.write("=");
26150 self.generate_expression(retention_period)?;
26151 }
26152 self.write(")");
26153 }
26154 } else {
26155 self.write_keyword("OFF");
26156 }
26157 Ok(())
26158 }
26159
26160 fn generate_date_func(&mut self, e: &UnaryFunc) -> Result<()> {
26164 use crate::dialects::DialectType;
26165 use crate::expressions::Literal;
26166
26167 match self.config.dialect {
26168 Some(DialectType::Exasol) => {
26170 self.write_keyword("TO_DATE");
26171 self.write("(");
26172 match &e.this {
26174 Expression::Literal(Literal::String(s)) => {
26175 self.write("'");
26176 self.write(s);
26177 self.write("'");
26178 }
26179 _ => {
26180 self.generate_expression(&e.this)?;
26181 }
26182 }
26183 self.write(")");
26184 }
26185 _ => {
26187 self.write_keyword("DATE");
26188 self.write("(");
26189 self.generate_expression(&e.this)?;
26190 self.write(")");
26191 }
26192 }
26193 Ok(())
26194 }
26195
26196 fn generate_date_bin(&mut self, e: &DateBin) -> Result<()> {
26197 self.write_keyword("DATE_BIN");
26199 self.write("(");
26200 self.generate_expression(&e.this)?;
26201 self.write(", ");
26202 self.generate_expression(&e.expression)?;
26203 if let Some(origin) = &e.origin {
26204 self.write(", ");
26205 self.generate_expression(origin)?;
26206 }
26207 self.write(")");
26208 Ok(())
26209 }
26210
26211 fn generate_date_format_column_constraint(
26212 &mut self,
26213 e: &DateFormatColumnConstraint,
26214 ) -> Result<()> {
26215 self.write_keyword("FORMAT");
26217 self.write_space();
26218 self.generate_expression(&e.this)?;
26219 Ok(())
26220 }
26221
26222 fn generate_date_from_parts(&mut self, e: &DateFromParts) -> Result<()> {
26223 self.write_keyword("DATE_FROM_PARTS");
26225 self.write("(");
26226 let mut first = true;
26227 if let Some(year) = &e.year {
26228 self.generate_expression(year)?;
26229 first = false;
26230 }
26231 if let Some(month) = &e.month {
26232 if !first {
26233 self.write(", ");
26234 }
26235 self.generate_expression(month)?;
26236 first = false;
26237 }
26238 if let Some(day) = &e.day {
26239 if !first {
26240 self.write(", ");
26241 }
26242 self.generate_expression(day)?;
26243 }
26244 self.write(")");
26245 Ok(())
26246 }
26247
26248 fn generate_datetime(&mut self, e: &Datetime) -> Result<()> {
26249 self.write_keyword("DATETIME");
26251 self.write("(");
26252 self.generate_expression(&e.this)?;
26253 if let Some(expr) = &e.expression {
26254 self.write(", ");
26255 self.generate_expression(expr)?;
26256 }
26257 self.write(")");
26258 Ok(())
26259 }
26260
26261 fn generate_datetime_add(&mut self, e: &DatetimeAdd) -> Result<()> {
26262 self.write_keyword("DATETIME_ADD");
26264 self.write("(");
26265 self.generate_expression(&e.this)?;
26266 self.write(", ");
26267 self.generate_expression(&e.expression)?;
26268 if let Some(unit) = &e.unit {
26269 self.write(", ");
26270 self.write_keyword(unit);
26271 }
26272 self.write(")");
26273 Ok(())
26274 }
26275
26276 fn generate_datetime_diff(&mut self, e: &DatetimeDiff) -> Result<()> {
26277 self.write_keyword("DATETIME_DIFF");
26279 self.write("(");
26280 self.generate_expression(&e.this)?;
26281 self.write(", ");
26282 self.generate_expression(&e.expression)?;
26283 if let Some(unit) = &e.unit {
26284 self.write(", ");
26285 self.write_keyword(unit);
26286 }
26287 self.write(")");
26288 Ok(())
26289 }
26290
26291 fn generate_datetime_sub(&mut self, e: &DatetimeSub) -> Result<()> {
26292 self.write_keyword("DATETIME_SUB");
26294 self.write("(");
26295 self.generate_expression(&e.this)?;
26296 self.write(", ");
26297 self.generate_expression(&e.expression)?;
26298 if let Some(unit) = &e.unit {
26299 self.write(", ");
26300 self.write_keyword(unit);
26301 }
26302 self.write(")");
26303 Ok(())
26304 }
26305
26306 fn generate_datetime_trunc(&mut self, e: &DatetimeTrunc) -> Result<()> {
26307 self.write_keyword("DATETIME_TRUNC");
26309 self.write("(");
26310 self.generate_expression(&e.this)?;
26311 self.write(", ");
26312 self.write_keyword(&e.unit);
26313 if let Some(zone) = &e.zone {
26314 self.write(", ");
26315 self.generate_expression(zone)?;
26316 }
26317 self.write(")");
26318 Ok(())
26319 }
26320
26321 fn generate_dayname(&mut self, e: &Dayname) -> Result<()> {
26322 self.write_keyword("DAYNAME");
26324 self.write("(");
26325 self.generate_expression(&e.this)?;
26326 self.write(")");
26327 Ok(())
26328 }
26329
26330 fn generate_declare(&mut self, e: &Declare) -> Result<()> {
26331 self.write_keyword("DECLARE");
26333 self.write_space();
26334 for (i, expr) in e.expressions.iter().enumerate() {
26335 if i > 0 {
26336 self.write(", ");
26337 }
26338 self.generate_expression(expr)?;
26339 }
26340 Ok(())
26341 }
26342
26343 fn generate_declare_item(&mut self, e: &DeclareItem) -> Result<()> {
26344 use crate::dialects::DialectType;
26345
26346 self.generate_expression(&e.this)?;
26348 for name in &e.additional_names {
26350 self.write(", ");
26351 self.generate_expression(name)?;
26352 }
26353 if let Some(kind) = &e.kind {
26354 self.write_space();
26355 match self.config.dialect {
26359 Some(DialectType::BigQuery) => {
26360 self.write(kind);
26361 }
26362 Some(DialectType::TSQL) => {
26363 let is_complex_table = kind.starts_with("TABLE")
26367 && (kind.contains("CLUSTERED") || kind.contains("INDEX"));
26368
26369 if is_complex_table {
26370 self.write(kind);
26372 } else {
26373 if !kind.starts_with("CURSOR") {
26375 self.write_keyword("AS");
26376 self.write_space();
26377 }
26378 if kind == "INT" {
26380 self.write("INTEGER");
26381 } else if kind.starts_with("TABLE") {
26382 let normalized = kind
26384 .replace(" INT ", " INTEGER ")
26385 .replace(" INT,", " INTEGER,")
26386 .replace(" INT)", " INTEGER)")
26387 .replace("(INT ", "(INTEGER ");
26388 self.write(&normalized);
26389 } else {
26390 self.write(kind);
26391 }
26392 }
26393 }
26394 _ => {
26395 if e.has_as {
26396 self.write_keyword("AS");
26397 self.write_space();
26398 }
26399 self.write(kind);
26400 }
26401 }
26402 }
26403 if let Some(default) = &e.default {
26404 match self.config.dialect {
26406 Some(DialectType::BigQuery) => {
26407 self.write_space();
26408 self.write_keyword("DEFAULT");
26409 self.write_space();
26410 }
26411 _ => {
26412 self.write(" = ");
26413 }
26414 }
26415 self.generate_expression(default)?;
26416 }
26417 Ok(())
26418 }
26419
26420 fn generate_decode_case(&mut self, e: &DecodeCase) -> Result<()> {
26421 self.write_keyword("DECODE");
26423 self.write("(");
26424 for (i, expr) in e.expressions.iter().enumerate() {
26425 if i > 0 {
26426 self.write(", ");
26427 }
26428 self.generate_expression(expr)?;
26429 }
26430 self.write(")");
26431 Ok(())
26432 }
26433
26434 fn generate_decompress_binary(&mut self, e: &DecompressBinary) -> Result<()> {
26435 self.write_keyword("DECOMPRESS");
26437 self.write("(");
26438 self.generate_expression(&e.this)?;
26439 self.write(", '");
26440 self.write(&e.method);
26441 self.write("')");
26442 Ok(())
26443 }
26444
26445 fn generate_decompress_string(&mut self, e: &DecompressString) -> Result<()> {
26446 self.write_keyword("DECOMPRESS");
26448 self.write("(");
26449 self.generate_expression(&e.this)?;
26450 self.write(", '");
26451 self.write(&e.method);
26452 self.write("')");
26453 Ok(())
26454 }
26455
26456 fn generate_decrypt(&mut self, e: &Decrypt) -> Result<()> {
26457 self.write_keyword("DECRYPT");
26459 self.write("(");
26460 self.generate_expression(&e.this)?;
26461 if let Some(passphrase) = &e.passphrase {
26462 self.write(", ");
26463 self.generate_expression(passphrase)?;
26464 }
26465 if let Some(aad) = &e.aad {
26466 self.write(", ");
26467 self.generate_expression(aad)?;
26468 }
26469 if let Some(method) = &e.encryption_method {
26470 self.write(", ");
26471 self.generate_expression(method)?;
26472 }
26473 self.write(")");
26474 Ok(())
26475 }
26476
26477 fn generate_decrypt_raw(&mut self, e: &DecryptRaw) -> Result<()> {
26478 self.write_keyword("DECRYPT_RAW");
26480 self.write("(");
26481 self.generate_expression(&e.this)?;
26482 if let Some(key) = &e.key {
26483 self.write(", ");
26484 self.generate_expression(key)?;
26485 }
26486 if let Some(iv) = &e.iv {
26487 self.write(", ");
26488 self.generate_expression(iv)?;
26489 }
26490 if let Some(aad) = &e.aad {
26491 self.write(", ");
26492 self.generate_expression(aad)?;
26493 }
26494 if let Some(method) = &e.encryption_method {
26495 self.write(", ");
26496 self.generate_expression(method)?;
26497 }
26498 self.write(")");
26499 Ok(())
26500 }
26501
26502 fn generate_definer_property(&mut self, e: &DefinerProperty) -> Result<()> {
26503 self.write_keyword("DEFINER");
26505 self.write(" = ");
26506 self.generate_expression(&e.this)?;
26507 Ok(())
26508 }
26509
26510 fn generate_detach(&mut self, e: &Detach) -> Result<()> {
26511 self.write_keyword("DETACH");
26513 if e.exists {
26514 self.write_keyword(" DATABASE IF EXISTS");
26515 }
26516 self.write_space();
26517 self.generate_expression(&e.this)?;
26518 Ok(())
26519 }
26520
26521 fn generate_dict_property(&mut self, e: &DictProperty) -> Result<()> {
26522 let property_name = match e.this.as_ref() {
26523 Expression::Identifier(id) => id.name.as_str(),
26524 Expression::Var(v) => v.this.as_str(),
26525 _ => "DICTIONARY",
26526 };
26527 self.write_keyword(property_name);
26528 self.write("(");
26529 self.write(&e.kind);
26530 if let Some(settings) = &e.settings {
26531 self.write("(");
26532 if let Expression::Tuple(t) = settings.as_ref() {
26533 if self.config.pretty && !t.expressions.is_empty() {
26534 self.write_newline();
26535 self.indent_level += 1;
26536 for (i, pair) in t.expressions.iter().enumerate() {
26537 if i > 0 {
26538 self.write(",");
26539 self.write_newline();
26540 }
26541 self.write_indent();
26542 if let Expression::Tuple(pair_tuple) = pair {
26543 if let Some(k) = pair_tuple.expressions.first() {
26544 self.generate_expression(k)?;
26545 }
26546 if let Some(v) = pair_tuple.expressions.get(1) {
26547 self.write(" ");
26548 self.generate_expression(v)?;
26549 }
26550 } else {
26551 self.generate_expression(pair)?;
26552 }
26553 }
26554 self.indent_level -= 1;
26555 self.write_newline();
26556 self.write_indent();
26557 } else {
26558 for (i, pair) in t.expressions.iter().enumerate() {
26559 if i > 0 {
26560 self.write(", ");
26561 }
26562 if let Expression::Tuple(pair_tuple) = pair {
26563 if let Some(k) = pair_tuple.expressions.first() {
26564 self.generate_expression(k)?;
26565 }
26566 if let Some(v) = pair_tuple.expressions.get(1) {
26567 self.write(" ");
26568 self.generate_expression(v)?;
26569 }
26570 } else {
26571 self.generate_expression(pair)?;
26572 }
26573 }
26574 }
26575 } else {
26576 self.generate_expression(settings)?;
26577 }
26578 self.write(")");
26579 } else if property_name.eq_ignore_ascii_case("LAYOUT") {
26580 self.write("()");
26581 }
26582 self.write(")");
26583 Ok(())
26584 }
26585
26586 fn generate_dict_range(&mut self, e: &DictRange) -> Result<()> {
26587 let property_name = match e.this.as_ref() {
26588 Expression::Identifier(id) => id.name.as_str(),
26589 Expression::Var(v) => v.this.as_str(),
26590 _ => "RANGE",
26591 };
26592 self.write_keyword(property_name);
26593 self.write("(");
26594 if let Some(min) = &e.min {
26595 self.write_keyword("MIN");
26596 self.write_space();
26597 self.generate_expression(min)?;
26598 }
26599 if let Some(max) = &e.max {
26600 self.write_space();
26601 self.write_keyword("MAX");
26602 self.write_space();
26603 self.generate_expression(max)?;
26604 }
26605 self.write(")");
26606 Ok(())
26607 }
26608
26609 fn generate_directory(&mut self, e: &Directory) -> Result<()> {
26610 if e.local.is_some() {
26612 self.write_keyword("LOCAL ");
26613 }
26614 self.write_keyword("DIRECTORY");
26615 self.write_space();
26616 self.generate_expression(&e.this)?;
26617 if let Some(row_format) = &e.row_format {
26618 self.write_space();
26619 self.generate_expression(row_format)?;
26620 }
26621 Ok(())
26622 }
26623
26624 fn generate_dist_key_property(&mut self, e: &DistKeyProperty) -> Result<()> {
26625 self.write_keyword("DISTKEY");
26627 self.write("(");
26628 self.generate_expression(&e.this)?;
26629 self.write(")");
26630 Ok(())
26631 }
26632
26633 fn generate_dist_style_property(&mut self, e: &DistStyleProperty) -> Result<()> {
26634 self.write_keyword("DISTSTYLE");
26636 self.write_space();
26637 self.generate_expression(&e.this)?;
26638 Ok(())
26639 }
26640
26641 fn generate_distribute_by(&mut self, e: &DistributeBy) -> Result<()> {
26642 self.write_keyword("DISTRIBUTE BY");
26644 self.write_space();
26645 for (i, expr) in e.expressions.iter().enumerate() {
26646 if i > 0 {
26647 self.write(", ");
26648 }
26649 self.generate_expression(expr)?;
26650 }
26651 Ok(())
26652 }
26653
26654 fn generate_distributed_by_property(&mut self, e: &DistributedByProperty) -> Result<()> {
26655 self.write_keyword("DISTRIBUTED BY");
26657 self.write_space();
26658 self.write(&e.kind);
26659 if !e.expressions.is_empty() {
26660 self.write(" (");
26661 for (i, expr) in e.expressions.iter().enumerate() {
26662 if i > 0 {
26663 self.write(", ");
26664 }
26665 self.generate_expression(expr)?;
26666 }
26667 self.write(")");
26668 }
26669 if let Some(buckets) = &e.buckets {
26670 self.write_space();
26671 self.write_keyword("BUCKETS");
26672 self.write_space();
26673 self.generate_expression(buckets)?;
26674 }
26675 if let Some(order) = &e.order {
26676 self.write_space();
26677 self.generate_expression(order)?;
26678 }
26679 Ok(())
26680 }
26681
26682 fn generate_dot_product(&mut self, e: &DotProduct) -> Result<()> {
26683 self.write_keyword("DOT_PRODUCT");
26685 self.write("(");
26686 self.generate_expression(&e.this)?;
26687 self.write(", ");
26688 self.generate_expression(&e.expression)?;
26689 self.write(")");
26690 Ok(())
26691 }
26692
26693 fn generate_drop_partition(&mut self, e: &DropPartition) -> Result<()> {
26694 self.write_keyword("DROP");
26696 if e.exists {
26697 self.write_keyword(" IF EXISTS ");
26698 } else {
26699 self.write_space();
26700 }
26701 for (i, expr) in e.expressions.iter().enumerate() {
26702 if i > 0 {
26703 self.write(", ");
26704 }
26705 self.generate_expression(expr)?;
26706 }
26707 Ok(())
26708 }
26709
26710 fn generate_duplicate_key_property(&mut self, e: &DuplicateKeyProperty) -> Result<()> {
26711 self.write_keyword("DUPLICATE KEY");
26713 self.write(" (");
26714 for (i, expr) in e.expressions.iter().enumerate() {
26715 if i > 0 {
26716 self.write(", ");
26717 }
26718 self.generate_expression(expr)?;
26719 }
26720 self.write(")");
26721 Ok(())
26722 }
26723
26724 fn generate_elt(&mut self, e: &Elt) -> Result<()> {
26725 self.write_keyword("ELT");
26727 self.write("(");
26728 self.generate_expression(&e.this)?;
26729 for expr in &e.expressions {
26730 self.write(", ");
26731 self.generate_expression(expr)?;
26732 }
26733 self.write(")");
26734 Ok(())
26735 }
26736
26737 fn generate_encode(&mut self, e: &Encode) -> Result<()> {
26738 self.write_keyword("ENCODE");
26740 self.write("(");
26741 self.generate_expression(&e.this)?;
26742 if let Some(charset) = &e.charset {
26743 self.write(", ");
26744 self.generate_expression(charset)?;
26745 }
26746 self.write(")");
26747 Ok(())
26748 }
26749
26750 fn generate_encode_property(&mut self, e: &EncodeProperty) -> Result<()> {
26751 if e.key.is_some() {
26753 self.write_keyword("KEY ");
26754 }
26755 self.write_keyword("ENCODE");
26756 self.write_space();
26757 self.generate_expression(&e.this)?;
26758 if !e.properties.is_empty() {
26759 self.write(" (");
26760 for (i, prop) in e.properties.iter().enumerate() {
26761 if i > 0 {
26762 self.write(", ");
26763 }
26764 self.generate_expression(prop)?;
26765 }
26766 self.write(")");
26767 }
26768 Ok(())
26769 }
26770
26771 fn generate_encrypt(&mut self, e: &Encrypt) -> Result<()> {
26772 self.write_keyword("ENCRYPT");
26774 self.write("(");
26775 self.generate_expression(&e.this)?;
26776 if let Some(passphrase) = &e.passphrase {
26777 self.write(", ");
26778 self.generate_expression(passphrase)?;
26779 }
26780 if let Some(aad) = &e.aad {
26781 self.write(", ");
26782 self.generate_expression(aad)?;
26783 }
26784 if let Some(method) = &e.encryption_method {
26785 self.write(", ");
26786 self.generate_expression(method)?;
26787 }
26788 self.write(")");
26789 Ok(())
26790 }
26791
26792 fn generate_encrypt_raw(&mut self, e: &EncryptRaw) -> Result<()> {
26793 self.write_keyword("ENCRYPT_RAW");
26795 self.write("(");
26796 self.generate_expression(&e.this)?;
26797 if let Some(key) = &e.key {
26798 self.write(", ");
26799 self.generate_expression(key)?;
26800 }
26801 if let Some(iv) = &e.iv {
26802 self.write(", ");
26803 self.generate_expression(iv)?;
26804 }
26805 if let Some(aad) = &e.aad {
26806 self.write(", ");
26807 self.generate_expression(aad)?;
26808 }
26809 if let Some(method) = &e.encryption_method {
26810 self.write(", ");
26811 self.generate_expression(method)?;
26812 }
26813 self.write(")");
26814 Ok(())
26815 }
26816
26817 fn generate_engine_property(&mut self, e: &EngineProperty) -> Result<()> {
26818 self.write_keyword("ENGINE");
26820 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
26821 self.write("=");
26822 } else {
26823 self.write(" = ");
26824 }
26825 self.generate_expression(&e.this)?;
26826 Ok(())
26827 }
26828
26829 fn generate_enviroment_property(&mut self, e: &EnviromentProperty) -> Result<()> {
26830 self.write_keyword("ENVIRONMENT");
26832 self.write(" (");
26833 for (i, expr) in e.expressions.iter().enumerate() {
26834 if i > 0 {
26835 self.write(", ");
26836 }
26837 self.generate_expression(expr)?;
26838 }
26839 self.write(")");
26840 Ok(())
26841 }
26842
26843 fn generate_ephemeral_column_constraint(
26844 &mut self,
26845 e: &EphemeralColumnConstraint,
26846 ) -> Result<()> {
26847 self.write_keyword("EPHEMERAL");
26849 if let Some(this) = &e.this {
26850 self.write_space();
26851 self.generate_expression(this)?;
26852 }
26853 Ok(())
26854 }
26855
26856 fn generate_equal_null(&mut self, e: &EqualNull) -> Result<()> {
26857 self.write_keyword("EQUAL_NULL");
26859 self.write("(");
26860 self.generate_expression(&e.this)?;
26861 self.write(", ");
26862 self.generate_expression(&e.expression)?;
26863 self.write(")");
26864 Ok(())
26865 }
26866
26867 fn generate_euclidean_distance(&mut self, e: &EuclideanDistance) -> Result<()> {
26868 use crate::dialects::DialectType;
26869
26870 match self.config.dialect {
26872 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
26873 self.generate_expression(&e.this)?;
26874 self.write(" <-> ");
26875 self.generate_expression(&e.expression)?;
26876 }
26877 _ => {
26878 self.write_keyword("EUCLIDEAN_DISTANCE");
26880 self.write("(");
26881 self.generate_expression(&e.this)?;
26882 self.write(", ");
26883 self.generate_expression(&e.expression)?;
26884 self.write(")");
26885 }
26886 }
26887 Ok(())
26888 }
26889
26890 fn generate_execute_as_property(&mut self, e: &ExecuteAsProperty) -> Result<()> {
26891 self.write_keyword("EXECUTE AS");
26893 self.write_space();
26894 self.generate_expression(&e.this)?;
26895 Ok(())
26896 }
26897
26898 fn generate_export(&mut self, e: &Export) -> Result<()> {
26899 self.write_keyword("EXPORT DATA");
26901 if let Some(connection) = &e.connection {
26902 self.write_space();
26903 self.write_keyword("WITH CONNECTION");
26904 self.write_space();
26905 self.generate_expression(connection)?;
26906 }
26907 if !e.options.is_empty() {
26908 self.write_space();
26909 self.generate_options_clause(&e.options)?;
26910 }
26911 self.write_space();
26912 self.write_keyword("AS");
26913 self.write_space();
26914 self.generate_expression(&e.this)?;
26915 Ok(())
26916 }
26917
26918 fn generate_external_property(&mut self, e: &ExternalProperty) -> Result<()> {
26919 self.write_keyword("EXTERNAL");
26921 if let Some(this) = &e.this {
26922 self.write_space();
26923 self.generate_expression(this)?;
26924 }
26925 Ok(())
26926 }
26927
26928 fn generate_fallback_property(&mut self, e: &FallbackProperty) -> Result<()> {
26929 if e.no.is_some() {
26931 self.write_keyword("NO ");
26932 }
26933 self.write_keyword("FALLBACK");
26934 if e.protection.is_some() {
26935 self.write_keyword(" PROTECTION");
26936 }
26937 Ok(())
26938 }
26939
26940 fn generate_farm_fingerprint(&mut self, e: &FarmFingerprint) -> Result<()> {
26941 self.write_keyword("FARM_FINGERPRINT");
26943 self.write("(");
26944 for (i, expr) in e.expressions.iter().enumerate() {
26945 if i > 0 {
26946 self.write(", ");
26947 }
26948 self.generate_expression(expr)?;
26949 }
26950 self.write(")");
26951 Ok(())
26952 }
26953
26954 fn generate_features_at_time(&mut self, e: &FeaturesAtTime) -> Result<()> {
26955 self.write_keyword("FEATURES_AT_TIME");
26957 self.write("(");
26958 self.generate_expression(&e.this)?;
26959 if let Some(time) = &e.time {
26960 self.write(", ");
26961 self.generate_expression(time)?;
26962 }
26963 if let Some(num_rows) = &e.num_rows {
26964 self.write(", ");
26965 self.generate_expression(num_rows)?;
26966 }
26967 if let Some(ignore_nulls) = &e.ignore_feature_nulls {
26968 self.write(", ");
26969 self.generate_expression(ignore_nulls)?;
26970 }
26971 self.write(")");
26972 Ok(())
26973 }
26974
26975 fn generate_fetch(&mut self, e: &Fetch) -> Result<()> {
26976 let use_limit = !e.percent
26978 && !e.with_ties
26979 && e.count.is_some()
26980 && matches!(
26981 self.config.dialect,
26982 Some(DialectType::Spark)
26983 | Some(DialectType::Hive)
26984 | Some(DialectType::DuckDB)
26985 | Some(DialectType::SQLite)
26986 | Some(DialectType::MySQL)
26987 | Some(DialectType::BigQuery)
26988 | Some(DialectType::Databricks)
26989 | Some(DialectType::StarRocks)
26990 | Some(DialectType::Doris)
26991 | Some(DialectType::Athena)
26992 | Some(DialectType::ClickHouse)
26993 );
26994
26995 if use_limit {
26996 self.write_keyword("LIMIT");
26997 self.write_space();
26998 self.generate_expression(e.count.as_ref().unwrap())?;
26999 return Ok(());
27000 }
27001
27002 self.write_keyword("FETCH");
27004 if !e.direction.is_empty() {
27005 self.write_space();
27006 self.write_keyword(&e.direction);
27007 }
27008 if let Some(count) = &e.count {
27009 self.write_space();
27010 self.generate_expression(count)?;
27011 }
27012 if e.percent {
27014 self.write_keyword(" PERCENT");
27015 }
27016 if e.rows {
27017 self.write_keyword(" ROWS");
27018 }
27019 if e.with_ties {
27020 self.write_keyword(" WITH TIES");
27021 } else if e.rows {
27022 self.write_keyword(" ONLY");
27023 } else {
27024 self.write_keyword(" ROWS ONLY");
27025 }
27026 Ok(())
27027 }
27028
27029 fn generate_file_format_property(&mut self, e: &FileFormatProperty) -> Result<()> {
27030 if e.hive_format.is_some() {
27034 self.write_keyword("STORED AS");
27036 self.write_space();
27037 if let Some(this) = &e.this {
27038 if let Expression::Identifier(id) = this.as_ref() {
27040 self.write_keyword(&id.name.to_uppercase());
27041 } else {
27042 self.generate_expression(this)?;
27043 }
27044 }
27045 } else if matches!(self.config.dialect, Some(DialectType::Hive)) {
27046 self.write_keyword("STORED AS");
27048 self.write_space();
27049 if let Some(this) = &e.this {
27050 if let Expression::Identifier(id) = this.as_ref() {
27051 self.write_keyword(&id.name.to_uppercase());
27052 } else {
27053 self.generate_expression(this)?;
27054 }
27055 }
27056 } else if matches!(
27057 self.config.dialect,
27058 Some(DialectType::Spark) | Some(DialectType::Databricks)
27059 ) {
27060 self.write_keyword("USING");
27062 self.write_space();
27063 if let Some(this) = &e.this {
27064 self.generate_expression(this)?;
27065 }
27066 } else {
27067 self.write_keyword("FILE_FORMAT");
27069 self.write(" = ");
27070 if let Some(this) = &e.this {
27071 self.generate_expression(this)?;
27072 } else if !e.expressions.is_empty() {
27073 self.write("(");
27074 for (i, expr) in e.expressions.iter().enumerate() {
27075 if i > 0 {
27076 self.write(", ");
27077 }
27078 self.generate_expression(expr)?;
27079 }
27080 self.write(")");
27081 }
27082 }
27083 Ok(())
27084 }
27085
27086 fn generate_filter(&mut self, e: &Filter) -> Result<()> {
27087 self.generate_expression(&e.this)?;
27089 self.write_space();
27090 self.write_keyword("FILTER");
27091 self.write("(");
27092 self.write_keyword("WHERE");
27093 self.write_space();
27094 self.generate_expression(&e.expression)?;
27095 self.write(")");
27096 Ok(())
27097 }
27098
27099 fn generate_float64(&mut self, e: &Float64) -> Result<()> {
27100 self.write_keyword("FLOAT64");
27102 self.write("(");
27103 self.generate_expression(&e.this)?;
27104 if let Some(expr) = &e.expression {
27105 self.write(", ");
27106 self.generate_expression(expr)?;
27107 }
27108 self.write(")");
27109 Ok(())
27110 }
27111
27112 fn generate_for_in(&mut self, e: &ForIn) -> Result<()> {
27113 self.write_keyword("FOR");
27115 self.write_space();
27116 self.generate_expression(&e.this)?;
27117 self.write_space();
27118 self.write_keyword("DO");
27119 self.write_space();
27120 self.generate_expression(&e.expression)?;
27121 Ok(())
27122 }
27123
27124 fn generate_foreign_key(&mut self, e: &ForeignKey) -> Result<()> {
27125 self.write_keyword("FOREIGN KEY");
27127 if !e.expressions.is_empty() {
27128 self.write(" (");
27129 for (i, expr) in e.expressions.iter().enumerate() {
27130 if i > 0 {
27131 self.write(", ");
27132 }
27133 self.generate_expression(expr)?;
27134 }
27135 self.write(")");
27136 }
27137 if let Some(reference) = &e.reference {
27138 self.write_space();
27139 self.generate_expression(reference)?;
27140 }
27141 if let Some(delete) = &e.delete {
27142 self.write_space();
27143 self.write_keyword("ON DELETE");
27144 self.write_space();
27145 self.generate_expression(delete)?;
27146 }
27147 if let Some(update) = &e.update {
27148 self.write_space();
27149 self.write_keyword("ON UPDATE");
27150 self.write_space();
27151 self.generate_expression(update)?;
27152 }
27153 if !e.options.is_empty() {
27154 self.write_space();
27155 for (i, opt) in e.options.iter().enumerate() {
27156 if i > 0 {
27157 self.write_space();
27158 }
27159 self.generate_expression(opt)?;
27160 }
27161 }
27162 Ok(())
27163 }
27164
27165 fn generate_format(&mut self, e: &Format) -> Result<()> {
27166 self.write_keyword("FORMAT");
27168 self.write("(");
27169 self.generate_expression(&e.this)?;
27170 for expr in &e.expressions {
27171 self.write(", ");
27172 self.generate_expression(expr)?;
27173 }
27174 self.write(")");
27175 Ok(())
27176 }
27177
27178 fn generate_format_phrase(&mut self, e: &FormatPhrase) -> Result<()> {
27179 self.generate_expression(&e.this)?;
27181 self.write(" (");
27182 self.write_keyword("FORMAT");
27183 self.write(" '");
27184 self.write(&e.format);
27185 self.write("')");
27186 Ok(())
27187 }
27188
27189 fn generate_freespace_property(&mut self, e: &FreespaceProperty) -> Result<()> {
27190 self.write_keyword("FREESPACE");
27192 self.write("=");
27193 self.generate_expression(&e.this)?;
27194 if e.percent.is_some() {
27195 self.write_keyword(" PERCENT");
27196 }
27197 Ok(())
27198 }
27199
27200 fn generate_from(&mut self, e: &From) -> Result<()> {
27201 self.write_keyword("FROM");
27203 self.write_space();
27204
27205 use crate::dialects::DialectType;
27209 let has_tablesample = e
27210 .expressions
27211 .iter()
27212 .any(|expr| matches!(expr, Expression::TableSample(_)));
27213 let is_cross_join_dialect = matches!(
27214 self.config.dialect,
27215 Some(DialectType::BigQuery)
27216 | Some(DialectType::Hive)
27217 | Some(DialectType::Spark)
27218 | Some(DialectType::Databricks)
27219 | Some(DialectType::SQLite)
27220 | Some(DialectType::ClickHouse)
27221 );
27222 let source_is_same_as_target2 = self.config.source_dialect.is_some()
27223 && self.config.source_dialect == self.config.dialect;
27224 let source_is_cross_join_dialect2 = matches!(
27225 self.config.source_dialect,
27226 Some(DialectType::BigQuery)
27227 | Some(DialectType::Hive)
27228 | Some(DialectType::Spark)
27229 | Some(DialectType::Databricks)
27230 | Some(DialectType::SQLite)
27231 | Some(DialectType::ClickHouse)
27232 );
27233 let use_cross_join = !has_tablesample
27234 && is_cross_join_dialect
27235 && (source_is_same_as_target2
27236 || source_is_cross_join_dialect2
27237 || self.config.source_dialect.is_none());
27238
27239 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
27241
27242 for (i, expr) in e.expressions.iter().enumerate() {
27243 if i > 0 {
27244 if use_cross_join {
27245 self.write(" CROSS JOIN ");
27246 } else {
27247 self.write(", ");
27248 }
27249 }
27250 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
27251 self.write("(");
27252 self.generate_expression(expr)?;
27253 self.write(")");
27254 } else {
27255 self.generate_expression(expr)?;
27256 }
27257 }
27258 Ok(())
27259 }
27260
27261 fn generate_from_base(&mut self, e: &FromBase) -> Result<()> {
27262 self.write_keyword("FROM_BASE");
27264 self.write("(");
27265 self.generate_expression(&e.this)?;
27266 self.write(", ");
27267 self.generate_expression(&e.expression)?;
27268 self.write(")");
27269 Ok(())
27270 }
27271
27272 fn generate_from_time_zone(&mut self, e: &FromTimeZone) -> Result<()> {
27273 self.generate_expression(&e.this)?;
27275 if let Some(zone) = &e.zone {
27276 self.write_space();
27277 self.write_keyword("AT TIME ZONE");
27278 self.write_space();
27279 self.generate_expression(zone)?;
27280 self.write_space();
27281 self.write_keyword("AT TIME ZONE");
27282 self.write(" 'UTC'");
27283 }
27284 Ok(())
27285 }
27286
27287 fn generate_gap_fill(&mut self, e: &GapFill) -> Result<()> {
27288 self.write_keyword("GAP_FILL");
27290 self.write("(");
27291 self.generate_expression(&e.this)?;
27292 if let Some(ts_column) = &e.ts_column {
27293 self.write(", ");
27294 self.generate_expression(ts_column)?;
27295 }
27296 if let Some(bucket_width) = &e.bucket_width {
27297 self.write(", ");
27298 self.generate_expression(bucket_width)?;
27299 }
27300 if let Some(partitioning_columns) = &e.partitioning_columns {
27301 self.write(", ");
27302 self.generate_expression(partitioning_columns)?;
27303 }
27304 if let Some(value_columns) = &e.value_columns {
27305 self.write(", ");
27306 self.generate_expression(value_columns)?;
27307 }
27308 self.write(")");
27309 Ok(())
27310 }
27311
27312 fn generate_generate_date_array(&mut self, e: &GenerateDateArray) -> Result<()> {
27313 self.write_keyword("GENERATE_DATE_ARRAY");
27315 self.write("(");
27316 let mut first = true;
27317 if let Some(start) = &e.start {
27318 self.generate_expression(start)?;
27319 first = false;
27320 }
27321 if let Some(end) = &e.end {
27322 if !first {
27323 self.write(", ");
27324 }
27325 self.generate_expression(end)?;
27326 first = false;
27327 }
27328 if let Some(step) = &e.step {
27329 if !first {
27330 self.write(", ");
27331 }
27332 self.generate_expression(step)?;
27333 }
27334 self.write(")");
27335 Ok(())
27336 }
27337
27338 fn generate_generate_embedding(&mut self, e: &GenerateEmbedding) -> Result<()> {
27339 self.write_keyword("ML.GENERATE_EMBEDDING");
27341 self.write("(");
27342 self.generate_expression(&e.this)?;
27343 self.write(", ");
27344 self.generate_expression(&e.expression)?;
27345 if let Some(params) = &e.params_struct {
27346 self.write(", ");
27347 self.generate_expression(params)?;
27348 }
27349 self.write(")");
27350 Ok(())
27351 }
27352
27353 fn generate_generate_series(&mut self, e: &GenerateSeries) -> Result<()> {
27354 let fn_name = match self.config.dialect {
27356 Some(DialectType::Presto)
27357 | Some(DialectType::Trino)
27358 | Some(DialectType::Athena)
27359 | Some(DialectType::Spark)
27360 | Some(DialectType::Databricks)
27361 | Some(DialectType::Hive) => "SEQUENCE",
27362 _ => "GENERATE_SERIES",
27363 };
27364 self.write_keyword(fn_name);
27365 self.write("(");
27366 let mut first = true;
27367 if let Some(start) = &e.start {
27368 self.generate_expression(start)?;
27369 first = false;
27370 }
27371 if let Some(end) = &e.end {
27372 if !first {
27373 self.write(", ");
27374 }
27375 self.generate_expression(end)?;
27376 first = false;
27377 }
27378 if let Some(step) = &e.step {
27379 if !first {
27380 self.write(", ");
27381 }
27382 if matches!(
27385 self.config.dialect,
27386 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
27387 ) {
27388 if let Some(converted) = self.convert_week_interval_to_day(step) {
27389 self.generate_expression(&converted)?;
27390 } else {
27391 self.generate_expression(step)?;
27392 }
27393 } else {
27394 self.generate_expression(step)?;
27395 }
27396 }
27397 self.write(")");
27398 Ok(())
27399 }
27400
27401 fn convert_week_interval_to_day(&self, expr: &Expression) -> Option<Expression> {
27404 use crate::expressions::*;
27405 if let Expression::Interval(ref iv) = expr {
27406 let (is_week, count_str) = if let Some(IntervalUnitSpec::Simple {
27408 unit: IntervalUnit::Week,
27409 ..
27410 }) = &iv.unit
27411 {
27412 let count = match &iv.this {
27414 Some(Expression::Literal(Literal::String(s))) => s.clone(),
27415 Some(Expression::Literal(Literal::Number(s))) => s.clone(),
27416 _ => return None,
27417 };
27418 (true, count)
27419 } else if iv.unit.is_none() {
27420 if let Some(Expression::Literal(Literal::String(s))) = &iv.this {
27422 let parts: Vec<&str> = s.trim().splitn(2, char::is_whitespace).collect();
27423 if parts.len() == 2 && parts[1].eq_ignore_ascii_case("WEEK") {
27424 (true, parts[0].to_string())
27425 } else {
27426 (false, String::new())
27427 }
27428 } else {
27429 (false, String::new())
27430 }
27431 } else {
27432 (false, String::new())
27433 };
27434
27435 if is_week {
27436 let count_expr = Expression::Literal(Literal::Number(count_str));
27438 let day_interval = Expression::Interval(Box::new(Interval {
27439 this: Some(Expression::Literal(Literal::String("7".to_string()))),
27440 unit: Some(IntervalUnitSpec::Simple {
27441 unit: IntervalUnit::Day,
27442 use_plural: false,
27443 }),
27444 }));
27445 let mul = Expression::Mul(Box::new(BinaryOp {
27446 left: count_expr,
27447 right: day_interval,
27448 left_comments: vec![],
27449 operator_comments: vec![],
27450 trailing_comments: vec![],
27451 }));
27452 return Some(Expression::Paren(Box::new(Paren {
27453 this: mul,
27454 trailing_comments: vec![],
27455 })));
27456 }
27457 }
27458 None
27459 }
27460
27461 fn generate_generate_timestamp_array(&mut self, e: &GenerateTimestampArray) -> Result<()> {
27462 self.write_keyword("GENERATE_TIMESTAMP_ARRAY");
27464 self.write("(");
27465 let mut first = true;
27466 if let Some(start) = &e.start {
27467 self.generate_expression(start)?;
27468 first = false;
27469 }
27470 if let Some(end) = &e.end {
27471 if !first {
27472 self.write(", ");
27473 }
27474 self.generate_expression(end)?;
27475 first = false;
27476 }
27477 if let Some(step) = &e.step {
27478 if !first {
27479 self.write(", ");
27480 }
27481 self.generate_expression(step)?;
27482 }
27483 self.write(")");
27484 Ok(())
27485 }
27486
27487 fn generate_generated_as_identity_column_constraint(
27488 &mut self,
27489 e: &GeneratedAsIdentityColumnConstraint,
27490 ) -> Result<()> {
27491 use crate::dialects::DialectType;
27492
27493 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
27495 self.write_keyword("AUTOINCREMENT");
27496 if let Some(start) = &e.start {
27497 self.write_keyword(" START ");
27498 self.generate_expression(start)?;
27499 }
27500 if let Some(increment) = &e.increment {
27501 self.write_keyword(" INCREMENT ");
27502 self.generate_expression(increment)?;
27503 }
27504 return Ok(());
27505 }
27506
27507 self.write_keyword("GENERATED");
27509 if let Some(this) = &e.this {
27510 if let Expression::Boolean(b) = this.as_ref() {
27512 if b.value {
27513 self.write_keyword(" ALWAYS");
27514 } else {
27515 self.write_keyword(" BY DEFAULT");
27516 if e.on_null.is_some() {
27517 self.write_keyword(" ON NULL");
27518 }
27519 }
27520 } else {
27521 self.write_keyword(" ALWAYS");
27522 }
27523 }
27524 self.write_keyword(" AS IDENTITY");
27525 let has_options = e.start.is_some()
27527 || e.increment.is_some()
27528 || e.minvalue.is_some()
27529 || e.maxvalue.is_some();
27530 if has_options {
27531 self.write(" (");
27532 let mut first = true;
27533 if let Some(start) = &e.start {
27534 self.write_keyword("START WITH ");
27535 self.generate_expression(start)?;
27536 first = false;
27537 }
27538 if let Some(increment) = &e.increment {
27539 if !first {
27540 self.write(" ");
27541 }
27542 self.write_keyword("INCREMENT BY ");
27543 self.generate_expression(increment)?;
27544 first = false;
27545 }
27546 if let Some(minvalue) = &e.minvalue {
27547 if !first {
27548 self.write(" ");
27549 }
27550 self.write_keyword("MINVALUE ");
27551 self.generate_expression(minvalue)?;
27552 first = false;
27553 }
27554 if let Some(maxvalue) = &e.maxvalue {
27555 if !first {
27556 self.write(" ");
27557 }
27558 self.write_keyword("MAXVALUE ");
27559 self.generate_expression(maxvalue)?;
27560 }
27561 self.write(")");
27562 }
27563 Ok(())
27564 }
27565
27566 fn generate_generated_as_row_column_constraint(
27567 &mut self,
27568 e: &GeneratedAsRowColumnConstraint,
27569 ) -> Result<()> {
27570 self.write_keyword("GENERATED ALWAYS AS ROW ");
27572 if e.start.is_some() {
27573 self.write_keyword("START");
27574 } else {
27575 self.write_keyword("END");
27576 }
27577 if e.hidden.is_some() {
27578 self.write_keyword(" HIDDEN");
27579 }
27580 Ok(())
27581 }
27582
27583 fn generate_get(&mut self, e: &Get) -> Result<()> {
27584 self.write_keyword("GET");
27586 self.write_space();
27587 self.generate_expression(&e.this)?;
27588 if let Some(target) = &e.target {
27589 self.write_space();
27590 self.generate_expression(target)?;
27591 }
27592 for prop in &e.properties {
27593 self.write_space();
27594 self.generate_expression(prop)?;
27595 }
27596 Ok(())
27597 }
27598
27599 fn generate_get_extract(&mut self, e: &GetExtract) -> Result<()> {
27600 self.generate_expression(&e.this)?;
27602 self.write("[");
27603 self.generate_expression(&e.expression)?;
27604 self.write("]");
27605 Ok(())
27606 }
27607
27608 fn generate_getbit(&mut self, e: &Getbit) -> Result<()> {
27609 self.write_keyword("GETBIT");
27611 self.write("(");
27612 self.generate_expression(&e.this)?;
27613 self.write(", ");
27614 self.generate_expression(&e.expression)?;
27615 self.write(")");
27616 Ok(())
27617 }
27618
27619 fn generate_grant_principal(&mut self, e: &GrantPrincipal) -> Result<()> {
27620 if e.is_role {
27622 self.write_keyword("ROLE");
27623 self.write_space();
27624 } else if e.is_group {
27625 self.write_keyword("GROUP");
27626 self.write_space();
27627 }
27628 self.write(&e.name.name);
27629 Ok(())
27630 }
27631
27632 fn generate_grant_privilege(&mut self, e: &GrantPrivilege) -> Result<()> {
27633 self.generate_expression(&e.this)?;
27635 if !e.expressions.is_empty() {
27636 self.write("(");
27637 for (i, expr) in e.expressions.iter().enumerate() {
27638 if i > 0 {
27639 self.write(", ");
27640 }
27641 self.generate_expression(expr)?;
27642 }
27643 self.write(")");
27644 }
27645 Ok(())
27646 }
27647
27648 fn generate_group(&mut self, e: &Group) -> Result<()> {
27649 self.write_keyword("GROUP BY");
27651 match e.all {
27653 Some(true) => {
27654 self.write_space();
27655 self.write_keyword("ALL");
27656 }
27657 Some(false) => {
27658 self.write_space();
27659 self.write_keyword("DISTINCT");
27660 }
27661 None => {}
27662 }
27663 if !e.expressions.is_empty() {
27664 self.write_space();
27665 for (i, expr) in e.expressions.iter().enumerate() {
27666 if i > 0 {
27667 self.write(", ");
27668 }
27669 self.generate_expression(expr)?;
27670 }
27671 }
27672 if let Some(cube) = &e.cube {
27674 if !e.expressions.is_empty() {
27675 self.write(", ");
27676 } else {
27677 self.write_space();
27678 }
27679 self.generate_expression(cube)?;
27680 }
27681 if let Some(rollup) = &e.rollup {
27682 if !e.expressions.is_empty() || e.cube.is_some() {
27683 self.write(", ");
27684 } else {
27685 self.write_space();
27686 }
27687 self.generate_expression(rollup)?;
27688 }
27689 if let Some(grouping_sets) = &e.grouping_sets {
27690 if !e.expressions.is_empty() || e.cube.is_some() || e.rollup.is_some() {
27691 self.write(", ");
27692 } else {
27693 self.write_space();
27694 }
27695 self.generate_expression(grouping_sets)?;
27696 }
27697 if let Some(totals) = &e.totals {
27698 self.write_space();
27699 self.write_keyword("WITH TOTALS");
27700 self.generate_expression(totals)?;
27701 }
27702 Ok(())
27703 }
27704
27705 fn generate_group_by(&mut self, e: &GroupBy) -> Result<()> {
27706 self.write_keyword("GROUP BY");
27708 match e.all {
27710 Some(true) => {
27711 self.write_space();
27712 self.write_keyword("ALL");
27713 }
27714 Some(false) => {
27715 self.write_space();
27716 self.write_keyword("DISTINCT");
27717 }
27718 None => {}
27719 }
27720
27721 let mut trailing_cube = false;
27724 let mut trailing_rollup = false;
27725 let mut regular_expressions: Vec<&Expression> = Vec::new();
27726
27727 for expr in &e.expressions {
27728 match expr {
27729 Expression::Cube(c) if c.expressions.is_empty() => {
27730 trailing_cube = true;
27731 }
27732 Expression::Rollup(r) if r.expressions.is_empty() => {
27733 trailing_rollup = true;
27734 }
27735 _ => {
27736 regular_expressions.push(expr);
27737 }
27738 }
27739 }
27740
27741 if self.config.pretty {
27743 self.write_newline();
27744 self.indent_level += 1;
27745 for (i, expr) in regular_expressions.iter().enumerate() {
27746 if i > 0 {
27747 self.write(",");
27748 self.write_newline();
27749 }
27750 self.write_indent();
27751 self.generate_expression(expr)?;
27752 }
27753 self.indent_level -= 1;
27754 } else {
27755 self.write_space();
27756 for (i, expr) in regular_expressions.iter().enumerate() {
27757 if i > 0 {
27758 self.write(", ");
27759 }
27760 self.generate_expression(expr)?;
27761 }
27762 }
27763
27764 if trailing_cube {
27766 self.write_space();
27767 self.write_keyword("WITH CUBE");
27768 } else if trailing_rollup {
27769 self.write_space();
27770 self.write_keyword("WITH ROLLUP");
27771 }
27772
27773 if e.totals {
27775 self.write_space();
27776 self.write_keyword("WITH TOTALS");
27777 }
27778
27779 Ok(())
27780 }
27781
27782 fn generate_grouping(&mut self, e: &Grouping) -> Result<()> {
27783 self.write_keyword("GROUPING");
27785 self.write("(");
27786 for (i, expr) in e.expressions.iter().enumerate() {
27787 if i > 0 {
27788 self.write(", ");
27789 }
27790 self.generate_expression(expr)?;
27791 }
27792 self.write(")");
27793 Ok(())
27794 }
27795
27796 fn generate_grouping_id(&mut self, e: &GroupingId) -> Result<()> {
27797 self.write_keyword("GROUPING_ID");
27799 self.write("(");
27800 for (i, expr) in e.expressions.iter().enumerate() {
27801 if i > 0 {
27802 self.write(", ");
27803 }
27804 self.generate_expression(expr)?;
27805 }
27806 self.write(")");
27807 Ok(())
27808 }
27809
27810 fn generate_grouping_sets(&mut self, e: &GroupingSets) -> Result<()> {
27811 self.write_keyword("GROUPING SETS");
27813 self.write(" (");
27814 for (i, expr) in e.expressions.iter().enumerate() {
27815 if i > 0 {
27816 self.write(", ");
27817 }
27818 self.generate_expression(expr)?;
27819 }
27820 self.write(")");
27821 Ok(())
27822 }
27823
27824 fn generate_hash_agg(&mut self, e: &HashAgg) -> Result<()> {
27825 self.write_keyword("HASH_AGG");
27827 self.write("(");
27828 self.generate_expression(&e.this)?;
27829 for expr in &e.expressions {
27830 self.write(", ");
27831 self.generate_expression(expr)?;
27832 }
27833 self.write(")");
27834 Ok(())
27835 }
27836
27837 fn generate_having(&mut self, e: &Having) -> Result<()> {
27838 self.write_keyword("HAVING");
27840 self.write_space();
27841 self.generate_expression(&e.this)?;
27842 Ok(())
27843 }
27844
27845 fn generate_having_max(&mut self, e: &HavingMax) -> Result<()> {
27846 self.generate_expression(&e.this)?;
27848 self.write_space();
27849 self.write_keyword("HAVING");
27850 self.write_space();
27851 if e.max.is_some() {
27852 self.write_keyword("MAX");
27853 } else {
27854 self.write_keyword("MIN");
27855 }
27856 self.write_space();
27857 self.generate_expression(&e.expression)?;
27858 Ok(())
27859 }
27860
27861 fn generate_heredoc(&mut self, e: &Heredoc) -> Result<()> {
27862 use crate::dialects::DialectType;
27863 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
27865 if let Expression::Literal(Literal::String(ref s)) = *e.this {
27867 return self.generate_string_literal(s);
27868 }
27869 }
27870 if matches!(
27872 self.config.dialect,
27873 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
27874 ) {
27875 self.write("$");
27876 if let Some(tag) = &e.tag {
27877 self.generate_expression(tag)?;
27878 }
27879 self.write("$");
27880 self.generate_expression(&e.this)?;
27881 self.write("$");
27882 if let Some(tag) = &e.tag {
27883 self.generate_expression(tag)?;
27884 }
27885 self.write("$");
27886 return Ok(());
27887 }
27888 self.write("$");
27890 if let Some(tag) = &e.tag {
27891 self.generate_expression(tag)?;
27892 }
27893 self.write("$");
27894 self.generate_expression(&e.this)?;
27895 self.write("$");
27896 if let Some(tag) = &e.tag {
27897 self.generate_expression(tag)?;
27898 }
27899 self.write("$");
27900 Ok(())
27901 }
27902
27903 fn generate_hex_encode(&mut self, e: &HexEncode) -> Result<()> {
27904 self.write_keyword("HEX_ENCODE");
27906 self.write("(");
27907 self.generate_expression(&e.this)?;
27908 self.write(")");
27909 Ok(())
27910 }
27911
27912 fn generate_historical_data(&mut self, e: &HistoricalData) -> Result<()> {
27913 match e.this.as_ref() {
27916 Expression::Identifier(id) => self.write(&id.name),
27917 other => self.generate_expression(other)?,
27918 }
27919 self.write(" (");
27920 self.write(&e.kind);
27921 self.write(" => ");
27922 self.generate_expression(&e.expression)?;
27923 self.write(")");
27924 Ok(())
27925 }
27926
27927 fn generate_hll(&mut self, e: &Hll) -> Result<()> {
27928 self.write_keyword("HLL");
27930 self.write("(");
27931 self.generate_expression(&e.this)?;
27932 for expr in &e.expressions {
27933 self.write(", ");
27934 self.generate_expression(expr)?;
27935 }
27936 self.write(")");
27937 Ok(())
27938 }
27939
27940 fn generate_in_out_column_constraint(&mut self, e: &InOutColumnConstraint) -> Result<()> {
27941 if e.input_.is_some() && e.output.is_some() {
27943 self.write_keyword("IN OUT");
27944 } else if e.input_.is_some() {
27945 self.write_keyword("IN");
27946 } else if e.output.is_some() {
27947 self.write_keyword("OUT");
27948 }
27949 Ok(())
27950 }
27951
27952 fn generate_include_property(&mut self, e: &IncludeProperty) -> Result<()> {
27953 self.write_keyword("INCLUDE");
27955 self.write_space();
27956 self.generate_expression(&e.this)?;
27957 if let Some(column_def) = &e.column_def {
27958 self.write_space();
27959 self.generate_expression(column_def)?;
27960 }
27961 if let Some(alias) = &e.alias {
27962 self.write_space();
27963 self.write_keyword("AS");
27964 self.write_space();
27965 self.write(alias);
27966 }
27967 Ok(())
27968 }
27969
27970 fn generate_index(&mut self, e: &Index) -> Result<()> {
27971 if e.unique {
27973 self.write_keyword("UNIQUE");
27974 self.write_space();
27975 }
27976 if e.primary.is_some() {
27977 self.write_keyword("PRIMARY");
27978 self.write_space();
27979 }
27980 if e.amp.is_some() {
27981 self.write_keyword("AMP");
27982 self.write_space();
27983 }
27984 if e.table.is_none() {
27985 self.write_keyword("INDEX");
27986 self.write_space();
27987 }
27988 if let Some(name) = &e.this {
27989 self.generate_expression(name)?;
27990 self.write_space();
27991 }
27992 if let Some(table) = &e.table {
27993 self.write_keyword("ON");
27994 self.write_space();
27995 self.generate_expression(table)?;
27996 }
27997 if !e.params.is_empty() {
27998 self.write("(");
27999 for (i, param) in e.params.iter().enumerate() {
28000 if i > 0 {
28001 self.write(", ");
28002 }
28003 self.generate_expression(param)?;
28004 }
28005 self.write(")");
28006 }
28007 Ok(())
28008 }
28009
28010 fn generate_index_column_constraint(&mut self, e: &IndexColumnConstraint) -> Result<()> {
28011 if let Some(kind) = &e.kind {
28013 self.write(kind);
28014 self.write_space();
28015 }
28016 self.write_keyword("INDEX");
28017 if let Some(this) = &e.this {
28018 self.write_space();
28019 self.generate_expression(this)?;
28020 }
28021 if let Some(index_type) = &e.index_type {
28022 self.write_space();
28023 self.write_keyword("USING");
28024 self.write_space();
28025 self.generate_expression(index_type)?;
28026 }
28027 if !e.expressions.is_empty() {
28028 self.write(" (");
28029 for (i, expr) in e.expressions.iter().enumerate() {
28030 if i > 0 {
28031 self.write(", ");
28032 }
28033 self.generate_expression(expr)?;
28034 }
28035 self.write(")");
28036 }
28037 for opt in &e.options {
28038 self.write_space();
28039 self.generate_expression(opt)?;
28040 }
28041 Ok(())
28042 }
28043
28044 fn generate_index_constraint_option(&mut self, e: &IndexConstraintOption) -> Result<()> {
28045 if let Some(key_block_size) = &e.key_block_size {
28047 self.write_keyword("KEY_BLOCK_SIZE");
28048 self.write(" = ");
28049 self.generate_expression(key_block_size)?;
28050 } else if let Some(using) = &e.using {
28051 self.write_keyword("USING");
28052 self.write_space();
28053 self.generate_expression(using)?;
28054 } else if let Some(parser) = &e.parser {
28055 self.write_keyword("WITH PARSER");
28056 self.write_space();
28057 self.generate_expression(parser)?;
28058 } else if let Some(comment) = &e.comment {
28059 self.write_keyword("COMMENT");
28060 self.write_space();
28061 self.generate_expression(comment)?;
28062 } else if let Some(visible) = &e.visible {
28063 self.generate_expression(visible)?;
28064 } else if let Some(engine_attr) = &e.engine_attr {
28065 self.write_keyword("ENGINE_ATTRIBUTE");
28066 self.write(" = ");
28067 self.generate_expression(engine_attr)?;
28068 } else if let Some(secondary_engine_attr) = &e.secondary_engine_attr {
28069 self.write_keyword("SECONDARY_ENGINE_ATTRIBUTE");
28070 self.write(" = ");
28071 self.generate_expression(secondary_engine_attr)?;
28072 }
28073 Ok(())
28074 }
28075
28076 fn generate_index_parameters(&mut self, e: &IndexParameters) -> Result<()> {
28077 if let Some(using) = &e.using {
28079 self.write_keyword("USING");
28080 self.write_space();
28081 self.generate_expression(using)?;
28082 }
28083 if !e.columns.is_empty() {
28084 self.write("(");
28085 for (i, col) in e.columns.iter().enumerate() {
28086 if i > 0 {
28087 self.write(", ");
28088 }
28089 self.generate_expression(col)?;
28090 }
28091 self.write(")");
28092 }
28093 if let Some(partition_by) = &e.partition_by {
28094 self.write_space();
28095 self.write_keyword("PARTITION BY");
28096 self.write_space();
28097 self.generate_expression(partition_by)?;
28098 }
28099 if let Some(where_) = &e.where_ {
28100 self.write_space();
28101 self.generate_expression(where_)?;
28102 }
28103 if let Some(include) = &e.include {
28104 self.write_space();
28105 self.write_keyword("INCLUDE");
28106 self.write(" (");
28107 self.generate_expression(include)?;
28108 self.write(")");
28109 }
28110 if let Some(with_storage) = &e.with_storage {
28111 self.write_space();
28112 self.write_keyword("WITH");
28113 self.write(" (");
28114 self.generate_expression(with_storage)?;
28115 self.write(")");
28116 }
28117 if let Some(tablespace) = &e.tablespace {
28118 self.write_space();
28119 self.write_keyword("USING INDEX TABLESPACE");
28120 self.write_space();
28121 self.generate_expression(tablespace)?;
28122 }
28123 Ok(())
28124 }
28125
28126 fn generate_index_table_hint(&mut self, e: &IndexTableHint) -> Result<()> {
28127 if let Expression::Identifier(id) = &*e.this {
28131 self.write_keyword(&id.name);
28132 } else {
28133 self.generate_expression(&e.this)?;
28134 }
28135 self.write_space();
28136 self.write_keyword("INDEX");
28137 if let Some(target) = &e.target {
28138 self.write_space();
28139 self.write_keyword("FOR");
28140 self.write_space();
28141 if let Expression::Identifier(id) = &**target {
28142 self.write_keyword(&id.name);
28143 } else {
28144 self.generate_expression(target)?;
28145 }
28146 }
28147 self.write(" (");
28149 for (i, expr) in e.expressions.iter().enumerate() {
28150 if i > 0 {
28151 self.write(", ");
28152 }
28153 self.generate_expression(expr)?;
28154 }
28155 self.write(")");
28156 Ok(())
28157 }
28158
28159 fn generate_inherits_property(&mut self, e: &InheritsProperty) -> Result<()> {
28160 self.write_keyword("INHERITS");
28162 self.write(" (");
28163 for (i, expr) in e.expressions.iter().enumerate() {
28164 if i > 0 {
28165 self.write(", ");
28166 }
28167 self.generate_expression(expr)?;
28168 }
28169 self.write(")");
28170 Ok(())
28171 }
28172
28173 fn generate_input_model_property(&mut self, e: &InputModelProperty) -> Result<()> {
28174 self.write_keyword("INPUT");
28176 self.write("(");
28177 self.generate_expression(&e.this)?;
28178 self.write(")");
28179 Ok(())
28180 }
28181
28182 fn generate_input_output_format(&mut self, e: &InputOutputFormat) -> Result<()> {
28183 if let Some(input_format) = &e.input_format {
28185 self.write_keyword("INPUTFORMAT");
28186 self.write_space();
28187 self.generate_expression(input_format)?;
28188 }
28189 if let Some(output_format) = &e.output_format {
28190 if e.input_format.is_some() {
28191 self.write(" ");
28192 }
28193 self.write_keyword("OUTPUTFORMAT");
28194 self.write_space();
28195 self.generate_expression(output_format)?;
28196 }
28197 Ok(())
28198 }
28199
28200 fn generate_install(&mut self, e: &Install) -> Result<()> {
28201 if e.force.is_some() {
28203 self.write_keyword("FORCE");
28204 self.write_space();
28205 }
28206 self.write_keyword("INSTALL");
28207 self.write_space();
28208 self.generate_expression(&e.this)?;
28209 if let Some(from) = &e.from_ {
28210 self.write_space();
28211 self.write_keyword("FROM");
28212 self.write_space();
28213 self.generate_expression(from)?;
28214 }
28215 Ok(())
28216 }
28217
28218 fn generate_interval_op(&mut self, e: &IntervalOp) -> Result<()> {
28219 self.write_keyword("INTERVAL");
28221 self.write_space();
28222 self.generate_expression(&e.expression)?;
28224 if let Some(unit) = &e.unit {
28225 self.write_space();
28226 self.write(unit);
28227 }
28228 Ok(())
28229 }
28230
28231 fn generate_interval_span(&mut self, e: &IntervalSpan) -> Result<()> {
28232 self.write(&format!("{:?}", e.this).to_uppercase());
28234 self.write_space();
28235 self.write_keyword("TO");
28236 self.write_space();
28237 self.write(&format!("{:?}", e.expression).to_uppercase());
28238 Ok(())
28239 }
28240
28241 fn generate_into_clause(&mut self, e: &IntoClause) -> Result<()> {
28242 self.write_keyword("INTO");
28244 if e.temporary {
28245 self.write_keyword(" TEMPORARY");
28246 }
28247 if e.unlogged.is_some() {
28248 self.write_keyword(" UNLOGGED");
28249 }
28250 if let Some(this) = &e.this {
28251 self.write_space();
28252 self.generate_expression(this)?;
28253 }
28254 if !e.expressions.is_empty() {
28255 self.write(" (");
28256 for (i, expr) in e.expressions.iter().enumerate() {
28257 if i > 0 {
28258 self.write(", ");
28259 }
28260 self.generate_expression(expr)?;
28261 }
28262 self.write(")");
28263 }
28264 Ok(())
28265 }
28266
28267 fn generate_introducer(&mut self, e: &Introducer) -> Result<()> {
28268 self.generate_expression(&e.this)?;
28270 self.write_space();
28271 self.generate_expression(&e.expression)?;
28272 Ok(())
28273 }
28274
28275 fn generate_isolated_loading_property(&mut self, e: &IsolatedLoadingProperty) -> Result<()> {
28276 self.write_keyword("WITH");
28278 if e.no.is_some() {
28279 self.write_keyword(" NO");
28280 }
28281 if e.concurrent.is_some() {
28282 self.write_keyword(" CONCURRENT");
28283 }
28284 self.write_keyword(" ISOLATED LOADING");
28285 if let Some(target) = &e.target {
28286 self.write_space();
28287 self.generate_expression(target)?;
28288 }
28289 Ok(())
28290 }
28291
28292 fn generate_json(&mut self, e: &JSON) -> Result<()> {
28293 self.write_keyword("JSON");
28295 if let Some(this) = &e.this {
28296 self.write_space();
28297 self.generate_expression(this)?;
28298 }
28299 if let Some(with_) = &e.with_ {
28300 if let Expression::Boolean(b) = with_.as_ref() {
28302 if b.value {
28303 self.write_keyword(" WITH");
28304 } else {
28305 self.write_keyword(" WITHOUT");
28306 }
28307 }
28308 }
28309 if e.unique {
28310 self.write_keyword(" UNIQUE KEYS");
28311 }
28312 Ok(())
28313 }
28314
28315 fn generate_json_array(&mut self, e: &JSONArray) -> Result<()> {
28316 self.write_keyword("JSON_ARRAY");
28318 self.write("(");
28319 for (i, expr) in e.expressions.iter().enumerate() {
28320 if i > 0 {
28321 self.write(", ");
28322 }
28323 self.generate_expression(expr)?;
28324 }
28325 if let Some(null_handling) = &e.null_handling {
28326 self.write_space();
28327 self.generate_expression(null_handling)?;
28328 }
28329 if let Some(return_type) = &e.return_type {
28330 self.write_space();
28331 self.write_keyword("RETURNING");
28332 self.write_space();
28333 self.generate_expression(return_type)?;
28334 }
28335 if e.strict.is_some() {
28336 self.write_space();
28337 self.write_keyword("STRICT");
28338 }
28339 self.write(")");
28340 Ok(())
28341 }
28342
28343 fn generate_json_array_agg_struct(&mut self, e: &JSONArrayAgg) -> Result<()> {
28344 self.write_keyword("JSON_ARRAYAGG");
28346 self.write("(");
28347 self.generate_expression(&e.this)?;
28348 if let Some(order) = &e.order {
28349 self.write_space();
28350 if let Expression::OrderBy(ob) = order.as_ref() {
28352 self.write_keyword("ORDER BY");
28353 self.write_space();
28354 for (i, ord) in ob.expressions.iter().enumerate() {
28355 if i > 0 {
28356 self.write(", ");
28357 }
28358 self.generate_ordered(ord)?;
28359 }
28360 } else {
28361 self.generate_expression(order)?;
28363 }
28364 }
28365 if let Some(null_handling) = &e.null_handling {
28366 self.write_space();
28367 self.generate_expression(null_handling)?;
28368 }
28369 if let Some(return_type) = &e.return_type {
28370 self.write_space();
28371 self.write_keyword("RETURNING");
28372 self.write_space();
28373 self.generate_expression(return_type)?;
28374 }
28375 if e.strict.is_some() {
28376 self.write_space();
28377 self.write_keyword("STRICT");
28378 }
28379 self.write(")");
28380 Ok(())
28381 }
28382
28383 fn generate_json_object_agg_struct(&mut self, e: &JSONObjectAgg) -> Result<()> {
28384 self.write_keyword("JSON_OBJECTAGG");
28386 self.write("(");
28387 for (i, expr) in e.expressions.iter().enumerate() {
28388 if i > 0 {
28389 self.write(", ");
28390 }
28391 self.generate_expression(expr)?;
28392 }
28393 if let Some(null_handling) = &e.null_handling {
28394 self.write_space();
28395 self.generate_expression(null_handling)?;
28396 }
28397 if let Some(unique_keys) = &e.unique_keys {
28398 self.write_space();
28399 if let Expression::Boolean(b) = unique_keys.as_ref() {
28400 if b.value {
28401 self.write_keyword("WITH UNIQUE KEYS");
28402 } else {
28403 self.write_keyword("WITHOUT UNIQUE KEYS");
28404 }
28405 }
28406 }
28407 if let Some(return_type) = &e.return_type {
28408 self.write_space();
28409 self.write_keyword("RETURNING");
28410 self.write_space();
28411 self.generate_expression(return_type)?;
28412 }
28413 self.write(")");
28414 Ok(())
28415 }
28416
28417 fn generate_json_array_append(&mut self, e: &JSONArrayAppend) -> Result<()> {
28418 self.write_keyword("JSON_ARRAY_APPEND");
28420 self.write("(");
28421 self.generate_expression(&e.this)?;
28422 for expr in &e.expressions {
28423 self.write(", ");
28424 self.generate_expression(expr)?;
28425 }
28426 self.write(")");
28427 Ok(())
28428 }
28429
28430 fn generate_json_array_contains(&mut self, e: &JSONArrayContains) -> Result<()> {
28431 self.write_keyword("JSON_ARRAY_CONTAINS");
28433 self.write("(");
28434 self.generate_expression(&e.this)?;
28435 self.write(", ");
28436 self.generate_expression(&e.expression)?;
28437 self.write(")");
28438 Ok(())
28439 }
28440
28441 fn generate_json_array_insert(&mut self, e: &JSONArrayInsert) -> Result<()> {
28442 self.write_keyword("JSON_ARRAY_INSERT");
28444 self.write("(");
28445 self.generate_expression(&e.this)?;
28446 for expr in &e.expressions {
28447 self.write(", ");
28448 self.generate_expression(expr)?;
28449 }
28450 self.write(")");
28451 Ok(())
28452 }
28453
28454 fn generate_jsonb_exists(&mut self, e: &JSONBExists) -> Result<()> {
28455 self.write_keyword("JSONB_EXISTS");
28457 self.write("(");
28458 self.generate_expression(&e.this)?;
28459 if let Some(path) = &e.path {
28460 self.write(", ");
28461 self.generate_expression(path)?;
28462 }
28463 self.write(")");
28464 Ok(())
28465 }
28466
28467 fn generate_jsonb_extract_scalar(&mut self, e: &JSONBExtractScalar) -> Result<()> {
28468 self.write_keyword("JSONB_EXTRACT_SCALAR");
28470 self.write("(");
28471 self.generate_expression(&e.this)?;
28472 self.write(", ");
28473 self.generate_expression(&e.expression)?;
28474 self.write(")");
28475 Ok(())
28476 }
28477
28478 fn generate_jsonb_object_agg(&mut self, e: &JSONBObjectAgg) -> Result<()> {
28479 self.write_keyword("JSONB_OBJECT_AGG");
28481 self.write("(");
28482 self.generate_expression(&e.this)?;
28483 self.write(", ");
28484 self.generate_expression(&e.expression)?;
28485 self.write(")");
28486 Ok(())
28487 }
28488
28489 fn generate_json_column_def(&mut self, e: &JSONColumnDef) -> Result<()> {
28490 if let Some(nested_schema) = &e.nested_schema {
28492 self.write_keyword("NESTED");
28493 if let Some(path) = &e.path {
28494 self.write_space();
28495 self.write_keyword("PATH");
28496 self.write_space();
28497 self.generate_expression(path)?;
28498 }
28499 self.write_space();
28500 self.generate_expression(nested_schema)?;
28501 } else {
28502 if let Some(this) = &e.this {
28503 self.generate_expression(this)?;
28504 }
28505 if let Some(kind) = &e.kind {
28506 self.write_space();
28507 self.write(kind);
28508 }
28509 if let Some(path) = &e.path {
28510 self.write_space();
28511 self.write_keyword("PATH");
28512 self.write_space();
28513 self.generate_expression(path)?;
28514 }
28515 if e.ordinality.is_some() {
28516 self.write_keyword(" FOR ORDINALITY");
28517 }
28518 }
28519 Ok(())
28520 }
28521
28522 fn generate_json_exists(&mut self, e: &JSONExists) -> Result<()> {
28523 self.write_keyword("JSON_EXISTS");
28525 self.write("(");
28526 self.generate_expression(&e.this)?;
28527 if let Some(path) = &e.path {
28528 self.write(", ");
28529 self.generate_expression(path)?;
28530 }
28531 if let Some(passing) = &e.passing {
28532 self.write_space();
28533 self.write_keyword("PASSING");
28534 self.write_space();
28535 self.generate_expression(passing)?;
28536 }
28537 if let Some(on_condition) = &e.on_condition {
28538 self.write_space();
28539 self.generate_expression(on_condition)?;
28540 }
28541 self.write(")");
28542 Ok(())
28543 }
28544
28545 fn generate_json_cast(&mut self, e: &JSONCast) -> Result<()> {
28546 self.generate_expression(&e.this)?;
28547 self.write(".:");
28548 self.generate_data_type(&e.to)?;
28549 Ok(())
28550 }
28551
28552 fn generate_json_extract_array(&mut self, e: &JSONExtractArray) -> Result<()> {
28553 self.write_keyword("JSON_EXTRACT_ARRAY");
28555 self.write("(");
28556 self.generate_expression(&e.this)?;
28557 if let Some(expr) = &e.expression {
28558 self.write(", ");
28559 self.generate_expression(expr)?;
28560 }
28561 self.write(")");
28562 Ok(())
28563 }
28564
28565 fn generate_json_extract_quote(&mut self, e: &JSONExtractQuote) -> Result<()> {
28566 if let Some(option) = &e.option {
28568 self.generate_expression(option)?;
28569 self.write_space();
28570 }
28571 self.write_keyword("QUOTES");
28572 if e.scalar.is_some() {
28573 self.write_keyword(" SCALAR_ONLY");
28574 }
28575 Ok(())
28576 }
28577
28578 fn generate_json_extract_scalar(&mut self, e: &JSONExtractScalar) -> Result<()> {
28579 self.write_keyword("JSON_EXTRACT_SCALAR");
28581 self.write("(");
28582 self.generate_expression(&e.this)?;
28583 self.write(", ");
28584 self.generate_expression(&e.expression)?;
28585 self.write(")");
28586 Ok(())
28587 }
28588
28589 fn generate_json_extract_path(&mut self, e: &JSONExtract) -> Result<()> {
28590 if e.variant_extract.is_some() {
28594 use crate::dialects::DialectType;
28595 if matches!(self.config.dialect, Some(DialectType::Databricks)) {
28596 self.generate_expression(&e.this)?;
28598 self.write(":");
28599 match e.expression.as_ref() {
28602 Expression::Literal(Literal::String(s)) => {
28603 self.write(s);
28604 }
28605 _ => {
28606 self.generate_expression(&e.expression)?;
28608 }
28609 }
28610 } else {
28611 self.write_keyword("GET_PATH");
28613 self.write("(");
28614 self.generate_expression(&e.this)?;
28615 self.write(", ");
28616 self.generate_expression(&e.expression)?;
28617 self.write(")");
28618 }
28619 } else {
28620 self.write_keyword("JSON_EXTRACT");
28621 self.write("(");
28622 self.generate_expression(&e.this)?;
28623 self.write(", ");
28624 self.generate_expression(&e.expression)?;
28625 for expr in &e.expressions {
28626 self.write(", ");
28627 self.generate_expression(expr)?;
28628 }
28629 self.write(")");
28630 }
28631 Ok(())
28632 }
28633
28634 fn generate_json_format(&mut self, e: &JSONFormat) -> Result<()> {
28635 if let Some(this) = &e.this {
28638 self.generate_expression(this)?;
28639 self.write_space();
28640 }
28641 self.write_keyword("FORMAT JSON");
28642 Ok(())
28643 }
28644
28645 fn generate_json_key_value(&mut self, e: &JSONKeyValue) -> Result<()> {
28646 self.generate_expression(&e.this)?;
28648 self.write(": ");
28649 self.generate_expression(&e.expression)?;
28650 Ok(())
28651 }
28652
28653 fn generate_json_keys(&mut self, e: &JSONKeys) -> Result<()> {
28654 self.write_keyword("JSON_KEYS");
28656 self.write("(");
28657 self.generate_expression(&e.this)?;
28658 if let Some(expr) = &e.expression {
28659 self.write(", ");
28660 self.generate_expression(expr)?;
28661 }
28662 for expr in &e.expressions {
28663 self.write(", ");
28664 self.generate_expression(expr)?;
28665 }
28666 self.write(")");
28667 Ok(())
28668 }
28669
28670 fn generate_json_keys_at_depth(&mut self, e: &JSONKeysAtDepth) -> Result<()> {
28671 self.write_keyword("JSON_KEYS");
28673 self.write("(");
28674 self.generate_expression(&e.this)?;
28675 if let Some(expr) = &e.expression {
28676 self.write(", ");
28677 self.generate_expression(expr)?;
28678 }
28679 self.write(")");
28680 Ok(())
28681 }
28682
28683 fn generate_json_path_expr(&mut self, e: &JSONPath) -> Result<()> {
28684 let mut path_str = String::new();
28687 for expr in &e.expressions {
28688 match expr {
28689 Expression::JSONPathRoot(_) => {
28690 path_str.push('$');
28691 }
28692 Expression::JSONPathKey(k) => {
28693 if let Expression::Literal(crate::expressions::Literal::String(s)) =
28695 k.this.as_ref()
28696 {
28697 path_str.push('.');
28698 let needs_quoting = s.chars().any(|c| !c.is_alphanumeric() && c != '_');
28700 if needs_quoting {
28701 path_str.push('"');
28702 path_str.push_str(s);
28703 path_str.push('"');
28704 } else {
28705 path_str.push_str(s);
28706 }
28707 }
28708 }
28709 Expression::JSONPathSubscript(s) => {
28710 if let Expression::Literal(crate::expressions::Literal::Number(n)) =
28712 s.this.as_ref()
28713 {
28714 path_str.push('[');
28715 path_str.push_str(n);
28716 path_str.push(']');
28717 }
28718 }
28719 _ => {
28720 let mut temp_gen = Self::with_config(self.config.clone());
28722 temp_gen.generate_expression(expr)?;
28723 path_str.push_str(&temp_gen.output);
28724 }
28725 }
28726 }
28727 self.write("'");
28729 self.write(&path_str);
28730 self.write("'");
28731 Ok(())
28732 }
28733
28734 fn generate_json_path_filter(&mut self, e: &JSONPathFilter) -> Result<()> {
28735 self.write("?(");
28737 self.generate_expression(&e.this)?;
28738 self.write(")");
28739 Ok(())
28740 }
28741
28742 fn generate_json_path_key(&mut self, e: &JSONPathKey) -> Result<()> {
28743 self.write(".");
28745 self.generate_expression(&e.this)?;
28746 Ok(())
28747 }
28748
28749 fn generate_json_path_recursive(&mut self, e: &JSONPathRecursive) -> Result<()> {
28750 self.write("..");
28752 if let Some(this) = &e.this {
28753 self.generate_expression(this)?;
28754 }
28755 Ok(())
28756 }
28757
28758 fn generate_json_path_root(&mut self) -> Result<()> {
28759 self.write("$");
28761 Ok(())
28762 }
28763
28764 fn generate_json_path_script(&mut self, e: &JSONPathScript) -> Result<()> {
28765 self.write("(");
28767 self.generate_expression(&e.this)?;
28768 self.write(")");
28769 Ok(())
28770 }
28771
28772 fn generate_json_path_selector(&mut self, e: &JSONPathSelector) -> Result<()> {
28773 self.generate_expression(&e.this)?;
28775 Ok(())
28776 }
28777
28778 fn generate_json_path_slice(&mut self, e: &JSONPathSlice) -> Result<()> {
28779 self.write("[");
28781 if let Some(start) = &e.start {
28782 self.generate_expression(start)?;
28783 }
28784 self.write(":");
28785 if let Some(end) = &e.end {
28786 self.generate_expression(end)?;
28787 }
28788 if let Some(step) = &e.step {
28789 self.write(":");
28790 self.generate_expression(step)?;
28791 }
28792 self.write("]");
28793 Ok(())
28794 }
28795
28796 fn generate_json_path_subscript(&mut self, e: &JSONPathSubscript) -> Result<()> {
28797 self.write("[");
28799 self.generate_expression(&e.this)?;
28800 self.write("]");
28801 Ok(())
28802 }
28803
28804 fn generate_json_path_union(&mut self, e: &JSONPathUnion) -> Result<()> {
28805 self.write("[");
28807 for (i, expr) in e.expressions.iter().enumerate() {
28808 if i > 0 {
28809 self.write(", ");
28810 }
28811 self.generate_expression(expr)?;
28812 }
28813 self.write("]");
28814 Ok(())
28815 }
28816
28817 fn generate_json_remove(&mut self, e: &JSONRemove) -> Result<()> {
28818 self.write_keyword("JSON_REMOVE");
28820 self.write("(");
28821 self.generate_expression(&e.this)?;
28822 for expr in &e.expressions {
28823 self.write(", ");
28824 self.generate_expression(expr)?;
28825 }
28826 self.write(")");
28827 Ok(())
28828 }
28829
28830 fn generate_json_schema(&mut self, e: &JSONSchema) -> Result<()> {
28831 self.write_keyword("COLUMNS");
28834 self.write("(");
28835
28836 if self.config.pretty && !e.expressions.is_empty() {
28837 let mut expr_strings: Vec<String> = Vec::with_capacity(e.expressions.len());
28839 for expr in &e.expressions {
28840 let mut temp_gen = Generator::with_config(self.config.clone());
28841 temp_gen.generate_expression(expr)?;
28842 expr_strings.push(temp_gen.output);
28843 }
28844
28845 if self.too_wide(&expr_strings) {
28847 self.write_newline();
28849 self.indent_level += 1;
28850 for (i, expr_str) in expr_strings.iter().enumerate() {
28851 if i > 0 {
28852 self.write(",");
28853 self.write_newline();
28854 }
28855 self.write_indent();
28856 self.write(expr_str);
28857 }
28858 self.write_newline();
28859 self.indent_level -= 1;
28860 self.write_indent();
28861 } else {
28862 for (i, expr_str) in expr_strings.iter().enumerate() {
28864 if i > 0 {
28865 self.write(", ");
28866 }
28867 self.write(expr_str);
28868 }
28869 }
28870 } else {
28871 for (i, expr) in e.expressions.iter().enumerate() {
28873 if i > 0 {
28874 self.write(", ");
28875 }
28876 self.generate_expression(expr)?;
28877 }
28878 }
28879 self.write(")");
28880 Ok(())
28881 }
28882
28883 fn generate_json_set(&mut self, e: &JSONSet) -> Result<()> {
28884 self.write_keyword("JSON_SET");
28886 self.write("(");
28887 self.generate_expression(&e.this)?;
28888 for expr in &e.expressions {
28889 self.write(", ");
28890 self.generate_expression(expr)?;
28891 }
28892 self.write(")");
28893 Ok(())
28894 }
28895
28896 fn generate_json_strip_nulls(&mut self, e: &JSONStripNulls) -> Result<()> {
28897 self.write_keyword("JSON_STRIP_NULLS");
28899 self.write("(");
28900 self.generate_expression(&e.this)?;
28901 if let Some(expr) = &e.expression {
28902 self.write(", ");
28903 self.generate_expression(expr)?;
28904 }
28905 self.write(")");
28906 Ok(())
28907 }
28908
28909 fn generate_json_table(&mut self, e: &JSONTable) -> Result<()> {
28910 self.write_keyword("JSON_TABLE");
28912 self.write("(");
28913 self.generate_expression(&e.this)?;
28914 if let Some(path) = &e.path {
28915 self.write(", ");
28916 self.generate_expression(path)?;
28917 }
28918 if let Some(error_handling) = &e.error_handling {
28919 self.write_space();
28920 self.generate_expression(error_handling)?;
28921 }
28922 if let Some(empty_handling) = &e.empty_handling {
28923 self.write_space();
28924 self.generate_expression(empty_handling)?;
28925 }
28926 if let Some(schema) = &e.schema {
28927 self.write_space();
28928 self.generate_expression(schema)?;
28929 }
28930 self.write(")");
28931 Ok(())
28932 }
28933
28934 fn generate_json_type(&mut self, e: &JSONType) -> Result<()> {
28935 self.write_keyword("JSON_TYPE");
28937 self.write("(");
28938 self.generate_expression(&e.this)?;
28939 self.write(")");
28940 Ok(())
28941 }
28942
28943 fn generate_json_value(&mut self, e: &JSONValue) -> Result<()> {
28944 self.write_keyword("JSON_VALUE");
28946 self.write("(");
28947 self.generate_expression(&e.this)?;
28948 if let Some(path) = &e.path {
28949 self.write(", ");
28950 self.generate_expression(path)?;
28951 }
28952 if let Some(returning) = &e.returning {
28953 self.write_space();
28954 self.write_keyword("RETURNING");
28955 self.write_space();
28956 self.generate_expression(returning)?;
28957 }
28958 if let Some(on_condition) = &e.on_condition {
28959 self.write_space();
28960 self.generate_expression(on_condition)?;
28961 }
28962 self.write(")");
28963 Ok(())
28964 }
28965
28966 fn generate_json_value_array(&mut self, e: &JSONValueArray) -> Result<()> {
28967 self.write_keyword("JSON_VALUE_ARRAY");
28969 self.write("(");
28970 self.generate_expression(&e.this)?;
28971 self.write(")");
28972 Ok(())
28973 }
28974
28975 fn generate_jarowinkler_similarity(&mut self, e: &JarowinklerSimilarity) -> Result<()> {
28976 self.write_keyword("JAROWINKLER_SIMILARITY");
28978 self.write("(");
28979 self.generate_expression(&e.this)?;
28980 self.write(", ");
28981 self.generate_expression(&e.expression)?;
28982 self.write(")");
28983 Ok(())
28984 }
28985
28986 fn generate_join_hint(&mut self, e: &JoinHint) -> Result<()> {
28987 self.generate_expression(&e.this)?;
28989 self.write("(");
28990 for (i, expr) in e.expressions.iter().enumerate() {
28991 if i > 0 {
28992 self.write(", ");
28993 }
28994 self.generate_expression(expr)?;
28995 }
28996 self.write(")");
28997 Ok(())
28998 }
28999
29000 fn generate_journal_property(&mut self, e: &JournalProperty) -> Result<()> {
29001 if e.no.is_some() {
29003 self.write_keyword("NO ");
29004 }
29005 if let Some(local) = &e.local {
29006 self.generate_expression(local)?;
29007 self.write_space();
29008 }
29009 if e.dual.is_some() {
29010 self.write_keyword("DUAL ");
29011 }
29012 if e.before.is_some() {
29013 self.write_keyword("BEFORE ");
29014 }
29015 if e.after.is_some() {
29016 self.write_keyword("AFTER ");
29017 }
29018 self.write_keyword("JOURNAL");
29019 Ok(())
29020 }
29021
29022 fn generate_language_property(&mut self, e: &LanguageProperty) -> Result<()> {
29023 self.write_keyword("LANGUAGE");
29025 self.write_space();
29026 self.generate_expression(&e.this)?;
29027 Ok(())
29028 }
29029
29030 fn generate_lateral(&mut self, e: &Lateral) -> Result<()> {
29031 if e.view.is_some() {
29033 self.write_keyword("LATERAL VIEW");
29035 if e.outer.is_some() {
29036 self.write_space();
29037 self.write_keyword("OUTER");
29038 }
29039 self.write_space();
29040 self.generate_expression(&e.this)?;
29041 if let Some(alias) = &e.alias {
29042 self.write_space();
29043 self.write(alias);
29044 }
29045 } else {
29046 self.write_keyword("LATERAL");
29048 self.write_space();
29049 self.generate_expression(&e.this)?;
29050 if e.ordinality.is_some() {
29051 self.write_space();
29052 self.write_keyword("WITH ORDINALITY");
29053 }
29054 if let Some(alias) = &e.alias {
29055 self.write_space();
29056 self.write_keyword("AS");
29057 self.write_space();
29058 self.write(alias);
29059 if !e.column_aliases.is_empty() {
29060 self.write("(");
29061 for (i, col) in e.column_aliases.iter().enumerate() {
29062 if i > 0 {
29063 self.write(", ");
29064 }
29065 self.write(col);
29066 }
29067 self.write(")");
29068 }
29069 }
29070 }
29071 Ok(())
29072 }
29073
29074 fn generate_like_property(&mut self, e: &LikeProperty) -> Result<()> {
29075 self.write_keyword("LIKE");
29077 self.write_space();
29078 self.generate_expression(&e.this)?;
29079 for expr in &e.expressions {
29080 self.write_space();
29081 self.generate_expression(expr)?;
29082 }
29083 Ok(())
29084 }
29085
29086 fn generate_limit(&mut self, e: &Limit) -> Result<()> {
29087 self.write_keyword("LIMIT");
29088 self.write_space();
29089 self.write_limit_expr(&e.this)?;
29090 if e.percent {
29091 self.write_space();
29092 self.write_keyword("PERCENT");
29093 }
29094 for comment in &e.comments {
29096 self.write(" ");
29097 self.write_formatted_comment(comment);
29098 }
29099 Ok(())
29100 }
29101
29102 fn generate_limit_options(&mut self, e: &LimitOptions) -> Result<()> {
29103 if e.percent.is_some() {
29105 self.write_keyword(" PERCENT");
29106 }
29107 if e.rows.is_some() {
29108 self.write_keyword(" ROWS");
29109 }
29110 if e.with_ties.is_some() {
29111 self.write_keyword(" WITH TIES");
29112 } else if e.rows.is_some() {
29113 self.write_keyword(" ONLY");
29114 }
29115 Ok(())
29116 }
29117
29118 fn generate_list(&mut self, e: &List) -> Result<()> {
29119 use crate::dialects::DialectType;
29120 let is_materialize = matches!(self.config.dialect, Some(DialectType::Materialize));
29121
29122 if e.expressions.len() == 1 {
29124 if let Expression::Select(_) = &e.expressions[0] {
29125 self.write_keyword("LIST");
29126 self.write("(");
29127 self.generate_expression(&e.expressions[0])?;
29128 self.write(")");
29129 return Ok(());
29130 }
29131 }
29132
29133 if is_materialize {
29135 self.write_keyword("LIST");
29136 self.write("[");
29137 for (i, expr) in e.expressions.iter().enumerate() {
29138 if i > 0 {
29139 self.write(", ");
29140 }
29141 self.generate_expression(expr)?;
29142 }
29143 self.write("]");
29144 } else {
29145 self.write_keyword("LIST");
29147 self.write("(");
29148 for (i, expr) in e.expressions.iter().enumerate() {
29149 if i > 0 {
29150 self.write(", ");
29151 }
29152 self.generate_expression(expr)?;
29153 }
29154 self.write(")");
29155 }
29156 Ok(())
29157 }
29158
29159 fn generate_tomap(&mut self, e: &ToMap) -> Result<()> {
29160 if let Expression::Select(_) = &*e.this {
29162 self.write_keyword("MAP");
29163 self.write("(");
29164 self.generate_expression(&e.this)?;
29165 self.write(")");
29166 return Ok(());
29167 }
29168
29169 let is_duckdb = matches!(self.config.dialect, Some(DialectType::DuckDB));
29170
29171 self.write_keyword("MAP");
29173 if is_duckdb {
29174 self.write(" {");
29175 } else {
29176 self.write("[");
29177 }
29178 if let Expression::Struct(s) = &*e.this {
29179 for (i, (_, expr)) in s.fields.iter().enumerate() {
29180 if i > 0 {
29181 self.write(", ");
29182 }
29183 if let Expression::PropertyEQ(op) = expr {
29184 self.generate_expression(&op.left)?;
29185 if is_duckdb {
29186 self.write(": ");
29187 } else {
29188 self.write(" => ");
29189 }
29190 self.generate_expression(&op.right)?;
29191 } else {
29192 self.generate_expression(expr)?;
29193 }
29194 }
29195 }
29196 if is_duckdb {
29197 self.write("}");
29198 } else {
29199 self.write("]");
29200 }
29201 Ok(())
29202 }
29203
29204 fn generate_localtime(&mut self, e: &Localtime) -> Result<()> {
29205 self.write_keyword("LOCALTIME");
29207 if let Some(precision) = &e.this {
29208 self.write("(");
29209 self.generate_expression(precision)?;
29210 self.write(")");
29211 }
29212 Ok(())
29213 }
29214
29215 fn generate_localtimestamp(&mut self, e: &Localtimestamp) -> Result<()> {
29216 self.write_keyword("LOCALTIMESTAMP");
29218 if let Some(precision) = &e.this {
29219 self.write("(");
29220 self.generate_expression(precision)?;
29221 self.write(")");
29222 }
29223 Ok(())
29224 }
29225
29226 fn generate_location_property(&mut self, e: &LocationProperty) -> Result<()> {
29227 self.write_keyword("LOCATION");
29229 self.write_space();
29230 self.generate_expression(&e.this)?;
29231 Ok(())
29232 }
29233
29234 fn generate_lock(&mut self, e: &Lock) -> Result<()> {
29235 if e.update.is_some() {
29237 if e.key.is_some() {
29238 self.write_keyword("FOR NO KEY UPDATE");
29239 } else {
29240 self.write_keyword("FOR UPDATE");
29241 }
29242 } else {
29243 if e.key.is_some() {
29244 self.write_keyword("FOR KEY SHARE");
29245 } else {
29246 self.write_keyword("FOR SHARE");
29247 }
29248 }
29249 if !e.expressions.is_empty() {
29250 self.write_keyword(" OF ");
29251 for (i, expr) in e.expressions.iter().enumerate() {
29252 if i > 0 {
29253 self.write(", ");
29254 }
29255 self.generate_expression(expr)?;
29256 }
29257 }
29258 if let Some(wait) = &e.wait {
29263 match wait.as_ref() {
29264 Expression::Boolean(b) => {
29265 if b.value {
29266 self.write_keyword(" NOWAIT");
29267 } else {
29268 self.write_keyword(" SKIP LOCKED");
29269 }
29270 }
29271 _ => {
29272 self.write_keyword(" WAIT ");
29274 self.generate_expression(wait)?;
29275 }
29276 }
29277 }
29278 Ok(())
29279 }
29280
29281 fn generate_lock_property(&mut self, e: &LockProperty) -> Result<()> {
29282 self.write_keyword("LOCK");
29284 self.write_space();
29285 self.generate_expression(&e.this)?;
29286 Ok(())
29287 }
29288
29289 fn generate_locking_property(&mut self, e: &LockingProperty) -> Result<()> {
29290 self.write_keyword("LOCKING");
29292 self.write_space();
29293 self.write(&e.kind);
29294 if let Some(this) = &e.this {
29295 self.write_space();
29296 self.generate_expression(this)?;
29297 }
29298 if let Some(for_or_in) = &e.for_or_in {
29299 self.write_space();
29300 self.generate_expression(for_or_in)?;
29301 }
29302 if let Some(lock_type) = &e.lock_type {
29303 self.write_space();
29304 self.generate_expression(lock_type)?;
29305 }
29306 if e.override_.is_some() {
29307 self.write_keyword(" OVERRIDE");
29308 }
29309 Ok(())
29310 }
29311
29312 fn generate_locking_statement(&mut self, e: &LockingStatement) -> Result<()> {
29313 self.generate_expression(&e.this)?;
29315 self.write_space();
29316 self.generate_expression(&e.expression)?;
29317 Ok(())
29318 }
29319
29320 fn generate_log_property(&mut self, e: &LogProperty) -> Result<()> {
29321 if e.no.is_some() {
29323 self.write_keyword("NO ");
29324 }
29325 self.write_keyword("LOG");
29326 Ok(())
29327 }
29328
29329 fn generate_md5_digest(&mut self, e: &MD5Digest) -> Result<()> {
29330 self.write_keyword("MD5");
29332 self.write("(");
29333 self.generate_expression(&e.this)?;
29334 for expr in &e.expressions {
29335 self.write(", ");
29336 self.generate_expression(expr)?;
29337 }
29338 self.write(")");
29339 Ok(())
29340 }
29341
29342 fn generate_ml_forecast(&mut self, e: &MLForecast) -> Result<()> {
29343 self.write_keyword("ML.FORECAST");
29345 self.write("(");
29346 self.generate_expression(&e.this)?;
29347 if let Some(expression) = &e.expression {
29348 self.write(", ");
29349 self.generate_expression(expression)?;
29350 }
29351 if let Some(params) = &e.params_struct {
29352 self.write(", ");
29353 self.generate_expression(params)?;
29354 }
29355 self.write(")");
29356 Ok(())
29357 }
29358
29359 fn generate_ml_translate(&mut self, e: &MLTranslate) -> Result<()> {
29360 self.write_keyword("ML.TRANSLATE");
29362 self.write("(");
29363 self.generate_expression(&e.this)?;
29364 self.write(", ");
29365 self.generate_expression(&e.expression)?;
29366 if let Some(params) = &e.params_struct {
29367 self.write(", ");
29368 self.generate_expression(params)?;
29369 }
29370 self.write(")");
29371 Ok(())
29372 }
29373
29374 fn generate_make_interval(&mut self, e: &MakeInterval) -> Result<()> {
29375 self.write_keyword("MAKE_INTERVAL");
29377 self.write("(");
29378 let mut first = true;
29379 if let Some(year) = &e.year {
29380 self.write("years => ");
29381 self.generate_expression(year)?;
29382 first = false;
29383 }
29384 if let Some(month) = &e.month {
29385 if !first {
29386 self.write(", ");
29387 }
29388 self.write("months => ");
29389 self.generate_expression(month)?;
29390 first = false;
29391 }
29392 if let Some(week) = &e.week {
29393 if !first {
29394 self.write(", ");
29395 }
29396 self.write("weeks => ");
29397 self.generate_expression(week)?;
29398 first = false;
29399 }
29400 if let Some(day) = &e.day {
29401 if !first {
29402 self.write(", ");
29403 }
29404 self.write("days => ");
29405 self.generate_expression(day)?;
29406 first = false;
29407 }
29408 if let Some(hour) = &e.hour {
29409 if !first {
29410 self.write(", ");
29411 }
29412 self.write("hours => ");
29413 self.generate_expression(hour)?;
29414 first = false;
29415 }
29416 if let Some(minute) = &e.minute {
29417 if !first {
29418 self.write(", ");
29419 }
29420 self.write("mins => ");
29421 self.generate_expression(minute)?;
29422 first = false;
29423 }
29424 if let Some(second) = &e.second {
29425 if !first {
29426 self.write(", ");
29427 }
29428 self.write("secs => ");
29429 self.generate_expression(second)?;
29430 }
29431 self.write(")");
29432 Ok(())
29433 }
29434
29435 fn generate_manhattan_distance(&mut self, e: &ManhattanDistance) -> Result<()> {
29436 self.write_keyword("MANHATTAN_DISTANCE");
29438 self.write("(");
29439 self.generate_expression(&e.this)?;
29440 self.write(", ");
29441 self.generate_expression(&e.expression)?;
29442 self.write(")");
29443 Ok(())
29444 }
29445
29446 fn generate_map(&mut self, e: &Map) -> Result<()> {
29447 self.write_keyword("MAP");
29449 self.write("(");
29450 for (i, (key, value)) in e.keys.iter().zip(e.values.iter()).enumerate() {
29451 if i > 0 {
29452 self.write(", ");
29453 }
29454 self.generate_expression(key)?;
29455 self.write(", ");
29456 self.generate_expression(value)?;
29457 }
29458 self.write(")");
29459 Ok(())
29460 }
29461
29462 fn generate_map_cat(&mut self, e: &MapCat) -> Result<()> {
29463 self.write_keyword("MAP_CAT");
29465 self.write("(");
29466 self.generate_expression(&e.this)?;
29467 self.write(", ");
29468 self.generate_expression(&e.expression)?;
29469 self.write(")");
29470 Ok(())
29471 }
29472
29473 fn generate_map_delete(&mut self, e: &MapDelete) -> Result<()> {
29474 self.write_keyword("MAP_DELETE");
29476 self.write("(");
29477 self.generate_expression(&e.this)?;
29478 for expr in &e.expressions {
29479 self.write(", ");
29480 self.generate_expression(expr)?;
29481 }
29482 self.write(")");
29483 Ok(())
29484 }
29485
29486 fn generate_map_insert(&mut self, e: &MapInsert) -> Result<()> {
29487 self.write_keyword("MAP_INSERT");
29489 self.write("(");
29490 self.generate_expression(&e.this)?;
29491 if let Some(key) = &e.key {
29492 self.write(", ");
29493 self.generate_expression(key)?;
29494 }
29495 if let Some(value) = &e.value {
29496 self.write(", ");
29497 self.generate_expression(value)?;
29498 }
29499 if let Some(update_flag) = &e.update_flag {
29500 self.write(", ");
29501 self.generate_expression(update_flag)?;
29502 }
29503 self.write(")");
29504 Ok(())
29505 }
29506
29507 fn generate_map_pick(&mut self, e: &MapPick) -> Result<()> {
29508 self.write_keyword("MAP_PICK");
29510 self.write("(");
29511 self.generate_expression(&e.this)?;
29512 for expr in &e.expressions {
29513 self.write(", ");
29514 self.generate_expression(expr)?;
29515 }
29516 self.write(")");
29517 Ok(())
29518 }
29519
29520 fn generate_masking_policy_column_constraint(
29521 &mut self,
29522 e: &MaskingPolicyColumnConstraint,
29523 ) -> Result<()> {
29524 self.write_keyword("MASKING POLICY");
29526 self.write_space();
29527 self.generate_expression(&e.this)?;
29528 if !e.expressions.is_empty() {
29529 self.write_keyword(" USING");
29530 self.write(" (");
29531 for (i, expr) in e.expressions.iter().enumerate() {
29532 if i > 0 {
29533 self.write(", ");
29534 }
29535 self.generate_expression(expr)?;
29536 }
29537 self.write(")");
29538 }
29539 Ok(())
29540 }
29541
29542 fn generate_match_against(&mut self, e: &MatchAgainst) -> Result<()> {
29543 if matches!(
29544 self.config.dialect,
29545 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
29546 ) {
29547 if e.expressions.len() > 1 {
29548 self.write("(");
29549 }
29550 for (i, expr) in e.expressions.iter().enumerate() {
29551 if i > 0 {
29552 self.write_keyword(" OR ");
29553 }
29554 self.generate_expression(expr)?;
29555 self.write_space();
29556 self.write("@@");
29557 self.write_space();
29558 self.generate_expression(&e.this)?;
29559 }
29560 if e.expressions.len() > 1 {
29561 self.write(")");
29562 }
29563 return Ok(());
29564 }
29565
29566 self.write_keyword("MATCH");
29568 self.write("(");
29569 for (i, expr) in e.expressions.iter().enumerate() {
29570 if i > 0 {
29571 self.write(", ");
29572 }
29573 self.generate_expression(expr)?;
29574 }
29575 self.write(")");
29576 self.write_keyword(" AGAINST");
29577 self.write("(");
29578 self.generate_expression(&e.this)?;
29579 if let Some(modifier) = &e.modifier {
29580 self.write_space();
29581 self.generate_expression(modifier)?;
29582 }
29583 self.write(")");
29584 Ok(())
29585 }
29586
29587 fn generate_match_recognize_measure(&mut self, e: &MatchRecognizeMeasure) -> Result<()> {
29588 if let Some(window_frame) = &e.window_frame {
29590 self.write(&format!("{:?}", window_frame).to_uppercase());
29591 self.write_space();
29592 }
29593 self.generate_expression(&e.this)?;
29594 Ok(())
29595 }
29596
29597 fn generate_materialized_property(&mut self, e: &MaterializedProperty) -> Result<()> {
29598 self.write_keyword("MATERIALIZED");
29600 if let Some(this) = &e.this {
29601 self.write_space();
29602 self.generate_expression(this)?;
29603 }
29604 Ok(())
29605 }
29606
29607 fn generate_merge(&mut self, e: &Merge) -> Result<()> {
29608 if let Some(with_) = &e.with_ {
29611 self.generate_expression(with_)?;
29612 self.write_space();
29613 }
29614 self.write_keyword("MERGE INTO");
29615 self.write_space();
29616 self.generate_expression(&e.this)?;
29617
29618 if self.config.pretty {
29620 self.write_newline();
29621 self.write_indent();
29622 } else {
29623 self.write_space();
29624 }
29625 self.write_keyword("USING");
29626 self.write_space();
29627 self.generate_expression(&e.using)?;
29628
29629 if let Some(on) = &e.on {
29631 if self.config.pretty {
29632 self.write_newline();
29633 self.write_indent();
29634 } else {
29635 self.write_space();
29636 }
29637 self.write_keyword("ON");
29638 self.write_space();
29639 self.generate_expression(on)?;
29640 }
29641 if let Some(using_cond) = &e.using_cond {
29643 self.write_space();
29644 self.write_keyword("USING");
29645 self.write_space();
29646 self.write("(");
29647 if let Expression::Tuple(tuple) = using_cond.as_ref() {
29649 for (i, col) in tuple.expressions.iter().enumerate() {
29650 if i > 0 {
29651 self.write(", ");
29652 }
29653 self.generate_expression(col)?;
29654 }
29655 } else {
29656 self.generate_expression(using_cond)?;
29657 }
29658 self.write(")");
29659 }
29660 let saved_merge_strip = std::mem::take(&mut self.merge_strip_qualifiers);
29662 if matches!(
29663 self.config.dialect,
29664 Some(crate::DialectType::PostgreSQL)
29665 | Some(crate::DialectType::Redshift)
29666 | Some(crate::DialectType::Trino)
29667 | Some(crate::DialectType::Presto)
29668 | Some(crate::DialectType::Athena)
29669 ) {
29670 let mut names = Vec::new();
29671 match e.this.as_ref() {
29672 Expression::Alias(a) => {
29673 if let Expression::Table(t) = &a.this {
29675 names.push(t.name.name.clone());
29676 } else if let Expression::Identifier(id) = &a.this {
29677 names.push(id.name.clone());
29678 }
29679 names.push(a.alias.name.clone());
29680 }
29681 Expression::Table(t) => {
29682 names.push(t.name.name.clone());
29683 }
29684 Expression::Identifier(id) => {
29685 names.push(id.name.clone());
29686 }
29687 _ => {}
29688 }
29689 self.merge_strip_qualifiers = names;
29690 }
29691
29692 if let Some(whens) = &e.whens {
29694 if self.config.pretty {
29695 self.write_newline();
29696 self.write_indent();
29697 } else {
29698 self.write_space();
29699 }
29700 self.generate_expression(whens)?;
29701 }
29702
29703 self.merge_strip_qualifiers = saved_merge_strip;
29705
29706 if let Some(returning) = &e.returning {
29708 if self.config.pretty {
29709 self.write_newline();
29710 self.write_indent();
29711 } else {
29712 self.write_space();
29713 }
29714 self.generate_expression(returning)?;
29715 }
29716 Ok(())
29717 }
29718
29719 fn generate_merge_block_ratio_property(&mut self, e: &MergeBlockRatioProperty) -> Result<()> {
29720 if e.no.is_some() {
29722 self.write_keyword("NO MERGEBLOCKRATIO");
29723 } else if e.default.is_some() {
29724 self.write_keyword("DEFAULT MERGEBLOCKRATIO");
29725 } else {
29726 self.write_keyword("MERGEBLOCKRATIO");
29727 self.write("=");
29728 if let Some(this) = &e.this {
29729 self.generate_expression(this)?;
29730 }
29731 if e.percent.is_some() {
29732 self.write_keyword(" PERCENT");
29733 }
29734 }
29735 Ok(())
29736 }
29737
29738 fn generate_merge_tree_ttl(&mut self, e: &MergeTreeTTL) -> Result<()> {
29739 self.write_keyword("TTL");
29741 let pretty_clickhouse = self.config.pretty
29742 && matches!(
29743 self.config.dialect,
29744 Some(crate::dialects::DialectType::ClickHouse)
29745 );
29746
29747 if pretty_clickhouse {
29748 self.write_newline();
29749 self.indent_level += 1;
29750 for (i, expr) in e.expressions.iter().enumerate() {
29751 if i > 0 {
29752 self.write(",");
29753 self.write_newline();
29754 }
29755 self.write_indent();
29756 self.generate_expression(expr)?;
29757 }
29758 self.indent_level -= 1;
29759 } else {
29760 self.write_space();
29761 for (i, expr) in e.expressions.iter().enumerate() {
29762 if i > 0 {
29763 self.write(", ");
29764 }
29765 self.generate_expression(expr)?;
29766 }
29767 }
29768
29769 if let Some(where_) = &e.where_ {
29770 if pretty_clickhouse {
29771 self.write_newline();
29772 if let Expression::Where(w) = where_.as_ref() {
29773 self.write_indent();
29774 self.write_keyword("WHERE");
29775 self.write_newline();
29776 self.indent_level += 1;
29777 self.write_indent();
29778 self.generate_expression(&w.this)?;
29779 self.indent_level -= 1;
29780 } else {
29781 self.write_indent();
29782 self.generate_expression(where_)?;
29783 }
29784 } else {
29785 self.write_space();
29786 self.generate_expression(where_)?;
29787 }
29788 }
29789 if let Some(group) = &e.group {
29790 if pretty_clickhouse {
29791 self.write_newline();
29792 if let Expression::Group(g) = group.as_ref() {
29793 self.write_indent();
29794 self.write_keyword("GROUP BY");
29795 self.write_newline();
29796 self.indent_level += 1;
29797 for (i, expr) in g.expressions.iter().enumerate() {
29798 if i > 0 {
29799 self.write(",");
29800 self.write_newline();
29801 }
29802 self.write_indent();
29803 self.generate_expression(expr)?;
29804 }
29805 self.indent_level -= 1;
29806 } else {
29807 self.write_indent();
29808 self.generate_expression(group)?;
29809 }
29810 } else {
29811 self.write_space();
29812 self.generate_expression(group)?;
29813 }
29814 }
29815 if let Some(aggregates) = &e.aggregates {
29816 if pretty_clickhouse {
29817 self.write_newline();
29818 self.write_indent();
29819 self.write_keyword("SET");
29820 self.write_newline();
29821 self.indent_level += 1;
29822 if let Expression::Tuple(t) = aggregates.as_ref() {
29823 for (i, agg) in t.expressions.iter().enumerate() {
29824 if i > 0 {
29825 self.write(",");
29826 self.write_newline();
29827 }
29828 self.write_indent();
29829 self.generate_expression(agg)?;
29830 }
29831 } else {
29832 self.write_indent();
29833 self.generate_expression(aggregates)?;
29834 }
29835 self.indent_level -= 1;
29836 } else {
29837 self.write_space();
29838 self.write_keyword("SET");
29839 self.write_space();
29840 self.generate_expression(aggregates)?;
29841 }
29842 }
29843 Ok(())
29844 }
29845
29846 fn generate_merge_tree_ttl_action(&mut self, e: &MergeTreeTTLAction) -> Result<()> {
29847 self.generate_expression(&e.this)?;
29849 if e.delete.is_some() {
29850 self.write_keyword(" DELETE");
29851 }
29852 if let Some(recompress) = &e.recompress {
29853 self.write_keyword(" RECOMPRESS ");
29854 self.generate_expression(recompress)?;
29855 }
29856 if let Some(to_disk) = &e.to_disk {
29857 self.write_keyword(" TO DISK ");
29858 self.generate_expression(to_disk)?;
29859 }
29860 if let Some(to_volume) = &e.to_volume {
29861 self.write_keyword(" TO VOLUME ");
29862 self.generate_expression(to_volume)?;
29863 }
29864 Ok(())
29865 }
29866
29867 fn generate_minhash(&mut self, e: &Minhash) -> Result<()> {
29868 self.write_keyword("MINHASH");
29870 self.write("(");
29871 self.generate_expression(&e.this)?;
29872 for expr in &e.expressions {
29873 self.write(", ");
29874 self.generate_expression(expr)?;
29875 }
29876 self.write(")");
29877 Ok(())
29878 }
29879
29880 fn generate_model_attribute(&mut self, e: &ModelAttribute) -> Result<()> {
29881 self.generate_expression(&e.this)?;
29883 self.write("!");
29884 self.generate_expression(&e.expression)?;
29885 Ok(())
29886 }
29887
29888 fn generate_monthname(&mut self, e: &Monthname) -> Result<()> {
29889 self.write_keyword("MONTHNAME");
29891 self.write("(");
29892 self.generate_expression(&e.this)?;
29893 self.write(")");
29894 Ok(())
29895 }
29896
29897 fn generate_multitable_inserts(&mut self, e: &MultitableInserts) -> Result<()> {
29898 for comment in &e.leading_comments {
29900 self.write_formatted_comment(comment);
29901 if self.config.pretty {
29902 self.write_newline();
29903 self.write_indent();
29904 } else {
29905 self.write_space();
29906 }
29907 }
29908 self.write_keyword("INSERT");
29910 self.write_space();
29911 self.write(&e.kind);
29912 if self.config.pretty {
29913 self.indent_level += 1;
29914 for expr in &e.expressions {
29915 self.write_newline();
29916 self.write_indent();
29917 self.generate_expression(expr)?;
29918 }
29919 self.indent_level -= 1;
29920 } else {
29921 for expr in &e.expressions {
29922 self.write_space();
29923 self.generate_expression(expr)?;
29924 }
29925 }
29926 if let Some(source) = &e.source {
29927 if self.config.pretty {
29928 self.write_newline();
29929 self.write_indent();
29930 } else {
29931 self.write_space();
29932 }
29933 self.generate_expression(source)?;
29934 }
29935 Ok(())
29936 }
29937
29938 fn generate_next_value_for(&mut self, e: &NextValueFor) -> Result<()> {
29939 self.write_keyword("NEXT VALUE FOR");
29941 self.write_space();
29942 self.generate_expression(&e.this)?;
29943 if let Some(order) = &e.order {
29944 self.write_space();
29945 self.write_keyword("OVER");
29946 self.write(" (");
29947 self.generate_expression(order)?;
29948 self.write(")");
29949 }
29950 Ok(())
29951 }
29952
29953 fn generate_normal(&mut self, e: &Normal) -> Result<()> {
29954 self.write_keyword("NORMAL");
29956 self.write("(");
29957 self.generate_expression(&e.this)?;
29958 if let Some(stddev) = &e.stddev {
29959 self.write(", ");
29960 self.generate_expression(stddev)?;
29961 }
29962 if let Some(gen) = &e.gen {
29963 self.write(", ");
29964 self.generate_expression(gen)?;
29965 }
29966 self.write(")");
29967 Ok(())
29968 }
29969
29970 fn generate_normalize(&mut self, e: &Normalize) -> Result<()> {
29971 if e.is_casefold.is_some() {
29973 self.write_keyword("NORMALIZE_AND_CASEFOLD");
29974 } else {
29975 self.write_keyword("NORMALIZE");
29976 }
29977 self.write("(");
29978 self.generate_expression(&e.this)?;
29979 if let Some(form) = &e.form {
29980 self.write(", ");
29981 self.generate_expression(form)?;
29982 }
29983 self.write(")");
29984 Ok(())
29985 }
29986
29987 fn generate_not_null_column_constraint(&mut self, e: &NotNullColumnConstraint) -> Result<()> {
29988 if e.allow_null.is_none() {
29990 self.write_keyword("NOT ");
29991 }
29992 self.write_keyword("NULL");
29993 Ok(())
29994 }
29995
29996 fn generate_nullif(&mut self, e: &Nullif) -> Result<()> {
29997 self.write_keyword("NULLIF");
29999 self.write("(");
30000 self.generate_expression(&e.this)?;
30001 self.write(", ");
30002 self.generate_expression(&e.expression)?;
30003 self.write(")");
30004 Ok(())
30005 }
30006
30007 fn generate_number_to_str(&mut self, e: &NumberToStr) -> Result<()> {
30008 self.write_keyword("FORMAT");
30010 self.write("(");
30011 self.generate_expression(&e.this)?;
30012 self.write(", '");
30013 self.write(&e.format);
30014 self.write("'");
30015 if let Some(culture) = &e.culture {
30016 self.write(", ");
30017 self.generate_expression(culture)?;
30018 }
30019 self.write(")");
30020 Ok(())
30021 }
30022
30023 fn generate_object_agg(&mut self, e: &ObjectAgg) -> Result<()> {
30024 self.write_keyword("OBJECT_AGG");
30026 self.write("(");
30027 self.generate_expression(&e.this)?;
30028 self.write(", ");
30029 self.generate_expression(&e.expression)?;
30030 self.write(")");
30031 Ok(())
30032 }
30033
30034 fn generate_object_identifier(&mut self, e: &ObjectIdentifier) -> Result<()> {
30035 self.generate_expression(&e.this)?;
30037 Ok(())
30038 }
30039
30040 fn generate_object_insert(&mut self, e: &ObjectInsert) -> Result<()> {
30041 self.write_keyword("OBJECT_INSERT");
30043 self.write("(");
30044 self.generate_expression(&e.this)?;
30045 if let Some(key) = &e.key {
30046 self.write(", ");
30047 self.generate_expression(key)?;
30048 }
30049 if let Some(value) = &e.value {
30050 self.write(", ");
30051 self.generate_expression(value)?;
30052 }
30053 if let Some(update_flag) = &e.update_flag {
30054 self.write(", ");
30055 self.generate_expression(update_flag)?;
30056 }
30057 self.write(")");
30058 Ok(())
30059 }
30060
30061 fn generate_offset(&mut self, e: &Offset) -> Result<()> {
30062 self.write_keyword("OFFSET");
30064 self.write_space();
30065 self.generate_expression(&e.this)?;
30066 if e.rows == Some(true)
30068 && matches!(
30069 self.config.dialect,
30070 Some(crate::dialects::DialectType::TSQL)
30071 | Some(crate::dialects::DialectType::Oracle)
30072 )
30073 {
30074 self.write_space();
30075 self.write_keyword("ROWS");
30076 }
30077 Ok(())
30078 }
30079
30080 fn generate_qualify(&mut self, e: &Qualify) -> Result<()> {
30081 self.write_keyword("QUALIFY");
30083 self.write_space();
30084 self.generate_expression(&e.this)?;
30085 Ok(())
30086 }
30087
30088 fn generate_on_cluster(&mut self, e: &OnCluster) -> Result<()> {
30089 self.write_keyword("ON CLUSTER");
30091 self.write_space();
30092 self.generate_expression(&e.this)?;
30093 Ok(())
30094 }
30095
30096 fn generate_on_commit_property(&mut self, e: &OnCommitProperty) -> Result<()> {
30097 self.write_keyword("ON COMMIT");
30099 if e.delete.is_some() {
30100 self.write_keyword(" DELETE ROWS");
30101 } else {
30102 self.write_keyword(" PRESERVE ROWS");
30103 }
30104 Ok(())
30105 }
30106
30107 fn generate_on_condition(&mut self, e: &OnCondition) -> Result<()> {
30108 if let Some(empty) = &e.empty {
30110 self.generate_expression(empty)?;
30111 self.write_keyword(" ON EMPTY");
30112 }
30113 if let Some(error) = &e.error {
30114 if e.empty.is_some() {
30115 self.write_space();
30116 }
30117 self.generate_expression(error)?;
30118 self.write_keyword(" ON ERROR");
30119 }
30120 if let Some(null) = &e.null {
30121 if e.empty.is_some() || e.error.is_some() {
30122 self.write_space();
30123 }
30124 self.generate_expression(null)?;
30125 self.write_keyword(" ON NULL");
30126 }
30127 Ok(())
30128 }
30129
30130 fn generate_on_conflict(&mut self, e: &OnConflict) -> Result<()> {
30131 if matches!(self.config.dialect, Some(DialectType::Materialize)) {
30133 return Ok(());
30134 }
30135 if e.duplicate.is_some() {
30137 self.write_keyword("ON DUPLICATE KEY UPDATE");
30139 for (i, expr) in e.expressions.iter().enumerate() {
30140 if i > 0 {
30141 self.write(",");
30142 }
30143 self.write_space();
30144 self.generate_expression(expr)?;
30145 }
30146 return Ok(());
30147 } else {
30148 self.write_keyword("ON CONFLICT");
30149 }
30150 if let Some(constraint) = &e.constraint {
30151 self.write_keyword(" ON CONSTRAINT ");
30152 self.generate_expression(constraint)?;
30153 }
30154 if let Some(conflict_keys) = &e.conflict_keys {
30155 if let Expression::Tuple(t) = conflict_keys.as_ref() {
30157 self.write("(");
30158 for (i, expr) in t.expressions.iter().enumerate() {
30159 if i > 0 {
30160 self.write(", ");
30161 }
30162 self.generate_expression(expr)?;
30163 }
30164 self.write(")");
30165 } else {
30166 self.write("(");
30167 self.generate_expression(conflict_keys)?;
30168 self.write(")");
30169 }
30170 }
30171 if let Some(index_predicate) = &e.index_predicate {
30172 self.write_keyword(" WHERE ");
30173 self.generate_expression(index_predicate)?;
30174 }
30175 if let Some(action) = &e.action {
30176 if let Expression::Identifier(id) = action.as_ref() {
30178 if id.name == "NOTHING" || id.name.to_uppercase() == "NOTHING" {
30179 self.write_keyword(" DO NOTHING");
30180 } else {
30181 self.write_keyword(" DO ");
30182 self.generate_expression(action)?;
30183 }
30184 } else if let Expression::Tuple(t) = action.as_ref() {
30185 self.write_keyword(" DO UPDATE SET ");
30187 for (i, expr) in t.expressions.iter().enumerate() {
30188 if i > 0 {
30189 self.write(", ");
30190 }
30191 self.generate_expression(expr)?;
30192 }
30193 } else {
30194 self.write_keyword(" DO ");
30195 self.generate_expression(action)?;
30196 }
30197 }
30198 if let Some(where_) = &e.where_ {
30200 self.write_keyword(" WHERE ");
30201 self.generate_expression(where_)?;
30202 }
30203 Ok(())
30204 }
30205
30206 fn generate_on_property(&mut self, e: &OnProperty) -> Result<()> {
30207 self.write_keyword("ON");
30209 self.write_space();
30210 self.generate_expression(&e.this)?;
30211 Ok(())
30212 }
30213
30214 fn generate_opclass(&mut self, e: &Opclass) -> Result<()> {
30215 self.generate_expression(&e.this)?;
30217 self.write_space();
30218 self.generate_expression(&e.expression)?;
30219 Ok(())
30220 }
30221
30222 fn generate_open_json(&mut self, e: &OpenJSON) -> Result<()> {
30223 self.write_keyword("OPENJSON");
30225 self.write("(");
30226 self.generate_expression(&e.this)?;
30227 if let Some(path) = &e.path {
30228 self.write(", ");
30229 self.generate_expression(path)?;
30230 }
30231 self.write(")");
30232 if !e.expressions.is_empty() {
30233 self.write_keyword(" WITH");
30234 if self.config.pretty {
30235 self.write(" (\n");
30236 self.indent_level += 2;
30237 for (i, expr) in e.expressions.iter().enumerate() {
30238 if i > 0 {
30239 self.write(",\n");
30240 }
30241 self.write_indent();
30242 self.generate_expression(expr)?;
30243 }
30244 self.write("\n");
30245 self.indent_level -= 2;
30246 self.write(")");
30247 } else {
30248 self.write(" (");
30249 for (i, expr) in e.expressions.iter().enumerate() {
30250 if i > 0 {
30251 self.write(", ");
30252 }
30253 self.generate_expression(expr)?;
30254 }
30255 self.write(")");
30256 }
30257 }
30258 Ok(())
30259 }
30260
30261 fn generate_open_json_column_def(&mut self, e: &OpenJSONColumnDef) -> Result<()> {
30262 self.generate_expression(&e.this)?;
30264 self.write_space();
30265 if let Some(ref dt) = e.data_type {
30267 self.generate_data_type(dt)?;
30268 } else if !e.kind.is_empty() {
30269 self.write(&e.kind);
30270 }
30271 if let Some(path) = &e.path {
30272 self.write_space();
30273 self.generate_expression(path)?;
30274 }
30275 if e.as_json.is_some() {
30276 self.write_keyword(" AS JSON");
30277 }
30278 Ok(())
30279 }
30280
30281 fn generate_operator(&mut self, e: &Operator) -> Result<()> {
30282 self.generate_expression(&e.this)?;
30284 self.write_space();
30285 if let Some(op) = &e.operator {
30286 self.write_keyword("OPERATOR");
30287 self.write("(");
30288 self.generate_expression(op)?;
30289 self.write(")");
30290 }
30291 for comment in &e.comments {
30293 self.write_space();
30294 self.write_formatted_comment(comment);
30295 }
30296 self.write_space();
30297 self.generate_expression(&e.expression)?;
30298 Ok(())
30299 }
30300
30301 fn generate_order_by(&mut self, e: &OrderBy) -> Result<()> {
30302 self.write_keyword("ORDER BY");
30304 let pretty_clickhouse_single_paren = self.config.pretty
30305 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
30306 && e.expressions.len() == 1
30307 && matches!(e.expressions[0].this, Expression::Paren(ref p) if !matches!(p.this, Expression::Tuple(_)));
30308 let clickhouse_single_tuple = matches!(self.config.dialect, Some(DialectType::ClickHouse))
30309 && e.expressions.len() == 1
30310 && matches!(e.expressions[0].this, Expression::Tuple(_))
30311 && !e.expressions[0].desc
30312 && e.expressions[0].nulls_first.is_none();
30313
30314 if pretty_clickhouse_single_paren {
30315 self.write_space();
30316 if let Expression::Paren(p) = &e.expressions[0].this {
30317 self.write("(");
30318 self.write_newline();
30319 self.indent_level += 1;
30320 self.write_indent();
30321 self.generate_expression(&p.this)?;
30322 self.indent_level -= 1;
30323 self.write_newline();
30324 self.write(")");
30325 }
30326 return Ok(());
30327 }
30328
30329 if clickhouse_single_tuple {
30330 self.write_space();
30331 if let Expression::Tuple(t) = &e.expressions[0].this {
30332 self.write("(");
30333 for (i, expr) in t.expressions.iter().enumerate() {
30334 if i > 0 {
30335 self.write(", ");
30336 }
30337 self.generate_expression(expr)?;
30338 }
30339 self.write(")");
30340 }
30341 return Ok(());
30342 }
30343
30344 self.write_space();
30345 for (i, ordered) in e.expressions.iter().enumerate() {
30346 if i > 0 {
30347 self.write(", ");
30348 }
30349 self.generate_expression(&ordered.this)?;
30350 if ordered.desc {
30351 self.write_space();
30352 self.write_keyword("DESC");
30353 } else if ordered.explicit_asc {
30354 self.write_space();
30355 self.write_keyword("ASC");
30356 }
30357 if let Some(nulls_first) = ordered.nulls_first {
30358 let skip_nulls_last =
30360 !nulls_first && matches!(self.config.dialect, Some(DialectType::Dremio));
30361 if !skip_nulls_last {
30362 self.write_space();
30363 self.write_keyword("NULLS");
30364 self.write_space();
30365 if nulls_first {
30366 self.write_keyword("FIRST");
30367 } else {
30368 self.write_keyword("LAST");
30369 }
30370 }
30371 }
30372 }
30373 Ok(())
30374 }
30375
30376 fn generate_output_model_property(&mut self, e: &OutputModelProperty) -> Result<()> {
30377 self.write_keyword("OUTPUT");
30379 self.write("(");
30380 if self.config.pretty {
30381 self.indent_level += 1;
30382 self.write_newline();
30383 self.write_indent();
30384 self.generate_expression(&e.this)?;
30385 self.indent_level -= 1;
30386 self.write_newline();
30387 } else {
30388 self.generate_expression(&e.this)?;
30389 }
30390 self.write(")");
30391 Ok(())
30392 }
30393
30394 fn generate_overflow_truncate_behavior(&mut self, e: &OverflowTruncateBehavior) -> Result<()> {
30395 self.write_keyword("TRUNCATE");
30397 if let Some(this) = &e.this {
30398 self.write_space();
30399 self.generate_expression(this)?;
30400 }
30401 if e.with_count.is_some() {
30402 self.write_keyword(" WITH COUNT");
30403 } else {
30404 self.write_keyword(" WITHOUT COUNT");
30405 }
30406 Ok(())
30407 }
30408
30409 fn generate_parameterized_agg(&mut self, e: &ParameterizedAgg) -> Result<()> {
30410 self.generate_expression(&e.this)?;
30412 self.write("(");
30413 for (i, expr) in e.expressions.iter().enumerate() {
30414 if i > 0 {
30415 self.write(", ");
30416 }
30417 self.generate_expression(expr)?;
30418 }
30419 self.write(")(");
30420 for (i, param) in e.params.iter().enumerate() {
30421 if i > 0 {
30422 self.write(", ");
30423 }
30424 self.generate_expression(param)?;
30425 }
30426 self.write(")");
30427 Ok(())
30428 }
30429
30430 fn generate_parse_datetime(&mut self, e: &ParseDatetime) -> Result<()> {
30431 self.write_keyword("PARSE_DATETIME");
30433 self.write("(");
30434 if let Some(format) = &e.format {
30435 self.write("'");
30436 self.write(format);
30437 self.write("', ");
30438 }
30439 self.generate_expression(&e.this)?;
30440 if let Some(zone) = &e.zone {
30441 self.write(", ");
30442 self.generate_expression(zone)?;
30443 }
30444 self.write(")");
30445 Ok(())
30446 }
30447
30448 fn generate_parse_ip(&mut self, e: &ParseIp) -> Result<()> {
30449 self.write_keyword("PARSE_IP");
30451 self.write("(");
30452 self.generate_expression(&e.this)?;
30453 if let Some(type_) = &e.type_ {
30454 self.write(", ");
30455 self.generate_expression(type_)?;
30456 }
30457 if let Some(permissive) = &e.permissive {
30458 self.write(", ");
30459 self.generate_expression(permissive)?;
30460 }
30461 self.write(")");
30462 Ok(())
30463 }
30464
30465 fn generate_parse_json(&mut self, e: &ParseJSON) -> Result<()> {
30466 self.write_keyword("PARSE_JSON");
30468 self.write("(");
30469 self.generate_expression(&e.this)?;
30470 if let Some(expression) = &e.expression {
30471 self.write(", ");
30472 self.generate_expression(expression)?;
30473 }
30474 self.write(")");
30475 Ok(())
30476 }
30477
30478 fn generate_parse_time(&mut self, e: &ParseTime) -> Result<()> {
30479 self.write_keyword("PARSE_TIME");
30481 self.write("(");
30482 self.write(&format!("'{}'", e.format));
30483 self.write(", ");
30484 self.generate_expression(&e.this)?;
30485 self.write(")");
30486 Ok(())
30487 }
30488
30489 fn generate_parse_url(&mut self, e: &ParseUrl) -> Result<()> {
30490 self.write_keyword("PARSE_URL");
30492 self.write("(");
30493 self.generate_expression(&e.this)?;
30494 if let Some(part) = &e.part_to_extract {
30495 self.write(", ");
30496 self.generate_expression(part)?;
30497 }
30498 if let Some(key) = &e.key {
30499 self.write(", ");
30500 self.generate_expression(key)?;
30501 }
30502 if let Some(permissive) = &e.permissive {
30503 self.write(", ");
30504 self.generate_expression(permissive)?;
30505 }
30506 self.write(")");
30507 Ok(())
30508 }
30509
30510 fn generate_partition_expr(&mut self, e: &Partition) -> Result<()> {
30511 if e.subpartition {
30513 self.write_keyword("SUBPARTITION");
30514 } else {
30515 self.write_keyword("PARTITION");
30516 }
30517 self.write("(");
30518 for (i, expr) in e.expressions.iter().enumerate() {
30519 if i > 0 {
30520 self.write(", ");
30521 }
30522 self.generate_expression(expr)?;
30523 }
30524 self.write(")");
30525 Ok(())
30526 }
30527
30528 fn generate_partition_bound_spec(&mut self, e: &PartitionBoundSpec) -> Result<()> {
30529 if let Some(this) = &e.this {
30531 if let Some(expression) = &e.expression {
30532 self.write_keyword("WITH");
30534 self.write(" (");
30535 self.write_keyword("MODULUS");
30536 self.write_space();
30537 self.generate_expression(this)?;
30538 self.write(", ");
30539 self.write_keyword("REMAINDER");
30540 self.write_space();
30541 self.generate_expression(expression)?;
30542 self.write(")");
30543 } else {
30544 self.write_keyword("IN");
30546 self.write(" (");
30547 self.generate_partition_bound_values(this)?;
30548 self.write(")");
30549 }
30550 } else if let (Some(from), Some(to)) = (&e.from_expressions, &e.to_expressions) {
30551 self.write_keyword("FROM");
30553 self.write(" (");
30554 self.generate_partition_bound_values(from)?;
30555 self.write(") ");
30556 self.write_keyword("TO");
30557 self.write(" (");
30558 self.generate_partition_bound_values(to)?;
30559 self.write(")");
30560 }
30561 Ok(())
30562 }
30563
30564 fn generate_partition_bound_values(&mut self, expr: &Expression) -> Result<()> {
30567 if let Expression::Tuple(t) = expr {
30568 for (i, e) in t.expressions.iter().enumerate() {
30569 if i > 0 {
30570 self.write(", ");
30571 }
30572 self.generate_expression(e)?;
30573 }
30574 Ok(())
30575 } else {
30576 self.generate_expression(expr)
30577 }
30578 }
30579
30580 fn generate_partition_by_list_property(&mut self, e: &PartitionByListProperty) -> Result<()> {
30581 self.write_keyword("PARTITION BY LIST");
30583 if let Some(partition_exprs) = &e.partition_expressions {
30584 self.write(" (");
30585 self.generate_doris_partition_expressions(partition_exprs)?;
30587 self.write(")");
30588 }
30589 if let Some(create_exprs) = &e.create_expressions {
30590 self.write(" (");
30591 self.generate_doris_partition_definitions(create_exprs)?;
30593 self.write(")");
30594 }
30595 Ok(())
30596 }
30597
30598 fn generate_partition_by_range_property(&mut self, e: &PartitionByRangeProperty) -> Result<()> {
30599 self.write_keyword("PARTITION BY RANGE");
30601 if let Some(partition_exprs) = &e.partition_expressions {
30602 self.write(" (");
30603 self.generate_doris_partition_expressions(partition_exprs)?;
30605 self.write(")");
30606 }
30607 if let Some(create_exprs) = &e.create_expressions {
30608 self.write(" (");
30609 self.generate_doris_partition_definitions(create_exprs)?;
30611 self.write(")");
30612 }
30613 Ok(())
30614 }
30615
30616 fn generate_doris_partition_expressions(&mut self, expr: &Expression) -> Result<()> {
30618 if let Expression::Tuple(t) = expr {
30619 for (i, e) in t.expressions.iter().enumerate() {
30620 if i > 0 {
30621 self.write(", ");
30622 }
30623 self.generate_expression(e)?;
30624 }
30625 } else {
30626 self.generate_expression(expr)?;
30627 }
30628 Ok(())
30629 }
30630
30631 fn generate_doris_partition_definitions(&mut self, expr: &Expression) -> Result<()> {
30633 match expr {
30634 Expression::Tuple(t) => {
30635 for (i, part) in t.expressions.iter().enumerate() {
30637 if i > 0 {
30638 self.write(", ");
30639 }
30640 if let Expression::Partition(p) = part {
30642 for (j, inner) in p.expressions.iter().enumerate() {
30643 if j > 0 {
30644 self.write(", ");
30645 }
30646 self.generate_expression(inner)?;
30647 }
30648 } else {
30649 self.generate_expression(part)?;
30650 }
30651 }
30652 }
30653 Expression::PartitionByRangePropertyDynamic(_) => {
30654 self.generate_expression(expr)?;
30656 }
30657 _ => {
30658 self.generate_expression(expr)?;
30659 }
30660 }
30661 Ok(())
30662 }
30663
30664 fn generate_partition_by_range_property_dynamic(
30665 &mut self,
30666 e: &PartitionByRangePropertyDynamic,
30667 ) -> Result<()> {
30668 if e.use_start_end {
30669 if let Some(start) = &e.start {
30671 self.write_keyword("START");
30672 self.write(" (");
30673 self.generate_expression(start)?;
30674 self.write(")");
30675 }
30676 if let Some(end) = &e.end {
30677 self.write_space();
30678 self.write_keyword("END");
30679 self.write(" (");
30680 self.generate_expression(end)?;
30681 self.write(")");
30682 }
30683 if let Some(every) = &e.every {
30684 self.write_space();
30685 self.write_keyword("EVERY");
30686 self.write(" (");
30687 self.generate_doris_interval(every)?;
30689 self.write(")");
30690 }
30691 } else {
30692 if let Some(start) = &e.start {
30694 self.write_keyword("FROM");
30695 self.write(" (");
30696 self.generate_expression(start)?;
30697 self.write(")");
30698 }
30699 if let Some(end) = &e.end {
30700 self.write_space();
30701 self.write_keyword("TO");
30702 self.write(" (");
30703 self.generate_expression(end)?;
30704 self.write(")");
30705 }
30706 if let Some(every) = &e.every {
30707 self.write_space();
30708 self.generate_doris_interval(every)?;
30710 }
30711 }
30712 Ok(())
30713 }
30714
30715 fn generate_doris_interval(&mut self, expr: &Expression) -> Result<()> {
30717 if let Expression::Interval(interval) = expr {
30718 self.write_keyword("INTERVAL");
30719 if let Some(ref value) = interval.this {
30720 self.write_space();
30721 match value {
30725 Expression::Literal(Literal::String(s))
30726 if s.chars()
30727 .all(|c| c.is_ascii_digit() || c == '.' || c == '-')
30728 && !s.is_empty() =>
30729 {
30730 self.write(s);
30731 }
30732 _ => {
30733 self.generate_expression(value)?;
30734 }
30735 }
30736 }
30737 if let Some(ref unit_spec) = interval.unit {
30738 self.write_space();
30739 self.write_interval_unit_spec(unit_spec)?;
30740 }
30741 Ok(())
30742 } else {
30743 self.generate_expression(expr)
30744 }
30745 }
30746
30747 fn generate_partition_by_truncate(&mut self, e: &PartitionByTruncate) -> Result<()> {
30748 self.write_keyword("TRUNCATE");
30750 self.write("(");
30751 self.generate_expression(&e.expression)?;
30752 self.write(", ");
30753 self.generate_expression(&e.this)?;
30754 self.write(")");
30755 Ok(())
30756 }
30757
30758 fn generate_partition_list(&mut self, e: &PartitionList) -> Result<()> {
30759 self.write_keyword("PARTITION");
30761 self.write_space();
30762 self.generate_expression(&e.this)?;
30763 self.write_space();
30764 self.write_keyword("VALUES IN");
30765 self.write(" (");
30766 for (i, expr) in e.expressions.iter().enumerate() {
30767 if i > 0 {
30768 self.write(", ");
30769 }
30770 self.generate_expression(expr)?;
30771 }
30772 self.write(")");
30773 Ok(())
30774 }
30775
30776 fn generate_partition_range(&mut self, e: &PartitionRange) -> Result<()> {
30777 if e.expressions.is_empty() && e.expression.is_some() {
30780 self.generate_expression(&e.this)?;
30782 self.write_space();
30783 self.write_keyword("TO");
30784 self.write_space();
30785 self.generate_expression(e.expression.as_ref().unwrap())?;
30786 return Ok(());
30787 }
30788
30789 self.write_keyword("PARTITION");
30791 self.write_space();
30792 self.generate_expression(&e.this)?;
30793 self.write_space();
30794
30795 if e.expressions.len() == 1 {
30797 self.write_keyword("VALUES LESS THAN");
30799 self.write(" (");
30800 self.generate_expression(&e.expressions[0])?;
30801 self.write(")");
30802 } else if !e.expressions.is_empty() {
30803 self.write_keyword("VALUES");
30805 self.write(" [");
30806 for (i, expr) in e.expressions.iter().enumerate() {
30807 if i > 0 {
30808 self.write(", ");
30809 }
30810 if let Expression::Tuple(t) = expr {
30812 self.write("(");
30813 for (j, inner) in t.expressions.iter().enumerate() {
30814 if j > 0 {
30815 self.write(", ");
30816 }
30817 self.generate_expression(inner)?;
30818 }
30819 self.write(")");
30820 } else {
30821 self.write("(");
30822 self.generate_expression(expr)?;
30823 self.write(")");
30824 }
30825 }
30826 self.write(")");
30827 }
30828 Ok(())
30829 }
30830
30831 fn generate_partitioned_by_bucket(&mut self, e: &PartitionedByBucket) -> Result<()> {
30832 self.write_keyword("BUCKET");
30834 self.write("(");
30835 self.generate_expression(&e.this)?;
30836 self.write(", ");
30837 self.generate_expression(&e.expression)?;
30838 self.write(")");
30839 Ok(())
30840 }
30841
30842 fn generate_partition_by_property(&mut self, e: &PartitionByProperty) -> Result<()> {
30843 self.write_keyword("PARTITION BY");
30845 self.write_space();
30846 for (i, expr) in e.expressions.iter().enumerate() {
30847 if i > 0 {
30848 self.write(", ");
30849 }
30850 self.generate_expression(expr)?;
30851 }
30852 Ok(())
30853 }
30854
30855 fn generate_partitioned_by_property(&mut self, e: &PartitionedByProperty) -> Result<()> {
30856 if matches!(
30858 self.config.dialect,
30859 Some(crate::dialects::DialectType::Teradata)
30860 | Some(crate::dialects::DialectType::ClickHouse)
30861 ) {
30862 self.write_keyword("PARTITION BY");
30863 } else {
30864 self.write_keyword("PARTITIONED BY");
30865 }
30866 self.write_space();
30867 if self.config.pretty {
30869 if let Expression::Tuple(ref tuple) = *e.this {
30870 self.write("(");
30871 self.write_newline();
30872 self.indent_level += 1;
30873 for (i, expr) in tuple.expressions.iter().enumerate() {
30874 if i > 0 {
30875 self.write(",");
30876 self.write_newline();
30877 }
30878 self.write_indent();
30879 self.generate_expression(expr)?;
30880 }
30881 self.indent_level -= 1;
30882 self.write_newline();
30883 self.write(")");
30884 } else {
30885 self.generate_expression(&e.this)?;
30886 }
30887 } else {
30888 self.generate_expression(&e.this)?;
30889 }
30890 Ok(())
30891 }
30892
30893 fn generate_partitioned_of_property(&mut self, e: &PartitionedOfProperty) -> Result<()> {
30894 self.write_keyword("PARTITION OF");
30896 self.write_space();
30897 self.generate_expression(&e.this)?;
30898 if let Expression::PartitionBoundSpec(_) = e.expression.as_ref() {
30900 self.write_space();
30901 self.write_keyword("FOR VALUES");
30902 self.write_space();
30903 self.generate_expression(&e.expression)?;
30904 } else {
30905 self.write_space();
30906 self.write_keyword("DEFAULT");
30907 }
30908 Ok(())
30909 }
30910
30911 fn generate_period_for_system_time_constraint(
30912 &mut self,
30913 e: &PeriodForSystemTimeConstraint,
30914 ) -> Result<()> {
30915 self.write_keyword("PERIOD FOR SYSTEM_TIME");
30917 self.write(" (");
30918 self.generate_expression(&e.this)?;
30919 self.write(", ");
30920 self.generate_expression(&e.expression)?;
30921 self.write(")");
30922 Ok(())
30923 }
30924
30925 fn generate_pivot_alias(&mut self, e: &PivotAlias) -> Result<()> {
30926 self.generate_expression(&e.this)?;
30929 self.write_space();
30930 self.write_keyword("AS");
30931 self.write_space();
30932 if self.config.unpivot_aliases_are_identifiers {
30934 match &e.alias {
30935 Expression::Literal(Literal::String(s)) => {
30936 self.generate_identifier(&Identifier::new(s.clone()))?;
30938 }
30939 Expression::Literal(Literal::Number(n)) => {
30940 let mut id = Identifier::new(n.clone());
30942 id.quoted = true;
30943 self.generate_identifier(&id)?;
30944 }
30945 other => {
30946 self.generate_expression(other)?;
30947 }
30948 }
30949 } else {
30950 self.generate_expression(&e.alias)?;
30951 }
30952 Ok(())
30953 }
30954
30955 fn generate_pivot_any(&mut self, e: &PivotAny) -> Result<()> {
30956 self.write_keyword("ANY");
30958 if let Some(this) = &e.this {
30959 self.write_space();
30960 self.generate_expression(this)?;
30961 }
30962 Ok(())
30963 }
30964
30965 fn generate_predict(&mut self, e: &Predict) -> Result<()> {
30966 self.write_keyword("ML.PREDICT");
30968 self.write("(");
30969 self.write_keyword("MODEL");
30970 self.write_space();
30971 self.generate_expression(&e.this)?;
30972 self.write(", ");
30973 self.generate_expression(&e.expression)?;
30974 if let Some(params) = &e.params_struct {
30975 self.write(", ");
30976 self.generate_expression(params)?;
30977 }
30978 self.write(")");
30979 Ok(())
30980 }
30981
30982 fn generate_previous_day(&mut self, e: &PreviousDay) -> Result<()> {
30983 self.write_keyword("PREVIOUS_DAY");
30985 self.write("(");
30986 self.generate_expression(&e.this)?;
30987 self.write(", ");
30988 self.generate_expression(&e.expression)?;
30989 self.write(")");
30990 Ok(())
30991 }
30992
30993 fn generate_primary_key(&mut self, e: &PrimaryKey) -> Result<()> {
30994 self.write_keyword("PRIMARY KEY");
30996 if let Some(name) = &e.this {
30997 self.write_space();
30998 self.generate_expression(name)?;
30999 }
31000 if !e.expressions.is_empty() {
31001 self.write(" (");
31002 for (i, expr) in e.expressions.iter().enumerate() {
31003 if i > 0 {
31004 self.write(", ");
31005 }
31006 self.generate_expression(expr)?;
31007 }
31008 self.write(")");
31009 }
31010 if let Some(include) = &e.include {
31011 self.write_space();
31012 self.generate_expression(include)?;
31013 }
31014 if !e.options.is_empty() {
31015 self.write_space();
31016 for (i, opt) in e.options.iter().enumerate() {
31017 if i > 0 {
31018 self.write_space();
31019 }
31020 self.generate_expression(opt)?;
31021 }
31022 }
31023 Ok(())
31024 }
31025
31026 fn generate_primary_key_column_constraint(
31027 &mut self,
31028 _e: &PrimaryKeyColumnConstraint,
31029 ) -> Result<()> {
31030 self.write_keyword("PRIMARY KEY");
31032 Ok(())
31033 }
31034
31035 fn generate_path_column_constraint(&mut self, e: &PathColumnConstraint) -> Result<()> {
31036 self.write_keyword("PATH");
31038 self.write_space();
31039 self.generate_expression(&e.this)?;
31040 Ok(())
31041 }
31042
31043 fn generate_projection_def(&mut self, e: &ProjectionDef) -> Result<()> {
31044 self.write_keyword("PROJECTION");
31046 self.write_space();
31047 self.generate_expression(&e.this)?;
31048 self.write(" (");
31049 self.generate_expression(&e.expression)?;
31050 self.write(")");
31051 Ok(())
31052 }
31053
31054 fn generate_properties(&mut self, e: &Properties) -> Result<()> {
31055 for (i, prop) in e.expressions.iter().enumerate() {
31057 if i > 0 {
31058 self.write(", ");
31059 }
31060 self.generate_expression(prop)?;
31061 }
31062 Ok(())
31063 }
31064
31065 fn generate_property(&mut self, e: &Property) -> Result<()> {
31066 self.generate_expression(&e.this)?;
31068 if let Some(value) = &e.value {
31069 self.write("=");
31070 self.generate_expression(value)?;
31071 }
31072 Ok(())
31073 }
31074
31075 fn generate_options_property(&mut self, e: &OptionsProperty) -> Result<()> {
31076 self.write_keyword("OPTIONS");
31077 if e.entries.is_empty() {
31078 self.write(" ()");
31079 return Ok(());
31080 }
31081
31082 if self.config.pretty {
31083 self.write(" (");
31084 self.write_newline();
31085 self.indent_level += 1;
31086 for (i, entry) in e.entries.iter().enumerate() {
31087 if i > 0 {
31088 self.write(",");
31089 self.write_newline();
31090 }
31091 self.write_indent();
31092 self.generate_identifier(&entry.key)?;
31093 self.write("=");
31094 self.generate_expression(&entry.value)?;
31095 }
31096 self.indent_level -= 1;
31097 self.write_newline();
31098 self.write(")");
31099 } else {
31100 self.write(" (");
31101 for (i, entry) in e.entries.iter().enumerate() {
31102 if i > 0 {
31103 self.write(", ");
31104 }
31105 self.generate_identifier(&entry.key)?;
31106 self.write("=");
31107 self.generate_expression(&entry.value)?;
31108 }
31109 self.write(")");
31110 }
31111 Ok(())
31112 }
31113
31114 fn generate_options_clause(&mut self, options: &[Expression]) -> Result<()> {
31116 self.write_keyword("OPTIONS");
31117 self.write(" (");
31118 for (i, opt) in options.iter().enumerate() {
31119 if i > 0 {
31120 self.write(", ");
31121 }
31122 self.generate_option_expression(opt)?;
31123 }
31124 self.write(")");
31125 Ok(())
31126 }
31127
31128 fn generate_properties_clause(&mut self, properties: &[Expression]) -> Result<()> {
31130 self.write_keyword("PROPERTIES");
31131 self.write(" (");
31132 for (i, prop) in properties.iter().enumerate() {
31133 if i > 0 {
31134 self.write(", ");
31135 }
31136 self.generate_option_expression(prop)?;
31137 }
31138 self.write(")");
31139 Ok(())
31140 }
31141
31142 fn generate_environment_clause(&mut self, environment: &[Expression]) -> Result<()> {
31144 self.write_keyword("ENVIRONMENT");
31145 self.write(" (");
31146 for (i, env_item) in environment.iter().enumerate() {
31147 if i > 0 {
31148 self.write(", ");
31149 }
31150 self.generate_environment_expression(env_item)?;
31151 }
31152 self.write(")");
31153 Ok(())
31154 }
31155
31156 fn generate_environment_expression(&mut self, expr: &Expression) -> Result<()> {
31158 match expr {
31159 Expression::Eq(eq) => {
31160 self.generate_expression(&eq.left)?;
31162 self.write(" = ");
31163 self.generate_expression(&eq.right)?;
31164 Ok(())
31165 }
31166 _ => self.generate_expression(expr),
31167 }
31168 }
31169
31170 fn generate_tblproperties_clause(&mut self, options: &[Expression]) -> Result<()> {
31172 self.write_keyword("TBLPROPERTIES");
31173 if self.config.pretty {
31174 self.write(" (");
31175 self.write_newline();
31176 self.indent_level += 1;
31177 for (i, opt) in options.iter().enumerate() {
31178 if i > 0 {
31179 self.write(",");
31180 self.write_newline();
31181 }
31182 self.write_indent();
31183 self.generate_option_expression(opt)?;
31184 }
31185 self.indent_level -= 1;
31186 self.write_newline();
31187 self.write(")");
31188 } else {
31189 self.write(" (");
31190 for (i, opt) in options.iter().enumerate() {
31191 if i > 0 {
31192 self.write(", ");
31193 }
31194 self.generate_option_expression(opt)?;
31195 }
31196 self.write(")");
31197 }
31198 Ok(())
31199 }
31200
31201 fn generate_option_expression(&mut self, expr: &Expression) -> Result<()> {
31203 match expr {
31204 Expression::Eq(eq) => {
31205 self.generate_expression(&eq.left)?;
31207 self.write("=");
31208 self.generate_expression(&eq.right)?;
31209 Ok(())
31210 }
31211 _ => self.generate_expression(expr),
31212 }
31213 }
31214
31215 fn generate_pseudo_type(&mut self, e: &PseudoType) -> Result<()> {
31216 self.generate_expression(&e.this)?;
31218 Ok(())
31219 }
31220
31221 fn generate_put(&mut self, e: &PutStmt) -> Result<()> {
31222 self.write_keyword("PUT");
31224 self.write_space();
31225
31226 if e.source_quoted {
31228 self.write("'");
31229 self.write(&e.source);
31230 self.write("'");
31231 } else {
31232 self.write(&e.source);
31233 }
31234
31235 self.write_space();
31236
31237 if let Expression::Literal(Literal::String(s)) = &e.target {
31239 self.write(s);
31240 } else {
31241 self.generate_expression(&e.target)?;
31242 }
31243
31244 for param in &e.params {
31246 self.write_space();
31247 self.write(¶m.name);
31248 if let Some(ref value) = param.value {
31249 self.write("=");
31250 self.generate_expression(value)?;
31251 }
31252 }
31253
31254 Ok(())
31255 }
31256
31257 fn generate_quantile(&mut self, e: &Quantile) -> Result<()> {
31258 self.write_keyword("QUANTILE");
31260 self.write("(");
31261 self.generate_expression(&e.this)?;
31262 if let Some(quantile) = &e.quantile {
31263 self.write(", ");
31264 self.generate_expression(quantile)?;
31265 }
31266 self.write(")");
31267 Ok(())
31268 }
31269
31270 fn generate_query_band(&mut self, e: &QueryBand) -> Result<()> {
31271 if matches!(
31273 self.config.dialect,
31274 Some(crate::dialects::DialectType::Teradata)
31275 ) {
31276 self.write_keyword("SET");
31277 self.write_space();
31278 }
31279 self.write_keyword("QUERY_BAND");
31280 self.write(" = ");
31281 self.generate_expression(&e.this)?;
31282 if e.update.is_some() {
31283 self.write_space();
31284 self.write_keyword("UPDATE");
31285 }
31286 if let Some(scope) = &e.scope {
31287 self.write_space();
31288 self.write_keyword("FOR");
31289 self.write_space();
31290 self.generate_expression(scope)?;
31291 }
31292 Ok(())
31293 }
31294
31295 fn generate_query_option(&mut self, e: &QueryOption) -> Result<()> {
31296 self.generate_expression(&e.this)?;
31298 if let Some(expression) = &e.expression {
31299 self.write(" = ");
31300 self.generate_expression(expression)?;
31301 }
31302 Ok(())
31303 }
31304
31305 fn generate_query_transform(&mut self, e: &QueryTransform) -> Result<()> {
31306 self.write_keyword("TRANSFORM");
31308 self.write("(");
31309 for (i, expr) in e.expressions.iter().enumerate() {
31310 if i > 0 {
31311 self.write(", ");
31312 }
31313 self.generate_expression(expr)?;
31314 }
31315 self.write(")");
31316 if let Some(row_format_before) = &e.row_format_before {
31317 self.write_space();
31318 self.generate_expression(row_format_before)?;
31319 }
31320 if let Some(record_writer) = &e.record_writer {
31321 self.write_space();
31322 self.write_keyword("RECORDWRITER");
31323 self.write_space();
31324 self.generate_expression(record_writer)?;
31325 }
31326 if let Some(command_script) = &e.command_script {
31327 self.write_space();
31328 self.write_keyword("USING");
31329 self.write_space();
31330 self.generate_expression(command_script)?;
31331 }
31332 if let Some(schema) = &e.schema {
31333 self.write_space();
31334 self.write_keyword("AS");
31335 self.write_space();
31336 self.generate_expression(schema)?;
31337 }
31338 if let Some(row_format_after) = &e.row_format_after {
31339 self.write_space();
31340 self.generate_expression(row_format_after)?;
31341 }
31342 if let Some(record_reader) = &e.record_reader {
31343 self.write_space();
31344 self.write_keyword("RECORDREADER");
31345 self.write_space();
31346 self.generate_expression(record_reader)?;
31347 }
31348 Ok(())
31349 }
31350
31351 fn generate_randn(&mut self, e: &Randn) -> Result<()> {
31352 self.write_keyword("RANDN");
31354 self.write("(");
31355 if let Some(this) = &e.this {
31356 self.generate_expression(this)?;
31357 }
31358 self.write(")");
31359 Ok(())
31360 }
31361
31362 fn generate_randstr(&mut self, e: &Randstr) -> Result<()> {
31363 self.write_keyword("RANDSTR");
31365 self.write("(");
31366 self.generate_expression(&e.this)?;
31367 if let Some(generator) = &e.generator {
31368 self.write(", ");
31369 self.generate_expression(generator)?;
31370 }
31371 self.write(")");
31372 Ok(())
31373 }
31374
31375 fn generate_range_bucket(&mut self, e: &RangeBucket) -> Result<()> {
31376 self.write_keyword("RANGE_BUCKET");
31378 self.write("(");
31379 self.generate_expression(&e.this)?;
31380 self.write(", ");
31381 self.generate_expression(&e.expression)?;
31382 self.write(")");
31383 Ok(())
31384 }
31385
31386 fn generate_range_n(&mut self, e: &RangeN) -> Result<()> {
31387 self.write_keyword("RANGE_N");
31389 self.write("(");
31390 self.generate_expression(&e.this)?;
31391 self.write_space();
31392 self.write_keyword("BETWEEN");
31393 self.write_space();
31394 for (i, expr) in e.expressions.iter().enumerate() {
31395 if i > 0 {
31396 self.write(", ");
31397 }
31398 self.generate_expression(expr)?;
31399 }
31400 if let Some(each) = &e.each {
31401 self.write_space();
31402 self.write_keyword("EACH");
31403 self.write_space();
31404 self.generate_expression(each)?;
31405 }
31406 self.write(")");
31407 Ok(())
31408 }
31409
31410 fn generate_read_csv(&mut self, e: &ReadCSV) -> Result<()> {
31411 self.write_keyword("READ_CSV");
31413 self.write("(");
31414 self.generate_expression(&e.this)?;
31415 for expr in &e.expressions {
31416 self.write(", ");
31417 self.generate_expression(expr)?;
31418 }
31419 self.write(")");
31420 Ok(())
31421 }
31422
31423 fn generate_read_parquet(&mut self, e: &ReadParquet) -> Result<()> {
31424 self.write_keyword("READ_PARQUET");
31426 self.write("(");
31427 for (i, expr) in e.expressions.iter().enumerate() {
31428 if i > 0 {
31429 self.write(", ");
31430 }
31431 self.generate_expression(expr)?;
31432 }
31433 self.write(")");
31434 Ok(())
31435 }
31436
31437 fn generate_recursive_with_search(&mut self, e: &RecursiveWithSearch) -> Result<()> {
31438 if e.kind == "CYCLE" {
31441 self.write_keyword("CYCLE");
31442 } else {
31443 self.write_keyword("SEARCH");
31444 self.write_space();
31445 self.write(&e.kind);
31446 self.write_space();
31447 self.write_keyword("FIRST BY");
31448 }
31449 self.write_space();
31450 self.generate_expression(&e.this)?;
31451 self.write_space();
31452 self.write_keyword("SET");
31453 self.write_space();
31454 self.generate_expression(&e.expression)?;
31455 if let Some(using) = &e.using {
31456 self.write_space();
31457 self.write_keyword("USING");
31458 self.write_space();
31459 self.generate_expression(using)?;
31460 }
31461 Ok(())
31462 }
31463
31464 fn generate_reduce(&mut self, e: &Reduce) -> Result<()> {
31465 self.write_keyword("REDUCE");
31467 self.write("(");
31468 self.generate_expression(&e.this)?;
31469 if let Some(initial) = &e.initial {
31470 self.write(", ");
31471 self.generate_expression(initial)?;
31472 }
31473 if let Some(merge) = &e.merge {
31474 self.write(", ");
31475 self.generate_expression(merge)?;
31476 }
31477 if let Some(finish) = &e.finish {
31478 self.write(", ");
31479 self.generate_expression(finish)?;
31480 }
31481 self.write(")");
31482 Ok(())
31483 }
31484
31485 fn generate_reference(&mut self, e: &Reference) -> Result<()> {
31486 self.write_keyword("REFERENCES");
31488 self.write_space();
31489 self.generate_expression(&e.this)?;
31490 if !e.expressions.is_empty() {
31491 self.write(" (");
31492 for (i, expr) in e.expressions.iter().enumerate() {
31493 if i > 0 {
31494 self.write(", ");
31495 }
31496 self.generate_expression(expr)?;
31497 }
31498 self.write(")");
31499 }
31500 for opt in &e.options {
31501 self.write_space();
31502 self.generate_expression(opt)?;
31503 }
31504 Ok(())
31505 }
31506
31507 fn generate_refresh(&mut self, e: &Refresh) -> Result<()> {
31508 self.write_keyword("REFRESH");
31510 if !e.kind.is_empty() {
31511 self.write_space();
31512 self.write_keyword(&e.kind);
31513 }
31514 self.write_space();
31515 self.generate_expression(&e.this)?;
31516 Ok(())
31517 }
31518
31519 fn generate_refresh_trigger_property(&mut self, e: &RefreshTriggerProperty) -> Result<()> {
31520 self.write_keyword("REFRESH");
31522 self.write_space();
31523 self.write_keyword(&e.method);
31524
31525 if let Some(ref kind) = e.kind {
31526 self.write_space();
31527 self.write_keyword("ON");
31528 self.write_space();
31529 self.write_keyword(kind);
31530
31531 if let Some(ref every) = e.every {
31533 self.write_space();
31534 self.write_keyword("EVERY");
31535 self.write_space();
31536 self.generate_expression(every)?;
31537 if let Some(ref unit) = e.unit {
31538 self.write_space();
31539 self.write_keyword(unit);
31540 }
31541 }
31542
31543 if let Some(ref starts) = e.starts {
31545 self.write_space();
31546 self.write_keyword("STARTS");
31547 self.write_space();
31548 self.generate_expression(starts)?;
31549 }
31550 }
31551 Ok(())
31552 }
31553
31554 fn generate_regexp_count(&mut self, e: &RegexpCount) -> Result<()> {
31555 self.write_keyword("REGEXP_COUNT");
31557 self.write("(");
31558 self.generate_expression(&e.this)?;
31559 self.write(", ");
31560 self.generate_expression(&e.expression)?;
31561 if let Some(position) = &e.position {
31562 self.write(", ");
31563 self.generate_expression(position)?;
31564 }
31565 if let Some(parameters) = &e.parameters {
31566 self.write(", ");
31567 self.generate_expression(parameters)?;
31568 }
31569 self.write(")");
31570 Ok(())
31571 }
31572
31573 fn generate_regexp_extract_all(&mut self, e: &RegexpExtractAll) -> Result<()> {
31574 self.write_keyword("REGEXP_EXTRACT_ALL");
31576 self.write("(");
31577 self.generate_expression(&e.this)?;
31578 self.write(", ");
31579 self.generate_expression(&e.expression)?;
31580 if let Some(group) = &e.group {
31581 self.write(", ");
31582 self.generate_expression(group)?;
31583 }
31584 self.write(")");
31585 Ok(())
31586 }
31587
31588 fn generate_regexp_full_match(&mut self, e: &RegexpFullMatch) -> Result<()> {
31589 self.write_keyword("REGEXP_FULL_MATCH");
31591 self.write("(");
31592 self.generate_expression(&e.this)?;
31593 self.write(", ");
31594 self.generate_expression(&e.expression)?;
31595 self.write(")");
31596 Ok(())
31597 }
31598
31599 fn generate_regexp_i_like(&mut self, e: &RegexpILike) -> Result<()> {
31600 use crate::dialects::DialectType;
31601 if matches!(
31603 self.config.dialect,
31604 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
31605 ) && e.flag.is_none()
31606 {
31607 self.generate_expression(&e.this)?;
31608 self.write(" ~* ");
31609 self.generate_expression(&e.expression)?;
31610 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
31611 self.write_keyword("REGEXP_LIKE");
31613 self.write("(");
31614 self.generate_expression(&e.this)?;
31615 self.write(", ");
31616 self.generate_expression(&e.expression)?;
31617 self.write(", ");
31618 if let Some(flag) = &e.flag {
31619 self.generate_expression(flag)?;
31620 } else {
31621 self.write("'i'");
31622 }
31623 self.write(")");
31624 } else {
31625 self.generate_expression(&e.this)?;
31627 self.write_space();
31628 self.write_keyword("REGEXP_ILIKE");
31629 self.write_space();
31630 self.generate_expression(&e.expression)?;
31631 if let Some(flag) = &e.flag {
31632 self.write(", ");
31633 self.generate_expression(flag)?;
31634 }
31635 }
31636 Ok(())
31637 }
31638
31639 fn generate_regexp_instr(&mut self, e: &RegexpInstr) -> Result<()> {
31640 self.write_keyword("REGEXP_INSTR");
31642 self.write("(");
31643 self.generate_expression(&e.this)?;
31644 self.write(", ");
31645 self.generate_expression(&e.expression)?;
31646 if let Some(position) = &e.position {
31647 self.write(", ");
31648 self.generate_expression(position)?;
31649 }
31650 if let Some(occurrence) = &e.occurrence {
31651 self.write(", ");
31652 self.generate_expression(occurrence)?;
31653 }
31654 if let Some(option) = &e.option {
31655 self.write(", ");
31656 self.generate_expression(option)?;
31657 }
31658 if let Some(parameters) = &e.parameters {
31659 self.write(", ");
31660 self.generate_expression(parameters)?;
31661 }
31662 if let Some(group) = &e.group {
31663 self.write(", ");
31664 self.generate_expression(group)?;
31665 }
31666 self.write(")");
31667 Ok(())
31668 }
31669
31670 fn generate_regexp_split(&mut self, e: &RegexpSplit) -> Result<()> {
31671 self.write_keyword("REGEXP_SPLIT");
31673 self.write("(");
31674 self.generate_expression(&e.this)?;
31675 self.write(", ");
31676 self.generate_expression(&e.expression)?;
31677 if let Some(limit) = &e.limit {
31678 self.write(", ");
31679 self.generate_expression(limit)?;
31680 }
31681 self.write(")");
31682 Ok(())
31683 }
31684
31685 fn generate_regr_avgx(&mut self, e: &RegrAvgx) -> Result<()> {
31686 self.write_keyword("REGR_AVGX");
31688 self.write("(");
31689 self.generate_expression(&e.this)?;
31690 self.write(", ");
31691 self.generate_expression(&e.expression)?;
31692 self.write(")");
31693 Ok(())
31694 }
31695
31696 fn generate_regr_avgy(&mut self, e: &RegrAvgy) -> Result<()> {
31697 self.write_keyword("REGR_AVGY");
31699 self.write("(");
31700 self.generate_expression(&e.this)?;
31701 self.write(", ");
31702 self.generate_expression(&e.expression)?;
31703 self.write(")");
31704 Ok(())
31705 }
31706
31707 fn generate_regr_count(&mut self, e: &RegrCount) -> Result<()> {
31708 self.write_keyword("REGR_COUNT");
31710 self.write("(");
31711 self.generate_expression(&e.this)?;
31712 self.write(", ");
31713 self.generate_expression(&e.expression)?;
31714 self.write(")");
31715 Ok(())
31716 }
31717
31718 fn generate_regr_intercept(&mut self, e: &RegrIntercept) -> Result<()> {
31719 self.write_keyword("REGR_INTERCEPT");
31721 self.write("(");
31722 self.generate_expression(&e.this)?;
31723 self.write(", ");
31724 self.generate_expression(&e.expression)?;
31725 self.write(")");
31726 Ok(())
31727 }
31728
31729 fn generate_regr_r2(&mut self, e: &RegrR2) -> Result<()> {
31730 self.write_keyword("REGR_R2");
31732 self.write("(");
31733 self.generate_expression(&e.this)?;
31734 self.write(", ");
31735 self.generate_expression(&e.expression)?;
31736 self.write(")");
31737 Ok(())
31738 }
31739
31740 fn generate_regr_slope(&mut self, e: &RegrSlope) -> Result<()> {
31741 self.write_keyword("REGR_SLOPE");
31743 self.write("(");
31744 self.generate_expression(&e.this)?;
31745 self.write(", ");
31746 self.generate_expression(&e.expression)?;
31747 self.write(")");
31748 Ok(())
31749 }
31750
31751 fn generate_regr_sxx(&mut self, e: &RegrSxx) -> Result<()> {
31752 self.write_keyword("REGR_SXX");
31754 self.write("(");
31755 self.generate_expression(&e.this)?;
31756 self.write(", ");
31757 self.generate_expression(&e.expression)?;
31758 self.write(")");
31759 Ok(())
31760 }
31761
31762 fn generate_regr_sxy(&mut self, e: &RegrSxy) -> Result<()> {
31763 self.write_keyword("REGR_SXY");
31765 self.write("(");
31766 self.generate_expression(&e.this)?;
31767 self.write(", ");
31768 self.generate_expression(&e.expression)?;
31769 self.write(")");
31770 Ok(())
31771 }
31772
31773 fn generate_regr_syy(&mut self, e: &RegrSyy) -> Result<()> {
31774 self.write_keyword("REGR_SYY");
31776 self.write("(");
31777 self.generate_expression(&e.this)?;
31778 self.write(", ");
31779 self.generate_expression(&e.expression)?;
31780 self.write(")");
31781 Ok(())
31782 }
31783
31784 fn generate_regr_valx(&mut self, e: &RegrValx) -> Result<()> {
31785 self.write_keyword("REGR_VALX");
31787 self.write("(");
31788 self.generate_expression(&e.this)?;
31789 self.write(", ");
31790 self.generate_expression(&e.expression)?;
31791 self.write(")");
31792 Ok(())
31793 }
31794
31795 fn generate_regr_valy(&mut self, e: &RegrValy) -> Result<()> {
31796 self.write_keyword("REGR_VALY");
31798 self.write("(");
31799 self.generate_expression(&e.this)?;
31800 self.write(", ");
31801 self.generate_expression(&e.expression)?;
31802 self.write(")");
31803 Ok(())
31804 }
31805
31806 fn generate_remote_with_connection_model_property(
31807 &mut self,
31808 e: &RemoteWithConnectionModelProperty,
31809 ) -> Result<()> {
31810 self.write_keyword("REMOTE WITH CONNECTION");
31812 self.write_space();
31813 self.generate_expression(&e.this)?;
31814 Ok(())
31815 }
31816
31817 fn generate_rename_column(&mut self, e: &RenameColumn) -> Result<()> {
31818 self.write_keyword("RENAME COLUMN");
31820 if e.exists {
31821 self.write_space();
31822 self.write_keyword("IF EXISTS");
31823 }
31824 self.write_space();
31825 self.generate_expression(&e.this)?;
31826 if let Some(to) = &e.to {
31827 self.write_space();
31828 self.write_keyword("TO");
31829 self.write_space();
31830 self.generate_expression(to)?;
31831 }
31832 Ok(())
31833 }
31834
31835 fn generate_replace_partition(&mut self, e: &ReplacePartition) -> Result<()> {
31836 self.write_keyword("REPLACE PARTITION");
31838 self.write_space();
31839 self.generate_expression(&e.expression)?;
31840 if let Some(source) = &e.source {
31841 self.write_space();
31842 self.write_keyword("FROM");
31843 self.write_space();
31844 self.generate_expression(source)?;
31845 }
31846 Ok(())
31847 }
31848
31849 fn generate_returning(&mut self, e: &Returning) -> Result<()> {
31850 let keyword = match self.config.dialect {
31853 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "OUTPUT",
31854 _ => "RETURNING",
31855 };
31856 self.write_keyword(keyword);
31857 self.write_space();
31858 for (i, expr) in e.expressions.iter().enumerate() {
31859 if i > 0 {
31860 self.write(", ");
31861 }
31862 self.generate_expression(expr)?;
31863 }
31864 if let Some(into) = &e.into {
31865 self.write_space();
31866 self.write_keyword("INTO");
31867 self.write_space();
31868 self.generate_expression(into)?;
31869 }
31870 Ok(())
31871 }
31872
31873 fn generate_output_clause(&mut self, output: &OutputClause) -> Result<()> {
31874 self.write_space();
31876 self.write_keyword("OUTPUT");
31877 self.write_space();
31878 for (i, expr) in output.columns.iter().enumerate() {
31879 if i > 0 {
31880 self.write(", ");
31881 }
31882 self.generate_expression(expr)?;
31883 }
31884 if let Some(into_table) = &output.into_table {
31885 self.write_space();
31886 self.write_keyword("INTO");
31887 self.write_space();
31888 self.generate_expression(into_table)?;
31889 }
31890 Ok(())
31891 }
31892
31893 fn generate_returns_property(&mut self, e: &ReturnsProperty) -> Result<()> {
31894 self.write_keyword("RETURNS");
31896 if e.is_table.is_some() {
31897 self.write_space();
31898 self.write_keyword("TABLE");
31899 }
31900 if let Some(table) = &e.table {
31901 self.write_space();
31902 self.generate_expression(table)?;
31903 } else if let Some(this) = &e.this {
31904 self.write_space();
31905 self.generate_expression(this)?;
31906 }
31907 if e.null.is_some() {
31908 self.write_space();
31909 self.write_keyword("NULL ON NULL INPUT");
31910 }
31911 Ok(())
31912 }
31913
31914 fn generate_rollback(&mut self, e: &Rollback) -> Result<()> {
31915 self.write_keyword("ROLLBACK");
31917
31918 if e.this.is_none()
31920 && matches!(
31921 self.config.dialect,
31922 Some(DialectType::TSQL) | Some(DialectType::Fabric)
31923 )
31924 {
31925 self.write_space();
31926 self.write_keyword("TRANSACTION");
31927 }
31928
31929 if let Some(this) = &e.this {
31931 let is_transaction_marker = matches!(
31933 this.as_ref(),
31934 Expression::Identifier(id) if id.name == "TRANSACTION"
31935 );
31936
31937 self.write_space();
31938 self.write_keyword("TRANSACTION");
31939
31940 if !is_transaction_marker {
31942 self.write_space();
31943 self.generate_expression(this)?;
31944 }
31945 }
31946
31947 if let Some(savepoint) = &e.savepoint {
31949 self.write_space();
31950 self.write_keyword("TO");
31951 self.write_space();
31952 self.generate_expression(savepoint)?;
31953 }
31954 Ok(())
31955 }
31956
31957 fn generate_rollup(&mut self, e: &Rollup) -> Result<()> {
31958 if e.expressions.is_empty() {
31960 self.write_keyword("WITH ROLLUP");
31961 } else {
31962 self.write_keyword("ROLLUP");
31963 self.write("(");
31964 for (i, expr) in e.expressions.iter().enumerate() {
31965 if i > 0 {
31966 self.write(", ");
31967 }
31968 self.generate_expression(expr)?;
31969 }
31970 self.write(")");
31971 }
31972 Ok(())
31973 }
31974
31975 fn generate_row_format_delimited_property(
31976 &mut self,
31977 e: &RowFormatDelimitedProperty,
31978 ) -> Result<()> {
31979 self.write_keyword("ROW FORMAT DELIMITED");
31981 if let Some(fields) = &e.fields {
31982 self.write_space();
31983 self.write_keyword("FIELDS TERMINATED BY");
31984 self.write_space();
31985 self.generate_expression(fields)?;
31986 }
31987 if let Some(escaped) = &e.escaped {
31988 self.write_space();
31989 self.write_keyword("ESCAPED BY");
31990 self.write_space();
31991 self.generate_expression(escaped)?;
31992 }
31993 if let Some(items) = &e.collection_items {
31994 self.write_space();
31995 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
31996 self.write_space();
31997 self.generate_expression(items)?;
31998 }
31999 if let Some(keys) = &e.map_keys {
32000 self.write_space();
32001 self.write_keyword("MAP KEYS TERMINATED BY");
32002 self.write_space();
32003 self.generate_expression(keys)?;
32004 }
32005 if let Some(lines) = &e.lines {
32006 self.write_space();
32007 self.write_keyword("LINES TERMINATED BY");
32008 self.write_space();
32009 self.generate_expression(lines)?;
32010 }
32011 if let Some(null) = &e.null {
32012 self.write_space();
32013 self.write_keyword("NULL DEFINED AS");
32014 self.write_space();
32015 self.generate_expression(null)?;
32016 }
32017 if let Some(serde) = &e.serde {
32018 self.write_space();
32019 self.generate_expression(serde)?;
32020 }
32021 Ok(())
32022 }
32023
32024 fn generate_row_format_property(&mut self, e: &RowFormatProperty) -> Result<()> {
32025 self.write_keyword("ROW FORMAT");
32027 self.write_space();
32028 self.generate_expression(&e.this)?;
32029 Ok(())
32030 }
32031
32032 fn generate_row_format_serde_property(&mut self, e: &RowFormatSerdeProperty) -> Result<()> {
32033 self.write_keyword("ROW FORMAT SERDE");
32035 self.write_space();
32036 self.generate_expression(&e.this)?;
32037 if let Some(props) = &e.serde_properties {
32038 self.write_space();
32039 self.generate_expression(props)?;
32041 }
32042 Ok(())
32043 }
32044
32045 fn generate_sha2(&mut self, e: &SHA2) -> Result<()> {
32046 self.write_keyword("SHA2");
32048 self.write("(");
32049 self.generate_expression(&e.this)?;
32050 if let Some(length) = e.length {
32051 self.write(", ");
32052 self.write(&length.to_string());
32053 }
32054 self.write(")");
32055 Ok(())
32056 }
32057
32058 fn generate_sha2_digest(&mut self, e: &SHA2Digest) -> Result<()> {
32059 self.write_keyword("SHA2_DIGEST");
32061 self.write("(");
32062 self.generate_expression(&e.this)?;
32063 if let Some(length) = e.length {
32064 self.write(", ");
32065 self.write(&length.to_string());
32066 }
32067 self.write(")");
32068 Ok(())
32069 }
32070
32071 fn generate_safe_add(&mut self, e: &SafeAdd) -> Result<()> {
32072 let name = if matches!(
32073 self.config.dialect,
32074 Some(crate::dialects::DialectType::Spark)
32075 | Some(crate::dialects::DialectType::Databricks)
32076 ) {
32077 "TRY_ADD"
32078 } else {
32079 "SAFE_ADD"
32080 };
32081 self.write_keyword(name);
32082 self.write("(");
32083 self.generate_expression(&e.this)?;
32084 self.write(", ");
32085 self.generate_expression(&e.expression)?;
32086 self.write(")");
32087 Ok(())
32088 }
32089
32090 fn generate_safe_divide(&mut self, e: &SafeDivide) -> Result<()> {
32091 self.write_keyword("SAFE_DIVIDE");
32093 self.write("(");
32094 self.generate_expression(&e.this)?;
32095 self.write(", ");
32096 self.generate_expression(&e.expression)?;
32097 self.write(")");
32098 Ok(())
32099 }
32100
32101 fn generate_safe_multiply(&mut self, e: &SafeMultiply) -> Result<()> {
32102 let name = if matches!(
32103 self.config.dialect,
32104 Some(crate::dialects::DialectType::Spark)
32105 | Some(crate::dialects::DialectType::Databricks)
32106 ) {
32107 "TRY_MULTIPLY"
32108 } else {
32109 "SAFE_MULTIPLY"
32110 };
32111 self.write_keyword(name);
32112 self.write("(");
32113 self.generate_expression(&e.this)?;
32114 self.write(", ");
32115 self.generate_expression(&e.expression)?;
32116 self.write(")");
32117 Ok(())
32118 }
32119
32120 fn generate_safe_subtract(&mut self, e: &SafeSubtract) -> Result<()> {
32121 let name = if matches!(
32122 self.config.dialect,
32123 Some(crate::dialects::DialectType::Spark)
32124 | Some(crate::dialects::DialectType::Databricks)
32125 ) {
32126 "TRY_SUBTRACT"
32127 } else {
32128 "SAFE_SUBTRACT"
32129 };
32130 self.write_keyword(name);
32131 self.write("(");
32132 self.generate_expression(&e.this)?;
32133 self.write(", ");
32134 self.generate_expression(&e.expression)?;
32135 self.write(")");
32136 Ok(())
32137 }
32138
32139 fn generate_sample_body(&mut self, sample: &Sample) -> Result<()> {
32142 if matches!(sample.method, SampleMethod::Bucket) {
32144 self.write(" (");
32145 self.write_keyword("BUCKET");
32146 self.write_space();
32147 if let Some(ref num) = sample.bucket_numerator {
32148 self.generate_expression(num)?;
32149 }
32150 self.write_space();
32151 self.write_keyword("OUT OF");
32152 self.write_space();
32153 if let Some(ref denom) = sample.bucket_denominator {
32154 self.generate_expression(denom)?;
32155 }
32156 if let Some(ref field) = sample.bucket_field {
32157 self.write_space();
32158 self.write_keyword("ON");
32159 self.write_space();
32160 self.generate_expression(field)?;
32161 }
32162 self.write(")");
32163 return Ok(());
32164 }
32165
32166 let is_snowflake = matches!(
32168 self.config.dialect,
32169 Some(crate::dialects::DialectType::Snowflake)
32170 );
32171 let is_postgres = matches!(
32172 self.config.dialect,
32173 Some(crate::dialects::DialectType::PostgreSQL)
32174 | Some(crate::dialects::DialectType::Redshift)
32175 );
32176 let is_databricks = matches!(
32178 self.config.dialect,
32179 Some(crate::dialects::DialectType::Databricks)
32180 );
32181 let is_spark = matches!(
32182 self.config.dialect,
32183 Some(crate::dialects::DialectType::Spark)
32184 );
32185 let suppress_method = is_databricks || is_spark || sample.suppress_method_output;
32186 let force_method = is_postgres && matches!(sample.method, SampleMethod::Bernoulli);
32188 if !suppress_method && (sample.explicit_method || is_snowflake || force_method) {
32189 self.write_space();
32190 if !sample.explicit_method && (is_snowflake || force_method) {
32191 self.write_keyword("BERNOULLI");
32193 } else {
32194 match sample.method {
32195 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
32196 SampleMethod::System => self.write_keyword("SYSTEM"),
32197 SampleMethod::Block => self.write_keyword("BLOCK"),
32198 SampleMethod::Row => self.write_keyword("ROW"),
32199 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
32200 SampleMethod::Percent => self.write_keyword("SYSTEM"),
32201 SampleMethod::Bucket => {} }
32203 }
32204 }
32205
32206 let emit_size_no_parens = !self.config.tablesample_requires_parens;
32208 if emit_size_no_parens {
32209 self.write_space();
32210 match &sample.size {
32211 Expression::Tuple(tuple) => {
32212 for (i, expr) in tuple.expressions.iter().enumerate() {
32213 if i > 0 {
32214 self.write(", ");
32215 }
32216 self.generate_expression(expr)?;
32217 }
32218 }
32219 expr => self.generate_expression(expr)?,
32220 }
32221 } else {
32222 self.write(" (");
32223 self.generate_expression(&sample.size)?;
32224 }
32225
32226 let is_rows_method = matches!(
32228 sample.method,
32229 SampleMethod::Reservoir | SampleMethod::Row | SampleMethod::Bucket
32230 );
32231 let is_percent = matches!(
32232 sample.method,
32233 SampleMethod::Percent
32234 | SampleMethod::System
32235 | SampleMethod::Bernoulli
32236 | SampleMethod::Block
32237 );
32238
32239 let is_presto = matches!(
32243 self.config.dialect,
32244 Some(crate::dialects::DialectType::Presto)
32245 | Some(crate::dialects::DialectType::Trino)
32246 | Some(crate::dialects::DialectType::Athena)
32247 );
32248 let should_output_unit = if is_databricks || is_spark {
32249 is_percent || is_rows_method || sample.unit_after_size
32251 } else if is_snowflake || is_postgres || is_presto {
32252 sample.unit_after_size
32253 } else {
32254 sample.unit_after_size || (sample.explicit_method && (is_rows_method || is_percent))
32255 };
32256
32257 if should_output_unit {
32258 self.write_space();
32259 if sample.is_percent {
32260 self.write_keyword("PERCENT");
32261 } else if is_rows_method && !sample.unit_after_size {
32262 self.write_keyword("ROWS");
32263 } else if sample.unit_after_size {
32264 match sample.method {
32265 SampleMethod::Percent
32266 | SampleMethod::System
32267 | SampleMethod::Bernoulli
32268 | SampleMethod::Block => {
32269 self.write_keyword("PERCENT");
32270 }
32271 SampleMethod::Row | SampleMethod::Reservoir => {
32272 self.write_keyword("ROWS");
32273 }
32274 _ => self.write_keyword("ROWS"),
32275 }
32276 } else {
32277 self.write_keyword("PERCENT");
32278 }
32279 }
32280
32281 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
32282 if let Some(ref offset) = sample.offset {
32283 self.write_space();
32284 self.write_keyword("OFFSET");
32285 self.write_space();
32286 self.generate_expression(offset)?;
32287 }
32288 }
32289 if !emit_size_no_parens {
32290 self.write(")");
32291 }
32292
32293 Ok(())
32294 }
32295
32296 fn generate_sample_property(&mut self, e: &SampleProperty) -> Result<()> {
32297 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
32299 self.write_keyword("SAMPLE BY");
32300 } else {
32301 self.write_keyword("SAMPLE");
32302 }
32303 self.write_space();
32304 self.generate_expression(&e.this)?;
32305 Ok(())
32306 }
32307
32308 fn generate_schema(&mut self, e: &Schema) -> Result<()> {
32309 if let Some(this) = &e.this {
32311 self.generate_expression(this)?;
32312 }
32313 if !e.expressions.is_empty() {
32314 if e.this.is_some() {
32316 self.write_space();
32317 }
32318 self.write("(");
32319 for (i, expr) in e.expressions.iter().enumerate() {
32320 if i > 0 {
32321 self.write(", ");
32322 }
32323 self.generate_expression(expr)?;
32324 }
32325 self.write(")");
32326 }
32327 Ok(())
32328 }
32329
32330 fn generate_schema_comment_property(&mut self, e: &SchemaCommentProperty) -> Result<()> {
32331 self.write_keyword("COMMENT");
32333 self.write_space();
32334 self.generate_expression(&e.this)?;
32335 Ok(())
32336 }
32337
32338 fn generate_scope_resolution(&mut self, e: &ScopeResolution) -> Result<()> {
32339 if let Some(this) = &e.this {
32341 self.generate_expression(this)?;
32342 self.write("::");
32343 }
32344 self.generate_expression(&e.expression)?;
32345 Ok(())
32346 }
32347
32348 fn generate_search(&mut self, e: &Search) -> Result<()> {
32349 self.write_keyword("SEARCH");
32351 self.write("(");
32352 self.generate_expression(&e.this)?;
32353 self.write(", ");
32354 self.generate_expression(&e.expression)?;
32355 if let Some(json_scope) = &e.json_scope {
32356 self.write(", ");
32357 self.generate_expression(json_scope)?;
32358 }
32359 if let Some(analyzer) = &e.analyzer {
32360 self.write(", ");
32361 self.generate_expression(analyzer)?;
32362 }
32363 if let Some(analyzer_options) = &e.analyzer_options {
32364 self.write(", ");
32365 self.generate_expression(analyzer_options)?;
32366 }
32367 if let Some(search_mode) = &e.search_mode {
32368 self.write(", ");
32369 self.generate_expression(search_mode)?;
32370 }
32371 self.write(")");
32372 Ok(())
32373 }
32374
32375 fn generate_search_ip(&mut self, e: &SearchIp) -> Result<()> {
32376 self.write_keyword("SEARCH_IP");
32378 self.write("(");
32379 self.generate_expression(&e.this)?;
32380 self.write(", ");
32381 self.generate_expression(&e.expression)?;
32382 self.write(")");
32383 Ok(())
32384 }
32385
32386 fn generate_security_property(&mut self, e: &SecurityProperty) -> Result<()> {
32387 self.write_keyword("SECURITY");
32389 self.write_space();
32390 self.generate_expression(&e.this)?;
32391 Ok(())
32392 }
32393
32394 fn generate_semantic_view(&mut self, e: &SemanticView) -> Result<()> {
32395 self.write("SEMANTIC_VIEW(");
32397
32398 if self.config.pretty {
32399 self.write_newline();
32401 self.indent_level += 1;
32402 self.write_indent();
32403 self.generate_expression(&e.this)?;
32404
32405 if let Some(metrics) = &e.metrics {
32406 self.write_newline();
32407 self.write_indent();
32408 self.write_keyword("METRICS");
32409 self.write_space();
32410 self.generate_semantic_view_tuple(metrics)?;
32411 }
32412 if let Some(dimensions) = &e.dimensions {
32413 self.write_newline();
32414 self.write_indent();
32415 self.write_keyword("DIMENSIONS");
32416 self.write_space();
32417 self.generate_semantic_view_tuple(dimensions)?;
32418 }
32419 if let Some(facts) = &e.facts {
32420 self.write_newline();
32421 self.write_indent();
32422 self.write_keyword("FACTS");
32423 self.write_space();
32424 self.generate_semantic_view_tuple(facts)?;
32425 }
32426 if let Some(where_) = &e.where_ {
32427 self.write_newline();
32428 self.write_indent();
32429 self.write_keyword("WHERE");
32430 self.write_space();
32431 self.generate_expression(where_)?;
32432 }
32433 self.write_newline();
32434 self.indent_level -= 1;
32435 self.write_indent();
32436 } else {
32437 self.generate_expression(&e.this)?;
32439 if let Some(metrics) = &e.metrics {
32440 self.write_space();
32441 self.write_keyword("METRICS");
32442 self.write_space();
32443 self.generate_semantic_view_tuple(metrics)?;
32444 }
32445 if let Some(dimensions) = &e.dimensions {
32446 self.write_space();
32447 self.write_keyword("DIMENSIONS");
32448 self.write_space();
32449 self.generate_semantic_view_tuple(dimensions)?;
32450 }
32451 if let Some(facts) = &e.facts {
32452 self.write_space();
32453 self.write_keyword("FACTS");
32454 self.write_space();
32455 self.generate_semantic_view_tuple(facts)?;
32456 }
32457 if let Some(where_) = &e.where_ {
32458 self.write_space();
32459 self.write_keyword("WHERE");
32460 self.write_space();
32461 self.generate_expression(where_)?;
32462 }
32463 }
32464 self.write(")");
32465 Ok(())
32466 }
32467
32468 fn generate_semantic_view_tuple(&mut self, expr: &Expression) -> Result<()> {
32470 if let Expression::Tuple(t) = expr {
32471 for (i, e) in t.expressions.iter().enumerate() {
32472 if i > 0 {
32473 self.write(", ");
32474 }
32475 self.generate_expression(e)?;
32476 }
32477 } else {
32478 self.generate_expression(expr)?;
32479 }
32480 Ok(())
32481 }
32482
32483 fn generate_sequence_properties(&mut self, e: &SequenceProperties) -> Result<()> {
32484 if let Some(start) = &e.start {
32486 self.write_keyword("START WITH");
32487 self.write_space();
32488 self.generate_expression(start)?;
32489 }
32490 if let Some(increment) = &e.increment {
32491 self.write_space();
32492 self.write_keyword("INCREMENT BY");
32493 self.write_space();
32494 self.generate_expression(increment)?;
32495 }
32496 if let Some(minvalue) = &e.minvalue {
32497 self.write_space();
32498 self.write_keyword("MINVALUE");
32499 self.write_space();
32500 self.generate_expression(minvalue)?;
32501 }
32502 if let Some(maxvalue) = &e.maxvalue {
32503 self.write_space();
32504 self.write_keyword("MAXVALUE");
32505 self.write_space();
32506 self.generate_expression(maxvalue)?;
32507 }
32508 if let Some(cache) = &e.cache {
32509 self.write_space();
32510 self.write_keyword("CACHE");
32511 self.write_space();
32512 self.generate_expression(cache)?;
32513 }
32514 if let Some(owned) = &e.owned {
32515 self.write_space();
32516 self.write_keyword("OWNED BY");
32517 self.write_space();
32518 self.generate_expression(owned)?;
32519 }
32520 for opt in &e.options {
32521 self.write_space();
32522 self.generate_expression(opt)?;
32523 }
32524 Ok(())
32525 }
32526
32527 fn generate_serde_properties(&mut self, e: &SerdeProperties) -> Result<()> {
32528 if e.with_.is_some() {
32530 self.write_keyword("WITH");
32531 self.write_space();
32532 }
32533 self.write_keyword("SERDEPROPERTIES");
32534 self.write(" (");
32535 for (i, expr) in e.expressions.iter().enumerate() {
32536 if i > 0 {
32537 self.write(", ");
32538 }
32539 match expr {
32541 Expression::Eq(eq) => {
32542 self.generate_expression(&eq.left)?;
32543 self.write("=");
32544 self.generate_expression(&eq.right)?;
32545 }
32546 _ => self.generate_expression(expr)?,
32547 }
32548 }
32549 self.write(")");
32550 Ok(())
32551 }
32552
32553 fn generate_session_parameter(&mut self, e: &SessionParameter) -> Result<()> {
32554 self.write("@@");
32556 if let Some(kind) = &e.kind {
32557 self.write(kind);
32558 self.write(".");
32559 }
32560 self.generate_expression(&e.this)?;
32561 Ok(())
32562 }
32563
32564 fn generate_set(&mut self, e: &Set) -> Result<()> {
32565 if e.unset.is_some() {
32567 self.write_keyword("UNSET");
32568 } else {
32569 self.write_keyword("SET");
32570 }
32571 if e.tag.is_some() {
32572 self.write_space();
32573 self.write_keyword("TAG");
32574 }
32575 if !e.expressions.is_empty() {
32576 self.write_space();
32577 for (i, expr) in e.expressions.iter().enumerate() {
32578 if i > 0 {
32579 self.write(", ");
32580 }
32581 self.generate_expression(expr)?;
32582 }
32583 }
32584 Ok(())
32585 }
32586
32587 fn generate_set_config_property(&mut self, e: &SetConfigProperty) -> Result<()> {
32588 self.write_keyword("SET");
32590 self.write_space();
32591 self.generate_expression(&e.this)?;
32592 Ok(())
32593 }
32594
32595 fn generate_set_item(&mut self, e: &SetItem) -> Result<()> {
32596 if let Some(kind) = &e.kind {
32598 self.write_keyword(kind);
32599 self.write_space();
32600 }
32601 self.generate_expression(&e.name)?;
32602 self.write(" = ");
32603 self.generate_expression(&e.value)?;
32604 Ok(())
32605 }
32606
32607 fn generate_set_operation(&mut self, e: &SetOperation) -> Result<()> {
32608 if let Some(with_) = &e.with_ {
32610 self.generate_expression(with_)?;
32611 self.write_space();
32612 }
32613 self.generate_expression(&e.this)?;
32614 self.write_space();
32615 if let Some(kind) = &e.kind {
32617 self.write_keyword(kind);
32618 }
32619 if e.distinct {
32620 self.write_space();
32621 self.write_keyword("DISTINCT");
32622 } else {
32623 self.write_space();
32624 self.write_keyword("ALL");
32625 }
32626 if e.by_name.is_some() {
32627 self.write_space();
32628 self.write_keyword("BY NAME");
32629 }
32630 self.write_space();
32631 self.generate_expression(&e.expression)?;
32632 Ok(())
32633 }
32634
32635 fn generate_set_property(&mut self, e: &SetProperty) -> Result<()> {
32636 if e.multi.is_some() {
32638 self.write_keyword("MULTISET");
32639 } else {
32640 self.write_keyword("SET");
32641 }
32642 Ok(())
32643 }
32644
32645 fn generate_settings_property(&mut self, e: &SettingsProperty) -> Result<()> {
32646 self.write_keyword("SETTINGS");
32648 if self.config.pretty && e.expressions.len() > 1 {
32649 self.indent_level += 1;
32651 for (i, expr) in e.expressions.iter().enumerate() {
32652 if i > 0 {
32653 self.write(",");
32654 }
32655 self.write_newline();
32656 self.write_indent();
32657 self.generate_expression(expr)?;
32658 }
32659 self.indent_level -= 1;
32660 } else {
32661 self.write_space();
32662 for (i, expr) in e.expressions.iter().enumerate() {
32663 if i > 0 {
32664 self.write(", ");
32665 }
32666 self.generate_expression(expr)?;
32667 }
32668 }
32669 Ok(())
32670 }
32671
32672 fn generate_sharing_property(&mut self, e: &SharingProperty) -> Result<()> {
32673 self.write_keyword("SHARING");
32675 if let Some(this) = &e.this {
32676 self.write(" = ");
32677 self.generate_expression(this)?;
32678 }
32679 Ok(())
32680 }
32681
32682 fn generate_slice(&mut self, e: &Slice) -> Result<()> {
32683 if let Some(begin) = &e.this {
32685 self.generate_expression(begin)?;
32686 }
32687 self.write(":");
32688 if let Some(end) = &e.expression {
32689 self.generate_expression(end)?;
32690 }
32691 if let Some(step) = &e.step {
32692 self.write(":");
32693 self.generate_expression(step)?;
32694 }
32695 Ok(())
32696 }
32697
32698 fn generate_sort_array(&mut self, e: &SortArray) -> Result<()> {
32699 self.write_keyword("SORT_ARRAY");
32701 self.write("(");
32702 self.generate_expression(&e.this)?;
32703 if let Some(asc) = &e.asc {
32704 self.write(", ");
32705 self.generate_expression(asc)?;
32706 }
32707 self.write(")");
32708 Ok(())
32709 }
32710
32711 fn generate_sort_by(&mut self, e: &SortBy) -> Result<()> {
32712 self.write_keyword("SORT BY");
32714 self.write_space();
32715 for (i, expr) in e.expressions.iter().enumerate() {
32716 if i > 0 {
32717 self.write(", ");
32718 }
32719 self.generate_ordered(expr)?;
32720 }
32721 Ok(())
32722 }
32723
32724 fn generate_sort_key_property(&mut self, e: &SortKeyProperty) -> Result<()> {
32725 if e.compound.is_some() {
32727 self.write_keyword("COMPOUND");
32728 self.write_space();
32729 }
32730 self.write_keyword("SORTKEY");
32731 self.write("(");
32732 if let Expression::Tuple(t) = e.this.as_ref() {
32734 for (i, expr) in t.expressions.iter().enumerate() {
32735 if i > 0 {
32736 self.write(", ");
32737 }
32738 self.generate_expression(expr)?;
32739 }
32740 } else {
32741 self.generate_expression(&e.this)?;
32742 }
32743 self.write(")");
32744 Ok(())
32745 }
32746
32747 fn generate_split_part(&mut self, e: &SplitPart) -> Result<()> {
32748 self.write_keyword("SPLIT_PART");
32750 self.write("(");
32751 self.generate_expression(&e.this)?;
32752 if let Some(delimiter) = &e.delimiter {
32753 self.write(", ");
32754 self.generate_expression(delimiter)?;
32755 }
32756 if let Some(part_index) = &e.part_index {
32757 self.write(", ");
32758 self.generate_expression(part_index)?;
32759 }
32760 self.write(")");
32761 Ok(())
32762 }
32763
32764 fn generate_sql_read_write_property(&mut self, e: &SqlReadWriteProperty) -> Result<()> {
32765 self.generate_expression(&e.this)?;
32767 Ok(())
32768 }
32769
32770 fn generate_sql_security_property(&mut self, e: &SqlSecurityProperty) -> Result<()> {
32771 self.write_keyword("SQL SECURITY");
32773 self.write_space();
32774 self.generate_expression(&e.this)?;
32775 Ok(())
32776 }
32777
32778 fn generate_st_distance(&mut self, e: &StDistance) -> Result<()> {
32779 self.write_keyword("ST_DISTANCE");
32781 self.write("(");
32782 self.generate_expression(&e.this)?;
32783 self.write(", ");
32784 self.generate_expression(&e.expression)?;
32785 if let Some(use_spheroid) = &e.use_spheroid {
32786 self.write(", ");
32787 self.generate_expression(use_spheroid)?;
32788 }
32789 self.write(")");
32790 Ok(())
32791 }
32792
32793 fn generate_st_point(&mut self, e: &StPoint) -> Result<()> {
32794 self.write_keyword("ST_POINT");
32796 self.write("(");
32797 self.generate_expression(&e.this)?;
32798 self.write(", ");
32799 self.generate_expression(&e.expression)?;
32800 self.write(")");
32801 Ok(())
32802 }
32803
32804 fn generate_stability_property(&mut self, e: &StabilityProperty) -> Result<()> {
32805 self.generate_expression(&e.this)?;
32807 Ok(())
32808 }
32809
32810 fn generate_standard_hash(&mut self, e: &StandardHash) -> Result<()> {
32811 self.write_keyword("STANDARD_HASH");
32813 self.write("(");
32814 self.generate_expression(&e.this)?;
32815 if let Some(expression) = &e.expression {
32816 self.write(", ");
32817 self.generate_expression(expression)?;
32818 }
32819 self.write(")");
32820 Ok(())
32821 }
32822
32823 fn generate_storage_handler_property(&mut self, e: &StorageHandlerProperty) -> Result<()> {
32824 self.write_keyword("STORED BY");
32826 self.write_space();
32827 self.generate_expression(&e.this)?;
32828 Ok(())
32829 }
32830
32831 fn generate_str_position(&mut self, e: &StrPosition) -> Result<()> {
32832 use crate::dialects::DialectType;
32835 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
32836 self.write_keyword("CHARINDEX");
32838 self.write("(");
32839 if let Some(substr) = &e.substr {
32840 self.generate_expression(substr)?;
32841 self.write(", ");
32842 }
32843 self.generate_expression(&e.this)?;
32844 if let Some(position) = &e.position {
32845 self.write(", ");
32846 self.generate_expression(position)?;
32847 }
32848 self.write(")");
32849 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
32850 self.write_keyword("POSITION");
32851 self.write("(");
32852 self.generate_expression(&e.this)?;
32853 if let Some(substr) = &e.substr {
32854 self.write(", ");
32855 self.generate_expression(substr)?;
32856 }
32857 if let Some(position) = &e.position {
32858 self.write(", ");
32859 self.generate_expression(position)?;
32860 }
32861 if let Some(occurrence) = &e.occurrence {
32862 self.write(", ");
32863 self.generate_expression(occurrence)?;
32864 }
32865 self.write(")");
32866 } else if matches!(
32867 self.config.dialect,
32868 Some(DialectType::SQLite)
32869 | Some(DialectType::Oracle)
32870 | Some(DialectType::BigQuery)
32871 | Some(DialectType::Teradata)
32872 ) {
32873 self.write_keyword("INSTR");
32874 self.write("(");
32875 self.generate_expression(&e.this)?;
32876 if let Some(substr) = &e.substr {
32877 self.write(", ");
32878 self.generate_expression(substr)?;
32879 }
32880 if let Some(position) = &e.position {
32881 self.write(", ");
32882 self.generate_expression(position)?;
32883 } else if e.occurrence.is_some() {
32884 self.write(", 1");
32887 }
32888 if let Some(occurrence) = &e.occurrence {
32889 self.write(", ");
32890 self.generate_expression(occurrence)?;
32891 }
32892 self.write(")");
32893 } else if matches!(
32894 self.config.dialect,
32895 Some(DialectType::MySQL)
32896 | Some(DialectType::SingleStore)
32897 | Some(DialectType::Doris)
32898 | Some(DialectType::StarRocks)
32899 | Some(DialectType::Hive)
32900 | Some(DialectType::Spark)
32901 | Some(DialectType::Databricks)
32902 ) {
32903 self.write_keyword("LOCATE");
32905 self.write("(");
32906 if let Some(substr) = &e.substr {
32907 self.generate_expression(substr)?;
32908 self.write(", ");
32909 }
32910 self.generate_expression(&e.this)?;
32911 if let Some(position) = &e.position {
32912 self.write(", ");
32913 self.generate_expression(position)?;
32914 }
32915 self.write(")");
32916 } else if matches!(self.config.dialect, Some(DialectType::TSQL)) {
32917 self.write_keyword("CHARINDEX");
32919 self.write("(");
32920 if let Some(substr) = &e.substr {
32921 self.generate_expression(substr)?;
32922 self.write(", ");
32923 }
32924 self.generate_expression(&e.this)?;
32925 if let Some(position) = &e.position {
32926 self.write(", ");
32927 self.generate_expression(position)?;
32928 }
32929 self.write(")");
32930 } else if matches!(
32931 self.config.dialect,
32932 Some(DialectType::PostgreSQL)
32933 | Some(DialectType::Materialize)
32934 | Some(DialectType::RisingWave)
32935 | Some(DialectType::Redshift)
32936 ) {
32937 self.write_keyword("POSITION");
32939 self.write("(");
32940 if let Some(substr) = &e.substr {
32941 self.generate_expression(substr)?;
32942 self.write(" IN ");
32943 }
32944 self.generate_expression(&e.this)?;
32945 self.write(")");
32946 } else {
32947 self.write_keyword("STRPOS");
32948 self.write("(");
32949 self.generate_expression(&e.this)?;
32950 if let Some(substr) = &e.substr {
32951 self.write(", ");
32952 self.generate_expression(substr)?;
32953 }
32954 if let Some(position) = &e.position {
32955 self.write(", ");
32956 self.generate_expression(position)?;
32957 }
32958 if let Some(occurrence) = &e.occurrence {
32959 self.write(", ");
32960 self.generate_expression(occurrence)?;
32961 }
32962 self.write(")");
32963 }
32964 Ok(())
32965 }
32966
32967 fn generate_str_to_date(&mut self, e: &StrToDate) -> Result<()> {
32968 match self.config.dialect {
32969 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
32970 self.write_keyword("TO_DATE");
32972 self.write("(");
32973 self.generate_expression(&e.this)?;
32974 if let Some(format) = &e.format {
32975 self.write(", '");
32976 self.write(&Self::strftime_to_java_format(format));
32977 self.write("'");
32978 }
32979 self.write(")");
32980 }
32981 Some(DialectType::DuckDB) => {
32982 self.write_keyword("CAST");
32984 self.write("(");
32985 self.write_keyword("STRPTIME");
32986 self.write("(");
32987 self.generate_expression(&e.this)?;
32988 if let Some(format) = &e.format {
32989 self.write(", '");
32990 self.write(format);
32991 self.write("'");
32992 }
32993 self.write(")");
32994 self.write_keyword(" AS ");
32995 self.write_keyword("DATE");
32996 self.write(")");
32997 }
32998 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
32999 self.write_keyword("TO_DATE");
33001 self.write("(");
33002 self.generate_expression(&e.this)?;
33003 if let Some(format) = &e.format {
33004 self.write(", '");
33005 self.write(&Self::strftime_to_postgres_format(format));
33006 self.write("'");
33007 }
33008 self.write(")");
33009 }
33010 Some(DialectType::BigQuery) => {
33011 self.write_keyword("PARSE_DATE");
33013 self.write("(");
33014 if let Some(format) = &e.format {
33015 self.write("'");
33016 self.write(format);
33017 self.write("'");
33018 self.write(", ");
33019 }
33020 self.generate_expression(&e.this)?;
33021 self.write(")");
33022 }
33023 Some(DialectType::Teradata) => {
33024 self.write_keyword("CAST");
33026 self.write("(");
33027 self.generate_expression(&e.this)?;
33028 self.write_keyword(" AS ");
33029 self.write_keyword("DATE");
33030 if let Some(format) = &e.format {
33031 self.write_keyword(" FORMAT ");
33032 self.write("'");
33033 self.write(&Self::strftime_to_teradata_format(format));
33034 self.write("'");
33035 }
33036 self.write(")");
33037 }
33038 _ => {
33039 self.write_keyword("STR_TO_DATE");
33041 self.write("(");
33042 self.generate_expression(&e.this)?;
33043 if let Some(format) = &e.format {
33044 self.write(", '");
33045 self.write(format);
33046 self.write("'");
33047 }
33048 self.write(")");
33049 }
33050 }
33051 Ok(())
33052 }
33053
33054 fn strftime_to_teradata_format(fmt: &str) -> String {
33056 let mut result = fmt.to_string();
33057 result = result.replace("%Y", "YYYY");
33058 result = result.replace("%y", "YY");
33059 result = result.replace("%m", "MM");
33060 result = result.replace("%B", "MMMM");
33061 result = result.replace("%b", "MMM");
33062 result = result.replace("%d", "DD");
33063 result = result.replace("%j", "DDD");
33064 result = result.replace("%H", "HH");
33065 result = result.replace("%M", "MI");
33066 result = result.replace("%S", "SS");
33067 result = result.replace("%f", "SSSSSS");
33068 result = result.replace("%A", "EEEE");
33069 result = result.replace("%a", "EEE");
33070 result
33071 }
33072
33073 pub fn strftime_to_java_format_static(fmt: &str) -> String {
33076 Self::strftime_to_java_format(fmt)
33077 }
33078
33079 fn strftime_to_java_format(fmt: &str) -> String {
33081 let mut result = fmt.to_string();
33082 result = result.replace("%-d", "d");
33084 result = result.replace("%-m", "M");
33085 result = result.replace("%-H", "H");
33086 result = result.replace("%-M", "m");
33087 result = result.replace("%-S", "s");
33088 result = result.replace("%Y", "yyyy");
33089 result = result.replace("%y", "yy");
33090 result = result.replace("%m", "MM");
33091 result = result.replace("%B", "MMMM");
33092 result = result.replace("%b", "MMM");
33093 result = result.replace("%d", "dd");
33094 result = result.replace("%j", "DDD");
33095 result = result.replace("%H", "HH");
33096 result = result.replace("%M", "mm");
33097 result = result.replace("%S", "ss");
33098 result = result.replace("%f", "SSSSSS");
33099 result = result.replace("%A", "EEEE");
33100 result = result.replace("%a", "EEE");
33101 result
33102 }
33103
33104 fn strftime_to_tsql_format(fmt: &str) -> String {
33107 let mut result = fmt.to_string();
33108 result = result.replace("%-d", "d");
33110 result = result.replace("%-m", "M");
33111 result = result.replace("%-H", "H");
33112 result = result.replace("%-M", "m");
33113 result = result.replace("%-S", "s");
33114 result = result.replace("%Y", "yyyy");
33115 result = result.replace("%y", "yy");
33116 result = result.replace("%m", "MM");
33117 result = result.replace("%B", "MMMM");
33118 result = result.replace("%b", "MMM");
33119 result = result.replace("%d", "dd");
33120 result = result.replace("%j", "DDD");
33121 result = result.replace("%H", "HH");
33122 result = result.replace("%M", "mm");
33123 result = result.replace("%S", "ss");
33124 result = result.replace("%f", "ffffff");
33125 result = result.replace("%A", "dddd");
33126 result = result.replace("%a", "ddd");
33127 result
33128 }
33129
33130 fn decompose_json_path(path: &str) -> Vec<String> {
33133 let mut parts = Vec::new();
33134 let path = if path.starts_with("$.") {
33136 &path[2..]
33137 } else if path.starts_with('$') {
33138 &path[1..]
33139 } else {
33140 path
33141 };
33142 if path.is_empty() {
33143 return parts;
33144 }
33145 let mut current = String::new();
33146 let chars: Vec<char> = path.chars().collect();
33147 let mut i = 0;
33148 while i < chars.len() {
33149 match chars[i] {
33150 '.' => {
33151 if !current.is_empty() {
33152 parts.push(current.clone());
33153 current.clear();
33154 }
33155 i += 1;
33156 }
33157 '[' => {
33158 if !current.is_empty() {
33159 parts.push(current.clone());
33160 current.clear();
33161 }
33162 i += 1;
33163 let mut bracket_content = String::new();
33165 while i < chars.len() && chars[i] != ']' {
33166 if chars[i] == '"' || chars[i] == '\'' {
33168 let quote = chars[i];
33169 i += 1;
33170 while i < chars.len() && chars[i] != quote {
33171 bracket_content.push(chars[i]);
33172 i += 1;
33173 }
33174 if i < chars.len() {
33175 i += 1;
33176 } } else {
33178 bracket_content.push(chars[i]);
33179 i += 1;
33180 }
33181 }
33182 if i < chars.len() {
33183 i += 1;
33184 } if bracket_content != "*" {
33187 parts.push(bracket_content);
33188 }
33189 }
33190 _ => {
33191 current.push(chars[i]);
33192 i += 1;
33193 }
33194 }
33195 }
33196 if !current.is_empty() {
33197 parts.push(current);
33198 }
33199 parts
33200 }
33201
33202 fn strftime_to_postgres_format(fmt: &str) -> String {
33204 let mut result = fmt.to_string();
33205 result = result.replace("%-d", "FMDD");
33207 result = result.replace("%-m", "FMMM");
33208 result = result.replace("%-H", "FMHH24");
33209 result = result.replace("%-M", "FMMI");
33210 result = result.replace("%-S", "FMSS");
33211 result = result.replace("%Y", "YYYY");
33212 result = result.replace("%y", "YY");
33213 result = result.replace("%m", "MM");
33214 result = result.replace("%B", "Month");
33215 result = result.replace("%b", "Mon");
33216 result = result.replace("%d", "DD");
33217 result = result.replace("%j", "DDD");
33218 result = result.replace("%H", "HH24");
33219 result = result.replace("%M", "MI");
33220 result = result.replace("%S", "SS");
33221 result = result.replace("%f", "US");
33222 result = result.replace("%A", "Day");
33223 result = result.replace("%a", "Dy");
33224 result
33225 }
33226
33227 fn strftime_to_snowflake_format(fmt: &str) -> String {
33229 let mut result = fmt.to_string();
33230 result = result.replace("%-d", "dd");
33232 result = result.replace("%-m", "mm"); result = result.replace("%Y", "yyyy");
33234 result = result.replace("%y", "yy");
33235 result = result.replace("%m", "mm");
33236 result = result.replace("%d", "DD");
33237 result = result.replace("%H", "hh24");
33238 result = result.replace("%M", "mi");
33239 result = result.replace("%S", "ss");
33240 result = result.replace("%f", "ff");
33241 result
33242 }
33243
33244 fn generate_str_to_map(&mut self, e: &StrToMap) -> Result<()> {
33245 self.write_keyword("STR_TO_MAP");
33247 self.write("(");
33248 self.generate_expression(&e.this)?;
33249 let needs_defaults = matches!(
33251 self.config.dialect,
33252 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
33253 );
33254 if let Some(pair_delim) = &e.pair_delim {
33255 self.write(", ");
33256 self.generate_expression(pair_delim)?;
33257 } else if needs_defaults {
33258 self.write(", ','");
33259 }
33260 if let Some(key_value_delim) = &e.key_value_delim {
33261 self.write(", ");
33262 self.generate_expression(key_value_delim)?;
33263 } else if needs_defaults {
33264 self.write(", ':'");
33265 }
33266 self.write(")");
33267 Ok(())
33268 }
33269
33270 fn generate_str_to_time(&mut self, e: &StrToTime) -> Result<()> {
33271 let is_strftime = e.format.contains('%');
33273 let to_strftime = |f: &str| -> String {
33275 if is_strftime {
33276 f.to_string()
33277 } else {
33278 Self::snowflake_format_to_strftime(f)
33279 }
33280 };
33281 let to_java = |f: &str| -> String {
33283 if is_strftime {
33284 Self::strftime_to_java_format(f)
33285 } else {
33286 Self::snowflake_format_to_spark(f)
33287 }
33288 };
33289 let to_pg = |f: &str| -> String {
33291 if is_strftime {
33292 Self::strftime_to_postgres_format(f)
33293 } else {
33294 Self::convert_strptime_to_postgres_format(f)
33295 }
33296 };
33297
33298 match self.config.dialect {
33299 Some(DialectType::Exasol) => {
33300 self.write_keyword("TO_DATE");
33301 self.write("(");
33302 self.generate_expression(&e.this)?;
33303 self.write(", '");
33304 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
33305 self.write("'");
33306 self.write(")");
33307 }
33308 Some(DialectType::BigQuery) => {
33309 let fmt = to_strftime(&e.format);
33311 let fmt = fmt.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
33313 self.write_keyword("PARSE_TIMESTAMP");
33314 self.write("('");
33315 self.write(&fmt);
33316 self.write("', ");
33317 self.generate_expression(&e.this)?;
33318 self.write(")");
33319 }
33320 Some(DialectType::Hive) => {
33321 let java_fmt = to_java(&e.format);
33324 if java_fmt == "yyyy-MM-dd HH:mm:ss"
33325 || java_fmt == "yyyy-MM-dd"
33326 || e.format == "yyyy-MM-dd HH:mm:ss"
33327 || e.format == "yyyy-MM-dd"
33328 {
33329 self.write_keyword("CAST");
33330 self.write("(");
33331 self.generate_expression(&e.this)?;
33332 self.write(" ");
33333 self.write_keyword("AS TIMESTAMP");
33334 self.write(")");
33335 } else {
33336 self.write_keyword("CAST");
33338 self.write("(");
33339 self.write_keyword("FROM_UNIXTIME");
33340 self.write("(");
33341 self.write_keyword("UNIX_TIMESTAMP");
33342 self.write("(");
33343 self.generate_expression(&e.this)?;
33344 self.write(", '");
33345 self.write(&java_fmt);
33346 self.write("')");
33347 self.write(") ");
33348 self.write_keyword("AS TIMESTAMP");
33349 self.write(")");
33350 }
33351 }
33352 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
33353 let java_fmt = to_java(&e.format);
33355 self.write_keyword("TO_TIMESTAMP");
33356 self.write("(");
33357 self.generate_expression(&e.this)?;
33358 self.write(", '");
33359 self.write(&java_fmt);
33360 self.write("')");
33361 }
33362 Some(DialectType::MySQL) => {
33363 let mut fmt = to_strftime(&e.format);
33365 fmt = fmt.replace("%-d", "%e");
33367 fmt = fmt.replace("%-m", "%c");
33368 fmt = fmt.replace("%H:%M:%S", "%T");
33369 self.write_keyword("STR_TO_DATE");
33370 self.write("(");
33371 self.generate_expression(&e.this)?;
33372 self.write(", '");
33373 self.write(&fmt);
33374 self.write("')");
33375 }
33376 Some(DialectType::Drill) => {
33377 let java_fmt = to_java(&e.format);
33379 let java_fmt = java_fmt.replace('T', "''T''");
33381 self.write_keyword("TO_TIMESTAMP");
33382 self.write("(");
33383 self.generate_expression(&e.this)?;
33384 self.write(", '");
33385 self.write(&java_fmt);
33386 self.write("')");
33387 }
33388 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
33389 let mut fmt = to_strftime(&e.format);
33391 fmt = fmt.replace("%-d", "%e");
33393 fmt = fmt.replace("%-m", "%c");
33394 fmt = fmt.replace("%H:%M:%S", "%T");
33395 self.write_keyword("DATE_PARSE");
33396 self.write("(");
33397 self.generate_expression(&e.this)?;
33398 self.write(", '");
33399 self.write(&fmt);
33400 self.write("')");
33401 }
33402 Some(DialectType::DuckDB) => {
33403 let fmt = to_strftime(&e.format);
33405 self.write_keyword("STRPTIME");
33406 self.write("(");
33407 self.generate_expression(&e.this)?;
33408 self.write(", '");
33409 self.write(&fmt);
33410 self.write("')");
33411 }
33412 Some(DialectType::PostgreSQL)
33413 | Some(DialectType::Redshift)
33414 | Some(DialectType::Materialize) => {
33415 let pg_fmt = to_pg(&e.format);
33417 self.write_keyword("TO_TIMESTAMP");
33418 self.write("(");
33419 self.generate_expression(&e.this)?;
33420 self.write(", '");
33421 self.write(&pg_fmt);
33422 self.write("')");
33423 }
33424 Some(DialectType::Oracle) => {
33425 let pg_fmt = to_pg(&e.format);
33427 self.write_keyword("TO_TIMESTAMP");
33428 self.write("(");
33429 self.generate_expression(&e.this)?;
33430 self.write(", '");
33431 self.write(&pg_fmt);
33432 self.write("')");
33433 }
33434 Some(DialectType::Snowflake) => {
33435 self.write_keyword("TO_TIMESTAMP");
33437 self.write("(");
33438 self.generate_expression(&e.this)?;
33439 self.write(", '");
33440 self.write(&e.format);
33441 self.write("')");
33442 }
33443 _ => {
33444 self.write_keyword("STR_TO_TIME");
33446 self.write("(");
33447 self.generate_expression(&e.this)?;
33448 self.write(", '");
33449 self.write(&e.format);
33450 self.write("'");
33451 self.write(")");
33452 }
33453 }
33454 Ok(())
33455 }
33456
33457 fn snowflake_format_to_strftime(format: &str) -> String {
33459 let mut result = String::new();
33460 let chars: Vec<char> = format.chars().collect();
33461 let mut i = 0;
33462 while i < chars.len() {
33463 let remaining = &format[i..];
33464 if remaining.starts_with("yyyy") {
33465 result.push_str("%Y");
33466 i += 4;
33467 } else if remaining.starts_with("yy") {
33468 result.push_str("%y");
33469 i += 2;
33470 } else if remaining.starts_with("mmmm") {
33471 result.push_str("%B"); i += 4;
33473 } else if remaining.starts_with("mon") {
33474 result.push_str("%b"); i += 3;
33476 } else if remaining.starts_with("mm") {
33477 result.push_str("%m");
33478 i += 2;
33479 } else if remaining.starts_with("DD") {
33480 result.push_str("%d");
33481 i += 2;
33482 } else if remaining.starts_with("dy") {
33483 result.push_str("%a"); i += 2;
33485 } else if remaining.starts_with("hh24") {
33486 result.push_str("%H");
33487 i += 4;
33488 } else if remaining.starts_with("hh12") {
33489 result.push_str("%I");
33490 i += 4;
33491 } else if remaining.starts_with("hh") {
33492 result.push_str("%H");
33493 i += 2;
33494 } else if remaining.starts_with("mi") {
33495 result.push_str("%M");
33496 i += 2;
33497 } else if remaining.starts_with("ss") {
33498 result.push_str("%S");
33499 i += 2;
33500 } else if remaining.starts_with("ff") {
33501 result.push_str("%f");
33503 i += 2;
33504 while i < chars.len() && chars[i].is_ascii_digit() {
33506 i += 1;
33507 }
33508 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
33509 result.push_str("%p");
33510 i += 2;
33511 } else if remaining.starts_with("tz") {
33512 result.push_str("%Z");
33513 i += 2;
33514 } else {
33515 result.push(chars[i]);
33516 i += 1;
33517 }
33518 }
33519 result
33520 }
33521
33522 fn snowflake_format_to_spark(format: &str) -> String {
33524 let mut result = String::new();
33525 let chars: Vec<char> = format.chars().collect();
33526 let mut i = 0;
33527 while i < chars.len() {
33528 let remaining = &format[i..];
33529 if remaining.starts_with("yyyy") {
33530 result.push_str("yyyy");
33531 i += 4;
33532 } else if remaining.starts_with("yy") {
33533 result.push_str("yy");
33534 i += 2;
33535 } else if remaining.starts_with("mmmm") {
33536 result.push_str("MMMM"); i += 4;
33538 } else if remaining.starts_with("mon") {
33539 result.push_str("MMM"); i += 3;
33541 } else if remaining.starts_with("mm") {
33542 result.push_str("MM");
33543 i += 2;
33544 } else if remaining.starts_with("DD") {
33545 result.push_str("dd");
33546 i += 2;
33547 } else if remaining.starts_with("dy") {
33548 result.push_str("EEE"); i += 2;
33550 } else if remaining.starts_with("hh24") {
33551 result.push_str("HH");
33552 i += 4;
33553 } else if remaining.starts_with("hh12") {
33554 result.push_str("hh");
33555 i += 4;
33556 } else if remaining.starts_with("hh") {
33557 result.push_str("HH");
33558 i += 2;
33559 } else if remaining.starts_with("mi") {
33560 result.push_str("mm");
33561 i += 2;
33562 } else if remaining.starts_with("ss") {
33563 result.push_str("ss");
33564 i += 2;
33565 } else if remaining.starts_with("ff") {
33566 result.push_str("SSS"); i += 2;
33568 while i < chars.len() && chars[i].is_ascii_digit() {
33570 i += 1;
33571 }
33572 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
33573 result.push_str("a");
33574 i += 2;
33575 } else if remaining.starts_with("tz") {
33576 result.push_str("z");
33577 i += 2;
33578 } else {
33579 result.push(chars[i]);
33580 i += 1;
33581 }
33582 }
33583 result
33584 }
33585
33586 fn generate_str_to_unix(&mut self, e: &StrToUnix) -> Result<()> {
33587 match self.config.dialect {
33588 Some(DialectType::DuckDB) => {
33589 self.write_keyword("EPOCH");
33591 self.write("(");
33592 self.write_keyword("STRPTIME");
33593 self.write("(");
33594 if let Some(this) = &e.this {
33595 self.generate_expression(this)?;
33596 }
33597 if let Some(format) = &e.format {
33598 self.write(", '");
33599 self.write(format);
33600 self.write("'");
33601 }
33602 self.write("))");
33603 }
33604 Some(DialectType::Hive) => {
33605 self.write_keyword("UNIX_TIMESTAMP");
33607 self.write("(");
33608 if let Some(this) = &e.this {
33609 self.generate_expression(this)?;
33610 }
33611 if let Some(format) = &e.format {
33612 let java_fmt = Self::strftime_to_java_format(format);
33613 if java_fmt != "yyyy-MM-dd HH:mm:ss" {
33614 self.write(", '");
33615 self.write(&java_fmt);
33616 self.write("'");
33617 }
33618 }
33619 self.write(")");
33620 }
33621 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
33622 self.write_keyword("UNIX_TIMESTAMP");
33624 self.write("(");
33625 if let Some(this) = &e.this {
33626 self.generate_expression(this)?;
33627 }
33628 if let Some(format) = &e.format {
33629 self.write(", '");
33630 self.write(format);
33631 self.write("'");
33632 }
33633 self.write(")");
33634 }
33635 Some(DialectType::Presto) | Some(DialectType::Trino) => {
33636 let c_fmt = e.format.as_deref().unwrap_or("%Y-%m-%d %T");
33639 let java_fmt = Self::strftime_to_java_format(c_fmt);
33640 self.write_keyword("TO_UNIXTIME");
33641 self.write("(");
33642 self.write_keyword("COALESCE");
33643 self.write("(");
33644 self.write_keyword("TRY");
33645 self.write("(");
33646 self.write_keyword("DATE_PARSE");
33647 self.write("(");
33648 self.write_keyword("CAST");
33649 self.write("(");
33650 if let Some(this) = &e.this {
33651 self.generate_expression(this)?;
33652 }
33653 self.write(" ");
33654 self.write_keyword("AS VARCHAR");
33655 self.write("), '");
33656 self.write(c_fmt);
33657 self.write("')), ");
33658 self.write_keyword("PARSE_DATETIME");
33659 self.write("(");
33660 self.write_keyword("DATE_FORMAT");
33661 self.write("(");
33662 self.write_keyword("CAST");
33663 self.write("(");
33664 if let Some(this) = &e.this {
33665 self.generate_expression(this)?;
33666 }
33667 self.write(" ");
33668 self.write_keyword("AS TIMESTAMP");
33669 self.write("), '");
33670 self.write(c_fmt);
33671 self.write("'), '");
33672 self.write(&java_fmt);
33673 self.write("')))");
33674 }
33675 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
33676 self.write_keyword("UNIX_TIMESTAMP");
33678 self.write("(");
33679 if let Some(this) = &e.this {
33680 self.generate_expression(this)?;
33681 }
33682 if let Some(format) = &e.format {
33683 let java_fmt = Self::strftime_to_java_format(format);
33684 self.write(", '");
33685 self.write(&java_fmt);
33686 self.write("'");
33687 }
33688 self.write(")");
33689 }
33690 _ => {
33691 self.write_keyword("STR_TO_UNIX");
33693 self.write("(");
33694 if let Some(this) = &e.this {
33695 self.generate_expression(this)?;
33696 }
33697 if let Some(format) = &e.format {
33698 self.write(", '");
33699 self.write(format);
33700 self.write("'");
33701 }
33702 self.write(")");
33703 }
33704 }
33705 Ok(())
33706 }
33707
33708 fn generate_string_to_array(&mut self, e: &StringToArray) -> Result<()> {
33709 self.write_keyword("STRING_TO_ARRAY");
33711 self.write("(");
33712 self.generate_expression(&e.this)?;
33713 if let Some(expression) = &e.expression {
33714 self.write(", ");
33715 self.generate_expression(expression)?;
33716 }
33717 if let Some(null_val) = &e.null {
33718 self.write(", ");
33719 self.generate_expression(null_val)?;
33720 }
33721 self.write(")");
33722 Ok(())
33723 }
33724
33725 fn generate_struct(&mut self, e: &Struct) -> Result<()> {
33726 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
33727 self.write_keyword("OBJECT_CONSTRUCT");
33729 self.write("(");
33730 for (i, (name, expr)) in e.fields.iter().enumerate() {
33731 if i > 0 {
33732 self.write(", ");
33733 }
33734 if let Some(name) = name {
33735 self.write("'");
33736 self.write(name);
33737 self.write("'");
33738 self.write(", ");
33739 } else {
33740 self.write("'_");
33741 self.write(&i.to_string());
33742 self.write("'");
33743 self.write(", ");
33744 }
33745 self.generate_expression(expr)?;
33746 }
33747 self.write(")");
33748 } else if self.config.struct_curly_brace_notation {
33749 self.write("{");
33751 for (i, (name, expr)) in e.fields.iter().enumerate() {
33752 if i > 0 {
33753 self.write(", ");
33754 }
33755 if let Some(name) = name {
33756 self.write("'");
33758 self.write(name);
33759 self.write("'");
33760 self.write(": ");
33761 } else {
33762 self.write("'_");
33764 self.write(&i.to_string());
33765 self.write("'");
33766 self.write(": ");
33767 }
33768 self.generate_expression(expr)?;
33769 }
33770 self.write("}");
33771 } else {
33772 let value_as_name = matches!(
33776 self.config.dialect,
33777 Some(DialectType::BigQuery)
33778 | Some(DialectType::Spark)
33779 | Some(DialectType::Databricks)
33780 | Some(DialectType::Hive)
33781 );
33782 self.write_keyword("STRUCT");
33783 self.write("(");
33784 for (i, (name, expr)) in e.fields.iter().enumerate() {
33785 if i > 0 {
33786 self.write(", ");
33787 }
33788 if let Some(name) = name {
33789 if value_as_name {
33790 self.generate_expression(expr)?;
33792 self.write_space();
33793 self.write_keyword("AS");
33794 self.write_space();
33795 let needs_quoting = name.contains(' ') || name.contains('-');
33797 if needs_quoting {
33798 if matches!(
33799 self.config.dialect,
33800 Some(DialectType::Spark)
33801 | Some(DialectType::Databricks)
33802 | Some(DialectType::Hive)
33803 ) {
33804 self.write("`");
33805 self.write(name);
33806 self.write("`");
33807 } else {
33808 self.write(name);
33809 }
33810 } else {
33811 self.write(name);
33812 }
33813 } else {
33814 self.write(name);
33816 self.write_space();
33817 self.write_keyword("AS");
33818 self.write_space();
33819 self.generate_expression(expr)?;
33820 }
33821 } else {
33822 self.generate_expression(expr)?;
33823 }
33824 }
33825 self.write(")");
33826 }
33827 Ok(())
33828 }
33829
33830 fn generate_stuff(&mut self, e: &Stuff) -> Result<()> {
33831 self.write_keyword("STUFF");
33833 self.write("(");
33834 self.generate_expression(&e.this)?;
33835 if let Some(start) = &e.start {
33836 self.write(", ");
33837 self.generate_expression(start)?;
33838 }
33839 if let Some(length) = e.length {
33840 self.write(", ");
33841 self.write(&length.to_string());
33842 }
33843 self.write(", ");
33844 self.generate_expression(&e.expression)?;
33845 self.write(")");
33846 Ok(())
33847 }
33848
33849 fn generate_substring_index(&mut self, e: &SubstringIndex) -> Result<()> {
33850 self.write_keyword("SUBSTRING_INDEX");
33852 self.write("(");
33853 self.generate_expression(&e.this)?;
33854 if let Some(delimiter) = &e.delimiter {
33855 self.write(", ");
33856 self.generate_expression(delimiter)?;
33857 }
33858 if let Some(count) = &e.count {
33859 self.write(", ");
33860 self.generate_expression(count)?;
33861 }
33862 self.write(")");
33863 Ok(())
33864 }
33865
33866 fn generate_summarize(&mut self, e: &Summarize) -> Result<()> {
33867 self.write_keyword("SUMMARIZE");
33869 if e.table.is_some() {
33870 self.write_space();
33871 self.write_keyword("TABLE");
33872 }
33873 self.write_space();
33874 self.generate_expression(&e.this)?;
33875 Ok(())
33876 }
33877
33878 fn generate_systimestamp(&mut self, _e: &Systimestamp) -> Result<()> {
33879 self.write_keyword("SYSTIMESTAMP");
33881 Ok(())
33882 }
33883
33884 fn generate_table_alias(&mut self, e: &TableAlias) -> Result<()> {
33885 if let Some(this) = &e.this {
33887 self.generate_expression(this)?;
33888 }
33889 if !e.columns.is_empty() {
33890 self.write("(");
33891 for (i, col) in e.columns.iter().enumerate() {
33892 if i > 0 {
33893 self.write(", ");
33894 }
33895 self.generate_expression(col)?;
33896 }
33897 self.write(")");
33898 }
33899 Ok(())
33900 }
33901
33902 fn generate_table_from_rows(&mut self, e: &TableFromRows) -> Result<()> {
33903 self.write_keyword("TABLE");
33905 self.write("(");
33906 self.generate_expression(&e.this)?;
33907 self.write(")");
33908 if let Some(alias) = &e.alias {
33909 self.write_space();
33910 self.write_keyword("AS");
33911 self.write_space();
33912 self.write(alias);
33913 }
33914 Ok(())
33915 }
33916
33917 fn generate_rows_from(&mut self, e: &RowsFrom) -> Result<()> {
33918 self.write_keyword("ROWS FROM");
33920 self.write(" (");
33921 for (i, expr) in e.expressions.iter().enumerate() {
33922 if i > 0 {
33923 self.write(", ");
33924 }
33925 match expr {
33929 Expression::Tuple(tuple) if tuple.expressions.len() == 2 => {
33930 self.generate_expression(&tuple.expressions[0])?;
33932 self.write_space();
33933 self.write_keyword("AS");
33934 self.write_space();
33935 self.generate_expression(&tuple.expressions[1])?;
33936 }
33937 _ => {
33938 self.generate_expression(expr)?;
33939 }
33940 }
33941 }
33942 self.write(")");
33943 if e.ordinality {
33944 self.write_space();
33945 self.write_keyword("WITH ORDINALITY");
33946 }
33947 if let Some(alias) = &e.alias {
33948 self.write_space();
33949 self.write_keyword("AS");
33950 self.write_space();
33951 self.generate_expression(alias)?;
33952 }
33953 Ok(())
33954 }
33955
33956 fn generate_table_sample(&mut self, e: &TableSample) -> Result<()> {
33957 use crate::dialects::DialectType;
33958
33959 if let (Some(this), Some(sample)) = (&e.this, &e.sample) {
33961 if self.config.alias_post_tablesample {
33963 if let Expression::Subquery(ref s) = **this {
33965 if let Some(ref alias) = s.alias {
33966 let mut subquery_no_alias = (**s).clone();
33968 subquery_no_alias.alias = None;
33969 subquery_no_alias.column_aliases = Vec::new();
33970 self.generate_expression(&Expression::Subquery(Box::new(
33971 subquery_no_alias,
33972 )))?;
33973 self.write_space();
33974 self.write_keyword("TABLESAMPLE");
33975 self.generate_sample_body(sample)?;
33976 if let Some(ref seed) = sample.seed {
33977 self.write_space();
33978 let use_seed = sample.use_seed_keyword
33979 && !matches!(
33980 self.config.dialect,
33981 Some(crate::dialects::DialectType::Databricks)
33982 | Some(crate::dialects::DialectType::Spark)
33983 );
33984 if use_seed {
33985 self.write_keyword("SEED");
33986 } else {
33987 self.write_keyword("REPEATABLE");
33988 }
33989 self.write(" (");
33990 self.generate_expression(seed)?;
33991 self.write(")");
33992 }
33993 self.write_space();
33994 self.write_keyword("AS");
33995 self.write_space();
33996 self.generate_identifier(alias)?;
33997 return Ok(());
33998 }
33999 } else if let Expression::Alias(ref a) = **this {
34000 self.generate_expression(&a.this)?;
34002 self.write_space();
34003 self.write_keyword("TABLESAMPLE");
34004 self.generate_sample_body(sample)?;
34005 if let Some(ref seed) = sample.seed {
34006 self.write_space();
34007 let use_seed = sample.use_seed_keyword
34008 && !matches!(
34009 self.config.dialect,
34010 Some(crate::dialects::DialectType::Databricks)
34011 | Some(crate::dialects::DialectType::Spark)
34012 );
34013 if use_seed {
34014 self.write_keyword("SEED");
34015 } else {
34016 self.write_keyword("REPEATABLE");
34017 }
34018 self.write(" (");
34019 self.generate_expression(seed)?;
34020 self.write(")");
34021 }
34022 self.write_space();
34024 self.write_keyword("AS");
34025 self.write_space();
34026 self.generate_identifier(&a.alias)?;
34027 return Ok(());
34028 }
34029 }
34030 self.generate_expression(this)?;
34032 self.write_space();
34033 self.write_keyword("TABLESAMPLE");
34034 self.generate_sample_body(sample)?;
34035 if let Some(ref seed) = sample.seed {
34037 self.write_space();
34038 let use_seed = sample.use_seed_keyword
34040 && !matches!(
34041 self.config.dialect,
34042 Some(crate::dialects::DialectType::Databricks)
34043 | Some(crate::dialects::DialectType::Spark)
34044 );
34045 if use_seed {
34046 self.write_keyword("SEED");
34047 } else {
34048 self.write_keyword("REPEATABLE");
34049 }
34050 self.write(" (");
34051 self.generate_expression(seed)?;
34052 self.write(")");
34053 }
34054 return Ok(());
34055 }
34056
34057 self.write_keyword("TABLESAMPLE");
34059 if let Some(method) = &e.method {
34060 self.write_space();
34061 self.write_keyword(method);
34062 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
34063 self.write_space();
34065 self.write_keyword("BERNOULLI");
34066 }
34067 if let (Some(numerator), Some(denominator)) = (&e.bucket_numerator, &e.bucket_denominator) {
34068 self.write_space();
34069 self.write_keyword("BUCKET");
34070 self.write_space();
34071 self.generate_expression(numerator)?;
34072 self.write_space();
34073 self.write_keyword("OUT OF");
34074 self.write_space();
34075 self.generate_expression(denominator)?;
34076 if let Some(field) = &e.bucket_field {
34077 self.write_space();
34078 self.write_keyword("ON");
34079 self.write_space();
34080 self.generate_expression(field)?;
34081 }
34082 } else if !e.expressions.is_empty() {
34083 self.write(" (");
34084 for (i, expr) in e.expressions.iter().enumerate() {
34085 if i > 0 {
34086 self.write(", ");
34087 }
34088 self.generate_expression(expr)?;
34089 }
34090 self.write(")");
34091 } else if let Some(percent) = &e.percent {
34092 self.write(" (");
34093 self.generate_expression(percent)?;
34094 self.write_space();
34095 self.write_keyword("PERCENT");
34096 self.write(")");
34097 }
34098 Ok(())
34099 }
34100
34101 fn generate_tag(&mut self, e: &Tag) -> Result<()> {
34102 if let Some(prefix) = &e.prefix {
34104 self.generate_expression(prefix)?;
34105 }
34106 if let Some(this) = &e.this {
34107 self.generate_expression(this)?;
34108 }
34109 if let Some(postfix) = &e.postfix {
34110 self.generate_expression(postfix)?;
34111 }
34112 Ok(())
34113 }
34114
34115 fn generate_tags(&mut self, e: &Tags) -> Result<()> {
34116 self.write_keyword("TAG");
34118 self.write(" (");
34119 for (i, expr) in e.expressions.iter().enumerate() {
34120 if i > 0 {
34121 self.write(", ");
34122 }
34123 self.generate_expression(expr)?;
34124 }
34125 self.write(")");
34126 Ok(())
34127 }
34128
34129 fn generate_temporary_property(&mut self, e: &TemporaryProperty) -> Result<()> {
34130 if let Some(this) = &e.this {
34132 self.generate_expression(this)?;
34133 self.write_space();
34134 }
34135 self.write_keyword("TEMPORARY");
34136 Ok(())
34137 }
34138
34139 fn generate_time_func(&mut self, e: &UnaryFunc) -> Result<()> {
34142 self.write_keyword("TIME");
34144 self.write("(");
34145 self.generate_expression(&e.this)?;
34146 self.write(")");
34147 Ok(())
34148 }
34149
34150 fn generate_time_add(&mut self, e: &TimeAdd) -> Result<()> {
34151 self.write_keyword("TIME_ADD");
34153 self.write("(");
34154 self.generate_expression(&e.this)?;
34155 self.write(", ");
34156 self.generate_expression(&e.expression)?;
34157 if let Some(unit) = &e.unit {
34158 self.write(", ");
34159 self.write_keyword(unit);
34160 }
34161 self.write(")");
34162 Ok(())
34163 }
34164
34165 fn generate_time_diff(&mut self, e: &TimeDiff) -> Result<()> {
34166 self.write_keyword("TIME_DIFF");
34168 self.write("(");
34169 self.generate_expression(&e.this)?;
34170 self.write(", ");
34171 self.generate_expression(&e.expression)?;
34172 if let Some(unit) = &e.unit {
34173 self.write(", ");
34174 self.write_keyword(unit);
34175 }
34176 self.write(")");
34177 Ok(())
34178 }
34179
34180 fn generate_time_from_parts(&mut self, e: &TimeFromParts) -> Result<()> {
34181 self.write_keyword("TIME_FROM_PARTS");
34183 self.write("(");
34184 let mut first = true;
34185 if let Some(hour) = &e.hour {
34186 self.generate_expression(hour)?;
34187 first = false;
34188 }
34189 if let Some(minute) = &e.min {
34190 if !first {
34191 self.write(", ");
34192 }
34193 self.generate_expression(minute)?;
34194 first = false;
34195 }
34196 if let Some(second) = &e.sec {
34197 if !first {
34198 self.write(", ");
34199 }
34200 self.generate_expression(second)?;
34201 first = false;
34202 }
34203 if let Some(ns) = &e.nano {
34204 if !first {
34205 self.write(", ");
34206 }
34207 self.generate_expression(ns)?;
34208 }
34209 self.write(")");
34210 Ok(())
34211 }
34212
34213 fn generate_time_slice(&mut self, e: &TimeSlice) -> Result<()> {
34214 self.write_keyword("TIME_SLICE");
34216 self.write("(");
34217 self.generate_expression(&e.this)?;
34218 self.write(", ");
34219 self.generate_expression(&e.expression)?;
34220 self.write(", ");
34221 self.write_keyword(&e.unit);
34222 self.write(")");
34223 Ok(())
34224 }
34225
34226 fn generate_time_str_to_time(&mut self, e: &TimeStrToTime) -> Result<()> {
34227 self.write_keyword("TIME_STR_TO_TIME");
34229 self.write("(");
34230 self.generate_expression(&e.this)?;
34231 self.write(")");
34232 Ok(())
34233 }
34234
34235 fn generate_time_sub(&mut self, e: &TimeSub) -> Result<()> {
34236 self.write_keyword("TIME_SUB");
34238 self.write("(");
34239 self.generate_expression(&e.this)?;
34240 self.write(", ");
34241 self.generate_expression(&e.expression)?;
34242 if let Some(unit) = &e.unit {
34243 self.write(", ");
34244 self.write_keyword(unit);
34245 }
34246 self.write(")");
34247 Ok(())
34248 }
34249
34250 fn generate_time_to_str(&mut self, e: &TimeToStr) -> Result<()> {
34251 match self.config.dialect {
34252 Some(DialectType::Exasol) => {
34253 self.write_keyword("TO_CHAR");
34255 self.write("(");
34256 self.generate_expression(&e.this)?;
34257 self.write(", '");
34258 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
34259 self.write("'");
34260 self.write(")");
34261 }
34262 Some(DialectType::PostgreSQL)
34263 | Some(DialectType::Redshift)
34264 | Some(DialectType::Materialize) => {
34265 self.write_keyword("TO_CHAR");
34267 self.write("(");
34268 self.generate_expression(&e.this)?;
34269 self.write(", '");
34270 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
34271 self.write("'");
34272 self.write(")");
34273 }
34274 Some(DialectType::Oracle) => {
34275 self.write_keyword("TO_CHAR");
34277 self.write("(");
34278 self.generate_expression(&e.this)?;
34279 self.write(", '");
34280 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
34281 self.write("'");
34282 self.write(")");
34283 }
34284 Some(DialectType::Drill) => {
34285 self.write_keyword("TO_CHAR");
34287 self.write("(");
34288 self.generate_expression(&e.this)?;
34289 self.write(", '");
34290 self.write(&Self::strftime_to_java_format(&e.format));
34291 self.write("'");
34292 self.write(")");
34293 }
34294 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
34295 self.write_keyword("FORMAT");
34297 self.write("(");
34298 self.generate_expression(&e.this)?;
34299 self.write(", '");
34300 self.write(&Self::strftime_to_tsql_format(&e.format));
34301 self.write("'");
34302 self.write(")");
34303 }
34304 Some(DialectType::DuckDB) => {
34305 self.write_keyword("STRFTIME");
34307 self.write("(");
34308 self.generate_expression(&e.this)?;
34309 self.write(", '");
34310 self.write(&e.format);
34311 self.write("'");
34312 self.write(")");
34313 }
34314 Some(DialectType::BigQuery) => {
34315 let fmt = e.format.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
34318 self.write_keyword("FORMAT_DATE");
34319 self.write("('");
34320 self.write(&fmt);
34321 self.write("', ");
34322 self.generate_expression(&e.this)?;
34323 self.write(")");
34324 }
34325 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
34326 self.write_keyword("DATE_FORMAT");
34328 self.write("(");
34329 self.generate_expression(&e.this)?;
34330 self.write(", '");
34331 self.write(&Self::strftime_to_java_format(&e.format));
34332 self.write("'");
34333 self.write(")");
34334 }
34335 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
34336 self.write_keyword("DATE_FORMAT");
34338 self.write("(");
34339 self.generate_expression(&e.this)?;
34340 self.write(", '");
34341 self.write(&e.format);
34342 self.write("'");
34343 self.write(")");
34344 }
34345 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
34346 self.write_keyword("DATE_FORMAT");
34348 self.write("(");
34349 self.generate_expression(&e.this)?;
34350 self.write(", '");
34351 self.write(&e.format);
34352 self.write("'");
34353 self.write(")");
34354 }
34355 _ => {
34356 self.write_keyword("TIME_TO_STR");
34358 self.write("(");
34359 self.generate_expression(&e.this)?;
34360 self.write(", '");
34361 self.write(&e.format);
34362 self.write("'");
34363 self.write(")");
34364 }
34365 }
34366 Ok(())
34367 }
34368
34369 fn generate_time_to_unix(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
34370 match self.config.dialect {
34371 Some(DialectType::DuckDB) => {
34372 self.write_keyword("EPOCH");
34374 self.write("(");
34375 self.generate_expression(&e.this)?;
34376 self.write(")");
34377 }
34378 Some(DialectType::Hive)
34379 | Some(DialectType::Spark)
34380 | Some(DialectType::Databricks)
34381 | Some(DialectType::Doris)
34382 | Some(DialectType::StarRocks)
34383 | Some(DialectType::Drill) => {
34384 self.write_keyword("UNIX_TIMESTAMP");
34386 self.write("(");
34387 self.generate_expression(&e.this)?;
34388 self.write(")");
34389 }
34390 Some(DialectType::Presto) | Some(DialectType::Trino) => {
34391 self.write_keyword("TO_UNIXTIME");
34393 self.write("(");
34394 self.generate_expression(&e.this)?;
34395 self.write(")");
34396 }
34397 _ => {
34398 self.write_keyword("TIME_TO_UNIX");
34400 self.write("(");
34401 self.generate_expression(&e.this)?;
34402 self.write(")");
34403 }
34404 }
34405 Ok(())
34406 }
34407
34408 fn generate_time_str_to_date(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
34409 match self.config.dialect {
34410 Some(DialectType::Hive) => {
34411 self.write_keyword("TO_DATE");
34413 self.write("(");
34414 self.generate_expression(&e.this)?;
34415 self.write(")");
34416 }
34417 _ => {
34418 self.write_keyword("TIME_STR_TO_DATE");
34420 self.write("(");
34421 self.generate_expression(&e.this)?;
34422 self.write(")");
34423 }
34424 }
34425 Ok(())
34426 }
34427
34428 fn generate_time_trunc(&mut self, e: &TimeTrunc) -> Result<()> {
34429 self.write_keyword("TIME_TRUNC");
34431 self.write("(");
34432 self.generate_expression(&e.this)?;
34433 self.write(", ");
34434 self.write_keyword(&e.unit);
34435 self.write(")");
34436 Ok(())
34437 }
34438
34439 fn generate_time_unit(&mut self, e: &TimeUnit) -> Result<()> {
34440 if let Some(unit) = &e.unit {
34442 self.write_keyword(unit);
34443 }
34444 Ok(())
34445 }
34446
34447 fn generate_timestamp_func(&mut self, e: &TimestampFunc) -> Result<()> {
34451 use crate::dialects::DialectType;
34452 use crate::expressions::Literal;
34453
34454 match self.config.dialect {
34455 Some(DialectType::Exasol) => {
34457 self.write_keyword("TO_TIMESTAMP");
34458 self.write("(");
34459 if let Some(this) = &e.this {
34461 match this.as_ref() {
34462 Expression::Literal(Literal::String(s)) => {
34463 self.write("'");
34464 self.write(s);
34465 self.write("'");
34466 }
34467 _ => {
34468 self.generate_expression(this)?;
34469 }
34470 }
34471 }
34472 self.write(")");
34473 }
34474 _ => {
34476 self.write_keyword("TIMESTAMP");
34477 self.write("(");
34478 if let Some(this) = &e.this {
34479 self.generate_expression(this)?;
34480 }
34481 if let Some(zone) = &e.zone {
34482 self.write(", ");
34483 self.generate_expression(zone)?;
34484 }
34485 self.write(")");
34486 }
34487 }
34488 Ok(())
34489 }
34490
34491 fn generate_timestamp_add(&mut self, e: &TimestampAdd) -> Result<()> {
34492 self.write_keyword("TIMESTAMP_ADD");
34494 self.write("(");
34495 self.generate_expression(&e.this)?;
34496 self.write(", ");
34497 self.generate_expression(&e.expression)?;
34498 if let Some(unit) = &e.unit {
34499 self.write(", ");
34500 self.write_keyword(unit);
34501 }
34502 self.write(")");
34503 Ok(())
34504 }
34505
34506 fn generate_timestamp_diff(&mut self, e: &TimestampDiff) -> Result<()> {
34507 self.write_keyword("TIMESTAMP_DIFF");
34509 self.write("(");
34510 self.generate_expression(&e.this)?;
34511 self.write(", ");
34512 self.generate_expression(&e.expression)?;
34513 if let Some(unit) = &e.unit {
34514 self.write(", ");
34515 self.write_keyword(unit);
34516 }
34517 self.write(")");
34518 Ok(())
34519 }
34520
34521 fn generate_timestamp_from_parts(&mut self, e: &TimestampFromParts) -> Result<()> {
34522 self.write_keyword("TIMESTAMP_FROM_PARTS");
34524 self.write("(");
34525 if let Some(this) = &e.this {
34526 self.generate_expression(this)?;
34527 }
34528 if let Some(expression) = &e.expression {
34529 self.write(", ");
34530 self.generate_expression(expression)?;
34531 }
34532 if let Some(zone) = &e.zone {
34533 self.write(", ");
34534 self.generate_expression(zone)?;
34535 }
34536 if let Some(milli) = &e.milli {
34537 self.write(", ");
34538 self.generate_expression(milli)?;
34539 }
34540 self.write(")");
34541 Ok(())
34542 }
34543
34544 fn generate_timestamp_sub(&mut self, e: &TimestampSub) -> Result<()> {
34545 self.write_keyword("TIMESTAMP_SUB");
34547 self.write("(");
34548 self.generate_expression(&e.this)?;
34549 self.write(", ");
34550 self.write_keyword("INTERVAL");
34551 self.write_space();
34552 self.generate_expression(&e.expression)?;
34553 if let Some(unit) = &e.unit {
34554 self.write_space();
34555 self.write_keyword(unit);
34556 }
34557 self.write(")");
34558 Ok(())
34559 }
34560
34561 fn generate_timestamp_tz_from_parts(&mut self, e: &TimestampTzFromParts) -> Result<()> {
34562 self.write_keyword("TIMESTAMP_TZ_FROM_PARTS");
34564 self.write("(");
34565 if let Some(zone) = &e.zone {
34566 self.generate_expression(zone)?;
34567 }
34568 self.write(")");
34569 Ok(())
34570 }
34571
34572 fn generate_to_binary(&mut self, e: &ToBinary) -> Result<()> {
34573 self.write_keyword("TO_BINARY");
34575 self.write("(");
34576 self.generate_expression(&e.this)?;
34577 if let Some(format) = &e.format {
34578 self.write(", '");
34579 self.write(format);
34580 self.write("'");
34581 }
34582 self.write(")");
34583 Ok(())
34584 }
34585
34586 fn generate_to_boolean(&mut self, e: &ToBoolean) -> Result<()> {
34587 self.write_keyword("TO_BOOLEAN");
34589 self.write("(");
34590 self.generate_expression(&e.this)?;
34591 self.write(")");
34592 Ok(())
34593 }
34594
34595 fn generate_to_char(&mut self, e: &ToChar) -> Result<()> {
34596 self.write_keyword("TO_CHAR");
34598 self.write("(");
34599 self.generate_expression(&e.this)?;
34600 if let Some(format) = &e.format {
34601 self.write(", '");
34602 self.write(format);
34603 self.write("'");
34604 }
34605 if let Some(nlsparam) = &e.nlsparam {
34606 self.write(", ");
34607 self.generate_expression(nlsparam)?;
34608 }
34609 self.write(")");
34610 Ok(())
34611 }
34612
34613 fn generate_to_decfloat(&mut self, e: &ToDecfloat) -> Result<()> {
34614 self.write_keyword("TO_DECFLOAT");
34616 self.write("(");
34617 self.generate_expression(&e.this)?;
34618 if let Some(format) = &e.format {
34619 self.write(", '");
34620 self.write(format);
34621 self.write("'");
34622 }
34623 self.write(")");
34624 Ok(())
34625 }
34626
34627 fn generate_to_double(&mut self, e: &ToDouble) -> Result<()> {
34628 self.write_keyword("TO_DOUBLE");
34630 self.write("(");
34631 self.generate_expression(&e.this)?;
34632 if let Some(format) = &e.format {
34633 self.write(", '");
34634 self.write(format);
34635 self.write("'");
34636 }
34637 self.write(")");
34638 Ok(())
34639 }
34640
34641 fn generate_to_file(&mut self, e: &ToFile) -> Result<()> {
34642 self.write_keyword("TO_FILE");
34644 self.write("(");
34645 self.generate_expression(&e.this)?;
34646 if let Some(path) = &e.path {
34647 self.write(", ");
34648 self.generate_expression(path)?;
34649 }
34650 self.write(")");
34651 Ok(())
34652 }
34653
34654 fn generate_to_number(&mut self, e: &ToNumber) -> Result<()> {
34655 let is_safe = e.safe.is_some();
34658 if is_safe {
34659 self.write_keyword("TRY_TO_NUMBER");
34660 } else {
34661 self.write_keyword("TO_NUMBER");
34662 }
34663 self.write("(");
34664 self.generate_expression(&e.this)?;
34665 if let Some(format) = &e.format {
34666 self.write(", ");
34667 self.generate_expression(format)?;
34668 }
34669 if let Some(nlsparam) = &e.nlsparam {
34670 self.write(", ");
34671 self.generate_expression(nlsparam)?;
34672 }
34673 if let Some(precision) = &e.precision {
34674 self.write(", ");
34675 self.generate_expression(precision)?;
34676 }
34677 if let Some(scale) = &e.scale {
34678 self.write(", ");
34679 self.generate_expression(scale)?;
34680 }
34681 self.write(")");
34682 Ok(())
34683 }
34684
34685 fn generate_to_table_property(&mut self, e: &ToTableProperty) -> Result<()> {
34686 self.write_keyword("TO_TABLE");
34688 self.write_space();
34689 self.generate_expression(&e.this)?;
34690 Ok(())
34691 }
34692
34693 fn generate_transaction(&mut self, e: &Transaction) -> Result<()> {
34694 let mark_text = e.mark.as_ref().map(|m| match m.as_ref() {
34696 Expression::Identifier(id) => id.name.clone(),
34697 Expression::Literal(Literal::String(s)) => s.clone(),
34698 _ => String::new(),
34699 });
34700
34701 let is_start = mark_text.as_ref().map_or(false, |s| s == "START");
34702 let has_transaction_keyword = mark_text.as_ref().map_or(false, |s| s == "TRANSACTION");
34703 let has_with_mark = e.mark.as_ref().map_or(false, |m| {
34704 matches!(m.as_ref(), Expression::Literal(Literal::String(_)))
34705 });
34706
34707 let use_start_transaction = matches!(
34709 self.config.dialect,
34710 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
34711 );
34712 let strip_transaction = matches!(
34714 self.config.dialect,
34715 Some(DialectType::Snowflake)
34716 | Some(DialectType::PostgreSQL)
34717 | Some(DialectType::Redshift)
34718 | Some(DialectType::MySQL)
34719 | Some(DialectType::Hive)
34720 | Some(DialectType::Spark)
34721 | Some(DialectType::Databricks)
34722 | Some(DialectType::DuckDB)
34723 | Some(DialectType::Oracle)
34724 | Some(DialectType::Doris)
34725 | Some(DialectType::StarRocks)
34726 | Some(DialectType::Materialize)
34727 | Some(DialectType::ClickHouse)
34728 );
34729
34730 if is_start || use_start_transaction {
34731 self.write_keyword("START TRANSACTION");
34733 if let Some(modes) = &e.modes {
34734 self.write_space();
34735 self.generate_expression(modes)?;
34736 }
34737 } else {
34738 self.write_keyword("BEGIN");
34740
34741 let is_kind = e.this.as_ref().map_or(false, |t| {
34743 if let Expression::Identifier(id) = t.as_ref() {
34744 matches!(
34745 id.name.to_uppercase().as_str(),
34746 "DEFERRED" | "IMMEDIATE" | "EXCLUSIVE"
34747 )
34748 } else {
34749 false
34750 }
34751 });
34752
34753 if is_kind {
34755 if let Some(this) = &e.this {
34756 self.write_space();
34757 if let Expression::Identifier(id) = this.as_ref() {
34758 self.write_keyword(&id.name);
34759 }
34760 }
34761 }
34762
34763 if (has_transaction_keyword || has_with_mark) && !strip_transaction {
34765 self.write_space();
34766 self.write_keyword("TRANSACTION");
34767 }
34768
34769 if !is_kind {
34771 if let Some(this) = &e.this {
34772 self.write_space();
34773 self.generate_expression(this)?;
34774 }
34775 }
34776
34777 if has_with_mark {
34779 self.write_space();
34780 self.write_keyword("WITH MARK");
34781 if let Some(Expression::Literal(Literal::String(desc))) = e.mark.as_deref() {
34782 if !desc.is_empty() {
34783 self.write_space();
34784 self.write(&format!("'{}'", desc));
34785 }
34786 }
34787 }
34788
34789 if let Some(modes) = &e.modes {
34791 self.write_space();
34792 self.generate_expression(modes)?;
34793 }
34794 }
34795 Ok(())
34796 }
34797
34798 fn generate_transform(&mut self, e: &Transform) -> Result<()> {
34799 self.write_keyword("TRANSFORM");
34801 self.write("(");
34802 self.generate_expression(&e.this)?;
34803 self.write(", ");
34804 self.generate_expression(&e.expression)?;
34805 self.write(")");
34806 Ok(())
34807 }
34808
34809 fn generate_transform_model_property(&mut self, e: &TransformModelProperty) -> Result<()> {
34810 self.write_keyword("TRANSFORM");
34812 self.write("(");
34813 if self.config.pretty && !e.expressions.is_empty() {
34814 self.indent_level += 1;
34815 for (i, expr) in e.expressions.iter().enumerate() {
34816 if i > 0 {
34817 self.write(",");
34818 }
34819 self.write_newline();
34820 self.write_indent();
34821 self.generate_expression(expr)?;
34822 }
34823 self.indent_level -= 1;
34824 self.write_newline();
34825 self.write(")");
34826 } else {
34827 for (i, expr) in e.expressions.iter().enumerate() {
34828 if i > 0 {
34829 self.write(", ");
34830 }
34831 self.generate_expression(expr)?;
34832 }
34833 self.write(")");
34834 }
34835 Ok(())
34836 }
34837
34838 fn generate_transient_property(&mut self, e: &TransientProperty) -> Result<()> {
34839 use crate::dialects::DialectType;
34840 if let Some(this) = &e.this {
34842 self.generate_expression(this)?;
34843 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
34844 self.write_space();
34845 }
34846 }
34847 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
34848 self.write_keyword("TRANSIENT");
34849 }
34850 Ok(())
34851 }
34852
34853 fn generate_translate(&mut self, e: &Translate) -> Result<()> {
34854 self.write_keyword("TRANSLATE");
34856 self.write("(");
34857 self.generate_expression(&e.this)?;
34858 if let Some(from) = &e.from_ {
34859 self.write(", ");
34860 self.generate_expression(from)?;
34861 }
34862 if let Some(to) = &e.to {
34863 self.write(", ");
34864 self.generate_expression(to)?;
34865 }
34866 self.write(")");
34867 Ok(())
34868 }
34869
34870 fn generate_translate_characters(&mut self, e: &TranslateCharacters) -> Result<()> {
34871 self.write_keyword("TRANSLATE");
34873 self.write("(");
34874 self.generate_expression(&e.this)?;
34875 self.write_space();
34876 self.write_keyword("USING");
34877 self.write_space();
34878 self.generate_expression(&e.expression)?;
34879 if e.with_error.is_some() {
34880 self.write_space();
34881 self.write_keyword("WITH ERROR");
34882 }
34883 self.write(")");
34884 Ok(())
34885 }
34886
34887 fn generate_truncate_table(&mut self, e: &TruncateTable) -> Result<()> {
34888 self.write_keyword("TRUNCATE TABLE");
34890 self.write_space();
34891 for (i, expr) in e.expressions.iter().enumerate() {
34892 if i > 0 {
34893 self.write(", ");
34894 }
34895 self.generate_expression(expr)?;
34896 }
34897 Ok(())
34898 }
34899
34900 fn generate_try_base64_decode_binary(&mut self, e: &TryBase64DecodeBinary) -> Result<()> {
34901 self.write_keyword("TRY_BASE64_DECODE_BINARY");
34903 self.write("(");
34904 self.generate_expression(&e.this)?;
34905 if let Some(alphabet) = &e.alphabet {
34906 self.write(", ");
34907 self.generate_expression(alphabet)?;
34908 }
34909 self.write(")");
34910 Ok(())
34911 }
34912
34913 fn generate_try_base64_decode_string(&mut self, e: &TryBase64DecodeString) -> Result<()> {
34914 self.write_keyword("TRY_BASE64_DECODE_STRING");
34916 self.write("(");
34917 self.generate_expression(&e.this)?;
34918 if let Some(alphabet) = &e.alphabet {
34919 self.write(", ");
34920 self.generate_expression(alphabet)?;
34921 }
34922 self.write(")");
34923 Ok(())
34924 }
34925
34926 fn generate_try_to_decfloat(&mut self, e: &TryToDecfloat) -> Result<()> {
34927 self.write_keyword("TRY_TO_DECFLOAT");
34929 self.write("(");
34930 self.generate_expression(&e.this)?;
34931 if let Some(format) = &e.format {
34932 self.write(", '");
34933 self.write(format);
34934 self.write("'");
34935 }
34936 self.write(")");
34937 Ok(())
34938 }
34939
34940 fn generate_ts_or_ds_add(&mut self, e: &TsOrDsAdd) -> Result<()> {
34941 self.write_keyword("TS_OR_DS_ADD");
34943 self.write("(");
34944 self.generate_expression(&e.this)?;
34945 self.write(", ");
34946 self.generate_expression(&e.expression)?;
34947 if let Some(unit) = &e.unit {
34948 self.write(", ");
34949 self.write_keyword(unit);
34950 }
34951 if let Some(return_type) = &e.return_type {
34952 self.write(", ");
34953 self.generate_expression(return_type)?;
34954 }
34955 self.write(")");
34956 Ok(())
34957 }
34958
34959 fn generate_ts_or_ds_diff(&mut self, e: &TsOrDsDiff) -> Result<()> {
34960 self.write_keyword("TS_OR_DS_DIFF");
34962 self.write("(");
34963 self.generate_expression(&e.this)?;
34964 self.write(", ");
34965 self.generate_expression(&e.expression)?;
34966 if let Some(unit) = &e.unit {
34967 self.write(", ");
34968 self.write_keyword(unit);
34969 }
34970 self.write(")");
34971 Ok(())
34972 }
34973
34974 fn generate_ts_or_ds_to_date(&mut self, e: &TsOrDsToDate) -> Result<()> {
34975 let default_time_format = "%Y-%m-%d %H:%M:%S";
34976 let default_date_format = "%Y-%m-%d";
34977 let has_non_default_format = e.format.as_ref().map_or(false, |f| {
34978 f != default_time_format && f != default_date_format
34979 });
34980
34981 if has_non_default_format {
34982 let fmt = e.format.as_ref().unwrap();
34984 match self.config.dialect {
34985 Some(DialectType::MySQL) | Some(DialectType::StarRocks) => {
34986 let str_to_time = crate::expressions::StrToTime {
34989 this: Box::new((*e.this).clone()),
34990 format: fmt.clone(),
34991 zone: None,
34992 safe: None,
34993 target_type: None,
34994 };
34995 self.generate_str_to_time(&str_to_time)?;
34996 }
34997 Some(DialectType::Hive)
34998 | Some(DialectType::Spark)
34999 | Some(DialectType::Databricks) => {
35000 self.write_keyword("TO_DATE");
35002 self.write("(");
35003 self.generate_expression(&e.this)?;
35004 self.write(", '");
35005 self.write(&Self::strftime_to_java_format(fmt));
35006 self.write("')");
35007 }
35008 Some(DialectType::Snowflake) => {
35009 self.write_keyword("TO_DATE");
35011 self.write("(");
35012 self.generate_expression(&e.this)?;
35013 self.write(", '");
35014 self.write(&Self::strftime_to_snowflake_format(fmt));
35015 self.write("')");
35016 }
35017 Some(DialectType::Doris) => {
35018 self.write_keyword("TO_DATE");
35020 self.write("(");
35021 self.generate_expression(&e.this)?;
35022 self.write(")");
35023 }
35024 _ => {
35025 self.write_keyword("CAST");
35027 self.write("(");
35028 let str_to_time = crate::expressions::StrToTime {
35029 this: Box::new((*e.this).clone()),
35030 format: fmt.clone(),
35031 zone: None,
35032 safe: None,
35033 target_type: None,
35034 };
35035 self.generate_str_to_time(&str_to_time)?;
35036 self.write_keyword(" AS ");
35037 self.write_keyword("DATE");
35038 self.write(")");
35039 }
35040 }
35041 } else {
35042 match self.config.dialect {
35044 Some(DialectType::MySQL)
35045 | Some(DialectType::SQLite)
35046 | Some(DialectType::StarRocks) => {
35047 self.write_keyword("DATE");
35049 self.write("(");
35050 self.generate_expression(&e.this)?;
35051 self.write(")");
35052 }
35053 Some(DialectType::Hive)
35054 | Some(DialectType::Spark)
35055 | Some(DialectType::Databricks)
35056 | Some(DialectType::Snowflake)
35057 | Some(DialectType::Doris) => {
35058 self.write_keyword("TO_DATE");
35060 self.write("(");
35061 self.generate_expression(&e.this)?;
35062 self.write(")");
35063 }
35064 Some(DialectType::Presto)
35065 | Some(DialectType::Trino)
35066 | Some(DialectType::Athena) => {
35067 self.write_keyword("CAST");
35069 self.write("(");
35070 self.write_keyword("CAST");
35071 self.write("(");
35072 self.generate_expression(&e.this)?;
35073 self.write_keyword(" AS ");
35074 self.write_keyword("TIMESTAMP");
35075 self.write(")");
35076 self.write_keyword(" AS ");
35077 self.write_keyword("DATE");
35078 self.write(")");
35079 }
35080 Some(DialectType::ClickHouse) => {
35081 self.write_keyword("CAST");
35083 self.write("(");
35084 self.generate_expression(&e.this)?;
35085 self.write_keyword(" AS ");
35086 self.write("Nullable(DATE)");
35087 self.write(")");
35088 }
35089 _ => {
35090 self.write_keyword("CAST");
35092 self.write("(");
35093 self.generate_expression(&e.this)?;
35094 self.write_keyword(" AS ");
35095 self.write_keyword("DATE");
35096 self.write(")");
35097 }
35098 }
35099 }
35100 Ok(())
35101 }
35102
35103 fn generate_ts_or_ds_to_time(&mut self, e: &TsOrDsToTime) -> Result<()> {
35104 self.write_keyword("TS_OR_DS_TO_TIME");
35106 self.write("(");
35107 self.generate_expression(&e.this)?;
35108 if let Some(format) = &e.format {
35109 self.write(", '");
35110 self.write(format);
35111 self.write("'");
35112 }
35113 self.write(")");
35114 Ok(())
35115 }
35116
35117 fn generate_unhex(&mut self, e: &Unhex) -> Result<()> {
35118 self.write_keyword("UNHEX");
35120 self.write("(");
35121 self.generate_expression(&e.this)?;
35122 if let Some(expression) = &e.expression {
35123 self.write(", ");
35124 self.generate_expression(expression)?;
35125 }
35126 self.write(")");
35127 Ok(())
35128 }
35129
35130 fn generate_unicode_string(&mut self, e: &UnicodeString) -> Result<()> {
35131 self.write("U&");
35133 self.generate_expression(&e.this)?;
35134 if let Some(escape) = &e.escape {
35135 self.write_space();
35136 self.write_keyword("UESCAPE");
35137 self.write_space();
35138 self.generate_expression(escape)?;
35139 }
35140 Ok(())
35141 }
35142
35143 fn generate_uniform(&mut self, e: &Uniform) -> Result<()> {
35144 self.write_keyword("UNIFORM");
35146 self.write("(");
35147 self.generate_expression(&e.this)?;
35148 self.write(", ");
35149 self.generate_expression(&e.expression)?;
35150 if let Some(gen) = &e.gen {
35151 self.write(", ");
35152 self.generate_expression(gen)?;
35153 }
35154 if let Some(seed) = &e.seed {
35155 self.write(", ");
35156 self.generate_expression(seed)?;
35157 }
35158 self.write(")");
35159 Ok(())
35160 }
35161
35162 fn generate_unique_column_constraint(&mut self, e: &UniqueColumnConstraint) -> Result<()> {
35163 self.write_keyword("UNIQUE");
35165 if e.nulls.is_some() {
35167 self.write(" NULLS NOT DISTINCT");
35168 }
35169 if let Some(this) = &e.this {
35170 self.write_space();
35171 self.generate_expression(this)?;
35172 }
35173 if let Some(index_type) = &e.index_type {
35174 self.write(" USING ");
35175 self.generate_expression(index_type)?;
35176 }
35177 if let Some(on_conflict) = &e.on_conflict {
35178 self.write_space();
35179 self.generate_expression(on_conflict)?;
35180 }
35181 for opt in &e.options {
35182 self.write_space();
35183 self.generate_expression(opt)?;
35184 }
35185 Ok(())
35186 }
35187
35188 fn generate_unique_key_property(&mut self, e: &UniqueKeyProperty) -> Result<()> {
35189 self.write_keyword("UNIQUE KEY");
35191 self.write(" (");
35192 for (i, expr) in e.expressions.iter().enumerate() {
35193 if i > 0 {
35194 self.write(", ");
35195 }
35196 self.generate_expression(expr)?;
35197 }
35198 self.write(")");
35199 Ok(())
35200 }
35201
35202 fn generate_rollup_property(&mut self, e: &RollupProperty) -> Result<()> {
35203 self.write_keyword("ROLLUP");
35205 self.write(" (");
35206 for (i, index) in e.expressions.iter().enumerate() {
35207 if i > 0 {
35208 self.write(", ");
35209 }
35210 self.generate_identifier(&index.name)?;
35211 self.write("(");
35212 for (j, col) in index.expressions.iter().enumerate() {
35213 if j > 0 {
35214 self.write(", ");
35215 }
35216 self.generate_identifier(col)?;
35217 }
35218 self.write(")");
35219 }
35220 self.write(")");
35221 Ok(())
35222 }
35223
35224 fn generate_unix_to_str(&mut self, e: &UnixToStr) -> Result<()> {
35225 match self.config.dialect {
35226 Some(DialectType::DuckDB) => {
35227 self.write_keyword("STRFTIME");
35229 self.write("(");
35230 self.write_keyword("TO_TIMESTAMP");
35231 self.write("(");
35232 self.generate_expression(&e.this)?;
35233 self.write("), '");
35234 if let Some(format) = &e.format {
35235 self.write(format);
35236 }
35237 self.write("')");
35238 }
35239 Some(DialectType::Hive) => {
35240 self.write_keyword("FROM_UNIXTIME");
35242 self.write("(");
35243 self.generate_expression(&e.this)?;
35244 if let Some(format) = &e.format {
35245 if format != "yyyy-MM-dd HH:mm:ss" {
35246 self.write(", '");
35247 self.write(format);
35248 self.write("'");
35249 }
35250 }
35251 self.write(")");
35252 }
35253 Some(DialectType::Presto) | Some(DialectType::Trino) => {
35254 self.write_keyword("DATE_FORMAT");
35256 self.write("(");
35257 self.write_keyword("FROM_UNIXTIME");
35258 self.write("(");
35259 self.generate_expression(&e.this)?;
35260 self.write("), '");
35261 if let Some(format) = &e.format {
35262 self.write(format);
35263 }
35264 self.write("')");
35265 }
35266 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
35267 self.write_keyword("FROM_UNIXTIME");
35269 self.write("(");
35270 self.generate_expression(&e.this)?;
35271 if let Some(format) = &e.format {
35272 self.write(", '");
35273 self.write(format);
35274 self.write("'");
35275 }
35276 self.write(")");
35277 }
35278 _ => {
35279 self.write_keyword("UNIX_TO_STR");
35281 self.write("(");
35282 self.generate_expression(&e.this)?;
35283 if let Some(format) = &e.format {
35284 self.write(", '");
35285 self.write(format);
35286 self.write("'");
35287 }
35288 self.write(")");
35289 }
35290 }
35291 Ok(())
35292 }
35293
35294 fn generate_unix_to_time(&mut self, e: &UnixToTime) -> Result<()> {
35295 use crate::dialects::DialectType;
35296 let scale = e.scale.unwrap_or(0); match self.config.dialect {
35299 Some(DialectType::Snowflake) => {
35300 self.write_keyword("TO_TIMESTAMP");
35302 self.write("(");
35303 self.generate_expression(&e.this)?;
35304 if let Some(s) = e.scale {
35305 if s > 0 {
35306 self.write(", ");
35307 self.write(&s.to_string());
35308 }
35309 }
35310 self.write(")");
35311 }
35312 Some(DialectType::BigQuery) => {
35313 match scale {
35316 0 => {
35317 self.write_keyword("TIMESTAMP_SECONDS");
35318 self.write("(");
35319 self.generate_expression(&e.this)?;
35320 self.write(")");
35321 }
35322 3 => {
35323 self.write_keyword("TIMESTAMP_MILLIS");
35324 self.write("(");
35325 self.generate_expression(&e.this)?;
35326 self.write(")");
35327 }
35328 6 => {
35329 self.write_keyword("TIMESTAMP_MICROS");
35330 self.write("(");
35331 self.generate_expression(&e.this)?;
35332 self.write(")");
35333 }
35334 _ => {
35335 self.write_keyword("TIMESTAMP_SECONDS");
35337 self.write("(CAST(");
35338 self.generate_expression(&e.this)?;
35339 self.write(&format!(" / POWER(10, {}) AS INT64))", scale));
35340 }
35341 }
35342 }
35343 Some(DialectType::Spark) => {
35344 match scale {
35349 0 => {
35350 self.write_keyword("CAST");
35351 self.write("(");
35352 self.write_keyword("FROM_UNIXTIME");
35353 self.write("(");
35354 self.generate_expression(&e.this)?;
35355 self.write(") ");
35356 self.write_keyword("AS TIMESTAMP");
35357 self.write(")");
35358 }
35359 3 => {
35360 self.write_keyword("TIMESTAMP_MILLIS");
35361 self.write("(");
35362 self.generate_expression(&e.this)?;
35363 self.write(")");
35364 }
35365 6 => {
35366 self.write_keyword("TIMESTAMP_MICROS");
35367 self.write("(");
35368 self.generate_expression(&e.this)?;
35369 self.write(")");
35370 }
35371 _ => {
35372 self.write_keyword("TIMESTAMP_SECONDS");
35373 self.write("(");
35374 self.generate_expression(&e.this)?;
35375 self.write(&format!(" / POWER(10, {}))", scale));
35376 }
35377 }
35378 }
35379 Some(DialectType::Databricks) => {
35380 match scale {
35384 0 => {
35385 self.write_keyword("CAST");
35386 self.write("(");
35387 self.write_keyword("FROM_UNIXTIME");
35388 self.write("(");
35389 self.generate_expression(&e.this)?;
35390 self.write(") ");
35391 self.write_keyword("AS TIMESTAMP");
35392 self.write(")");
35393 }
35394 3 => {
35395 self.write_keyword("TIMESTAMP_MILLIS");
35396 self.write("(");
35397 self.generate_expression(&e.this)?;
35398 self.write(")");
35399 }
35400 6 => {
35401 self.write_keyword("TIMESTAMP_MICROS");
35402 self.write("(");
35403 self.generate_expression(&e.this)?;
35404 self.write(")");
35405 }
35406 _ => {
35407 self.write_keyword("TIMESTAMP_SECONDS");
35408 self.write("(");
35409 self.generate_expression(&e.this)?;
35410 self.write(&format!(" / POWER(10, {}))", scale));
35411 }
35412 }
35413 }
35414 Some(DialectType::Hive) => {
35415 if scale == 0 {
35417 self.write_keyword("FROM_UNIXTIME");
35418 self.write("(");
35419 self.generate_expression(&e.this)?;
35420 self.write(")");
35421 } else {
35422 self.write_keyword("FROM_UNIXTIME");
35423 self.write("(");
35424 self.generate_expression(&e.this)?;
35425 self.write(&format!(" / POWER(10, {})", scale));
35426 self.write(")");
35427 }
35428 }
35429 Some(DialectType::Presto) | Some(DialectType::Trino) => {
35430 if scale == 0 {
35433 self.write_keyword("FROM_UNIXTIME");
35434 self.write("(");
35435 self.generate_expression(&e.this)?;
35436 self.write(")");
35437 } else {
35438 self.write_keyword("FROM_UNIXTIME");
35439 self.write("(CAST(");
35440 self.generate_expression(&e.this)?;
35441 self.write(&format!(" AS DOUBLE) / POW(10, {}))", scale));
35442 }
35443 }
35444 Some(DialectType::DuckDB) => {
35445 match scale {
35449 0 => {
35450 self.write_keyword("TO_TIMESTAMP");
35451 self.write("(");
35452 self.generate_expression(&e.this)?;
35453 self.write(")");
35454 }
35455 3 => {
35456 self.write_keyword("EPOCH_MS");
35457 self.write("(");
35458 self.generate_expression(&e.this)?;
35459 self.write(")");
35460 }
35461 6 => {
35462 self.write_keyword("MAKE_TIMESTAMP");
35463 self.write("(");
35464 self.generate_expression(&e.this)?;
35465 self.write(")");
35466 }
35467 _ => {
35468 self.write_keyword("TO_TIMESTAMP");
35469 self.write("(");
35470 self.generate_expression(&e.this)?;
35471 self.write(&format!(" / POWER(10, {}))", scale));
35472 self.write_keyword(" AT TIME ZONE");
35473 self.write(" 'UTC'");
35474 }
35475 }
35476 }
35477 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
35478 self.write_keyword("FROM_UNIXTIME");
35480 self.write("(");
35481 self.generate_expression(&e.this)?;
35482 self.write(")");
35483 }
35484 Some(DialectType::Oracle) => {
35485 self.write("TO_DATE('1970-01-01', 'YYYY-MM-DD') + (");
35487 self.generate_expression(&e.this)?;
35488 self.write(" / 86400)");
35489 }
35490 Some(DialectType::Redshift) => {
35491 self.write("(TIMESTAMP 'epoch' + ");
35494 if scale == 0 {
35495 self.generate_expression(&e.this)?;
35496 } else {
35497 self.write("(");
35498 self.generate_expression(&e.this)?;
35499 self.write(&format!(" / POWER(10, {}))", scale));
35500 }
35501 self.write(" * INTERVAL '1 SECOND')");
35502 }
35503 _ => {
35504 self.write_keyword("TO_TIMESTAMP");
35506 self.write("(");
35507 self.generate_expression(&e.this)?;
35508 if let Some(s) = e.scale {
35509 self.write(", ");
35510 self.write(&s.to_string());
35511 }
35512 self.write(")");
35513 }
35514 }
35515 Ok(())
35516 }
35517
35518 fn generate_unpivot_columns(&mut self, e: &UnpivotColumns) -> Result<()> {
35519 if !matches!(&*e.this, Expression::Null(_)) {
35521 self.write_keyword("NAME");
35522 self.write_space();
35523 self.generate_expression(&e.this)?;
35524 }
35525 if !e.expressions.is_empty() {
35526 self.write_space();
35527 self.write_keyword("VALUE");
35528 self.write_space();
35529 for (i, expr) in e.expressions.iter().enumerate() {
35530 if i > 0 {
35531 self.write(", ");
35532 }
35533 self.generate_expression(expr)?;
35534 }
35535 }
35536 Ok(())
35537 }
35538
35539 fn generate_user_defined_function(&mut self, e: &UserDefinedFunction) -> Result<()> {
35540 if e.wrapped.is_some() {
35542 self.write("(");
35543 }
35544 self.generate_expression(&e.this)?;
35545 if e.wrapped.is_some() {
35546 self.write(")");
35547 }
35548 self.write("(");
35549 for (i, expr) in e.expressions.iter().enumerate() {
35550 if i > 0 {
35551 self.write(", ");
35552 }
35553 self.generate_expression(expr)?;
35554 }
35555 self.write(")");
35556 Ok(())
35557 }
35558
35559 fn generate_using_template_property(&mut self, e: &UsingTemplateProperty) -> Result<()> {
35560 self.write_keyword("USING TEMPLATE");
35562 self.write_space();
35563 self.generate_expression(&e.this)?;
35564 Ok(())
35565 }
35566
35567 fn generate_utc_time(&mut self, _e: &UtcTime) -> Result<()> {
35568 self.write_keyword("UTC_TIME");
35570 Ok(())
35571 }
35572
35573 fn generate_utc_timestamp(&mut self, _e: &UtcTimestamp) -> Result<()> {
35574 self.write_keyword("UTC_TIMESTAMP");
35576 Ok(())
35577 }
35578
35579 fn generate_uuid(&mut self, e: &Uuid) -> Result<()> {
35580 use crate::dialects::DialectType;
35581 let func_name = match self.config.dialect {
35583 Some(DialectType::Snowflake) => "UUID_STRING",
35584 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
35585 Some(DialectType::BigQuery) => "GENERATE_UUID",
35586 _ => {
35587 if let Some(name) = &e.name {
35588 name.as_str()
35589 } else {
35590 "UUID"
35591 }
35592 }
35593 };
35594 self.write_keyword(func_name);
35595 self.write("(");
35596 if let Some(this) = &e.this {
35597 self.generate_expression(this)?;
35598 }
35599 self.write(")");
35600 Ok(())
35601 }
35602
35603 fn generate_var_map(&mut self, e: &VarMap) -> Result<()> {
35604 self.write_keyword("MAP");
35606 self.write("(");
35607 let mut first = true;
35608 for (k, v) in e.keys.iter().zip(e.values.iter()) {
35609 if !first {
35610 self.write(", ");
35611 }
35612 self.generate_expression(k)?;
35613 self.write(", ");
35614 self.generate_expression(v)?;
35615 first = false;
35616 }
35617 self.write(")");
35618 Ok(())
35619 }
35620
35621 fn generate_vector_search(&mut self, e: &VectorSearch) -> Result<()> {
35622 self.write_keyword("VECTOR_SEARCH");
35624 self.write("(");
35625 self.generate_expression(&e.this)?;
35626 if let Some(col) = &e.column_to_search {
35627 self.write(", ");
35628 self.generate_expression(col)?;
35629 }
35630 if let Some(query_table) = &e.query_table {
35631 self.write(", ");
35632 self.generate_expression(query_table)?;
35633 }
35634 if let Some(query_col) = &e.query_column_to_search {
35635 self.write(", ");
35636 self.generate_expression(query_col)?;
35637 }
35638 if let Some(top_k) = &e.top_k {
35639 self.write(", ");
35640 self.generate_expression(top_k)?;
35641 }
35642 if let Some(dist_type) = &e.distance_type {
35643 self.write(", ");
35644 self.generate_expression(dist_type)?;
35645 }
35646 self.write(")");
35647 Ok(())
35648 }
35649
35650 fn generate_version(&mut self, e: &Version) -> Result<()> {
35651 use crate::dialects::DialectType;
35657 let skip_for = matches!(
35658 self.config.dialect,
35659 Some(DialectType::Hive) | Some(DialectType::Spark)
35660 );
35661 if !skip_for {
35662 self.write_keyword("FOR");
35663 self.write_space();
35664 }
35665 match e.this.as_ref() {
35667 Expression::Identifier(ident) => {
35668 self.write_keyword(&ident.name);
35669 }
35670 _ => {
35671 self.generate_expression(&e.this)?;
35672 }
35673 }
35674 self.write_space();
35675 self.write_keyword(&e.kind);
35676 if let Some(expression) = &e.expression {
35677 self.write_space();
35678 self.generate_expression(expression)?;
35679 }
35680 Ok(())
35681 }
35682
35683 fn generate_view_attribute_property(&mut self, e: &ViewAttributeProperty) -> Result<()> {
35684 self.generate_expression(&e.this)?;
35686 Ok(())
35687 }
35688
35689 fn generate_volatile_property(&mut self, e: &VolatileProperty) -> Result<()> {
35690 if e.this.is_some() {
35692 self.write_keyword("NOT VOLATILE");
35693 } else {
35694 self.write_keyword("VOLATILE");
35695 }
35696 Ok(())
35697 }
35698
35699 fn generate_watermark_column_constraint(
35700 &mut self,
35701 e: &WatermarkColumnConstraint,
35702 ) -> Result<()> {
35703 self.write_keyword("WATERMARK FOR");
35705 self.write_space();
35706 self.generate_expression(&e.this)?;
35707 self.write_space();
35708 self.write_keyword("AS");
35709 self.write_space();
35710 self.generate_expression(&e.expression)?;
35711 Ok(())
35712 }
35713
35714 fn generate_week(&mut self, e: &Week) -> Result<()> {
35715 self.write_keyword("WEEK");
35717 self.write("(");
35718 self.generate_expression(&e.this)?;
35719 if let Some(mode) = &e.mode {
35720 self.write(", ");
35721 self.generate_expression(mode)?;
35722 }
35723 self.write(")");
35724 Ok(())
35725 }
35726
35727 fn generate_when(&mut self, e: &When) -> Result<()> {
35728 self.write_keyword("WHEN");
35732 self.write_space();
35733
35734 if let Some(matched) = &e.matched {
35736 match matched.as_ref() {
35738 Expression::Boolean(b) if b.value => {
35739 self.write_keyword("MATCHED");
35740 }
35741 _ => {
35742 self.write_keyword("NOT MATCHED");
35743 }
35744 }
35745 } else {
35746 self.write_keyword("NOT MATCHED");
35747 }
35748
35749 if self.config.matched_by_source {
35754 if let Some(source) = &e.source {
35755 if let Expression::Boolean(b) = source.as_ref() {
35756 if b.value {
35757 self.write_space();
35759 self.write_keyword("BY SOURCE");
35760 }
35761 } else {
35763 self.write_space();
35765 self.write_keyword("BY SOURCE");
35766 }
35767 }
35768 }
35769
35770 if let Some(condition) = &e.condition {
35772 self.write_space();
35773 self.write_keyword("AND");
35774 self.write_space();
35775 self.generate_expression(condition)?;
35776 }
35777
35778 self.write_space();
35779 self.write_keyword("THEN");
35780 self.write_space();
35781
35782 self.generate_merge_action(&e.then)?;
35785
35786 Ok(())
35787 }
35788
35789 fn generate_merge_action(&mut self, action: &Expression) -> Result<()> {
35790 match action {
35791 Expression::Tuple(tuple) => {
35792 let elements = &tuple.expressions;
35793 if elements.is_empty() {
35794 return self.generate_expression(action);
35795 }
35796 match &elements[0] {
35798 Expression::Var(v) if v.this == "INSERT" => {
35799 self.write_keyword("INSERT");
35800 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
35802 self.write(" *");
35803 } else {
35804 let mut values_idx = 1;
35805 if elements.len() > 1 {
35807 if let Expression::Tuple(cols) = &elements[1] {
35808 if elements.len() > 2 {
35810 self.write(" (");
35812 for (i, col) in cols.expressions.iter().enumerate() {
35813 if i > 0 {
35814 self.write(", ");
35815 }
35816 if !self.merge_strip_qualifiers.is_empty() {
35818 let stripped = self.strip_merge_qualifier(col);
35819 self.generate_expression(&stripped)?;
35820 } else {
35821 self.generate_expression(col)?;
35822 }
35823 }
35824 self.write(")");
35825 values_idx = 2;
35826 } else {
35827 values_idx = 1;
35829 }
35830 }
35831 }
35832 if values_idx < elements.len() {
35834 let is_row = matches!(&elements[values_idx], Expression::Var(v) if v.this == "ROW");
35836 if !is_row {
35837 self.write_space();
35838 self.write_keyword("VALUES");
35839 }
35840 self.write(" ");
35841 if let Expression::Tuple(vals) = &elements[values_idx] {
35842 self.write("(");
35843 for (i, val) in vals.expressions.iter().enumerate() {
35844 if i > 0 {
35845 self.write(", ");
35846 }
35847 self.generate_expression(val)?;
35848 }
35849 self.write(")");
35850 } else {
35851 self.generate_expression(&elements[values_idx])?;
35852 }
35853 }
35854 } }
35856 Expression::Var(v) if v.this == "UPDATE" => {
35857 self.write_keyword("UPDATE");
35858 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
35860 self.write(" *");
35861 } else if elements.len() > 1 {
35862 self.write_space();
35863 self.write_keyword("SET");
35864 if self.config.pretty {
35866 self.write_newline();
35867 self.indent_level += 1;
35868 self.write_indent();
35869 } else {
35870 self.write_space();
35871 }
35872 if let Expression::Tuple(assignments) = &elements[1] {
35873 for (i, assignment) in assignments.expressions.iter().enumerate() {
35874 if i > 0 {
35875 if self.config.pretty {
35876 self.write(",");
35877 self.write_newline();
35878 self.write_indent();
35879 } else {
35880 self.write(", ");
35881 }
35882 }
35883 if !self.merge_strip_qualifiers.is_empty() {
35885 self.generate_merge_set_assignment(assignment)?;
35886 } else {
35887 self.generate_expression(assignment)?;
35888 }
35889 }
35890 } else {
35891 self.generate_expression(&elements[1])?;
35892 }
35893 if self.config.pretty {
35894 self.indent_level -= 1;
35895 }
35896 }
35897 }
35898 _ => {
35899 self.generate_expression(action)?;
35901 }
35902 }
35903 }
35904 Expression::Var(v)
35905 if v.this == "INSERT"
35906 || v.this == "UPDATE"
35907 || v.this == "DELETE"
35908 || v.this == "DO NOTHING" =>
35909 {
35910 self.write_keyword(&v.this);
35911 }
35912 _ => {
35913 self.generate_expression(action)?;
35914 }
35915 }
35916 Ok(())
35917 }
35918
35919 fn generate_merge_set_assignment(&mut self, assignment: &Expression) -> Result<()> {
35921 match assignment {
35922 Expression::Eq(eq) => {
35923 let stripped_left = self.strip_merge_qualifier(&eq.left);
35925 self.generate_expression(&stripped_left)?;
35926 self.write(" = ");
35927 self.generate_expression(&eq.right)?;
35928 Ok(())
35929 }
35930 other => self.generate_expression(other),
35931 }
35932 }
35933
35934 fn strip_merge_qualifier(&self, expr: &Expression) -> Expression {
35936 match expr {
35937 Expression::Column(col) => {
35938 if let Some(ref table_ident) = col.table {
35939 if self
35940 .merge_strip_qualifiers
35941 .iter()
35942 .any(|n| n.eq_ignore_ascii_case(&table_ident.name))
35943 {
35944 let mut col = col.clone();
35946 col.table = None;
35947 return Expression::Column(col);
35948 }
35949 }
35950 expr.clone()
35951 }
35952 Expression::Dot(dot) => {
35953 if let Expression::Identifier(id) = &dot.this {
35955 if self
35956 .merge_strip_qualifiers
35957 .iter()
35958 .any(|n| n.eq_ignore_ascii_case(&id.name))
35959 {
35960 return Expression::Identifier(dot.field.clone());
35961 }
35962 }
35963 expr.clone()
35964 }
35965 _ => expr.clone(),
35966 }
35967 }
35968
35969 fn generate_whens(&mut self, e: &Whens) -> Result<()> {
35970 for (i, expr) in e.expressions.iter().enumerate() {
35972 if i > 0 {
35973 if self.config.pretty {
35975 self.write_newline();
35976 self.write_indent();
35977 } else {
35978 self.write_space();
35979 }
35980 }
35981 self.generate_expression(expr)?;
35982 }
35983 Ok(())
35984 }
35985
35986 fn generate_where(&mut self, e: &Where) -> Result<()> {
35987 self.write_keyword("WHERE");
35989 self.write_space();
35990 self.generate_expression(&e.this)?;
35991 Ok(())
35992 }
35993
35994 fn generate_width_bucket(&mut self, e: &WidthBucket) -> Result<()> {
35995 self.write_keyword("WIDTH_BUCKET");
35997 self.write("(");
35998 self.generate_expression(&e.this)?;
35999 if let Some(min_value) = &e.min_value {
36000 self.write(", ");
36001 self.generate_expression(min_value)?;
36002 }
36003 if let Some(max_value) = &e.max_value {
36004 self.write(", ");
36005 self.generate_expression(max_value)?;
36006 }
36007 if let Some(num_buckets) = &e.num_buckets {
36008 self.write(", ");
36009 self.generate_expression(num_buckets)?;
36010 }
36011 self.write(")");
36012 Ok(())
36013 }
36014
36015 fn generate_window(&mut self, e: &WindowSpec) -> Result<()> {
36016 self.generate_window_spec(e)
36018 }
36019
36020 fn generate_window_spec(&mut self, e: &WindowSpec) -> Result<()> {
36021 let mut has_content = false;
36023
36024 if !e.partition_by.is_empty() {
36026 self.write_keyword("PARTITION BY");
36027 self.write_space();
36028 for (i, expr) in e.partition_by.iter().enumerate() {
36029 if i > 0 {
36030 self.write(", ");
36031 }
36032 self.generate_expression(expr)?;
36033 }
36034 has_content = true;
36035 }
36036
36037 if !e.order_by.is_empty() {
36039 if has_content {
36040 self.write_space();
36041 }
36042 self.write_keyword("ORDER BY");
36043 self.write_space();
36044 for (i, ordered) in e.order_by.iter().enumerate() {
36045 if i > 0 {
36046 self.write(", ");
36047 }
36048 self.generate_expression(&ordered.this)?;
36049 if ordered.desc {
36050 self.write_space();
36051 self.write_keyword("DESC");
36052 } else if ordered.explicit_asc {
36053 self.write_space();
36054 self.write_keyword("ASC");
36055 }
36056 if let Some(nulls_first) = ordered.nulls_first {
36057 self.write_space();
36058 self.write_keyword("NULLS");
36059 self.write_space();
36060 if nulls_first {
36061 self.write_keyword("FIRST");
36062 } else {
36063 self.write_keyword("LAST");
36064 }
36065 }
36066 }
36067 has_content = true;
36068 }
36069
36070 if let Some(frame) = &e.frame {
36072 if has_content {
36073 self.write_space();
36074 }
36075 self.generate_window_frame(frame)?;
36076 }
36077
36078 Ok(())
36079 }
36080
36081 fn generate_with_data_property(&mut self, e: &WithDataProperty) -> Result<()> {
36082 self.write_keyword("WITH");
36084 self.write_space();
36085 if e.no.is_some() {
36086 self.write_keyword("NO");
36087 self.write_space();
36088 }
36089 self.write_keyword("DATA");
36090
36091 if let Some(statistics) = &e.statistics {
36093 self.write_space();
36094 self.write_keyword("AND");
36095 self.write_space();
36096 match statistics.as_ref() {
36098 Expression::Boolean(b) if !b.value => {
36099 self.write_keyword("NO");
36100 self.write_space();
36101 }
36102 _ => {}
36103 }
36104 self.write_keyword("STATISTICS");
36105 }
36106 Ok(())
36107 }
36108
36109 fn generate_with_fill(&mut self, e: &WithFill) -> Result<()> {
36110 self.write_keyword("WITH FILL");
36112
36113 if let Some(from_) = &e.from_ {
36114 self.write_space();
36115 self.write_keyword("FROM");
36116 self.write_space();
36117 self.generate_expression(from_)?;
36118 }
36119
36120 if let Some(to) = &e.to {
36121 self.write_space();
36122 self.write_keyword("TO");
36123 self.write_space();
36124 self.generate_expression(to)?;
36125 }
36126
36127 if let Some(step) = &e.step {
36128 self.write_space();
36129 self.write_keyword("STEP");
36130 self.write_space();
36131 self.generate_expression(step)?;
36132 }
36133
36134 if let Some(staleness) = &e.staleness {
36135 self.write_space();
36136 self.write_keyword("STALENESS");
36137 self.write_space();
36138 self.generate_expression(staleness)?;
36139 }
36140
36141 if let Some(interpolate) = &e.interpolate {
36142 self.write_space();
36143 self.write_keyword("INTERPOLATE");
36144 self.write(" (");
36145 self.generate_interpolate_item(interpolate)?;
36147 self.write(")");
36148 }
36149
36150 Ok(())
36151 }
36152
36153 fn generate_interpolate_item(&mut self, expr: &Expression) -> Result<()> {
36155 match expr {
36156 Expression::Alias(alias) => {
36157 self.generate_identifier(&alias.alias)?;
36159 self.write_space();
36160 self.write_keyword("AS");
36161 self.write_space();
36162 self.generate_expression(&alias.this)?;
36163 }
36164 Expression::Tuple(tuple) => {
36165 for (i, item) in tuple.expressions.iter().enumerate() {
36166 if i > 0 {
36167 self.write(", ");
36168 }
36169 self.generate_interpolate_item(item)?;
36170 }
36171 }
36172 other => {
36173 self.generate_expression(other)?;
36174 }
36175 }
36176 Ok(())
36177 }
36178
36179 fn generate_with_journal_table_property(&mut self, e: &WithJournalTableProperty) -> Result<()> {
36180 self.write_keyword("WITH JOURNAL TABLE");
36182 self.write("=");
36183 self.generate_expression(&e.this)?;
36184 Ok(())
36185 }
36186
36187 fn generate_with_operator(&mut self, e: &WithOperator) -> Result<()> {
36188 self.generate_expression(&e.this)?;
36190 self.write_space();
36191 self.write_keyword("WITH");
36192 self.write_space();
36193 self.write_keyword(&e.op);
36194 Ok(())
36195 }
36196
36197 fn generate_with_procedure_options(&mut self, e: &WithProcedureOptions) -> Result<()> {
36198 self.write_keyword("WITH");
36200 self.write_space();
36201 for (i, expr) in e.expressions.iter().enumerate() {
36202 if i > 0 {
36203 self.write(", ");
36204 }
36205 self.generate_expression(expr)?;
36206 }
36207 Ok(())
36208 }
36209
36210 fn generate_with_schema_binding_property(
36211 &mut self,
36212 e: &WithSchemaBindingProperty,
36213 ) -> Result<()> {
36214 self.write_keyword("WITH");
36216 self.write_space();
36217 self.generate_expression(&e.this)?;
36218 Ok(())
36219 }
36220
36221 fn generate_with_system_versioning_property(
36222 &mut self,
36223 e: &WithSystemVersioningProperty,
36224 ) -> Result<()> {
36225 let mut parts = Vec::new();
36231
36232 if let Some(this) = &e.this {
36233 let mut s = String::from("HISTORY_TABLE=");
36235 let mut gen = Generator::new();
36236 gen.generate_expression(this)?;
36237 s.push_str(&gen.output);
36238 parts.push(s);
36239 }
36240
36241 if let Some(data_consistency) = &e.data_consistency {
36242 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
36243 let mut gen = Generator::new();
36244 gen.generate_expression(data_consistency)?;
36245 s.push_str(&gen.output);
36246 parts.push(s);
36247 }
36248
36249 if let Some(retention_period) = &e.retention_period {
36250 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
36251 let mut gen = Generator::new();
36252 gen.generate_expression(retention_period)?;
36253 s.push_str(&gen.output);
36254 parts.push(s);
36255 }
36256
36257 self.write_keyword("SYSTEM_VERSIONING");
36258 self.write("=");
36259
36260 if !parts.is_empty() {
36261 self.write_keyword("ON");
36262 self.write("(");
36263 self.write(&parts.join(", "));
36264 self.write(")");
36265 } else if e.on.is_some() {
36266 self.write_keyword("ON");
36267 } else {
36268 self.write_keyword("OFF");
36269 }
36270
36271 if e.with_.is_some() {
36273 let inner = self.output.clone();
36274 self.output.clear();
36275 self.write("WITH(");
36276 self.write(&inner);
36277 self.write(")");
36278 }
36279
36280 Ok(())
36281 }
36282
36283 fn generate_with_table_hint(&mut self, e: &WithTableHint) -> Result<()> {
36284 self.write_keyword("WITH");
36286 self.write(" (");
36287 for (i, expr) in e.expressions.iter().enumerate() {
36288 if i > 0 {
36289 self.write(", ");
36290 }
36291 self.generate_expression(expr)?;
36292 }
36293 self.write(")");
36294 Ok(())
36295 }
36296
36297 fn generate_xml_element(&mut self, e: &XMLElement) -> Result<()> {
36298 self.write_keyword("XMLELEMENT");
36301 self.write("(");
36302
36303 if e.evalname.is_some() {
36304 self.write_keyword("EVALNAME");
36305 } else {
36306 self.write_keyword("NAME");
36307 }
36308 self.write_space();
36309 self.generate_expression(&e.this)?;
36310
36311 for expr in &e.expressions {
36312 self.write(", ");
36313 self.generate_expression(expr)?;
36314 }
36315 self.write(")");
36316 Ok(())
36317 }
36318
36319 fn generate_xml_get(&mut self, e: &XMLGet) -> Result<()> {
36320 self.write_keyword("XMLGET");
36322 self.write("(");
36323 self.generate_expression(&e.this)?;
36324 self.write(", ");
36325 self.generate_expression(&e.expression)?;
36326 if let Some(instance) = &e.instance {
36327 self.write(", ");
36328 self.generate_expression(instance)?;
36329 }
36330 self.write(")");
36331 Ok(())
36332 }
36333
36334 fn generate_xml_key_value_option(&mut self, e: &XMLKeyValueOption) -> Result<()> {
36335 self.generate_expression(&e.this)?;
36337 if let Some(expression) = &e.expression {
36338 self.write("(");
36339 self.generate_expression(expression)?;
36340 self.write(")");
36341 }
36342 Ok(())
36343 }
36344
36345 fn generate_xml_table(&mut self, e: &XMLTable) -> Result<()> {
36346 self.write_keyword("XMLTABLE");
36348 self.write("(");
36349
36350 if self.config.pretty {
36351 self.indent_level += 1;
36352 self.write_newline();
36353 self.write_indent();
36354 self.generate_expression(&e.this)?;
36355
36356 if let Some(passing) = &e.passing {
36357 self.write_newline();
36358 self.write_indent();
36359 self.write_keyword("PASSING");
36360 if let Expression::Tuple(tuple) = passing.as_ref() {
36361 for expr in &tuple.expressions {
36362 self.write_newline();
36363 self.indent_level += 1;
36364 self.write_indent();
36365 self.generate_expression(expr)?;
36366 self.indent_level -= 1;
36367 }
36368 } else {
36369 self.write_newline();
36370 self.indent_level += 1;
36371 self.write_indent();
36372 self.generate_expression(passing)?;
36373 self.indent_level -= 1;
36374 }
36375 }
36376
36377 if e.by_ref.is_some() {
36378 self.write_newline();
36379 self.write_indent();
36380 self.write_keyword("RETURNING SEQUENCE BY REF");
36381 }
36382
36383 if !e.columns.is_empty() {
36384 self.write_newline();
36385 self.write_indent();
36386 self.write_keyword("COLUMNS");
36387 for (i, col) in e.columns.iter().enumerate() {
36388 self.write_newline();
36389 self.indent_level += 1;
36390 self.write_indent();
36391 self.generate_expression(col)?;
36392 self.indent_level -= 1;
36393 if i < e.columns.len() - 1 {
36394 self.write(",");
36395 }
36396 }
36397 }
36398
36399 self.indent_level -= 1;
36400 self.write_newline();
36401 self.write_indent();
36402 self.write(")");
36403 return Ok(());
36404 }
36405
36406 if let Some(namespaces) = &e.namespaces {
36408 self.write_keyword("XMLNAMESPACES");
36409 self.write("(");
36410 if let Expression::Tuple(tuple) = namespaces.as_ref() {
36412 for (i, expr) in tuple.expressions.iter().enumerate() {
36413 if i > 0 {
36414 self.write(", ");
36415 }
36416 if !matches!(expr, Expression::Alias(_)) {
36419 self.write_keyword("DEFAULT");
36420 self.write_space();
36421 }
36422 self.generate_expression(expr)?;
36423 }
36424 } else {
36425 if !matches!(namespaces.as_ref(), Expression::Alias(_)) {
36427 self.write_keyword("DEFAULT");
36428 self.write_space();
36429 }
36430 self.generate_expression(namespaces)?;
36431 }
36432 self.write("), ");
36433 }
36434
36435 self.generate_expression(&e.this)?;
36437
36438 if let Some(passing) = &e.passing {
36440 self.write_space();
36441 self.write_keyword("PASSING");
36442 self.write_space();
36443 if let Expression::Tuple(tuple) = passing.as_ref() {
36445 for (i, expr) in tuple.expressions.iter().enumerate() {
36446 if i > 0 {
36447 self.write(", ");
36448 }
36449 self.generate_expression(expr)?;
36450 }
36451 } else {
36452 self.generate_expression(passing)?;
36453 }
36454 }
36455
36456 if e.by_ref.is_some() {
36458 self.write_space();
36459 self.write_keyword("RETURNING SEQUENCE BY REF");
36460 }
36461
36462 if !e.columns.is_empty() {
36464 self.write_space();
36465 self.write_keyword("COLUMNS");
36466 self.write_space();
36467 for (i, col) in e.columns.iter().enumerate() {
36468 if i > 0 {
36469 self.write(", ");
36470 }
36471 self.generate_expression(col)?;
36472 }
36473 }
36474
36475 self.write(")");
36476 Ok(())
36477 }
36478
36479 fn generate_xor(&mut self, e: &Xor) -> Result<()> {
36480 if let Some(this) = &e.this {
36483 self.generate_expression(this)?;
36484 if let Some(expression) = &e.expression {
36485 self.write_space();
36486 self.write_keyword("XOR");
36487 self.write_space();
36488 self.generate_expression(expression)?;
36489 }
36490 }
36491
36492 for (i, expr) in e.expressions.iter().enumerate() {
36494 if i > 0 || e.this.is_some() {
36495 self.write_space();
36496 self.write_keyword("XOR");
36497 self.write_space();
36498 }
36499 self.generate_expression(expr)?;
36500 }
36501 Ok(())
36502 }
36503
36504 fn generate_zipf(&mut self, e: &Zipf) -> Result<()> {
36505 self.write_keyword("ZIPF");
36507 self.write("(");
36508 self.generate_expression(&e.this)?;
36509 if let Some(elementcount) = &e.elementcount {
36510 self.write(", ");
36511 self.generate_expression(elementcount)?;
36512 }
36513 if let Some(gen) = &e.gen {
36514 self.write(", ");
36515 self.generate_expression(gen)?;
36516 }
36517 self.write(")");
36518 Ok(())
36519 }
36520}
36521
36522impl Default for Generator {
36523 fn default() -> Self {
36524 Self::new()
36525 }
36526}
36527
36528#[cfg(test)]
36529mod tests {
36530 use super::*;
36531 use crate::parser::Parser;
36532
36533 fn roundtrip(sql: &str) -> String {
36534 let ast = Parser::parse_sql(sql).unwrap();
36535 Generator::sql(&ast[0]).unwrap()
36536 }
36537
36538 #[test]
36539 fn test_simple_select() {
36540 let result = roundtrip("SELECT 1");
36541 assert_eq!(result, "SELECT 1");
36542 }
36543
36544 #[test]
36545 fn test_select_from() {
36546 let result = roundtrip("SELECT a, b FROM t");
36547 assert_eq!(result, "SELECT a, b FROM t");
36548 }
36549
36550 #[test]
36551 fn test_select_where() {
36552 let result = roundtrip("SELECT * FROM t WHERE x = 1");
36553 assert_eq!(result, "SELECT * FROM t WHERE x = 1");
36554 }
36555
36556 #[test]
36557 fn test_select_join() {
36558 let result = roundtrip("SELECT * FROM a JOIN b ON a.id = b.id");
36559 assert_eq!(result, "SELECT * FROM a JOIN b ON a.id = b.id");
36560 }
36561
36562 #[test]
36563 fn test_insert() {
36564 let result = roundtrip("INSERT INTO t (a, b) VALUES (1, 2)");
36565 assert_eq!(result, "INSERT INTO t (a, b) VALUES (1, 2)");
36566 }
36567
36568 #[test]
36569 fn test_pretty_print() {
36570 let ast = Parser::parse_sql("SELECT a, b FROM t WHERE x = 1").unwrap();
36571 let result = Generator::pretty_sql(&ast[0]).unwrap();
36572 assert!(result.contains('\n'));
36573 }
36574
36575 #[test]
36576 fn test_window_function() {
36577 let result = roundtrip("SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)");
36578 assert_eq!(
36579 result,
36580 "SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)"
36581 );
36582 }
36583
36584 #[test]
36585 fn test_window_function_with_frame() {
36586 let result = roundtrip("SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
36587 assert_eq!(result, "SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
36588 }
36589
36590 #[test]
36591 fn test_aggregate_with_filter() {
36592 let result = roundtrip("SELECT COUNT(*) FILTER (WHERE status = 1) FROM orders");
36593 assert_eq!(
36594 result,
36595 "SELECT COUNT(*) FILTER(WHERE status = 1) FROM orders"
36596 );
36597 }
36598
36599 #[test]
36600 fn test_subscript() {
36601 let result = roundtrip("SELECT arr[0]");
36602 assert_eq!(result, "SELECT arr[0]");
36603 }
36604
36605 #[test]
36607 fn test_create_table() {
36608 let result = roundtrip("CREATE TABLE users (id INT, name VARCHAR(100))");
36609 assert_eq!(result, "CREATE TABLE users (id INT, name VARCHAR(100))");
36610 }
36611
36612 #[test]
36613 fn test_create_table_with_constraints() {
36614 let result = roundtrip(
36615 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)",
36616 );
36617 assert_eq!(
36618 result,
36619 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)"
36620 );
36621 }
36622
36623 #[test]
36624 fn test_create_table_if_not_exists() {
36625 let result = roundtrip("CREATE TABLE IF NOT EXISTS t (id INT)");
36626 assert_eq!(result, "CREATE TABLE IF NOT EXISTS t (id INT)");
36627 }
36628
36629 #[test]
36630 fn test_drop_table() {
36631 let result = roundtrip("DROP TABLE users");
36632 assert_eq!(result, "DROP TABLE users");
36633 }
36634
36635 #[test]
36636 fn test_drop_table_if_exists_cascade() {
36637 let result = roundtrip("DROP TABLE IF EXISTS users CASCADE");
36638 assert_eq!(result, "DROP TABLE IF EXISTS users CASCADE");
36639 }
36640
36641 #[test]
36642 fn test_alter_table_add_column() {
36643 let result = roundtrip("ALTER TABLE users ADD COLUMN email VARCHAR(255)");
36644 assert_eq!(result, "ALTER TABLE users ADD COLUMN email VARCHAR(255)");
36645 }
36646
36647 #[test]
36648 fn test_alter_table_drop_column() {
36649 let result = roundtrip("ALTER TABLE users DROP COLUMN email");
36650 assert_eq!(result, "ALTER TABLE users DROP COLUMN email");
36651 }
36652
36653 #[test]
36654 fn test_create_index() {
36655 let result = roundtrip("CREATE INDEX idx_name ON users(name)");
36656 assert_eq!(result, "CREATE INDEX idx_name ON users(name)");
36657 }
36658
36659 #[test]
36660 fn test_create_unique_index() {
36661 let result = roundtrip("CREATE UNIQUE INDEX idx_email ON users(email)");
36662 assert_eq!(result, "CREATE UNIQUE INDEX idx_email ON users(email)");
36663 }
36664
36665 #[test]
36666 fn test_drop_index() {
36667 let result = roundtrip("DROP INDEX idx_name");
36668 assert_eq!(result, "DROP INDEX idx_name");
36669 }
36670
36671 #[test]
36672 fn test_create_view() {
36673 let result = roundtrip("CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1");
36674 assert_eq!(
36675 result,
36676 "CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1"
36677 );
36678 }
36679
36680 #[test]
36681 fn test_drop_view() {
36682 let result = roundtrip("DROP VIEW active_users");
36683 assert_eq!(result, "DROP VIEW active_users");
36684 }
36685
36686 #[test]
36687 fn test_truncate() {
36688 let result = roundtrip("TRUNCATE TABLE users");
36689 assert_eq!(result, "TRUNCATE TABLE users");
36690 }
36691
36692 #[test]
36693 fn test_string_literal_escaping_default() {
36694 let result = roundtrip("SELECT 'hello'");
36696 assert_eq!(result, "SELECT 'hello'");
36697
36698 let result = roundtrip("SELECT 'it''s a test'");
36700 assert_eq!(result, "SELECT 'it''s a test'");
36701 }
36702
36703 #[test]
36704 fn test_not_in_style_prefix_default_generic() {
36705 let result = roundtrip("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')");
36706 assert_eq!(
36707 result,
36708 "SELECT id FROM users WHERE NOT status IN ('deleted', 'banned')"
36709 );
36710 }
36711
36712 #[test]
36713 fn test_not_in_style_infix_generic_override() {
36714 let ast =
36715 Parser::parse_sql("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')")
36716 .unwrap();
36717 let config = GeneratorConfig {
36718 not_in_style: NotInStyle::Infix,
36719 ..Default::default()
36720 };
36721 let mut gen = Generator::with_config(config);
36722 let result = gen.generate(&ast[0]).unwrap();
36723 assert_eq!(
36724 result,
36725 "SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')"
36726 );
36727 }
36728
36729 #[test]
36730 fn test_string_literal_escaping_mysql() {
36731 use crate::dialects::DialectType;
36732
36733 let config = GeneratorConfig {
36734 dialect: Some(DialectType::MySQL),
36735 ..Default::default()
36736 };
36737
36738 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
36739 let mut gen = Generator::with_config(config.clone());
36740 let result = gen.generate(&ast[0]).unwrap();
36741 assert_eq!(result, "SELECT 'hello'");
36742
36743 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
36745 let mut gen = Generator::with_config(config.clone());
36746 let result = gen.generate(&ast[0]).unwrap();
36747 assert_eq!(result, "SELECT 'it''s'");
36748 }
36749
36750 #[test]
36751 fn test_string_literal_escaping_postgres() {
36752 use crate::dialects::DialectType;
36753
36754 let config = GeneratorConfig {
36755 dialect: Some(DialectType::PostgreSQL),
36756 ..Default::default()
36757 };
36758
36759 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
36760 let mut gen = Generator::with_config(config.clone());
36761 let result = gen.generate(&ast[0]).unwrap();
36762 assert_eq!(result, "SELECT 'hello'");
36763
36764 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
36766 let mut gen = Generator::with_config(config.clone());
36767 let result = gen.generate(&ast[0]).unwrap();
36768 assert_eq!(result, "SELECT 'it''s'");
36769 }
36770
36771 #[test]
36772 fn test_string_literal_escaping_bigquery() {
36773 use crate::dialects::DialectType;
36774
36775 let config = GeneratorConfig {
36776 dialect: Some(DialectType::BigQuery),
36777 ..Default::default()
36778 };
36779
36780 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
36781 let mut gen = Generator::with_config(config.clone());
36782 let result = gen.generate(&ast[0]).unwrap();
36783 assert_eq!(result, "SELECT 'hello'");
36784
36785 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
36787 let mut gen = Generator::with_config(config.clone());
36788 let result = gen.generate(&ast[0]).unwrap();
36789 assert_eq!(result, "SELECT 'it\\'s'");
36790 }
36791
36792 #[test]
36793 fn test_generate_deep_and_chain_without_stack_growth() {
36794 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
36795 Expression::column("c0"),
36796 Expression::number(0),
36797 )));
36798
36799 for i in 1..2500 {
36800 let predicate = Expression::Eq(Box::new(BinaryOp::new(
36801 Expression::column(format!("c{i}")),
36802 Expression::number(i as i64),
36803 )));
36804 expr = Expression::And(Box::new(BinaryOp::new(expr, predicate)));
36805 }
36806
36807 let sql = Generator::sql(&expr).expect("deep AND chain should generate");
36808 assert!(sql.contains("c2499 = 2499"), "{}", sql);
36809 }
36810
36811 #[test]
36812 fn test_generate_deep_or_chain_without_stack_growth() {
36813 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
36814 Expression::column("c0"),
36815 Expression::number(0),
36816 )));
36817
36818 for i in 1..2500 {
36819 let predicate = Expression::Eq(Box::new(BinaryOp::new(
36820 Expression::column(format!("c{i}")),
36821 Expression::number(i as i64),
36822 )));
36823 expr = Expression::Or(Box::new(BinaryOp::new(expr, predicate)));
36824 }
36825
36826 let sql = Generator::sql(&expr).expect("deep OR chain should generate");
36827 assert!(sql.contains("c2499 = 2499"), "{}", sql);
36828 }
36829}