1use std::borrow::Cow;
14use std::sync::Arc;
15
16use crate::error::Result;
17use crate::expressions::*;
18use crate::DialectType;
19
20pub struct Generator {
45 config: Arc<GeneratorConfig>,
46 output: String,
47 unsupported_messages: Vec<String>,
48 indent_level: usize,
49 athena_hive_context: bool,
52 sqlite_inline_pk_columns: std::collections::HashSet<String>,
54 merge_strip_qualifiers: Vec<String>,
56 clickhouse_nullable_depth: i32,
61}
62
63#[derive(Debug, Clone, Copy, PartialEq, Default)]
69pub enum NormalizeFunctions {
70 #[default]
72 Upper,
73 Lower,
75 None,
77}
78
79#[derive(Debug, Clone, Copy, PartialEq, Default)]
81pub enum LimitFetchStyle {
82 #[default]
84 Limit,
85 Top,
87 FetchFirst,
89}
90
91#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
93pub enum NotInStyle {
94 #[default]
96 Prefix,
97 Infix,
99}
100
101#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
103pub enum UnsupportedLevel {
104 Ignore,
106 #[default]
108 Warn,
109 Raise,
111 Immediate,
113}
114
115#[derive(Debug, Clone, Copy, PartialEq, Eq)]
116enum ConnectorOperator {
117 And,
118 Or,
119}
120
121impl ConnectorOperator {
122 fn keyword(self) -> &'static str {
123 match self {
124 Self::And => "AND",
125 Self::Or => "OR",
126 }
127 }
128}
129
130#[derive(Debug, Clone, Copy, PartialEq)]
132pub struct IdentifierQuoteStyle {
133 pub start: char,
135 pub end: char,
137}
138
139impl Default for IdentifierQuoteStyle {
140 fn default() -> Self {
141 Self {
142 start: '"',
143 end: '"',
144 }
145 }
146}
147
148impl IdentifierQuoteStyle {
149 pub const DOUBLE_QUOTE: Self = Self {
151 start: '"',
152 end: '"',
153 };
154 pub const BACKTICK: Self = Self {
156 start: '`',
157 end: '`',
158 };
159 pub const BRACKET: Self = Self {
161 start: '[',
162 end: ']',
163 };
164}
165
166#[derive(Debug, Clone)]
188pub struct GeneratorConfig {
189 pub pretty: bool,
192 pub indent: &'static str,
194 pub max_text_width: usize,
196 pub identifier_quote: char,
198 pub identifier_quote_style: IdentifierQuoteStyle,
200 pub uppercase_keywords: bool,
202 pub normalize_identifiers: bool,
204 pub dialect: Option<crate::dialects::DialectType>,
206 pub source_dialect: Option<crate::dialects::DialectType>,
208 pub unsupported_level: UnsupportedLevel,
210 pub max_unsupported: usize,
212 pub normalize_functions: NormalizeFunctions,
214 pub string_escape: char,
216 pub case_sensitive_identifiers: bool,
218 pub identifiers_can_start_with_digit: bool,
220 pub always_quote_identifiers: bool,
223 pub not_in_style: NotInStyle,
225
226 pub null_ordering_supported: bool,
230 pub ignore_nulls_in_func: bool,
233 pub nvl2_supported: bool,
235
236 pub limit_fetch_style: LimitFetchStyle,
239 pub limit_is_top: bool,
241 pub limit_only_literals: bool,
243
244 pub single_string_interval: bool,
247 pub interval_allows_plural_form: bool,
249
250 pub cte_recursive_keyword_required: bool,
253
254 pub values_as_table: bool,
257 pub wrap_derived_values: bool,
259
260 pub tablesample_seed_keyword: &'static str,
263 pub tablesample_requires_parens: bool,
265 pub tablesample_size_is_rows: bool,
267 pub tablesample_keywords: &'static str,
269 pub tablesample_with_method: bool,
271 pub alias_post_tablesample: bool,
273
274 pub aggregate_filter_supported: bool,
277 pub multi_arg_distinct: bool,
279 pub quantified_no_paren_space: bool,
281 pub supports_median: bool,
283
284 pub supports_select_into: bool,
287 pub locking_reads_supported: bool,
289
290 pub rename_table_with_db: bool,
293 pub semi_anti_join_with_side: bool,
295 pub supports_table_alias_columns: bool,
297 pub join_hints: bool,
299 pub table_hints: bool,
301 pub query_hints: bool,
303 pub query_hint_sep: &'static str,
305 pub supports_column_join_marks: bool,
307
308 pub index_using_no_space: bool,
312 pub supports_unlogged_tables: bool,
314 pub supports_create_table_like: bool,
316 pub like_property_inside_schema: bool,
318 pub alter_table_include_column_keyword: bool,
320 pub supports_table_copy: bool,
322 pub alter_set_type: &'static str,
324 pub alter_set_wrapped: bool,
326
327 pub tz_to_with_time_zone: bool,
330 pub supports_convert_timezone: bool,
332
333 pub json_type_required_for_extraction: bool,
336 pub json_path_bracketed_key_supported: bool,
338 pub json_path_single_quote_escape: bool,
340 pub quote_json_path: bool,
342 pub json_key_value_pair_sep: &'static str,
344
345 pub copy_params_are_wrapped: bool,
348 pub copy_params_eq_required: bool,
350 pub copy_has_into_keyword: bool,
352
353 pub supports_window_exclude: bool,
356 pub unnest_with_ordinality: bool,
358 pub lowercase_window_frame_keywords: bool,
361 pub normalize_window_frame_between: bool,
364
365 pub array_concat_is_var_len: bool,
368 pub array_size_dim_required: Option<bool>,
371 pub can_implement_array_any: bool,
373 pub array_size_name: &'static str,
375
376 pub supports_between_flags: bool,
379
380 pub is_bool_allowed: bool,
383 pub ensure_bools: bool,
385
386 pub extract_allows_quotes: bool,
389 pub normalize_extract_date_parts: bool,
391
392 pub try_supported: bool,
395 pub supports_uescape: bool,
397 pub supports_to_number: bool,
399 pub supports_single_arg_concat: bool,
401 pub last_day_supports_date_part: bool,
403 pub supports_exploding_projections: bool,
405 pub supports_unix_seconds: bool,
407 pub supports_like_quantifiers: bool,
409 pub supports_decode_case: bool,
411 pub set_op_modifiers: bool,
413 pub update_statement_supports_from: bool,
415
416 pub collate_is_func: bool,
419
420 pub duplicate_key_update_with_set: bool,
423 pub insert_overwrite: &'static str,
425
426 pub returning_end: bool,
429
430 pub matched_by_source: bool,
433
434 pub create_function_return_as: bool,
437 pub parameter_default_equals: bool,
439
440 pub computed_column_with_type: bool,
443
444 pub unpivot_aliases_are_identifiers: bool,
447
448 pub star_except: &'static str,
451
452 pub hex_func: &'static str,
455
456 pub with_properties_prefix: &'static str,
459
460 pub pad_fill_pattern_is_required: bool,
463
464 pub index_on: &'static str,
467
468 pub groupings_sep: &'static str,
471
472 pub struct_delimiter: (&'static str, &'static str),
475 pub struct_curly_brace_notation: bool,
477 pub array_bracket_only: bool,
479 pub struct_field_sep: &'static str,
481
482 pub except_intersect_support_all_clause: bool,
485
486 pub parameter_token: &'static str,
489 pub named_placeholder_token: &'static str,
491
492 pub data_type_specifiers_allowed: bool,
495
496 pub schema_comment_with_eq: bool,
500}
501
502impl Default for GeneratorConfig {
503 fn default() -> Self {
504 Self {
505 pretty: false,
507 indent: " ",
508 max_text_width: 80,
509 identifier_quote: '"',
510 identifier_quote_style: IdentifierQuoteStyle::DOUBLE_QUOTE,
511 uppercase_keywords: true,
512 normalize_identifiers: false,
513 dialect: None,
514 source_dialect: None,
515 unsupported_level: UnsupportedLevel::Warn,
516 max_unsupported: 3,
517 normalize_functions: NormalizeFunctions::Upper,
518 string_escape: '\'',
519 case_sensitive_identifiers: false,
520 identifiers_can_start_with_digit: false,
521 always_quote_identifiers: false,
522 not_in_style: NotInStyle::Prefix,
523
524 null_ordering_supported: true,
526 ignore_nulls_in_func: false,
527 nvl2_supported: true,
528
529 limit_fetch_style: LimitFetchStyle::Limit,
531 limit_is_top: false,
532 limit_only_literals: false,
533
534 single_string_interval: false,
536 interval_allows_plural_form: true,
537
538 cte_recursive_keyword_required: true,
540
541 values_as_table: true,
543 wrap_derived_values: true,
544
545 tablesample_seed_keyword: "SEED",
547 tablesample_requires_parens: true,
548 tablesample_size_is_rows: true,
549 tablesample_keywords: "TABLESAMPLE",
550 tablesample_with_method: true,
551 alias_post_tablesample: false,
552
553 aggregate_filter_supported: true,
555 multi_arg_distinct: true,
556 quantified_no_paren_space: false,
557 supports_median: true,
558
559 supports_select_into: false,
561 locking_reads_supported: true,
562
563 rename_table_with_db: true,
565 semi_anti_join_with_side: true,
566 supports_table_alias_columns: true,
567 join_hints: true,
568 table_hints: true,
569 query_hints: true,
570 query_hint_sep: ", ",
571 supports_column_join_marks: false,
572
573 index_using_no_space: false,
575 supports_unlogged_tables: false,
576 supports_create_table_like: true,
577 like_property_inside_schema: false,
578 alter_table_include_column_keyword: true,
579 supports_table_copy: true,
580 alter_set_type: "SET DATA TYPE",
581 alter_set_wrapped: false,
582
583 tz_to_with_time_zone: false,
585 supports_convert_timezone: false,
586
587 json_type_required_for_extraction: false,
589 json_path_bracketed_key_supported: true,
590 json_path_single_quote_escape: false,
591 quote_json_path: true,
592 json_key_value_pair_sep: ":",
593
594 copy_params_are_wrapped: true,
596 copy_params_eq_required: false,
597 copy_has_into_keyword: true,
598
599 supports_window_exclude: false,
601 unnest_with_ordinality: true,
602 lowercase_window_frame_keywords: false,
603 normalize_window_frame_between: false,
604
605 array_concat_is_var_len: true,
607 array_size_dim_required: None,
608 can_implement_array_any: false,
609 array_size_name: "ARRAY_LENGTH",
610
611 supports_between_flags: false,
613
614 is_bool_allowed: true,
616 ensure_bools: false,
617
618 extract_allows_quotes: true,
620 normalize_extract_date_parts: false,
621
622 try_supported: true,
624 supports_uescape: true,
625 supports_to_number: true,
626 supports_single_arg_concat: true,
627 last_day_supports_date_part: true,
628 supports_exploding_projections: true,
629 supports_unix_seconds: false,
630 supports_like_quantifiers: true,
631 supports_decode_case: true,
632 set_op_modifiers: true,
633 update_statement_supports_from: true,
634
635 collate_is_func: false,
637
638 duplicate_key_update_with_set: true,
640 insert_overwrite: " OVERWRITE TABLE",
641
642 returning_end: true,
644
645 matched_by_source: true,
647
648 create_function_return_as: true,
650 parameter_default_equals: false,
651
652 computed_column_with_type: true,
654
655 unpivot_aliases_are_identifiers: true,
657
658 star_except: "EXCEPT",
660
661 hex_func: "HEX",
663
664 with_properties_prefix: "WITH",
666
667 pad_fill_pattern_is_required: false,
669
670 index_on: "ON",
672
673 groupings_sep: ",",
675
676 struct_delimiter: ("<", ">"),
678 struct_curly_brace_notation: false,
679 array_bracket_only: false,
680 struct_field_sep: " ",
681
682 except_intersect_support_all_clause: true,
684
685 parameter_token: "@",
687 named_placeholder_token: ":",
688
689 data_type_specifiers_allowed: false,
691
692 schema_comment_with_eq: true,
694 }
695 }
696}
697
698mod reserved_keywords {
701 use std::collections::HashSet;
702 use std::sync::LazyLock;
703
704 pub static SQL_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
706 [
707 "all",
708 "alter",
709 "and",
710 "any",
711 "array",
712 "as",
713 "asc",
714 "at",
715 "authorization",
716 "begin",
717 "between",
718 "both",
719 "by",
720 "case",
721 "cast",
722 "check",
723 "collate",
724 "column",
725 "commit",
726 "constraint",
727 "create",
728 "cross",
729 "cube",
730 "current",
731 "current_date",
732 "current_time",
733 "current_timestamp",
734 "current_user",
735 "default",
736 "delete",
737 "desc",
738 "distinct",
739 "drop",
740 "else",
741 "end",
742 "escape",
743 "except",
744 "execute",
745 "exists",
746 "external",
747 "false",
748 "fetch",
749 "filter",
750 "for",
751 "foreign",
752 "from",
753 "full",
754 "function",
755 "grant",
756 "group",
757 "grouping",
758 "having",
759 "if",
760 "in",
761 "index",
762 "inner",
763 "insert",
764 "intersect",
765 "interval",
766 "into",
767 "is",
768 "join",
769 "key",
770 "leading",
771 "left",
772 "like",
773 "limit",
774 "local",
775 "localtime",
776 "localtimestamp",
777 "match",
778 "merge",
779 "natural",
780 "no",
781 "not",
782 "null",
783 "of",
784 "offset",
785 "on",
786 "only",
787 "or",
788 "order",
789 "outer",
790 "over",
791 "partition",
792 "primary",
793 "procedure",
794 "range",
795 "references",
796 "right",
797 "rollback",
798 "rollup",
799 "row",
800 "rows",
801 "select",
802 "session_user",
803 "set",
804 "some",
805 "table",
806 "tablesample",
807 "then",
808 "to",
809 "trailing",
810 "true",
811 "truncate",
812 "union",
813 "unique",
814 "unknown",
815 "update",
816 "user",
817 "using",
818 "values",
819 "view",
820 "when",
821 "where",
822 "window",
823 "with",
824 ]
825 .into_iter()
826 .collect()
827 });
828
829 pub static BIGQUERY_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
832 let mut set = SQL_RESERVED.clone();
833 set.extend([
834 "assert_rows_modified",
835 "at",
836 "contains",
837 "cube",
838 "current",
839 "define",
840 "enum",
841 "escape",
842 "exclude",
843 "following",
844 "for",
845 "groups",
846 "hash",
847 "ignore",
848 "lateral",
849 "lookup",
850 "new",
851 "no",
852 "nulls",
853 "of",
854 "over",
855 "preceding",
856 "proto",
857 "qualify",
858 "recursive",
859 "respect",
860 "struct",
861 "tablesample",
862 "treat",
863 "unbounded",
864 "unnest",
865 "window",
866 "within",
867 ]);
868 set.remove("grant");
870 set.remove("key");
871 set.remove("index");
872 set.remove("offset");
873 set.remove("values");
874 set.remove("table");
875 set
876 });
877
878 pub static MYSQL_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
880 let mut set = SQL_RESERVED.clone();
881 set.extend([
882 "accessible",
883 "add",
884 "analyze",
885 "asensitive",
886 "before",
887 "bigint",
888 "binary",
889 "blob",
890 "call",
891 "cascade",
892 "change",
893 "char",
894 "character",
895 "condition",
896 "continue",
897 "convert",
898 "current_date",
899 "current_time",
900 "current_timestamp",
901 "current_user",
902 "cursor",
903 "database",
904 "databases",
905 "day_hour",
906 "day_microsecond",
907 "day_minute",
908 "day_second",
909 "dec",
910 "decimal",
911 "declare",
912 "delayed",
913 "describe",
914 "deterministic",
915 "distinctrow",
916 "div",
917 "double",
918 "dual",
919 "each",
920 "elseif",
921 "enclosed",
922 "escaped",
923 "exit",
924 "explain",
925 "float",
926 "float4",
927 "float8",
928 "force",
929 "get",
930 "high_priority",
931 "hour_microsecond",
932 "hour_minute",
933 "hour_second",
934 "ignore",
935 "infile",
936 "inout",
937 "insensitive",
938 "int",
939 "int1",
940 "int2",
941 "int3",
942 "int4",
943 "int8",
944 "integer",
945 "iterate",
946 "keys",
947 "kill",
948 "leave",
949 "linear",
950 "lines",
951 "load",
952 "lock",
953 "long",
954 "longblob",
955 "longtext",
956 "loop",
957 "low_priority",
958 "master_ssl_verify_server_cert",
959 "maxvalue",
960 "mediumblob",
961 "mediumint",
962 "mediumtext",
963 "middleint",
964 "minute_microsecond",
965 "minute_second",
966 "mod",
967 "modifies",
968 "no_write_to_binlog",
969 "numeric",
970 "optimize",
971 "option",
972 "optionally",
973 "out",
974 "outfile",
975 "precision",
976 "purge",
977 "read",
978 "reads",
979 "real",
980 "regexp",
981 "release",
982 "rename",
983 "repeat",
984 "replace",
985 "require",
986 "resignal",
987 "restrict",
988 "return",
989 "revoke",
990 "rlike",
991 "schema",
992 "schemas",
993 "second_microsecond",
994 "sensitive",
995 "separator",
996 "show",
997 "signal",
998 "smallint",
999 "spatial",
1000 "specific",
1001 "sql",
1002 "sql_big_result",
1003 "sql_calc_found_rows",
1004 "sql_small_result",
1005 "sqlexception",
1006 "sqlstate",
1007 "sqlwarning",
1008 "ssl",
1009 "starting",
1010 "straight_join",
1011 "terminated",
1012 "text",
1013 "tinyblob",
1014 "tinyint",
1015 "tinytext",
1016 "trigger",
1017 "undo",
1018 "unlock",
1019 "unsigned",
1020 "usage",
1021 "utc_date",
1022 "utc_time",
1023 "utc_timestamp",
1024 "varbinary",
1025 "varchar",
1026 "varcharacter",
1027 "varying",
1028 "while",
1029 "write",
1030 "xor",
1031 "year_month",
1032 "zerofill",
1033 ]);
1034 set.remove("table");
1035 set
1036 });
1037
1038 pub static DORIS_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1041 let mut set = MYSQL_RESERVED.clone();
1042 set.extend([
1043 "aggregate",
1044 "anti",
1045 "array",
1046 "backend",
1047 "backup",
1048 "begin",
1049 "bitmap",
1050 "boolean",
1051 "broker",
1052 "buckets",
1053 "cached",
1054 "cancel",
1055 "cast",
1056 "catalog",
1057 "charset",
1058 "cluster",
1059 "collation",
1060 "columns",
1061 "comment",
1062 "commit",
1063 "config",
1064 "connection",
1065 "count",
1066 "current",
1067 "data",
1068 "date",
1069 "datetime",
1070 "day",
1071 "deferred",
1072 "distributed",
1073 "dynamic",
1074 "enable",
1075 "end",
1076 "events",
1077 "export",
1078 "external",
1079 "fields",
1080 "first",
1081 "follower",
1082 "format",
1083 "free",
1084 "frontend",
1085 "full",
1086 "functions",
1087 "global",
1088 "grants",
1089 "hash",
1090 "help",
1091 "hour",
1092 "install",
1093 "intermediate",
1094 "json",
1095 "label",
1096 "last",
1097 "less",
1098 "level",
1099 "link",
1100 "local",
1101 "location",
1102 "max",
1103 "merge",
1104 "min",
1105 "minute",
1106 "modify",
1107 "month",
1108 "name",
1109 "names",
1110 "negative",
1111 "nulls",
1112 "observer",
1113 "offset",
1114 "only",
1115 "open",
1116 "overwrite",
1117 "password",
1118 "path",
1119 "plan",
1120 "plugin",
1121 "plugins",
1122 "policy",
1123 "process",
1124 "properties",
1125 "property",
1126 "query",
1127 "quota",
1128 "recover",
1129 "refresh",
1130 "repair",
1131 "replica",
1132 "repository",
1133 "resource",
1134 "restore",
1135 "resume",
1136 "role",
1137 "roles",
1138 "rollback",
1139 "rollup",
1140 "routine",
1141 "sample",
1142 "second",
1143 "semi",
1144 "session",
1145 "signed",
1146 "snapshot",
1147 "start",
1148 "stats",
1149 "status",
1150 "stop",
1151 "stream",
1152 "string",
1153 "sum",
1154 "tables",
1155 "tablet",
1156 "temporary",
1157 "text",
1158 "timestamp",
1159 "transaction",
1160 "trash",
1161 "trim",
1162 "truncate",
1163 "type",
1164 "user",
1165 "value",
1166 "variables",
1167 "verbose",
1168 "version",
1169 "view",
1170 "warnings",
1171 "week",
1172 "work",
1173 "year",
1174 ]);
1175 set
1176 });
1177
1178 pub static POSTGRES_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1180 let mut set = SQL_RESERVED.clone();
1181 set.extend([
1182 "analyse",
1183 "analyze",
1184 "asymmetric",
1185 "binary",
1186 "collation",
1187 "concurrently",
1188 "current_catalog",
1189 "current_role",
1190 "current_schema",
1191 "deferrable",
1192 "do",
1193 "freeze",
1194 "ilike",
1195 "initially",
1196 "isnull",
1197 "lateral",
1198 "notnull",
1199 "placing",
1200 "returning",
1201 "similar",
1202 "symmetric",
1203 "variadic",
1204 "verbose",
1205 ]);
1206 set.remove("default");
1208 set.remove("interval");
1209 set.remove("match");
1210 set.remove("offset");
1211 set.remove("table");
1212 set
1213 });
1214
1215 pub static REDSHIFT_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1219 [
1220 "aes128",
1221 "aes256",
1222 "all",
1223 "allowoverwrite",
1224 "analyse",
1225 "analyze",
1226 "and",
1227 "any",
1228 "array",
1229 "as",
1230 "asc",
1231 "authorization",
1232 "az64",
1233 "backup",
1234 "between",
1235 "binary",
1236 "blanksasnull",
1237 "both",
1238 "bytedict",
1239 "bzip2",
1240 "case",
1241 "cast",
1242 "check",
1243 "collate",
1244 "column",
1245 "constraint",
1246 "create",
1247 "credentials",
1248 "cross",
1249 "current_date",
1250 "current_time",
1251 "current_timestamp",
1252 "current_user",
1253 "current_user_id",
1254 "default",
1255 "deferrable",
1256 "deflate",
1257 "defrag",
1258 "delta",
1259 "delta32k",
1260 "desc",
1261 "disable",
1262 "distinct",
1263 "do",
1264 "else",
1265 "emptyasnull",
1266 "enable",
1267 "encode",
1268 "encrypt",
1269 "encryption",
1270 "end",
1271 "except",
1272 "explicit",
1273 "false",
1274 "for",
1275 "foreign",
1276 "freeze",
1277 "from",
1278 "full",
1279 "globaldict256",
1280 "globaldict64k",
1281 "grant",
1282 "group",
1283 "gzip",
1284 "having",
1285 "identity",
1286 "ignore",
1287 "ilike",
1288 "in",
1289 "initially",
1290 "inner",
1291 "intersect",
1292 "interval",
1293 "into",
1294 "is",
1295 "isnull",
1296 "join",
1297 "leading",
1298 "left",
1299 "like",
1300 "limit",
1301 "localtime",
1302 "localtimestamp",
1303 "lun",
1304 "luns",
1305 "lzo",
1306 "lzop",
1307 "minus",
1308 "mostly16",
1309 "mostly32",
1310 "mostly8",
1311 "natural",
1312 "new",
1313 "not",
1314 "notnull",
1315 "null",
1316 "nulls",
1317 "off",
1318 "offline",
1319 "offset",
1320 "oid",
1321 "old",
1322 "on",
1323 "only",
1324 "open",
1325 "or",
1326 "order",
1327 "outer",
1328 "overlaps",
1329 "parallel",
1330 "partition",
1331 "percent",
1332 "permissions",
1333 "pivot",
1334 "placing",
1335 "primary",
1336 "raw",
1337 "readratio",
1338 "recover",
1339 "references",
1340 "rejectlog",
1341 "resort",
1342 "respect",
1343 "restore",
1344 "right",
1345 "select",
1346 "session_user",
1347 "similar",
1348 "snapshot",
1349 "some",
1350 "sysdate",
1351 "system",
1352 "table",
1353 "tag",
1354 "tdes",
1355 "text255",
1356 "text32k",
1357 "then",
1358 "timestamp",
1359 "to",
1360 "top",
1361 "trailing",
1362 "true",
1363 "truncatecolumns",
1364 "type",
1365 "union",
1366 "unique",
1367 "unnest",
1368 "unpivot",
1369 "user",
1370 "using",
1371 "verbose",
1372 "wallet",
1373 "when",
1374 "where",
1375 "with",
1376 "without",
1377 ]
1378 .into_iter()
1379 .collect()
1380 });
1381
1382 pub static DUCKDB_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1384 let mut set = POSTGRES_RESERVED.clone();
1385 set.extend([
1386 "anti",
1387 "asof",
1388 "columns",
1389 "describe",
1390 "groups",
1391 "macro",
1392 "pivot",
1393 "pivot_longer",
1394 "pivot_wider",
1395 "qualify",
1396 "replace",
1397 "respect",
1398 "semi",
1399 "show",
1400 "table",
1401 "unpivot",
1402 ]);
1403 set.remove("at");
1404 set.remove("key");
1405 set.remove("range");
1406 set.remove("row");
1407 set.remove("values");
1408 set
1409 });
1410
1411 pub static PRESTO_TRINO_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1413 let mut set = SQL_RESERVED.clone();
1414 set.extend([
1415 "alter",
1416 "and",
1417 "as",
1418 "between",
1419 "by",
1420 "case",
1421 "cast",
1422 "constraint",
1423 "create",
1424 "cross",
1425 "cube",
1426 "current_catalog",
1427 "current_date",
1428 "current_path",
1429 "current_role",
1430 "current_schema",
1431 "current_time",
1432 "current_timestamp",
1433 "current_user",
1434 "deallocate",
1435 "delete",
1436 "describe",
1437 "distinct",
1438 "drop",
1439 "else",
1440 "end",
1441 "escape",
1442 "except",
1443 "execute",
1444 "exists",
1445 "extract",
1446 "false",
1447 "for",
1448 "from",
1449 "full",
1450 "group",
1451 "grouping",
1452 "having",
1453 "in",
1454 "inner",
1455 "insert",
1456 "intersect",
1457 "into",
1458 "is",
1459 "join",
1460 "json_array",
1461 "json_exists",
1462 "json_object",
1463 "json_query",
1464 "json_table",
1465 "json_value",
1466 "left",
1467 "like",
1468 "listagg",
1469 "localtime",
1470 "localtimestamp",
1471 "natural",
1472 "normalize",
1473 "not",
1474 "null",
1475 "on",
1476 "or",
1477 "order",
1478 "outer",
1479 "prepare",
1480 "recursive",
1481 "right",
1482 "rollup",
1483 "select",
1484 "skip",
1485 "table",
1486 "then",
1487 "trim",
1488 "true",
1489 "uescape",
1490 "union",
1491 "unnest",
1492 "using",
1493 "values",
1494 "when",
1495 "where",
1496 "with",
1497 ]);
1498 set.remove("key");
1500 set
1501 });
1502
1503 pub static STARROCKS_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1506 [
1507 "add",
1508 "all",
1509 "alter",
1510 "analyze",
1511 "and",
1512 "array",
1513 "as",
1514 "asc",
1515 "between",
1516 "bigint",
1517 "bitmap",
1518 "both",
1519 "by",
1520 "case",
1521 "char",
1522 "character",
1523 "check",
1524 "collate",
1525 "column",
1526 "compaction",
1527 "convert",
1528 "create",
1529 "cross",
1530 "cube",
1531 "current_date",
1532 "current_role",
1533 "current_time",
1534 "current_timestamp",
1535 "current_user",
1536 "database",
1537 "databases",
1538 "decimal",
1539 "decimalv2",
1540 "decimal32",
1541 "decimal64",
1542 "decimal128",
1543 "default",
1544 "deferred",
1545 "delete",
1546 "dense_rank",
1547 "desc",
1548 "describe",
1549 "distinct",
1550 "double",
1551 "drop",
1552 "dual",
1553 "else",
1554 "except",
1555 "exists",
1556 "explain",
1557 "false",
1558 "first_value",
1559 "float",
1560 "for",
1561 "force",
1562 "from",
1563 "full",
1564 "function",
1565 "grant",
1566 "group",
1567 "grouping",
1568 "grouping_id",
1569 "groups",
1570 "having",
1571 "hll",
1572 "host",
1573 "if",
1574 "ignore",
1575 "immediate",
1576 "in",
1577 "index",
1578 "infile",
1579 "inner",
1580 "insert",
1581 "int",
1582 "integer",
1583 "intersect",
1584 "into",
1585 "is",
1586 "join",
1587 "json",
1588 "key",
1589 "keys",
1590 "kill",
1591 "lag",
1592 "largeint",
1593 "last_value",
1594 "lateral",
1595 "lead",
1596 "left",
1597 "like",
1598 "limit",
1599 "load",
1600 "localtime",
1601 "localtimestamp",
1602 "maxvalue",
1603 "minus",
1604 "mod",
1605 "not",
1606 "ntile",
1607 "null",
1608 "on",
1609 "or",
1610 "order",
1611 "outer",
1612 "outfile",
1613 "over",
1614 "partition",
1615 "percentile",
1616 "primary",
1617 "procedure",
1618 "qualify",
1619 "range",
1620 "rank",
1621 "read",
1622 "regexp",
1623 "release",
1624 "rename",
1625 "replace",
1626 "revoke",
1627 "right",
1628 "rlike",
1629 "row",
1630 "row_number",
1631 "rows",
1632 "schema",
1633 "schemas",
1634 "select",
1635 "set",
1636 "set_var",
1637 "show",
1638 "smallint",
1639 "system",
1640 "table",
1641 "terminated",
1642 "text",
1643 "then",
1644 "tinyint",
1645 "to",
1646 "true",
1647 "union",
1648 "unique",
1649 "unsigned",
1650 "update",
1651 "use",
1652 "using",
1653 "values",
1654 "varchar",
1655 "when",
1656 "where",
1657 "with",
1658 ]
1659 .into_iter()
1660 .collect()
1661 });
1662
1663 pub static SINGLESTORE_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1666 let mut set = MYSQL_RESERVED.clone();
1667 set.extend([
1668 "abs",
1671 "account",
1672 "acos",
1673 "adddate",
1674 "addtime",
1675 "admin",
1676 "aes_decrypt",
1677 "aes_encrypt",
1678 "aggregate",
1679 "aggregates",
1680 "aggregator",
1681 "anti_join",
1682 "any_value",
1683 "approx_count_distinct",
1684 "approx_percentile",
1685 "arrange",
1686 "arrangement",
1687 "asin",
1688 "atan",
1689 "atan2",
1690 "attach",
1691 "autostats",
1692 "avro",
1693 "background",
1694 "backup",
1695 "batch",
1696 "batches",
1697 "boot_strapping",
1698 "ceil",
1699 "ceiling",
1700 "coercibility",
1701 "columnar",
1702 "columnstore",
1703 "compile",
1704 "concurrent",
1705 "connection_id",
1706 "cos",
1707 "cot",
1708 "current_security_groups",
1709 "current_security_roles",
1710 "dayname",
1711 "dayofmonth",
1712 "dayofweek",
1713 "dayofyear",
1714 "degrees",
1715 "dot_product",
1716 "dump",
1717 "durability",
1718 "earliest",
1719 "echo",
1720 "election",
1721 "euclidean_distance",
1722 "exp",
1723 "extractor",
1724 "extractors",
1725 "floor",
1726 "foreground",
1727 "found_rows",
1728 "from_base64",
1729 "from_days",
1730 "from_unixtime",
1731 "fs",
1732 "fulltext",
1733 "gc",
1734 "gcs",
1735 "geography",
1736 "geography_area",
1737 "geography_contains",
1738 "geography_distance",
1739 "geography_intersects",
1740 "geography_latitude",
1741 "geography_length",
1742 "geography_longitude",
1743 "geographypoint",
1744 "geography_point",
1745 "geography_within_distance",
1746 "geometry",
1747 "geometry_area",
1748 "geometry_contains",
1749 "geometry_distance",
1750 "geometry_filter",
1751 "geometry_intersects",
1752 "geometry_length",
1753 "geometrypoint",
1754 "geometry_point",
1755 "geometry_within_distance",
1756 "geometry_x",
1757 "geometry_y",
1758 "greatest",
1759 "groups",
1760 "group_concat",
1761 "gzip",
1762 "hdfs",
1763 "hex",
1764 "highlight",
1765 "ifnull",
1766 "ilike",
1767 "inet_aton",
1768 "inet_ntoa",
1769 "inet6_aton",
1770 "inet6_ntoa",
1771 "initcap",
1772 "instr",
1773 "interpreter_mode",
1774 "isnull",
1775 "json",
1776 "json_agg",
1777 "json_array_contains_double",
1778 "json_array_contains_json",
1779 "json_array_contains_string",
1780 "json_delete_key",
1781 "json_extract_double",
1782 "json_extract_json",
1783 "json_extract_string",
1784 "json_extract_bigint",
1785 "json_get_type",
1786 "json_length",
1787 "json_set_double",
1788 "json_set_json",
1789 "json_set_string",
1790 "kafka",
1791 "lag",
1792 "last_day",
1793 "last_insert_id",
1794 "latest",
1795 "lcase",
1796 "lead",
1797 "leaf",
1798 "least",
1799 "leaves",
1800 "length",
1801 "license",
1802 "links",
1803 "llvm",
1804 "ln",
1805 "load",
1806 "locate",
1807 "log",
1808 "log10",
1809 "log2",
1810 "lpad",
1811 "lz4",
1812 "management",
1813 "match",
1814 "mbc",
1815 "md5",
1816 "median",
1817 "memsql",
1818 "memsql_deserialize",
1819 "memsql_serialize",
1820 "metadata",
1821 "microsecond",
1822 "minute",
1823 "model",
1824 "monthname",
1825 "months_between",
1826 "mpl",
1827 "namespace",
1828 "node",
1829 "noparam",
1830 "now",
1831 "nth_value",
1832 "ntile",
1833 "nullcols",
1834 "nullif",
1835 "object",
1836 "octet_length",
1837 "offsets",
1838 "online",
1839 "optimizer",
1840 "orphan",
1841 "parquet",
1842 "partitions",
1843 "pause",
1844 "percentile_cont",
1845 "percentile_disc",
1846 "periodic",
1847 "persisted",
1848 "pi",
1849 "pipeline",
1850 "pipelines",
1851 "plancache",
1852 "plugins",
1853 "pool",
1854 "pools",
1855 "pow",
1856 "power",
1857 "process",
1858 "processlist",
1859 "profile",
1860 "profiles",
1861 "quarter",
1862 "queries",
1863 "query",
1864 "radians",
1865 "rand",
1866 "record",
1867 "reduce",
1868 "redundancy",
1869 "regexp_match",
1870 "regexp_substr",
1871 "remote",
1872 "replication",
1873 "resource",
1874 "resource_pool",
1875 "restore",
1876 "retry",
1877 "role",
1878 "roles",
1879 "round",
1880 "rpad",
1881 "rtrim",
1882 "running",
1883 "s3",
1884 "scalar",
1885 "sec_to_time",
1886 "second",
1887 "security_lists_intersect",
1888 "semi_join",
1889 "sha",
1890 "sha1",
1891 "sha2",
1892 "shard",
1893 "sharded",
1894 "sharded_id",
1895 "sigmoid",
1896 "sign",
1897 "sin",
1898 "skip",
1899 "sleep",
1900 "snapshot",
1901 "soname",
1902 "sparse",
1903 "spatial_check_index",
1904 "split",
1905 "sqrt",
1906 "standalone",
1907 "std",
1908 "stddev",
1909 "stddev_pop",
1910 "stddev_samp",
1911 "stop",
1912 "str_to_date",
1913 "subdate",
1914 "substr",
1915 "substring_index",
1916 "success",
1917 "synchronize",
1918 "table_checksum",
1919 "tan",
1920 "task",
1921 "timediff",
1922 "time_bucket",
1923 "time_format",
1924 "time_to_sec",
1925 "timestampadd",
1926 "timestampdiff",
1927 "to_base64",
1928 "to_char",
1929 "to_date",
1930 "to_days",
1931 "to_json",
1932 "to_number",
1933 "to_seconds",
1934 "to_timestamp",
1935 "tracelogs",
1936 "transform",
1937 "trim",
1938 "trunc",
1939 "truncate",
1940 "ucase",
1941 "unhex",
1942 "unix_timestamp",
1943 "utc_date",
1944 "utc_time",
1945 "utc_timestamp",
1946 "vacuum",
1947 "variance",
1948 "var_pop",
1949 "var_samp",
1950 "vector_sub",
1951 "voting",
1952 "week",
1953 "weekday",
1954 "weekofyear",
1955 "workload",
1956 "year",
1957 ]);
1958 set.remove("all");
1960 set
1961 });
1962
1963 pub static SQLITE_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1967 [
1969 "abort",
1970 "action",
1971 "add",
1972 "after",
1973 "all",
1974 "alter",
1975 "always",
1976 "analyze",
1977 "and",
1978 "as",
1979 "asc",
1980 "attach",
1981 "autoincrement",
1982 "before",
1983 "begin",
1984 "between",
1985 "by",
1986 "cascade",
1987 "case",
1988 "cast",
1989 "check",
1990 "collate",
1991 "column",
1992 "commit",
1993 "conflict",
1994 "constraint",
1995 "create",
1996 "cross",
1997 "current",
1998 "current_date",
1999 "current_time",
2000 "current_timestamp",
2001 "database",
2002 "default",
2003 "deferrable",
2004 "deferred",
2005 "delete",
2006 "desc",
2007 "detach",
2008 "distinct",
2009 "do",
2010 "drop",
2011 "each",
2012 "else",
2013 "end",
2014 "escape",
2015 "except",
2016 "exclude",
2017 "exclusive",
2018 "exists",
2019 "explain",
2020 "fail",
2021 "filter",
2022 "first",
2023 "following",
2024 "for",
2025 "foreign",
2026 "from",
2027 "full",
2028 "generated",
2029 "glob",
2030 "group",
2031 "groups",
2032 "having",
2033 "if",
2034 "ignore",
2035 "immediate",
2036 "in",
2037 "index",
2038 "indexed",
2039 "initially",
2040 "inner",
2041 "insert",
2042 "instead",
2043 "intersect",
2044 "into",
2045 "is",
2046 "isnull",
2047 "join",
2048 "key",
2049 "last",
2050 "left",
2051 "like",
2052 "limit",
2053 "natural",
2054 "no",
2055 "not",
2056 "nothing",
2057 "notnull",
2058 "null",
2059 "nulls",
2060 "of",
2061 "offset",
2062 "on",
2063 "or",
2064 "order",
2065 "others",
2066 "outer",
2067 "partition",
2068 "plan",
2069 "pragma",
2070 "preceding",
2071 "primary",
2072 "query",
2073 "raise",
2074 "range",
2075 "recursive",
2076 "references",
2077 "regexp",
2078 "reindex",
2079 "release",
2080 "rename",
2081 "replace",
2082 "restrict",
2083 "returning",
2084 "right",
2085 "rollback",
2086 "row",
2087 "rows",
2088 "savepoint",
2089 "select",
2090 "set",
2091 "table",
2092 "temp",
2093 "temporary",
2094 "then",
2095 "ties",
2096 "to",
2097 "transaction",
2098 "trigger",
2099 "unbounded",
2100 "union",
2101 "unique",
2102 "update",
2103 "using",
2104 "vacuum",
2105 "values",
2106 "view",
2107 "virtual",
2108 "when",
2109 "where",
2110 "window",
2111 "with",
2112 "without",
2113 ]
2114 .into_iter()
2115 .collect()
2116 });
2117}
2118
2119impl Generator {
2120 pub fn new() -> Self {
2126 Self::with_config(GeneratorConfig::default())
2127 }
2128
2129 pub fn with_config(config: GeneratorConfig) -> Self {
2134 Self::with_arc_config(Arc::new(config))
2135 }
2136
2137 pub(crate) fn with_arc_config(config: Arc<GeneratorConfig>) -> Self {
2142 Self {
2143 config,
2144 output: String::new(),
2145 unsupported_messages: Vec::new(),
2146 indent_level: 0,
2147 athena_hive_context: false,
2148 sqlite_inline_pk_columns: std::collections::HashSet::new(),
2149 merge_strip_qualifiers: Vec::new(),
2150 clickhouse_nullable_depth: 0,
2151 }
2152 }
2153
2154 fn add_column_aliases_to_query(expr: Expression) -> Expression {
2158 match expr {
2159 Expression::Select(mut select) => {
2160 select.expressions = select
2162 .expressions
2163 .into_iter()
2164 .map(|e| Self::add_alias_to_expression(e))
2165 .collect();
2166
2167 if let Some(ref mut from) = select.from {
2169 from.expressions = from
2170 .expressions
2171 .iter()
2172 .cloned()
2173 .map(|e| Self::add_column_aliases_to_query(e))
2174 .collect();
2175 }
2176
2177 Expression::Select(select)
2178 }
2179 Expression::Subquery(mut sq) => {
2180 sq.this = Self::add_column_aliases_to_query(sq.this);
2181 Expression::Subquery(sq)
2182 }
2183 Expression::Paren(mut p) => {
2184 p.this = Self::add_column_aliases_to_query(p.this);
2185 Expression::Paren(p)
2186 }
2187 other => other,
2189 }
2190 }
2191
2192 fn add_alias_to_expression(expr: Expression) -> Expression {
2195 use crate::expressions::Alias;
2196
2197 match &expr {
2198 Expression::Alias(_) => expr,
2200
2201 Expression::Column(col) => Expression::Alias(Box::new(Alias {
2203 this: expr.clone(),
2204 alias: col.name.clone(),
2205 column_aliases: Vec::new(),
2206 pre_alias_comments: Vec::new(),
2207 trailing_comments: Vec::new(),
2208 inferred_type: None,
2209 })),
2210
2211 Expression::Identifier(ident) => Expression::Alias(Box::new(Alias {
2213 this: expr.clone(),
2214 alias: ident.clone(),
2215 column_aliases: Vec::new(),
2216 pre_alias_comments: Vec::new(),
2217 trailing_comments: Vec::new(),
2218 inferred_type: None,
2219 })),
2220
2221 Expression::Subquery(sq) => {
2223 let processed = Self::add_column_aliases_to_query(Expression::Subquery(sq.clone()));
2224 if sq.alias.is_some() {
2226 processed
2227 } else {
2228 processed
2230 }
2231 }
2232
2233 Expression::Star(_) => expr,
2235
2236 _ => expr,
2239 }
2240 }
2241
2242 fn try_evaluate_constant(expr: &Expression) -> Option<i64> {
2246 match expr {
2247 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
2248 let Literal::Number(n) = lit.as_ref() else {
2249 unreachable!()
2250 };
2251 n.parse::<i64>().ok()
2252 }
2253 Expression::Add(op) => {
2254 let left = Self::try_evaluate_constant(&op.left)?;
2255 let right = Self::try_evaluate_constant(&op.right)?;
2256 Some(left + right)
2257 }
2258 Expression::Sub(op) => {
2259 let left = Self::try_evaluate_constant(&op.left)?;
2260 let right = Self::try_evaluate_constant(&op.right)?;
2261 Some(left - right)
2262 }
2263 Expression::Mul(op) => {
2264 let left = Self::try_evaluate_constant(&op.left)?;
2265 let right = Self::try_evaluate_constant(&op.right)?;
2266 Some(left * right)
2267 }
2268 Expression::Div(op) => {
2269 let left = Self::try_evaluate_constant(&op.left)?;
2270 let right = Self::try_evaluate_constant(&op.right)?;
2271 if right != 0 {
2272 Some(left / right)
2273 } else {
2274 None
2275 }
2276 }
2277 Expression::Paren(p) => Self::try_evaluate_constant(&p.this),
2278 _ => None,
2279 }
2280 }
2281
2282 fn is_reserved_keyword(&self, name: &str) -> bool {
2284 use crate::dialects::DialectType;
2285 let mut buf = [0u8; 128];
2286 let lower_ref: &str = if name.len() <= 128 {
2287 for (i, b) in name.bytes().enumerate() {
2288 buf[i] = b.to_ascii_lowercase();
2289 }
2290 std::str::from_utf8(&buf[..name.len()]).unwrap_or(name)
2292 } else {
2293 return false;
2294 };
2295
2296 match self.config.dialect {
2297 Some(DialectType::BigQuery) => reserved_keywords::BIGQUERY_RESERVED.contains(lower_ref),
2298 Some(DialectType::MySQL) | Some(DialectType::TiDB) => {
2299 reserved_keywords::MYSQL_RESERVED.contains(lower_ref)
2300 }
2301 Some(DialectType::Doris) => reserved_keywords::DORIS_RESERVED.contains(lower_ref),
2302 Some(DialectType::SingleStore) => {
2303 reserved_keywords::SINGLESTORE_RESERVED.contains(lower_ref)
2304 }
2305 Some(DialectType::StarRocks) => {
2306 reserved_keywords::STARROCKS_RESERVED.contains(lower_ref)
2307 }
2308 Some(DialectType::PostgreSQL)
2309 | Some(DialectType::CockroachDB)
2310 | Some(DialectType::Materialize)
2311 | Some(DialectType::RisingWave) => {
2312 reserved_keywords::POSTGRES_RESERVED.contains(lower_ref)
2313 }
2314 Some(DialectType::Redshift) => reserved_keywords::REDSHIFT_RESERVED.contains(lower_ref),
2315 Some(DialectType::Snowflake) => false,
2318 Some(DialectType::ClickHouse) => false,
2320 Some(DialectType::DuckDB) => reserved_keywords::DUCKDB_RESERVED.contains(lower_ref),
2321 Some(DialectType::Teradata) => false,
2323 Some(DialectType::TSQL)
2325 | Some(DialectType::Fabric)
2326 | Some(DialectType::Oracle)
2327 | Some(DialectType::Spark)
2328 | Some(DialectType::Databricks)
2329 | Some(DialectType::Hive)
2330 | Some(DialectType::Solr) => false,
2331 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
2332 reserved_keywords::PRESTO_TRINO_RESERVED.contains(lower_ref)
2333 }
2334 Some(DialectType::SQLite) => reserved_keywords::SQLITE_RESERVED.contains(lower_ref),
2335 Some(DialectType::Generic) | None => false,
2337 _ => reserved_keywords::SQL_RESERVED.contains(lower_ref),
2339 }
2340 }
2341
2342 fn normalize_func_name<'a>(&self, name: &'a str) -> Cow<'a, str> {
2344 match self.config.normalize_functions {
2345 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
2346 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
2347 NormalizeFunctions::None => Cow::Borrowed(name),
2348 }
2349 }
2350
2351 pub fn generate(&mut self, expr: &Expression) -> Result<String> {
2360 self.output.clear();
2361 self.unsupported_messages.clear();
2362 self.generate_expression(expr)?;
2363 if self.config.unsupported_level == UnsupportedLevel::Raise
2364 && !self.unsupported_messages.is_empty()
2365 {
2366 return Err(crate::error::Error::generate(
2367 self.format_unsupported_messages(),
2368 ));
2369 }
2370 Ok(std::mem::take(&mut self.output))
2371 }
2372
2373 pub fn unsupported_messages(&self) -> &[String] {
2375 &self.unsupported_messages
2376 }
2377
2378 fn unsupported(&mut self, message: impl Into<String>) -> Result<()> {
2379 let message = message.into();
2380 if self.config.unsupported_level == UnsupportedLevel::Immediate {
2381 return Err(crate::error::Error::generate(message));
2382 }
2383 self.unsupported_messages.push(message);
2384 Ok(())
2385 }
2386
2387 fn write_unsupported_comment(&mut self, message: &str) -> Result<()> {
2388 self.unsupported(message.to_string())?;
2389 self.write("/* ");
2390 self.write(message);
2391 self.write(" */");
2392 Ok(())
2393 }
2394
2395 fn format_unsupported_messages(&self) -> String {
2396 let limit = self.config.max_unsupported.max(1);
2397 if self.unsupported_messages.len() <= limit {
2398 return self.unsupported_messages.join("; ");
2399 }
2400
2401 let mut messages = self
2402 .unsupported_messages
2403 .iter()
2404 .take(limit)
2405 .cloned()
2406 .collect::<Vec<_>>();
2407 messages.push(format!(
2408 "... and {} more",
2409 self.unsupported_messages.len() - limit
2410 ));
2411 messages.join("; ")
2412 }
2413
2414 pub fn sql(expr: &Expression) -> Result<String> {
2420 let mut gen = Generator::new();
2421 gen.generate(expr)
2422 }
2423
2424 pub fn pretty_sql(expr: &Expression) -> Result<String> {
2429 let config = GeneratorConfig {
2430 pretty: true,
2431 ..Default::default()
2432 };
2433 let mut gen = Generator::with_config(config);
2434 let mut sql = gen.generate(expr)?;
2435 if !sql.ends_with(';') {
2437 sql.push(';');
2438 }
2439 Ok(sql)
2440 }
2441
2442 fn generate_expression(&mut self, expr: &Expression) -> Result<()> {
2443 #[cfg(feature = "stacker")]
2444 {
2445 let red_zone = if cfg!(debug_assertions) {
2446 4 * 1024 * 1024
2447 } else {
2448 1024 * 1024
2449 };
2450 stacker::maybe_grow(red_zone, 8 * 1024 * 1024, || {
2451 self.generate_expression_inner(expr)
2452 })
2453 }
2454 #[cfg(not(feature = "stacker"))]
2455 {
2456 self.generate_expression_inner(expr)
2457 }
2458 }
2459
2460 fn generate_expression_inner(&mut self, expr: &Expression) -> Result<()> {
2461 match expr {
2462 Expression::Select(select) => self.generate_select(select),
2463 Expression::Union(union) => self.generate_union(union),
2464 Expression::Intersect(intersect) => self.generate_intersect(intersect),
2465 Expression::Except(except) => self.generate_except(except),
2466 Expression::Insert(insert) => self.generate_insert(insert),
2467 Expression::Update(update) => self.generate_update(update),
2468 Expression::Delete(delete) => self.generate_delete(delete),
2469 Expression::Literal(lit) => self.generate_literal(lit),
2470 Expression::Boolean(b) => self.generate_boolean(b),
2471 Expression::Null(_) => {
2472 self.write_keyword("NULL");
2473 Ok(())
2474 }
2475 Expression::Identifier(id) => self.generate_identifier(id),
2476 Expression::Column(col) => self.generate_column(col),
2477 Expression::Pseudocolumn(pc) => self.generate_pseudocolumn(pc),
2478 Expression::Connect(c) => self.generate_connect_expr(c),
2479 Expression::Prior(p) => self.generate_prior(p),
2480 Expression::ConnectByRoot(cbr) => self.generate_connect_by_root(cbr),
2481 Expression::MatchRecognize(mr) => self.generate_match_recognize(mr),
2482 Expression::Table(table) => self.generate_table(table),
2483 Expression::StageReference(sr) => self.generate_stage_reference(sr),
2484 Expression::HistoricalData(hd) => self.generate_historical_data(hd),
2485 Expression::JoinedTable(jt) => self.generate_joined_table(jt),
2486 Expression::Star(star) => self.generate_star(star),
2487 Expression::BracedWildcard(expr) => self.generate_braced_wildcard(expr),
2488 Expression::Alias(alias) => self.generate_alias(alias),
2489 Expression::Cast(cast) => self.generate_cast(cast),
2490 Expression::Collation(coll) => self.generate_collation(coll),
2491 Expression::Case(case) => self.generate_case(case),
2492 Expression::Function(func) => self.generate_function(func),
2493 Expression::FunctionEmits(fe) => self.generate_function_emits(fe),
2494 Expression::AggregateFunction(func) => self.generate_aggregate_function(func),
2495 Expression::WindowFunction(wf) => self.generate_window_function(wf),
2496 Expression::WithinGroup(wg) => self.generate_within_group(wg),
2497 Expression::Interval(interval) => self.generate_interval(interval),
2498
2499 Expression::ConcatWs(f) => self.generate_concat_ws(f),
2501 Expression::Substring(f) => self.generate_substring(f),
2502 Expression::Upper(f) => self.generate_unary_func("UPPER", f),
2503 Expression::Lower(f) => self.generate_unary_func("LOWER", f),
2504 Expression::Length(f) => self.generate_unary_func("LENGTH", f),
2505 Expression::Trim(f) => self.generate_trim(f),
2506 Expression::LTrim(f) => self.generate_simple_func("LTRIM", &f.this),
2507 Expression::RTrim(f) => self.generate_simple_func("RTRIM", &f.this),
2508 Expression::Replace(f) => self.generate_replace(f),
2509 Expression::Reverse(f) => self.generate_simple_func("REVERSE", &f.this),
2510 Expression::Left(f) => self.generate_left_right("LEFT", f),
2511 Expression::Right(f) => self.generate_left_right("RIGHT", f),
2512 Expression::Repeat(f) => self.generate_repeat(f),
2513 Expression::Lpad(f) => self.generate_pad("LPAD", f),
2514 Expression::Rpad(f) => self.generate_pad("RPAD", f),
2515 Expression::Split(f) => self.generate_split(f),
2516 Expression::RegexpLike(f) => self.generate_regexp_like(f),
2517 Expression::RegexpReplace(f) => self.generate_regexp_replace(f),
2518 Expression::RegexpExtract(f) => self.generate_regexp_extract(f),
2519 Expression::Overlay(f) => self.generate_overlay(f),
2520
2521 Expression::Abs(f) => self.generate_simple_func("ABS", &f.this),
2523 Expression::Round(f) => self.generate_round(f),
2524 Expression::Floor(f) => self.generate_floor(f),
2525 Expression::Ceil(f) => self.generate_ceil(f),
2526 Expression::Power(f) => self.generate_power(f),
2527 Expression::Sqrt(f) => self.generate_sqrt_cbrt(f, "SQRT", "|/"),
2528 Expression::Cbrt(f) => self.generate_sqrt_cbrt(f, "CBRT", "||/"),
2529 Expression::Ln(f) => self.generate_simple_func("LN", &f.this),
2530 Expression::Log(f) => self.generate_log(f),
2531 Expression::Exp(f) => self.generate_simple_func("EXP", &f.this),
2532 Expression::Sign(f) => self.generate_simple_func("SIGN", &f.this),
2533 Expression::Greatest(f) => self.generate_vararg_func("GREATEST", &f.expressions),
2534 Expression::Least(f) => self.generate_vararg_func("LEAST", &f.expressions),
2535
2536 Expression::CurrentDate(_) => {
2538 self.write_keyword("CURRENT_DATE");
2539 Ok(())
2540 }
2541 Expression::CurrentTime(f) => self.generate_current_time(f),
2542 Expression::CurrentTimestamp(f) => self.generate_current_timestamp(f),
2543 Expression::AtTimeZone(f) => self.generate_at_time_zone(f),
2544 Expression::DateAdd(f) => self.generate_date_add(f, "DATE_ADD"),
2545 Expression::DateSub(f) => self.generate_date_add(f, "DATE_SUB"),
2546 Expression::DateDiff(f) => self.generate_datediff(f),
2547 Expression::DateTrunc(f) => self.generate_date_trunc(f),
2548 Expression::Extract(f) => self.generate_extract(f),
2549 Expression::ToDate(f) => self.generate_to_date(f),
2550 Expression::ToTimestamp(f) => self.generate_to_timestamp(f),
2551
2552 Expression::Coalesce(f) => {
2554 let func_name = f.original_name.as_deref().unwrap_or("COALESCE");
2556 self.generate_vararg_func(func_name, &f.expressions)
2557 }
2558 Expression::NullIf(f) => self.generate_binary_func("NULLIF", &f.this, &f.expression),
2559 Expression::IfFunc(f) => self.generate_if_func(f),
2560 Expression::IfNull(f) => self.generate_ifnull(f),
2561 Expression::Nvl(f) => self.generate_nvl(f),
2562 Expression::Nvl2(f) => self.generate_nvl2(f),
2563
2564 Expression::TryCast(cast) => self.generate_try_cast(cast),
2566 Expression::SafeCast(cast) => self.generate_safe_cast(cast),
2567
2568 Expression::Count(f) => self.generate_count(f),
2570 Expression::Sum(f) => self.generate_agg_func("SUM", f),
2571 Expression::Avg(f) => self.generate_agg_func("AVG", f),
2572 Expression::Min(f) => self.generate_agg_func("MIN", f),
2573 Expression::Max(f) => self.generate_agg_func("MAX", f),
2574 Expression::GroupConcat(f) => self.generate_group_concat(f),
2575 Expression::StringAgg(f) => self.generate_string_agg(f),
2576 Expression::ListAgg(f) => self.generate_listagg(f),
2577 Expression::ArrayAgg(f) => {
2578 let override_name = f
2581 .name
2582 .as_ref()
2583 .filter(|n| !n.eq_ignore_ascii_case("ARRAY_AGG"))
2584 .map(|n| n.to_ascii_uppercase());
2585 match override_name {
2586 Some(name) => self.generate_agg_func(&name, f),
2587 None => self.generate_agg_func("ARRAY_AGG", f),
2588 }
2589 }
2590 Expression::ArrayConcatAgg(f) => self.generate_agg_func("ARRAY_CONCAT_AGG", f),
2591 Expression::CountIf(f) => self.generate_agg_func("COUNT_IF", f),
2592 Expression::SumIf(f) => self.generate_sum_if(f),
2593 Expression::Stddev(f) => self.generate_agg_func("STDDEV", f),
2594 Expression::StddevPop(f) => self.generate_agg_func("STDDEV_POP", f),
2595 Expression::StddevSamp(f) => self.generate_stddev_samp(f),
2596 Expression::Variance(f) => self.generate_agg_func("VARIANCE", f),
2597 Expression::VarPop(f) => {
2598 let name = if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
2599 "VARIANCE_POP"
2600 } else {
2601 "VAR_POP"
2602 };
2603 self.generate_agg_func(name, f)
2604 }
2605 Expression::VarSamp(f) => self.generate_agg_func("VAR_SAMP", f),
2606 Expression::Skewness(f) => {
2607 let name = match self.config.dialect {
2608 Some(DialectType::Snowflake) => "SKEW",
2609 _ => "SKEWNESS",
2610 };
2611 self.generate_agg_func(name, f)
2612 }
2613 Expression::Median(f) => self.generate_agg_func("MEDIAN", f),
2614 Expression::Mode(f) => self.generate_agg_func("MODE", f),
2615 Expression::First(f) => self.generate_agg_func_with_ignore_nulls_bool("FIRST", f),
2616 Expression::Last(f) => self.generate_agg_func_with_ignore_nulls_bool("LAST", f),
2617 Expression::AnyValue(f) => self.generate_agg_func("ANY_VALUE", f),
2618 Expression::ApproxDistinct(f) => {
2619 match self.config.dialect {
2620 Some(DialectType::Hive)
2621 | Some(DialectType::Spark)
2622 | Some(DialectType::Databricks)
2623 | Some(DialectType::BigQuery) => {
2624 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2626 }
2627 Some(DialectType::Redshift) => {
2628 self.write_keyword("APPROXIMATE COUNT");
2630 self.write("(");
2631 self.write_keyword("DISTINCT");
2632 self.write(" ");
2633 self.generate_expression(&f.this)?;
2634 self.write(")");
2635 Ok(())
2636 }
2637 _ => self.generate_agg_func("APPROX_DISTINCT", f),
2638 }
2639 }
2640 Expression::ApproxCountDistinct(f) => {
2641 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2642 }
2643 Expression::ApproxPercentile(f) => self.generate_approx_percentile(f),
2644 Expression::Percentile(f) => self.generate_percentile("PERCENTILE", f),
2645 Expression::LogicalAnd(f) => {
2646 let name = match self.config.dialect {
2647 Some(DialectType::Snowflake) => "BOOLAND_AGG",
2648 Some(DialectType::Spark)
2649 | Some(DialectType::Databricks)
2650 | Some(DialectType::PostgreSQL)
2651 | Some(DialectType::DuckDB)
2652 | Some(DialectType::Redshift) => "BOOL_AND",
2653 Some(DialectType::Oracle)
2654 | Some(DialectType::SQLite)
2655 | Some(DialectType::MySQL) => "MIN",
2656 _ => "BOOL_AND",
2657 };
2658 self.generate_agg_func(name, f)
2659 }
2660 Expression::LogicalOr(f) => {
2661 let name = match self.config.dialect {
2662 Some(DialectType::Snowflake) => "BOOLOR_AGG",
2663 Some(DialectType::Spark)
2664 | Some(DialectType::Databricks)
2665 | Some(DialectType::PostgreSQL)
2666 | Some(DialectType::DuckDB)
2667 | Some(DialectType::Redshift) => "BOOL_OR",
2668 Some(DialectType::Oracle)
2669 | Some(DialectType::SQLite)
2670 | Some(DialectType::MySQL) => "MAX",
2671 _ => "BOOL_OR",
2672 };
2673 self.generate_agg_func(name, f)
2674 }
2675
2676 Expression::RowNumber(_) => {
2678 if self.config.dialect == Some(DialectType::ClickHouse) {
2679 self.write("row_number");
2680 } else {
2681 self.write_keyword("ROW_NUMBER");
2682 }
2683 self.write("()");
2684 Ok(())
2685 }
2686 Expression::Rank(r) => {
2687 self.write_keyword("RANK");
2688 self.write("(");
2689 if !r.args.is_empty() {
2691 for (i, arg) in r.args.iter().enumerate() {
2692 if i > 0 {
2693 self.write(", ");
2694 }
2695 self.generate_expression(arg)?;
2696 }
2697 } else if let Some(order_by) = &r.order_by {
2698 self.write_keyword(" ORDER BY ");
2700 for (i, ob) in order_by.iter().enumerate() {
2701 if i > 0 {
2702 self.write(", ");
2703 }
2704 self.generate_ordered(ob)?;
2705 }
2706 }
2707 self.write(")");
2708 Ok(())
2709 }
2710 Expression::DenseRank(dr) => {
2711 self.write_keyword("DENSE_RANK");
2712 self.write("(");
2713 for (i, arg) in dr.args.iter().enumerate() {
2715 if i > 0 {
2716 self.write(", ");
2717 }
2718 self.generate_expression(arg)?;
2719 }
2720 self.write(")");
2721 Ok(())
2722 }
2723 Expression::NTile(f) => self.generate_ntile(f),
2724 Expression::Lead(f) => self.generate_lead_lag("LEAD", f),
2725 Expression::Lag(f) => self.generate_lead_lag("LAG", f),
2726 Expression::FirstValue(f) => {
2727 self.generate_value_func_with_ignore_nulls_bool("FIRST_VALUE", f)
2728 }
2729 Expression::LastValue(f) => {
2730 self.generate_value_func_with_ignore_nulls_bool("LAST_VALUE", f)
2731 }
2732 Expression::NthValue(f) => self.generate_nth_value(f),
2733 Expression::PercentRank(pr) => {
2734 self.write_keyword("PERCENT_RANK");
2735 self.write("(");
2736 if !pr.args.is_empty() {
2738 for (i, arg) in pr.args.iter().enumerate() {
2739 if i > 0 {
2740 self.write(", ");
2741 }
2742 self.generate_expression(arg)?;
2743 }
2744 } else if let Some(order_by) = &pr.order_by {
2745 self.write_keyword(" ORDER BY ");
2747 for (i, ob) in order_by.iter().enumerate() {
2748 if i > 0 {
2749 self.write(", ");
2750 }
2751 self.generate_ordered(ob)?;
2752 }
2753 }
2754 self.write(")");
2755 Ok(())
2756 }
2757 Expression::CumeDist(cd) => {
2758 self.write_keyword("CUME_DIST");
2759 self.write("(");
2760 if !cd.args.is_empty() {
2762 for (i, arg) in cd.args.iter().enumerate() {
2763 if i > 0 {
2764 self.write(", ");
2765 }
2766 self.generate_expression(arg)?;
2767 }
2768 } else if let Some(order_by) = &cd.order_by {
2769 self.write_keyword(" ORDER BY ");
2771 for (i, ob) in order_by.iter().enumerate() {
2772 if i > 0 {
2773 self.write(", ");
2774 }
2775 self.generate_ordered(ob)?;
2776 }
2777 }
2778 self.write(")");
2779 Ok(())
2780 }
2781 Expression::PercentileCont(f) => self.generate_percentile("PERCENTILE_CONT", f),
2782 Expression::PercentileDisc(f) => self.generate_percentile("PERCENTILE_DISC", f),
2783
2784 Expression::Contains(f) => {
2786 self.generate_binary_func("CONTAINS", &f.this, &f.expression)
2787 }
2788 Expression::StartsWith(f) => {
2789 let name = match self.config.dialect {
2790 Some(DialectType::Spark) | Some(DialectType::Databricks) => "STARTSWITH",
2791 _ => "STARTS_WITH",
2792 };
2793 self.generate_binary_func(name, &f.this, &f.expression)
2794 }
2795 Expression::EndsWith(f) => {
2796 let name = match self.config.dialect {
2797 Some(DialectType::Snowflake) => "ENDSWITH",
2798 Some(DialectType::Spark) | Some(DialectType::Databricks) => "ENDSWITH",
2799 Some(DialectType::ClickHouse) => "endsWith",
2800 _ => "ENDS_WITH",
2801 };
2802 self.generate_binary_func(name, &f.this, &f.expression)
2803 }
2804 Expression::Position(f) => self.generate_position(f),
2805 Expression::Initcap(f) => match self.config.dialect {
2806 Some(DialectType::Presto)
2807 | Some(DialectType::Trino)
2808 | Some(DialectType::Athena) => {
2809 self.write_keyword("REGEXP_REPLACE");
2810 self.write("(");
2811 self.generate_expression(&f.this)?;
2812 self.write(", '(\\w)(\\w*)', x -> UPPER(x[1]) || LOWER(x[2]))");
2813 Ok(())
2814 }
2815 _ => self.generate_simple_func("INITCAP", &f.this),
2816 },
2817 Expression::Ascii(f) => self.generate_simple_func("ASCII", &f.this),
2818 Expression::Chr(f) => self.generate_simple_func("CHR", &f.this),
2819 Expression::CharFunc(f) => self.generate_char_func(f),
2820 Expression::Soundex(f) => self.generate_simple_func("SOUNDEX", &f.this),
2821 Expression::Levenshtein(f) => {
2822 self.generate_binary_func("LEVENSHTEIN", &f.this, &f.expression)
2823 }
2824
2825 Expression::ModFunc(f) => self.generate_mod_func(f),
2827 Expression::Random(_) => {
2828 self.write_keyword("RANDOM");
2829 self.write("()");
2830 Ok(())
2831 }
2832 Expression::Rand(f) => self.generate_rand(f),
2833 Expression::TruncFunc(f) => self.generate_truncate_func(f),
2834 Expression::Pi(_) => {
2835 self.write_keyword("PI");
2836 self.write("()");
2837 Ok(())
2838 }
2839 Expression::Radians(f) => self.generate_simple_func("RADIANS", &f.this),
2840 Expression::Degrees(f) => self.generate_simple_func("DEGREES", &f.this),
2841 Expression::Sin(f) => self.generate_simple_func("SIN", &f.this),
2842 Expression::Cos(f) => self.generate_simple_func("COS", &f.this),
2843 Expression::Tan(f) => self.generate_simple_func("TAN", &f.this),
2844 Expression::Asin(f) => self.generate_simple_func("ASIN", &f.this),
2845 Expression::Acos(f) => self.generate_simple_func("ACOS", &f.this),
2846 Expression::Atan(f) => self.generate_simple_func("ATAN", &f.this),
2847 Expression::Atan2(f) => {
2848 let name = f.original_name.as_deref().unwrap_or("ATAN2");
2849 self.generate_binary_func(name, &f.this, &f.expression)
2850 }
2851
2852 Expression::Decode(f) => self.generate_decode(f),
2854
2855 Expression::DateFormat(f) => self.generate_date_format("DATE_FORMAT", f),
2857 Expression::FormatDate(f) => self.generate_date_format("FORMAT_DATE", f),
2858 Expression::Year(f) => self.generate_simple_func("YEAR", &f.this),
2859 Expression::Month(f) => self.generate_simple_func("MONTH", &f.this),
2860 Expression::Day(f) => self.generate_simple_func("DAY", &f.this),
2861 Expression::Hour(f) => self.generate_simple_func("HOUR", &f.this),
2862 Expression::Minute(f) => self.generate_simple_func("MINUTE", &f.this),
2863 Expression::Second(f) => self.generate_simple_func("SECOND", &f.this),
2864 Expression::DayOfWeek(f) => {
2865 let name = match self.config.dialect {
2866 Some(DialectType::Presto)
2867 | Some(DialectType::Trino)
2868 | Some(DialectType::Athena) => "DAY_OF_WEEK",
2869 Some(DialectType::DuckDB) => "ISODOW",
2870 _ => "DAYOFWEEK",
2871 };
2872 self.generate_simple_func(name, &f.this)
2873 }
2874 Expression::DayOfMonth(f) => {
2875 let name = match self.config.dialect {
2876 Some(DialectType::Presto)
2877 | Some(DialectType::Trino)
2878 | Some(DialectType::Athena) => "DAY_OF_MONTH",
2879 _ => "DAYOFMONTH",
2880 };
2881 self.generate_simple_func(name, &f.this)
2882 }
2883 Expression::DayOfYear(f) => {
2884 let name = match self.config.dialect {
2885 Some(DialectType::Presto)
2886 | Some(DialectType::Trino)
2887 | Some(DialectType::Athena) => "DAY_OF_YEAR",
2888 _ => "DAYOFYEAR",
2889 };
2890 self.generate_simple_func(name, &f.this)
2891 }
2892 Expression::WeekOfYear(f) => {
2893 let name = match self.config.dialect {
2895 Some(DialectType::Hive)
2896 | Some(DialectType::DuckDB)
2897 | Some(DialectType::Spark)
2898 | Some(DialectType::Databricks)
2899 | Some(DialectType::MySQL) => "WEEKOFYEAR",
2900 _ => "WEEK_OF_YEAR",
2901 };
2902 self.generate_simple_func(name, &f.this)
2903 }
2904 Expression::Quarter(f) => self.generate_simple_func("QUARTER", &f.this),
2905 Expression::AddMonths(f) => {
2906 self.generate_binary_func("ADD_MONTHS", &f.this, &f.expression)
2907 }
2908 Expression::MonthsBetween(f) => {
2909 self.generate_binary_func("MONTHS_BETWEEN", &f.this, &f.expression)
2910 }
2911 Expression::LastDay(f) => self.generate_last_day(f),
2912 Expression::NextDay(f) => self.generate_binary_func("NEXT_DAY", &f.this, &f.expression),
2913 Expression::Epoch(f) => self.generate_simple_func("EPOCH", &f.this),
2914 Expression::EpochMs(f) => self.generate_simple_func("EPOCH_MS", &f.this),
2915 Expression::FromUnixtime(f) => self.generate_from_unixtime(f),
2916 Expression::UnixTimestamp(f) => self.generate_unix_timestamp(f),
2917 Expression::MakeDate(f) => self.generate_make_date(f),
2918 Expression::MakeTimestamp(f) => self.generate_make_timestamp(f),
2919 Expression::TimestampTrunc(f) => self.generate_date_trunc(f),
2920
2921 Expression::ArrayFunc(f) => self.generate_array_constructor(f),
2923 Expression::ArrayLength(f) => self.generate_simple_func("ARRAY_LENGTH", &f.this),
2924 Expression::ArraySize(f) => self.generate_simple_func("ARRAY_SIZE", &f.this),
2925 Expression::Cardinality(f) => self.generate_simple_func("CARDINALITY", &f.this),
2926 Expression::ArrayContains(f) => {
2927 self.generate_binary_func("ARRAY_CONTAINS", &f.this, &f.expression)
2928 }
2929 Expression::ArrayPosition(f) => {
2930 self.generate_binary_func("ARRAY_POSITION", &f.this, &f.expression)
2931 }
2932 Expression::ArrayAppend(f) => {
2933 self.generate_binary_func("ARRAY_APPEND", &f.this, &f.expression)
2934 }
2935 Expression::ArrayPrepend(f) => {
2936 self.generate_binary_func("ARRAY_PREPEND", &f.this, &f.expression)
2937 }
2938 Expression::ArrayConcat(f) => self.generate_vararg_func("ARRAY_CONCAT", &f.expressions),
2939 Expression::ArraySort(f) => self.generate_array_sort(f),
2940 Expression::ArrayReverse(f) => self.generate_simple_func("ARRAY_REVERSE", &f.this),
2941 Expression::ArrayDistinct(f) => self.generate_simple_func("ARRAY_DISTINCT", &f.this),
2942 Expression::ArrayJoin(f) => self.generate_array_join("ARRAY_JOIN", f),
2943 Expression::ArrayToString(f) => self.generate_array_join("ARRAY_TO_STRING", f),
2944 Expression::Unnest(f) => self.generate_unnest(f),
2945 Expression::Explode(f) => self.generate_simple_func("EXPLODE", &f.this),
2946 Expression::ExplodeOuter(f) => self.generate_simple_func("EXPLODE_OUTER", &f.this),
2947 Expression::ArrayFilter(f) => self.generate_array_filter(f),
2948 Expression::ArrayTransform(f) => self.generate_array_transform(f),
2949 Expression::ArrayFlatten(f) => self.generate_simple_func("FLATTEN", &f.this),
2950 Expression::ArrayCompact(f) => {
2951 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
2952 self.write("LIST_FILTER(");
2954 self.generate_expression(&f.this)?;
2955 self.write(", _u -> NOT _u IS NULL)");
2956 Ok(())
2957 } else {
2958 self.generate_simple_func("ARRAY_COMPACT", &f.this)
2959 }
2960 }
2961 Expression::ArrayIntersect(f) => {
2962 let func_name = f.original_name.as_deref().unwrap_or("ARRAY_INTERSECT");
2963 self.generate_vararg_func(func_name, &f.expressions)
2964 }
2965 Expression::ArrayUnion(f) => {
2966 self.generate_binary_func("ARRAY_UNION", &f.this, &f.expression)
2967 }
2968 Expression::ArrayExcept(f) => {
2969 self.generate_binary_func("ARRAY_EXCEPT", &f.this, &f.expression)
2970 }
2971 Expression::ArrayRemove(f) => {
2972 self.generate_binary_func("ARRAY_REMOVE", &f.this, &f.expression)
2973 }
2974 Expression::ArrayZip(f) => self.generate_vararg_func("ARRAYS_ZIP", &f.expressions),
2975 Expression::Sequence(f) => self.generate_sequence("SEQUENCE", f),
2976 Expression::Generate(f) => self.generate_sequence("GENERATE_SERIES", f),
2977
2978 Expression::StructFunc(f) => self.generate_struct_constructor(f),
2980 Expression::StructExtract(f) => self.generate_struct_extract(f),
2981 Expression::NamedStruct(f) => self.generate_named_struct(f),
2982
2983 Expression::MapFunc(f) => self.generate_map_constructor(f),
2985 Expression::MapFromEntries(f) => self.generate_simple_func("MAP_FROM_ENTRIES", &f.this),
2986 Expression::MapFromArrays(f) => {
2987 self.generate_binary_func("MAP_FROM_ARRAYS", &f.this, &f.expression)
2988 }
2989 Expression::MapKeys(f) => self.generate_simple_func("MAP_KEYS", &f.this),
2990 Expression::MapValues(f) => self.generate_simple_func("MAP_VALUES", &f.this),
2991 Expression::MapContainsKey(f) => {
2992 self.generate_binary_func("MAP_CONTAINS_KEY", &f.this, &f.expression)
2993 }
2994 Expression::MapConcat(f) => self.generate_vararg_func("MAP_CONCAT", &f.expressions),
2995 Expression::ElementAt(f) => {
2996 self.generate_binary_func("ELEMENT_AT", &f.this, &f.expression)
2997 }
2998 Expression::TransformKeys(f) => self.generate_transform_func("TRANSFORM_KEYS", f),
2999 Expression::TransformValues(f) => self.generate_transform_func("TRANSFORM_VALUES", f),
3000
3001 Expression::JsonExtract(f) => self.generate_json_extract("JSON_EXTRACT", f),
3003 Expression::JsonExtractScalar(f) => {
3004 self.generate_json_extract("JSON_EXTRACT_SCALAR", f)
3005 }
3006 Expression::JsonExtractPath(f) => self.generate_json_path("JSON_EXTRACT_PATH", f),
3007 Expression::JsonArray(f) => self.generate_vararg_func("JSON_ARRAY", &f.expressions),
3008 Expression::JsonObject(f) => self.generate_json_object(f),
3009 Expression::JsonQuery(f) => self.generate_json_extract("JSON_QUERY", f),
3010 Expression::JsonValue(f) => self.generate_json_extract("JSON_VALUE", f),
3011 Expression::JsonArrayLength(f) => {
3012 self.generate_simple_func("JSON_ARRAY_LENGTH", &f.this)
3013 }
3014 Expression::JsonKeys(f) => self.generate_simple_func("JSON_KEYS", &f.this),
3015 Expression::JsonType(f) => self.generate_simple_func("JSON_TYPE", &f.this),
3016 Expression::ParseJson(f) => {
3017 let name = match self.config.dialect {
3018 Some(DialectType::Presto)
3019 | Some(DialectType::Trino)
3020 | Some(DialectType::Athena) => "JSON_PARSE",
3021 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
3022 self.write_keyword("CAST");
3024 self.write("(");
3025 self.generate_expression(&f.this)?;
3026 self.write_keyword(" AS ");
3027 self.write_keyword("JSON");
3028 self.write(")");
3029 return Ok(());
3030 }
3031 Some(DialectType::Hive)
3032 | Some(DialectType::Spark)
3033 | Some(DialectType::MySQL)
3034 | Some(DialectType::SingleStore)
3035 | Some(DialectType::TiDB)
3036 | Some(DialectType::TSQL) => {
3037 self.generate_expression(&f.this)?;
3039 return Ok(());
3040 }
3041 Some(DialectType::DuckDB) => "JSON",
3042 _ => "PARSE_JSON",
3043 };
3044 self.generate_simple_func(name, &f.this)
3045 }
3046 Expression::ToJson(f) => self.generate_simple_func("TO_JSON", &f.this),
3047 Expression::JsonSet(f) => self.generate_json_modify("JSON_SET", f),
3048 Expression::JsonInsert(f) => self.generate_json_modify("JSON_INSERT", f),
3049 Expression::JsonRemove(f) => self.generate_json_path("JSON_REMOVE", f),
3050 Expression::JsonMergePatch(f) => {
3051 self.generate_binary_func("JSON_MERGE_PATCH", &f.this, &f.expression)
3052 }
3053 Expression::JsonArrayAgg(f) => self.generate_json_array_agg(f),
3054 Expression::JsonObjectAgg(f) => self.generate_json_object_agg(f),
3055
3056 Expression::Convert(f) => self.generate_convert(f),
3058 Expression::Typeof(f) => self.generate_simple_func("TYPEOF", &f.this),
3059
3060 Expression::Lambda(f) => self.generate_lambda(f),
3062 Expression::Parameter(f) => self.generate_parameter(f),
3063 Expression::Placeholder(f) => self.generate_placeholder(f),
3064 Expression::NamedArgument(f) => self.generate_named_argument(f),
3065 Expression::TableArgument(f) => self.generate_table_argument(f),
3066 Expression::SqlComment(f) => self.generate_sql_comment(f),
3067
3068 Expression::NullSafeEq(op) => self.generate_null_safe_eq(op),
3070 Expression::NullSafeNeq(op) => self.generate_null_safe_neq(op),
3071 Expression::Glob(op) => self.generate_binary_op(op, "GLOB"),
3072 Expression::SimilarTo(f) => self.generate_similar_to(f),
3073 Expression::Any(f) => self.generate_quantified("ANY", f),
3074 Expression::All(f) => self.generate_quantified("ALL", f),
3075 Expression::Overlaps(f) => self.generate_overlaps(f),
3076
3077 Expression::BitwiseLeftShift(op) => {
3079 if matches!(
3080 self.config.dialect,
3081 Some(DialectType::Presto) | Some(DialectType::Trino)
3082 ) {
3083 self.write_keyword("BITWISE_ARITHMETIC_SHIFT_LEFT");
3084 self.write("(");
3085 self.generate_expression(&op.left)?;
3086 self.write(", ");
3087 self.generate_expression(&op.right)?;
3088 self.write(")");
3089 Ok(())
3090 } else if matches!(
3091 self.config.dialect,
3092 Some(DialectType::Spark) | Some(DialectType::Databricks)
3093 ) {
3094 self.write_keyword("SHIFTLEFT");
3095 self.write("(");
3096 self.generate_expression(&op.left)?;
3097 self.write(", ");
3098 self.generate_expression(&op.right)?;
3099 self.write(")");
3100 Ok(())
3101 } else {
3102 self.generate_binary_op(op, "<<")
3103 }
3104 }
3105 Expression::BitwiseRightShift(op) => {
3106 if matches!(
3107 self.config.dialect,
3108 Some(DialectType::Presto) | Some(DialectType::Trino)
3109 ) {
3110 self.write_keyword("BITWISE_ARITHMETIC_SHIFT_RIGHT");
3111 self.write("(");
3112 self.generate_expression(&op.left)?;
3113 self.write(", ");
3114 self.generate_expression(&op.right)?;
3115 self.write(")");
3116 Ok(())
3117 } else if matches!(
3118 self.config.dialect,
3119 Some(DialectType::Spark) | Some(DialectType::Databricks)
3120 ) {
3121 self.write_keyword("SHIFTRIGHT");
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 {
3129 self.generate_binary_op(op, ">>")
3130 }
3131 }
3132 Expression::BitwiseAndAgg(f) => self.generate_agg_func("BIT_AND", f),
3133 Expression::BitwiseOrAgg(f) => self.generate_agg_func("BIT_OR", f),
3134 Expression::BitwiseXorAgg(f) => self.generate_agg_func("BIT_XOR", f),
3135
3136 Expression::Subscript(s) => self.generate_subscript(s),
3138 Expression::Dot(d) => self.generate_dot_access(d),
3139 Expression::MethodCall(m) => self.generate_method_call(m),
3140 Expression::ArraySlice(s) => self.generate_array_slice(s),
3141
3142 Expression::And(op) => self.generate_connector_op(op, ConnectorOperator::And),
3143 Expression::Or(op) => self.generate_connector_op(op, ConnectorOperator::Or),
3144 Expression::Add(op) => self.generate_binary_op(op, "+"),
3145 Expression::Sub(op) => self.generate_binary_op(op, "-"),
3146 Expression::Mul(op) => self.generate_binary_op(op, "*"),
3147 Expression::Div(op) => self.generate_binary_op(op, "/"),
3148 Expression::IntDiv(f) => {
3149 use crate::dialects::DialectType;
3150 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
3151 self.generate_expression(&f.this)?;
3153 self.write(" // ");
3154 self.generate_expression(&f.expression)?;
3155 Ok(())
3156 } else if matches!(
3157 self.config.dialect,
3158 Some(DialectType::Hive | DialectType::Spark | DialectType::Databricks)
3159 ) {
3160 self.generate_expression(&f.this)?;
3162 self.write(" ");
3163 self.write_keyword("DIV");
3164 self.write(" ");
3165 self.generate_expression(&f.expression)?;
3166 Ok(())
3167 } else {
3168 self.write_keyword("DIV");
3170 self.write("(");
3171 self.generate_expression(&f.this)?;
3172 self.write(", ");
3173 self.generate_expression(&f.expression)?;
3174 self.write(")");
3175 Ok(())
3176 }
3177 }
3178 Expression::Mod(op) => {
3179 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
3180 self.generate_binary_op(op, "MOD")
3181 } else {
3182 self.generate_binary_op(op, "%")
3183 }
3184 }
3185 Expression::Eq(op) => self.generate_binary_op(op, "="),
3186 Expression::Neq(op) => self.generate_binary_op(op, "<>"),
3187 Expression::Lt(op) => self.generate_binary_op(op, "<"),
3188 Expression::Lte(op) => self.generate_binary_op(op, "<="),
3189 Expression::Gt(op) => self.generate_binary_op(op, ">"),
3190 Expression::Gte(op) => self.generate_binary_op(op, ">="),
3191 Expression::Like(op) => self.generate_like_op(op, "LIKE"),
3192 Expression::ILike(op) => self.generate_like_op(op, "ILIKE"),
3193 Expression::Match(op) => self.generate_binary_op(op, "MATCH"),
3194 Expression::Concat(op) => {
3195 if self.config.dialect == Some(DialectType::Solr) {
3197 self.generate_binary_op(op, "OR")
3198 } else if self.config.dialect == Some(DialectType::MySQL) {
3199 self.generate_mysql_concat_from_concat(op)
3200 } else {
3201 self.generate_binary_op(op, "||")
3202 }
3203 }
3204 Expression::BitwiseAnd(op) => {
3205 if matches!(
3207 self.config.dialect,
3208 Some(DialectType::Presto) | Some(DialectType::Trino)
3209 ) {
3210 self.write_keyword("BITWISE_AND");
3211 self.write("(");
3212 self.generate_expression(&op.left)?;
3213 self.write(", ");
3214 self.generate_expression(&op.right)?;
3215 self.write(")");
3216 Ok(())
3217 } else {
3218 self.generate_binary_op(op, "&")
3219 }
3220 }
3221 Expression::BitwiseOr(op) => {
3222 if matches!(
3224 self.config.dialect,
3225 Some(DialectType::Presto) | Some(DialectType::Trino)
3226 ) {
3227 self.write_keyword("BITWISE_OR");
3228 self.write("(");
3229 self.generate_expression(&op.left)?;
3230 self.write(", ");
3231 self.generate_expression(&op.right)?;
3232 self.write(")");
3233 Ok(())
3234 } else {
3235 self.generate_binary_op(op, "|")
3236 }
3237 }
3238 Expression::BitwiseXor(op) => {
3239 if matches!(
3241 self.config.dialect,
3242 Some(DialectType::Presto) | Some(DialectType::Trino)
3243 ) {
3244 self.write_keyword("BITWISE_XOR");
3245 self.write("(");
3246 self.generate_expression(&op.left)?;
3247 self.write(", ");
3248 self.generate_expression(&op.right)?;
3249 self.write(")");
3250 Ok(())
3251 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
3252 self.generate_binary_op(op, "#")
3253 } else {
3254 self.generate_binary_op(op, "^")
3255 }
3256 }
3257 Expression::Adjacent(op) => self.generate_binary_op(op, "-|-"),
3258 Expression::TsMatch(op) => self.generate_binary_op(op, "@@"),
3259 Expression::PropertyEQ(op) => self.generate_binary_op(op, ":="),
3260 Expression::ArrayContainsAll(op) => self.generate_binary_op(op, "@>"),
3261 Expression::ArrayContainedBy(op) => self.generate_binary_op(op, "<@"),
3262 Expression::ArrayOverlaps(op) => self.generate_binary_op(op, "&&"),
3263 Expression::JSONBContainsAllTopKeys(op) => self.generate_binary_op(op, "?&"),
3264 Expression::JSONBContainsAnyTopKeys(op) => self.generate_binary_op(op, "?|"),
3265 Expression::JSONBContains(f) => {
3266 self.generate_expression(&f.this)?;
3268 self.write_space();
3269 self.write("?");
3270 self.write_space();
3271 self.generate_expression(&f.expression)
3272 }
3273 Expression::JSONBDeleteAtPath(op) => self.generate_binary_op(op, "#-"),
3274 Expression::ExtendsLeft(op) => self.generate_binary_op(op, "&<"),
3275 Expression::ExtendsRight(op) => self.generate_binary_op(op, "&>"),
3276 Expression::Not(op) => self.generate_unary_op(op, "NOT"),
3277 Expression::Neg(op) => self.generate_unary_op(op, "-"),
3278 Expression::BitwiseNot(op) => {
3279 if matches!(
3281 self.config.dialect,
3282 Some(DialectType::Presto) | Some(DialectType::Trino)
3283 ) {
3284 self.write_keyword("BITWISE_NOT");
3285 self.write("(");
3286 self.generate_expression(&op.this)?;
3287 self.write(")");
3288 Ok(())
3289 } else {
3290 self.generate_unary_op(op, "~")
3291 }
3292 }
3293 Expression::In(in_expr) => self.generate_in(in_expr),
3294 Expression::Between(between) => self.generate_between(between),
3295 Expression::IsNull(is_null) => self.generate_is_null(is_null),
3296 Expression::IsTrue(is_true) => self.generate_is_true(is_true),
3297 Expression::IsFalse(is_false) => self.generate_is_false(is_false),
3298 Expression::IsJson(is_json) => self.generate_is_json(is_json),
3299 Expression::Is(is_expr) => self.generate_is(is_expr),
3300 Expression::Exists(exists) => self.generate_exists(exists),
3301 Expression::MemberOf(member_of) => self.generate_member_of(member_of),
3302 Expression::Subquery(subquery) => self.generate_subquery(subquery),
3303 Expression::Paren(paren) => {
3304 let skip_parens = matches!(&paren.this, Expression::JoinedTable(_));
3306
3307 if !skip_parens {
3308 self.write("(");
3309 if self.config.pretty {
3310 self.write_newline();
3311 self.indent_level += 1;
3312 self.write_indent();
3313 }
3314 }
3315 self.generate_expression(&paren.this)?;
3316 if !skip_parens {
3317 if self.config.pretty {
3318 self.write_newline();
3319 self.indent_level -= 1;
3320 self.write_indent();
3321 }
3322 self.write(")");
3323 }
3324 for comment in &paren.trailing_comments {
3326 self.write(" ");
3327 self.write_formatted_comment(comment);
3328 }
3329 Ok(())
3330 }
3331 Expression::Array(arr) => self.generate_array(arr),
3332 Expression::Tuple(tuple) => self.generate_tuple(tuple),
3333 Expression::PipeOperator(pipe) => self.generate_pipe_operator(pipe),
3334 Expression::Ordered(ordered) => self.generate_ordered(ordered),
3335 Expression::DataType(dt) => self.generate_data_type(dt),
3336 Expression::Raw(raw) => {
3337 self.write(&raw.sql);
3338 Ok(())
3339 }
3340 Expression::CreateTask(task) => self.generate_create_task(task),
3341 Expression::Command(cmd) => {
3342 self.write(&cmd.this);
3343 Ok(())
3344 }
3345 Expression::Kill(kill) => {
3346 self.write_keyword("KILL");
3347 if let Some(kind) = &kill.kind {
3348 self.write_space();
3349 self.write_keyword(kind);
3350 }
3351 self.write_space();
3352 self.generate_expression(&kill.this)?;
3353 Ok(())
3354 }
3355 Expression::Execute(exec) => {
3356 self.write_keyword("EXECUTE");
3357 self.write_space();
3358 self.generate_expression(&exec.this)?;
3359 for (i, param) in exec.parameters.iter().enumerate() {
3360 if i == 0 {
3361 self.write_space();
3362 } else {
3363 self.write(", ");
3364 }
3365 self.write(¶m.name);
3366 if !param.positional {
3368 self.write(" = ");
3369 self.generate_expression(¶m.value)?;
3370 }
3371 if param.output {
3372 self.write_space();
3373 self.write_keyword("OUTPUT");
3374 }
3375 }
3376 if let Some(ref suffix) = exec.suffix {
3377 self.write_space();
3378 self.write(suffix);
3379 }
3380 Ok(())
3381 }
3382 Expression::Annotated(annotated) => {
3383 self.generate_expression(&annotated.this)?;
3384 for comment in &annotated.trailing_comments {
3385 self.write(" ");
3386 self.write_formatted_comment(comment);
3387 }
3388 Ok(())
3389 }
3390
3391 Expression::CreateTable(ct) => self.generate_create_table(ct),
3393 Expression::DropTable(dt) => self.generate_drop_table(dt),
3394 Expression::Undrop(u) => self.generate_undrop(u),
3395 Expression::AlterTable(at) => self.generate_alter_table(at),
3396 Expression::CreateIndex(ci) => self.generate_create_index(ci),
3397 Expression::DropIndex(di) => self.generate_drop_index(di),
3398 Expression::CreateView(cv) => self.generate_create_view(cv),
3399 Expression::DropView(dv) => self.generate_drop_view(dv),
3400 Expression::AlterView(av) => self.generate_alter_view(av),
3401 Expression::AlterIndex(ai) => self.generate_alter_index(ai),
3402 Expression::Truncate(tr) => self.generate_truncate(tr),
3403 Expression::Use(u) => self.generate_use(u),
3404 Expression::CreateSchema(cs) => self.generate_create_schema(cs),
3406 Expression::DropSchema(ds) => self.generate_drop_schema(ds),
3407 Expression::DropNamespace(dn) => self.generate_drop_namespace(dn),
3408 Expression::CreateDatabase(cd) => self.generate_create_database(cd),
3409 Expression::DropDatabase(dd) => self.generate_drop_database(dd),
3410 Expression::CreateFunction(cf) => self.generate_create_function(cf),
3411 Expression::DropFunction(df) => self.generate_drop_function(df),
3412 Expression::CreateProcedure(cp) => self.generate_create_procedure(cp),
3413 Expression::DropProcedure(dp) => self.generate_drop_procedure(dp),
3414 Expression::CreateSequence(cs) => self.generate_create_sequence(cs),
3415 Expression::CreateSynonym(cs) => {
3416 self.write_keyword("CREATE SYNONYM");
3417 self.write_space();
3418 self.generate_table(&cs.name)?;
3419 self.write_space();
3420 self.write_keyword("FOR");
3421 self.write_space();
3422 self.generate_table(&cs.target)?;
3423 Ok(())
3424 }
3425 Expression::DropSequence(ds) => self.generate_drop_sequence(ds),
3426 Expression::AlterSequence(als) => self.generate_alter_sequence(als),
3427 Expression::CreateTrigger(ct) => self.generate_create_trigger(ct),
3428 Expression::DropTrigger(dt) => self.generate_drop_trigger(dt),
3429 Expression::CreateType(ct) => self.generate_create_type(ct),
3430 Expression::DropType(dt) => self.generate_drop_type(dt),
3431 Expression::Describe(d) => self.generate_describe(d),
3432 Expression::Show(s) => self.generate_show(s),
3433
3434 Expression::Cache(c) => self.generate_cache(c),
3436 Expression::Uncache(u) => self.generate_uncache(u),
3437 Expression::LoadData(l) => self.generate_load_data(l),
3438 Expression::Pragma(p) => self.generate_pragma(p),
3439 Expression::Grant(g) => self.generate_grant(g),
3440 Expression::Revoke(r) => self.generate_revoke(r),
3441 Expression::Comment(c) => self.generate_comment(c),
3442 Expression::SetStatement(s) => self.generate_set_statement(s),
3443
3444 Expression::Pivot(pivot) => self.generate_pivot(pivot),
3446 Expression::Unpivot(unpivot) => self.generate_unpivot(unpivot),
3447
3448 Expression::Values(values) => self.generate_values(values),
3450
3451 Expression::AIAgg(e) => self.generate_ai_agg(e),
3453 Expression::AIClassify(e) => self.generate_ai_classify(e),
3454 Expression::AddPartition(e) => self.generate_add_partition(e),
3455 Expression::AlgorithmProperty(e) => self.generate_algorithm_property(e),
3456 Expression::Aliases(e) => self.generate_aliases(e),
3457 Expression::AllowedValuesProperty(e) => self.generate_allowed_values_property(e),
3458 Expression::AlterColumn(e) => self.generate_alter_column(e),
3459 Expression::AlterSession(e) => self.generate_alter_session(e),
3460 Expression::AlterSet(e) => self.generate_alter_set(e),
3461 Expression::AlterSortKey(e) => self.generate_alter_sort_key(e),
3462 Expression::Analyze(e) => self.generate_analyze(e),
3463 Expression::AnalyzeDelete(e) => self.generate_analyze_delete(e),
3464 Expression::AnalyzeHistogram(e) => self.generate_analyze_histogram(e),
3465 Expression::AnalyzeListChainedRows(e) => self.generate_analyze_list_chained_rows(e),
3466 Expression::AnalyzeSample(e) => self.generate_analyze_sample(e),
3467 Expression::AnalyzeStatistics(e) => self.generate_analyze_statistics(e),
3468 Expression::AnalyzeValidate(e) => self.generate_analyze_validate(e),
3469 Expression::AnalyzeWith(e) => self.generate_analyze_with(e),
3470 Expression::Anonymous(e) => self.generate_anonymous(e),
3471 Expression::AnonymousAggFunc(e) => self.generate_anonymous_agg_func(e),
3472 Expression::Apply(e) => self.generate_apply(e),
3473 Expression::ApproxPercentileEstimate(e) => self.generate_approx_percentile_estimate(e),
3474 Expression::ApproxQuantile(e) => self.generate_approx_quantile(e),
3475 Expression::ApproxQuantiles(e) => self.generate_approx_quantiles(e),
3476 Expression::ApproxTopK(e) => self.generate_approx_top_k(e),
3477 Expression::ApproxTopKAccumulate(e) => self.generate_approx_top_k_accumulate(e),
3478 Expression::ApproxTopKCombine(e) => self.generate_approx_top_k_combine(e),
3479 Expression::ApproxTopKEstimate(e) => self.generate_approx_top_k_estimate(e),
3480 Expression::ApproxTopSum(e) => self.generate_approx_top_sum(e),
3481 Expression::ArgMax(e) => self.generate_arg_max(e),
3482 Expression::ArgMin(e) => self.generate_arg_min(e),
3483 Expression::ArrayAll(e) => self.generate_array_all(e),
3484 Expression::ArrayAny(e) => self.generate_array_any(e),
3485 Expression::ArrayConstructCompact(e) => self.generate_array_construct_compact(e),
3486 Expression::ArraySum(e) => self.generate_array_sum(e),
3487 Expression::AtIndex(e) => self.generate_at_index(e),
3488 Expression::Attach(e) => self.generate_attach(e),
3489 Expression::AttachOption(e) => self.generate_attach_option(e),
3490 Expression::AutoIncrementProperty(e) => self.generate_auto_increment_property(e),
3491 Expression::AutoRefreshProperty(e) => self.generate_auto_refresh_property(e),
3492 Expression::BackupProperty(e) => self.generate_backup_property(e),
3493 Expression::Base64DecodeBinary(e) => self.generate_base64_decode_binary(e),
3494 Expression::Base64DecodeString(e) => self.generate_base64_decode_string(e),
3495 Expression::Base64Encode(e) => self.generate_base64_encode(e),
3496 Expression::BlockCompressionProperty(e) => self.generate_block_compression_property(e),
3497 Expression::Booland(e) => self.generate_booland(e),
3498 Expression::Boolor(e) => self.generate_boolor(e),
3499 Expression::BuildProperty(e) => self.generate_build_property(e),
3500 Expression::ByteString(e) => self.generate_byte_string(e),
3501 Expression::CaseSpecificColumnConstraint(e) => {
3502 self.generate_case_specific_column_constraint(e)
3503 }
3504 Expression::CastToStrType(e) => self.generate_cast_to_str_type(e),
3505 Expression::Changes(e) => self.generate_changes(e),
3506 Expression::CharacterSetColumnConstraint(e) => {
3507 self.generate_character_set_column_constraint(e)
3508 }
3509 Expression::CharacterSetProperty(e) => self.generate_character_set_property(e),
3510 Expression::CheckColumnConstraint(e) => self.generate_check_column_constraint(e),
3511 Expression::AssumeColumnConstraint(e) => self.generate_assume_column_constraint(e),
3512 Expression::CheckJson(e) => self.generate_check_json(e),
3513 Expression::CheckXml(e) => self.generate_check_xml(e),
3514 Expression::ChecksumProperty(e) => self.generate_checksum_property(e),
3515 Expression::Clone(e) => self.generate_clone(e),
3516 Expression::ClusterBy(e) => self.generate_cluster_by(e),
3517 Expression::ClusterByColumnsProperty(e) => self.generate_cluster_by_columns_property(e),
3518 Expression::ClusteredByProperty(e) => self.generate_clustered_by_property(e),
3519 Expression::CollateProperty(e) => self.generate_collate_property(e),
3520 Expression::ColumnConstraint(e) => self.generate_column_constraint(e),
3521 Expression::ColumnDef(e) => self.generate_column_def_expr(e),
3522 Expression::ColumnPosition(e) => self.generate_column_position(e),
3523 Expression::ColumnPrefix(e) => self.generate_column_prefix(e),
3524 Expression::Columns(e) => self.generate_columns(e),
3525 Expression::CombinedAggFunc(e) => self.generate_combined_agg_func(e),
3526 Expression::CombinedParameterizedAgg(e) => self.generate_combined_parameterized_agg(e),
3527 Expression::Commit(e) => self.generate_commit(e),
3528 Expression::Comprehension(e) => self.generate_comprehension(e),
3529 Expression::Compress(e) => self.generate_compress(e),
3530 Expression::CompressColumnConstraint(e) => self.generate_compress_column_constraint(e),
3531 Expression::ComputedColumnConstraint(e) => self.generate_computed_column_constraint(e),
3532 Expression::ConditionalInsert(e) => self.generate_conditional_insert(e),
3533 Expression::Constraint(e) => self.generate_constraint(e),
3534 Expression::ConvertTimezone(e) => self.generate_convert_timezone(e),
3535 Expression::ConvertToCharset(e) => self.generate_convert_to_charset(e),
3536 Expression::Copy(e) => self.generate_copy(e),
3537 Expression::CopyParameter(e) => self.generate_copy_parameter(e),
3538 Expression::Corr(e) => self.generate_corr(e),
3539 Expression::CosineDistance(e) => self.generate_cosine_distance(e),
3540 Expression::CovarPop(e) => self.generate_covar_pop(e),
3541 Expression::CovarSamp(e) => self.generate_covar_samp(e),
3542 Expression::Credentials(e) => self.generate_credentials(e),
3543 Expression::CredentialsProperty(e) => self.generate_credentials_property(e),
3544 Expression::Cte(e) => self.generate_cte(e),
3545 Expression::Cube(e) => self.generate_cube(e),
3546 Expression::CurrentDatetime(e) => self.generate_current_datetime(e),
3547 Expression::CurrentSchema(e) => self.generate_current_schema(e),
3548 Expression::CurrentSchemas(e) => self.generate_current_schemas(e),
3549 Expression::CurrentUser(e) => self.generate_current_user(e),
3550 Expression::DPipe(e) => self.generate_d_pipe(e),
3551 Expression::DataBlocksizeProperty(e) => self.generate_data_blocksize_property(e),
3552 Expression::DataDeletionProperty(e) => self.generate_data_deletion_property(e),
3553 Expression::Date(e) => self.generate_date_func(e),
3554 Expression::DateBin(e) => self.generate_date_bin(e),
3555 Expression::DateFormatColumnConstraint(e) => {
3556 self.generate_date_format_column_constraint(e)
3557 }
3558 Expression::DateFromParts(e) => self.generate_date_from_parts(e),
3559 Expression::Datetime(e) => self.generate_datetime(e),
3560 Expression::DatetimeAdd(e) => self.generate_datetime_add(e),
3561 Expression::DatetimeDiff(e) => self.generate_datetime_diff(e),
3562 Expression::DatetimeSub(e) => self.generate_datetime_sub(e),
3563 Expression::DatetimeTrunc(e) => self.generate_datetime_trunc(e),
3564 Expression::Dayname(e) => self.generate_dayname(e),
3565 Expression::Declare(e) => self.generate_declare(e),
3566 Expression::DeclareItem(e) => self.generate_declare_item(e),
3567 Expression::DecodeCase(e) => self.generate_decode_case(e),
3568 Expression::DecompressBinary(e) => self.generate_decompress_binary(e),
3569 Expression::DecompressString(e) => self.generate_decompress_string(e),
3570 Expression::Decrypt(e) => self.generate_decrypt(e),
3571 Expression::DecryptRaw(e) => self.generate_decrypt_raw(e),
3572 Expression::DefaultColumnConstraint(e) => {
3573 self.write_keyword("DEFAULT");
3574 self.write_space();
3575 self.generate_expression(&e.this)?;
3576 if let Some(ref col) = e.for_column {
3577 self.write_space();
3578 self.write_keyword("FOR");
3579 self.write_space();
3580 self.generate_identifier(col)?;
3581 }
3582 Ok(())
3583 }
3584 Expression::DefinerProperty(e) => self.generate_definer_property(e),
3585 Expression::Detach(e) => self.generate_detach(e),
3586 Expression::DictProperty(e) => self.generate_dict_property(e),
3587 Expression::DictRange(e) => self.generate_dict_range(e),
3588 Expression::Directory(e) => self.generate_directory(e),
3589 Expression::DistKeyProperty(e) => self.generate_dist_key_property(e),
3590 Expression::DistStyleProperty(e) => self.generate_dist_style_property(e),
3591 Expression::DistributeBy(e) => self.generate_distribute_by(e),
3592 Expression::DistributedByProperty(e) => self.generate_distributed_by_property(e),
3593 Expression::DotProduct(e) => self.generate_dot_product(e),
3594 Expression::DropPartition(e) => self.generate_drop_partition(e),
3595 Expression::DuplicateKeyProperty(e) => self.generate_duplicate_key_property(e),
3596 Expression::Elt(e) => self.generate_elt(e),
3597 Expression::Encode(e) => self.generate_encode(e),
3598 Expression::EncodeProperty(e) => self.generate_encode_property(e),
3599 Expression::Encrypt(e) => self.generate_encrypt(e),
3600 Expression::EncryptRaw(e) => self.generate_encrypt_raw(e),
3601 Expression::EngineProperty(e) => self.generate_engine_property(e),
3602 Expression::EnviromentProperty(e) => self.generate_enviroment_property(e),
3603 Expression::EphemeralColumnConstraint(e) => {
3604 self.generate_ephemeral_column_constraint(e)
3605 }
3606 Expression::EqualNull(e) => self.generate_equal_null(e),
3607 Expression::EuclideanDistance(e) => self.generate_euclidean_distance(e),
3608 Expression::ExecuteAsProperty(e) => self.generate_execute_as_property(e),
3609 Expression::Export(e) => self.generate_export(e),
3610 Expression::ExternalProperty(e) => self.generate_external_property(e),
3611 Expression::FallbackProperty(e) => self.generate_fallback_property(e),
3612 Expression::FarmFingerprint(e) => self.generate_farm_fingerprint(e),
3613 Expression::FeaturesAtTime(e) => self.generate_features_at_time(e),
3614 Expression::Fetch(e) => self.generate_fetch(e),
3615 Expression::FileFormatProperty(e) => self.generate_file_format_property(e),
3616 Expression::Filter(e) => self.generate_filter(e),
3617 Expression::Float64(e) => self.generate_float64(e),
3618 Expression::ForIn(e) => self.generate_for_in(e),
3619 Expression::ForeignKey(e) => self.generate_foreign_key(e),
3620 Expression::Format(e) => self.generate_format(e),
3621 Expression::FormatPhrase(e) => self.generate_format_phrase(e),
3622 Expression::FreespaceProperty(e) => self.generate_freespace_property(e),
3623 Expression::From(e) => self.generate_from(e),
3624 Expression::FromBase(e) => self.generate_from_base(e),
3625 Expression::FromTimeZone(e) => self.generate_from_time_zone(e),
3626 Expression::GapFill(e) => self.generate_gap_fill(e),
3627 Expression::GenerateDateArray(e) => self.generate_generate_date_array(e),
3628 Expression::GenerateEmbedding(e) => self.generate_generate_embedding(e),
3629 Expression::GenerateSeries(e) => self.generate_generate_series(e),
3630 Expression::GenerateTimestampArray(e) => self.generate_generate_timestamp_array(e),
3631 Expression::GeneratedAsIdentityColumnConstraint(e) => {
3632 self.generate_generated_as_identity_column_constraint(e)
3633 }
3634 Expression::GeneratedAsRowColumnConstraint(e) => {
3635 self.generate_generated_as_row_column_constraint(e)
3636 }
3637 Expression::Get(e) => self.generate_get(e),
3638 Expression::GetExtract(e) => self.generate_get_extract(e),
3639 Expression::Getbit(e) => self.generate_getbit(e),
3640 Expression::GrantPrincipal(e) => self.generate_grant_principal(e),
3641 Expression::GrantPrivilege(e) => self.generate_grant_privilege(e),
3642 Expression::Group(e) => self.generate_group(e),
3643 Expression::GroupBy(e) => self.generate_group_by(e),
3644 Expression::Grouping(e) => self.generate_grouping(e),
3645 Expression::GroupingId(e) => self.generate_grouping_id(e),
3646 Expression::GroupingSets(e) => self.generate_grouping_sets(e),
3647 Expression::HashAgg(e) => self.generate_hash_agg(e),
3648 Expression::Having(e) => self.generate_having(e),
3649 Expression::HavingMax(e) => self.generate_having_max(e),
3650 Expression::Heredoc(e) => self.generate_heredoc(e),
3651 Expression::HexEncode(e) => self.generate_hex_encode(e),
3652 Expression::Hll(e) => self.generate_hll(e),
3653 Expression::InOutColumnConstraint(e) => self.generate_in_out_column_constraint(e),
3654 Expression::IncludeProperty(e) => self.generate_include_property(e),
3655 Expression::Index(e) => self.generate_index(e),
3656 Expression::IndexColumnConstraint(e) => self.generate_index_column_constraint(e),
3657 Expression::IndexConstraintOption(e) => self.generate_index_constraint_option(e),
3658 Expression::IndexParameters(e) => self.generate_index_parameters(e),
3659 Expression::IndexTableHint(e) => self.generate_index_table_hint(e),
3660 Expression::InheritsProperty(e) => self.generate_inherits_property(e),
3661 Expression::InputModelProperty(e) => self.generate_input_model_property(e),
3662 Expression::InputOutputFormat(e) => self.generate_input_output_format(e),
3663 Expression::Install(e) => self.generate_install(e),
3664 Expression::IntervalOp(e) => self.generate_interval_op(e),
3665 Expression::IntervalSpan(e) => self.generate_interval_span(e),
3666 Expression::IntoClause(e) => self.generate_into_clause(e),
3667 Expression::Introducer(e) => self.generate_introducer(e),
3668 Expression::IsolatedLoadingProperty(e) => self.generate_isolated_loading_property(e),
3669 Expression::JSON(e) => self.generate_json(e),
3670 Expression::JSONArray(e) => self.generate_json_array(e),
3671 Expression::JSONArrayAgg(e) => self.generate_json_array_agg_struct(e),
3672 Expression::JSONArrayAppend(e) => self.generate_json_array_append(e),
3673 Expression::JSONArrayContains(e) => self.generate_json_array_contains(e),
3674 Expression::JSONArrayInsert(e) => self.generate_json_array_insert(e),
3675 Expression::JSONBExists(e) => self.generate_jsonb_exists(e),
3676 Expression::JSONBExtractScalar(e) => self.generate_jsonb_extract_scalar(e),
3677 Expression::JSONBObjectAgg(e) => self.generate_jsonb_object_agg(e),
3678 Expression::JSONObjectAgg(e) => self.generate_json_object_agg_struct(e),
3679 Expression::JSONColumnDef(e) => self.generate_json_column_def(e),
3680 Expression::JSONExists(e) => self.generate_json_exists(e),
3681 Expression::JSONCast(e) => self.generate_json_cast(e),
3682 Expression::JSONExtract(e) => self.generate_json_extract_path(e),
3683 Expression::JSONExtractArray(e) => self.generate_json_extract_array(e),
3684 Expression::JSONExtractQuote(e) => self.generate_json_extract_quote(e),
3685 Expression::JSONExtractScalar(e) => self.generate_json_extract_scalar(e),
3686 Expression::JSONFormat(e) => self.generate_json_format(e),
3687 Expression::JSONKeyValue(e) => self.generate_json_key_value(e),
3688 Expression::JSONKeys(e) => self.generate_json_keys(e),
3689 Expression::JSONKeysAtDepth(e) => self.generate_json_keys_at_depth(e),
3690 Expression::JSONPath(e) => self.generate_json_path_expr(e),
3691 Expression::JSONPathFilter(e) => self.generate_json_path_filter(e),
3692 Expression::JSONPathKey(e) => self.generate_json_path_key(e),
3693 Expression::JSONPathRecursive(e) => self.generate_json_path_recursive(e),
3694 Expression::JSONPathRoot(_) => self.generate_json_path_root(),
3695 Expression::JSONPathScript(e) => self.generate_json_path_script(e),
3696 Expression::JSONPathSelector(e) => self.generate_json_path_selector(e),
3697 Expression::JSONPathSlice(e) => self.generate_json_path_slice(e),
3698 Expression::JSONPathSubscript(e) => self.generate_json_path_subscript(e),
3699 Expression::JSONPathUnion(e) => self.generate_json_path_union(e),
3700 Expression::JSONRemove(e) => self.generate_json_remove(e),
3701 Expression::JSONSchema(e) => self.generate_json_schema(e),
3702 Expression::JSONSet(e) => self.generate_json_set(e),
3703 Expression::JSONStripNulls(e) => self.generate_json_strip_nulls(e),
3704 Expression::JSONTable(e) => self.generate_json_table(e),
3705 Expression::JSONType(e) => self.generate_json_type(e),
3706 Expression::JSONValue(e) => self.generate_json_value(e),
3707 Expression::JSONValueArray(e) => self.generate_json_value_array(e),
3708 Expression::JarowinklerSimilarity(e) => self.generate_jarowinkler_similarity(e),
3709 Expression::JoinHint(e) => self.generate_join_hint(e),
3710 Expression::JournalProperty(e) => self.generate_journal_property(e),
3711 Expression::LanguageProperty(e) => self.generate_language_property(e),
3712 Expression::Lateral(e) => self.generate_lateral(e),
3713 Expression::LikeProperty(e) => self.generate_like_property(e),
3714 Expression::Limit(e) => self.generate_limit(e),
3715 Expression::LimitOptions(e) => self.generate_limit_options(e),
3716 Expression::List(e) => self.generate_list(e),
3717 Expression::ToMap(e) => self.generate_tomap(e),
3718 Expression::Localtime(e) => self.generate_localtime(e),
3719 Expression::Localtimestamp(e) => self.generate_localtimestamp(e),
3720 Expression::LocationProperty(e) => self.generate_location_property(e),
3721 Expression::Lock(e) => self.generate_lock(e),
3722 Expression::LockProperty(e) => self.generate_lock_property(e),
3723 Expression::LockingProperty(e) => self.generate_locking_property(e),
3724 Expression::LockingStatement(e) => self.generate_locking_statement(e),
3725 Expression::LogProperty(e) => self.generate_log_property(e),
3726 Expression::MD5Digest(e) => self.generate_md5_digest(e),
3727 Expression::MLForecast(e) => self.generate_ml_forecast(e),
3728 Expression::MLTranslate(e) => self.generate_ml_translate(e),
3729 Expression::MakeInterval(e) => self.generate_make_interval(e),
3730 Expression::ManhattanDistance(e) => self.generate_manhattan_distance(e),
3731 Expression::Map(e) => self.generate_map(e),
3732 Expression::MapCat(e) => self.generate_map_cat(e),
3733 Expression::MapDelete(e) => self.generate_map_delete(e),
3734 Expression::MapInsert(e) => self.generate_map_insert(e),
3735 Expression::MapPick(e) => self.generate_map_pick(e),
3736 Expression::MaskingPolicyColumnConstraint(e) => {
3737 self.generate_masking_policy_column_constraint(e)
3738 }
3739 Expression::MatchAgainst(e) => self.generate_match_against(e),
3740 Expression::MatchRecognizeMeasure(e) => self.generate_match_recognize_measure(e),
3741 Expression::MaterializedProperty(e) => self.generate_materialized_property(e),
3742 Expression::Merge(e) => self.generate_merge(e),
3743 Expression::MergeBlockRatioProperty(e) => self.generate_merge_block_ratio_property(e),
3744 Expression::MergeTreeTTL(e) => self.generate_merge_tree_ttl(e),
3745 Expression::MergeTreeTTLAction(e) => self.generate_merge_tree_ttl_action(e),
3746 Expression::Minhash(e) => self.generate_minhash(e),
3747 Expression::ModelAttribute(e) => self.generate_model_attribute(e),
3748 Expression::Monthname(e) => self.generate_monthname(e),
3749 Expression::MultitableInserts(e) => self.generate_multitable_inserts(e),
3750 Expression::NextValueFor(e) => self.generate_next_value_for(e),
3751 Expression::Normal(e) => self.generate_normal(e),
3752 Expression::Normalize(e) => self.generate_normalize(e),
3753 Expression::NotNullColumnConstraint(e) => self.generate_not_null_column_constraint(e),
3754 Expression::Nullif(e) => self.generate_nullif(e),
3755 Expression::NumberToStr(e) => self.generate_number_to_str(e),
3756 Expression::ObjectAgg(e) => self.generate_object_agg(e),
3757 Expression::ObjectIdentifier(e) => self.generate_object_identifier(e),
3758 Expression::ObjectInsert(e) => self.generate_object_insert(e),
3759 Expression::Offset(e) => self.generate_offset(e),
3760 Expression::Qualify(e) => self.generate_qualify(e),
3761 Expression::OnCluster(e) => self.generate_on_cluster(e),
3762 Expression::OnCommitProperty(e) => self.generate_on_commit_property(e),
3763 Expression::OnCondition(e) => self.generate_on_condition(e),
3764 Expression::OnConflict(e) => self.generate_on_conflict(e),
3765 Expression::OnProperty(e) => self.generate_on_property(e),
3766 Expression::Opclass(e) => self.generate_opclass(e),
3767 Expression::OpenJSON(e) => self.generate_open_json(e),
3768 Expression::OpenJSONColumnDef(e) => self.generate_open_json_column_def(e),
3769 Expression::Operator(e) => self.generate_operator(e),
3770 Expression::OrderBy(e) => self.generate_order_by(e),
3771 Expression::OutputModelProperty(e) => self.generate_output_model_property(e),
3772 Expression::OverflowTruncateBehavior(e) => self.generate_overflow_truncate_behavior(e),
3773 Expression::ParameterizedAgg(e) => self.generate_parameterized_agg(e),
3774 Expression::ParseDatetime(e) => self.generate_parse_datetime(e),
3775 Expression::ParseIp(e) => self.generate_parse_ip(e),
3776 Expression::ParseJSON(e) => self.generate_parse_json(e),
3777 Expression::ParseTime(e) => self.generate_parse_time(e),
3778 Expression::ParseUrl(e) => self.generate_parse_url(e),
3779 Expression::Partition(e) => self.generate_partition_expr(e),
3780 Expression::PartitionBoundSpec(e) => self.generate_partition_bound_spec(e),
3781 Expression::PartitionByListProperty(e) => self.generate_partition_by_list_property(e),
3782 Expression::PartitionByRangeProperty(e) => self.generate_partition_by_range_property(e),
3783 Expression::PartitionByRangePropertyDynamic(e) => {
3784 self.generate_partition_by_range_property_dynamic(e)
3785 }
3786 Expression::PartitionByTruncate(e) => self.generate_partition_by_truncate(e),
3787 Expression::PartitionList(e) => self.generate_partition_list(e),
3788 Expression::PartitionRange(e) => self.generate_partition_range(e),
3789 Expression::PartitionByProperty(e) => self.generate_partition_by_property(e),
3790 Expression::PartitionedByBucket(e) => self.generate_partitioned_by_bucket(e),
3791 Expression::PartitionedByProperty(e) => self.generate_partitioned_by_property(e),
3792 Expression::PartitionedOfProperty(e) => self.generate_partitioned_of_property(e),
3793 Expression::PeriodForSystemTimeConstraint(e) => {
3794 self.generate_period_for_system_time_constraint(e)
3795 }
3796 Expression::PivotAlias(e) => self.generate_pivot_alias(e),
3797 Expression::PivotAny(e) => self.generate_pivot_any(e),
3798 Expression::Predict(e) => self.generate_predict(e),
3799 Expression::PreviousDay(e) => self.generate_previous_day(e),
3800 Expression::PrimaryKey(e) => self.generate_primary_key(e),
3801 Expression::PrimaryKeyColumnConstraint(e) => {
3802 self.generate_primary_key_column_constraint(e)
3803 }
3804 Expression::PathColumnConstraint(e) => self.generate_path_column_constraint(e),
3805 Expression::ProjectionDef(e) => self.generate_projection_def(e),
3806 Expression::OptionsProperty(e) => self.generate_options_property(e),
3807 Expression::Properties(e) => self.generate_properties(e),
3808 Expression::Property(e) => self.generate_property(e),
3809 Expression::PseudoType(e) => self.generate_pseudo_type(e),
3810 Expression::Put(e) => self.generate_put(e),
3811 Expression::Quantile(e) => self.generate_quantile(e),
3812 Expression::QueryBand(e) => self.generate_query_band(e),
3813 Expression::QueryOption(e) => self.generate_query_option(e),
3814 Expression::QueryTransform(e) => self.generate_query_transform(e),
3815 Expression::Randn(e) => self.generate_randn(e),
3816 Expression::Randstr(e) => self.generate_randstr(e),
3817 Expression::RangeBucket(e) => self.generate_range_bucket(e),
3818 Expression::RangeN(e) => self.generate_range_n(e),
3819 Expression::ReadCSV(e) => self.generate_read_csv(e),
3820 Expression::ReadParquet(e) => self.generate_read_parquet(e),
3821 Expression::RecursiveWithSearch(e) => self.generate_recursive_with_search(e),
3822 Expression::Reduce(e) => self.generate_reduce(e),
3823 Expression::Reference(e) => self.generate_reference(e),
3824 Expression::Refresh(e) => self.generate_refresh(e),
3825 Expression::RefreshTriggerProperty(e) => self.generate_refresh_trigger_property(e),
3826 Expression::RegexpCount(e) => self.generate_regexp_count(e),
3827 Expression::RegexpExtractAll(e) => self.generate_regexp_extract_all(e),
3828 Expression::RegexpFullMatch(e) => self.generate_regexp_full_match(e),
3829 Expression::RegexpILike(e) => self.generate_regexp_i_like(e),
3830 Expression::RegexpInstr(e) => self.generate_regexp_instr(e),
3831 Expression::RegexpSplit(e) => self.generate_regexp_split(e),
3832 Expression::RegrAvgx(e) => self.generate_regr_avgx(e),
3833 Expression::RegrAvgy(e) => self.generate_regr_avgy(e),
3834 Expression::RegrCount(e) => self.generate_regr_count(e),
3835 Expression::RegrIntercept(e) => self.generate_regr_intercept(e),
3836 Expression::RegrR2(e) => self.generate_regr_r2(e),
3837 Expression::RegrSlope(e) => self.generate_regr_slope(e),
3838 Expression::RegrSxx(e) => self.generate_regr_sxx(e),
3839 Expression::RegrSxy(e) => self.generate_regr_sxy(e),
3840 Expression::RegrSyy(e) => self.generate_regr_syy(e),
3841 Expression::RegrValx(e) => self.generate_regr_valx(e),
3842 Expression::RegrValy(e) => self.generate_regr_valy(e),
3843 Expression::RemoteWithConnectionModelProperty(e) => {
3844 self.generate_remote_with_connection_model_property(e)
3845 }
3846 Expression::RenameColumn(e) => self.generate_rename_column(e),
3847 Expression::ReplacePartition(e) => self.generate_replace_partition(e),
3848 Expression::Returning(e) => self.generate_returning(e),
3849 Expression::ReturnsProperty(e) => self.generate_returns_property(e),
3850 Expression::Rollback(e) => self.generate_rollback(e),
3851 Expression::Rollup(e) => self.generate_rollup(e),
3852 Expression::RowFormatDelimitedProperty(e) => {
3853 self.generate_row_format_delimited_property(e)
3854 }
3855 Expression::RowFormatProperty(e) => self.generate_row_format_property(e),
3856 Expression::RowFormatSerdeProperty(e) => self.generate_row_format_serde_property(e),
3857 Expression::SHA2(e) => self.generate_sha2(e),
3858 Expression::SHA2Digest(e) => self.generate_sha2_digest(e),
3859 Expression::SafeAdd(e) => self.generate_safe_add(e),
3860 Expression::SafeDivide(e) => self.generate_safe_divide(e),
3861 Expression::SafeMultiply(e) => self.generate_safe_multiply(e),
3862 Expression::SafeSubtract(e) => self.generate_safe_subtract(e),
3863 Expression::SampleProperty(e) => self.generate_sample_property(e),
3864 Expression::Schema(e) => self.generate_schema(e),
3865 Expression::SchemaCommentProperty(e) => self.generate_schema_comment_property(e),
3866 Expression::ScopeResolution(e) => self.generate_scope_resolution(e),
3867 Expression::Search(e) => self.generate_search(e),
3868 Expression::SearchIp(e) => self.generate_search_ip(e),
3869 Expression::SecurityProperty(e) => self.generate_security_property(e),
3870 Expression::SemanticView(e) => self.generate_semantic_view(e),
3871 Expression::SequenceProperties(e) => self.generate_sequence_properties(e),
3872 Expression::SerdeProperties(e) => self.generate_serde_properties(e),
3873 Expression::SessionParameter(e) => self.generate_session_parameter(e),
3874 Expression::Set(e) => self.generate_set(e),
3875 Expression::SetConfigProperty(e) => self.generate_set_config_property(e),
3876 Expression::SetItem(e) => self.generate_set_item(e),
3877 Expression::SetOperation(e) => self.generate_set_operation(e),
3878 Expression::SetProperty(e) => self.generate_set_property(e),
3879 Expression::SettingsProperty(e) => self.generate_settings_property(e),
3880 Expression::SharingProperty(e) => self.generate_sharing_property(e),
3881 Expression::Slice(e) => self.generate_slice(e),
3882 Expression::SortArray(e) => self.generate_sort_array(e),
3883 Expression::SortBy(e) => self.generate_sort_by(e),
3884 Expression::SortKeyProperty(e) => self.generate_sort_key_property(e),
3885 Expression::SplitPart(e) => self.generate_split_part(e),
3886 Expression::SqlReadWriteProperty(e) => self.generate_sql_read_write_property(e),
3887 Expression::SqlSecurityProperty(e) => self.generate_sql_security_property(e),
3888 Expression::StDistance(e) => self.generate_st_distance(e),
3889 Expression::StPoint(e) => self.generate_st_point(e),
3890 Expression::StabilityProperty(e) => self.generate_stability_property(e),
3891 Expression::StandardHash(e) => self.generate_standard_hash(e),
3892 Expression::StorageHandlerProperty(e) => self.generate_storage_handler_property(e),
3893 Expression::StrPosition(e) => self.generate_str_position(e),
3894 Expression::StrToDate(e) => self.generate_str_to_date(e),
3895 Expression::DateStrToDate(f) => self.generate_simple_func("DATE_STR_TO_DATE", &f.this),
3896 Expression::DateToDateStr(f) => self.generate_simple_func("DATE_TO_DATE_STR", &f.this),
3897 Expression::StrToMap(e) => self.generate_str_to_map(e),
3898 Expression::StrToTime(e) => self.generate_str_to_time(e),
3899 Expression::StrToUnix(e) => self.generate_str_to_unix(e),
3900 Expression::StringToArray(e) => self.generate_string_to_array(e),
3901 Expression::Struct(e) => self.generate_struct(e),
3902 Expression::Stuff(e) => self.generate_stuff(e),
3903 Expression::SubstringIndex(e) => self.generate_substring_index(e),
3904 Expression::Summarize(e) => self.generate_summarize(e),
3905 Expression::Systimestamp(e) => self.generate_systimestamp(e),
3906 Expression::TableAlias(e) => self.generate_table_alias(e),
3907 Expression::TableFromRows(e) => self.generate_table_from_rows(e),
3908 Expression::RowsFrom(e) => self.generate_rows_from(e),
3909 Expression::TableSample(e) => self.generate_table_sample(e),
3910 Expression::Tag(e) => self.generate_tag(e),
3911 Expression::Tags(e) => self.generate_tags(e),
3912 Expression::TemporaryProperty(e) => self.generate_temporary_property(e),
3913 Expression::Time(e) => self.generate_time_func(e),
3914 Expression::TimeAdd(e) => self.generate_time_add(e),
3915 Expression::TimeDiff(e) => self.generate_time_diff(e),
3916 Expression::TimeFromParts(e) => self.generate_time_from_parts(e),
3917 Expression::TimeSlice(e) => self.generate_time_slice(e),
3918 Expression::TimeStrToDate(e) => self.generate_time_str_to_date(e),
3919 Expression::TimeStrToTime(e) => self.generate_time_str_to_time(e),
3920 Expression::TimeSub(e) => self.generate_time_sub(e),
3921 Expression::TimeToStr(e) => self.generate_time_to_str(e),
3922 Expression::TimeToUnix(e) => self.generate_time_to_unix(e),
3923 Expression::TimeTrunc(e) => self.generate_time_trunc(e),
3924 Expression::TimeUnit(e) => self.generate_time_unit(e),
3925 Expression::Timestamp(e) => self.generate_timestamp_func(e),
3926 Expression::TimestampAdd(e) => self.generate_timestamp_add(e),
3927 Expression::TimestampDiff(e) => self.generate_timestamp_diff(e),
3928 Expression::TimestampFromParts(e) => self.generate_timestamp_from_parts(e),
3929 Expression::TimestampSub(e) => self.generate_timestamp_sub(e),
3930 Expression::TimestampTzFromParts(e) => self.generate_timestamp_tz_from_parts(e),
3931 Expression::ToBinary(e) => self.generate_to_binary(e),
3932 Expression::ToBoolean(e) => self.generate_to_boolean(e),
3933 Expression::ToChar(e) => self.generate_to_char(e),
3934 Expression::ToDecfloat(e) => self.generate_to_decfloat(e),
3935 Expression::ToDouble(e) => self.generate_to_double(e),
3936 Expression::ToFile(e) => self.generate_to_file(e),
3937 Expression::ToNumber(e) => self.generate_to_number(e),
3938 Expression::ToTableProperty(e) => self.generate_to_table_property(e),
3939 Expression::Transaction(e) => self.generate_transaction(e),
3940 Expression::Transform(e) => self.generate_transform(e),
3941 Expression::TransformModelProperty(e) => self.generate_transform_model_property(e),
3942 Expression::TransientProperty(e) => self.generate_transient_property(e),
3943 Expression::Translate(e) => self.generate_translate(e),
3944 Expression::TranslateCharacters(e) => self.generate_translate_characters(e),
3945 Expression::TruncateTable(e) => self.generate_truncate_table(e),
3946 Expression::TryBase64DecodeBinary(e) => self.generate_try_base64_decode_binary(e),
3947 Expression::TryBase64DecodeString(e) => self.generate_try_base64_decode_string(e),
3948 Expression::TryToDecfloat(e) => self.generate_try_to_decfloat(e),
3949 Expression::TsOrDsAdd(e) => self.generate_ts_or_ds_add(e),
3950 Expression::TsOrDsDiff(e) => self.generate_ts_or_ds_diff(e),
3951 Expression::TsOrDsToDate(e) => self.generate_ts_or_ds_to_date(e),
3952 Expression::TsOrDsToTime(e) => self.generate_ts_or_ds_to_time(e),
3953 Expression::Unhex(e) => self.generate_unhex(e),
3954 Expression::UnicodeString(e) => self.generate_unicode_string(e),
3955 Expression::Uniform(e) => self.generate_uniform(e),
3956 Expression::UniqueColumnConstraint(e) => self.generate_unique_column_constraint(e),
3957 Expression::UniqueKeyProperty(e) => self.generate_unique_key_property(e),
3958 Expression::RollupProperty(e) => self.generate_rollup_property(e),
3959 Expression::UnixToStr(e) => self.generate_unix_to_str(e),
3960 Expression::UnixToTime(e) => self.generate_unix_to_time(e),
3961 Expression::UnpivotColumns(e) => self.generate_unpivot_columns(e),
3962 Expression::UserDefinedFunction(e) => self.generate_user_defined_function(e),
3963 Expression::UsingTemplateProperty(e) => self.generate_using_template_property(e),
3964 Expression::UtcTime(e) => self.generate_utc_time(e),
3965 Expression::UtcTimestamp(e) => self.generate_utc_timestamp(e),
3966 Expression::Uuid(e) => self.generate_uuid(e),
3967 Expression::Var(v) => {
3968 if matches!(self.config.dialect, Some(DialectType::MySQL))
3969 && v.this.len() > 2
3970 && (v.this.starts_with("0x") || v.this.starts_with("0X"))
3971 && !v.this[2..].chars().all(|c| c.is_ascii_hexdigit())
3972 {
3973 return self.generate_identifier(&Identifier {
3974 name: v.this.clone(),
3975 quoted: true,
3976 trailing_comments: Vec::new(),
3977 span: None,
3978 });
3979 }
3980 self.write(&v.this);
3981 Ok(())
3982 }
3983 Expression::Variadic(e) => {
3984 self.write_keyword("VARIADIC");
3985 self.write_space();
3986 self.generate_expression(&e.this)?;
3987 Ok(())
3988 }
3989 Expression::VarMap(e) => self.generate_var_map(e),
3990 Expression::VectorSearch(e) => self.generate_vector_search(e),
3991 Expression::Version(e) => self.generate_version(e),
3992 Expression::ViewAttributeProperty(e) => self.generate_view_attribute_property(e),
3993 Expression::VolatileProperty(e) => self.generate_volatile_property(e),
3994 Expression::WatermarkColumnConstraint(e) => {
3995 self.generate_watermark_column_constraint(e)
3996 }
3997 Expression::Week(e) => self.generate_week(e),
3998 Expression::When(e) => self.generate_when(e),
3999 Expression::Whens(e) => self.generate_whens(e),
4000 Expression::Where(e) => self.generate_where(e),
4001 Expression::WidthBucket(e) => self.generate_width_bucket(e),
4002 Expression::Window(e) => self.generate_window(e),
4003 Expression::WindowSpec(e) => self.generate_window_spec(e),
4004 Expression::WithDataProperty(e) => self.generate_with_data_property(e),
4005 Expression::WithFill(e) => self.generate_with_fill(e),
4006 Expression::WithJournalTableProperty(e) => self.generate_with_journal_table_property(e),
4007 Expression::WithOperator(e) => self.generate_with_operator(e),
4008 Expression::WithProcedureOptions(e) => self.generate_with_procedure_options(e),
4009 Expression::WithSchemaBindingProperty(e) => {
4010 self.generate_with_schema_binding_property(e)
4011 }
4012 Expression::WithSystemVersioningProperty(e) => {
4013 self.generate_with_system_versioning_property(e)
4014 }
4015 Expression::WithTableHint(e) => self.generate_with_table_hint(e),
4016 Expression::XMLElement(e) => self.generate_xml_element(e),
4017 Expression::XMLGet(e) => self.generate_xml_get(e),
4018 Expression::XMLKeyValueOption(e) => self.generate_xml_key_value_option(e),
4019 Expression::XMLTable(e) => self.generate_xml_table(e),
4020 Expression::Xor(e) => self.generate_xor(e),
4021 Expression::Zipf(e) => self.generate_zipf(e),
4022 _ => self.write_unsupported_comment("unsupported expression"),
4023 }
4024 }
4025
4026 fn generate_select(&mut self, select: &Select) -> Result<()> {
4027 use crate::dialects::DialectType;
4028
4029 if let Some(exclude) = &select.exclude {
4033 if !exclude.is_empty() && !matches!(self.config.dialect, Some(DialectType::Redshift)) {
4034 let mut inner_select = select.clone();
4036 inner_select.exclude = None;
4037 let inner_expr = Expression::Select(Box::new(inner_select));
4038
4039 let subquery = crate::expressions::Subquery {
4041 this: inner_expr,
4042 alias: None,
4043 column_aliases: Vec::new(),
4044 order_by: None,
4045 limit: None,
4046 offset: None,
4047 distribute_by: None,
4048 sort_by: None,
4049 cluster_by: None,
4050 lateral: false,
4051 modifiers_inside: false,
4052 trailing_comments: Vec::new(),
4053 inferred_type: None,
4054 };
4055
4056 let star = Expression::Star(crate::expressions::Star {
4058 table: None,
4059 except: Some(
4060 exclude
4061 .iter()
4062 .map(|e| match e {
4063 Expression::Column(col) => col.name.clone(),
4064 Expression::Identifier(id) => id.clone(),
4065 _ => crate::expressions::Identifier::new("unknown".to_string()),
4066 })
4067 .collect(),
4068 ),
4069 replace: None,
4070 rename: None,
4071 trailing_comments: Vec::new(),
4072 span: None,
4073 });
4074
4075 let outer_select = Select {
4076 expressions: vec![star],
4077 from: Some(crate::expressions::From {
4078 expressions: vec![Expression::Subquery(Box::new(subquery))],
4079 }),
4080 ..Select::new()
4081 };
4082
4083 return self.generate_select(&outer_select);
4084 }
4085 }
4086
4087 for comment in &select.leading_comments {
4089 self.write_formatted_comment(comment);
4090 self.write(" ");
4091 }
4092
4093 if let Some(with) = &select.with {
4095 self.generate_with(with)?;
4096 if self.config.pretty {
4097 self.write_newline();
4098 self.write_indent();
4099 } else {
4100 self.write_space();
4101 }
4102 }
4103
4104 for comment in &select.post_select_comments {
4107 self.write_formatted_comment(comment);
4108 self.write(" ");
4109 }
4110
4111 self.write_keyword("SELECT");
4112
4113 if let Some(hint) = &select.hint {
4115 self.generate_hint(hint)?;
4116 }
4117
4118 let use_top_from_limit = matches!(
4122 self.config.dialect,
4123 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4124 ) && select.top.is_none()
4125 && select.limit.is_some()
4126 && select.offset.is_none(); let is_top_dialect = matches!(
4131 self.config.dialect,
4132 Some(DialectType::TSQL) | Some(DialectType::Teradata) | Some(DialectType::Fabric)
4133 );
4134 let keep_top_verbatim = !is_top_dialect
4135 && select.limit.is_none()
4136 && select
4137 .top
4138 .as_ref()
4139 .map_or(false, |top| top.percent || top.with_ties);
4140
4141 if select.distinct && (is_top_dialect || select.top.is_some()) {
4142 self.write_space();
4143 self.write_keyword("DISTINCT");
4144 }
4145
4146 if is_top_dialect || keep_top_verbatim {
4147 if let Some(top) = &select.top {
4148 self.write_space();
4149 self.write_keyword("TOP");
4150 if top.parenthesized {
4151 if matches!(&top.this, Expression::Subquery(_) | Expression::Paren(_)) {
4152 self.write_space();
4153 self.generate_expression(&top.this)?;
4154 } else {
4155 self.write(" (");
4156 self.generate_expression(&top.this)?;
4157 self.write(")");
4158 }
4159 } else {
4160 self.write_space();
4161 self.generate_expression(&top.this)?;
4162 }
4163 if top.percent {
4164 self.write_space();
4165 self.write_keyword("PERCENT");
4166 }
4167 if top.with_ties {
4168 self.write_space();
4169 self.write_keyword("WITH TIES");
4170 }
4171 } else if use_top_from_limit {
4172 if let Some(limit) = &select.limit {
4174 self.write_space();
4175 self.write_keyword("TOP");
4176 let is_simple_literal = matches!(&limit.this, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)));
4178 if is_simple_literal {
4179 self.write_space();
4180 self.generate_expression(&limit.this)?;
4181 } else {
4182 self.write(" (");
4183 self.generate_expression(&limit.this)?;
4184 self.write(")");
4185 }
4186 }
4187 }
4188 }
4189
4190 if select.distinct && !is_top_dialect && select.top.is_none() {
4191 self.write_space();
4192 self.write_keyword("DISTINCT");
4193 }
4194
4195 if let Some(distinct_on) = &select.distinct_on {
4197 self.write_space();
4198 self.write_keyword("ON");
4199 self.write(" (");
4200 for (i, expr) in distinct_on.iter().enumerate() {
4201 if i > 0 {
4202 self.write(", ");
4203 }
4204 self.generate_expression(expr)?;
4205 }
4206 self.write(")");
4207 }
4208
4209 for modifier in &select.operation_modifiers {
4211 self.write_space();
4212 self.write_keyword(modifier);
4213 }
4214
4215 if let Some(kind) = &select.kind {
4217 self.write_space();
4218 self.write_keyword("AS");
4219 self.write_space();
4220 self.write_keyword(kind);
4221 }
4222
4223 if !select.expressions.is_empty() {
4225 if self.config.pretty {
4226 self.write_newline();
4227 self.indent_level += 1;
4228 } else {
4229 self.write_space();
4230 }
4231 }
4232
4233 for (i, expr) in select.expressions.iter().enumerate() {
4234 if i > 0 {
4235 self.write(",");
4236 if self.config.pretty {
4237 self.write_newline();
4238 } else {
4239 self.write_space();
4240 }
4241 }
4242 if self.config.pretty {
4243 self.write_indent();
4244 }
4245 self.generate_expression(expr)?;
4246 }
4247
4248 if self.config.pretty && !select.expressions.is_empty() {
4249 self.indent_level -= 1;
4250 }
4251
4252 if let Some(exclude) = &select.exclude {
4257 if !exclude.is_empty() && matches!(self.config.dialect, Some(DialectType::Redshift)) {
4258 self.write_space();
4259 self.write_keyword("EXCLUDE");
4260 self.write(" (");
4261 for (i, col) in exclude.iter().enumerate() {
4262 if i > 0 {
4263 self.write(", ");
4264 }
4265 self.generate_expression(col)?;
4266 }
4267 self.write(")");
4268 }
4269 }
4270
4271 if let Some(into) = &select.into {
4274 if self.config.pretty {
4275 self.write_newline();
4276 self.write_indent();
4277 } else {
4278 self.write_space();
4279 }
4280 if into.bulk_collect {
4281 self.write_keyword("BULK COLLECT INTO");
4282 } else {
4283 self.write_keyword("INTO");
4284 }
4285 if into.temporary {
4286 self.write_space();
4287 self.write_keyword("TEMPORARY");
4288 }
4289 if into.unlogged {
4290 self.write_space();
4291 self.write_keyword("UNLOGGED");
4292 }
4293 self.write_space();
4294 if !into.expressions.is_empty() {
4296 for (i, expr) in into.expressions.iter().enumerate() {
4297 if i > 0 {
4298 self.write(", ");
4299 }
4300 self.generate_expression(expr)?;
4301 }
4302 } else {
4303 self.generate_expression(&into.this)?;
4304 }
4305 }
4306
4307 if let Some(from) = &select.from {
4309 if self.config.pretty {
4310 self.write_newline();
4311 self.write_indent();
4312 } else {
4313 self.write_space();
4314 }
4315 self.write_keyword("FROM");
4316 self.write_space();
4317
4318 let has_tablesample = from
4323 .expressions
4324 .iter()
4325 .any(|e| matches!(e, Expression::TableSample(_)));
4326 let is_cross_join_dialect = matches!(
4327 self.config.dialect,
4328 Some(DialectType::BigQuery)
4329 | Some(DialectType::Hive)
4330 | Some(DialectType::Spark)
4331 | Some(DialectType::Databricks)
4332 | Some(DialectType::SQLite)
4333 | Some(DialectType::ClickHouse)
4334 );
4335 let source_is_same_as_target = self.config.source_dialect.is_some()
4338 && self.config.source_dialect == self.config.dialect;
4339 let source_is_cross_join_dialect = matches!(
4340 self.config.source_dialect,
4341 Some(DialectType::BigQuery)
4342 | Some(DialectType::Hive)
4343 | Some(DialectType::Spark)
4344 | Some(DialectType::Databricks)
4345 | Some(DialectType::SQLite)
4346 | Some(DialectType::ClickHouse)
4347 );
4348 let use_cross_join = !has_tablesample
4349 && is_cross_join_dialect
4350 && (source_is_same_as_target
4351 || source_is_cross_join_dialect
4352 || self.config.source_dialect.is_none());
4353
4354 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
4356
4357 for (i, expr) in from.expressions.iter().enumerate() {
4358 if i > 0 {
4359 if use_cross_join {
4360 self.write(" CROSS JOIN ");
4361 } else {
4362 self.write(", ");
4363 }
4364 }
4365 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
4366 self.write("(");
4367 self.generate_expression(expr)?;
4368 self.write(")");
4369 } else {
4370 self.generate_expression(expr)?;
4371 }
4372 let leading = Self::extract_table_leading_comments(expr);
4375 for comment in &leading {
4376 self.write_space();
4377 self.write_formatted_comment(comment);
4378 }
4379 }
4380 }
4381
4382 if self.config.pretty {
4386 self.generate_joins_with_nesting(&select.joins)?;
4387 } else {
4388 for join in &select.joins {
4389 self.generate_join(join)?;
4390 }
4391 for join in select.joins.iter().rev() {
4393 if join.deferred_condition {
4394 self.generate_join_condition(join)?;
4395 }
4396 }
4397 }
4398
4399 for (lv_idx, lateral_view) in select.lateral_views.iter().enumerate() {
4401 self.generate_lateral_view(lateral_view, lv_idx)?;
4402 }
4403
4404 if let Some(prewhere) = &select.prewhere {
4406 self.write_clause_condition("PREWHERE", prewhere)?;
4407 }
4408
4409 if let Some(where_clause) = &select.where_clause {
4411 self.write_clause_condition("WHERE", &where_clause.this)?;
4412 }
4413
4414 if let Some(connect) = &select.connect {
4416 self.generate_connect(connect)?;
4417 }
4418
4419 if let Some(group_by) = &select.group_by {
4421 if self.config.pretty {
4422 for comment in &group_by.comments {
4424 self.write_newline();
4425 self.write_indent();
4426 self.write_formatted_comment(comment);
4427 }
4428 self.write_newline();
4429 self.write_indent();
4430 } else {
4431 self.write_space();
4432 for comment in &group_by.comments {
4434 self.write_formatted_comment(comment);
4435 self.write_space();
4436 }
4437 }
4438 self.write_keyword("GROUP BY");
4439 match group_by.all {
4441 Some(true) => {
4442 self.write_space();
4443 self.write_keyword("ALL");
4444 }
4445 Some(false) => {
4446 self.write_space();
4447 self.write_keyword("DISTINCT");
4448 }
4449 None => {}
4450 }
4451 if !group_by.expressions.is_empty() {
4452 let mut trailing_cube = false;
4455 let mut trailing_rollup = false;
4456 let mut plain_expressions: Vec<&Expression> = Vec::new();
4457 let mut grouping_sets_expressions: Vec<&Expression> = Vec::new();
4458 let mut cube_expressions: Vec<&Expression> = Vec::new();
4459 let mut rollup_expressions: Vec<&Expression> = Vec::new();
4460
4461 for expr in &group_by.expressions {
4462 match expr {
4463 Expression::Cube(c) if c.expressions.is_empty() => {
4464 trailing_cube = true;
4465 }
4466 Expression::Rollup(r) if r.expressions.is_empty() => {
4467 trailing_rollup = true;
4468 }
4469 Expression::Function(f) if f.name == "CUBE" => {
4470 cube_expressions.push(expr);
4471 }
4472 Expression::Function(f) if f.name == "ROLLUP" => {
4473 rollup_expressions.push(expr);
4474 }
4475 Expression::Function(f) if f.name == "GROUPING SETS" => {
4476 grouping_sets_expressions.push(expr);
4477 }
4478 _ => {
4479 plain_expressions.push(expr);
4480 }
4481 }
4482 }
4483
4484 let mut regular_expressions: Vec<&Expression> = Vec::new();
4486 regular_expressions.extend(plain_expressions);
4487 regular_expressions.extend(grouping_sets_expressions);
4488 regular_expressions.extend(cube_expressions);
4489 regular_expressions.extend(rollup_expressions);
4490
4491 if self.config.pretty {
4492 self.write_newline();
4493 self.indent_level += 1;
4494 self.write_indent();
4495 } else {
4496 self.write_space();
4497 }
4498
4499 for (i, expr) in regular_expressions.iter().enumerate() {
4500 if i > 0 {
4501 if self.config.pretty {
4502 self.write(",");
4503 self.write_newline();
4504 self.write_indent();
4505 } else {
4506 self.write(", ");
4507 }
4508 }
4509 self.generate_expression(expr)?;
4510 }
4511
4512 if self.config.pretty {
4513 self.indent_level -= 1;
4514 }
4515
4516 if trailing_cube {
4518 self.write_space();
4519 self.write_keyword("WITH CUBE");
4520 } else if trailing_rollup {
4521 self.write_space();
4522 self.write_keyword("WITH ROLLUP");
4523 }
4524 }
4525
4526 if group_by.totals {
4528 self.write_space();
4529 self.write_keyword("WITH TOTALS");
4530 }
4531 }
4532
4533 if let Some(having) = &select.having {
4535 if self.config.pretty {
4536 for comment in &having.comments {
4538 self.write_newline();
4539 self.write_indent();
4540 self.write_formatted_comment(comment);
4541 }
4542 } else {
4543 for comment in &having.comments {
4544 self.write_space();
4545 self.write_formatted_comment(comment);
4546 }
4547 }
4548 self.write_clause_condition("HAVING", &having.this)?;
4549 }
4550
4551 if select.qualify_after_window {
4553 if let Some(windows) = &select.windows {
4555 self.write_window_clause(windows)?;
4556 }
4557 if let Some(qualify) = &select.qualify {
4558 self.write_clause_condition("QUALIFY", &qualify.this)?;
4559 }
4560 } else {
4561 if let Some(qualify) = &select.qualify {
4563 self.write_clause_condition("QUALIFY", &qualify.this)?;
4564 }
4565 if let Some(windows) = &select.windows {
4566 self.write_window_clause(windows)?;
4567 }
4568 }
4569
4570 if let Some(distribute_by) = &select.distribute_by {
4572 self.write_clause_expressions("DISTRIBUTE BY", &distribute_by.expressions)?;
4573 }
4574
4575 if let Some(cluster_by) = &select.cluster_by {
4577 self.write_order_clause("CLUSTER BY", &cluster_by.expressions)?;
4578 }
4579
4580 if let Some(sort_by) = &select.sort_by {
4582 self.write_order_clause("SORT BY", &sort_by.expressions)?;
4583 }
4584
4585 if let Some(order_by) = &select.order_by {
4587 if self.config.pretty {
4588 for comment in &order_by.comments {
4590 self.write_newline();
4591 self.write_indent();
4592 self.write_formatted_comment(comment);
4593 }
4594 } else {
4595 for comment in &order_by.comments {
4596 self.write_space();
4597 self.write_formatted_comment(comment);
4598 }
4599 }
4600 let keyword = if order_by.siblings {
4601 "ORDER SIBLINGS BY"
4602 } else {
4603 "ORDER BY"
4604 };
4605 self.write_order_clause(keyword, &order_by.expressions)?;
4606 }
4607
4608 if select.order_by.is_none()
4610 && select.fetch.is_some()
4611 && matches!(
4612 self.config.dialect,
4613 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4614 )
4615 {
4616 if self.config.pretty {
4617 self.write_newline();
4618 self.write_indent();
4619 } else {
4620 self.write_space();
4621 }
4622 self.write_keyword("ORDER BY (SELECT NULL) OFFSET 0 ROWS");
4623 }
4624
4625 let is_presto_like = matches!(
4630 self.config.dialect,
4631 Some(DialectType::Presto) | Some(DialectType::Trino)
4632 );
4633
4634 if is_presto_like && select.offset.is_some() {
4635 if let Some(offset) = &select.offset {
4637 if self.config.pretty {
4638 self.write_newline();
4639 self.write_indent();
4640 } else {
4641 self.write_space();
4642 }
4643 self.write_keyword("OFFSET");
4644 self.write_space();
4645 self.write_limit_expr(&offset.this)?;
4646 if offset.rows == Some(true) {
4647 self.write_space();
4648 self.write_keyword("ROWS");
4649 }
4650 }
4651 if let Some(limit) = &select.limit {
4652 if self.config.pretty {
4653 self.write_newline();
4654 self.write_indent();
4655 } else {
4656 self.write_space();
4657 }
4658 self.write_keyword("LIMIT");
4659 self.write_space();
4660 self.write_limit_expr(&limit.this)?;
4661 if limit.percent {
4662 self.write_space();
4663 self.write_keyword("PERCENT");
4664 }
4665 for comment in &limit.comments {
4667 self.write(" ");
4668 self.write_formatted_comment(comment);
4669 }
4670 }
4671 } else {
4672 let fetch_as_limit = select.fetch.as_ref().map_or(false, |fetch| {
4674 !fetch.percent
4675 && !fetch.with_ties
4676 && fetch.count.is_some()
4677 && matches!(
4678 self.config.dialect,
4679 Some(DialectType::Spark)
4680 | Some(DialectType::Hive)
4681 | Some(DialectType::DuckDB)
4682 | Some(DialectType::SQLite)
4683 | Some(DialectType::MySQL)
4684 | Some(DialectType::BigQuery)
4685 | Some(DialectType::Databricks)
4686 | Some(DialectType::StarRocks)
4687 | Some(DialectType::Doris)
4688 | Some(DialectType::Athena)
4689 | Some(DialectType::ClickHouse)
4690 | Some(DialectType::Redshift)
4691 )
4692 });
4693
4694 if let Some(limit) = &select.limit {
4696 if !matches!(
4698 self.config.dialect,
4699 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4700 ) {
4701 if self.config.pretty {
4702 self.write_newline();
4703 self.write_indent();
4704 } else {
4705 self.write_space();
4706 }
4707 self.write_keyword("LIMIT");
4708 self.write_space();
4709 self.write_limit_expr(&limit.this)?;
4710 if limit.percent {
4711 self.write_space();
4712 self.write_keyword("PERCENT");
4713 }
4714 for comment in &limit.comments {
4716 self.write(" ");
4717 self.write_formatted_comment(comment);
4718 }
4719 }
4720 }
4721
4722 if select.top.is_some() && !is_top_dialect && select.limit.is_none() {
4724 if let Some(top) = &select.top {
4725 if !top.percent && !top.with_ties {
4726 if self.config.pretty {
4727 self.write_newline();
4728 self.write_indent();
4729 } else {
4730 self.write_space();
4731 }
4732 self.write_keyword("LIMIT");
4733 self.write_space();
4734 self.generate_expression(&top.this)?;
4735 }
4736 }
4737 }
4738
4739 if fetch_as_limit && select.offset.is_some() {
4742 if let Some(fetch) = &select.fetch {
4743 if self.config.pretty {
4744 self.write_newline();
4745 self.write_indent();
4746 } else {
4747 self.write_space();
4748 }
4749 self.write_keyword("LIMIT");
4750 self.write_space();
4751 self.generate_expression(fetch.count.as_ref().unwrap())?;
4752 }
4753 }
4754
4755 if let Some(offset) = &select.offset {
4759 if self.config.pretty {
4760 self.write_newline();
4761 self.write_indent();
4762 } else {
4763 self.write_space();
4764 }
4765 if matches!(self.config.dialect, Some(DialectType::TSQL)) {
4766 self.write_keyword("OFFSET");
4768 self.write_space();
4769 self.write_limit_expr(&offset.this)?;
4770 self.write_space();
4771 self.write_keyword("ROWS");
4772 if let Some(limit) = &select.limit {
4774 self.write_space();
4775 self.write_keyword("FETCH NEXT");
4776 self.write_space();
4777 self.write_limit_expr(&limit.this)?;
4778 self.write_space();
4779 self.write_keyword("ROWS ONLY");
4780 }
4781 } else {
4782 self.write_keyword("OFFSET");
4783 self.write_space();
4784 self.write_limit_expr(&offset.this)?;
4785 if offset.rows == Some(true) {
4787 self.write_space();
4788 self.write_keyword("ROWS");
4789 }
4790 }
4791 }
4792 }
4793
4794 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4796 if let Some(limit_by) = &select.limit_by {
4797 if !limit_by.is_empty() {
4798 self.write_space();
4799 self.write_keyword("BY");
4800 self.write_space();
4801 for (i, expr) in limit_by.iter().enumerate() {
4802 if i > 0 {
4803 self.write(", ");
4804 }
4805 self.generate_expression(expr)?;
4806 }
4807 }
4808 }
4809 }
4810
4811 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4813 if let Some(settings) = &select.settings {
4814 if self.config.pretty {
4815 self.write_newline();
4816 self.write_indent();
4817 } else {
4818 self.write_space();
4819 }
4820 self.write_keyword("SETTINGS");
4821 self.write_space();
4822 for (i, expr) in settings.iter().enumerate() {
4823 if i > 0 {
4824 self.write(", ");
4825 }
4826 self.generate_expression(expr)?;
4827 }
4828 }
4829
4830 if let Some(format_expr) = &select.format {
4831 if self.config.pretty {
4832 self.write_newline();
4833 self.write_indent();
4834 } else {
4835 self.write_space();
4836 }
4837 self.write_keyword("FORMAT");
4838 self.write_space();
4839 self.generate_expression(format_expr)?;
4840 }
4841 }
4842
4843 if let Some(fetch) = &select.fetch {
4845 let fetch_already_as_limit = select.offset.is_some()
4847 && !fetch.percent
4848 && !fetch.with_ties
4849 && fetch.count.is_some()
4850 && matches!(
4851 self.config.dialect,
4852 Some(DialectType::Spark)
4853 | Some(DialectType::Hive)
4854 | Some(DialectType::DuckDB)
4855 | Some(DialectType::SQLite)
4856 | Some(DialectType::MySQL)
4857 | Some(DialectType::BigQuery)
4858 | Some(DialectType::Databricks)
4859 | Some(DialectType::StarRocks)
4860 | Some(DialectType::Doris)
4861 | Some(DialectType::Athena)
4862 | Some(DialectType::ClickHouse)
4863 | Some(DialectType::Redshift)
4864 );
4865
4866 if fetch_already_as_limit {
4867 } else {
4869 if self.config.pretty {
4870 self.write_newline();
4871 self.write_indent();
4872 } else {
4873 self.write_space();
4874 }
4875
4876 let use_limit = !fetch.percent
4878 && !fetch.with_ties
4879 && fetch.count.is_some()
4880 && matches!(
4881 self.config.dialect,
4882 Some(DialectType::Spark)
4883 | Some(DialectType::Hive)
4884 | Some(DialectType::DuckDB)
4885 | Some(DialectType::SQLite)
4886 | Some(DialectType::MySQL)
4887 | Some(DialectType::BigQuery)
4888 | Some(DialectType::Databricks)
4889 | Some(DialectType::StarRocks)
4890 | Some(DialectType::Doris)
4891 | Some(DialectType::Athena)
4892 | Some(DialectType::ClickHouse)
4893 | Some(DialectType::Redshift)
4894 );
4895
4896 if use_limit {
4897 self.write_keyword("LIMIT");
4898 self.write_space();
4899 self.generate_expression(fetch.count.as_ref().unwrap())?;
4900 } else {
4901 self.write_keyword("FETCH");
4902 self.write_space();
4903 self.write_keyword(&fetch.direction);
4904 if let Some(ref count) = fetch.count {
4905 self.write_space();
4906 self.generate_expression(count)?;
4907 }
4908 if fetch.percent {
4909 self.write_space();
4910 self.write_keyword("PERCENT");
4911 }
4912 if fetch.rows {
4913 self.write_space();
4914 self.write_keyword("ROWS");
4915 }
4916 if fetch.with_ties {
4917 self.write_space();
4918 self.write_keyword("WITH TIES");
4919 } else {
4920 self.write_space();
4921 self.write_keyword("ONLY");
4922 }
4923 }
4924 } }
4926
4927 if let Some(sample) = &select.sample {
4929 use crate::dialects::DialectType;
4930 if self.config.pretty {
4931 self.write_newline();
4932 } else {
4933 self.write_space();
4934 }
4935
4936 if sample.is_using_sample {
4937 self.write_keyword("USING SAMPLE");
4939 self.generate_sample_body(sample)?;
4940 } else {
4941 self.write_keyword("TABLESAMPLE");
4942
4943 let snowflake_bernoulli =
4945 matches!(self.config.dialect, Some(DialectType::Snowflake))
4946 && !sample.explicit_method;
4947 if snowflake_bernoulli {
4948 self.write_space();
4949 self.write_keyword("BERNOULLI");
4950 }
4951
4952 if matches!(sample.method, SampleMethod::Bucket) {
4954 self.write_space();
4955 self.write("(");
4956 self.write_keyword("BUCKET");
4957 self.write_space();
4958 if let Some(ref num) = sample.bucket_numerator {
4959 self.generate_expression(num)?;
4960 }
4961 self.write_space();
4962 self.write_keyword("OUT OF");
4963 self.write_space();
4964 if let Some(ref denom) = sample.bucket_denominator {
4965 self.generate_expression(denom)?;
4966 }
4967 if let Some(ref field) = sample.bucket_field {
4968 self.write_space();
4969 self.write_keyword("ON");
4970 self.write_space();
4971 self.generate_expression(field)?;
4972 }
4973 self.write(")");
4974 } else if sample.unit_after_size {
4975 if sample.explicit_method && sample.method_before_size {
4977 self.write_space();
4978 match sample.method {
4979 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
4980 SampleMethod::System => self.write_keyword("SYSTEM"),
4981 SampleMethod::Block => self.write_keyword("BLOCK"),
4982 SampleMethod::Row => self.write_keyword("ROW"),
4983 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
4984 _ => {}
4985 }
4986 }
4987 self.write(" (");
4988 self.generate_expression(&sample.size)?;
4989 self.write_space();
4990 match sample.method {
4991 SampleMethod::Percent => self.write_keyword("PERCENT"),
4992 SampleMethod::Row => self.write_keyword("ROWS"),
4993 SampleMethod::Reservoir => self.write_keyword("ROWS"),
4994 _ => {
4995 self.write_keyword("PERCENT");
4996 }
4997 }
4998 self.write(")");
4999 } else {
5000 self.write_space();
5002 match sample.method {
5003 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
5004 SampleMethod::System => self.write_keyword("SYSTEM"),
5005 SampleMethod::Block => self.write_keyword("BLOCK"),
5006 SampleMethod::Row => self.write_keyword("ROW"),
5007 SampleMethod::Percent => self.write_keyword("BERNOULLI"),
5008 SampleMethod::Bucket => {}
5009 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
5010 }
5011 self.write(" (");
5012 self.generate_expression(&sample.size)?;
5013 if matches!(sample.method, SampleMethod::Percent) {
5014 self.write_space();
5015 self.write_keyword("PERCENT");
5016 }
5017 self.write(")");
5018 }
5019 }
5020
5021 if let Some(seed) = &sample.seed {
5022 self.write_space();
5023 let use_seed = sample.use_seed_keyword
5025 && !matches!(
5026 self.config.dialect,
5027 Some(crate::dialects::DialectType::Databricks)
5028 | Some(crate::dialects::DialectType::Spark)
5029 );
5030 if use_seed {
5031 self.write_keyword("SEED");
5032 } else {
5033 self.write_keyword("REPEATABLE");
5034 }
5035 self.write(" (");
5036 self.generate_expression(seed)?;
5037 self.write(")");
5038 }
5039 }
5040
5041 if self.config.locking_reads_supported {
5044 for lock in &select.locks {
5045 if self.config.pretty {
5046 self.write_newline();
5047 self.write_indent();
5048 } else {
5049 self.write_space();
5050 }
5051 self.generate_lock(lock)?;
5052 }
5053 }
5054
5055 if !select.for_xml.is_empty() {
5057 if self.config.pretty {
5058 self.write_newline();
5059 self.write_indent();
5060 } else {
5061 self.write_space();
5062 }
5063 self.write_keyword("FOR XML");
5064 for (i, opt) in select.for_xml.iter().enumerate() {
5065 if self.config.pretty {
5066 if i > 0 {
5067 self.write(",");
5068 }
5069 self.write_newline();
5070 self.write_indent();
5071 self.write(" "); } else {
5073 if i > 0 {
5074 self.write(",");
5075 }
5076 self.write_space();
5077 }
5078 self.generate_for_xml_option(opt)?;
5079 }
5080 }
5081
5082 if !select.for_json.is_empty() {
5084 if self.config.pretty {
5085 self.write_newline();
5086 self.write_indent();
5087 } else {
5088 self.write_space();
5089 }
5090 self.write_keyword("FOR JSON");
5091 for (i, opt) in select.for_json.iter().enumerate() {
5092 if self.config.pretty {
5093 if i > 0 {
5094 self.write(",");
5095 }
5096 self.write_newline();
5097 self.write_indent();
5098 self.write(" "); } else {
5100 if i > 0 {
5101 self.write(",");
5102 }
5103 self.write_space();
5104 }
5105 self.generate_for_xml_option(opt)?;
5106 }
5107 }
5108
5109 if let Some(ref option) = select.option {
5111 if matches!(
5112 self.config.dialect,
5113 Some(crate::dialects::DialectType::TSQL)
5114 | Some(crate::dialects::DialectType::Fabric)
5115 ) {
5116 self.write_space();
5117 self.write(option);
5118 }
5119 }
5120
5121 Ok(())
5122 }
5123
5124 fn generate_for_xml_option(&mut self, opt: &Expression) -> Result<()> {
5126 match opt {
5127 Expression::QueryOption(qo) => {
5128 if let Expression::Var(var) = &*qo.this {
5130 self.write(&var.this);
5131 } else {
5132 self.generate_expression(&qo.this)?;
5133 }
5134 if let Some(expr) = &qo.expression {
5136 self.write("(");
5137 self.generate_expression(expr)?;
5138 self.write(")");
5139 }
5140 }
5141 _ => {
5142 self.generate_expression(opt)?;
5143 }
5144 }
5145 Ok(())
5146 }
5147
5148 fn generate_with(&mut self, with: &With) -> Result<()> {
5149 use crate::dialects::DialectType;
5150
5151 for comment in &with.leading_comments {
5153 self.write_formatted_comment(comment);
5154 self.write(" ");
5155 }
5156 self.write_keyword("WITH");
5157 if with.recursive && self.config.cte_recursive_keyword_required {
5158 self.write_space();
5159 self.write_keyword("RECURSIVE");
5160 }
5161 self.write_space();
5162
5163 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
5165
5166 for (i, cte) in with.ctes.iter().enumerate() {
5167 if i > 0 {
5168 self.write(",");
5169 if self.config.pretty {
5170 self.write_space();
5171 } else {
5172 self.write(" ");
5173 }
5174 }
5175 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !cte.alias_first {
5176 self.generate_expression(&cte.this)?;
5177 self.write_space();
5178 self.write_keyword("AS");
5179 self.write_space();
5180 self.generate_identifier(&cte.alias)?;
5181 continue;
5182 }
5183 self.generate_identifier(&cte.alias)?;
5184 for comment in &cte.comments {
5186 self.write_space();
5187 self.write_formatted_comment(comment);
5188 }
5189 if !cte.columns.is_empty() && !skip_cte_columns {
5190 self.write("(");
5191 for (j, col) in cte.columns.iter().enumerate() {
5192 if j > 0 {
5193 self.write(", ");
5194 }
5195 self.generate_identifier(col)?;
5196 }
5197 self.write(")");
5198 }
5199 if !cte.key_expressions.is_empty() {
5201 self.write_space();
5202 self.write_keyword("USING KEY");
5203 self.write(" (");
5204 for (i, key) in cte.key_expressions.iter().enumerate() {
5205 if i > 0 {
5206 self.write(", ");
5207 }
5208 self.generate_identifier(key)?;
5209 }
5210 self.write(")");
5211 }
5212 self.write_space();
5213 self.write_keyword("AS");
5214 if let Some(materialized) = cte.materialized {
5216 self.write_space();
5217 if materialized {
5218 self.write_keyword("MATERIALIZED");
5219 } else {
5220 self.write_keyword("NOT MATERIALIZED");
5221 }
5222 }
5223 self.write(" (");
5224 if self.config.pretty {
5225 self.write_newline();
5226 self.indent_level += 1;
5227 self.write_indent();
5228 }
5229 let wrap_values_in_select = matches!(
5232 self.config.dialect,
5233 Some(DialectType::Spark) | Some(DialectType::Databricks)
5234 ) && matches!(&cte.this, Expression::Values(_));
5235
5236 if wrap_values_in_select {
5237 self.write_keyword("SELECT");
5238 self.write(" * ");
5239 self.write_keyword("FROM");
5240 self.write_space();
5241 }
5242 self.generate_expression(&cte.this)?;
5243 if self.config.pretty {
5244 self.write_newline();
5245 self.indent_level -= 1;
5246 self.write_indent();
5247 }
5248 self.write(")");
5249 }
5250
5251 if let Some(search) = &with.search {
5253 self.write_space();
5254 self.generate_expression(search)?;
5255 }
5256
5257 Ok(())
5258 }
5259
5260 fn generate_joins_with_nesting(&mut self, joins: &[Join]) -> Result<()> {
5264 let mut i = 0;
5265 while i < joins.len() {
5266 if joins[i].deferred_condition {
5267 let parent_group = joins[i].nesting_group;
5268
5269 self.generate_join_without_condition(&joins[i])?;
5272
5273 let child_start = i + 1;
5275 let mut child_end = child_start;
5276 while child_end < joins.len()
5277 && !joins[child_end].deferred_condition
5278 && joins[child_end].nesting_group == parent_group
5279 {
5280 child_end += 1;
5281 }
5282
5283 if child_start < child_end {
5285 self.indent_level += 1;
5286 for j in child_start..child_end {
5287 self.generate_join(&joins[j])?;
5288 }
5289 self.indent_level -= 1;
5290 }
5291
5292 self.generate_join_condition(&joins[i])?;
5294
5295 i = child_end;
5296 } else {
5297 self.generate_join(&joins[i])?;
5299 i += 1;
5300 }
5301 }
5302 Ok(())
5303 }
5304
5305 fn generate_join_without_condition(&mut self, join: &Join) -> Result<()> {
5308 let mut join_copy = join.clone();
5311 join_copy.on = None;
5312 join_copy.using = Vec::new();
5313 join_copy.deferred_condition = false;
5314 self.generate_join(&join_copy)
5315 }
5316
5317 fn generate_join(&mut self, join: &Join) -> Result<()> {
5318 if join.kind == JoinKind::Implicit {
5320 self.write(",");
5321 if self.config.pretty {
5322 self.write_newline();
5323 self.write_indent();
5324 } else {
5325 self.write_space();
5326 }
5327 self.generate_expression(&join.this)?;
5328 return Ok(());
5329 }
5330
5331 if self.config.pretty {
5332 self.write_newline();
5333 self.write_indent();
5334 } else {
5335 self.write_space();
5336 }
5337
5338 let hint_str = if self.config.join_hints {
5341 join.join_hint
5342 .as_ref()
5343 .map(|h| format!(" {}", h))
5344 .unwrap_or_default()
5345 } else {
5346 String::new()
5347 };
5348
5349 let clickhouse_join_keyword =
5350 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
5351 if let Some(hint) = &join.join_hint {
5352 let mut global = false;
5353 let mut strictness: Option<&'static str> = None;
5354 for part in hint.split_whitespace() {
5355 if part.eq_ignore_ascii_case("GLOBAL") {
5356 global = true;
5357 } else if part.eq_ignore_ascii_case("ANY") {
5358 strictness = Some("ANY");
5359 } else if part.eq_ignore_ascii_case("ASOF") {
5360 strictness = Some("ASOF");
5361 } else if part.eq_ignore_ascii_case("SEMI") {
5362 strictness = Some("SEMI");
5363 } else if part.eq_ignore_ascii_case("ANTI") {
5364 strictness = Some("ANTI");
5365 }
5366 }
5367
5368 if global || strictness.is_some() {
5369 let join_type = match join.kind {
5370 JoinKind::Left => {
5371 if join.use_outer_keyword {
5372 "LEFT OUTER"
5373 } else if join.use_inner_keyword {
5374 "LEFT INNER"
5375 } else {
5376 "LEFT"
5377 }
5378 }
5379 JoinKind::Right => {
5380 if join.use_outer_keyword {
5381 "RIGHT OUTER"
5382 } else if join.use_inner_keyword {
5383 "RIGHT INNER"
5384 } else {
5385 "RIGHT"
5386 }
5387 }
5388 JoinKind::Full => {
5389 if join.use_outer_keyword {
5390 "FULL OUTER"
5391 } else {
5392 "FULL"
5393 }
5394 }
5395 JoinKind::Inner => {
5396 if join.use_inner_keyword {
5397 "INNER"
5398 } else {
5399 ""
5400 }
5401 }
5402 _ => "",
5403 };
5404
5405 let mut parts = Vec::new();
5406 if global {
5407 parts.push("GLOBAL");
5408 }
5409 if !join_type.is_empty() {
5410 parts.push(join_type);
5411 }
5412 if let Some(strict) = strictness {
5413 parts.push(strict);
5414 }
5415 parts.push("JOIN");
5416 Some(parts.join(" "))
5417 } else {
5418 None
5419 }
5420 } else {
5421 None
5422 }
5423 } else {
5424 None
5425 };
5426
5427 if !join.comments.is_empty() {
5431 if self.config.pretty {
5432 let trimmed = self.output.trim_end().len();
5437 self.output.truncate(trimmed);
5438 for comment in &join.comments {
5439 self.write_newline();
5440 self.write_indent();
5441 self.write_formatted_comment(comment);
5442 }
5443 self.write_newline();
5444 self.write_indent();
5445 } else {
5446 for comment in &join.comments {
5447 self.write_formatted_comment(comment);
5448 self.write_space();
5449 }
5450 }
5451 }
5452
5453 let directed_str = if join.directed { " DIRECTED" } else { "" };
5454
5455 if let Some(keyword) = clickhouse_join_keyword {
5456 self.write_keyword(&keyword);
5457 } else {
5458 match join.kind {
5459 JoinKind::Inner => {
5460 if join.use_inner_keyword {
5461 if hint_str.is_empty() && directed_str.is_empty() {
5462 self.write_keyword("INNER JOIN");
5463 } else {
5464 self.write_keyword("INNER");
5465 if !hint_str.is_empty() {
5466 self.write_keyword(&hint_str);
5467 }
5468 if !directed_str.is_empty() {
5469 self.write_keyword(directed_str);
5470 }
5471 self.write_keyword(" JOIN");
5472 }
5473 } else {
5474 if !hint_str.is_empty() {
5475 self.write_keyword(hint_str.trim());
5476 self.write_keyword(" ");
5477 }
5478 if !directed_str.is_empty() {
5479 self.write_keyword("DIRECTED ");
5480 }
5481 self.write_keyword("JOIN");
5482 }
5483 }
5484 JoinKind::Left => {
5485 if join.use_outer_keyword {
5486 if hint_str.is_empty() && directed_str.is_empty() {
5487 self.write_keyword("LEFT OUTER JOIN");
5488 } else {
5489 self.write_keyword("LEFT OUTER");
5490 if !hint_str.is_empty() {
5491 self.write_keyword(&hint_str);
5492 }
5493 if !directed_str.is_empty() {
5494 self.write_keyword(directed_str);
5495 }
5496 self.write_keyword(" JOIN");
5497 }
5498 } else if join.use_inner_keyword {
5499 if hint_str.is_empty() && directed_str.is_empty() {
5500 self.write_keyword("LEFT INNER JOIN");
5501 } else {
5502 self.write_keyword("LEFT INNER");
5503 if !hint_str.is_empty() {
5504 self.write_keyword(&hint_str);
5505 }
5506 if !directed_str.is_empty() {
5507 self.write_keyword(directed_str);
5508 }
5509 self.write_keyword(" JOIN");
5510 }
5511 } else {
5512 if hint_str.is_empty() && directed_str.is_empty() {
5513 self.write_keyword("LEFT JOIN");
5514 } else {
5515 self.write_keyword("LEFT");
5516 if !hint_str.is_empty() {
5517 self.write_keyword(&hint_str);
5518 }
5519 if !directed_str.is_empty() {
5520 self.write_keyword(directed_str);
5521 }
5522 self.write_keyword(" JOIN");
5523 }
5524 }
5525 }
5526 JoinKind::Right => {
5527 if join.use_outer_keyword {
5528 if hint_str.is_empty() && directed_str.is_empty() {
5529 self.write_keyword("RIGHT OUTER JOIN");
5530 } else {
5531 self.write_keyword("RIGHT OUTER");
5532 if !hint_str.is_empty() {
5533 self.write_keyword(&hint_str);
5534 }
5535 if !directed_str.is_empty() {
5536 self.write_keyword(directed_str);
5537 }
5538 self.write_keyword(" JOIN");
5539 }
5540 } else if join.use_inner_keyword {
5541 if hint_str.is_empty() && directed_str.is_empty() {
5542 self.write_keyword("RIGHT INNER JOIN");
5543 } else {
5544 self.write_keyword("RIGHT INNER");
5545 if !hint_str.is_empty() {
5546 self.write_keyword(&hint_str);
5547 }
5548 if !directed_str.is_empty() {
5549 self.write_keyword(directed_str);
5550 }
5551 self.write_keyword(" JOIN");
5552 }
5553 } else {
5554 if hint_str.is_empty() && directed_str.is_empty() {
5555 self.write_keyword("RIGHT JOIN");
5556 } else {
5557 self.write_keyword("RIGHT");
5558 if !hint_str.is_empty() {
5559 self.write_keyword(&hint_str);
5560 }
5561 if !directed_str.is_empty() {
5562 self.write_keyword(directed_str);
5563 }
5564 self.write_keyword(" JOIN");
5565 }
5566 }
5567 }
5568 JoinKind::Full => {
5569 if join.use_outer_keyword {
5570 if hint_str.is_empty() && directed_str.is_empty() {
5571 self.write_keyword("FULL OUTER JOIN");
5572 } else {
5573 self.write_keyword("FULL OUTER");
5574 if !hint_str.is_empty() {
5575 self.write_keyword(&hint_str);
5576 }
5577 if !directed_str.is_empty() {
5578 self.write_keyword(directed_str);
5579 }
5580 self.write_keyword(" JOIN");
5581 }
5582 } else {
5583 if hint_str.is_empty() && directed_str.is_empty() {
5584 self.write_keyword("FULL JOIN");
5585 } else {
5586 self.write_keyword("FULL");
5587 if !hint_str.is_empty() {
5588 self.write_keyword(&hint_str);
5589 }
5590 if !directed_str.is_empty() {
5591 self.write_keyword(directed_str);
5592 }
5593 self.write_keyword(" JOIN");
5594 }
5595 }
5596 }
5597 JoinKind::Outer => {
5598 if directed_str.is_empty() {
5599 self.write_keyword("OUTER JOIN");
5600 } else {
5601 self.write_keyword("OUTER");
5602 self.write_keyword(directed_str);
5603 self.write_keyword(" JOIN");
5604 }
5605 }
5606 JoinKind::Cross => {
5607 if directed_str.is_empty() {
5608 self.write_keyword("CROSS JOIN");
5609 } else {
5610 self.write_keyword("CROSS");
5611 self.write_keyword(directed_str);
5612 self.write_keyword(" JOIN");
5613 }
5614 }
5615 JoinKind::Natural => {
5616 if join.use_inner_keyword {
5617 if directed_str.is_empty() {
5618 self.write_keyword("NATURAL INNER JOIN");
5619 } else {
5620 self.write_keyword("NATURAL INNER");
5621 self.write_keyword(directed_str);
5622 self.write_keyword(" JOIN");
5623 }
5624 } else {
5625 if directed_str.is_empty() {
5626 self.write_keyword("NATURAL JOIN");
5627 } else {
5628 self.write_keyword("NATURAL");
5629 self.write_keyword(directed_str);
5630 self.write_keyword(" JOIN");
5631 }
5632 }
5633 }
5634 JoinKind::NaturalLeft => {
5635 if join.use_outer_keyword {
5636 if directed_str.is_empty() {
5637 self.write_keyword("NATURAL LEFT OUTER JOIN");
5638 } else {
5639 self.write_keyword("NATURAL LEFT OUTER");
5640 self.write_keyword(directed_str);
5641 self.write_keyword(" JOIN");
5642 }
5643 } else {
5644 if directed_str.is_empty() {
5645 self.write_keyword("NATURAL LEFT JOIN");
5646 } else {
5647 self.write_keyword("NATURAL LEFT");
5648 self.write_keyword(directed_str);
5649 self.write_keyword(" JOIN");
5650 }
5651 }
5652 }
5653 JoinKind::NaturalRight => {
5654 if join.use_outer_keyword {
5655 if directed_str.is_empty() {
5656 self.write_keyword("NATURAL RIGHT OUTER JOIN");
5657 } else {
5658 self.write_keyword("NATURAL RIGHT OUTER");
5659 self.write_keyword(directed_str);
5660 self.write_keyword(" JOIN");
5661 }
5662 } else {
5663 if directed_str.is_empty() {
5664 self.write_keyword("NATURAL RIGHT JOIN");
5665 } else {
5666 self.write_keyword("NATURAL RIGHT");
5667 self.write_keyword(directed_str);
5668 self.write_keyword(" JOIN");
5669 }
5670 }
5671 }
5672 JoinKind::NaturalFull => {
5673 if join.use_outer_keyword {
5674 if directed_str.is_empty() {
5675 self.write_keyword("NATURAL FULL OUTER JOIN");
5676 } else {
5677 self.write_keyword("NATURAL FULL OUTER");
5678 self.write_keyword(directed_str);
5679 self.write_keyword(" JOIN");
5680 }
5681 } else {
5682 if directed_str.is_empty() {
5683 self.write_keyword("NATURAL FULL JOIN");
5684 } else {
5685 self.write_keyword("NATURAL FULL");
5686 self.write_keyword(directed_str);
5687 self.write_keyword(" JOIN");
5688 }
5689 }
5690 }
5691 JoinKind::Semi => self.write_keyword("SEMI JOIN"),
5692 JoinKind::Anti => self.write_keyword("ANTI JOIN"),
5693 JoinKind::LeftSemi => self.write_keyword("LEFT SEMI JOIN"),
5694 JoinKind::LeftAnti => self.write_keyword("LEFT ANTI JOIN"),
5695 JoinKind::RightSemi => self.write_keyword("RIGHT SEMI JOIN"),
5696 JoinKind::RightAnti => self.write_keyword("RIGHT ANTI JOIN"),
5697 JoinKind::CrossApply => {
5698 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
5700 self.write_keyword("CROSS APPLY");
5701 } else {
5702 self.write_keyword("INNER JOIN LATERAL");
5703 }
5704 }
5705 JoinKind::OuterApply => {
5706 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
5708 self.write_keyword("OUTER APPLY");
5709 } else {
5710 self.write_keyword("LEFT JOIN LATERAL");
5711 }
5712 }
5713 JoinKind::AsOf => self.write_keyword("ASOF JOIN"),
5714 JoinKind::AsOfLeft => {
5715 if join.use_outer_keyword {
5716 self.write_keyword("ASOF LEFT OUTER JOIN");
5717 } else {
5718 self.write_keyword("ASOF LEFT JOIN");
5719 }
5720 }
5721 JoinKind::AsOfRight => {
5722 if join.use_outer_keyword {
5723 self.write_keyword("ASOF RIGHT OUTER JOIN");
5724 } else {
5725 self.write_keyword("ASOF RIGHT JOIN");
5726 }
5727 }
5728 JoinKind::Lateral => self.write_keyword("LATERAL JOIN"),
5729 JoinKind::LeftLateral => {
5730 if join.use_outer_keyword {
5731 self.write_keyword("LEFT OUTER LATERAL JOIN");
5732 } else {
5733 self.write_keyword("LEFT LATERAL JOIN");
5734 }
5735 }
5736 JoinKind::Straight => self.write_keyword("STRAIGHT_JOIN"),
5737 JoinKind::Implicit => {
5738 use crate::dialects::DialectType;
5742 let is_cj_dialect = matches!(
5743 self.config.dialect,
5744 Some(DialectType::BigQuery)
5745 | Some(DialectType::Hive)
5746 | Some(DialectType::Spark)
5747 | Some(DialectType::Databricks)
5748 );
5749 let source_is_same = self.config.source_dialect.is_some()
5750 && self.config.source_dialect == self.config.dialect;
5751 let source_is_cj = matches!(
5752 self.config.source_dialect,
5753 Some(DialectType::BigQuery)
5754 | Some(DialectType::Hive)
5755 | Some(DialectType::Spark)
5756 | Some(DialectType::Databricks)
5757 );
5758 if is_cj_dialect
5759 && (source_is_same || source_is_cj || self.config.source_dialect.is_none())
5760 {
5761 self.write_keyword("CROSS JOIN");
5762 } else {
5763 self.output.truncate(self.output.trim_end().len());
5767 self.write(",");
5768 }
5769 }
5770 JoinKind::Array => self.write_keyword("ARRAY JOIN"),
5771 JoinKind::LeftArray => self.write_keyword("LEFT ARRAY JOIN"),
5772 JoinKind::Paste => self.write_keyword("PASTE JOIN"),
5773 JoinKind::Positional => self.write_keyword("POSITIONAL JOIN"),
5774 }
5775 }
5776
5777 if matches!(join.kind, JoinKind::Array | JoinKind::LeftArray) {
5779 self.write_space();
5780 match &join.this {
5781 Expression::Tuple(t) => {
5782 for (i, item) in t.expressions.iter().enumerate() {
5783 if i > 0 {
5784 self.write(", ");
5785 }
5786 self.generate_expression(item)?;
5787 }
5788 }
5789 other => {
5790 self.generate_expression(other)?;
5791 }
5792 }
5793 } else {
5794 self.write_space();
5795 self.generate_expression(&join.this)?;
5796 }
5797
5798 if !join.deferred_condition {
5800 if let Some(match_cond) = &join.match_condition {
5802 self.write_space();
5803 self.write_keyword("MATCH_CONDITION");
5804 self.write(" (");
5805 self.generate_expression(match_cond)?;
5806 self.write(")");
5807 }
5808
5809 if let Some(on) = &join.on {
5810 if self.config.pretty {
5811 self.write_newline();
5812 self.indent_level += 1;
5813 self.write_indent();
5814 self.write_keyword("ON");
5815 self.write_space();
5816 self.generate_join_on_condition(on)?;
5817 self.indent_level -= 1;
5818 } else {
5819 self.write_space();
5820 self.write_keyword("ON");
5821 self.write_space();
5822 self.generate_expression(on)?;
5823 }
5824 }
5825
5826 if !join.using.is_empty() {
5827 if self.config.pretty {
5828 self.write_newline();
5829 self.indent_level += 1;
5830 self.write_indent();
5831 self.write_keyword("USING");
5832 self.write(" (");
5833 for (i, col) in join.using.iter().enumerate() {
5834 if i > 0 {
5835 self.write(", ");
5836 }
5837 self.generate_identifier(col)?;
5838 }
5839 self.write(")");
5840 self.indent_level -= 1;
5841 } else {
5842 self.write_space();
5843 self.write_keyword("USING");
5844 self.write(" (");
5845 for (i, col) in join.using.iter().enumerate() {
5846 if i > 0 {
5847 self.write(", ");
5848 }
5849 self.generate_identifier(col)?;
5850 }
5851 self.write(")");
5852 }
5853 }
5854 }
5855
5856 for pivot in &join.pivots {
5858 self.write_space();
5859 self.generate_expression(pivot)?;
5860 }
5861
5862 Ok(())
5863 }
5864
5865 fn generate_join_condition(&mut self, join: &Join) -> Result<()> {
5867 if let Some(match_cond) = &join.match_condition {
5869 self.write_space();
5870 self.write_keyword("MATCH_CONDITION");
5871 self.write(" (");
5872 self.generate_expression(match_cond)?;
5873 self.write(")");
5874 }
5875
5876 if let Some(on) = &join.on {
5877 if self.config.pretty {
5878 self.write_newline();
5879 self.indent_level += 1;
5880 self.write_indent();
5881 self.write_keyword("ON");
5882 self.write_space();
5883 self.generate_join_on_condition(on)?;
5885 self.indent_level -= 1;
5886 } else {
5887 self.write_space();
5888 self.write_keyword("ON");
5889 self.write_space();
5890 self.generate_expression(on)?;
5891 }
5892 }
5893
5894 if !join.using.is_empty() {
5895 if self.config.pretty {
5896 self.write_newline();
5897 self.indent_level += 1;
5898 self.write_indent();
5899 self.write_keyword("USING");
5900 self.write(" (");
5901 for (i, col) in join.using.iter().enumerate() {
5902 if i > 0 {
5903 self.write(", ");
5904 }
5905 self.generate_identifier(col)?;
5906 }
5907 self.write(")");
5908 self.indent_level -= 1;
5909 } else {
5910 self.write_space();
5911 self.write_keyword("USING");
5912 self.write(" (");
5913 for (i, col) in join.using.iter().enumerate() {
5914 if i > 0 {
5915 self.write(", ");
5916 }
5917 self.generate_identifier(col)?;
5918 }
5919 self.write(")");
5920 }
5921 }
5922
5923 for pivot in &join.pivots {
5925 self.write_space();
5926 self.generate_expression(pivot)?;
5927 }
5928
5929 Ok(())
5930 }
5931
5932 fn generate_join_on_condition(&mut self, expr: &Expression) -> Result<()> {
5934 if let Expression::And(and_op) = expr {
5935 if let Some(conditions) = self.flatten_connector_terms(and_op, ConnectorOperator::And) {
5936 self.generate_expression(conditions[0])?;
5937 for condition in conditions.iter().skip(1) {
5938 self.write_newline();
5939 self.write_indent();
5940 self.write_keyword("AND");
5941 self.write_space();
5942 self.generate_expression(condition)?;
5943 }
5944 return Ok(());
5945 }
5946 }
5947
5948 self.generate_expression(expr)
5949 }
5950
5951 fn generate_joined_table(&mut self, jt: &JoinedTable) -> Result<()> {
5952 self.write("(");
5954 self.generate_expression(&jt.left)?;
5955
5956 for join in &jt.joins {
5958 self.generate_join(join)?;
5959 }
5960
5961 for (lv_idx, lv) in jt.lateral_views.iter().enumerate() {
5963 self.generate_lateral_view(lv, lv_idx)?;
5964 }
5965
5966 self.write(")");
5967
5968 if let Some(alias) = &jt.alias {
5970 self.write_space();
5971 self.write_keyword("AS");
5972 self.write_space();
5973 self.generate_identifier(alias)?;
5974 }
5975
5976 Ok(())
5977 }
5978
5979 fn generate_lateral_view(&mut self, lv: &LateralView, lv_index: usize) -> Result<()> {
5980 use crate::dialects::DialectType;
5981
5982 if self.config.pretty {
5983 self.write_newline();
5984 self.write_indent();
5985 } else {
5986 self.write_space();
5987 }
5988
5989 let use_lateral_join = matches!(
5992 self.config.dialect,
5993 Some(DialectType::PostgreSQL)
5994 | Some(DialectType::DuckDB)
5995 | Some(DialectType::Snowflake)
5996 | Some(DialectType::TSQL)
5997 | Some(DialectType::Presto)
5998 | Some(DialectType::Trino)
5999 | Some(DialectType::Athena)
6000 );
6001
6002 let use_unnest = matches!(
6004 self.config.dialect,
6005 Some(DialectType::DuckDB)
6006 | Some(DialectType::Presto)
6007 | Some(DialectType::Trino)
6008 | Some(DialectType::Athena)
6009 );
6010
6011 let (is_posexplode, is_inline, func_args) = match &lv.this {
6013 Expression::Explode(uf) => {
6014 (false, false, vec![uf.this.clone()])
6016 }
6017 Expression::Unnest(uf) => {
6018 let mut args = vec![uf.this.clone()];
6019 args.extend(uf.expressions.clone());
6020 (false, false, args)
6021 }
6022 Expression::Function(func) => {
6023 if func.name.eq_ignore_ascii_case("POSEXPLODE")
6024 || func.name.eq_ignore_ascii_case("POSEXPLODE_OUTER")
6025 {
6026 (true, false, func.args.clone())
6027 } else if func.name.eq_ignore_ascii_case("INLINE") {
6028 (false, true, func.args.clone())
6029 } else if func.name.eq_ignore_ascii_case("EXPLODE")
6030 || func.name.eq_ignore_ascii_case("EXPLODE_OUTER")
6031 {
6032 (false, false, func.args.clone())
6033 } else {
6034 (false, false, vec![])
6035 }
6036 }
6037 _ => (false, false, vec![]),
6038 };
6039
6040 if use_lateral_join {
6041 if lv.outer {
6043 self.write_keyword("LEFT JOIN LATERAL");
6044 } else {
6045 self.write_keyword("CROSS JOIN");
6046 }
6047 self.write_space();
6048
6049 if use_unnest && !func_args.is_empty() {
6050 let unnest_args = if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
6053 func_args
6055 .iter()
6056 .map(|a| {
6057 if let Expression::Function(ref f) = a {
6058 if f.name.eq_ignore_ascii_case("ARRAY") && f.args.len() == 1 {
6059 return Expression::ArrayFunc(Box::new(
6060 crate::expressions::ArrayConstructor {
6061 expressions: f.args.clone(),
6062 bracket_notation: true,
6063 use_list_keyword: false,
6064 },
6065 ));
6066 }
6067 }
6068 a.clone()
6069 })
6070 .collect::<Vec<_>>()
6071 } else if matches!(
6072 self.config.dialect,
6073 Some(DialectType::Presto)
6074 | Some(DialectType::Trino)
6075 | Some(DialectType::Athena)
6076 ) {
6077 func_args
6079 .iter()
6080 .map(|a| {
6081 if let Expression::Function(ref f) = a {
6082 if f.name.eq_ignore_ascii_case("ARRAY") && f.args.len() >= 1 {
6083 return Expression::ArrayFunc(Box::new(
6084 crate::expressions::ArrayConstructor {
6085 expressions: f.args.clone(),
6086 bracket_notation: true,
6087 use_list_keyword: false,
6088 },
6089 ));
6090 }
6091 }
6092 a.clone()
6093 })
6094 .collect::<Vec<_>>()
6095 } else {
6096 func_args
6097 };
6098
6099 if is_posexplode {
6101 self.write_keyword("LATERAL");
6102 self.write(" (");
6103 self.write_keyword("SELECT");
6104 self.write_space();
6105
6106 let pos_alias = if !lv.column_aliases.is_empty() {
6109 lv.column_aliases[0].clone()
6110 } else {
6111 Identifier::new("pos")
6112 };
6113 let data_aliases: Vec<Identifier> = if lv.column_aliases.len() > 1 {
6114 lv.column_aliases[1..].to_vec()
6115 } else {
6116 vec![Identifier::new("col")]
6117 };
6118
6119 self.generate_identifier(&pos_alias)?;
6121 self.write(" - 1");
6122 self.write_space();
6123 self.write_keyword("AS");
6124 self.write_space();
6125 self.generate_identifier(&pos_alias)?;
6126
6127 for data_col in &data_aliases {
6129 self.write(", ");
6130 self.generate_identifier(data_col)?;
6131 }
6132
6133 self.write_space();
6134 self.write_keyword("FROM");
6135 self.write_space();
6136 self.write_keyword("UNNEST");
6137 self.write("(");
6138 for (i, arg) in unnest_args.iter().enumerate() {
6139 if i > 0 {
6140 self.write(", ");
6141 }
6142 self.generate_expression(arg)?;
6143 }
6144 self.write(")");
6145 self.write_space();
6146 self.write_keyword("WITH ORDINALITY");
6147 self.write_space();
6148 self.write_keyword("AS");
6149 self.write_space();
6150
6151 let table_alias_ident = lv
6153 .table_alias
6154 .clone()
6155 .unwrap_or_else(|| Identifier::new("t"));
6156 self.generate_identifier(&table_alias_ident)?;
6157 self.write("(");
6158 for (i, data_col) in data_aliases.iter().enumerate() {
6159 if i > 0 {
6160 self.write(", ");
6161 }
6162 self.generate_identifier(data_col)?;
6163 }
6164 self.write(", ");
6165 self.generate_identifier(&pos_alias)?;
6166 self.write("))");
6167 } else if is_inline && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
6168 self.write_keyword("LATERAL");
6170 self.write(" (");
6171 self.write_keyword("SELECT");
6172 self.write_space();
6173 self.write_keyword("UNNEST");
6174 self.write("(");
6175 for (i, arg) in unnest_args.iter().enumerate() {
6176 if i > 0 {
6177 self.write(", ");
6178 }
6179 self.generate_expression(arg)?;
6180 }
6181 self.write(", ");
6182 self.write_keyword("max_depth");
6183 self.write(" => 2))");
6184
6185 if let Some(alias) = &lv.table_alias {
6187 self.write_space();
6188 self.write_keyword("AS");
6189 self.write_space();
6190 self.generate_identifier(alias)?;
6191 if !lv.column_aliases.is_empty() {
6192 self.write("(");
6193 for (i, col) in lv.column_aliases.iter().enumerate() {
6194 if i > 0 {
6195 self.write(", ");
6196 }
6197 self.generate_identifier(col)?;
6198 }
6199 self.write(")");
6200 }
6201 } else if !lv.column_aliases.is_empty() {
6202 self.write_space();
6204 self.write_keyword("AS");
6205 self.write_space();
6206 self.write(&format!("_u_{}", lv_index));
6207 self.write("(");
6208 for (i, col) in lv.column_aliases.iter().enumerate() {
6209 if i > 0 {
6210 self.write(", ");
6211 }
6212 self.generate_identifier(col)?;
6213 }
6214 self.write(")");
6215 }
6216 } else {
6217 self.write_keyword("UNNEST");
6218 self.write("(");
6219 for (i, arg) in unnest_args.iter().enumerate() {
6220 if i > 0 {
6221 self.write(", ");
6222 }
6223 self.generate_expression(arg)?;
6224 }
6225 self.write(")");
6226
6227 if let Some(alias) = &lv.table_alias {
6229 self.write_space();
6230 self.write_keyword("AS");
6231 self.write_space();
6232 self.generate_identifier(alias)?;
6233 if !lv.column_aliases.is_empty() {
6234 self.write("(");
6235 for (i, col) in lv.column_aliases.iter().enumerate() {
6236 if i > 0 {
6237 self.write(", ");
6238 }
6239 self.generate_identifier(col)?;
6240 }
6241 self.write(")");
6242 }
6243 } else if !lv.column_aliases.is_empty() {
6244 self.write_space();
6245 self.write_keyword("AS");
6246 self.write(" t(");
6247 for (i, col) in lv.column_aliases.iter().enumerate() {
6248 if i > 0 {
6249 self.write(", ");
6250 }
6251 self.generate_identifier(col)?;
6252 }
6253 self.write(")");
6254 }
6255 }
6256 } else {
6257 if !lv.outer {
6259 self.write_keyword("LATERAL");
6260 self.write_space();
6261 }
6262 self.generate_expression(&lv.this)?;
6263
6264 if let Some(alias) = &lv.table_alias {
6266 self.write_space();
6267 self.write_keyword("AS");
6268 self.write_space();
6269 self.generate_identifier(alias)?;
6270 if !lv.column_aliases.is_empty() {
6271 self.write("(");
6272 for (i, col) in lv.column_aliases.iter().enumerate() {
6273 if i > 0 {
6274 self.write(", ");
6275 }
6276 self.generate_identifier(col)?;
6277 }
6278 self.write(")");
6279 }
6280 } else if !lv.column_aliases.is_empty() {
6281 self.write_space();
6282 self.write_keyword("AS");
6283 self.write(" t(");
6284 for (i, col) in lv.column_aliases.iter().enumerate() {
6285 if i > 0 {
6286 self.write(", ");
6287 }
6288 self.generate_identifier(col)?;
6289 }
6290 self.write(")");
6291 }
6292 }
6293
6294 if lv.outer {
6296 self.write_space();
6297 self.write_keyword("ON TRUE");
6298 }
6299 } else {
6300 self.write_keyword("LATERAL VIEW");
6302 if lv.outer {
6303 self.write_space();
6304 self.write_keyword("OUTER");
6305 }
6306 if self.config.pretty {
6307 self.write_newline();
6308 self.write_indent();
6309 } else {
6310 self.write_space();
6311 }
6312 self.generate_expression(&lv.this)?;
6313
6314 if let Some(alias) = &lv.table_alias {
6316 self.write_space();
6317 self.generate_identifier(alias)?;
6318 }
6319
6320 if !lv.column_aliases.is_empty() {
6322 self.write_space();
6323 self.write_keyword("AS");
6324 self.write_space();
6325 for (i, col) in lv.column_aliases.iter().enumerate() {
6326 if i > 0 {
6327 self.write(", ");
6328 }
6329 self.generate_identifier(col)?;
6330 }
6331 }
6332 }
6333
6334 Ok(())
6335 }
6336
6337 fn generate_union(&mut self, outermost: &Union) -> Result<()> {
6338 let mut chain: Vec<&Union> = vec![outermost];
6343 let mut leftmost: &Expression = &outermost.left;
6344 while let Expression::Union(inner) = leftmost {
6345 chain.push(inner);
6346 leftmost = &inner.left;
6347 }
6348 if let Some(with) = &outermost.with {
6353 self.generate_with(with)?;
6354 self.write_space();
6355 }
6356
6357 self.generate_expression(leftmost)?;
6359
6360 for union in chain.iter().rev() {
6362 self.generate_union_step(union)?;
6363 }
6364 Ok(())
6365 }
6366
6367 fn generate_union_step(&mut self, union: &Union) -> Result<()> {
6369 if self.config.pretty {
6370 self.write_newline();
6371 self.write_indent();
6372 } else {
6373 self.write_space();
6374 }
6375
6376 if let Some(side) = &union.side {
6378 self.write_keyword(side);
6379 self.write_space();
6380 }
6381 if let Some(kind) = &union.kind {
6382 self.write_keyword(kind);
6383 self.write_space();
6384 }
6385
6386 self.write_keyword("UNION");
6387 if union.all {
6388 self.write_space();
6389 self.write_keyword("ALL");
6390 } else if union.distinct {
6391 self.write_space();
6392 self.write_keyword("DISTINCT");
6393 }
6394
6395 if union.corresponding || union.by_name {
6398 self.write_space();
6399 self.write_keyword("BY NAME");
6400 }
6401 if !union.on_columns.is_empty() {
6402 self.write_space();
6403 self.write_keyword("ON");
6404 self.write(" (");
6405 for (i, col) in union.on_columns.iter().enumerate() {
6406 if i > 0 {
6407 self.write(", ");
6408 }
6409 self.generate_expression(col)?;
6410 }
6411 self.write(")");
6412 }
6413
6414 if self.config.pretty {
6415 self.write_newline();
6416 self.write_indent();
6417 } else {
6418 self.write_space();
6419 }
6420 self.generate_expression(&union.right)?;
6421 if let Some(order_by) = &union.order_by {
6423 if self.config.pretty {
6424 self.write_newline();
6425 } else {
6426 self.write_space();
6427 }
6428 self.write_keyword("ORDER BY");
6429 self.write_space();
6430 for (i, ordered) in order_by.expressions.iter().enumerate() {
6431 if i > 0 {
6432 self.write(", ");
6433 }
6434 self.generate_ordered(ordered)?;
6435 }
6436 }
6437 if let Some(limit) = &union.limit {
6438 if self.config.pretty {
6439 self.write_newline();
6440 } else {
6441 self.write_space();
6442 }
6443 self.write_keyword("LIMIT");
6444 self.write_space();
6445 self.generate_expression(limit)?;
6446 }
6447 if let Some(offset) = &union.offset {
6448 if self.config.pretty {
6449 self.write_newline();
6450 } else {
6451 self.write_space();
6452 }
6453 self.write_keyword("OFFSET");
6454 self.write_space();
6455 self.generate_expression(offset)?;
6456 }
6457 if let Some(distribute_by) = &union.distribute_by {
6459 self.write_space();
6460 self.write_keyword("DISTRIBUTE BY");
6461 self.write_space();
6462 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6463 if i > 0 {
6464 self.write(", ");
6465 }
6466 self.generate_expression(expr)?;
6467 }
6468 }
6469 if let Some(sort_by) = &union.sort_by {
6471 self.write_space();
6472 self.write_keyword("SORT BY");
6473 self.write_space();
6474 for (i, ord) in sort_by.expressions.iter().enumerate() {
6475 if i > 0 {
6476 self.write(", ");
6477 }
6478 self.generate_ordered(ord)?;
6479 }
6480 }
6481 if let Some(cluster_by) = &union.cluster_by {
6483 self.write_space();
6484 self.write_keyword("CLUSTER BY");
6485 self.write_space();
6486 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6487 if i > 0 {
6488 self.write(", ");
6489 }
6490 self.generate_ordered(ord)?;
6491 }
6492 }
6493 Ok(())
6494 }
6495
6496 fn generate_intersect(&mut self, outermost: &Intersect) -> Result<()> {
6497 let mut chain: Vec<&Intersect> = vec![outermost];
6499 let mut leftmost: &Expression = &outermost.left;
6500 while let Expression::Intersect(inner) = leftmost {
6501 chain.push(inner);
6502 leftmost = &inner.left;
6503 }
6504
6505 if let Some(with) = &outermost.with {
6506 self.generate_with(with)?;
6507 self.write_space();
6508 }
6509
6510 self.generate_expression(leftmost)?;
6511
6512 for intersect in chain.iter().rev() {
6513 self.generate_intersect_step(intersect)?;
6514 }
6515 Ok(())
6516 }
6517
6518 fn generate_intersect_step(&mut self, intersect: &Intersect) -> Result<()> {
6520 if self.config.pretty {
6521 self.write_newline();
6522 self.write_indent();
6523 } else {
6524 self.write_space();
6525 }
6526
6527 if let Some(side) = &intersect.side {
6529 self.write_keyword(side);
6530 self.write_space();
6531 }
6532 if let Some(kind) = &intersect.kind {
6533 self.write_keyword(kind);
6534 self.write_space();
6535 }
6536
6537 self.write_keyword("INTERSECT");
6538 if intersect.all {
6539 self.write_space();
6540 self.write_keyword("ALL");
6541 } else if intersect.distinct {
6542 self.write_space();
6543 self.write_keyword("DISTINCT");
6544 }
6545
6546 if intersect.corresponding || intersect.by_name {
6549 self.write_space();
6550 self.write_keyword("BY NAME");
6551 }
6552 if !intersect.on_columns.is_empty() {
6553 self.write_space();
6554 self.write_keyword("ON");
6555 self.write(" (");
6556 for (i, col) in intersect.on_columns.iter().enumerate() {
6557 if i > 0 {
6558 self.write(", ");
6559 }
6560 self.generate_expression(col)?;
6561 }
6562 self.write(")");
6563 }
6564
6565 if self.config.pretty {
6566 self.write_newline();
6567 self.write_indent();
6568 } else {
6569 self.write_space();
6570 }
6571 self.generate_expression(&intersect.right)?;
6572 if let Some(order_by) = &intersect.order_by {
6574 if self.config.pretty {
6575 self.write_newline();
6576 } else {
6577 self.write_space();
6578 }
6579 self.write_keyword("ORDER BY");
6580 self.write_space();
6581 for (i, ordered) in order_by.expressions.iter().enumerate() {
6582 if i > 0 {
6583 self.write(", ");
6584 }
6585 self.generate_ordered(ordered)?;
6586 }
6587 }
6588 if let Some(limit) = &intersect.limit {
6589 if self.config.pretty {
6590 self.write_newline();
6591 } else {
6592 self.write_space();
6593 }
6594 self.write_keyword("LIMIT");
6595 self.write_space();
6596 self.generate_expression(limit)?;
6597 }
6598 if let Some(offset) = &intersect.offset {
6599 if self.config.pretty {
6600 self.write_newline();
6601 } else {
6602 self.write_space();
6603 }
6604 self.write_keyword("OFFSET");
6605 self.write_space();
6606 self.generate_expression(offset)?;
6607 }
6608 if let Some(distribute_by) = &intersect.distribute_by {
6610 self.write_space();
6611 self.write_keyword("DISTRIBUTE BY");
6612 self.write_space();
6613 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6614 if i > 0 {
6615 self.write(", ");
6616 }
6617 self.generate_expression(expr)?;
6618 }
6619 }
6620 if let Some(sort_by) = &intersect.sort_by {
6622 self.write_space();
6623 self.write_keyword("SORT BY");
6624 self.write_space();
6625 for (i, ord) in sort_by.expressions.iter().enumerate() {
6626 if i > 0 {
6627 self.write(", ");
6628 }
6629 self.generate_ordered(ord)?;
6630 }
6631 }
6632 if let Some(cluster_by) = &intersect.cluster_by {
6634 self.write_space();
6635 self.write_keyword("CLUSTER BY");
6636 self.write_space();
6637 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6638 if i > 0 {
6639 self.write(", ");
6640 }
6641 self.generate_ordered(ord)?;
6642 }
6643 }
6644 Ok(())
6645 }
6646
6647 fn generate_except(&mut self, outermost: &Except) -> Result<()> {
6648 let mut chain: Vec<&Except> = vec![outermost];
6650 let mut leftmost: &Expression = &outermost.left;
6651 while let Expression::Except(inner) = leftmost {
6652 chain.push(inner);
6653 leftmost = &inner.left;
6654 }
6655
6656 if let Some(with) = &outermost.with {
6657 self.generate_with(with)?;
6658 self.write_space();
6659 }
6660
6661 self.generate_expression(leftmost)?;
6662
6663 for except in chain.iter().rev() {
6664 self.generate_except_step(except)?;
6665 }
6666 Ok(())
6667 }
6668
6669 fn generate_except_step(&mut self, except: &Except) -> Result<()> {
6671 use crate::dialects::DialectType;
6672
6673 if self.config.pretty {
6674 self.write_newline();
6675 self.write_indent();
6676 } else {
6677 self.write_space();
6678 }
6679
6680 if let Some(side) = &except.side {
6682 self.write_keyword(side);
6683 self.write_space();
6684 }
6685 if let Some(kind) = &except.kind {
6686 self.write_keyword(kind);
6687 self.write_space();
6688 }
6689
6690 match self.config.dialect {
6692 Some(DialectType::Oracle) if !except.all => {
6693 self.write_keyword("MINUS");
6694 }
6695 Some(DialectType::ClickHouse) => {
6696 self.write_keyword("EXCEPT");
6698 if except.distinct {
6699 self.write_space();
6700 self.write_keyword("DISTINCT");
6701 }
6702 }
6703 Some(DialectType::BigQuery) => {
6704 self.write_keyword("EXCEPT");
6706 if except.all {
6707 self.write_space();
6708 self.write_keyword("ALL");
6709 } else {
6710 self.write_space();
6711 self.write_keyword("DISTINCT");
6712 }
6713 }
6714 _ => {
6715 self.write_keyword("EXCEPT");
6716 if except.all {
6717 self.write_space();
6718 self.write_keyword("ALL");
6719 } else if except.distinct {
6720 self.write_space();
6721 self.write_keyword("DISTINCT");
6722 }
6723 }
6724 }
6725
6726 if except.corresponding || except.by_name {
6729 self.write_space();
6730 self.write_keyword("BY NAME");
6731 }
6732 if !except.on_columns.is_empty() {
6733 self.write_space();
6734 self.write_keyword("ON");
6735 self.write(" (");
6736 for (i, col) in except.on_columns.iter().enumerate() {
6737 if i > 0 {
6738 self.write(", ");
6739 }
6740 self.generate_expression(col)?;
6741 }
6742 self.write(")");
6743 }
6744
6745 if self.config.pretty {
6746 self.write_newline();
6747 self.write_indent();
6748 } else {
6749 self.write_space();
6750 }
6751 self.generate_expression(&except.right)?;
6752 if let Some(order_by) = &except.order_by {
6754 if self.config.pretty {
6755 self.write_newline();
6756 } else {
6757 self.write_space();
6758 }
6759 self.write_keyword("ORDER BY");
6760 self.write_space();
6761 for (i, ordered) in order_by.expressions.iter().enumerate() {
6762 if i > 0 {
6763 self.write(", ");
6764 }
6765 self.generate_ordered(ordered)?;
6766 }
6767 }
6768 if let Some(limit) = &except.limit {
6769 if self.config.pretty {
6770 self.write_newline();
6771 } else {
6772 self.write_space();
6773 }
6774 self.write_keyword("LIMIT");
6775 self.write_space();
6776 self.generate_expression(limit)?;
6777 }
6778 if let Some(offset) = &except.offset {
6779 if self.config.pretty {
6780 self.write_newline();
6781 } else {
6782 self.write_space();
6783 }
6784 self.write_keyword("OFFSET");
6785 self.write_space();
6786 self.generate_expression(offset)?;
6787 }
6788 if let Some(distribute_by) = &except.distribute_by {
6790 self.write_space();
6791 self.write_keyword("DISTRIBUTE BY");
6792 self.write_space();
6793 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6794 if i > 0 {
6795 self.write(", ");
6796 }
6797 self.generate_expression(expr)?;
6798 }
6799 }
6800 if let Some(sort_by) = &except.sort_by {
6802 self.write_space();
6803 self.write_keyword("SORT BY");
6804 self.write_space();
6805 for (i, ord) in sort_by.expressions.iter().enumerate() {
6806 if i > 0 {
6807 self.write(", ");
6808 }
6809 self.generate_ordered(ord)?;
6810 }
6811 }
6812 if let Some(cluster_by) = &except.cluster_by {
6814 self.write_space();
6815 self.write_keyword("CLUSTER BY");
6816 self.write_space();
6817 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6818 if i > 0 {
6819 self.write(", ");
6820 }
6821 self.generate_ordered(ord)?;
6822 }
6823 }
6824 Ok(())
6825 }
6826
6827 fn generate_insert(&mut self, insert: &Insert) -> Result<()> {
6828 let prepend_query_cte = if insert.with.is_none() {
6830 use crate::dialects::DialectType;
6831 let should_prepend = matches!(
6832 self.config.dialect,
6833 Some(DialectType::TSQL)
6834 | Some(DialectType::Fabric)
6835 | Some(DialectType::Spark)
6836 | Some(DialectType::Databricks)
6837 | Some(DialectType::Hive)
6838 );
6839 if should_prepend {
6840 if let Some(Expression::Select(select)) = &insert.query {
6841 select.with.clone()
6842 } else {
6843 None
6844 }
6845 } else {
6846 None
6847 }
6848 } else {
6849 None
6850 };
6851
6852 if let Some(with) = &insert.with {
6854 self.generate_with(with)?;
6855 self.write_space();
6856 } else if let Some(with) = &prepend_query_cte {
6857 self.generate_with(with)?;
6858 self.write_space();
6859 }
6860
6861 for comment in &insert.leading_comments {
6863 self.write_formatted_comment(comment);
6864 self.write(" ");
6865 }
6866
6867 if let Some(dir) = &insert.directory {
6869 self.write_keyword("INSERT OVERWRITE");
6870 if dir.local {
6871 self.write_space();
6872 self.write_keyword("LOCAL");
6873 }
6874 self.write_space();
6875 self.write_keyword("DIRECTORY");
6876 self.write_space();
6877 self.write("'");
6878 self.write(&dir.path);
6879 self.write("'");
6880
6881 if let Some(row_format) = &dir.row_format {
6883 self.write_space();
6884 self.write_keyword("ROW FORMAT");
6885 if row_format.delimited {
6886 self.write_space();
6887 self.write_keyword("DELIMITED");
6888 }
6889 if let Some(val) = &row_format.fields_terminated_by {
6890 self.write_space();
6891 self.write_keyword("FIELDS TERMINATED BY");
6892 self.write_space();
6893 self.write("'");
6894 self.write(val);
6895 self.write("'");
6896 }
6897 if let Some(val) = &row_format.collection_items_terminated_by {
6898 self.write_space();
6899 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
6900 self.write_space();
6901 self.write("'");
6902 self.write(val);
6903 self.write("'");
6904 }
6905 if let Some(val) = &row_format.map_keys_terminated_by {
6906 self.write_space();
6907 self.write_keyword("MAP KEYS TERMINATED BY");
6908 self.write_space();
6909 self.write("'");
6910 self.write(val);
6911 self.write("'");
6912 }
6913 if let Some(val) = &row_format.lines_terminated_by {
6914 self.write_space();
6915 self.write_keyword("LINES TERMINATED BY");
6916 self.write_space();
6917 self.write("'");
6918 self.write(val);
6919 self.write("'");
6920 }
6921 if let Some(val) = &row_format.null_defined_as {
6922 self.write_space();
6923 self.write_keyword("NULL DEFINED AS");
6924 self.write_space();
6925 self.write("'");
6926 self.write(val);
6927 self.write("'");
6928 }
6929 }
6930
6931 if let Some(format) = &dir.stored_as {
6933 self.write_space();
6934 self.write_keyword("STORED AS");
6935 self.write_space();
6936 self.write_keyword(format);
6937 }
6938
6939 if let Some(query) = &insert.query {
6941 self.write_space();
6942 self.generate_expression(query)?;
6943 }
6944
6945 return Ok(());
6946 }
6947
6948 if insert.is_replace {
6949 self.write_keyword("REPLACE INTO");
6951 } else if insert.overwrite {
6952 self.write_keyword("INSERT");
6954 if let Some(ref hint) = insert.hint {
6956 self.generate_hint(hint)?;
6957 }
6958 self.write(&self.config.insert_overwrite.to_ascii_uppercase());
6959 } else if let Some(ref action) = insert.conflict_action {
6960 self.write_keyword("INSERT OR");
6962 self.write_space();
6963 self.write_keyword(action);
6964 self.write_space();
6965 self.write_keyword("INTO");
6966 } else if insert.ignore {
6967 self.write_keyword("INSERT IGNORE INTO");
6969 } else {
6970 self.write_keyword("INSERT");
6971 if let Some(ref hint) = insert.hint {
6973 self.generate_hint(hint)?;
6974 }
6975 self.write_space();
6976 self.write_keyword("INTO");
6977 }
6978 if let Some(ref func) = insert.function_target {
6980 self.write_space();
6981 self.write_keyword("FUNCTION");
6982 self.write_space();
6983 self.generate_expression(func)?;
6984 } else {
6985 self.write_space();
6986 self.generate_table(&insert.table)?;
6987 }
6988
6989 if let Some(ref alias) = insert.alias {
6991 self.write_space();
6992 if insert.alias_explicit_as {
6993 self.write_keyword("AS");
6994 self.write_space();
6995 }
6996 self.generate_identifier(alias)?;
6997 }
6998
6999 if insert.if_exists {
7001 self.write_space();
7002 self.write_keyword("IF EXISTS");
7003 }
7004
7005 if let Some(ref replace_where) = insert.replace_where {
7007 if self.config.pretty {
7008 self.write_newline();
7009 self.write_indent();
7010 } else {
7011 self.write_space();
7012 }
7013 self.write_keyword("REPLACE WHERE");
7014 self.write_space();
7015 self.generate_expression(replace_where)?;
7016 }
7017
7018 if !insert.partition.is_empty() {
7020 self.write_space();
7021 self.write_keyword("PARTITION");
7022 self.write("(");
7023 for (i, (col, val)) in insert.partition.iter().enumerate() {
7024 if i > 0 {
7025 self.write(", ");
7026 }
7027 self.generate_identifier(col)?;
7028 if let Some(v) = val {
7029 self.write(" = ");
7030 self.generate_expression(v)?;
7031 }
7032 }
7033 self.write(")");
7034 }
7035
7036 if let Some(ref partition_by) = insert.partition_by {
7038 self.write_space();
7039 self.write_keyword("PARTITION BY");
7040 self.write_space();
7041 self.generate_expression(partition_by)?;
7042 }
7043
7044 if !insert.settings.is_empty() {
7046 self.write_space();
7047 self.write_keyword("SETTINGS");
7048 self.write_space();
7049 for (i, setting) in insert.settings.iter().enumerate() {
7050 if i > 0 {
7051 self.write(", ");
7052 }
7053 self.generate_expression(setting)?;
7054 }
7055 }
7056
7057 if !insert.columns.is_empty() {
7058 if insert.alias.is_some() && insert.alias_explicit_as {
7059 self.write("(");
7061 } else {
7062 self.write(" (");
7064 }
7065 for (i, col) in insert.columns.iter().enumerate() {
7066 if i > 0 {
7067 self.write(", ");
7068 }
7069 self.generate_identifier(col)?;
7070 }
7071 self.write(")");
7072 }
7073
7074 if let Some(ref output) = insert.output {
7076 self.generate_output_clause(output)?;
7077 }
7078
7079 if insert.by_name {
7081 self.write_space();
7082 self.write_keyword("BY NAME");
7083 }
7084
7085 if insert.default_values {
7086 self.write_space();
7087 self.write_keyword("DEFAULT VALUES");
7088 } else if let Some(query) = &insert.query {
7089 if self.config.pretty {
7090 self.write_newline();
7091 } else {
7092 self.write_space();
7093 }
7094 if prepend_query_cte.is_some() {
7096 if let Expression::Select(select) = query {
7097 let mut select_no_with = select.clone();
7098 select_no_with.with = None;
7099 self.generate_select(&select_no_with)?;
7100 } else {
7101 self.generate_expression(query)?;
7102 }
7103 } else {
7104 self.generate_expression(query)?;
7105 }
7106 } else if !insert.values.is_empty() {
7107 if self.config.pretty {
7108 self.write_newline();
7110 self.write_keyword("VALUES");
7111 self.write_newline();
7112 self.indent_level += 1;
7113 for (i, row) in insert.values.iter().enumerate() {
7114 if i > 0 {
7115 self.write(",");
7116 self.write_newline();
7117 }
7118 self.write_indent();
7119 self.write("(");
7120 for (j, val) in row.iter().enumerate() {
7121 if j > 0 {
7122 self.write(", ");
7123 }
7124 self.generate_expression(val)?;
7125 }
7126 self.write(")");
7127 }
7128 self.indent_level -= 1;
7129 } else {
7130 self.write_space();
7132 self.write_keyword("VALUES");
7133 for (i, row) in insert.values.iter().enumerate() {
7134 if i > 0 {
7135 self.write(",");
7136 }
7137 self.write(" (");
7138 for (j, val) in row.iter().enumerate() {
7139 if j > 0 {
7140 self.write(", ");
7141 }
7142 self.generate_expression(val)?;
7143 }
7144 self.write(")");
7145 }
7146 }
7147 }
7148
7149 if let Some(ref source) = insert.source {
7151 self.write_space();
7152 self.write_keyword("TABLE");
7153 self.write_space();
7154 self.generate_expression(source)?;
7155 }
7156
7157 if let Some(alias) = &insert.source_alias {
7159 self.write_space();
7160 self.write_keyword("AS");
7161 self.write_space();
7162 self.generate_identifier(alias)?;
7163 }
7164
7165 if let Some(on_conflict) = &insert.on_conflict {
7167 if !matches!(self.config.dialect, Some(DialectType::Materialize)) {
7168 self.write_space();
7169 self.generate_expression(on_conflict)?;
7170 }
7171 }
7172
7173 if !insert.returning.is_empty() {
7175 self.write_space();
7176 self.write_keyword("RETURNING");
7177 self.write_space();
7178 for (i, expr) in insert.returning.iter().enumerate() {
7179 if i > 0 {
7180 self.write(", ");
7181 }
7182 self.generate_expression(expr)?;
7183 }
7184 }
7185
7186 Ok(())
7187 }
7188
7189 fn generate_update(&mut self, update: &Update) -> Result<()> {
7190 for comment in &update.leading_comments {
7192 self.write_formatted_comment(comment);
7193 self.write(" ");
7194 }
7195
7196 if let Some(ref with) = update.with {
7198 self.generate_with(with)?;
7199 self.write_space();
7200 }
7201
7202 self.write_keyword("UPDATE");
7203 if let Some(hint) = &update.hint {
7204 self.generate_hint(hint)?;
7205 }
7206 self.write_space();
7207 self.generate_table(&update.table)?;
7208
7209 let mysql_like_update_from = matches!(
7210 self.config.dialect,
7211 Some(DialectType::MySQL) | Some(DialectType::SingleStore)
7212 ) && update.from_clause.is_some();
7213
7214 let mut set_pairs = update.set.clone();
7215
7216 let mut pre_set_joins = update.table_joins.clone();
7218 if mysql_like_update_from {
7219 let target_name = update
7220 .table
7221 .alias
7222 .as_ref()
7223 .map(|a| a.name.clone())
7224 .unwrap_or_else(|| update.table.name.name.clone());
7225
7226 for (col, _) in &mut set_pairs {
7227 if !col.name.contains('.') {
7228 col.name = format!("{}.{}", target_name, col.name);
7229 }
7230 }
7231
7232 if let Some(from_clause) = &update.from_clause {
7233 for table_expr in &from_clause.expressions {
7234 pre_set_joins.push(crate::expressions::Join {
7235 this: table_expr.clone(),
7236 on: Some(Expression::Boolean(crate::expressions::BooleanLiteral {
7237 value: true,
7238 })),
7239 using: Vec::new(),
7240 kind: crate::expressions::JoinKind::Inner,
7241 use_inner_keyword: false,
7242 use_outer_keyword: false,
7243 deferred_condition: false,
7244 join_hint: None,
7245 match_condition: None,
7246 pivots: Vec::new(),
7247 comments: Vec::new(),
7248 nesting_group: 0,
7249 directed: false,
7250 });
7251 }
7252 }
7253 for join in &update.from_joins {
7254 let mut join = join.clone();
7255 if join.on.is_none() && join.using.is_empty() {
7256 join.on = Some(Expression::Boolean(crate::expressions::BooleanLiteral {
7257 value: true,
7258 }));
7259 }
7260 pre_set_joins.push(join);
7261 }
7262 }
7263
7264 for extra_table in &update.extra_tables {
7266 self.write(", ");
7267 self.generate_table(extra_table)?;
7268 }
7269
7270 for join in &pre_set_joins {
7272 self.generate_join(join)?;
7274 }
7275
7276 let teradata_from_before_set = matches!(self.config.dialect, Some(DialectType::Teradata));
7278 if teradata_from_before_set && !mysql_like_update_from {
7279 if let Some(ref from_clause) = update.from_clause {
7280 self.write_space();
7281 self.write_keyword("FROM");
7282 self.write_space();
7283 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
7284 if i > 0 {
7285 self.write(", ");
7286 }
7287 self.generate_expression(table_expr)?;
7288 }
7289 }
7290 for join in &update.from_joins {
7291 self.generate_join(join)?;
7292 }
7293 }
7294
7295 self.write_space();
7296 self.write_keyword("SET");
7297 self.write_space();
7298
7299 for (i, (col, val)) in set_pairs.iter().enumerate() {
7300 if i > 0 {
7301 self.write(", ");
7302 }
7303 self.generate_identifier(col)?;
7304 self.write(" = ");
7305 self.generate_expression(val)?;
7306 }
7307
7308 if let Some(ref output) = update.output {
7310 self.generate_output_clause(output)?;
7311 }
7312
7313 if !mysql_like_update_from && !teradata_from_before_set {
7315 if let Some(ref from_clause) = update.from_clause {
7316 self.write_space();
7317 self.write_keyword("FROM");
7318 self.write_space();
7319 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
7321 if i > 0 {
7322 self.write(", ");
7323 }
7324 self.generate_expression(table_expr)?;
7325 }
7326 }
7327 }
7328
7329 if !mysql_like_update_from && !teradata_from_before_set {
7330 for join in &update.from_joins {
7332 self.generate_join(join)?;
7333 }
7334 }
7335
7336 if let Some(where_clause) = &update.where_clause {
7337 self.write_space();
7338 self.write_keyword("WHERE");
7339 self.write_space();
7340 self.generate_expression(&where_clause.this)?;
7341 }
7342
7343 if !update.returning.is_empty() {
7345 self.write_space();
7346 self.write_keyword("RETURNING");
7347 self.write_space();
7348 for (i, expr) in update.returning.iter().enumerate() {
7349 if i > 0 {
7350 self.write(", ");
7351 }
7352 self.generate_expression(expr)?;
7353 }
7354 }
7355
7356 if let Some(ref order_by) = update.order_by {
7358 self.write_space();
7359 self.generate_order_by(order_by)?;
7360 }
7361
7362 if let Some(ref limit) = update.limit {
7364 self.write_space();
7365 self.write_keyword("LIMIT");
7366 self.write_space();
7367 self.generate_expression(limit)?;
7368 }
7369
7370 Ok(())
7371 }
7372
7373 fn generate_delete(&mut self, delete: &Delete) -> Result<()> {
7374 if let Some(with) = &delete.with {
7376 self.generate_with(with)?;
7377 self.write_space();
7378 }
7379
7380 for comment in &delete.leading_comments {
7382 self.write_formatted_comment(comment);
7383 self.write(" ");
7384 }
7385
7386 if !delete.tables.is_empty() && !delete.tables_from_using {
7388 self.write_keyword("DELETE");
7390 if let Some(hint) = &delete.hint {
7391 self.generate_hint(hint)?;
7392 }
7393 self.write_space();
7394 for (i, tbl) in delete.tables.iter().enumerate() {
7395 if i > 0 {
7396 self.write(", ");
7397 }
7398 self.generate_table(tbl)?;
7399 }
7400 if let Some(ref output) = delete.output {
7402 self.generate_output_clause(output)?;
7403 }
7404 self.write_space();
7405 self.write_keyword("FROM");
7406 self.write_space();
7407 self.generate_table(&delete.table)?;
7408 } else if !delete.tables.is_empty() && delete.tables_from_using {
7409 self.write_keyword("DELETE");
7411 if let Some(hint) = &delete.hint {
7412 self.generate_hint(hint)?;
7413 }
7414 self.write_space();
7415 self.write_keyword("FROM");
7416 self.write_space();
7417 for (i, tbl) in delete.tables.iter().enumerate() {
7418 if i > 0 {
7419 self.write(", ");
7420 }
7421 self.generate_table(tbl)?;
7422 }
7423 } else if delete.no_from && matches!(self.config.dialect, Some(DialectType::BigQuery)) {
7424 self.write_keyword("DELETE");
7426 if let Some(hint) = &delete.hint {
7427 self.generate_hint(hint)?;
7428 }
7429 self.write_space();
7430 self.generate_table(&delete.table)?;
7431 } else {
7432 self.write_keyword("DELETE");
7433 if let Some(hint) = &delete.hint {
7434 self.generate_hint(hint)?;
7435 }
7436 self.write_space();
7437 self.write_keyword("FROM");
7438 self.write_space();
7439 self.generate_table(&delete.table)?;
7440 }
7441
7442 if let Some(ref on_cluster) = delete.on_cluster {
7444 self.write_space();
7445 self.generate_on_cluster(on_cluster)?;
7446 }
7447
7448 if let Some(ref idx) = delete.force_index {
7450 self.write_space();
7451 self.write_keyword("FORCE INDEX");
7452 self.write(" (");
7453 self.write(idx);
7454 self.write(")");
7455 }
7456
7457 if let Some(ref alias) = delete.alias {
7459 self.write_space();
7460 if delete.alias_explicit_as
7461 || matches!(self.config.dialect, Some(DialectType::BigQuery))
7462 {
7463 self.write_keyword("AS");
7464 self.write_space();
7465 }
7466 self.generate_identifier(alias)?;
7467 }
7468
7469 if !delete.tables_from_using {
7471 for join in &delete.joins {
7472 self.generate_join(join)?;
7473 }
7474 }
7475
7476 if !delete.using.is_empty() {
7478 self.write_space();
7479 self.write_keyword("USING");
7480 for (i, table) in delete.using.iter().enumerate() {
7481 if i > 0 {
7482 self.write(",");
7483 }
7484 self.write_space();
7485 if !table.hints.is_empty() && table.name.is_empty() {
7487 self.generate_expression(&table.hints[0])?;
7489 if let Some(ref alias) = table.alias {
7490 self.write_space();
7491 if table.alias_explicit_as {
7492 self.write_keyword("AS");
7493 self.write_space();
7494 }
7495 self.generate_identifier(alias)?;
7496 if !table.column_aliases.is_empty() {
7497 self.write("(");
7498 for (j, col_alias) in table.column_aliases.iter().enumerate() {
7499 if j > 0 {
7500 self.write(", ");
7501 }
7502 self.generate_identifier(col_alias)?;
7503 }
7504 self.write(")");
7505 }
7506 }
7507 } else {
7508 self.generate_table(table)?;
7509 }
7510 }
7511 }
7512
7513 if delete.tables_from_using {
7515 for join in &delete.joins {
7516 self.generate_join(join)?;
7517 }
7518 }
7519
7520 let output_already_emitted =
7522 !delete.tables.is_empty() && !delete.tables_from_using && delete.output.is_some();
7523 if !output_already_emitted {
7524 if let Some(ref output) = delete.output {
7525 self.generate_output_clause(output)?;
7526 }
7527 }
7528
7529 if let Some(where_clause) = &delete.where_clause {
7530 self.write_space();
7531 self.write_keyword("WHERE");
7532 self.write_space();
7533 self.generate_expression(&where_clause.this)?;
7534 }
7535
7536 if let Some(ref order_by) = delete.order_by {
7538 self.write_space();
7539 self.generate_order_by(order_by)?;
7540 }
7541
7542 if let Some(ref limit) = delete.limit {
7544 self.write_space();
7545 self.write_keyword("LIMIT");
7546 self.write_space();
7547 self.generate_expression(limit)?;
7548 }
7549
7550 if !delete.returning.is_empty() {
7552 self.write_space();
7553 self.write_keyword("RETURNING");
7554 self.write_space();
7555 for (i, expr) in delete.returning.iter().enumerate() {
7556 if i > 0 {
7557 self.write(", ");
7558 }
7559 self.generate_expression(expr)?;
7560 }
7561 }
7562
7563 Ok(())
7564 }
7565
7566 fn generate_create_table(&mut self, ct: &CreateTable) -> Result<()> {
7569 let saved_athena_hive_context = self.athena_hive_context;
7573 let is_clickhouse = matches!(self.config.dialect, Some(DialectType::ClickHouse));
7574 if matches!(
7575 self.config.dialect,
7576 Some(crate::dialects::DialectType::Athena)
7577 ) {
7578 let is_external = ct
7582 .table_modifier
7583 .as_ref()
7584 .map(|m| m.eq_ignore_ascii_case("EXTERNAL"))
7585 .unwrap_or(false);
7586 let has_as_select = ct.as_select.is_some();
7587 self.athena_hive_context = is_external || !has_as_select;
7588 }
7589
7590 if matches!(
7592 self.config.dialect,
7593 Some(crate::dialects::DialectType::TSQL)
7594 ) {
7595 if let Some(ref query) = ct.as_select {
7596 if let Some(with_cte) = &ct.with_cte {
7598 self.generate_with(with_cte)?;
7599 self.write_space();
7600 }
7601
7602 self.write_keyword("SELECT");
7604 self.write(" * ");
7605 self.write_keyword("INTO");
7606 self.write_space();
7607
7608 if ct.temporary {
7610 self.write("#");
7611 }
7612 self.generate_table(&ct.name)?;
7613
7614 self.write_space();
7615 self.write_keyword("FROM");
7616 self.write(" (");
7617 let aliased_query = Self::add_column_aliases_to_query(query.clone());
7619 self.generate_expression(&aliased_query)?;
7620 self.write(") ");
7621 self.write_keyword("AS");
7622 self.write(" temp");
7623 return Ok(());
7624 }
7625 }
7626
7627 if let Some(with_cte) = &ct.with_cte {
7629 self.generate_with(with_cte)?;
7630 self.write_space();
7631 }
7632
7633 for comment in &ct.leading_comments {
7635 self.write_formatted_comment(comment);
7636 self.write(" ");
7637 }
7638 self.write_keyword("CREATE");
7639
7640 if ct.or_replace {
7641 self.write_space();
7642 self.write_keyword("OR REPLACE");
7643 }
7644
7645 if ct.temporary {
7646 self.write_space();
7647 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
7649 self.write_keyword("GLOBAL TEMPORARY");
7650 } else {
7651 self.write_keyword("TEMPORARY");
7652 }
7653 }
7654
7655 let is_dictionary = ct
7657 .table_modifier
7658 .as_ref()
7659 .map(|m| m.eq_ignore_ascii_case("DICTIONARY"))
7660 .unwrap_or(false);
7661 if let Some(ref modifier) = ct.table_modifier {
7662 let skip_transient = modifier.eq_ignore_ascii_case("TRANSIENT")
7664 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None);
7665 let is_teradata_modifier = modifier.eq_ignore_ascii_case("VOLATILE")
7667 || modifier.eq_ignore_ascii_case("SET")
7668 || modifier.eq_ignore_ascii_case("MULTISET")
7669 || modifier.to_ascii_uppercase().contains("VOLATILE")
7670 || modifier.to_ascii_uppercase().starts_with("SET ")
7671 || modifier.to_ascii_uppercase().starts_with("MULTISET ");
7672 let skip_teradata =
7673 is_teradata_modifier && !matches!(self.config.dialect, Some(DialectType::Teradata));
7674 if !skip_transient && !skip_teradata {
7675 self.write_space();
7676 self.write_keyword(modifier);
7677 }
7678 }
7679
7680 if !is_dictionary {
7681 self.write_space();
7682 self.write_keyword("TABLE");
7683 }
7684
7685 if ct.if_not_exists {
7686 self.write_space();
7687 self.write_keyword("IF NOT EXISTS");
7688 }
7689
7690 self.write_space();
7691 self.generate_table(&ct.name)?;
7692
7693 if let Some(ref uuid) = ct.uuid {
7695 self.write_space();
7696 self.write_keyword("UUID");
7697 self.write(" '");
7698 self.write(uuid);
7699 self.write("'");
7700 }
7701
7702 if let Some(ref on_cluster) = ct.on_cluster {
7704 self.write_space();
7705 self.generate_on_cluster(on_cluster)?;
7706 }
7707
7708 if matches!(
7710 self.config.dialect,
7711 Some(crate::dialects::DialectType::Teradata)
7712 ) && !ct.teradata_post_name_options.is_empty()
7713 {
7714 for opt in &ct.teradata_post_name_options {
7715 self.write(", ");
7716 self.write(opt);
7717 }
7718 }
7719
7720 if ct.copy_grants {
7722 self.write_space();
7723 self.write_keyword("COPY GRANTS");
7724 }
7725
7726 if let Some(ref using_template) = ct.using_template {
7728 self.write_space();
7729 self.write_keyword("USING TEMPLATE");
7730 self.write_space();
7731 self.generate_expression(using_template)?;
7732 return Ok(());
7733 }
7734
7735 if let Some(ref clone_source) = ct.clone_source {
7737 self.write_space();
7738 if ct.is_copy && self.config.supports_table_copy {
7739 self.write_keyword("COPY");
7741 } else if ct.shallow_clone {
7742 self.write_keyword("SHALLOW CLONE");
7743 } else if ct.deep_clone {
7744 self.write_keyword("DEEP CLONE");
7745 } else {
7746 self.write_keyword("CLONE");
7747 }
7748 self.write_space();
7749 self.generate_table(clone_source)?;
7750 if let Some(ref at_clause) = ct.clone_at_clause {
7752 self.write_space();
7753 self.generate_expression(at_clause)?;
7754 }
7755 return Ok(());
7756 }
7757
7758 if let Some(ref partition_of) = ct.partition_of {
7762 self.write_space();
7763
7764 if let Expression::PartitionedOfProperty(ref pop) = partition_of {
7766 self.write_keyword("PARTITION OF");
7768 self.write_space();
7769 self.generate_expression(&pop.this)?;
7770
7771 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
7773 self.write(" (");
7774 let mut first = true;
7775 for col in &ct.columns {
7776 if !first {
7777 self.write(", ");
7778 }
7779 first = false;
7780 self.generate_column_def(col)?;
7781 }
7782 for constraint in &ct.constraints {
7783 if !first {
7784 self.write(", ");
7785 }
7786 first = false;
7787 self.generate_table_constraint(constraint)?;
7788 }
7789 self.write(")");
7790 }
7791
7792 if let Expression::PartitionBoundSpec(_) = pop.expression.as_ref() {
7794 self.write_space();
7795 self.write_keyword("FOR VALUES");
7796 self.write_space();
7797 self.generate_expression(&pop.expression)?;
7798 } else {
7799 self.write_space();
7800 self.write_keyword("DEFAULT");
7801 }
7802 } else {
7803 self.generate_expression(partition_of)?;
7805
7806 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
7808 self.write(" (");
7809 let mut first = true;
7810 for col in &ct.columns {
7811 if !first {
7812 self.write(", ");
7813 }
7814 first = false;
7815 self.generate_column_def(col)?;
7816 }
7817 for constraint in &ct.constraints {
7818 if !first {
7819 self.write(", ");
7820 }
7821 first = false;
7822 self.generate_table_constraint(constraint)?;
7823 }
7824 self.write(")");
7825 }
7826 }
7827
7828 for prop in &ct.properties {
7830 self.write_space();
7831 self.generate_expression(prop)?;
7832 }
7833
7834 return Ok(());
7835 }
7836
7837 self.sqlite_inline_pk_columns.clear();
7840 if matches!(
7841 self.config.dialect,
7842 Some(crate::dialects::DialectType::SQLite)
7843 ) {
7844 for constraint in &ct.constraints {
7845 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7846 if columns.len() == 1 && name.is_none() {
7848 let pk_col_name = columns[0].name.to_ascii_lowercase();
7849 if ct
7851 .columns
7852 .iter()
7853 .any(|c| c.name.name.to_ascii_lowercase() == pk_col_name)
7854 {
7855 self.sqlite_inline_pk_columns.insert(pk_col_name);
7856 }
7857 }
7858 }
7859 }
7860 }
7861
7862 if !ct.columns.is_empty() {
7864 if self.config.pretty {
7865 self.write(" (");
7867 self.write_newline();
7868 self.indent_level += 1;
7869 for (i, col) in ct.columns.iter().enumerate() {
7870 if i > 0 {
7871 self.write(",");
7872 self.write_newline();
7873 }
7874 self.write_indent();
7875 self.generate_column_def(col)?;
7876 }
7877 for constraint in &ct.constraints {
7879 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7881 if columns.len() == 1
7882 && name.is_none()
7883 && self
7884 .sqlite_inline_pk_columns
7885 .contains(&columns[0].name.to_ascii_lowercase())
7886 {
7887 continue;
7888 }
7889 }
7890 self.write(",");
7891 self.write_newline();
7892 self.write_indent();
7893 self.generate_table_constraint(constraint)?;
7894 }
7895 self.indent_level -= 1;
7896 self.write_newline();
7897 self.write(")");
7898 } else {
7899 self.write(" (");
7900 for (i, col) in ct.columns.iter().enumerate() {
7901 if i > 0 {
7902 self.write(", ");
7903 }
7904 self.generate_column_def(col)?;
7905 }
7906 let mut first_constraint = true;
7908 for constraint in &ct.constraints {
7909 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7911 if columns.len() == 1
7912 && name.is_none()
7913 && self
7914 .sqlite_inline_pk_columns
7915 .contains(&columns[0].name.to_ascii_lowercase())
7916 {
7917 continue;
7918 }
7919 }
7920 if first_constraint {
7921 self.write(", ");
7922 first_constraint = false;
7923 } else {
7924 self.write(", ");
7925 }
7926 self.generate_table_constraint(constraint)?;
7927 }
7928 self.write(")");
7929 }
7930 } else if !ct.constraints.is_empty() {
7931 let has_like_only = ct
7933 .constraints
7934 .iter()
7935 .all(|c| matches!(c, TableConstraint::Like { .. }));
7936 let has_tags_only = ct
7937 .constraints
7938 .iter()
7939 .all(|c| matches!(c, TableConstraint::Tags(_)));
7940 let is_pg_like = matches!(
7944 self.config.dialect,
7945 Some(crate::dialects::DialectType::PostgreSQL)
7946 | Some(crate::dialects::DialectType::CockroachDB)
7947 | Some(crate::dialects::DialectType::Materialize)
7948 | Some(crate::dialects::DialectType::RisingWave)
7949 | Some(crate::dialects::DialectType::Redshift)
7950 | Some(crate::dialects::DialectType::Presto)
7951 | Some(crate::dialects::DialectType::Trino)
7952 | Some(crate::dialects::DialectType::Athena)
7953 );
7954 let use_parens = if has_like_only {
7955 is_pg_like
7956 } else {
7957 !has_tags_only
7958 };
7959 if self.config.pretty && use_parens {
7960 self.write(" (");
7961 self.write_newline();
7962 self.indent_level += 1;
7963 for (i, constraint) in ct.constraints.iter().enumerate() {
7964 if i > 0 {
7965 self.write(",");
7966 self.write_newline();
7967 }
7968 self.write_indent();
7969 self.generate_table_constraint(constraint)?;
7970 }
7971 self.indent_level -= 1;
7972 self.write_newline();
7973 self.write(")");
7974 } else {
7975 if use_parens {
7976 self.write(" (");
7977 } else {
7978 self.write_space();
7979 }
7980 for (i, constraint) in ct.constraints.iter().enumerate() {
7981 if i > 0 {
7982 self.write(", ");
7983 }
7984 self.generate_table_constraint(constraint)?;
7985 }
7986 if use_parens {
7987 self.write(")");
7988 }
7989 }
7990 }
7991
7992 if let Some(ref on_prop) = ct.on_property {
7994 self.write(" ");
7995 self.write_keyword("ON");
7996 self.write(" ");
7997 self.generate_expression(&on_prop.this)?;
7998 }
7999
8000 if !ct.with_partition_columns.is_empty() {
8002 if self.config.pretty {
8003 self.write_newline();
8004 } else {
8005 self.write_space();
8006 }
8007 self.write_keyword("WITH PARTITION COLUMNS");
8008 self.write(" (");
8009 if self.config.pretty {
8010 self.write_newline();
8011 self.indent_level += 1;
8012 for (i, col) in ct.with_partition_columns.iter().enumerate() {
8013 if i > 0 {
8014 self.write(",");
8015 self.write_newline();
8016 }
8017 self.write_indent();
8018 self.generate_column_def(col)?;
8019 }
8020 self.indent_level -= 1;
8021 self.write_newline();
8022 } else {
8023 for (i, col) in ct.with_partition_columns.iter().enumerate() {
8024 if i > 0 {
8025 self.write(", ");
8026 }
8027 self.generate_column_def(col)?;
8028 }
8029 }
8030 self.write(")");
8031 }
8032
8033 if let Some(ref conn) = ct.with_connection {
8035 if self.config.pretty {
8036 self.write_newline();
8037 } else {
8038 self.write_space();
8039 }
8040 self.write_keyword("WITH CONNECTION");
8041 self.write_space();
8042 self.generate_table(conn)?;
8043 }
8044
8045 if !is_clickhouse {
8048 for prop in &ct.properties {
8049 if let Expression::SchemaCommentProperty(_) = prop {
8050 if self.config.pretty {
8051 self.write_newline();
8052 } else {
8053 self.write_space();
8054 }
8055 self.generate_expression(prop)?;
8056 }
8057 }
8058 }
8059
8060 if !ct.with_properties.is_empty() {
8062 let is_snowflake_special_table = matches!(
8064 self.config.dialect,
8065 Some(crate::dialects::DialectType::Snowflake)
8066 ) && (ct.table_modifier.as_deref() == Some("ICEBERG")
8067 || ct.table_modifier.as_deref() == Some("DYNAMIC"));
8068 if is_snowflake_special_table {
8069 for (key, value) in &ct.with_properties {
8070 self.write_space();
8071 self.write(key);
8072 self.write("=");
8073 self.write(value);
8074 }
8075 } else if self.config.pretty {
8076 self.write_newline();
8077 self.write_keyword("WITH");
8078 self.write(" (");
8079 self.write_newline();
8080 self.indent_level += 1;
8081 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
8082 if i > 0 {
8083 self.write(",");
8084 self.write_newline();
8085 }
8086 self.write_indent();
8087 self.write(key);
8088 self.write("=");
8089 self.write(value);
8090 }
8091 self.indent_level -= 1;
8092 self.write_newline();
8093 self.write(")");
8094 } else {
8095 self.write_space();
8096 self.write_keyword("WITH");
8097 self.write(" (");
8098 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
8099 if i > 0 {
8100 self.write(", ");
8101 }
8102 self.write(key);
8103 self.write("=");
8104 self.write(value);
8105 }
8106 self.write(")");
8107 }
8108 }
8109
8110 let (pre_as_properties, post_as_properties): (Vec<&Expression>, Vec<&Expression>) =
8111 if is_clickhouse && ct.as_select.is_some() {
8112 let mut pre = Vec::new();
8113 let mut post = Vec::new();
8114 for prop in &ct.properties {
8115 if matches!(prop, Expression::SchemaCommentProperty(_)) {
8116 post.push(prop);
8117 } else {
8118 pre.push(prop);
8119 }
8120 }
8121 (pre, post)
8122 } else {
8123 (ct.properties.iter().collect(), Vec::new())
8124 };
8125
8126 for prop in pre_as_properties {
8128 if !is_clickhouse && matches!(prop, Expression::SchemaCommentProperty(_)) {
8130 continue;
8131 }
8132 if self.config.pretty {
8133 self.write_newline();
8134 } else {
8135 self.write_space();
8136 }
8137 if let Expression::Properties(props) = prop {
8141 let is_hive_dialect = matches!(
8142 self.config.dialect,
8143 Some(crate::dialects::DialectType::Hive)
8144 | Some(crate::dialects::DialectType::Spark)
8145 | Some(crate::dialects::DialectType::Databricks)
8146 | Some(crate::dialects::DialectType::Athena)
8147 );
8148 let is_doris_starrocks = matches!(
8149 self.config.dialect,
8150 Some(crate::dialects::DialectType::Doris)
8151 | Some(crate::dialects::DialectType::StarRocks)
8152 );
8153 if is_hive_dialect {
8154 self.generate_tblproperties_clause(&props.expressions)?;
8155 } else if is_doris_starrocks {
8156 self.generate_properties_clause(&props.expressions)?;
8157 } else {
8158 self.generate_options_clause(&props.expressions)?;
8159 }
8160 } else {
8161 self.generate_expression(prop)?;
8162 }
8163 }
8164
8165 for prop in &ct.post_table_properties {
8167 if let Expression::WithSystemVersioningProperty(ref svp) = prop {
8168 self.write(" WITH(");
8169 self.generate_system_versioning_content(svp)?;
8170 self.write(")");
8171 } else if let Expression::Properties(props) = prop {
8172 let is_doris_starrocks = matches!(
8174 self.config.dialect,
8175 Some(crate::dialects::DialectType::Doris)
8176 | Some(crate::dialects::DialectType::StarRocks)
8177 );
8178 self.write_space();
8179 if is_doris_starrocks {
8180 self.generate_properties_clause(&props.expressions)?;
8181 } else {
8182 self.generate_options_clause(&props.expressions)?;
8183 }
8184 } else {
8185 self.write_space();
8186 self.generate_expression(prop)?;
8187 }
8188 }
8189
8190 if let Some(ref rollup) = ct.rollup {
8193 if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
8194 self.write_space();
8195 self.generate_rollup_property(rollup)?;
8196 }
8197 }
8198
8199 let is_mysql_compatible = matches!(
8203 self.config.dialect,
8204 Some(DialectType::MySQL)
8205 | Some(DialectType::SingleStore)
8206 | Some(DialectType::Doris)
8207 | Some(DialectType::StarRocks)
8208 | None
8209 );
8210 let is_hive_compatible = matches!(
8211 self.config.dialect,
8212 Some(DialectType::Hive)
8213 | Some(DialectType::Spark)
8214 | Some(DialectType::Databricks)
8215 | Some(DialectType::Athena)
8216 );
8217 let mysql_pretty_options =
8218 self.config.pretty && matches!(self.config.dialect, Some(DialectType::MySQL));
8219 for (key, value) in &ct.mysql_table_options {
8220 let should_output = if is_mysql_compatible {
8222 true
8223 } else if is_hive_compatible && key == "COMMENT" {
8224 true } else {
8226 false
8227 };
8228 if should_output {
8229 if mysql_pretty_options {
8230 self.write_newline();
8231 self.write_indent();
8232 } else {
8233 self.write_space();
8234 }
8235 self.write_keyword(key);
8236 if key == "COMMENT" && !self.config.schema_comment_with_eq {
8238 self.write_space();
8239 } else {
8240 self.write("=");
8241 }
8242 self.write(value);
8243 }
8244 }
8245
8246 if ct.temporary
8248 && matches!(
8249 self.config.dialect,
8250 Some(DialectType::Spark) | Some(DialectType::Databricks)
8251 )
8252 && ct.as_select.is_none()
8253 {
8254 self.write_space();
8255 self.write_keyword("USING PARQUET");
8256 }
8257
8258 if !ct.inherits.is_empty() {
8260 self.write_space();
8261 self.write_keyword("INHERITS");
8262 self.write(" (");
8263 for (i, parent) in ct.inherits.iter().enumerate() {
8264 if i > 0 {
8265 self.write(", ");
8266 }
8267 self.generate_table(parent)?;
8268 }
8269 self.write(")");
8270 }
8271
8272 if let Some(ref query) = ct.as_select {
8274 self.write_space();
8275 self.write_keyword("AS");
8276 self.write_space();
8277 if ct.as_select_parenthesized {
8278 self.write("(");
8279 }
8280 self.generate_expression(query)?;
8281 if ct.as_select_parenthesized {
8282 self.write(")");
8283 }
8284
8285 if let Some(with_data) = ct.with_data {
8287 self.write_space();
8288 self.write_keyword("WITH");
8289 if !with_data {
8290 self.write_space();
8291 self.write_keyword("NO");
8292 }
8293 self.write_space();
8294 self.write_keyword("DATA");
8295 }
8296
8297 if let Some(with_statistics) = ct.with_statistics {
8299 self.write_space();
8300 self.write_keyword("AND");
8301 if !with_statistics {
8302 self.write_space();
8303 self.write_keyword("NO");
8304 }
8305 self.write_space();
8306 self.write_keyword("STATISTICS");
8307 }
8308
8309 for index in &ct.teradata_indexes {
8311 self.write_space();
8312 match index.kind {
8313 TeradataIndexKind::NoPrimary => {
8314 self.write_keyword("NO PRIMARY INDEX");
8315 }
8316 TeradataIndexKind::Primary => {
8317 self.write_keyword("PRIMARY INDEX");
8318 }
8319 TeradataIndexKind::PrimaryAmp => {
8320 self.write_keyword("PRIMARY AMP INDEX");
8321 }
8322 TeradataIndexKind::Unique => {
8323 self.write_keyword("UNIQUE INDEX");
8324 }
8325 TeradataIndexKind::UniquePrimary => {
8326 self.write_keyword("UNIQUE PRIMARY INDEX");
8327 }
8328 TeradataIndexKind::Secondary => {
8329 self.write_keyword("INDEX");
8330 }
8331 }
8332 if let Some(ref name) = index.name {
8334 self.write_space();
8335 self.write(name);
8336 }
8337 if !index.columns.is_empty() {
8339 self.write(" (");
8340 for (i, col) in index.columns.iter().enumerate() {
8341 if i > 0 {
8342 self.write(", ");
8343 }
8344 self.write(col);
8345 }
8346 self.write(")");
8347 }
8348 }
8349
8350 if let Some(ref on_commit) = ct.on_commit {
8352 self.write_space();
8353 self.write_keyword("ON COMMIT");
8354 self.write_space();
8355 match on_commit {
8356 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
8357 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
8358 }
8359 }
8360
8361 if !post_as_properties.is_empty() {
8362 for prop in post_as_properties {
8363 self.write_space();
8364 self.generate_expression(prop)?;
8365 }
8366 }
8367
8368 self.athena_hive_context = saved_athena_hive_context;
8370 return Ok(());
8371 }
8372
8373 if let Some(ref on_commit) = ct.on_commit {
8375 self.write_space();
8376 self.write_keyword("ON COMMIT");
8377 self.write_space();
8378 match on_commit {
8379 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
8380 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
8381 }
8382 }
8383
8384 self.athena_hive_context = saved_athena_hive_context;
8386
8387 Ok(())
8388 }
8389
8390 fn generate_column_def_expr(&mut self, col: &ColumnDef) -> Result<()> {
8393 self.generate_identifier(&col.name)?;
8395 if !matches!(col.data_type, DataType::Unknown) {
8397 self.write_space();
8398 self.generate_data_type(&col.data_type)?;
8399 }
8400 for constraint in &col.constraints {
8402 if let ColumnConstraint::Path(path_expr) = constraint {
8403 self.write_space();
8404 self.write_keyword("PATH");
8405 self.write_space();
8406 self.generate_expression(path_expr)?;
8407 }
8408 }
8409 Ok(())
8410 }
8411
8412 fn generate_column_def(&mut self, col: &ColumnDef) -> Result<()> {
8413 let has_computed_no_type = matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
8415 && col
8416 .constraints
8417 .iter()
8418 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
8419 let omit_computed_type = !self.config.computed_column_with_type
8421 && col
8422 .constraints
8423 .iter()
8424 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
8425
8426 let is_partition_column_spec = matches!(col.data_type, DataType::Unknown);
8429
8430 let has_no_type = col.no_type
8433 || (matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
8434 && col.constraints.is_empty());
8435
8436 self.generate_identifier(&col.name)?;
8437
8438 let serial_expansion = if matches!(
8440 self.config.dialect,
8441 Some(DialectType::Materialize) | Some(DialectType::PostgreSQL)
8442 ) {
8443 if let DataType::Custom { ref name } = col.data_type {
8444 if name.eq_ignore_ascii_case("SERIAL") {
8445 Some("INT")
8446 } else if name.eq_ignore_ascii_case("BIGSERIAL") {
8447 Some("BIGINT")
8448 } else if name.eq_ignore_ascii_case("SMALLSERIAL") {
8449 Some("SMALLINT")
8450 } else {
8451 None
8452 }
8453 } else {
8454 None
8455 }
8456 } else {
8457 None
8458 };
8459
8460 if !has_computed_no_type && !omit_computed_type && !is_partition_column_spec && !has_no_type
8461 {
8462 self.write_space();
8463 let saved_nullable_depth = self.clickhouse_nullable_depth;
8466 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
8467 self.clickhouse_nullable_depth = -1;
8468 }
8469 if let Some(int_type) = serial_expansion {
8470 self.write_keyword(int_type);
8472 } else if col.unsigned && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
8473 let unsigned_type = match &col.data_type {
8475 DataType::Int { .. } => Some("UINTEGER"),
8476 DataType::BigInt { .. } => Some("UBIGINT"),
8477 DataType::SmallInt { .. } => Some("USMALLINT"),
8478 DataType::TinyInt { .. } => Some("UTINYINT"),
8479 _ => None,
8480 };
8481 if let Some(utype) = unsigned_type {
8482 self.write_keyword(utype);
8483 } else {
8484 self.generate_data_type(&col.data_type)?;
8485 }
8486 } else {
8487 self.generate_data_type(&col.data_type)?;
8488 }
8489 self.clickhouse_nullable_depth = saved_nullable_depth;
8490 }
8491
8492 if col.unsigned && !matches!(self.config.dialect, Some(DialectType::DuckDB)) {
8495 self.write_space();
8496 self.write_keyword("UNSIGNED");
8497 }
8498 if col.zerofill {
8499 self.write_space();
8500 self.write_keyword("ZEROFILL");
8501 }
8502
8503 if let Some(ref charset) = col.character_set {
8507 self.write_space();
8508 self.write_keyword("CHARACTER SET");
8509 self.write_space();
8510 self.write(charset);
8511 }
8512
8513 if col.uppercase {
8514 self.write_space();
8515 self.write_keyword("UPPERCASE");
8516 }
8517
8518 if let Some(casespecific) = col.casespecific {
8519 self.write_space();
8520 if casespecific {
8521 self.write_keyword("CASESPECIFIC");
8522 } else {
8523 self.write_keyword("NOT CASESPECIFIC");
8524 }
8525 }
8526
8527 if let Some(ref format) = col.format {
8528 self.write_space();
8529 self.write_keyword("FORMAT");
8530 self.write(" '");
8531 self.write(format);
8532 self.write("'");
8533 }
8534
8535 if let Some(ref title) = col.title {
8536 self.write_space();
8537 self.write_keyword("TITLE");
8538 self.write(" '");
8539 self.write(title);
8540 self.write("'");
8541 }
8542
8543 if let Some(length) = col.inline_length {
8544 self.write_space();
8545 self.write_keyword("INLINE LENGTH");
8546 self.write(" ");
8547 self.write(&length.to_string());
8548 }
8549
8550 if let Some(ref compress) = col.compress {
8551 self.write_space();
8552 self.write_keyword("COMPRESS");
8553 if !compress.is_empty() {
8554 if compress.len() == 1 {
8556 if let Expression::Literal(lit) = &compress[0] {
8557 if let Literal::String(_) = lit.as_ref() {
8558 self.write_space();
8559 self.generate_expression(&compress[0])?;
8560 }
8561 } else {
8562 self.write(" (");
8563 self.generate_expression(&compress[0])?;
8564 self.write(")");
8565 }
8566 } else {
8567 self.write(" (");
8568 for (i, val) in compress.iter().enumerate() {
8569 if i > 0 {
8570 self.write(", ");
8571 }
8572 self.generate_expression(val)?;
8573 }
8574 self.write(")");
8575 }
8576 }
8577 }
8578
8579 if !col.constraint_order.is_empty() {
8582 let mut references_idx = 0;
8585 let mut check_idx = 0;
8586 let mut generated_idx = 0;
8587 let mut collate_idx = 0;
8588 let mut comment_idx = 0;
8589 let defer_not_null_after_identity = false;
8592 let mut pending_not_null_after_identity = false;
8593
8594 for constraint_type in &col.constraint_order {
8595 match constraint_type {
8596 ConstraintType::PrimaryKey => {
8597 if col.primary_key
8599 && !matches!(self.config.dialect, Some(DialectType::Materialize))
8600 {
8601 if let Some(ref cname) = col.primary_key_constraint_name {
8602 self.write_space();
8603 self.write_keyword("CONSTRAINT");
8604 self.write_space();
8605 self.write(cname);
8606 }
8607 self.write_space();
8608 self.write_keyword("PRIMARY KEY");
8609 if let Some(ref order) = col.primary_key_order {
8610 self.write_space();
8611 match order {
8612 SortOrder::Asc => self.write_keyword("ASC"),
8613 SortOrder::Desc => self.write_keyword("DESC"),
8614 }
8615 }
8616 }
8617 }
8618 ConstraintType::Unique => {
8619 if col.unique {
8620 if let Some(ref cname) = col.unique_constraint_name {
8621 self.write_space();
8622 self.write_keyword("CONSTRAINT");
8623 self.write_space();
8624 self.write(cname);
8625 }
8626 self.write_space();
8627 self.write_keyword("UNIQUE");
8628 if col.unique_nulls_not_distinct {
8630 self.write(" NULLS NOT DISTINCT");
8631 }
8632 }
8633 }
8634 ConstraintType::NotNull => {
8635 if col.nullable == Some(false) {
8636 if defer_not_null_after_identity {
8637 pending_not_null_after_identity = true;
8638 continue;
8639 }
8640 if let Some(ref cname) = col.not_null_constraint_name {
8641 self.write_space();
8642 self.write_keyword("CONSTRAINT");
8643 self.write_space();
8644 self.write(cname);
8645 }
8646 self.write_space();
8647 self.write_keyword("NOT NULL");
8648 }
8649 }
8650 ConstraintType::Null => {
8651 if col.nullable == Some(true) {
8652 self.write_space();
8653 self.write_keyword("NULL");
8654 }
8655 }
8656 ConstraintType::Default => {
8657 if let Some(ref default) = col.default {
8658 self.write_space();
8659 self.write_keyword("DEFAULT");
8660 self.write_space();
8661 self.generate_expression(default)?;
8662 }
8663 }
8664 ConstraintType::AutoIncrement => {
8665 if col.auto_increment {
8666 if matches!(
8668 self.config.dialect,
8669 Some(crate::dialects::DialectType::DuckDB)
8670 ) {
8671 } else if matches!(
8673 self.config.dialect,
8674 Some(crate::dialects::DialectType::Materialize)
8675 ) {
8676 if !matches!(col.nullable, Some(false)) {
8678 self.write_space();
8679 self.write_keyword("NOT NULL");
8680 }
8681 } else if matches!(
8682 self.config.dialect,
8683 Some(crate::dialects::DialectType::PostgreSQL)
8684 ) {
8685 self.write_space();
8687 self.generate_auto_increment_keyword(col)?;
8688 } else {
8689 self.write_space();
8690 self.generate_auto_increment_keyword(col)?;
8691 if pending_not_null_after_identity {
8692 self.write_space();
8693 self.write_keyword("NOT NULL");
8694 pending_not_null_after_identity = false;
8695 }
8696 }
8697 } }
8699 ConstraintType::References => {
8700 while references_idx < col.constraints.len() {
8702 if let ColumnConstraint::References(fk_ref) =
8703 &col.constraints[references_idx]
8704 {
8705 if let Some(ref name) = fk_ref.constraint_name {
8707 self.write_space();
8708 self.write_keyword("CONSTRAINT");
8709 self.write_space();
8710 self.write(name);
8711 }
8712 self.write_space();
8713 if fk_ref.has_foreign_key_keywords {
8714 self.write_keyword("FOREIGN KEY");
8715 self.write_space();
8716 }
8717 self.write_keyword("REFERENCES");
8718 self.write_space();
8719 self.generate_table(&fk_ref.table)?;
8720 if !fk_ref.columns.is_empty() {
8721 self.write(" (");
8722 for (i, c) in fk_ref.columns.iter().enumerate() {
8723 if i > 0 {
8724 self.write(", ");
8725 }
8726 self.generate_identifier(c)?;
8727 }
8728 self.write(")");
8729 }
8730 self.generate_referential_actions(fk_ref)?;
8731 references_idx += 1;
8732 break;
8733 }
8734 references_idx += 1;
8735 }
8736 }
8737 ConstraintType::Check => {
8738 while check_idx < col.constraints.len() {
8740 if let ColumnConstraint::Check(expr) = &col.constraints[check_idx] {
8741 if check_idx == 0 {
8743 if let Some(ref cname) = col.check_constraint_name {
8744 self.write_space();
8745 self.write_keyword("CONSTRAINT");
8746 self.write_space();
8747 self.write(cname);
8748 }
8749 }
8750 self.write_space();
8751 self.write_keyword("CHECK");
8752 self.write(" (");
8753 self.generate_expression(expr)?;
8754 self.write(")");
8755 check_idx += 1;
8756 break;
8757 }
8758 check_idx += 1;
8759 }
8760 }
8761 ConstraintType::GeneratedAsIdentity => {
8762 while generated_idx < col.constraints.len() {
8764 if let ColumnConstraint::GeneratedAsIdentity(gen) =
8765 &col.constraints[generated_idx]
8766 {
8767 self.write_space();
8768 if matches!(
8770 self.config.dialect,
8771 Some(crate::dialects::DialectType::Redshift)
8772 ) {
8773 self.write_keyword("IDENTITY");
8774 self.write("(");
8775 if let Some(ref start) = gen.start {
8776 self.generate_expression(start)?;
8777 } else {
8778 self.write("0");
8779 }
8780 self.write(", ");
8781 if let Some(ref incr) = gen.increment {
8782 self.generate_expression(incr)?;
8783 } else {
8784 self.write("1");
8785 }
8786 self.write(")");
8787 } else {
8788 self.write_keyword("GENERATED");
8789 if gen.always {
8790 self.write_space();
8791 self.write_keyword("ALWAYS");
8792 } else {
8793 self.write_space();
8794 self.write_keyword("BY DEFAULT");
8795 if gen.on_null {
8796 self.write_space();
8797 self.write_keyword("ON NULL");
8798 }
8799 }
8800 self.write_space();
8801 self.write_keyword("AS IDENTITY");
8802
8803 let has_options = gen.start.is_some()
8804 || gen.increment.is_some()
8805 || gen.minvalue.is_some()
8806 || gen.maxvalue.is_some()
8807 || gen.cycle.is_some();
8808 if has_options {
8809 self.write(" (");
8810 let mut first = true;
8811 if let Some(ref start) = gen.start {
8812 if !first {
8813 self.write(" ");
8814 }
8815 first = false;
8816 self.write_keyword("START WITH");
8817 self.write_space();
8818 self.generate_expression(start)?;
8819 }
8820 if let Some(ref incr) = gen.increment {
8821 if !first {
8822 self.write(" ");
8823 }
8824 first = false;
8825 self.write_keyword("INCREMENT BY");
8826 self.write_space();
8827 self.generate_expression(incr)?;
8828 }
8829 if let Some(ref minv) = gen.minvalue {
8830 if !first {
8831 self.write(" ");
8832 }
8833 first = false;
8834 self.write_keyword("MINVALUE");
8835 self.write_space();
8836 self.generate_expression(minv)?;
8837 }
8838 if let Some(ref maxv) = gen.maxvalue {
8839 if !first {
8840 self.write(" ");
8841 }
8842 first = false;
8843 self.write_keyword("MAXVALUE");
8844 self.write_space();
8845 self.generate_expression(maxv)?;
8846 }
8847 if let Some(cycle) = gen.cycle {
8848 if !first {
8849 self.write(" ");
8850 }
8851 if cycle {
8852 self.write_keyword("CYCLE");
8853 } else {
8854 self.write_keyword("NO CYCLE");
8855 }
8856 }
8857 self.write(")");
8858 }
8859 }
8860 generated_idx += 1;
8861 break;
8862 }
8863 generated_idx += 1;
8864 }
8865 }
8866 ConstraintType::Collate => {
8867 while collate_idx < col.constraints.len() {
8869 if let ColumnConstraint::Collate(collation) =
8870 &col.constraints[collate_idx]
8871 {
8872 self.write_space();
8873 self.write_keyword("COLLATE");
8874 self.write_space();
8875 self.generate_identifier(collation)?;
8876 collate_idx += 1;
8877 break;
8878 }
8879 collate_idx += 1;
8880 }
8881 }
8882 ConstraintType::Comment => {
8883 while comment_idx < col.constraints.len() {
8885 if let ColumnConstraint::Comment(comment) =
8886 &col.constraints[comment_idx]
8887 {
8888 self.write_space();
8889 self.write_keyword("COMMENT");
8890 self.write_space();
8891 self.generate_string_literal(comment)?;
8892 comment_idx += 1;
8893 break;
8894 }
8895 comment_idx += 1;
8896 }
8897 }
8898 ConstraintType::Tags => {
8899 for constraint in &col.constraints {
8901 if let ColumnConstraint::Tags(tags) = constraint {
8902 self.write_space();
8903 self.write_keyword("TAG");
8904 self.write(" (");
8905 for (i, expr) in tags.expressions.iter().enumerate() {
8906 if i > 0 {
8907 self.write(", ");
8908 }
8909 self.generate_expression(expr)?;
8910 }
8911 self.write(")");
8912 break;
8913 }
8914 }
8915 }
8916 ConstraintType::ComputedColumn => {
8917 for constraint in &col.constraints {
8919 if let ColumnConstraint::ComputedColumn(cc) = constraint {
8920 self.write_space();
8921 self.generate_computed_column_inline(cc)?;
8922 break;
8923 }
8924 }
8925 }
8926 ConstraintType::GeneratedAsRow => {
8927 for constraint in &col.constraints {
8929 if let ColumnConstraint::GeneratedAsRow(gar) = constraint {
8930 self.write_space();
8931 self.generate_generated_as_row_inline(gar)?;
8932 break;
8933 }
8934 }
8935 }
8936 ConstraintType::OnUpdate => {
8937 if let Some(ref expr) = col.on_update {
8938 self.write_space();
8939 self.write_keyword("ON UPDATE");
8940 self.write_space();
8941 self.generate_expression(expr)?;
8942 }
8943 }
8944 ConstraintType::Encode => {
8945 if let Some(ref encoding) = col.encoding {
8946 self.write_space();
8947 self.write_keyword("ENCODE");
8948 self.write_space();
8949 self.write(encoding);
8950 }
8951 }
8952 ConstraintType::Path => {
8953 for constraint in &col.constraints {
8955 if let ColumnConstraint::Path(path_expr) = constraint {
8956 self.write_space();
8957 self.write_keyword("PATH");
8958 self.write_space();
8959 self.generate_expression(path_expr)?;
8960 break;
8961 }
8962 }
8963 }
8964 }
8965 }
8966 if pending_not_null_after_identity {
8967 self.write_space();
8968 self.write_keyword("NOT NULL");
8969 }
8970 } else {
8971 if col.primary_key {
8973 self.write_space();
8974 self.write_keyword("PRIMARY KEY");
8975 if let Some(ref order) = col.primary_key_order {
8976 self.write_space();
8977 match order {
8978 SortOrder::Asc => self.write_keyword("ASC"),
8979 SortOrder::Desc => self.write_keyword("DESC"),
8980 }
8981 }
8982 }
8983
8984 if col.unique {
8985 self.write_space();
8986 self.write_keyword("UNIQUE");
8987 if col.unique_nulls_not_distinct {
8989 self.write(" NULLS NOT DISTINCT");
8990 }
8991 }
8992
8993 match col.nullable {
8994 Some(false) => {
8995 self.write_space();
8996 self.write_keyword("NOT NULL");
8997 }
8998 Some(true) => {
8999 self.write_space();
9000 self.write_keyword("NULL");
9001 }
9002 None => {}
9003 }
9004
9005 if let Some(ref default) = col.default {
9006 self.write_space();
9007 self.write_keyword("DEFAULT");
9008 self.write_space();
9009 self.generate_expression(default)?;
9010 }
9011
9012 if col.auto_increment {
9013 self.write_space();
9014 self.generate_auto_increment_keyword(col)?;
9015 }
9016
9017 for constraint in &col.constraints {
9019 match constraint {
9020 ColumnConstraint::References(fk_ref) => {
9021 self.write_space();
9022 if fk_ref.has_foreign_key_keywords {
9023 self.write_keyword("FOREIGN KEY");
9024 self.write_space();
9025 }
9026 self.write_keyword("REFERENCES");
9027 self.write_space();
9028 self.generate_table(&fk_ref.table)?;
9029 if !fk_ref.columns.is_empty() {
9030 self.write(" (");
9031 for (i, c) in fk_ref.columns.iter().enumerate() {
9032 if i > 0 {
9033 self.write(", ");
9034 }
9035 self.generate_identifier(c)?;
9036 }
9037 self.write(")");
9038 }
9039 self.generate_referential_actions(fk_ref)?;
9040 }
9041 ColumnConstraint::Check(expr) => {
9042 self.write_space();
9043 self.write_keyword("CHECK");
9044 self.write(" (");
9045 self.generate_expression(expr)?;
9046 self.write(")");
9047 }
9048 ColumnConstraint::GeneratedAsIdentity(gen) => {
9049 self.write_space();
9050 if matches!(
9052 self.config.dialect,
9053 Some(crate::dialects::DialectType::Redshift)
9054 ) {
9055 self.write_keyword("IDENTITY");
9056 self.write("(");
9057 if let Some(ref start) = gen.start {
9058 self.generate_expression(start)?;
9059 } else {
9060 self.write("0");
9061 }
9062 self.write(", ");
9063 if let Some(ref incr) = gen.increment {
9064 self.generate_expression(incr)?;
9065 } else {
9066 self.write("1");
9067 }
9068 self.write(")");
9069 } else {
9070 self.write_keyword("GENERATED");
9071 if gen.always {
9072 self.write_space();
9073 self.write_keyword("ALWAYS");
9074 } else {
9075 self.write_space();
9076 self.write_keyword("BY DEFAULT");
9077 if gen.on_null {
9078 self.write_space();
9079 self.write_keyword("ON NULL");
9080 }
9081 }
9082 self.write_space();
9083 self.write_keyword("AS IDENTITY");
9084
9085 let has_options = gen.start.is_some()
9086 || gen.increment.is_some()
9087 || gen.minvalue.is_some()
9088 || gen.maxvalue.is_some()
9089 || gen.cycle.is_some();
9090 if has_options {
9091 self.write(" (");
9092 let mut first = true;
9093 if let Some(ref start) = gen.start {
9094 if !first {
9095 self.write(" ");
9096 }
9097 first = false;
9098 self.write_keyword("START WITH");
9099 self.write_space();
9100 self.generate_expression(start)?;
9101 }
9102 if let Some(ref incr) = gen.increment {
9103 if !first {
9104 self.write(" ");
9105 }
9106 first = false;
9107 self.write_keyword("INCREMENT BY");
9108 self.write_space();
9109 self.generate_expression(incr)?;
9110 }
9111 if let Some(ref minv) = gen.minvalue {
9112 if !first {
9113 self.write(" ");
9114 }
9115 first = false;
9116 self.write_keyword("MINVALUE");
9117 self.write_space();
9118 self.generate_expression(minv)?;
9119 }
9120 if let Some(ref maxv) = gen.maxvalue {
9121 if !first {
9122 self.write(" ");
9123 }
9124 first = false;
9125 self.write_keyword("MAXVALUE");
9126 self.write_space();
9127 self.generate_expression(maxv)?;
9128 }
9129 if let Some(cycle) = gen.cycle {
9130 if !first {
9131 self.write(" ");
9132 }
9133 if cycle {
9134 self.write_keyword("CYCLE");
9135 } else {
9136 self.write_keyword("NO CYCLE");
9137 }
9138 }
9139 self.write(")");
9140 }
9141 }
9142 }
9143 ColumnConstraint::Collate(collation) => {
9144 self.write_space();
9145 self.write_keyword("COLLATE");
9146 self.write_space();
9147 self.generate_identifier(collation)?;
9148 }
9149 ColumnConstraint::Comment(comment) => {
9150 self.write_space();
9151 self.write_keyword("COMMENT");
9152 self.write_space();
9153 self.generate_string_literal(comment)?;
9154 }
9155 ColumnConstraint::Path(path_expr) => {
9156 self.write_space();
9157 self.write_keyword("PATH");
9158 self.write_space();
9159 self.generate_expression(path_expr)?;
9160 }
9161 _ => {} }
9163 }
9164
9165 if let Some(ref encoding) = col.encoding {
9167 self.write_space();
9168 self.write_keyword("ENCODE");
9169 self.write_space();
9170 self.write(encoding);
9171 }
9172 }
9173
9174 if let Some(ref codec) = col.codec {
9176 self.write_space();
9177 self.write_keyword("CODEC");
9178 self.write("(");
9179 self.write(codec);
9180 self.write(")");
9181 }
9182
9183 if let Some(visible) = col.visible {
9184 self.write_space();
9185 if visible {
9186 self.write_keyword("VISIBLE");
9187 } else {
9188 self.write_keyword("INVISIBLE");
9189 }
9190 }
9191
9192 if let Some(ref ephemeral) = col.ephemeral {
9194 self.write_space();
9195 self.write_keyword("EPHEMERAL");
9196 if let Some(ref expr) = ephemeral {
9197 self.write_space();
9198 self.generate_expression(expr)?;
9199 }
9200 }
9201
9202 if let Some(ref mat_expr) = col.materialized_expr {
9204 self.write_space();
9205 self.write_keyword("MATERIALIZED");
9206 self.write_space();
9207 self.generate_expression(mat_expr)?;
9208 }
9209
9210 if let Some(ref alias_expr) = col.alias_expr {
9212 self.write_space();
9213 self.write_keyword("ALIAS");
9214 self.write_space();
9215 self.generate_expression(alias_expr)?;
9216 }
9217
9218 if let Some(ref ttl_expr) = col.ttl_expr {
9220 self.write_space();
9221 self.write_keyword("TTL");
9222 self.write_space();
9223 self.generate_expression(ttl_expr)?;
9224 }
9225
9226 if col.not_for_replication
9228 && matches!(
9229 self.config.dialect,
9230 Some(crate::dialects::DialectType::TSQL)
9231 | Some(crate::dialects::DialectType::Fabric)
9232 )
9233 {
9234 self.write_space();
9235 self.write_keyword("NOT FOR REPLICATION");
9236 }
9237
9238 if !col.options.is_empty() {
9240 self.write_space();
9241 self.generate_options_clause(&col.options)?;
9242 }
9243
9244 if !col.primary_key
9247 && self
9248 .sqlite_inline_pk_columns
9249 .contains(&col.name.name.to_ascii_lowercase())
9250 {
9251 self.write_space();
9252 self.write_keyword("PRIMARY KEY");
9253 }
9254
9255 if serial_expansion.is_some() {
9258 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
9259 self.write_space();
9260 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY NOT NULL");
9261 } else if matches!(self.config.dialect, Some(DialectType::Materialize)) {
9262 self.write_space();
9263 self.write_keyword("NOT NULL");
9264 }
9265 }
9266
9267 Ok(())
9268 }
9269
9270 fn generate_table_constraint(&mut self, constraint: &TableConstraint) -> Result<()> {
9271 match constraint {
9272 TableConstraint::PrimaryKey {
9273 name,
9274 columns,
9275 include_columns,
9276 modifiers,
9277 has_constraint_keyword,
9278 } => {
9279 if let Some(ref n) = name {
9280 if *has_constraint_keyword {
9281 self.write_keyword("CONSTRAINT");
9282 self.write_space();
9283 self.generate_identifier(n)?;
9284 self.write_space();
9285 }
9286 }
9287 self.write_keyword("PRIMARY KEY");
9288 if let Some(ref clustered) = modifiers.clustered {
9290 self.write_space();
9291 self.write_keyword(clustered);
9292 }
9293 if let Some(ref n) = name {
9295 if !*has_constraint_keyword {
9296 self.write_space();
9297 self.generate_identifier(n)?;
9298 }
9299 }
9300 self.write(" (");
9301 for (i, col) in columns.iter().enumerate() {
9302 if i > 0 {
9303 self.write(", ");
9304 }
9305 self.generate_identifier(col)?;
9306 }
9307 self.write(")");
9308 if !include_columns.is_empty() {
9309 self.write_space();
9310 self.write_keyword("INCLUDE");
9311 self.write(" (");
9312 for (i, col) in include_columns.iter().enumerate() {
9313 if i > 0 {
9314 self.write(", ");
9315 }
9316 self.generate_identifier(col)?;
9317 }
9318 self.write(")");
9319 }
9320 self.generate_constraint_modifiers(modifiers);
9321 }
9322 TableConstraint::Unique {
9323 name,
9324 columns,
9325 columns_parenthesized,
9326 modifiers,
9327 has_constraint_keyword,
9328 nulls_not_distinct,
9329 } => {
9330 if let Some(ref n) = name {
9331 if *has_constraint_keyword {
9332 self.write_keyword("CONSTRAINT");
9333 self.write_space();
9334 self.generate_identifier(n)?;
9335 self.write_space();
9336 }
9337 }
9338 self.write_keyword("UNIQUE");
9339 if let Some(ref clustered) = modifiers.clustered {
9341 self.write_space();
9342 self.write_keyword(clustered);
9343 }
9344 if *nulls_not_distinct {
9346 self.write(" NULLS NOT DISTINCT");
9347 }
9348 if let Some(ref n) = name {
9350 if !*has_constraint_keyword {
9351 self.write_space();
9352 self.generate_identifier(n)?;
9353 }
9354 }
9355 if *columns_parenthesized {
9356 self.write(" (");
9357 for (i, col) in columns.iter().enumerate() {
9358 if i > 0 {
9359 self.write(", ");
9360 }
9361 self.generate_identifier(col)?;
9362 }
9363 self.write(")");
9364 } else {
9365 for col in columns.iter() {
9367 self.write_space();
9368 self.generate_identifier(col)?;
9369 }
9370 }
9371 self.generate_constraint_modifiers(modifiers);
9372 }
9373 TableConstraint::ForeignKey {
9374 name,
9375 columns,
9376 references,
9377 on_delete,
9378 on_update,
9379 modifiers,
9380 } => {
9381 if let Some(ref n) = name {
9382 self.write_keyword("CONSTRAINT");
9383 self.write_space();
9384 self.generate_identifier(n)?;
9385 self.write_space();
9386 }
9387 self.write_keyword("FOREIGN KEY");
9388 self.write(" (");
9389 for (i, col) in columns.iter().enumerate() {
9390 if i > 0 {
9391 self.write(", ");
9392 }
9393 self.generate_identifier(col)?;
9394 }
9395 self.write(")");
9396 if let Some(ref refs) = references {
9397 self.write(" ");
9398 self.write_keyword("REFERENCES");
9399 self.write_space();
9400 self.generate_table(&refs.table)?;
9401 if !refs.columns.is_empty() {
9402 if self.config.pretty {
9403 self.write(" (");
9404 self.write_newline();
9405 self.indent_level += 1;
9406 for (i, col) in refs.columns.iter().enumerate() {
9407 if i > 0 {
9408 self.write(",");
9409 self.write_newline();
9410 }
9411 self.write_indent();
9412 self.generate_identifier(col)?;
9413 }
9414 self.indent_level -= 1;
9415 self.write_newline();
9416 self.write_indent();
9417 self.write(")");
9418 } else {
9419 self.write(" (");
9420 for (i, col) in refs.columns.iter().enumerate() {
9421 if i > 0 {
9422 self.write(", ");
9423 }
9424 self.generate_identifier(col)?;
9425 }
9426 self.write(")");
9427 }
9428 }
9429 self.generate_referential_actions(refs)?;
9430 } else {
9431 if let Some(ref action) = on_delete {
9433 self.write_space();
9434 self.write_keyword("ON DELETE");
9435 self.write_space();
9436 self.generate_referential_action(action);
9437 }
9438 if let Some(ref action) = on_update {
9439 self.write_space();
9440 self.write_keyword("ON UPDATE");
9441 self.write_space();
9442 self.generate_referential_action(action);
9443 }
9444 }
9445 self.generate_constraint_modifiers(modifiers);
9446 }
9447 TableConstraint::Check {
9448 name,
9449 expression,
9450 modifiers,
9451 } => {
9452 if let Some(ref n) = name {
9453 self.write_keyword("CONSTRAINT");
9454 self.write_space();
9455 self.generate_identifier(n)?;
9456 self.write_space();
9457 }
9458 self.write_keyword("CHECK");
9459 self.write(" (");
9460 self.generate_expression(expression)?;
9461 self.write(")");
9462 self.generate_constraint_modifiers(modifiers);
9463 }
9464 TableConstraint::Assume { name, expression } => {
9465 if let Some(ref n) = name {
9466 self.write_keyword("CONSTRAINT");
9467 self.write_space();
9468 self.generate_identifier(n)?;
9469 self.write_space();
9470 }
9471 self.write_keyword("ASSUME");
9472 self.write(" (");
9473 self.generate_expression(expression)?;
9474 self.write(")");
9475 }
9476 TableConstraint::Default {
9477 name,
9478 expression,
9479 column,
9480 } => {
9481 if let Some(ref n) = name {
9482 self.write_keyword("CONSTRAINT");
9483 self.write_space();
9484 self.generate_identifier(n)?;
9485 self.write_space();
9486 }
9487 self.write_keyword("DEFAULT");
9488 self.write_space();
9489 self.generate_expression(expression)?;
9490 self.write_space();
9491 self.write_keyword("FOR");
9492 self.write_space();
9493 self.generate_identifier(column)?;
9494 }
9495 TableConstraint::Index {
9496 name,
9497 columns,
9498 kind,
9499 modifiers,
9500 use_key_keyword,
9501 expression,
9502 index_type,
9503 granularity,
9504 } => {
9505 if expression.is_some() {
9507 self.write_keyword("INDEX");
9508 if let Some(ref n) = name {
9509 self.write_space();
9510 self.generate_identifier(n)?;
9511 }
9512 if let Some(ref expr) = expression {
9513 self.write_space();
9514 self.generate_expression(expr)?;
9515 }
9516 if let Some(ref idx_type) = index_type {
9517 self.write_space();
9518 self.write_keyword("TYPE");
9519 self.write_space();
9520 self.generate_expression(idx_type)?;
9521 }
9522 if let Some(ref gran) = granularity {
9523 self.write_space();
9524 self.write_keyword("GRANULARITY");
9525 self.write_space();
9526 self.generate_expression(gran)?;
9527 }
9528 } else {
9529 use crate::dialects::DialectType;
9533 let index_keyword = if *use_key_keyword
9534 && !matches!(self.config.dialect, Some(DialectType::MySQL))
9535 {
9536 "KEY"
9537 } else {
9538 "INDEX"
9539 };
9540
9541 if let Some(ref k) = kind {
9543 self.write_keyword(k);
9544 if k != "UNIQUE" {
9546 self.write_space();
9547 self.write_keyword(index_keyword);
9548 }
9549 } else {
9550 self.write_keyword(index_keyword);
9551 }
9552
9553 if modifiers.using_before_columns && name.is_none() {
9555 if let Some(ref using) = modifiers.using {
9556 self.write_space();
9557 self.write_keyword("USING");
9558 self.write_space();
9559 self.write_keyword(using);
9560 }
9561 }
9562
9563 if let Some(ref n) = name {
9565 self.write_space();
9566 self.generate_identifier(n)?;
9567 }
9568
9569 if modifiers.using_before_columns && name.is_some() {
9571 if let Some(ref using) = modifiers.using {
9572 self.write_space();
9573 self.write_keyword("USING");
9574 self.write_space();
9575 self.write_keyword(using);
9576 }
9577 }
9578
9579 self.write(" (");
9581 for (i, col) in columns.iter().enumerate() {
9582 if i > 0 {
9583 self.write(", ");
9584 }
9585 self.generate_identifier(col)?;
9586 }
9587 self.write(")");
9588
9589 if !modifiers.using_before_columns {
9591 if let Some(ref using) = modifiers.using {
9592 self.write_space();
9593 self.write_keyword("USING");
9594 self.write_space();
9595 self.write_keyword(using);
9596 }
9597 }
9598
9599 self.generate_constraint_modifiers_without_using(modifiers);
9601 }
9602 }
9603 TableConstraint::Projection { name, expression } => {
9604 self.write_keyword("PROJECTION");
9606 self.write_space();
9607 self.generate_identifier(name)?;
9608 self.write(" (");
9609 self.generate_expression(expression)?;
9610 self.write(")");
9611 }
9612 TableConstraint::Like { source, options } => {
9613 self.write_keyword("LIKE");
9614 self.write_space();
9615 self.generate_table(source)?;
9616 for (action, prop) in options {
9617 self.write_space();
9618 match action {
9619 LikeOptionAction::Including => self.write_keyword("INCLUDING"),
9620 LikeOptionAction::Excluding => self.write_keyword("EXCLUDING"),
9621 }
9622 self.write_space();
9623 self.write_keyword(prop);
9624 }
9625 }
9626 TableConstraint::PeriodForSystemTime { start_col, end_col } => {
9627 self.write_keyword("PERIOD FOR SYSTEM_TIME");
9628 self.write(" (");
9629 self.generate_identifier(start_col)?;
9630 self.write(", ");
9631 self.generate_identifier(end_col)?;
9632 self.write(")");
9633 }
9634 TableConstraint::Exclude {
9635 name,
9636 using,
9637 elements,
9638 include_columns,
9639 where_clause,
9640 with_params,
9641 using_index_tablespace,
9642 modifiers: _,
9643 } => {
9644 if let Some(ref n) = name {
9645 self.write_keyword("CONSTRAINT");
9646 self.write_space();
9647 self.generate_identifier(n)?;
9648 self.write_space();
9649 }
9650 self.write_keyword("EXCLUDE");
9651 if let Some(ref method) = using {
9652 self.write_space();
9653 self.write_keyword("USING");
9654 self.write_space();
9655 self.write(method);
9656 self.write("(");
9657 } else {
9658 self.write(" (");
9659 }
9660 for (i, elem) in elements.iter().enumerate() {
9661 if i > 0 {
9662 self.write(", ");
9663 }
9664 self.write(&elem.expression);
9665 self.write_space();
9666 self.write_keyword("WITH");
9667 self.write_space();
9668 self.write(&elem.operator);
9669 }
9670 self.write(")");
9671 if !include_columns.is_empty() {
9672 self.write_space();
9673 self.write_keyword("INCLUDE");
9674 self.write(" (");
9675 for (i, col) in include_columns.iter().enumerate() {
9676 if i > 0 {
9677 self.write(", ");
9678 }
9679 self.generate_identifier(col)?;
9680 }
9681 self.write(")");
9682 }
9683 if !with_params.is_empty() {
9684 self.write_space();
9685 self.write_keyword("WITH");
9686 self.write(" (");
9687 for (i, (key, val)) in with_params.iter().enumerate() {
9688 if i > 0 {
9689 self.write(", ");
9690 }
9691 self.write(key);
9692 self.write("=");
9693 self.write(val);
9694 }
9695 self.write(")");
9696 }
9697 if let Some(ref tablespace) = using_index_tablespace {
9698 self.write_space();
9699 self.write_keyword("USING INDEX TABLESPACE");
9700 self.write_space();
9701 self.write(tablespace);
9702 }
9703 if let Some(ref where_expr) = where_clause {
9704 self.write_space();
9705 self.write_keyword("WHERE");
9706 self.write(" (");
9707 self.generate_expression(where_expr)?;
9708 self.write(")");
9709 }
9710 }
9711 TableConstraint::Tags(tags) => {
9712 self.write_keyword("TAG");
9713 self.write(" (");
9714 for (i, expr) in tags.expressions.iter().enumerate() {
9715 if i > 0 {
9716 self.write(", ");
9717 }
9718 self.generate_expression(expr)?;
9719 }
9720 self.write(")");
9721 }
9722 TableConstraint::InitiallyDeferred { deferred } => {
9723 self.write_keyword("INITIALLY");
9724 self.write_space();
9725 if *deferred {
9726 self.write_keyword("DEFERRED");
9727 } else {
9728 self.write_keyword("IMMEDIATE");
9729 }
9730 }
9731 }
9732 Ok(())
9733 }
9734
9735 fn generate_constraint_modifiers(&mut self, modifiers: &ConstraintModifiers) {
9736 if let Some(using) = &modifiers.using {
9738 self.write_space();
9739 self.write_keyword("USING");
9740 self.write_space();
9741 self.write_keyword(using);
9742 }
9743 if let Some(enforced) = modifiers.enforced {
9745 self.write_space();
9746 if enforced {
9747 self.write_keyword("ENFORCED");
9748 } else {
9749 self.write_keyword("NOT ENFORCED");
9750 }
9751 }
9752 if let Some(deferrable) = modifiers.deferrable {
9754 self.write_space();
9755 if deferrable {
9756 self.write_keyword("DEFERRABLE");
9757 } else {
9758 self.write_keyword("NOT DEFERRABLE");
9759 }
9760 }
9761 if let Some(initially_deferred) = modifiers.initially_deferred {
9763 self.write_space();
9764 if initially_deferred {
9765 self.write_keyword("INITIALLY DEFERRED");
9766 } else {
9767 self.write_keyword("INITIALLY IMMEDIATE");
9768 }
9769 }
9770 if modifiers.norely {
9772 self.write_space();
9773 self.write_keyword("NORELY");
9774 }
9775 if modifiers.rely {
9777 self.write_space();
9778 self.write_keyword("RELY");
9779 }
9780 if modifiers.not_valid {
9782 self.write_space();
9783 self.write_keyword("NOT VALID");
9784 }
9785 if let Some(on_conflict) = &modifiers.on_conflict {
9787 self.write_space();
9788 self.write_keyword("ON CONFLICT");
9789 self.write_space();
9790 self.write_keyword(on_conflict);
9791 }
9792 if !modifiers.with_options.is_empty() {
9794 self.write_space();
9795 self.write_keyword("WITH");
9796 self.write(" (");
9797 for (i, (key, value)) in modifiers.with_options.iter().enumerate() {
9798 if i > 0 {
9799 self.write(", ");
9800 }
9801 self.write(key);
9802 self.write("=");
9803 self.write(value);
9804 }
9805 self.write(")");
9806 }
9807 if let Some(ref fg) = modifiers.on_filegroup {
9809 self.write_space();
9810 self.write_keyword("ON");
9811 self.write_space();
9812 let _ = self.generate_identifier(fg);
9813 }
9814 }
9815
9816 fn generate_constraint_modifiers_without_using(&mut self, modifiers: &ConstraintModifiers) {
9818 if let Some(enforced) = modifiers.enforced {
9820 self.write_space();
9821 if enforced {
9822 self.write_keyword("ENFORCED");
9823 } else {
9824 self.write_keyword("NOT ENFORCED");
9825 }
9826 }
9827 if let Some(deferrable) = modifiers.deferrable {
9829 self.write_space();
9830 if deferrable {
9831 self.write_keyword("DEFERRABLE");
9832 } else {
9833 self.write_keyword("NOT DEFERRABLE");
9834 }
9835 }
9836 if let Some(initially_deferred) = modifiers.initially_deferred {
9838 self.write_space();
9839 if initially_deferred {
9840 self.write_keyword("INITIALLY DEFERRED");
9841 } else {
9842 self.write_keyword("INITIALLY IMMEDIATE");
9843 }
9844 }
9845 if modifiers.norely {
9847 self.write_space();
9848 self.write_keyword("NORELY");
9849 }
9850 if modifiers.rely {
9852 self.write_space();
9853 self.write_keyword("RELY");
9854 }
9855 if modifiers.not_valid {
9857 self.write_space();
9858 self.write_keyword("NOT VALID");
9859 }
9860 if let Some(on_conflict) = &modifiers.on_conflict {
9862 self.write_space();
9863 self.write_keyword("ON CONFLICT");
9864 self.write_space();
9865 self.write_keyword(on_conflict);
9866 }
9867 self.generate_index_specific_modifiers(modifiers);
9869 }
9870
9871 fn generate_index_specific_modifiers(&mut self, modifiers: &ConstraintModifiers) {
9873 if let Some(ref comment) = modifiers.comment {
9874 self.write_space();
9875 self.write_keyword("COMMENT");
9876 self.write(" '");
9877 self.write(comment);
9878 self.write("'");
9879 }
9880 if let Some(visible) = modifiers.visible {
9881 self.write_space();
9882 if visible {
9883 self.write_keyword("VISIBLE");
9884 } else {
9885 self.write_keyword("INVISIBLE");
9886 }
9887 }
9888 if let Some(ref attr) = modifiers.engine_attribute {
9889 self.write_space();
9890 self.write_keyword("ENGINE_ATTRIBUTE");
9891 self.write(" = '");
9892 self.write(attr);
9893 self.write("'");
9894 }
9895 if let Some(ref parser) = modifiers.with_parser {
9896 self.write_space();
9897 self.write_keyword("WITH PARSER");
9898 self.write_space();
9899 self.write(parser);
9900 }
9901 }
9902
9903 fn generate_referential_actions(&mut self, fk_ref: &ForeignKeyRef) -> Result<()> {
9904 if !fk_ref.match_after_actions {
9906 if let Some(ref match_type) = fk_ref.match_type {
9907 self.write_space();
9908 self.write_keyword("MATCH");
9909 self.write_space();
9910 match match_type {
9911 MatchType::Full => self.write_keyword("FULL"),
9912 MatchType::Partial => self.write_keyword("PARTIAL"),
9913 MatchType::Simple => self.write_keyword("SIMPLE"),
9914 }
9915 }
9916 }
9917
9918 if fk_ref.on_update_first {
9920 if let Some(ref action) = fk_ref.on_update {
9921 self.write_space();
9922 self.write_keyword("ON UPDATE");
9923 self.write_space();
9924 self.generate_referential_action(action);
9925 }
9926 if let Some(ref action) = fk_ref.on_delete {
9927 self.write_space();
9928 self.write_keyword("ON DELETE");
9929 self.write_space();
9930 self.generate_referential_action(action);
9931 }
9932 } else {
9933 if let Some(ref action) = fk_ref.on_delete {
9934 self.write_space();
9935 self.write_keyword("ON DELETE");
9936 self.write_space();
9937 self.generate_referential_action(action);
9938 }
9939 if let Some(ref action) = fk_ref.on_update {
9940 self.write_space();
9941 self.write_keyword("ON UPDATE");
9942 self.write_space();
9943 self.generate_referential_action(action);
9944 }
9945 }
9946
9947 if fk_ref.match_after_actions {
9949 if let Some(ref match_type) = fk_ref.match_type {
9950 self.write_space();
9951 self.write_keyword("MATCH");
9952 self.write_space();
9953 match match_type {
9954 MatchType::Full => self.write_keyword("FULL"),
9955 MatchType::Partial => self.write_keyword("PARTIAL"),
9956 MatchType::Simple => self.write_keyword("SIMPLE"),
9957 }
9958 }
9959 }
9960
9961 if let Some(deferrable) = fk_ref.deferrable {
9963 self.write_space();
9964 if deferrable {
9965 self.write_keyword("DEFERRABLE");
9966 } else {
9967 self.write_keyword("NOT DEFERRABLE");
9968 }
9969 }
9970
9971 Ok(())
9972 }
9973
9974 fn generate_referential_action(&mut self, action: &ReferentialAction) {
9975 match action {
9976 ReferentialAction::Cascade => self.write_keyword("CASCADE"),
9977 ReferentialAction::SetNull => self.write_keyword("SET NULL"),
9978 ReferentialAction::SetDefault => self.write_keyword("SET DEFAULT"),
9979 ReferentialAction::Restrict => self.write_keyword("RESTRICT"),
9980 ReferentialAction::NoAction => self.write_keyword("NO ACTION"),
9981 }
9982 }
9983
9984 fn generate_drop_table(&mut self, dt: &DropTable) -> Result<()> {
9985 if let Some(ref object_id_args) = dt.object_id_args {
9987 if matches!(
9988 self.config.dialect,
9989 Some(crate::dialects::DialectType::TSQL)
9990 | Some(crate::dialects::DialectType::Fabric)
9991 ) {
9992 self.write_keyword("IF NOT OBJECT_ID");
9993 self.write("(");
9994 self.write(object_id_args);
9995 self.write(")");
9996 self.write_space();
9997 self.write_keyword("IS NULL BEGIN DROP TABLE");
9998 self.write_space();
9999 for (i, table) in dt.names.iter().enumerate() {
10000 if i > 0 {
10001 self.write(", ");
10002 }
10003 self.generate_table(table)?;
10004 }
10005 self.write("; ");
10006 self.write_keyword("END");
10007 return Ok(());
10008 }
10009 }
10010
10011 let saved_athena_hive_context = self.athena_hive_context;
10013 if matches!(
10014 self.config.dialect,
10015 Some(crate::dialects::DialectType::Athena)
10016 ) {
10017 self.athena_hive_context = true;
10018 }
10019
10020 for comment in &dt.leading_comments {
10022 self.write_formatted_comment(comment);
10023 self.write_space();
10024 }
10025 if dt.iceberg {
10026 self.write_keyword("DROP ICEBERG TABLE");
10027 } else {
10028 self.write_keyword("DROP TABLE");
10029 }
10030
10031 if dt.if_exists {
10032 self.write_space();
10033 self.write_keyword("IF EXISTS");
10034 }
10035
10036 self.write_space();
10037 for (i, table) in dt.names.iter().enumerate() {
10038 if i > 0 {
10039 self.write(", ");
10040 }
10041 self.generate_table(table)?;
10042 }
10043
10044 if dt.cascade_constraints {
10045 self.write_space();
10046 self.write_keyword("CASCADE CONSTRAINTS");
10047 } else if dt.cascade {
10048 self.write_space();
10049 self.write_keyword("CASCADE");
10050 }
10051
10052 if dt.restrict {
10053 self.write_space();
10054 self.write_keyword("RESTRICT");
10055 }
10056
10057 if dt.purge {
10058 self.write_space();
10059 self.write_keyword("PURGE");
10060 }
10061
10062 if dt.sync {
10063 self.write_space();
10064 self.write_keyword("SYNC");
10065 }
10066
10067 self.athena_hive_context = saved_athena_hive_context;
10069
10070 Ok(())
10071 }
10072
10073 fn generate_undrop(&mut self, u: &Undrop) -> Result<()> {
10074 self.write_keyword("UNDROP");
10075 self.write_space();
10076 self.write_keyword(&u.kind);
10077 if u.if_exists {
10078 self.write_space();
10079 self.write_keyword("IF EXISTS");
10080 }
10081 self.write_space();
10082 self.generate_table(&u.name)?;
10083 Ok(())
10084 }
10085
10086 fn generate_alter_table(&mut self, at: &AlterTable) -> Result<()> {
10087 let saved_athena_hive_context = self.athena_hive_context;
10089 if matches!(
10090 self.config.dialect,
10091 Some(crate::dialects::DialectType::Athena)
10092 ) {
10093 self.athena_hive_context = true;
10094 }
10095
10096 self.write_keyword("ALTER");
10097 if let Some(ref modifier) = at.table_modifier {
10099 if !matches!(
10100 self.config.dialect,
10101 Some(crate::dialects::DialectType::DuckDB)
10102 ) {
10103 self.write_space();
10104 self.write_keyword(modifier);
10105 }
10106 }
10107 self.write(" ");
10108 self.write_keyword("TABLE");
10109 if at.if_exists {
10110 self.write_space();
10111 self.write_keyword("IF EXISTS");
10112 }
10113 self.write_space();
10114 self.generate_table(&at.name)?;
10115
10116 if let Some(ref on_cluster) = at.on_cluster {
10118 self.write_space();
10119 self.generate_on_cluster(on_cluster)?;
10120 }
10121
10122 if let Some(ref partition) = at.partition {
10124 self.write_space();
10125 self.write_keyword("PARTITION");
10126 self.write("(");
10127 for (i, (key, value)) in partition.iter().enumerate() {
10128 if i > 0 {
10129 self.write(", ");
10130 }
10131 self.generate_identifier(key)?;
10132 self.write(" = ");
10133 self.generate_expression(value)?;
10134 }
10135 self.write(")");
10136 }
10137
10138 if let Some(ref with_check) = at.with_check {
10140 self.write_space();
10141 self.write_keyword(with_check);
10142 }
10143
10144 if self.config.pretty {
10145 self.write_newline();
10147 self.indent_level += 1;
10148 for (i, action) in at.actions.iter().enumerate() {
10149 let is_continuation = i > 0
10151 && matches!(
10152 (&at.actions[i - 1], action),
10153 (
10154 AlterTableAction::AddColumn { .. },
10155 AlterTableAction::AddColumn { .. }
10156 ) | (
10157 AlterTableAction::AddConstraint(_),
10158 AlterTableAction::AddConstraint(_)
10159 )
10160 );
10161 if i > 0 {
10162 self.write(",");
10163 self.write_newline();
10164 }
10165 self.write_indent();
10166 self.generate_alter_action_with_continuation(action, is_continuation)?;
10167 }
10168 self.indent_level -= 1;
10169 } else {
10170 for (i, action) in at.actions.iter().enumerate() {
10171 let is_continuation = i > 0
10173 && matches!(
10174 (&at.actions[i - 1], action),
10175 (
10176 AlterTableAction::AddColumn { .. },
10177 AlterTableAction::AddColumn { .. }
10178 ) | (
10179 AlterTableAction::AddConstraint(_),
10180 AlterTableAction::AddConstraint(_)
10181 )
10182 );
10183 if i > 0 {
10184 self.write(",");
10185 }
10186 self.write_space();
10187 self.generate_alter_action_with_continuation(action, is_continuation)?;
10188 }
10189 }
10190
10191 if let Some(ref algorithm) = at.algorithm {
10193 self.write(", ");
10194 self.write_keyword("ALGORITHM");
10195 self.write("=");
10196 self.write_keyword(algorithm);
10197 }
10198 if let Some(ref lock) = at.lock {
10199 self.write(", ");
10200 self.write_keyword("LOCK");
10201 self.write("=");
10202 self.write_keyword(lock);
10203 }
10204
10205 self.athena_hive_context = saved_athena_hive_context;
10207
10208 Ok(())
10209 }
10210
10211 fn generate_alter_action_with_continuation(
10212 &mut self,
10213 action: &AlterTableAction,
10214 is_continuation: bool,
10215 ) -> Result<()> {
10216 match action {
10217 AlterTableAction::AddColumn {
10218 column,
10219 if_not_exists,
10220 position,
10221 } => {
10222 use crate::dialects::DialectType;
10223 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
10227 let is_tsql_like = matches!(
10228 self.config.dialect,
10229 Some(DialectType::TSQL) | Some(DialectType::Fabric)
10230 );
10231 let is_athena = matches!(self.config.dialect, Some(DialectType::Athena));
10233
10234 if is_continuation && (is_snowflake || is_tsql_like) {
10235 } else if is_snowflake {
10237 self.write_keyword("ADD");
10238 self.write_space();
10239 } else if is_athena {
10240 self.write_keyword("ADD COLUMNS");
10242 self.write(" (");
10243 } else if self.config.alter_table_include_column_keyword {
10244 self.write_keyword("ADD COLUMN");
10245 self.write_space();
10246 } else {
10247 self.write_keyword("ADD");
10249 self.write_space();
10250 }
10251
10252 if *if_not_exists {
10253 self.write_keyword("IF NOT EXISTS");
10254 self.write_space();
10255 }
10256 self.generate_column_def(column)?;
10257
10258 if is_athena {
10260 self.write(")");
10261 }
10262
10263 if let Some(pos) = position {
10265 self.write_space();
10266 match pos {
10267 ColumnPosition::First => self.write_keyword("FIRST"),
10268 ColumnPosition::After(col_name) => {
10269 self.write_keyword("AFTER");
10270 self.write_space();
10271 self.generate_identifier(col_name)?;
10272 }
10273 }
10274 }
10275 }
10276 AlterTableAction::DropColumn {
10277 name,
10278 if_exists,
10279 cascade,
10280 } => {
10281 self.write_keyword("DROP COLUMN");
10282 if *if_exists {
10283 self.write_space();
10284 self.write_keyword("IF EXISTS");
10285 }
10286 self.write_space();
10287 self.generate_identifier(name)?;
10288 if *cascade {
10289 self.write_space();
10290 self.write_keyword("CASCADE");
10291 }
10292 }
10293 AlterTableAction::DropColumns { names } => {
10294 self.write_keyword("DROP COLUMNS");
10295 self.write(" (");
10296 for (i, name) in names.iter().enumerate() {
10297 if i > 0 {
10298 self.write(", ");
10299 }
10300 self.generate_identifier(name)?;
10301 }
10302 self.write(")");
10303 }
10304 AlterTableAction::RenameColumn {
10305 old_name,
10306 new_name,
10307 if_exists,
10308 } => {
10309 self.write_keyword("RENAME COLUMN");
10310 if *if_exists {
10311 self.write_space();
10312 self.write_keyword("IF EXISTS");
10313 }
10314 self.write_space();
10315 self.generate_identifier(old_name)?;
10316 self.write_space();
10317 self.write_keyword("TO");
10318 self.write_space();
10319 self.generate_identifier(new_name)?;
10320 }
10321 AlterTableAction::AlterColumn {
10322 name,
10323 action,
10324 use_modify_keyword,
10325 } => {
10326 use crate::dialects::DialectType;
10327 let use_modify = *use_modify_keyword
10330 || (matches!(self.config.dialect, Some(DialectType::MySQL))
10331 && matches!(action, AlterColumnAction::SetDataType { .. }));
10332 if use_modify {
10333 self.write_keyword("MODIFY COLUMN");
10334 self.write_space();
10335 self.generate_identifier(name)?;
10336 if let AlterColumnAction::SetDataType {
10338 data_type,
10339 using: _,
10340 collate,
10341 } = action
10342 {
10343 self.write_space();
10344 self.generate_data_type(data_type)?;
10345 if let Some(collate_name) = collate {
10347 self.write_space();
10348 self.write_keyword("COLLATE");
10349 self.write_space();
10350 self.write(&format!("'{}'", collate_name));
10352 }
10353 } else {
10354 self.write_space();
10355 self.generate_alter_column_action(action)?;
10356 }
10357 } else if matches!(self.config.dialect, Some(DialectType::Hive))
10358 && matches!(action, AlterColumnAction::SetDataType { .. })
10359 {
10360 self.write_keyword("CHANGE COLUMN");
10362 self.write_space();
10363 self.generate_identifier(name)?;
10364 self.write_space();
10365 self.generate_identifier(name)?;
10366 if let AlterColumnAction::SetDataType { data_type, .. } = action {
10367 self.write_space();
10368 self.generate_data_type(data_type)?;
10369 }
10370 } else {
10371 self.write_keyword("ALTER COLUMN");
10372 self.write_space();
10373 self.generate_identifier(name)?;
10374 self.write_space();
10375 self.generate_alter_column_action(action)?;
10376 }
10377 }
10378 AlterTableAction::RenameTable(new_name) => {
10379 let mysql_like = matches!(
10381 self.config.dialect,
10382 Some(DialectType::MySQL)
10383 | Some(DialectType::Doris)
10384 | Some(DialectType::StarRocks)
10385 | Some(DialectType::SingleStore)
10386 );
10387 if mysql_like {
10388 self.write_keyword("RENAME");
10389 } else {
10390 self.write_keyword("RENAME TO");
10391 }
10392 self.write_space();
10393 let rename_table_with_db = !matches!(
10395 self.config.dialect,
10396 Some(DialectType::Doris)
10397 | Some(DialectType::DuckDB)
10398 | Some(DialectType::BigQuery)
10399 | Some(DialectType::PostgreSQL)
10400 );
10401 if !rename_table_with_db {
10402 let mut stripped = new_name.clone();
10403 stripped.schema = None;
10404 stripped.catalog = None;
10405 self.generate_table(&stripped)?;
10406 } else {
10407 self.generate_table(new_name)?;
10408 }
10409 }
10410 AlterTableAction::AddConstraint(constraint) => {
10411 if !is_continuation {
10414 self.write_keyword("ADD");
10415 self.write_space();
10416 }
10417 self.generate_table_constraint(constraint)?;
10418 }
10419 AlterTableAction::DropConstraint { name, if_exists } => {
10420 self.write_keyword("DROP CONSTRAINT");
10421 if *if_exists {
10422 self.write_space();
10423 self.write_keyword("IF EXISTS");
10424 }
10425 self.write_space();
10426 self.generate_identifier(name)?;
10427 }
10428 AlterTableAction::DropForeignKey { name } => {
10429 self.write_keyword("DROP FOREIGN KEY");
10430 self.write_space();
10431 self.generate_identifier(name)?;
10432 }
10433 AlterTableAction::DropPartition {
10434 partitions,
10435 if_exists,
10436 } => {
10437 self.write_keyword("DROP");
10438 if *if_exists {
10439 self.write_space();
10440 self.write_keyword("IF EXISTS");
10441 }
10442 for (i, partition) in partitions.iter().enumerate() {
10443 if i > 0 {
10444 self.write(",");
10445 }
10446 self.write_space();
10447 self.write_keyword("PARTITION");
10448 if partition.len() == 1 && partition[0].0.name == "__expr__" {
10450 self.write_space();
10452 self.generate_expression(&partition[0].1)?;
10453 } else if partition.len() == 1 && partition[0].0.name == "ALL" {
10454 self.write_space();
10456 self.write_keyword("ALL");
10457 } else if partition.len() == 1 && partition[0].0.name == "ID" {
10458 self.write_space();
10460 self.write_keyword("ID");
10461 self.write_space();
10462 self.generate_expression(&partition[0].1)?;
10463 } else {
10464 self.write("(");
10466 for (j, (key, value)) in partition.iter().enumerate() {
10467 if j > 0 {
10468 self.write(", ");
10469 }
10470 self.generate_identifier(key)?;
10471 self.write(" = ");
10472 self.generate_expression(value)?;
10473 }
10474 self.write(")");
10475 }
10476 }
10477 }
10478 AlterTableAction::Delete { where_clause } => {
10479 self.write_keyword("DELETE");
10480 self.write_space();
10481 self.write_keyword("WHERE");
10482 self.write_space();
10483 self.generate_expression(where_clause)?;
10484 }
10485 AlterTableAction::SwapWith(target) => {
10486 self.write_keyword("SWAP WITH");
10487 self.write_space();
10488 self.generate_table(target)?;
10489 }
10490 AlterTableAction::SetProperty { properties } => {
10491 use crate::dialects::DialectType;
10492 self.write_keyword("SET");
10493 let is_trino_presto = matches!(
10495 self.config.dialect,
10496 Some(DialectType::Trino) | Some(DialectType::Presto)
10497 );
10498 if is_trino_presto {
10499 self.write_space();
10500 self.write_keyword("PROPERTIES");
10501 }
10502 let eq = if is_trino_presto { " = " } else { "=" };
10503 for (i, (key, value)) in properties.iter().enumerate() {
10504 if i > 0 {
10505 self.write(",");
10506 }
10507 self.write_space();
10508 if key.contains(' ') {
10510 self.generate_string_literal(key)?;
10511 } else {
10512 self.write(key);
10513 }
10514 self.write(eq);
10515 self.generate_expression(value)?;
10516 }
10517 }
10518 AlterTableAction::UnsetProperty { properties } => {
10519 self.write_keyword("UNSET");
10520 for (i, name) in properties.iter().enumerate() {
10521 if i > 0 {
10522 self.write(",");
10523 }
10524 self.write_space();
10525 self.write(name);
10526 }
10527 }
10528 AlterTableAction::ClusterBy { expressions } => {
10529 self.write_keyword("CLUSTER BY");
10530 self.write(" (");
10531 for (i, expr) in expressions.iter().enumerate() {
10532 if i > 0 {
10533 self.write(", ");
10534 }
10535 self.generate_expression(expr)?;
10536 }
10537 self.write(")");
10538 }
10539 AlterTableAction::SetTag { expressions } => {
10540 self.write_keyword("SET TAG");
10541 for (i, (key, value)) in expressions.iter().enumerate() {
10542 if i > 0 {
10543 self.write(",");
10544 }
10545 self.write_space();
10546 self.write(key);
10547 self.write(" = ");
10548 self.generate_expression(value)?;
10549 }
10550 }
10551 AlterTableAction::UnsetTag { names } => {
10552 self.write_keyword("UNSET TAG");
10553 for (i, name) in names.iter().enumerate() {
10554 if i > 0 {
10555 self.write(",");
10556 }
10557 self.write_space();
10558 self.write(name);
10559 }
10560 }
10561 AlterTableAction::SetOptions { expressions } => {
10562 self.write_keyword("SET");
10563 self.write(" (");
10564 for (i, expr) in expressions.iter().enumerate() {
10565 if i > 0 {
10566 self.write(", ");
10567 }
10568 self.generate_expression(expr)?;
10569 }
10570 self.write(")");
10571 }
10572 AlterTableAction::AlterIndex { name, visible } => {
10573 self.write_keyword("ALTER INDEX");
10574 self.write_space();
10575 self.generate_identifier(name)?;
10576 self.write_space();
10577 if *visible {
10578 self.write_keyword("VISIBLE");
10579 } else {
10580 self.write_keyword("INVISIBLE");
10581 }
10582 }
10583 AlterTableAction::SetAttribute { attribute } => {
10584 self.write_keyword("SET");
10585 self.write_space();
10586 self.write_keyword(attribute);
10587 }
10588 AlterTableAction::SetStageFileFormat { options } => {
10589 self.write_keyword("SET");
10590 self.write_space();
10591 self.write_keyword("STAGE_FILE_FORMAT");
10592 self.write(" = (");
10593 if let Some(opts) = options {
10594 self.generate_space_separated_properties(opts)?;
10595 }
10596 self.write(")");
10597 }
10598 AlterTableAction::SetStageCopyOptions { options } => {
10599 self.write_keyword("SET");
10600 self.write_space();
10601 self.write_keyword("STAGE_COPY_OPTIONS");
10602 self.write(" = (");
10603 if let Some(opts) = options {
10604 self.generate_space_separated_properties(opts)?;
10605 }
10606 self.write(")");
10607 }
10608 AlterTableAction::AddColumns { columns, cascade } => {
10609 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
10612 if is_oracle {
10613 self.write_keyword("ADD");
10614 } else {
10615 self.write_keyword("ADD COLUMNS");
10616 }
10617 self.write(" (");
10618 for (i, col) in columns.iter().enumerate() {
10619 if i > 0 {
10620 self.write(", ");
10621 }
10622 self.generate_column_def(col)?;
10623 }
10624 self.write(")");
10625 if *cascade {
10626 self.write_space();
10627 self.write_keyword("CASCADE");
10628 }
10629 }
10630 AlterTableAction::ChangeColumn {
10631 old_name,
10632 new_name,
10633 data_type,
10634 comment,
10635 cascade,
10636 } => {
10637 use crate::dialects::DialectType;
10638 let is_spark = matches!(
10639 self.config.dialect,
10640 Some(DialectType::Spark) | Some(DialectType::Databricks)
10641 );
10642 let is_rename = old_name.name != new_name.name;
10643
10644 if is_spark {
10645 if is_rename {
10646 self.write_keyword("RENAME COLUMN");
10648 self.write_space();
10649 self.generate_identifier(old_name)?;
10650 self.write_space();
10651 self.write_keyword("TO");
10652 self.write_space();
10653 self.generate_identifier(new_name)?;
10654 } else if comment.is_some() {
10655 self.write_keyword("ALTER COLUMN");
10657 self.write_space();
10658 self.generate_identifier(old_name)?;
10659 self.write_space();
10660 self.write_keyword("COMMENT");
10661 self.write_space();
10662 self.write("'");
10663 self.write(comment.as_ref().unwrap());
10664 self.write("'");
10665 } else if data_type.is_some() {
10666 self.write_keyword("ALTER COLUMN");
10668 self.write_space();
10669 self.generate_identifier(old_name)?;
10670 self.write_space();
10671 self.write_keyword("TYPE");
10672 self.write_space();
10673 self.generate_data_type(data_type.as_ref().unwrap())?;
10674 } else {
10675 self.write_keyword("CHANGE COLUMN");
10677 self.write_space();
10678 self.generate_identifier(old_name)?;
10679 self.write_space();
10680 self.generate_identifier(new_name)?;
10681 }
10682 } else {
10683 if data_type.is_some() {
10685 self.write_keyword("CHANGE COLUMN");
10686 } else {
10687 self.write_keyword("CHANGE");
10688 }
10689 self.write_space();
10690 self.generate_identifier(old_name)?;
10691 self.write_space();
10692 self.generate_identifier(new_name)?;
10693 if let Some(ref dt) = data_type {
10694 self.write_space();
10695 self.generate_data_type(dt)?;
10696 }
10697 if let Some(ref c) = comment {
10698 self.write_space();
10699 self.write_keyword("COMMENT");
10700 self.write_space();
10701 self.write("'");
10702 self.write(c);
10703 self.write("'");
10704 }
10705 if *cascade {
10706 self.write_space();
10707 self.write_keyword("CASCADE");
10708 }
10709 }
10710 }
10711 AlterTableAction::AddPartition {
10712 partition,
10713 if_not_exists,
10714 location,
10715 } => {
10716 self.write_keyword("ADD");
10717 self.write_space();
10718 if *if_not_exists {
10719 self.write_keyword("IF NOT EXISTS");
10720 self.write_space();
10721 }
10722 self.generate_expression(partition)?;
10723 if let Some(ref loc) = location {
10724 self.write_space();
10725 self.write_keyword("LOCATION");
10726 self.write_space();
10727 self.generate_expression(loc)?;
10728 }
10729 }
10730 AlterTableAction::AlterSortKey {
10731 this,
10732 expressions,
10733 compound,
10734 } => {
10735 self.write_keyword("ALTER");
10737 if *compound {
10738 self.write_space();
10739 self.write_keyword("COMPOUND");
10740 }
10741 self.write_space();
10742 self.write_keyword("SORTKEY");
10743 self.write_space();
10744 if let Some(style) = this {
10745 self.write_keyword(style);
10746 } else if !expressions.is_empty() {
10747 self.write("(");
10748 for (i, expr) in expressions.iter().enumerate() {
10749 if i > 0 {
10750 self.write(", ");
10751 }
10752 self.generate_expression(expr)?;
10753 }
10754 self.write(")");
10755 }
10756 }
10757 AlterTableAction::AlterDistStyle { style, distkey } => {
10758 self.write_keyword("ALTER");
10760 self.write_space();
10761 self.write_keyword("DISTSTYLE");
10762 self.write_space();
10763 self.write_keyword(style);
10764 if let Some(col) = distkey {
10765 self.write_space();
10766 self.write_keyword("DISTKEY");
10767 self.write_space();
10768 self.generate_identifier(col)?;
10769 }
10770 }
10771 AlterTableAction::SetTableProperties { properties } => {
10772 self.write_keyword("SET TABLE PROPERTIES");
10774 self.write(" (");
10775 for (i, (key, value)) in properties.iter().enumerate() {
10776 if i > 0 {
10777 self.write(", ");
10778 }
10779 self.generate_expression(key)?;
10780 self.write(" = ");
10781 self.generate_expression(value)?;
10782 }
10783 self.write(")");
10784 }
10785 AlterTableAction::SetLocation { location } => {
10786 self.write_keyword("SET LOCATION");
10788 self.write_space();
10789 self.write("'");
10790 self.write(location);
10791 self.write("'");
10792 }
10793 AlterTableAction::SetFileFormat { format } => {
10794 self.write_keyword("SET FILE FORMAT");
10796 self.write_space();
10797 self.write_keyword(format);
10798 }
10799 AlterTableAction::ReplacePartition { partition, source } => {
10800 self.write_keyword("REPLACE PARTITION");
10802 self.write_space();
10803 self.generate_expression(partition)?;
10804 if let Some(src) = source {
10805 self.write_space();
10806 self.write_keyword("FROM");
10807 self.write_space();
10808 self.generate_expression(src)?;
10809 }
10810 }
10811 AlterTableAction::Raw { sql } => {
10812 self.write(sql);
10813 }
10814 }
10815 Ok(())
10816 }
10817
10818 fn generate_alter_column_action(&mut self, action: &AlterColumnAction) -> Result<()> {
10819 match action {
10820 AlterColumnAction::SetDataType {
10821 data_type,
10822 using,
10823 collate,
10824 } => {
10825 use crate::dialects::DialectType;
10826 let is_no_prefix = matches!(
10831 self.config.dialect,
10832 Some(DialectType::TSQL) | Some(DialectType::Fabric) | Some(DialectType::Hive)
10833 );
10834 let is_type_only = matches!(
10835 self.config.dialect,
10836 Some(DialectType::Redshift)
10837 | Some(DialectType::Spark)
10838 | Some(DialectType::Databricks)
10839 );
10840 if is_type_only {
10841 self.write_keyword("TYPE");
10842 self.write_space();
10843 } else if !is_no_prefix {
10844 self.write_keyword("SET DATA TYPE");
10845 self.write_space();
10846 }
10847 self.generate_data_type(data_type)?;
10848 if let Some(ref collation) = collate {
10849 self.write_space();
10850 self.write_keyword("COLLATE");
10851 self.write_space();
10852 self.write(collation);
10853 }
10854 if let Some(ref using_expr) = using {
10855 self.write_space();
10856 self.write_keyword("USING");
10857 self.write_space();
10858 self.generate_expression(using_expr)?;
10859 }
10860 }
10861 AlterColumnAction::SetDefault(expr) => {
10862 self.write_keyword("SET DEFAULT");
10863 self.write_space();
10864 self.generate_expression(expr)?;
10865 }
10866 AlterColumnAction::DropDefault => {
10867 self.write_keyword("DROP DEFAULT");
10868 }
10869 AlterColumnAction::SetNotNull => {
10870 self.write_keyword("SET NOT NULL");
10871 }
10872 AlterColumnAction::DropNotNull => {
10873 self.write_keyword("DROP NOT NULL");
10874 }
10875 AlterColumnAction::Comment(comment) => {
10876 self.write_keyword("COMMENT");
10877 self.write_space();
10878 self.generate_string_literal(comment)?;
10879 }
10880 AlterColumnAction::SetVisible => {
10881 self.write_keyword("SET VISIBLE");
10882 }
10883 AlterColumnAction::SetInvisible => {
10884 self.write_keyword("SET INVISIBLE");
10885 }
10886 }
10887 Ok(())
10888 }
10889
10890 fn generate_create_index(&mut self, ci: &CreateIndex) -> Result<()> {
10891 self.write_keyword("CREATE");
10892
10893 if ci.unique {
10894 self.write_space();
10895 self.write_keyword("UNIQUE");
10896 }
10897
10898 if let Some(ref clustered) = ci.clustered {
10900 self.write_space();
10901 self.write_keyword(clustered);
10902 }
10903
10904 self.write_space();
10905 self.write_keyword("INDEX");
10906
10907 if ci.concurrently {
10909 self.write_space();
10910 self.write_keyword("CONCURRENTLY");
10911 }
10912
10913 if ci.if_not_exists {
10914 self.write_space();
10915 self.write_keyword("IF NOT EXISTS");
10916 }
10917
10918 if !ci.name.name.is_empty() {
10920 self.write_space();
10921 self.generate_identifier(&ci.name)?;
10922 }
10923 self.write_space();
10924 self.write_keyword("ON");
10925 if matches!(self.config.dialect, Some(DialectType::Hive)) {
10927 self.write_space();
10928 self.write_keyword("TABLE");
10929 }
10930 self.write_space();
10931 self.generate_table(&ci.table)?;
10932
10933 if !ci.columns.is_empty() || ci.using.is_some() {
10936 let space_before_paren = false;
10937
10938 if let Some(ref using) = ci.using {
10939 self.write_space();
10940 self.write_keyword("USING");
10941 self.write_space();
10942 self.write(using);
10943 if space_before_paren {
10944 self.write(" (");
10945 } else {
10946 self.write("(");
10947 }
10948 } else {
10949 if space_before_paren {
10950 self.write(" (");
10951 } else {
10952 self.write("(");
10953 }
10954 }
10955 for (i, col) in ci.columns.iter().enumerate() {
10956 if i > 0 {
10957 self.write(", ");
10958 }
10959 self.generate_identifier(&col.column)?;
10960 if let Some(ref opclass) = col.opclass {
10961 self.write_space();
10962 self.write(opclass);
10963 }
10964 if col.desc {
10965 self.write_space();
10966 self.write_keyword("DESC");
10967 } else if col.asc {
10968 self.write_space();
10969 self.write_keyword("ASC");
10970 }
10971 if let Some(nulls_first) = col.nulls_first {
10972 self.write_space();
10973 self.write_keyword("NULLS");
10974 self.write_space();
10975 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
10976 }
10977 }
10978 self.write(")");
10979 }
10980
10981 if !ci.include_columns.is_empty() {
10983 self.write_space();
10984 self.write_keyword("INCLUDE");
10985 self.write(" (");
10986 for (i, col) in ci.include_columns.iter().enumerate() {
10987 if i > 0 {
10988 self.write(", ");
10989 }
10990 self.generate_identifier(col)?;
10991 }
10992 self.write(")");
10993 }
10994
10995 if !ci.with_options.is_empty() {
10997 self.write_space();
10998 self.write_keyword("WITH");
10999 self.write(" (");
11000 for (i, (key, value)) in ci.with_options.iter().enumerate() {
11001 if i > 0 {
11002 self.write(", ");
11003 }
11004 self.write(key);
11005 self.write("=");
11006 self.write(value);
11007 }
11008 self.write(")");
11009 }
11010
11011 if let Some(ref where_clause) = ci.where_clause {
11013 self.write_space();
11014 self.write_keyword("WHERE");
11015 self.write_space();
11016 self.generate_expression(where_clause)?;
11017 }
11018
11019 if let Some(ref on_fg) = ci.on_filegroup {
11021 self.write_space();
11022 self.write_keyword("ON");
11023 self.write_space();
11024 self.write(on_fg);
11025 }
11026
11027 Ok(())
11028 }
11029
11030 fn generate_drop_index(&mut self, di: &DropIndex) -> Result<()> {
11031 self.write_keyword("DROP INDEX");
11032
11033 if di.concurrently {
11034 self.write_space();
11035 self.write_keyword("CONCURRENTLY");
11036 }
11037
11038 if di.if_exists {
11039 self.write_space();
11040 self.write_keyword("IF EXISTS");
11041 }
11042
11043 self.write_space();
11044 self.generate_identifier(&di.name)?;
11045
11046 if let Some(ref table) = di.table {
11047 self.write_space();
11048 self.write_keyword("ON");
11049 self.write_space();
11050 self.generate_table(table)?;
11051 }
11052
11053 Ok(())
11054 }
11055
11056 fn generate_create_view(&mut self, cv: &CreateView) -> Result<()> {
11057 self.write_keyword("CREATE");
11058
11059 if let Some(ref algorithm) = cv.algorithm {
11061 self.write_space();
11062 self.write_keyword("ALGORITHM");
11063 self.write("=");
11064 self.write_keyword(algorithm);
11065 }
11066
11067 if let Some(ref definer) = cv.definer {
11069 self.write_space();
11070 self.write_keyword("DEFINER");
11071 self.write("=");
11072 self.write(definer);
11073 }
11074
11075 if cv.security_sql_style && !cv.security_after_name {
11077 if let Some(ref security) = cv.security {
11078 self.write_space();
11079 self.write_keyword("SQL SECURITY");
11080 self.write_space();
11081 match security {
11082 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
11083 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
11084 FunctionSecurity::None => self.write_keyword("NONE"),
11085 }
11086 }
11087 }
11088
11089 if cv.or_alter {
11090 self.write_space();
11091 self.write_keyword("OR ALTER");
11092 } else if cv.or_replace {
11093 self.write_space();
11094 self.write_keyword("OR REPLACE");
11095 }
11096
11097 if cv.temporary {
11098 self.write_space();
11099 self.write_keyword("TEMPORARY");
11100 }
11101
11102 if cv.materialized {
11103 self.write_space();
11104 self.write_keyword("MATERIALIZED");
11105 }
11106
11107 if cv.secure {
11109 self.write_space();
11110 self.write_keyword("SECURE");
11111 }
11112
11113 self.write_space();
11114 self.write_keyword("VIEW");
11115
11116 if cv.if_not_exists {
11117 self.write_space();
11118 self.write_keyword("IF NOT EXISTS");
11119 }
11120
11121 self.write_space();
11122 self.generate_table(&cv.name)?;
11123
11124 if let Some(ref on_cluster) = cv.on_cluster {
11126 self.write_space();
11127 self.generate_on_cluster(on_cluster)?;
11128 }
11129
11130 if let Some(ref to_table) = cv.to_table {
11132 self.write_space();
11133 self.write_keyword("TO");
11134 self.write_space();
11135 self.generate_table(to_table)?;
11136 }
11137
11138 if !cv.materialized {
11141 if !cv.columns.is_empty() {
11143 self.write(" (");
11144 for (i, col) in cv.columns.iter().enumerate() {
11145 if i > 0 {
11146 self.write(", ");
11147 }
11148 self.generate_identifier(&col.name)?;
11149 if !col.options.is_empty() {
11151 self.write_space();
11152 self.generate_options_clause(&col.options)?;
11153 }
11154 if let Some(ref comment) = col.comment {
11155 self.write_space();
11156 self.write_keyword("COMMENT");
11157 self.write_space();
11158 self.generate_string_literal(comment)?;
11159 }
11160 }
11161 self.write(")");
11162 }
11163
11164 if !cv.security_sql_style || cv.security_after_name {
11167 if let Some(ref security) = cv.security {
11168 self.write_space();
11169 if cv.security_sql_style {
11170 self.write_keyword("SQL SECURITY");
11171 } else {
11172 self.write_keyword("SECURITY");
11173 }
11174 self.write_space();
11175 match security {
11176 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
11177 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
11178 FunctionSecurity::None => self.write_keyword("NONE"),
11179 }
11180 }
11181 }
11182
11183 if cv.copy_grants {
11185 self.write_space();
11186 self.write_keyword("COPY GRANTS");
11187 }
11188 } else {
11189 if cv.copy_grants {
11191 self.write_space();
11192 self.write_keyword("COPY GRANTS");
11193 }
11194
11195 if let Some(ref schema) = cv.schema {
11197 self.write(" (");
11198 for (i, expr) in schema.expressions.iter().enumerate() {
11199 if i > 0 {
11200 self.write(", ");
11201 }
11202 self.generate_expression(expr)?;
11203 }
11204 self.write(")");
11205 } else if !cv.columns.is_empty() {
11206 self.write(" (");
11208 for (i, col) in cv.columns.iter().enumerate() {
11209 if i > 0 {
11210 self.write(", ");
11211 }
11212 self.generate_identifier(&col.name)?;
11213 if !col.options.is_empty() {
11215 self.write_space();
11216 self.generate_options_clause(&col.options)?;
11217 }
11218 if let Some(ref comment) = col.comment {
11219 self.write_space();
11220 self.write_keyword("COMMENT");
11221 self.write_space();
11222 self.generate_string_literal(comment)?;
11223 }
11224 }
11225 self.write(")");
11226 }
11227
11228 if let Some(ref unique_key) = cv.unique_key {
11230 self.write_space();
11231 self.write_keyword("KEY");
11232 self.write(" (");
11233 for (i, expr) in unique_key.expressions.iter().enumerate() {
11234 if i > 0 {
11235 self.write(", ");
11236 }
11237 self.generate_expression(expr)?;
11238 }
11239 self.write(")");
11240 }
11241 }
11242
11243 if let Some(ref row_access_policy) = cv.row_access_policy {
11244 self.write_space();
11245 self.write_keyword("WITH");
11246 self.write_space();
11247 self.write(row_access_policy);
11248 }
11249
11250 if let Some(ref comment) = cv.comment {
11252 self.write_space();
11253 self.write_keyword("COMMENT");
11254 self.write("=");
11255 self.generate_string_literal(comment)?;
11256 }
11257
11258 if !cv.tags.is_empty() {
11260 self.write_space();
11261 self.write_keyword("TAG");
11262 self.write(" (");
11263 for (i, (name, value)) in cv.tags.iter().enumerate() {
11264 if i > 0 {
11265 self.write(", ");
11266 }
11267 self.write(name);
11268 self.write("='");
11269 self.write(value);
11270 self.write("'");
11271 }
11272 self.write(")");
11273 }
11274
11275 if !cv.options.is_empty() {
11277 self.write_space();
11278 self.generate_options_clause(&cv.options)?;
11279 }
11280
11281 if let Some(ref build) = cv.build {
11283 self.write_space();
11284 self.write_keyword("BUILD");
11285 self.write_space();
11286 self.write_keyword(build);
11287 }
11288
11289 if let Some(ref refresh) = cv.refresh {
11291 self.write_space();
11292 self.generate_refresh_trigger_property(refresh)?;
11293 }
11294
11295 if let Some(auto_refresh) = cv.auto_refresh {
11297 self.write_space();
11298 self.write_keyword("AUTO REFRESH");
11299 self.write_space();
11300 if auto_refresh {
11301 self.write_keyword("YES");
11302 } else {
11303 self.write_keyword("NO");
11304 }
11305 }
11306
11307 for prop in &cv.table_properties {
11309 self.write_space();
11310 self.generate_expression(prop)?;
11311 }
11312
11313 if !matches!(&cv.query, Expression::Null(_)) {
11315 self.write_space();
11316 self.write_keyword("AS");
11317 self.write_space();
11318
11319 if let Some(ref mode) = cv.locking_mode {
11321 self.write_keyword("LOCKING");
11322 self.write_space();
11323 self.write_keyword(mode);
11324 if let Some(ref access) = cv.locking_access {
11325 self.write_space();
11326 self.write_keyword("FOR");
11327 self.write_space();
11328 self.write_keyword(access);
11329 }
11330 self.write_space();
11331 }
11332
11333 if cv.query_parenthesized {
11334 self.write("(");
11335 }
11336 self.generate_expression(&cv.query)?;
11337 if cv.query_parenthesized {
11338 self.write(")");
11339 }
11340 }
11341
11342 if cv.no_schema_binding {
11344 self.write_space();
11345 self.write_keyword("WITH NO SCHEMA BINDING");
11346 }
11347
11348 Ok(())
11349 }
11350
11351 fn generate_drop_view(&mut self, dv: &DropView) -> Result<()> {
11352 self.write_keyword("DROP");
11353
11354 if dv.materialized {
11355 self.write_space();
11356 self.write_keyword("MATERIALIZED");
11357 }
11358
11359 self.write_space();
11360 self.write_keyword("VIEW");
11361
11362 if dv.if_exists {
11363 self.write_space();
11364 self.write_keyword("IF EXISTS");
11365 }
11366
11367 self.write_space();
11368 self.generate_table(&dv.name)?;
11369
11370 Ok(())
11371 }
11372
11373 fn generate_truncate(&mut self, tr: &Truncate) -> Result<()> {
11374 match tr.target {
11375 TruncateTarget::Database => self.write_keyword("TRUNCATE DATABASE"),
11376 TruncateTarget::Table => self.write_keyword("TRUNCATE TABLE"),
11377 }
11378 if tr.if_exists {
11379 self.write_space();
11380 self.write_keyword("IF EXISTS");
11381 }
11382 self.write_space();
11383 self.generate_table(&tr.table)?;
11384
11385 if let Some(ref on_cluster) = tr.on_cluster {
11387 self.write_space();
11388 self.generate_on_cluster(on_cluster)?;
11389 }
11390
11391 if !tr.extra_tables.is_empty() {
11393 let skip_first = if let Some(first) = tr.extra_tables.first() {
11395 first.table.name == tr.table.name && first.star
11396 } else {
11397 false
11398 };
11399
11400 let strip_star = matches!(
11402 self.config.dialect,
11403 Some(crate::dialects::DialectType::PostgreSQL)
11404 | Some(crate::dialects::DialectType::Redshift)
11405 );
11406 if skip_first && !strip_star {
11407 self.write("*");
11408 }
11409
11410 for (i, entry) in tr.extra_tables.iter().enumerate() {
11412 if i == 0 && skip_first {
11413 continue; }
11415 self.write(", ");
11416 self.generate_table(&entry.table)?;
11417 if entry.star && !strip_star {
11418 self.write("*");
11419 }
11420 }
11421 }
11422
11423 if let Some(identity) = &tr.identity {
11425 self.write_space();
11426 match identity {
11427 TruncateIdentity::Restart => self.write_keyword("RESTART IDENTITY"),
11428 TruncateIdentity::Continue => self.write_keyword("CONTINUE IDENTITY"),
11429 }
11430 }
11431
11432 if tr.cascade {
11433 self.write_space();
11434 self.write_keyword("CASCADE");
11435 }
11436
11437 if tr.restrict {
11438 self.write_space();
11439 self.write_keyword("RESTRICT");
11440 }
11441
11442 if let Some(ref partition) = tr.partition {
11444 self.write_space();
11445 self.generate_expression(partition)?;
11446 }
11447
11448 Ok(())
11449 }
11450
11451 fn generate_use(&mut self, u: &Use) -> Result<()> {
11452 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
11454 self.write_keyword("DATABASE");
11455 self.write_space();
11456 self.generate_identifier(&u.this)?;
11457 return Ok(());
11458 }
11459
11460 self.write_keyword("USE");
11461
11462 if let Some(kind) = &u.kind {
11463 self.write_space();
11464 match kind {
11465 UseKind::Database => self.write_keyword("DATABASE"),
11466 UseKind::Schema => self.write_keyword("SCHEMA"),
11467 UseKind::Role => self.write_keyword("ROLE"),
11468 UseKind::Warehouse => self.write_keyword("WAREHOUSE"),
11469 UseKind::Catalog => self.write_keyword("CATALOG"),
11470 UseKind::SecondaryRoles => self.write_keyword("SECONDARY ROLES"),
11471 }
11472 }
11473
11474 self.write_space();
11475 if matches!(&u.kind, Some(UseKind::SecondaryRoles)) {
11478 self.write(&u.this.name);
11479 } else {
11480 self.generate_identifier(&u.this)?;
11481 }
11482 Ok(())
11483 }
11484
11485 fn generate_cache(&mut self, c: &Cache) -> Result<()> {
11486 self.write_keyword("CACHE");
11487 if c.lazy {
11488 self.write_space();
11489 self.write_keyword("LAZY");
11490 }
11491 self.write_space();
11492 self.write_keyword("TABLE");
11493 self.write_space();
11494 self.generate_identifier(&c.table)?;
11495
11496 if !c.options.is_empty() {
11498 self.write_space();
11499 self.write_keyword("OPTIONS");
11500 self.write("(");
11501 for (i, (key, value)) in c.options.iter().enumerate() {
11502 if i > 0 {
11503 self.write(", ");
11504 }
11505 self.generate_expression(key)?;
11506 self.write(" = ");
11507 self.generate_expression(value)?;
11508 }
11509 self.write(")");
11510 }
11511
11512 if let Some(query) = &c.query {
11514 self.write_space();
11515 self.write_keyword("AS");
11516 self.write_space();
11517 self.generate_expression(query)?;
11518 }
11519
11520 Ok(())
11521 }
11522
11523 fn generate_uncache(&mut self, u: &Uncache) -> Result<()> {
11524 self.write_keyword("UNCACHE TABLE");
11525 if u.if_exists {
11526 self.write_space();
11527 self.write_keyword("IF EXISTS");
11528 }
11529 self.write_space();
11530 self.generate_identifier(&u.table)?;
11531 Ok(())
11532 }
11533
11534 fn generate_load_data(&mut self, l: &LoadData) -> Result<()> {
11535 self.write_keyword("LOAD DATA");
11536 if l.local {
11537 self.write_space();
11538 self.write_keyword("LOCAL");
11539 }
11540 self.write_space();
11541 self.write_keyword("INPATH");
11542 self.write_space();
11543 self.write("'");
11544 self.write(&l.inpath);
11545 self.write("'");
11546
11547 if l.overwrite {
11548 self.write_space();
11549 self.write_keyword("OVERWRITE");
11550 }
11551
11552 self.write_space();
11553 self.write_keyword("INTO TABLE");
11554 self.write_space();
11555 self.generate_expression(&l.table)?;
11556
11557 if !l.partition.is_empty() {
11559 self.write_space();
11560 self.write_keyword("PARTITION");
11561 self.write("(");
11562 for (i, (col, val)) in l.partition.iter().enumerate() {
11563 if i > 0 {
11564 self.write(", ");
11565 }
11566 self.generate_identifier(col)?;
11567 self.write(" = ");
11568 self.generate_expression(val)?;
11569 }
11570 self.write(")");
11571 }
11572
11573 if let Some(fmt) = &l.input_format {
11575 self.write_space();
11576 self.write_keyword("INPUTFORMAT");
11577 self.write_space();
11578 self.write("'");
11579 self.write(fmt);
11580 self.write("'");
11581 }
11582
11583 if let Some(serde) = &l.serde {
11585 self.write_space();
11586 self.write_keyword("SERDE");
11587 self.write_space();
11588 self.write("'");
11589 self.write(serde);
11590 self.write("'");
11591 }
11592
11593 Ok(())
11594 }
11595
11596 fn generate_pragma(&mut self, p: &Pragma) -> Result<()> {
11597 self.write_keyword("PRAGMA");
11598 self.write_space();
11599
11600 if let Some(schema) = &p.schema {
11602 self.generate_identifier(schema)?;
11603 self.write(".");
11604 }
11605
11606 self.generate_identifier(&p.name)?;
11608
11609 if p.use_assignment_syntax {
11611 self.write(" = ");
11612 if let Some(value) = &p.value {
11613 self.generate_expression(value)?;
11614 } else if let Some(arg) = p.args.first() {
11615 self.generate_expression(arg)?;
11616 }
11617 } else if !p.args.is_empty() {
11618 self.write("(");
11619 for (i, arg) in p.args.iter().enumerate() {
11620 if i > 0 {
11621 self.write(", ");
11622 }
11623 self.generate_expression(arg)?;
11624 }
11625 self.write(")");
11626 }
11627
11628 Ok(())
11629 }
11630
11631 fn generate_grant(&mut self, g: &Grant) -> Result<()> {
11632 self.write_keyword("GRANT");
11633 self.write_space();
11634
11635 for (i, privilege) in g.privileges.iter().enumerate() {
11637 if i > 0 {
11638 self.write(", ");
11639 }
11640 self.write_keyword(&privilege.name);
11641 if !privilege.columns.is_empty() {
11643 self.write("(");
11644 for (j, col) in privilege.columns.iter().enumerate() {
11645 if j > 0 {
11646 self.write(", ");
11647 }
11648 self.write(col);
11649 }
11650 self.write(")");
11651 }
11652 }
11653
11654 self.write_space();
11655 self.write_keyword("ON");
11656 self.write_space();
11657
11658 if let Some(kind) = &g.kind {
11660 self.write_keyword(kind);
11661 self.write_space();
11662 }
11663
11664 {
11666 use crate::dialects::DialectType;
11667 let should_upper = matches!(
11668 self.config.dialect,
11669 Some(DialectType::PostgreSQL)
11670 | Some(DialectType::CockroachDB)
11671 | Some(DialectType::Materialize)
11672 | Some(DialectType::RisingWave)
11673 ) && (g.kind.as_deref() == Some("FUNCTION")
11674 || g.kind.as_deref() == Some("PROCEDURE"));
11675 if should_upper {
11676 use crate::expressions::Identifier;
11677 let upper_id = Identifier {
11678 name: g.securable.name.to_ascii_uppercase(),
11679 quoted: g.securable.quoted,
11680 ..g.securable.clone()
11681 };
11682 self.generate_identifier(&upper_id)?;
11683 } else {
11684 self.generate_identifier(&g.securable)?;
11685 }
11686 }
11687
11688 if !g.function_params.is_empty() {
11690 self.write("(");
11691 for (i, param) in g.function_params.iter().enumerate() {
11692 if i > 0 {
11693 self.write(", ");
11694 }
11695 self.write(param);
11696 }
11697 self.write(")");
11698 }
11699
11700 self.write_space();
11701 self.write_keyword("TO");
11702 self.write_space();
11703
11704 for (i, principal) in g.principals.iter().enumerate() {
11706 if i > 0 {
11707 self.write(", ");
11708 }
11709 if principal.is_role {
11710 self.write_keyword("ROLE");
11711 self.write_space();
11712 } else if principal.is_group {
11713 self.write_keyword("GROUP");
11714 self.write_space();
11715 } else if principal.is_share {
11716 self.write_keyword("SHARE");
11717 self.write_space();
11718 }
11719 self.generate_identifier(&principal.name)?;
11720 }
11721
11722 if g.grant_option {
11724 self.write_space();
11725 self.write_keyword("WITH GRANT OPTION");
11726 }
11727
11728 if let Some(ref principal) = g.as_principal {
11730 self.write_space();
11731 self.write_keyword("AS");
11732 self.write_space();
11733 self.generate_identifier(principal)?;
11734 }
11735
11736 Ok(())
11737 }
11738
11739 fn generate_revoke(&mut self, r: &Revoke) -> Result<()> {
11740 self.write_keyword("REVOKE");
11741 self.write_space();
11742
11743 if r.grant_option {
11745 self.write_keyword("GRANT OPTION FOR");
11746 self.write_space();
11747 }
11748
11749 for (i, privilege) in r.privileges.iter().enumerate() {
11751 if i > 0 {
11752 self.write(", ");
11753 }
11754 self.write_keyword(&privilege.name);
11755 if !privilege.columns.is_empty() {
11757 self.write("(");
11758 for (j, col) in privilege.columns.iter().enumerate() {
11759 if j > 0 {
11760 self.write(", ");
11761 }
11762 self.write(col);
11763 }
11764 self.write(")");
11765 }
11766 }
11767
11768 self.write_space();
11769 self.write_keyword("ON");
11770 self.write_space();
11771
11772 if let Some(kind) = &r.kind {
11774 self.write_keyword(kind);
11775 self.write_space();
11776 }
11777
11778 {
11780 use crate::dialects::DialectType;
11781 let should_upper = matches!(
11782 self.config.dialect,
11783 Some(DialectType::PostgreSQL)
11784 | Some(DialectType::CockroachDB)
11785 | Some(DialectType::Materialize)
11786 | Some(DialectType::RisingWave)
11787 ) && (r.kind.as_deref() == Some("FUNCTION")
11788 || r.kind.as_deref() == Some("PROCEDURE"));
11789 if should_upper {
11790 use crate::expressions::Identifier;
11791 let upper_id = Identifier {
11792 name: r.securable.name.to_ascii_uppercase(),
11793 quoted: r.securable.quoted,
11794 ..r.securable.clone()
11795 };
11796 self.generate_identifier(&upper_id)?;
11797 } else {
11798 self.generate_identifier(&r.securable)?;
11799 }
11800 }
11801
11802 if !r.function_params.is_empty() {
11804 self.write("(");
11805 for (i, param) in r.function_params.iter().enumerate() {
11806 if i > 0 {
11807 self.write(", ");
11808 }
11809 self.write(param);
11810 }
11811 self.write(")");
11812 }
11813
11814 self.write_space();
11815 self.write_keyword("FROM");
11816 self.write_space();
11817
11818 for (i, principal) in r.principals.iter().enumerate() {
11820 if i > 0 {
11821 self.write(", ");
11822 }
11823 if principal.is_role {
11824 self.write_keyword("ROLE");
11825 self.write_space();
11826 } else if principal.is_group {
11827 self.write_keyword("GROUP");
11828 self.write_space();
11829 } else if principal.is_share {
11830 self.write_keyword("SHARE");
11831 self.write_space();
11832 }
11833 self.generate_identifier(&principal.name)?;
11834 }
11835
11836 if r.cascade {
11838 self.write_space();
11839 self.write_keyword("CASCADE");
11840 } else if r.restrict {
11841 self.write_space();
11842 self.write_keyword("RESTRICT");
11843 }
11844
11845 Ok(())
11846 }
11847
11848 fn generate_comment(&mut self, c: &Comment) -> Result<()> {
11849 self.write_keyword("COMMENT");
11850
11851 if c.exists {
11853 self.write_space();
11854 self.write_keyword("IF EXISTS");
11855 }
11856
11857 self.write_space();
11858 self.write_keyword("ON");
11859
11860 if c.materialized {
11862 self.write_space();
11863 self.write_keyword("MATERIALIZED");
11864 }
11865
11866 self.write_space();
11867 self.write_keyword(&c.kind);
11868 self.write_space();
11869
11870 self.generate_expression(&c.this)?;
11872
11873 self.write_space();
11874 self.write_keyword("IS");
11875 self.write_space();
11876
11877 self.generate_expression(&c.expression)?;
11879
11880 Ok(())
11881 }
11882
11883 fn generate_set_statement(&mut self, s: &SetStatement) -> Result<()> {
11884 self.write_keyword("SET");
11885
11886 for (i, item) in s.items.iter().enumerate() {
11887 if i > 0 {
11888 self.write(",");
11889 }
11890 self.write_space();
11891
11892 let has_variable_kind = item.kind.as_deref() == Some("VARIABLE");
11894 if let Some(ref kind) = item.kind {
11895 if has_variable_kind {
11899 if matches!(
11900 self.config.dialect,
11901 Some(DialectType::Spark | DialectType::Databricks | DialectType::DuckDB)
11902 ) {
11903 self.write_keyword("VARIABLE");
11904 self.write_space();
11905 }
11906 } else {
11907 self.write_keyword(kind);
11908 self.write_space();
11909 }
11910 }
11911
11912 let name_str = match &item.name {
11914 Expression::Identifier(id) => Some(id.name.as_str()),
11915 _ => None,
11916 };
11917
11918 let is_transaction = name_str == Some("TRANSACTION");
11919 let is_character_set = name_str == Some("CHARACTER SET");
11920 let is_names = name_str == Some("NAMES");
11921 let is_collate = name_str == Some("COLLATE");
11922 let is_value_only =
11923 matches!(&item.value, Expression::Identifier(id) if id.name.is_empty());
11924
11925 if is_transaction {
11926 self.write_keyword("TRANSACTION");
11928 if let Expression::Identifier(id) = &item.value {
11929 if !id.name.is_empty() {
11930 self.write_space();
11931 self.write(&id.name);
11932 }
11933 }
11934 } else if is_character_set {
11935 self.write_keyword("CHARACTER SET");
11937 self.write_space();
11938 self.generate_set_value(&item.value)?;
11939 } else if is_names {
11940 self.write_keyword("NAMES");
11942 self.write_space();
11943 self.generate_set_value(&item.value)?;
11944 } else if is_collate {
11945 self.write_keyword("COLLATE");
11947 self.write_space();
11948 self.generate_set_value(&item.value)?;
11949 } else if has_variable_kind {
11950 if let Some(ns) = name_str {
11953 self.write(ns);
11954 } else {
11955 self.generate_expression(&item.name)?;
11956 }
11957 self.write(" = ");
11958 self.generate_set_value(&item.value)?;
11959 } else if is_value_only {
11960 self.generate_expression(&item.name)?;
11962 } else if item.no_equals && matches!(self.config.dialect, Some(DialectType::TSQL)) {
11963 self.generate_expression(&item.name)?;
11965 self.write_space();
11966 self.generate_set_value(&item.value)?;
11967 } else {
11968 match &item.name {
11971 Expression::Identifier(id) => {
11972 self.write(&id.name);
11973 }
11974 _ => {
11975 self.generate_expression(&item.name)?;
11976 }
11977 }
11978 self.write(" = ");
11979 self.generate_set_value(&item.value)?;
11980 }
11981 }
11982
11983 Ok(())
11984 }
11985
11986 fn generate_set_value(&mut self, value: &Expression) -> Result<()> {
11989 if let Expression::Identifier(id) = value {
11990 match id.name.as_str() {
11991 "DEFAULT" | "ON" | "OFF" => {
11992 self.write_keyword(&id.name);
11993 return Ok(());
11994 }
11995 _ => {}
11996 }
11997 }
11998 self.generate_expression(value)
11999 }
12000
12001 fn generate_alter_view(&mut self, av: &AlterView) -> Result<()> {
12004 self.write_keyword("ALTER");
12005 if let Some(ref algorithm) = av.algorithm {
12007 self.write_space();
12008 self.write_keyword("ALGORITHM");
12009 self.write(" = ");
12010 self.write_keyword(algorithm);
12011 }
12012 if let Some(ref definer) = av.definer {
12013 self.write_space();
12014 self.write_keyword("DEFINER");
12015 self.write(" = ");
12016 self.write(definer);
12017 }
12018 if let Some(ref sql_security) = av.sql_security {
12019 self.write_space();
12020 self.write_keyword("SQL SECURITY");
12021 self.write(" = ");
12022 self.write_keyword(sql_security);
12023 }
12024 self.write_space();
12025 self.write_keyword("VIEW");
12026 self.write_space();
12027 self.generate_table(&av.name)?;
12028
12029 if !av.columns.is_empty() {
12031 self.write(" (");
12032 for (i, col) in av.columns.iter().enumerate() {
12033 if i > 0 {
12034 self.write(", ");
12035 }
12036 self.generate_identifier(&col.name)?;
12037 if let Some(ref comment) = col.comment {
12038 self.write_space();
12039 self.write_keyword("COMMENT");
12040 self.write(" ");
12041 self.generate_string_literal(comment)?;
12042 }
12043 }
12044 self.write(")");
12045 }
12046
12047 if let Some(ref opt) = av.with_option {
12049 self.write_space();
12050 self.write_keyword("WITH");
12051 self.write_space();
12052 self.write_keyword(opt);
12053 }
12054
12055 for action in &av.actions {
12056 self.write_space();
12057 match action {
12058 AlterViewAction::Rename(new_name) => {
12059 self.write_keyword("RENAME TO");
12060 self.write_space();
12061 self.generate_table(new_name)?;
12062 }
12063 AlterViewAction::OwnerTo(owner) => {
12064 self.write_keyword("OWNER TO");
12065 self.write_space();
12066 self.generate_identifier(owner)?;
12067 }
12068 AlterViewAction::SetSchema(schema) => {
12069 self.write_keyword("SET SCHEMA");
12070 self.write_space();
12071 self.generate_identifier(schema)?;
12072 }
12073 AlterViewAction::SetAuthorization(auth) => {
12074 self.write_keyword("SET AUTHORIZATION");
12075 self.write_space();
12076 self.write(auth);
12077 }
12078 AlterViewAction::AlterColumn { name, action } => {
12079 self.write_keyword("ALTER COLUMN");
12080 self.write_space();
12081 self.generate_identifier(name)?;
12082 self.write_space();
12083 self.generate_alter_column_action(action)?;
12084 }
12085 AlterViewAction::AsSelect(query) => {
12086 self.write_keyword("AS");
12087 self.write_space();
12088 self.generate_expression(query)?;
12089 }
12090 AlterViewAction::SetTblproperties(props) => {
12091 self.write_keyword("SET TBLPROPERTIES");
12092 self.write(" (");
12093 for (i, (key, value)) in props.iter().enumerate() {
12094 if i > 0 {
12095 self.write(", ");
12096 }
12097 self.generate_string_literal(key)?;
12098 self.write("=");
12099 self.generate_string_literal(value)?;
12100 }
12101 self.write(")");
12102 }
12103 AlterViewAction::UnsetTblproperties(keys) => {
12104 self.write_keyword("UNSET TBLPROPERTIES");
12105 self.write(" (");
12106 for (i, key) in keys.iter().enumerate() {
12107 if i > 0 {
12108 self.write(", ");
12109 }
12110 self.generate_string_literal(key)?;
12111 }
12112 self.write(")");
12113 }
12114 }
12115 }
12116
12117 Ok(())
12118 }
12119
12120 fn generate_alter_index(&mut self, ai: &AlterIndex) -> Result<()> {
12121 self.write_keyword("ALTER INDEX");
12122 self.write_space();
12123 self.generate_identifier(&ai.name)?;
12124
12125 if let Some(table) = &ai.table {
12126 self.write_space();
12127 self.write_keyword("ON");
12128 self.write_space();
12129 self.generate_table(table)?;
12130 }
12131
12132 for action in &ai.actions {
12133 self.write_space();
12134 match action {
12135 AlterIndexAction::Rename(new_name) => {
12136 self.write_keyword("RENAME TO");
12137 self.write_space();
12138 self.generate_identifier(new_name)?;
12139 }
12140 AlterIndexAction::SetTablespace(tablespace) => {
12141 self.write_keyword("SET TABLESPACE");
12142 self.write_space();
12143 self.generate_identifier(tablespace)?;
12144 }
12145 AlterIndexAction::Visible(visible) => {
12146 if *visible {
12147 self.write_keyword("VISIBLE");
12148 } else {
12149 self.write_keyword("INVISIBLE");
12150 }
12151 }
12152 }
12153 }
12154
12155 Ok(())
12156 }
12157
12158 fn generate_create_schema(&mut self, cs: &CreateSchema) -> Result<()> {
12159 for comment in &cs.leading_comments {
12161 self.write_formatted_comment(comment);
12162 self.write_space();
12163 }
12164
12165 let saved_athena_hive_context = self.athena_hive_context;
12167 if matches!(
12168 self.config.dialect,
12169 Some(crate::dialects::DialectType::Athena)
12170 ) {
12171 self.athena_hive_context = true;
12172 }
12173
12174 self.write_keyword("CREATE SCHEMA");
12175
12176 if cs.if_not_exists {
12177 self.write_space();
12178 self.write_keyword("IF NOT EXISTS");
12179 }
12180
12181 self.write_space();
12182 for (i, part) in cs.name.iter().enumerate() {
12183 if i > 0 {
12184 self.write(".");
12185 }
12186 self.generate_identifier(part)?;
12187 }
12188
12189 if let Some(ref clone_parts) = cs.clone_from {
12190 self.write_keyword(" CLONE ");
12191 for (i, part) in clone_parts.iter().enumerate() {
12192 if i > 0 {
12193 self.write(".");
12194 }
12195 self.generate_identifier(part)?;
12196 }
12197 }
12198
12199 if let Some(ref at_clause) = cs.at_clause {
12200 self.write_space();
12201 self.generate_expression(at_clause)?;
12202 }
12203
12204 if let Some(auth) = &cs.authorization {
12205 self.write_space();
12206 self.write_keyword("AUTHORIZATION");
12207 self.write_space();
12208 self.generate_identifier(auth)?;
12209 }
12210
12211 let with_properties: Vec<_> = cs
12214 .properties
12215 .iter()
12216 .filter(|p| matches!(p, Expression::Property(_)))
12217 .collect();
12218 let other_properties: Vec<_> = cs
12219 .properties
12220 .iter()
12221 .filter(|p| !matches!(p, Expression::Property(_)))
12222 .collect();
12223
12224 if !with_properties.is_empty() {
12226 self.write_space();
12227 self.write_keyword("WITH");
12228 self.write(" (");
12229 for (i, prop) in with_properties.iter().enumerate() {
12230 if i > 0 {
12231 self.write(", ");
12232 }
12233 self.generate_expression(prop)?;
12234 }
12235 self.write(")");
12236 }
12237
12238 for prop in other_properties {
12240 self.write_space();
12241 self.generate_expression(prop)?;
12242 }
12243
12244 self.athena_hive_context = saved_athena_hive_context;
12246
12247 Ok(())
12248 }
12249
12250 fn generate_drop_schema(&mut self, ds: &DropSchema) -> Result<()> {
12251 self.write_keyword("DROP SCHEMA");
12252
12253 if ds.if_exists {
12254 self.write_space();
12255 self.write_keyword("IF EXISTS");
12256 }
12257
12258 self.write_space();
12259 self.generate_identifier(&ds.name)?;
12260
12261 if ds.cascade {
12262 self.write_space();
12263 self.write_keyword("CASCADE");
12264 }
12265
12266 Ok(())
12267 }
12268
12269 fn generate_drop_namespace(&mut self, dn: &DropNamespace) -> Result<()> {
12270 self.write_keyword("DROP NAMESPACE");
12271
12272 if dn.if_exists {
12273 self.write_space();
12274 self.write_keyword("IF EXISTS");
12275 }
12276
12277 self.write_space();
12278 self.generate_identifier(&dn.name)?;
12279
12280 if dn.cascade {
12281 self.write_space();
12282 self.write_keyword("CASCADE");
12283 }
12284
12285 Ok(())
12286 }
12287
12288 fn generate_create_database(&mut self, cd: &CreateDatabase) -> Result<()> {
12289 self.write_keyword("CREATE DATABASE");
12290
12291 if cd.if_not_exists {
12292 self.write_space();
12293 self.write_keyword("IF NOT EXISTS");
12294 }
12295
12296 self.write_space();
12297 self.generate_identifier(&cd.name)?;
12298
12299 if let Some(ref clone_src) = cd.clone_from {
12300 self.write_keyword(" CLONE ");
12301 self.generate_identifier(clone_src)?;
12302 }
12303
12304 if let Some(ref at_clause) = cd.at_clause {
12306 self.write_space();
12307 self.generate_expression(at_clause)?;
12308 }
12309
12310 for option in &cd.options {
12311 self.write_space();
12312 match option {
12313 DatabaseOption::CharacterSet(charset) => {
12314 self.write_keyword("CHARACTER SET");
12315 self.write(" = ");
12316 self.write(&format!("'{}'", charset));
12317 }
12318 DatabaseOption::Collate(collate) => {
12319 self.write_keyword("COLLATE");
12320 self.write(" = ");
12321 self.write(&format!("'{}'", collate));
12322 }
12323 DatabaseOption::Owner(owner) => {
12324 self.write_keyword("OWNER");
12325 self.write(" = ");
12326 self.generate_identifier(owner)?;
12327 }
12328 DatabaseOption::Template(template) => {
12329 self.write_keyword("TEMPLATE");
12330 self.write(" = ");
12331 self.generate_identifier(template)?;
12332 }
12333 DatabaseOption::Encoding(encoding) => {
12334 self.write_keyword("ENCODING");
12335 self.write(" = ");
12336 self.write(&format!("'{}'", encoding));
12337 }
12338 DatabaseOption::Location(location) => {
12339 self.write_keyword("LOCATION");
12340 self.write(" = ");
12341 self.write(&format!("'{}'", location));
12342 }
12343 }
12344 }
12345
12346 Ok(())
12347 }
12348
12349 fn generate_drop_database(&mut self, dd: &DropDatabase) -> Result<()> {
12350 self.write_keyword("DROP DATABASE");
12351
12352 if dd.if_exists {
12353 self.write_space();
12354 self.write_keyword("IF EXISTS");
12355 }
12356
12357 self.write_space();
12358 self.generate_identifier(&dd.name)?;
12359
12360 if dd.sync {
12361 self.write_space();
12362 self.write_keyword("SYNC");
12363 }
12364
12365 Ok(())
12366 }
12367
12368 fn generate_create_function(&mut self, cf: &CreateFunction) -> Result<()> {
12369 self.write_keyword("CREATE");
12370
12371 if cf.or_alter {
12372 self.write_space();
12373 self.write_keyword("OR ALTER");
12374 } else if cf.or_replace {
12375 self.write_space();
12376 self.write_keyword("OR REPLACE");
12377 }
12378
12379 if cf.temporary {
12380 self.write_space();
12381 self.write_keyword("TEMPORARY");
12382 }
12383
12384 self.write_space();
12385 if cf.is_table_function {
12386 self.write_keyword("TABLE FUNCTION");
12387 } else {
12388 self.write_keyword("FUNCTION");
12389 }
12390
12391 if cf.if_not_exists {
12392 self.write_space();
12393 self.write_keyword("IF NOT EXISTS");
12394 }
12395
12396 self.write_space();
12397 self.generate_table(&cf.name)?;
12398 if cf.has_parens {
12399 let func_multiline = self.config.pretty
12400 && matches!(
12401 self.config.dialect,
12402 Some(crate::dialects::DialectType::TSQL)
12403 | Some(crate::dialects::DialectType::Fabric)
12404 )
12405 && !cf.parameters.is_empty();
12406 if func_multiline {
12407 self.write("(\n");
12408 self.indent_level += 2;
12409 self.write_indent();
12410 self.generate_function_parameters(&cf.parameters)?;
12411 self.write("\n");
12412 self.indent_level -= 2;
12413 self.write(")");
12414 } else {
12415 self.write("(");
12416 self.generate_function_parameters(&cf.parameters)?;
12417 self.write(")");
12418 }
12419 }
12420
12421 let use_multiline = self.config.pretty
12424 && matches!(
12425 self.config.dialect,
12426 Some(crate::dialects::DialectType::BigQuery)
12427 | Some(crate::dialects::DialectType::TSQL)
12428 | Some(crate::dialects::DialectType::Fabric)
12429 );
12430
12431 if cf.language_first {
12432 if let Some(lang) = &cf.language {
12434 if use_multiline {
12435 self.write_newline();
12436 } else {
12437 self.write_space();
12438 }
12439 self.write_keyword("LANGUAGE");
12440 self.write_space();
12441 self.write(lang);
12442 }
12443
12444 if let Some(sql_data) = &cf.sql_data_access {
12446 self.write_space();
12447 match sql_data {
12448 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
12449 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
12450 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
12451 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
12452 }
12453 }
12454
12455 if let Some(ref rtb) = cf.returns_table_body {
12456 if use_multiline {
12457 self.write_newline();
12458 } else {
12459 self.write_space();
12460 }
12461 self.write_keyword("RETURNS");
12462 self.write_space();
12463 self.write(rtb);
12464 } else if let Some(return_type) = &cf.return_type {
12465 if use_multiline {
12466 self.write_newline();
12467 } else {
12468 self.write_space();
12469 }
12470 self.write_keyword("RETURNS");
12471 self.write_space();
12472 self.generate_data_type(return_type)?;
12473 }
12474 } else {
12475 let is_duckdb = matches!(
12478 self.config.dialect,
12479 Some(crate::dialects::DialectType::DuckDB)
12480 );
12481 if let Some(ref rtb) = cf.returns_table_body {
12482 if !(is_duckdb && rtb.is_empty()) {
12483 if use_multiline {
12484 self.write_newline();
12485 } else {
12486 self.write_space();
12487 }
12488 self.write_keyword("RETURNS");
12489 self.write_space();
12490 self.write(rtb);
12491 }
12492 } else if let Some(return_type) = &cf.return_type {
12493 if !is_duckdb {
12495 let is_table_return = matches!(return_type, crate::expressions::DataType::Custom { ref name } if name.eq_ignore_ascii_case("TABLE"));
12496 if use_multiline {
12497 self.write_newline();
12498 } else {
12499 self.write_space();
12500 }
12501 self.write_keyword("RETURNS");
12502 self.write_space();
12503 if is_table_return {
12504 self.write_keyword("TABLE");
12505 } else {
12506 self.generate_data_type(return_type)?;
12507 }
12508 }
12509 }
12510 }
12511
12512 if !cf.property_order.is_empty() {
12514 let is_bigquery = matches!(
12516 self.config.dialect,
12517 Some(crate::dialects::DialectType::BigQuery)
12518 );
12519 let property_order = if is_bigquery {
12520 let mut reordered = Vec::new();
12522 let mut has_as = false;
12523 let mut has_options = false;
12524 for prop in &cf.property_order {
12525 match prop {
12526 FunctionPropertyKind::As => has_as = true,
12527 FunctionPropertyKind::Options => has_options = true,
12528 _ => {}
12529 }
12530 }
12531 if has_as && has_options {
12532 for prop in &cf.property_order {
12534 if *prop != FunctionPropertyKind::As
12535 && *prop != FunctionPropertyKind::Options
12536 {
12537 reordered.push(*prop);
12538 }
12539 }
12540 reordered.push(FunctionPropertyKind::Options);
12541 reordered.push(FunctionPropertyKind::As);
12542 reordered
12543 } else {
12544 cf.property_order.clone()
12545 }
12546 } else {
12547 cf.property_order.clone()
12548 };
12549
12550 for prop in &property_order {
12551 match prop {
12552 FunctionPropertyKind::Set => {
12553 self.generate_function_set_options(cf)?;
12554 }
12555 FunctionPropertyKind::As => {
12556 self.generate_function_body(cf)?;
12557 }
12558 FunctionPropertyKind::Using => {
12559 self.generate_function_using_resources(cf)?;
12560 }
12561 FunctionPropertyKind::Language => {
12562 if !cf.language_first {
12563 if let Some(lang) = &cf.language {
12565 let use_multiline = self.config.pretty
12567 && matches!(
12568 self.config.dialect,
12569 Some(crate::dialects::DialectType::BigQuery)
12570 );
12571 if use_multiline {
12572 self.write_newline();
12573 } else {
12574 self.write_space();
12575 }
12576 self.write_keyword("LANGUAGE");
12577 self.write_space();
12578 self.write(lang);
12579 }
12580 }
12581 }
12582 FunctionPropertyKind::Determinism => {
12583 self.generate_function_determinism(cf)?;
12584 }
12585 FunctionPropertyKind::NullInput => {
12586 self.generate_function_null_input(cf)?;
12587 }
12588 FunctionPropertyKind::Security => {
12589 self.generate_function_security(cf)?;
12590 }
12591 FunctionPropertyKind::SqlDataAccess => {
12592 if !cf.language_first {
12593 self.generate_function_sql_data_access(cf)?;
12595 }
12596 }
12597 FunctionPropertyKind::Options => {
12598 if !cf.options.is_empty() {
12599 self.write_space();
12600 self.generate_options_clause(&cf.options)?;
12601 }
12602 }
12603 FunctionPropertyKind::Environment => {
12604 if !cf.environment.is_empty() {
12605 self.write_space();
12606 self.generate_environment_clause(&cf.environment)?;
12607 }
12608 }
12609 FunctionPropertyKind::Handler => {
12610 if let Some(ref h) = cf.handler {
12611 self.write_space();
12612 self.write_keyword("HANDLER");
12613 if cf.handler_uses_eq {
12614 self.write(" = ");
12615 } else {
12616 self.write_space();
12617 }
12618 self.write("'");
12619 self.write(h);
12620 self.write("'");
12621 }
12622 }
12623 FunctionPropertyKind::RuntimeVersion => {
12624 if let Some(ref runtime_version) = cf.runtime_version {
12625 self.write_space();
12626 self.write_keyword("RUNTIME_VERSION");
12627 self.write("='");
12628 self.write(runtime_version);
12629 self.write("'");
12630 }
12631 }
12632 FunctionPropertyKind::Packages => {
12633 if let Some(ref packages) = cf.packages {
12634 self.write_space();
12635 self.write_keyword("PACKAGES");
12636 self.write("=(");
12637 for (i, package) in packages.iter().enumerate() {
12638 if i > 0 {
12639 self.write(", ");
12640 }
12641 self.write("'");
12642 self.write(package);
12643 self.write("'");
12644 }
12645 self.write(")");
12646 }
12647 }
12648 FunctionPropertyKind::ParameterStyle => {
12649 if let Some(ref ps) = cf.parameter_style {
12650 self.write_space();
12651 self.write_keyword("PARAMETER STYLE");
12652 self.write_space();
12653 self.write_keyword(ps);
12654 }
12655 }
12656 }
12657 }
12658
12659 if !cf.options.is_empty() && !cf.property_order.contains(&FunctionPropertyKind::Options)
12661 {
12662 self.write_space();
12663 self.generate_options_clause(&cf.options)?;
12664 }
12665
12666 if !cf.environment.is_empty()
12668 && !cf
12669 .property_order
12670 .contains(&FunctionPropertyKind::Environment)
12671 {
12672 self.write_space();
12673 self.generate_environment_clause(&cf.environment)?;
12674 }
12675 } else {
12676 if matches!(
12679 self.config.dialect,
12680 Some(crate::dialects::DialectType::BigQuery)
12681 ) {
12682 self.generate_function_determinism(cf)?;
12683 }
12684
12685 let use_multiline = self.config.pretty
12687 && matches!(
12688 self.config.dialect,
12689 Some(crate::dialects::DialectType::BigQuery)
12690 );
12691
12692 if !cf.language_first {
12693 if let Some(lang) = &cf.language {
12694 if use_multiline {
12695 self.write_newline();
12696 } else {
12697 self.write_space();
12698 }
12699 self.write_keyword("LANGUAGE");
12700 self.write_space();
12701 self.write(lang);
12702 }
12703
12704 self.generate_function_sql_data_access(cf)?;
12706 }
12707
12708 if !matches!(
12710 self.config.dialect,
12711 Some(crate::dialects::DialectType::BigQuery)
12712 ) {
12713 self.generate_function_determinism(cf)?;
12714 }
12715
12716 self.generate_function_null_input(cf)?;
12717 self.generate_function_security(cf)?;
12718 self.generate_function_set_options(cf)?;
12719
12720 if !cf.options.is_empty() {
12722 self.write_space();
12723 self.generate_options_clause(&cf.options)?;
12724 }
12725
12726 if !cf.environment.is_empty() {
12728 self.write_space();
12729 self.generate_environment_clause(&cf.environment)?;
12730 }
12731
12732 if let Some(ref h) = cf.handler {
12733 self.write_space();
12734 self.write_keyword("HANDLER");
12735 if cf.handler_uses_eq {
12736 self.write(" = ");
12737 } else {
12738 self.write_space();
12739 }
12740 self.write("'");
12741 self.write(h);
12742 self.write("'");
12743 }
12744
12745 if let Some(ref runtime_version) = cf.runtime_version {
12746 self.write_space();
12747 self.write_keyword("RUNTIME_VERSION");
12748 self.write("='");
12749 self.write(runtime_version);
12750 self.write("'");
12751 }
12752
12753 if let Some(ref packages) = cf.packages {
12754 self.write_space();
12755 self.write_keyword("PACKAGES");
12756 self.write("=(");
12757 for (i, package) in packages.iter().enumerate() {
12758 if i > 0 {
12759 self.write(", ");
12760 }
12761 self.write("'");
12762 self.write(package);
12763 self.write("'");
12764 }
12765 self.write(")");
12766 }
12767
12768 self.generate_function_body(cf)?;
12769 self.generate_function_using_resources(cf)?;
12770 }
12771
12772 Ok(())
12773 }
12774
12775 fn generate_function_set_options(&mut self, cf: &CreateFunction) -> Result<()> {
12777 for opt in &cf.set_options {
12778 self.write_space();
12779 self.write_keyword("SET");
12780 self.write_space();
12781 self.write(&opt.name);
12782 match &opt.value {
12783 FunctionSetValue::Value { value, use_to } => {
12784 if *use_to {
12785 self.write(" TO ");
12786 } else {
12787 self.write(" = ");
12788 }
12789 self.write(value);
12790 }
12791 FunctionSetValue::FromCurrent => {
12792 self.write_space();
12793 self.write_keyword("FROM CURRENT");
12794 }
12795 }
12796 }
12797 Ok(())
12798 }
12799
12800 fn generate_function_using_resources(&mut self, cf: &CreateFunction) -> Result<()> {
12801 if cf.using_resources.is_empty() {
12802 return Ok(());
12803 }
12804
12805 self.write_space();
12806 self.write_keyword("USING");
12807 for resource in &cf.using_resources {
12808 self.write_space();
12809 self.write_keyword(&resource.kind);
12810 self.write_space();
12811 self.generate_string_literal(&resource.uri)?;
12812 }
12813 Ok(())
12814 }
12815
12816 fn generate_function_body(&mut self, cf: &CreateFunction) -> Result<()> {
12818 if let Some(body) = &cf.body {
12819 self.write_space();
12821 let use_multiline = self.config.pretty
12823 && matches!(
12824 self.config.dialect,
12825 Some(crate::dialects::DialectType::BigQuery)
12826 );
12827 match body {
12828 FunctionBody::Block(block) => {
12829 self.write_keyword("AS");
12830 if matches!(
12831 self.config.dialect,
12832 Some(crate::dialects::DialectType::TSQL)
12833 ) {
12834 self.write(" BEGIN ");
12835 self.write(block);
12836 self.write(" END");
12837 } else if matches!(
12838 self.config.dialect,
12839 Some(crate::dialects::DialectType::PostgreSQL)
12840 ) {
12841 self.write(" $$");
12842 self.write(block);
12843 self.write("$$");
12844 } else {
12845 let escaped = self.escape_block_for_single_quote(block);
12847 if use_multiline {
12849 self.write_newline();
12850 } else {
12851 self.write(" ");
12852 }
12853 self.write("'");
12854 self.write(&escaped);
12855 self.write("'");
12856 }
12857 }
12858 FunctionBody::StringLiteral(s) => {
12859 self.write_keyword("AS");
12860 if use_multiline {
12862 self.write_newline();
12863 } else {
12864 self.write(" ");
12865 }
12866 self.write("'");
12867 self.write(s);
12868 self.write("'");
12869 }
12870 FunctionBody::Expression(expr) => {
12871 self.write_keyword("AS");
12872 self.write_space();
12873 self.generate_expression(expr)?;
12874 }
12875 FunctionBody::External(name) => {
12876 self.write_keyword("EXTERNAL NAME");
12877 self.write(" '");
12878 self.write(name);
12879 self.write("'");
12880 }
12881 FunctionBody::Return(expr) => {
12882 if matches!(
12883 self.config.dialect,
12884 Some(crate::dialects::DialectType::DuckDB)
12885 ) {
12886 self.write_keyword("AS");
12888 self.write_space();
12889 let is_table_return = cf.returns_table_body.is_some()
12891 || matches!(&cf.return_type, Some(crate::expressions::DataType::Custom { ref name }) if name.eq_ignore_ascii_case("TABLE"));
12892 if is_table_return {
12893 self.write_keyword("TABLE");
12894 self.write_space();
12895 }
12896 self.generate_expression(expr)?;
12897 } else {
12898 if self.config.create_function_return_as {
12899 self.write_keyword("AS");
12900 if self.config.pretty
12902 && matches!(
12903 self.config.dialect,
12904 Some(crate::dialects::DialectType::TSQL)
12905 | Some(crate::dialects::DialectType::Fabric)
12906 )
12907 {
12908 self.write_newline();
12909 } else {
12910 self.write_space();
12911 }
12912 }
12913 self.write_keyword("RETURN");
12914 self.write_space();
12915 self.generate_expression(expr)?;
12916 }
12917 }
12918 FunctionBody::Statements(stmts) => {
12919 self.write_keyword("AS");
12920 self.write(" BEGIN ");
12921 for (i, stmt) in stmts.iter().enumerate() {
12922 if i > 0 {
12923 self.write(" ");
12924 }
12925 self.generate_expression(stmt)?;
12926 self.write(";");
12927 }
12928 self.write(" END");
12929 }
12930 FunctionBody::RawBlock(text) => {
12931 self.write_newline();
12932 self.write(text);
12933 }
12934 FunctionBody::DollarQuoted { content, tag } => {
12935 self.write_keyword("AS");
12936 self.write(" ");
12937 let supports_dollar_quoting = matches!(
12939 self.config.dialect,
12940 Some(crate::dialects::DialectType::PostgreSQL)
12941 | Some(crate::dialects::DialectType::Databricks)
12942 | Some(crate::dialects::DialectType::Redshift)
12943 | Some(crate::dialects::DialectType::DuckDB)
12944 );
12945 if supports_dollar_quoting {
12946 self.write("$");
12948 if let Some(t) = tag {
12949 self.write(t);
12950 }
12951 self.write("$");
12952 self.write(content);
12953 self.write("$");
12954 if let Some(t) = tag {
12955 self.write(t);
12956 }
12957 self.write("$");
12958 } else {
12959 let escaped = self.escape_block_for_single_quote(content);
12961 self.write("'");
12962 self.write(&escaped);
12963 self.write("'");
12964 }
12965 }
12966 }
12967 }
12968 Ok(())
12969 }
12970
12971 fn generate_function_determinism(&mut self, cf: &CreateFunction) -> Result<()> {
12973 if let Some(det) = cf.deterministic {
12974 self.write_space();
12975 if matches!(
12976 self.config.dialect,
12977 Some(crate::dialects::DialectType::BigQuery)
12978 ) {
12979 if det {
12981 self.write_keyword("DETERMINISTIC");
12982 } else {
12983 self.write_keyword("NOT DETERMINISTIC");
12984 }
12985 } else {
12986 if det {
12988 self.write_keyword("IMMUTABLE");
12989 } else {
12990 self.write_keyword("VOLATILE");
12991 }
12992 }
12993 }
12994 Ok(())
12995 }
12996
12997 fn generate_function_null_input(&mut self, cf: &CreateFunction) -> Result<()> {
12999 if let Some(returns_null) = cf.returns_null_on_null_input {
13000 self.write_space();
13001 if returns_null {
13002 if cf.strict {
13003 self.write_keyword("STRICT");
13004 } else {
13005 self.write_keyword("RETURNS NULL ON NULL INPUT");
13006 }
13007 } else {
13008 self.write_keyword("CALLED ON NULL INPUT");
13009 }
13010 }
13011 Ok(())
13012 }
13013
13014 fn generate_function_security(&mut self, cf: &CreateFunction) -> Result<()> {
13016 if let Some(security) = &cf.security {
13017 self.write_space();
13018 if matches!(
13020 self.config.dialect,
13021 Some(crate::dialects::DialectType::MySQL)
13022 ) {
13023 self.write_keyword("SQL SECURITY");
13024 } else {
13025 self.write_keyword("SECURITY");
13026 }
13027 self.write_space();
13028 match security {
13029 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
13030 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
13031 FunctionSecurity::None => self.write_keyword("NONE"),
13032 }
13033 }
13034 Ok(())
13035 }
13036
13037 fn generate_function_sql_data_access(&mut self, cf: &CreateFunction) -> Result<()> {
13039 if let Some(sql_data) = &cf.sql_data_access {
13040 self.write_space();
13041 match sql_data {
13042 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
13043 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
13044 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
13045 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
13046 }
13047 }
13048 Ok(())
13049 }
13050
13051 fn generate_function_parameters(&mut self, params: &[FunctionParameter]) -> Result<()> {
13052 for (i, param) in params.iter().enumerate() {
13053 if i > 0 {
13054 self.write(", ");
13055 }
13056
13057 if let Some(mode) = ¶m.mode {
13058 if let Some(text) = ¶m.mode_text {
13059 self.write(text);
13060 } else {
13061 match mode {
13062 ParameterMode::In => self.write_keyword("IN"),
13063 ParameterMode::Out => self.write_keyword("OUT"),
13064 ParameterMode::InOut => self.write_keyword("INOUT"),
13065 ParameterMode::Variadic => self.write_keyword("VARIADIC"),
13066 }
13067 }
13068 self.write_space();
13069 }
13070
13071 if let Some(name) = ¶m.name {
13072 self.generate_identifier(name)?;
13073 let skip_type =
13075 matches!(¶m.data_type, DataType::Custom { name } if name.is_empty());
13076 if !skip_type {
13077 self.write_space();
13078 self.generate_data_type(¶m.data_type)?;
13079 }
13080 } else {
13081 self.generate_data_type(¶m.data_type)?;
13082 }
13083
13084 if let Some(default) = ¶m.default {
13085 if self.config.parameter_default_equals {
13086 self.write(" = ");
13087 } else {
13088 self.write(" DEFAULT ");
13089 }
13090 self.generate_expression(default)?;
13091 }
13092 }
13093
13094 Ok(())
13095 }
13096
13097 fn generate_drop_function(&mut self, df: &DropFunction) -> Result<()> {
13098 self.write_keyword("DROP FUNCTION");
13099
13100 if df.if_exists {
13101 self.write_space();
13102 self.write_keyword("IF EXISTS");
13103 }
13104
13105 self.write_space();
13106 self.generate_table(&df.name)?;
13107
13108 if let Some(params) = &df.parameters {
13109 self.write(" (");
13110 for (i, dt) in params.iter().enumerate() {
13111 if i > 0 {
13112 self.write(", ");
13113 }
13114 self.generate_data_type(dt)?;
13115 }
13116 self.write(")");
13117 }
13118
13119 if df.cascade {
13120 self.write_space();
13121 self.write_keyword("CASCADE");
13122 }
13123
13124 Ok(())
13125 }
13126
13127 fn generate_create_procedure(&mut self, cp: &CreateProcedure) -> Result<()> {
13128 self.write_keyword("CREATE");
13129
13130 if cp.or_alter {
13131 self.write_space();
13132 self.write_keyword("OR ALTER");
13133 } else if cp.or_replace {
13134 self.write_space();
13135 self.write_keyword("OR REPLACE");
13136 }
13137
13138 self.write_space();
13139 if cp.use_proc_keyword {
13140 self.write_keyword("PROC");
13141 } else {
13142 self.write_keyword("PROCEDURE");
13143 }
13144
13145 if cp.if_not_exists {
13146 self.write_space();
13147 self.write_keyword("IF NOT EXISTS");
13148 }
13149
13150 self.write_space();
13151 self.generate_table(&cp.name)?;
13152 if cp.has_parens {
13153 self.write("(");
13154 self.generate_function_parameters(&cp.parameters)?;
13155 self.write(")");
13156 } else if !cp.parameters.is_empty() {
13157 self.write_space();
13159 self.generate_function_parameters(&cp.parameters)?;
13160 }
13161
13162 if let Some(return_type) = &cp.return_type {
13164 self.write_space();
13165 self.write_keyword("RETURNS");
13166 self.write_space();
13167 self.generate_data_type(return_type)?;
13168 }
13169
13170 if let Some(execute_as) = &cp.execute_as {
13172 self.write_space();
13173 self.write_keyword("EXECUTE AS");
13174 self.write_space();
13175 self.write_keyword(execute_as);
13176 }
13177
13178 if let Some(lang) = &cp.language {
13179 self.write_space();
13180 self.write_keyword("LANGUAGE");
13181 self.write_space();
13182 self.write(lang);
13183 }
13184
13185 if let Some(security) = &cp.security {
13186 self.write_space();
13187 self.write_keyword("SECURITY");
13188 self.write_space();
13189 match security {
13190 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
13191 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
13192 FunctionSecurity::None => self.write_keyword("NONE"),
13193 }
13194 }
13195
13196 if !cp.with_options.is_empty() {
13198 self.write_space();
13199 self.write_keyword("WITH");
13200 self.write_space();
13201 for (i, opt) in cp.with_options.iter().enumerate() {
13202 if i > 0 {
13203 self.write(", ");
13204 }
13205 self.write(opt);
13206 }
13207 }
13208
13209 if let Some(body) = &cp.body {
13210 self.write_space();
13211 match body {
13212 FunctionBody::Block(block) => {
13213 self.write_keyword("AS");
13214 if matches!(
13215 self.config.dialect,
13216 Some(crate::dialects::DialectType::TSQL)
13217 ) {
13218 self.write(" BEGIN ");
13219 self.write(block);
13220 self.write(" END");
13221 } else if matches!(
13222 self.config.dialect,
13223 Some(crate::dialects::DialectType::PostgreSQL)
13224 ) {
13225 self.write(" $$");
13226 self.write(block);
13227 self.write("$$");
13228 } else {
13229 let escaped = self.escape_block_for_single_quote(block);
13231 self.write(" '");
13232 self.write(&escaped);
13233 self.write("'");
13234 }
13235 }
13236 FunctionBody::StringLiteral(s) => {
13237 self.write_keyword("AS");
13238 self.write(" '");
13239 self.write(s);
13240 self.write("'");
13241 }
13242 FunctionBody::Expression(expr) => {
13243 self.write_keyword("AS");
13244 self.write_space();
13245 self.generate_expression(expr)?;
13246 }
13247 FunctionBody::External(name) => {
13248 self.write_keyword("EXTERNAL NAME");
13249 self.write(" '");
13250 self.write(name);
13251 self.write("'");
13252 }
13253 FunctionBody::Return(expr) => {
13254 self.write_keyword("RETURN");
13255 self.write_space();
13256 self.generate_expression(expr)?;
13257 }
13258 FunctionBody::Statements(stmts) => {
13259 self.write_keyword("AS");
13260 self.write(" BEGIN ");
13261 for (i, stmt) in stmts.iter().enumerate() {
13262 if i > 0 {
13263 self.write(" ");
13264 }
13265 self.generate_expression(stmt)?;
13266 self.write(";");
13267 }
13268 self.write(" END");
13269 }
13270 FunctionBody::RawBlock(text) => {
13271 self.write_newline();
13272 self.write(text);
13273 }
13274 FunctionBody::DollarQuoted { content, tag } => {
13275 self.write_keyword("AS");
13276 self.write(" ");
13277 let supports_dollar_quoting = matches!(
13279 self.config.dialect,
13280 Some(crate::dialects::DialectType::PostgreSQL)
13281 | Some(crate::dialects::DialectType::Databricks)
13282 | Some(crate::dialects::DialectType::Redshift)
13283 | Some(crate::dialects::DialectType::DuckDB)
13284 );
13285 if supports_dollar_quoting {
13286 self.write("$");
13288 if let Some(t) = tag {
13289 self.write(t);
13290 }
13291 self.write("$");
13292 self.write(content);
13293 self.write("$");
13294 if let Some(t) = tag {
13295 self.write(t);
13296 }
13297 self.write("$");
13298 } else {
13299 let escaped = self.escape_block_for_single_quote(content);
13301 self.write("'");
13302 self.write(&escaped);
13303 self.write("'");
13304 }
13305 }
13306 }
13307 }
13308
13309 Ok(())
13310 }
13311
13312 fn generate_drop_procedure(&mut self, dp: &DropProcedure) -> Result<()> {
13313 self.write_keyword("DROP PROCEDURE");
13314
13315 if dp.if_exists {
13316 self.write_space();
13317 self.write_keyword("IF EXISTS");
13318 }
13319
13320 self.write_space();
13321 self.generate_table(&dp.name)?;
13322
13323 if let Some(params) = &dp.parameters {
13324 self.write(" (");
13325 for (i, dt) in params.iter().enumerate() {
13326 if i > 0 {
13327 self.write(", ");
13328 }
13329 self.generate_data_type(dt)?;
13330 }
13331 self.write(")");
13332 }
13333
13334 if dp.cascade {
13335 self.write_space();
13336 self.write_keyword("CASCADE");
13337 }
13338
13339 Ok(())
13340 }
13341
13342 fn generate_create_sequence(&mut self, cs: &CreateSequence) -> Result<()> {
13343 self.write_keyword("CREATE");
13344
13345 if cs.or_replace {
13346 self.write_space();
13347 self.write_keyword("OR REPLACE");
13348 }
13349
13350 if cs.temporary {
13351 self.write_space();
13352 self.write_keyword("TEMPORARY");
13353 }
13354
13355 self.write_space();
13356 self.write_keyword("SEQUENCE");
13357
13358 if cs.if_not_exists {
13359 self.write_space();
13360 self.write_keyword("IF NOT EXISTS");
13361 }
13362
13363 self.write_space();
13364 self.generate_table(&cs.name)?;
13365
13366 if let Some(as_type) = &cs.as_type {
13368 self.write_space();
13369 self.write_keyword("AS");
13370 self.write_space();
13371 self.generate_data_type(as_type)?;
13372 }
13373
13374 if let Some(comment) = &cs.comment {
13376 self.write_space();
13377 self.write_keyword("COMMENT");
13378 self.write("=");
13379 self.generate_string_literal(comment)?;
13380 }
13381
13382 if !cs.property_order.is_empty() {
13384 for prop in &cs.property_order {
13385 match prop {
13386 SeqPropKind::Start => {
13387 if let Some(start) = cs.start {
13388 self.write_space();
13389 self.write_keyword("START WITH");
13390 self.write(&format!(" {}", start));
13391 }
13392 }
13393 SeqPropKind::Increment => {
13394 if let Some(inc) = cs.increment {
13395 self.write_space();
13396 self.write_keyword("INCREMENT BY");
13397 self.write(&format!(" {}", inc));
13398 }
13399 }
13400 SeqPropKind::Minvalue => {
13401 if let Some(min) = &cs.minvalue {
13402 self.write_space();
13403 match min {
13404 SequenceBound::Value(v) => {
13405 self.write_keyword("MINVALUE");
13406 self.write(&format!(" {}", v));
13407 }
13408 SequenceBound::None => {
13409 self.write_keyword("NO MINVALUE");
13410 }
13411 }
13412 }
13413 }
13414 SeqPropKind::Maxvalue => {
13415 if let Some(max) = &cs.maxvalue {
13416 self.write_space();
13417 match max {
13418 SequenceBound::Value(v) => {
13419 self.write_keyword("MAXVALUE");
13420 self.write(&format!(" {}", v));
13421 }
13422 SequenceBound::None => {
13423 self.write_keyword("NO MAXVALUE");
13424 }
13425 }
13426 }
13427 }
13428 SeqPropKind::Cache => {
13429 if let Some(cache) = cs.cache {
13430 self.write_space();
13431 self.write_keyword("CACHE");
13432 self.write(&format!(" {}", cache));
13433 }
13434 }
13435 SeqPropKind::NoCache => {
13436 self.write_space();
13437 self.write_keyword("NO CACHE");
13438 }
13439 SeqPropKind::NoCacheWord => {
13440 self.write_space();
13441 self.write_keyword("NOCACHE");
13442 }
13443 SeqPropKind::Cycle => {
13444 self.write_space();
13445 self.write_keyword("CYCLE");
13446 }
13447 SeqPropKind::NoCycle => {
13448 self.write_space();
13449 self.write_keyword("NO CYCLE");
13450 }
13451 SeqPropKind::NoCycleWord => {
13452 self.write_space();
13453 self.write_keyword("NOCYCLE");
13454 }
13455 SeqPropKind::OwnedBy => {
13456 if !cs.owned_by_none {
13458 if let Some(owned) = &cs.owned_by {
13459 self.write_space();
13460 self.write_keyword("OWNED BY");
13461 self.write_space();
13462 self.generate_table(owned)?;
13463 }
13464 }
13465 }
13466 SeqPropKind::Order => {
13467 self.write_space();
13468 self.write_keyword("ORDER");
13469 }
13470 SeqPropKind::NoOrder => {
13471 self.write_space();
13472 self.write_keyword("NOORDER");
13473 }
13474 SeqPropKind::Comment => {
13475 }
13477 SeqPropKind::Sharing => {
13478 if let Some(val) = &cs.sharing {
13479 self.write_space();
13480 self.write(&format!("SHARING={}", val));
13481 }
13482 }
13483 SeqPropKind::Keep => {
13484 self.write_space();
13485 self.write_keyword("KEEP");
13486 }
13487 SeqPropKind::NoKeep => {
13488 self.write_space();
13489 self.write_keyword("NOKEEP");
13490 }
13491 SeqPropKind::Scale => {
13492 self.write_space();
13493 self.write_keyword("SCALE");
13494 if let Some(modifier) = &cs.scale_modifier {
13495 if !modifier.is_empty() {
13496 self.write_space();
13497 self.write_keyword(modifier);
13498 }
13499 }
13500 }
13501 SeqPropKind::NoScale => {
13502 self.write_space();
13503 self.write_keyword("NOSCALE");
13504 }
13505 SeqPropKind::Shard => {
13506 self.write_space();
13507 self.write_keyword("SHARD");
13508 if let Some(modifier) = &cs.shard_modifier {
13509 if !modifier.is_empty() {
13510 self.write_space();
13511 self.write_keyword(modifier);
13512 }
13513 }
13514 }
13515 SeqPropKind::NoShard => {
13516 self.write_space();
13517 self.write_keyword("NOSHARD");
13518 }
13519 SeqPropKind::Session => {
13520 self.write_space();
13521 self.write_keyword("SESSION");
13522 }
13523 SeqPropKind::Global => {
13524 self.write_space();
13525 self.write_keyword("GLOBAL");
13526 }
13527 SeqPropKind::NoMinvalueWord => {
13528 self.write_space();
13529 self.write_keyword("NOMINVALUE");
13530 }
13531 SeqPropKind::NoMaxvalueWord => {
13532 self.write_space();
13533 self.write_keyword("NOMAXVALUE");
13534 }
13535 }
13536 }
13537 } else {
13538 if let Some(inc) = cs.increment {
13540 self.write_space();
13541 self.write_keyword("INCREMENT BY");
13542 self.write(&format!(" {}", inc));
13543 }
13544
13545 if let Some(min) = &cs.minvalue {
13546 self.write_space();
13547 match min {
13548 SequenceBound::Value(v) => {
13549 self.write_keyword("MINVALUE");
13550 self.write(&format!(" {}", v));
13551 }
13552 SequenceBound::None => {
13553 self.write_keyword("NO MINVALUE");
13554 }
13555 }
13556 }
13557
13558 if let Some(max) = &cs.maxvalue {
13559 self.write_space();
13560 match max {
13561 SequenceBound::Value(v) => {
13562 self.write_keyword("MAXVALUE");
13563 self.write(&format!(" {}", v));
13564 }
13565 SequenceBound::None => {
13566 self.write_keyword("NO MAXVALUE");
13567 }
13568 }
13569 }
13570
13571 if let Some(start) = cs.start {
13572 self.write_space();
13573 self.write_keyword("START WITH");
13574 self.write(&format!(" {}", start));
13575 }
13576
13577 if let Some(cache) = cs.cache {
13578 self.write_space();
13579 self.write_keyword("CACHE");
13580 self.write(&format!(" {}", cache));
13581 }
13582
13583 if cs.cycle {
13584 self.write_space();
13585 self.write_keyword("CYCLE");
13586 }
13587
13588 if let Some(owned) = &cs.owned_by {
13589 self.write_space();
13590 self.write_keyword("OWNED BY");
13591 self.write_space();
13592 self.generate_table(owned)?;
13593 }
13594 }
13595
13596 Ok(())
13597 }
13598
13599 fn generate_drop_sequence(&mut self, ds: &DropSequence) -> Result<()> {
13600 self.write_keyword("DROP SEQUENCE");
13601
13602 if ds.if_exists {
13603 self.write_space();
13604 self.write_keyword("IF EXISTS");
13605 }
13606
13607 self.write_space();
13608 self.generate_table(&ds.name)?;
13609
13610 if ds.cascade {
13611 self.write_space();
13612 self.write_keyword("CASCADE");
13613 }
13614
13615 Ok(())
13616 }
13617
13618 fn generate_alter_sequence(&mut self, als: &AlterSequence) -> Result<()> {
13619 self.write_keyword("ALTER SEQUENCE");
13620
13621 if als.if_exists {
13622 self.write_space();
13623 self.write_keyword("IF EXISTS");
13624 }
13625
13626 self.write_space();
13627 self.generate_table(&als.name)?;
13628
13629 if let Some(inc) = als.increment {
13630 self.write_space();
13631 self.write_keyword("INCREMENT BY");
13632 self.write(&format!(" {}", inc));
13633 }
13634
13635 if let Some(min) = &als.minvalue {
13636 self.write_space();
13637 match min {
13638 SequenceBound::Value(v) => {
13639 self.write_keyword("MINVALUE");
13640 self.write(&format!(" {}", v));
13641 }
13642 SequenceBound::None => {
13643 self.write_keyword("NO MINVALUE");
13644 }
13645 }
13646 }
13647
13648 if let Some(max) = &als.maxvalue {
13649 self.write_space();
13650 match max {
13651 SequenceBound::Value(v) => {
13652 self.write_keyword("MAXVALUE");
13653 self.write(&format!(" {}", v));
13654 }
13655 SequenceBound::None => {
13656 self.write_keyword("NO MAXVALUE");
13657 }
13658 }
13659 }
13660
13661 if let Some(start) = als.start {
13662 self.write_space();
13663 self.write_keyword("START WITH");
13664 self.write(&format!(" {}", start));
13665 }
13666
13667 if let Some(restart) = &als.restart {
13668 self.write_space();
13669 self.write_keyword("RESTART");
13670 if let Some(val) = restart {
13671 self.write_keyword(" WITH");
13672 self.write(&format!(" {}", val));
13673 }
13674 }
13675
13676 if let Some(cache) = als.cache {
13677 self.write_space();
13678 self.write_keyword("CACHE");
13679 self.write(&format!(" {}", cache));
13680 }
13681
13682 if let Some(cycle) = als.cycle {
13683 self.write_space();
13684 if cycle {
13685 self.write_keyword("CYCLE");
13686 } else {
13687 self.write_keyword("NO CYCLE");
13688 }
13689 }
13690
13691 if let Some(owned) = &als.owned_by {
13692 self.write_space();
13693 self.write_keyword("OWNED BY");
13694 self.write_space();
13695 if let Some(table) = owned {
13696 self.generate_table(table)?;
13697 } else {
13698 self.write_keyword("NONE");
13699 }
13700 }
13701
13702 Ok(())
13703 }
13704
13705 fn generate_create_trigger(&mut self, ct: &CreateTrigger) -> Result<()> {
13706 self.write_keyword("CREATE");
13707
13708 if ct.or_alter {
13709 self.write_space();
13710 self.write_keyword("OR ALTER");
13711 } else if ct.or_replace {
13712 self.write_space();
13713 self.write_keyword("OR REPLACE");
13714 }
13715
13716 if ct.constraint {
13717 self.write_space();
13718 self.write_keyword("CONSTRAINT");
13719 }
13720
13721 self.write_space();
13722 self.write_keyword("TRIGGER");
13723 self.write_space();
13724 self.generate_identifier(&ct.name)?;
13725
13726 self.write_space();
13727 match ct.timing {
13728 TriggerTiming::Before => self.write_keyword("BEFORE"),
13729 TriggerTiming::After => self.write_keyword("AFTER"),
13730 TriggerTiming::InsteadOf => self.write_keyword("INSTEAD OF"),
13731 }
13732
13733 for (i, event) in ct.events.iter().enumerate() {
13735 if i > 0 {
13736 self.write_keyword(" OR");
13737 }
13738 self.write_space();
13739 match event {
13740 TriggerEvent::Insert => self.write_keyword("INSERT"),
13741 TriggerEvent::Update(cols) => {
13742 self.write_keyword("UPDATE");
13743 if let Some(cols) = cols {
13744 self.write_space();
13745 self.write_keyword("OF");
13746 for (j, col) in cols.iter().enumerate() {
13747 if j > 0 {
13748 self.write(",");
13749 }
13750 self.write_space();
13751 self.generate_identifier(col)?;
13752 }
13753 }
13754 }
13755 TriggerEvent::Delete => self.write_keyword("DELETE"),
13756 TriggerEvent::Truncate => self.write_keyword("TRUNCATE"),
13757 }
13758 }
13759
13760 self.write_space();
13761 self.write_keyword("ON");
13762 self.write_space();
13763 self.generate_table(&ct.table)?;
13764
13765 if let Some(ref_clause) = &ct.referencing {
13767 self.write_space();
13768 self.write_keyword("REFERENCING");
13769 if let Some(old_table) = &ref_clause.old_table {
13770 self.write_space();
13771 self.write_keyword("OLD TABLE AS");
13772 self.write_space();
13773 self.generate_identifier(old_table)?;
13774 }
13775 if let Some(new_table) = &ref_clause.new_table {
13776 self.write_space();
13777 self.write_keyword("NEW TABLE AS");
13778 self.write_space();
13779 self.generate_identifier(new_table)?;
13780 }
13781 if let Some(old_row) = &ref_clause.old_row {
13782 self.write_space();
13783 self.write_keyword("OLD ROW AS");
13784 self.write_space();
13785 self.generate_identifier(old_row)?;
13786 }
13787 if let Some(new_row) = &ref_clause.new_row {
13788 self.write_space();
13789 self.write_keyword("NEW ROW AS");
13790 self.write_space();
13791 self.generate_identifier(new_row)?;
13792 }
13793 }
13794
13795 if let Some(deferrable) = ct.deferrable {
13797 self.write_space();
13798 if deferrable {
13799 self.write_keyword("DEFERRABLE");
13800 } else {
13801 self.write_keyword("NOT DEFERRABLE");
13802 }
13803 }
13804
13805 if let Some(initially) = ct.initially_deferred {
13806 self.write_space();
13807 self.write_keyword("INITIALLY");
13808 self.write_space();
13809 if initially {
13810 self.write_keyword("DEFERRED");
13811 } else {
13812 self.write_keyword("IMMEDIATE");
13813 }
13814 }
13815
13816 if let Some(for_each) = ct.for_each {
13817 self.write_space();
13818 self.write_keyword("FOR EACH");
13819 self.write_space();
13820 match for_each {
13821 TriggerForEach::Row => self.write_keyword("ROW"),
13822 TriggerForEach::Statement => self.write_keyword("STATEMENT"),
13823 }
13824 }
13825
13826 if let Some(when) = &ct.when {
13828 self.write_space();
13829 self.write_keyword("WHEN");
13830 if ct.when_paren {
13831 self.write(" (");
13832 self.generate_expression(when)?;
13833 self.write(")");
13834 } else {
13835 self.write_space();
13836 self.generate_expression(when)?;
13837 }
13838 }
13839
13840 self.write_space();
13842 match &ct.body {
13843 TriggerBody::Execute { function, args } => {
13844 self.write_keyword("EXECUTE FUNCTION");
13845 self.write_space();
13846 self.generate_table(function)?;
13847 self.write("(");
13848 for (i, arg) in args.iter().enumerate() {
13849 if i > 0 {
13850 self.write(", ");
13851 }
13852 self.generate_expression(arg)?;
13853 }
13854 self.write(")");
13855 }
13856 TriggerBody::Block(block) => {
13857 self.write_keyword("BEGIN");
13858 self.write_space();
13859 self.write(block);
13860 self.write_space();
13861 self.write_keyword("END");
13862 }
13863 }
13864
13865 Ok(())
13866 }
13867
13868 fn generate_drop_trigger(&mut self, dt: &DropTrigger) -> Result<()> {
13869 self.write_keyword("DROP TRIGGER");
13870
13871 if dt.if_exists {
13872 self.write_space();
13873 self.write_keyword("IF EXISTS");
13874 }
13875
13876 self.write_space();
13877 self.generate_identifier(&dt.name)?;
13878
13879 if let Some(table) = &dt.table {
13880 self.write_space();
13881 self.write_keyword("ON");
13882 self.write_space();
13883 self.generate_table(table)?;
13884 }
13885
13886 if dt.cascade {
13887 self.write_space();
13888 self.write_keyword("CASCADE");
13889 }
13890
13891 Ok(())
13892 }
13893
13894 fn generate_create_type(&mut self, ct: &CreateType) -> Result<()> {
13895 self.write_keyword("CREATE TYPE");
13896
13897 if ct.if_not_exists {
13898 self.write_space();
13899 self.write_keyword("IF NOT EXISTS");
13900 }
13901
13902 self.write_space();
13903 self.generate_table(&ct.name)?;
13904
13905 self.write_space();
13906 self.write_keyword("AS");
13907 self.write_space();
13908
13909 match &ct.definition {
13910 TypeDefinition::Enum(values) => {
13911 self.write_keyword("ENUM");
13912 self.write(" (");
13913 for (i, val) in values.iter().enumerate() {
13914 if i > 0 {
13915 self.write(", ");
13916 }
13917 self.write(&format!("'{}'", val));
13918 }
13919 self.write(")");
13920 }
13921 TypeDefinition::Composite(attrs) => {
13922 self.write("(");
13923 for (i, attr) in attrs.iter().enumerate() {
13924 if i > 0 {
13925 self.write(", ");
13926 }
13927 self.generate_identifier(&attr.name)?;
13928 self.write_space();
13929 self.generate_data_type(&attr.data_type)?;
13930 if let Some(collate) = &attr.collate {
13931 self.write_space();
13932 self.write_keyword("COLLATE");
13933 self.write_space();
13934 self.generate_identifier(collate)?;
13935 }
13936 }
13937 self.write(")");
13938 }
13939 TypeDefinition::Range {
13940 subtype,
13941 subtype_diff,
13942 canonical,
13943 } => {
13944 self.write_keyword("RANGE");
13945 self.write(" (");
13946 self.write_keyword("SUBTYPE");
13947 self.write(" = ");
13948 self.generate_data_type(subtype)?;
13949 if let Some(diff) = subtype_diff {
13950 self.write(", ");
13951 self.write_keyword("SUBTYPE_DIFF");
13952 self.write(" = ");
13953 self.write(diff);
13954 }
13955 if let Some(canon) = canonical {
13956 self.write(", ");
13957 self.write_keyword("CANONICAL");
13958 self.write(" = ");
13959 self.write(canon);
13960 }
13961 self.write(")");
13962 }
13963 TypeDefinition::Base {
13964 input,
13965 output,
13966 internallength,
13967 } => {
13968 self.write("(");
13969 self.write_keyword("INPUT");
13970 self.write(" = ");
13971 self.write(input);
13972 self.write(", ");
13973 self.write_keyword("OUTPUT");
13974 self.write(" = ");
13975 self.write(output);
13976 if let Some(len) = internallength {
13977 self.write(", ");
13978 self.write_keyword("INTERNALLENGTH");
13979 self.write(" = ");
13980 self.write(&len.to_string());
13981 }
13982 self.write(")");
13983 }
13984 TypeDefinition::Domain {
13985 base_type,
13986 default,
13987 constraints,
13988 } => {
13989 self.generate_data_type(base_type)?;
13990 if let Some(def) = default {
13991 self.write_space();
13992 self.write_keyword("DEFAULT");
13993 self.write_space();
13994 self.generate_expression(def)?;
13995 }
13996 for constr in constraints {
13997 self.write_space();
13998 if let Some(name) = &constr.name {
13999 self.write_keyword("CONSTRAINT");
14000 self.write_space();
14001 self.generate_identifier(name)?;
14002 self.write_space();
14003 }
14004 self.write_keyword("CHECK");
14005 self.write(" (");
14006 self.generate_expression(&constr.check)?;
14007 self.write(")");
14008 }
14009 }
14010 }
14011
14012 Ok(())
14013 }
14014
14015 fn generate_create_task(&mut self, task: &crate::expressions::CreateTask) -> Result<()> {
14016 self.write_keyword("CREATE");
14017 if task.or_replace {
14018 self.write_space();
14019 self.write_keyword("OR REPLACE");
14020 }
14021 self.write_space();
14022 self.write_keyword("TASK");
14023 if task.if_not_exists {
14024 self.write_space();
14025 self.write_keyword("IF NOT EXISTS");
14026 }
14027 self.write_space();
14028 self.write(&task.name);
14029 if !task.properties.is_empty() {
14030 if !task.properties.starts_with('\n') && !task.properties.starts_with(' ') {
14032 self.write_space();
14033 }
14034 self.write(&task.properties);
14035 }
14036 self.write_space();
14037 self.write_keyword("AS");
14038 self.write_space();
14039 self.generate_expression(&task.body)?;
14040 Ok(())
14041 }
14042
14043 fn generate_drop_type(&mut self, dt: &DropType) -> Result<()> {
14044 self.write_keyword("DROP TYPE");
14045
14046 if dt.if_exists {
14047 self.write_space();
14048 self.write_keyword("IF EXISTS");
14049 }
14050
14051 self.write_space();
14052 self.generate_table(&dt.name)?;
14053
14054 if dt.cascade {
14055 self.write_space();
14056 self.write_keyword("CASCADE");
14057 }
14058
14059 Ok(())
14060 }
14061
14062 fn generate_describe(&mut self, d: &Describe) -> Result<()> {
14063 let saved_athena_hive_context = self.athena_hive_context;
14065 if matches!(
14066 self.config.dialect,
14067 Some(crate::dialects::DialectType::Athena)
14068 ) {
14069 self.athena_hive_context = true;
14070 }
14071
14072 for comment in &d.leading_comments {
14074 self.write_formatted_comment(comment);
14075 self.write(" ");
14076 }
14077
14078 self.write_keyword("DESCRIBE");
14079
14080 if d.extended {
14081 self.write_space();
14082 self.write_keyword("EXTENDED");
14083 } else if d.formatted {
14084 self.write_space();
14085 self.write_keyword("FORMATTED");
14086 }
14087
14088 if let Some(ref style) = d.style {
14090 self.write_space();
14091 self.write_keyword(style);
14092 }
14093
14094 let should_output_kind = match self.config.dialect {
14096 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
14098 false
14099 }
14100 Some(DialectType::Snowflake) => true,
14102 _ => d.kind.is_some(),
14103 };
14104 if should_output_kind {
14105 if let Some(ref kind) = d.kind {
14106 self.write_space();
14107 self.write_keyword(kind);
14108 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
14109 self.write_space();
14110 self.write_keyword("TABLE");
14111 }
14112 }
14113
14114 self.write_space();
14115 self.generate_expression(&d.target)?;
14116
14117 if !d.params.is_empty() {
14119 self.write("(");
14120 for (i, param) in d.params.iter().enumerate() {
14121 if i > 0 {
14122 self.write(", ");
14123 }
14124 self.write(param);
14125 }
14126 self.write(")");
14127 }
14128
14129 if let Some(ref partition) = d.partition {
14131 self.write_space();
14132 self.generate_expression(partition)?;
14133 }
14134
14135 if d.as_json {
14137 self.write_space();
14138 self.write_keyword("AS JSON");
14139 }
14140
14141 for (name, value) in &d.properties {
14143 self.write_space();
14144 self.write(name);
14145 self.write("=");
14146 self.write(value);
14147 }
14148
14149 self.athena_hive_context = saved_athena_hive_context;
14151
14152 Ok(())
14153 }
14154
14155 fn generate_show(&mut self, s: &Show) -> Result<()> {
14158 self.write_keyword("SHOW");
14159 self.write_space();
14160
14161 let show_terse = s.terse
14164 && !matches!(
14165 s.this.as_str(),
14166 "PRIMARY KEYS" | "UNIQUE KEYS" | "IMPORTED KEYS"
14167 );
14168 if show_terse {
14169 self.write_keyword("TERSE");
14170 self.write_space();
14171 }
14172
14173 self.write_keyword(&s.this);
14175
14176 if let Some(ref target_expr) = s.target {
14178 self.write_space();
14179 self.generate_expression(target_expr)?;
14180 }
14181
14182 if s.history {
14184 self.write_space();
14185 self.write_keyword("HISTORY");
14186 }
14187
14188 if let Some(ref for_target) = s.for_target {
14190 self.write_space();
14191 self.write_keyword("FOR");
14192 self.write_space();
14193 self.generate_expression(for_target)?;
14194 }
14195
14196 use crate::dialects::DialectType;
14200 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
14201 let is_mysql = matches!(self.config.dialect, Some(DialectType::MySQL));
14202 let mysql_tables_scope_as_from = is_mysql
14203 && matches!(s.this.as_str(), "TABLES" | "FULL TABLES")
14204 && s.scope_kind.as_deref() == Some("SCHEMA")
14205 && s.scope.is_some()
14206 && s.from.is_none();
14207
14208 if !is_snowflake && s.from.is_some() {
14209 if let Some(ref scope_kind) = s.scope_kind {
14213 self.write_space();
14214 self.write_keyword("IN");
14215 self.write_space();
14216 self.write_keyword(scope_kind);
14217 if let Some(ref scope) = s.scope {
14218 self.write_space();
14219 self.generate_expression(scope)?;
14220 }
14221 } else if let Some(ref scope) = s.scope {
14222 self.write_space();
14223 self.write_keyword("IN");
14224 self.write_space();
14225 self.generate_expression(scope)?;
14226 }
14227
14228 if let Some(ref from) = s.from {
14230 self.write_space();
14231 self.write_keyword("FROM");
14232 self.write_space();
14233 self.generate_expression(from)?;
14234 }
14235
14236 if let Some(ref db) = s.db {
14238 self.write_space();
14239 self.write_keyword("FROM");
14240 self.write_space();
14241 self.generate_expression(db)?;
14242 }
14243
14244 if let Some(ref like) = s.like {
14246 self.write_space();
14247 self.write_keyword("LIKE");
14248 self.write_space();
14249 self.generate_expression(like)?;
14250 }
14251 } else {
14252 if let Some(ref like) = s.like {
14256 self.write_space();
14257 self.write_keyword("LIKE");
14258 self.write_space();
14259 self.generate_expression(like)?;
14260 }
14261
14262 if mysql_tables_scope_as_from {
14264 self.write_space();
14265 self.write_keyword("FROM");
14266 self.write_space();
14267 self.generate_expression(s.scope.as_ref().unwrap())?;
14268 } else if let Some(ref scope_kind) = s.scope_kind {
14269 self.write_space();
14270 self.write_keyword("IN");
14271 self.write_space();
14272 self.write_keyword(scope_kind);
14273 if let Some(ref scope) = s.scope {
14274 self.write_space();
14275 self.generate_expression(scope)?;
14276 }
14277 } else if let Some(ref scope) = s.scope {
14278 self.write_space();
14279 self.write_keyword("IN");
14280 self.write_space();
14281 self.generate_expression(scope)?;
14282 }
14283 }
14284
14285 if let Some(ref starts_with) = s.starts_with {
14287 self.write_space();
14288 self.write_keyword("STARTS WITH");
14289 self.write_space();
14290 self.generate_expression(starts_with)?;
14291 }
14292
14293 if let Some(ref limit) = s.limit {
14295 self.write_space();
14296 self.generate_limit(limit)?;
14297 }
14298
14299 if is_snowflake {
14301 if let Some(ref from) = s.from {
14302 self.write_space();
14303 self.write_keyword("FROM");
14304 self.write_space();
14305 self.generate_expression(from)?;
14306 }
14307 }
14308
14309 if let Some(ref where_clause) = s.where_clause {
14311 self.write_space();
14312 self.write_keyword("WHERE");
14313 self.write_space();
14314 self.generate_expression(where_clause)?;
14315 }
14316
14317 if let Some(is_mutex) = s.mutex {
14319 self.write_space();
14320 if is_mutex {
14321 self.write_keyword("MUTEX");
14322 } else {
14323 self.write_keyword("STATUS");
14324 }
14325 }
14326
14327 if !s.privileges.is_empty() {
14329 self.write_space();
14330 self.write_keyword("WITH PRIVILEGES");
14331 self.write_space();
14332 for (i, priv_name) in s.privileges.iter().enumerate() {
14333 if i > 0 {
14334 self.write(", ");
14335 }
14336 self.write_keyword(priv_name);
14337 }
14338 }
14339
14340 Ok(())
14341 }
14342
14343 fn generate_literal(&mut self, lit: &Literal) -> Result<()> {
14346 use crate::dialects::DialectType;
14347 match lit {
14348 Literal::String(s) => {
14349 self.generate_string_literal(s)?;
14350 }
14351 Literal::Number(n) => {
14352 if matches!(self.config.dialect, Some(DialectType::MySQL))
14353 && n.len() > 2
14354 && (n.starts_with("0x") || n.starts_with("0X"))
14355 && !n[2..].chars().all(|c| c.is_ascii_hexdigit())
14356 {
14357 return self.generate_identifier(&Identifier {
14358 name: n.clone(),
14359 quoted: true,
14360 trailing_comments: Vec::new(),
14361 span: None,
14362 });
14363 }
14364 let n = if n.contains('_')
14368 && !matches!(
14369 self.config.dialect,
14370 Some(DialectType::ClickHouse)
14371 | Some(DialectType::DuckDB)
14372 | Some(DialectType::PostgreSQL)
14373 | Some(DialectType::Hive)
14374 | Some(DialectType::Spark)
14375 | Some(DialectType::Databricks)
14376 ) {
14377 std::borrow::Cow::Owned(n.replace('_', ""))
14378 } else {
14379 std::borrow::Cow::Borrowed(n.as_str())
14380 };
14381 if n.starts_with('.') {
14384 self.write("0");
14385 self.write(&n);
14386 } else if n.starts_with("-.") {
14387 self.write("-0");
14389 self.write(&n[1..]);
14390 } else {
14391 self.write(&n);
14392 }
14393 }
14394 Literal::HexString(h) => {
14395 match self.config.dialect {
14397 Some(DialectType::Spark)
14398 | Some(DialectType::Databricks)
14399 | Some(DialectType::Teradata) => self.write("X'"),
14400 _ => self.write("x'"),
14401 }
14402 self.write(h);
14403 self.write("'");
14404 }
14405 Literal::HexNumber(h) => {
14406 match self.config.dialect {
14410 Some(DialectType::BigQuery)
14411 | Some(DialectType::TSQL)
14412 | Some(DialectType::Fabric) => {
14413 self.write("0x");
14414 self.write(h);
14415 }
14416 _ => {
14417 if let Ok(val) = u64::from_str_radix(h, 16) {
14419 self.write(&val.to_string());
14420 } else {
14421 self.write("0x");
14423 self.write(h);
14424 }
14425 }
14426 }
14427 }
14428 Literal::BitString(b) => {
14429 self.write("B'");
14431 self.write(b);
14432 self.write("'");
14433 }
14434 Literal::ByteString(b) => {
14435 self.write("b'");
14437 self.write_escaped_byte_string(b);
14439 self.write("'");
14440 }
14441 Literal::NationalString(s) => {
14442 let keep_n_prefix = matches!(
14445 self.config.dialect,
14446 Some(DialectType::TSQL)
14447 | Some(DialectType::Oracle)
14448 | Some(DialectType::MySQL)
14449 | None
14450 );
14451 if keep_n_prefix {
14452 self.write("N'");
14453 } else {
14454 self.write("'");
14455 }
14456 self.write(s);
14457 self.write("'");
14458 }
14459 Literal::Date(d) => {
14460 self.generate_date_literal(d)?;
14461 }
14462 Literal::Time(t) => {
14463 self.generate_time_literal(t)?;
14464 }
14465 Literal::Timestamp(ts) => {
14466 self.generate_timestamp_literal(ts)?;
14467 }
14468 Literal::Datetime(dt) => {
14469 self.generate_datetime_literal(dt)?;
14470 }
14471 Literal::TripleQuotedString(s, _quote_char) => {
14472 if matches!(
14474 self.config.dialect,
14475 Some(crate::dialects::DialectType::BigQuery)
14476 | Some(crate::dialects::DialectType::DuckDB)
14477 | Some(crate::dialects::DialectType::Snowflake)
14478 | Some(crate::dialects::DialectType::Spark)
14479 | Some(crate::dialects::DialectType::Hive)
14480 | Some(crate::dialects::DialectType::Presto)
14481 | Some(crate::dialects::DialectType::Trino)
14482 | Some(crate::dialects::DialectType::PostgreSQL)
14483 | Some(crate::dialects::DialectType::MySQL)
14484 | Some(crate::dialects::DialectType::Redshift)
14485 | Some(crate::dialects::DialectType::TSQL)
14486 | Some(crate::dialects::DialectType::Oracle)
14487 | Some(crate::dialects::DialectType::ClickHouse)
14488 | Some(crate::dialects::DialectType::Databricks)
14489 | Some(crate::dialects::DialectType::SQLite)
14490 ) {
14491 self.generate_string_literal(s)?;
14492 } else {
14493 let quotes = format!("{0}{0}{0}", _quote_char);
14495 self.write("es);
14496 self.write(s);
14497 self.write("es);
14498 }
14499 }
14500 Literal::EscapeString(s) => {
14501 use crate::dialects::DialectType;
14505 let content = if let Some(c) = s.strip_prefix("e:") {
14506 c
14507 } else if let Some(c) = s.strip_prefix("E:") {
14508 c
14509 } else {
14510 s.as_str()
14511 };
14512
14513 if matches!(
14515 self.config.dialect,
14516 Some(DialectType::MySQL) | Some(DialectType::TiDB)
14517 ) {
14518 self.write(content);
14519 } else {
14520 let prefix = if matches!(
14522 self.config.dialect,
14523 Some(DialectType::SingleStore)
14524 | Some(DialectType::DuckDB)
14525 | Some(DialectType::PostgreSQL)
14526 | Some(DialectType::CockroachDB)
14527 | Some(DialectType::Materialize)
14528 | Some(DialectType::RisingWave)
14529 ) {
14530 "e'"
14531 } else {
14532 "E'"
14533 };
14534
14535 let normalized = content.replace("\\'", "''");
14537 self.write(prefix);
14538 self.write(&normalized);
14539 self.write("'");
14540 }
14541 }
14542 Literal::DollarString(s) => {
14543 use crate::dialects::DialectType;
14546 let (_tag, content) = crate::tokens::parse_dollar_string_token(s);
14548 let escape_backslash = matches!(self.config.dialect, Some(DialectType::Snowflake));
14550 let use_backslash_quote =
14554 matches!(self.config.dialect, Some(DialectType::Snowflake));
14555
14556 let mut escaped = String::with_capacity(content.len() + 4);
14557 for ch in content.chars() {
14558 if escape_backslash && ch == '\\' {
14559 escaped.push('\\');
14561 escaped.push('\\');
14562 } else if ch == '\'' {
14563 if use_backslash_quote {
14564 escaped.push('\\');
14565 escaped.push('\'');
14566 } else {
14567 escaped.push('\'');
14568 escaped.push('\'');
14569 }
14570 } else {
14571 escaped.push(ch);
14572 }
14573 }
14574 self.write("'");
14575 self.write(&escaped);
14576 self.write("'");
14577 }
14578 Literal::RawString(s) => {
14579 use crate::dialects::DialectType;
14585
14586 let escape_backslash = matches!(
14588 self.config.dialect,
14589 Some(DialectType::BigQuery)
14590 | Some(DialectType::MySQL)
14591 | Some(DialectType::SingleStore)
14592 | Some(DialectType::TiDB)
14593 | Some(DialectType::Hive)
14594 | Some(DialectType::Spark)
14595 | Some(DialectType::Databricks)
14596 | Some(DialectType::Drill)
14597 | Some(DialectType::Snowflake)
14598 | Some(DialectType::Redshift)
14599 | Some(DialectType::ClickHouse)
14600 );
14601
14602 let backslash_escapes_quote = matches!(
14605 self.config.dialect,
14606 Some(DialectType::BigQuery)
14607 | Some(DialectType::Hive)
14608 | Some(DialectType::Spark)
14609 | Some(DialectType::Databricks)
14610 | Some(DialectType::Drill)
14611 | Some(DialectType::Snowflake)
14612 | Some(DialectType::Redshift)
14613 );
14614
14615 let supports_escape_sequences = escape_backslash;
14618
14619 let mut escaped = String::with_capacity(s.len() + 4);
14620 for ch in s.chars() {
14621 if escape_backslash && ch == '\\' {
14622 escaped.push('\\');
14624 escaped.push('\\');
14625 } else if ch == '\'' {
14626 if backslash_escapes_quote {
14627 escaped.push('\\');
14629 escaped.push('\'');
14630 } else {
14631 escaped.push('\'');
14633 escaped.push('\'');
14634 }
14635 } else if supports_escape_sequences {
14636 match ch {
14639 '\n' => {
14640 escaped.push('\\');
14641 escaped.push('n');
14642 }
14643 '\r' => {
14644 escaped.push('\\');
14645 escaped.push('r');
14646 }
14647 '\t' => {
14648 escaped.push('\\');
14649 escaped.push('t');
14650 }
14651 '\x07' => {
14652 escaped.push('\\');
14653 escaped.push('a');
14654 }
14655 '\x08' => {
14656 escaped.push('\\');
14657 escaped.push('b');
14658 }
14659 '\x0C' => {
14660 escaped.push('\\');
14661 escaped.push('f');
14662 }
14663 '\x0B' => {
14664 escaped.push('\\');
14665 escaped.push('v');
14666 }
14667 _ => escaped.push(ch),
14668 }
14669 } else {
14670 escaped.push(ch);
14671 }
14672 }
14673 self.write("'");
14674 self.write(&escaped);
14675 self.write("'");
14676 }
14677 }
14678 Ok(())
14679 }
14680
14681 fn generate_date_literal(&mut self, d: &str) -> Result<()> {
14683 use crate::dialects::DialectType;
14684
14685 match self.config.dialect {
14686 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
14688 self.write("CAST('");
14689 self.write(d);
14690 self.write("' AS DATE)");
14691 }
14692 Some(DialectType::BigQuery) => {
14695 self.write("CAST('");
14696 self.write(d);
14697 self.write("' AS DATE)");
14698 }
14699 Some(DialectType::Exasol) => {
14702 self.write("CAST('");
14703 self.write(d);
14704 self.write("' AS DATE)");
14705 }
14706 Some(DialectType::Snowflake) => {
14709 self.write("CAST('");
14710 self.write(d);
14711 self.write("' AS DATE)");
14712 }
14713 Some(DialectType::PostgreSQL)
14715 | Some(DialectType::MySQL)
14716 | Some(DialectType::SingleStore)
14717 | Some(DialectType::TiDB)
14718 | Some(DialectType::Redshift) => {
14719 self.write("CAST('");
14720 self.write(d);
14721 self.write("' AS DATE)");
14722 }
14723 Some(DialectType::DuckDB)
14725 | Some(DialectType::Presto)
14726 | Some(DialectType::Trino)
14727 | Some(DialectType::Athena)
14728 | Some(DialectType::Spark)
14729 | Some(DialectType::Databricks)
14730 | Some(DialectType::Hive) => {
14731 self.write("CAST('");
14732 self.write(d);
14733 self.write("' AS DATE)");
14734 }
14735 Some(DialectType::Oracle) => {
14737 self.write("TO_DATE('");
14738 self.write(d);
14739 self.write("', 'YYYY-MM-DD')");
14740 }
14741 _ => {
14743 self.write_keyword("DATE");
14744 self.write(" '");
14745 self.write(d);
14746 self.write("'");
14747 }
14748 }
14749 Ok(())
14750 }
14751
14752 fn generate_time_literal(&mut self, t: &str) -> Result<()> {
14754 use crate::dialects::DialectType;
14755
14756 match self.config.dialect {
14757 Some(DialectType::TSQL) => {
14759 self.write("CAST('");
14760 self.write(t);
14761 self.write("' AS TIME)");
14762 }
14763 _ => {
14765 self.write_keyword("TIME");
14766 self.write(" '");
14767 self.write(t);
14768 self.write("'");
14769 }
14770 }
14771 Ok(())
14772 }
14773
14774 fn generate_dremio_date_expression(&mut self, expr: &Expression) -> Result<()> {
14776 use crate::expressions::Literal;
14777
14778 match expr {
14779 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Date(_)) => {
14780 let Literal::Date(d) = lit.as_ref() else {
14781 unreachable!()
14782 };
14783 self.write("CAST('");
14785 self.write(d);
14786 self.write("' AS DATE)");
14787 }
14788 _ => {
14789 self.generate_expression(expr)?;
14791 }
14792 }
14793 Ok(())
14794 }
14795
14796 fn generate_timestamp_literal(&mut self, ts: &str) -> Result<()> {
14798 use crate::dialects::DialectType;
14799
14800 match self.config.dialect {
14801 Some(DialectType::TSQL) => {
14803 self.write("CAST('");
14804 self.write(ts);
14805 self.write("' AS DATETIME2)");
14806 }
14807 Some(DialectType::BigQuery) => {
14810 self.write("CAST('");
14811 self.write(ts);
14812 self.write("' AS TIMESTAMP)");
14813 }
14814 Some(DialectType::Snowflake) => {
14817 self.write("CAST('");
14818 self.write(ts);
14819 self.write("' AS TIMESTAMP)");
14820 }
14821 Some(DialectType::Dremio) => {
14824 self.write("CAST('");
14825 self.write(ts);
14826 self.write("' AS TIMESTAMP)");
14827 }
14828 Some(DialectType::Exasol) => {
14831 self.write("CAST('");
14832 self.write(ts);
14833 self.write("' AS TIMESTAMP)");
14834 }
14835 Some(DialectType::Oracle) => {
14838 self.write("TO_TIMESTAMP('");
14839 self.write(ts);
14840 self.write("', 'YYYY-MM-DD HH24:MI:SS.FF6')");
14841 }
14842 Some(DialectType::Presto) | Some(DialectType::Trino) => {
14844 if Self::timestamp_has_timezone(ts) {
14845 self.write("CAST('");
14846 self.write(ts);
14847 self.write("' AS TIMESTAMP WITH TIME ZONE)");
14848 } else {
14849 self.write("CAST('");
14850 self.write(ts);
14851 self.write("' AS TIMESTAMP)");
14852 }
14853 }
14854 Some(DialectType::ClickHouse) => {
14856 self.write("CAST('");
14857 self.write(ts);
14858 self.write("' AS Nullable(DateTime))");
14859 }
14860 Some(DialectType::Spark) => {
14862 self.write("CAST('");
14863 self.write(ts);
14864 self.write("' AS TIMESTAMP)");
14865 }
14866 Some(DialectType::Redshift) => {
14869 if ts == "epoch" {
14870 self.write_keyword("TIMESTAMP");
14871 self.write(" '");
14872 self.write(ts);
14873 self.write("'");
14874 } else {
14875 self.write("CAST('");
14876 self.write(ts);
14877 self.write("' AS TIMESTAMP)");
14878 }
14879 }
14880 Some(DialectType::PostgreSQL)
14882 | Some(DialectType::Hive)
14883 | Some(DialectType::SQLite)
14884 | Some(DialectType::DuckDB)
14885 | Some(DialectType::Athena)
14886 | Some(DialectType::Drill)
14887 | Some(DialectType::Teradata) => {
14888 self.write("CAST('");
14889 self.write(ts);
14890 self.write("' AS TIMESTAMP)");
14891 }
14892 Some(DialectType::MySQL) | Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
14894 self.write("CAST('");
14895 self.write(ts);
14896 self.write("' AS DATETIME)");
14897 }
14898 Some(DialectType::Databricks) => {
14900 self.write("CAST('");
14901 self.write(ts);
14902 self.write("' AS TIMESTAMP_NTZ)");
14903 }
14904 _ => {
14906 self.write_keyword("TIMESTAMP");
14907 self.write(" '");
14908 self.write(ts);
14909 self.write("'");
14910 }
14911 }
14912 Ok(())
14913 }
14914
14915 fn timestamp_has_timezone(ts: &str) -> bool {
14918 let ts_lower = ts.to_ascii_lowercase();
14922
14923 let continent_prefixes = [
14925 "africa/",
14926 "america/",
14927 "antarctica/",
14928 "arctic/",
14929 "asia/",
14930 "atlantic/",
14931 "australia/",
14932 "europe/",
14933 "indian/",
14934 "pacific/",
14935 "etc/",
14936 "brazil/",
14937 "canada/",
14938 "chile/",
14939 "mexico/",
14940 "us/",
14941 ];
14942
14943 for prefix in &continent_prefixes {
14944 if ts_lower.contains(prefix) {
14945 return true;
14946 }
14947 }
14948
14949 let tz_abbrevs = [
14952 " utc", " gmt", " cet", " cest", " eet", " eest", " wet", " west", " est", " edt",
14953 " cst", " cdt", " mst", " mdt", " pst", " pdt", " ist", " bst", " jst", " kst", " hkt",
14954 " sgt", " aest", " aedt", " acst", " acdt", " awst",
14955 ];
14956
14957 for abbrev in &tz_abbrevs {
14958 if ts_lower.ends_with(abbrev) {
14959 return true;
14960 }
14961 }
14962
14963 let trimmed = ts.trim();
14967 if let Some(last_space) = trimmed.rfind(' ') {
14968 let suffix = &trimmed[last_space + 1..];
14969 if (suffix.starts_with('+') || suffix.starts_with('-')) && suffix.len() > 1 {
14970 let rest = &suffix[1..];
14972 if rest.chars().all(|c| c.is_ascii_digit() || c == ':') {
14973 return true;
14974 }
14975 }
14976 }
14977
14978 false
14979 }
14980
14981 fn generate_datetime_literal(&mut self, dt: &str) -> Result<()> {
14983 use crate::dialects::DialectType;
14984
14985 match self.config.dialect {
14986 Some(DialectType::BigQuery) => {
14989 self.write("CAST('");
14990 self.write(dt);
14991 self.write("' AS DATETIME)");
14992 }
14993 Some(DialectType::DuckDB) => {
14995 self.write("CAST('");
14996 self.write(dt);
14997 self.write("' AS TIMESTAMP)");
14998 }
14999 _ => {
15002 self.write_keyword("DATETIME");
15003 self.write(" '");
15004 self.write(dt);
15005 self.write("'");
15006 }
15007 }
15008 Ok(())
15009 }
15010
15011 fn generate_string_literal(&mut self, s: &str) -> Result<()> {
15013 use crate::dialects::DialectType;
15014
15015 match self.config.dialect {
15016 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
15020 self.write("'");
15022 for c in s.chars() {
15023 match c {
15024 '\'' => self.write("\\'"),
15025 '\\' => self.write("\\\\"),
15026 '\n' => self.write("\\n"),
15027 '\r' => self.write("\\r"),
15028 '\t' => self.write("\\t"),
15029 '\0' => self.write("\\0"),
15030 _ => self.output.push(c),
15031 }
15032 }
15033 self.write("'");
15034 }
15035 Some(DialectType::Drill) => {
15036 self.write("'");
15039 for c in s.chars() {
15040 match c {
15041 '\'' => self.write("''"),
15042 '\\' => self.write("\\\\"),
15043 '\n' => self.write("\\n"),
15044 '\r' => self.write("\\r"),
15045 '\t' => self.write("\\t"),
15046 '\0' => self.write("\\0"),
15047 _ => self.output.push(c),
15048 }
15049 }
15050 self.write("'");
15051 }
15052 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB) => {
15053 self.write("'");
15054 for c in s.chars() {
15055 match c {
15056 '\'' => self.write("''"),
15058 '\\' => self.write("\\\\"),
15059 '\n' => self.write("\\n"),
15060 '\r' => self.write("\\r"),
15061 '\t' => self.write("\\t"),
15062 '\0' => self.output.push('\0'),
15064 _ => self.output.push(c),
15065 }
15066 }
15067 self.write("'");
15068 }
15069 Some(DialectType::BigQuery) => {
15071 self.write("'");
15072 for c in s.chars() {
15073 match c {
15074 '\'' => self.write("\\'"),
15075 '\\' => self.write("\\\\"),
15076 '\n' => self.write("\\n"),
15077 '\r' => self.write("\\r"),
15078 '\t' => self.write("\\t"),
15079 '\0' => self.write("\\0"),
15080 '\x07' => self.write("\\a"),
15081 '\x08' => self.write("\\b"),
15082 '\x0C' => self.write("\\f"),
15083 '\x0B' => self.write("\\v"),
15084 _ => self.output.push(c),
15085 }
15086 }
15087 self.write("'");
15088 }
15089 Some(DialectType::Athena) => {
15093 if self.athena_hive_context {
15094 self.write("'");
15096 for c in s.chars() {
15097 match c {
15098 '\'' => self.write("\\'"),
15099 '\\' => self.write("\\\\"),
15100 '\n' => self.write("\\n"),
15101 '\r' => self.write("\\r"),
15102 '\t' => self.write("\\t"),
15103 '\0' => self.write("\\0"),
15104 _ => self.output.push(c),
15105 }
15106 }
15107 self.write("'");
15108 } else {
15109 self.write("'");
15111 for c in s.chars() {
15112 match c {
15113 '\'' => self.write("''"),
15114 _ => self.output.push(c),
15116 }
15117 }
15118 self.write("'");
15119 }
15120 }
15121 Some(DialectType::Snowflake) => {
15126 self.write("'");
15127 for c in s.chars() {
15128 match c {
15129 '\'' => self.write("\\'"),
15130 '\n' => self.write("\\n"),
15133 '\r' => self.write("\\r"),
15134 '\t' => self.write("\\t"),
15135 _ => self.output.push(c),
15136 }
15137 }
15138 self.write("'");
15139 }
15140 Some(DialectType::PostgreSQL) => {
15142 self.write("'");
15143 for c in s.chars() {
15144 match c {
15145 '\'' => self.write("''"),
15146 _ => self.output.push(c),
15147 }
15148 }
15149 self.write("'");
15150 }
15151 Some(DialectType::Redshift) => {
15153 self.write("'");
15154 for c in s.chars() {
15155 match c {
15156 '\'' => self.write("\\'"),
15157 _ => self.output.push(c),
15158 }
15159 }
15160 self.write("'");
15161 }
15162 Some(DialectType::Oracle) => {
15164 self.write("'");
15165 for ch in s.chars() {
15166 if ch == '\'' {
15167 self.output.push_str("''");
15168 } else {
15169 self.output.push(ch);
15170 }
15171 }
15172 self.write("'");
15173 }
15174 Some(DialectType::ClickHouse) => {
15177 self.write("'");
15178 for c in s.chars() {
15179 match c {
15180 '\'' => self.write("''"),
15181 '\\' => self.write("\\\\"),
15182 '\n' => self.write("\\n"),
15183 '\r' => self.write("\\r"),
15184 '\t' => self.write("\\t"),
15185 '\0' => self.write("\\0"),
15186 '\x07' => self.write("\\a"),
15187 '\x08' => self.write("\\b"),
15188 '\x0C' => self.write("\\f"),
15189 '\x0B' => self.write("\\v"),
15190 c if c.is_control() || (c as u32) < 0x20 => {
15192 let byte = c as u32;
15193 if byte < 256 {
15194 self.write(&format!("\\x{:02X}", byte));
15195 } else {
15196 self.output.push(c);
15197 }
15198 }
15199 _ => self.output.push(c),
15200 }
15201 }
15202 self.write("'");
15203 }
15204 _ => {
15207 self.write("'");
15208 for ch in s.chars() {
15209 if ch == '\'' {
15210 self.output.push_str("''");
15211 } else {
15212 self.output.push(ch);
15213 }
15214 }
15215 self.write("'");
15216 }
15217 }
15218 Ok(())
15219 }
15220
15221 fn write_escaped_byte_string(&mut self, s: &str) {
15224 for c in s.chars() {
15225 match c {
15226 '\'' => self.write("\\'"),
15228 '\\' => self.write("\\\\"),
15230 _ if !c.is_control() => self.output.push(c),
15232 _ => {
15234 let byte = c as u32;
15235 if byte < 256 {
15236 self.write(&format!("\\x{:02x}", byte));
15237 } else {
15238 for b in c.to_string().as_bytes() {
15240 self.write(&format!("\\x{:02x}", b));
15241 }
15242 }
15243 }
15244 }
15245 }
15246 }
15247
15248 fn generate_boolean(&mut self, b: &BooleanLiteral) -> Result<()> {
15249 use crate::dialects::DialectType;
15250
15251 match self.config.dialect {
15253 Some(DialectType::TSQL) => {
15256 self.write(if b.value { "1" } else { "0" });
15257 }
15258 Some(DialectType::Oracle) => {
15260 self.write(if b.value { "1" } else { "0" });
15261 }
15262 Some(DialectType::MySQL) => {
15264 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
15265 }
15266 _ => {
15268 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
15269 }
15270 }
15271 Ok(())
15272 }
15273
15274 fn generate_alias_identifier(&mut self, id: &Identifier) -> Result<()> {
15277 let name = &id.name;
15278 let quote_style = &self.config.identifier_quote_style;
15279
15280 let needs_quoting = id.quoted || self.is_reserved_keyword(name);
15284
15285 let output_name = if self.config.normalize_identifiers && !id.quoted {
15287 name.to_ascii_lowercase()
15288 } else {
15289 name.to_string()
15290 };
15291
15292 if needs_quoting {
15293 let escaped_name = if quote_style.start == quote_style.end {
15295 output_name.replace(
15296 quote_style.end,
15297 &format!("{}{}", quote_style.end, quote_style.end),
15298 )
15299 } else {
15300 output_name.replace(
15301 quote_style.end,
15302 &format!("{}{}", quote_style.end, quote_style.end),
15303 )
15304 };
15305 self.write(&format!(
15306 "{}{}{}",
15307 quote_style.start, escaped_name, quote_style.end
15308 ));
15309 } else {
15310 self.write(&output_name);
15311 }
15312
15313 for comment in &id.trailing_comments {
15315 self.write(" ");
15316 self.write_formatted_comment(comment);
15317 }
15318 Ok(())
15319 }
15320
15321 fn generate_identifier(&mut self, id: &Identifier) -> Result<()> {
15322 use crate::dialects::DialectType;
15323
15324 let name = &id.name;
15325
15326 let quote_style = if matches!(self.config.dialect, Some(DialectType::Athena))
15328 && self.athena_hive_context
15329 {
15330 &IdentifierQuoteStyle::BACKTICK
15331 } else {
15332 &self.config.identifier_quote_style
15333 };
15334
15335 let starts_with_digit = name.chars().next().map_or(false, |c| c.is_ascii_digit());
15342 let needs_digit_quoting = starts_with_digit
15343 && !self.config.identifiers_can_start_with_digit
15344 && self.config.dialect.is_some();
15345 let mysql_invalid_hex_identifier = matches!(self.config.dialect, Some(DialectType::MySQL))
15346 && name.len() > 2
15347 && (name.starts_with("0x") || name.starts_with("0X"))
15348 && !name[2..].chars().all(|c| c.is_ascii_hexdigit());
15349 let needs_quoting = id.quoted
15350 || self.is_reserved_keyword(name)
15351 || self.config.always_quote_identifiers
15352 || needs_digit_quoting
15353 || mysql_invalid_hex_identifier;
15354
15355 let (base_name, suffix) = if needs_quoting {
15358 if let Some(paren_pos) = name.find('(') {
15360 let base = &name[..paren_pos];
15361 let rest = &name[paren_pos..];
15362 if rest.starts_with('(')
15364 && (rest.ends_with(')') || rest.ends_with(") ASC") || rest.ends_with(") DESC"))
15365 {
15366 let close_paren = rest.find(')').unwrap_or(rest.len());
15368 let inside = &rest[1..close_paren];
15369 if inside.chars().all(|c| c.is_ascii_digit()) {
15370 (base.to_string(), rest.to_string())
15371 } else {
15372 (name.to_string(), String::new())
15373 }
15374 } else {
15375 (name.to_string(), String::new())
15376 }
15377 } else if name.ends_with(" ASC") {
15378 let base = &name[..name.len() - 4];
15379 (base.to_string(), " ASC".to_string())
15380 } else if name.ends_with(" DESC") {
15381 let base = &name[..name.len() - 5];
15382 (base.to_string(), " DESC".to_string())
15383 } else {
15384 (name.to_string(), String::new())
15385 }
15386 } else {
15387 (name.to_string(), String::new())
15388 };
15389
15390 let output_name = if self.config.normalize_identifiers && !id.quoted {
15394 base_name.to_ascii_lowercase()
15395 } else if matches!(self.config.dialect, Some(DialectType::Exasol))
15396 && !id.quoted
15397 && self.is_reserved_keyword(name)
15398 {
15399 base_name.to_ascii_uppercase()
15402 } else {
15403 base_name
15404 };
15405
15406 if needs_quoting {
15407 let escaped_name = if quote_style.start == quote_style.end {
15409 output_name.replace(
15411 quote_style.end,
15412 &format!("{}{}", quote_style.end, quote_style.end),
15413 )
15414 } else {
15415 output_name.replace(
15417 quote_style.end,
15418 &format!("{}{}", quote_style.end, quote_style.end),
15419 )
15420 };
15421 self.write(&format!(
15422 "{}{}{}{}",
15423 quote_style.start, escaped_name, quote_style.end, suffix
15424 ));
15425 } else {
15426 self.write(&output_name);
15427 }
15428
15429 for comment in &id.trailing_comments {
15431 self.write(" ");
15432 self.write_formatted_comment(comment);
15433 }
15434 Ok(())
15435 }
15436
15437 fn generate_column(&mut self, col: &Column) -> Result<()> {
15438 use crate::dialects::DialectType;
15439
15440 if let Some(table) = &col.table {
15441 let is_exasol_local_prefix = matches!(self.config.dialect, Some(DialectType::Exasol))
15445 && !table.quoted
15446 && table.name.eq_ignore_ascii_case("LOCAL");
15447
15448 if is_exasol_local_prefix {
15449 self.write("LOCAL");
15451 } else {
15452 self.generate_identifier(table)?;
15453 }
15454 self.write(".");
15455 }
15456 self.generate_identifier(&col.name)?;
15457 if col.join_mark && self.config.supports_column_join_marks {
15460 self.write(" (+)");
15461 }
15462 for comment in &col.trailing_comments {
15464 self.write_space();
15465 self.write_formatted_comment(comment);
15466 }
15467 Ok(())
15468 }
15469
15470 fn generate_pseudocolumn(&mut self, pc: &Pseudocolumn) -> Result<()> {
15473 use crate::dialects::DialectType;
15474 use crate::expressions::PseudocolumnType;
15475
15476 if pc.kind == PseudocolumnType::Sysdate
15478 && !matches!(
15479 self.config.dialect,
15480 Some(DialectType::Oracle) | Some(DialectType::Redshift) | None
15481 )
15482 {
15483 self.write_keyword("CURRENT_TIMESTAMP");
15484 if matches!(
15486 self.config.dialect,
15487 Some(DialectType::MySQL)
15488 | Some(DialectType::ClickHouse)
15489 | Some(DialectType::Spark)
15490 | Some(DialectType::Databricks)
15491 | Some(DialectType::Hive)
15492 ) {
15493 self.write("()");
15494 }
15495 } else {
15496 self.write(pc.kind.as_str());
15497 }
15498 Ok(())
15499 }
15500
15501 fn generate_connect(&mut self, connect: &Connect) -> Result<()> {
15503 use crate::dialects::DialectType;
15504
15505 let supports_connect_by = matches!(
15508 self.config.dialect,
15509 Some(DialectType::Oracle) | Some(DialectType::Snowflake)
15510 );
15511
15512 if !supports_connect_by && self.config.dialect.is_some() {
15513 if self.config.pretty {
15515 self.write_newline();
15516 } else {
15517 self.write_space();
15518 }
15519 self.write_unsupported_comment(
15520 "CONNECT BY requires manual conversion to recursive CTE",
15521 )?;
15522 }
15523
15524 if let Some(start) = &connect.start {
15526 if self.config.pretty {
15527 self.write_newline();
15528 } else {
15529 self.write_space();
15530 }
15531 self.write_keyword("START WITH");
15532 self.write_space();
15533 self.generate_expression(start)?;
15534 }
15535
15536 if self.config.pretty {
15538 self.write_newline();
15539 } else {
15540 self.write_space();
15541 }
15542 self.write_keyword("CONNECT BY");
15543 if connect.nocycle {
15544 self.write_space();
15545 self.write_keyword("NOCYCLE");
15546 }
15547 self.write_space();
15548 self.generate_expression(&connect.connect)?;
15549
15550 Ok(())
15551 }
15552
15553 fn generate_connect_expr(&mut self, connect: &Connect) -> Result<()> {
15555 self.generate_connect(connect)
15556 }
15557
15558 fn generate_prior(&mut self, prior: &Prior) -> Result<()> {
15560 self.write_keyword("PRIOR");
15561 self.write_space();
15562 self.generate_expression(&prior.this)?;
15563 Ok(())
15564 }
15565
15566 fn generate_connect_by_root(&mut self, cbr: &ConnectByRoot) -> Result<()> {
15569 self.write_keyword("CONNECT_BY_ROOT");
15570 self.write_space();
15571 self.generate_expression(&cbr.this)?;
15572 Ok(())
15573 }
15574
15575 fn generate_match_recognize(&mut self, mr: &MatchRecognize) -> Result<()> {
15577 use crate::dialects::DialectType;
15578
15579 let supports_match_recognize = matches!(
15581 self.config.dialect,
15582 Some(DialectType::Oracle)
15583 | Some(DialectType::Snowflake)
15584 | Some(DialectType::Presto)
15585 | Some(DialectType::Trino)
15586 );
15587
15588 if let Some(source) = &mr.this {
15590 self.generate_expression(source)?;
15591 }
15592
15593 if !supports_match_recognize {
15594 self.write_unsupported_comment("MATCH_RECOGNIZE not supported in this dialect")?;
15595 return Ok(());
15596 }
15597
15598 if self.config.pretty {
15600 self.write_newline();
15601 } else {
15602 self.write_space();
15603 }
15604
15605 self.write_keyword("MATCH_RECOGNIZE");
15606 self.write(" (");
15607
15608 if self.config.pretty {
15609 self.indent_level += 1;
15610 }
15611
15612 let mut needs_separator = false;
15613
15614 if let Some(partition_by) = &mr.partition_by {
15616 if !partition_by.is_empty() {
15617 if self.config.pretty {
15618 self.write_newline();
15619 self.write_indent();
15620 }
15621 self.write_keyword("PARTITION BY");
15622 self.write_space();
15623 for (i, expr) in partition_by.iter().enumerate() {
15624 if i > 0 {
15625 self.write(", ");
15626 }
15627 self.generate_expression(expr)?;
15628 }
15629 needs_separator = true;
15630 }
15631 }
15632
15633 if let Some(order_by) = &mr.order_by {
15635 if !order_by.is_empty() {
15636 if needs_separator {
15637 if self.config.pretty {
15638 self.write_newline();
15639 self.write_indent();
15640 } else {
15641 self.write_space();
15642 }
15643 } else if self.config.pretty {
15644 self.write_newline();
15645 self.write_indent();
15646 }
15647 self.write_keyword("ORDER BY");
15648 if self.config.pretty {
15650 self.indent_level += 1;
15651 for (i, ordered) in order_by.iter().enumerate() {
15652 if i > 0 {
15653 self.write(",");
15654 }
15655 self.write_newline();
15656 self.write_indent();
15657 self.generate_ordered(ordered)?;
15658 }
15659 self.indent_level -= 1;
15660 } else {
15661 self.write_space();
15662 for (i, ordered) in order_by.iter().enumerate() {
15663 if i > 0 {
15664 self.write(", ");
15665 }
15666 self.generate_ordered(ordered)?;
15667 }
15668 }
15669 needs_separator = true;
15670 }
15671 }
15672
15673 if let Some(measures) = &mr.measures {
15675 if !measures.is_empty() {
15676 if needs_separator {
15677 if self.config.pretty {
15678 self.write_newline();
15679 self.write_indent();
15680 } else {
15681 self.write_space();
15682 }
15683 } else if self.config.pretty {
15684 self.write_newline();
15685 self.write_indent();
15686 }
15687 self.write_keyword("MEASURES");
15688 if self.config.pretty {
15690 self.indent_level += 1;
15691 for (i, measure) in measures.iter().enumerate() {
15692 if i > 0 {
15693 self.write(",");
15694 }
15695 self.write_newline();
15696 self.write_indent();
15697 if let Some(semantics) = &measure.window_frame {
15699 match semantics {
15700 MatchRecognizeSemantics::Running => {
15701 self.write_keyword("RUNNING");
15702 self.write_space();
15703 }
15704 MatchRecognizeSemantics::Final => {
15705 self.write_keyword("FINAL");
15706 self.write_space();
15707 }
15708 }
15709 }
15710 self.generate_expression(&measure.this)?;
15711 }
15712 self.indent_level -= 1;
15713 } else {
15714 self.write_space();
15715 for (i, measure) in measures.iter().enumerate() {
15716 if i > 0 {
15717 self.write(", ");
15718 }
15719 if let Some(semantics) = &measure.window_frame {
15721 match semantics {
15722 MatchRecognizeSemantics::Running => {
15723 self.write_keyword("RUNNING");
15724 self.write_space();
15725 }
15726 MatchRecognizeSemantics::Final => {
15727 self.write_keyword("FINAL");
15728 self.write_space();
15729 }
15730 }
15731 }
15732 self.generate_expression(&measure.this)?;
15733 }
15734 }
15735 needs_separator = true;
15736 }
15737 }
15738
15739 if let Some(rows) = &mr.rows {
15741 if needs_separator {
15742 if self.config.pretty {
15743 self.write_newline();
15744 self.write_indent();
15745 } else {
15746 self.write_space();
15747 }
15748 } else if self.config.pretty {
15749 self.write_newline();
15750 self.write_indent();
15751 }
15752 match rows {
15753 MatchRecognizeRows::OneRowPerMatch => {
15754 self.write_keyword("ONE ROW PER MATCH");
15755 }
15756 MatchRecognizeRows::AllRowsPerMatch => {
15757 self.write_keyword("ALL ROWS PER MATCH");
15758 }
15759 MatchRecognizeRows::AllRowsPerMatchShowEmptyMatches => {
15760 self.write_keyword("ALL ROWS PER MATCH SHOW EMPTY MATCHES");
15761 }
15762 MatchRecognizeRows::AllRowsPerMatchOmitEmptyMatches => {
15763 self.write_keyword("ALL ROWS PER MATCH OMIT EMPTY MATCHES");
15764 }
15765 MatchRecognizeRows::AllRowsPerMatchWithUnmatchedRows => {
15766 self.write_keyword("ALL ROWS PER MATCH WITH UNMATCHED ROWS");
15767 }
15768 }
15769 needs_separator = true;
15770 }
15771
15772 if let Some(after) = &mr.after {
15774 if needs_separator {
15775 if self.config.pretty {
15776 self.write_newline();
15777 self.write_indent();
15778 } else {
15779 self.write_space();
15780 }
15781 } else if self.config.pretty {
15782 self.write_newline();
15783 self.write_indent();
15784 }
15785 match after {
15786 MatchRecognizeAfter::PastLastRow => {
15787 self.write_keyword("AFTER MATCH SKIP PAST LAST ROW");
15788 }
15789 MatchRecognizeAfter::ToNextRow => {
15790 self.write_keyword("AFTER MATCH SKIP TO NEXT ROW");
15791 }
15792 MatchRecognizeAfter::ToFirst(ident) => {
15793 self.write_keyword("AFTER MATCH SKIP TO FIRST");
15794 self.write_space();
15795 self.generate_identifier(ident)?;
15796 }
15797 MatchRecognizeAfter::ToLast(ident) => {
15798 self.write_keyword("AFTER MATCH SKIP TO LAST");
15799 self.write_space();
15800 self.generate_identifier(ident)?;
15801 }
15802 }
15803 needs_separator = true;
15804 }
15805
15806 if let Some(pattern) = &mr.pattern {
15808 if needs_separator {
15809 if self.config.pretty {
15810 self.write_newline();
15811 self.write_indent();
15812 } else {
15813 self.write_space();
15814 }
15815 } else if self.config.pretty {
15816 self.write_newline();
15817 self.write_indent();
15818 }
15819 self.write_keyword("PATTERN");
15820 self.write_space();
15821 self.write("(");
15822 self.write(pattern);
15823 self.write(")");
15824 needs_separator = true;
15825 }
15826
15827 if let Some(define) = &mr.define {
15829 if !define.is_empty() {
15830 if needs_separator {
15831 if self.config.pretty {
15832 self.write_newline();
15833 self.write_indent();
15834 } else {
15835 self.write_space();
15836 }
15837 } else if self.config.pretty {
15838 self.write_newline();
15839 self.write_indent();
15840 }
15841 self.write_keyword("DEFINE");
15842 if self.config.pretty {
15844 self.indent_level += 1;
15845 for (i, (name, expr)) in define.iter().enumerate() {
15846 if i > 0 {
15847 self.write(",");
15848 }
15849 self.write_newline();
15850 self.write_indent();
15851 self.generate_identifier(name)?;
15852 self.write(" AS ");
15853 self.generate_expression(expr)?;
15854 }
15855 self.indent_level -= 1;
15856 } else {
15857 self.write_space();
15858 for (i, (name, expr)) in define.iter().enumerate() {
15859 if i > 0 {
15860 self.write(", ");
15861 }
15862 self.generate_identifier(name)?;
15863 self.write(" AS ");
15864 self.generate_expression(expr)?;
15865 }
15866 }
15867 }
15868 }
15869
15870 if self.config.pretty {
15871 self.indent_level -= 1;
15872 self.write_newline();
15873 }
15874 self.write(")");
15875
15876 if let Some(alias) = &mr.alias {
15878 self.write(" ");
15879 if mr.alias_explicit_as {
15880 self.write_keyword("AS");
15881 self.write(" ");
15882 }
15883 self.generate_identifier(alias)?;
15884 }
15885
15886 Ok(())
15887 }
15888
15889 fn generate_hint(&mut self, hint: &Hint) -> Result<()> {
15891 use crate::dialects::DialectType;
15892
15893 let supports_hints = matches!(
15895 self.config.dialect,
15896 None | Some(DialectType::Oracle) | Some(DialectType::MySQL) |
15898 Some(DialectType::Spark) | Some(DialectType::Hive) |
15899 Some(DialectType::Databricks) | Some(DialectType::PostgreSQL)
15900 );
15901
15902 if !supports_hints || hint.expressions.is_empty() {
15903 return Ok(());
15904 }
15905
15906 let mut hint_strings: Vec<String> = Vec::new();
15909 for expr in &hint.expressions {
15910 match expr {
15911 HintExpression::Raw(text) => {
15912 let parsed = self.parse_raw_hint_text(text);
15914 hint_strings.extend(parsed);
15915 }
15916 _ => {
15917 hint_strings.push(self.hint_expression_to_string(expr)?);
15918 }
15919 }
15920 }
15921
15922 let use_multiline = self.config.pretty && hint_strings.len() > 1;
15926
15927 if use_multiline {
15928 self.write(" /*+ ");
15930 for (i, hint_str) in hint_strings.iter().enumerate() {
15931 if i > 0 {
15932 self.write_newline();
15933 self.write(" "); }
15935 self.write(hint_str);
15936 }
15937 self.write(" */");
15938 } else {
15939 self.write(" /*+ ");
15941 let sep = match self.config.dialect {
15942 Some(DialectType::Spark) | Some(DialectType::Databricks) => ", ",
15943 _ => " ",
15944 };
15945 for (i, hint_str) in hint_strings.iter().enumerate() {
15946 if i > 0 {
15947 self.write(sep);
15948 }
15949 self.write(hint_str);
15950 }
15951 self.write(" */");
15952 }
15953
15954 Ok(())
15955 }
15956
15957 fn parse_raw_hint_text(&self, text: &str) -> Vec<String> {
15961 let mut results = Vec::new();
15962 let mut chars = text.chars().peekable();
15963 let mut current = String::new();
15964 let mut paren_depth = 0;
15965 let mut has_unparseable_content = false;
15966 let mut position_after_last_function = 0;
15967 let mut char_position = 0;
15968
15969 while let Some(c) = chars.next() {
15970 char_position += c.len_utf8();
15971 match c {
15972 '(' => {
15973 paren_depth += 1;
15974 current.push(c);
15975 }
15976 ')' => {
15977 paren_depth -= 1;
15978 current.push(c);
15979 if paren_depth == 0 {
15981 let trimmed = current.trim().to_string();
15982 if !trimmed.is_empty() {
15983 let formatted = self.format_hint_function(&trimmed);
15985 results.push(formatted);
15986 }
15987 current.clear();
15988 position_after_last_function = char_position;
15989 }
15990 }
15991 ' ' | '\t' | '\n' | ',' if paren_depth == 0 => {
15992 }
15994 _ if paren_depth == 0 => {
15995 current.push(c);
15997 }
15998 _ => {
15999 current.push(c);
16000 }
16001 }
16002 }
16003
16004 let remaining_text = text[position_after_last_function..].trim();
16006 if !remaining_text.is_empty() {
16007 let words: Vec<&str> = remaining_text.split_whitespace().collect();
16011 let looks_like_hint_functions = words.iter().all(|word| {
16012 word.contains('(') || (word.chars().all(|c| c.is_ascii_uppercase() || c == '_'))
16014 });
16015
16016 if !looks_like_hint_functions && words.len() > 1 {
16017 has_unparseable_content = true;
16018 }
16019 }
16020
16021 if has_unparseable_content {
16023 return vec![text.trim().to_string()];
16024 }
16025
16026 if results.is_empty() {
16028 results.push(text.trim().to_string());
16029 }
16030
16031 results
16032 }
16033
16034 fn format_hint_function(&self, hint: &str) -> String {
16037 if !self.config.pretty {
16038 return hint.to_string();
16039 }
16040
16041 if let Some(paren_pos) = hint.find('(') {
16043 if hint.ends_with(')') {
16044 let name = &hint[..paren_pos];
16045 let args_str = &hint[paren_pos + 1..hint.len() - 1];
16046
16047 let args: Vec<&str> = args_str.split_whitespace().collect();
16049
16050 let total_args_width: usize =
16052 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() {
16056 let mut result = format!("{}(\n", name);
16057 for arg in &args {
16058 result.push_str(" "); result.push_str(arg);
16060 result.push('\n');
16061 }
16062 result.push_str(" )"); return result;
16064 }
16065 }
16066 }
16067
16068 hint.to_string()
16069 }
16070
16071 fn hint_expression_to_string(&mut self, expr: &HintExpression) -> Result<String> {
16073 match expr {
16074 HintExpression::Function { name, args } => {
16075 let arg_strings: Vec<String> = args
16077 .iter()
16078 .map(|arg| {
16079 let mut gen = Generator::with_arc_config(self.config.clone());
16080 gen.generate_expression(arg)?;
16081 Ok(gen.output)
16082 })
16083 .collect::<Result<Vec<_>>>()?;
16084
16085 let total_args_width: usize = arg_strings.iter().map(|s| s.len()).sum::<usize>()
16087 + arg_strings.len().saturating_sub(1); let args_multiline =
16092 self.config.pretty && total_args_width > self.config.max_text_width;
16093
16094 if args_multiline && !arg_strings.is_empty() {
16095 let mut result = format!("{}(\n", name);
16097 for arg_str in &arg_strings {
16098 result.push_str(" "); result.push_str(arg_str);
16100 result.push('\n');
16101 }
16102 result.push_str(" )"); Ok(result)
16104 } else {
16105 let args_str = arg_strings.join(" ");
16107 Ok(format!("{}({})", name, args_str))
16108 }
16109 }
16110 HintExpression::Identifier(name) => Ok(name.clone()),
16111 HintExpression::Raw(text) => {
16112 if self.config.pretty {
16114 Ok(self.format_hint_function(text))
16115 } else {
16116 Ok(text.clone())
16117 }
16118 }
16119 }
16120 }
16121
16122 fn generate_table(&mut self, table: &TableRef) -> Result<()> {
16123 if table.only {
16125 self.write_keyword("ONLY");
16126 self.write_space();
16127 }
16128
16129 if let Some(ref identifier_func) = table.identifier_func {
16131 self.generate_expression(identifier_func)?;
16132 if !table.name.name.is_empty() {
16134 if let Some(catalog) = &table.catalog {
16135 self.write(".");
16136 self.generate_identifier(catalog)?;
16137 }
16138 if let Some(schema) = &table.schema {
16139 self.write(".");
16140 self.generate_identifier(schema)?;
16141 }
16142 self.write(".");
16143 self.generate_identifier(&table.name)?;
16144 }
16145 } else {
16146 if let Some(catalog) = &table.catalog {
16147 self.generate_identifier(catalog)?;
16148 self.write(".");
16149 }
16150 if let Some(schema) = &table.schema {
16151 self.generate_identifier(schema)?;
16152 self.write(".");
16153 }
16154 self.generate_identifier(&table.name)?;
16155 }
16156
16157 if let Some(changes) = &table.changes {
16159 self.write(" ");
16160 self.generate_changes(changes)?;
16161 }
16162
16163 if !table.partitions.is_empty() {
16165 self.write_space();
16166 self.write_keyword("PARTITION");
16167 self.write("(");
16168 for (i, partition) in table.partitions.iter().enumerate() {
16169 if i > 0 {
16170 self.write(", ");
16171 }
16172 self.generate_identifier(partition)?;
16173 }
16174 self.write(")");
16175 }
16176
16177 if table.changes.is_none() {
16180 if let Some(when) = &table.when {
16181 self.write_space();
16182 self.generate_historical_data(when)?;
16183 }
16184 }
16185
16186 let system_time_post_alias = matches!(self.config.dialect, Some(DialectType::BigQuery));
16188 if !system_time_post_alias {
16189 if let Some(ref system_time) = table.system_time {
16190 self.write_space();
16191 self.write(system_time);
16192 }
16193 }
16194
16195 if let Some(ref version) = table.version {
16197 self.write_space();
16198 self.generate_version(version)?;
16199 }
16200
16201 let alias_post_tablesample = self.config.alias_post_tablesample;
16205
16206 if alias_post_tablesample {
16207 self.generate_table_sample_clause(table)?;
16209 }
16210
16211 let is_sqlite_hint = matches!(self.config.dialect, Some(DialectType::SQLite))
16214 && table.hints.iter().any(|h| {
16215 if let Expression::Identifier(id) = h {
16216 id.name.starts_with("INDEXED BY") || id.name == "NOT INDEXED"
16217 } else {
16218 false
16219 }
16220 });
16221 if !table.hints.is_empty() && !is_sqlite_hint {
16222 for hint in &table.hints {
16223 self.write_space();
16224 self.generate_expression(hint)?;
16225 }
16226 }
16227
16228 if let Some(alias) = &table.alias {
16229 self.write_space();
16230 let always_use_as = self.config.dialect.is_none()
16233 || matches!(
16234 self.config.dialect,
16235 Some(DialectType::Generic)
16236 | Some(DialectType::PostgreSQL)
16237 | Some(DialectType::Redshift)
16238 | Some(DialectType::Snowflake)
16239 | Some(DialectType::BigQuery)
16240 | Some(DialectType::DuckDB)
16241 | Some(DialectType::Presto)
16242 | Some(DialectType::Trino)
16243 | Some(DialectType::TSQL)
16244 | Some(DialectType::Fabric)
16245 | Some(DialectType::MySQL)
16246 | Some(DialectType::Spark)
16247 | Some(DialectType::Hive)
16248 | Some(DialectType::SQLite)
16249 | Some(DialectType::Drill)
16250 );
16251 let is_stage_ref = table.name.name.starts_with('@');
16252 let suppress_as = matches!(self.config.dialect, Some(DialectType::Oracle));
16254 if !suppress_as && (table.alias_explicit_as || always_use_as || is_stage_ref) {
16255 self.write_keyword("AS");
16256 self.write_space();
16257 }
16258 self.generate_identifier(alias)?;
16259
16260 if !table.column_aliases.is_empty() && self.config.supports_table_alias_columns {
16263 self.write("(");
16264 for (i, col_alias) in table.column_aliases.iter().enumerate() {
16265 if i > 0 {
16266 self.write(", ");
16267 }
16268 self.generate_identifier(col_alias)?;
16269 }
16270 self.write(")");
16271 }
16272 }
16273
16274 if system_time_post_alias {
16276 if let Some(ref system_time) = table.system_time {
16277 self.write_space();
16278 self.write(system_time);
16279 }
16280 }
16281
16282 if !alias_post_tablesample {
16284 self.generate_table_sample_clause(table)?;
16285 }
16286
16287 if is_sqlite_hint {
16289 for hint in &table.hints {
16290 self.write_space();
16291 self.generate_expression(hint)?;
16292 }
16293 }
16294
16295 if table.final_ && matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
16297 self.write_space();
16298 self.write_keyword("FINAL");
16299 }
16300
16301 for comment in &table.trailing_comments {
16303 self.write_space();
16304 self.write_formatted_comment(comment);
16305 }
16306 Ok(())
16310 }
16311
16312 fn generate_table_sample_clause(&mut self, table: &TableRef) -> Result<()> {
16314 if let Some(ref ts) = table.table_sample {
16315 self.write_space();
16316 if ts.is_using_sample {
16317 self.write_keyword("USING SAMPLE");
16318 } else {
16319 self.write_keyword(self.config.tablesample_keywords);
16321 }
16322 self.generate_sample_body(ts)?;
16323 if let Some(ref seed) = ts.seed {
16325 self.write_space();
16326 self.write_keyword(self.config.tablesample_seed_keyword);
16327 self.write(" (");
16328 self.generate_expression(seed)?;
16329 self.write(")");
16330 }
16331 }
16332 Ok(())
16333 }
16334
16335 fn generate_stage_reference(&mut self, sr: &StageReference) -> Result<()> {
16336 if sr.quoted {
16340 self.write("'");
16341 }
16342
16343 self.write(&sr.name);
16344 if let Some(path) = &sr.path {
16345 self.write(path);
16346 }
16347
16348 if sr.quoted {
16349 self.write("'");
16350 }
16351
16352 let has_options = sr.file_format.is_some() || sr.pattern.is_some();
16354 if has_options {
16355 self.write(" (");
16356 let mut first = true;
16357
16358 if let Some(file_format) = &sr.file_format {
16359 if !first {
16360 self.write(", ");
16361 }
16362 self.write_keyword("FILE_FORMAT");
16363 self.write(" => ");
16364 self.generate_expression(file_format)?;
16365 first = false;
16366 }
16367
16368 if let Some(pattern) = &sr.pattern {
16369 if !first {
16370 self.write(", ");
16371 }
16372 self.write_keyword("PATTERN");
16373 self.write(" => '");
16374 self.write(pattern);
16375 self.write("'");
16376 }
16377
16378 self.write(")");
16379 }
16380 Ok(())
16381 }
16382
16383 fn generate_star(&mut self, star: &Star) -> Result<()> {
16384 use crate::dialects::DialectType;
16385
16386 if let Some(table) = &star.table {
16387 self.generate_identifier(table)?;
16388 self.write(".");
16389 }
16390 self.write("*");
16391
16392 if let Some(except) = &star.except {
16394 if !except.is_empty() {
16395 self.write_space();
16396 match self.config.dialect {
16398 Some(DialectType::BigQuery) => self.write_keyword("EXCEPT"),
16399 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => {
16400 self.write_keyword("EXCLUDE")
16401 }
16402 _ => self.write_keyword("EXCEPT"), }
16404 self.write(" (");
16405 for (i, col) in except.iter().enumerate() {
16406 if i > 0 {
16407 self.write(", ");
16408 }
16409 self.generate_identifier(col)?;
16410 }
16411 self.write(")");
16412 }
16413 }
16414
16415 if let Some(replace) = &star.replace {
16417 if !replace.is_empty() {
16418 self.write_space();
16419 self.write_keyword("REPLACE");
16420 self.write(" (");
16421 for (i, alias) in replace.iter().enumerate() {
16422 if i > 0 {
16423 self.write(", ");
16424 }
16425 self.generate_expression(&alias.this)?;
16426 self.write_space();
16427 self.write_keyword("AS");
16428 self.write_space();
16429 self.generate_identifier(&alias.alias)?;
16430 }
16431 self.write(")");
16432 }
16433 }
16434
16435 if let Some(rename) = &star.rename {
16437 if !rename.is_empty() {
16438 self.write_space();
16439 self.write_keyword("RENAME");
16440 self.write(" (");
16441 for (i, (old_name, new_name)) in rename.iter().enumerate() {
16442 if i > 0 {
16443 self.write(", ");
16444 }
16445 self.generate_identifier(old_name)?;
16446 self.write_space();
16447 self.write_keyword("AS");
16448 self.write_space();
16449 self.generate_identifier(new_name)?;
16450 }
16451 self.write(")");
16452 }
16453 }
16454
16455 for comment in &star.trailing_comments {
16457 self.write_space();
16458 self.write_formatted_comment(comment);
16459 }
16460
16461 Ok(())
16462 }
16463
16464 fn generate_braced_wildcard(&mut self, expr: &Expression) -> Result<()> {
16466 self.write("{");
16467 match expr {
16468 Expression::Star(star) => {
16469 self.generate_star(star)?;
16471 }
16472 Expression::ILike(ilike) => {
16473 self.generate_expression(&ilike.left)?;
16475 self.write_space();
16476 self.write_keyword("ILIKE");
16477 self.write_space();
16478 self.generate_expression(&ilike.right)?;
16479 }
16480 _ => {
16481 self.generate_expression(expr)?;
16482 }
16483 }
16484 self.write("}");
16485 Ok(())
16486 }
16487
16488 fn generate_alias(&mut self, alias: &Alias) -> Result<()> {
16489 match &alias.this {
16493 Expression::Column(col) => {
16494 if let Some(table) = &col.table {
16496 self.generate_identifier(table)?;
16497 self.write(".");
16498 }
16499 self.generate_identifier(&col.name)?;
16500 }
16501 _ => {
16502 self.generate_expression(&alias.this)?;
16503 }
16504 }
16505
16506 if !alias.pre_alias_comments.is_empty() && !alias.trailing_comments.is_empty() {
16510 for comment in &alias.pre_alias_comments {
16511 self.write_space();
16512 self.write_formatted_comment(comment);
16513 }
16514 }
16515
16516 use crate::dialects::DialectType;
16517
16518 let is_table_source = matches!(
16524 &alias.this,
16525 Expression::JSONTable(_)
16526 | Expression::XMLTable(_)
16527 | Expression::TableFromRows(_)
16528 | Expression::Unnest(_)
16529 | Expression::MatchRecognize(_)
16530 | Expression::Select(_)
16531 | Expression::Subquery(_)
16532 | Expression::Paren(_)
16533 );
16534 let dialect_skips_table_alias_as = matches!(self.config.dialect, Some(DialectType::Oracle));
16535 let skip_as = is_table_source && dialect_skips_table_alias_as;
16536
16537 self.write_space();
16538 if !skip_as {
16539 self.write_keyword("AS");
16540 self.write_space();
16541 }
16542
16543 let skip_column_aliases = matches!(self.config.dialect, Some(DialectType::BigQuery));
16545
16546 if alias.alias.is_empty() && !alias.column_aliases.is_empty() && !skip_column_aliases {
16548 self.write("(");
16550 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
16551 if i > 0 {
16552 self.write(", ");
16553 }
16554 self.generate_alias_identifier(col_alias)?;
16555 }
16556 self.write(")");
16557 } else if !alias.column_aliases.is_empty() && !skip_column_aliases {
16558 self.generate_alias_identifier(&alias.alias)?;
16560 self.write("(");
16561 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
16562 if i > 0 {
16563 self.write(", ");
16564 }
16565 self.generate_alias_identifier(col_alias)?;
16566 }
16567 self.write(")");
16568 } else {
16569 self.generate_alias_identifier(&alias.alias)?;
16571 }
16572
16573 for comment in &alias.trailing_comments {
16575 self.write_space();
16576 self.write_formatted_comment(comment);
16577 }
16578
16579 if alias.trailing_comments.is_empty() {
16584 for comment in &alias.pre_alias_comments {
16585 self.write_space();
16586 self.write_formatted_comment(comment);
16587 }
16588 }
16589
16590 Ok(())
16591 }
16592
16593 fn generate_cast(&mut self, cast: &Cast) -> Result<()> {
16594 use crate::dialects::DialectType;
16595
16596 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
16598 self.generate_expression(&cast.this)?;
16599 self.write(" :> ");
16600 self.generate_data_type(&cast.to)?;
16601 return Ok(());
16602 }
16603
16604 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
16606 let is_unknown_type = matches!(cast.to, DataType::Unknown)
16607 || matches!(cast.to, DataType::Custom { ref name } if name.is_empty());
16608 if is_unknown_type {
16609 if let Some(format) = &cast.format {
16610 self.write_keyword("CAST");
16611 self.write("(");
16612 self.generate_expression(&cast.this)?;
16613 self.write_space();
16614 self.write_keyword("AS");
16615 self.write_space();
16616 self.write_keyword("FORMAT");
16617 self.write_space();
16618 self.generate_expression(format)?;
16619 self.write(")");
16620 return Ok(());
16621 }
16622 }
16623 }
16624
16625 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
16628 if let Some(format) = &cast.format {
16629 let is_date = matches!(cast.to, DataType::Date);
16631 let is_timestamp = matches!(cast.to, DataType::Timestamp { .. });
16632
16633 if is_date || is_timestamp {
16634 let func_name = if is_date { "TO_DATE" } else { "TO_TIMESTAMP" };
16635 self.write_keyword(func_name);
16636 self.write("(");
16637 self.generate_expression(&cast.this)?;
16638 self.write(", ");
16639
16640 if let Expression::Literal(lit) = format.as_ref() {
16643 if let Literal::String(fmt_str) = lit.as_ref() {
16644 let normalized = self.normalize_oracle_format(fmt_str);
16645 self.write("'");
16646 self.write(&normalized);
16647 self.write("'");
16648 }
16649 } else {
16650 self.generate_expression(format)?;
16651 }
16652
16653 self.write(")");
16654 return Ok(());
16655 }
16656 }
16657 }
16658
16659 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
16662 if let Expression::Array(arr) = &cast.this {
16663 self.generate_data_type(&cast.to)?;
16664 self.write("[");
16666 for (i, expr) in arr.expressions.iter().enumerate() {
16667 if i > 0 {
16668 self.write(", ");
16669 }
16670 self.generate_expression(expr)?;
16671 }
16672 self.write("]");
16673 return Ok(());
16674 }
16675 if matches!(&cast.this, Expression::ArrayFunc(_)) {
16676 self.generate_data_type(&cast.to)?;
16677 self.generate_expression(&cast.this)?;
16678 return Ok(());
16679 }
16680 }
16681
16682 if matches!(
16685 self.config.dialect,
16686 Some(DialectType::DuckDB) | Some(DialectType::Presto) | Some(DialectType::Trino)
16687 ) {
16688 if let Expression::Struct(ref s) = cast.this {
16689 let all_unnamed = s.fields.iter().all(|(name, _)| name.is_none());
16690 if all_unnamed && matches!(cast.to, DataType::Struct { .. }) {
16691 self.write_keyword("CAST");
16692 self.write("(");
16693 self.generate_struct_as_row(s)?;
16694 self.write_space();
16695 self.write_keyword("AS");
16696 self.write_space();
16697 self.generate_data_type(&cast.to)?;
16698 self.write(")");
16699 return Ok(());
16700 }
16701 }
16702 }
16703
16704 let use_double_colon = cast.double_colon_syntax && self.dialect_prefers_double_colon();
16707
16708 if use_double_colon {
16709 self.generate_expression(&cast.this)?;
16711 self.write("::");
16712 self.generate_data_type(&cast.to)?;
16713 } else {
16714 self.write_keyword("CAST");
16716 self.write("(");
16717 self.generate_expression(&cast.this)?;
16718 self.write_space();
16719 self.write_keyword("AS");
16720 self.write_space();
16721 if matches!(
16724 self.config.dialect,
16725 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB)
16726 ) {
16727 match &cast.to {
16728 DataType::Custom { ref name } => {
16729 if name.eq_ignore_ascii_case("LONGTEXT")
16730 || name.eq_ignore_ascii_case("MEDIUMTEXT")
16731 || name.eq_ignore_ascii_case("TINYTEXT")
16732 || name.eq_ignore_ascii_case("LONGBLOB")
16733 || name.eq_ignore_ascii_case("MEDIUMBLOB")
16734 || name.eq_ignore_ascii_case("TINYBLOB")
16735 {
16736 self.write_keyword("CHAR");
16737 } else {
16738 self.generate_data_type(&cast.to)?;
16739 }
16740 }
16741 DataType::VarChar { length, .. } => {
16742 self.write_keyword("CHAR");
16744 if let Some(n) = length {
16745 self.write(&format!("({})", n));
16746 }
16747 }
16748 DataType::Text => {
16749 self.write_keyword("CHAR");
16751 }
16752 DataType::Timestamp {
16753 precision,
16754 timezone: false,
16755 } => {
16756 self.write_keyword("DATETIME");
16758 if let Some(p) = precision {
16759 self.write(&format!("({})", p));
16760 }
16761 }
16762 _ => {
16763 self.generate_data_type(&cast.to)?;
16764 }
16765 }
16766 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
16767 match &cast.to {
16769 DataType::String { length } => {
16770 self.write_keyword("VARCHAR");
16771 if let Some(n) = length {
16772 self.write(&format!("({})", n));
16773 }
16774 }
16775 _ => {
16776 self.generate_data_type(&cast.to)?;
16777 }
16778 }
16779 } else {
16780 self.generate_data_type(&cast.to)?;
16781 }
16782
16783 if let Some(default) = &cast.default {
16785 self.write_space();
16786 self.write_keyword("DEFAULT");
16787 self.write_space();
16788 self.generate_expression(default)?;
16789 self.write_space();
16790 self.write_keyword("ON");
16791 self.write_space();
16792 self.write_keyword("CONVERSION");
16793 self.write_space();
16794 self.write_keyword("ERROR");
16795 }
16796
16797 if let Some(format) = &cast.format {
16800 if matches!(
16802 self.config.dialect,
16803 Some(crate::dialects::DialectType::Oracle)
16804 ) {
16805 self.write(", ");
16806 } else {
16807 self.write_space();
16808 self.write_keyword("FORMAT");
16809 self.write_space();
16810 }
16811 self.generate_expression(format)?;
16812 }
16813
16814 self.write(")");
16815 for comment in &cast.trailing_comments {
16817 self.write_space();
16818 self.write_formatted_comment(comment);
16819 }
16820 }
16821 Ok(())
16822 }
16823
16824 fn generate_struct_as_row(&mut self, s: &crate::expressions::Struct) -> Result<()> {
16827 self.write_keyword("ROW");
16828 self.write("(");
16829 for (i, (_, expr)) in s.fields.iter().enumerate() {
16830 if i > 0 {
16831 self.write(", ");
16832 }
16833 if let Expression::Struct(ref inner_s) = expr {
16835 self.generate_struct_as_row(inner_s)?;
16836 } else {
16837 self.generate_expression(expr)?;
16838 }
16839 }
16840 self.write(")");
16841 Ok(())
16842 }
16843
16844 fn normalize_oracle_format(&self, format: &str) -> String {
16847 let mut result = String::new();
16850 let chars: Vec<char> = format.chars().collect();
16851 let mut i = 0;
16852
16853 while i < chars.len() {
16854 if i + 1 < chars.len() && chars[i] == 'H' && chars[i + 1] == 'H' {
16855 if i + 2 < chars.len() {
16857 let next = chars[i + 2];
16858 if next == '1' || next == '2' {
16859 result.push('H');
16861 result.push('H');
16862 i += 2;
16863 continue;
16864 }
16865 }
16866 result.push_str("HH12");
16868 i += 2;
16869 } else {
16870 result.push(chars[i]);
16871 i += 1;
16872 }
16873 }
16874
16875 result
16876 }
16877
16878 fn dialect_prefers_double_colon(&self) -> bool {
16882 false
16885 }
16886
16887 fn generate_mod_func(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
16889 use crate::dialects::DialectType;
16890
16891 let use_percent_operator = matches!(
16893 self.config.dialect,
16894 Some(DialectType::Snowflake)
16895 | Some(DialectType::MySQL)
16896 | Some(DialectType::Presto)
16897 | Some(DialectType::Trino)
16898 | Some(DialectType::PostgreSQL)
16899 | Some(DialectType::DuckDB)
16900 | Some(DialectType::Hive)
16901 | Some(DialectType::Spark)
16902 | Some(DialectType::Databricks)
16903 | Some(DialectType::Athena)
16904 );
16905
16906 if use_percent_operator {
16907 let needs_paren = |e: &Expression| matches!(e, Expression::Add(_) | Expression::Sub(_));
16910 if needs_paren(&f.this) {
16911 self.write("(");
16912 self.generate_expression(&f.this)?;
16913 self.write(")");
16914 } else {
16915 self.generate_expression(&f.this)?;
16916 }
16917 self.write(" % ");
16918 if needs_paren(&f.expression) {
16919 self.write("(");
16920 self.generate_expression(&f.expression)?;
16921 self.write(")");
16922 } else {
16923 self.generate_expression(&f.expression)?;
16924 }
16925 Ok(())
16926 } else {
16927 self.generate_binary_func("MOD", &f.this, &f.expression)
16928 }
16929 }
16930
16931 fn generate_ifnull(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
16933 use crate::dialects::DialectType;
16934
16935 let func_name = match self.config.dialect {
16937 Some(DialectType::Snowflake) => "COALESCE",
16938 _ => "IFNULL",
16939 };
16940
16941 self.generate_binary_func(func_name, &f.this, &f.expression)
16942 }
16943
16944 fn generate_nvl(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
16946 if let Some(ref original_name) = f.original_name {
16948 return self.generate_binary_func(original_name, &f.this, &f.expression);
16949 }
16950
16951 use crate::dialects::DialectType;
16953 let func_name = match self.config.dialect {
16954 Some(DialectType::Snowflake)
16955 | Some(DialectType::ClickHouse)
16956 | Some(DialectType::PostgreSQL)
16957 | Some(DialectType::Presto)
16958 | Some(DialectType::Trino)
16959 | Some(DialectType::Athena)
16960 | Some(DialectType::DuckDB)
16961 | Some(DialectType::BigQuery)
16962 | Some(DialectType::Spark)
16963 | Some(DialectType::Databricks)
16964 | Some(DialectType::Hive) => "COALESCE",
16965 Some(DialectType::MySQL)
16966 | Some(DialectType::Doris)
16967 | Some(DialectType::StarRocks)
16968 | Some(DialectType::SingleStore)
16969 | Some(DialectType::TiDB) => "IFNULL",
16970 _ => "NVL",
16971 };
16972
16973 self.generate_binary_func(func_name, &f.this, &f.expression)
16974 }
16975
16976 fn generate_stddev_samp(&mut self, f: &crate::expressions::AggFunc) -> Result<()> {
16978 use crate::dialects::DialectType;
16979
16980 let func_name = match self.config.dialect {
16982 Some(DialectType::Snowflake) => "STDDEV",
16983 _ => "STDDEV_SAMP",
16984 };
16985
16986 self.generate_agg_func(func_name, f)
16987 }
16988
16989 fn generate_collation(&mut self, coll: &CollationExpr) -> Result<()> {
16990 self.generate_expression(&coll.this)?;
16991 self.write_space();
16992 self.write_keyword("COLLATE");
16993 self.write_space();
16994 if coll.quoted {
16995 self.write("'");
16997 self.write(&coll.collation);
16998 self.write("'");
16999 } else if coll.double_quoted {
17000 self.write("\"");
17002 self.write(&coll.collation);
17003 self.write("\"");
17004 } else {
17005 self.write(&coll.collation);
17007 }
17008 Ok(())
17009 }
17010
17011 fn generate_case(&mut self, case: &Case) -> Result<()> {
17012 let multiline_case = if self.config.pretty {
17014 let mut statements: Vec<String> = Vec::new();
17016 let operand_str = if let Some(operand) = &case.operand {
17017 let s = self.generate_to_string(operand)?;
17018 statements.push(format!("CASE {}", s));
17019 s
17020 } else {
17021 statements.push("CASE".to_string());
17022 String::new()
17023 };
17024 let _ = operand_str;
17025 for (condition, result) in &case.whens {
17026 statements.push(format!("WHEN {}", self.generate_to_string(condition)?));
17027 statements.push(format!("THEN {}", self.generate_to_string(result)?));
17028 }
17029 if let Some(else_) = &case.else_ {
17030 statements.push(format!("ELSE {}", self.generate_to_string(else_)?));
17031 }
17032 statements.push("END".to_string());
17033 self.too_wide(&statements)
17034 } else {
17035 false
17036 };
17037
17038 self.write_keyword("CASE");
17039 if let Some(operand) = &case.operand {
17040 self.write_space();
17041 self.generate_expression(operand)?;
17042 }
17043 if multiline_case {
17044 self.indent_level += 1;
17045 }
17046 for (condition, result) in &case.whens {
17047 if multiline_case {
17048 self.write_newline();
17049 self.write_indent();
17050 } else {
17051 self.write_space();
17052 }
17053 self.write_keyword("WHEN");
17054 self.write_space();
17055 self.generate_expression(condition)?;
17056 if multiline_case {
17057 self.write_newline();
17058 self.write_indent();
17059 } else {
17060 self.write_space();
17061 }
17062 self.write_keyword("THEN");
17063 self.write_space();
17064 self.generate_expression(result)?;
17065 }
17066 if let Some(else_) = &case.else_ {
17067 if multiline_case {
17068 self.write_newline();
17069 self.write_indent();
17070 } else {
17071 self.write_space();
17072 }
17073 self.write_keyword("ELSE");
17074 self.write_space();
17075 self.generate_expression(else_)?;
17076 }
17077 if multiline_case {
17078 self.indent_level -= 1;
17079 self.write_newline();
17080 self.write_indent();
17081 } else {
17082 self.write_space();
17083 }
17084 self.write_keyword("END");
17085 for comment in &case.comments {
17087 self.write(" ");
17088 self.write_formatted_comment(comment);
17089 }
17090 Ok(())
17091 }
17092
17093 fn generate_function(&mut self, func: &Function) -> Result<()> {
17094 let normalized_name = self.normalize_func_name(&func.name);
17096
17097 if matches!(self.config.dialect, Some(DialectType::DuckDB))
17099 && func.name.eq_ignore_ascii_case("ARRAY_CONSTRUCT_COMPACT")
17100 {
17101 self.write("LIST_FILTER(");
17102 self.write("[");
17103 for (i, arg) in func.args.iter().enumerate() {
17104 if i > 0 {
17105 self.write(", ");
17106 }
17107 self.generate_expression(arg)?;
17108 }
17109 self.write("], _u -> NOT _u IS NULL)");
17110 return Ok(());
17111 }
17112
17113 if matches!(self.config.dialect, Some(DialectType::Snowflake))
17116 && func.name.eq_ignore_ascii_case("TO_VARIANT")
17117 && func.args.len() == 1
17118 {
17119 let array_expressions = match &func.args[0] {
17120 Expression::ArrayFunc(arr) => Some(&arr.expressions),
17121 Expression::Array(arr) => Some(&arr.expressions),
17122 _ => None,
17123 };
17124 if let Some(expressions) = array_expressions {
17125 self.write_keyword("TO_VARIANT");
17126 self.write("(");
17127 self.write_keyword("ARRAY_CONSTRUCT");
17128 self.write("(");
17129 for (i, arg) in expressions.iter().enumerate() {
17130 if i > 0 {
17131 self.write(", ");
17132 }
17133 self.generate_expression(arg)?;
17134 }
17135 self.write(")");
17136 self.write(")");
17137 return Ok(());
17138 }
17139 }
17140
17141 if func.name.eq_ignore_ascii_case("STRUCT")
17143 && !matches!(
17144 self.config.dialect,
17145 Some(DialectType::BigQuery)
17146 | Some(DialectType::Spark)
17147 | Some(DialectType::Databricks)
17148 | Some(DialectType::Hive)
17149 | None
17150 )
17151 {
17152 return self.generate_struct_function_cross_dialect(func);
17153 }
17154
17155 if func.name.eq_ignore_ascii_case("__SS_JSON_PATH_QMARK__") && func.args.len() == 2 {
17158 self.generate_expression(&func.args[0])?;
17159 self.write("::?");
17160 if let Expression::Literal(lit) = &func.args[1] {
17162 if let crate::expressions::Literal::String(key) = lit.as_ref() {
17163 self.write(key);
17164 }
17165 } else {
17166 self.generate_expression(&func.args[1])?;
17167 }
17168 return Ok(());
17169 }
17170
17171 if func.name.eq_ignore_ascii_case("__PG_BITWISE_XOR__") && func.args.len() == 2 {
17173 self.generate_expression(&func.args[0])?;
17174 self.write(" # ");
17175 self.generate_expression(&func.args[1])?;
17176 return Ok(());
17177 }
17178
17179 if matches!(
17181 self.config.dialect,
17182 Some(DialectType::Spark | DialectType::Databricks | DialectType::Hive)
17183 ) && func.name.eq_ignore_ascii_case("TRY")
17184 && func.args.len() == 1
17185 {
17186 self.generate_expression(&func.args[0])?;
17187 return Ok(());
17188 }
17189
17190 if self.config.dialect == Some(DialectType::ClickHouse)
17192 && func.name.eq_ignore_ascii_case("TOSTARTOFDAY")
17193 && func.args.len() == 1
17194 {
17195 self.write("dateTrunc('DAY', ");
17196 self.generate_expression(&func.args[0])?;
17197 self.write(")");
17198 return Ok(());
17199 }
17200
17201 if self.config.dialect == Some(DialectType::ClickHouse)
17203 && func.name.eq_ignore_ascii_case("DATE_TRUNC")
17204 && func.args.len() == 2
17205 {
17206 self.write("dateTrunc(");
17207 self.generate_expression(&func.args[0])?;
17208 self.write(", ");
17209 self.generate_expression(&func.args[1])?;
17210 self.write(")");
17211 return Ok(());
17212 }
17213
17214 if matches!(
17216 self.config.dialect,
17217 Some(DialectType::Presto | DialectType::Trino | DialectType::Athena)
17218 ) && func.name.eq_ignore_ascii_case("SUBSTRING")
17219 {
17220 self.write_keyword("SUBSTR");
17221 self.write("(");
17222 for (i, arg) in func.args.iter().enumerate() {
17223 if i > 0 {
17224 self.write(", ");
17225 }
17226 self.generate_expression(arg)?;
17227 }
17228 self.write(")");
17229 return Ok(());
17230 }
17231
17232 if self.config.dialect == Some(DialectType::Snowflake)
17233 && func.name.eq_ignore_ascii_case("LIST_DISTINCT")
17234 && func.args.len() == 1
17235 {
17236 self.write_keyword("ARRAY_DISTINCT");
17237 self.write("(");
17238 self.write_keyword("ARRAY_COMPACT");
17239 self.write("(");
17240 self.generate_expression(&func.args[0])?;
17241 self.write("))");
17242 return Ok(());
17243 }
17244
17245 if self.config.dialect == Some(DialectType::Snowflake)
17246 && func.name.eq_ignore_ascii_case("LIST")
17247 && func.args.len() == 1
17248 && !matches!(func.args.first(), Some(Expression::Select(_)))
17249 {
17250 self.write_keyword("ARRAY_AGG");
17251 self.write("(");
17252 self.generate_expression(&func.args[0])?;
17253 self.write(")");
17254 return Ok(());
17255 }
17256
17257 if self.config.dialect == Some(DialectType::Redshift)
17259 && func.name.eq_ignore_ascii_case("CONCAT")
17260 && func.args.len() >= 2
17261 {
17262 for (i, arg) in func.args.iter().enumerate() {
17263 if i > 0 {
17264 self.write(" || ");
17265 }
17266 self.generate_expression(arg)?;
17267 }
17268 return Ok(());
17269 }
17270
17271 if self.config.dialect == Some(DialectType::Redshift)
17273 && func.name.eq_ignore_ascii_case("CONCAT_WS")
17274 && func.args.len() >= 2
17275 {
17276 let sep = &func.args[0];
17277 for (i, arg) in func.args.iter().skip(1).enumerate() {
17278 if i > 0 {
17279 self.write(" || ");
17280 self.generate_expression(sep)?;
17281 self.write(" || ");
17282 }
17283 self.generate_expression(arg)?;
17284 }
17285 return Ok(());
17286 }
17287
17288 if self.config.dialect == Some(DialectType::Redshift)
17291 && (func.name.eq_ignore_ascii_case("DATEDIFF")
17292 || func.name.eq_ignore_ascii_case("DATE_DIFF"))
17293 && func.args.len() == 3
17294 {
17295 self.write_keyword("DATEDIFF");
17296 self.write("(");
17297 self.write_redshift_date_part(&func.args[0]);
17299 self.write(", ");
17300 self.generate_expression(&func.args[1])?;
17301 self.write(", ");
17302 self.generate_expression(&func.args[2])?;
17303 self.write(")");
17304 return Ok(());
17305 }
17306
17307 if self.config.dialect == Some(DialectType::Redshift)
17310 && (func.name.eq_ignore_ascii_case("DATEADD")
17311 || func.name.eq_ignore_ascii_case("DATE_ADD"))
17312 && func.args.len() == 3
17313 {
17314 self.write_keyword("DATEADD");
17315 self.write("(");
17316 self.write_redshift_date_part(&func.args[0]);
17318 self.write(", ");
17319 self.generate_expression(&func.args[1])?;
17320 self.write(", ");
17321 self.generate_expression(&func.args[2])?;
17322 self.write(")");
17323 return Ok(());
17324 }
17325
17326 if func.name.eq_ignore_ascii_case("UUID_STRING")
17328 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None)
17329 {
17330 if matches!(
17331 self.config.dialect,
17332 Some(DialectType::Hive | DialectType::Spark | DialectType::Databricks)
17333 ) {
17334 self.write_keyword("CAST");
17335 self.write("(");
17336 self.write_keyword("UUID");
17337 self.write("() ");
17338 self.write_keyword("AS");
17339 self.write(" ");
17340 self.write_keyword("STRING");
17341 self.write(")");
17342 return Ok(());
17343 }
17344
17345 if matches!(
17346 self.config.dialect,
17347 Some(DialectType::Presto | DialectType::Trino)
17348 ) {
17349 self.write_keyword("CAST");
17350 self.write("(");
17351 self.write_keyword("UUID");
17352 self.write("() ");
17353 self.write_keyword("AS");
17354 self.write(" ");
17355 self.write_keyword("VARCHAR");
17356 self.write(")");
17357 return Ok(());
17358 }
17359
17360 if self.config.dialect == Some(DialectType::DuckDB) && func.args.len() == 2 {
17361 self.write("(SELECT LOWER(SUBSTRING(h, 1, 8) || '-' || SUBSTRING(h, 9, 4) || '-' || '5' || SUBSTRING(h, 14, 3) || '-' || FORMAT('{:02x}', CAST('0x' || SUBSTRING(h, 17, 2) AS INT) & 63 | 128) || SUBSTRING(h, 19, 2) || '-' || SUBSTRING(h, 21, 12)) FROM (SELECT SUBSTRING(SHA1(UNHEX(REPLACE(");
17362 self.generate_expression(&func.args[0])?;
17363 self.write(", '-', '')) || ENCODE(");
17364 self.generate_expression(&func.args[1])?;
17365 self.write(")), 1, 32) AS h))");
17366 return Ok(());
17367 }
17368
17369 let func_name = match self.config.dialect {
17370 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
17371 Some(DialectType::BigQuery) => "GENERATE_UUID",
17372 _ => "UUID",
17373 };
17374 self.write_keyword(func_name);
17375 self.write("()");
17376 return Ok(());
17377 }
17378
17379 if matches!(self.config.dialect, Some(DialectType::Snowflake))
17383 && func.name.eq_ignore_ascii_case("GENERATOR")
17384 {
17385 let has_positional_args =
17386 !func.args.is_empty() && !matches!(&func.args[0], Expression::NamedArgument(_));
17387 if has_positional_args {
17388 let param_names = ["ROWCOUNT", "TIMELIMIT"];
17389 self.write_keyword("GENERATOR");
17390 self.write("(");
17391 for (i, arg) in func.args.iter().enumerate() {
17392 if i > 0 {
17393 self.write(", ");
17394 }
17395 if i < param_names.len() {
17396 self.write_keyword(param_names[i]);
17397 self.write(" => ");
17398 self.generate_expression(arg)?;
17399 } else {
17400 self.generate_expression(arg)?;
17401 }
17402 }
17403 self.write(")");
17404 return Ok(());
17405 }
17406 }
17407
17408 if self.config.dialect == Some(DialectType::Redshift)
17411 && func.name.eq_ignore_ascii_case("DATE_TRUNC")
17412 && func.args.len() == 2
17413 {
17414 self.write_keyword("DATE_TRUNC");
17415 self.write("(");
17416 self.write_redshift_date_part_quoted(&func.args[0]);
17418 self.write(", ");
17419 self.generate_expression(&func.args[1])?;
17420 self.write(")");
17421 return Ok(());
17422 }
17423
17424 if matches!(
17426 self.config.dialect,
17427 Some(DialectType::TSQL) | Some(DialectType::Fabric)
17428 ) && (func.name.eq_ignore_ascii_case("DATE_PART")
17429 || func.name.eq_ignore_ascii_case("DATEPART"))
17430 && func.args.len() == 2
17431 {
17432 self.write_keyword("DATEPART");
17433 self.write("(");
17434 self.generate_expression(&func.args[0])?;
17435 self.write(", ");
17436 self.generate_expression(&func.args[1])?;
17437 self.write(")");
17438 return Ok(());
17439 }
17440
17441 if matches!(
17443 self.config.dialect,
17444 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
17445 ) && (func.name.eq_ignore_ascii_case("DATE_PART")
17446 || func.name.eq_ignore_ascii_case("DATEPART"))
17447 && func.args.len() == 2
17448 {
17449 self.write_keyword("EXTRACT");
17450 self.write("(");
17451 match &func.args[0] {
17453 Expression::Literal(lit)
17454 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
17455 {
17456 let crate::expressions::Literal::String(s) = lit.as_ref() else {
17457 unreachable!()
17458 };
17459 self.write(&s.to_ascii_lowercase());
17460 }
17461 _ => self.generate_expression(&func.args[0])?,
17462 }
17463 self.write_space();
17464 self.write_keyword("FROM");
17465 self.write_space();
17466 self.generate_expression(&func.args[1])?;
17467 self.write(")");
17468 return Ok(());
17469 }
17470
17471 if self.config.dialect == Some(DialectType::PostgreSQL)
17473 && matches!(
17474 func.name.to_ascii_uppercase().as_str(),
17475 "DATE_ADD" | "DATE_SUB"
17476 )
17477 && func.args.len() == 2
17478 && matches!(func.args[1], Expression::Interval(_))
17479 {
17480 self.generate_expression(&func.args[0])?;
17481 self.write_space();
17482 if func.name.eq_ignore_ascii_case("DATE_SUB") {
17483 self.write("-");
17484 } else {
17485 self.write("+");
17486 }
17487 self.write_space();
17488 self.generate_expression(&func.args[1])?;
17489 return Ok(());
17490 }
17491
17492 if self.config.dialect == Some(DialectType::Dremio)
17495 && (func.name.eq_ignore_ascii_case("DATE_PART")
17496 || func.name.eq_ignore_ascii_case("DATEPART"))
17497 && func.args.len() == 2
17498 {
17499 self.write_keyword("EXTRACT");
17500 self.write("(");
17501 self.generate_expression(&func.args[0])?;
17502 self.write_space();
17503 self.write_keyword("FROM");
17504 self.write_space();
17505 self.generate_dremio_date_expression(&func.args[1])?;
17507 self.write(")");
17508 return Ok(());
17509 }
17510
17511 if self.config.dialect == Some(DialectType::Dremio)
17513 && func.name.eq_ignore_ascii_case("CURRENT_DATE_UTC")
17514 && func.args.is_empty()
17515 {
17516 self.write_keyword("CURRENT_DATE_UTC");
17517 return Ok(());
17518 }
17519
17520 if self.config.dialect == Some(DialectType::Dremio)
17524 && func.name.eq_ignore_ascii_case("DATETYPE")
17525 && func.args.len() == 3
17526 {
17527 fn get_int_literal(expr: &Expression) -> Option<i64> {
17529 if let Expression::Literal(lit) = expr {
17530 if let crate::expressions::Literal::Number(s) = lit.as_ref() {
17531 s.parse::<i64>().ok()
17532 } else {
17533 None
17534 }
17535 } else {
17536 None
17537 }
17538 }
17539
17540 if let (Some(year), Some(month), Some(day)) = (
17542 get_int_literal(&func.args[0]),
17543 get_int_literal(&func.args[1]),
17544 get_int_literal(&func.args[2]),
17545 ) {
17546 self.write_keyword("DATE");
17548 self.write(&format!("('{:04}-{:02}-{:02}')", year, month, day));
17549 return Ok(());
17550 }
17551
17552 self.write_keyword("CAST");
17554 self.write("(");
17555 self.write_keyword("CONCAT");
17556 self.write("(");
17557 self.generate_expression(&func.args[0])?;
17558 self.write(", '-', ");
17559 self.generate_expression(&func.args[1])?;
17560 self.write(", '-', ");
17561 self.generate_expression(&func.args[2])?;
17562 self.write(")");
17563 self.write_space();
17564 self.write_keyword("AS");
17565 self.write_space();
17566 self.write_keyword("DATE");
17567 self.write(")");
17568 return Ok(());
17569 }
17570
17571 let is_presto_like = matches!(
17574 self.config.dialect,
17575 Some(DialectType::Presto) | Some(DialectType::Trino)
17576 );
17577 if is_presto_like && func.name.eq_ignore_ascii_case("DATE_ADD") && func.args.len() == 3 {
17578 self.write_keyword("DATE_ADD");
17579 self.write("(");
17580 self.generate_expression(&func.args[0])?;
17582 self.write(", ");
17583 let interval = &func.args[1];
17585 let needs_cast = !self.returns_integer_type(interval);
17586 if needs_cast {
17587 self.write_keyword("CAST");
17588 self.write("(");
17589 }
17590 self.generate_expression(interval)?;
17591 if needs_cast {
17592 self.write_space();
17593 self.write_keyword("AS");
17594 self.write_space();
17595 self.write_keyword("BIGINT");
17596 self.write(")");
17597 }
17598 self.write(", ");
17599 self.generate_expression(&func.args[2])?;
17601 self.write(")");
17602 return Ok(());
17603 }
17604
17605 let use_brackets = func.use_bracket_syntax;
17607
17608 let has_ordinality = func.name.len() >= 16
17613 && func.name[func.name.len() - 16..].eq_ignore_ascii_case(" WITH ORDINALITY");
17614 let output_name = if has_ordinality {
17615 let base_name = &func.name[..func.name.len() - " WITH ORDINALITY".len()];
17616 self.normalize_func_name(base_name)
17617 } else {
17618 normalized_name.clone()
17619 };
17620
17621 if func.name.contains('.') && !has_ordinality {
17624 if func.quoted {
17627 self.write("`");
17628 self.write(&func.name);
17629 self.write("`");
17630 } else {
17631 self.write(&func.name);
17632 }
17633 } else {
17634 self.write(&output_name);
17635 }
17636
17637 let force_parens = func.no_parens && func.args.is_empty() && !func.distinct && {
17640 let needs_parens = if func.name.eq_ignore_ascii_case("CURRENT_USER")
17641 || func.name.eq_ignore_ascii_case("SESSION_USER")
17642 || func.name.eq_ignore_ascii_case("SYSTEM_USER")
17643 {
17644 matches!(
17645 self.config.dialect,
17646 Some(DialectType::Snowflake)
17647 | Some(DialectType::Spark)
17648 | Some(DialectType::Databricks)
17649 | Some(DialectType::Hive)
17650 )
17651 } else {
17652 false
17653 };
17654 !needs_parens
17655 };
17656 if force_parens {
17657 for comment in &func.trailing_comments {
17659 self.write_space();
17660 self.write_formatted_comment(comment);
17661 }
17662 return Ok(());
17663 }
17664
17665 if func.name.eq_ignore_ascii_case("CUBE")
17667 || func.name.eq_ignore_ascii_case("ROLLUP")
17668 || func.name.eq_ignore_ascii_case("GROUPING SETS")
17669 {
17670 self.write(" (");
17671 } else if use_brackets {
17672 self.write("[");
17673 } else {
17674 self.write("(");
17675 }
17676 if func.distinct {
17677 self.write_keyword("DISTINCT");
17678 self.write_space();
17679 }
17680
17681 let compact_pretty_func = matches!(self.config.dialect, Some(DialectType::Snowflake))
17683 && (func.name.eq_ignore_ascii_case("TABLE")
17684 || func.name.eq_ignore_ascii_case("FLATTEN"));
17685 let is_grouping_func = func.name.eq_ignore_ascii_case("GROUPING SETS")
17687 || func.name.eq_ignore_ascii_case("CUBE")
17688 || func.name.eq_ignore_ascii_case("ROLLUP");
17689 let should_split = if self.config.pretty && !func.args.is_empty() && !compact_pretty_func {
17690 if is_grouping_func {
17691 true
17692 } else {
17693 let mut expr_strings: Vec<String> = Vec::with_capacity(func.args.len());
17695 for arg in &func.args {
17696 let mut temp_gen = Generator::with_arc_config(self.config.clone());
17697 Arc::make_mut(&mut temp_gen.config).pretty = false; temp_gen.generate_expression(arg)?;
17699 expr_strings.push(temp_gen.output);
17700 }
17701 self.too_wide(&expr_strings)
17702 }
17703 } else {
17704 false
17705 };
17706
17707 if should_split {
17708 self.write_newline();
17710 self.indent_level += 1;
17711 for (i, arg) in func.args.iter().enumerate() {
17712 self.write_indent();
17713 self.generate_expression(arg)?;
17714 if i + 1 < func.args.len() {
17715 self.write(",");
17716 }
17717 self.write_newline();
17718 }
17719 self.indent_level -= 1;
17720 self.write_indent();
17721 } else {
17722 for (i, arg) in func.args.iter().enumerate() {
17724 if i > 0 {
17725 self.write(", ");
17726 }
17727 self.generate_expression(arg)?;
17728 }
17729 }
17730
17731 if use_brackets {
17732 self.write("]");
17733 } else {
17734 self.write(")");
17735 }
17736 if has_ordinality {
17738 self.write_space();
17739 self.write_keyword("WITH ORDINALITY");
17740 }
17741 for comment in &func.trailing_comments {
17743 self.write_space();
17744 self.write_formatted_comment(comment);
17745 }
17746 Ok(())
17747 }
17748
17749 fn generate_function_emits(&mut self, fe: &FunctionEmits) -> Result<()> {
17750 self.generate_expression(&fe.this)?;
17751 self.write_keyword(" EMITS ");
17752 self.generate_expression(&fe.emits)?;
17753 Ok(())
17754 }
17755
17756 fn generate_aggregate_function(&mut self, func: &AggregateFunction) -> Result<()> {
17757 let mut normalized_name = self.normalize_func_name(&func.name);
17759
17760 if func.name.eq_ignore_ascii_case("MAX_BY") || func.name.eq_ignore_ascii_case("MIN_BY") {
17762 let is_max = func.name.eq_ignore_ascii_case("MAX_BY");
17763 match self.config.dialect {
17764 Some(DialectType::ClickHouse) => {
17765 normalized_name = if is_max {
17766 Cow::Borrowed("argMax")
17767 } else {
17768 Cow::Borrowed("argMin")
17769 };
17770 }
17771 Some(DialectType::DuckDB) => {
17772 normalized_name = if is_max {
17773 Cow::Borrowed("ARG_MAX")
17774 } else {
17775 Cow::Borrowed("ARG_MIN")
17776 };
17777 }
17778 _ => {}
17779 }
17780 }
17781 self.write(normalized_name.as_ref());
17782 self.write("(");
17783 if func.distinct {
17784 self.write_keyword("DISTINCT");
17785 self.write_space();
17786 }
17787
17788 let is_count = normalized_name.eq_ignore_ascii_case("COUNT");
17792 let needs_multi_arg_transform =
17793 func.distinct && is_count && func.args.len() > 1 && !self.config.multi_arg_distinct;
17794
17795 if needs_multi_arg_transform {
17796 self.write_keyword("CASE");
17798 for arg in &func.args {
17799 self.write_space();
17800 self.write_keyword("WHEN");
17801 self.write_space();
17802 self.generate_expression(arg)?;
17803 self.write_space();
17804 self.write_keyword("IS NULL THEN NULL");
17805 }
17806 self.write_space();
17807 self.write_keyword("ELSE");
17808 self.write(" (");
17809 for (i, arg) in func.args.iter().enumerate() {
17810 if i > 0 {
17811 self.write(", ");
17812 }
17813 self.generate_expression(arg)?;
17814 }
17815 self.write(")");
17816 self.write_space();
17817 self.write_keyword("END");
17818 } else {
17819 for (i, arg) in func.args.iter().enumerate() {
17820 if i > 0 {
17821 self.write(", ");
17822 }
17823 self.generate_expression(arg)?;
17824 }
17825 }
17826
17827 if self.config.ignore_nulls_in_func
17829 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
17830 {
17831 if let Some(ignore) = func.ignore_nulls {
17832 self.write_space();
17833 if ignore {
17834 self.write_keyword("IGNORE NULLS");
17835 } else {
17836 self.write_keyword("RESPECT NULLS");
17837 }
17838 }
17839 }
17840
17841 if !func.order_by.is_empty() {
17843 self.write_space();
17844 self.write_keyword("ORDER BY");
17845 self.write_space();
17846 for (i, ord) in func.order_by.iter().enumerate() {
17847 if i > 0 {
17848 self.write(", ");
17849 }
17850 self.generate_ordered(ord)?;
17851 }
17852 }
17853
17854 if let Some(limit) = &func.limit {
17856 self.write_space();
17857 self.write_keyword("LIMIT");
17858 self.write_space();
17859 if let Expression::Tuple(t) = limit.as_ref() {
17861 if t.expressions.len() == 2 {
17862 self.generate_expression(&t.expressions[0])?;
17863 self.write(", ");
17864 self.generate_expression(&t.expressions[1])?;
17865 } else {
17866 self.generate_expression(limit)?;
17867 }
17868 } else {
17869 self.generate_expression(limit)?;
17870 }
17871 }
17872
17873 self.write(")");
17874
17875 if !self.config.ignore_nulls_in_func
17877 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
17878 {
17879 if let Some(ignore) = func.ignore_nulls {
17880 self.write_space();
17881 if ignore {
17882 self.write_keyword("IGNORE NULLS");
17883 } else {
17884 self.write_keyword("RESPECT NULLS");
17885 }
17886 }
17887 }
17888
17889 if let Some(filter) = &func.filter {
17890 self.write_space();
17891 self.write_keyword("FILTER");
17892 self.write("(");
17893 self.write_keyword("WHERE");
17894 self.write_space();
17895 self.generate_expression(filter)?;
17896 self.write(")");
17897 }
17898
17899 Ok(())
17900 }
17901
17902 fn generate_window_function(&mut self, wf: &WindowFunction) -> Result<()> {
17903 self.generate_expression(&wf.this)?;
17904
17905 if let Some(keep) = &wf.keep {
17907 self.write_space();
17908 self.write_keyword("KEEP");
17909 self.write(" (");
17910 self.write_keyword("DENSE_RANK");
17911 self.write_space();
17912 if keep.first {
17913 self.write_keyword("FIRST");
17914 } else {
17915 self.write_keyword("LAST");
17916 }
17917 self.write_space();
17918 self.write_keyword("ORDER BY");
17919 self.write_space();
17920 for (i, ord) in keep.order_by.iter().enumerate() {
17921 if i > 0 {
17922 self.write(", ");
17923 }
17924 self.generate_ordered(ord)?;
17925 }
17926 self.write(")");
17927 }
17928
17929 let has_over = !wf.over.partition_by.is_empty()
17931 || !wf.over.order_by.is_empty()
17932 || wf.over.frame.is_some()
17933 || wf.over.window_name.is_some();
17934
17935 if has_over {
17937 self.write_space();
17938 self.write_keyword("OVER");
17939
17940 let has_specs = !wf.over.partition_by.is_empty()
17942 || !wf.over.order_by.is_empty()
17943 || wf.over.frame.is_some();
17944
17945 if wf.over.window_name.is_some() && !has_specs {
17946 self.write_space();
17948 self.write(&wf.over.window_name.as_ref().unwrap().name);
17949 } else {
17950 self.write(" (");
17952 self.generate_over(&wf.over)?;
17953 self.write(")");
17954 }
17955 } else if wf.keep.is_none() {
17956 self.write_space();
17958 self.write_keyword("OVER");
17959 self.write(" ()");
17960 }
17961
17962 Ok(())
17963 }
17964
17965 fn generate_within_group(&mut self, wg: &WithinGroup) -> Result<()> {
17967 self.generate_expression(&wg.this)?;
17968 self.write_space();
17969 self.write_keyword("WITHIN GROUP");
17970 self.write(" (");
17971 self.write_keyword("ORDER BY");
17972 self.write_space();
17973 for (i, ord) in wg.order_by.iter().enumerate() {
17974 if i > 0 {
17975 self.write(", ");
17976 }
17977 self.generate_ordered(ord)?;
17978 }
17979 self.write(")");
17980 Ok(())
17981 }
17982
17983 fn generate_over(&mut self, over: &Over) -> Result<()> {
17985 let mut has_content = false;
17986
17987 if let Some(name) = &over.window_name {
17989 self.write(&name.name);
17990 has_content = true;
17991 }
17992
17993 if !over.partition_by.is_empty() {
17995 if has_content {
17996 self.write_space();
17997 }
17998 self.write_keyword("PARTITION BY");
17999 self.write_space();
18000 for (i, expr) in over.partition_by.iter().enumerate() {
18001 if i > 0 {
18002 self.write(", ");
18003 }
18004 self.generate_expression(expr)?;
18005 }
18006 has_content = true;
18007 }
18008
18009 if !over.order_by.is_empty() {
18011 if has_content {
18012 self.write_space();
18013 }
18014 self.write_keyword("ORDER BY");
18015 self.write_space();
18016 for (i, ordered) in over.order_by.iter().enumerate() {
18017 if i > 0 {
18018 self.write(", ");
18019 }
18020 self.generate_ordered(ordered)?;
18021 }
18022 has_content = true;
18023 }
18024
18025 if let Some(frame) = &over.frame {
18027 if has_content {
18028 self.write_space();
18029 }
18030 self.generate_window_frame(frame)?;
18031 }
18032
18033 Ok(())
18034 }
18035
18036 fn generate_window_frame(&mut self, frame: &WindowFrame) -> Result<()> {
18037 let lowercase_frame = self.config.lowercase_window_frame_keywords;
18039
18040 if !lowercase_frame {
18042 if let Some(kind_text) = &frame.kind_text {
18043 self.write(kind_text);
18044 } else {
18045 match frame.kind {
18046 WindowFrameKind::Rows => self.write_keyword("ROWS"),
18047 WindowFrameKind::Range => self.write_keyword("RANGE"),
18048 WindowFrameKind::Groups => self.write_keyword("GROUPS"),
18049 }
18050 }
18051 } else {
18052 match frame.kind {
18053 WindowFrameKind::Rows => self.write("rows"),
18054 WindowFrameKind::Range => self.write("range"),
18055 WindowFrameKind::Groups => self.write("groups"),
18056 }
18057 }
18058
18059 self.write_space();
18062 let should_normalize = self.config.normalize_window_frame_between
18063 && frame.end.is_none()
18064 && matches!(
18065 frame.start,
18066 WindowFrameBound::Preceding(_)
18067 | WindowFrameBound::Following(_)
18068 | WindowFrameBound::UnboundedPreceding
18069 | WindowFrameBound::UnboundedFollowing
18070 );
18071
18072 if let Some(end) = &frame.end {
18073 self.write_keyword("BETWEEN");
18075 self.write_space();
18076 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
18077 self.write_space();
18078 self.write_keyword("AND");
18079 self.write_space();
18080 self.generate_window_frame_bound(end, frame.end_side_text.as_deref())?;
18081 } else if should_normalize {
18082 self.write_keyword("BETWEEN");
18084 self.write_space();
18085 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
18086 self.write_space();
18087 self.write_keyword("AND");
18088 self.write_space();
18089 self.write_keyword("CURRENT ROW");
18090 } else {
18091 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
18093 }
18094
18095 if let Some(exclude) = &frame.exclude {
18097 self.write_space();
18098 self.write_keyword("EXCLUDE");
18099 self.write_space();
18100 match exclude {
18101 WindowFrameExclude::CurrentRow => self.write_keyword("CURRENT ROW"),
18102 WindowFrameExclude::Group => self.write_keyword("GROUP"),
18103 WindowFrameExclude::Ties => self.write_keyword("TIES"),
18104 WindowFrameExclude::NoOthers => self.write_keyword("NO OTHERS"),
18105 }
18106 }
18107
18108 Ok(())
18109 }
18110
18111 fn generate_window_frame_bound(
18112 &mut self,
18113 bound: &WindowFrameBound,
18114 side_text: Option<&str>,
18115 ) -> Result<()> {
18116 let lowercase_frame = self.config.lowercase_window_frame_keywords;
18118
18119 match bound {
18120 WindowFrameBound::CurrentRow => {
18121 self.write_keyword("CURRENT ROW");
18122 }
18123 WindowFrameBound::UnboundedPreceding => {
18124 self.write_keyword("UNBOUNDED");
18125 self.write_space();
18126 if lowercase_frame {
18127 self.write("preceding");
18128 } else if let Some(text) = side_text {
18129 self.write(text);
18130 } else {
18131 self.write_keyword("PRECEDING");
18132 }
18133 }
18134 WindowFrameBound::UnboundedFollowing => {
18135 self.write_keyword("UNBOUNDED");
18136 self.write_space();
18137 if lowercase_frame {
18138 self.write("following");
18139 } else if let Some(text) = side_text {
18140 self.write(text);
18141 } else {
18142 self.write_keyword("FOLLOWING");
18143 }
18144 }
18145 WindowFrameBound::Preceding(expr) => {
18146 self.generate_expression(expr)?;
18147 self.write_space();
18148 if lowercase_frame {
18149 self.write("preceding");
18150 } else if let Some(text) = side_text {
18151 self.write(text);
18152 } else {
18153 self.write_keyword("PRECEDING");
18154 }
18155 }
18156 WindowFrameBound::Following(expr) => {
18157 self.generate_expression(expr)?;
18158 self.write_space();
18159 if lowercase_frame {
18160 self.write("following");
18161 } else if let Some(text) = side_text {
18162 self.write(text);
18163 } else {
18164 self.write_keyword("FOLLOWING");
18165 }
18166 }
18167 WindowFrameBound::BarePreceding => {
18168 if lowercase_frame {
18169 self.write("preceding");
18170 } else if let Some(text) = side_text {
18171 self.write(text);
18172 } else {
18173 self.write_keyword("PRECEDING");
18174 }
18175 }
18176 WindowFrameBound::BareFollowing => {
18177 if lowercase_frame {
18178 self.write("following");
18179 } else if let Some(text) = side_text {
18180 self.write(text);
18181 } else {
18182 self.write_keyword("FOLLOWING");
18183 }
18184 }
18185 WindowFrameBound::Value(expr) => {
18186 self.generate_expression(expr)?;
18188 }
18189 }
18190 Ok(())
18191 }
18192
18193 fn generate_interval(&mut self, interval: &Interval) -> Result<()> {
18194 let skip_interval_keyword = matches!(self.config.dialect, Some(DialectType::Oracle))
18197 && matches!(&interval.unit, Some(IntervalUnitSpec::ExprSpan(_)))
18198 && !matches!(&interval.this, Some(Expression::Literal(_)));
18199
18200 if self.config.single_string_interval {
18203 if let (
18204 Some(Expression::Literal(lit)),
18205 Some(IntervalUnitSpec::Simple {
18206 ref unit,
18207 ref use_plural,
18208 }),
18209 ) = (&interval.this, &interval.unit)
18210 {
18211 if let Literal::String(ref val) = lit.as_ref() {
18212 self.write_keyword("INTERVAL");
18213 self.write_space();
18214 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
18215 let unit_str = self.interval_unit_str(unit, effective_plural);
18216 self.write("'");
18217 self.write(val);
18218 self.write(" ");
18219 self.write(&unit_str);
18220 self.write("'");
18221 return Ok(());
18222 }
18223 }
18224 }
18225
18226 if !skip_interval_keyword {
18227 self.write_keyword("INTERVAL");
18228 }
18229
18230 if let Some(ref value) = interval.this {
18232 if !skip_interval_keyword {
18233 self.write_space();
18234 }
18235 let needs_parens = interval.unit.is_some()
18239 && matches!(
18240 value,
18241 Expression::Add(_)
18242 | Expression::Sub(_)
18243 | Expression::Mul(_)
18244 | Expression::Div(_)
18245 | Expression::Mod(_)
18246 | Expression::BitwiseAnd(_)
18247 | Expression::BitwiseOr(_)
18248 | Expression::BitwiseXor(_)
18249 );
18250 if needs_parens {
18251 self.write("(");
18252 }
18253 self.generate_expression(value)?;
18254 if needs_parens {
18255 self.write(")");
18256 }
18257 }
18258
18259 if let Some(ref unit_spec) = interval.unit {
18261 self.write_space();
18262 self.write_interval_unit_spec(unit_spec)?;
18263 }
18264
18265 Ok(())
18266 }
18267
18268 fn interval_unit_str(&self, unit: &IntervalUnit, use_plural: bool) -> &'static str {
18270 match (unit, use_plural) {
18271 (IntervalUnit::Year, false) => "YEAR",
18272 (IntervalUnit::Year, true) => "YEARS",
18273 (IntervalUnit::Quarter, false) => "QUARTER",
18274 (IntervalUnit::Quarter, true) => "QUARTERS",
18275 (IntervalUnit::Month, false) => "MONTH",
18276 (IntervalUnit::Month, true) => "MONTHS",
18277 (IntervalUnit::Week, false) => "WEEK",
18278 (IntervalUnit::Week, true) => "WEEKS",
18279 (IntervalUnit::Day, false) => "DAY",
18280 (IntervalUnit::Day, true) => "DAYS",
18281 (IntervalUnit::Hour, false) => "HOUR",
18282 (IntervalUnit::Hour, true) => "HOURS",
18283 (IntervalUnit::Minute, false) => "MINUTE",
18284 (IntervalUnit::Minute, true) => "MINUTES",
18285 (IntervalUnit::Second, false) => "SECOND",
18286 (IntervalUnit::Second, true) => "SECONDS",
18287 (IntervalUnit::Millisecond, false) => "MILLISECOND",
18288 (IntervalUnit::Millisecond, true) => "MILLISECONDS",
18289 (IntervalUnit::Microsecond, false) => "MICROSECOND",
18290 (IntervalUnit::Microsecond, true) => "MICROSECONDS",
18291 (IntervalUnit::Nanosecond, false) => "NANOSECOND",
18292 (IntervalUnit::Nanosecond, true) => "NANOSECONDS",
18293 }
18294 }
18295
18296 fn write_interval_unit_spec(&mut self, unit_spec: &IntervalUnitSpec) -> Result<()> {
18297 match unit_spec {
18298 IntervalUnitSpec::Simple { unit, use_plural } => {
18299 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
18301 self.write_simple_interval_unit(unit, effective_plural);
18302 }
18303 IntervalUnitSpec::Span(span) => {
18304 self.write_simple_interval_unit(&span.this, false);
18305 self.write_space();
18306 self.write_keyword("TO");
18307 self.write_space();
18308 self.write_simple_interval_unit(&span.expression, false);
18309 }
18310 IntervalUnitSpec::ExprSpan(span) => {
18311 self.generate_expression(&span.this)?;
18313 self.write_space();
18314 self.write_keyword("TO");
18315 self.write_space();
18316 self.generate_expression(&span.expression)?;
18317 }
18318 IntervalUnitSpec::Expr(expr) => {
18319 self.generate_expression(expr)?;
18320 }
18321 }
18322 Ok(())
18323 }
18324
18325 fn write_simple_interval_unit(&mut self, unit: &IntervalUnit, use_plural: bool) {
18326 match (unit, use_plural) {
18328 (IntervalUnit::Year, false) => self.write_keyword("YEAR"),
18329 (IntervalUnit::Year, true) => self.write_keyword("YEARS"),
18330 (IntervalUnit::Quarter, false) => self.write_keyword("QUARTER"),
18331 (IntervalUnit::Quarter, true) => self.write_keyword("QUARTERS"),
18332 (IntervalUnit::Month, false) => self.write_keyword("MONTH"),
18333 (IntervalUnit::Month, true) => self.write_keyword("MONTHS"),
18334 (IntervalUnit::Week, false) => self.write_keyword("WEEK"),
18335 (IntervalUnit::Week, true) => self.write_keyword("WEEKS"),
18336 (IntervalUnit::Day, false) => self.write_keyword("DAY"),
18337 (IntervalUnit::Day, true) => self.write_keyword("DAYS"),
18338 (IntervalUnit::Hour, false) => self.write_keyword("HOUR"),
18339 (IntervalUnit::Hour, true) => self.write_keyword("HOURS"),
18340 (IntervalUnit::Minute, false) => self.write_keyword("MINUTE"),
18341 (IntervalUnit::Minute, true) => self.write_keyword("MINUTES"),
18342 (IntervalUnit::Second, false) => self.write_keyword("SECOND"),
18343 (IntervalUnit::Second, true) => self.write_keyword("SECONDS"),
18344 (IntervalUnit::Millisecond, false) => self.write_keyword("MILLISECOND"),
18345 (IntervalUnit::Millisecond, true) => self.write_keyword("MILLISECONDS"),
18346 (IntervalUnit::Microsecond, false) => self.write_keyword("MICROSECOND"),
18347 (IntervalUnit::Microsecond, true) => self.write_keyword("MICROSECONDS"),
18348 (IntervalUnit::Nanosecond, false) => self.write_keyword("NANOSECOND"),
18349 (IntervalUnit::Nanosecond, true) => self.write_keyword("NANOSECONDS"),
18350 }
18351 }
18352
18353 fn write_redshift_date_part(&mut self, expr: &Expression) {
18356 let part_str = self.extract_date_part_string(expr);
18357 if let Some(part) = part_str {
18358 let normalized = self.normalize_date_part(&part);
18359 self.write_keyword(&normalized);
18360 } else {
18361 let _ = self.generate_expression(expr);
18363 }
18364 }
18365
18366 fn write_redshift_date_part_quoted(&mut self, expr: &Expression) {
18369 let part_str = self.extract_date_part_string(expr);
18370 if let Some(part) = part_str {
18371 let normalized = self.normalize_date_part(&part);
18372 self.write("'");
18373 self.write(&normalized);
18374 self.write("'");
18375 } else {
18376 let _ = self.generate_expression(expr);
18378 }
18379 }
18380
18381 fn extract_date_part_string(&self, expr: &Expression) -> Option<String> {
18383 match expr {
18384 Expression::Literal(lit)
18385 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
18386 {
18387 let crate::expressions::Literal::String(s) = lit.as_ref() else {
18388 unreachable!()
18389 };
18390 Some(s.clone())
18391 }
18392 Expression::Identifier(id) => Some(id.name.clone()),
18393 Expression::Var(v) => Some(v.this.clone()),
18394 Expression::Column(col) if col.table.is_none() => {
18395 Some(col.name.name.clone())
18397 }
18398 _ => None,
18399 }
18400 }
18401
18402 fn normalize_date_part(&self, part: &str) -> String {
18405 let mut buf = [0u8; 64];
18406 let lower: &str = if part.len() <= 64 {
18407 for (i, b) in part.bytes().enumerate() {
18408 buf[i] = b.to_ascii_lowercase();
18409 }
18410 std::str::from_utf8(&buf[..part.len()]).unwrap_or(part)
18411 } else {
18412 return part.to_ascii_uppercase();
18413 };
18414 match lower {
18415 "day" | "days" | "d" => "DAY".to_string(),
18416 "month" | "months" | "mon" | "mm" => "MONTH".to_string(),
18417 "year" | "years" | "y" | "yy" | "yyyy" => "YEAR".to_string(),
18418 "week" | "weeks" | "w" | "wk" => "WEEK".to_string(),
18419 "hour" | "hours" | "h" | "hh" => "HOUR".to_string(),
18420 "minute" | "minutes" | "m" | "mi" | "n" => "MINUTE".to_string(),
18421 "second" | "seconds" | "s" | "ss" => "SECOND".to_string(),
18422 "millisecond" | "milliseconds" | "ms" => "MILLISECOND".to_string(),
18423 "microsecond" | "microseconds" | "us" => "MICROSECOND".to_string(),
18424 "quarter" | "quarters" | "q" | "qq" => "QUARTER".to_string(),
18425 _ => part.to_ascii_uppercase(),
18426 }
18427 }
18428
18429 fn write_datetime_field(&mut self, field: &DateTimeField) {
18430 match field {
18431 DateTimeField::Year => self.write_keyword("YEAR"),
18432 DateTimeField::Month => self.write_keyword("MONTH"),
18433 DateTimeField::Day => self.write_keyword("DAY"),
18434 DateTimeField::Hour => self.write_keyword("HOUR"),
18435 DateTimeField::Minute => self.write_keyword("MINUTE"),
18436 DateTimeField::Second => self.write_keyword("SECOND"),
18437 DateTimeField::Millisecond => self.write_keyword("MILLISECOND"),
18438 DateTimeField::Microsecond => self.write_keyword("MICROSECOND"),
18439 DateTimeField::DayOfWeek => {
18440 let name = match self.config.dialect {
18441 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFWEEK",
18442 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "WEEKDAY",
18443 _ => "DOW",
18444 };
18445 self.write_keyword(name);
18446 }
18447 DateTimeField::DayOfYear => {
18448 let name = match self.config.dialect {
18449 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFYEAR",
18450 _ => "DOY",
18451 };
18452 self.write_keyword(name);
18453 }
18454 DateTimeField::Week => self.write_keyword("WEEK"),
18455 DateTimeField::WeekWithModifier(modifier) => {
18456 self.write_keyword("WEEK");
18457 self.write("(");
18458 self.write(modifier);
18459 self.write(")");
18460 }
18461 DateTimeField::Quarter => self.write_keyword("QUARTER"),
18462 DateTimeField::Epoch => self.write_keyword("EPOCH"),
18463 DateTimeField::Timezone => self.write_keyword("TIMEZONE"),
18464 DateTimeField::TimezoneHour => self.write_keyword("TIMEZONE_HOUR"),
18465 DateTimeField::TimezoneMinute => self.write_keyword("TIMEZONE_MINUTE"),
18466 DateTimeField::Date => self.write_keyword("DATE"),
18467 DateTimeField::Time => self.write_keyword("TIME"),
18468 DateTimeField::Custom(name) => self.write(name),
18469 }
18470 }
18471
18472 fn write_datetime_field_lower(&mut self, field: &DateTimeField) {
18474 match field {
18475 DateTimeField::Year => self.write("year"),
18476 DateTimeField::Month => self.write("month"),
18477 DateTimeField::Day => self.write("day"),
18478 DateTimeField::Hour => self.write("hour"),
18479 DateTimeField::Minute => self.write("minute"),
18480 DateTimeField::Second => self.write("second"),
18481 DateTimeField::Millisecond => self.write("millisecond"),
18482 DateTimeField::Microsecond => self.write("microsecond"),
18483 DateTimeField::DayOfWeek => self.write("dow"),
18484 DateTimeField::DayOfYear => self.write("doy"),
18485 DateTimeField::Week => self.write("week"),
18486 DateTimeField::WeekWithModifier(modifier) => {
18487 self.write("week(");
18488 self.write(modifier);
18489 self.write(")");
18490 }
18491 DateTimeField::Quarter => self.write("quarter"),
18492 DateTimeField::Epoch => self.write("epoch"),
18493 DateTimeField::Timezone => self.write("timezone"),
18494 DateTimeField::TimezoneHour => self.write("timezone_hour"),
18495 DateTimeField::TimezoneMinute => self.write("timezone_minute"),
18496 DateTimeField::Date => self.write("date"),
18497 DateTimeField::Time => self.write("time"),
18498 DateTimeField::Custom(name) => self.write(name),
18499 }
18500 }
18501
18502 fn generate_simple_func(&mut self, name: &str, arg: &Expression) -> Result<()> {
18505 self.write_keyword(name);
18506 self.write("(");
18507 self.generate_expression(arg)?;
18508 self.write(")");
18509 Ok(())
18510 }
18511
18512 fn generate_unary_func(
18514 &mut self,
18515 default_name: &str,
18516 f: &crate::expressions::UnaryFunc,
18517 ) -> Result<()> {
18518 let name = f.original_name.as_deref().unwrap_or(default_name);
18519 self.write_keyword(name);
18520 self.write("(");
18521 self.generate_expression(&f.this)?;
18522 self.write(")");
18523 Ok(())
18524 }
18525
18526 fn generate_sqrt_cbrt(
18528 &mut self,
18529 f: &crate::expressions::UnaryFunc,
18530 func_name: &str,
18531 _op: &str,
18532 ) -> Result<()> {
18533 self.write_keyword(func_name);
18536 self.write("(");
18537 self.generate_expression(&f.this)?;
18538 self.write(")");
18539 Ok(())
18540 }
18541
18542 fn generate_binary_func(
18543 &mut self,
18544 name: &str,
18545 arg1: &Expression,
18546 arg2: &Expression,
18547 ) -> Result<()> {
18548 self.write_keyword(name);
18549 self.write("(");
18550 self.generate_expression(arg1)?;
18551 self.write(", ");
18552 self.generate_expression(arg2)?;
18553 self.write(")");
18554 Ok(())
18555 }
18556
18557 fn generate_char_func(&mut self, f: &crate::expressions::CharFunc) -> Result<()> {
18561 let func_name = f.name.as_deref().unwrap_or("CHAR");
18563 self.write_keyword(func_name);
18564 self.write("(");
18565 for (i, arg) in f.args.iter().enumerate() {
18566 if i > 0 {
18567 self.write(", ");
18568 }
18569 self.generate_expression(arg)?;
18570 }
18571 if let Some(ref charset) = f.charset {
18572 self.write(" ");
18573 self.write_keyword("USING");
18574 self.write(" ");
18575 self.write(charset);
18576 }
18577 self.write(")");
18578 Ok(())
18579 }
18580
18581 fn generate_power(&mut self, f: &BinaryFunc) -> Result<()> {
18582 use crate::dialects::DialectType;
18583
18584 match self.config.dialect {
18585 Some(DialectType::Teradata) => {
18586 self.generate_expression(&f.this)?;
18588 self.write(" ** ");
18589 self.generate_expression(&f.expression)?;
18590 Ok(())
18591 }
18592 _ => {
18593 self.generate_binary_func("POWER", &f.this, &f.expression)
18595 }
18596 }
18597 }
18598
18599 fn generate_vararg_func(&mut self, name: &str, args: &[Expression]) -> Result<()> {
18600 self.write_func_name(name);
18601 self.write("(");
18602 for (i, arg) in args.iter().enumerate() {
18603 if i > 0 {
18604 self.write(", ");
18605 }
18606 self.generate_expression(arg)?;
18607 }
18608 self.write(")");
18609 Ok(())
18610 }
18611
18612 fn generate_concat_ws(&mut self, f: &ConcatWs) -> Result<()> {
18615 self.write_keyword("CONCAT_WS");
18616 self.write("(");
18617 self.generate_expression(&f.separator)?;
18618 for expr in &f.expressions {
18619 self.write(", ");
18620 self.generate_expression(expr)?;
18621 }
18622 self.write(")");
18623 Ok(())
18624 }
18625
18626 fn collect_concat_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
18627 if let Expression::Concat(op) = expr {
18628 Self::collect_concat_operands(&op.left, out);
18629 Self::collect_concat_operands(&op.right, out);
18630 } else {
18631 out.push(expr);
18632 }
18633 }
18634
18635 fn generate_mysql_concat_from_concat(&mut self, op: &BinaryOp) -> Result<()> {
18636 let mut operands = Vec::new();
18637 Self::collect_concat_operands(&op.left, &mut operands);
18638 Self::collect_concat_operands(&op.right, &mut operands);
18639
18640 self.write_keyword("CONCAT");
18641 self.write("(");
18642 for (i, operand) in operands.iter().enumerate() {
18643 if i > 0 {
18644 self.write(", ");
18645 }
18646 self.generate_expression(operand)?;
18647 }
18648 self.write(")");
18649 Ok(())
18650 }
18651
18652 fn collect_dpipe_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
18653 if let Expression::DPipe(dpipe) = expr {
18654 Self::collect_dpipe_operands(&dpipe.this, out);
18655 Self::collect_dpipe_operands(&dpipe.expression, out);
18656 } else {
18657 out.push(expr);
18658 }
18659 }
18660
18661 fn generate_mysql_concat_from_dpipe(&mut self, e: &DPipe) -> Result<()> {
18662 let mut operands = Vec::new();
18663 Self::collect_dpipe_operands(&e.this, &mut operands);
18664 Self::collect_dpipe_operands(&e.expression, &mut operands);
18665
18666 self.write_keyword("CONCAT");
18667 self.write("(");
18668 for (i, operand) in operands.iter().enumerate() {
18669 if i > 0 {
18670 self.write(", ");
18671 }
18672 self.generate_expression(operand)?;
18673 }
18674 self.write(")");
18675 Ok(())
18676 }
18677
18678 fn generate_substring(&mut self, f: &SubstringFunc) -> Result<()> {
18679 let use_substr = matches!(
18681 self.config.dialect,
18682 Some(
18683 DialectType::Oracle
18684 | DialectType::Presto
18685 | DialectType::Trino
18686 | DialectType::Athena
18687 )
18688 );
18689 if use_substr {
18690 self.write_keyword("SUBSTR");
18691 } else {
18692 self.write_keyword("SUBSTRING");
18693 }
18694 self.write("(");
18695 self.generate_expression(&f.this)?;
18696 let force_from_for = matches!(self.config.dialect, Some(DialectType::PostgreSQL));
18698 let use_comma_syntax = matches!(
18700 self.config.dialect,
18701 Some(DialectType::Spark)
18702 | Some(DialectType::Hive)
18703 | Some(DialectType::Databricks)
18704 | Some(DialectType::TSQL)
18705 | Some(DialectType::Fabric)
18706 );
18707 if (f.from_for_syntax || force_from_for) && !use_comma_syntax {
18708 self.write_space();
18710 self.write_keyword("FROM");
18711 self.write_space();
18712 self.generate_expression(&f.start)?;
18713 if let Some(length) = &f.length {
18714 self.write_space();
18715 self.write_keyword("FOR");
18716 self.write_space();
18717 self.generate_expression(length)?;
18718 }
18719 } else {
18720 self.write(", ");
18722 self.generate_expression(&f.start)?;
18723 if let Some(length) = &f.length {
18724 self.write(", ");
18725 self.generate_expression(length)?;
18726 }
18727 }
18728 self.write(")");
18729 Ok(())
18730 }
18731
18732 fn generate_overlay(&mut self, f: &OverlayFunc) -> Result<()> {
18733 self.write_keyword("OVERLAY");
18734 self.write("(");
18735 self.generate_expression(&f.this)?;
18736 self.write_space();
18737 self.write_keyword("PLACING");
18738 self.write_space();
18739 self.generate_expression(&f.replacement)?;
18740 self.write_space();
18741 self.write_keyword("FROM");
18742 self.write_space();
18743 self.generate_expression(&f.from)?;
18744 if let Some(length) = &f.length {
18745 self.write_space();
18746 self.write_keyword("FOR");
18747 self.write_space();
18748 self.generate_expression(length)?;
18749 }
18750 self.write(")");
18751 Ok(())
18752 }
18753
18754 fn generate_trim(&mut self, f: &TrimFunc) -> Result<()> {
18755 if f.position_explicit && f.characters.is_none() {
18758 match f.position {
18759 TrimPosition::Leading => {
18760 self.write_keyword("LTRIM");
18761 self.write("(");
18762 self.generate_expression(&f.this)?;
18763 self.write(")");
18764 return Ok(());
18765 }
18766 TrimPosition::Trailing => {
18767 self.write_keyword("RTRIM");
18768 self.write("(");
18769 self.generate_expression(&f.this)?;
18770 self.write(")");
18771 return Ok(());
18772 }
18773 TrimPosition::Both => {
18774 }
18777 }
18778 }
18779
18780 self.write_keyword("TRIM");
18781 self.write("(");
18782 let force_standard = f.characters.is_some()
18785 && !f.sql_standard_syntax
18786 && matches!(
18787 self.config.dialect,
18788 Some(DialectType::Hive)
18789 | Some(DialectType::Spark)
18790 | Some(DialectType::Databricks)
18791 | Some(DialectType::ClickHouse)
18792 );
18793 let use_standard = (f.sql_standard_syntax || force_standard)
18794 && !(f.position_explicit
18795 && f.characters.is_none()
18796 && matches!(f.position, TrimPosition::Both));
18797 if use_standard {
18798 if f.position_explicit {
18801 match f.position {
18802 TrimPosition::Both => self.write_keyword("BOTH"),
18803 TrimPosition::Leading => self.write_keyword("LEADING"),
18804 TrimPosition::Trailing => self.write_keyword("TRAILING"),
18805 }
18806 self.write_space();
18807 }
18808 if let Some(chars) = &f.characters {
18809 self.generate_expression(chars)?;
18810 self.write_space();
18811 }
18812 self.write_keyword("FROM");
18813 self.write_space();
18814 self.generate_expression(&f.this)?;
18815 } else {
18816 self.generate_expression(&f.this)?;
18818 if let Some(chars) = &f.characters {
18819 self.write(", ");
18820 self.generate_expression(chars)?;
18821 }
18822 }
18823 self.write(")");
18824 Ok(())
18825 }
18826
18827 fn generate_replace(&mut self, f: &ReplaceFunc) -> Result<()> {
18828 self.write_keyword("REPLACE");
18829 self.write("(");
18830 self.generate_expression(&f.this)?;
18831 self.write(", ");
18832 self.generate_expression(&f.old)?;
18833 self.write(", ");
18834 self.generate_expression(&f.new)?;
18835 self.write(")");
18836 Ok(())
18837 }
18838
18839 fn generate_left_right(&mut self, name: &str, f: &LeftRightFunc) -> Result<()> {
18840 self.write_keyword(name);
18841 self.write("(");
18842 self.generate_expression(&f.this)?;
18843 self.write(", ");
18844 self.generate_expression(&f.length)?;
18845 self.write(")");
18846 Ok(())
18847 }
18848
18849 fn generate_repeat(&mut self, f: &RepeatFunc) -> Result<()> {
18850 self.write_keyword("REPEAT");
18851 self.write("(");
18852 self.generate_expression(&f.this)?;
18853 self.write(", ");
18854 self.generate_expression(&f.times)?;
18855 self.write(")");
18856 Ok(())
18857 }
18858
18859 fn generate_pad(&mut self, name: &str, f: &PadFunc) -> Result<()> {
18860 self.write_keyword(name);
18861 self.write("(");
18862 self.generate_expression(&f.this)?;
18863 self.write(", ");
18864 self.generate_expression(&f.length)?;
18865 if let Some(fill) = &f.fill {
18866 self.write(", ");
18867 self.generate_expression(fill)?;
18868 }
18869 self.write(")");
18870 Ok(())
18871 }
18872
18873 fn generate_split(&mut self, f: &SplitFunc) -> Result<()> {
18874 self.write_keyword("SPLIT");
18875 self.write("(");
18876 self.generate_expression(&f.this)?;
18877 self.write(", ");
18878 self.generate_expression(&f.delimiter)?;
18879 self.write(")");
18880 Ok(())
18881 }
18882
18883 fn generate_regexp_like(&mut self, f: &RegexpFunc) -> Result<()> {
18884 use crate::dialects::DialectType;
18885 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) && f.flags.is_none() {
18887 self.generate_expression(&f.this)?;
18888 self.write(" ~ ");
18889 self.generate_expression(&f.pattern)?;
18890 } else if matches!(self.config.dialect, Some(DialectType::Exasol)) && f.flags.is_none() {
18891 self.generate_expression(&f.this)?;
18893 self.write_keyword(" REGEXP_LIKE ");
18894 self.generate_expression(&f.pattern)?;
18895 } else if matches!(
18896 self.config.dialect,
18897 Some(DialectType::SingleStore)
18898 | Some(DialectType::Spark)
18899 | Some(DialectType::Hive)
18900 | Some(DialectType::Databricks)
18901 ) && f.flags.is_none()
18902 {
18903 self.generate_expression(&f.this)?;
18905 self.write_keyword(" RLIKE ");
18906 self.generate_expression(&f.pattern)?;
18907 } else if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
18908 self.write_keyword("REGEXP");
18910 self.write("(");
18911 self.generate_expression(&f.this)?;
18912 self.write(", ");
18913 self.generate_expression(&f.pattern)?;
18914 if let Some(flags) = &f.flags {
18915 self.write(", ");
18916 self.generate_expression(flags)?;
18917 }
18918 self.write(")");
18919 } else {
18920 self.write_keyword("REGEXP_LIKE");
18921 self.write("(");
18922 self.generate_expression(&f.this)?;
18923 self.write(", ");
18924 self.generate_expression(&f.pattern)?;
18925 if let Some(flags) = &f.flags {
18926 self.write(", ");
18927 self.generate_expression(flags)?;
18928 }
18929 self.write(")");
18930 }
18931 Ok(())
18932 }
18933
18934 fn generate_regexp_replace(&mut self, f: &RegexpReplaceFunc) -> Result<()> {
18935 self.write_keyword("REGEXP_REPLACE");
18936 self.write("(");
18937 self.generate_expression(&f.this)?;
18938 self.write(", ");
18939 self.generate_expression(&f.pattern)?;
18940 self.write(", ");
18941 self.generate_expression(&f.replacement)?;
18942 if let Some(flags) = &f.flags {
18943 self.write(", ");
18944 self.generate_expression(flags)?;
18945 }
18946 self.write(")");
18947 Ok(())
18948 }
18949
18950 fn generate_regexp_extract(&mut self, f: &RegexpExtractFunc) -> Result<()> {
18951 self.write_keyword("REGEXP_EXTRACT");
18952 self.write("(");
18953 self.generate_expression(&f.this)?;
18954 self.write(", ");
18955 self.generate_expression(&f.pattern)?;
18956 if let Some(group) = &f.group {
18957 self.write(", ");
18958 self.generate_expression(group)?;
18959 }
18960 self.write(")");
18961 Ok(())
18962 }
18963
18964 fn generate_round(&mut self, f: &RoundFunc) -> Result<()> {
18967 self.write_keyword("ROUND");
18968 self.write("(");
18969 self.generate_expression(&f.this)?;
18970 if let Some(decimals) = &f.decimals {
18971 self.write(", ");
18972 self.generate_expression(decimals)?;
18973 }
18974 self.write(")");
18975 Ok(())
18976 }
18977
18978 fn generate_floor(&mut self, f: &FloorFunc) -> Result<()> {
18979 self.write_keyword("FLOOR");
18980 self.write("(");
18981 self.generate_expression(&f.this)?;
18982 if let Some(to) = &f.to {
18984 self.write(" ");
18985 self.write_keyword("TO");
18986 self.write(" ");
18987 self.generate_expression(to)?;
18988 } else if let Some(scale) = &f.scale {
18989 self.write(", ");
18990 self.generate_expression(scale)?;
18991 }
18992 self.write(")");
18993 Ok(())
18994 }
18995
18996 fn generate_ceil(&mut self, f: &CeilFunc) -> Result<()> {
18997 self.write_keyword("CEIL");
18998 self.write("(");
18999 self.generate_expression(&f.this)?;
19000 if let Some(to) = &f.to {
19002 self.write(" ");
19003 self.write_keyword("TO");
19004 self.write(" ");
19005 self.generate_expression(to)?;
19006 } else if let Some(decimals) = &f.decimals {
19007 self.write(", ");
19008 self.generate_expression(decimals)?;
19009 }
19010 self.write(")");
19011 Ok(())
19012 }
19013
19014 fn generate_log(&mut self, f: &LogFunc) -> Result<()> {
19015 use crate::expressions::Literal;
19016
19017 if let Some(base) = &f.base {
19018 if self.is_log_base_none() {
19021 if matches!(base, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(s) if s == "2"))
19022 {
19023 self.write_func_name("LOG2");
19024 self.write("(");
19025 self.generate_expression(&f.this)?;
19026 self.write(")");
19027 return Ok(());
19028 } else if matches!(base, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(s) if s == "10"))
19029 {
19030 self.write_func_name("LOG10");
19031 self.write("(");
19032 self.generate_expression(&f.this)?;
19033 self.write(")");
19034 return Ok(());
19035 }
19036 }
19038
19039 self.write_func_name("LOG");
19040 self.write("(");
19041 if self.is_log_value_first() {
19042 self.generate_expression(&f.this)?;
19044 self.write(", ");
19045 self.generate_expression(base)?;
19046 } else {
19047 self.generate_expression(base)?;
19049 self.write(", ");
19050 self.generate_expression(&f.this)?;
19051 }
19052 self.write(")");
19053 } else {
19054 self.write_func_name("LOG");
19056 self.write("(");
19057 self.generate_expression(&f.this)?;
19058 self.write(")");
19059 }
19060 Ok(())
19061 }
19062
19063 fn is_log_value_first(&self) -> bool {
19066 use crate::dialects::DialectType;
19067 matches!(
19068 self.config.dialect,
19069 Some(DialectType::BigQuery)
19070 | Some(DialectType::TSQL)
19071 | Some(DialectType::Tableau)
19072 | Some(DialectType::Fabric)
19073 )
19074 }
19075
19076 fn is_log_base_none(&self) -> bool {
19079 use crate::dialects::DialectType;
19080 matches!(
19081 self.config.dialect,
19082 Some(DialectType::Presto)
19083 | Some(DialectType::Trino)
19084 | Some(DialectType::ClickHouse)
19085 | Some(DialectType::Athena)
19086 )
19087 }
19088
19089 fn generate_current_time(&mut self, f: &CurrentTime) -> Result<()> {
19092 self.write_keyword("CURRENT_TIME");
19093 if let Some(precision) = f.precision {
19094 self.write(&format!("({})", precision));
19095 } else if matches!(
19096 self.config.dialect,
19097 Some(crate::dialects::DialectType::MySQL)
19098 | Some(crate::dialects::DialectType::SingleStore)
19099 | Some(crate::dialects::DialectType::TiDB)
19100 ) {
19101 self.write("()");
19102 }
19103 Ok(())
19104 }
19105
19106 fn generate_current_timestamp(&mut self, f: &CurrentTimestamp) -> Result<()> {
19107 use crate::dialects::DialectType;
19108
19109 if f.sysdate {
19111 match self.config.dialect {
19112 Some(DialectType::Oracle) | Some(DialectType::Redshift) => {
19113 self.write_keyword("SYSDATE");
19114 return Ok(());
19115 }
19116 Some(DialectType::Snowflake) => {
19117 self.write_keyword("SYSDATE");
19119 self.write("()");
19120 return Ok(());
19121 }
19122 _ => {
19123 }
19125 }
19126 }
19127
19128 self.write_keyword("CURRENT_TIMESTAMP");
19129 if let Some(precision) = f.precision {
19131 self.write(&format!("({})", precision));
19132 } else if matches!(
19133 self.config.dialect,
19134 Some(crate::dialects::DialectType::MySQL)
19135 | Some(crate::dialects::DialectType::SingleStore)
19136 | Some(crate::dialects::DialectType::TiDB)
19137 | Some(crate::dialects::DialectType::Spark)
19138 | Some(crate::dialects::DialectType::Hive)
19139 | Some(crate::dialects::DialectType::Databricks)
19140 | Some(crate::dialects::DialectType::ClickHouse)
19141 | Some(crate::dialects::DialectType::BigQuery)
19142 | Some(crate::dialects::DialectType::Snowflake)
19143 | Some(crate::dialects::DialectType::Exasol)
19144 ) {
19145 self.write("()");
19146 }
19147 Ok(())
19148 }
19149
19150 fn generate_at_time_zone(&mut self, f: &AtTimeZone) -> Result<()> {
19151 if self.config.dialect == Some(DialectType::Exasol) {
19153 self.write_keyword("CONVERT_TZ");
19154 self.write("(");
19155 self.generate_expression(&f.this)?;
19156 self.write(", 'UTC', ");
19157 self.generate_expression(&f.zone)?;
19158 self.write(")");
19159 return Ok(());
19160 }
19161
19162 self.generate_expression(&f.this)?;
19163 self.write_space();
19164 self.write_keyword("AT TIME ZONE");
19165 self.write_space();
19166 self.generate_expression(&f.zone)?;
19167 Ok(())
19168 }
19169
19170 fn generate_date_add(&mut self, f: &DateAddFunc, name: &str) -> Result<()> {
19171 use crate::dialects::DialectType;
19172
19173 let is_presto_like = matches!(
19176 self.config.dialect,
19177 Some(DialectType::Presto) | Some(DialectType::Trino)
19178 );
19179
19180 if is_presto_like {
19181 self.write_keyword(name);
19182 self.write("(");
19183 self.write("'");
19185 self.write_simple_interval_unit(&f.unit, false);
19186 self.write("'");
19187 self.write(", ");
19188 let needs_cast = !self.returns_integer_type(&f.interval);
19190 if needs_cast {
19191 self.write_keyword("CAST");
19192 self.write("(");
19193 }
19194 self.generate_expression(&f.interval)?;
19195 if needs_cast {
19196 self.write_space();
19197 self.write_keyword("AS");
19198 self.write_space();
19199 self.write_keyword("BIGINT");
19200 self.write(")");
19201 }
19202 self.write(", ");
19203 self.generate_expression(&f.this)?;
19204 self.write(")");
19205 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
19206 self.generate_expression(&f.this)?;
19207 self.write_space();
19208 if name.eq_ignore_ascii_case("DATE_SUB") {
19209 self.write("-");
19210 } else {
19211 self.write("+");
19212 }
19213 self.write_space();
19214 self.write_keyword("INTERVAL");
19215 self.write_space();
19216 self.write("'");
19217 let mut interval_gen = Generator::with_arc_config(self.config.clone());
19218 let interval_sql = interval_gen.generate(&f.interval)?;
19219 self.write(&interval_sql);
19220 self.write(" ");
19221 self.write_simple_interval_unit(&f.unit, false);
19222 self.write("'");
19223 } else {
19224 self.write_keyword(name);
19225 self.write("(");
19226 self.generate_expression(&f.this)?;
19227 self.write(", ");
19228 self.write_keyword("INTERVAL");
19229 self.write_space();
19230 self.generate_expression(&f.interval)?;
19231 self.write_space();
19232 self.write_simple_interval_unit(&f.unit, false); self.write(")");
19234 }
19235 Ok(())
19236 }
19237
19238 fn returns_integer_type(&self, expr: &Expression) -> bool {
19241 use crate::expressions::{DataType, Literal};
19242 match expr {
19243 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
19245 let Literal::Number(n) = lit.as_ref() else {
19246 unreachable!()
19247 };
19248 !n.contains('.')
19249 }
19250
19251 Expression::Floor(f) => self.returns_integer_type(&f.this),
19253
19254 Expression::Round(f) => {
19256 f.decimals.is_none() && self.returns_integer_type(&f.this)
19258 }
19259
19260 Expression::Sign(f) => self.returns_integer_type(&f.this),
19262
19263 Expression::Abs(f) => self.returns_integer_type(&f.this),
19265
19266 Expression::Mul(op) => {
19268 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
19269 }
19270 Expression::Add(op) => {
19271 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
19272 }
19273 Expression::Sub(op) => {
19274 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
19275 }
19276 Expression::Mod(op) => self.returns_integer_type(&op.left),
19277
19278 Expression::Cast(c) => matches!(
19280 &c.to,
19281 DataType::BigInt { .. }
19282 | DataType::Int { .. }
19283 | DataType::SmallInt { .. }
19284 | DataType::TinyInt { .. }
19285 ),
19286
19287 Expression::Neg(op) => self.returns_integer_type(&op.this),
19289
19290 Expression::Paren(p) => self.returns_integer_type(&p.this),
19292
19293 _ => false,
19296 }
19297 }
19298
19299 fn generate_datediff(&mut self, f: &DateDiffFunc) -> Result<()> {
19300 self.write_keyword("DATEDIFF");
19301 self.write("(");
19302 if let Some(unit) = &f.unit {
19303 self.write_simple_interval_unit(unit, false); self.write(", ");
19305 }
19306 self.generate_expression(&f.this)?;
19307 self.write(", ");
19308 self.generate_expression(&f.expression)?;
19309 self.write(")");
19310 Ok(())
19311 }
19312
19313 fn generate_date_trunc(&mut self, f: &DateTruncFunc) -> Result<()> {
19314 if self.config.dialect == Some(DialectType::ClickHouse) {
19315 self.write("dateTrunc");
19316 } else {
19317 self.write_keyword("DATE_TRUNC");
19318 }
19319 self.write("('");
19320 self.write_datetime_field(&f.unit);
19321 self.write("', ");
19322 self.generate_expression(&f.this)?;
19323 self.write(")");
19324 Ok(())
19325 }
19326
19327 fn generate_last_day(&mut self, f: &LastDayFunc) -> Result<()> {
19328 use crate::dialects::DialectType;
19329 use crate::expressions::DateTimeField;
19330
19331 self.write_keyword("LAST_DAY");
19332 self.write("(");
19333 self.generate_expression(&f.this)?;
19334 if let Some(unit) = &f.unit {
19335 self.write(", ");
19336 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
19339 if let DateTimeField::WeekWithModifier(_) = unit {
19340 self.write_keyword("WEEK");
19341 } else {
19342 self.write_datetime_field(unit);
19343 }
19344 } else {
19345 self.write_datetime_field(unit);
19346 }
19347 }
19348 self.write(")");
19349 Ok(())
19350 }
19351
19352 fn generate_extract(&mut self, f: &ExtractFunc) -> Result<()> {
19353 if matches!(
19355 self.config.dialect,
19356 Some(DialectType::TSQL) | Some(DialectType::Fabric)
19357 ) {
19358 self.write_keyword("DATEPART");
19359 self.write("(");
19360 self.write_datetime_field(&f.field);
19361 self.write(", ");
19362 self.generate_expression(&f.this)?;
19363 self.write(")");
19364 return Ok(());
19365 }
19366 self.write_keyword("EXTRACT");
19367 self.write("(");
19368 if matches!(
19370 self.config.dialect,
19371 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
19372 ) {
19373 self.write_datetime_field_lower(&f.field);
19374 } else {
19375 self.write_datetime_field(&f.field);
19376 }
19377 self.write_space();
19378 self.write_keyword("FROM");
19379 self.write_space();
19380 self.generate_expression(&f.this)?;
19381 self.write(")");
19382 Ok(())
19383 }
19384
19385 fn generate_to_date(&mut self, f: &ToDateFunc) -> Result<()> {
19386 self.write_keyword("TO_DATE");
19387 self.write("(");
19388 self.generate_expression(&f.this)?;
19389 if let Some(format) = &f.format {
19390 self.write(", ");
19391 self.generate_expression(format)?;
19392 }
19393 self.write(")");
19394 Ok(())
19395 }
19396
19397 fn generate_to_timestamp(&mut self, f: &ToTimestampFunc) -> Result<()> {
19398 self.write_keyword("TO_TIMESTAMP");
19399 self.write("(");
19400 self.generate_expression(&f.this)?;
19401 if let Some(format) = &f.format {
19402 self.write(", ");
19403 self.generate_expression(format)?;
19404 }
19405 self.write(")");
19406 Ok(())
19407 }
19408
19409 fn generate_if_func(&mut self, f: &IfFunc) -> Result<()> {
19412 use crate::dialects::DialectType;
19413
19414 if self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic) {
19416 self.write_keyword("CASE WHEN");
19417 self.write_space();
19418 self.generate_expression(&f.condition)?;
19419 self.write_space();
19420 self.write_keyword("THEN");
19421 self.write_space();
19422 self.generate_expression(&f.true_value)?;
19423 if let Some(false_val) = &f.false_value {
19424 self.write_space();
19425 self.write_keyword("ELSE");
19426 self.write_space();
19427 self.generate_expression(false_val)?;
19428 }
19429 self.write_space();
19430 self.write_keyword("END");
19431 return Ok(());
19432 }
19433
19434 if self.config.dialect == Some(DialectType::Exasol) {
19436 self.write_keyword("IF");
19437 self.write_space();
19438 self.generate_expression(&f.condition)?;
19439 self.write_space();
19440 self.write_keyword("THEN");
19441 self.write_space();
19442 self.generate_expression(&f.true_value)?;
19443 if let Some(false_val) = &f.false_value {
19444 self.write_space();
19445 self.write_keyword("ELSE");
19446 self.write_space();
19447 self.generate_expression(false_val)?;
19448 }
19449 self.write_space();
19450 self.write_keyword("ENDIF");
19451 return Ok(());
19452 }
19453
19454 let func_name = match self.config.dialect {
19456 Some(DialectType::Snowflake) => "IFF",
19457 Some(DialectType::SQLite) | Some(DialectType::TSQL) => "IIF",
19458 Some(DialectType::Drill) => "`IF`",
19459 _ => "IF",
19460 };
19461 self.write(func_name);
19462 self.write("(");
19463 self.generate_expression(&f.condition)?;
19464 self.write(", ");
19465 self.generate_expression(&f.true_value)?;
19466 if let Some(false_val) = &f.false_value {
19467 self.write(", ");
19468 self.generate_expression(false_val)?;
19469 }
19470 self.write(")");
19471 Ok(())
19472 }
19473
19474 fn generate_nvl2(&mut self, f: &Nvl2Func) -> Result<()> {
19475 self.write_keyword("NVL2");
19476 self.write("(");
19477 self.generate_expression(&f.this)?;
19478 self.write(", ");
19479 self.generate_expression(&f.true_value)?;
19480 self.write(", ");
19481 self.generate_expression(&f.false_value)?;
19482 self.write(")");
19483 Ok(())
19484 }
19485
19486 fn generate_count(&mut self, f: &CountFunc) -> Result<()> {
19489 let count_name = match self.config.normalize_functions {
19491 NormalizeFunctions::Upper => "COUNT".to_string(),
19492 NormalizeFunctions::Lower => "count".to_string(),
19493 NormalizeFunctions::None => f
19494 .original_name
19495 .clone()
19496 .unwrap_or_else(|| "COUNT".to_string()),
19497 };
19498 self.write(&count_name);
19499 self.write("(");
19500 if f.distinct {
19501 self.write_keyword("DISTINCT");
19502 self.write_space();
19503 }
19504 if f.star {
19505 self.write("*");
19506 } else if let Some(ref expr) = f.this {
19507 if let Expression::Tuple(tuple) = expr {
19509 let needs_transform =
19513 f.distinct && tuple.expressions.len() > 1 && !self.config.multi_arg_distinct;
19514
19515 if needs_transform {
19516 self.write_keyword("CASE");
19518 for e in &tuple.expressions {
19519 self.write_space();
19520 self.write_keyword("WHEN");
19521 self.write_space();
19522 self.generate_expression(e)?;
19523 self.write_space();
19524 self.write_keyword("IS NULL THEN NULL");
19525 }
19526 self.write_space();
19527 self.write_keyword("ELSE");
19528 self.write(" (");
19529 for (i, e) in tuple.expressions.iter().enumerate() {
19530 if i > 0 {
19531 self.write(", ");
19532 }
19533 self.generate_expression(e)?;
19534 }
19535 self.write(")");
19536 self.write_space();
19537 self.write_keyword("END");
19538 } else {
19539 for (i, e) in tuple.expressions.iter().enumerate() {
19540 if i > 0 {
19541 self.write(", ");
19542 }
19543 self.generate_expression(e)?;
19544 }
19545 }
19546 } else {
19547 self.generate_expression(expr)?;
19548 }
19549 }
19550 if let Some(ignore) = f.ignore_nulls {
19552 self.write_space();
19553 if ignore {
19554 self.write_keyword("IGNORE NULLS");
19555 } else {
19556 self.write_keyword("RESPECT NULLS");
19557 }
19558 }
19559 self.write(")");
19560 if let Some(ref filter) = f.filter {
19561 self.write_space();
19562 self.write_keyword("FILTER");
19563 self.write("(");
19564 self.write_keyword("WHERE");
19565 self.write_space();
19566 self.generate_expression(filter)?;
19567 self.write(")");
19568 }
19569 Ok(())
19570 }
19571
19572 fn generate_agg_func(&mut self, name: &str, f: &AggFunc) -> Result<()> {
19573 let func_name: Cow<'_, str> = match self.config.normalize_functions {
19575 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
19576 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
19577 NormalizeFunctions::None => {
19578 if let Some(ref original) = f.name {
19581 Cow::Owned(original.clone())
19582 } else {
19583 Cow::Owned(name.to_ascii_lowercase())
19584 }
19585 }
19586 };
19587 self.write(func_name.as_ref());
19588 self.write("(");
19589 if f.distinct {
19590 self.write_keyword("DISTINCT");
19591 self.write_space();
19592 }
19593 if !matches!(f.this, Expression::Null(_)) {
19595 self.generate_expression(&f.this)?;
19596 }
19597 if self.config.ignore_nulls_in_func
19600 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
19601 {
19602 match f.ignore_nulls {
19603 Some(true) => {
19604 self.write_space();
19605 self.write_keyword("IGNORE NULLS");
19606 }
19607 Some(false) => {
19608 self.write_space();
19609 self.write_keyword("RESPECT NULLS");
19610 }
19611 None => {}
19612 }
19613 }
19614 if let Some((ref expr, is_max)) = f.having_max {
19617 self.write_space();
19618 self.write_keyword("HAVING");
19619 self.write_space();
19620 if is_max {
19621 self.write_keyword("MAX");
19622 } else {
19623 self.write_keyword("MIN");
19624 }
19625 self.write_space();
19626 self.generate_expression(expr)?;
19627 }
19628 if !f.order_by.is_empty() {
19630 self.write_space();
19631 self.write_keyword("ORDER BY");
19632 self.write_space();
19633 for (i, ord) in f.order_by.iter().enumerate() {
19634 if i > 0 {
19635 self.write(", ");
19636 }
19637 self.generate_ordered(ord)?;
19638 }
19639 }
19640 if let Some(ref limit) = f.limit {
19642 self.write_space();
19643 self.write_keyword("LIMIT");
19644 self.write_space();
19645 if let Expression::Tuple(t) = limit.as_ref() {
19647 if t.expressions.len() == 2 {
19648 self.generate_expression(&t.expressions[0])?;
19649 self.write(", ");
19650 self.generate_expression(&t.expressions[1])?;
19651 } else {
19652 self.generate_expression(limit)?;
19653 }
19654 } else {
19655 self.generate_expression(limit)?;
19656 }
19657 }
19658 self.write(")");
19659 if !self.config.ignore_nulls_in_func
19662 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
19663 {
19664 match f.ignore_nulls {
19665 Some(true) => {
19666 self.write_space();
19667 self.write_keyword("IGNORE NULLS");
19668 }
19669 Some(false) => {
19670 self.write_space();
19671 self.write_keyword("RESPECT NULLS");
19672 }
19673 None => {}
19674 }
19675 }
19676 if let Some(ref filter) = f.filter {
19677 self.write_space();
19678 self.write_keyword("FILTER");
19679 self.write("(");
19680 self.write_keyword("WHERE");
19681 self.write_space();
19682 self.generate_expression(filter)?;
19683 self.write(")");
19684 }
19685 Ok(())
19686 }
19687
19688 fn generate_agg_func_with_ignore_nulls_bool(&mut self, name: &str, f: &AggFunc) -> Result<()> {
19691 if matches!(self.config.dialect, Some(DialectType::Hive)) && f.ignore_nulls == Some(true) {
19693 let func_name: Cow<'_, str> = match self.config.normalize_functions {
19695 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
19696 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
19697 NormalizeFunctions::None => {
19698 if let Some(ref original) = f.name {
19699 Cow::Owned(original.clone())
19700 } else {
19701 Cow::Owned(name.to_ascii_lowercase())
19702 }
19703 }
19704 };
19705 self.write(func_name.as_ref());
19706 self.write("(");
19707 if f.distinct {
19708 self.write_keyword("DISTINCT");
19709 self.write_space();
19710 }
19711 if !matches!(f.this, Expression::Null(_)) {
19712 self.generate_expression(&f.this)?;
19713 }
19714 self.write(", ");
19715 self.write_keyword("TRUE");
19716 self.write(")");
19717 return Ok(());
19718 }
19719 self.generate_agg_func(name, f)
19720 }
19721
19722 fn generate_group_concat(&mut self, f: &GroupConcatFunc) -> Result<()> {
19723 self.write_keyword("GROUP_CONCAT");
19724 self.write("(");
19725 if f.distinct {
19726 self.write_keyword("DISTINCT");
19727 self.write_space();
19728 }
19729 self.generate_expression(&f.this)?;
19730 if let Some(ref order_by) = f.order_by {
19731 self.write_space();
19732 self.write_keyword("ORDER BY");
19733 self.write_space();
19734 for (i, ord) in order_by.iter().enumerate() {
19735 if i > 0 {
19736 self.write(", ");
19737 }
19738 self.generate_ordered(ord)?;
19739 }
19740 }
19741 if let Some(ref sep) = f.separator {
19742 if matches!(
19745 self.config.dialect,
19746 Some(crate::dialects::DialectType::SQLite)
19747 ) {
19748 self.write(", ");
19749 self.generate_expression(sep)?;
19750 } else {
19751 self.write_space();
19752 self.write_keyword("SEPARATOR");
19753 self.write_space();
19754 self.generate_expression(sep)?;
19755 }
19756 }
19757 if let Some(ref limit) = f.limit {
19758 self.write_space();
19759 self.write_keyword("LIMIT");
19760 self.write_space();
19761 self.generate_expression(limit)?;
19762 }
19763 self.write(")");
19764 if let Some(ref filter) = f.filter {
19765 self.write_space();
19766 self.write_keyword("FILTER");
19767 self.write("(");
19768 self.write_keyword("WHERE");
19769 self.write_space();
19770 self.generate_expression(filter)?;
19771 self.write(")");
19772 }
19773 Ok(())
19774 }
19775
19776 fn generate_string_agg(&mut self, f: &StringAggFunc) -> Result<()> {
19777 let is_tsql = matches!(
19778 self.config.dialect,
19779 Some(crate::dialects::DialectType::TSQL)
19780 );
19781 self.write_keyword("STRING_AGG");
19782 self.write("(");
19783 if f.distinct {
19784 self.write_keyword("DISTINCT");
19785 self.write_space();
19786 }
19787 self.generate_expression(&f.this)?;
19788 if let Some(ref separator) = f.separator {
19789 self.write(", ");
19790 self.generate_expression(separator)?;
19791 }
19792 if !is_tsql {
19794 if let Some(ref order_by) = f.order_by {
19795 self.write_space();
19796 self.write_keyword("ORDER BY");
19797 self.write_space();
19798 for (i, ord) in order_by.iter().enumerate() {
19799 if i > 0 {
19800 self.write(", ");
19801 }
19802 self.generate_ordered(ord)?;
19803 }
19804 }
19805 }
19806 if let Some(ref limit) = f.limit {
19807 self.write_space();
19808 self.write_keyword("LIMIT");
19809 self.write_space();
19810 self.generate_expression(limit)?;
19811 }
19812 self.write(")");
19813 if is_tsql {
19815 if let Some(ref order_by) = f.order_by {
19816 self.write_space();
19817 self.write_keyword("WITHIN GROUP");
19818 self.write(" (");
19819 self.write_keyword("ORDER BY");
19820 self.write_space();
19821 for (i, ord) in order_by.iter().enumerate() {
19822 if i > 0 {
19823 self.write(", ");
19824 }
19825 self.generate_ordered(ord)?;
19826 }
19827 self.write(")");
19828 }
19829 }
19830 if let Some(ref filter) = f.filter {
19831 self.write_space();
19832 self.write_keyword("FILTER");
19833 self.write("(");
19834 self.write_keyword("WHERE");
19835 self.write_space();
19836 self.generate_expression(filter)?;
19837 self.write(")");
19838 }
19839 Ok(())
19840 }
19841
19842 fn generate_listagg(&mut self, f: &ListAggFunc) -> Result<()> {
19843 use crate::dialects::DialectType;
19844 self.write_keyword("LISTAGG");
19845 self.write("(");
19846 if f.distinct {
19847 self.write_keyword("DISTINCT");
19848 self.write_space();
19849 }
19850 self.generate_expression(&f.this)?;
19851 if let Some(ref sep) = f.separator {
19852 self.write(", ");
19853 self.generate_expression(sep)?;
19854 } else if matches!(
19855 self.config.dialect,
19856 Some(DialectType::Trino) | Some(DialectType::Presto)
19857 ) {
19858 self.write(", ','");
19860 }
19861 if let Some(ref overflow) = f.on_overflow {
19862 self.write_space();
19863 self.write_keyword("ON OVERFLOW");
19864 self.write_space();
19865 match overflow {
19866 ListAggOverflow::Error => self.write_keyword("ERROR"),
19867 ListAggOverflow::Truncate { filler, with_count } => {
19868 self.write_keyword("TRUNCATE");
19869 if let Some(ref fill) = filler {
19870 self.write_space();
19871 self.generate_expression(fill)?;
19872 }
19873 if *with_count {
19874 self.write_space();
19875 self.write_keyword("WITH COUNT");
19876 } else {
19877 self.write_space();
19878 self.write_keyword("WITHOUT COUNT");
19879 }
19880 }
19881 }
19882 }
19883 self.write(")");
19884 if let Some(ref order_by) = f.order_by {
19885 self.write_space();
19886 self.write_keyword("WITHIN GROUP");
19887 self.write(" (");
19888 self.write_keyword("ORDER BY");
19889 self.write_space();
19890 for (i, ord) in order_by.iter().enumerate() {
19891 if i > 0 {
19892 self.write(", ");
19893 }
19894 self.generate_ordered(ord)?;
19895 }
19896 self.write(")");
19897 }
19898 if let Some(ref filter) = f.filter {
19899 self.write_space();
19900 self.write_keyword("FILTER");
19901 self.write("(");
19902 self.write_keyword("WHERE");
19903 self.write_space();
19904 self.generate_expression(filter)?;
19905 self.write(")");
19906 }
19907 Ok(())
19908 }
19909
19910 fn generate_sum_if(&mut self, f: &SumIfFunc) -> Result<()> {
19911 self.write_keyword("SUM_IF");
19912 self.write("(");
19913 self.generate_expression(&f.this)?;
19914 self.write(", ");
19915 self.generate_expression(&f.condition)?;
19916 self.write(")");
19917 if let Some(ref filter) = f.filter {
19918 self.write_space();
19919 self.write_keyword("FILTER");
19920 self.write("(");
19921 self.write_keyword("WHERE");
19922 self.write_space();
19923 self.generate_expression(filter)?;
19924 self.write(")");
19925 }
19926 Ok(())
19927 }
19928
19929 fn generate_approx_percentile(&mut self, f: &ApproxPercentileFunc) -> Result<()> {
19930 self.write_keyword("APPROX_PERCENTILE");
19931 self.write("(");
19932 self.generate_expression(&f.this)?;
19933 self.write(", ");
19934 self.generate_expression(&f.percentile)?;
19935 if let Some(ref acc) = f.accuracy {
19936 self.write(", ");
19937 self.generate_expression(acc)?;
19938 }
19939 self.write(")");
19940 if let Some(ref filter) = f.filter {
19941 self.write_space();
19942 self.write_keyword("FILTER");
19943 self.write("(");
19944 self.write_keyword("WHERE");
19945 self.write_space();
19946 self.generate_expression(filter)?;
19947 self.write(")");
19948 }
19949 Ok(())
19950 }
19951
19952 fn generate_percentile(&mut self, name: &str, f: &PercentileFunc) -> Result<()> {
19953 self.write_keyword(name);
19954 self.write("(");
19955 self.generate_expression(&f.percentile)?;
19956 self.write(")");
19957 if let Some(ref order_by) = f.order_by {
19958 self.write_space();
19959 self.write_keyword("WITHIN GROUP");
19960 self.write(" (");
19961 self.write_keyword("ORDER BY");
19962 self.write_space();
19963 self.generate_expression(&f.this)?;
19964 for ord in order_by.iter() {
19965 if ord.desc {
19966 self.write_space();
19967 self.write_keyword("DESC");
19968 }
19969 }
19970 self.write(")");
19971 }
19972 if let Some(ref filter) = f.filter {
19973 self.write_space();
19974 self.write_keyword("FILTER");
19975 self.write("(");
19976 self.write_keyword("WHERE");
19977 self.write_space();
19978 self.generate_expression(filter)?;
19979 self.write(")");
19980 }
19981 Ok(())
19982 }
19983
19984 fn generate_ntile(&mut self, f: &NTileFunc) -> Result<()> {
19987 self.write_keyword("NTILE");
19988 self.write("(");
19989 if let Some(num_buckets) = &f.num_buckets {
19990 self.generate_expression(num_buckets)?;
19991 }
19992 if let Some(order_by) = &f.order_by {
19993 self.write_keyword(" ORDER BY ");
19994 for (i, ob) in order_by.iter().enumerate() {
19995 if i > 0 {
19996 self.write(", ");
19997 }
19998 self.generate_ordered(ob)?;
19999 }
20000 }
20001 self.write(")");
20002 Ok(())
20003 }
20004
20005 fn generate_lead_lag(&mut self, name: &str, f: &LeadLagFunc) -> Result<()> {
20006 self.write_keyword(name);
20007 self.write("(");
20008 self.generate_expression(&f.this)?;
20009 if let Some(ref offset) = f.offset {
20010 self.write(", ");
20011 self.generate_expression(offset)?;
20012 if let Some(ref default) = f.default {
20013 self.write(", ");
20014 self.generate_expression(default)?;
20015 }
20016 }
20017 if self.config.ignore_nulls_in_func {
20019 match f.ignore_nulls {
20020 Some(true) => {
20021 self.write_space();
20022 self.write_keyword("IGNORE NULLS");
20023 }
20024 Some(false) => {
20025 self.write_space();
20026 self.write_keyword("RESPECT NULLS");
20027 }
20028 None => {}
20029 }
20030 }
20031 self.write(")");
20032 if !self.config.ignore_nulls_in_func {
20034 match f.ignore_nulls {
20035 Some(true) => {
20036 self.write_space();
20037 self.write_keyword("IGNORE NULLS");
20038 }
20039 Some(false) => {
20040 self.write_space();
20041 self.write_keyword("RESPECT NULLS");
20042 }
20043 None => {}
20044 }
20045 }
20046 Ok(())
20047 }
20048
20049 fn generate_value_func(&mut self, name: &str, f: &ValueFunc) -> Result<()> {
20050 self.write_keyword(name);
20051 self.write("(");
20052 self.generate_expression(&f.this)?;
20053 if !f.order_by.is_empty() {
20055 self.write_space();
20056 self.write_keyword("ORDER BY");
20057 self.write_space();
20058 for (i, ordered) in f.order_by.iter().enumerate() {
20059 if i > 0 {
20060 self.write(", ");
20061 }
20062 self.generate_ordered(ordered)?;
20063 }
20064 }
20065 if self.config.ignore_nulls_in_func {
20067 match f.ignore_nulls {
20068 Some(true) => {
20069 self.write_space();
20070 self.write_keyword("IGNORE NULLS");
20071 }
20072 Some(false) => {
20073 self.write_space();
20074 self.write_keyword("RESPECT NULLS");
20075 }
20076 None => {}
20077 }
20078 }
20079 self.write(")");
20080 if !self.config.ignore_nulls_in_func {
20082 match f.ignore_nulls {
20083 Some(true) => {
20084 self.write_space();
20085 self.write_keyword("IGNORE NULLS");
20086 }
20087 Some(false) => {
20088 self.write_space();
20089 self.write_keyword("RESPECT NULLS");
20090 }
20091 None => {}
20092 }
20093 }
20094 Ok(())
20095 }
20096
20097 fn generate_value_func_with_ignore_nulls_bool(
20100 &mut self,
20101 name: &str,
20102 f: &ValueFunc,
20103 ) -> Result<()> {
20104 if matches!(self.config.dialect, Some(DialectType::Hive)) && f.ignore_nulls == Some(true) {
20105 self.write_keyword(name);
20106 self.write("(");
20107 self.generate_expression(&f.this)?;
20108 self.write(", ");
20109 self.write_keyword("TRUE");
20110 self.write(")");
20111 return Ok(());
20112 }
20113 self.generate_value_func(name, f)
20114 }
20115
20116 fn generate_nth_value(&mut self, f: &NthValueFunc) -> Result<()> {
20117 self.write_keyword("NTH_VALUE");
20118 self.write("(");
20119 self.generate_expression(&f.this)?;
20120 self.write(", ");
20121 self.generate_expression(&f.offset)?;
20122 if self.config.ignore_nulls_in_func {
20124 match f.ignore_nulls {
20125 Some(true) => {
20126 self.write_space();
20127 self.write_keyword("IGNORE NULLS");
20128 }
20129 Some(false) => {
20130 self.write_space();
20131 self.write_keyword("RESPECT NULLS");
20132 }
20133 None => {}
20134 }
20135 }
20136 self.write(")");
20137 if matches!(
20139 self.config.dialect,
20140 Some(crate::dialects::DialectType::Snowflake)
20141 ) {
20142 match f.from_first {
20143 Some(true) => {
20144 self.write_space();
20145 self.write_keyword("FROM FIRST");
20146 }
20147 Some(false) => {
20148 self.write_space();
20149 self.write_keyword("FROM LAST");
20150 }
20151 None => {}
20152 }
20153 }
20154 if !self.config.ignore_nulls_in_func {
20156 match f.ignore_nulls {
20157 Some(true) => {
20158 self.write_space();
20159 self.write_keyword("IGNORE NULLS");
20160 }
20161 Some(false) => {
20162 self.write_space();
20163 self.write_keyword("RESPECT NULLS");
20164 }
20165 None => {}
20166 }
20167 }
20168 Ok(())
20169 }
20170
20171 fn generate_position(&mut self, f: &PositionFunc) -> Result<()> {
20174 if matches!(
20177 self.config.dialect,
20178 Some(crate::dialects::DialectType::ClickHouse)
20179 ) {
20180 self.write_keyword("POSITION");
20181 self.write("(");
20182 self.generate_expression(&f.string)?;
20183 self.write(", ");
20184 self.generate_expression(&f.substring)?;
20185 if let Some(ref start) = f.start {
20186 self.write(", ");
20187 self.generate_expression(start)?;
20188 }
20189 self.write(")");
20190 return Ok(());
20191 }
20192
20193 self.write_keyword("POSITION");
20194 self.write("(");
20195 self.generate_expression(&f.substring)?;
20196 self.write_space();
20197 self.write_keyword("IN");
20198 self.write_space();
20199 self.generate_expression(&f.string)?;
20200 if let Some(ref start) = f.start {
20201 self.write(", ");
20202 self.generate_expression(start)?;
20203 }
20204 self.write(")");
20205 Ok(())
20206 }
20207
20208 fn generate_rand(&mut self, f: &Rand) -> Result<()> {
20211 if f.lower.is_some() || f.upper.is_some() {
20213 self.write_keyword("RANDOM");
20214 self.write("(");
20215 if let Some(ref lower) = f.lower {
20216 self.generate_expression(lower)?;
20217 }
20218 if let Some(ref upper) = f.upper {
20219 self.write(", ");
20220 self.generate_expression(upper)?;
20221 }
20222 self.write(")");
20223 return Ok(());
20224 }
20225 let func_name = match self.config.dialect {
20227 Some(crate::dialects::DialectType::Snowflake)
20228 | Some(crate::dialects::DialectType::DuckDB) => "RANDOM",
20229 _ => "RAND",
20230 };
20231 self.write_keyword(func_name);
20232 self.write("(");
20233 if !matches!(
20235 self.config.dialect,
20236 Some(crate::dialects::DialectType::DuckDB)
20237 ) {
20238 if let Some(ref seed) = f.seed {
20239 self.generate_expression(seed)?;
20240 }
20241 }
20242 self.write(")");
20243 Ok(())
20244 }
20245
20246 fn generate_truncate_func(&mut self, f: &TruncateFunc) -> Result<()> {
20247 self.write_keyword("TRUNCATE");
20248 self.write("(");
20249 self.generate_expression(&f.this)?;
20250 if let Some(ref decimals) = f.decimals {
20251 self.write(", ");
20252 self.generate_expression(decimals)?;
20253 }
20254 self.write(")");
20255 Ok(())
20256 }
20257
20258 fn generate_decode(&mut self, f: &DecodeFunc) -> Result<()> {
20261 self.write_keyword("DECODE");
20262 self.write("(");
20263 self.generate_expression(&f.this)?;
20264 for (search, result) in &f.search_results {
20265 self.write(", ");
20266 self.generate_expression(search)?;
20267 self.write(", ");
20268 self.generate_expression(result)?;
20269 }
20270 if let Some(ref default) = f.default {
20271 self.write(", ");
20272 self.generate_expression(default)?;
20273 }
20274 self.write(")");
20275 Ok(())
20276 }
20277
20278 fn generate_date_format(&mut self, name: &str, f: &DateFormatFunc) -> Result<()> {
20281 self.write_keyword(name);
20282 self.write("(");
20283 self.generate_expression(&f.this)?;
20284 self.write(", ");
20285 self.generate_expression(&f.format)?;
20286 self.write(")");
20287 Ok(())
20288 }
20289
20290 fn generate_from_unixtime(&mut self, f: &FromUnixtimeFunc) -> Result<()> {
20291 self.write_keyword("FROM_UNIXTIME");
20292 self.write("(");
20293 self.generate_expression(&f.this)?;
20294 if let Some(ref format) = f.format {
20295 self.write(", ");
20296 self.generate_expression(format)?;
20297 }
20298 self.write(")");
20299 Ok(())
20300 }
20301
20302 fn generate_unix_timestamp(&mut self, f: &UnixTimestampFunc) -> Result<()> {
20303 self.write_keyword("UNIX_TIMESTAMP");
20304 self.write("(");
20305 if let Some(ref expr) = f.this {
20306 self.generate_expression(expr)?;
20307 if let Some(ref format) = f.format {
20308 self.write(", ");
20309 self.generate_expression(format)?;
20310 }
20311 } else if matches!(
20312 self.config.dialect,
20313 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
20314 ) {
20315 self.write_keyword("CURRENT_TIMESTAMP");
20317 self.write("()");
20318 }
20319 self.write(")");
20320 Ok(())
20321 }
20322
20323 fn generate_make_date(&mut self, f: &MakeDateFunc) -> Result<()> {
20324 self.write_keyword("MAKE_DATE");
20325 self.write("(");
20326 self.generate_expression(&f.year)?;
20327 self.write(", ");
20328 self.generate_expression(&f.month)?;
20329 self.write(", ");
20330 self.generate_expression(&f.day)?;
20331 self.write(")");
20332 Ok(())
20333 }
20334
20335 fn generate_make_timestamp(&mut self, f: &MakeTimestampFunc) -> Result<()> {
20336 self.write_keyword("MAKE_TIMESTAMP");
20337 self.write("(");
20338 self.generate_expression(&f.year)?;
20339 self.write(", ");
20340 self.generate_expression(&f.month)?;
20341 self.write(", ");
20342 self.generate_expression(&f.day)?;
20343 self.write(", ");
20344 self.generate_expression(&f.hour)?;
20345 self.write(", ");
20346 self.generate_expression(&f.minute)?;
20347 self.write(", ");
20348 self.generate_expression(&f.second)?;
20349 if let Some(ref tz) = f.timezone {
20350 self.write(", ");
20351 self.generate_expression(tz)?;
20352 }
20353 self.write(")");
20354 Ok(())
20355 }
20356
20357 fn extract_struct_field_names(expr: &Expression) -> Option<Vec<String>> {
20359 match expr {
20360 Expression::Struct(s) => {
20361 if s.fields.iter().all(|(name, _)| name.is_some()) {
20362 Some(
20363 s.fields
20364 .iter()
20365 .map(|(name, _)| name.as_deref().unwrap_or("").to_string())
20366 .collect(),
20367 )
20368 } else {
20369 None
20370 }
20371 }
20372 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
20373 if f.args.iter().all(|a| matches!(a, Expression::Alias(_))) {
20375 Some(
20376 f.args
20377 .iter()
20378 .filter_map(|a| {
20379 if let Expression::Alias(alias) = a {
20380 Some(alias.alias.name.clone())
20381 } else {
20382 None
20383 }
20384 })
20385 .collect(),
20386 )
20387 } else {
20388 None
20389 }
20390 }
20391 _ => None,
20392 }
20393 }
20394
20395 fn struct_has_unnamed_fields(expr: &Expression) -> bool {
20397 match expr {
20398 Expression::Struct(s) => s.fields.iter().any(|(name, _)| name.is_none()),
20399 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
20400 f.args.iter().any(|a| !matches!(a, Expression::Alias(_)))
20401 }
20402 _ => false,
20403 }
20404 }
20405
20406 fn struct_field_count(expr: &Expression) -> usize {
20408 match expr {
20409 Expression::Struct(s) => s.fields.len(),
20410 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => f.args.len(),
20411 _ => 0,
20412 }
20413 }
20414
20415 fn apply_struct_field_names(expr: &Expression, field_names: &[String]) -> Expression {
20417 match expr {
20418 Expression::Struct(s) => {
20419 let mut new_fields = Vec::with_capacity(s.fields.len());
20420 for (i, (name, value)) in s.fields.iter().enumerate() {
20421 if name.is_none() && i < field_names.len() {
20422 new_fields.push((Some(field_names[i].clone()), value.clone()));
20423 } else {
20424 new_fields.push((name.clone(), value.clone()));
20425 }
20426 }
20427 Expression::Struct(Box::new(crate::expressions::Struct { fields: new_fields }))
20428 }
20429 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
20430 let mut new_args = Vec::with_capacity(f.args.len());
20431 for (i, arg) in f.args.iter().enumerate() {
20432 if !matches!(arg, Expression::Alias(_)) && i < field_names.len() {
20433 new_args.push(Expression::Alias(Box::new(crate::expressions::Alias {
20435 this: arg.clone(),
20436 alias: crate::expressions::Identifier::new(field_names[i].clone()),
20437 column_aliases: Vec::new(),
20438 pre_alias_comments: Vec::new(),
20439 trailing_comments: Vec::new(),
20440 inferred_type: None,
20441 })));
20442 } else {
20443 new_args.push(arg.clone());
20444 }
20445 }
20446 Expression::Function(Box::new(crate::expressions::Function {
20447 name: f.name.clone(),
20448 args: new_args,
20449 distinct: f.distinct,
20450 trailing_comments: f.trailing_comments.clone(),
20451 use_bracket_syntax: f.use_bracket_syntax,
20452 no_parens: f.no_parens,
20453 quoted: f.quoted,
20454 span: None,
20455 inferred_type: None,
20456 }))
20457 }
20458 _ => expr.clone(),
20459 }
20460 }
20461
20462 fn inherit_struct_field_names(expressions: &[Expression]) -> Vec<Expression> {
20466 let first = match expressions.first() {
20467 Some(e) => e,
20468 None => return expressions.to_vec(),
20469 };
20470
20471 let field_names = match Self::extract_struct_field_names(first) {
20472 Some(names) if !names.is_empty() => names,
20473 _ => return expressions.to_vec(),
20474 };
20475
20476 let mut result = Vec::with_capacity(expressions.len());
20477 for (idx, expr) in expressions.iter().enumerate() {
20478 if idx == 0 {
20479 result.push(expr.clone());
20480 continue;
20481 }
20482 if Self::struct_field_count(expr) == field_names.len()
20484 && Self::struct_has_unnamed_fields(expr)
20485 {
20486 result.push(Self::apply_struct_field_names(expr, &field_names));
20487 } else {
20488 result.push(expr.clone());
20489 }
20490 }
20491 result
20492 }
20493
20494 fn generate_array_constructor(&mut self, f: &ArrayConstructor) -> Result<()> {
20497 let needs_inheritance = matches!(
20500 self.config.dialect,
20501 Some(DialectType::DuckDB)
20502 | Some(DialectType::Spark)
20503 | Some(DialectType::Databricks)
20504 | Some(DialectType::Hive)
20505 | Some(DialectType::Snowflake)
20506 | Some(DialectType::Presto)
20507 | Some(DialectType::Trino)
20508 );
20509 let propagated: Vec<Expression>;
20510 let expressions = if needs_inheritance && f.expressions.len() > 1 {
20511 propagated = Self::inherit_struct_field_names(&f.expressions);
20512 &propagated
20513 } else {
20514 &f.expressions
20515 };
20516
20517 let should_split = if self.config.pretty && !expressions.is_empty() {
20519 let mut expr_strings: Vec<String> = Vec::with_capacity(expressions.len());
20520 for expr in expressions {
20521 let mut temp_gen = Generator::with_arc_config(self.config.clone());
20522 Arc::make_mut(&mut temp_gen.config).pretty = false;
20523 temp_gen.generate_expression(expr)?;
20524 expr_strings.push(temp_gen.output);
20525 }
20526 self.too_wide(&expr_strings)
20527 } else {
20528 false
20529 };
20530
20531 if f.bracket_notation {
20532 let (open, close) = match self.config.dialect {
20536 None
20537 | Some(DialectType::Generic)
20538 | Some(DialectType::Spark)
20539 | Some(DialectType::Databricks)
20540 | Some(DialectType::Hive) => {
20541 self.write_keyword("ARRAY");
20542 ("(", ")")
20543 }
20544 Some(DialectType::Presto)
20545 | Some(DialectType::Trino)
20546 | Some(DialectType::PostgreSQL)
20547 | Some(DialectType::Redshift)
20548 | Some(DialectType::Materialize)
20549 | Some(DialectType::RisingWave)
20550 | Some(DialectType::CockroachDB) => {
20551 self.write_keyword("ARRAY");
20552 ("[", "]")
20553 }
20554 _ => ("[", "]"),
20555 };
20556 self.write(open);
20557 if should_split {
20558 self.write_newline();
20559 self.indent_level += 1;
20560 for (i, expr) in expressions.iter().enumerate() {
20561 self.write_indent();
20562 self.generate_expression(expr)?;
20563 if i + 1 < expressions.len() {
20564 self.write(",");
20565 }
20566 self.write_newline();
20567 }
20568 self.indent_level -= 1;
20569 self.write_indent();
20570 } else {
20571 for (i, expr) in expressions.iter().enumerate() {
20572 if i > 0 {
20573 self.write(", ");
20574 }
20575 self.generate_expression(expr)?;
20576 }
20577 }
20578 self.write(close);
20579 } else {
20580 if f.use_list_keyword {
20582 self.write_keyword("LIST");
20583 } else {
20584 self.write_keyword("ARRAY");
20585 }
20586 let has_subquery = expressions
20589 .iter()
20590 .any(|e| matches!(e, Expression::Select(_)));
20591 let (open, close) = if matches!(
20592 self.config.dialect,
20593 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive)
20594 ) || (matches!(self.config.dialect, Some(DialectType::BigQuery))
20595 && has_subquery)
20596 {
20597 ("(", ")")
20598 } else {
20599 ("[", "]")
20600 };
20601 self.write(open);
20602 if should_split {
20603 self.write_newline();
20604 self.indent_level += 1;
20605 for (i, expr) in expressions.iter().enumerate() {
20606 self.write_indent();
20607 self.generate_expression(expr)?;
20608 if i + 1 < expressions.len() {
20609 self.write(",");
20610 }
20611 self.write_newline();
20612 }
20613 self.indent_level -= 1;
20614 self.write_indent();
20615 } else {
20616 for (i, expr) in expressions.iter().enumerate() {
20617 if i > 0 {
20618 self.write(", ");
20619 }
20620 self.generate_expression(expr)?;
20621 }
20622 }
20623 self.write(close);
20624 }
20625 Ok(())
20626 }
20627
20628 fn generate_array_sort(&mut self, f: &ArraySortFunc) -> Result<()> {
20629 self.write_keyword("ARRAY_SORT");
20630 self.write("(");
20631 self.generate_expression(&f.this)?;
20632 if let Some(ref comp) = f.comparator {
20633 self.write(", ");
20634 self.generate_expression(comp)?;
20635 }
20636 self.write(")");
20637 Ok(())
20638 }
20639
20640 fn generate_array_join(&mut self, name: &str, f: &ArrayJoinFunc) -> Result<()> {
20641 self.write_keyword(name);
20642 self.write("(");
20643 self.generate_expression(&f.this)?;
20644 self.write(", ");
20645 self.generate_expression(&f.separator)?;
20646 if let Some(ref null_rep) = f.null_replacement {
20647 self.write(", ");
20648 self.generate_expression(null_rep)?;
20649 }
20650 self.write(")");
20651 Ok(())
20652 }
20653
20654 fn generate_unnest(&mut self, f: &UnnestFunc) -> Result<()> {
20655 self.write_keyword("UNNEST");
20656 self.write("(");
20657 self.generate_expression(&f.this)?;
20658 for extra in &f.expressions {
20659 self.write(", ");
20660 self.generate_expression(extra)?;
20661 }
20662 self.write(")");
20663 if f.with_ordinality {
20664 self.write_space();
20665 if self.config.unnest_with_ordinality {
20666 self.write_keyword("WITH ORDINALITY");
20668 } else if f.offset_alias.is_some() {
20669 if let Some(ref alias) = f.alias {
20672 self.write_keyword("AS");
20673 self.write_space();
20674 self.generate_identifier(alias)?;
20675 self.write_space();
20676 }
20677 self.write_keyword("WITH OFFSET");
20678 if let Some(ref offset_alias) = f.offset_alias {
20679 self.write_space();
20680 self.write_keyword("AS");
20681 self.write_space();
20682 self.generate_identifier(offset_alias)?;
20683 }
20684 } else {
20685 self.write_keyword("WITH OFFSET");
20687 if f.alias.is_none() {
20688 self.write(" AS offset");
20689 }
20690 }
20691 }
20692 if let Some(ref alias) = f.alias {
20693 let should_add_alias = if !f.with_ordinality {
20695 true
20696 } else if self.config.unnest_with_ordinality {
20697 true
20699 } else if f.offset_alias.is_some() {
20700 false
20702 } else {
20703 true
20705 };
20706 if should_add_alias {
20707 self.write_space();
20708 self.write_keyword("AS");
20709 self.write_space();
20710 self.generate_identifier(alias)?;
20711 }
20712 }
20713 Ok(())
20714 }
20715
20716 fn generate_array_filter(&mut self, f: &ArrayFilterFunc) -> Result<()> {
20717 self.write_keyword("FILTER");
20718 self.write("(");
20719 self.generate_expression(&f.this)?;
20720 self.write(", ");
20721 self.generate_expression(&f.filter)?;
20722 self.write(")");
20723 Ok(())
20724 }
20725
20726 fn generate_array_transform(&mut self, f: &ArrayTransformFunc) -> Result<()> {
20727 self.write_keyword("TRANSFORM");
20728 self.write("(");
20729 self.generate_expression(&f.this)?;
20730 self.write(", ");
20731 self.generate_expression(&f.transform)?;
20732 self.write(")");
20733 Ok(())
20734 }
20735
20736 fn generate_sequence(&mut self, name: &str, f: &SequenceFunc) -> Result<()> {
20737 self.write_keyword(name);
20738 self.write("(");
20739 self.generate_expression(&f.start)?;
20740 self.write(", ");
20741 self.generate_expression(&f.stop)?;
20742 if let Some(ref step) = f.step {
20743 self.write(", ");
20744 self.generate_expression(step)?;
20745 }
20746 self.write(")");
20747 Ok(())
20748 }
20749
20750 fn generate_struct_constructor(&mut self, f: &StructConstructor) -> Result<()> {
20753 self.write_keyword("STRUCT");
20754 self.write("(");
20755 for (i, (name, expr)) in f.fields.iter().enumerate() {
20756 if i > 0 {
20757 self.write(", ");
20758 }
20759 if let Some(ref id) = name {
20760 self.generate_identifier(id)?;
20761 self.write(" ");
20762 self.write_keyword("AS");
20763 self.write(" ");
20764 }
20765 self.generate_expression(expr)?;
20766 }
20767 self.write(")");
20768 Ok(())
20769 }
20770
20771 fn generate_struct_function_cross_dialect(&mut self, func: &Function) -> Result<()> {
20773 let mut names: Vec<Option<String>> = Vec::new();
20776 let mut values: Vec<&Expression> = Vec::new();
20777 let mut all_named = true;
20778
20779 for arg in &func.args {
20780 match arg {
20781 Expression::Alias(a) => {
20782 names.push(Some(a.alias.name.clone()));
20783 values.push(&a.this);
20784 }
20785 _ => {
20786 names.push(None);
20787 values.push(arg);
20788 all_named = false;
20789 }
20790 }
20791 }
20792
20793 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
20794 self.write("{");
20796 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
20797 if i > 0 {
20798 self.write(", ");
20799 }
20800 if let Some(n) = name {
20801 self.write("'");
20802 self.write(n);
20803 self.write("'");
20804 } else {
20805 self.write("'_");
20806 self.write(&i.to_string());
20807 self.write("'");
20808 }
20809 self.write(": ");
20810 self.generate_expression(value)?;
20811 }
20812 self.write("}");
20813 return Ok(());
20814 }
20815
20816 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
20817 self.write_keyword("OBJECT_CONSTRUCT");
20819 self.write("(");
20820 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
20821 if i > 0 {
20822 self.write(", ");
20823 }
20824 if let Some(n) = name {
20825 self.write("'");
20826 self.write(n);
20827 self.write("'");
20828 } else {
20829 self.write("'_");
20830 self.write(&i.to_string());
20831 self.write("'");
20832 }
20833 self.write(", ");
20834 self.generate_expression(value)?;
20835 }
20836 self.write(")");
20837 return Ok(());
20838 }
20839
20840 if matches!(
20841 self.config.dialect,
20842 Some(DialectType::Presto) | Some(DialectType::Trino)
20843 ) {
20844 if all_named && !names.is_empty() {
20845 self.write_keyword("CAST");
20848 self.write("(");
20849 self.write_keyword("ROW");
20850 self.write("(");
20851 for (i, value) in values.iter().enumerate() {
20852 if i > 0 {
20853 self.write(", ");
20854 }
20855 self.generate_expression(value)?;
20856 }
20857 self.write(")");
20858 self.write(" ");
20859 self.write_keyword("AS");
20860 self.write(" ");
20861 self.write_keyword("ROW");
20862 self.write("(");
20863 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
20864 if i > 0 {
20865 self.write(", ");
20866 }
20867 if let Some(n) = name {
20868 self.write(n);
20869 }
20870 self.write(" ");
20871 let type_str = Self::infer_sql_type_for_presto(value);
20872 self.write_keyword(&type_str);
20873 }
20874 self.write(")");
20875 self.write(")");
20876 } else {
20877 self.write_keyword("ROW");
20879 self.write("(");
20880 for (i, value) in values.iter().enumerate() {
20881 if i > 0 {
20882 self.write(", ");
20883 }
20884 self.generate_expression(value)?;
20885 }
20886 self.write(")");
20887 }
20888 return Ok(());
20889 }
20890
20891 self.write_keyword("ROW");
20893 self.write("(");
20894 for (i, value) in values.iter().enumerate() {
20895 if i > 0 {
20896 self.write(", ");
20897 }
20898 self.generate_expression(value)?;
20899 }
20900 self.write(")");
20901 Ok(())
20902 }
20903
20904 fn infer_sql_type_for_presto(expr: &Expression) -> String {
20906 match expr {
20907 Expression::Literal(lit)
20908 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
20909 {
20910 "VARCHAR".to_string()
20911 }
20912 Expression::Literal(lit)
20913 if matches!(lit.as_ref(), crate::expressions::Literal::Number(_)) =>
20914 {
20915 let crate::expressions::Literal::Number(n) = lit.as_ref() else {
20916 unreachable!()
20917 };
20918 if n.contains('.') {
20919 "DOUBLE".to_string()
20920 } else {
20921 "INTEGER".to_string()
20922 }
20923 }
20924 Expression::Boolean(_) => "BOOLEAN".to_string(),
20925 Expression::Literal(lit)
20926 if matches!(lit.as_ref(), crate::expressions::Literal::Date(_)) =>
20927 {
20928 "DATE".to_string()
20929 }
20930 Expression::Literal(lit)
20931 if matches!(lit.as_ref(), crate::expressions::Literal::Timestamp(_)) =>
20932 {
20933 "TIMESTAMP".to_string()
20934 }
20935 Expression::Literal(lit)
20936 if matches!(lit.as_ref(), crate::expressions::Literal::Datetime(_)) =>
20937 {
20938 "TIMESTAMP".to_string()
20939 }
20940 Expression::Array(_) | Expression::ArrayFunc(_) => {
20941 "ARRAY(VARCHAR)".to_string()
20943 }
20944 Expression::Struct(_) | Expression::StructFunc(_) => "ROW".to_string(),
20946 Expression::Function(f) => {
20947 if f.name.eq_ignore_ascii_case("STRUCT") {
20948 "ROW".to_string()
20949 } else if f.name.eq_ignore_ascii_case("CURRENT_DATE") {
20950 "DATE".to_string()
20951 } else if f.name.eq_ignore_ascii_case("CURRENT_TIMESTAMP")
20952 || f.name.eq_ignore_ascii_case("NOW")
20953 {
20954 "TIMESTAMP".to_string()
20955 } else {
20956 "VARCHAR".to_string()
20957 }
20958 }
20959 _ => "VARCHAR".to_string(),
20960 }
20961 }
20962
20963 fn generate_struct_extract(&mut self, f: &StructExtractFunc) -> Result<()> {
20964 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
20966 self.write_keyword("STRUCT_EXTRACT");
20967 self.write("(");
20968 self.generate_expression(&f.this)?;
20969 self.write(", ");
20970 self.write("'");
20972 self.write(&f.field.name);
20973 self.write("'");
20974 self.write(")");
20975 return Ok(());
20976 }
20977 self.generate_expression(&f.this)?;
20978 self.write(".");
20979 self.generate_identifier(&f.field)
20980 }
20981
20982 fn generate_named_struct(&mut self, f: &NamedStructFunc) -> Result<()> {
20983 if matches!(
20984 self.config.dialect,
20985 Some(DialectType::Spark | DialectType::Databricks)
20986 ) {
20987 self.write_keyword("STRUCT");
20988 self.write("(");
20989 for (i, (name, value)) in f.pairs.iter().enumerate() {
20990 if i > 0 {
20991 self.write(", ");
20992 }
20993 self.generate_expression(value)?;
20994 self.write(" ");
20995 self.write_keyword("AS");
20996 self.write(" ");
20997 if let Expression::Literal(lit) = name {
20998 if let Literal::String(field_name) = lit.as_ref() {
20999 self.generate_identifier(&Identifier::new(field_name))?;
21000 } else {
21001 self.generate_expression(name)?;
21002 }
21003 } else {
21004 self.generate_expression(name)?;
21005 }
21006 }
21007 self.write(")");
21008 return Ok(());
21009 }
21010
21011 self.write_keyword("NAMED_STRUCT");
21012 self.write("(");
21013 for (i, (name, value)) in f.pairs.iter().enumerate() {
21014 if i > 0 {
21015 self.write(", ");
21016 }
21017 self.generate_expression(name)?;
21018 self.write(", ");
21019 self.generate_expression(value)?;
21020 }
21021 self.write(")");
21022 Ok(())
21023 }
21024
21025 fn generate_map_constructor(&mut self, f: &MapConstructor) -> Result<()> {
21028 if f.curly_brace_syntax {
21029 if f.with_map_keyword {
21031 self.write_keyword("MAP");
21032 self.write(" ");
21033 }
21034 self.write("{");
21035 for (i, (key, val)) in f.keys.iter().zip(f.values.iter()).enumerate() {
21036 if i > 0 {
21037 self.write(", ");
21038 }
21039 self.generate_expression(key)?;
21040 self.write(": ");
21041 self.generate_expression(val)?;
21042 }
21043 self.write("}");
21044 } else {
21045 self.write_keyword("MAP");
21047 self.write("(");
21048 self.write_keyword("ARRAY");
21049 self.write("[");
21050 for (i, key) in f.keys.iter().enumerate() {
21051 if i > 0 {
21052 self.write(", ");
21053 }
21054 self.generate_expression(key)?;
21055 }
21056 self.write("], ");
21057 self.write_keyword("ARRAY");
21058 self.write("[");
21059 for (i, val) in f.values.iter().enumerate() {
21060 if i > 0 {
21061 self.write(", ");
21062 }
21063 self.generate_expression(val)?;
21064 }
21065 self.write("])");
21066 }
21067 Ok(())
21068 }
21069
21070 fn generate_transform_func(&mut self, name: &str, f: &TransformFunc) -> Result<()> {
21071 self.write_keyword(name);
21072 self.write("(");
21073 self.generate_expression(&f.this)?;
21074 self.write(", ");
21075 self.generate_expression(&f.transform)?;
21076 self.write(")");
21077 Ok(())
21078 }
21079
21080 fn generate_json_extract(&mut self, name: &str, f: &JsonExtractFunc) -> Result<()> {
21083 use crate::dialects::DialectType;
21084
21085 let use_arrow = f.arrow_syntax && self.dialect_supports_json_arrow();
21087
21088 if use_arrow {
21089 self.generate_expression(&f.this)?;
21091 if name == "JSON_EXTRACT_SCALAR" || name == "JSON_EXTRACT_PATH_TEXT" {
21092 self.write(" ->> ");
21093 } else {
21094 self.write(" -> ");
21095 }
21096 self.generate_expression(&f.path)?;
21097 return Ok(());
21098 }
21099
21100 if f.hash_arrow_syntax
21102 && matches!(
21103 self.config.dialect,
21104 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
21105 )
21106 {
21107 self.generate_expression(&f.this)?;
21108 self.write(" #>> ");
21109 self.generate_expression(&f.path)?;
21110 return Ok(());
21111 }
21112
21113 let func_name = if matches!(self.config.dialect, Some(DialectType::Redshift)) {
21116 match name {
21117 "JSON_EXTRACT_SCALAR"
21118 | "JSON_EXTRACT_PATH_TEXT"
21119 | "JSON_EXTRACT"
21120 | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH_TEXT",
21121 _ => name,
21122 }
21123 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
21124 match name {
21125 "JSON_EXTRACT_SCALAR" | "JSON_EXTRACT_PATH_TEXT" => "JSON_EXTRACT_PATH_TEXT",
21126 "JSON_EXTRACT" | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH",
21127 _ => name,
21128 }
21129 } else {
21130 name
21131 };
21132
21133 self.write_keyword(func_name);
21134 self.write("(");
21135 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
21137 if let Expression::Cast(ref cast) = f.this {
21138 if matches!(cast.to, crate::expressions::DataType::Json) {
21139 self.generate_expression(&cast.this)?;
21140 } else {
21141 self.generate_expression(&f.this)?;
21142 }
21143 } else {
21144 self.generate_expression(&f.this)?;
21145 }
21146 } else {
21147 self.generate_expression(&f.this)?;
21148 }
21149 if matches!(
21152 self.config.dialect,
21153 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
21154 ) && (func_name == "JSON_EXTRACT_PATH" || func_name == "JSON_EXTRACT_PATH_TEXT")
21155 {
21156 if let Expression::Literal(ref lit) = f.path {
21157 if let Literal::String(ref s) = lit.as_ref() {
21158 let parts = Self::decompose_json_path(s);
21159 for part in &parts {
21160 self.write(", '");
21161 self.write(part);
21162 self.write("'");
21163 }
21164 }
21165 } else {
21166 self.write(", ");
21167 self.generate_expression(&f.path)?;
21168 }
21169 } else {
21170 self.write(", ");
21171 self.generate_expression(&f.path)?;
21172 }
21173
21174 if let Some(ref wrapper) = f.wrapper_option {
21177 self.write_space();
21178 self.write_keyword(wrapper);
21179 }
21180 if let Some(ref quotes) = f.quotes_option {
21181 self.write_space();
21182 self.write_keyword(quotes);
21183 if f.on_scalar_string {
21184 self.write_space();
21185 self.write_keyword("ON SCALAR STRING");
21186 }
21187 }
21188 if let Some(ref on_err) = f.on_error {
21189 self.write_space();
21190 self.write_keyword(on_err);
21191 }
21192 if let Some(ref ret_type) = f.returning {
21193 self.write_space();
21194 self.write_keyword("RETURNING");
21195 self.write_space();
21196 self.generate_data_type(ret_type)?;
21197 }
21198
21199 self.write(")");
21200 Ok(())
21201 }
21202
21203 fn dialect_supports_json_arrow(&self) -> bool {
21205 use crate::dialects::DialectType;
21206 match self.config.dialect {
21207 Some(DialectType::PostgreSQL) => true,
21209 Some(DialectType::MySQL) => true,
21210 Some(DialectType::DuckDB) => true,
21211 Some(DialectType::CockroachDB) => true,
21212 Some(DialectType::StarRocks) => true,
21213 Some(DialectType::SQLite) => true,
21214 _ => false,
21216 }
21217 }
21218
21219 fn generate_json_path(&mut self, name: &str, f: &JsonPathFunc) -> Result<()> {
21220 use crate::dialects::DialectType;
21221
21222 if matches!(
21224 self.config.dialect,
21225 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
21226 ) && name == "JSON_EXTRACT_PATH"
21227 {
21228 self.generate_expression(&f.this)?;
21229 self.write(" #> ");
21230 if f.paths.len() == 1 {
21231 self.generate_expression(&f.paths[0])?;
21232 } else {
21233 self.write_keyword("ARRAY");
21235 self.write("[");
21236 for (i, path) in f.paths.iter().enumerate() {
21237 if i > 0 {
21238 self.write(", ");
21239 }
21240 self.generate_expression(path)?;
21241 }
21242 self.write("]");
21243 }
21244 return Ok(());
21245 }
21246
21247 self.write_keyword(name);
21248 self.write("(");
21249 self.generate_expression(&f.this)?;
21250 for path in &f.paths {
21251 self.write(", ");
21252 self.generate_expression(path)?;
21253 }
21254 self.write(")");
21255 Ok(())
21256 }
21257
21258 fn generate_json_object(&mut self, f: &JsonObjectFunc) -> Result<()> {
21259 use crate::dialects::DialectType;
21260
21261 self.write_keyword("JSON_OBJECT");
21262 self.write("(");
21263 if f.star {
21264 self.write("*");
21265 } else {
21266 let use_comma_syntax = self.config.json_key_value_pair_sep == ","
21270 || matches!(
21271 self.config.dialect,
21272 Some(DialectType::BigQuery)
21273 | Some(DialectType::MySQL)
21274 | Some(DialectType::SQLite)
21275 );
21276
21277 for (i, (key, value)) in f.pairs.iter().enumerate() {
21278 if i > 0 {
21279 self.write(", ");
21280 }
21281 self.generate_expression(key)?;
21282 if use_comma_syntax {
21283 self.write(", ");
21284 } else {
21285 self.write(": ");
21286 }
21287 self.generate_expression(value)?;
21288 }
21289 }
21290 if let Some(null_handling) = f.null_handling {
21291 self.write_space();
21292 match null_handling {
21293 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
21294 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
21295 }
21296 }
21297 if f.with_unique_keys {
21298 self.write_space();
21299 self.write_keyword("WITH UNIQUE KEYS");
21300 }
21301 if let Some(ref ret_type) = f.returning_type {
21302 self.write_space();
21303 self.write_keyword("RETURNING");
21304 self.write_space();
21305 self.generate_data_type(ret_type)?;
21306 if f.format_json {
21307 self.write_space();
21308 self.write_keyword("FORMAT JSON");
21309 }
21310 if let Some(ref enc) = f.encoding {
21311 self.write_space();
21312 self.write_keyword("ENCODING");
21313 self.write_space();
21314 self.write(enc);
21315 }
21316 }
21317 self.write(")");
21318 Ok(())
21319 }
21320
21321 fn generate_json_modify(&mut self, name: &str, f: &JsonModifyFunc) -> Result<()> {
21322 self.write_keyword(name);
21323 self.write("(");
21324 self.generate_expression(&f.this)?;
21325 for (path, value) in &f.path_values {
21326 self.write(", ");
21327 self.generate_expression(path)?;
21328 self.write(", ");
21329 self.generate_expression(value)?;
21330 }
21331 self.write(")");
21332 Ok(())
21333 }
21334
21335 fn generate_json_array_agg(&mut self, f: &JsonArrayAggFunc) -> Result<()> {
21336 self.write_keyword("JSON_ARRAYAGG");
21337 self.write("(");
21338 self.generate_expression(&f.this)?;
21339 if let Some(ref order_by) = f.order_by {
21340 self.write_space();
21341 self.write_keyword("ORDER BY");
21342 self.write_space();
21343 for (i, ord) in order_by.iter().enumerate() {
21344 if i > 0 {
21345 self.write(", ");
21346 }
21347 self.generate_ordered(ord)?;
21348 }
21349 }
21350 if let Some(null_handling) = f.null_handling {
21351 self.write_space();
21352 match null_handling {
21353 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
21354 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
21355 }
21356 }
21357 self.write(")");
21358 if let Some(ref filter) = f.filter {
21359 self.write_space();
21360 self.write_keyword("FILTER");
21361 self.write("(");
21362 self.write_keyword("WHERE");
21363 self.write_space();
21364 self.generate_expression(filter)?;
21365 self.write(")");
21366 }
21367 Ok(())
21368 }
21369
21370 fn generate_json_object_agg(&mut self, f: &JsonObjectAggFunc) -> Result<()> {
21371 self.write_keyword("JSON_OBJECTAGG");
21372 self.write("(");
21373 self.generate_expression(&f.key)?;
21374 self.write(": ");
21375 self.generate_expression(&f.value)?;
21376 if let Some(null_handling) = f.null_handling {
21377 self.write_space();
21378 match null_handling {
21379 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
21380 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
21381 }
21382 }
21383 self.write(")");
21384 if let Some(ref filter) = f.filter {
21385 self.write_space();
21386 self.write_keyword("FILTER");
21387 self.write("(");
21388 self.write_keyword("WHERE");
21389 self.write_space();
21390 self.generate_expression(filter)?;
21391 self.write(")");
21392 }
21393 Ok(())
21394 }
21395
21396 fn generate_convert(&mut self, f: &ConvertFunc) -> Result<()> {
21399 use crate::dialects::DialectType;
21400
21401 if self.config.dialect == Some(DialectType::Redshift) {
21403 self.write_keyword("CAST");
21404 self.write("(");
21405 self.generate_expression(&f.this)?;
21406 self.write_space();
21407 self.write_keyword("AS");
21408 self.write_space();
21409 self.generate_data_type(&f.to)?;
21410 self.write(")");
21411 return Ok(());
21412 }
21413
21414 self.write_keyword("CONVERT");
21415 self.write("(");
21416 self.generate_data_type(&f.to)?;
21417 self.write(", ");
21418 self.generate_expression(&f.this)?;
21419 if let Some(ref style) = f.style {
21420 self.write(", ");
21421 self.generate_expression(style)?;
21422 }
21423 self.write(")");
21424 Ok(())
21425 }
21426
21427 fn generate_lambda(&mut self, f: &LambdaExpr) -> Result<()> {
21430 if f.colon {
21431 self.write_keyword("LAMBDA");
21433 self.write_space();
21434 for (i, param) in f.parameters.iter().enumerate() {
21435 if i > 0 {
21436 self.write(", ");
21437 }
21438 self.generate_identifier(param)?;
21439 }
21440 self.write(" : ");
21441 } else {
21442 if f.parameters.len() == 1 {
21444 self.generate_identifier(&f.parameters[0])?;
21445 } else {
21446 self.write("(");
21447 for (i, param) in f.parameters.iter().enumerate() {
21448 if i > 0 {
21449 self.write(", ");
21450 }
21451 self.generate_identifier(param)?;
21452 }
21453 self.write(")");
21454 }
21455 self.write(" -> ");
21456 }
21457 self.generate_expression(&f.body)
21458 }
21459
21460 fn generate_named_argument(&mut self, f: &NamedArgument) -> Result<()> {
21461 self.generate_identifier(&f.name)?;
21462 match f.separator {
21463 NamedArgSeparator::DArrow => self.write(" => "),
21464 NamedArgSeparator::ColonEq => self.write(" := "),
21465 NamedArgSeparator::Eq => self.write(" = "),
21466 }
21467 self.generate_expression(&f.value)
21468 }
21469
21470 fn generate_table_argument(&mut self, f: &TableArgument) -> Result<()> {
21471 self.write_keyword(&f.prefix);
21472 self.write(" ");
21473 self.generate_expression(&f.this)
21474 }
21475
21476 fn generate_parameter(&mut self, f: &Parameter) -> Result<()> {
21477 match f.style {
21478 ParameterStyle::Question => self.write("?"),
21479 ParameterStyle::Dollar => {
21480 self.write("$");
21481 if let Some(idx) = f.index {
21482 self.write(&idx.to_string());
21483 } else if let Some(ref name) = f.name {
21484 self.write(name);
21486 }
21487 }
21488 ParameterStyle::DollarBrace => {
21489 self.write("${");
21491 if let Some(ref name) = f.name {
21492 self.write(name);
21493 }
21494 if let Some(ref expr) = f.expression {
21495 self.write(":");
21496 self.write(expr);
21497 }
21498 self.write("}");
21499 }
21500 ParameterStyle::Colon => {
21501 self.write(":");
21502 if let Some(idx) = f.index {
21503 self.write(&idx.to_string());
21504 } else if let Some(ref name) = f.name {
21505 self.write(name);
21506 }
21507 }
21508 ParameterStyle::At => {
21509 self.write("@");
21510 if let Some(ref name) = f.name {
21511 if f.string_quoted {
21512 self.write("'");
21513 self.write(name);
21514 self.write("'");
21515 } else if f.quoted {
21516 self.write("\"");
21517 self.write(name);
21518 self.write("\"");
21519 } else {
21520 self.write(name);
21521 }
21522 }
21523 }
21524 ParameterStyle::DoubleAt => {
21525 self.write("@@");
21526 if let Some(ref name) = f.name {
21527 self.write(name);
21528 }
21529 }
21530 ParameterStyle::DoubleDollar => {
21531 self.write("$$");
21532 if let Some(ref name) = f.name {
21533 self.write(name);
21534 }
21535 }
21536 ParameterStyle::Percent => {
21537 if let Some(ref name) = f.name {
21538 self.write("%(");
21540 self.write(name);
21541 self.write(")s");
21542 } else {
21543 self.write("%s");
21545 }
21546 }
21547 ParameterStyle::Brace => {
21548 self.write("{");
21551 if let Some(ref name) = f.name {
21552 self.write(name);
21553 }
21554 if let Some(ref expr) = f.expression {
21555 self.write(": ");
21556 self.write(expr);
21557 }
21558 self.write("}");
21559 }
21560 }
21561 Ok(())
21562 }
21563
21564 fn generate_placeholder(&mut self, f: &Placeholder) -> Result<()> {
21565 self.write("?");
21566 if let Some(idx) = f.index {
21567 self.write(&idx.to_string());
21568 }
21569 Ok(())
21570 }
21571
21572 fn generate_sql_comment(&mut self, f: &SqlComment) -> Result<()> {
21573 if f.is_block {
21574 self.write("/*");
21575 self.write(&f.text);
21576 self.write("*/");
21577 } else {
21578 self.write("--");
21579 self.write(&f.text);
21580 }
21581 Ok(())
21582 }
21583
21584 fn generate_similar_to(&mut self, f: &SimilarToExpr) -> Result<()> {
21587 self.generate_expression(&f.this)?;
21588 if f.not {
21589 self.write_space();
21590 self.write_keyword("NOT");
21591 }
21592 self.write_space();
21593 self.write_keyword("SIMILAR TO");
21594 self.write_space();
21595 self.generate_expression(&f.pattern)?;
21596 if let Some(ref escape) = f.escape {
21597 self.write_space();
21598 self.write_keyword("ESCAPE");
21599 self.write_space();
21600 self.generate_expression(escape)?;
21601 }
21602 Ok(())
21603 }
21604
21605 fn generate_quantified(&mut self, name: &str, f: &QuantifiedExpr) -> Result<()> {
21606 self.generate_expression(&f.this)?;
21607 self.write_space();
21608 if let Some(op) = &f.op {
21610 match op {
21611 QuantifiedOp::Eq => self.write("="),
21612 QuantifiedOp::Neq => self.write("<>"),
21613 QuantifiedOp::Lt => self.write("<"),
21614 QuantifiedOp::Lte => self.write("<="),
21615 QuantifiedOp::Gt => self.write(">"),
21616 QuantifiedOp::Gte => self.write(">="),
21617 }
21618 self.write_space();
21619 }
21620 self.write_keyword(name);
21621
21622 if matches!(&f.subquery, Expression::Subquery(_)) {
21624 self.write_space();
21625 self.generate_expression(&f.subquery)?;
21626 } else {
21627 self.write("(");
21628
21629 let is_statement = matches!(
21630 &f.subquery,
21631 Expression::Select(_)
21632 | Expression::Union(_)
21633 | Expression::Intersect(_)
21634 | Expression::Except(_)
21635 );
21636
21637 if self.config.pretty && is_statement {
21638 self.write_newline();
21639 self.indent_level += 1;
21640 self.write_indent();
21641 }
21642 self.generate_expression(&f.subquery)?;
21643 if self.config.pretty && is_statement {
21644 self.write_newline();
21645 self.indent_level -= 1;
21646 self.write_indent();
21647 }
21648 self.write(")");
21649 }
21650 Ok(())
21651 }
21652
21653 fn generate_overlaps(&mut self, f: &OverlapsExpr) -> Result<()> {
21654 if let (Some(this), Some(expr)) = (&f.this, &f.expression) {
21656 self.generate_expression(this)?;
21657 self.write_space();
21658 self.write_keyword("OVERLAPS");
21659 self.write_space();
21660 self.generate_expression(expr)?;
21661 } else if let (Some(ls), Some(le), Some(rs), Some(re)) =
21662 (&f.left_start, &f.left_end, &f.right_start, &f.right_end)
21663 {
21664 self.write("(");
21666 self.generate_expression(ls)?;
21667 self.write(", ");
21668 self.generate_expression(le)?;
21669 self.write(")");
21670 self.write_space();
21671 self.write_keyword("OVERLAPS");
21672 self.write_space();
21673 self.write("(");
21674 self.generate_expression(rs)?;
21675 self.write(", ");
21676 self.generate_expression(re)?;
21677 self.write(")");
21678 }
21679 Ok(())
21680 }
21681
21682 fn generate_try_cast(&mut self, cast: &Cast) -> Result<()> {
21685 use crate::dialects::DialectType;
21686
21687 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
21689 self.generate_expression(&cast.this)?;
21690 self.write(" !:> ");
21691 self.generate_data_type(&cast.to)?;
21692 return Ok(());
21693 }
21694
21695 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
21697 self.write_keyword("TRYCAST");
21698 self.write("(");
21699 self.generate_expression(&cast.this)?;
21700 self.write_space();
21701 self.write_keyword("AS");
21702 self.write_space();
21703 self.generate_data_type(&cast.to)?;
21704 self.write(")");
21705 return Ok(());
21706 }
21707
21708 let keyword = if matches!(
21710 self.config.dialect,
21711 Some(DialectType::Hive)
21712 | Some(DialectType::MySQL)
21713 | Some(DialectType::SQLite)
21714 | Some(DialectType::Oracle)
21715 | Some(DialectType::ClickHouse)
21716 | Some(DialectType::Redshift)
21717 | Some(DialectType::PostgreSQL)
21718 | Some(DialectType::StarRocks)
21719 | Some(DialectType::Doris)
21720 ) {
21721 "CAST"
21722 } else {
21723 "TRY_CAST"
21724 };
21725
21726 self.write_keyword(keyword);
21727 self.write("(");
21728 self.generate_expression(&cast.this)?;
21729 self.write_space();
21730 self.write_keyword("AS");
21731 self.write_space();
21732 self.generate_data_type(&cast.to)?;
21733
21734 if let Some(format) = &cast.format {
21736 self.write_space();
21737 self.write_keyword("FORMAT");
21738 self.write_space();
21739 self.generate_expression(format)?;
21740 }
21741
21742 self.write(")");
21743 Ok(())
21744 }
21745
21746 fn generate_safe_cast(&mut self, cast: &Cast) -> Result<()> {
21747 self.write_keyword("SAFE_CAST");
21748 self.write("(");
21749 self.generate_expression(&cast.this)?;
21750 self.write_space();
21751 self.write_keyword("AS");
21752 self.write_space();
21753 self.generate_data_type(&cast.to)?;
21754
21755 if let Some(format) = &cast.format {
21757 self.write_space();
21758 self.write_keyword("FORMAT");
21759 self.write_space();
21760 self.generate_expression(format)?;
21761 }
21762
21763 self.write(")");
21764 Ok(())
21765 }
21766
21767 fn generate_subscript(&mut self, s: &Subscript) -> Result<()> {
21770 let needs_parens = matches!(&s.this, Expression::JsonExtract(ref f) if f.arrow_syntax);
21774 if needs_parens {
21775 self.write("(");
21776 }
21777 self.generate_expression(&s.this)?;
21778 if needs_parens {
21779 self.write(")");
21780 }
21781 self.write("[");
21782 self.generate_expression(&s.index)?;
21783 self.write("]");
21784 Ok(())
21785 }
21786
21787 fn generate_dot_access(&mut self, d: &DotAccess) -> Result<()> {
21788 self.generate_expression(&d.this)?;
21789 let use_colon = matches!(self.config.dialect, Some(DialectType::Snowflake))
21792 && matches!(
21793 &d.this,
21794 Expression::Cast(_) | Expression::SafeCast(_) | Expression::TryCast(_)
21795 );
21796 if use_colon {
21797 self.write(":");
21798 } else {
21799 self.write(".");
21800 }
21801 self.generate_identifier(&d.field)
21802 }
21803
21804 fn generate_method_call(&mut self, m: &MethodCall) -> Result<()> {
21805 self.generate_expression(&m.this)?;
21806 self.write(".");
21807 if m.method.quoted {
21810 let q = self.config.identifier_quote;
21811 self.write(&format!("{}{}{}", q, m.method.name, q));
21812 } else {
21813 self.write(&m.method.name);
21814 }
21815 self.write("(");
21816 for (i, arg) in m.args.iter().enumerate() {
21817 if i > 0 {
21818 self.write(", ");
21819 }
21820 self.generate_expression(arg)?;
21821 }
21822 self.write(")");
21823 Ok(())
21824 }
21825
21826 fn generate_array_slice(&mut self, s: &ArraySlice) -> Result<()> {
21827 let needs_parens = matches!(
21830 &s.this,
21831 Expression::JsonExtract(f) if f.arrow_syntax
21832 ) || matches!(
21833 &s.this,
21834 Expression::JsonExtractScalar(f) if f.arrow_syntax
21835 );
21836
21837 if needs_parens {
21838 self.write("(");
21839 }
21840 self.generate_expression(&s.this)?;
21841 if needs_parens {
21842 self.write(")");
21843 }
21844 self.write("[");
21845 if let Some(start) = &s.start {
21846 self.generate_expression(start)?;
21847 }
21848 self.write(":");
21849 if let Some(end) = &s.end {
21850 self.generate_expression(end)?;
21851 }
21852 self.write("]");
21853 Ok(())
21854 }
21855
21856 fn generate_binary_op(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
21857 match &op.left {
21861 Expression::Column(col) => {
21862 if let Some(table) = &col.table {
21865 self.generate_identifier(table)?;
21866 self.write(".");
21867 }
21868 self.generate_identifier(&col.name)?;
21869 if col.join_mark && self.config.supports_column_join_marks {
21871 self.write(" (+)");
21872 }
21873 if op.left_comments.is_empty() {
21875 for comment in &col.trailing_comments {
21876 self.write_space();
21877 self.write_formatted_comment(comment);
21878 }
21879 }
21880 }
21881 Expression::Add(inner_op)
21882 | Expression::Sub(inner_op)
21883 | Expression::Mul(inner_op)
21884 | Expression::Div(inner_op)
21885 | Expression::Concat(inner_op) => {
21886 self.generate_binary_op_no_trailing(inner_op, match &op.left {
21888 Expression::Add(_) => "+",
21889 Expression::Sub(_) => "-",
21890 Expression::Mul(_) => "*",
21891 Expression::Div(_) => "/",
21892 Expression::Concat(_) => "||",
21893 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
21894 })?;
21895 }
21896 _ => {
21897 self.generate_expression(&op.left)?;
21898 }
21899 }
21900 for comment in &op.left_comments {
21902 self.write_space();
21903 self.write_formatted_comment(comment);
21904 }
21905 if self.config.pretty
21906 && matches!(self.config.dialect, Some(DialectType::Snowflake))
21907 && (operator == "AND" || operator == "OR")
21908 {
21909 self.write_newline();
21910 self.write_indent();
21911 self.write_keyword(operator);
21912 } else {
21913 self.write_space();
21914 if operator.chars().all(|c| c.is_alphabetic()) {
21915 self.write_keyword(operator);
21916 } else {
21917 self.write(operator);
21918 }
21919 }
21920 for comment in &op.operator_comments {
21922 self.write_space();
21923 self.write_formatted_comment(comment);
21924 }
21925 self.write_space();
21926 self.generate_expression(&op.right)?;
21927 for comment in &op.trailing_comments {
21929 self.write_space();
21930 self.write_formatted_comment(comment);
21931 }
21932 Ok(())
21933 }
21934
21935 fn generate_connector_op(&mut self, op: &BinaryOp, connector: ConnectorOperator) -> Result<()> {
21936 let keyword = connector.keyword();
21937 let Some(terms) = self.flatten_connector_terms(op, connector) else {
21938 return self.generate_binary_op(op, keyword);
21939 };
21940
21941 self.generate_expression(terms[0])?;
21942 for term in terms.iter().skip(1) {
21943 if self.config.pretty && matches!(self.config.dialect, Some(DialectType::Snowflake)) {
21944 self.write_newline();
21945 self.write_indent();
21946 self.write_keyword(keyword);
21947 } else {
21948 self.write_space();
21949 self.write_keyword(keyword);
21950 }
21951 self.write_space();
21952 self.generate_expression(term)?;
21953 }
21954
21955 Ok(())
21956 }
21957
21958 fn flatten_connector_terms<'a>(
21959 &self,
21960 root: &'a BinaryOp,
21961 connector: ConnectorOperator,
21962 ) -> Option<Vec<&'a Expression>> {
21963 if !root.left_comments.is_empty()
21964 || !root.operator_comments.is_empty()
21965 || !root.trailing_comments.is_empty()
21966 {
21967 return None;
21968 }
21969
21970 let mut terms = Vec::new();
21971 let mut stack: Vec<&Expression> = vec![&root.right, &root.left];
21972
21973 while let Some(expr) = stack.pop() {
21974 match (connector, expr) {
21975 (ConnectorOperator::And, Expression::And(inner))
21976 if inner.left_comments.is_empty()
21977 && inner.operator_comments.is_empty()
21978 && inner.trailing_comments.is_empty() =>
21979 {
21980 stack.push(&inner.right);
21981 stack.push(&inner.left);
21982 }
21983 (ConnectorOperator::Or, Expression::Or(inner))
21984 if inner.left_comments.is_empty()
21985 && inner.operator_comments.is_empty()
21986 && inner.trailing_comments.is_empty() =>
21987 {
21988 stack.push(&inner.right);
21989 stack.push(&inner.left);
21990 }
21991 _ => terms.push(expr),
21992 }
21993 }
21994
21995 if terms.len() > 1 {
21996 Some(terms)
21997 } else {
21998 None
21999 }
22000 }
22001
22002 fn generate_like_op(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
22004 self.generate_expression(&op.left)?;
22005 self.write_space();
22006 if operator == "ILIKE" && matches!(self.config.dialect, Some(DialectType::Drill)) {
22008 self.write("`ILIKE`");
22009 } else {
22010 self.write_keyword(operator);
22011 }
22012 if let Some(quantifier) = &op.quantifier {
22013 self.write_space();
22014 self.write_keyword(quantifier);
22015 let is_any =
22020 quantifier.eq_ignore_ascii_case("ANY") || quantifier.eq_ignore_ascii_case("SOME");
22021 if !(is_any && matches!(&op.right, Expression::Paren(_))) {
22022 self.write_space();
22023 }
22024 } else {
22025 self.write_space();
22026 }
22027 self.generate_expression(&op.right)?;
22028 if let Some(escape) = &op.escape {
22029 self.write_space();
22030 self.write_keyword("ESCAPE");
22031 self.write_space();
22032 self.generate_expression(escape)?;
22033 }
22034 Ok(())
22035 }
22036
22037 fn generate_null_safe_eq(&mut self, op: &BinaryOp) -> Result<()> {
22040 use crate::dialects::DialectType;
22041 self.generate_expression(&op.left)?;
22042 self.write_space();
22043 if matches!(self.config.dialect, Some(DialectType::MySQL)) {
22044 self.write("<=>");
22045 } else {
22046 self.write_keyword("IS NOT DISTINCT FROM");
22047 }
22048 self.write_space();
22049 self.generate_expression(&op.right)?;
22050 Ok(())
22051 }
22052
22053 fn generate_null_safe_neq(&mut self, op: &BinaryOp) -> Result<()> {
22055 self.generate_expression(&op.left)?;
22056 self.write_space();
22057 self.write_keyword("IS DISTINCT FROM");
22058 self.write_space();
22059 self.generate_expression(&op.right)?;
22060 Ok(())
22061 }
22062
22063 fn generate_binary_op_no_trailing(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
22065 match &op.left {
22067 Expression::Column(col) => {
22068 if let Some(table) = &col.table {
22069 self.generate_identifier(table)?;
22070 self.write(".");
22071 }
22072 self.generate_identifier(&col.name)?;
22073 if col.join_mark && self.config.supports_column_join_marks {
22075 self.write(" (+)");
22076 }
22077 }
22078 Expression::Add(inner_op)
22079 | Expression::Sub(inner_op)
22080 | Expression::Mul(inner_op)
22081 | Expression::Div(inner_op)
22082 | Expression::Concat(inner_op) => {
22083 self.generate_binary_op_no_trailing(inner_op, match &op.left {
22084 Expression::Add(_) => "+",
22085 Expression::Sub(_) => "-",
22086 Expression::Mul(_) => "*",
22087 Expression::Div(_) => "/",
22088 Expression::Concat(_) => "||",
22089 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
22090 })?;
22091 }
22092 _ => {
22093 self.generate_expression(&op.left)?;
22094 }
22095 }
22096 for comment in &op.left_comments {
22098 self.write_space();
22099 self.write_formatted_comment(comment);
22100 }
22101 self.write_space();
22102 if operator.chars().all(|c| c.is_alphabetic()) {
22103 self.write_keyword(operator);
22104 } else {
22105 self.write(operator);
22106 }
22107 for comment in &op.operator_comments {
22109 self.write_space();
22110 self.write_formatted_comment(comment);
22111 }
22112 self.write_space();
22113 match &op.right {
22116 Expression::Column(col) => {
22117 if let Some(table) = &col.table {
22118 self.generate_identifier(table)?;
22119 self.write(".");
22120 }
22121 self.generate_identifier(&col.name)?;
22122 if col.join_mark && self.config.supports_column_join_marks {
22124 self.write(" (+)");
22125 }
22126 }
22127 _ => {
22128 self.generate_expression(&op.right)?;
22129 }
22130 }
22131 Ok(())
22133 }
22134
22135 fn generate_unary_op(&mut self, op: &UnaryOp, operator: &str) -> Result<()> {
22136 if operator.chars().all(|c| c.is_alphabetic()) {
22137 self.write_keyword(operator);
22138 self.write_space();
22139 } else {
22140 self.write(operator);
22141 if matches!(&op.this, Expression::Neg(_) | Expression::BitwiseNot(_)) {
22143 self.write_space();
22144 }
22145 }
22146 self.generate_expression(&op.this)
22147 }
22148
22149 fn generate_in(&mut self, in_expr: &In) -> Result<()> {
22150 let is_generic =
22154 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
22155 let use_prefix_not =
22156 in_expr.not && is_generic && self.config.not_in_style == NotInStyle::Prefix;
22157 if use_prefix_not {
22158 self.write_keyword("NOT");
22159 self.write_space();
22160 }
22161 self.generate_expression(&in_expr.this)?;
22162 if in_expr.global {
22163 self.write_space();
22164 self.write_keyword("GLOBAL");
22165 }
22166 if in_expr.not && !use_prefix_not {
22167 self.write_space();
22168 self.write_keyword("NOT");
22169 }
22170 self.write_space();
22171 self.write_keyword("IN");
22172
22173 if let Some(unnest_expr) = &in_expr.unnest {
22175 self.write_space();
22176 self.write_keyword("UNNEST");
22177 self.write("(");
22178 self.generate_expression(unnest_expr)?;
22179 self.write(")");
22180 return Ok(());
22181 }
22182
22183 if let Some(query) = &in_expr.query {
22184 let is_bare = in_expr.expressions.is_empty()
22187 && !matches!(
22188 query,
22189 Expression::Select(_)
22190 | Expression::Union(_)
22191 | Expression::Intersect(_)
22192 | Expression::Except(_)
22193 | Expression::Subquery(_)
22194 );
22195 if is_bare {
22196 self.write_space();
22198 self.generate_expression(query)?;
22199 } else {
22200 self.write(" (");
22202 let is_statement = matches!(
22203 query,
22204 Expression::Select(_)
22205 | Expression::Union(_)
22206 | Expression::Intersect(_)
22207 | Expression::Except(_)
22208 | Expression::Subquery(_)
22209 );
22210 if self.config.pretty && is_statement {
22211 self.write_newline();
22212 self.indent_level += 1;
22213 self.write_indent();
22214 }
22215 self.generate_expression(query)?;
22216 if self.config.pretty && is_statement {
22217 self.write_newline();
22218 self.indent_level -= 1;
22219 self.write_indent();
22220 }
22221 self.write(")");
22222 }
22223 } else {
22224 let is_duckdb = matches!(
22228 self.config.dialect,
22229 Some(crate::dialects::DialectType::DuckDB)
22230 );
22231 let is_clickhouse = matches!(
22232 self.config.dialect,
22233 Some(crate::dialects::DialectType::ClickHouse)
22234 );
22235 let single_expr = in_expr.expressions.len() == 1;
22236 if is_clickhouse && single_expr {
22237 if let Expression::Array(arr) = &in_expr.expressions[0] {
22238 self.write(" (");
22240 for (i, expr) in arr.expressions.iter().enumerate() {
22241 if i > 0 {
22242 self.write(", ");
22243 }
22244 self.generate_expression(expr)?;
22245 }
22246 self.write(")");
22247 } else {
22248 self.write_space();
22249 self.generate_expression(&in_expr.expressions[0])?;
22250 }
22251 } else {
22252 let is_bare_ref = single_expr
22253 && matches!(
22254 &in_expr.expressions[0],
22255 Expression::Column(_) | Expression::Identifier(_) | Expression::Dot(_)
22256 );
22257 if (is_duckdb && is_bare_ref) || (in_expr.is_field && single_expr) {
22258 self.write_space();
22261 self.generate_expression(&in_expr.expressions[0])?;
22262 } else {
22263 self.write(" (");
22265 for (i, expr) in in_expr.expressions.iter().enumerate() {
22266 if i > 0 {
22267 self.write(", ");
22268 }
22269 self.generate_expression(expr)?;
22270 }
22271 self.write(")");
22272 }
22273 }
22274 }
22275
22276 Ok(())
22277 }
22278
22279 fn generate_between(&mut self, between: &Between) -> Result<()> {
22280 let use_prefix_not = between.not
22282 && (self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic));
22283 if use_prefix_not {
22284 self.write_keyword("NOT");
22285 self.write_space();
22286 }
22287 self.generate_expression(&between.this)?;
22288 if between.not && !use_prefix_not {
22289 self.write_space();
22290 self.write_keyword("NOT");
22291 }
22292 self.write_space();
22293 self.write_keyword("BETWEEN");
22294 if let Some(sym) = between.symmetric {
22296 if sym {
22297 self.write(" SYMMETRIC");
22298 } else {
22299 self.write(" ASYMMETRIC");
22300 }
22301 }
22302 self.write_space();
22303 self.generate_expression(&between.low)?;
22304 self.write_space();
22305 self.write_keyword("AND");
22306 self.write_space();
22307 self.generate_expression(&between.high)
22308 }
22309
22310 fn generate_is_null(&mut self, is_null: &IsNull) -> Result<()> {
22311 let use_prefix_not = is_null.not
22313 && (self.config.dialect.is_none()
22314 || self.config.dialect == Some(DialectType::Generic)
22315 || is_null.postfix_form);
22316 if use_prefix_not {
22317 self.write_keyword("NOT");
22319 self.write_space();
22320 self.generate_expression(&is_null.this)?;
22321 self.write_space();
22322 self.write_keyword("IS");
22323 self.write_space();
22324 self.write_keyword("NULL");
22325 } else {
22326 self.generate_expression(&is_null.this)?;
22327 self.write_space();
22328 self.write_keyword("IS");
22329 if is_null.not {
22330 self.write_space();
22331 self.write_keyword("NOT");
22332 }
22333 self.write_space();
22334 self.write_keyword("NULL");
22335 }
22336 Ok(())
22337 }
22338
22339 fn generate_is_true(&mut self, is_true: &IsTrueFalse) -> Result<()> {
22340 self.generate_expression(&is_true.this)?;
22341 self.write_space();
22342 self.write_keyword("IS");
22343 if is_true.not {
22344 self.write_space();
22345 self.write_keyword("NOT");
22346 }
22347 self.write_space();
22348 self.write_keyword("TRUE");
22349 Ok(())
22350 }
22351
22352 fn generate_is_false(&mut self, is_false: &IsTrueFalse) -> Result<()> {
22353 self.generate_expression(&is_false.this)?;
22354 self.write_space();
22355 self.write_keyword("IS");
22356 if is_false.not {
22357 self.write_space();
22358 self.write_keyword("NOT");
22359 }
22360 self.write_space();
22361 self.write_keyword("FALSE");
22362 Ok(())
22363 }
22364
22365 fn generate_is_json(&mut self, is_json: &IsJson) -> Result<()> {
22366 self.generate_expression(&is_json.this)?;
22367 self.write_space();
22368 self.write_keyword("IS");
22369 if is_json.negated {
22370 self.write_space();
22371 self.write_keyword("NOT");
22372 }
22373 self.write_space();
22374 self.write_keyword("JSON");
22375
22376 if let Some(ref json_type) = is_json.json_type {
22378 self.write_space();
22379 self.write_keyword(json_type);
22380 }
22381
22382 match &is_json.unique_keys {
22384 Some(JsonUniqueKeys::With) => {
22385 self.write_space();
22386 self.write_keyword("WITH UNIQUE KEYS");
22387 }
22388 Some(JsonUniqueKeys::Without) => {
22389 self.write_space();
22390 self.write_keyword("WITHOUT UNIQUE KEYS");
22391 }
22392 Some(JsonUniqueKeys::Shorthand) => {
22393 self.write_space();
22394 self.write_keyword("UNIQUE KEYS");
22395 }
22396 None => {}
22397 }
22398
22399 Ok(())
22400 }
22401
22402 fn generate_is(&mut self, is_expr: &BinaryOp) -> Result<()> {
22403 self.generate_expression(&is_expr.left)?;
22404 self.write_space();
22405 self.write_keyword("IS");
22406 self.write_space();
22407 self.generate_expression(&is_expr.right)
22408 }
22409
22410 fn generate_exists(&mut self, exists: &Exists) -> Result<()> {
22411 if exists.not {
22412 self.write_keyword("NOT");
22413 self.write_space();
22414 }
22415 self.write_keyword("EXISTS");
22416 self.write("(");
22417 let is_statement = matches!(
22418 &exists.this,
22419 Expression::Select(_)
22420 | Expression::Union(_)
22421 | Expression::Intersect(_)
22422 | Expression::Except(_)
22423 );
22424 if self.config.pretty && is_statement {
22425 self.write_newline();
22426 self.indent_level += 1;
22427 self.write_indent();
22428 self.generate_expression(&exists.this)?;
22429 self.write_newline();
22430 self.indent_level -= 1;
22431 self.write_indent();
22432 self.write(")");
22433 } else {
22434 self.generate_expression(&exists.this)?;
22435 self.write(")");
22436 }
22437 Ok(())
22438 }
22439
22440 fn generate_member_of(&mut self, op: &BinaryOp) -> Result<()> {
22441 self.generate_expression(&op.left)?;
22442 self.write_space();
22443 self.write_keyword("MEMBER OF");
22444 self.write("(");
22445 self.generate_expression(&op.right)?;
22446 self.write(")");
22447 Ok(())
22448 }
22449
22450 fn generate_subquery(&mut self, subquery: &Subquery) -> Result<()> {
22451 if subquery.lateral {
22452 self.write_keyword("LATERAL");
22453 self.write_space();
22454 }
22455
22456 let skip_outer_parens = if let Expression::Paren(ref p) = &subquery.this {
22460 matches!(
22461 &p.this,
22462 Expression::Select(_)
22463 | Expression::Union(_)
22464 | Expression::Intersect(_)
22465 | Expression::Except(_)
22466 | Expression::Subquery(_)
22467 )
22468 } else {
22469 false
22470 };
22471
22472 let is_statement = matches!(
22474 &subquery.this,
22475 Expression::Select(_)
22476 | Expression::Union(_)
22477 | Expression::Intersect(_)
22478 | Expression::Except(_)
22479 | Expression::Merge(_)
22480 );
22481
22482 if !skip_outer_parens {
22483 self.write("(");
22484 if self.config.pretty && is_statement {
22485 self.write_newline();
22486 self.indent_level += 1;
22487 self.write_indent();
22488 }
22489 }
22490 self.generate_expression(&subquery.this)?;
22491
22492 if subquery.modifiers_inside {
22494 if let Some(order_by) = &subquery.order_by {
22496 self.write_space();
22497 self.write_keyword("ORDER BY");
22498 self.write_space();
22499 for (i, ord) in order_by.expressions.iter().enumerate() {
22500 if i > 0 {
22501 self.write(", ");
22502 }
22503 self.generate_ordered(ord)?;
22504 }
22505 }
22506
22507 if let Some(limit) = &subquery.limit {
22508 self.write_space();
22509 self.write_keyword("LIMIT");
22510 self.write_space();
22511 self.generate_expression(&limit.this)?;
22512 if limit.percent {
22513 self.write_space();
22514 self.write_keyword("PERCENT");
22515 }
22516 }
22517
22518 if let Some(offset) = &subquery.offset {
22519 self.write_space();
22520 self.write_keyword("OFFSET");
22521 self.write_space();
22522 self.generate_expression(&offset.this)?;
22523 }
22524 }
22525
22526 if !skip_outer_parens {
22527 if self.config.pretty && is_statement {
22528 self.write_newline();
22529 self.indent_level -= 1;
22530 self.write_indent();
22531 }
22532 self.write(")");
22533 }
22534
22535 if !subquery.modifiers_inside {
22537 if let Some(order_by) = &subquery.order_by {
22538 self.write_space();
22539 self.write_keyword("ORDER BY");
22540 self.write_space();
22541 for (i, ord) in order_by.expressions.iter().enumerate() {
22542 if i > 0 {
22543 self.write(", ");
22544 }
22545 self.generate_ordered(ord)?;
22546 }
22547 }
22548
22549 if let Some(limit) = &subquery.limit {
22550 self.write_space();
22551 self.write_keyword("LIMIT");
22552 self.write_space();
22553 self.generate_expression(&limit.this)?;
22554 if limit.percent {
22555 self.write_space();
22556 self.write_keyword("PERCENT");
22557 }
22558 }
22559
22560 if let Some(offset) = &subquery.offset {
22561 self.write_space();
22562 self.write_keyword("OFFSET");
22563 self.write_space();
22564 self.generate_expression(&offset.this)?;
22565 }
22566
22567 if let Some(distribute_by) = &subquery.distribute_by {
22569 self.write_space();
22570 self.write_keyword("DISTRIBUTE BY");
22571 self.write_space();
22572 for (i, expr) in distribute_by.expressions.iter().enumerate() {
22573 if i > 0 {
22574 self.write(", ");
22575 }
22576 self.generate_expression(expr)?;
22577 }
22578 }
22579
22580 if let Some(sort_by) = &subquery.sort_by {
22582 self.write_space();
22583 self.write_keyword("SORT BY");
22584 self.write_space();
22585 for (i, ord) in sort_by.expressions.iter().enumerate() {
22586 if i > 0 {
22587 self.write(", ");
22588 }
22589 self.generate_ordered(ord)?;
22590 }
22591 }
22592
22593 if let Some(cluster_by) = &subquery.cluster_by {
22595 self.write_space();
22596 self.write_keyword("CLUSTER BY");
22597 self.write_space();
22598 for (i, ord) in cluster_by.expressions.iter().enumerate() {
22599 if i > 0 {
22600 self.write(", ");
22601 }
22602 self.generate_ordered(ord)?;
22603 }
22604 }
22605 }
22606
22607 if let Some(alias) = &subquery.alias {
22608 self.write_space();
22609 let skip_as = matches!(
22611 self.config.dialect,
22612 Some(crate::dialects::DialectType::Oracle)
22613 );
22614 if !skip_as {
22615 self.write_keyword("AS");
22616 self.write_space();
22617 }
22618 self.generate_identifier(alias)?;
22619 if !subquery.column_aliases.is_empty() {
22620 self.write("(");
22621 for (i, col) in subquery.column_aliases.iter().enumerate() {
22622 if i > 0 {
22623 self.write(", ");
22624 }
22625 self.generate_identifier(col)?;
22626 }
22627 self.write(")");
22628 }
22629 }
22630 for comment in &subquery.trailing_comments {
22632 self.write(" ");
22633 self.write_formatted_comment(comment);
22634 }
22635 Ok(())
22636 }
22637
22638 fn generate_pivot(&mut self, pivot: &Pivot) -> Result<()> {
22639 if let Some(ref with) = pivot.with {
22641 self.generate_with(with)?;
22642 self.write_space();
22643 }
22644
22645 let direction = if pivot.unpivot { "UNPIVOT" } else { "PIVOT" };
22646
22647 let is_redshift_unpivot = pivot.unpivot
22651 && pivot.expressions.is_empty()
22652 && pivot.fields.is_empty()
22653 && pivot.using.is_empty()
22654 && pivot.into.is_none()
22655 && !matches!(&pivot.this, Expression::Null(_));
22656
22657 if is_redshift_unpivot {
22658 self.write_keyword("UNPIVOT");
22660 self.write_space();
22661 self.generate_expression(&pivot.this)?;
22662 if let Some(alias) = &pivot.alias {
22664 self.write_space();
22665 self.write_keyword("AS");
22666 self.write_space();
22667 self.write(&alias.name);
22669 }
22670 return Ok(());
22671 }
22672
22673 let is_simplified = !pivot.using.is_empty()
22675 || pivot.into.is_some()
22676 || (pivot.fields.is_empty()
22677 && !pivot.expressions.is_empty()
22678 && !matches!(&pivot.this, Expression::Null(_)));
22679
22680 if is_simplified {
22681 self.write_keyword(direction);
22685 self.write_space();
22686 self.generate_expression(&pivot.this)?;
22687
22688 if !pivot.expressions.is_empty() {
22689 self.write_space();
22690 self.write_keyword("ON");
22691 self.write_space();
22692 for (i, expr) in pivot.expressions.iter().enumerate() {
22693 if i > 0 {
22694 self.write(", ");
22695 }
22696 self.generate_expression(expr)?;
22697 }
22698 }
22699
22700 if let Some(into) = &pivot.into {
22702 self.write_space();
22703 self.write_keyword("INTO");
22704 self.write_space();
22705 self.generate_expression(into)?;
22706 }
22707
22708 if !pivot.using.is_empty() {
22710 self.write_space();
22711 self.write_keyword("USING");
22712 self.write_space();
22713 for (i, expr) in pivot.using.iter().enumerate() {
22714 if i > 0 {
22715 self.write(", ");
22716 }
22717 self.generate_expression(expr)?;
22718 }
22719 }
22720
22721 if let Some(group) = &pivot.group {
22723 self.write_space();
22724 self.generate_expression(group)?;
22725 }
22726 } else {
22727 if !matches!(&pivot.this, Expression::Null(_)) {
22732 self.generate_expression(&pivot.this)?;
22733 self.write_space();
22734 }
22735 self.write_keyword(direction);
22736 self.write("(");
22737
22738 for (i, expr) in pivot.expressions.iter().enumerate() {
22740 if i > 0 {
22741 self.write(", ");
22742 }
22743 self.generate_expression(expr)?;
22744 }
22745
22746 if !pivot.fields.is_empty() {
22748 if !pivot.expressions.is_empty() {
22749 self.write_space();
22750 }
22751 self.write_keyword("FOR");
22752 self.write_space();
22753 for (i, field) in pivot.fields.iter().enumerate() {
22754 if i > 0 {
22755 self.write_space();
22756 }
22757 self.generate_expression(field)?;
22759 }
22760 }
22761
22762 if let Some(default_val) = &pivot.default_on_null {
22764 self.write_space();
22765 self.write_keyword("DEFAULT ON NULL");
22766 self.write(" (");
22767 self.generate_expression(default_val)?;
22768 self.write(")");
22769 }
22770
22771 if let Some(group) = &pivot.group {
22773 self.write_space();
22774 self.generate_expression(group)?;
22775 }
22776
22777 self.write(")");
22778 }
22779
22780 if let Some(alias) = &pivot.alias {
22782 self.write_space();
22783 self.write_keyword("AS");
22784 self.write_space();
22785 self.generate_identifier(alias)?;
22786 }
22787
22788 Ok(())
22789 }
22790
22791 fn generate_unpivot(&mut self, unpivot: &Unpivot) -> Result<()> {
22792 self.generate_expression(&unpivot.this)?;
22793 self.write_space();
22794 self.write_keyword("UNPIVOT");
22795 if let Some(include) = unpivot.include_nulls {
22797 self.write_space();
22798 if include {
22799 self.write_keyword("INCLUDE NULLS");
22800 } else {
22801 self.write_keyword("EXCLUDE NULLS");
22802 }
22803 self.write_space();
22804 }
22805 self.write("(");
22806 if unpivot.value_column_parenthesized {
22807 self.write("(");
22808 }
22809 self.generate_identifier(&unpivot.value_column)?;
22810 for extra_col in &unpivot.extra_value_columns {
22812 self.write(", ");
22813 self.generate_identifier(extra_col)?;
22814 }
22815 if unpivot.value_column_parenthesized {
22816 self.write(")");
22817 }
22818 self.write_space();
22819 self.write_keyword("FOR");
22820 self.write_space();
22821 self.generate_identifier(&unpivot.name_column)?;
22822 self.write_space();
22823 self.write_keyword("IN");
22824 self.write(" (");
22825 for (i, col) in unpivot.columns.iter().enumerate() {
22826 if i > 0 {
22827 self.write(", ");
22828 }
22829 self.generate_expression(col)?;
22830 }
22831 self.write("))");
22832 if let Some(alias) = &unpivot.alias {
22833 self.write_space();
22834 self.write_keyword("AS");
22835 self.write_space();
22836 self.generate_identifier(alias)?;
22837 }
22838 Ok(())
22839 }
22840
22841 fn generate_values(&mut self, values: &Values) -> Result<()> {
22842 self.write_keyword("VALUES");
22843 for (i, row) in values.expressions.iter().enumerate() {
22844 if i > 0 {
22845 self.write(",");
22846 }
22847 self.write(" (");
22848 for (j, expr) in row.expressions.iter().enumerate() {
22849 if j > 0 {
22850 self.write(", ");
22851 }
22852 self.generate_expression(expr)?;
22853 }
22854 self.write(")");
22855 }
22856 if let Some(alias) = &values.alias {
22857 self.write_space();
22858 self.write_keyword("AS");
22859 self.write_space();
22860 self.generate_identifier(alias)?;
22861 if !values.column_aliases.is_empty() {
22862 self.write("(");
22863 for (i, col) in values.column_aliases.iter().enumerate() {
22864 if i > 0 {
22865 self.write(", ");
22866 }
22867 self.generate_identifier(col)?;
22868 }
22869 self.write(")");
22870 }
22871 }
22872 Ok(())
22873 }
22874
22875 fn generate_array(&mut self, arr: &Array) -> Result<()> {
22876 let needs_inheritance = matches!(
22878 self.config.dialect,
22879 Some(DialectType::DuckDB)
22880 | Some(DialectType::Spark)
22881 | Some(DialectType::Databricks)
22882 | Some(DialectType::Hive)
22883 | Some(DialectType::Snowflake)
22884 | Some(DialectType::Presto)
22885 | Some(DialectType::Trino)
22886 );
22887 let propagated: Vec<Expression>;
22888 let expressions = if needs_inheritance && arr.expressions.len() > 1 {
22889 propagated = Self::inherit_struct_field_names(&arr.expressions);
22890 &propagated
22891 } else {
22892 &arr.expressions
22893 };
22894
22895 let use_parens =
22898 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
22899 if !self.config.array_bracket_only {
22900 self.write_keyword("ARRAY");
22901 }
22902 if use_parens {
22903 self.write("(");
22904 } else {
22905 self.write("[");
22906 }
22907 for (i, expr) in expressions.iter().enumerate() {
22908 if i > 0 {
22909 self.write(", ");
22910 }
22911 self.generate_expression(expr)?;
22912 }
22913 if use_parens {
22914 self.write(")");
22915 } else {
22916 self.write("]");
22917 }
22918 Ok(())
22919 }
22920
22921 fn generate_tuple(&mut self, tuple: &Tuple) -> Result<()> {
22922 if tuple.expressions.len() == 2 {
22925 if let Expression::TableAlias(_) = &tuple.expressions[1] {
22926 self.generate_expression(&tuple.expressions[0])?;
22928 self.write_space();
22929 self.write_keyword("AS");
22930 self.write_space();
22931 self.generate_expression(&tuple.expressions[1])?;
22932 return Ok(());
22933 }
22934 }
22935
22936 let expand_tuple = if self.config.pretty && tuple.expressions.len() > 1 {
22939 let mut expr_strings: Vec<String> = Vec::with_capacity(tuple.expressions.len());
22940 for expr in &tuple.expressions {
22941 expr_strings.push(self.generate_to_string(expr)?);
22942 }
22943 self.too_wide(&expr_strings)
22944 } else {
22945 false
22946 };
22947
22948 if expand_tuple {
22949 self.write("(");
22950 self.write_newline();
22951 self.indent_level += 1;
22952 for (i, expr) in tuple.expressions.iter().enumerate() {
22953 if i > 0 {
22954 self.write(",");
22955 self.write_newline();
22956 }
22957 self.write_indent();
22958 self.generate_expression(expr)?;
22959 }
22960 self.indent_level -= 1;
22961 self.write_newline();
22962 self.write_indent();
22963 self.write(")");
22964 } else {
22965 self.write("(");
22966 for (i, expr) in tuple.expressions.iter().enumerate() {
22967 if i > 0 {
22968 self.write(", ");
22969 }
22970 self.generate_expression(expr)?;
22971 }
22972 self.write(")");
22973 }
22974 Ok(())
22975 }
22976
22977 fn generate_pipe_operator(&mut self, pipe: &PipeOperator) -> Result<()> {
22978 self.generate_expression(&pipe.this)?;
22979 self.write(" |> ");
22980 self.generate_expression(&pipe.expression)?;
22981 Ok(())
22982 }
22983
22984 fn generate_ordered(&mut self, ordered: &Ordered) -> Result<()> {
22985 self.generate_expression(&ordered.this)?;
22986 if ordered.desc {
22987 self.write_space();
22988 self.write_keyword("DESC");
22989 } else if ordered.explicit_asc {
22990 self.write_space();
22991 self.write_keyword("ASC");
22992 }
22993 if let Some(nulls_first) = ordered.nulls_first {
22994 if self.config.null_ordering_supported
22995 || !matches!(self.config.dialect, Some(DialectType::Fabric))
22996 {
22997 let is_asc = !ordered.desc;
23011 let is_nulls_are_large = matches!(
23012 self.config.dialect,
23013 Some(DialectType::Oracle)
23014 | Some(DialectType::PostgreSQL)
23015 | Some(DialectType::Redshift)
23016 | Some(DialectType::Snowflake)
23017 );
23018 let is_nulls_are_last = matches!(
23019 self.config.dialect,
23020 Some(DialectType::Dremio)
23021 | Some(DialectType::DuckDB)
23022 | Some(DialectType::Presto)
23023 | Some(DialectType::Trino)
23024 | Some(DialectType::Athena)
23025 | Some(DialectType::ClickHouse)
23026 | Some(DialectType::Drill)
23027 | Some(DialectType::Exasol)
23028 );
23029
23030 let is_default_nulls = if is_nulls_are_large {
23032 (is_asc && !nulls_first) || (!is_asc && nulls_first)
23034 } else if is_nulls_are_last {
23035 !nulls_first
23037 } else {
23038 false
23039 };
23040
23041 if !is_default_nulls {
23042 self.write_space();
23043 self.write_keyword("NULLS");
23044 self.write_space();
23045 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
23046 }
23047 }
23048 }
23049 if let Some(ref with_fill) = ordered.with_fill {
23051 self.write_space();
23052 self.generate_with_fill(with_fill)?;
23053 }
23054 Ok(())
23055 }
23056
23057 fn write_clickhouse_type(&mut self, type_str: &str) {
23059 if self.clickhouse_nullable_depth < 0 {
23060 self.write(type_str);
23062 } else {
23063 self.write(&format!("Nullable({})", type_str));
23064 }
23065 }
23066
23067 fn generate_data_type(&mut self, dt: &DataType) -> Result<()> {
23068 use crate::dialects::DialectType;
23069
23070 match dt {
23071 DataType::Boolean => {
23072 match self.config.dialect {
23074 Some(DialectType::TSQL) => self.write_keyword("BIT"),
23075 Some(DialectType::MySQL) => self.write_keyword("BOOLEAN"), Some(DialectType::Oracle) => {
23077 self.write_keyword("NUMBER(1)")
23079 }
23080 Some(DialectType::ClickHouse) => self.write("Bool"), _ => self.write_keyword("BOOLEAN"),
23082 }
23083 }
23084 DataType::TinyInt { length } => {
23085 match self.config.dialect {
23089 Some(DialectType::PostgreSQL)
23090 | Some(DialectType::Redshift)
23091 | Some(DialectType::Oracle)
23092 | Some(DialectType::Exasol) => {
23093 self.write_keyword("SMALLINT");
23094 }
23095 Some(DialectType::Teradata) => {
23096 self.write_keyword("BYTEINT");
23098 }
23099 Some(DialectType::Dremio) => {
23100 self.write_keyword("INT");
23102 }
23103 Some(DialectType::ClickHouse) => {
23104 self.write_clickhouse_type("Int8");
23105 }
23106 _ => {
23107 self.write_keyword("TINYINT");
23108 }
23109 }
23110 if let Some(n) = length {
23111 if !matches!(
23112 self.config.dialect,
23113 Some(DialectType::Dremio) | Some(DialectType::ClickHouse)
23114 ) {
23115 self.write(&format!("({})", n));
23116 }
23117 }
23118 }
23119 DataType::SmallInt { length } => {
23120 match self.config.dialect {
23122 Some(DialectType::Dremio) => {
23123 self.write_keyword("INT");
23124 }
23125 Some(DialectType::SQLite) | Some(DialectType::Drill) => {
23126 self.write_keyword("INTEGER");
23127 }
23128 Some(DialectType::BigQuery) => {
23129 self.write_keyword("INT64");
23130 }
23131 Some(DialectType::ClickHouse) => {
23132 self.write_clickhouse_type("Int16");
23133 }
23134 _ => {
23135 self.write_keyword("SMALLINT");
23136 if let Some(n) = length {
23137 self.write(&format!("({})", n));
23138 }
23139 }
23140 }
23141 }
23142 DataType::Int {
23143 length,
23144 integer_spelling: _,
23145 } => {
23146 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
23148 self.write_keyword("INT64");
23149 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23150 self.write_clickhouse_type("Int32");
23151 } else {
23152 let use_integer = match self.config.dialect {
23154 Some(DialectType::TSQL)
23155 | Some(DialectType::Fabric)
23156 | Some(DialectType::Presto)
23157 | Some(DialectType::Trino)
23158 | Some(DialectType::SQLite)
23159 | Some(DialectType::Redshift) => true,
23160 _ => false,
23161 };
23162 if use_integer {
23163 self.write_keyword("INTEGER");
23164 } else {
23165 self.write_keyword("INT");
23166 }
23167 if let Some(n) = length {
23168 self.write(&format!("({})", n));
23169 }
23170 }
23171 }
23172 DataType::BigInt { length } => {
23173 match self.config.dialect {
23175 Some(DialectType::Oracle) => {
23176 self.write_keyword("INT");
23178 }
23179 Some(DialectType::ClickHouse) => {
23180 self.write_clickhouse_type("Int64");
23181 }
23182 _ => {
23183 self.write_keyword("BIGINT");
23184 if let Some(n) = length {
23185 self.write(&format!("({})", n));
23186 }
23187 }
23188 }
23189 }
23190 DataType::Float {
23191 precision,
23192 scale,
23193 real_spelling,
23194 } => {
23195 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23199 self.write_clickhouse_type("Float32");
23200 } else if *real_spelling
23201 && !matches!(
23202 self.config.dialect,
23203 Some(DialectType::Spark)
23204 | Some(DialectType::Databricks)
23205 | Some(DialectType::Hive)
23206 | Some(DialectType::Snowflake)
23207 | Some(DialectType::MySQL)
23208 | Some(DialectType::BigQuery)
23209 )
23210 {
23211 self.write_keyword("REAL")
23212 } else {
23213 match self.config.dialect {
23214 Some(DialectType::PostgreSQL) => self.write_keyword("REAL"),
23215 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
23216 _ => self.write_keyword("FLOAT"),
23217 }
23218 }
23219 if !matches!(
23222 self.config.dialect,
23223 Some(DialectType::Spark)
23224 | Some(DialectType::Databricks)
23225 | Some(DialectType::Hive)
23226 | Some(DialectType::Presto)
23227 | Some(DialectType::Trino)
23228 ) {
23229 if let Some(p) = precision {
23230 self.write(&format!("({}", p));
23231 if let Some(s) = scale {
23232 self.write(&format!(", {})", s));
23233 } else {
23234 self.write(")");
23235 }
23236 }
23237 }
23238 }
23239 DataType::Double { precision, scale } => {
23240 match self.config.dialect {
23242 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23243 self.write_keyword("FLOAT")
23244 } Some(DialectType::Oracle) => self.write_keyword("DOUBLE PRECISION"),
23246 Some(DialectType::ClickHouse) => self.write_clickhouse_type("Float64"),
23247 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
23248 Some(DialectType::SQLite) => self.write_keyword("REAL"),
23249 Some(DialectType::PostgreSQL)
23250 | Some(DialectType::Redshift)
23251 | Some(DialectType::Teradata)
23252 | Some(DialectType::Materialize) => self.write_keyword("DOUBLE PRECISION"),
23253 _ => self.write_keyword("DOUBLE"),
23254 }
23255 if let Some(p) = precision {
23257 self.write(&format!("({}", p));
23258 if let Some(s) = scale {
23259 self.write(&format!(", {})", s));
23260 } else {
23261 self.write(")");
23262 }
23263 }
23264 }
23265 DataType::Decimal { precision, scale } => {
23266 match self.config.dialect {
23268 Some(DialectType::ClickHouse) => {
23269 self.write("Decimal");
23270 if let Some(p) = precision {
23271 self.write(&format!("({}", p));
23272 if let Some(s) = scale {
23273 self.write(&format!(", {}", s));
23274 }
23275 self.write(")");
23276 }
23277 }
23278 Some(DialectType::Oracle) => {
23279 self.write_keyword("NUMBER");
23281 if let Some(p) = precision {
23282 self.write(&format!("({}", p));
23283 if let Some(s) = scale {
23284 self.write(&format!(", {}", s));
23285 }
23286 self.write(")");
23287 }
23288 }
23289 Some(DialectType::BigQuery) => {
23290 self.write_keyword("NUMERIC");
23292 if let Some(p) = precision {
23293 self.write(&format!("({}", p));
23294 if let Some(s) = scale {
23295 self.write(&format!(", {}", s));
23296 }
23297 self.write(")");
23298 }
23299 }
23300 _ => {
23301 self.write_keyword("DECIMAL");
23302 if let Some(p) = precision {
23303 self.write(&format!("({}", p));
23304 if let Some(s) = scale {
23305 self.write(&format!(", {}", s));
23306 }
23307 self.write(")");
23308 }
23309 }
23310 }
23311 }
23312 DataType::Char { length } => {
23313 match self.config.dialect {
23315 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
23316 self.write_keyword("TEXT");
23318 }
23319 Some(DialectType::Hive)
23320 | Some(DialectType::Spark)
23321 | Some(DialectType::Databricks) => {
23322 if length.is_some()
23325 && !matches!(self.config.dialect, Some(DialectType::Hive))
23326 {
23327 self.write_keyword("CHAR");
23328 if let Some(n) = length {
23329 self.write(&format!("({})", n));
23330 }
23331 } else {
23332 self.write_keyword("STRING");
23333 }
23334 }
23335 Some(DialectType::Dremio) => {
23336 self.write_keyword("VARCHAR");
23338 if let Some(n) = length {
23339 self.write(&format!("({})", n));
23340 }
23341 }
23342 _ => {
23343 self.write_keyword("CHAR");
23344 if let Some(n) = length {
23345 self.write(&format!("({})", n));
23346 }
23347 }
23348 }
23349 }
23350 DataType::VarChar {
23351 length,
23352 parenthesized_length,
23353 } => {
23354 match self.config.dialect {
23356 Some(DialectType::Oracle) => {
23357 self.write_keyword("VARCHAR2");
23358 if let Some(n) = length {
23359 self.write(&format!("({})", n));
23360 }
23361 }
23362 Some(DialectType::DuckDB) => {
23363 self.write_keyword("TEXT");
23365 if let Some(n) = length {
23366 self.write(&format!("({})", n));
23367 }
23368 }
23369 Some(DialectType::SQLite) => {
23370 self.write_keyword("TEXT");
23372 if let Some(n) = length {
23373 self.write(&format!("({})", n));
23374 }
23375 }
23376 Some(DialectType::MySQL) if length.is_none() => {
23377 self.write_keyword("TEXT");
23379 }
23380 Some(DialectType::Hive)
23381 | Some(DialectType::Spark)
23382 | Some(DialectType::Databricks)
23383 if length.is_none() =>
23384 {
23385 self.write_keyword("STRING");
23387 }
23388 _ => {
23389 self.write_keyword("VARCHAR");
23390 if let Some(n) = length {
23391 if *parenthesized_length {
23393 self.write(&format!("(({}))", n));
23394 } else {
23395 self.write(&format!("({})", n));
23396 }
23397 }
23398 }
23399 }
23400 }
23401 DataType::Text => {
23402 match self.config.dialect {
23404 Some(DialectType::Oracle) => self.write_keyword("CLOB"),
23405 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23406 self.write_keyword("VARCHAR(MAX)")
23407 }
23408 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
23409 Some(DialectType::Snowflake)
23410 | Some(DialectType::Dremio)
23411 | Some(DialectType::Drill) => self.write_keyword("VARCHAR"),
23412 Some(DialectType::Exasol) => self.write_keyword("LONG VARCHAR"),
23413 Some(DialectType::Presto)
23414 | Some(DialectType::Trino)
23415 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
23416 Some(DialectType::Spark)
23417 | Some(DialectType::Databricks)
23418 | Some(DialectType::Hive) => self.write_keyword("STRING"),
23419 Some(DialectType::Redshift) => self.write_keyword("VARCHAR(MAX)"),
23420 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
23421 self.write_keyword("STRING")
23422 }
23423 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
23424 _ => self.write_keyword("TEXT"),
23425 }
23426 }
23427 DataType::TextWithLength { length } => {
23428 match self.config.dialect {
23430 Some(DialectType::Oracle) => self.write(&format!("CLOB({})", length)),
23431 Some(DialectType::Hive)
23432 | Some(DialectType::Spark)
23433 | Some(DialectType::Databricks) => {
23434 self.write(&format!("VARCHAR({})", length));
23435 }
23436 Some(DialectType::Redshift) => self.write(&format!("VARCHAR({})", length)),
23437 Some(DialectType::BigQuery) => self.write(&format!("STRING({})", length)),
23438 Some(DialectType::Snowflake)
23439 | Some(DialectType::Presto)
23440 | Some(DialectType::Trino)
23441 | Some(DialectType::Athena)
23442 | Some(DialectType::Drill)
23443 | Some(DialectType::Dremio) => {
23444 self.write(&format!("VARCHAR({})", length));
23445 }
23446 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23447 self.write(&format!("VARCHAR({})", length))
23448 }
23449 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
23450 self.write(&format!("STRING({})", length))
23451 }
23452 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
23453 _ => self.write(&format!("TEXT({})", length)),
23454 }
23455 }
23456 DataType::String { length } => {
23457 match self.config.dialect {
23459 Some(DialectType::ClickHouse) => {
23460 self.write("String");
23462 if let Some(n) = length {
23463 self.write(&format!("({})", n));
23464 }
23465 }
23466 Some(DialectType::BigQuery)
23467 | Some(DialectType::Hive)
23468 | Some(DialectType::Spark)
23469 | Some(DialectType::Databricks)
23470 | Some(DialectType::StarRocks)
23471 | Some(DialectType::Doris) => {
23472 self.write_keyword("STRING");
23473 if let Some(n) = length {
23474 self.write(&format!("({})", n));
23475 }
23476 }
23477 Some(DialectType::PostgreSQL) => {
23478 if let Some(n) = length {
23480 self.write_keyword("VARCHAR");
23481 self.write(&format!("({})", n));
23482 } else {
23483 self.write_keyword("TEXT");
23484 }
23485 }
23486 Some(DialectType::Redshift) => {
23487 if let Some(n) = length {
23489 self.write_keyword("VARCHAR");
23490 self.write(&format!("({})", n));
23491 } else {
23492 self.write_keyword("VARCHAR(MAX)");
23493 }
23494 }
23495 Some(DialectType::MySQL) => {
23496 if let Some(n) = length {
23498 self.write_keyword("VARCHAR");
23499 self.write(&format!("({})", n));
23500 } else {
23501 self.write_keyword("TEXT");
23502 }
23503 }
23504 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23505 if let Some(n) = length {
23507 self.write_keyword("VARCHAR");
23508 self.write(&format!("({})", n));
23509 } else {
23510 self.write_keyword("VARCHAR(MAX)");
23511 }
23512 }
23513 Some(DialectType::Oracle) => {
23514 self.write_keyword("CLOB");
23516 }
23517 Some(DialectType::DuckDB) | Some(DialectType::Materialize) => {
23518 self.write_keyword("TEXT");
23520 if let Some(n) = length {
23521 self.write(&format!("({})", n));
23522 }
23523 }
23524 Some(DialectType::Presto)
23525 | Some(DialectType::Trino)
23526 | Some(DialectType::Drill)
23527 | Some(DialectType::Dremio) => {
23528 self.write_keyword("VARCHAR");
23530 if let Some(n) = length {
23531 self.write(&format!("({})", n));
23532 }
23533 }
23534 Some(DialectType::Snowflake) => {
23535 self.write_keyword("STRING");
23538 if let Some(n) = length {
23539 self.write(&format!("({})", n));
23540 }
23541 }
23542 _ => {
23543 self.write_keyword("STRING");
23545 if let Some(n) = length {
23546 self.write(&format!("({})", n));
23547 }
23548 }
23549 }
23550 }
23551 DataType::Binary { length } => {
23552 match self.config.dialect {
23554 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
23555 self.write_keyword("BYTEA");
23556 if let Some(n) = length {
23557 self.write(&format!("({})", n));
23558 }
23559 }
23560 Some(DialectType::Redshift) => {
23561 self.write_keyword("VARBYTE");
23562 if let Some(n) = length {
23563 self.write(&format!("({})", n));
23564 }
23565 }
23566 Some(DialectType::DuckDB)
23567 | Some(DialectType::SQLite)
23568 | Some(DialectType::Oracle) => {
23569 self.write_keyword("BLOB");
23571 if let Some(n) = length {
23572 self.write(&format!("({})", n));
23573 }
23574 }
23575 Some(DialectType::Presto)
23576 | Some(DialectType::Trino)
23577 | Some(DialectType::Athena)
23578 | Some(DialectType::Drill)
23579 | Some(DialectType::Dremio) => {
23580 self.write_keyword("VARBINARY");
23582 if let Some(n) = length {
23583 self.write(&format!("({})", n));
23584 }
23585 }
23586 Some(DialectType::ClickHouse) => {
23587 if self.clickhouse_nullable_depth < 0 {
23589 self.write("BINARY");
23590 } else {
23591 self.write("Nullable(BINARY");
23592 }
23593 if let Some(n) = length {
23594 self.write(&format!("({})", n));
23595 }
23596 if self.clickhouse_nullable_depth >= 0 {
23597 self.write(")");
23598 }
23599 }
23600 _ => {
23601 self.write_keyword("BINARY");
23602 if let Some(n) = length {
23603 self.write(&format!("({})", n));
23604 }
23605 }
23606 }
23607 }
23608 DataType::VarBinary { length } => {
23609 match self.config.dialect {
23611 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
23612 self.write_keyword("BYTEA");
23613 if let Some(n) = length {
23614 self.write(&format!("({})", n));
23615 }
23616 }
23617 Some(DialectType::Redshift) => {
23618 self.write_keyword("VARBYTE");
23619 if let Some(n) = length {
23620 self.write(&format!("({})", n));
23621 }
23622 }
23623 Some(DialectType::DuckDB)
23624 | Some(DialectType::SQLite)
23625 | Some(DialectType::Oracle) => {
23626 self.write_keyword("BLOB");
23628 if let Some(n) = length {
23629 self.write(&format!("({})", n));
23630 }
23631 }
23632 Some(DialectType::Exasol) => {
23633 self.write_keyword("VARCHAR");
23635 }
23636 Some(DialectType::Spark)
23637 | Some(DialectType::Hive)
23638 | Some(DialectType::Databricks) => {
23639 self.write_keyword("BINARY");
23641 if let Some(n) = length {
23642 self.write(&format!("({})", n));
23643 }
23644 }
23645 Some(DialectType::ClickHouse) => {
23646 self.write_clickhouse_type("String");
23648 }
23649 _ => {
23650 self.write_keyword("VARBINARY");
23651 if let Some(n) = length {
23652 self.write(&format!("({})", n));
23653 }
23654 }
23655 }
23656 }
23657 DataType::Blob => {
23658 match self.config.dialect {
23660 Some(DialectType::PostgreSQL) => self.write_keyword("BYTEA"),
23661 Some(DialectType::Redshift) => self.write_keyword("VARBYTE"),
23662 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23663 self.write_keyword("VARBINARY")
23664 }
23665 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
23666 Some(DialectType::Exasol) => self.write_keyword("VARCHAR"),
23667 Some(DialectType::Presto)
23668 | Some(DialectType::Trino)
23669 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
23670 Some(DialectType::DuckDB) => {
23671 self.write_keyword("VARBINARY");
23674 }
23675 Some(DialectType::Spark)
23676 | Some(DialectType::Databricks)
23677 | Some(DialectType::Hive) => self.write_keyword("BINARY"),
23678 Some(DialectType::ClickHouse) => {
23679 self.write("Nullable(String)");
23683 }
23684 _ => self.write_keyword("BLOB"),
23685 }
23686 }
23687 DataType::Bit { length } => {
23688 match self.config.dialect {
23690 Some(DialectType::Dremio)
23691 | Some(DialectType::Spark)
23692 | Some(DialectType::Databricks)
23693 | Some(DialectType::Hive)
23694 | Some(DialectType::Snowflake)
23695 | Some(DialectType::BigQuery)
23696 | Some(DialectType::Presto)
23697 | Some(DialectType::Trino)
23698 | Some(DialectType::ClickHouse)
23699 | Some(DialectType::Redshift) => {
23700 self.write_keyword("BOOLEAN");
23702 }
23703 _ => {
23704 self.write_keyword("BIT");
23705 if let Some(n) = length {
23706 self.write(&format!("({})", n));
23707 }
23708 }
23709 }
23710 }
23711 DataType::VarBit { length } => {
23712 self.write_keyword("VARBIT");
23713 if let Some(n) = length {
23714 self.write(&format!("({})", n));
23715 }
23716 }
23717 DataType::Date => self.write_keyword("DATE"),
23718 DataType::Time {
23719 precision,
23720 timezone,
23721 } => {
23722 if *timezone {
23723 match self.config.dialect {
23725 Some(DialectType::DuckDB) => {
23726 self.write_keyword("TIMETZ");
23728 }
23729 Some(DialectType::PostgreSQL) => {
23730 self.write_keyword("TIMETZ");
23732 if let Some(p) = precision {
23733 self.write(&format!("({})", p));
23734 }
23735 }
23736 _ => {
23737 self.write_keyword("TIME");
23739 if let Some(p) = precision {
23740 self.write(&format!("({})", p));
23741 }
23742 self.write_keyword(" WITH TIME ZONE");
23743 }
23744 }
23745 } else {
23746 if matches!(
23748 self.config.dialect,
23749 Some(DialectType::Spark)
23750 | Some(DialectType::Databricks)
23751 | Some(DialectType::Hive)
23752 ) {
23753 self.write_keyword("TIMESTAMP");
23754 } else {
23755 self.write_keyword("TIME");
23756 if let Some(p) = precision {
23757 self.write(&format!("({})", p));
23758 }
23759 }
23760 }
23761 }
23762 DataType::Timestamp {
23763 precision,
23764 timezone,
23765 } => {
23766 match self.config.dialect {
23768 Some(DialectType::ClickHouse) => {
23769 self.write("DateTime");
23770 if let Some(p) = precision {
23771 self.write(&format!("({})", p));
23772 }
23773 }
23774 Some(DialectType::TSQL) => {
23775 if *timezone {
23776 self.write_keyword("DATETIMEOFFSET");
23777 } else {
23778 self.write_keyword("DATETIME2");
23779 }
23780 if let Some(p) = precision {
23781 self.write(&format!("({})", p));
23782 }
23783 }
23784 Some(DialectType::MySQL) => {
23785 self.write_keyword("TIMESTAMP");
23787 if let Some(p) = precision {
23788 self.write(&format!("({})", p));
23789 }
23790 }
23791 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
23792 self.write_keyword("DATETIME");
23794 if let Some(p) = precision {
23795 self.write(&format!("({})", p));
23796 }
23797 }
23798 Some(DialectType::BigQuery) => {
23799 if *timezone {
23801 self.write_keyword("TIMESTAMP");
23802 } else {
23803 self.write_keyword("DATETIME");
23804 }
23805 }
23806 Some(DialectType::DuckDB) => {
23807 if *timezone {
23809 self.write_keyword("TIMESTAMPTZ");
23810 } else {
23811 self.write_keyword("TIMESTAMP");
23812 if let Some(p) = precision {
23813 self.write(&format!("({})", p));
23814 }
23815 }
23816 }
23817 _ => {
23818 if *timezone && !self.config.tz_to_with_time_zone {
23819 self.write_keyword("TIMESTAMPTZ");
23821 if let Some(p) = precision {
23822 self.write(&format!("({})", p));
23823 }
23824 } else {
23825 self.write_keyword("TIMESTAMP");
23826 if let Some(p) = precision {
23827 self.write(&format!("({})", p));
23828 }
23829 if *timezone {
23830 self.write_space();
23831 self.write_keyword("WITH TIME ZONE");
23832 }
23833 }
23834 }
23835 }
23836 }
23837 DataType::Interval { unit, to } => {
23838 self.write_keyword("INTERVAL");
23839 if let Some(u) = unit {
23840 self.write_space();
23841 self.write_keyword(u);
23842 }
23843 if let Some(t) = to {
23845 self.write_space();
23846 self.write_keyword("TO");
23847 self.write_space();
23848 self.write_keyword(t);
23849 }
23850 }
23851 DataType::Json => {
23852 match self.config.dialect {
23854 Some(DialectType::Oracle) => self.write_keyword("JSON"), Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"), Some(DialectType::MySQL) => self.write_keyword("JSON"),
23857 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
23858 _ => self.write_keyword("JSON"),
23859 }
23860 }
23861 DataType::JsonB => {
23862 match self.config.dialect {
23864 Some(DialectType::PostgreSQL) => self.write_keyword("JSONB"),
23865 Some(DialectType::Doris) => self.write_keyword("JSONB"),
23866 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
23867 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
23868 Some(DialectType::DuckDB) => self.write_keyword("JSON"), _ => self.write_keyword("JSON"), }
23871 }
23872 DataType::Uuid => {
23873 match self.config.dialect {
23875 Some(DialectType::TSQL) => self.write_keyword("UNIQUEIDENTIFIER"),
23876 Some(DialectType::MySQL) => self.write_keyword("CHAR(36)"),
23877 Some(DialectType::Oracle) => self.write_keyword("RAW(16)"),
23878 Some(DialectType::BigQuery)
23879 | Some(DialectType::Spark)
23880 | Some(DialectType::Databricks) => self.write_keyword("STRING"),
23881 _ => self.write_keyword("UUID"),
23882 }
23883 }
23884 DataType::Array {
23885 element_type,
23886 dimension,
23887 } => {
23888 match self.config.dialect {
23890 Some(DialectType::PostgreSQL)
23891 | Some(DialectType::Redshift)
23892 | Some(DialectType::DuckDB) => {
23893 self.generate_data_type(element_type)?;
23895 if let Some(dim) = dimension {
23896 self.write(&format!("[{}]", dim));
23897 } else {
23898 self.write("[]");
23899 }
23900 }
23901 Some(DialectType::BigQuery) => {
23902 self.write_keyword("ARRAY<");
23903 self.generate_data_type(element_type)?;
23904 self.write(">");
23905 }
23906 Some(DialectType::Snowflake)
23907 | Some(DialectType::Presto)
23908 | Some(DialectType::Trino)
23909 | Some(DialectType::ClickHouse) => {
23910 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23912 self.write("Array(");
23913 } else {
23914 self.write_keyword("ARRAY(");
23915 }
23916 self.generate_data_type(element_type)?;
23917 self.write(")");
23918 }
23919 Some(DialectType::TSQL)
23920 | Some(DialectType::MySQL)
23921 | Some(DialectType::Oracle) => {
23922 match self.config.dialect {
23925 Some(DialectType::MySQL) => self.write_keyword("JSON"),
23926 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
23927 _ => self.write_keyword("JSON"),
23928 }
23929 }
23930 _ => {
23931 self.write_keyword("ARRAY<");
23933 self.generate_data_type(element_type)?;
23934 self.write(">");
23935 }
23936 }
23937 }
23938 DataType::List { element_type } => {
23939 self.generate_data_type(element_type)?;
23941 self.write_keyword(" LIST");
23942 }
23943 DataType::Map {
23944 key_type,
23945 value_type,
23946 } => {
23947 match self.config.dialect {
23949 Some(DialectType::Materialize) => {
23950 self.write_keyword("MAP[");
23952 self.generate_data_type(key_type)?;
23953 self.write(" => ");
23954 self.generate_data_type(value_type)?;
23955 self.write("]");
23956 }
23957 Some(DialectType::Snowflake)
23958 | Some(DialectType::RisingWave)
23959 | Some(DialectType::DuckDB)
23960 | Some(DialectType::Presto)
23961 | Some(DialectType::Trino)
23962 | Some(DialectType::Athena) => {
23963 self.write_keyword("MAP(");
23964 self.generate_data_type(key_type)?;
23965 self.write(", ");
23966 self.generate_data_type(value_type)?;
23967 self.write(")");
23968 }
23969 Some(DialectType::ClickHouse) => {
23970 self.write("Map(");
23973 self.clickhouse_nullable_depth = -1; self.generate_data_type(key_type)?;
23975 self.clickhouse_nullable_depth = 0;
23976 self.write(", ");
23977 self.generate_data_type(value_type)?;
23978 self.write(")");
23979 }
23980 _ => {
23981 self.write_keyword("MAP<");
23982 self.generate_data_type(key_type)?;
23983 self.write(", ");
23984 self.generate_data_type(value_type)?;
23985 self.write(">");
23986 }
23987 }
23988 }
23989 DataType::Vector {
23990 element_type,
23991 dimension,
23992 } => {
23993 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
23994 self.write_keyword("VECTOR(");
23996 if let Some(dim) = dimension {
23997 self.write(&dim.to_string());
23998 }
23999 let type_alias = element_type.as_ref().and_then(|et| match et.as_ref() {
24001 DataType::TinyInt { .. } => Some("I8"),
24002 DataType::SmallInt { .. } => Some("I16"),
24003 DataType::Int { .. } => Some("I32"),
24004 DataType::BigInt { .. } => Some("I64"),
24005 DataType::Float { .. } => Some("F32"),
24006 DataType::Double { .. } => Some("F64"),
24007 _ => None,
24008 });
24009 if let Some(alias) = type_alias {
24010 if dimension.is_some() {
24011 self.write(", ");
24012 }
24013 self.write(alias);
24014 }
24015 self.write(")");
24016 } else {
24017 self.write_keyword("VECTOR(");
24019 if let Some(ref et) = element_type {
24020 self.generate_data_type(et)?;
24021 if dimension.is_some() {
24022 self.write(", ");
24023 }
24024 }
24025 if let Some(dim) = dimension {
24026 self.write(&dim.to_string());
24027 }
24028 self.write(")");
24029 }
24030 }
24031 DataType::Object { fields, modifier } => {
24032 self.write_keyword("OBJECT(");
24033 for (i, (name, dt, not_null)) in fields.iter().enumerate() {
24034 if i > 0 {
24035 self.write(", ");
24036 }
24037 self.write(name);
24038 self.write(" ");
24039 self.generate_data_type(dt)?;
24040 if *not_null {
24041 self.write_keyword(" NOT NULL");
24042 }
24043 }
24044 self.write(")");
24045 if let Some(mod_str) = modifier {
24046 self.write(" ");
24047 self.write_keyword(mod_str);
24048 }
24049 }
24050 DataType::Struct { fields, nested } => {
24051 match self.config.dialect {
24053 Some(DialectType::Snowflake) => {
24054 self.write_keyword("OBJECT(");
24056 for (i, field) in fields.iter().enumerate() {
24057 if i > 0 {
24058 self.write(", ");
24059 }
24060 if !field.name.is_empty() {
24061 self.write(&field.name);
24062 self.write(" ");
24063 }
24064 self.generate_data_type(&field.data_type)?;
24065 }
24066 self.write(")");
24067 }
24068 Some(DialectType::Presto) | Some(DialectType::Trino) => {
24069 self.write_keyword("ROW(");
24071 for (i, field) in fields.iter().enumerate() {
24072 if i > 0 {
24073 self.write(", ");
24074 }
24075 if !field.name.is_empty() {
24076 self.write(&field.name);
24077 self.write(" ");
24078 }
24079 self.generate_data_type(&field.data_type)?;
24080 }
24081 self.write(")");
24082 }
24083 Some(DialectType::DuckDB) => {
24084 self.write_keyword("STRUCT(");
24086 for (i, field) in fields.iter().enumerate() {
24087 if i > 0 {
24088 self.write(", ");
24089 }
24090 if !field.name.is_empty() {
24091 self.write(&field.name);
24092 self.write(" ");
24093 }
24094 self.generate_data_type(&field.data_type)?;
24095 }
24096 self.write(")");
24097 }
24098 Some(DialectType::ClickHouse) => {
24099 self.write("Tuple(");
24101 for (i, field) in fields.iter().enumerate() {
24102 if i > 0 {
24103 self.write(", ");
24104 }
24105 if !field.name.is_empty() {
24106 self.write(&field.name);
24107 self.write(" ");
24108 }
24109 self.generate_data_type(&field.data_type)?;
24110 }
24111 self.write(")");
24112 }
24113 Some(DialectType::SingleStore) => {
24114 self.write_keyword("RECORD(");
24116 for (i, field) in fields.iter().enumerate() {
24117 if i > 0 {
24118 self.write(", ");
24119 }
24120 if !field.name.is_empty() {
24121 self.write(&field.name);
24122 self.write(" ");
24123 }
24124 self.generate_data_type(&field.data_type)?;
24125 }
24126 self.write(")");
24127 }
24128 _ => {
24129 let force_angle_brackets = matches!(
24131 self.config.dialect,
24132 Some(DialectType::Hive)
24133 | Some(DialectType::Spark)
24134 | Some(DialectType::Databricks)
24135 );
24136 if *nested && !force_angle_brackets {
24137 self.write_keyword("STRUCT(");
24138 for (i, field) in fields.iter().enumerate() {
24139 if i > 0 {
24140 self.write(", ");
24141 }
24142 if !field.name.is_empty() {
24143 self.write(&field.name);
24144 self.write(" ");
24145 }
24146 self.generate_data_type(&field.data_type)?;
24147 }
24148 self.write(")");
24149 } else {
24150 self.write_keyword("STRUCT<");
24151 for (i, field) in fields.iter().enumerate() {
24152 if i > 0 {
24153 self.write(", ");
24154 }
24155 if !field.name.is_empty() {
24156 self.write(&field.name);
24158 self.write(self.config.struct_field_sep);
24159 }
24160 self.generate_data_type(&field.data_type)?;
24162 if let Some(comment) = &field.comment {
24164 self.write(" COMMENT '");
24165 self.write(comment);
24166 self.write("'");
24167 }
24168 if !field.options.is_empty() {
24170 self.write(" ");
24171 self.generate_options_clause(&field.options)?;
24172 }
24173 }
24174 self.write(">");
24175 }
24176 }
24177 }
24178 }
24179 DataType::Enum {
24180 values,
24181 assignments,
24182 } => {
24183 if self.config.dialect == Some(DialectType::ClickHouse) {
24186 self.write("Enum(");
24187 } else {
24188 self.write_keyword("ENUM(");
24189 }
24190 for (i, val) in values.iter().enumerate() {
24191 if i > 0 {
24192 self.write(", ");
24193 }
24194 self.write("'");
24195 self.write(val);
24196 self.write("'");
24197 if let Some(Some(assignment)) = assignments.get(i) {
24198 self.write(" = ");
24199 self.write(assignment);
24200 }
24201 }
24202 self.write(")");
24203 }
24204 DataType::Set { values } => {
24205 self.write_keyword("SET(");
24207 for (i, val) in values.iter().enumerate() {
24208 if i > 0 {
24209 self.write(", ");
24210 }
24211 self.write("'");
24212 self.write(val);
24213 self.write("'");
24214 }
24215 self.write(")");
24216 }
24217 DataType::Union { fields } => {
24218 self.write_keyword("UNION(");
24220 for (i, (name, dt)) in fields.iter().enumerate() {
24221 if i > 0 {
24222 self.write(", ");
24223 }
24224 if !name.is_empty() {
24225 self.write(name);
24226 self.write(" ");
24227 }
24228 self.generate_data_type(dt)?;
24229 }
24230 self.write(")");
24231 }
24232 DataType::Nullable { inner } => {
24233 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
24235 self.write("Nullable(");
24236 let saved_depth = self.clickhouse_nullable_depth;
24238 self.clickhouse_nullable_depth = -1;
24239 self.generate_data_type(inner)?;
24240 self.clickhouse_nullable_depth = saved_depth;
24241 self.write(")");
24242 } else {
24243 match inner.as_ref() {
24245 DataType::Custom { name } if name.eq_ignore_ascii_case("DATETIME") => {
24246 self.generate_data_type(&DataType::Timestamp {
24247 precision: None,
24248 timezone: false,
24249 })?;
24250 }
24251 _ => {
24252 self.generate_data_type(inner)?;
24253 }
24254 }
24255 }
24256 }
24257 DataType::Custom { name } => {
24258 let name_upper = name.to_ascii_uppercase();
24260 match self.config.dialect {
24261 Some(DialectType::ClickHouse) => {
24262 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
24263 (name_upper[..idx].to_string(), &name[idx..])
24264 } else {
24265 (name_upper.clone(), "")
24266 };
24267 let mapped = match base_upper.as_str() {
24268 "DATETIME" | "TIMESTAMPTZ" | "TIMESTAMP" | "TIMESTAMPNTZ"
24269 | "SMALLDATETIME" | "DATETIME2" => "DateTime",
24270 "DATETIME64" => "DateTime64",
24271 "DATE32" => "Date32",
24272 "INT" => "Int32",
24273 "MEDIUMINT" => "Int32",
24274 "INT8" => "Int8",
24275 "INT16" => "Int16",
24276 "INT32" => "Int32",
24277 "INT64" => "Int64",
24278 "INT128" => "Int128",
24279 "INT256" => "Int256",
24280 "UINT8" => "UInt8",
24281 "UINT16" => "UInt16",
24282 "UINT32" => "UInt32",
24283 "UINT64" => "UInt64",
24284 "UINT128" => "UInt128",
24285 "UINT256" => "UInt256",
24286 "FLOAT32" => "Float32",
24287 "FLOAT64" => "Float64",
24288 "DECIMAL32" => "Decimal32",
24289 "DECIMAL64" => "Decimal64",
24290 "DECIMAL128" => "Decimal128",
24291 "DECIMAL256" => "Decimal256",
24292 "ENUM" => "Enum",
24293 "ENUM8" => "Enum8",
24294 "ENUM16" => "Enum16",
24295 "FIXEDSTRING" => "FixedString",
24296 "NESTED" => "Nested",
24297 "LOWCARDINALITY" => "LowCardinality",
24298 "NULLABLE" => "Nullable",
24299 "IPV4" => "IPv4",
24300 "IPV6" => "IPv6",
24301 "POINT" => "Point",
24302 "RING" => "Ring",
24303 "LINESTRING" => "LineString",
24304 "MULTILINESTRING" => "MultiLineString",
24305 "POLYGON" => "Polygon",
24306 "MULTIPOLYGON" => "MultiPolygon",
24307 "AGGREGATEFUNCTION" => "AggregateFunction",
24308 "SIMPLEAGGREGATEFUNCTION" => "SimpleAggregateFunction",
24309 "DYNAMIC" => "Dynamic",
24310 _ => "",
24311 };
24312 if mapped.is_empty() {
24313 self.write(name);
24314 } else {
24315 self.write(mapped);
24316 self.write(suffix);
24317 }
24318 }
24319 Some(DialectType::MySQL)
24320 if name_upper == "TIMESTAMPTZ" || name_upper == "TIMESTAMPLTZ" =>
24321 {
24322 self.write_keyword("TIMESTAMP");
24324 }
24325 Some(DialectType::TSQL) if name_upper == "VARIANT" => {
24326 self.write_keyword("SQL_VARIANT");
24327 }
24328 Some(DialectType::DuckDB) if name_upper == "DECFLOAT" => {
24329 self.write_keyword("DECIMAL(38, 5)");
24330 }
24331 Some(DialectType::Exasol) => {
24332 match name_upper.as_str() {
24334 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => self.write_keyword("VARCHAR"),
24336 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => self.write_keyword("VARCHAR"),
24338 "MEDIUMINT" => self.write_keyword("INT"),
24340 "DECIMAL32" | "DECIMAL64" | "DECIMAL128" | "DECIMAL256" => {
24342 self.write_keyword("DECIMAL")
24343 }
24344 "DATETIME" => self.write_keyword("TIMESTAMP"),
24346 "TIMESTAMPLTZ" => self.write_keyword("TIMESTAMP WITH LOCAL TIME ZONE"),
24347 _ => self.write(name),
24348 }
24349 }
24350 Some(DialectType::Dremio) => {
24351 match name_upper.as_str() {
24353 "TIMESTAMPNTZ" | "DATETIME" => self.write_keyword("TIMESTAMP"),
24354 "ARRAY" => self.write_keyword("LIST"),
24355 "NCHAR" => self.write_keyword("VARCHAR"),
24356 _ => self.write(name),
24357 }
24358 }
24359 _ => {
24361 let (base_upper, _args_str) = if let Some(idx) = name_upper.find('(') {
24363 (name_upper[..idx].to_string(), Some(&name[idx..]))
24364 } else {
24365 (name_upper.clone(), None)
24366 };
24367
24368 match base_upper.as_str() {
24369 "INT64"
24370 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
24371 {
24372 self.write_keyword("BIGINT");
24373 }
24374 "FLOAT64"
24375 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
24376 {
24377 self.write_keyword("DOUBLE");
24378 }
24379 "BOOL"
24380 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
24381 {
24382 self.write_keyword("BOOLEAN");
24383 }
24384 "BYTES"
24385 if matches!(
24386 self.config.dialect,
24387 Some(DialectType::Spark)
24388 | Some(DialectType::Hive)
24389 | Some(DialectType::Databricks)
24390 ) =>
24391 {
24392 self.write_keyword("BINARY");
24393 }
24394 "BYTES"
24395 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
24396 {
24397 self.write_keyword("VARBINARY");
24398 }
24399 "DATETIME2" | "SMALLDATETIME"
24401 if !matches!(
24402 self.config.dialect,
24403 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24404 ) =>
24405 {
24406 if matches!(
24408 self.config.dialect,
24409 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
24410 ) {
24411 self.write_keyword("TIMESTAMP");
24412 if let Some(args) = _args_str {
24413 self.write(args);
24414 }
24415 } else {
24416 self.write_keyword("TIMESTAMP");
24417 }
24418 }
24419 "DATETIMEOFFSET"
24421 if !matches!(
24422 self.config.dialect,
24423 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24424 ) =>
24425 {
24426 if matches!(
24427 self.config.dialect,
24428 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
24429 ) {
24430 self.write_keyword("TIMESTAMPTZ");
24431 if let Some(args) = _args_str {
24432 self.write(args);
24433 }
24434 } else {
24435 self.write_keyword("TIMESTAMPTZ");
24436 }
24437 }
24438 "UNIQUEIDENTIFIER"
24440 if !matches!(
24441 self.config.dialect,
24442 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24443 ) =>
24444 {
24445 match self.config.dialect {
24446 Some(DialectType::Spark)
24447 | Some(DialectType::Databricks)
24448 | Some(DialectType::Hive) => self.write_keyword("STRING"),
24449 _ => self.write_keyword("UUID"),
24450 }
24451 }
24452 "BIT"
24454 if !matches!(
24455 self.config.dialect,
24456 Some(DialectType::TSQL)
24457 | Some(DialectType::Fabric)
24458 | Some(DialectType::PostgreSQL)
24459 | Some(DialectType::MySQL)
24460 | Some(DialectType::DuckDB)
24461 ) =>
24462 {
24463 self.write_keyword("BOOLEAN");
24464 }
24465 "NVARCHAR"
24467 if !matches!(
24468 self.config.dialect,
24469 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24470 ) =>
24471 {
24472 match self.config.dialect {
24473 Some(DialectType::Oracle) => {
24474 self.write_keyword("NVARCHAR2");
24476 if let Some(args) = _args_str {
24477 self.write(args);
24478 }
24479 }
24480 Some(DialectType::BigQuery) => {
24481 self.write_keyword("STRING");
24483 }
24484 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
24485 self.write_keyword("TEXT");
24486 if let Some(args) = _args_str {
24487 self.write(args);
24488 }
24489 }
24490 Some(DialectType::Hive) => {
24491 self.write_keyword("STRING");
24493 }
24494 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
24495 if _args_str.is_some() {
24496 self.write_keyword("VARCHAR");
24497 self.write(_args_str.unwrap());
24498 } else {
24499 self.write_keyword("STRING");
24500 }
24501 }
24502 _ => {
24503 self.write_keyword("VARCHAR");
24504 if let Some(args) = _args_str {
24505 self.write(args);
24506 }
24507 }
24508 }
24509 }
24510 "NCHAR"
24512 if !matches!(
24513 self.config.dialect,
24514 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24515 ) =>
24516 {
24517 match self.config.dialect {
24518 Some(DialectType::Oracle) => {
24519 self.write_keyword("NCHAR");
24521 if let Some(args) = _args_str {
24522 self.write(args);
24523 }
24524 }
24525 Some(DialectType::BigQuery) => {
24526 self.write_keyword("STRING");
24528 }
24529 Some(DialectType::Hive) => {
24530 self.write_keyword("STRING");
24532 }
24533 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
24534 self.write_keyword("TEXT");
24535 if let Some(args) = _args_str {
24536 self.write(args);
24537 }
24538 }
24539 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
24540 if _args_str.is_some() {
24541 self.write_keyword("CHAR");
24542 self.write(_args_str.unwrap());
24543 } else {
24544 self.write_keyword("STRING");
24545 }
24546 }
24547 _ => {
24548 self.write_keyword("CHAR");
24549 if let Some(args) = _args_str {
24550 self.write(args);
24551 }
24552 }
24553 }
24554 }
24555 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => match self.config.dialect {
24558 Some(DialectType::MySQL)
24559 | Some(DialectType::SingleStore)
24560 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
24561 Some(DialectType::Spark)
24562 | Some(DialectType::Databricks)
24563 | Some(DialectType::Hive) => self.write_keyword("TEXT"),
24564 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
24565 Some(DialectType::Presto)
24566 | Some(DialectType::Trino)
24567 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
24568 Some(DialectType::Snowflake)
24569 | Some(DialectType::Redshift)
24570 | Some(DialectType::Dremio) => self.write_keyword("VARCHAR"),
24571 _ => self.write_keyword("TEXT"),
24572 },
24573 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => match self.config.dialect {
24576 Some(DialectType::MySQL)
24577 | Some(DialectType::SingleStore)
24578 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
24579 Some(DialectType::Spark)
24580 | Some(DialectType::Databricks)
24581 | Some(DialectType::Hive) => self.write_keyword("BLOB"),
24582 Some(DialectType::DuckDB) => self.write_keyword("VARBINARY"),
24583 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
24584 Some(DialectType::Presto)
24585 | Some(DialectType::Trino)
24586 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
24587 Some(DialectType::Snowflake)
24588 | Some(DialectType::Redshift)
24589 | Some(DialectType::Dremio) => self.write_keyword("VARBINARY"),
24590 _ => self.write_keyword("BLOB"),
24591 },
24592 "LONGVARCHAR" => match self.config.dialect {
24594 Some(DialectType::SQLite) => self.write_keyword("TEXT"),
24595 _ => self.write_keyword("VARCHAR"),
24596 },
24597 "DATETIME" => {
24599 match self.config.dialect {
24600 Some(DialectType::MySQL)
24601 | Some(DialectType::Doris)
24602 | Some(DialectType::StarRocks)
24603 | Some(DialectType::TSQL)
24604 | Some(DialectType::Fabric)
24605 | Some(DialectType::BigQuery)
24606 | Some(DialectType::SQLite)
24607 | Some(DialectType::Snowflake) => {
24608 self.write_keyword("DATETIME");
24609 if let Some(args) = _args_str {
24610 self.write(args);
24611 }
24612 }
24613 Some(_) => {
24614 self.write_keyword("TIMESTAMP");
24616 if let Some(args) = _args_str {
24617 self.write(args);
24618 }
24619 }
24620 None => {
24621 self.write(name);
24623 }
24624 }
24625 }
24626 "VARCHAR2"
24628 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
24629 {
24630 match self.config.dialect {
24631 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
24632 self.write_keyword("TEXT");
24633 }
24634 Some(DialectType::Hive)
24635 | Some(DialectType::Spark)
24636 | Some(DialectType::Databricks)
24637 | Some(DialectType::BigQuery)
24638 | Some(DialectType::ClickHouse)
24639 | Some(DialectType::StarRocks)
24640 | Some(DialectType::Doris) => {
24641 self.write_keyword("STRING");
24642 }
24643 _ => {
24644 self.write_keyword("VARCHAR");
24645 if let Some(args) = _args_str {
24646 self.write(args);
24647 }
24648 }
24649 }
24650 }
24651 "NVARCHAR2"
24652 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
24653 {
24654 match self.config.dialect {
24655 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
24656 self.write_keyword("TEXT");
24657 }
24658 Some(DialectType::Hive)
24659 | Some(DialectType::Spark)
24660 | Some(DialectType::Databricks)
24661 | Some(DialectType::BigQuery)
24662 | Some(DialectType::ClickHouse)
24663 | Some(DialectType::StarRocks)
24664 | Some(DialectType::Doris) => {
24665 self.write_keyword("STRING");
24666 }
24667 _ => {
24668 self.write_keyword("VARCHAR");
24669 if let Some(args) = _args_str {
24670 self.write(args);
24671 }
24672 }
24673 }
24674 }
24675 _ => self.write(name),
24676 }
24677 }
24678 }
24679 }
24680 DataType::Geometry { subtype, srid } => {
24681 match self.config.dialect {
24683 Some(DialectType::MySQL) => {
24684 if let Some(sub) = subtype {
24686 self.write_keyword(sub);
24687 if let Some(s) = srid {
24688 self.write(" SRID ");
24689 self.write(&s.to_string());
24690 }
24691 } else {
24692 self.write_keyword("GEOMETRY");
24693 }
24694 }
24695 Some(DialectType::BigQuery) => {
24696 self.write_keyword("GEOGRAPHY");
24698 }
24699 Some(DialectType::Teradata) => {
24700 self.write_keyword("ST_GEOMETRY");
24702 if subtype.is_some() || srid.is_some() {
24703 self.write("(");
24704 if let Some(sub) = subtype {
24705 self.write_keyword(sub);
24706 }
24707 if let Some(s) = srid {
24708 if subtype.is_some() {
24709 self.write(", ");
24710 }
24711 self.write(&s.to_string());
24712 }
24713 self.write(")");
24714 }
24715 }
24716 _ => {
24717 self.write_keyword("GEOMETRY");
24719 if subtype.is_some() || srid.is_some() {
24720 self.write("(");
24721 if let Some(sub) = subtype {
24722 self.write_keyword(sub);
24723 }
24724 if let Some(s) = srid {
24725 if subtype.is_some() {
24726 self.write(", ");
24727 }
24728 self.write(&s.to_string());
24729 }
24730 self.write(")");
24731 }
24732 }
24733 }
24734 }
24735 DataType::Geography { subtype, srid } => {
24736 match self.config.dialect {
24738 Some(DialectType::MySQL) => {
24739 if let Some(sub) = subtype {
24741 self.write_keyword(sub);
24742 } else {
24743 self.write_keyword("GEOMETRY");
24744 }
24745 let effective_srid = srid.unwrap_or(4326);
24747 self.write(" SRID ");
24748 self.write(&effective_srid.to_string());
24749 }
24750 Some(DialectType::BigQuery) => {
24751 self.write_keyword("GEOGRAPHY");
24753 }
24754 Some(DialectType::Snowflake) => {
24755 self.write_keyword("GEOGRAPHY");
24757 }
24758 _ => {
24759 self.write_keyword("GEOGRAPHY");
24761 if subtype.is_some() || srid.is_some() {
24762 self.write("(");
24763 if let Some(sub) = subtype {
24764 self.write_keyword(sub);
24765 }
24766 if let Some(s) = srid {
24767 if subtype.is_some() {
24768 self.write(", ");
24769 }
24770 self.write(&s.to_string());
24771 }
24772 self.write(")");
24773 }
24774 }
24775 }
24776 }
24777 DataType::CharacterSet { name } => {
24778 self.write_keyword("CHAR CHARACTER SET ");
24780 self.write(name);
24781 }
24782 _ => self.write("UNKNOWN"),
24783 }
24784 Ok(())
24785 }
24786
24787 #[inline]
24790 fn write(&mut self, s: &str) {
24791 self.output.push_str(s);
24792 }
24793
24794 #[inline]
24795 fn write_space(&mut self) {
24796 self.output.push(' ');
24797 }
24798
24799 #[inline]
24800 fn write_keyword(&mut self, keyword: &str) {
24801 if self.config.uppercase_keywords {
24802 self.output.push_str(keyword);
24803 } else {
24804 for b in keyword.bytes() {
24805 self.output.push(b.to_ascii_lowercase() as char);
24806 }
24807 }
24808 }
24809
24810 fn write_func_name(&mut self, name: &str) {
24812 let normalized = self.normalize_func_name(name);
24813 self.output.push_str(normalized.as_ref());
24814 }
24815
24816 fn convert_strptime_to_exasol_format(format: &str) -> String {
24820 let mut result = String::new();
24821 let chars: Vec<char> = format.chars().collect();
24822 let mut i = 0;
24823 while i < chars.len() {
24824 if chars[i] == '%' && i + 1 < chars.len() {
24825 let spec = chars[i + 1];
24826 let exasol_spec = match spec {
24827 'Y' => "YYYY",
24828 'y' => "YY",
24829 'm' => "MM",
24830 'd' => "DD",
24831 'H' => "HH",
24832 'M' => "MI",
24833 'S' => "SS",
24834 'a' => "DY", 'A' => "DAY", 'b' => "MON", 'B' => "MONTH", 'I' => "H12", 'u' => "ID", 'V' => "IW", 'G' => "IYYY", 'W' => "UW", 'U' => "UW", 'z' => "Z", _ => {
24846 result.push('%');
24848 result.push(spec);
24849 i += 2;
24850 continue;
24851 }
24852 };
24853 result.push_str(exasol_spec);
24854 i += 2;
24855 } else {
24856 result.push(chars[i]);
24857 i += 1;
24858 }
24859 }
24860 result
24861 }
24862
24863 fn convert_strptime_to_postgres_format(format: &str) -> String {
24867 let mut result = String::new();
24868 let chars: Vec<char> = format.chars().collect();
24869 let mut i = 0;
24870 while i < chars.len() {
24871 if chars[i] == '%' && i + 1 < chars.len() {
24872 if chars[i + 1] == '-' && i + 2 < chars.len() {
24874 let spec = chars[i + 2];
24875 let pg_spec = match spec {
24876 'd' => "FMDD",
24877 'm' => "FMMM",
24878 'H' => "FMHH24",
24879 'M' => "FMMI",
24880 'S' => "FMSS",
24881 _ => {
24882 result.push('%');
24883 result.push('-');
24884 result.push(spec);
24885 i += 3;
24886 continue;
24887 }
24888 };
24889 result.push_str(pg_spec);
24890 i += 3;
24891 continue;
24892 }
24893 let spec = chars[i + 1];
24894 let pg_spec = match spec {
24895 'Y' => "YYYY",
24896 'y' => "YY",
24897 'm' => "MM",
24898 'd' => "DD",
24899 'H' => "HH24",
24900 'I' => "HH12",
24901 'M' => "MI",
24902 'S' => "SS",
24903 'f' => "US", 'u' => "D", 'j' => "DDD", 'z' => "OF", 'Z' => "TZ", 'A' => "TMDay", 'a' => "TMDy", 'b' => "TMMon", 'B' => "TMMonth", 'U' => "WW", _ => {
24914 result.push('%');
24916 result.push(spec);
24917 i += 2;
24918 continue;
24919 }
24920 };
24921 result.push_str(pg_spec);
24922 i += 2;
24923 } else {
24924 result.push(chars[i]);
24925 i += 1;
24926 }
24927 }
24928 result
24929 }
24930
24931 fn write_limit_expr(&mut self, expr: &Expression) -> Result<()> {
24933 if self.config.limit_only_literals {
24934 if let Some(value) = Self::try_evaluate_constant(expr) {
24935 self.write(&value.to_string());
24936 return Ok(());
24937 }
24938 }
24939 self.generate_expression(expr)
24940 }
24941
24942 fn write_formatted_comment(&mut self, comment: &str) {
24946 let content = if comment.starts_with("/*") && comment.ends_with("*/") {
24949 &comment[2..comment.len() - 2]
24952 } else if comment.starts_with("--") {
24953 &comment[2..]
24956 } else {
24957 comment
24959 };
24960 if content.trim().is_empty() {
24962 return;
24963 }
24964 let sanitized = content.replace("*/", "* /").replace("/*", "/ *");
24967 let content = &sanitized;
24968 self.output.push_str("/*");
24970 if !content.starts_with(' ') {
24971 self.output.push(' ');
24972 }
24973 self.output.push_str(content);
24974 if !content.ends_with(' ') {
24975 self.output.push(' ');
24976 }
24977 self.output.push_str("*/");
24978 }
24979
24980 fn escape_block_for_single_quote(&self, block: &str) -> String {
24983 let escape_backslash = matches!(
24984 self.config.dialect,
24985 Some(crate::dialects::DialectType::Snowflake)
24986 );
24987 let mut escaped = String::with_capacity(block.len() + 4);
24988 for ch in block.chars() {
24989 if ch == '\'' {
24990 escaped.push('\\');
24991 escaped.push('\'');
24992 } else if escape_backslash && ch == '\\' {
24993 escaped.push('\\');
24994 escaped.push('\\');
24995 } else {
24996 escaped.push(ch);
24997 }
24998 }
24999 escaped
25000 }
25001
25002 fn write_newline(&mut self) {
25003 self.output.push('\n');
25004 }
25005
25006 fn write_indent(&mut self) {
25007 for _ in 0..self.indent_level {
25008 self.output.push_str(self.config.indent);
25009 }
25010 }
25011
25012 fn too_wide(&self, args: &[String]) -> bool {
25018 args.iter().map(|s| s.len()).sum::<usize>() > self.config.max_text_width
25019 }
25020
25021 fn generate_to_string(&self, expr: &Expression) -> Result<String> {
25024 let config = GeneratorConfig {
25025 pretty: false,
25026 dialect: self.config.dialect,
25027 ..Default::default()
25028 };
25029 let mut gen = Generator::with_config(config);
25030 gen.generate_expression(expr)?;
25031 Ok(gen.output)
25032 }
25033
25034 fn write_clause_condition(&mut self, keyword: &str, condition: &Expression) -> Result<()> {
25037 if self.config.pretty {
25038 self.write_newline();
25039 self.write_indent();
25040 self.write_keyword(keyword);
25041 self.write_newline();
25042 self.indent_level += 1;
25043 self.write_indent();
25044 self.generate_expression(condition)?;
25045 self.indent_level -= 1;
25046 } else {
25047 self.write_space();
25048 self.write_keyword(keyword);
25049 self.write_space();
25050 self.generate_expression(condition)?;
25051 }
25052 Ok(())
25053 }
25054
25055 fn write_clause_expressions(&mut self, keyword: &str, exprs: &[Expression]) -> Result<()> {
25058 if exprs.is_empty() {
25059 return Ok(());
25060 }
25061
25062 if self.config.pretty {
25063 self.write_newline();
25064 self.write_indent();
25065 self.write_keyword(keyword);
25066 self.write_newline();
25067 self.indent_level += 1;
25068 for (i, expr) in exprs.iter().enumerate() {
25069 if i > 0 {
25070 self.write(",");
25071 self.write_newline();
25072 }
25073 self.write_indent();
25074 self.generate_expression(expr)?;
25075 }
25076 self.indent_level -= 1;
25077 } else {
25078 self.write_space();
25079 self.write_keyword(keyword);
25080 self.write_space();
25081 for (i, expr) in exprs.iter().enumerate() {
25082 if i > 0 {
25083 self.write(", ");
25084 }
25085 self.generate_expression(expr)?;
25086 }
25087 }
25088 Ok(())
25089 }
25090
25091 fn write_order_clause(&mut self, keyword: &str, orderings: &[Ordered]) -> Result<()> {
25093 if orderings.is_empty() {
25094 return Ok(());
25095 }
25096
25097 if self.config.pretty {
25098 self.write_newline();
25099 self.write_indent();
25100 self.write_keyword(keyword);
25101 self.write_newline();
25102 self.indent_level += 1;
25103 for (i, ordered) in orderings.iter().enumerate() {
25104 if i > 0 {
25105 self.write(",");
25106 self.write_newline();
25107 }
25108 self.write_indent();
25109 self.generate_ordered(ordered)?;
25110 }
25111 self.indent_level -= 1;
25112 } else {
25113 self.write_space();
25114 self.write_keyword(keyword);
25115 self.write_space();
25116 for (i, ordered) in orderings.iter().enumerate() {
25117 if i > 0 {
25118 self.write(", ");
25119 }
25120 self.generate_ordered(ordered)?;
25121 }
25122 }
25123 Ok(())
25124 }
25125
25126 fn write_window_clause(&mut self, windows: &[NamedWindow]) -> Result<()> {
25128 if windows.is_empty() {
25129 return Ok(());
25130 }
25131
25132 if self.config.pretty {
25133 self.write_newline();
25134 self.write_indent();
25135 self.write_keyword("WINDOW");
25136 self.write_newline();
25137 self.indent_level += 1;
25138 for (i, named_window) in windows.iter().enumerate() {
25139 if i > 0 {
25140 self.write(",");
25141 self.write_newline();
25142 }
25143 self.write_indent();
25144 self.generate_identifier(&named_window.name)?;
25145 self.write_space();
25146 self.write_keyword("AS");
25147 self.write(" (");
25148 self.generate_over(&named_window.spec)?;
25149 self.write(")");
25150 }
25151 self.indent_level -= 1;
25152 } else {
25153 self.write_space();
25154 self.write_keyword("WINDOW");
25155 self.write_space();
25156 for (i, named_window) in windows.iter().enumerate() {
25157 if i > 0 {
25158 self.write(", ");
25159 }
25160 self.generate_identifier(&named_window.name)?;
25161 self.write_space();
25162 self.write_keyword("AS");
25163 self.write(" (");
25164 self.generate_over(&named_window.spec)?;
25165 self.write(")");
25166 }
25167 }
25168 Ok(())
25169 }
25170
25171 fn generate_ai_agg(&mut self, e: &AIAgg) -> Result<()> {
25173 self.write_keyword("AI_AGG");
25175 self.write("(");
25176 self.generate_expression(&e.this)?;
25177 self.write(", ");
25178 self.generate_expression(&e.expression)?;
25179 self.write(")");
25180 Ok(())
25181 }
25182
25183 fn generate_ai_classify(&mut self, e: &AIClassify) -> Result<()> {
25184 self.write_keyword("AI_CLASSIFY");
25186 self.write("(");
25187 self.generate_expression(&e.this)?;
25188 if let Some(categories) = &e.categories {
25189 self.write(", ");
25190 self.generate_expression(categories)?;
25191 }
25192 if let Some(config) = &e.config {
25193 self.write(", ");
25194 self.generate_expression(config)?;
25195 }
25196 self.write(")");
25197 Ok(())
25198 }
25199
25200 fn generate_add_partition(&mut self, e: &AddPartition) -> Result<()> {
25201 self.write_keyword("ADD");
25203 self.write_space();
25204 if e.exists {
25205 self.write_keyword("IF NOT EXISTS");
25206 self.write_space();
25207 }
25208 self.generate_expression(&e.this)?;
25209 if let Some(location) = &e.location {
25210 self.write_space();
25211 self.generate_expression(location)?;
25212 }
25213 Ok(())
25214 }
25215
25216 fn generate_algorithm_property(&mut self, e: &AlgorithmProperty) -> Result<()> {
25217 self.write_keyword("ALGORITHM");
25219 self.write("=");
25220 self.generate_expression(&e.this)?;
25221 Ok(())
25222 }
25223
25224 fn generate_aliases(&mut self, e: &Aliases) -> Result<()> {
25225 self.generate_expression(&e.this)?;
25227 self.write_space();
25228 self.write_keyword("AS");
25229 self.write(" (");
25230 for (i, expr) in e.expressions.iter().enumerate() {
25231 if i > 0 {
25232 self.write(", ");
25233 }
25234 self.generate_expression(expr)?;
25235 }
25236 self.write(")");
25237 Ok(())
25238 }
25239
25240 fn generate_allowed_values_property(&mut self, e: &AllowedValuesProperty) -> Result<()> {
25241 self.write_keyword("ALLOWED_VALUES");
25243 self.write_space();
25244 for (i, expr) in e.expressions.iter().enumerate() {
25245 if i > 0 {
25246 self.write(", ");
25247 }
25248 self.generate_expression(expr)?;
25249 }
25250 Ok(())
25251 }
25252
25253 fn generate_alter_column(&mut self, e: &AlterColumn) -> Result<()> {
25254 self.write_keyword("ALTER COLUMN");
25256 self.write_space();
25257 self.generate_expression(&e.this)?;
25258
25259 if let Some(dtype) = &e.dtype {
25260 self.write_space();
25261 self.write_keyword("SET DATA TYPE");
25262 self.write_space();
25263 self.generate_expression(dtype)?;
25264 if let Some(collate) = &e.collate {
25265 self.write_space();
25266 self.write_keyword("COLLATE");
25267 self.write_space();
25268 self.generate_expression(collate)?;
25269 }
25270 if let Some(using) = &e.using {
25271 self.write_space();
25272 self.write_keyword("USING");
25273 self.write_space();
25274 self.generate_expression(using)?;
25275 }
25276 } else if let Some(default) = &e.default {
25277 self.write_space();
25278 self.write_keyword("SET DEFAULT");
25279 self.write_space();
25280 self.generate_expression(default)?;
25281 } else if let Some(comment) = &e.comment {
25282 self.write_space();
25283 self.write_keyword("COMMENT");
25284 self.write_space();
25285 self.generate_expression(comment)?;
25286 } else if let Some(drop) = &e.drop {
25287 self.write_space();
25288 self.write_keyword("DROP");
25289 self.write_space();
25290 self.generate_expression(drop)?;
25291 } else if let Some(visible) = &e.visible {
25292 self.write_space();
25293 self.generate_expression(visible)?;
25294 } else if let Some(rename_to) = &e.rename_to {
25295 self.write_space();
25296 self.write_keyword("RENAME TO");
25297 self.write_space();
25298 self.generate_expression(rename_to)?;
25299 } else if let Some(allow_null) = &e.allow_null {
25300 self.write_space();
25301 self.generate_expression(allow_null)?;
25302 }
25303 Ok(())
25304 }
25305
25306 fn generate_alter_session(&mut self, e: &AlterSession) -> Result<()> {
25307 self.write_keyword("ALTER SESSION");
25309 self.write_space();
25310 if e.unset.is_some() {
25311 self.write_keyword("UNSET");
25312 } else {
25313 self.write_keyword("SET");
25314 }
25315 self.write_space();
25316 for (i, expr) in e.expressions.iter().enumerate() {
25317 if i > 0 {
25318 self.write(", ");
25319 }
25320 self.generate_expression(expr)?;
25321 }
25322 Ok(())
25323 }
25324
25325 fn generate_alter_set(&mut self, e: &AlterSet) -> Result<()> {
25326 self.write_keyword("SET");
25328
25329 if let Some(opt) = &e.option {
25331 self.write_space();
25332 self.generate_expression(opt)?;
25333 }
25334
25335 if !e.expressions.is_empty() {
25338 let is_properties = e
25340 .expressions
25341 .iter()
25342 .any(|expr| matches!(expr, Expression::Eq(_)));
25343 if is_properties && e.option.is_none() {
25344 self.write_space();
25345 self.write_keyword("PROPERTIES");
25346 }
25347 self.write_space();
25348 for (i, expr) in e.expressions.iter().enumerate() {
25349 if i > 0 {
25350 self.write(", ");
25351 }
25352 self.generate_expression(expr)?;
25353 }
25354 }
25355
25356 if let Some(file_format) = &e.file_format {
25358 self.write(" ");
25359 self.write_keyword("STAGE_FILE_FORMAT");
25360 self.write(" = (");
25361 self.generate_space_separated_properties(file_format)?;
25362 self.write(")");
25363 }
25364
25365 if let Some(copy_options) = &e.copy_options {
25367 self.write(" ");
25368 self.write_keyword("STAGE_COPY_OPTIONS");
25369 self.write(" = (");
25370 self.generate_space_separated_properties(copy_options)?;
25371 self.write(")");
25372 }
25373
25374 if let Some(tag) = &e.tag {
25376 self.write(" ");
25377 self.write_keyword("TAG");
25378 self.write(" ");
25379 self.generate_expression(tag)?;
25380 }
25381
25382 Ok(())
25383 }
25384
25385 fn generate_space_separated_properties(&mut self, expr: &Expression) -> Result<()> {
25387 match expr {
25388 Expression::Tuple(t) => {
25389 for (i, prop) in t.expressions.iter().enumerate() {
25390 if i > 0 {
25391 self.write(" ");
25392 }
25393 self.generate_expression(prop)?;
25394 }
25395 }
25396 _ => {
25397 self.generate_expression(expr)?;
25398 }
25399 }
25400 Ok(())
25401 }
25402
25403 fn generate_alter_sort_key(&mut self, e: &AlterSortKey) -> Result<()> {
25404 self.write_keyword("ALTER");
25406 if e.compound.is_some() {
25407 self.write_space();
25408 self.write_keyword("COMPOUND");
25409 }
25410 self.write_space();
25411 self.write_keyword("SORTKEY");
25412 self.write_space();
25413 if let Some(this) = &e.this {
25414 self.generate_expression(this)?;
25415 } else if !e.expressions.is_empty() {
25416 self.write("(");
25417 for (i, expr) in e.expressions.iter().enumerate() {
25418 if i > 0 {
25419 self.write(", ");
25420 }
25421 self.generate_expression(expr)?;
25422 }
25423 self.write(")");
25424 }
25425 Ok(())
25426 }
25427
25428 fn generate_analyze(&mut self, e: &Analyze) -> Result<()> {
25429 self.write_keyword("ANALYZE");
25431 if !e.options.is_empty() {
25432 self.write_space();
25433 for (i, opt) in e.options.iter().enumerate() {
25434 if i > 0 {
25435 self.write_space();
25436 }
25437 if let Expression::Identifier(id) = opt {
25439 self.write_keyword(&id.name);
25440 } else {
25441 self.generate_expression(opt)?;
25442 }
25443 }
25444 }
25445 if let Some(kind) = &e.kind {
25446 self.write_space();
25447 self.write_keyword(kind);
25448 }
25449 if let Some(this) = &e.this {
25450 self.write_space();
25451 self.generate_expression(this)?;
25452 }
25453 if !e.columns.is_empty() {
25455 self.write("(");
25456 for (i, col) in e.columns.iter().enumerate() {
25457 if i > 0 {
25458 self.write(", ");
25459 }
25460 self.write(col);
25461 }
25462 self.write(")");
25463 }
25464 if let Some(partition) = &e.partition {
25465 self.write_space();
25466 self.generate_expression(partition)?;
25467 }
25468 if let Some(mode) = &e.mode {
25469 self.write_space();
25470 self.generate_expression(mode)?;
25471 }
25472 if let Some(expression) = &e.expression {
25473 self.write_space();
25474 self.generate_expression(expression)?;
25475 }
25476 if !e.properties.is_empty() {
25477 self.write_space();
25478 self.write_keyword(self.config.with_properties_prefix);
25479 self.write(" (");
25480 for (i, prop) in e.properties.iter().enumerate() {
25481 if i > 0 {
25482 self.write(", ");
25483 }
25484 self.generate_expression(prop)?;
25485 }
25486 self.write(")");
25487 }
25488 Ok(())
25489 }
25490
25491 fn generate_analyze_delete(&mut self, e: &AnalyzeDelete) -> Result<()> {
25492 self.write_keyword("DELETE");
25494 if let Some(kind) = &e.kind {
25495 self.write_space();
25496 self.write_keyword(kind);
25497 }
25498 self.write_space();
25499 self.write_keyword("STATISTICS");
25500 Ok(())
25501 }
25502
25503 fn generate_analyze_histogram(&mut self, e: &AnalyzeHistogram) -> Result<()> {
25504 if let Expression::Identifier(id) = e.this.as_ref() {
25507 self.write_keyword(&id.name);
25508 } else {
25509 self.generate_expression(&e.this)?;
25510 }
25511 self.write_space();
25512 self.write_keyword("HISTOGRAM ON");
25513 self.write_space();
25514 for (i, expr) in e.expressions.iter().enumerate() {
25515 if i > 0 {
25516 self.write(", ");
25517 }
25518 self.generate_expression(expr)?;
25519 }
25520 if let Some(expression) = &e.expression {
25521 self.write_space();
25522 self.generate_expression(expression)?;
25523 }
25524 if let Some(update_options) = &e.update_options {
25525 self.write_space();
25526 self.generate_expression(update_options)?;
25527 self.write_space();
25528 self.write_keyword("UPDATE");
25529 }
25530 Ok(())
25531 }
25532
25533 fn generate_analyze_list_chained_rows(&mut self, e: &AnalyzeListChainedRows) -> Result<()> {
25534 self.write_keyword("LIST CHAINED ROWS");
25536 if let Some(expression) = &e.expression {
25537 self.write_space();
25538 self.write_keyword("INTO");
25539 self.write_space();
25540 self.generate_expression(expression)?;
25541 }
25542 Ok(())
25543 }
25544
25545 fn generate_analyze_sample(&mut self, e: &AnalyzeSample) -> Result<()> {
25546 self.write_keyword("SAMPLE");
25548 self.write_space();
25549 if let Some(sample) = &e.sample {
25550 self.generate_expression(sample)?;
25551 self.write_space();
25552 }
25553 self.write_keyword(&e.kind);
25554 Ok(())
25555 }
25556
25557 fn generate_analyze_statistics(&mut self, e: &AnalyzeStatistics) -> Result<()> {
25558 self.write_keyword(&e.kind);
25560 if let Some(option) = &e.option {
25561 self.write_space();
25562 self.generate_expression(option)?;
25563 }
25564 self.write_space();
25565 self.write_keyword("STATISTICS");
25566 if let Some(this) = &e.this {
25567 self.write_space();
25568 self.generate_expression(this)?;
25569 }
25570 if !e.expressions.is_empty() {
25571 self.write_space();
25572 for (i, expr) in e.expressions.iter().enumerate() {
25573 if i > 0 {
25574 self.write(", ");
25575 }
25576 self.generate_expression(expr)?;
25577 }
25578 }
25579 Ok(())
25580 }
25581
25582 fn generate_analyze_validate(&mut self, e: &AnalyzeValidate) -> Result<()> {
25583 self.write_keyword("VALIDATE");
25585 self.write_space();
25586 self.write_keyword(&e.kind);
25587 if let Some(this) = &e.this {
25588 self.write_space();
25589 if let Expression::Identifier(id) = this.as_ref() {
25591 self.write_keyword(&id.name);
25592 } else {
25593 self.generate_expression(this)?;
25594 }
25595 }
25596 if let Some(expression) = &e.expression {
25597 self.write_space();
25598 self.write_keyword("INTO");
25599 self.write_space();
25600 self.generate_expression(expression)?;
25601 }
25602 Ok(())
25603 }
25604
25605 fn generate_analyze_with(&mut self, e: &AnalyzeWith) -> Result<()> {
25606 self.write_keyword("WITH");
25608 self.write_space();
25609 for (i, expr) in e.expressions.iter().enumerate() {
25610 if i > 0 {
25611 self.write(", ");
25612 }
25613 self.generate_expression(expr)?;
25614 }
25615 Ok(())
25616 }
25617
25618 fn generate_anonymous(&mut self, e: &Anonymous) -> Result<()> {
25619 self.generate_expression(&e.this)?;
25622 self.write("(");
25623 for (i, arg) in e.expressions.iter().enumerate() {
25624 if i > 0 {
25625 self.write(", ");
25626 }
25627 self.generate_expression(arg)?;
25628 }
25629 self.write(")");
25630 Ok(())
25631 }
25632
25633 fn generate_anonymous_agg_func(&mut self, e: &AnonymousAggFunc) -> Result<()> {
25634 self.generate_expression(&e.this)?;
25636 self.write("(");
25637 for (i, arg) in e.expressions.iter().enumerate() {
25638 if i > 0 {
25639 self.write(", ");
25640 }
25641 self.generate_expression(arg)?;
25642 }
25643 self.write(")");
25644 Ok(())
25645 }
25646
25647 fn generate_apply(&mut self, e: &Apply) -> Result<()> {
25648 self.generate_expression(&e.this)?;
25650 self.write_space();
25651 self.write_keyword("APPLY");
25652 self.write("(");
25653 self.generate_expression(&e.expression)?;
25654 self.write(")");
25655 Ok(())
25656 }
25657
25658 fn generate_approx_percentile_estimate(&mut self, e: &ApproxPercentileEstimate) -> Result<()> {
25659 self.write_keyword("APPROX_PERCENTILE_ESTIMATE");
25661 self.write("(");
25662 self.generate_expression(&e.this)?;
25663 if let Some(percentile) = &e.percentile {
25664 self.write(", ");
25665 self.generate_expression(percentile)?;
25666 }
25667 self.write(")");
25668 Ok(())
25669 }
25670
25671 fn generate_approx_quantile(&mut self, e: &ApproxQuantile) -> Result<()> {
25672 self.write_keyword("APPROX_QUANTILE");
25674 self.write("(");
25675 self.generate_expression(&e.this)?;
25676 if let Some(quantile) = &e.quantile {
25677 self.write(", ");
25678 self.generate_expression(quantile)?;
25679 }
25680 if let Some(accuracy) = &e.accuracy {
25681 self.write(", ");
25682 self.generate_expression(accuracy)?;
25683 }
25684 if let Some(weight) = &e.weight {
25685 self.write(", ");
25686 self.generate_expression(weight)?;
25687 }
25688 self.write(")");
25689 Ok(())
25690 }
25691
25692 fn generate_approx_quantiles(&mut self, e: &ApproxQuantiles) -> Result<()> {
25693 self.write_keyword("APPROX_QUANTILES");
25695 self.write("(");
25696 self.generate_expression(&e.this)?;
25697 if let Some(expression) = &e.expression {
25698 self.write(", ");
25699 self.generate_expression(expression)?;
25700 }
25701 self.write(")");
25702 Ok(())
25703 }
25704
25705 fn generate_approx_top_k(&mut self, e: &ApproxTopK) -> Result<()> {
25706 self.write_keyword("APPROX_TOP_K");
25708 self.write("(");
25709 self.generate_expression(&e.this)?;
25710 if let Some(expression) = &e.expression {
25711 self.write(", ");
25712 self.generate_expression(expression)?;
25713 }
25714 if let Some(counters) = &e.counters {
25715 self.write(", ");
25716 self.generate_expression(counters)?;
25717 }
25718 self.write(")");
25719 Ok(())
25720 }
25721
25722 fn generate_approx_top_k_accumulate(&mut self, e: &ApproxTopKAccumulate) -> Result<()> {
25723 self.write_keyword("APPROX_TOP_K_ACCUMULATE");
25725 self.write("(");
25726 self.generate_expression(&e.this)?;
25727 if let Some(expression) = &e.expression {
25728 self.write(", ");
25729 self.generate_expression(expression)?;
25730 }
25731 self.write(")");
25732 Ok(())
25733 }
25734
25735 fn generate_approx_top_k_combine(&mut self, e: &ApproxTopKCombine) -> Result<()> {
25736 self.write_keyword("APPROX_TOP_K_COMBINE");
25738 self.write("(");
25739 self.generate_expression(&e.this)?;
25740 if let Some(expression) = &e.expression {
25741 self.write(", ");
25742 self.generate_expression(expression)?;
25743 }
25744 self.write(")");
25745 Ok(())
25746 }
25747
25748 fn generate_approx_top_k_estimate(&mut self, e: &ApproxTopKEstimate) -> Result<()> {
25749 self.write_keyword("APPROX_TOP_K_ESTIMATE");
25751 self.write("(");
25752 self.generate_expression(&e.this)?;
25753 if let Some(expression) = &e.expression {
25754 self.write(", ");
25755 self.generate_expression(expression)?;
25756 }
25757 self.write(")");
25758 Ok(())
25759 }
25760
25761 fn generate_approx_top_sum(&mut self, e: &ApproxTopSum) -> Result<()> {
25762 self.write_keyword("APPROX_TOP_SUM");
25764 self.write("(");
25765 self.generate_expression(&e.this)?;
25766 self.write(", ");
25767 self.generate_expression(&e.expression)?;
25768 if let Some(count) = &e.count {
25769 self.write(", ");
25770 self.generate_expression(count)?;
25771 }
25772 self.write(")");
25773 Ok(())
25774 }
25775
25776 fn generate_arg_max(&mut self, e: &ArgMax) -> Result<()> {
25777 self.write_keyword("ARG_MAX");
25779 self.write("(");
25780 self.generate_expression(&e.this)?;
25781 self.write(", ");
25782 self.generate_expression(&e.expression)?;
25783 if let Some(count) = &e.count {
25784 self.write(", ");
25785 self.generate_expression(count)?;
25786 }
25787 self.write(")");
25788 Ok(())
25789 }
25790
25791 fn generate_arg_min(&mut self, e: &ArgMin) -> Result<()> {
25792 self.write_keyword("ARG_MIN");
25794 self.write("(");
25795 self.generate_expression(&e.this)?;
25796 self.write(", ");
25797 self.generate_expression(&e.expression)?;
25798 if let Some(count) = &e.count {
25799 self.write(", ");
25800 self.generate_expression(count)?;
25801 }
25802 self.write(")");
25803 Ok(())
25804 }
25805
25806 fn generate_array_all(&mut self, e: &ArrayAll) -> Result<()> {
25807 self.write_keyword("ARRAY_ALL");
25809 self.write("(");
25810 self.generate_expression(&e.this)?;
25811 self.write(", ");
25812 self.generate_expression(&e.expression)?;
25813 self.write(")");
25814 Ok(())
25815 }
25816
25817 fn generate_array_any(&mut self, e: &ArrayAny) -> Result<()> {
25818 self.write_keyword("ARRAY_ANY");
25820 self.write("(");
25821 self.generate_expression(&e.this)?;
25822 self.write(", ");
25823 self.generate_expression(&e.expression)?;
25824 self.write(")");
25825 Ok(())
25826 }
25827
25828 fn generate_array_construct_compact(&mut self, e: &ArrayConstructCompact) -> Result<()> {
25829 self.write_keyword("ARRAY_CONSTRUCT_COMPACT");
25831 self.write("(");
25832 for (i, expr) in e.expressions.iter().enumerate() {
25833 if i > 0 {
25834 self.write(", ");
25835 }
25836 self.generate_expression(expr)?;
25837 }
25838 self.write(")");
25839 Ok(())
25840 }
25841
25842 fn generate_array_sum(&mut self, e: &ArraySum) -> Result<()> {
25843 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
25845 self.write("arraySum");
25846 } else {
25847 self.write_keyword("ARRAY_SUM");
25848 }
25849 self.write("(");
25850 self.generate_expression(&e.this)?;
25851 if let Some(expression) = &e.expression {
25852 self.write(", ");
25853 self.generate_expression(expression)?;
25854 }
25855 self.write(")");
25856 Ok(())
25857 }
25858
25859 fn generate_at_index(&mut self, e: &AtIndex) -> Result<()> {
25860 self.generate_expression(&e.this)?;
25862 self.write_space();
25863 self.write_keyword("AT");
25864 self.write_space();
25865 self.generate_expression(&e.expression)?;
25866 Ok(())
25867 }
25868
25869 fn generate_attach(&mut self, e: &Attach) -> Result<()> {
25870 self.write_keyword("ATTACH");
25872 if e.exists {
25873 self.write_space();
25874 self.write_keyword("IF NOT EXISTS");
25875 }
25876 self.write_space();
25877 self.generate_expression(&e.this)?;
25878 if !e.expressions.is_empty() {
25879 self.write(" (");
25880 for (i, expr) in e.expressions.iter().enumerate() {
25881 if i > 0 {
25882 self.write(", ");
25883 }
25884 self.generate_expression(expr)?;
25885 }
25886 self.write(")");
25887 }
25888 Ok(())
25889 }
25890
25891 fn generate_attach_option(&mut self, e: &AttachOption) -> Result<()> {
25892 self.generate_expression(&e.this)?;
25895 if let Some(expression) = &e.expression {
25896 self.write_space();
25897 self.generate_expression(expression)?;
25898 }
25899 Ok(())
25900 }
25901
25902 fn generate_auto_increment_keyword(
25906 &mut self,
25907 col: &crate::expressions::ColumnDef,
25908 ) -> Result<()> {
25909 use crate::dialects::DialectType;
25910 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
25911 self.write_keyword("IDENTITY");
25912 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
25913 self.write("(");
25914 if let Some(ref start) = col.auto_increment_start {
25915 self.generate_expression(start)?;
25916 } else {
25917 self.write("0");
25918 }
25919 self.write(", ");
25920 if let Some(ref inc) = col.auto_increment_increment {
25921 self.generate_expression(inc)?;
25922 } else {
25923 self.write("1");
25924 }
25925 self.write(")");
25926 }
25927 } else if matches!(
25928 self.config.dialect,
25929 Some(DialectType::Snowflake) | Some(DialectType::SQLite)
25930 ) {
25931 self.write_keyword("AUTOINCREMENT");
25932 if let Some(ref start) = col.auto_increment_start {
25933 self.write_space();
25934 self.write_keyword("START");
25935 self.write_space();
25936 self.generate_expression(start)?;
25937 }
25938 if let Some(ref inc) = col.auto_increment_increment {
25939 self.write_space();
25940 self.write_keyword("INCREMENT");
25941 self.write_space();
25942 self.generate_expression(inc)?;
25943 }
25944 if let Some(order) = col.auto_increment_order {
25945 self.write_space();
25946 if order {
25947 self.write_keyword("ORDER");
25948 } else {
25949 self.write_keyword("NOORDER");
25950 }
25951 }
25952 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
25953 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
25954 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
25955 self.write(" (");
25956 let mut first = true;
25957 if let Some(ref start) = col.auto_increment_start {
25958 self.write_keyword("START WITH");
25959 self.write_space();
25960 self.generate_expression(start)?;
25961 first = false;
25962 }
25963 if let Some(ref inc) = col.auto_increment_increment {
25964 if !first {
25965 self.write_space();
25966 }
25967 self.write_keyword("INCREMENT BY");
25968 self.write_space();
25969 self.generate_expression(inc)?;
25970 }
25971 self.write(")");
25972 }
25973 } else if matches!(self.config.dialect, Some(DialectType::Databricks)) {
25974 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
25977 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
25978 } else {
25979 self.write_keyword("GENERATED ALWAYS AS IDENTITY");
25980 }
25981 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
25982 self.write(" (");
25983 let mut first = true;
25984 if let Some(ref start) = col.auto_increment_start {
25985 self.write_keyword("START WITH");
25986 self.write_space();
25987 self.generate_expression(start)?;
25988 first = false;
25989 }
25990 if let Some(ref inc) = col.auto_increment_increment {
25991 if !first {
25992 self.write_space();
25993 }
25994 self.write_keyword("INCREMENT BY");
25995 self.write_space();
25996 self.generate_expression(inc)?;
25997 }
25998 self.write(")");
25999 }
26000 } else if matches!(
26001 self.config.dialect,
26002 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26003 ) {
26004 self.write_keyword("IDENTITY");
26005 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26006 self.write("(");
26007 if let Some(ref start) = col.auto_increment_start {
26008 self.generate_expression(start)?;
26009 } else {
26010 self.write("0");
26011 }
26012 self.write(", ");
26013 if let Some(ref inc) = col.auto_increment_increment {
26014 self.generate_expression(inc)?;
26015 } else {
26016 self.write("1");
26017 }
26018 self.write(")");
26019 }
26020 } else {
26021 self.write_keyword("AUTO_INCREMENT");
26022 if let Some(ref start) = col.auto_increment_start {
26023 self.write_space();
26024 self.write_keyword("START");
26025 self.write_space();
26026 self.generate_expression(start)?;
26027 }
26028 if let Some(ref inc) = col.auto_increment_increment {
26029 self.write_space();
26030 self.write_keyword("INCREMENT");
26031 self.write_space();
26032 self.generate_expression(inc)?;
26033 }
26034 if let Some(order) = col.auto_increment_order {
26035 self.write_space();
26036 if order {
26037 self.write_keyword("ORDER");
26038 } else {
26039 self.write_keyword("NOORDER");
26040 }
26041 }
26042 }
26043 Ok(())
26044 }
26045
26046 fn generate_auto_increment_property(&mut self, e: &AutoIncrementProperty) -> Result<()> {
26047 self.write_keyword("AUTO_INCREMENT");
26049 self.write("=");
26050 self.generate_expression(&e.this)?;
26051 Ok(())
26052 }
26053
26054 fn generate_auto_refresh_property(&mut self, e: &AutoRefreshProperty) -> Result<()> {
26055 self.write_keyword("AUTO_REFRESH");
26057 self.write("=");
26058 self.generate_expression(&e.this)?;
26059 Ok(())
26060 }
26061
26062 fn generate_backup_property(&mut self, e: &BackupProperty) -> Result<()> {
26063 self.write_keyword("BACKUP");
26065 self.write_space();
26066 self.generate_expression(&e.this)?;
26067 Ok(())
26068 }
26069
26070 fn generate_base64_decode_binary(&mut self, e: &Base64DecodeBinary) -> Result<()> {
26071 self.write_keyword("BASE64_DECODE_BINARY");
26073 self.write("(");
26074 self.generate_expression(&e.this)?;
26075 if let Some(alphabet) = &e.alphabet {
26076 self.write(", ");
26077 self.generate_expression(alphabet)?;
26078 }
26079 self.write(")");
26080 Ok(())
26081 }
26082
26083 fn generate_base64_decode_string(&mut self, e: &Base64DecodeString) -> Result<()> {
26084 self.write_keyword("BASE64_DECODE_STRING");
26086 self.write("(");
26087 self.generate_expression(&e.this)?;
26088 if let Some(alphabet) = &e.alphabet {
26089 self.write(", ");
26090 self.generate_expression(alphabet)?;
26091 }
26092 self.write(")");
26093 Ok(())
26094 }
26095
26096 fn generate_base64_encode(&mut self, e: &Base64Encode) -> Result<()> {
26097 self.write_keyword("BASE64_ENCODE");
26099 self.write("(");
26100 self.generate_expression(&e.this)?;
26101 if let Some(max_line_length) = &e.max_line_length {
26102 self.write(", ");
26103 self.generate_expression(max_line_length)?;
26104 }
26105 if let Some(alphabet) = &e.alphabet {
26106 self.write(", ");
26107 self.generate_expression(alphabet)?;
26108 }
26109 self.write(")");
26110 Ok(())
26111 }
26112
26113 fn generate_block_compression_property(&mut self, e: &BlockCompressionProperty) -> Result<()> {
26114 self.write_keyword("BLOCKCOMPRESSION");
26116 self.write("=");
26117 if let Some(autotemp) = &e.autotemp {
26118 self.write_keyword("AUTOTEMP");
26119 self.write("(");
26120 self.generate_expression(autotemp)?;
26121 self.write(")");
26122 }
26123 if let Some(always) = &e.always {
26124 self.generate_expression(always)?;
26125 }
26126 if let Some(default) = &e.default {
26127 self.generate_expression(default)?;
26128 }
26129 if let Some(manual) = &e.manual {
26130 self.generate_expression(manual)?;
26131 }
26132 if let Some(never) = &e.never {
26133 self.generate_expression(never)?;
26134 }
26135 Ok(())
26136 }
26137
26138 fn generate_booland(&mut self, e: &Booland) -> Result<()> {
26139 self.write("((");
26141 self.generate_expression(&e.this)?;
26142 self.write(") ");
26143 self.write_keyword("AND");
26144 self.write(" (");
26145 self.generate_expression(&e.expression)?;
26146 self.write("))");
26147 Ok(())
26148 }
26149
26150 fn generate_boolor(&mut self, e: &Boolor) -> Result<()> {
26151 self.write("((");
26153 self.generate_expression(&e.this)?;
26154 self.write(") ");
26155 self.write_keyword("OR");
26156 self.write(" (");
26157 self.generate_expression(&e.expression)?;
26158 self.write("))");
26159 Ok(())
26160 }
26161
26162 fn generate_build_property(&mut self, e: &BuildProperty) -> Result<()> {
26163 self.write_keyword("BUILD");
26165 self.write_space();
26166 self.generate_expression(&e.this)?;
26167 Ok(())
26168 }
26169
26170 fn generate_byte_string(&mut self, e: &ByteString) -> Result<()> {
26171 self.generate_expression(&e.this)?;
26173 Ok(())
26174 }
26175
26176 fn generate_case_specific_column_constraint(
26177 &mut self,
26178 e: &CaseSpecificColumnConstraint,
26179 ) -> Result<()> {
26180 if e.not_.is_some() {
26182 self.write_keyword("NOT");
26183 self.write_space();
26184 }
26185 self.write_keyword("CASESPECIFIC");
26186 Ok(())
26187 }
26188
26189 fn generate_cast_to_str_type(&mut self, e: &CastToStrType) -> Result<()> {
26190 self.write_keyword("CAST");
26192 self.write("(");
26193 self.generate_expression(&e.this)?;
26194 if self.config.dialect == Some(DialectType::ClickHouse) {
26195 self.write(", ");
26197 } else {
26198 self.write_space();
26199 self.write_keyword("AS");
26200 self.write_space();
26201 }
26202 if let Some(to) = &e.to {
26203 self.generate_expression(to)?;
26204 }
26205 self.write(")");
26206 Ok(())
26207 }
26208
26209 fn generate_changes(&mut self, e: &Changes) -> Result<()> {
26210 self.write_keyword("CHANGES");
26213 self.write(" (");
26214 if let Some(information) = &e.information {
26215 self.write_keyword("INFORMATION");
26216 self.write(" => ");
26217 self.generate_expression(information)?;
26218 }
26219 self.write(")");
26220 if let Some(at_before) = &e.at_before {
26222 self.write(" ");
26223 self.generate_expression(at_before)?;
26224 }
26225 if let Some(end) = &e.end {
26226 self.write(" ");
26227 self.generate_expression(end)?;
26228 }
26229 Ok(())
26230 }
26231
26232 fn generate_character_set_column_constraint(
26233 &mut self,
26234 e: &CharacterSetColumnConstraint,
26235 ) -> Result<()> {
26236 self.write_keyword("CHARACTER SET");
26238 self.write_space();
26239 self.generate_expression(&e.this)?;
26240 Ok(())
26241 }
26242
26243 fn generate_character_set_property(&mut self, e: &CharacterSetProperty) -> Result<()> {
26244 if e.default.is_some() {
26246 self.write_keyword("DEFAULT");
26247 self.write_space();
26248 }
26249 self.write_keyword("CHARACTER SET");
26250 self.write("=");
26251 self.generate_expression(&e.this)?;
26252 Ok(())
26253 }
26254
26255 fn generate_check_column_constraint(&mut self, e: &CheckColumnConstraint) -> Result<()> {
26256 self.write_keyword("CHECK");
26258 self.write(" (");
26259 self.generate_expression(&e.this)?;
26260 self.write(")");
26261 if e.enforced.is_some() {
26262 self.write_space();
26263 self.write_keyword("ENFORCED");
26264 }
26265 Ok(())
26266 }
26267
26268 fn generate_assume_column_constraint(&mut self, e: &AssumeColumnConstraint) -> Result<()> {
26269 self.write_keyword("ASSUME");
26271 self.write(" (");
26272 self.generate_expression(&e.this)?;
26273 self.write(")");
26274 Ok(())
26275 }
26276
26277 fn generate_check_json(&mut self, e: &CheckJson) -> Result<()> {
26278 self.write_keyword("CHECK_JSON");
26280 self.write("(");
26281 self.generate_expression(&e.this)?;
26282 self.write(")");
26283 Ok(())
26284 }
26285
26286 fn generate_check_xml(&mut self, e: &CheckXml) -> Result<()> {
26287 self.write_keyword("CHECK_XML");
26289 self.write("(");
26290 self.generate_expression(&e.this)?;
26291 self.write(")");
26292 Ok(())
26293 }
26294
26295 fn generate_checksum_property(&mut self, e: &ChecksumProperty) -> Result<()> {
26296 self.write_keyword("CHECKSUM");
26298 self.write("=");
26299 if e.on.is_some() {
26300 self.write_keyword("ON");
26301 } else if e.default.is_some() {
26302 self.write_keyword("DEFAULT");
26303 } else {
26304 self.write_keyword("OFF");
26305 }
26306 Ok(())
26307 }
26308
26309 fn generate_clone(&mut self, e: &Clone) -> Result<()> {
26310 if e.shallow.is_some() {
26312 self.write_keyword("SHALLOW");
26313 self.write_space();
26314 }
26315 if e.copy.is_some() {
26316 self.write_keyword("COPY");
26317 } else {
26318 self.write_keyword("CLONE");
26319 }
26320 self.write_space();
26321 self.generate_expression(&e.this)?;
26322 Ok(())
26323 }
26324
26325 fn generate_cluster_by(&mut self, e: &ClusterBy) -> Result<()> {
26326 self.write_keyword("CLUSTER BY");
26328 self.write(" (");
26329 for (i, ord) in e.expressions.iter().enumerate() {
26330 if i > 0 {
26331 self.write(", ");
26332 }
26333 self.generate_ordered(ord)?;
26334 }
26335 self.write(")");
26336 Ok(())
26337 }
26338
26339 fn generate_cluster_by_columns_property(&mut self, e: &ClusterByColumnsProperty) -> Result<()> {
26340 self.write_keyword("CLUSTER BY");
26342 self.write_space();
26343 for (i, col) in e.columns.iter().enumerate() {
26344 if i > 0 {
26345 self.write(", ");
26346 }
26347 self.generate_identifier(col)?;
26348 }
26349 Ok(())
26350 }
26351
26352 fn generate_clustered_by_property(&mut self, e: &ClusteredByProperty) -> Result<()> {
26353 self.write_keyword("CLUSTERED BY");
26355 self.write(" (");
26356 for (i, expr) in e.expressions.iter().enumerate() {
26357 if i > 0 {
26358 self.write(", ");
26359 }
26360 self.generate_expression(expr)?;
26361 }
26362 self.write(")");
26363 if let Some(sorted_by) = &e.sorted_by {
26364 self.write_space();
26365 self.write_keyword("SORTED BY");
26366 self.write(" (");
26367 if let Expression::Tuple(t) = sorted_by.as_ref() {
26369 for (i, expr) in t.expressions.iter().enumerate() {
26370 if i > 0 {
26371 self.write(", ");
26372 }
26373 self.generate_expression(expr)?;
26374 }
26375 } else {
26376 self.generate_expression(sorted_by)?;
26377 }
26378 self.write(")");
26379 }
26380 if let Some(buckets) = &e.buckets {
26381 self.write_space();
26382 self.write_keyword("INTO");
26383 self.write_space();
26384 self.generate_expression(buckets)?;
26385 self.write_space();
26386 self.write_keyword("BUCKETS");
26387 }
26388 Ok(())
26389 }
26390
26391 fn generate_collate_property(&mut self, e: &CollateProperty) -> Result<()> {
26392 if e.default.is_some() {
26396 self.write_keyword("DEFAULT");
26397 self.write_space();
26398 }
26399 self.write_keyword("COLLATE");
26400 match self.config.dialect {
26402 Some(DialectType::BigQuery) => self.write_space(),
26403 _ => self.write("="),
26404 }
26405 self.generate_expression(&e.this)?;
26406 Ok(())
26407 }
26408
26409 fn generate_column_constraint(&mut self, e: &ColumnConstraint) -> Result<()> {
26410 match e {
26412 ColumnConstraint::NotNull => {
26413 self.write_keyword("NOT NULL");
26414 }
26415 ColumnConstraint::Null => {
26416 self.write_keyword("NULL");
26417 }
26418 ColumnConstraint::Unique => {
26419 self.write_keyword("UNIQUE");
26420 }
26421 ColumnConstraint::PrimaryKey => {
26422 self.write_keyword("PRIMARY KEY");
26423 }
26424 ColumnConstraint::Default(expr) => {
26425 self.write_keyword("DEFAULT");
26426 self.write_space();
26427 self.generate_expression(expr)?;
26428 }
26429 ColumnConstraint::Check(expr) => {
26430 self.write_keyword("CHECK");
26431 self.write(" (");
26432 self.generate_expression(expr)?;
26433 self.write(")");
26434 }
26435 ColumnConstraint::References(fk_ref) => {
26436 if fk_ref.has_foreign_key_keywords {
26437 self.write_keyword("FOREIGN KEY");
26438 self.write_space();
26439 }
26440 self.write_keyword("REFERENCES");
26441 self.write_space();
26442 self.generate_table(&fk_ref.table)?;
26443 if !fk_ref.columns.is_empty() {
26444 self.write(" (");
26445 for (i, col) in fk_ref.columns.iter().enumerate() {
26446 if i > 0 {
26447 self.write(", ");
26448 }
26449 self.generate_identifier(col)?;
26450 }
26451 self.write(")");
26452 }
26453 }
26454 ColumnConstraint::GeneratedAsIdentity(gen) => {
26455 self.write_keyword("GENERATED");
26456 self.write_space();
26457 if gen.always {
26458 self.write_keyword("ALWAYS");
26459 } else {
26460 self.write_keyword("BY DEFAULT");
26461 if gen.on_null {
26462 self.write_space();
26463 self.write_keyword("ON NULL");
26464 }
26465 }
26466 self.write_space();
26467 self.write_keyword("AS IDENTITY");
26468 }
26469 ColumnConstraint::Collate(collation) => {
26470 self.write_keyword("COLLATE");
26471 self.write_space();
26472 self.generate_identifier(collation)?;
26473 }
26474 ColumnConstraint::Comment(comment) => {
26475 self.write_keyword("COMMENT");
26476 self.write(" '");
26477 self.write(comment);
26478 self.write("'");
26479 }
26480 ColumnConstraint::ComputedColumn(cc) => {
26481 self.generate_computed_column_inline(cc)?;
26482 }
26483 ColumnConstraint::GeneratedAsRow(gar) => {
26484 self.generate_generated_as_row_inline(gar)?;
26485 }
26486 ColumnConstraint::Tags(tags) => {
26487 self.write_keyword("TAG");
26488 self.write(" (");
26489 for (i, expr) in tags.expressions.iter().enumerate() {
26490 if i > 0 {
26491 self.write(", ");
26492 }
26493 self.generate_expression(expr)?;
26494 }
26495 self.write(")");
26496 }
26497 ColumnConstraint::Path(path_expr) => {
26498 self.write_keyword("PATH");
26499 self.write_space();
26500 self.generate_expression(path_expr)?;
26501 }
26502 }
26503 Ok(())
26504 }
26505
26506 fn generate_column_position(&mut self, e: &ColumnPosition) -> Result<()> {
26507 match e {
26509 ColumnPosition::First => {
26510 self.write_keyword("FIRST");
26511 }
26512 ColumnPosition::After(ident) => {
26513 self.write_keyword("AFTER");
26514 self.write_space();
26515 self.generate_identifier(ident)?;
26516 }
26517 }
26518 Ok(())
26519 }
26520
26521 fn generate_column_prefix(&mut self, e: &ColumnPrefix) -> Result<()> {
26522 self.generate_expression(&e.this)?;
26524 self.write("(");
26525 self.generate_expression(&e.expression)?;
26526 self.write(")");
26527 Ok(())
26528 }
26529
26530 fn generate_columns(&mut self, e: &Columns) -> Result<()> {
26531 if let Some(ref unpack) = e.unpack {
26534 if let Expression::Boolean(b) = unpack.as_ref() {
26535 if b.value {
26536 self.write("*");
26537 }
26538 }
26539 }
26540 self.write_keyword("COLUMNS");
26541 self.write("(");
26542 self.generate_expression(&e.this)?;
26543 self.write(")");
26544 Ok(())
26545 }
26546
26547 fn generate_combined_agg_func(&mut self, e: &CombinedAggFunc) -> Result<()> {
26548 self.generate_expression(&e.this)?;
26550 self.write("(");
26551 for (i, expr) in e.expressions.iter().enumerate() {
26552 if i > 0 {
26553 self.write(", ");
26554 }
26555 self.generate_expression(expr)?;
26556 }
26557 self.write(")");
26558 Ok(())
26559 }
26560
26561 fn generate_combined_parameterized_agg(&mut self, e: &CombinedParameterizedAgg) -> Result<()> {
26562 self.generate_expression(&e.this)?;
26564 self.write("(");
26565 for (i, param) in e.params.iter().enumerate() {
26566 if i > 0 {
26567 self.write(", ");
26568 }
26569 self.generate_expression(param)?;
26570 }
26571 self.write(")(");
26572 for (i, expr) in e.expressions.iter().enumerate() {
26573 if i > 0 {
26574 self.write(", ");
26575 }
26576 self.generate_expression(expr)?;
26577 }
26578 self.write(")");
26579 Ok(())
26580 }
26581
26582 fn generate_commit(&mut self, e: &Commit) -> Result<()> {
26583 self.write_keyword("COMMIT");
26585
26586 if e.this.is_none()
26588 && matches!(
26589 self.config.dialect,
26590 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26591 )
26592 {
26593 self.write_space();
26594 self.write_keyword("TRANSACTION");
26595 }
26596
26597 if let Some(this) = &e.this {
26599 let is_transaction_marker = matches!(
26601 this.as_ref(),
26602 Expression::Identifier(id) if id.name == "TRANSACTION"
26603 );
26604
26605 self.write_space();
26606 self.write_keyword("TRANSACTION");
26607
26608 if !is_transaction_marker {
26610 self.write_space();
26611 self.generate_expression(this)?;
26612 }
26613 }
26614
26615 if let Some(durability) = &e.durability {
26617 self.write_space();
26618 self.write_keyword("WITH");
26619 self.write(" (");
26620 self.write_keyword("DELAYED_DURABILITY");
26621 self.write(" = ");
26622 if let Expression::Boolean(BooleanLiteral { value: true }) = durability.as_ref() {
26623 self.write_keyword("ON");
26624 } else {
26625 self.write_keyword("OFF");
26626 }
26627 self.write(")");
26628 }
26629
26630 if let Some(chain) = &e.chain {
26632 self.write_space();
26633 if let Expression::Boolean(BooleanLiteral { value: false }) = chain.as_ref() {
26634 self.write_keyword("AND NO CHAIN");
26635 } else {
26636 self.write_keyword("AND CHAIN");
26637 }
26638 }
26639 Ok(())
26640 }
26641
26642 fn generate_comprehension(&mut self, e: &Comprehension) -> Result<()> {
26643 self.write("[");
26645 self.generate_expression(&e.this)?;
26646 self.write_space();
26647 self.write_keyword("FOR");
26648 self.write_space();
26649 self.generate_expression(&e.expression)?;
26650 if let Some(pos) = &e.position {
26652 self.write(", ");
26653 self.generate_expression(pos)?;
26654 }
26655 if let Some(iterator) = &e.iterator {
26656 self.write_space();
26657 self.write_keyword("IN");
26658 self.write_space();
26659 self.generate_expression(iterator)?;
26660 }
26661 if let Some(condition) = &e.condition {
26662 self.write_space();
26663 self.write_keyword("IF");
26664 self.write_space();
26665 self.generate_expression(condition)?;
26666 }
26667 self.write("]");
26668 Ok(())
26669 }
26670
26671 fn generate_compress(&mut self, e: &Compress) -> Result<()> {
26672 self.write_keyword("COMPRESS");
26674 self.write("(");
26675 self.generate_expression(&e.this)?;
26676 if let Some(method) = &e.method {
26677 self.write(", '");
26678 self.write(method);
26679 self.write("'");
26680 }
26681 self.write(")");
26682 Ok(())
26683 }
26684
26685 fn generate_compress_column_constraint(&mut self, e: &CompressColumnConstraint) -> Result<()> {
26686 self.write_keyword("COMPRESS");
26688 if let Some(this) = &e.this {
26689 self.write_space();
26690 self.generate_expression(this)?;
26691 }
26692 Ok(())
26693 }
26694
26695 fn generate_computed_column_constraint(&mut self, e: &ComputedColumnConstraint) -> Result<()> {
26696 self.write_keyword("AS");
26698 self.write_space();
26699 self.generate_expression(&e.this)?;
26700 if e.not_null.is_some() {
26701 self.write_space();
26702 self.write_keyword("PERSISTED NOT NULL");
26703 } else if e.persisted.is_some() {
26704 self.write_space();
26705 self.write_keyword("PERSISTED");
26706 }
26707 Ok(())
26708 }
26709
26710 fn generate_computed_column_inline(&mut self, cc: &ComputedColumn) -> Result<()> {
26714 let computed_expr = if matches!(
26715 self.config.dialect,
26716 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26717 ) {
26718 match &*cc.expression {
26719 Expression::Year(y) if !matches!(&y.this, Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
26720 {
26721 let wrapped = Expression::Cast(Box::new(Cast {
26722 this: y.this.clone(),
26723 to: DataType::Date,
26724 trailing_comments: Vec::new(),
26725 double_colon_syntax: false,
26726 format: None,
26727 default: None,
26728 inferred_type: None,
26729 }));
26730 Expression::Year(Box::new(UnaryFunc::new(wrapped)))
26731 }
26732 Expression::Function(f)
26733 if f.name.eq_ignore_ascii_case("YEAR")
26734 && f.args.len() == 1
26735 && !matches!(&f.args[0], Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
26736 {
26737 let wrapped = Expression::Cast(Box::new(Cast {
26738 this: f.args[0].clone(),
26739 to: DataType::Date,
26740 trailing_comments: Vec::new(),
26741 double_colon_syntax: false,
26742 format: None,
26743 default: None,
26744 inferred_type: None,
26745 }));
26746 Expression::Function(Box::new(Function::new("YEAR".to_string(), vec![wrapped])))
26747 }
26748 _ => *cc.expression.clone(),
26749 }
26750 } else {
26751 *cc.expression.clone()
26752 };
26753
26754 match cc.persistence_kind.as_deref() {
26755 Some("STORED") | Some("VIRTUAL") => {
26756 self.write_keyword("GENERATED ALWAYS AS");
26758 self.write(" (");
26759 self.generate_expression(&computed_expr)?;
26760 self.write(")");
26761 self.write_space();
26762 if cc.persisted {
26763 self.write_keyword("STORED");
26764 } else {
26765 self.write_keyword("VIRTUAL");
26766 }
26767 }
26768 Some("PERSISTED") => {
26769 self.write_keyword("AS");
26771 self.write(" (");
26772 self.generate_expression(&computed_expr)?;
26773 self.write(")");
26774 self.write_space();
26775 self.write_keyword("PERSISTED");
26776 if let Some(ref dt) = cc.data_type {
26778 self.write_space();
26779 self.generate_data_type(dt)?;
26780 }
26781 if cc.not_null {
26782 self.write_space();
26783 self.write_keyword("NOT NULL");
26784 }
26785 }
26786 _ => {
26787 if matches!(
26790 self.config.dialect,
26791 Some(DialectType::Spark)
26792 | Some(DialectType::Databricks)
26793 | Some(DialectType::Hive)
26794 ) {
26795 self.write_keyword("GENERATED ALWAYS AS");
26796 self.write(" (");
26797 self.generate_expression(&computed_expr)?;
26798 self.write(")");
26799 } else if matches!(
26800 self.config.dialect,
26801 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26802 ) {
26803 self.write_keyword("AS");
26804 let omit_parens = matches!(computed_expr, Expression::Year(_))
26805 || matches!(&computed_expr, Expression::Function(f) if f.name.eq_ignore_ascii_case("YEAR"));
26806 if omit_parens {
26807 self.write_space();
26808 self.generate_expression(&computed_expr)?;
26809 } else {
26810 self.write(" (");
26811 self.generate_expression(&computed_expr)?;
26812 self.write(")");
26813 }
26814 } else {
26815 self.write_keyword("AS");
26816 self.write(" (");
26817 self.generate_expression(&computed_expr)?;
26818 self.write(")");
26819 }
26820 }
26821 }
26822 Ok(())
26823 }
26824
26825 fn generate_generated_as_row_inline(&mut self, gar: &GeneratedAsRow) -> Result<()> {
26828 self.write_keyword("GENERATED ALWAYS AS ROW ");
26829 if gar.start {
26830 self.write_keyword("START");
26831 } else {
26832 self.write_keyword("END");
26833 }
26834 if gar.hidden {
26835 self.write_space();
26836 self.write_keyword("HIDDEN");
26837 }
26838 Ok(())
26839 }
26840
26841 fn generate_system_versioning_content(
26843 &mut self,
26844 e: &WithSystemVersioningProperty,
26845 ) -> Result<()> {
26846 let mut parts = Vec::new();
26847
26848 if let Some(this) = &e.this {
26849 let mut s = String::from("HISTORY_TABLE=");
26850 let mut gen = Generator::with_arc_config(self.config.clone());
26851 gen.generate_expression(this)?;
26852 s.push_str(&gen.output);
26853 parts.push(s);
26854 }
26855
26856 if let Some(data_consistency) = &e.data_consistency {
26857 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
26858 let mut gen = Generator::with_arc_config(self.config.clone());
26859 gen.generate_expression(data_consistency)?;
26860 s.push_str(&gen.output);
26861 parts.push(s);
26862 }
26863
26864 if let Some(retention_period) = &e.retention_period {
26865 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
26866 let mut gen = Generator::with_arc_config(self.config.clone());
26867 gen.generate_expression(retention_period)?;
26868 s.push_str(&gen.output);
26869 parts.push(s);
26870 }
26871
26872 self.write_keyword("SYSTEM_VERSIONING");
26873 self.write("=");
26874
26875 if !parts.is_empty() {
26876 self.write_keyword("ON");
26877 self.write("(");
26878 self.write(&parts.join(", "));
26879 self.write(")");
26880 } else if e.on.is_some() {
26881 self.write_keyword("ON");
26882 } else {
26883 self.write_keyword("OFF");
26884 }
26885
26886 Ok(())
26887 }
26888
26889 fn generate_conditional_insert(&mut self, e: &ConditionalInsert) -> Result<()> {
26890 if e.else_.is_some() {
26893 self.write_keyword("ELSE");
26894 self.write_space();
26895 } else if let Some(expression) = &e.expression {
26896 self.write_keyword("WHEN");
26897 self.write_space();
26898 self.generate_expression(expression)?;
26899 self.write_space();
26900 self.write_keyword("THEN");
26901 self.write_space();
26902 }
26903
26904 if let Expression::Insert(insert) = e.this.as_ref() {
26907 self.write_keyword("INTO");
26908 self.write_space();
26909 self.generate_table(&insert.table)?;
26910
26911 if !insert.columns.is_empty() {
26913 self.write(" (");
26914 for (i, col) in insert.columns.iter().enumerate() {
26915 if i > 0 {
26916 self.write(", ");
26917 }
26918 self.generate_identifier(col)?;
26919 }
26920 self.write(")");
26921 }
26922
26923 if !insert.values.is_empty() {
26925 self.write_space();
26926 self.write_keyword("VALUES");
26927 for (row_idx, row) in insert.values.iter().enumerate() {
26928 if row_idx > 0 {
26929 self.write(", ");
26930 }
26931 self.write(" (");
26932 for (i, val) in row.iter().enumerate() {
26933 if i > 0 {
26934 self.write(", ");
26935 }
26936 self.generate_expression(val)?;
26937 }
26938 self.write(")");
26939 }
26940 }
26941 } else {
26942 self.generate_expression(&e.this)?;
26944 }
26945 Ok(())
26946 }
26947
26948 fn generate_constraint(&mut self, e: &Constraint) -> Result<()> {
26949 self.write_keyword("CONSTRAINT");
26951 self.write_space();
26952 self.generate_expression(&e.this)?;
26953 if !e.expressions.is_empty() {
26954 self.write_space();
26955 for (i, expr) in e.expressions.iter().enumerate() {
26956 if i > 0 {
26957 self.write_space();
26958 }
26959 self.generate_expression(expr)?;
26960 }
26961 }
26962 Ok(())
26963 }
26964
26965 fn generate_convert_timezone(&mut self, e: &ConvertTimezone) -> Result<()> {
26966 self.write_keyword("CONVERT_TIMEZONE");
26968 self.write("(");
26969 let mut first = true;
26970 if let Some(source_tz) = &e.source_tz {
26971 self.generate_expression(source_tz)?;
26972 first = false;
26973 }
26974 if let Some(target_tz) = &e.target_tz {
26975 if !first {
26976 self.write(", ");
26977 }
26978 self.generate_expression(target_tz)?;
26979 first = false;
26980 }
26981 if let Some(timestamp) = &e.timestamp {
26982 if !first {
26983 self.write(", ");
26984 }
26985 self.generate_expression(timestamp)?;
26986 }
26987 self.write(")");
26988 Ok(())
26989 }
26990
26991 fn generate_convert_to_charset(&mut self, e: &ConvertToCharset) -> Result<()> {
26992 self.write_keyword("CONVERT");
26994 self.write("(");
26995 self.generate_expression(&e.this)?;
26996 if let Some(dest) = &e.dest {
26997 self.write_space();
26998 self.write_keyword("USING");
26999 self.write_space();
27000 self.generate_expression(dest)?;
27001 }
27002 self.write(")");
27003 Ok(())
27004 }
27005
27006 fn generate_copy(&mut self, e: &CopyStmt) -> Result<()> {
27007 self.write_keyword("COPY");
27008 if e.is_into {
27009 self.write_space();
27010 self.write_keyword("INTO");
27011 }
27012 self.write_space();
27013
27014 if let Expression::Literal(lit) = &e.this {
27016 if let Literal::String(s) = lit.as_ref() {
27017 if s.starts_with('@') {
27018 self.write(s);
27019 } else {
27020 self.generate_expression(&e.this)?;
27021 }
27022 }
27023 } else {
27024 self.generate_expression(&e.this)?;
27025 }
27026
27027 if e.kind {
27029 if self.config.pretty {
27031 self.write_newline();
27032 } else {
27033 self.write_space();
27034 }
27035 self.write_keyword("FROM");
27036 self.write_space();
27037 } else if !e.files.is_empty() {
27038 if self.config.pretty {
27040 self.write_newline();
27041 } else {
27042 self.write_space();
27043 }
27044 self.write_keyword("TO");
27045 self.write_space();
27046 }
27047
27048 for (i, file) in e.files.iter().enumerate() {
27050 if i > 0 {
27051 self.write_space();
27052 }
27053 if let Expression::Literal(lit) = file {
27055 if let Literal::String(s) = lit.as_ref() {
27056 if s.starts_with('@') {
27057 self.write(s);
27058 } else {
27059 self.generate_expression(file)?;
27060 }
27061 }
27062 } else if let Expression::Identifier(id) = file {
27063 if id.quoted {
27065 self.write("`");
27066 self.write(&id.name);
27067 self.write("`");
27068 } else {
27069 self.generate_expression(file)?;
27070 }
27071 } else {
27072 self.generate_expression(file)?;
27073 }
27074 }
27075
27076 if !e.with_wrapped {
27078 if let Some(ref creds) = e.credentials {
27079 if let Some(ref storage) = creds.storage {
27080 if self.config.pretty {
27081 self.write_newline();
27082 } else {
27083 self.write_space();
27084 }
27085 self.write_keyword("STORAGE_INTEGRATION");
27086 self.write(" = ");
27087 self.write(storage);
27088 }
27089 if creds.credentials.is_empty() {
27090 if self.config.pretty {
27092 self.write_newline();
27093 } else {
27094 self.write_space();
27095 }
27096 self.write_keyword("CREDENTIALS");
27097 self.write(" = ()");
27098 } else {
27099 if self.config.pretty {
27100 self.write_newline();
27101 } else {
27102 self.write_space();
27103 }
27104 self.write_keyword("CREDENTIALS");
27105 if creds.credentials.len() == 1 && creds.credentials[0].0.is_empty() {
27108 self.write(" '");
27110 self.write(&creds.credentials[0].1);
27111 self.write("'");
27112 } else {
27113 self.write(" = (");
27115 for (i, (k, v)) in creds.credentials.iter().enumerate() {
27116 if i > 0 {
27117 self.write_space();
27118 }
27119 self.write(k);
27120 self.write("='");
27121 self.write(v);
27122 self.write("'");
27123 }
27124 self.write(")");
27125 }
27126 }
27127 if let Some(ref encryption) = creds.encryption {
27128 self.write_space();
27129 self.write_keyword("ENCRYPTION");
27130 self.write(" = ");
27131 self.write(encryption);
27132 }
27133 }
27134 }
27135
27136 if !e.params.is_empty() {
27138 if e.with_wrapped {
27139 self.write_space();
27141 self.write_keyword("WITH");
27142 self.write(" (");
27143 for (i, param) in e.params.iter().enumerate() {
27144 if i > 0 {
27145 self.write(", ");
27146 }
27147 self.generate_copy_param_with_format(param)?;
27148 }
27149 self.write(")");
27150 } else {
27151 for param in &e.params {
27155 if self.config.pretty {
27156 self.write_newline();
27157 } else {
27158 self.write_space();
27159 }
27160 self.write(¶m.name);
27162 if let Some(ref value) = param.value {
27163 if param.eq {
27165 self.write(" = ");
27166 } else {
27167 self.write(" ");
27168 }
27169 if !param.values.is_empty() {
27170 self.write("(");
27171 for (i, v) in param.values.iter().enumerate() {
27172 if i > 0 {
27173 self.write_space();
27174 }
27175 self.generate_copy_nested_param(v)?;
27176 }
27177 self.write(")");
27178 } else {
27179 self.generate_copy_param_value(value)?;
27181 }
27182 } else if !param.values.is_empty() {
27183 if param.eq {
27185 self.write(" = (");
27186 } else {
27187 self.write(" (");
27188 }
27189 let is_key_value_pairs = param
27194 .values
27195 .first()
27196 .map_or(false, |v| matches!(v, Expression::Eq(_)));
27197 let sep = if is_key_value_pairs && param.eq {
27198 " "
27199 } else {
27200 ", "
27201 };
27202 for (i, v) in param.values.iter().enumerate() {
27203 if i > 0 {
27204 self.write(sep);
27205 }
27206 self.generate_copy_nested_param(v)?;
27207 }
27208 self.write(")");
27209 }
27210 }
27211 }
27212 }
27213
27214 Ok(())
27215 }
27216
27217 fn generate_copy_param_with_format(&mut self, param: &CopyParameter) -> Result<()> {
27220 self.write_keyword(¶m.name);
27221 if !param.values.is_empty() {
27222 self.write(" = (");
27224 for (i, v) in param.values.iter().enumerate() {
27225 if i > 0 {
27226 self.write(", ");
27227 }
27228 self.generate_copy_nested_param(v)?;
27229 }
27230 self.write(")");
27231 } else if let Some(ref value) = param.value {
27232 if param.eq {
27233 self.write(" = ");
27234 } else {
27235 self.write(" ");
27236 }
27237 self.generate_expression(value)?;
27238 }
27239 Ok(())
27240 }
27241
27242 fn generate_copy_nested_param(&mut self, expr: &Expression) -> Result<()> {
27244 match expr {
27245 Expression::Eq(eq) => {
27246 match &eq.left {
27248 Expression::Column(c) => self.write(&c.name.name),
27249 _ => self.generate_expression(&eq.left)?,
27250 }
27251 self.write("=");
27252 match &eq.right {
27254 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
27255 let Literal::String(s) = lit.as_ref() else {
27256 unreachable!()
27257 };
27258 self.write("'");
27259 self.write(s);
27260 self.write("'");
27261 }
27262 Expression::Tuple(t) => {
27263 self.write("(");
27265 if self.config.pretty {
27266 self.write_newline();
27267 self.indent_level += 1;
27268 for (i, item) in t.expressions.iter().enumerate() {
27269 if i > 0 {
27270 self.write(", ");
27271 }
27272 self.write_indent();
27273 self.generate_expression(item)?;
27274 }
27275 self.write_newline();
27276 self.indent_level -= 1;
27277 } else {
27278 for (i, item) in t.expressions.iter().enumerate() {
27279 if i > 0 {
27280 self.write(", ");
27281 }
27282 self.generate_expression(item)?;
27283 }
27284 }
27285 self.write(")");
27286 }
27287 _ => self.generate_expression(&eq.right)?,
27288 }
27289 Ok(())
27290 }
27291 Expression::Column(c) => {
27292 self.write(&c.name.name);
27294 Ok(())
27295 }
27296 _ => self.generate_expression(expr),
27297 }
27298 }
27299
27300 fn generate_copy_param_value(&mut self, expr: &Expression) -> Result<()> {
27303 match expr {
27304 Expression::Column(c) => {
27305 if c.name.quoted {
27307 self.write("\"");
27308 self.write(&c.name.name);
27309 self.write("\"");
27310 } else {
27311 self.write(&c.name.name);
27312 }
27313 Ok(())
27314 }
27315 Expression::Identifier(id) => {
27316 if id.quoted {
27318 self.write("\"");
27319 self.write(&id.name);
27320 self.write("\"");
27321 } else {
27322 self.write(&id.name);
27323 }
27324 Ok(())
27325 }
27326 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
27327 let Literal::String(s) = lit.as_ref() else {
27328 unreachable!()
27329 };
27330 self.write("'");
27332 self.write(s);
27333 self.write("'");
27334 Ok(())
27335 }
27336 _ => self.generate_expression(expr),
27337 }
27338 }
27339
27340 fn generate_copy_parameter(&mut self, e: &CopyParameter) -> Result<()> {
27341 self.write_keyword(&e.name);
27342 if let Some(ref value) = e.value {
27343 if e.eq {
27344 self.write(" = ");
27345 } else {
27346 self.write(" ");
27347 }
27348 self.generate_expression(value)?;
27349 }
27350 if !e.values.is_empty() {
27351 if e.eq {
27352 self.write(" = ");
27353 } else {
27354 self.write(" ");
27355 }
27356 self.write("(");
27357 for (i, v) in e.values.iter().enumerate() {
27358 if i > 0 {
27359 self.write(", ");
27360 }
27361 self.generate_expression(v)?;
27362 }
27363 self.write(")");
27364 }
27365 Ok(())
27366 }
27367
27368 fn generate_corr(&mut self, e: &Corr) -> Result<()> {
27369 self.write_keyword("CORR");
27371 self.write("(");
27372 self.generate_expression(&e.this)?;
27373 self.write(", ");
27374 self.generate_expression(&e.expression)?;
27375 self.write(")");
27376 Ok(())
27377 }
27378
27379 fn generate_cosine_distance(&mut self, e: &CosineDistance) -> Result<()> {
27380 self.write_keyword("COSINE_DISTANCE");
27382 self.write("(");
27383 self.generate_expression(&e.this)?;
27384 self.write(", ");
27385 self.generate_expression(&e.expression)?;
27386 self.write(")");
27387 Ok(())
27388 }
27389
27390 fn generate_covar_pop(&mut self, e: &CovarPop) -> Result<()> {
27391 self.write_keyword("COVAR_POP");
27393 self.write("(");
27394 self.generate_expression(&e.this)?;
27395 self.write(", ");
27396 self.generate_expression(&e.expression)?;
27397 self.write(")");
27398 Ok(())
27399 }
27400
27401 fn generate_covar_samp(&mut self, e: &CovarSamp) -> Result<()> {
27402 self.write_keyword("COVAR_SAMP");
27404 self.write("(");
27405 self.generate_expression(&e.this)?;
27406 self.write(", ");
27407 self.generate_expression(&e.expression)?;
27408 self.write(")");
27409 Ok(())
27410 }
27411
27412 fn generate_credentials(&mut self, e: &Credentials) -> Result<()> {
27413 self.write_keyword("CREDENTIALS");
27415 self.write(" (");
27416 for (i, (key, value)) in e.credentials.iter().enumerate() {
27417 if i > 0 {
27418 self.write(", ");
27419 }
27420 self.write(key);
27421 self.write("='");
27422 self.write(value);
27423 self.write("'");
27424 }
27425 self.write(")");
27426 Ok(())
27427 }
27428
27429 fn generate_credentials_property(&mut self, e: &CredentialsProperty) -> Result<()> {
27430 self.write_keyword("CREDENTIALS");
27432 self.write("=(");
27433 for (i, expr) in e.expressions.iter().enumerate() {
27434 if i > 0 {
27435 self.write(", ");
27436 }
27437 self.generate_expression(expr)?;
27438 }
27439 self.write(")");
27440 Ok(())
27441 }
27442
27443 fn generate_cte(&mut self, e: &Cte) -> Result<()> {
27444 use crate::dialects::DialectType;
27445
27446 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !e.alias_first {
27449 self.generate_expression(&e.this)?;
27450 self.write_space();
27451 self.write_keyword("AS");
27452 self.write_space();
27453 self.generate_identifier(&e.alias)?;
27454 return Ok(());
27455 }
27456 self.write(&e.alias.name);
27457
27458 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
27460
27461 if !e.columns.is_empty() && !skip_cte_columns {
27462 self.write("(");
27463 for (i, col) in e.columns.iter().enumerate() {
27464 if i > 0 {
27465 self.write(", ");
27466 }
27467 self.write(&col.name);
27468 }
27469 self.write(")");
27470 }
27471 if !e.key_expressions.is_empty() {
27473 self.write_space();
27474 self.write_keyword("USING KEY");
27475 self.write(" (");
27476 for (i, key) in e.key_expressions.iter().enumerate() {
27477 if i > 0 {
27478 self.write(", ");
27479 }
27480 self.write(&key.name);
27481 }
27482 self.write(")");
27483 }
27484 self.write_space();
27485 self.write_keyword("AS");
27486 self.write_space();
27487 if let Some(materialized) = e.materialized {
27488 if materialized {
27489 self.write_keyword("MATERIALIZED");
27490 } else {
27491 self.write_keyword("NOT MATERIALIZED");
27492 }
27493 self.write_space();
27494 }
27495 self.write("(");
27496 self.generate_expression(&e.this)?;
27497 self.write(")");
27498 Ok(())
27499 }
27500
27501 fn generate_cube(&mut self, e: &Cube) -> Result<()> {
27502 if e.expressions.is_empty() {
27504 self.write_keyword("WITH CUBE");
27505 } else {
27506 self.write_keyword("CUBE");
27507 self.write("(");
27508 for (i, expr) in e.expressions.iter().enumerate() {
27509 if i > 0 {
27510 self.write(", ");
27511 }
27512 self.generate_expression(expr)?;
27513 }
27514 self.write(")");
27515 }
27516 Ok(())
27517 }
27518
27519 fn generate_current_datetime(&mut self, e: &CurrentDatetime) -> Result<()> {
27520 self.write_keyword("CURRENT_DATETIME");
27522 if let Some(this) = &e.this {
27523 self.write("(");
27524 self.generate_expression(this)?;
27525 self.write(")");
27526 }
27527 Ok(())
27528 }
27529
27530 fn generate_current_schema(&mut self, _e: &CurrentSchema) -> Result<()> {
27531 self.write_keyword("CURRENT_SCHEMA");
27533 Ok(())
27534 }
27535
27536 fn generate_current_schemas(&mut self, e: &CurrentSchemas) -> Result<()> {
27537 self.write_keyword("CURRENT_SCHEMAS");
27539 self.write("(");
27540 if !matches!(
27542 self.config.dialect,
27543 Some(crate::dialects::DialectType::Snowflake)
27544 ) {
27545 if let Some(this) = &e.this {
27546 self.generate_expression(this)?;
27547 }
27548 }
27549 self.write(")");
27550 Ok(())
27551 }
27552
27553 fn generate_current_user(&mut self, e: &CurrentUser) -> Result<()> {
27554 self.write_keyword("CURRENT_USER");
27556 let needs_parens = e.this.is_some()
27558 || matches!(
27559 self.config.dialect,
27560 Some(DialectType::Snowflake)
27561 | Some(DialectType::Spark)
27562 | Some(DialectType::Hive)
27563 | Some(DialectType::DuckDB)
27564 | Some(DialectType::BigQuery)
27565 | Some(DialectType::MySQL)
27566 | Some(DialectType::Databricks)
27567 );
27568 if needs_parens {
27569 self.write("()");
27570 }
27571 Ok(())
27572 }
27573
27574 fn generate_d_pipe(&mut self, e: &DPipe) -> Result<()> {
27575 if self.config.dialect == Some(DialectType::Solr) {
27577 self.generate_expression(&e.this)?;
27578 self.write(" ");
27579 self.write_keyword("OR");
27580 self.write(" ");
27581 self.generate_expression(&e.expression)?;
27582 } else if self.config.dialect == Some(DialectType::MySQL) {
27583 self.generate_mysql_concat_from_dpipe(e)?;
27584 } else {
27585 self.generate_expression(&e.this)?;
27587 self.write(" || ");
27588 self.generate_expression(&e.expression)?;
27589 }
27590 Ok(())
27591 }
27592
27593 fn generate_data_blocksize_property(&mut self, e: &DataBlocksizeProperty) -> Result<()> {
27594 self.write_keyword("DATABLOCKSIZE");
27596 self.write("=");
27597 if let Some(size) = e.size {
27598 self.write(&size.to_string());
27599 if let Some(units) = &e.units {
27600 self.write_space();
27601 self.generate_expression(units)?;
27602 }
27603 } else if e.minimum.is_some() {
27604 self.write_keyword("MINIMUM");
27605 } else if e.maximum.is_some() {
27606 self.write_keyword("MAXIMUM");
27607 } else if e.default.is_some() {
27608 self.write_keyword("DEFAULT");
27609 }
27610 Ok(())
27611 }
27612
27613 fn generate_data_deletion_property(&mut self, e: &DataDeletionProperty) -> Result<()> {
27614 self.write_keyword("DATA_DELETION");
27616 self.write("=");
27617
27618 let is_on = matches!(&*e.on, Expression::Boolean(BooleanLiteral { value: true }));
27619 let has_options = e.filter_column.is_some() || e.retention_period.is_some();
27620
27621 if is_on {
27622 self.write_keyword("ON");
27623 if has_options {
27624 self.write("(");
27625 let mut first = true;
27626 if let Some(filter_column) = &e.filter_column {
27627 self.write_keyword("FILTER_COLUMN");
27628 self.write("=");
27629 self.generate_expression(filter_column)?;
27630 first = false;
27631 }
27632 if let Some(retention_period) = &e.retention_period {
27633 if !first {
27634 self.write(", ");
27635 }
27636 self.write_keyword("RETENTION_PERIOD");
27637 self.write("=");
27638 self.generate_expression(retention_period)?;
27639 }
27640 self.write(")");
27641 }
27642 } else {
27643 self.write_keyword("OFF");
27644 }
27645 Ok(())
27646 }
27647
27648 fn generate_date_func(&mut self, e: &UnaryFunc) -> Result<()> {
27652 use crate::dialects::DialectType;
27653 use crate::expressions::Literal;
27654
27655 match self.config.dialect {
27656 Some(DialectType::Exasol) => {
27658 self.write_keyword("TO_DATE");
27659 self.write("(");
27660 match &e.this {
27662 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
27663 let Literal::String(s) = lit.as_ref() else {
27664 unreachable!()
27665 };
27666 self.write("'");
27667 self.write(s);
27668 self.write("'");
27669 }
27670 _ => {
27671 self.generate_expression(&e.this)?;
27672 }
27673 }
27674 self.write(")");
27675 }
27676 _ => {
27678 self.write_keyword("DATE");
27679 self.write("(");
27680 self.generate_expression(&e.this)?;
27681 self.write(")");
27682 }
27683 }
27684 Ok(())
27685 }
27686
27687 fn generate_date_bin(&mut self, e: &DateBin) -> Result<()> {
27688 self.write_keyword("DATE_BIN");
27690 self.write("(");
27691 self.generate_expression(&e.this)?;
27692 self.write(", ");
27693 self.generate_expression(&e.expression)?;
27694 if let Some(origin) = &e.origin {
27695 self.write(", ");
27696 self.generate_expression(origin)?;
27697 }
27698 self.write(")");
27699 Ok(())
27700 }
27701
27702 fn generate_date_format_column_constraint(
27703 &mut self,
27704 e: &DateFormatColumnConstraint,
27705 ) -> Result<()> {
27706 self.write_keyword("FORMAT");
27708 self.write_space();
27709 self.generate_expression(&e.this)?;
27710 Ok(())
27711 }
27712
27713 fn generate_date_from_parts(&mut self, e: &DateFromParts) -> Result<()> {
27714 self.write_keyword("DATE_FROM_PARTS");
27716 self.write("(");
27717 let mut first = true;
27718 if let Some(year) = &e.year {
27719 self.generate_expression(year)?;
27720 first = false;
27721 }
27722 if let Some(month) = &e.month {
27723 if !first {
27724 self.write(", ");
27725 }
27726 self.generate_expression(month)?;
27727 first = false;
27728 }
27729 if let Some(day) = &e.day {
27730 if !first {
27731 self.write(", ");
27732 }
27733 self.generate_expression(day)?;
27734 }
27735 self.write(")");
27736 Ok(())
27737 }
27738
27739 fn generate_datetime(&mut self, e: &Datetime) -> Result<()> {
27740 self.write_keyword("DATETIME");
27742 self.write("(");
27743 self.generate_expression(&e.this)?;
27744 if let Some(expr) = &e.expression {
27745 self.write(", ");
27746 self.generate_expression(expr)?;
27747 }
27748 self.write(")");
27749 Ok(())
27750 }
27751
27752 fn generate_datetime_add(&mut self, e: &DatetimeAdd) -> Result<()> {
27753 self.write_keyword("DATETIME_ADD");
27755 self.write("(");
27756 self.generate_expression(&e.this)?;
27757 self.write(", ");
27758 self.generate_expression(&e.expression)?;
27759 if let Some(unit) = &e.unit {
27760 self.write(", ");
27761 self.write_keyword(unit);
27762 }
27763 self.write(")");
27764 Ok(())
27765 }
27766
27767 fn generate_datetime_diff(&mut self, e: &DatetimeDiff) -> Result<()> {
27768 self.write_keyword("DATETIME_DIFF");
27770 self.write("(");
27771 self.generate_expression(&e.this)?;
27772 self.write(", ");
27773 self.generate_expression(&e.expression)?;
27774 if let Some(unit) = &e.unit {
27775 self.write(", ");
27776 self.write_keyword(unit);
27777 }
27778 self.write(")");
27779 Ok(())
27780 }
27781
27782 fn generate_datetime_sub(&mut self, e: &DatetimeSub) -> Result<()> {
27783 self.write_keyword("DATETIME_SUB");
27785 self.write("(");
27786 self.generate_expression(&e.this)?;
27787 self.write(", ");
27788 self.generate_expression(&e.expression)?;
27789 if let Some(unit) = &e.unit {
27790 self.write(", ");
27791 self.write_keyword(unit);
27792 }
27793 self.write(")");
27794 Ok(())
27795 }
27796
27797 fn generate_datetime_trunc(&mut self, e: &DatetimeTrunc) -> Result<()> {
27798 self.write_keyword("DATETIME_TRUNC");
27800 self.write("(");
27801 self.generate_expression(&e.this)?;
27802 self.write(", ");
27803 self.write_keyword(&e.unit);
27804 if let Some(zone) = &e.zone {
27805 self.write(", ");
27806 self.generate_expression(zone)?;
27807 }
27808 self.write(")");
27809 Ok(())
27810 }
27811
27812 fn generate_dayname(&mut self, e: &Dayname) -> Result<()> {
27813 self.write_keyword("DAYNAME");
27815 self.write("(");
27816 self.generate_expression(&e.this)?;
27817 self.write(")");
27818 Ok(())
27819 }
27820
27821 fn generate_declare(&mut self, e: &Declare) -> Result<()> {
27822 self.write_keyword("DECLARE");
27824 self.write_space();
27825 if e.replace {
27826 self.write_keyword("OR");
27827 self.write_space();
27828 self.write_keyword("REPLACE");
27829 self.write_space();
27830 }
27831 for (i, expr) in e.expressions.iter().enumerate() {
27832 if i > 0 {
27833 self.write(", ");
27834 }
27835 self.generate_expression(expr)?;
27836 }
27837 Ok(())
27838 }
27839
27840 fn generate_declare_item(&mut self, e: &DeclareItem) -> Result<()> {
27841 use crate::dialects::DialectType;
27842
27843 self.generate_expression(&e.this)?;
27845 for name in &e.additional_names {
27847 self.write(", ");
27848 self.generate_expression(name)?;
27849 }
27850 if let Some(kind) = &e.kind {
27851 self.write_space();
27852 match self.config.dialect {
27856 Some(DialectType::BigQuery) => {
27857 self.write(kind);
27858 }
27859 Some(DialectType::TSQL) => {
27860 let is_complex_table = kind.starts_with("TABLE")
27864 && (kind.contains("CLUSTERED") || kind.contains("INDEX"));
27865 if is_complex_table {
27866 self.write(kind);
27867 } else if kind == "INT" {
27868 self.write("INTEGER");
27869 } else if kind.starts_with("TABLE") {
27870 let normalized = kind
27872 .replace(" INT ", " INTEGER ")
27873 .replace(" INT,", " INTEGER,")
27874 .replace(" INT)", " INTEGER)")
27875 .replace("(INT ", "(INTEGER ");
27876 self.write(&normalized);
27877 } else {
27878 self.write(kind);
27879 }
27880 }
27881 _ => {
27882 if e.has_as {
27883 self.write_keyword("AS");
27884 self.write_space();
27885 }
27886 self.write(kind);
27887 }
27888 }
27889 }
27890 if let Some(default) = &e.default {
27891 match self.config.dialect {
27893 Some(DialectType::BigQuery) => {
27894 self.write_space();
27895 self.write_keyword("DEFAULT");
27896 self.write_space();
27897 }
27898 _ => {
27899 self.write(" = ");
27900 }
27901 }
27902 self.generate_expression(default)?;
27903 }
27904 Ok(())
27905 }
27906
27907 fn generate_decode_case(&mut self, e: &DecodeCase) -> Result<()> {
27908 self.write_keyword("DECODE");
27910 self.write("(");
27911 for (i, expr) in e.expressions.iter().enumerate() {
27912 if i > 0 {
27913 self.write(", ");
27914 }
27915 self.generate_expression(expr)?;
27916 }
27917 self.write(")");
27918 Ok(())
27919 }
27920
27921 fn generate_decompress_binary(&mut self, e: &DecompressBinary) -> Result<()> {
27922 self.write_keyword("DECOMPRESS");
27924 self.write("(");
27925 self.generate_expression(&e.this)?;
27926 self.write(", '");
27927 self.write(&e.method);
27928 self.write("')");
27929 Ok(())
27930 }
27931
27932 fn generate_decompress_string(&mut self, e: &DecompressString) -> Result<()> {
27933 self.write_keyword("DECOMPRESS");
27935 self.write("(");
27936 self.generate_expression(&e.this)?;
27937 self.write(", '");
27938 self.write(&e.method);
27939 self.write("')");
27940 Ok(())
27941 }
27942
27943 fn generate_decrypt(&mut self, e: &Decrypt) -> Result<()> {
27944 self.write_keyword("DECRYPT");
27946 self.write("(");
27947 self.generate_expression(&e.this)?;
27948 if let Some(passphrase) = &e.passphrase {
27949 self.write(", ");
27950 self.generate_expression(passphrase)?;
27951 }
27952 if let Some(aad) = &e.aad {
27953 self.write(", ");
27954 self.generate_expression(aad)?;
27955 }
27956 if let Some(method) = &e.encryption_method {
27957 self.write(", ");
27958 self.generate_expression(method)?;
27959 }
27960 self.write(")");
27961 Ok(())
27962 }
27963
27964 fn generate_decrypt_raw(&mut self, e: &DecryptRaw) -> Result<()> {
27965 self.write_keyword("DECRYPT_RAW");
27967 self.write("(");
27968 self.generate_expression(&e.this)?;
27969 if let Some(key) = &e.key {
27970 self.write(", ");
27971 self.generate_expression(key)?;
27972 }
27973 if let Some(iv) = &e.iv {
27974 self.write(", ");
27975 self.generate_expression(iv)?;
27976 }
27977 if let Some(aad) = &e.aad {
27978 self.write(", ");
27979 self.generate_expression(aad)?;
27980 }
27981 if let Some(method) = &e.encryption_method {
27982 self.write(", ");
27983 self.generate_expression(method)?;
27984 }
27985 self.write(")");
27986 Ok(())
27987 }
27988
27989 fn generate_definer_property(&mut self, e: &DefinerProperty) -> Result<()> {
27990 self.write_keyword("DEFINER");
27992 self.write(" = ");
27993 self.generate_expression(&e.this)?;
27994 Ok(())
27995 }
27996
27997 fn generate_detach(&mut self, e: &Detach) -> Result<()> {
27998 self.write_keyword("DETACH");
28000 if e.exists {
28001 self.write_keyword(" DATABASE IF EXISTS");
28002 }
28003 self.write_space();
28004 self.generate_expression(&e.this)?;
28005 Ok(())
28006 }
28007
28008 fn generate_dict_property(&mut self, e: &DictProperty) -> Result<()> {
28009 let property_name = match e.this.as_ref() {
28010 Expression::Identifier(id) => id.name.as_str(),
28011 Expression::Var(v) => v.this.as_str(),
28012 _ => "DICTIONARY",
28013 };
28014 self.write_keyword(property_name);
28015 self.write("(");
28016 self.write(&e.kind);
28017 if let Some(settings) = &e.settings {
28018 self.write("(");
28019 if let Expression::Tuple(t) = settings.as_ref() {
28020 if self.config.pretty && !t.expressions.is_empty() {
28021 self.write_newline();
28022 self.indent_level += 1;
28023 for (i, pair) in t.expressions.iter().enumerate() {
28024 if i > 0 {
28025 self.write(",");
28026 self.write_newline();
28027 }
28028 self.write_indent();
28029 if let Expression::Tuple(pair_tuple) = pair {
28030 if let Some(k) = pair_tuple.expressions.first() {
28031 self.generate_expression(k)?;
28032 }
28033 if let Some(v) = pair_tuple.expressions.get(1) {
28034 self.write(" ");
28035 self.generate_expression(v)?;
28036 }
28037 } else {
28038 self.generate_expression(pair)?;
28039 }
28040 }
28041 self.indent_level -= 1;
28042 self.write_newline();
28043 self.write_indent();
28044 } else {
28045 for (i, pair) in t.expressions.iter().enumerate() {
28046 if i > 0 {
28047 self.write(" ");
28049 }
28050 if let Expression::Tuple(pair_tuple) = pair {
28051 if let Some(k) = pair_tuple.expressions.first() {
28052 self.generate_expression(k)?;
28053 }
28054 if let Some(v) = pair_tuple.expressions.get(1) {
28055 self.write(" ");
28056 self.generate_expression(v)?;
28057 }
28058 } else {
28059 self.generate_expression(pair)?;
28060 }
28061 }
28062 }
28063 } else {
28064 self.generate_expression(settings)?;
28065 }
28066 self.write(")");
28067 } else {
28068 self.write("()");
28070 }
28071 self.write(")");
28072 Ok(())
28073 }
28074
28075 fn generate_dict_range(&mut self, e: &DictRange) -> Result<()> {
28076 let property_name = match e.this.as_ref() {
28077 Expression::Identifier(id) => id.name.as_str(),
28078 Expression::Var(v) => v.this.as_str(),
28079 _ => "RANGE",
28080 };
28081 self.write_keyword(property_name);
28082 self.write("(");
28083 if let Some(min) = &e.min {
28084 self.write_keyword("MIN");
28085 self.write_space();
28086 self.generate_expression(min)?;
28087 }
28088 if let Some(max) = &e.max {
28089 self.write_space();
28090 self.write_keyword("MAX");
28091 self.write_space();
28092 self.generate_expression(max)?;
28093 }
28094 self.write(")");
28095 Ok(())
28096 }
28097
28098 fn generate_directory(&mut self, e: &Directory) -> Result<()> {
28099 if e.local.is_some() {
28101 self.write_keyword("LOCAL ");
28102 }
28103 self.write_keyword("DIRECTORY");
28104 self.write_space();
28105 self.generate_expression(&e.this)?;
28106 if let Some(row_format) = &e.row_format {
28107 self.write_space();
28108 self.generate_expression(row_format)?;
28109 }
28110 Ok(())
28111 }
28112
28113 fn generate_dist_key_property(&mut self, e: &DistKeyProperty) -> Result<()> {
28114 self.write_keyword("DISTKEY");
28116 self.write("(");
28117 self.generate_expression(&e.this)?;
28118 self.write(")");
28119 Ok(())
28120 }
28121
28122 fn generate_dist_style_property(&mut self, e: &DistStyleProperty) -> Result<()> {
28123 self.write_keyword("DISTSTYLE");
28125 self.write_space();
28126 self.generate_expression(&e.this)?;
28127 Ok(())
28128 }
28129
28130 fn generate_distribute_by(&mut self, e: &DistributeBy) -> Result<()> {
28131 self.write_keyword("DISTRIBUTE BY");
28133 self.write_space();
28134 for (i, expr) in e.expressions.iter().enumerate() {
28135 if i > 0 {
28136 self.write(", ");
28137 }
28138 self.generate_expression(expr)?;
28139 }
28140 Ok(())
28141 }
28142
28143 fn generate_distributed_by_property(&mut self, e: &DistributedByProperty) -> Result<()> {
28144 self.write_keyword("DISTRIBUTED BY");
28146 self.write_space();
28147 self.write(&e.kind);
28148 if !e.expressions.is_empty() {
28149 self.write(" (");
28150 for (i, expr) in e.expressions.iter().enumerate() {
28151 if i > 0 {
28152 self.write(", ");
28153 }
28154 self.generate_expression(expr)?;
28155 }
28156 self.write(")");
28157 }
28158 if let Some(buckets) = &e.buckets {
28159 self.write_space();
28160 self.write_keyword("BUCKETS");
28161 self.write_space();
28162 self.generate_expression(buckets)?;
28163 }
28164 if let Some(order) = &e.order {
28165 self.write_space();
28166 self.generate_expression(order)?;
28167 }
28168 Ok(())
28169 }
28170
28171 fn generate_dot_product(&mut self, e: &DotProduct) -> Result<()> {
28172 self.write_keyword("DOT_PRODUCT");
28174 self.write("(");
28175 self.generate_expression(&e.this)?;
28176 self.write(", ");
28177 self.generate_expression(&e.expression)?;
28178 self.write(")");
28179 Ok(())
28180 }
28181
28182 fn generate_drop_partition(&mut self, e: &DropPartition) -> Result<()> {
28183 self.write_keyword("DROP");
28185 if e.exists {
28186 self.write_keyword(" IF EXISTS ");
28187 } else {
28188 self.write_space();
28189 }
28190 for (i, expr) in e.expressions.iter().enumerate() {
28191 if i > 0 {
28192 self.write(", ");
28193 }
28194 self.generate_expression(expr)?;
28195 }
28196 Ok(())
28197 }
28198
28199 fn generate_duplicate_key_property(&mut self, e: &DuplicateKeyProperty) -> Result<()> {
28200 self.write_keyword("DUPLICATE KEY");
28202 self.write(" (");
28203 for (i, expr) in e.expressions.iter().enumerate() {
28204 if i > 0 {
28205 self.write(", ");
28206 }
28207 self.generate_expression(expr)?;
28208 }
28209 self.write(")");
28210 Ok(())
28211 }
28212
28213 fn generate_elt(&mut self, e: &Elt) -> Result<()> {
28214 self.write_keyword("ELT");
28216 self.write("(");
28217 self.generate_expression(&e.this)?;
28218 for expr in &e.expressions {
28219 self.write(", ");
28220 self.generate_expression(expr)?;
28221 }
28222 self.write(")");
28223 Ok(())
28224 }
28225
28226 fn generate_encode(&mut self, e: &Encode) -> Result<()> {
28227 self.write_keyword("ENCODE");
28229 self.write("(");
28230 self.generate_expression(&e.this)?;
28231 if let Some(charset) = &e.charset {
28232 self.write(", ");
28233 self.generate_expression(charset)?;
28234 }
28235 self.write(")");
28236 Ok(())
28237 }
28238
28239 fn generate_encode_property(&mut self, e: &EncodeProperty) -> Result<()> {
28240 if e.key.is_some() {
28242 self.write_keyword("KEY ");
28243 }
28244 self.write_keyword("ENCODE");
28245 self.write_space();
28246 self.generate_expression(&e.this)?;
28247 if !e.properties.is_empty() {
28248 self.write(" (");
28249 for (i, prop) in e.properties.iter().enumerate() {
28250 if i > 0 {
28251 self.write(", ");
28252 }
28253 self.generate_expression(prop)?;
28254 }
28255 self.write(")");
28256 }
28257 Ok(())
28258 }
28259
28260 fn generate_encrypt(&mut self, e: &Encrypt) -> Result<()> {
28261 self.write_keyword("ENCRYPT");
28263 self.write("(");
28264 self.generate_expression(&e.this)?;
28265 if let Some(passphrase) = &e.passphrase {
28266 self.write(", ");
28267 self.generate_expression(passphrase)?;
28268 }
28269 if let Some(aad) = &e.aad {
28270 self.write(", ");
28271 self.generate_expression(aad)?;
28272 }
28273 if let Some(method) = &e.encryption_method {
28274 self.write(", ");
28275 self.generate_expression(method)?;
28276 }
28277 self.write(")");
28278 Ok(())
28279 }
28280
28281 fn generate_encrypt_raw(&mut self, e: &EncryptRaw) -> Result<()> {
28282 self.write_keyword("ENCRYPT_RAW");
28284 self.write("(");
28285 self.generate_expression(&e.this)?;
28286 if let Some(key) = &e.key {
28287 self.write(", ");
28288 self.generate_expression(key)?;
28289 }
28290 if let Some(iv) = &e.iv {
28291 self.write(", ");
28292 self.generate_expression(iv)?;
28293 }
28294 if let Some(aad) = &e.aad {
28295 self.write(", ");
28296 self.generate_expression(aad)?;
28297 }
28298 if let Some(method) = &e.encryption_method {
28299 self.write(", ");
28300 self.generate_expression(method)?;
28301 }
28302 self.write(")");
28303 Ok(())
28304 }
28305
28306 fn generate_engine_property(&mut self, e: &EngineProperty) -> Result<()> {
28307 self.write_keyword("ENGINE");
28309 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
28310 self.write("=");
28311 } else {
28312 self.write(" = ");
28313 }
28314 self.generate_expression(&e.this)?;
28315 Ok(())
28316 }
28317
28318 fn generate_enviroment_property(&mut self, e: &EnviromentProperty) -> Result<()> {
28319 self.write_keyword("ENVIRONMENT");
28321 self.write(" (");
28322 for (i, expr) in e.expressions.iter().enumerate() {
28323 if i > 0 {
28324 self.write(", ");
28325 }
28326 self.generate_expression(expr)?;
28327 }
28328 self.write(")");
28329 Ok(())
28330 }
28331
28332 fn generate_ephemeral_column_constraint(
28333 &mut self,
28334 e: &EphemeralColumnConstraint,
28335 ) -> Result<()> {
28336 self.write_keyword("EPHEMERAL");
28338 if let Some(this) = &e.this {
28339 self.write_space();
28340 self.generate_expression(this)?;
28341 }
28342 Ok(())
28343 }
28344
28345 fn generate_equal_null(&mut self, e: &EqualNull) -> Result<()> {
28346 self.write_keyword("EQUAL_NULL");
28348 self.write("(");
28349 self.generate_expression(&e.this)?;
28350 self.write(", ");
28351 self.generate_expression(&e.expression)?;
28352 self.write(")");
28353 Ok(())
28354 }
28355
28356 fn generate_euclidean_distance(&mut self, e: &EuclideanDistance) -> Result<()> {
28357 use crate::dialects::DialectType;
28358
28359 match self.config.dialect {
28361 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
28362 self.generate_expression(&e.this)?;
28363 self.write(" <-> ");
28364 self.generate_expression(&e.expression)?;
28365 }
28366 _ => {
28367 self.write_keyword("EUCLIDEAN_DISTANCE");
28369 self.write("(");
28370 self.generate_expression(&e.this)?;
28371 self.write(", ");
28372 self.generate_expression(&e.expression)?;
28373 self.write(")");
28374 }
28375 }
28376 Ok(())
28377 }
28378
28379 fn generate_execute_as_property(&mut self, e: &ExecuteAsProperty) -> Result<()> {
28380 self.write_keyword("EXECUTE AS");
28382 self.write_space();
28383 self.generate_expression(&e.this)?;
28384 Ok(())
28385 }
28386
28387 fn generate_export(&mut self, e: &Export) -> Result<()> {
28388 self.write_keyword("EXPORT DATA");
28390 if let Some(connection) = &e.connection {
28391 self.write_space();
28392 self.write_keyword("WITH CONNECTION");
28393 self.write_space();
28394 self.generate_expression(connection)?;
28395 }
28396 if !e.options.is_empty() {
28397 self.write_space();
28398 self.generate_options_clause(&e.options)?;
28399 }
28400 self.write_space();
28401 self.write_keyword("AS");
28402 self.write_space();
28403 self.generate_expression(&e.this)?;
28404 Ok(())
28405 }
28406
28407 fn generate_external_property(&mut self, e: &ExternalProperty) -> Result<()> {
28408 self.write_keyword("EXTERNAL");
28410 if let Some(this) = &e.this {
28411 self.write_space();
28412 self.generate_expression(this)?;
28413 }
28414 Ok(())
28415 }
28416
28417 fn generate_fallback_property(&mut self, e: &FallbackProperty) -> Result<()> {
28418 if e.no.is_some() {
28420 self.write_keyword("NO ");
28421 }
28422 self.write_keyword("FALLBACK");
28423 if e.protection.is_some() {
28424 self.write_keyword(" PROTECTION");
28425 }
28426 Ok(())
28427 }
28428
28429 fn generate_farm_fingerprint(&mut self, e: &FarmFingerprint) -> Result<()> {
28430 self.write_keyword("FARM_FINGERPRINT");
28432 self.write("(");
28433 for (i, expr) in e.expressions.iter().enumerate() {
28434 if i > 0 {
28435 self.write(", ");
28436 }
28437 self.generate_expression(expr)?;
28438 }
28439 self.write(")");
28440 Ok(())
28441 }
28442
28443 fn generate_features_at_time(&mut self, e: &FeaturesAtTime) -> Result<()> {
28444 self.write_keyword("FEATURES_AT_TIME");
28446 self.write("(");
28447 self.generate_expression(&e.this)?;
28448 if let Some(time) = &e.time {
28449 self.write(", ");
28450 self.generate_expression(time)?;
28451 }
28452 if let Some(num_rows) = &e.num_rows {
28453 self.write(", ");
28454 self.generate_expression(num_rows)?;
28455 }
28456 if let Some(ignore_nulls) = &e.ignore_feature_nulls {
28457 self.write(", ");
28458 self.generate_expression(ignore_nulls)?;
28459 }
28460 self.write(")");
28461 Ok(())
28462 }
28463
28464 fn generate_fetch(&mut self, e: &Fetch) -> Result<()> {
28465 let use_limit = !e.percent
28467 && !e.with_ties
28468 && e.count.is_some()
28469 && matches!(
28470 self.config.dialect,
28471 Some(DialectType::Spark)
28472 | Some(DialectType::Hive)
28473 | Some(DialectType::DuckDB)
28474 | Some(DialectType::SQLite)
28475 | Some(DialectType::MySQL)
28476 | Some(DialectType::BigQuery)
28477 | Some(DialectType::Databricks)
28478 | Some(DialectType::StarRocks)
28479 | Some(DialectType::Doris)
28480 | Some(DialectType::Athena)
28481 | Some(DialectType::ClickHouse)
28482 );
28483
28484 if use_limit {
28485 self.write_keyword("LIMIT");
28486 self.write_space();
28487 self.generate_expression(e.count.as_ref().unwrap())?;
28488 return Ok(());
28489 }
28490
28491 self.write_keyword("FETCH");
28493 if !e.direction.is_empty() {
28494 self.write_space();
28495 self.write_keyword(&e.direction);
28496 }
28497 if let Some(count) = &e.count {
28498 self.write_space();
28499 self.generate_expression(count)?;
28500 }
28501 if e.percent {
28503 self.write_keyword(" PERCENT");
28504 }
28505 if e.rows {
28506 self.write_keyword(" ROWS");
28507 }
28508 if e.with_ties {
28509 self.write_keyword(" WITH TIES");
28510 } else if e.rows {
28511 self.write_keyword(" ONLY");
28512 } else {
28513 self.write_keyword(" ROWS ONLY");
28514 }
28515 Ok(())
28516 }
28517
28518 fn generate_file_format_property(&mut self, e: &FileFormatProperty) -> Result<()> {
28519 if e.hive_format.is_some() {
28523 self.write_keyword("STORED AS");
28525 self.write_space();
28526 if let Some(this) = &e.this {
28527 if let Expression::Identifier(id) = this.as_ref() {
28529 self.write_keyword(&id.name.to_ascii_uppercase());
28530 } else {
28531 self.generate_expression(this)?;
28532 }
28533 }
28534 } else if matches!(self.config.dialect, Some(DialectType::Hive)) {
28535 self.write_keyword("STORED AS");
28537 self.write_space();
28538 if let Some(this) = &e.this {
28539 if let Expression::Identifier(id) = this.as_ref() {
28540 self.write_keyword(&id.name.to_ascii_uppercase());
28541 } else {
28542 self.generate_expression(this)?;
28543 }
28544 }
28545 } else if matches!(
28546 self.config.dialect,
28547 Some(DialectType::Spark) | Some(DialectType::Databricks)
28548 ) {
28549 self.write_keyword("USING");
28551 self.write_space();
28552 if let Some(this) = &e.this {
28553 self.generate_expression(this)?;
28554 }
28555 } else {
28556 self.write_keyword("FILE_FORMAT");
28558 self.write(" = ");
28559 if let Some(this) = &e.this {
28560 self.generate_expression(this)?;
28561 } else if !e.expressions.is_empty() {
28562 self.write("(");
28563 for (i, expr) in e.expressions.iter().enumerate() {
28564 if i > 0 {
28565 self.write(", ");
28566 }
28567 self.generate_expression(expr)?;
28568 }
28569 self.write(")");
28570 }
28571 }
28572 Ok(())
28573 }
28574
28575 fn generate_filter(&mut self, e: &Filter) -> Result<()> {
28576 self.generate_expression(&e.this)?;
28578 self.write_space();
28579 self.write_keyword("FILTER");
28580 self.write("(");
28581 self.write_keyword("WHERE");
28582 self.write_space();
28583 self.generate_expression(&e.expression)?;
28584 self.write(")");
28585 Ok(())
28586 }
28587
28588 fn generate_float64(&mut self, e: &Float64) -> Result<()> {
28589 self.write_keyword("FLOAT64");
28591 self.write("(");
28592 self.generate_expression(&e.this)?;
28593 if let Some(expr) = &e.expression {
28594 self.write(", ");
28595 self.generate_expression(expr)?;
28596 }
28597 self.write(")");
28598 Ok(())
28599 }
28600
28601 fn generate_for_in(&mut self, e: &ForIn) -> Result<()> {
28602 self.write_keyword("FOR");
28604 self.write_space();
28605 self.generate_expression(&e.this)?;
28606 self.write_space();
28607 self.write_keyword("DO");
28608 self.write_space();
28609 self.generate_expression(&e.expression)?;
28610 Ok(())
28611 }
28612
28613 fn generate_foreign_key(&mut self, e: &ForeignKey) -> Result<()> {
28614 self.write_keyword("FOREIGN KEY");
28616 if !e.expressions.is_empty() {
28617 self.write(" (");
28618 for (i, expr) in e.expressions.iter().enumerate() {
28619 if i > 0 {
28620 self.write(", ");
28621 }
28622 self.generate_expression(expr)?;
28623 }
28624 self.write(")");
28625 }
28626 if let Some(reference) = &e.reference {
28627 self.write_space();
28628 self.generate_expression(reference)?;
28629 }
28630 if let Some(delete) = &e.delete {
28631 self.write_space();
28632 self.write_keyword("ON DELETE");
28633 self.write_space();
28634 self.generate_expression(delete)?;
28635 }
28636 if let Some(update) = &e.update {
28637 self.write_space();
28638 self.write_keyword("ON UPDATE");
28639 self.write_space();
28640 self.generate_expression(update)?;
28641 }
28642 if !e.options.is_empty() {
28643 self.write_space();
28644 for (i, opt) in e.options.iter().enumerate() {
28645 if i > 0 {
28646 self.write_space();
28647 }
28648 self.generate_expression(opt)?;
28649 }
28650 }
28651 Ok(())
28652 }
28653
28654 fn generate_format(&mut self, e: &Format) -> Result<()> {
28655 self.write_keyword("FORMAT");
28657 self.write("(");
28658 self.generate_expression(&e.this)?;
28659 for expr in &e.expressions {
28660 self.write(", ");
28661 self.generate_expression(expr)?;
28662 }
28663 self.write(")");
28664 Ok(())
28665 }
28666
28667 fn generate_format_phrase(&mut self, e: &FormatPhrase) -> Result<()> {
28668 self.generate_expression(&e.this)?;
28670 self.write(" (");
28671 self.write_keyword("FORMAT");
28672 self.write(" '");
28673 self.write(&e.format);
28674 self.write("')");
28675 Ok(())
28676 }
28677
28678 fn generate_freespace_property(&mut self, e: &FreespaceProperty) -> Result<()> {
28679 self.write_keyword("FREESPACE");
28681 self.write("=");
28682 self.generate_expression(&e.this)?;
28683 if e.percent.is_some() {
28684 self.write_keyword(" PERCENT");
28685 }
28686 Ok(())
28687 }
28688
28689 fn generate_from(&mut self, e: &From) -> Result<()> {
28690 self.write_keyword("FROM");
28692 self.write_space();
28693
28694 use crate::dialects::DialectType;
28698 let has_tablesample = e
28699 .expressions
28700 .iter()
28701 .any(|expr| matches!(expr, Expression::TableSample(_)));
28702 let is_cross_join_dialect = matches!(
28703 self.config.dialect,
28704 Some(DialectType::BigQuery)
28705 | Some(DialectType::Hive)
28706 | Some(DialectType::Spark)
28707 | Some(DialectType::Databricks)
28708 | Some(DialectType::SQLite)
28709 | Some(DialectType::ClickHouse)
28710 );
28711 let source_is_same_as_target2 = self.config.source_dialect.is_some()
28712 && self.config.source_dialect == self.config.dialect;
28713 let source_is_cross_join_dialect2 = matches!(
28714 self.config.source_dialect,
28715 Some(DialectType::BigQuery)
28716 | Some(DialectType::Hive)
28717 | Some(DialectType::Spark)
28718 | Some(DialectType::Databricks)
28719 | Some(DialectType::SQLite)
28720 | Some(DialectType::ClickHouse)
28721 );
28722 let use_cross_join = !has_tablesample
28723 && is_cross_join_dialect
28724 && (source_is_same_as_target2
28725 || source_is_cross_join_dialect2
28726 || self.config.source_dialect.is_none());
28727
28728 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
28730
28731 for (i, expr) in e.expressions.iter().enumerate() {
28732 if i > 0 {
28733 if use_cross_join {
28734 self.write(" CROSS JOIN ");
28735 } else {
28736 self.write(", ");
28737 }
28738 }
28739 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
28740 self.write("(");
28741 self.generate_expression(expr)?;
28742 self.write(")");
28743 } else {
28744 self.generate_expression(expr)?;
28745 }
28746 let leading = Self::extract_table_leading_comments(expr);
28749 for comment in &leading {
28750 self.write_space();
28751 self.write_formatted_comment(comment);
28752 }
28753 }
28754 Ok(())
28755 }
28756
28757 fn extract_table_leading_comments(expr: &Expression) -> Vec<String> {
28759 match expr {
28760 Expression::Table(t) => t.leading_comments.clone(),
28761 Expression::Pivot(p) => {
28762 if let Expression::Table(t) = &p.this {
28763 t.leading_comments.clone()
28764 } else {
28765 Vec::new()
28766 }
28767 }
28768 _ => Vec::new(),
28769 }
28770 }
28771
28772 fn generate_from_base(&mut self, e: &FromBase) -> Result<()> {
28773 self.write_keyword("FROM_BASE");
28775 self.write("(");
28776 self.generate_expression(&e.this)?;
28777 self.write(", ");
28778 self.generate_expression(&e.expression)?;
28779 self.write(")");
28780 Ok(())
28781 }
28782
28783 fn generate_from_time_zone(&mut self, e: &FromTimeZone) -> Result<()> {
28784 self.generate_expression(&e.this)?;
28786 if let Some(zone) = &e.zone {
28787 self.write_space();
28788 self.write_keyword("AT TIME ZONE");
28789 self.write_space();
28790 self.generate_expression(zone)?;
28791 self.write_space();
28792 self.write_keyword("AT TIME ZONE");
28793 self.write(" 'UTC'");
28794 }
28795 Ok(())
28796 }
28797
28798 fn generate_gap_fill(&mut self, e: &GapFill) -> Result<()> {
28799 self.write_keyword("GAP_FILL");
28801 self.write("(");
28802 self.generate_expression(&e.this)?;
28803 if let Some(ts_column) = &e.ts_column {
28804 self.write(", ");
28805 self.generate_expression(ts_column)?;
28806 }
28807 if let Some(bucket_width) = &e.bucket_width {
28808 self.write(", ");
28809 self.generate_expression(bucket_width)?;
28810 }
28811 if let Some(partitioning_columns) = &e.partitioning_columns {
28812 self.write(", ");
28813 self.generate_expression(partitioning_columns)?;
28814 }
28815 if let Some(value_columns) = &e.value_columns {
28816 self.write(", ");
28817 self.generate_expression(value_columns)?;
28818 }
28819 self.write(")");
28820 Ok(())
28821 }
28822
28823 fn generate_generate_date_array(&mut self, e: &GenerateDateArray) -> Result<()> {
28824 self.write_keyword("GENERATE_DATE_ARRAY");
28826 self.write("(");
28827 let mut first = true;
28828 if let Some(start) = &e.start {
28829 self.generate_expression(start)?;
28830 first = false;
28831 }
28832 if let Some(end) = &e.end {
28833 if !first {
28834 self.write(", ");
28835 }
28836 self.generate_expression(end)?;
28837 first = false;
28838 }
28839 if let Some(step) = &e.step {
28840 if !first {
28841 self.write(", ");
28842 }
28843 self.generate_expression(step)?;
28844 }
28845 self.write(")");
28846 Ok(())
28847 }
28848
28849 fn generate_generate_embedding(&mut self, e: &GenerateEmbedding) -> Result<()> {
28850 self.write_keyword("ML.GENERATE_EMBEDDING");
28852 self.write("(");
28853 self.generate_expression(&e.this)?;
28854 self.write(", ");
28855 self.generate_expression(&e.expression)?;
28856 if let Some(params) = &e.params_struct {
28857 self.write(", ");
28858 self.generate_expression(params)?;
28859 }
28860 self.write(")");
28861 Ok(())
28862 }
28863
28864 fn generate_generate_series(&mut self, e: &GenerateSeries) -> Result<()> {
28865 let fn_name = match self.config.dialect {
28867 Some(DialectType::Presto)
28868 | Some(DialectType::Trino)
28869 | Some(DialectType::Athena)
28870 | Some(DialectType::Spark)
28871 | Some(DialectType::Databricks)
28872 | Some(DialectType::Hive) => "SEQUENCE",
28873 _ => "GENERATE_SERIES",
28874 };
28875 self.write_keyword(fn_name);
28876 self.write("(");
28877 let mut first = true;
28878 if let Some(start) = &e.start {
28879 self.generate_expression(start)?;
28880 first = false;
28881 }
28882 if let Some(end) = &e.end {
28883 if !first {
28884 self.write(", ");
28885 }
28886 self.generate_expression(end)?;
28887 first = false;
28888 }
28889 if let Some(step) = &e.step {
28890 if !first {
28891 self.write(", ");
28892 }
28893 if matches!(
28896 self.config.dialect,
28897 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
28898 ) {
28899 if let Some(converted) = self.convert_week_interval_to_day(step) {
28900 self.generate_expression(&converted)?;
28901 } else {
28902 self.generate_expression(step)?;
28903 }
28904 } else {
28905 self.generate_expression(step)?;
28906 }
28907 }
28908 self.write(")");
28909 Ok(())
28910 }
28911
28912 fn convert_week_interval_to_day(&self, expr: &Expression) -> Option<Expression> {
28915 use crate::expressions::*;
28916 if let Expression::Interval(ref iv) = expr {
28917 let (is_week, count_str) = if let Some(IntervalUnitSpec::Simple {
28919 unit: IntervalUnit::Week,
28920 ..
28921 }) = &iv.unit
28922 {
28923 let count = match &iv.this {
28925 Some(Expression::Literal(lit)) => match lit.as_ref() {
28926 Literal::String(s) | Literal::Number(s) => s.clone(),
28927 _ => return None,
28928 },
28929 _ => return None,
28930 };
28931 (true, count)
28932 } else if iv.unit.is_none() {
28933 if let Some(Expression::Literal(lit)) = &iv.this {
28935 if let Literal::String(s) = lit.as_ref() {
28936 let parts: Vec<&str> = s.trim().splitn(2, char::is_whitespace).collect();
28937 if parts.len() == 2 && parts[1].eq_ignore_ascii_case("WEEK") {
28938 (true, parts[0].to_string())
28939 } else {
28940 (false, String::new())
28941 }
28942 } else {
28943 (false, String::new())
28944 }
28945 } else {
28946 (false, String::new())
28947 }
28948 } else {
28949 (false, String::new())
28950 };
28951
28952 if is_week {
28953 let count_expr = Expression::Literal(Box::new(Literal::Number(count_str)));
28955 let day_interval = Expression::Interval(Box::new(Interval {
28956 this: Some(Expression::Literal(Box::new(Literal::String(
28957 "7".to_string(),
28958 )))),
28959 unit: Some(IntervalUnitSpec::Simple {
28960 unit: IntervalUnit::Day,
28961 use_plural: false,
28962 }),
28963 }));
28964 let mul = Expression::Mul(Box::new(BinaryOp {
28965 left: count_expr,
28966 right: day_interval,
28967 left_comments: vec![],
28968 operator_comments: vec![],
28969 trailing_comments: vec![],
28970 inferred_type: None,
28971 }));
28972 return Some(Expression::Paren(Box::new(Paren {
28973 this: mul,
28974 trailing_comments: vec![],
28975 })));
28976 }
28977 }
28978 None
28979 }
28980
28981 fn generate_generate_timestamp_array(&mut self, e: &GenerateTimestampArray) -> Result<()> {
28982 self.write_keyword("GENERATE_TIMESTAMP_ARRAY");
28984 self.write("(");
28985 let mut first = true;
28986 if let Some(start) = &e.start {
28987 self.generate_expression(start)?;
28988 first = false;
28989 }
28990 if let Some(end) = &e.end {
28991 if !first {
28992 self.write(", ");
28993 }
28994 self.generate_expression(end)?;
28995 first = false;
28996 }
28997 if let Some(step) = &e.step {
28998 if !first {
28999 self.write(", ");
29000 }
29001 self.generate_expression(step)?;
29002 }
29003 self.write(")");
29004 Ok(())
29005 }
29006
29007 fn generate_generated_as_identity_column_constraint(
29008 &mut self,
29009 e: &GeneratedAsIdentityColumnConstraint,
29010 ) -> Result<()> {
29011 use crate::dialects::DialectType;
29012
29013 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
29015 self.write_keyword("AUTOINCREMENT");
29016 if let Some(start) = &e.start {
29017 self.write_keyword(" START ");
29018 self.generate_expression(start)?;
29019 }
29020 if let Some(increment) = &e.increment {
29021 self.write_keyword(" INCREMENT ");
29022 self.generate_expression(increment)?;
29023 }
29024 return Ok(());
29025 }
29026
29027 self.write_keyword("GENERATED");
29029 if let Some(this) = &e.this {
29030 if let Expression::Boolean(b) = this.as_ref() {
29032 if b.value {
29033 self.write_keyword(" ALWAYS");
29034 } else {
29035 self.write_keyword(" BY DEFAULT");
29036 if e.on_null.is_some() {
29037 self.write_keyword(" ON NULL");
29038 }
29039 }
29040 } else {
29041 self.write_keyword(" ALWAYS");
29042 }
29043 }
29044 self.write_keyword(" AS IDENTITY");
29045 let has_options = e.start.is_some()
29047 || e.increment.is_some()
29048 || e.minvalue.is_some()
29049 || e.maxvalue.is_some();
29050 if has_options {
29051 self.write(" (");
29052 let mut first = true;
29053 if let Some(start) = &e.start {
29054 self.write_keyword("START WITH ");
29055 self.generate_expression(start)?;
29056 first = false;
29057 }
29058 if let Some(increment) = &e.increment {
29059 if !first {
29060 self.write(" ");
29061 }
29062 self.write_keyword("INCREMENT BY ");
29063 self.generate_expression(increment)?;
29064 first = false;
29065 }
29066 if let Some(minvalue) = &e.minvalue {
29067 if !first {
29068 self.write(" ");
29069 }
29070 self.write_keyword("MINVALUE ");
29071 self.generate_expression(minvalue)?;
29072 first = false;
29073 }
29074 if let Some(maxvalue) = &e.maxvalue {
29075 if !first {
29076 self.write(" ");
29077 }
29078 self.write_keyword("MAXVALUE ");
29079 self.generate_expression(maxvalue)?;
29080 }
29081 self.write(")");
29082 }
29083 Ok(())
29084 }
29085
29086 fn generate_generated_as_row_column_constraint(
29087 &mut self,
29088 e: &GeneratedAsRowColumnConstraint,
29089 ) -> Result<()> {
29090 self.write_keyword("GENERATED ALWAYS AS ROW ");
29092 if e.start.is_some() {
29093 self.write_keyword("START");
29094 } else {
29095 self.write_keyword("END");
29096 }
29097 if e.hidden.is_some() {
29098 self.write_keyword(" HIDDEN");
29099 }
29100 Ok(())
29101 }
29102
29103 fn generate_get(&mut self, e: &Get) -> Result<()> {
29104 self.write_keyword("GET");
29106 self.write_space();
29107 self.generate_expression(&e.this)?;
29108 if let Some(target) = &e.target {
29109 self.write_space();
29110 self.generate_expression(target)?;
29111 }
29112 for prop in &e.properties {
29113 self.write_space();
29114 self.generate_expression(prop)?;
29115 }
29116 Ok(())
29117 }
29118
29119 fn generate_get_extract(&mut self, e: &GetExtract) -> Result<()> {
29120 self.generate_expression(&e.this)?;
29122 self.write("[");
29123 self.generate_expression(&e.expression)?;
29124 self.write("]");
29125 Ok(())
29126 }
29127
29128 fn generate_getbit(&mut self, e: &Getbit) -> Result<()> {
29129 self.write_keyword("GETBIT");
29131 self.write("(");
29132 self.generate_expression(&e.this)?;
29133 self.write(", ");
29134 self.generate_expression(&e.expression)?;
29135 self.write(")");
29136 Ok(())
29137 }
29138
29139 fn generate_grant_principal(&mut self, e: &GrantPrincipal) -> Result<()> {
29140 if e.is_role {
29142 self.write_keyword("ROLE");
29143 self.write_space();
29144 } else if e.is_group {
29145 self.write_keyword("GROUP");
29146 self.write_space();
29147 } else if e.is_share {
29148 self.write_keyword("SHARE");
29149 self.write_space();
29150 }
29151 self.write(&e.name.name);
29152 Ok(())
29153 }
29154
29155 fn generate_grant_privilege(&mut self, e: &GrantPrivilege) -> Result<()> {
29156 self.generate_expression(&e.this)?;
29158 if !e.expressions.is_empty() {
29159 self.write("(");
29160 for (i, expr) in e.expressions.iter().enumerate() {
29161 if i > 0 {
29162 self.write(", ");
29163 }
29164 self.generate_expression(expr)?;
29165 }
29166 self.write(")");
29167 }
29168 Ok(())
29169 }
29170
29171 fn generate_group(&mut self, e: &Group) -> Result<()> {
29172 self.write_keyword("GROUP BY");
29174 match e.all {
29176 Some(true) => {
29177 self.write_space();
29178 self.write_keyword("ALL");
29179 }
29180 Some(false) => {
29181 self.write_space();
29182 self.write_keyword("DISTINCT");
29183 }
29184 None => {}
29185 }
29186 if !e.expressions.is_empty() {
29187 self.write_space();
29188 for (i, expr) in e.expressions.iter().enumerate() {
29189 if i > 0 {
29190 self.write(", ");
29191 }
29192 self.generate_expression(expr)?;
29193 }
29194 }
29195 if let Some(cube) = &e.cube {
29197 if !e.expressions.is_empty() {
29198 self.write(", ");
29199 } else {
29200 self.write_space();
29201 }
29202 self.generate_expression(cube)?;
29203 }
29204 if let Some(rollup) = &e.rollup {
29205 if !e.expressions.is_empty() || e.cube.is_some() {
29206 self.write(", ");
29207 } else {
29208 self.write_space();
29209 }
29210 self.generate_expression(rollup)?;
29211 }
29212 if let Some(grouping_sets) = &e.grouping_sets {
29213 if !e.expressions.is_empty() || e.cube.is_some() || e.rollup.is_some() {
29214 self.write(", ");
29215 } else {
29216 self.write_space();
29217 }
29218 self.generate_expression(grouping_sets)?;
29219 }
29220 if let Some(totals) = &e.totals {
29221 self.write_space();
29222 self.write_keyword("WITH TOTALS");
29223 self.generate_expression(totals)?;
29224 }
29225 Ok(())
29226 }
29227
29228 fn generate_group_by(&mut self, e: &GroupBy) -> Result<()> {
29229 self.write_keyword("GROUP BY");
29231 match e.all {
29233 Some(true) => {
29234 self.write_space();
29235 self.write_keyword("ALL");
29236 }
29237 Some(false) => {
29238 self.write_space();
29239 self.write_keyword("DISTINCT");
29240 }
29241 None => {}
29242 }
29243
29244 let mut trailing_cube = false;
29247 let mut trailing_rollup = false;
29248 let mut regular_expressions: Vec<&Expression> = Vec::new();
29249
29250 for expr in &e.expressions {
29251 match expr {
29252 Expression::Cube(c) if c.expressions.is_empty() => {
29253 trailing_cube = true;
29254 }
29255 Expression::Rollup(r) if r.expressions.is_empty() => {
29256 trailing_rollup = true;
29257 }
29258 _ => {
29259 regular_expressions.push(expr);
29260 }
29261 }
29262 }
29263
29264 if self.config.pretty {
29266 self.write_newline();
29267 self.indent_level += 1;
29268 for (i, expr) in regular_expressions.iter().enumerate() {
29269 if i > 0 {
29270 self.write(",");
29271 self.write_newline();
29272 }
29273 self.write_indent();
29274 self.generate_expression(expr)?;
29275 }
29276 self.indent_level -= 1;
29277 } else {
29278 self.write_space();
29279 for (i, expr) in regular_expressions.iter().enumerate() {
29280 if i > 0 {
29281 self.write(", ");
29282 }
29283 self.generate_expression(expr)?;
29284 }
29285 }
29286
29287 if trailing_cube {
29289 self.write_space();
29290 self.write_keyword("WITH CUBE");
29291 } else if trailing_rollup {
29292 self.write_space();
29293 self.write_keyword("WITH ROLLUP");
29294 }
29295
29296 if e.totals {
29298 self.write_space();
29299 self.write_keyword("WITH TOTALS");
29300 }
29301
29302 Ok(())
29303 }
29304
29305 fn generate_grouping(&mut self, e: &Grouping) -> Result<()> {
29306 self.write_keyword("GROUPING");
29308 self.write("(");
29309 for (i, expr) in e.expressions.iter().enumerate() {
29310 if i > 0 {
29311 self.write(", ");
29312 }
29313 self.generate_expression(expr)?;
29314 }
29315 self.write(")");
29316 Ok(())
29317 }
29318
29319 fn generate_grouping_id(&mut self, e: &GroupingId) -> Result<()> {
29320 self.write_keyword("GROUPING_ID");
29322 self.write("(");
29323 for (i, expr) in e.expressions.iter().enumerate() {
29324 if i > 0 {
29325 self.write(", ");
29326 }
29327 self.generate_expression(expr)?;
29328 }
29329 self.write(")");
29330 Ok(())
29331 }
29332
29333 fn generate_grouping_sets(&mut self, e: &GroupingSets) -> Result<()> {
29334 self.write_keyword("GROUPING SETS");
29336 self.write(" (");
29337 for (i, expr) in e.expressions.iter().enumerate() {
29338 if i > 0 {
29339 self.write(", ");
29340 }
29341 self.generate_expression(expr)?;
29342 }
29343 self.write(")");
29344 Ok(())
29345 }
29346
29347 fn generate_hash_agg(&mut self, e: &HashAgg) -> Result<()> {
29348 self.write_keyword("HASH_AGG");
29350 self.write("(");
29351 self.generate_expression(&e.this)?;
29352 for expr in &e.expressions {
29353 self.write(", ");
29354 self.generate_expression(expr)?;
29355 }
29356 self.write(")");
29357 Ok(())
29358 }
29359
29360 fn generate_having(&mut self, e: &Having) -> Result<()> {
29361 self.write_keyword("HAVING");
29363 self.write_space();
29364 self.generate_expression(&e.this)?;
29365 Ok(())
29366 }
29367
29368 fn generate_having_max(&mut self, e: &HavingMax) -> Result<()> {
29369 self.generate_expression(&e.this)?;
29371 self.write_space();
29372 self.write_keyword("HAVING");
29373 self.write_space();
29374 if e.max.is_some() {
29375 self.write_keyword("MAX");
29376 } else {
29377 self.write_keyword("MIN");
29378 }
29379 self.write_space();
29380 self.generate_expression(&e.expression)?;
29381 Ok(())
29382 }
29383
29384 fn generate_heredoc(&mut self, e: &Heredoc) -> Result<()> {
29385 use crate::dialects::DialectType;
29386 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
29388 if let Expression::Literal(ref lit) = *e.this {
29390 if let Literal::String(ref s) = lit.as_ref() {
29391 return self.generate_string_literal(s);
29392 }
29393 }
29394 }
29395 if matches!(
29397 self.config.dialect,
29398 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
29399 ) {
29400 self.write("$");
29401 if let Some(tag) = &e.tag {
29402 self.generate_expression(tag)?;
29403 }
29404 self.write("$");
29405 self.generate_expression(&e.this)?;
29406 self.write("$");
29407 if let Some(tag) = &e.tag {
29408 self.generate_expression(tag)?;
29409 }
29410 self.write("$");
29411 return Ok(());
29412 }
29413 self.write("$");
29415 if let Some(tag) = &e.tag {
29416 self.generate_expression(tag)?;
29417 }
29418 self.write("$");
29419 self.generate_expression(&e.this)?;
29420 self.write("$");
29421 if let Some(tag) = &e.tag {
29422 self.generate_expression(tag)?;
29423 }
29424 self.write("$");
29425 Ok(())
29426 }
29427
29428 fn generate_hex_encode(&mut self, e: &HexEncode) -> Result<()> {
29429 self.write_keyword("HEX_ENCODE");
29431 self.write("(");
29432 self.generate_expression(&e.this)?;
29433 self.write(")");
29434 Ok(())
29435 }
29436
29437 fn generate_historical_data(&mut self, e: &HistoricalData) -> Result<()> {
29438 match e.this.as_ref() {
29441 Expression::Identifier(id) => self.write(&id.name),
29442 other => self.generate_expression(other)?,
29443 }
29444 self.write(" (");
29445 self.write(&e.kind);
29446 self.write(" => ");
29447 self.generate_expression(&e.expression)?;
29448 self.write(")");
29449 Ok(())
29450 }
29451
29452 fn generate_hll(&mut self, e: &Hll) -> Result<()> {
29453 self.write_keyword("HLL");
29455 self.write("(");
29456 self.generate_expression(&e.this)?;
29457 for expr in &e.expressions {
29458 self.write(", ");
29459 self.generate_expression(expr)?;
29460 }
29461 self.write(")");
29462 Ok(())
29463 }
29464
29465 fn generate_in_out_column_constraint(&mut self, e: &InOutColumnConstraint) -> Result<()> {
29466 if e.input_.is_some() && e.output.is_some() {
29468 self.write_keyword("IN OUT");
29469 } else if e.input_.is_some() {
29470 self.write_keyword("IN");
29471 } else if e.output.is_some() {
29472 self.write_keyword("OUT");
29473 }
29474 Ok(())
29475 }
29476
29477 fn generate_include_property(&mut self, e: &IncludeProperty) -> Result<()> {
29478 self.write_keyword("INCLUDE");
29480 self.write_space();
29481 self.generate_expression(&e.this)?;
29482 if let Some(column_def) = &e.column_def {
29483 self.write_space();
29484 self.generate_expression(column_def)?;
29485 }
29486 if let Some(alias) = &e.alias {
29487 self.write_space();
29488 self.write_keyword("AS");
29489 self.write_space();
29490 self.write(alias);
29491 }
29492 Ok(())
29493 }
29494
29495 fn generate_index(&mut self, e: &Index) -> Result<()> {
29496 if e.unique {
29498 self.write_keyword("UNIQUE");
29499 self.write_space();
29500 }
29501 if e.primary.is_some() {
29502 self.write_keyword("PRIMARY");
29503 self.write_space();
29504 }
29505 if e.amp.is_some() {
29506 self.write_keyword("AMP");
29507 self.write_space();
29508 }
29509 if e.table.is_none() {
29510 self.write_keyword("INDEX");
29511 self.write_space();
29512 }
29513 if let Some(name) = &e.this {
29514 self.generate_expression(name)?;
29515 self.write_space();
29516 }
29517 if let Some(table) = &e.table {
29518 self.write_keyword("ON");
29519 self.write_space();
29520 self.generate_expression(table)?;
29521 }
29522 if !e.params.is_empty() {
29523 self.write("(");
29524 for (i, param) in e.params.iter().enumerate() {
29525 if i > 0 {
29526 self.write(", ");
29527 }
29528 self.generate_expression(param)?;
29529 }
29530 self.write(")");
29531 }
29532 Ok(())
29533 }
29534
29535 fn generate_index_column_constraint(&mut self, e: &IndexColumnConstraint) -> Result<()> {
29536 if let Some(kind) = &e.kind {
29538 self.write(kind);
29539 self.write_space();
29540 }
29541 self.write_keyword("INDEX");
29542 if let Some(this) = &e.this {
29543 self.write_space();
29544 self.generate_expression(this)?;
29545 }
29546 if let Some(index_type) = &e.index_type {
29547 self.write_space();
29548 self.write_keyword("USING");
29549 self.write_space();
29550 self.generate_expression(index_type)?;
29551 }
29552 if !e.expressions.is_empty() {
29553 self.write(" (");
29554 for (i, expr) in e.expressions.iter().enumerate() {
29555 if i > 0 {
29556 self.write(", ");
29557 }
29558 self.generate_expression(expr)?;
29559 }
29560 self.write(")");
29561 }
29562 for opt in &e.options {
29563 self.write_space();
29564 self.generate_expression(opt)?;
29565 }
29566 Ok(())
29567 }
29568
29569 fn generate_index_constraint_option(&mut self, e: &IndexConstraintOption) -> Result<()> {
29570 if let Some(key_block_size) = &e.key_block_size {
29572 self.write_keyword("KEY_BLOCK_SIZE");
29573 self.write(" = ");
29574 self.generate_expression(key_block_size)?;
29575 } else if let Some(using) = &e.using {
29576 self.write_keyword("USING");
29577 self.write_space();
29578 self.generate_expression(using)?;
29579 } else if let Some(parser) = &e.parser {
29580 self.write_keyword("WITH PARSER");
29581 self.write_space();
29582 self.generate_expression(parser)?;
29583 } else if let Some(comment) = &e.comment {
29584 self.write_keyword("COMMENT");
29585 self.write_space();
29586 self.generate_expression(comment)?;
29587 } else if let Some(visible) = &e.visible {
29588 self.generate_expression(visible)?;
29589 } else if let Some(engine_attr) = &e.engine_attr {
29590 self.write_keyword("ENGINE_ATTRIBUTE");
29591 self.write(" = ");
29592 self.generate_expression(engine_attr)?;
29593 } else if let Some(secondary_engine_attr) = &e.secondary_engine_attr {
29594 self.write_keyword("SECONDARY_ENGINE_ATTRIBUTE");
29595 self.write(" = ");
29596 self.generate_expression(secondary_engine_attr)?;
29597 }
29598 Ok(())
29599 }
29600
29601 fn generate_index_parameters(&mut self, e: &IndexParameters) -> Result<()> {
29602 if let Some(using) = &e.using {
29604 self.write_keyword("USING");
29605 self.write_space();
29606 self.generate_expression(using)?;
29607 }
29608 if !e.columns.is_empty() {
29609 self.write("(");
29610 for (i, col) in e.columns.iter().enumerate() {
29611 if i > 0 {
29612 self.write(", ");
29613 }
29614 self.generate_expression(col)?;
29615 }
29616 self.write(")");
29617 }
29618 if let Some(partition_by) = &e.partition_by {
29619 self.write_space();
29620 self.write_keyword("PARTITION BY");
29621 self.write_space();
29622 self.generate_expression(partition_by)?;
29623 }
29624 if let Some(where_) = &e.where_ {
29625 self.write_space();
29626 self.generate_expression(where_)?;
29627 }
29628 if let Some(include) = &e.include {
29629 self.write_space();
29630 self.write_keyword("INCLUDE");
29631 self.write(" (");
29632 self.generate_expression(include)?;
29633 self.write(")");
29634 }
29635 if let Some(with_storage) = &e.with_storage {
29636 self.write_space();
29637 self.write_keyword("WITH");
29638 self.write(" (");
29639 self.generate_expression(with_storage)?;
29640 self.write(")");
29641 }
29642 if let Some(tablespace) = &e.tablespace {
29643 self.write_space();
29644 self.write_keyword("USING INDEX TABLESPACE");
29645 self.write_space();
29646 self.generate_expression(tablespace)?;
29647 }
29648 Ok(())
29649 }
29650
29651 fn generate_index_table_hint(&mut self, e: &IndexTableHint) -> Result<()> {
29652 if let Expression::Identifier(id) = &*e.this {
29656 self.write_keyword(&id.name);
29657 } else {
29658 self.generate_expression(&e.this)?;
29659 }
29660 self.write_space();
29661 self.write_keyword("INDEX");
29662 if let Some(target) = &e.target {
29663 self.write_space();
29664 self.write_keyword("FOR");
29665 self.write_space();
29666 if let Expression::Identifier(id) = &**target {
29667 self.write_keyword(&id.name);
29668 } else {
29669 self.generate_expression(target)?;
29670 }
29671 }
29672 self.write(" (");
29674 for (i, expr) in e.expressions.iter().enumerate() {
29675 if i > 0 {
29676 self.write(", ");
29677 }
29678 self.generate_expression(expr)?;
29679 }
29680 self.write(")");
29681 Ok(())
29682 }
29683
29684 fn generate_inherits_property(&mut self, e: &InheritsProperty) -> Result<()> {
29685 self.write_keyword("INHERITS");
29687 self.write(" (");
29688 for (i, expr) in e.expressions.iter().enumerate() {
29689 if i > 0 {
29690 self.write(", ");
29691 }
29692 self.generate_expression(expr)?;
29693 }
29694 self.write(")");
29695 Ok(())
29696 }
29697
29698 fn generate_input_model_property(&mut self, e: &InputModelProperty) -> Result<()> {
29699 self.write_keyword("INPUT");
29701 self.write("(");
29702 self.generate_expression(&e.this)?;
29703 self.write(")");
29704 Ok(())
29705 }
29706
29707 fn generate_input_output_format(&mut self, e: &InputOutputFormat) -> Result<()> {
29708 if let Some(input_format) = &e.input_format {
29710 self.write_keyword("INPUTFORMAT");
29711 self.write_space();
29712 self.generate_expression(input_format)?;
29713 }
29714 if let Some(output_format) = &e.output_format {
29715 if e.input_format.is_some() {
29716 self.write(" ");
29717 }
29718 self.write_keyword("OUTPUTFORMAT");
29719 self.write_space();
29720 self.generate_expression(output_format)?;
29721 }
29722 Ok(())
29723 }
29724
29725 fn generate_install(&mut self, e: &Install) -> Result<()> {
29726 if e.force.is_some() {
29728 self.write_keyword("FORCE");
29729 self.write_space();
29730 }
29731 self.write_keyword("INSTALL");
29732 self.write_space();
29733 self.generate_expression(&e.this)?;
29734 if let Some(from) = &e.from_ {
29735 self.write_space();
29736 self.write_keyword("FROM");
29737 self.write_space();
29738 self.generate_expression(from)?;
29739 }
29740 Ok(())
29741 }
29742
29743 fn generate_interval_op(&mut self, e: &IntervalOp) -> Result<()> {
29744 self.write_keyword("INTERVAL");
29746 self.write_space();
29747 self.generate_expression(&e.expression)?;
29749 if let Some(unit) = &e.unit {
29750 self.write_space();
29751 self.write(unit);
29752 }
29753 Ok(())
29754 }
29755
29756 fn generate_interval_span(&mut self, e: &IntervalSpan) -> Result<()> {
29757 self.write(&format!("{:?}", e.this).to_ascii_uppercase());
29759 self.write_space();
29760 self.write_keyword("TO");
29761 self.write_space();
29762 self.write(&format!("{:?}", e.expression).to_ascii_uppercase());
29763 Ok(())
29764 }
29765
29766 fn generate_into_clause(&mut self, e: &IntoClause) -> Result<()> {
29767 self.write_keyword("INTO");
29769 if e.temporary {
29770 self.write_keyword(" TEMPORARY");
29771 }
29772 if e.unlogged.is_some() {
29773 self.write_keyword(" UNLOGGED");
29774 }
29775 if let Some(this) = &e.this {
29776 self.write_space();
29777 self.generate_expression(this)?;
29778 }
29779 if !e.expressions.is_empty() {
29780 self.write(" (");
29781 for (i, expr) in e.expressions.iter().enumerate() {
29782 if i > 0 {
29783 self.write(", ");
29784 }
29785 self.generate_expression(expr)?;
29786 }
29787 self.write(")");
29788 }
29789 Ok(())
29790 }
29791
29792 fn generate_introducer(&mut self, e: &Introducer) -> Result<()> {
29793 self.generate_expression(&e.this)?;
29795 self.write_space();
29796 self.generate_expression(&e.expression)?;
29797 Ok(())
29798 }
29799
29800 fn generate_isolated_loading_property(&mut self, e: &IsolatedLoadingProperty) -> Result<()> {
29801 self.write_keyword("WITH");
29803 if e.no.is_some() {
29804 self.write_keyword(" NO");
29805 }
29806 if e.concurrent.is_some() {
29807 self.write_keyword(" CONCURRENT");
29808 }
29809 self.write_keyword(" ISOLATED LOADING");
29810 if let Some(target) = &e.target {
29811 self.write_space();
29812 self.generate_expression(target)?;
29813 }
29814 Ok(())
29815 }
29816
29817 fn generate_json(&mut self, e: &JSON) -> Result<()> {
29818 self.write_keyword("JSON");
29820 if let Some(this) = &e.this {
29821 self.write_space();
29822 self.generate_expression(this)?;
29823 }
29824 if let Some(with_) = &e.with_ {
29825 if let Expression::Boolean(b) = with_.as_ref() {
29827 if b.value {
29828 self.write_keyword(" WITH");
29829 } else {
29830 self.write_keyword(" WITHOUT");
29831 }
29832 }
29833 }
29834 if e.unique {
29835 self.write_keyword(" UNIQUE KEYS");
29836 }
29837 Ok(())
29838 }
29839
29840 fn generate_json_array(&mut self, e: &JSONArray) -> Result<()> {
29841 self.write_keyword("JSON_ARRAY");
29843 self.write("(");
29844 for (i, expr) in e.expressions.iter().enumerate() {
29845 if i > 0 {
29846 self.write(", ");
29847 }
29848 self.generate_expression(expr)?;
29849 }
29850 if let Some(null_handling) = &e.null_handling {
29851 self.write_space();
29852 self.generate_expression(null_handling)?;
29853 }
29854 if let Some(return_type) = &e.return_type {
29855 self.write_space();
29856 self.write_keyword("RETURNING");
29857 self.write_space();
29858 self.generate_expression(return_type)?;
29859 }
29860 if e.strict.is_some() {
29861 self.write_space();
29862 self.write_keyword("STRICT");
29863 }
29864 self.write(")");
29865 Ok(())
29866 }
29867
29868 fn generate_json_array_agg_struct(&mut self, e: &JSONArrayAgg) -> Result<()> {
29869 self.write_keyword("JSON_ARRAYAGG");
29871 self.write("(");
29872 self.generate_expression(&e.this)?;
29873 if let Some(order) = &e.order {
29874 self.write_space();
29875 if let Expression::OrderBy(ob) = order.as_ref() {
29877 self.write_keyword("ORDER BY");
29878 self.write_space();
29879 for (i, ord) in ob.expressions.iter().enumerate() {
29880 if i > 0 {
29881 self.write(", ");
29882 }
29883 self.generate_ordered(ord)?;
29884 }
29885 } else {
29886 self.generate_expression(order)?;
29888 }
29889 }
29890 if let Some(null_handling) = &e.null_handling {
29891 self.write_space();
29892 self.generate_expression(null_handling)?;
29893 }
29894 if let Some(return_type) = &e.return_type {
29895 self.write_space();
29896 self.write_keyword("RETURNING");
29897 self.write_space();
29898 self.generate_expression(return_type)?;
29899 }
29900 if e.strict.is_some() {
29901 self.write_space();
29902 self.write_keyword("STRICT");
29903 }
29904 self.write(")");
29905 Ok(())
29906 }
29907
29908 fn generate_json_object_agg_struct(&mut self, e: &JSONObjectAgg) -> Result<()> {
29909 self.write_keyword("JSON_OBJECTAGG");
29911 self.write("(");
29912 for (i, expr) in e.expressions.iter().enumerate() {
29913 if i > 0 {
29914 self.write(", ");
29915 }
29916 self.generate_expression(expr)?;
29917 }
29918 if let Some(null_handling) = &e.null_handling {
29919 self.write_space();
29920 self.generate_expression(null_handling)?;
29921 }
29922 if let Some(unique_keys) = &e.unique_keys {
29923 self.write_space();
29924 if let Expression::Boolean(b) = unique_keys.as_ref() {
29925 if b.value {
29926 self.write_keyword("WITH UNIQUE KEYS");
29927 } else {
29928 self.write_keyword("WITHOUT UNIQUE KEYS");
29929 }
29930 }
29931 }
29932 if let Some(return_type) = &e.return_type {
29933 self.write_space();
29934 self.write_keyword("RETURNING");
29935 self.write_space();
29936 self.generate_expression(return_type)?;
29937 }
29938 self.write(")");
29939 Ok(())
29940 }
29941
29942 fn generate_json_array_append(&mut self, e: &JSONArrayAppend) -> Result<()> {
29943 self.write_keyword("JSON_ARRAY_APPEND");
29945 self.write("(");
29946 self.generate_expression(&e.this)?;
29947 for expr in &e.expressions {
29948 self.write(", ");
29949 self.generate_expression(expr)?;
29950 }
29951 self.write(")");
29952 Ok(())
29953 }
29954
29955 fn generate_json_array_contains(&mut self, e: &JSONArrayContains) -> Result<()> {
29956 self.write_keyword("JSON_ARRAY_CONTAINS");
29958 self.write("(");
29959 self.generate_expression(&e.this)?;
29960 self.write(", ");
29961 self.generate_expression(&e.expression)?;
29962 self.write(")");
29963 Ok(())
29964 }
29965
29966 fn generate_json_array_insert(&mut self, e: &JSONArrayInsert) -> Result<()> {
29967 self.write_keyword("JSON_ARRAY_INSERT");
29969 self.write("(");
29970 self.generate_expression(&e.this)?;
29971 for expr in &e.expressions {
29972 self.write(", ");
29973 self.generate_expression(expr)?;
29974 }
29975 self.write(")");
29976 Ok(())
29977 }
29978
29979 fn generate_jsonb_exists(&mut self, e: &JSONBExists) -> Result<()> {
29980 self.write_keyword("JSONB_EXISTS");
29982 self.write("(");
29983 self.generate_expression(&e.this)?;
29984 if let Some(path) = &e.path {
29985 self.write(", ");
29986 self.generate_expression(path)?;
29987 }
29988 self.write(")");
29989 Ok(())
29990 }
29991
29992 fn generate_jsonb_extract_scalar(&mut self, e: &JSONBExtractScalar) -> Result<()> {
29993 self.write_keyword("JSONB_EXTRACT_SCALAR");
29995 self.write("(");
29996 self.generate_expression(&e.this)?;
29997 self.write(", ");
29998 self.generate_expression(&e.expression)?;
29999 self.write(")");
30000 Ok(())
30001 }
30002
30003 fn generate_jsonb_object_agg(&mut self, e: &JSONBObjectAgg) -> Result<()> {
30004 self.write_keyword("JSONB_OBJECT_AGG");
30006 self.write("(");
30007 self.generate_expression(&e.this)?;
30008 self.write(", ");
30009 self.generate_expression(&e.expression)?;
30010 self.write(")");
30011 Ok(())
30012 }
30013
30014 fn generate_json_column_def(&mut self, e: &JSONColumnDef) -> Result<()> {
30015 if let Some(nested_schema) = &e.nested_schema {
30017 self.write_keyword("NESTED");
30018 if let Some(path) = &e.path {
30019 self.write_space();
30020 self.write_keyword("PATH");
30021 self.write_space();
30022 self.generate_expression(path)?;
30023 }
30024 self.write_space();
30025 self.generate_expression(nested_schema)?;
30026 } else {
30027 if let Some(this) = &e.this {
30028 self.generate_expression(this)?;
30029 }
30030 if let Some(kind) = &e.kind {
30031 self.write_space();
30032 self.write(kind);
30033 }
30034 if e.format_json {
30035 self.write_space();
30036 self.write_keyword("FORMAT JSON");
30037 }
30038 if let Some(path) = &e.path {
30039 self.write_space();
30040 self.write_keyword("PATH");
30041 self.write_space();
30042 self.generate_expression(path)?;
30043 }
30044 if e.ordinality.is_some() {
30045 self.write_keyword(" FOR ORDINALITY");
30046 }
30047 }
30048 Ok(())
30049 }
30050
30051 fn generate_json_exists(&mut self, e: &JSONExists) -> Result<()> {
30052 self.write_keyword("JSON_EXISTS");
30054 self.write("(");
30055 self.generate_expression(&e.this)?;
30056 if let Some(path) = &e.path {
30057 self.write(", ");
30058 self.generate_expression(path)?;
30059 }
30060 if let Some(passing) = &e.passing {
30061 self.write_space();
30062 self.write_keyword("PASSING");
30063 self.write_space();
30064 self.generate_expression(passing)?;
30065 }
30066 if let Some(on_condition) = &e.on_condition {
30067 self.write_space();
30068 self.generate_expression(on_condition)?;
30069 }
30070 self.write(")");
30071 Ok(())
30072 }
30073
30074 fn generate_json_cast(&mut self, e: &JSONCast) -> Result<()> {
30075 self.generate_expression(&e.this)?;
30076 self.write(".:");
30077 if Self::data_type_has_nested_expressions(&e.to) {
30081 let saved = std::mem::take(&mut self.output);
30083 self.generate_data_type(&e.to)?;
30084 let type_sql = std::mem::replace(&mut self.output, saved);
30085 self.write("\"");
30086 self.write(&type_sql);
30087 self.write("\"");
30088 } else {
30089 self.generate_data_type(&e.to)?;
30090 }
30091 Ok(())
30092 }
30093
30094 fn data_type_has_nested_expressions(dt: &DataType) -> bool {
30097 matches!(
30098 dt,
30099 DataType::Array { .. } | DataType::Map { .. } | DataType::Struct { .. }
30100 )
30101 }
30102
30103 fn generate_json_extract_array(&mut self, e: &JSONExtractArray) -> Result<()> {
30104 self.write_keyword("JSON_EXTRACT_ARRAY");
30106 self.write("(");
30107 self.generate_expression(&e.this)?;
30108 if let Some(expr) = &e.expression {
30109 self.write(", ");
30110 self.generate_expression(expr)?;
30111 }
30112 self.write(")");
30113 Ok(())
30114 }
30115
30116 fn generate_json_extract_quote(&mut self, e: &JSONExtractQuote) -> Result<()> {
30117 if let Some(option) = &e.option {
30119 self.generate_expression(option)?;
30120 self.write_space();
30121 }
30122 self.write_keyword("QUOTES");
30123 if e.scalar.is_some() {
30124 self.write_keyword(" SCALAR_ONLY");
30125 }
30126 Ok(())
30127 }
30128
30129 fn generate_json_extract_scalar(&mut self, e: &JSONExtractScalar) -> Result<()> {
30130 self.write_keyword("JSON_EXTRACT_SCALAR");
30132 self.write("(");
30133 self.generate_expression(&e.this)?;
30134 self.write(", ");
30135 self.generate_expression(&e.expression)?;
30136 self.write(")");
30137 Ok(())
30138 }
30139
30140 fn generate_json_extract_path(&mut self, e: &JSONExtract) -> Result<()> {
30141 if e.variant_extract.is_some() {
30145 use crate::dialects::DialectType;
30146 if matches!(self.config.dialect, Some(DialectType::Databricks)) {
30147 self.generate_expression(&e.this)?;
30151 self.write(":");
30152 match e.expression.as_ref() {
30153 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
30154 let Literal::String(s) = lit.as_ref() else {
30155 unreachable!()
30156 };
30157 self.write_databricks_json_path(s);
30158 }
30159 _ => {
30160 self.generate_expression(&e.expression)?;
30162 }
30163 }
30164 } else {
30165 self.write_keyword("GET_PATH");
30167 self.write("(");
30168 self.generate_expression(&e.this)?;
30169 self.write(", ");
30170 self.generate_expression(&e.expression)?;
30171 self.write(")");
30172 }
30173 } else {
30174 self.write_keyword("JSON_EXTRACT");
30175 self.write("(");
30176 self.generate_expression(&e.this)?;
30177 self.write(", ");
30178 self.generate_expression(&e.expression)?;
30179 for expr in &e.expressions {
30180 self.write(", ");
30181 self.generate_expression(expr)?;
30182 }
30183 self.write(")");
30184 }
30185 Ok(())
30186 }
30187
30188 fn write_databricks_json_path(&mut self, path: &str) {
30192 if path.starts_with("[\"") || path.starts_with("['") {
30195 self.write(path);
30196 return;
30197 }
30198 let mut first = true;
30202 for segment in path.split('.') {
30203 if !first {
30204 self.write(".");
30205 }
30206 first = false;
30207 if let Some(bracket_pos) = segment.find('[') {
30209 let key = &segment[..bracket_pos];
30210 let subscript = &segment[bracket_pos..];
30211 if key.is_empty() {
30212 self.write(segment);
30214 } else if Self::is_safe_json_path_key(key) {
30215 self.write(key);
30216 self.write(subscript);
30217 } else {
30218 self.write("[\"");
30219 self.write(key);
30220 self.write("\"]");
30221 self.write(subscript);
30222 }
30223 } else if Self::is_safe_json_path_key(segment) {
30224 self.write(segment);
30225 } else {
30226 self.write("[\"");
30227 self.write(segment);
30228 self.write("\"]");
30229 }
30230 }
30231 }
30232
30233 fn is_safe_json_path_key(key: &str) -> bool {
30236 if key.is_empty() {
30237 return false;
30238 }
30239 let mut chars = key.chars();
30240 let first = chars.next().unwrap();
30241 if first != '_' && !first.is_ascii_alphabetic() {
30242 return false;
30243 }
30244 chars.all(|c| c == '_' || c.is_ascii_alphanumeric())
30245 }
30246
30247 fn generate_json_format(&mut self, e: &JSONFormat) -> Result<()> {
30248 if let Some(this) = &e.this {
30251 self.generate_expression(this)?;
30252 self.write_space();
30253 }
30254 self.write_keyword("FORMAT JSON");
30255 Ok(())
30256 }
30257
30258 fn generate_json_key_value(&mut self, e: &JSONKeyValue) -> Result<()> {
30259 self.generate_expression(&e.this)?;
30261 self.write(": ");
30262 self.generate_expression(&e.expression)?;
30263 Ok(())
30264 }
30265
30266 fn generate_json_keys(&mut self, e: &JSONKeys) -> Result<()> {
30267 self.write_keyword("JSON_KEYS");
30269 self.write("(");
30270 self.generate_expression(&e.this)?;
30271 if let Some(expr) = &e.expression {
30272 self.write(", ");
30273 self.generate_expression(expr)?;
30274 }
30275 for expr in &e.expressions {
30276 self.write(", ");
30277 self.generate_expression(expr)?;
30278 }
30279 self.write(")");
30280 Ok(())
30281 }
30282
30283 fn generate_json_keys_at_depth(&mut self, e: &JSONKeysAtDepth) -> Result<()> {
30284 self.write_keyword("JSON_KEYS");
30286 self.write("(");
30287 self.generate_expression(&e.this)?;
30288 if let Some(expr) = &e.expression {
30289 self.write(", ");
30290 self.generate_expression(expr)?;
30291 }
30292 self.write(")");
30293 Ok(())
30294 }
30295
30296 fn generate_json_path_expr(&mut self, e: &JSONPath) -> Result<()> {
30297 let mut path_str = String::new();
30300 for expr in &e.expressions {
30301 match expr {
30302 Expression::JSONPathRoot(_) => {
30303 path_str.push('$');
30304 }
30305 Expression::JSONPathKey(k) => {
30306 if let Expression::Literal(lit) = k.this.as_ref() {
30308 if let crate::expressions::Literal::String(s) = lit.as_ref() {
30309 path_str.push('.');
30310 let needs_quoting = s.chars().any(|c| !c.is_alphanumeric() && c != '_');
30312 if needs_quoting {
30313 path_str.push('"');
30314 path_str.push_str(s);
30315 path_str.push('"');
30316 } else {
30317 path_str.push_str(s);
30318 }
30319 }
30320 }
30321 }
30322 Expression::JSONPathSubscript(s) => {
30323 if let Expression::Literal(lit) = s.this.as_ref() {
30325 if let crate::expressions::Literal::Number(n) = lit.as_ref() {
30326 path_str.push('[');
30327 path_str.push_str(n);
30328 path_str.push(']');
30329 }
30330 }
30331 }
30332 _ => {
30333 let mut temp_gen = Self::with_arc_config(self.config.clone());
30335 temp_gen.generate_expression(expr)?;
30336 path_str.push_str(&temp_gen.output);
30337 }
30338 }
30339 }
30340 self.write("'");
30342 self.write(&path_str);
30343 self.write("'");
30344 Ok(())
30345 }
30346
30347 fn generate_json_path_filter(&mut self, e: &JSONPathFilter) -> Result<()> {
30348 self.write("?(");
30350 self.generate_expression(&e.this)?;
30351 self.write(")");
30352 Ok(())
30353 }
30354
30355 fn generate_json_path_key(&mut self, e: &JSONPathKey) -> Result<()> {
30356 self.write(".");
30358 self.generate_expression(&e.this)?;
30359 Ok(())
30360 }
30361
30362 fn generate_json_path_recursive(&mut self, e: &JSONPathRecursive) -> Result<()> {
30363 self.write("..");
30365 if let Some(this) = &e.this {
30366 self.generate_expression(this)?;
30367 }
30368 Ok(())
30369 }
30370
30371 fn generate_json_path_root(&mut self) -> Result<()> {
30372 self.write("$");
30374 Ok(())
30375 }
30376
30377 fn generate_json_path_script(&mut self, e: &JSONPathScript) -> Result<()> {
30378 self.write("(");
30380 self.generate_expression(&e.this)?;
30381 self.write(")");
30382 Ok(())
30383 }
30384
30385 fn generate_json_path_selector(&mut self, e: &JSONPathSelector) -> Result<()> {
30386 self.generate_expression(&e.this)?;
30388 Ok(())
30389 }
30390
30391 fn generate_json_path_slice(&mut self, e: &JSONPathSlice) -> Result<()> {
30392 self.write("[");
30394 if let Some(start) = &e.start {
30395 self.generate_expression(start)?;
30396 }
30397 self.write(":");
30398 if let Some(end) = &e.end {
30399 self.generate_expression(end)?;
30400 }
30401 if let Some(step) = &e.step {
30402 self.write(":");
30403 self.generate_expression(step)?;
30404 }
30405 self.write("]");
30406 Ok(())
30407 }
30408
30409 fn generate_json_path_subscript(&mut self, e: &JSONPathSubscript) -> Result<()> {
30410 self.write("[");
30412 self.generate_expression(&e.this)?;
30413 self.write("]");
30414 Ok(())
30415 }
30416
30417 fn generate_json_path_union(&mut self, e: &JSONPathUnion) -> Result<()> {
30418 self.write("[");
30420 for (i, expr) in e.expressions.iter().enumerate() {
30421 if i > 0 {
30422 self.write(", ");
30423 }
30424 self.generate_expression(expr)?;
30425 }
30426 self.write("]");
30427 Ok(())
30428 }
30429
30430 fn generate_json_remove(&mut self, e: &JSONRemove) -> Result<()> {
30431 self.write_keyword("JSON_REMOVE");
30433 self.write("(");
30434 self.generate_expression(&e.this)?;
30435 for expr in &e.expressions {
30436 self.write(", ");
30437 self.generate_expression(expr)?;
30438 }
30439 self.write(")");
30440 Ok(())
30441 }
30442
30443 fn generate_json_schema(&mut self, e: &JSONSchema) -> Result<()> {
30444 self.write_keyword("COLUMNS");
30447 self.write("(");
30448
30449 if self.config.pretty && !e.expressions.is_empty() {
30450 let mut expr_strings: Vec<String> = Vec::with_capacity(e.expressions.len());
30452 for expr in &e.expressions {
30453 let mut temp_gen = Generator::with_arc_config(self.config.clone());
30454 temp_gen.generate_expression(expr)?;
30455 expr_strings.push(temp_gen.output);
30456 }
30457
30458 if self.too_wide(&expr_strings) {
30460 self.write_newline();
30462 self.indent_level += 1;
30463 for (i, expr_str) in expr_strings.iter().enumerate() {
30464 if i > 0 {
30465 self.write(",");
30466 self.write_newline();
30467 }
30468 self.write_indent();
30469 self.write(expr_str);
30470 }
30471 self.write_newline();
30472 self.indent_level -= 1;
30473 self.write_indent();
30474 } else {
30475 for (i, expr_str) in expr_strings.iter().enumerate() {
30477 if i > 0 {
30478 self.write(", ");
30479 }
30480 self.write(expr_str);
30481 }
30482 }
30483 } else {
30484 for (i, expr) in e.expressions.iter().enumerate() {
30486 if i > 0 {
30487 self.write(", ");
30488 }
30489 self.generate_expression(expr)?;
30490 }
30491 }
30492 self.write(")");
30493 Ok(())
30494 }
30495
30496 fn generate_json_set(&mut self, e: &JSONSet) -> Result<()> {
30497 self.write_keyword("JSON_SET");
30499 self.write("(");
30500 self.generate_expression(&e.this)?;
30501 for expr in &e.expressions {
30502 self.write(", ");
30503 self.generate_expression(expr)?;
30504 }
30505 self.write(")");
30506 Ok(())
30507 }
30508
30509 fn generate_json_strip_nulls(&mut self, e: &JSONStripNulls) -> Result<()> {
30510 self.write_keyword("JSON_STRIP_NULLS");
30512 self.write("(");
30513 self.generate_expression(&e.this)?;
30514 if let Some(expr) = &e.expression {
30515 self.write(", ");
30516 self.generate_expression(expr)?;
30517 }
30518 self.write(")");
30519 Ok(())
30520 }
30521
30522 fn generate_json_table(&mut self, e: &JSONTable) -> Result<()> {
30523 self.write_keyword("JSON_TABLE");
30525 self.write("(");
30526 self.generate_expression(&e.this)?;
30527 if let Some(path) = &e.path {
30528 self.write(", ");
30529 self.generate_expression(path)?;
30530 }
30531 if let Some(error_handling) = &e.error_handling {
30532 self.write_space();
30533 self.generate_expression(error_handling)?;
30534 }
30535 if let Some(empty_handling) = &e.empty_handling {
30536 self.write_space();
30537 self.generate_expression(empty_handling)?;
30538 }
30539 if let Some(schema) = &e.schema {
30540 self.write_space();
30541 self.generate_expression(schema)?;
30542 }
30543 self.write(")");
30544 Ok(())
30545 }
30546
30547 fn generate_json_type(&mut self, e: &JSONType) -> Result<()> {
30548 self.write_keyword("JSON_TYPE");
30550 self.write("(");
30551 self.generate_expression(&e.this)?;
30552 self.write(")");
30553 Ok(())
30554 }
30555
30556 fn generate_json_value(&mut self, e: &JSONValue) -> Result<()> {
30557 self.write_keyword("JSON_VALUE");
30559 self.write("(");
30560 self.generate_expression(&e.this)?;
30561 if let Some(path) = &e.path {
30562 self.write(", ");
30563 self.generate_expression(path)?;
30564 }
30565 if let Some(returning) = &e.returning {
30566 self.write_space();
30567 self.write_keyword("RETURNING");
30568 self.write_space();
30569 self.generate_expression(returning)?;
30570 }
30571 if let Some(on_condition) = &e.on_condition {
30572 self.write_space();
30573 self.generate_expression(on_condition)?;
30574 }
30575 self.write(")");
30576 Ok(())
30577 }
30578
30579 fn generate_json_value_array(&mut self, e: &JSONValueArray) -> Result<()> {
30580 self.write_keyword("JSON_VALUE_ARRAY");
30582 self.write("(");
30583 self.generate_expression(&e.this)?;
30584 self.write(")");
30585 Ok(())
30586 }
30587
30588 fn generate_jarowinkler_similarity(&mut self, e: &JarowinklerSimilarity) -> Result<()> {
30589 self.write_keyword("JAROWINKLER_SIMILARITY");
30591 self.write("(");
30592 self.generate_expression(&e.this)?;
30593 self.write(", ");
30594 self.generate_expression(&e.expression)?;
30595 self.write(")");
30596 Ok(())
30597 }
30598
30599 fn generate_join_hint(&mut self, e: &JoinHint) -> Result<()> {
30600 self.generate_expression(&e.this)?;
30602 self.write("(");
30603 for (i, expr) in e.expressions.iter().enumerate() {
30604 if i > 0 {
30605 self.write(", ");
30606 }
30607 self.generate_expression(expr)?;
30608 }
30609 self.write(")");
30610 Ok(())
30611 }
30612
30613 fn generate_journal_property(&mut self, e: &JournalProperty) -> Result<()> {
30614 if e.no.is_some() {
30616 self.write_keyword("NO ");
30617 }
30618 if let Some(local) = &e.local {
30619 self.generate_expression(local)?;
30620 self.write_space();
30621 }
30622 if e.dual.is_some() {
30623 self.write_keyword("DUAL ");
30624 }
30625 if e.before.is_some() {
30626 self.write_keyword("BEFORE ");
30627 }
30628 if e.after.is_some() {
30629 self.write_keyword("AFTER ");
30630 }
30631 self.write_keyword("JOURNAL");
30632 Ok(())
30633 }
30634
30635 fn generate_language_property(&mut self, e: &LanguageProperty) -> Result<()> {
30636 self.write_keyword("LANGUAGE");
30638 self.write_space();
30639 self.generate_expression(&e.this)?;
30640 Ok(())
30641 }
30642
30643 fn generate_lateral(&mut self, e: &Lateral) -> Result<()> {
30644 if e.view.is_some() {
30646 self.write_keyword("LATERAL VIEW");
30648 if e.outer.is_some() {
30649 self.write_space();
30650 self.write_keyword("OUTER");
30651 }
30652 self.write_space();
30653 self.generate_expression(&e.this)?;
30654 if let Some(alias) = &e.alias {
30655 self.write_space();
30656 self.write(alias);
30657 }
30658 } else {
30659 self.write_keyword("LATERAL");
30661 self.write_space();
30662 self.generate_expression(&e.this)?;
30663 if e.ordinality.is_some() {
30664 self.write_space();
30665 self.write_keyword("WITH ORDINALITY");
30666 }
30667 if let Some(alias) = &e.alias {
30668 self.write_space();
30669 self.write_keyword("AS");
30670 self.write_space();
30671 self.write(alias);
30672 if !e.column_aliases.is_empty() {
30673 self.write("(");
30674 for (i, col) in e.column_aliases.iter().enumerate() {
30675 if i > 0 {
30676 self.write(", ");
30677 }
30678 self.write(col);
30679 }
30680 self.write(")");
30681 }
30682 }
30683 }
30684 Ok(())
30685 }
30686
30687 fn generate_like_property(&mut self, e: &LikeProperty) -> Result<()> {
30688 self.write_keyword("LIKE");
30690 self.write_space();
30691 self.generate_expression(&e.this)?;
30692 for expr in &e.expressions {
30693 self.write_space();
30694 self.generate_expression(expr)?;
30695 }
30696 Ok(())
30697 }
30698
30699 fn generate_limit(&mut self, e: &Limit) -> Result<()> {
30700 self.write_keyword("LIMIT");
30701 self.write_space();
30702 self.write_limit_expr(&e.this)?;
30703 if e.percent {
30704 self.write_space();
30705 self.write_keyword("PERCENT");
30706 }
30707 for comment in &e.comments {
30709 self.write(" ");
30710 self.write_formatted_comment(comment);
30711 }
30712 Ok(())
30713 }
30714
30715 fn generate_limit_options(&mut self, e: &LimitOptions) -> Result<()> {
30716 if e.percent.is_some() {
30718 self.write_keyword(" PERCENT");
30719 }
30720 if e.rows.is_some() {
30721 self.write_keyword(" ROWS");
30722 }
30723 if e.with_ties.is_some() {
30724 self.write_keyword(" WITH TIES");
30725 } else if e.rows.is_some() {
30726 self.write_keyword(" ONLY");
30727 }
30728 Ok(())
30729 }
30730
30731 fn generate_list(&mut self, e: &List) -> Result<()> {
30732 use crate::dialects::DialectType;
30733 let is_materialize = matches!(self.config.dialect, Some(DialectType::Materialize));
30734
30735 if e.expressions.len() == 1 {
30737 if let Expression::Select(_) = &e.expressions[0] {
30738 self.write_keyword("LIST");
30739 self.write("(");
30740 self.generate_expression(&e.expressions[0])?;
30741 self.write(")");
30742 return Ok(());
30743 }
30744 }
30745
30746 if is_materialize {
30748 self.write_keyword("LIST");
30749 self.write("[");
30750 for (i, expr) in e.expressions.iter().enumerate() {
30751 if i > 0 {
30752 self.write(", ");
30753 }
30754 self.generate_expression(expr)?;
30755 }
30756 self.write("]");
30757 } else {
30758 self.write_keyword("LIST");
30760 self.write("(");
30761 for (i, expr) in e.expressions.iter().enumerate() {
30762 if i > 0 {
30763 self.write(", ");
30764 }
30765 self.generate_expression(expr)?;
30766 }
30767 self.write(")");
30768 }
30769 Ok(())
30770 }
30771
30772 fn generate_tomap(&mut self, e: &ToMap) -> Result<()> {
30773 if let Expression::Select(_) = &*e.this {
30775 self.write_keyword("MAP");
30776 self.write("(");
30777 self.generate_expression(&e.this)?;
30778 self.write(")");
30779 return Ok(());
30780 }
30781
30782 let is_duckdb = matches!(self.config.dialect, Some(DialectType::DuckDB));
30783
30784 self.write_keyword("MAP");
30786 if is_duckdb {
30787 self.write(" {");
30788 } else {
30789 self.write("[");
30790 }
30791 if let Expression::Struct(s) = &*e.this {
30792 for (i, (_, expr)) in s.fields.iter().enumerate() {
30793 if i > 0 {
30794 self.write(", ");
30795 }
30796 if let Expression::PropertyEQ(op) = expr {
30797 self.generate_expression(&op.left)?;
30798 if is_duckdb {
30799 self.write(": ");
30800 } else {
30801 self.write(" => ");
30802 }
30803 self.generate_expression(&op.right)?;
30804 } else {
30805 self.generate_expression(expr)?;
30806 }
30807 }
30808 }
30809 if is_duckdb {
30810 self.write("}");
30811 } else {
30812 self.write("]");
30813 }
30814 Ok(())
30815 }
30816
30817 fn generate_localtime(&mut self, e: &Localtime) -> Result<()> {
30818 self.write_keyword("LOCALTIME");
30820 if let Some(precision) = &e.this {
30821 self.write("(");
30822 self.generate_expression(precision)?;
30823 self.write(")");
30824 }
30825 Ok(())
30826 }
30827
30828 fn generate_localtimestamp(&mut self, e: &Localtimestamp) -> Result<()> {
30829 self.write_keyword("LOCALTIMESTAMP");
30831 if let Some(precision) = &e.this {
30832 self.write("(");
30833 self.generate_expression(precision)?;
30834 self.write(")");
30835 }
30836 Ok(())
30837 }
30838
30839 fn generate_location_property(&mut self, e: &LocationProperty) -> Result<()> {
30840 self.write_keyword("LOCATION");
30842 self.write_space();
30843 self.generate_expression(&e.this)?;
30844 Ok(())
30845 }
30846
30847 fn generate_lock(&mut self, e: &Lock) -> Result<()> {
30848 if e.update.is_some() {
30850 if e.key.is_some() {
30851 self.write_keyword("FOR NO KEY UPDATE");
30852 } else {
30853 self.write_keyword("FOR UPDATE");
30854 }
30855 } else {
30856 if e.key.is_some() {
30857 self.write_keyword("FOR KEY SHARE");
30858 } else {
30859 self.write_keyword("FOR SHARE");
30860 }
30861 }
30862 if !e.expressions.is_empty() {
30863 self.write_keyword(" OF ");
30864 for (i, expr) in e.expressions.iter().enumerate() {
30865 if i > 0 {
30866 self.write(", ");
30867 }
30868 self.generate_expression(expr)?;
30869 }
30870 }
30871 if let Some(wait) = &e.wait {
30876 match wait.as_ref() {
30877 Expression::Boolean(b) => {
30878 if b.value {
30879 self.write_keyword(" NOWAIT");
30880 } else {
30881 self.write_keyword(" SKIP LOCKED");
30882 }
30883 }
30884 _ => {
30885 self.write_keyword(" WAIT ");
30887 self.generate_expression(wait)?;
30888 }
30889 }
30890 }
30891 Ok(())
30892 }
30893
30894 fn generate_lock_property(&mut self, e: &LockProperty) -> Result<()> {
30895 self.write_keyword("LOCK");
30897 self.write_space();
30898 self.generate_expression(&e.this)?;
30899 Ok(())
30900 }
30901
30902 fn generate_locking_property(&mut self, e: &LockingProperty) -> Result<()> {
30903 self.write_keyword("LOCKING");
30905 self.write_space();
30906 self.write(&e.kind);
30907 if let Some(this) = &e.this {
30908 self.write_space();
30909 self.generate_expression(this)?;
30910 }
30911 if let Some(for_or_in) = &e.for_or_in {
30912 self.write_space();
30913 self.generate_expression(for_or_in)?;
30914 }
30915 if let Some(lock_type) = &e.lock_type {
30916 self.write_space();
30917 self.generate_expression(lock_type)?;
30918 }
30919 if e.override_.is_some() {
30920 self.write_keyword(" OVERRIDE");
30921 }
30922 Ok(())
30923 }
30924
30925 fn generate_locking_statement(&mut self, e: &LockingStatement) -> Result<()> {
30926 self.generate_expression(&e.this)?;
30928 self.write_space();
30929 self.generate_expression(&e.expression)?;
30930 Ok(())
30931 }
30932
30933 fn generate_log_property(&mut self, e: &LogProperty) -> Result<()> {
30934 if e.no.is_some() {
30936 self.write_keyword("NO ");
30937 }
30938 self.write_keyword("LOG");
30939 Ok(())
30940 }
30941
30942 fn generate_md5_digest(&mut self, e: &MD5Digest) -> Result<()> {
30943 self.write_keyword("MD5");
30945 self.write("(");
30946 self.generate_expression(&e.this)?;
30947 for expr in &e.expressions {
30948 self.write(", ");
30949 self.generate_expression(expr)?;
30950 }
30951 self.write(")");
30952 Ok(())
30953 }
30954
30955 fn generate_ml_forecast(&mut self, e: &MLForecast) -> Result<()> {
30956 self.write_keyword("ML.FORECAST");
30958 self.write("(");
30959 self.generate_expression(&e.this)?;
30960 if let Some(expression) = &e.expression {
30961 self.write(", ");
30962 self.generate_expression(expression)?;
30963 }
30964 if let Some(params) = &e.params_struct {
30965 self.write(", ");
30966 self.generate_expression(params)?;
30967 }
30968 self.write(")");
30969 Ok(())
30970 }
30971
30972 fn generate_ml_translate(&mut self, e: &MLTranslate) -> Result<()> {
30973 self.write_keyword("ML.TRANSLATE");
30975 self.write("(");
30976 self.generate_expression(&e.this)?;
30977 self.write(", ");
30978 self.generate_expression(&e.expression)?;
30979 if let Some(params) = &e.params_struct {
30980 self.write(", ");
30981 self.generate_expression(params)?;
30982 }
30983 self.write(")");
30984 Ok(())
30985 }
30986
30987 fn generate_make_interval(&mut self, e: &MakeInterval) -> Result<()> {
30988 self.write_keyword("MAKE_INTERVAL");
30990 self.write("(");
30991 let mut first = true;
30992 if let Some(year) = &e.year {
30993 self.write("years => ");
30994 self.generate_expression(year)?;
30995 first = false;
30996 }
30997 if let Some(month) = &e.month {
30998 if !first {
30999 self.write(", ");
31000 }
31001 self.write("months => ");
31002 self.generate_expression(month)?;
31003 first = false;
31004 }
31005 if let Some(week) = &e.week {
31006 if !first {
31007 self.write(", ");
31008 }
31009 self.write("weeks => ");
31010 self.generate_expression(week)?;
31011 first = false;
31012 }
31013 if let Some(day) = &e.day {
31014 if !first {
31015 self.write(", ");
31016 }
31017 self.write("days => ");
31018 self.generate_expression(day)?;
31019 first = false;
31020 }
31021 if let Some(hour) = &e.hour {
31022 if !first {
31023 self.write(", ");
31024 }
31025 self.write("hours => ");
31026 self.generate_expression(hour)?;
31027 first = false;
31028 }
31029 if let Some(minute) = &e.minute {
31030 if !first {
31031 self.write(", ");
31032 }
31033 self.write("mins => ");
31034 self.generate_expression(minute)?;
31035 first = false;
31036 }
31037 if let Some(second) = &e.second {
31038 if !first {
31039 self.write(", ");
31040 }
31041 self.write("secs => ");
31042 self.generate_expression(second)?;
31043 }
31044 self.write(")");
31045 Ok(())
31046 }
31047
31048 fn generate_manhattan_distance(&mut self, e: &ManhattanDistance) -> Result<()> {
31049 self.write_keyword("MANHATTAN_DISTANCE");
31051 self.write("(");
31052 self.generate_expression(&e.this)?;
31053 self.write(", ");
31054 self.generate_expression(&e.expression)?;
31055 self.write(")");
31056 Ok(())
31057 }
31058
31059 fn generate_map(&mut self, e: &Map) -> Result<()> {
31060 self.write_keyword("MAP");
31062 self.write("(");
31063 for (i, (key, value)) in e.keys.iter().zip(e.values.iter()).enumerate() {
31064 if i > 0 {
31065 self.write(", ");
31066 }
31067 self.generate_expression(key)?;
31068 self.write(", ");
31069 self.generate_expression(value)?;
31070 }
31071 self.write(")");
31072 Ok(())
31073 }
31074
31075 fn generate_map_cat(&mut self, e: &MapCat) -> Result<()> {
31076 self.write_keyword("MAP_CAT");
31078 self.write("(");
31079 self.generate_expression(&e.this)?;
31080 self.write(", ");
31081 self.generate_expression(&e.expression)?;
31082 self.write(")");
31083 Ok(())
31084 }
31085
31086 fn generate_map_delete(&mut self, e: &MapDelete) -> Result<()> {
31087 self.write_keyword("MAP_DELETE");
31089 self.write("(");
31090 self.generate_expression(&e.this)?;
31091 for expr in &e.expressions {
31092 self.write(", ");
31093 self.generate_expression(expr)?;
31094 }
31095 self.write(")");
31096 Ok(())
31097 }
31098
31099 fn generate_map_insert(&mut self, e: &MapInsert) -> Result<()> {
31100 self.write_keyword("MAP_INSERT");
31102 self.write("(");
31103 self.generate_expression(&e.this)?;
31104 if let Some(key) = &e.key {
31105 self.write(", ");
31106 self.generate_expression(key)?;
31107 }
31108 if let Some(value) = &e.value {
31109 self.write(", ");
31110 self.generate_expression(value)?;
31111 }
31112 if let Some(update_flag) = &e.update_flag {
31113 self.write(", ");
31114 self.generate_expression(update_flag)?;
31115 }
31116 self.write(")");
31117 Ok(())
31118 }
31119
31120 fn generate_map_pick(&mut self, e: &MapPick) -> Result<()> {
31121 self.write_keyword("MAP_PICK");
31123 self.write("(");
31124 self.generate_expression(&e.this)?;
31125 for expr in &e.expressions {
31126 self.write(", ");
31127 self.generate_expression(expr)?;
31128 }
31129 self.write(")");
31130 Ok(())
31131 }
31132
31133 fn generate_masking_policy_column_constraint(
31134 &mut self,
31135 e: &MaskingPolicyColumnConstraint,
31136 ) -> Result<()> {
31137 self.write_keyword("MASKING POLICY");
31139 self.write_space();
31140 self.generate_expression(&e.this)?;
31141 if !e.expressions.is_empty() {
31142 self.write_keyword(" USING");
31143 self.write(" (");
31144 for (i, expr) in e.expressions.iter().enumerate() {
31145 if i > 0 {
31146 self.write(", ");
31147 }
31148 self.generate_expression(expr)?;
31149 }
31150 self.write(")");
31151 }
31152 Ok(())
31153 }
31154
31155 fn generate_match_against(&mut self, e: &MatchAgainst) -> Result<()> {
31156 if matches!(
31157 self.config.dialect,
31158 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
31159 ) {
31160 if e.expressions.len() > 1 {
31161 self.write("(");
31162 }
31163 for (i, expr) in e.expressions.iter().enumerate() {
31164 if i > 0 {
31165 self.write_keyword(" OR ");
31166 }
31167 self.generate_expression(expr)?;
31168 self.write_space();
31169 self.write("@@");
31170 self.write_space();
31171 self.generate_expression(&e.this)?;
31172 }
31173 if e.expressions.len() > 1 {
31174 self.write(")");
31175 }
31176 return Ok(());
31177 }
31178
31179 self.write_keyword("MATCH");
31181 self.write("(");
31182 for (i, expr) in e.expressions.iter().enumerate() {
31183 if i > 0 {
31184 self.write(", ");
31185 }
31186 self.generate_expression(expr)?;
31187 }
31188 self.write(")");
31189 self.write_keyword(" AGAINST");
31190 self.write("(");
31191 self.generate_expression(&e.this)?;
31192 if let Some(modifier) = &e.modifier {
31193 self.write_space();
31194 self.generate_expression(modifier)?;
31195 }
31196 self.write(")");
31197 Ok(())
31198 }
31199
31200 fn generate_match_recognize_measure(&mut self, e: &MatchRecognizeMeasure) -> Result<()> {
31201 if let Some(window_frame) = &e.window_frame {
31203 self.write(&format!("{:?}", window_frame).to_ascii_uppercase());
31204 self.write_space();
31205 }
31206 self.generate_expression(&e.this)?;
31207 Ok(())
31208 }
31209
31210 fn generate_materialized_property(&mut self, e: &MaterializedProperty) -> Result<()> {
31211 self.write_keyword("MATERIALIZED");
31213 if let Some(this) = &e.this {
31214 self.write_space();
31215 self.generate_expression(this)?;
31216 }
31217 Ok(())
31218 }
31219
31220 fn generate_merge(&mut self, e: &Merge) -> Result<()> {
31221 if let Some(with_) = &e.with_ {
31224 if let Expression::With(with_clause) = with_.as_ref() {
31225 self.generate_with(with_clause)?;
31226 self.write_space();
31227 } else {
31228 self.generate_expression(with_)?;
31229 self.write_space();
31230 }
31231 }
31232 self.write_keyword("MERGE INTO");
31233 self.write_space();
31234 if matches!(self.config.dialect, Some(crate::DialectType::Oracle)) {
31235 if let Expression::Alias(alias) = e.this.as_ref() {
31236 self.generate_expression(&alias.this)?;
31237 self.write_space();
31238 self.generate_identifier(&alias.alias)?;
31239 } else {
31240 self.generate_expression(&e.this)?;
31241 }
31242 } else {
31243 self.generate_expression(&e.this)?;
31244 }
31245
31246 if self.config.pretty {
31248 self.write_newline();
31249 self.write_indent();
31250 } else {
31251 self.write_space();
31252 }
31253 self.write_keyword("USING");
31254 self.write_space();
31255 self.generate_expression(&e.using)?;
31256
31257 if let Some(on) = &e.on {
31259 if self.config.pretty {
31260 self.write_newline();
31261 self.write_indent();
31262 } else {
31263 self.write_space();
31264 }
31265 self.write_keyword("ON");
31266 self.write_space();
31267 self.generate_expression(on)?;
31268 }
31269 if let Some(using_cond) = &e.using_cond {
31271 self.write_space();
31272 self.write_keyword("USING");
31273 self.write_space();
31274 self.write("(");
31275 if let Expression::Tuple(tuple) = using_cond.as_ref() {
31277 for (i, col) in tuple.expressions.iter().enumerate() {
31278 if i > 0 {
31279 self.write(", ");
31280 }
31281 self.generate_expression(col)?;
31282 }
31283 } else {
31284 self.generate_expression(using_cond)?;
31285 }
31286 self.write(")");
31287 }
31288 let saved_merge_strip = std::mem::take(&mut self.merge_strip_qualifiers);
31290 if matches!(
31291 self.config.dialect,
31292 Some(crate::DialectType::PostgreSQL)
31293 | Some(crate::DialectType::Redshift)
31294 | Some(crate::DialectType::Trino)
31295 | Some(crate::DialectType::Presto)
31296 | Some(crate::DialectType::Athena)
31297 ) {
31298 let mut names = Vec::new();
31299 match e.this.as_ref() {
31300 Expression::Alias(a) => {
31301 if let Expression::Table(t) = &a.this {
31303 names.push(t.name.name.clone());
31304 } else if let Expression::Identifier(id) = &a.this {
31305 names.push(id.name.clone());
31306 }
31307 names.push(a.alias.name.clone());
31308 }
31309 Expression::Table(t) => {
31310 names.push(t.name.name.clone());
31311 }
31312 Expression::Identifier(id) => {
31313 names.push(id.name.clone());
31314 }
31315 _ => {}
31316 }
31317 self.merge_strip_qualifiers = names;
31318 }
31319
31320 if let Some(whens) = &e.whens {
31322 if self.config.pretty {
31323 self.write_newline();
31324 self.write_indent();
31325 } else {
31326 self.write_space();
31327 }
31328 self.generate_expression(whens)?;
31329 }
31330
31331 self.merge_strip_qualifiers = saved_merge_strip;
31333
31334 if let Some(returning) = &e.returning {
31336 if self.config.pretty {
31337 self.write_newline();
31338 self.write_indent();
31339 } else {
31340 self.write_space();
31341 }
31342 self.generate_expression(returning)?;
31343 }
31344 Ok(())
31345 }
31346
31347 fn generate_merge_block_ratio_property(&mut self, e: &MergeBlockRatioProperty) -> Result<()> {
31348 if e.no.is_some() {
31350 self.write_keyword("NO MERGEBLOCKRATIO");
31351 } else if e.default.is_some() {
31352 self.write_keyword("DEFAULT MERGEBLOCKRATIO");
31353 } else {
31354 self.write_keyword("MERGEBLOCKRATIO");
31355 self.write("=");
31356 if let Some(this) = &e.this {
31357 self.generate_expression(this)?;
31358 }
31359 if e.percent.is_some() {
31360 self.write_keyword(" PERCENT");
31361 }
31362 }
31363 Ok(())
31364 }
31365
31366 fn generate_merge_tree_ttl(&mut self, e: &MergeTreeTTL) -> Result<()> {
31367 self.write_keyword("TTL");
31369 let pretty_clickhouse = self.config.pretty
31370 && matches!(
31371 self.config.dialect,
31372 Some(crate::dialects::DialectType::ClickHouse)
31373 );
31374
31375 if pretty_clickhouse {
31376 self.write_newline();
31377 self.indent_level += 1;
31378 for (i, expr) in e.expressions.iter().enumerate() {
31379 if i > 0 {
31380 self.write(",");
31381 self.write_newline();
31382 }
31383 self.write_indent();
31384 self.generate_expression(expr)?;
31385 }
31386 self.indent_level -= 1;
31387 } else {
31388 self.write_space();
31389 for (i, expr) in e.expressions.iter().enumerate() {
31390 if i > 0 {
31391 self.write(", ");
31392 }
31393 self.generate_expression(expr)?;
31394 }
31395 }
31396
31397 if let Some(where_) = &e.where_ {
31398 if pretty_clickhouse {
31399 self.write_newline();
31400 if let Expression::Where(w) = where_.as_ref() {
31401 self.write_indent();
31402 self.write_keyword("WHERE");
31403 self.write_newline();
31404 self.indent_level += 1;
31405 self.write_indent();
31406 self.generate_expression(&w.this)?;
31407 self.indent_level -= 1;
31408 } else {
31409 self.write_indent();
31410 self.generate_expression(where_)?;
31411 }
31412 } else {
31413 self.write_space();
31414 self.generate_expression(where_)?;
31415 }
31416 }
31417 if let Some(group) = &e.group {
31418 if pretty_clickhouse {
31419 self.write_newline();
31420 if let Expression::Group(g) = group.as_ref() {
31421 self.write_indent();
31422 self.write_keyword("GROUP BY");
31423 self.write_newline();
31424 self.indent_level += 1;
31425 for (i, expr) in g.expressions.iter().enumerate() {
31426 if i > 0 {
31427 self.write(",");
31428 self.write_newline();
31429 }
31430 self.write_indent();
31431 self.generate_expression(expr)?;
31432 }
31433 self.indent_level -= 1;
31434 } else {
31435 self.write_indent();
31436 self.generate_expression(group)?;
31437 }
31438 } else {
31439 self.write_space();
31440 self.generate_expression(group)?;
31441 }
31442 }
31443 if let Some(aggregates) = &e.aggregates {
31444 if pretty_clickhouse {
31445 self.write_newline();
31446 self.write_indent();
31447 self.write_keyword("SET");
31448 self.write_newline();
31449 self.indent_level += 1;
31450 if let Expression::Tuple(t) = aggregates.as_ref() {
31451 for (i, agg) in t.expressions.iter().enumerate() {
31452 if i > 0 {
31453 self.write(",");
31454 self.write_newline();
31455 }
31456 self.write_indent();
31457 self.generate_expression(agg)?;
31458 }
31459 } else {
31460 self.write_indent();
31461 self.generate_expression(aggregates)?;
31462 }
31463 self.indent_level -= 1;
31464 } else {
31465 self.write_space();
31466 self.write_keyword("SET");
31467 self.write_space();
31468 self.generate_expression(aggregates)?;
31469 }
31470 }
31471 Ok(())
31472 }
31473
31474 fn generate_merge_tree_ttl_action(&mut self, e: &MergeTreeTTLAction) -> Result<()> {
31475 self.generate_expression(&e.this)?;
31477 if e.delete.is_some() {
31478 self.write_keyword(" DELETE");
31479 }
31480 if let Some(recompress) = &e.recompress {
31481 self.write_keyword(" RECOMPRESS ");
31482 self.generate_expression(recompress)?;
31483 }
31484 if let Some(to_disk) = &e.to_disk {
31485 self.write_keyword(" TO DISK ");
31486 self.generate_expression(to_disk)?;
31487 }
31488 if let Some(to_volume) = &e.to_volume {
31489 self.write_keyword(" TO VOLUME ");
31490 self.generate_expression(to_volume)?;
31491 }
31492 Ok(())
31493 }
31494
31495 fn generate_minhash(&mut self, e: &Minhash) -> Result<()> {
31496 self.write_keyword("MINHASH");
31498 self.write("(");
31499 self.generate_expression(&e.this)?;
31500 for expr in &e.expressions {
31501 self.write(", ");
31502 self.generate_expression(expr)?;
31503 }
31504 self.write(")");
31505 Ok(())
31506 }
31507
31508 fn generate_model_attribute(&mut self, e: &ModelAttribute) -> Result<()> {
31509 self.generate_expression(&e.this)?;
31511 self.write("!");
31512 self.generate_expression(&e.expression)?;
31513 Ok(())
31514 }
31515
31516 fn generate_monthname(&mut self, e: &Monthname) -> Result<()> {
31517 self.write_keyword("MONTHNAME");
31519 self.write("(");
31520 self.generate_expression(&e.this)?;
31521 self.write(")");
31522 Ok(())
31523 }
31524
31525 fn generate_multitable_inserts(&mut self, e: &MultitableInserts) -> Result<()> {
31526 for comment in &e.leading_comments {
31528 self.write_formatted_comment(comment);
31529 if self.config.pretty {
31530 self.write_newline();
31531 self.write_indent();
31532 } else {
31533 self.write_space();
31534 }
31535 }
31536 self.write_keyword("INSERT");
31538 if e.overwrite {
31539 self.write_space();
31540 self.write_keyword("OVERWRITE");
31541 }
31542 self.write_space();
31543 self.write(&e.kind);
31544 if self.config.pretty {
31545 self.indent_level += 1;
31546 for expr in &e.expressions {
31547 self.write_newline();
31548 self.write_indent();
31549 self.generate_expression(expr)?;
31550 }
31551 self.indent_level -= 1;
31552 } else {
31553 for expr in &e.expressions {
31554 self.write_space();
31555 self.generate_expression(expr)?;
31556 }
31557 }
31558 if let Some(source) = &e.source {
31559 if self.config.pretty {
31560 self.write_newline();
31561 self.write_indent();
31562 } else {
31563 self.write_space();
31564 }
31565 self.generate_expression(source)?;
31566 }
31567 Ok(())
31568 }
31569
31570 fn generate_next_value_for(&mut self, e: &NextValueFor) -> Result<()> {
31571 self.write_keyword("NEXT VALUE FOR");
31573 self.write_space();
31574 self.generate_expression(&e.this)?;
31575 if let Some(order) = &e.order {
31576 self.write_space();
31577 self.write_keyword("OVER");
31578 self.write(" (");
31579 self.generate_expression(order)?;
31580 self.write(")");
31581 }
31582 Ok(())
31583 }
31584
31585 fn generate_normal(&mut self, e: &Normal) -> Result<()> {
31586 self.write_keyword("NORMAL");
31588 self.write("(");
31589 self.generate_expression(&e.this)?;
31590 if let Some(stddev) = &e.stddev {
31591 self.write(", ");
31592 self.generate_expression(stddev)?;
31593 }
31594 if let Some(gen) = &e.gen {
31595 self.write(", ");
31596 self.generate_expression(gen)?;
31597 }
31598 self.write(")");
31599 Ok(())
31600 }
31601
31602 fn generate_normalize(&mut self, e: &Normalize) -> Result<()> {
31603 if e.is_casefold.is_some() {
31605 self.write_keyword("NORMALIZE_AND_CASEFOLD");
31606 } else {
31607 self.write_keyword("NORMALIZE");
31608 }
31609 self.write("(");
31610 self.generate_expression(&e.this)?;
31611 if let Some(form) = &e.form {
31612 self.write(", ");
31613 self.generate_expression(form)?;
31614 }
31615 self.write(")");
31616 Ok(())
31617 }
31618
31619 fn generate_not_null_column_constraint(&mut self, e: &NotNullColumnConstraint) -> Result<()> {
31620 if e.allow_null.is_none() {
31622 self.write_keyword("NOT ");
31623 }
31624 self.write_keyword("NULL");
31625 Ok(())
31626 }
31627
31628 fn generate_nullif(&mut self, e: &Nullif) -> Result<()> {
31629 self.write_keyword("NULLIF");
31631 self.write("(");
31632 self.generate_expression(&e.this)?;
31633 self.write(", ");
31634 self.generate_expression(&e.expression)?;
31635 self.write(")");
31636 Ok(())
31637 }
31638
31639 fn generate_number_to_str(&mut self, e: &NumberToStr) -> Result<()> {
31640 self.write_keyword("FORMAT");
31642 self.write("(");
31643 self.generate_expression(&e.this)?;
31644 self.write(", '");
31645 self.write(&e.format);
31646 self.write("'");
31647 if let Some(culture) = &e.culture {
31648 self.write(", ");
31649 self.generate_expression(culture)?;
31650 }
31651 self.write(")");
31652 Ok(())
31653 }
31654
31655 fn generate_object_agg(&mut self, e: &ObjectAgg) -> Result<()> {
31656 self.write_keyword("OBJECT_AGG");
31658 self.write("(");
31659 self.generate_expression(&e.this)?;
31660 self.write(", ");
31661 self.generate_expression(&e.expression)?;
31662 self.write(")");
31663 Ok(())
31664 }
31665
31666 fn generate_object_identifier(&mut self, e: &ObjectIdentifier) -> Result<()> {
31667 self.generate_expression(&e.this)?;
31669 Ok(())
31670 }
31671
31672 fn generate_object_insert(&mut self, e: &ObjectInsert) -> Result<()> {
31673 self.write_keyword("OBJECT_INSERT");
31675 self.write("(");
31676 self.generate_expression(&e.this)?;
31677 if let Some(key) = &e.key {
31678 self.write(", ");
31679 self.generate_expression(key)?;
31680 }
31681 if let Some(value) = &e.value {
31682 self.write(", ");
31683 self.generate_expression(value)?;
31684 }
31685 if let Some(update_flag) = &e.update_flag {
31686 self.write(", ");
31687 self.generate_expression(update_flag)?;
31688 }
31689 self.write(")");
31690 Ok(())
31691 }
31692
31693 fn generate_offset(&mut self, e: &Offset) -> Result<()> {
31694 self.write_keyword("OFFSET");
31696 self.write_space();
31697 self.generate_expression(&e.this)?;
31698 if e.rows == Some(true)
31700 && matches!(
31701 self.config.dialect,
31702 Some(crate::dialects::DialectType::TSQL)
31703 | Some(crate::dialects::DialectType::Oracle)
31704 )
31705 {
31706 self.write_space();
31707 self.write_keyword("ROWS");
31708 }
31709 Ok(())
31710 }
31711
31712 fn generate_qualify(&mut self, e: &Qualify) -> Result<()> {
31713 self.write_keyword("QUALIFY");
31715 self.write_space();
31716 self.generate_expression(&e.this)?;
31717 Ok(())
31718 }
31719
31720 fn generate_on_cluster(&mut self, e: &OnCluster) -> Result<()> {
31721 self.write_keyword("ON CLUSTER");
31723 self.write_space();
31724 self.generate_expression(&e.this)?;
31725 Ok(())
31726 }
31727
31728 fn generate_on_commit_property(&mut self, e: &OnCommitProperty) -> Result<()> {
31729 self.write_keyword("ON COMMIT");
31731 if e.delete.is_some() {
31732 self.write_keyword(" DELETE ROWS");
31733 } else {
31734 self.write_keyword(" PRESERVE ROWS");
31735 }
31736 Ok(())
31737 }
31738
31739 fn generate_on_condition(&mut self, e: &OnCondition) -> Result<()> {
31740 if let Some(empty) = &e.empty {
31742 self.generate_expression(empty)?;
31743 self.write_keyword(" ON EMPTY");
31744 }
31745 if let Some(error) = &e.error {
31746 if e.empty.is_some() {
31747 self.write_space();
31748 }
31749 self.generate_expression(error)?;
31750 self.write_keyword(" ON ERROR");
31751 }
31752 if let Some(null) = &e.null {
31753 if e.empty.is_some() || e.error.is_some() {
31754 self.write_space();
31755 }
31756 self.generate_expression(null)?;
31757 self.write_keyword(" ON NULL");
31758 }
31759 Ok(())
31760 }
31761
31762 fn generate_on_conflict(&mut self, e: &OnConflict) -> Result<()> {
31763 if matches!(self.config.dialect, Some(DialectType::Materialize)) {
31765 return Ok(());
31766 }
31767 if e.duplicate.is_some() {
31769 self.write_keyword("ON DUPLICATE KEY UPDATE");
31771 for (i, expr) in e.expressions.iter().enumerate() {
31772 if i > 0 {
31773 self.write(",");
31774 }
31775 self.write_space();
31776 self.generate_expression(expr)?;
31777 }
31778 return Ok(());
31779 } else {
31780 self.write_keyword("ON CONFLICT");
31781 }
31782 if let Some(constraint) = &e.constraint {
31783 self.write_keyword(" ON CONSTRAINT ");
31784 self.generate_expression(constraint)?;
31785 }
31786 if let Some(conflict_keys) = &e.conflict_keys {
31787 if let Expression::Tuple(t) = conflict_keys.as_ref() {
31789 self.write("(");
31790 for (i, expr) in t.expressions.iter().enumerate() {
31791 if i > 0 {
31792 self.write(", ");
31793 }
31794 self.generate_expression(expr)?;
31795 }
31796 self.write(")");
31797 } else {
31798 self.write("(");
31799 self.generate_expression(conflict_keys)?;
31800 self.write(")");
31801 }
31802 }
31803 if let Some(index_predicate) = &e.index_predicate {
31804 self.write_keyword(" WHERE ");
31805 self.generate_expression(index_predicate)?;
31806 }
31807 if let Some(action) = &e.action {
31808 if let Expression::Identifier(id) = action.as_ref() {
31810 if id.name.eq_ignore_ascii_case("NOTHING") {
31811 self.write_keyword(" DO NOTHING");
31812 } else {
31813 self.write_keyword(" DO ");
31814 self.generate_expression(action)?;
31815 }
31816 } else if let Expression::Tuple(t) = action.as_ref() {
31817 self.write_keyword(" DO UPDATE SET ");
31819 for (i, expr) in t.expressions.iter().enumerate() {
31820 if i > 0 {
31821 self.write(", ");
31822 }
31823 self.generate_expression(expr)?;
31824 }
31825 } else {
31826 self.write_keyword(" DO ");
31827 self.generate_expression(action)?;
31828 }
31829 }
31830 if let Some(where_) = &e.where_ {
31832 self.write_keyword(" WHERE ");
31833 self.generate_expression(where_)?;
31834 }
31835 Ok(())
31836 }
31837
31838 fn generate_on_property(&mut self, e: &OnProperty) -> Result<()> {
31839 self.write_keyword("ON");
31841 self.write_space();
31842 self.generate_expression(&e.this)?;
31843 Ok(())
31844 }
31845
31846 fn generate_opclass(&mut self, e: &Opclass) -> Result<()> {
31847 self.generate_expression(&e.this)?;
31849 self.write_space();
31850 self.generate_expression(&e.expression)?;
31851 Ok(())
31852 }
31853
31854 fn generate_open_json(&mut self, e: &OpenJSON) -> Result<()> {
31855 self.write_keyword("OPENJSON");
31857 self.write("(");
31858 self.generate_expression(&e.this)?;
31859 if let Some(path) = &e.path {
31860 self.write(", ");
31861 self.generate_expression(path)?;
31862 }
31863 self.write(")");
31864 if !e.expressions.is_empty() {
31865 self.write_keyword(" WITH");
31866 if self.config.pretty {
31867 self.write(" (\n");
31868 self.indent_level += 2;
31869 for (i, expr) in e.expressions.iter().enumerate() {
31870 if i > 0 {
31871 self.write(",\n");
31872 }
31873 self.write_indent();
31874 self.generate_expression(expr)?;
31875 }
31876 self.write("\n");
31877 self.indent_level -= 2;
31878 self.write(")");
31879 } else {
31880 self.write(" (");
31881 for (i, expr) in e.expressions.iter().enumerate() {
31882 if i > 0 {
31883 self.write(", ");
31884 }
31885 self.generate_expression(expr)?;
31886 }
31887 self.write(")");
31888 }
31889 }
31890 Ok(())
31891 }
31892
31893 fn generate_open_json_column_def(&mut self, e: &OpenJSONColumnDef) -> Result<()> {
31894 self.generate_expression(&e.this)?;
31896 self.write_space();
31897 if let Some(ref dt) = e.data_type {
31899 self.generate_data_type(dt)?;
31900 } else if !e.kind.is_empty() {
31901 self.write(&e.kind);
31902 }
31903 if let Some(path) = &e.path {
31904 self.write_space();
31905 self.generate_expression(path)?;
31906 }
31907 if e.as_json.is_some() {
31908 self.write_keyword(" AS JSON");
31909 }
31910 Ok(())
31911 }
31912
31913 fn generate_operator(&mut self, e: &Operator) -> Result<()> {
31914 self.generate_expression(&e.this)?;
31916 self.write_space();
31917 if let Some(op) = &e.operator {
31918 self.write_keyword("OPERATOR");
31919 self.write("(");
31920 self.generate_expression(op)?;
31921 self.write(")");
31922 }
31923 for comment in &e.comments {
31925 self.write_space();
31926 self.write_formatted_comment(comment);
31927 }
31928 self.write_space();
31929 self.generate_expression(&e.expression)?;
31930 Ok(())
31931 }
31932
31933 fn generate_order_by(&mut self, e: &OrderBy) -> Result<()> {
31934 self.write_keyword("ORDER BY");
31936 let pretty_clickhouse_single_paren = self.config.pretty
31937 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
31938 && e.expressions.len() == 1
31939 && matches!(e.expressions[0].this, Expression::Paren(ref p) if !matches!(p.this, Expression::Tuple(_)));
31940 let clickhouse_single_tuple = matches!(self.config.dialect, Some(DialectType::ClickHouse))
31941 && e.expressions.len() == 1
31942 && matches!(e.expressions[0].this, Expression::Tuple(_))
31943 && !e.expressions[0].desc
31944 && e.expressions[0].nulls_first.is_none();
31945
31946 if pretty_clickhouse_single_paren {
31947 self.write_space();
31948 if let Expression::Paren(p) = &e.expressions[0].this {
31949 self.write("(");
31950 self.write_newline();
31951 self.indent_level += 1;
31952 self.write_indent();
31953 self.generate_expression(&p.this)?;
31954 self.indent_level -= 1;
31955 self.write_newline();
31956 self.write(")");
31957 }
31958 return Ok(());
31959 }
31960
31961 if clickhouse_single_tuple {
31962 self.write_space();
31963 if let Expression::Tuple(t) = &e.expressions[0].this {
31964 self.write("(");
31965 for (i, expr) in t.expressions.iter().enumerate() {
31966 if i > 0 {
31967 self.write(", ");
31968 }
31969 self.generate_expression(expr)?;
31970 }
31971 self.write(")");
31972 }
31973 return Ok(());
31974 }
31975
31976 self.write_space();
31977 for (i, ordered) in e.expressions.iter().enumerate() {
31978 if i > 0 {
31979 self.write(", ");
31980 }
31981 self.generate_expression(&ordered.this)?;
31982 if ordered.desc {
31983 self.write_space();
31984 self.write_keyword("DESC");
31985 } else if ordered.explicit_asc {
31986 self.write_space();
31987 self.write_keyword("ASC");
31988 }
31989 if let Some(nulls_first) = ordered.nulls_first {
31990 let skip_nulls_last =
31992 !nulls_first && matches!(self.config.dialect, Some(DialectType::Dremio));
31993 if !skip_nulls_last {
31994 self.write_space();
31995 self.write_keyword("NULLS");
31996 self.write_space();
31997 if nulls_first {
31998 self.write_keyword("FIRST");
31999 } else {
32000 self.write_keyword("LAST");
32001 }
32002 }
32003 }
32004 }
32005 Ok(())
32006 }
32007
32008 fn generate_output_model_property(&mut self, e: &OutputModelProperty) -> Result<()> {
32009 self.write_keyword("OUTPUT");
32011 self.write("(");
32012 if self.config.pretty {
32013 self.indent_level += 1;
32014 self.write_newline();
32015 self.write_indent();
32016 self.generate_expression(&e.this)?;
32017 self.indent_level -= 1;
32018 self.write_newline();
32019 } else {
32020 self.generate_expression(&e.this)?;
32021 }
32022 self.write(")");
32023 Ok(())
32024 }
32025
32026 fn generate_overflow_truncate_behavior(&mut self, e: &OverflowTruncateBehavior) -> Result<()> {
32027 self.write_keyword("TRUNCATE");
32029 if let Some(this) = &e.this {
32030 self.write_space();
32031 self.generate_expression(this)?;
32032 }
32033 if e.with_count.is_some() {
32034 self.write_keyword(" WITH COUNT");
32035 } else {
32036 self.write_keyword(" WITHOUT COUNT");
32037 }
32038 Ok(())
32039 }
32040
32041 fn generate_parameterized_agg(&mut self, e: &ParameterizedAgg) -> Result<()> {
32042 self.generate_expression(&e.this)?;
32044 self.write("(");
32045 for (i, expr) in e.expressions.iter().enumerate() {
32046 if i > 0 {
32047 self.write(", ");
32048 }
32049 self.generate_expression(expr)?;
32050 }
32051 self.write(")(");
32052 for (i, param) in e.params.iter().enumerate() {
32053 if i > 0 {
32054 self.write(", ");
32055 }
32056 self.generate_expression(param)?;
32057 }
32058 self.write(")");
32059 Ok(())
32060 }
32061
32062 fn generate_parse_datetime(&mut self, e: &ParseDatetime) -> Result<()> {
32063 self.write_keyword("PARSE_DATETIME");
32065 self.write("(");
32066 if let Some(format) = &e.format {
32067 self.write("'");
32068 self.write(format);
32069 self.write("', ");
32070 }
32071 self.generate_expression(&e.this)?;
32072 if let Some(zone) = &e.zone {
32073 self.write(", ");
32074 self.generate_expression(zone)?;
32075 }
32076 self.write(")");
32077 Ok(())
32078 }
32079
32080 fn generate_parse_ip(&mut self, e: &ParseIp) -> Result<()> {
32081 self.write_keyword("PARSE_IP");
32083 self.write("(");
32084 self.generate_expression(&e.this)?;
32085 if let Some(type_) = &e.type_ {
32086 self.write(", ");
32087 self.generate_expression(type_)?;
32088 }
32089 if let Some(permissive) = &e.permissive {
32090 self.write(", ");
32091 self.generate_expression(permissive)?;
32092 }
32093 self.write(")");
32094 Ok(())
32095 }
32096
32097 fn generate_parse_json(&mut self, e: &ParseJSON) -> Result<()> {
32098 self.write_keyword("PARSE_JSON");
32100 self.write("(");
32101 self.generate_expression(&e.this)?;
32102 if let Some(expression) = &e.expression {
32103 self.write(", ");
32104 self.generate_expression(expression)?;
32105 }
32106 self.write(")");
32107 Ok(())
32108 }
32109
32110 fn generate_parse_time(&mut self, e: &ParseTime) -> Result<()> {
32111 self.write_keyword("PARSE_TIME");
32113 self.write("(");
32114 self.write(&format!("'{}'", e.format));
32115 self.write(", ");
32116 self.generate_expression(&e.this)?;
32117 self.write(")");
32118 Ok(())
32119 }
32120
32121 fn generate_parse_url(&mut self, e: &ParseUrl) -> Result<()> {
32122 self.write_keyword("PARSE_URL");
32124 self.write("(");
32125 self.generate_expression(&e.this)?;
32126 if let Some(part) = &e.part_to_extract {
32127 self.write(", ");
32128 self.generate_expression(part)?;
32129 }
32130 if let Some(key) = &e.key {
32131 self.write(", ");
32132 self.generate_expression(key)?;
32133 }
32134 if let Some(permissive) = &e.permissive {
32135 self.write(", ");
32136 self.generate_expression(permissive)?;
32137 }
32138 self.write(")");
32139 Ok(())
32140 }
32141
32142 fn generate_partition_expr(&mut self, e: &Partition) -> Result<()> {
32143 if e.subpartition {
32145 self.write_keyword("SUBPARTITION");
32146 } else {
32147 self.write_keyword("PARTITION");
32148 }
32149 self.write("(");
32150 for (i, expr) in e.expressions.iter().enumerate() {
32151 if i > 0 {
32152 self.write(", ");
32153 }
32154 self.generate_expression(expr)?;
32155 }
32156 self.write(")");
32157 Ok(())
32158 }
32159
32160 fn generate_partition_bound_spec(&mut self, e: &PartitionBoundSpec) -> Result<()> {
32161 if let Some(this) = &e.this {
32163 if let Some(expression) = &e.expression {
32164 self.write_keyword("WITH");
32166 self.write(" (");
32167 self.write_keyword("MODULUS");
32168 self.write_space();
32169 self.generate_expression(this)?;
32170 self.write(", ");
32171 self.write_keyword("REMAINDER");
32172 self.write_space();
32173 self.generate_expression(expression)?;
32174 self.write(")");
32175 } else {
32176 self.write_keyword("IN");
32178 self.write(" (");
32179 self.generate_partition_bound_values(this)?;
32180 self.write(")");
32181 }
32182 } else if let (Some(from), Some(to)) = (&e.from_expressions, &e.to_expressions) {
32183 self.write_keyword("FROM");
32185 self.write(" (");
32186 self.generate_partition_bound_values(from)?;
32187 self.write(") ");
32188 self.write_keyword("TO");
32189 self.write(" (");
32190 self.generate_partition_bound_values(to)?;
32191 self.write(")");
32192 }
32193 Ok(())
32194 }
32195
32196 fn generate_partition_bound_values(&mut self, expr: &Expression) -> Result<()> {
32199 if let Expression::Tuple(t) = expr {
32200 for (i, e) in t.expressions.iter().enumerate() {
32201 if i > 0 {
32202 self.write(", ");
32203 }
32204 self.generate_expression(e)?;
32205 }
32206 Ok(())
32207 } else {
32208 self.generate_expression(expr)
32209 }
32210 }
32211
32212 fn generate_partition_by_list_property(&mut self, e: &PartitionByListProperty) -> Result<()> {
32213 self.write_keyword("PARTITION BY LIST");
32215 if let Some(partition_exprs) = &e.partition_expressions {
32216 self.write(" (");
32217 self.generate_doris_partition_expressions(partition_exprs)?;
32219 self.write(")");
32220 }
32221 if let Some(create_exprs) = &e.create_expressions {
32222 self.write(" (");
32223 self.generate_doris_partition_definitions(create_exprs)?;
32225 self.write(")");
32226 }
32227 Ok(())
32228 }
32229
32230 fn generate_partition_by_range_property(&mut self, e: &PartitionByRangeProperty) -> Result<()> {
32231 self.write_keyword("PARTITION BY RANGE");
32233 if let Some(partition_exprs) = &e.partition_expressions {
32234 self.write(" (");
32235 self.generate_doris_partition_expressions(partition_exprs)?;
32237 self.write(")");
32238 }
32239 if let Some(create_exprs) = &e.create_expressions {
32240 self.write(" (");
32241 self.generate_doris_partition_definitions(create_exprs)?;
32243 self.write(")");
32244 }
32245 Ok(())
32246 }
32247
32248 fn generate_doris_partition_expressions(&mut self, expr: &Expression) -> Result<()> {
32250 if let Expression::Tuple(t) = expr {
32251 for (i, e) in t.expressions.iter().enumerate() {
32252 if i > 0 {
32253 self.write(", ");
32254 }
32255 self.generate_expression(e)?;
32256 }
32257 } else {
32258 self.generate_expression(expr)?;
32259 }
32260 Ok(())
32261 }
32262
32263 fn generate_doris_partition_definitions(&mut self, expr: &Expression) -> Result<()> {
32265 match expr {
32266 Expression::Tuple(t) => {
32267 for (i, part) in t.expressions.iter().enumerate() {
32269 if i > 0 {
32270 self.write(", ");
32271 }
32272 if let Expression::Partition(p) = part {
32274 for (j, inner) in p.expressions.iter().enumerate() {
32275 if j > 0 {
32276 self.write(", ");
32277 }
32278 self.generate_expression(inner)?;
32279 }
32280 } else {
32281 self.generate_expression(part)?;
32282 }
32283 }
32284 }
32285 Expression::PartitionByRangePropertyDynamic(_) => {
32286 self.generate_expression(expr)?;
32288 }
32289 _ => {
32290 self.generate_expression(expr)?;
32291 }
32292 }
32293 Ok(())
32294 }
32295
32296 fn generate_partition_by_range_property_dynamic(
32297 &mut self,
32298 e: &PartitionByRangePropertyDynamic,
32299 ) -> Result<()> {
32300 if e.use_start_end {
32301 if let Some(start) = &e.start {
32303 self.write_keyword("START");
32304 self.write(" (");
32305 self.generate_expression(start)?;
32306 self.write(")");
32307 }
32308 if let Some(end) = &e.end {
32309 self.write_space();
32310 self.write_keyword("END");
32311 self.write(" (");
32312 self.generate_expression(end)?;
32313 self.write(")");
32314 }
32315 if let Some(every) = &e.every {
32316 self.write_space();
32317 self.write_keyword("EVERY");
32318 self.write(" (");
32319 self.generate_doris_interval(every)?;
32321 self.write(")");
32322 }
32323 } else {
32324 if let Some(start) = &e.start {
32326 self.write_keyword("FROM");
32327 self.write(" (");
32328 self.generate_expression(start)?;
32329 self.write(")");
32330 }
32331 if let Some(end) = &e.end {
32332 self.write_space();
32333 self.write_keyword("TO");
32334 self.write(" (");
32335 self.generate_expression(end)?;
32336 self.write(")");
32337 }
32338 if let Some(every) = &e.every {
32339 self.write_space();
32340 self.generate_doris_interval(every)?;
32342 }
32343 }
32344 Ok(())
32345 }
32346
32347 fn generate_doris_interval(&mut self, expr: &Expression) -> Result<()> {
32349 if let Expression::Interval(interval) = expr {
32350 self.write_keyword("INTERVAL");
32351 if let Some(ref value) = interval.this {
32352 self.write_space();
32353 match value {
32357 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(s) if s.chars().all(|c| c.is_ascii_digit() || c == '.' || c == '-') && !s.is_empty()) => {
32358 if let Literal::String(s) = lit.as_ref() {
32359 self.write(s);
32360 }
32361 }
32362 _ => {
32363 self.generate_expression(value)?;
32364 }
32365 }
32366 }
32367 if let Some(ref unit_spec) = interval.unit {
32368 self.write_space();
32369 self.write_interval_unit_spec(unit_spec)?;
32370 }
32371 Ok(())
32372 } else {
32373 self.generate_expression(expr)
32374 }
32375 }
32376
32377 fn generate_partition_by_truncate(&mut self, e: &PartitionByTruncate) -> Result<()> {
32378 self.write_keyword("TRUNCATE");
32380 self.write("(");
32381 self.generate_expression(&e.expression)?;
32382 self.write(", ");
32383 self.generate_expression(&e.this)?;
32384 self.write(")");
32385 Ok(())
32386 }
32387
32388 fn generate_partition_list(&mut self, e: &PartitionList) -> Result<()> {
32389 self.write_keyword("PARTITION");
32391 self.write_space();
32392 self.generate_expression(&e.this)?;
32393 self.write_space();
32394 self.write_keyword("VALUES IN");
32395 self.write(" (");
32396 for (i, expr) in e.expressions.iter().enumerate() {
32397 if i > 0 {
32398 self.write(", ");
32399 }
32400 self.generate_expression(expr)?;
32401 }
32402 self.write(")");
32403 Ok(())
32404 }
32405
32406 fn generate_partition_range(&mut self, e: &PartitionRange) -> Result<()> {
32407 if e.expressions.is_empty() && e.expression.is_some() {
32410 self.generate_expression(&e.this)?;
32412 self.write_space();
32413 self.write_keyword("TO");
32414 self.write_space();
32415 self.generate_expression(e.expression.as_ref().unwrap())?;
32416 return Ok(());
32417 }
32418
32419 self.write_keyword("PARTITION");
32421 self.write_space();
32422 self.generate_expression(&e.this)?;
32423 self.write_space();
32424
32425 if e.expressions.len() == 1 {
32427 self.write_keyword("VALUES LESS THAN");
32429 self.write(" (");
32430 self.generate_expression(&e.expressions[0])?;
32431 self.write(")");
32432 } else if !e.expressions.is_empty() {
32433 self.write_keyword("VALUES");
32435 self.write(" [");
32436 for (i, expr) in e.expressions.iter().enumerate() {
32437 if i > 0 {
32438 self.write(", ");
32439 }
32440 if let Expression::Tuple(t) = expr {
32442 self.write("(");
32443 for (j, inner) in t.expressions.iter().enumerate() {
32444 if j > 0 {
32445 self.write(", ");
32446 }
32447 self.generate_expression(inner)?;
32448 }
32449 self.write(")");
32450 } else {
32451 self.write("(");
32452 self.generate_expression(expr)?;
32453 self.write(")");
32454 }
32455 }
32456 self.write(")");
32457 }
32458 Ok(())
32459 }
32460
32461 fn generate_partitioned_by_bucket(&mut self, e: &PartitionedByBucket) -> Result<()> {
32462 self.write_keyword("BUCKET");
32464 self.write("(");
32465 self.generate_expression(&e.this)?;
32466 self.write(", ");
32467 self.generate_expression(&e.expression)?;
32468 self.write(")");
32469 Ok(())
32470 }
32471
32472 fn generate_partition_by_property(&mut self, e: &PartitionByProperty) -> Result<()> {
32473 self.write_keyword("PARTITION BY");
32475 self.write_space();
32476 for (i, expr) in e.expressions.iter().enumerate() {
32477 if i > 0 {
32478 self.write(", ");
32479 }
32480 self.generate_expression(expr)?;
32481 }
32482 Ok(())
32483 }
32484
32485 fn generate_partitioned_by_property(&mut self, e: &PartitionedByProperty) -> Result<()> {
32486 if matches!(
32488 self.config.dialect,
32489 Some(crate::dialects::DialectType::Teradata)
32490 | Some(crate::dialects::DialectType::ClickHouse)
32491 ) {
32492 self.write_keyword("PARTITION BY");
32493 } else {
32494 self.write_keyword("PARTITIONED BY");
32495 }
32496 self.write_space();
32497 if self.config.pretty {
32499 if let Expression::Tuple(ref tuple) = *e.this {
32500 self.write("(");
32501 self.write_newline();
32502 self.indent_level += 1;
32503 for (i, expr) in tuple.expressions.iter().enumerate() {
32504 if i > 0 {
32505 self.write(",");
32506 self.write_newline();
32507 }
32508 self.write_indent();
32509 self.generate_expression(expr)?;
32510 }
32511 self.indent_level -= 1;
32512 self.write_newline();
32513 self.write(")");
32514 } else {
32515 self.generate_expression(&e.this)?;
32516 }
32517 } else {
32518 self.generate_expression(&e.this)?;
32519 }
32520 Ok(())
32521 }
32522
32523 fn generate_partitioned_of_property(&mut self, e: &PartitionedOfProperty) -> Result<()> {
32524 self.write_keyword("PARTITION OF");
32526 self.write_space();
32527 self.generate_expression(&e.this)?;
32528 if let Expression::PartitionBoundSpec(_) = e.expression.as_ref() {
32530 self.write_space();
32531 self.write_keyword("FOR VALUES");
32532 self.write_space();
32533 self.generate_expression(&e.expression)?;
32534 } else {
32535 self.write_space();
32536 self.write_keyword("DEFAULT");
32537 }
32538 Ok(())
32539 }
32540
32541 fn generate_period_for_system_time_constraint(
32542 &mut self,
32543 e: &PeriodForSystemTimeConstraint,
32544 ) -> Result<()> {
32545 self.write_keyword("PERIOD FOR SYSTEM_TIME");
32547 self.write(" (");
32548 self.generate_expression(&e.this)?;
32549 self.write(", ");
32550 self.generate_expression(&e.expression)?;
32551 self.write(")");
32552 Ok(())
32553 }
32554
32555 fn generate_pivot_alias(&mut self, e: &PivotAlias) -> Result<()> {
32556 self.generate_expression(&e.this)?;
32559 self.write_space();
32560 self.write_keyword("AS");
32561 self.write_space();
32562 if self.config.unpivot_aliases_are_identifiers {
32564 match &e.alias {
32565 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
32566 let Literal::String(s) = lit.as_ref() else {
32567 unreachable!()
32568 };
32569 self.generate_identifier(&Identifier::new(s.clone()))?;
32571 }
32572 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
32573 let Literal::Number(n) = lit.as_ref() else {
32574 unreachable!()
32575 };
32576 let mut id = Identifier::new(n.clone());
32578 id.quoted = true;
32579 self.generate_identifier(&id)?;
32580 }
32581 other => {
32582 self.generate_expression(other)?;
32583 }
32584 }
32585 } else {
32586 self.generate_expression(&e.alias)?;
32587 }
32588 Ok(())
32589 }
32590
32591 fn generate_pivot_any(&mut self, e: &PivotAny) -> Result<()> {
32592 self.write_keyword("ANY");
32594 if let Some(this) = &e.this {
32595 self.write_space();
32596 self.generate_expression(this)?;
32597 }
32598 Ok(())
32599 }
32600
32601 fn generate_predict(&mut self, e: &Predict) -> Result<()> {
32602 self.write_keyword("ML.PREDICT");
32604 self.write("(");
32605 self.write_keyword("MODEL");
32606 self.write_space();
32607 self.generate_expression(&e.this)?;
32608 self.write(", ");
32609 self.generate_expression(&e.expression)?;
32610 if let Some(params) = &e.params_struct {
32611 self.write(", ");
32612 self.generate_expression(params)?;
32613 }
32614 self.write(")");
32615 Ok(())
32616 }
32617
32618 fn generate_previous_day(&mut self, e: &PreviousDay) -> Result<()> {
32619 self.write_keyword("PREVIOUS_DAY");
32621 self.write("(");
32622 self.generate_expression(&e.this)?;
32623 self.write(", ");
32624 self.generate_expression(&e.expression)?;
32625 self.write(")");
32626 Ok(())
32627 }
32628
32629 fn generate_primary_key(&mut self, e: &PrimaryKey) -> Result<()> {
32630 self.write_keyword("PRIMARY KEY");
32632 if let Some(name) = &e.this {
32633 self.write_space();
32634 self.generate_expression(name)?;
32635 }
32636 if !e.expressions.is_empty() {
32637 self.write(" (");
32638 for (i, expr) in e.expressions.iter().enumerate() {
32639 if i > 0 {
32640 self.write(", ");
32641 }
32642 self.generate_expression(expr)?;
32643 }
32644 self.write(")");
32645 }
32646 if let Some(include) = &e.include {
32647 self.write_space();
32648 self.generate_expression(include)?;
32649 }
32650 if !e.options.is_empty() {
32651 self.write_space();
32652 for (i, opt) in e.options.iter().enumerate() {
32653 if i > 0 {
32654 self.write_space();
32655 }
32656 self.generate_expression(opt)?;
32657 }
32658 }
32659 Ok(())
32660 }
32661
32662 fn generate_primary_key_column_constraint(
32663 &mut self,
32664 _e: &PrimaryKeyColumnConstraint,
32665 ) -> Result<()> {
32666 self.write_keyword("PRIMARY KEY");
32668 Ok(())
32669 }
32670
32671 fn generate_path_column_constraint(&mut self, e: &PathColumnConstraint) -> Result<()> {
32672 self.write_keyword("PATH");
32674 self.write_space();
32675 self.generate_expression(&e.this)?;
32676 Ok(())
32677 }
32678
32679 fn generate_projection_def(&mut self, e: &ProjectionDef) -> Result<()> {
32680 self.write_keyword("PROJECTION");
32682 self.write_space();
32683 self.generate_expression(&e.this)?;
32684 self.write(" (");
32685 self.generate_expression(&e.expression)?;
32686 self.write(")");
32687 Ok(())
32688 }
32689
32690 fn generate_properties(&mut self, e: &Properties) -> Result<()> {
32691 for (i, prop) in e.expressions.iter().enumerate() {
32693 if i > 0 {
32694 self.write(", ");
32695 }
32696 self.generate_expression(prop)?;
32697 }
32698 Ok(())
32699 }
32700
32701 fn generate_property(&mut self, e: &Property) -> Result<()> {
32702 self.generate_expression(&e.this)?;
32704 if let Some(value) = &e.value {
32705 self.write("=");
32706 self.generate_expression(value)?;
32707 }
32708 Ok(())
32709 }
32710
32711 fn generate_options_property(&mut self, e: &OptionsProperty) -> Result<()> {
32712 self.write_keyword("OPTIONS");
32713 if e.entries.is_empty() {
32714 self.write(" ()");
32715 return Ok(());
32716 }
32717
32718 if self.config.pretty {
32719 self.write(" (");
32720 self.write_newline();
32721 self.indent_level += 1;
32722 for (i, entry) in e.entries.iter().enumerate() {
32723 if i > 0 {
32724 self.write(",");
32725 self.write_newline();
32726 }
32727 self.write_indent();
32728 self.generate_identifier(&entry.key)?;
32729 self.write("=");
32730 self.generate_expression(&entry.value)?;
32731 }
32732 self.indent_level -= 1;
32733 self.write_newline();
32734 self.write(")");
32735 } else {
32736 self.write(" (");
32737 for (i, entry) in e.entries.iter().enumerate() {
32738 if i > 0 {
32739 self.write(", ");
32740 }
32741 self.generate_identifier(&entry.key)?;
32742 self.write("=");
32743 self.generate_expression(&entry.value)?;
32744 }
32745 self.write(")");
32746 }
32747 Ok(())
32748 }
32749
32750 fn generate_options_clause(&mut self, options: &[Expression]) -> Result<()> {
32752 self.write_keyword("OPTIONS");
32753 self.write(" (");
32754 for (i, opt) in options.iter().enumerate() {
32755 if i > 0 {
32756 self.write(", ");
32757 }
32758 self.generate_option_expression(opt)?;
32759 }
32760 self.write(")");
32761 Ok(())
32762 }
32763
32764 fn generate_properties_clause(&mut self, properties: &[Expression]) -> Result<()> {
32766 self.write_keyword("PROPERTIES");
32767 self.write(" (");
32768 for (i, prop) in properties.iter().enumerate() {
32769 if i > 0 {
32770 self.write(", ");
32771 }
32772 self.generate_option_expression(prop)?;
32773 }
32774 self.write(")");
32775 Ok(())
32776 }
32777
32778 fn generate_environment_clause(&mut self, environment: &[Expression]) -> Result<()> {
32780 self.write_keyword("ENVIRONMENT");
32781 self.write(" (");
32782 for (i, env_item) in environment.iter().enumerate() {
32783 if i > 0 {
32784 self.write(", ");
32785 }
32786 self.generate_environment_expression(env_item)?;
32787 }
32788 self.write(")");
32789 Ok(())
32790 }
32791
32792 fn generate_environment_expression(&mut self, expr: &Expression) -> Result<()> {
32794 match expr {
32795 Expression::Eq(eq) => {
32796 self.generate_expression(&eq.left)?;
32798 self.write(" = ");
32799 self.generate_expression(&eq.right)?;
32800 Ok(())
32801 }
32802 _ => self.generate_expression(expr),
32803 }
32804 }
32805
32806 fn generate_tblproperties_clause(&mut self, options: &[Expression]) -> Result<()> {
32808 self.write_keyword("TBLPROPERTIES");
32809 if self.config.pretty {
32810 self.write(" (");
32811 self.write_newline();
32812 self.indent_level += 1;
32813 for (i, opt) in options.iter().enumerate() {
32814 if i > 0 {
32815 self.write(",");
32816 self.write_newline();
32817 }
32818 self.write_indent();
32819 self.generate_option_expression(opt)?;
32820 }
32821 self.indent_level -= 1;
32822 self.write_newline();
32823 self.write(")");
32824 } else {
32825 self.write(" (");
32826 for (i, opt) in options.iter().enumerate() {
32827 if i > 0 {
32828 self.write(", ");
32829 }
32830 self.generate_option_expression(opt)?;
32831 }
32832 self.write(")");
32833 }
32834 Ok(())
32835 }
32836
32837 fn generate_option_expression(&mut self, expr: &Expression) -> Result<()> {
32839 match expr {
32840 Expression::Eq(eq) => {
32841 self.generate_expression(&eq.left)?;
32843 self.write("=");
32844 self.generate_expression(&eq.right)?;
32845 Ok(())
32846 }
32847 _ => self.generate_expression(expr),
32848 }
32849 }
32850
32851 fn generate_pseudo_type(&mut self, e: &PseudoType) -> Result<()> {
32852 self.generate_expression(&e.this)?;
32854 Ok(())
32855 }
32856
32857 fn generate_put(&mut self, e: &PutStmt) -> Result<()> {
32858 self.write_keyword("PUT");
32860 self.write_space();
32861
32862 if e.source_quoted {
32864 self.write("'");
32865 self.write(&e.source);
32866 self.write("'");
32867 } else {
32868 self.write(&e.source);
32869 }
32870
32871 self.write_space();
32872
32873 if let Expression::Literal(lit) = &e.target {
32875 if let Literal::String(s) = lit.as_ref() {
32876 self.write(s);
32877 }
32878 } else {
32879 self.generate_expression(&e.target)?;
32880 }
32881
32882 for param in &e.params {
32884 self.write_space();
32885 self.write(¶m.name);
32886 if let Some(ref value) = param.value {
32887 self.write("=");
32888 self.generate_expression(value)?;
32889 }
32890 }
32891
32892 Ok(())
32893 }
32894
32895 fn generate_quantile(&mut self, e: &Quantile) -> Result<()> {
32896 self.write_keyword("QUANTILE");
32898 self.write("(");
32899 self.generate_expression(&e.this)?;
32900 if let Some(quantile) = &e.quantile {
32901 self.write(", ");
32902 self.generate_expression(quantile)?;
32903 }
32904 self.write(")");
32905 Ok(())
32906 }
32907
32908 fn generate_query_band(&mut self, e: &QueryBand) -> Result<()> {
32909 if matches!(
32911 self.config.dialect,
32912 Some(crate::dialects::DialectType::Teradata)
32913 ) {
32914 self.write_keyword("SET");
32915 self.write_space();
32916 }
32917 self.write_keyword("QUERY_BAND");
32918 self.write(" = ");
32919 self.generate_expression(&e.this)?;
32920 if e.update.is_some() {
32921 self.write_space();
32922 self.write_keyword("UPDATE");
32923 }
32924 if let Some(scope) = &e.scope {
32925 self.write_space();
32926 self.write_keyword("FOR");
32927 self.write_space();
32928 self.generate_expression(scope)?;
32929 }
32930 Ok(())
32931 }
32932
32933 fn generate_query_option(&mut self, e: &QueryOption) -> Result<()> {
32934 self.generate_expression(&e.this)?;
32936 if let Some(expression) = &e.expression {
32937 self.write(" = ");
32938 self.generate_expression(expression)?;
32939 }
32940 Ok(())
32941 }
32942
32943 fn generate_query_transform(&mut self, e: &QueryTransform) -> Result<()> {
32944 self.write_keyword("TRANSFORM");
32946 self.write("(");
32947 for (i, expr) in e.expressions.iter().enumerate() {
32948 if i > 0 {
32949 self.write(", ");
32950 }
32951 self.generate_expression(expr)?;
32952 }
32953 self.write(")");
32954 if let Some(row_format_before) = &e.row_format_before {
32955 self.write_space();
32956 self.generate_expression(row_format_before)?;
32957 }
32958 if let Some(record_writer) = &e.record_writer {
32959 self.write_space();
32960 self.write_keyword("RECORDWRITER");
32961 self.write_space();
32962 self.generate_expression(record_writer)?;
32963 }
32964 if let Some(command_script) = &e.command_script {
32965 self.write_space();
32966 self.write_keyword("USING");
32967 self.write_space();
32968 self.generate_expression(command_script)?;
32969 }
32970 if let Some(schema) = &e.schema {
32971 self.write_space();
32972 self.write_keyword("AS");
32973 self.write_space();
32974 self.generate_expression(schema)?;
32975 }
32976 if let Some(row_format_after) = &e.row_format_after {
32977 self.write_space();
32978 self.generate_expression(row_format_after)?;
32979 }
32980 if let Some(record_reader) = &e.record_reader {
32981 self.write_space();
32982 self.write_keyword("RECORDREADER");
32983 self.write_space();
32984 self.generate_expression(record_reader)?;
32985 }
32986 Ok(())
32987 }
32988
32989 fn generate_randn(&mut self, e: &Randn) -> Result<()> {
32990 self.write_keyword("RANDN");
32992 self.write("(");
32993 if let Some(this) = &e.this {
32994 self.generate_expression(this)?;
32995 }
32996 self.write(")");
32997 Ok(())
32998 }
32999
33000 fn generate_randstr(&mut self, e: &Randstr) -> Result<()> {
33001 self.write_keyword("RANDSTR");
33003 self.write("(");
33004 self.generate_expression(&e.this)?;
33005 if let Some(generator) = &e.generator {
33006 self.write(", ");
33007 self.generate_expression(generator)?;
33008 }
33009 self.write(")");
33010 Ok(())
33011 }
33012
33013 fn generate_range_bucket(&mut self, e: &RangeBucket) -> Result<()> {
33014 self.write_keyword("RANGE_BUCKET");
33016 self.write("(");
33017 self.generate_expression(&e.this)?;
33018 self.write(", ");
33019 self.generate_expression(&e.expression)?;
33020 self.write(")");
33021 Ok(())
33022 }
33023
33024 fn generate_range_n(&mut self, e: &RangeN) -> Result<()> {
33025 self.write_keyword("RANGE_N");
33027 self.write("(");
33028 self.generate_expression(&e.this)?;
33029 self.write_space();
33030 self.write_keyword("BETWEEN");
33031 self.write_space();
33032 for (i, expr) in e.expressions.iter().enumerate() {
33033 if i > 0 {
33034 self.write(", ");
33035 }
33036 self.generate_expression(expr)?;
33037 }
33038 if let Some(each) = &e.each {
33039 self.write_space();
33040 self.write_keyword("EACH");
33041 self.write_space();
33042 self.generate_expression(each)?;
33043 }
33044 self.write(")");
33045 Ok(())
33046 }
33047
33048 fn generate_read_csv(&mut self, e: &ReadCSV) -> Result<()> {
33049 self.write_keyword("READ_CSV");
33051 self.write("(");
33052 self.generate_expression(&e.this)?;
33053 for expr in &e.expressions {
33054 self.write(", ");
33055 self.generate_expression(expr)?;
33056 }
33057 self.write(")");
33058 Ok(())
33059 }
33060
33061 fn generate_read_parquet(&mut self, e: &ReadParquet) -> Result<()> {
33062 self.write_keyword("READ_PARQUET");
33064 self.write("(");
33065 for (i, expr) in e.expressions.iter().enumerate() {
33066 if i > 0 {
33067 self.write(", ");
33068 }
33069 self.generate_expression(expr)?;
33070 }
33071 self.write(")");
33072 Ok(())
33073 }
33074
33075 fn generate_recursive_with_search(&mut self, e: &RecursiveWithSearch) -> Result<()> {
33076 if e.kind == "CYCLE" {
33079 self.write_keyword("CYCLE");
33080 } else {
33081 self.write_keyword("SEARCH");
33082 self.write_space();
33083 self.write(&e.kind);
33084 self.write_space();
33085 self.write_keyword("FIRST BY");
33086 }
33087 self.write_space();
33088 self.generate_expression(&e.this)?;
33089 self.write_space();
33090 self.write_keyword("SET");
33091 self.write_space();
33092 self.generate_expression(&e.expression)?;
33093 if let Some(using) = &e.using {
33094 self.write_space();
33095 self.write_keyword("USING");
33096 self.write_space();
33097 self.generate_expression(using)?;
33098 }
33099 Ok(())
33100 }
33101
33102 fn generate_reduce(&mut self, e: &Reduce) -> Result<()> {
33103 self.write_keyword("REDUCE");
33105 self.write("(");
33106 self.generate_expression(&e.this)?;
33107 if let Some(initial) = &e.initial {
33108 self.write(", ");
33109 self.generate_expression(initial)?;
33110 }
33111 if let Some(merge) = &e.merge {
33112 self.write(", ");
33113 self.generate_expression(merge)?;
33114 }
33115 if let Some(finish) = &e.finish {
33116 self.write(", ");
33117 self.generate_expression(finish)?;
33118 }
33119 self.write(")");
33120 Ok(())
33121 }
33122
33123 fn generate_reference(&mut self, e: &Reference) -> Result<()> {
33124 self.write_keyword("REFERENCES");
33126 self.write_space();
33127 self.generate_expression(&e.this)?;
33128 if !e.expressions.is_empty() {
33129 self.write(" (");
33130 for (i, expr) in e.expressions.iter().enumerate() {
33131 if i > 0 {
33132 self.write(", ");
33133 }
33134 self.generate_expression(expr)?;
33135 }
33136 self.write(")");
33137 }
33138 for opt in &e.options {
33139 self.write_space();
33140 self.generate_expression(opt)?;
33141 }
33142 Ok(())
33143 }
33144
33145 fn generate_refresh(&mut self, e: &Refresh) -> Result<()> {
33146 self.write_keyword("REFRESH");
33148 if !e.kind.is_empty() {
33149 self.write_space();
33150 self.write_keyword(&e.kind);
33151 }
33152 self.write_space();
33153 self.generate_expression(&e.this)?;
33154 Ok(())
33155 }
33156
33157 fn generate_refresh_trigger_property(&mut self, e: &RefreshTriggerProperty) -> Result<()> {
33158 self.write_keyword("REFRESH");
33160 self.write_space();
33161 self.write_keyword(&e.method);
33162
33163 if let Some(ref kind) = e.kind {
33164 self.write_space();
33165 self.write_keyword("ON");
33166 self.write_space();
33167 self.write_keyword(kind);
33168
33169 if let Some(ref every) = e.every {
33171 self.write_space();
33172 self.write_keyword("EVERY");
33173 self.write_space();
33174 self.generate_expression(every)?;
33175 if let Some(ref unit) = e.unit {
33176 self.write_space();
33177 self.write_keyword(unit);
33178 }
33179 }
33180
33181 if let Some(ref starts) = e.starts {
33183 self.write_space();
33184 self.write_keyword("STARTS");
33185 self.write_space();
33186 self.generate_expression(starts)?;
33187 }
33188 }
33189 Ok(())
33190 }
33191
33192 fn generate_regexp_count(&mut self, e: &RegexpCount) -> Result<()> {
33193 self.write_keyword("REGEXP_COUNT");
33195 self.write("(");
33196 self.generate_expression(&e.this)?;
33197 self.write(", ");
33198 self.generate_expression(&e.expression)?;
33199 if let Some(position) = &e.position {
33200 self.write(", ");
33201 self.generate_expression(position)?;
33202 }
33203 if let Some(parameters) = &e.parameters {
33204 self.write(", ");
33205 self.generate_expression(parameters)?;
33206 }
33207 self.write(")");
33208 Ok(())
33209 }
33210
33211 fn generate_regexp_extract_all(&mut self, e: &RegexpExtractAll) -> Result<()> {
33212 self.write_keyword("REGEXP_EXTRACT_ALL");
33214 self.write("(");
33215 self.generate_expression(&e.this)?;
33216 self.write(", ");
33217 self.generate_expression(&e.expression)?;
33218 if let Some(group) = &e.group {
33219 self.write(", ");
33220 self.generate_expression(group)?;
33221 }
33222 self.write(")");
33223 Ok(())
33224 }
33225
33226 fn generate_regexp_full_match(&mut self, e: &RegexpFullMatch) -> Result<()> {
33227 self.write_keyword("REGEXP_FULL_MATCH");
33229 self.write("(");
33230 self.generate_expression(&e.this)?;
33231 self.write(", ");
33232 self.generate_expression(&e.expression)?;
33233 self.write(")");
33234 Ok(())
33235 }
33236
33237 fn generate_regexp_i_like(&mut self, e: &RegexpILike) -> Result<()> {
33238 use crate::dialects::DialectType;
33239 if matches!(
33241 self.config.dialect,
33242 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
33243 ) && e.flag.is_none()
33244 {
33245 self.generate_expression(&e.this)?;
33246 self.write(" ~* ");
33247 self.generate_expression(&e.expression)?;
33248 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
33249 self.write_keyword("REGEXP_LIKE");
33251 self.write("(");
33252 self.generate_expression(&e.this)?;
33253 self.write(", ");
33254 self.generate_expression(&e.expression)?;
33255 self.write(", ");
33256 if let Some(flag) = &e.flag {
33257 self.generate_expression(flag)?;
33258 } else {
33259 self.write("'i'");
33260 }
33261 self.write(")");
33262 } else {
33263 self.generate_expression(&e.this)?;
33265 self.write_space();
33266 self.write_keyword("REGEXP_ILIKE");
33267 self.write_space();
33268 self.generate_expression(&e.expression)?;
33269 if let Some(flag) = &e.flag {
33270 self.write(", ");
33271 self.generate_expression(flag)?;
33272 }
33273 }
33274 Ok(())
33275 }
33276
33277 fn generate_regexp_instr(&mut self, e: &RegexpInstr) -> Result<()> {
33278 self.write_keyword("REGEXP_INSTR");
33280 self.write("(");
33281 self.generate_expression(&e.this)?;
33282 self.write(", ");
33283 self.generate_expression(&e.expression)?;
33284 if let Some(position) = &e.position {
33285 self.write(", ");
33286 self.generate_expression(position)?;
33287 }
33288 if let Some(occurrence) = &e.occurrence {
33289 self.write(", ");
33290 self.generate_expression(occurrence)?;
33291 }
33292 if let Some(option) = &e.option {
33293 self.write(", ");
33294 self.generate_expression(option)?;
33295 }
33296 if let Some(parameters) = &e.parameters {
33297 self.write(", ");
33298 self.generate_expression(parameters)?;
33299 }
33300 if let Some(group) = &e.group {
33301 self.write(", ");
33302 self.generate_expression(group)?;
33303 }
33304 self.write(")");
33305 Ok(())
33306 }
33307
33308 fn generate_regexp_split(&mut self, e: &RegexpSplit) -> Result<()> {
33309 self.write_keyword("REGEXP_SPLIT");
33311 self.write("(");
33312 self.generate_expression(&e.this)?;
33313 self.write(", ");
33314 self.generate_expression(&e.expression)?;
33315 if let Some(limit) = &e.limit {
33316 self.write(", ");
33317 self.generate_expression(limit)?;
33318 }
33319 self.write(")");
33320 Ok(())
33321 }
33322
33323 fn generate_regr_avgx(&mut self, e: &RegrAvgx) -> Result<()> {
33324 self.write_keyword("REGR_AVGX");
33326 self.write("(");
33327 self.generate_expression(&e.this)?;
33328 self.write(", ");
33329 self.generate_expression(&e.expression)?;
33330 self.write(")");
33331 Ok(())
33332 }
33333
33334 fn generate_regr_avgy(&mut self, e: &RegrAvgy) -> Result<()> {
33335 self.write_keyword("REGR_AVGY");
33337 self.write("(");
33338 self.generate_expression(&e.this)?;
33339 self.write(", ");
33340 self.generate_expression(&e.expression)?;
33341 self.write(")");
33342 Ok(())
33343 }
33344
33345 fn generate_regr_count(&mut self, e: &RegrCount) -> Result<()> {
33346 self.write_keyword("REGR_COUNT");
33348 self.write("(");
33349 self.generate_expression(&e.this)?;
33350 self.write(", ");
33351 self.generate_expression(&e.expression)?;
33352 self.write(")");
33353 Ok(())
33354 }
33355
33356 fn generate_regr_intercept(&mut self, e: &RegrIntercept) -> Result<()> {
33357 self.write_keyword("REGR_INTERCEPT");
33359 self.write("(");
33360 self.generate_expression(&e.this)?;
33361 self.write(", ");
33362 self.generate_expression(&e.expression)?;
33363 self.write(")");
33364 Ok(())
33365 }
33366
33367 fn generate_regr_r2(&mut self, e: &RegrR2) -> Result<()> {
33368 self.write_keyword("REGR_R2");
33370 self.write("(");
33371 self.generate_expression(&e.this)?;
33372 self.write(", ");
33373 self.generate_expression(&e.expression)?;
33374 self.write(")");
33375 Ok(())
33376 }
33377
33378 fn generate_regr_slope(&mut self, e: &RegrSlope) -> Result<()> {
33379 self.write_keyword("REGR_SLOPE");
33381 self.write("(");
33382 self.generate_expression(&e.this)?;
33383 self.write(", ");
33384 self.generate_expression(&e.expression)?;
33385 self.write(")");
33386 Ok(())
33387 }
33388
33389 fn generate_regr_sxx(&mut self, e: &RegrSxx) -> Result<()> {
33390 self.write_keyword("REGR_SXX");
33392 self.write("(");
33393 self.generate_expression(&e.this)?;
33394 self.write(", ");
33395 self.generate_expression(&e.expression)?;
33396 self.write(")");
33397 Ok(())
33398 }
33399
33400 fn generate_regr_sxy(&mut self, e: &RegrSxy) -> Result<()> {
33401 self.write_keyword("REGR_SXY");
33403 self.write("(");
33404 self.generate_expression(&e.this)?;
33405 self.write(", ");
33406 self.generate_expression(&e.expression)?;
33407 self.write(")");
33408 Ok(())
33409 }
33410
33411 fn generate_regr_syy(&mut self, e: &RegrSyy) -> Result<()> {
33412 self.write_keyword("REGR_SYY");
33414 self.write("(");
33415 self.generate_expression(&e.this)?;
33416 self.write(", ");
33417 self.generate_expression(&e.expression)?;
33418 self.write(")");
33419 Ok(())
33420 }
33421
33422 fn generate_regr_valx(&mut self, e: &RegrValx) -> Result<()> {
33423 self.write_keyword("REGR_VALX");
33425 self.write("(");
33426 self.generate_expression(&e.this)?;
33427 self.write(", ");
33428 self.generate_expression(&e.expression)?;
33429 self.write(")");
33430 Ok(())
33431 }
33432
33433 fn generate_regr_valy(&mut self, e: &RegrValy) -> Result<()> {
33434 self.write_keyword("REGR_VALY");
33436 self.write("(");
33437 self.generate_expression(&e.this)?;
33438 self.write(", ");
33439 self.generate_expression(&e.expression)?;
33440 self.write(")");
33441 Ok(())
33442 }
33443
33444 fn generate_remote_with_connection_model_property(
33445 &mut self,
33446 e: &RemoteWithConnectionModelProperty,
33447 ) -> Result<()> {
33448 self.write_keyword("REMOTE WITH CONNECTION");
33450 self.write_space();
33451 self.generate_expression(&e.this)?;
33452 Ok(())
33453 }
33454
33455 fn generate_rename_column(&mut self, e: &RenameColumn) -> Result<()> {
33456 self.write_keyword("RENAME COLUMN");
33458 if e.exists {
33459 self.write_space();
33460 self.write_keyword("IF EXISTS");
33461 }
33462 self.write_space();
33463 self.generate_expression(&e.this)?;
33464 if let Some(to) = &e.to {
33465 self.write_space();
33466 self.write_keyword("TO");
33467 self.write_space();
33468 self.generate_expression(to)?;
33469 }
33470 Ok(())
33471 }
33472
33473 fn generate_replace_partition(&mut self, e: &ReplacePartition) -> Result<()> {
33474 self.write_keyword("REPLACE PARTITION");
33476 self.write_space();
33477 self.generate_expression(&e.expression)?;
33478 if let Some(source) = &e.source {
33479 self.write_space();
33480 self.write_keyword("FROM");
33481 self.write_space();
33482 self.generate_expression(source)?;
33483 }
33484 Ok(())
33485 }
33486
33487 fn generate_returning(&mut self, e: &Returning) -> Result<()> {
33488 let keyword = match self.config.dialect {
33491 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "OUTPUT",
33492 _ => "RETURNING",
33493 };
33494 self.write_keyword(keyword);
33495 self.write_space();
33496 for (i, expr) in e.expressions.iter().enumerate() {
33497 if i > 0 {
33498 self.write(", ");
33499 }
33500 self.generate_expression(expr)?;
33501 }
33502 if let Some(into) = &e.into {
33503 self.write_space();
33504 self.write_keyword("INTO");
33505 self.write_space();
33506 self.generate_expression(into)?;
33507 }
33508 Ok(())
33509 }
33510
33511 fn generate_output_clause(&mut self, output: &OutputClause) -> Result<()> {
33512 self.write_space();
33514 self.write_keyword("OUTPUT");
33515 self.write_space();
33516 for (i, expr) in output.columns.iter().enumerate() {
33517 if i > 0 {
33518 self.write(", ");
33519 }
33520 self.generate_expression(expr)?;
33521 }
33522 if let Some(into_table) = &output.into_table {
33523 self.write_space();
33524 self.write_keyword("INTO");
33525 self.write_space();
33526 self.generate_expression(into_table)?;
33527 }
33528 Ok(())
33529 }
33530
33531 fn generate_returns_property(&mut self, e: &ReturnsProperty) -> Result<()> {
33532 self.write_keyword("RETURNS");
33534 if e.is_table.is_some() {
33535 self.write_space();
33536 self.write_keyword("TABLE");
33537 }
33538 if let Some(table) = &e.table {
33539 self.write_space();
33540 self.generate_expression(table)?;
33541 } else if let Some(this) = &e.this {
33542 self.write_space();
33543 self.generate_expression(this)?;
33544 }
33545 if e.null.is_some() {
33546 self.write_space();
33547 self.write_keyword("NULL ON NULL INPUT");
33548 }
33549 Ok(())
33550 }
33551
33552 fn generate_rollback(&mut self, e: &Rollback) -> Result<()> {
33553 self.write_keyword("ROLLBACK");
33555
33556 if e.this.is_none()
33558 && matches!(
33559 self.config.dialect,
33560 Some(DialectType::TSQL) | Some(DialectType::Fabric)
33561 )
33562 {
33563 self.write_space();
33564 self.write_keyword("TRANSACTION");
33565 }
33566
33567 if let Some(this) = &e.this {
33569 let is_transaction_marker = matches!(
33571 this.as_ref(),
33572 Expression::Identifier(id) if id.name == "TRANSACTION"
33573 );
33574
33575 self.write_space();
33576 self.write_keyword("TRANSACTION");
33577
33578 if !is_transaction_marker {
33580 self.write_space();
33581 self.generate_expression(this)?;
33582 }
33583 }
33584
33585 if let Some(savepoint) = &e.savepoint {
33587 self.write_space();
33588 self.write_keyword("TO");
33589 self.write_space();
33590 self.generate_expression(savepoint)?;
33591 }
33592 Ok(())
33593 }
33594
33595 fn generate_rollup(&mut self, e: &Rollup) -> Result<()> {
33596 if e.expressions.is_empty() {
33598 self.write_keyword("WITH ROLLUP");
33599 } else {
33600 self.write_keyword("ROLLUP");
33601 self.write("(");
33602 for (i, expr) in e.expressions.iter().enumerate() {
33603 if i > 0 {
33604 self.write(", ");
33605 }
33606 self.generate_expression(expr)?;
33607 }
33608 self.write(")");
33609 }
33610 Ok(())
33611 }
33612
33613 fn generate_row_format_delimited_property(
33614 &mut self,
33615 e: &RowFormatDelimitedProperty,
33616 ) -> Result<()> {
33617 self.write_keyword("ROW FORMAT DELIMITED");
33619 if let Some(fields) = &e.fields {
33620 self.write_space();
33621 self.write_keyword("FIELDS TERMINATED BY");
33622 self.write_space();
33623 self.generate_expression(fields)?;
33624 }
33625 if let Some(escaped) = &e.escaped {
33626 self.write_space();
33627 self.write_keyword("ESCAPED BY");
33628 self.write_space();
33629 self.generate_expression(escaped)?;
33630 }
33631 if let Some(items) = &e.collection_items {
33632 self.write_space();
33633 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
33634 self.write_space();
33635 self.generate_expression(items)?;
33636 }
33637 if let Some(keys) = &e.map_keys {
33638 self.write_space();
33639 self.write_keyword("MAP KEYS TERMINATED BY");
33640 self.write_space();
33641 self.generate_expression(keys)?;
33642 }
33643 if let Some(lines) = &e.lines {
33644 self.write_space();
33645 self.write_keyword("LINES TERMINATED BY");
33646 self.write_space();
33647 self.generate_expression(lines)?;
33648 }
33649 if let Some(null) = &e.null {
33650 self.write_space();
33651 self.write_keyword("NULL DEFINED AS");
33652 self.write_space();
33653 self.generate_expression(null)?;
33654 }
33655 if let Some(serde) = &e.serde {
33656 self.write_space();
33657 self.generate_expression(serde)?;
33658 }
33659 Ok(())
33660 }
33661
33662 fn generate_row_format_property(&mut self, e: &RowFormatProperty) -> Result<()> {
33663 self.write_keyword("ROW FORMAT");
33665 self.write_space();
33666 self.generate_expression(&e.this)?;
33667 Ok(())
33668 }
33669
33670 fn generate_row_format_serde_property(&mut self, e: &RowFormatSerdeProperty) -> Result<()> {
33671 self.write_keyword("ROW FORMAT SERDE");
33673 self.write_space();
33674 self.generate_expression(&e.this)?;
33675 if let Some(props) = &e.serde_properties {
33676 self.write_space();
33677 self.generate_expression(props)?;
33679 }
33680 Ok(())
33681 }
33682
33683 fn generate_sha2(&mut self, e: &SHA2) -> Result<()> {
33684 self.write_keyword("SHA2");
33686 self.write("(");
33687 self.generate_expression(&e.this)?;
33688 if let Some(length) = e.length {
33689 self.write(", ");
33690 self.write(&length.to_string());
33691 }
33692 self.write(")");
33693 Ok(())
33694 }
33695
33696 fn generate_sha2_digest(&mut self, e: &SHA2Digest) -> Result<()> {
33697 self.write_keyword("SHA2_DIGEST");
33699 self.write("(");
33700 self.generate_expression(&e.this)?;
33701 if let Some(length) = e.length {
33702 self.write(", ");
33703 self.write(&length.to_string());
33704 }
33705 self.write(")");
33706 Ok(())
33707 }
33708
33709 fn generate_safe_add(&mut self, e: &SafeAdd) -> Result<()> {
33710 let name = if matches!(
33711 self.config.dialect,
33712 Some(crate::dialects::DialectType::Spark)
33713 | Some(crate::dialects::DialectType::Databricks)
33714 ) {
33715 "TRY_ADD"
33716 } else {
33717 "SAFE_ADD"
33718 };
33719 self.write_keyword(name);
33720 self.write("(");
33721 self.generate_expression(&e.this)?;
33722 self.write(", ");
33723 self.generate_expression(&e.expression)?;
33724 self.write(")");
33725 Ok(())
33726 }
33727
33728 fn generate_safe_divide(&mut self, e: &SafeDivide) -> Result<()> {
33729 self.write_keyword("SAFE_DIVIDE");
33731 self.write("(");
33732 self.generate_expression(&e.this)?;
33733 self.write(", ");
33734 self.generate_expression(&e.expression)?;
33735 self.write(")");
33736 Ok(())
33737 }
33738
33739 fn generate_safe_multiply(&mut self, e: &SafeMultiply) -> Result<()> {
33740 let name = if matches!(
33741 self.config.dialect,
33742 Some(crate::dialects::DialectType::Spark)
33743 | Some(crate::dialects::DialectType::Databricks)
33744 ) {
33745 "TRY_MULTIPLY"
33746 } else {
33747 "SAFE_MULTIPLY"
33748 };
33749 self.write_keyword(name);
33750 self.write("(");
33751 self.generate_expression(&e.this)?;
33752 self.write(", ");
33753 self.generate_expression(&e.expression)?;
33754 self.write(")");
33755 Ok(())
33756 }
33757
33758 fn generate_safe_subtract(&mut self, e: &SafeSubtract) -> Result<()> {
33759 let name = if matches!(
33760 self.config.dialect,
33761 Some(crate::dialects::DialectType::Spark)
33762 | Some(crate::dialects::DialectType::Databricks)
33763 ) {
33764 "TRY_SUBTRACT"
33765 } else {
33766 "SAFE_SUBTRACT"
33767 };
33768 self.write_keyword(name);
33769 self.write("(");
33770 self.generate_expression(&e.this)?;
33771 self.write(", ");
33772 self.generate_expression(&e.expression)?;
33773 self.write(")");
33774 Ok(())
33775 }
33776
33777 fn generate_sample_body(&mut self, sample: &Sample) -> Result<()> {
33780 if matches!(sample.method, SampleMethod::Bucket) {
33782 self.write(" (");
33783 self.write_keyword("BUCKET");
33784 self.write_space();
33785 if let Some(ref num) = sample.bucket_numerator {
33786 self.generate_expression(num)?;
33787 }
33788 self.write_space();
33789 self.write_keyword("OUT OF");
33790 self.write_space();
33791 if let Some(ref denom) = sample.bucket_denominator {
33792 self.generate_expression(denom)?;
33793 }
33794 if let Some(ref field) = sample.bucket_field {
33795 self.write_space();
33796 self.write_keyword("ON");
33797 self.write_space();
33798 self.generate_expression(field)?;
33799 }
33800 self.write(")");
33801 return Ok(());
33802 }
33803
33804 let is_snowflake = matches!(
33806 self.config.dialect,
33807 Some(crate::dialects::DialectType::Snowflake)
33808 );
33809 let is_postgres = matches!(
33810 self.config.dialect,
33811 Some(crate::dialects::DialectType::PostgreSQL)
33812 | Some(crate::dialects::DialectType::Redshift)
33813 );
33814 let is_databricks = matches!(
33816 self.config.dialect,
33817 Some(crate::dialects::DialectType::Databricks)
33818 );
33819 let is_spark = matches!(
33820 self.config.dialect,
33821 Some(crate::dialects::DialectType::Spark)
33822 );
33823 let suppress_method = is_databricks || is_spark || sample.suppress_method_output;
33824 let force_method = is_postgres && matches!(sample.method, SampleMethod::Bernoulli);
33826 if !suppress_method && (sample.explicit_method || is_snowflake || force_method) {
33827 self.write_space();
33828 if !sample.explicit_method && (is_snowflake || force_method) {
33829 self.write_keyword("BERNOULLI");
33831 } else {
33832 match sample.method {
33833 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
33834 SampleMethod::System => self.write_keyword("SYSTEM"),
33835 SampleMethod::Block => self.write_keyword("BLOCK"),
33836 SampleMethod::Row => self.write_keyword("ROW"),
33837 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
33838 SampleMethod::Percent => self.write_keyword("SYSTEM"),
33839 SampleMethod::Bucket => {} }
33841 }
33842 }
33843
33844 let emit_size_no_parens = !self.config.tablesample_requires_parens;
33846 if emit_size_no_parens {
33847 self.write_space();
33848 match &sample.size {
33849 Expression::Tuple(tuple) => {
33850 for (i, expr) in tuple.expressions.iter().enumerate() {
33851 if i > 0 {
33852 self.write(", ");
33853 }
33854 self.generate_expression(expr)?;
33855 }
33856 }
33857 expr => self.generate_expression(expr)?,
33858 }
33859 } else {
33860 self.write(" (");
33861 self.generate_expression(&sample.size)?;
33862 }
33863
33864 let is_rows_method = matches!(
33866 sample.method,
33867 SampleMethod::Reservoir | SampleMethod::Row | SampleMethod::Bucket
33868 );
33869 let is_percent = matches!(
33870 sample.method,
33871 SampleMethod::Percent
33872 | SampleMethod::System
33873 | SampleMethod::Bernoulli
33874 | SampleMethod::Block
33875 );
33876
33877 let is_presto = matches!(
33881 self.config.dialect,
33882 Some(crate::dialects::DialectType::Presto)
33883 | Some(crate::dialects::DialectType::Trino)
33884 | Some(crate::dialects::DialectType::Athena)
33885 );
33886 let should_output_unit = if is_databricks || is_spark {
33887 is_percent || is_rows_method || sample.unit_after_size
33889 } else if is_snowflake || is_postgres || is_presto {
33890 sample.unit_after_size
33891 } else {
33892 sample.unit_after_size || (sample.explicit_method && (is_rows_method || is_percent))
33893 };
33894
33895 if should_output_unit {
33896 self.write_space();
33897 if sample.is_percent {
33898 self.write_keyword("PERCENT");
33899 } else if is_rows_method && !sample.unit_after_size {
33900 self.write_keyword("ROWS");
33901 } else if sample.unit_after_size {
33902 match sample.method {
33903 SampleMethod::Percent
33904 | SampleMethod::System
33905 | SampleMethod::Bernoulli
33906 | SampleMethod::Block => {
33907 self.write_keyword("PERCENT");
33908 }
33909 SampleMethod::Row | SampleMethod::Reservoir => {
33910 self.write_keyword("ROWS");
33911 }
33912 _ => self.write_keyword("ROWS"),
33913 }
33914 } else {
33915 self.write_keyword("PERCENT");
33916 }
33917 }
33918
33919 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
33920 if let Some(ref offset) = sample.offset {
33921 self.write_space();
33922 self.write_keyword("OFFSET");
33923 self.write_space();
33924 self.generate_expression(offset)?;
33925 }
33926 }
33927 if !emit_size_no_parens {
33928 self.write(")");
33929 }
33930
33931 Ok(())
33932 }
33933
33934 fn generate_sample_property(&mut self, e: &SampleProperty) -> Result<()> {
33935 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
33937 self.write_keyword("SAMPLE BY");
33938 } else {
33939 self.write_keyword("SAMPLE");
33940 }
33941 self.write_space();
33942 self.generate_expression(&e.this)?;
33943 Ok(())
33944 }
33945
33946 fn generate_schema(&mut self, e: &Schema) -> Result<()> {
33947 if let Some(this) = &e.this {
33949 self.generate_expression(this)?;
33950 }
33951 if !e.expressions.is_empty() {
33952 if e.this.is_some() {
33954 self.write_space();
33955 }
33956 self.write("(");
33957 for (i, expr) in e.expressions.iter().enumerate() {
33958 if i > 0 {
33959 self.write(", ");
33960 }
33961 self.generate_expression(expr)?;
33962 }
33963 self.write(")");
33964 }
33965 Ok(())
33966 }
33967
33968 fn generate_schema_comment_property(&mut self, e: &SchemaCommentProperty) -> Result<()> {
33969 self.write_keyword("COMMENT");
33971 self.write_space();
33972 self.generate_expression(&e.this)?;
33973 Ok(())
33974 }
33975
33976 fn generate_scope_resolution(&mut self, e: &ScopeResolution) -> Result<()> {
33977 if let Some(this) = &e.this {
33979 self.generate_expression(this)?;
33980 self.write("::");
33981 }
33982 self.generate_expression(&e.expression)?;
33983 Ok(())
33984 }
33985
33986 fn generate_search(&mut self, e: &Search) -> Result<()> {
33987 self.write_keyword("SEARCH");
33989 self.write("(");
33990 self.generate_expression(&e.this)?;
33991 self.write(", ");
33992 self.generate_expression(&e.expression)?;
33993 if let Some(json_scope) = &e.json_scope {
33994 self.write(", ");
33995 self.generate_expression(json_scope)?;
33996 }
33997 if let Some(analyzer) = &e.analyzer {
33998 self.write(", ");
33999 self.generate_expression(analyzer)?;
34000 }
34001 if let Some(analyzer_options) = &e.analyzer_options {
34002 self.write(", ");
34003 self.generate_expression(analyzer_options)?;
34004 }
34005 if let Some(search_mode) = &e.search_mode {
34006 self.write(", ");
34007 self.generate_expression(search_mode)?;
34008 }
34009 self.write(")");
34010 Ok(())
34011 }
34012
34013 fn generate_search_ip(&mut self, e: &SearchIp) -> Result<()> {
34014 self.write_keyword("SEARCH_IP");
34016 self.write("(");
34017 self.generate_expression(&e.this)?;
34018 self.write(", ");
34019 self.generate_expression(&e.expression)?;
34020 self.write(")");
34021 Ok(())
34022 }
34023
34024 fn generate_security_property(&mut self, e: &SecurityProperty) -> Result<()> {
34025 self.write_keyword("SECURITY");
34027 self.write_space();
34028 self.generate_expression(&e.this)?;
34029 Ok(())
34030 }
34031
34032 fn generate_semantic_view(&mut self, e: &SemanticView) -> Result<()> {
34033 self.write("SEMANTIC_VIEW(");
34035
34036 if self.config.pretty {
34037 self.write_newline();
34039 self.indent_level += 1;
34040 self.write_indent();
34041 self.generate_expression(&e.this)?;
34042
34043 if let Some(metrics) = &e.metrics {
34044 self.write_newline();
34045 self.write_indent();
34046 self.write_keyword("METRICS");
34047 self.write_space();
34048 self.generate_semantic_view_tuple(metrics)?;
34049 }
34050 if let Some(dimensions) = &e.dimensions {
34051 self.write_newline();
34052 self.write_indent();
34053 self.write_keyword("DIMENSIONS");
34054 self.write_space();
34055 self.generate_semantic_view_tuple(dimensions)?;
34056 }
34057 if let Some(facts) = &e.facts {
34058 self.write_newline();
34059 self.write_indent();
34060 self.write_keyword("FACTS");
34061 self.write_space();
34062 self.generate_semantic_view_tuple(facts)?;
34063 }
34064 if let Some(where_) = &e.where_ {
34065 self.write_newline();
34066 self.write_indent();
34067 self.write_keyword("WHERE");
34068 self.write_space();
34069 self.generate_expression(where_)?;
34070 }
34071 self.write_newline();
34072 self.indent_level -= 1;
34073 self.write_indent();
34074 } else {
34075 self.generate_expression(&e.this)?;
34077 if let Some(metrics) = &e.metrics {
34078 self.write_space();
34079 self.write_keyword("METRICS");
34080 self.write_space();
34081 self.generate_semantic_view_tuple(metrics)?;
34082 }
34083 if let Some(dimensions) = &e.dimensions {
34084 self.write_space();
34085 self.write_keyword("DIMENSIONS");
34086 self.write_space();
34087 self.generate_semantic_view_tuple(dimensions)?;
34088 }
34089 if let Some(facts) = &e.facts {
34090 self.write_space();
34091 self.write_keyword("FACTS");
34092 self.write_space();
34093 self.generate_semantic_view_tuple(facts)?;
34094 }
34095 if let Some(where_) = &e.where_ {
34096 self.write_space();
34097 self.write_keyword("WHERE");
34098 self.write_space();
34099 self.generate_expression(where_)?;
34100 }
34101 }
34102 self.write(")");
34103 Ok(())
34104 }
34105
34106 fn generate_semantic_view_tuple(&mut self, expr: &Expression) -> Result<()> {
34108 if let Expression::Tuple(t) = expr {
34109 for (i, e) in t.expressions.iter().enumerate() {
34110 if i > 0 {
34111 self.write(", ");
34112 }
34113 self.generate_expression(e)?;
34114 }
34115 } else {
34116 self.generate_expression(expr)?;
34117 }
34118 Ok(())
34119 }
34120
34121 fn generate_sequence_properties(&mut self, e: &SequenceProperties) -> Result<()> {
34122 if let Some(start) = &e.start {
34124 self.write_keyword("START WITH");
34125 self.write_space();
34126 self.generate_expression(start)?;
34127 }
34128 if let Some(increment) = &e.increment {
34129 self.write_space();
34130 self.write_keyword("INCREMENT BY");
34131 self.write_space();
34132 self.generate_expression(increment)?;
34133 }
34134 if let Some(minvalue) = &e.minvalue {
34135 self.write_space();
34136 self.write_keyword("MINVALUE");
34137 self.write_space();
34138 self.generate_expression(minvalue)?;
34139 }
34140 if let Some(maxvalue) = &e.maxvalue {
34141 self.write_space();
34142 self.write_keyword("MAXVALUE");
34143 self.write_space();
34144 self.generate_expression(maxvalue)?;
34145 }
34146 if let Some(cache) = &e.cache {
34147 self.write_space();
34148 self.write_keyword("CACHE");
34149 self.write_space();
34150 self.generate_expression(cache)?;
34151 }
34152 if let Some(owned) = &e.owned {
34153 self.write_space();
34154 self.write_keyword("OWNED BY");
34155 self.write_space();
34156 self.generate_expression(owned)?;
34157 }
34158 for opt in &e.options {
34159 self.write_space();
34160 self.generate_expression(opt)?;
34161 }
34162 Ok(())
34163 }
34164
34165 fn generate_serde_properties(&mut self, e: &SerdeProperties) -> Result<()> {
34166 if e.with_.is_some() {
34168 self.write_keyword("WITH");
34169 self.write_space();
34170 }
34171 self.write_keyword("SERDEPROPERTIES");
34172 self.write(" (");
34173 for (i, expr) in e.expressions.iter().enumerate() {
34174 if i > 0 {
34175 self.write(", ");
34176 }
34177 match expr {
34179 Expression::Eq(eq) => {
34180 self.generate_expression(&eq.left)?;
34181 self.write("=");
34182 self.generate_expression(&eq.right)?;
34183 }
34184 _ => self.generate_expression(expr)?,
34185 }
34186 }
34187 self.write(")");
34188 Ok(())
34189 }
34190
34191 fn generate_session_parameter(&mut self, e: &SessionParameter) -> Result<()> {
34192 self.write("@@");
34194 if let Some(kind) = &e.kind {
34195 self.write(kind);
34196 self.write(".");
34197 }
34198 self.generate_expression(&e.this)?;
34199 Ok(())
34200 }
34201
34202 fn generate_set(&mut self, e: &Set) -> Result<()> {
34203 if e.unset.is_some() {
34205 self.write_keyword("UNSET");
34206 } else {
34207 self.write_keyword("SET");
34208 }
34209 if e.tag.is_some() {
34210 self.write_space();
34211 self.write_keyword("TAG");
34212 }
34213 if !e.expressions.is_empty() {
34214 self.write_space();
34215 for (i, expr) in e.expressions.iter().enumerate() {
34216 if i > 0 {
34217 self.write(", ");
34218 }
34219 self.generate_expression(expr)?;
34220 }
34221 }
34222 Ok(())
34223 }
34224
34225 fn generate_set_config_property(&mut self, e: &SetConfigProperty) -> Result<()> {
34226 self.write_keyword("SET");
34228 self.write_space();
34229 self.generate_expression(&e.this)?;
34230 Ok(())
34231 }
34232
34233 fn generate_set_item(&mut self, e: &SetItem) -> Result<()> {
34234 if let Some(kind) = &e.kind {
34236 self.write_keyword(kind);
34237 self.write_space();
34238 }
34239 self.generate_expression(&e.name)?;
34240 self.write(" = ");
34241 self.generate_expression(&e.value)?;
34242 Ok(())
34243 }
34244
34245 fn generate_set_operation(&mut self, e: &SetOperation) -> Result<()> {
34246 if let Some(with_) = &e.with_ {
34248 self.generate_expression(with_)?;
34249 self.write_space();
34250 }
34251 self.generate_expression(&e.this)?;
34252 self.write_space();
34253 if let Some(kind) = &e.kind {
34255 self.write_keyword(kind);
34256 }
34257 if e.distinct {
34258 self.write_space();
34259 self.write_keyword("DISTINCT");
34260 } else {
34261 self.write_space();
34262 self.write_keyword("ALL");
34263 }
34264 if e.by_name.is_some() {
34265 self.write_space();
34266 self.write_keyword("BY NAME");
34267 }
34268 self.write_space();
34269 self.generate_expression(&e.expression)?;
34270 Ok(())
34271 }
34272
34273 fn generate_set_property(&mut self, e: &SetProperty) -> Result<()> {
34274 if e.multi.is_some() {
34276 self.write_keyword("MULTISET");
34277 } else {
34278 self.write_keyword("SET");
34279 }
34280 Ok(())
34281 }
34282
34283 fn generate_settings_property(&mut self, e: &SettingsProperty) -> Result<()> {
34284 self.write_keyword("SETTINGS");
34286 if self.config.pretty && e.expressions.len() > 1 {
34287 self.indent_level += 1;
34289 for (i, expr) in e.expressions.iter().enumerate() {
34290 if i > 0 {
34291 self.write(",");
34292 }
34293 self.write_newline();
34294 self.write_indent();
34295 self.generate_expression(expr)?;
34296 }
34297 self.indent_level -= 1;
34298 } else {
34299 self.write_space();
34300 for (i, expr) in e.expressions.iter().enumerate() {
34301 if i > 0 {
34302 self.write(", ");
34303 }
34304 self.generate_expression(expr)?;
34305 }
34306 }
34307 Ok(())
34308 }
34309
34310 fn generate_sharing_property(&mut self, e: &SharingProperty) -> Result<()> {
34311 self.write_keyword("SHARING");
34313 if let Some(this) = &e.this {
34314 self.write(" = ");
34315 self.generate_expression(this)?;
34316 }
34317 Ok(())
34318 }
34319
34320 fn generate_slice(&mut self, e: &Slice) -> Result<()> {
34321 if let Some(begin) = &e.this {
34323 self.generate_expression(begin)?;
34324 }
34325 self.write(":");
34326 if let Some(end) = &e.expression {
34327 self.generate_expression(end)?;
34328 }
34329 if let Some(step) = &e.step {
34330 self.write(":");
34331 self.generate_expression(step)?;
34332 }
34333 Ok(())
34334 }
34335
34336 fn generate_sort_array(&mut self, e: &SortArray) -> Result<()> {
34337 self.write_keyword("SORT_ARRAY");
34339 self.write("(");
34340 self.generate_expression(&e.this)?;
34341 if let Some(asc) = &e.asc {
34342 self.write(", ");
34343 self.generate_expression(asc)?;
34344 }
34345 self.write(")");
34346 Ok(())
34347 }
34348
34349 fn generate_sort_by(&mut self, e: &SortBy) -> Result<()> {
34350 self.write_keyword("SORT BY");
34352 self.write_space();
34353 for (i, expr) in e.expressions.iter().enumerate() {
34354 if i > 0 {
34355 self.write(", ");
34356 }
34357 self.generate_ordered(expr)?;
34358 }
34359 Ok(())
34360 }
34361
34362 fn generate_sort_key_property(&mut self, e: &SortKeyProperty) -> Result<()> {
34363 if e.compound.is_some() {
34365 self.write_keyword("COMPOUND");
34366 self.write_space();
34367 }
34368 self.write_keyword("SORTKEY");
34369 self.write("(");
34370 if let Expression::Tuple(t) = e.this.as_ref() {
34372 for (i, expr) in t.expressions.iter().enumerate() {
34373 if i > 0 {
34374 self.write(", ");
34375 }
34376 self.generate_expression(expr)?;
34377 }
34378 } else {
34379 self.generate_expression(&e.this)?;
34380 }
34381 self.write(")");
34382 Ok(())
34383 }
34384
34385 fn generate_split_part(&mut self, e: &SplitPart) -> Result<()> {
34386 self.write_keyword("SPLIT_PART");
34388 self.write("(");
34389 self.generate_expression(&e.this)?;
34390 if let Some(delimiter) = &e.delimiter {
34391 self.write(", ");
34392 self.generate_expression(delimiter)?;
34393 }
34394 if let Some(part_index) = &e.part_index {
34395 self.write(", ");
34396 self.generate_expression(part_index)?;
34397 }
34398 self.write(")");
34399 Ok(())
34400 }
34401
34402 fn generate_sql_read_write_property(&mut self, e: &SqlReadWriteProperty) -> Result<()> {
34403 self.generate_expression(&e.this)?;
34405 Ok(())
34406 }
34407
34408 fn generate_sql_security_property(&mut self, e: &SqlSecurityProperty) -> Result<()> {
34409 self.write_keyword("SQL SECURITY");
34411 self.write_space();
34412 self.generate_expression(&e.this)?;
34413 Ok(())
34414 }
34415
34416 fn generate_st_distance(&mut self, e: &StDistance) -> Result<()> {
34417 self.write_keyword("ST_DISTANCE");
34419 self.write("(");
34420 self.generate_expression(&e.this)?;
34421 self.write(", ");
34422 self.generate_expression(&e.expression)?;
34423 if let Some(use_spheroid) = &e.use_spheroid {
34424 self.write(", ");
34425 self.generate_expression(use_spheroid)?;
34426 }
34427 self.write(")");
34428 Ok(())
34429 }
34430
34431 fn generate_st_point(&mut self, e: &StPoint) -> Result<()> {
34432 self.write_keyword("ST_POINT");
34434 self.write("(");
34435 self.generate_expression(&e.this)?;
34436 self.write(", ");
34437 self.generate_expression(&e.expression)?;
34438 self.write(")");
34439 Ok(())
34440 }
34441
34442 fn generate_stability_property(&mut self, e: &StabilityProperty) -> Result<()> {
34443 self.generate_expression(&e.this)?;
34445 Ok(())
34446 }
34447
34448 fn generate_standard_hash(&mut self, e: &StandardHash) -> Result<()> {
34449 self.write_keyword("STANDARD_HASH");
34451 self.write("(");
34452 self.generate_expression(&e.this)?;
34453 if let Some(expression) = &e.expression {
34454 self.write(", ");
34455 self.generate_expression(expression)?;
34456 }
34457 self.write(")");
34458 Ok(())
34459 }
34460
34461 fn generate_storage_handler_property(&mut self, e: &StorageHandlerProperty) -> Result<()> {
34462 self.write_keyword("STORED BY");
34464 self.write_space();
34465 self.generate_expression(&e.this)?;
34466 Ok(())
34467 }
34468
34469 fn generate_str_position(&mut self, e: &StrPosition) -> Result<()> {
34470 use crate::dialects::DialectType;
34473 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
34474 self.write_keyword("CHARINDEX");
34476 self.write("(");
34477 if let Some(substr) = &e.substr {
34478 self.generate_expression(substr)?;
34479 self.write(", ");
34480 }
34481 self.generate_expression(&e.this)?;
34482 if let Some(position) = &e.position {
34483 self.write(", ");
34484 self.generate_expression(position)?;
34485 }
34486 self.write(")");
34487 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
34488 self.write_keyword("POSITION");
34489 self.write("(");
34490 self.generate_expression(&e.this)?;
34491 if let Some(substr) = &e.substr {
34492 self.write(", ");
34493 self.generate_expression(substr)?;
34494 }
34495 if let Some(position) = &e.position {
34496 self.write(", ");
34497 self.generate_expression(position)?;
34498 }
34499 if let Some(occurrence) = &e.occurrence {
34500 self.write(", ");
34501 self.generate_expression(occurrence)?;
34502 }
34503 self.write(")");
34504 } else if matches!(
34505 self.config.dialect,
34506 Some(DialectType::SQLite)
34507 | Some(DialectType::Oracle)
34508 | Some(DialectType::BigQuery)
34509 | Some(DialectType::Teradata)
34510 ) {
34511 self.write_keyword("INSTR");
34512 self.write("(");
34513 self.generate_expression(&e.this)?;
34514 if let Some(substr) = &e.substr {
34515 self.write(", ");
34516 self.generate_expression(substr)?;
34517 }
34518 if let Some(position) = &e.position {
34519 self.write(", ");
34520 self.generate_expression(position)?;
34521 } else if e.occurrence.is_some() {
34522 self.write(", 1");
34525 }
34526 if let Some(occurrence) = &e.occurrence {
34527 self.write(", ");
34528 self.generate_expression(occurrence)?;
34529 }
34530 self.write(")");
34531 } else if matches!(
34532 self.config.dialect,
34533 Some(DialectType::MySQL)
34534 | Some(DialectType::SingleStore)
34535 | Some(DialectType::Doris)
34536 | Some(DialectType::StarRocks)
34537 | Some(DialectType::Hive)
34538 | Some(DialectType::Spark)
34539 | Some(DialectType::Databricks)
34540 ) {
34541 self.write_keyword("LOCATE");
34543 self.write("(");
34544 if let Some(substr) = &e.substr {
34545 self.generate_expression(substr)?;
34546 self.write(", ");
34547 }
34548 self.generate_expression(&e.this)?;
34549 if let Some(position) = &e.position {
34550 self.write(", ");
34551 self.generate_expression(position)?;
34552 }
34553 self.write(")");
34554 } else if matches!(self.config.dialect, Some(DialectType::TSQL)) {
34555 self.write_keyword("CHARINDEX");
34557 self.write("(");
34558 if let Some(substr) = &e.substr {
34559 self.generate_expression(substr)?;
34560 self.write(", ");
34561 }
34562 self.generate_expression(&e.this)?;
34563 if let Some(position) = &e.position {
34564 self.write(", ");
34565 self.generate_expression(position)?;
34566 }
34567 self.write(")");
34568 } else if matches!(
34569 self.config.dialect,
34570 Some(DialectType::PostgreSQL)
34571 | Some(DialectType::Materialize)
34572 | Some(DialectType::RisingWave)
34573 | Some(DialectType::Redshift)
34574 ) {
34575 self.write_keyword("POSITION");
34577 self.write("(");
34578 if let Some(substr) = &e.substr {
34579 self.generate_expression(substr)?;
34580 self.write(" IN ");
34581 }
34582 self.generate_expression(&e.this)?;
34583 self.write(")");
34584 } else {
34585 self.write_keyword("STRPOS");
34586 self.write("(");
34587 self.generate_expression(&e.this)?;
34588 if let Some(substr) = &e.substr {
34589 self.write(", ");
34590 self.generate_expression(substr)?;
34591 }
34592 if let Some(position) = &e.position {
34593 self.write(", ");
34594 self.generate_expression(position)?;
34595 }
34596 if let Some(occurrence) = &e.occurrence {
34597 self.write(", ");
34598 self.generate_expression(occurrence)?;
34599 }
34600 self.write(")");
34601 }
34602 Ok(())
34603 }
34604
34605 fn generate_str_to_date(&mut self, e: &StrToDate) -> Result<()> {
34606 match self.config.dialect {
34607 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
34608 self.write_keyword("TO_DATE");
34610 self.write("(");
34611 self.generate_expression(&e.this)?;
34612 if let Some(format) = &e.format {
34613 self.write(", '");
34614 self.write(&Self::strftime_to_java_format(format));
34615 self.write("'");
34616 }
34617 self.write(")");
34618 }
34619 Some(DialectType::DuckDB) => {
34620 self.write_keyword("CAST");
34622 self.write("(");
34623 self.write_keyword("STRPTIME");
34624 self.write("(");
34625 self.generate_expression(&e.this)?;
34626 if let Some(format) = &e.format {
34627 self.write(", '");
34628 self.write(format);
34629 self.write("'");
34630 }
34631 self.write(")");
34632 self.write_keyword(" AS ");
34633 self.write_keyword("DATE");
34634 self.write(")");
34635 }
34636 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
34637 self.write_keyword("TO_DATE");
34639 self.write("(");
34640 self.generate_expression(&e.this)?;
34641 if let Some(format) = &e.format {
34642 self.write(", '");
34643 self.write(&Self::strftime_to_postgres_format(format));
34644 self.write("'");
34645 }
34646 self.write(")");
34647 }
34648 Some(DialectType::BigQuery) => {
34649 self.write_keyword("PARSE_DATE");
34651 self.write("(");
34652 if let Some(format) = &e.format {
34653 self.write("'");
34654 self.write(format);
34655 self.write("'");
34656 self.write(", ");
34657 }
34658 self.generate_expression(&e.this)?;
34659 self.write(")");
34660 }
34661 Some(DialectType::Teradata) => {
34662 self.write_keyword("CAST");
34664 self.write("(");
34665 self.generate_expression(&e.this)?;
34666 self.write_keyword(" AS ");
34667 self.write_keyword("DATE");
34668 if let Some(format) = &e.format {
34669 self.write_keyword(" FORMAT ");
34670 self.write("'");
34671 self.write(&Self::strftime_to_teradata_format(format));
34672 self.write("'");
34673 }
34674 self.write(")");
34675 }
34676 _ => {
34677 self.write_keyword("STR_TO_DATE");
34679 self.write("(");
34680 self.generate_expression(&e.this)?;
34681 if let Some(format) = &e.format {
34682 self.write(", '");
34683 self.write(format);
34684 self.write("'");
34685 }
34686 self.write(")");
34687 }
34688 }
34689 Ok(())
34690 }
34691
34692 fn strftime_to_teradata_format(fmt: &str) -> String {
34694 let mut result = String::with_capacity(fmt.len() * 2);
34695 let bytes = fmt.as_bytes();
34696 let len = bytes.len();
34697 let mut i = 0;
34698 while i < len {
34699 if bytes[i] == b'%' && i + 1 < len {
34700 let replacement = match bytes[i + 1] {
34701 b'Y' => "YYYY",
34702 b'y' => "YY",
34703 b'm' => "MM",
34704 b'B' => "MMMM",
34705 b'b' => "MMM",
34706 b'd' => "DD",
34707 b'j' => "DDD",
34708 b'H' => "HH",
34709 b'M' => "MI",
34710 b'S' => "SS",
34711 b'f' => "SSSSSS",
34712 b'A' => "EEEE",
34713 b'a' => "EEE",
34714 _ => {
34715 result.push('%');
34716 i += 1;
34717 continue;
34718 }
34719 };
34720 result.push_str(replacement);
34721 i += 2;
34722 } else {
34723 result.push(bytes[i] as char);
34724 i += 1;
34725 }
34726 }
34727 result
34728 }
34729
34730 pub fn strftime_to_java_format_static(fmt: &str) -> String {
34733 Self::strftime_to_java_format(fmt)
34734 }
34735
34736 fn strftime_to_java_format(fmt: &str) -> String {
34738 let mut result = String::with_capacity(fmt.len() * 2);
34739 let bytes = fmt.as_bytes();
34740 let len = bytes.len();
34741 let mut i = 0;
34742 while i < len {
34743 if bytes[i] == b'%' && i + 1 < len {
34744 if bytes[i + 1] == b'-' && i + 2 < len {
34746 let replacement = match bytes[i + 2] {
34747 b'd' => "d",
34748 b'm' => "M",
34749 b'H' => "H",
34750 b'M' => "m",
34751 b'S' => "s",
34752 _ => {
34753 result.push('%');
34754 i += 1;
34755 continue;
34756 }
34757 };
34758 result.push_str(replacement);
34759 i += 3;
34760 } else {
34761 let replacement = match bytes[i + 1] {
34762 b'Y' => "yyyy",
34763 b'y' => "yy",
34764 b'm' => "MM",
34765 b'B' => "MMMM",
34766 b'b' => "MMM",
34767 b'd' => "dd",
34768 b'j' => "DDD",
34769 b'H' => "HH",
34770 b'M' => "mm",
34771 b'S' => "ss",
34772 b'f' => "SSSSSS",
34773 b'A' => "EEEE",
34774 b'a' => "EEE",
34775 _ => {
34776 result.push('%');
34777 i += 1;
34778 continue;
34779 }
34780 };
34781 result.push_str(replacement);
34782 i += 2;
34783 }
34784 } else {
34785 result.push(bytes[i] as char);
34786 i += 1;
34787 }
34788 }
34789 result
34790 }
34791
34792 fn strftime_to_tsql_format(fmt: &str) -> String {
34795 let mut result = String::with_capacity(fmt.len() * 2);
34796 let bytes = fmt.as_bytes();
34797 let len = bytes.len();
34798 let mut i = 0;
34799 while i < len {
34800 if bytes[i] == b'%' && i + 1 < len {
34801 if bytes[i + 1] == b'-' && i + 2 < len {
34803 let replacement = match bytes[i + 2] {
34804 b'd' => "d",
34805 b'm' => "M",
34806 b'H' => "H",
34807 b'M' => "m",
34808 b'S' => "s",
34809 _ => {
34810 result.push('%');
34811 i += 1;
34812 continue;
34813 }
34814 };
34815 result.push_str(replacement);
34816 i += 3;
34817 } else {
34818 let replacement = match bytes[i + 1] {
34819 b'Y' => "yyyy",
34820 b'y' => "yy",
34821 b'm' => "MM",
34822 b'B' => "MMMM",
34823 b'b' => "MMM",
34824 b'd' => "dd",
34825 b'j' => "DDD",
34826 b'H' => "HH",
34827 b'M' => "mm",
34828 b'S' => "ss",
34829 b'f' => "ffffff",
34830 b'A' => "dddd",
34831 b'a' => "ddd",
34832 _ => {
34833 result.push('%');
34834 i += 1;
34835 continue;
34836 }
34837 };
34838 result.push_str(replacement);
34839 i += 2;
34840 }
34841 } else {
34842 result.push(bytes[i] as char);
34843 i += 1;
34844 }
34845 }
34846 result
34847 }
34848
34849 fn decompose_json_path(path: &str) -> Vec<String> {
34852 let mut parts = Vec::new();
34853 let path = if path.starts_with("$.") {
34855 &path[2..]
34856 } else if path.starts_with('$') {
34857 &path[1..]
34858 } else {
34859 path
34860 };
34861 if path.is_empty() {
34862 return parts;
34863 }
34864 let mut current = String::new();
34865 let chars: Vec<char> = path.chars().collect();
34866 let mut i = 0;
34867 while i < chars.len() {
34868 match chars[i] {
34869 '.' => {
34870 if !current.is_empty() {
34871 parts.push(current.clone());
34872 current.clear();
34873 }
34874 i += 1;
34875 }
34876 '[' => {
34877 if !current.is_empty() {
34878 parts.push(current.clone());
34879 current.clear();
34880 }
34881 i += 1;
34882 let mut bracket_content = String::new();
34884 while i < chars.len() && chars[i] != ']' {
34885 if chars[i] == '"' || chars[i] == '\'' {
34887 let quote = chars[i];
34888 i += 1;
34889 while i < chars.len() && chars[i] != quote {
34890 bracket_content.push(chars[i]);
34891 i += 1;
34892 }
34893 if i < chars.len() {
34894 i += 1;
34895 } } else {
34897 bracket_content.push(chars[i]);
34898 i += 1;
34899 }
34900 }
34901 if i < chars.len() {
34902 i += 1;
34903 } if bracket_content != "*" {
34906 parts.push(bracket_content);
34907 }
34908 }
34909 _ => {
34910 current.push(chars[i]);
34911 i += 1;
34912 }
34913 }
34914 }
34915 if !current.is_empty() {
34916 parts.push(current);
34917 }
34918 parts
34919 }
34920
34921 fn strftime_to_postgres_format(fmt: &str) -> String {
34923 let mut result = String::with_capacity(fmt.len() * 2);
34924 let bytes = fmt.as_bytes();
34925 let len = bytes.len();
34926 let mut i = 0;
34927 while i < len {
34928 if bytes[i] == b'%' && i + 1 < len {
34929 if bytes[i + 1] == b'-' && i + 2 < len {
34931 let replacement = match bytes[i + 2] {
34932 b'd' => "FMDD",
34933 b'm' => "FMMM",
34934 b'H' => "FMHH24",
34935 b'M' => "FMMI",
34936 b'S' => "FMSS",
34937 _ => {
34938 result.push('%');
34939 i += 1;
34940 continue;
34941 }
34942 };
34943 result.push_str(replacement);
34944 i += 3;
34945 } else {
34946 let replacement = match bytes[i + 1] {
34947 b'Y' => "YYYY",
34948 b'y' => "YY",
34949 b'm' => "MM",
34950 b'B' => "Month",
34951 b'b' => "Mon",
34952 b'd' => "DD",
34953 b'j' => "DDD",
34954 b'H' => "HH24",
34955 b'M' => "MI",
34956 b'S' => "SS",
34957 b'f' => "US",
34958 b'A' => "Day",
34959 b'a' => "Dy",
34960 _ => {
34961 result.push('%');
34962 i += 1;
34963 continue;
34964 }
34965 };
34966 result.push_str(replacement);
34967 i += 2;
34968 }
34969 } else {
34970 result.push(bytes[i] as char);
34971 i += 1;
34972 }
34973 }
34974 result
34975 }
34976
34977 fn strftime_to_snowflake_format(fmt: &str) -> String {
34979 let mut result = String::with_capacity(fmt.len() * 2);
34980 let bytes = fmt.as_bytes();
34981 let len = bytes.len();
34982 let mut i = 0;
34983 while i < len {
34984 if bytes[i] == b'%' && i + 1 < len {
34985 if bytes[i + 1] == b'-' && i + 2 < len {
34987 let replacement = match bytes[i + 2] {
34988 b'd' => "dd",
34989 b'm' => "mm",
34990 _ => {
34991 result.push('%');
34992 i += 1;
34993 continue;
34994 }
34995 };
34996 result.push_str(replacement);
34997 i += 3;
34998 } else {
34999 let replacement = match bytes[i + 1] {
35000 b'Y' => "yyyy",
35001 b'y' => "yy",
35002 b'm' => "mm",
35003 b'd' => "DD",
35004 b'H' => "hh24",
35005 b'M' => "mi",
35006 b'S' => "ss",
35007 b'f' => "ff",
35008 _ => {
35009 result.push('%');
35010 i += 1;
35011 continue;
35012 }
35013 };
35014 result.push_str(replacement);
35015 i += 2;
35016 }
35017 } else {
35018 result.push(bytes[i] as char);
35019 i += 1;
35020 }
35021 }
35022 result
35023 }
35024
35025 fn generate_str_to_map(&mut self, e: &StrToMap) -> Result<()> {
35026 self.write_keyword("STR_TO_MAP");
35028 self.write("(");
35029 self.generate_expression(&e.this)?;
35030 let needs_defaults = matches!(
35032 self.config.dialect,
35033 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
35034 );
35035 if let Some(pair_delim) = &e.pair_delim {
35036 self.write(", ");
35037 self.generate_expression(pair_delim)?;
35038 } else if needs_defaults {
35039 self.write(", ','");
35040 }
35041 if let Some(key_value_delim) = &e.key_value_delim {
35042 self.write(", ");
35043 self.generate_expression(key_value_delim)?;
35044 } else if needs_defaults {
35045 self.write(", ':'");
35046 }
35047 self.write(")");
35048 Ok(())
35049 }
35050
35051 fn generate_str_to_time(&mut self, e: &StrToTime) -> Result<()> {
35052 let is_strftime = e.format.contains('%');
35054 let to_strftime = |f: &str| -> String {
35056 if is_strftime {
35057 f.to_string()
35058 } else {
35059 Self::snowflake_format_to_strftime(f)
35060 }
35061 };
35062 let to_java = |f: &str| -> String {
35064 if is_strftime {
35065 Self::strftime_to_java_format(f)
35066 } else {
35067 Self::snowflake_format_to_spark(f)
35068 }
35069 };
35070 let to_pg = |f: &str| -> String {
35072 if is_strftime {
35073 Self::strftime_to_postgres_format(f)
35074 } else {
35075 Self::convert_strptime_to_postgres_format(f)
35076 }
35077 };
35078
35079 match self.config.dialect {
35080 Some(DialectType::Exasol) => {
35081 self.write_keyword("TO_DATE");
35082 self.write("(");
35083 self.generate_expression(&e.this)?;
35084 self.write(", '");
35085 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
35086 self.write("'");
35087 self.write(")");
35088 }
35089 Some(DialectType::BigQuery) => {
35090 let fmt = to_strftime(&e.format);
35092 let fmt = fmt.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
35094 self.write_keyword("PARSE_TIMESTAMP");
35095 self.write("('");
35096 self.write(&fmt);
35097 self.write("', ");
35098 self.generate_expression(&e.this)?;
35099 self.write(")");
35100 }
35101 Some(DialectType::Hive) => {
35102 let java_fmt = to_java(&e.format);
35105 if java_fmt == "yyyy-MM-dd HH:mm:ss"
35106 || java_fmt == "yyyy-MM-dd"
35107 || e.format == "yyyy-MM-dd HH:mm:ss"
35108 || e.format == "yyyy-MM-dd"
35109 {
35110 self.write_keyword("CAST");
35111 self.write("(");
35112 self.generate_expression(&e.this)?;
35113 self.write(" ");
35114 self.write_keyword("AS TIMESTAMP");
35115 self.write(")");
35116 } else {
35117 self.write_keyword("CAST");
35119 self.write("(");
35120 self.write_keyword("FROM_UNIXTIME");
35121 self.write("(");
35122 self.write_keyword("UNIX_TIMESTAMP");
35123 self.write("(");
35124 self.generate_expression(&e.this)?;
35125 self.write(", '");
35126 self.write(&java_fmt);
35127 self.write("')");
35128 self.write(") ");
35129 self.write_keyword("AS TIMESTAMP");
35130 self.write(")");
35131 }
35132 }
35133 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
35134 let java_fmt = to_java(&e.format);
35136 self.write_keyword("TO_TIMESTAMP");
35137 self.write("(");
35138 self.generate_expression(&e.this)?;
35139 self.write(", '");
35140 self.write(&java_fmt);
35141 self.write("')");
35142 }
35143 Some(DialectType::MySQL) => {
35144 let mut fmt = to_strftime(&e.format);
35146 fmt = fmt.replace("%-d", "%e");
35148 fmt = fmt.replace("%-m", "%c");
35149 fmt = fmt.replace("%H:%M:%S", "%T");
35150 self.write_keyword("STR_TO_DATE");
35151 self.write("(");
35152 self.generate_expression(&e.this)?;
35153 self.write(", '");
35154 self.write(&fmt);
35155 self.write("')");
35156 }
35157 Some(DialectType::Drill) => {
35158 let java_fmt = to_java(&e.format);
35160 let java_fmt = java_fmt.replace('T', "''T''");
35162 self.write_keyword("TO_TIMESTAMP");
35163 self.write("(");
35164 self.generate_expression(&e.this)?;
35165 self.write(", '");
35166 self.write(&java_fmt);
35167 self.write("')");
35168 }
35169 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
35170 let mut fmt = to_strftime(&e.format);
35172 fmt = fmt.replace("%-d", "%e");
35174 fmt = fmt.replace("%-m", "%c");
35175 fmt = fmt.replace("%H:%M:%S", "%T");
35176 self.write_keyword("DATE_PARSE");
35177 self.write("(");
35178 self.generate_expression(&e.this)?;
35179 self.write(", '");
35180 self.write(&fmt);
35181 self.write("')");
35182 }
35183 Some(DialectType::DuckDB) => {
35184 let fmt = to_strftime(&e.format);
35186 self.write_keyword("STRPTIME");
35187 self.write("(");
35188 self.generate_expression(&e.this)?;
35189 self.write(", '");
35190 self.write(&fmt);
35191 self.write("')");
35192 }
35193 Some(DialectType::PostgreSQL)
35194 | Some(DialectType::Redshift)
35195 | Some(DialectType::Materialize) => {
35196 let pg_fmt = to_pg(&e.format);
35198 self.write_keyword("TO_TIMESTAMP");
35199 self.write("(");
35200 self.generate_expression(&e.this)?;
35201 self.write(", '");
35202 self.write(&pg_fmt);
35203 self.write("')");
35204 }
35205 Some(DialectType::Oracle) => {
35206 let pg_fmt = to_pg(&e.format);
35208 self.write_keyword("TO_TIMESTAMP");
35209 self.write("(");
35210 self.generate_expression(&e.this)?;
35211 self.write(", '");
35212 self.write(&pg_fmt);
35213 self.write("')");
35214 }
35215 Some(DialectType::Snowflake) => {
35216 self.write_keyword("TO_TIMESTAMP");
35218 self.write("(");
35219 self.generate_expression(&e.this)?;
35220 self.write(", '");
35221 self.write(&e.format);
35222 self.write("')");
35223 }
35224 _ => {
35225 self.write_keyword("STR_TO_TIME");
35227 self.write("(");
35228 self.generate_expression(&e.this)?;
35229 self.write(", '");
35230 self.write(&e.format);
35231 self.write("'");
35232 self.write(")");
35233 }
35234 }
35235 Ok(())
35236 }
35237
35238 fn snowflake_format_to_strftime(format: &str) -> String {
35240 let mut result = String::new();
35241 let chars: Vec<char> = format.chars().collect();
35242 let mut i = 0;
35243 while i < chars.len() {
35244 let remaining = &format[i..];
35245 if remaining.starts_with("yyyy") {
35246 result.push_str("%Y");
35247 i += 4;
35248 } else if remaining.starts_with("yy") {
35249 result.push_str("%y");
35250 i += 2;
35251 } else if remaining.starts_with("mmmm") {
35252 result.push_str("%B"); i += 4;
35254 } else if remaining.starts_with("mon") {
35255 result.push_str("%b"); i += 3;
35257 } else if remaining.starts_with("mm") {
35258 result.push_str("%m");
35259 i += 2;
35260 } else if remaining.starts_with("DD") {
35261 result.push_str("%d");
35262 i += 2;
35263 } else if remaining.starts_with("dy") {
35264 result.push_str("%a"); i += 2;
35266 } else if remaining.starts_with("hh24") {
35267 result.push_str("%H");
35268 i += 4;
35269 } else if remaining.starts_with("hh12") {
35270 result.push_str("%I");
35271 i += 4;
35272 } else if remaining.starts_with("hh") {
35273 result.push_str("%H");
35274 i += 2;
35275 } else if remaining.starts_with("mi") {
35276 result.push_str("%M");
35277 i += 2;
35278 } else if remaining.starts_with("ss") {
35279 result.push_str("%S");
35280 i += 2;
35281 } else if remaining.starts_with("ff") {
35282 result.push_str("%f");
35284 i += 2;
35285 while i < chars.len() && chars[i].is_ascii_digit() {
35287 i += 1;
35288 }
35289 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
35290 result.push_str("%p");
35291 i += 2;
35292 } else if remaining.starts_with("tz") {
35293 result.push_str("%Z");
35294 i += 2;
35295 } else {
35296 result.push(chars[i]);
35297 i += 1;
35298 }
35299 }
35300 result
35301 }
35302
35303 fn snowflake_format_to_spark(format: &str) -> String {
35305 let mut result = String::new();
35306 let chars: Vec<char> = format.chars().collect();
35307 let mut i = 0;
35308 while i < chars.len() {
35309 let remaining = &format[i..];
35310 if remaining.starts_with("yyyy") {
35311 result.push_str("yyyy");
35312 i += 4;
35313 } else if remaining.starts_with("yy") {
35314 result.push_str("yy");
35315 i += 2;
35316 } else if remaining.starts_with("mmmm") {
35317 result.push_str("MMMM"); i += 4;
35319 } else if remaining.starts_with("mon") {
35320 result.push_str("MMM"); i += 3;
35322 } else if remaining.starts_with("mm") {
35323 result.push_str("MM");
35324 i += 2;
35325 } else if remaining.starts_with("DD") {
35326 result.push_str("dd");
35327 i += 2;
35328 } else if remaining.starts_with("dy") {
35329 result.push_str("EEE"); i += 2;
35331 } else if remaining.starts_with("hh24") {
35332 result.push_str("HH");
35333 i += 4;
35334 } else if remaining.starts_with("hh12") {
35335 result.push_str("hh");
35336 i += 4;
35337 } else if remaining.starts_with("hh") {
35338 result.push_str("HH");
35339 i += 2;
35340 } else if remaining.starts_with("mi") {
35341 result.push_str("mm");
35342 i += 2;
35343 } else if remaining.starts_with("ss") {
35344 result.push_str("ss");
35345 i += 2;
35346 } else if remaining.starts_with("ff") {
35347 result.push_str("SSS"); i += 2;
35349 while i < chars.len() && chars[i].is_ascii_digit() {
35351 i += 1;
35352 }
35353 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
35354 result.push_str("a");
35355 i += 2;
35356 } else if remaining.starts_with("tz") {
35357 result.push_str("z");
35358 i += 2;
35359 } else {
35360 result.push(chars[i]);
35361 i += 1;
35362 }
35363 }
35364 result
35365 }
35366
35367 fn generate_str_to_unix(&mut self, e: &StrToUnix) -> Result<()> {
35368 match self.config.dialect {
35369 Some(DialectType::DuckDB) => {
35370 self.write_keyword("EPOCH");
35372 self.write("(");
35373 self.write_keyword("STRPTIME");
35374 self.write("(");
35375 if let Some(this) = &e.this {
35376 self.generate_expression(this)?;
35377 }
35378 if let Some(format) = &e.format {
35379 self.write(", '");
35380 self.write(format);
35381 self.write("'");
35382 }
35383 self.write("))");
35384 }
35385 Some(DialectType::Hive) => {
35386 self.write_keyword("UNIX_TIMESTAMP");
35388 self.write("(");
35389 if let Some(this) = &e.this {
35390 self.generate_expression(this)?;
35391 }
35392 if let Some(format) = &e.format {
35393 let java_fmt = Self::strftime_to_java_format(format);
35394 if java_fmt != "yyyy-MM-dd HH:mm:ss" {
35395 self.write(", '");
35396 self.write(&java_fmt);
35397 self.write("'");
35398 }
35399 }
35400 self.write(")");
35401 }
35402 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
35403 self.write_keyword("UNIX_TIMESTAMP");
35405 self.write("(");
35406 if let Some(this) = &e.this {
35407 self.generate_expression(this)?;
35408 }
35409 if let Some(format) = &e.format {
35410 self.write(", '");
35411 self.write(format);
35412 self.write("'");
35413 }
35414 self.write(")");
35415 }
35416 Some(DialectType::Presto) | Some(DialectType::Trino) => {
35417 let c_fmt = e.format.as_deref().unwrap_or("%Y-%m-%d %T");
35420 let java_fmt = Self::strftime_to_java_format(c_fmt);
35421 self.write_keyword("TO_UNIXTIME");
35422 self.write("(");
35423 self.write_keyword("COALESCE");
35424 self.write("(");
35425 self.write_keyword("TRY");
35426 self.write("(");
35427 self.write_keyword("DATE_PARSE");
35428 self.write("(");
35429 self.write_keyword("CAST");
35430 self.write("(");
35431 if let Some(this) = &e.this {
35432 self.generate_expression(this)?;
35433 }
35434 self.write(" ");
35435 self.write_keyword("AS VARCHAR");
35436 self.write("), '");
35437 self.write(c_fmt);
35438 self.write("')), ");
35439 self.write_keyword("PARSE_DATETIME");
35440 self.write("(");
35441 self.write_keyword("DATE_FORMAT");
35442 self.write("(");
35443 self.write_keyword("CAST");
35444 self.write("(");
35445 if let Some(this) = &e.this {
35446 self.generate_expression(this)?;
35447 }
35448 self.write(" ");
35449 self.write_keyword("AS TIMESTAMP");
35450 self.write("), '");
35451 self.write(c_fmt);
35452 self.write("'), '");
35453 self.write(&java_fmt);
35454 self.write("')))");
35455 }
35456 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
35457 self.write_keyword("UNIX_TIMESTAMP");
35459 self.write("(");
35460 if let Some(this) = &e.this {
35461 self.generate_expression(this)?;
35462 }
35463 if let Some(format) = &e.format {
35464 let java_fmt = Self::strftime_to_java_format(format);
35465 self.write(", '");
35466 self.write(&java_fmt);
35467 self.write("'");
35468 }
35469 self.write(")");
35470 }
35471 _ => {
35472 self.write_keyword("STR_TO_UNIX");
35474 self.write("(");
35475 if let Some(this) = &e.this {
35476 self.generate_expression(this)?;
35477 }
35478 if let Some(format) = &e.format {
35479 self.write(", '");
35480 self.write(format);
35481 self.write("'");
35482 }
35483 self.write(")");
35484 }
35485 }
35486 Ok(())
35487 }
35488
35489 fn generate_string_to_array(&mut self, e: &StringToArray) -> Result<()> {
35490 self.write_keyword("STRING_TO_ARRAY");
35492 self.write("(");
35493 self.generate_expression(&e.this)?;
35494 if let Some(expression) = &e.expression {
35495 self.write(", ");
35496 self.generate_expression(expression)?;
35497 }
35498 if let Some(null_val) = &e.null {
35499 self.write(", ");
35500 self.generate_expression(null_val)?;
35501 }
35502 self.write(")");
35503 Ok(())
35504 }
35505
35506 fn generate_struct(&mut self, e: &Struct) -> Result<()> {
35507 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
35508 self.write_keyword("OBJECT_CONSTRUCT");
35510 self.write("(");
35511 for (i, (name, expr)) in e.fields.iter().enumerate() {
35512 if i > 0 {
35513 self.write(", ");
35514 }
35515 if let Some(name) = name {
35516 self.write("'");
35517 self.write(name);
35518 self.write("'");
35519 self.write(", ");
35520 } else {
35521 self.write("'_");
35522 self.write(&i.to_string());
35523 self.write("'");
35524 self.write(", ");
35525 }
35526 self.generate_expression(expr)?;
35527 }
35528 self.write(")");
35529 } else if self.config.struct_curly_brace_notation {
35530 self.write("{");
35532 for (i, (name, expr)) in e.fields.iter().enumerate() {
35533 if i > 0 {
35534 self.write(", ");
35535 }
35536 if let Some(name) = name {
35537 self.write("'");
35539 self.write(name);
35540 self.write("'");
35541 self.write(": ");
35542 } else {
35543 self.write("'_");
35545 self.write(&i.to_string());
35546 self.write("'");
35547 self.write(": ");
35548 }
35549 self.generate_expression(expr)?;
35550 }
35551 self.write("}");
35552 } else {
35553 let value_as_name = matches!(
35557 self.config.dialect,
35558 Some(DialectType::BigQuery)
35559 | Some(DialectType::Spark)
35560 | Some(DialectType::Databricks)
35561 | Some(DialectType::Hive)
35562 );
35563 self.write_keyword("STRUCT");
35564 self.write("(");
35565 for (i, (name, expr)) in e.fields.iter().enumerate() {
35566 if i > 0 {
35567 self.write(", ");
35568 }
35569 if let Some(name) = name {
35570 if value_as_name {
35571 self.generate_expression(expr)?;
35573 self.write_space();
35574 self.write_keyword("AS");
35575 self.write_space();
35576 let needs_quoting = name.contains(' ') || name.contains('-');
35578 if needs_quoting {
35579 if matches!(
35580 self.config.dialect,
35581 Some(DialectType::Spark)
35582 | Some(DialectType::Databricks)
35583 | Some(DialectType::Hive)
35584 ) {
35585 self.write("`");
35586 self.write(name);
35587 self.write("`");
35588 } else {
35589 self.write(name);
35590 }
35591 } else {
35592 self.write(name);
35593 }
35594 } else {
35595 self.write(name);
35597 self.write_space();
35598 self.write_keyword("AS");
35599 self.write_space();
35600 self.generate_expression(expr)?;
35601 }
35602 } else {
35603 self.generate_expression(expr)?;
35604 }
35605 }
35606 self.write(")");
35607 }
35608 Ok(())
35609 }
35610
35611 fn generate_stuff(&mut self, e: &Stuff) -> Result<()> {
35612 self.write_keyword("STUFF");
35614 self.write("(");
35615 self.generate_expression(&e.this)?;
35616 if let Some(start) = &e.start {
35617 self.write(", ");
35618 self.generate_expression(start)?;
35619 }
35620 if let Some(length) = e.length {
35621 self.write(", ");
35622 self.write(&length.to_string());
35623 }
35624 self.write(", ");
35625 self.generate_expression(&e.expression)?;
35626 self.write(")");
35627 Ok(())
35628 }
35629
35630 fn generate_substring_index(&mut self, e: &SubstringIndex) -> Result<()> {
35631 self.write_keyword("SUBSTRING_INDEX");
35633 self.write("(");
35634 self.generate_expression(&e.this)?;
35635 if let Some(delimiter) = &e.delimiter {
35636 self.write(", ");
35637 self.generate_expression(delimiter)?;
35638 }
35639 if let Some(count) = &e.count {
35640 self.write(", ");
35641 self.generate_expression(count)?;
35642 }
35643 self.write(")");
35644 Ok(())
35645 }
35646
35647 fn generate_summarize(&mut self, e: &Summarize) -> Result<()> {
35648 self.write_keyword("SUMMARIZE");
35650 if e.table.is_some() {
35651 self.write_space();
35652 self.write_keyword("TABLE");
35653 }
35654 self.write_space();
35655 self.generate_expression(&e.this)?;
35656 Ok(())
35657 }
35658
35659 fn generate_systimestamp(&mut self, _e: &Systimestamp) -> Result<()> {
35660 self.write_keyword("SYSTIMESTAMP");
35662 Ok(())
35663 }
35664
35665 fn generate_table_alias(&mut self, e: &TableAlias) -> Result<()> {
35666 if let Some(this) = &e.this {
35668 self.generate_expression(this)?;
35669 }
35670 if !e.columns.is_empty() {
35671 self.write("(");
35672 for (i, col) in e.columns.iter().enumerate() {
35673 if i > 0 {
35674 self.write(", ");
35675 }
35676 self.generate_expression(col)?;
35677 }
35678 self.write(")");
35679 }
35680 Ok(())
35681 }
35682
35683 fn generate_table_from_rows(&mut self, e: &TableFromRows) -> Result<()> {
35684 self.write_keyword("TABLE");
35686 self.write("(");
35687 self.generate_expression(&e.this)?;
35688 self.write(")");
35689 if let Some(alias) = &e.alias {
35690 self.write_space();
35691 self.write_keyword("AS");
35692 self.write_space();
35693 self.write(alias);
35694 }
35695 Ok(())
35696 }
35697
35698 fn generate_rows_from(&mut self, e: &RowsFrom) -> Result<()> {
35699 self.write_keyword("ROWS FROM");
35701 self.write(" (");
35702 for (i, expr) in e.expressions.iter().enumerate() {
35703 if i > 0 {
35704 self.write(", ");
35705 }
35706 match expr {
35710 Expression::Tuple(tuple) if tuple.expressions.len() == 2 => {
35711 self.generate_expression(&tuple.expressions[0])?;
35713 self.write_space();
35714 self.write_keyword("AS");
35715 self.write_space();
35716 self.generate_expression(&tuple.expressions[1])?;
35717 }
35718 _ => {
35719 self.generate_expression(expr)?;
35720 }
35721 }
35722 }
35723 self.write(")");
35724 if e.ordinality {
35725 self.write_space();
35726 self.write_keyword("WITH ORDINALITY");
35727 }
35728 if let Some(alias) = &e.alias {
35729 self.write_space();
35730 self.write_keyword("AS");
35731 self.write_space();
35732 self.generate_expression(alias)?;
35733 }
35734 Ok(())
35735 }
35736
35737 fn generate_table_sample(&mut self, e: &TableSample) -> Result<()> {
35738 use crate::dialects::DialectType;
35739
35740 if let (Some(this), Some(sample)) = (&e.this, &e.sample) {
35742 if self.config.alias_post_tablesample {
35744 if let Expression::Subquery(ref s) = **this {
35746 if let Some(ref alias) = s.alias {
35747 let mut subquery_no_alias = (**s).clone();
35749 subquery_no_alias.alias = None;
35750 subquery_no_alias.column_aliases = Vec::new();
35751 self.generate_expression(&Expression::Subquery(Box::new(
35752 subquery_no_alias,
35753 )))?;
35754 self.write_space();
35755 self.write_keyword("TABLESAMPLE");
35756 self.generate_sample_body(sample)?;
35757 if let Some(ref seed) = sample.seed {
35758 self.write_space();
35759 let use_seed = sample.use_seed_keyword
35760 && !matches!(
35761 self.config.dialect,
35762 Some(crate::dialects::DialectType::Databricks)
35763 | Some(crate::dialects::DialectType::Spark)
35764 );
35765 if use_seed {
35766 self.write_keyword("SEED");
35767 } else {
35768 self.write_keyword("REPEATABLE");
35769 }
35770 self.write(" (");
35771 self.generate_expression(seed)?;
35772 self.write(")");
35773 }
35774 self.write_space();
35775 self.write_keyword("AS");
35776 self.write_space();
35777 self.generate_identifier(alias)?;
35778 return Ok(());
35779 }
35780 } else if let Expression::Alias(ref a) = **this {
35781 self.generate_expression(&a.this)?;
35783 self.write_space();
35784 self.write_keyword("TABLESAMPLE");
35785 self.generate_sample_body(sample)?;
35786 if let Some(ref seed) = sample.seed {
35787 self.write_space();
35788 let use_seed = sample.use_seed_keyword
35789 && !matches!(
35790 self.config.dialect,
35791 Some(crate::dialects::DialectType::Databricks)
35792 | Some(crate::dialects::DialectType::Spark)
35793 );
35794 if use_seed {
35795 self.write_keyword("SEED");
35796 } else {
35797 self.write_keyword("REPEATABLE");
35798 }
35799 self.write(" (");
35800 self.generate_expression(seed)?;
35801 self.write(")");
35802 }
35803 self.write_space();
35805 self.write_keyword("AS");
35806 self.write_space();
35807 self.generate_identifier(&a.alias)?;
35808 return Ok(());
35809 }
35810 }
35811 self.generate_expression(this)?;
35813 self.write_space();
35814 self.write_keyword("TABLESAMPLE");
35815 self.generate_sample_body(sample)?;
35816 if let Some(ref seed) = sample.seed {
35818 self.write_space();
35819 let use_seed = sample.use_seed_keyword
35821 && !matches!(
35822 self.config.dialect,
35823 Some(crate::dialects::DialectType::Databricks)
35824 | Some(crate::dialects::DialectType::Spark)
35825 );
35826 if use_seed {
35827 self.write_keyword("SEED");
35828 } else {
35829 self.write_keyword("REPEATABLE");
35830 }
35831 self.write(" (");
35832 self.generate_expression(seed)?;
35833 self.write(")");
35834 }
35835 return Ok(());
35836 }
35837
35838 self.write_keyword("TABLESAMPLE");
35840 if let Some(method) = &e.method {
35841 self.write_space();
35842 self.write_keyword(method);
35843 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
35844 self.write_space();
35846 self.write_keyword("BERNOULLI");
35847 }
35848 if let (Some(numerator), Some(denominator)) = (&e.bucket_numerator, &e.bucket_denominator) {
35849 self.write_space();
35850 self.write_keyword("BUCKET");
35851 self.write_space();
35852 self.generate_expression(numerator)?;
35853 self.write_space();
35854 self.write_keyword("OUT OF");
35855 self.write_space();
35856 self.generate_expression(denominator)?;
35857 if let Some(field) = &e.bucket_field {
35858 self.write_space();
35859 self.write_keyword("ON");
35860 self.write_space();
35861 self.generate_expression(field)?;
35862 }
35863 } else if !e.expressions.is_empty() {
35864 self.write(" (");
35865 for (i, expr) in e.expressions.iter().enumerate() {
35866 if i > 0 {
35867 self.write(", ");
35868 }
35869 self.generate_expression(expr)?;
35870 }
35871 self.write(")");
35872 } else if let Some(percent) = &e.percent {
35873 self.write(" (");
35874 self.generate_expression(percent)?;
35875 self.write_space();
35876 self.write_keyword("PERCENT");
35877 self.write(")");
35878 }
35879 Ok(())
35880 }
35881
35882 fn generate_tag(&mut self, e: &Tag) -> Result<()> {
35883 if let Some(prefix) = &e.prefix {
35885 self.generate_expression(prefix)?;
35886 }
35887 if let Some(this) = &e.this {
35888 self.generate_expression(this)?;
35889 }
35890 if let Some(postfix) = &e.postfix {
35891 self.generate_expression(postfix)?;
35892 }
35893 Ok(())
35894 }
35895
35896 fn generate_tags(&mut self, e: &Tags) -> Result<()> {
35897 self.write_keyword("TAG");
35899 self.write(" (");
35900 for (i, expr) in e.expressions.iter().enumerate() {
35901 if i > 0 {
35902 self.write(", ");
35903 }
35904 self.generate_expression(expr)?;
35905 }
35906 self.write(")");
35907 Ok(())
35908 }
35909
35910 fn generate_temporary_property(&mut self, e: &TemporaryProperty) -> Result<()> {
35911 if let Some(this) = &e.this {
35913 self.generate_expression(this)?;
35914 self.write_space();
35915 }
35916 self.write_keyword("TEMPORARY");
35917 Ok(())
35918 }
35919
35920 fn generate_time_func(&mut self, e: &UnaryFunc) -> Result<()> {
35923 self.write_keyword("TIME");
35925 self.write("(");
35926 self.generate_expression(&e.this)?;
35927 self.write(")");
35928 Ok(())
35929 }
35930
35931 fn generate_time_add(&mut self, e: &TimeAdd) -> Result<()> {
35932 self.write_keyword("TIME_ADD");
35934 self.write("(");
35935 self.generate_expression(&e.this)?;
35936 self.write(", ");
35937 self.generate_expression(&e.expression)?;
35938 if let Some(unit) = &e.unit {
35939 self.write(", ");
35940 self.write_keyword(unit);
35941 }
35942 self.write(")");
35943 Ok(())
35944 }
35945
35946 fn generate_time_diff(&mut self, e: &TimeDiff) -> Result<()> {
35947 self.write_keyword("TIME_DIFF");
35949 self.write("(");
35950 self.generate_expression(&e.this)?;
35951 self.write(", ");
35952 self.generate_expression(&e.expression)?;
35953 if let Some(unit) = &e.unit {
35954 self.write(", ");
35955 self.write_keyword(unit);
35956 }
35957 self.write(")");
35958 Ok(())
35959 }
35960
35961 fn generate_time_from_parts(&mut self, e: &TimeFromParts) -> Result<()> {
35962 self.write_keyword("TIME_FROM_PARTS");
35964 self.write("(");
35965 let mut first = true;
35966 if let Some(hour) = &e.hour {
35967 self.generate_expression(hour)?;
35968 first = false;
35969 }
35970 if let Some(minute) = &e.min {
35971 if !first {
35972 self.write(", ");
35973 }
35974 self.generate_expression(minute)?;
35975 first = false;
35976 }
35977 if let Some(second) = &e.sec {
35978 if !first {
35979 self.write(", ");
35980 }
35981 self.generate_expression(second)?;
35982 first = false;
35983 }
35984 if let Some(ns) = &e.nano {
35985 if !first {
35986 self.write(", ");
35987 }
35988 self.generate_expression(ns)?;
35989 }
35990 self.write(")");
35991 Ok(())
35992 }
35993
35994 fn generate_time_slice(&mut self, e: &TimeSlice) -> Result<()> {
35995 self.write_keyword("TIME_SLICE");
35997 self.write("(");
35998 self.generate_expression(&e.this)?;
35999 self.write(", ");
36000 self.generate_expression(&e.expression)?;
36001 self.write(", ");
36002 self.write_keyword(&e.unit);
36003 self.write(")");
36004 Ok(())
36005 }
36006
36007 fn generate_time_str_to_time(&mut self, e: &TimeStrToTime) -> Result<()> {
36008 self.write_keyword("TIME_STR_TO_TIME");
36010 self.write("(");
36011 self.generate_expression(&e.this)?;
36012 self.write(")");
36013 Ok(())
36014 }
36015
36016 fn generate_time_sub(&mut self, e: &TimeSub) -> Result<()> {
36017 self.write_keyword("TIME_SUB");
36019 self.write("(");
36020 self.generate_expression(&e.this)?;
36021 self.write(", ");
36022 self.generate_expression(&e.expression)?;
36023 if let Some(unit) = &e.unit {
36024 self.write(", ");
36025 self.write_keyword(unit);
36026 }
36027 self.write(")");
36028 Ok(())
36029 }
36030
36031 fn generate_time_to_str(&mut self, e: &TimeToStr) -> Result<()> {
36032 match self.config.dialect {
36033 Some(DialectType::Exasol) => {
36034 self.write_keyword("TO_CHAR");
36036 self.write("(");
36037 self.generate_expression(&e.this)?;
36038 self.write(", '");
36039 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
36040 self.write("'");
36041 self.write(")");
36042 }
36043 Some(DialectType::PostgreSQL)
36044 | Some(DialectType::Redshift)
36045 | Some(DialectType::Materialize) => {
36046 self.write_keyword("TO_CHAR");
36048 self.write("(");
36049 self.generate_expression(&e.this)?;
36050 self.write(", '");
36051 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
36052 self.write("'");
36053 self.write(")");
36054 }
36055 Some(DialectType::Oracle) => {
36056 self.write_keyword("TO_CHAR");
36058 self.write("(");
36059 self.generate_expression(&e.this)?;
36060 self.write(", '");
36061 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
36062 self.write("'");
36063 self.write(")");
36064 }
36065 Some(DialectType::Drill) => {
36066 self.write_keyword("TO_CHAR");
36068 self.write("(");
36069 self.generate_expression(&e.this)?;
36070 self.write(", '");
36071 self.write(&Self::strftime_to_java_format(&e.format));
36072 self.write("'");
36073 self.write(")");
36074 }
36075 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
36076 self.write_keyword("FORMAT");
36078 self.write("(");
36079 self.generate_expression(&e.this)?;
36080 self.write(", '");
36081 self.write(&Self::strftime_to_tsql_format(&e.format));
36082 self.write("'");
36083 self.write(")");
36084 }
36085 Some(DialectType::DuckDB) => {
36086 self.write_keyword("STRFTIME");
36088 self.write("(");
36089 self.generate_expression(&e.this)?;
36090 self.write(", '");
36091 self.write(&e.format);
36092 self.write("'");
36093 self.write(")");
36094 }
36095 Some(DialectType::BigQuery) => {
36096 let fmt = e.format.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
36099 self.write_keyword("FORMAT_DATE");
36100 self.write("('");
36101 self.write(&fmt);
36102 self.write("', ");
36103 self.generate_expression(&e.this)?;
36104 self.write(")");
36105 }
36106 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
36107 self.write_keyword("DATE_FORMAT");
36109 self.write("(");
36110 self.generate_expression(&e.this)?;
36111 self.write(", '");
36112 self.write(&Self::strftime_to_java_format(&e.format));
36113 self.write("'");
36114 self.write(")");
36115 }
36116 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
36117 self.write_keyword("DATE_FORMAT");
36119 self.write("(");
36120 self.generate_expression(&e.this)?;
36121 self.write(", '");
36122 self.write(&e.format);
36123 self.write("'");
36124 self.write(")");
36125 }
36126 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
36127 self.write_keyword("DATE_FORMAT");
36129 self.write("(");
36130 self.generate_expression(&e.this)?;
36131 self.write(", '");
36132 self.write(&e.format);
36133 self.write("'");
36134 self.write(")");
36135 }
36136 _ => {
36137 self.write_keyword("TIME_TO_STR");
36139 self.write("(");
36140 self.generate_expression(&e.this)?;
36141 self.write(", '");
36142 self.write(&e.format);
36143 self.write("'");
36144 self.write(")");
36145 }
36146 }
36147 Ok(())
36148 }
36149
36150 fn generate_time_to_unix(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
36151 match self.config.dialect {
36152 Some(DialectType::DuckDB) => {
36153 self.write_keyword("EPOCH");
36155 self.write("(");
36156 self.generate_expression(&e.this)?;
36157 self.write(")");
36158 }
36159 Some(DialectType::Hive)
36160 | Some(DialectType::Spark)
36161 | Some(DialectType::Databricks)
36162 | Some(DialectType::Doris)
36163 | Some(DialectType::StarRocks)
36164 | Some(DialectType::Drill) => {
36165 self.write_keyword("UNIX_TIMESTAMP");
36167 self.write("(");
36168 self.generate_expression(&e.this)?;
36169 self.write(")");
36170 }
36171 Some(DialectType::Presto) | Some(DialectType::Trino) => {
36172 self.write_keyword("TO_UNIXTIME");
36174 self.write("(");
36175 self.generate_expression(&e.this)?;
36176 self.write(")");
36177 }
36178 _ => {
36179 self.write_keyword("TIME_TO_UNIX");
36181 self.write("(");
36182 self.generate_expression(&e.this)?;
36183 self.write(")");
36184 }
36185 }
36186 Ok(())
36187 }
36188
36189 fn generate_time_str_to_date(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
36190 match self.config.dialect {
36191 Some(DialectType::Hive) => {
36192 self.write_keyword("TO_DATE");
36194 self.write("(");
36195 self.generate_expression(&e.this)?;
36196 self.write(")");
36197 }
36198 _ => {
36199 self.write_keyword("TIME_STR_TO_DATE");
36201 self.write("(");
36202 self.generate_expression(&e.this)?;
36203 self.write(")");
36204 }
36205 }
36206 Ok(())
36207 }
36208
36209 fn generate_time_trunc(&mut self, e: &TimeTrunc) -> Result<()> {
36210 self.write_keyword("TIME_TRUNC");
36212 self.write("(");
36213 self.generate_expression(&e.this)?;
36214 self.write(", ");
36215 self.write_keyword(&e.unit);
36216 self.write(")");
36217 Ok(())
36218 }
36219
36220 fn generate_time_unit(&mut self, e: &TimeUnit) -> Result<()> {
36221 if let Some(unit) = &e.unit {
36223 self.write_keyword(unit);
36224 }
36225 Ok(())
36226 }
36227
36228 fn generate_timestamp_func(&mut self, e: &TimestampFunc) -> Result<()> {
36232 use crate::dialects::DialectType;
36233 use crate::expressions::Literal;
36234
36235 match self.config.dialect {
36236 Some(DialectType::Exasol) => {
36238 self.write_keyword("TO_TIMESTAMP");
36239 self.write("(");
36240 if let Some(this) = &e.this {
36242 match this.as_ref() {
36243 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
36244 let Literal::String(s) = lit.as_ref() else {
36245 unreachable!()
36246 };
36247 self.write("'");
36248 self.write(s);
36249 self.write("'");
36250 }
36251 _ => {
36252 self.generate_expression(this)?;
36253 }
36254 }
36255 }
36256 self.write(")");
36257 }
36258 _ => {
36260 self.write_keyword("TIMESTAMP");
36261 self.write("(");
36262 if let Some(this) = &e.this {
36263 self.generate_expression(this)?;
36264 }
36265 if let Some(zone) = &e.zone {
36266 self.write(", ");
36267 self.generate_expression(zone)?;
36268 }
36269 self.write(")");
36270 }
36271 }
36272 Ok(())
36273 }
36274
36275 fn generate_timestamp_add(&mut self, e: &TimestampAdd) -> Result<()> {
36276 self.write_keyword("TIMESTAMP_ADD");
36278 self.write("(");
36279 self.generate_expression(&e.this)?;
36280 self.write(", ");
36281 self.generate_expression(&e.expression)?;
36282 if let Some(unit) = &e.unit {
36283 self.write(", ");
36284 self.write_keyword(unit);
36285 }
36286 self.write(")");
36287 Ok(())
36288 }
36289
36290 fn generate_timestamp_diff(&mut self, e: &TimestampDiff) -> Result<()> {
36291 self.write_keyword("TIMESTAMP_DIFF");
36293 self.write("(");
36294 self.generate_expression(&e.this)?;
36295 self.write(", ");
36296 self.generate_expression(&e.expression)?;
36297 if let Some(unit) = &e.unit {
36298 self.write(", ");
36299 self.write_keyword(unit);
36300 }
36301 self.write(")");
36302 Ok(())
36303 }
36304
36305 fn generate_timestamp_from_parts(&mut self, e: &TimestampFromParts) -> Result<()> {
36306 self.write_keyword("TIMESTAMP_FROM_PARTS");
36308 self.write("(");
36309 if let Some(this) = &e.this {
36310 self.generate_expression(this)?;
36311 }
36312 if let Some(expression) = &e.expression {
36313 self.write(", ");
36314 self.generate_expression(expression)?;
36315 }
36316 if let Some(zone) = &e.zone {
36317 self.write(", ");
36318 self.generate_expression(zone)?;
36319 }
36320 if let Some(milli) = &e.milli {
36321 self.write(", ");
36322 self.generate_expression(milli)?;
36323 }
36324 self.write(")");
36325 Ok(())
36326 }
36327
36328 fn generate_timestamp_sub(&mut self, e: &TimestampSub) -> Result<()> {
36329 self.write_keyword("TIMESTAMP_SUB");
36331 self.write("(");
36332 self.generate_expression(&e.this)?;
36333 self.write(", ");
36334 self.write_keyword("INTERVAL");
36335 self.write_space();
36336 self.generate_expression(&e.expression)?;
36337 if let Some(unit) = &e.unit {
36338 self.write_space();
36339 self.write_keyword(unit);
36340 }
36341 self.write(")");
36342 Ok(())
36343 }
36344
36345 fn generate_timestamp_tz_from_parts(&mut self, e: &TimestampTzFromParts) -> Result<()> {
36346 self.write_keyword("TIMESTAMP_TZ_FROM_PARTS");
36348 self.write("(");
36349 if let Some(zone) = &e.zone {
36350 self.generate_expression(zone)?;
36351 }
36352 self.write(")");
36353 Ok(())
36354 }
36355
36356 fn generate_to_binary(&mut self, e: &ToBinary) -> Result<()> {
36357 self.write_keyword("TO_BINARY");
36359 self.write("(");
36360 self.generate_expression(&e.this)?;
36361 if let Some(format) = &e.format {
36362 self.write(", '");
36363 self.write(format);
36364 self.write("'");
36365 }
36366 self.write(")");
36367 Ok(())
36368 }
36369
36370 fn generate_to_boolean(&mut self, e: &ToBoolean) -> Result<()> {
36371 self.write_keyword("TO_BOOLEAN");
36373 self.write("(");
36374 self.generate_expression(&e.this)?;
36375 self.write(")");
36376 Ok(())
36377 }
36378
36379 fn generate_to_char(&mut self, e: &ToChar) -> Result<()> {
36380 self.write_keyword("TO_CHAR");
36382 self.write("(");
36383 self.generate_expression(&e.this)?;
36384 if let Some(format) = &e.format {
36385 self.write(", '");
36386 self.write(format);
36387 self.write("'");
36388 }
36389 if let Some(nlsparam) = &e.nlsparam {
36390 self.write(", ");
36391 self.generate_expression(nlsparam)?;
36392 }
36393 self.write(")");
36394 Ok(())
36395 }
36396
36397 fn generate_to_decfloat(&mut self, e: &ToDecfloat) -> Result<()> {
36398 self.write_keyword("TO_DECFLOAT");
36400 self.write("(");
36401 self.generate_expression(&e.this)?;
36402 if let Some(format) = &e.format {
36403 self.write(", '");
36404 self.write(format);
36405 self.write("'");
36406 }
36407 self.write(")");
36408 Ok(())
36409 }
36410
36411 fn generate_to_double(&mut self, e: &ToDouble) -> Result<()> {
36412 self.write_keyword("TO_DOUBLE");
36414 self.write("(");
36415 self.generate_expression(&e.this)?;
36416 if let Some(format) = &e.format {
36417 self.write(", '");
36418 self.write(format);
36419 self.write("'");
36420 }
36421 self.write(")");
36422 Ok(())
36423 }
36424
36425 fn generate_to_file(&mut self, e: &ToFile) -> Result<()> {
36426 self.write_keyword("TO_FILE");
36428 self.write("(");
36429 self.generate_expression(&e.this)?;
36430 if let Some(path) = &e.path {
36431 self.write(", ");
36432 self.generate_expression(path)?;
36433 }
36434 self.write(")");
36435 Ok(())
36436 }
36437
36438 fn generate_to_number(&mut self, e: &ToNumber) -> Result<()> {
36439 let is_safe = e.safe.is_some();
36442 if is_safe {
36443 self.write_keyword("TRY_TO_NUMBER");
36444 } else {
36445 self.write_keyword("TO_NUMBER");
36446 }
36447 self.write("(");
36448 self.generate_expression(&e.this)?;
36449 let precision_is_snowflake_default = e.precision.is_none()
36450 || matches!(
36451 e.precision.as_deref(),
36452 Some(Expression::Literal(lit))
36453 if matches!(lit.as_ref(), Literal::Number(n) if n == "0")
36454 );
36455 let is_snowflake_default_precision =
36456 matches!(self.config.dialect, Some(DialectType::Snowflake))
36457 && e.nlsparam.is_none()
36458 && e.scale.is_none()
36459 && matches!(
36460 e.format.as_deref(),
36461 Some(Expression::Literal(lit))
36462 if matches!(lit.as_ref(), Literal::Number(n) if n == "38")
36463 )
36464 && precision_is_snowflake_default;
36465
36466 if !is_snowflake_default_precision {
36467 if let Some(format) = &e.format {
36468 self.write(", ");
36469 self.generate_expression(format)?;
36470 }
36471 if let Some(nlsparam) = &e.nlsparam {
36472 self.write(", ");
36473 self.generate_expression(nlsparam)?;
36474 }
36475 if let Some(precision) = &e.precision {
36476 self.write(", ");
36477 self.generate_expression(precision)?;
36478 }
36479 if let Some(scale) = &e.scale {
36480 self.write(", ");
36481 self.generate_expression(scale)?;
36482 }
36483 }
36484 self.write(")");
36485 Ok(())
36486 }
36487
36488 fn generate_to_table_property(&mut self, e: &ToTableProperty) -> Result<()> {
36489 self.write_keyword("TO_TABLE");
36491 self.write_space();
36492 self.generate_expression(&e.this)?;
36493 Ok(())
36494 }
36495
36496 fn generate_transaction(&mut self, e: &Transaction) -> Result<()> {
36497 let mark_text = e.mark.as_ref().map(|m| match m.as_ref() {
36499 Expression::Identifier(id) => id.name.clone(),
36500 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
36501 let Literal::String(s) = lit.as_ref() else {
36502 unreachable!()
36503 };
36504 s.clone()
36505 }
36506 _ => String::new(),
36507 });
36508
36509 let is_start = mark_text.as_ref().map_or(false, |s| s == "START");
36510 let has_transaction_keyword = mark_text.as_ref().map_or(false, |s| s == "TRANSACTION");
36511 let has_with_mark = e.mark.as_ref().map_or(false, |m| {
36512 matches!(m.as_ref(), Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)))
36513 });
36514
36515 let use_start_transaction = matches!(
36517 self.config.dialect,
36518 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
36519 );
36520 let strip_transaction = matches!(
36522 self.config.dialect,
36523 Some(DialectType::Snowflake)
36524 | Some(DialectType::PostgreSQL)
36525 | Some(DialectType::Redshift)
36526 | Some(DialectType::MySQL)
36527 | Some(DialectType::Hive)
36528 | Some(DialectType::Spark)
36529 | Some(DialectType::Databricks)
36530 | Some(DialectType::DuckDB)
36531 | Some(DialectType::Oracle)
36532 | Some(DialectType::Doris)
36533 | Some(DialectType::StarRocks)
36534 | Some(DialectType::Materialize)
36535 | Some(DialectType::ClickHouse)
36536 );
36537
36538 if is_start || use_start_transaction {
36539 self.write_keyword("START TRANSACTION");
36541 if let Some(modes) = &e.modes {
36542 self.write_space();
36543 self.generate_expression(modes)?;
36544 }
36545 } else {
36546 self.write_keyword("BEGIN");
36548
36549 let is_kind = e.this.as_ref().map_or(false, |t| {
36551 if let Expression::Identifier(id) = t.as_ref() {
36552 id.name.eq_ignore_ascii_case("DEFERRED")
36553 || id.name.eq_ignore_ascii_case("IMMEDIATE")
36554 || id.name.eq_ignore_ascii_case("EXCLUSIVE")
36555 } else {
36556 false
36557 }
36558 });
36559
36560 if is_kind {
36562 if let Some(this) = &e.this {
36563 self.write_space();
36564 if let Expression::Identifier(id) = this.as_ref() {
36565 self.write_keyword(&id.name);
36566 }
36567 }
36568 }
36569
36570 if (has_transaction_keyword || has_with_mark) && !strip_transaction {
36572 self.write_space();
36573 self.write_keyword("TRANSACTION");
36574 }
36575
36576 if !is_kind {
36578 if let Some(this) = &e.this {
36579 self.write_space();
36580 self.generate_expression(this)?;
36581 }
36582 }
36583
36584 if has_with_mark {
36586 self.write_space();
36587 self.write_keyword("WITH MARK");
36588 if let Some(Expression::Literal(lit)) = e.mark.as_deref() {
36589 if let Literal::String(desc) = lit.as_ref() {
36590 if !desc.is_empty() {
36591 self.write_space();
36592 self.write(&format!("'{}'", desc));
36593 }
36594 }
36595 }
36596 }
36597
36598 if let Some(modes) = &e.modes {
36600 self.write_space();
36601 self.generate_expression(modes)?;
36602 }
36603 }
36604 Ok(())
36605 }
36606
36607 fn generate_transform(&mut self, e: &Transform) -> Result<()> {
36608 self.write_keyword("TRANSFORM");
36610 self.write("(");
36611 self.generate_expression(&e.this)?;
36612 self.write(", ");
36613 self.generate_expression(&e.expression)?;
36614 self.write(")");
36615 Ok(())
36616 }
36617
36618 fn generate_transform_model_property(&mut self, e: &TransformModelProperty) -> Result<()> {
36619 self.write_keyword("TRANSFORM");
36621 self.write("(");
36622 if self.config.pretty && !e.expressions.is_empty() {
36623 self.indent_level += 1;
36624 for (i, expr) in e.expressions.iter().enumerate() {
36625 if i > 0 {
36626 self.write(",");
36627 }
36628 self.write_newline();
36629 self.write_indent();
36630 self.generate_expression(expr)?;
36631 }
36632 self.indent_level -= 1;
36633 self.write_newline();
36634 self.write(")");
36635 } else {
36636 for (i, expr) in e.expressions.iter().enumerate() {
36637 if i > 0 {
36638 self.write(", ");
36639 }
36640 self.generate_expression(expr)?;
36641 }
36642 self.write(")");
36643 }
36644 Ok(())
36645 }
36646
36647 fn generate_transient_property(&mut self, e: &TransientProperty) -> Result<()> {
36648 use crate::dialects::DialectType;
36649 if let Some(this) = &e.this {
36651 self.generate_expression(this)?;
36652 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
36653 self.write_space();
36654 }
36655 }
36656 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
36657 self.write_keyword("TRANSIENT");
36658 }
36659 Ok(())
36660 }
36661
36662 fn generate_translate(&mut self, e: &Translate) -> Result<()> {
36663 self.write_keyword("TRANSLATE");
36665 self.write("(");
36666 self.generate_expression(&e.this)?;
36667 if let Some(from) = &e.from_ {
36668 self.write(", ");
36669 self.generate_expression(from)?;
36670 }
36671 if let Some(to) = &e.to {
36672 self.write(", ");
36673 self.generate_expression(to)?;
36674 }
36675 self.write(")");
36676 Ok(())
36677 }
36678
36679 fn generate_translate_characters(&mut self, e: &TranslateCharacters) -> Result<()> {
36680 self.write_keyword("TRANSLATE");
36682 self.write("(");
36683 self.generate_expression(&e.this)?;
36684 self.write_space();
36685 self.write_keyword("USING");
36686 self.write_space();
36687 self.generate_expression(&e.expression)?;
36688 if e.with_error.is_some() {
36689 self.write_space();
36690 self.write_keyword("WITH ERROR");
36691 }
36692 self.write(")");
36693 Ok(())
36694 }
36695
36696 fn generate_truncate_table(&mut self, e: &TruncateTable) -> Result<()> {
36697 self.write_keyword("TRUNCATE TABLE");
36699 self.write_space();
36700 for (i, expr) in e.expressions.iter().enumerate() {
36701 if i > 0 {
36702 self.write(", ");
36703 }
36704 self.generate_expression(expr)?;
36705 }
36706 Ok(())
36707 }
36708
36709 fn generate_try_base64_decode_binary(&mut self, e: &TryBase64DecodeBinary) -> Result<()> {
36710 self.write_keyword("TRY_BASE64_DECODE_BINARY");
36712 self.write("(");
36713 self.generate_expression(&e.this)?;
36714 if let Some(alphabet) = &e.alphabet {
36715 self.write(", ");
36716 self.generate_expression(alphabet)?;
36717 }
36718 self.write(")");
36719 Ok(())
36720 }
36721
36722 fn generate_try_base64_decode_string(&mut self, e: &TryBase64DecodeString) -> Result<()> {
36723 self.write_keyword("TRY_BASE64_DECODE_STRING");
36725 self.write("(");
36726 self.generate_expression(&e.this)?;
36727 if let Some(alphabet) = &e.alphabet {
36728 self.write(", ");
36729 self.generate_expression(alphabet)?;
36730 }
36731 self.write(")");
36732 Ok(())
36733 }
36734
36735 fn generate_try_to_decfloat(&mut self, e: &TryToDecfloat) -> Result<()> {
36736 self.write_keyword("TRY_TO_DECFLOAT");
36738 self.write("(");
36739 self.generate_expression(&e.this)?;
36740 if let Some(format) = &e.format {
36741 self.write(", '");
36742 self.write(format);
36743 self.write("'");
36744 }
36745 self.write(")");
36746 Ok(())
36747 }
36748
36749 fn generate_ts_or_ds_add(&mut self, e: &TsOrDsAdd) -> Result<()> {
36750 self.write_keyword("TS_OR_DS_ADD");
36752 self.write("(");
36753 self.generate_expression(&e.this)?;
36754 self.write(", ");
36755 self.generate_expression(&e.expression)?;
36756 if let Some(unit) = &e.unit {
36757 self.write(", ");
36758 self.write_keyword(unit);
36759 }
36760 if let Some(return_type) = &e.return_type {
36761 self.write(", ");
36762 self.generate_expression(return_type)?;
36763 }
36764 self.write(")");
36765 Ok(())
36766 }
36767
36768 fn generate_ts_or_ds_diff(&mut self, e: &TsOrDsDiff) -> Result<()> {
36769 self.write_keyword("TS_OR_DS_DIFF");
36771 self.write("(");
36772 self.generate_expression(&e.this)?;
36773 self.write(", ");
36774 self.generate_expression(&e.expression)?;
36775 if let Some(unit) = &e.unit {
36776 self.write(", ");
36777 self.write_keyword(unit);
36778 }
36779 self.write(")");
36780 Ok(())
36781 }
36782
36783 fn generate_ts_or_ds_to_date(&mut self, e: &TsOrDsToDate) -> Result<()> {
36784 let default_time_format = "%Y-%m-%d %H:%M:%S";
36785 let default_date_format = "%Y-%m-%d";
36786 let has_non_default_format = e.format.as_ref().map_or(false, |f| {
36787 f != default_time_format && f != default_date_format
36788 });
36789
36790 if has_non_default_format {
36791 let fmt = e.format.as_ref().unwrap();
36793 match self.config.dialect {
36794 Some(DialectType::MySQL) | Some(DialectType::StarRocks) => {
36795 let str_to_time = crate::expressions::StrToTime {
36798 this: Box::new((*e.this).clone()),
36799 format: fmt.clone(),
36800 zone: None,
36801 safe: None,
36802 target_type: None,
36803 };
36804 self.generate_str_to_time(&str_to_time)?;
36805 }
36806 Some(DialectType::Hive)
36807 | Some(DialectType::Spark)
36808 | Some(DialectType::Databricks) => {
36809 self.write_keyword("TO_DATE");
36811 self.write("(");
36812 self.generate_expression(&e.this)?;
36813 self.write(", '");
36814 self.write(&Self::strftime_to_java_format(fmt));
36815 self.write("')");
36816 }
36817 Some(DialectType::Snowflake) => {
36818 self.write_keyword("TO_DATE");
36820 self.write("(");
36821 self.generate_expression(&e.this)?;
36822 self.write(", '");
36823 self.write(&Self::strftime_to_snowflake_format(fmt));
36824 self.write("')");
36825 }
36826 Some(DialectType::Doris) => {
36827 self.write_keyword("TO_DATE");
36829 self.write("(");
36830 self.generate_expression(&e.this)?;
36831 self.write(")");
36832 }
36833 _ => {
36834 self.write_keyword("CAST");
36836 self.write("(");
36837 let str_to_time = crate::expressions::StrToTime {
36838 this: Box::new((*e.this).clone()),
36839 format: fmt.clone(),
36840 zone: None,
36841 safe: None,
36842 target_type: None,
36843 };
36844 self.generate_str_to_time(&str_to_time)?;
36845 self.write_keyword(" AS ");
36846 self.write_keyword("DATE");
36847 self.write(")");
36848 }
36849 }
36850 } else {
36851 match self.config.dialect {
36853 Some(DialectType::MySQL)
36854 | Some(DialectType::SQLite)
36855 | Some(DialectType::StarRocks) => {
36856 self.write_keyword("DATE");
36858 self.write("(");
36859 self.generate_expression(&e.this)?;
36860 self.write(")");
36861 }
36862 Some(DialectType::Hive)
36863 | Some(DialectType::Spark)
36864 | Some(DialectType::Databricks)
36865 | Some(DialectType::Snowflake)
36866 | Some(DialectType::Doris) => {
36867 self.write_keyword("TO_DATE");
36869 self.write("(");
36870 self.generate_expression(&e.this)?;
36871 self.write(")");
36872 }
36873 Some(DialectType::Presto)
36874 | Some(DialectType::Trino)
36875 | Some(DialectType::Athena) => {
36876 self.write_keyword("CAST");
36878 self.write("(");
36879 self.write_keyword("CAST");
36880 self.write("(");
36881 self.generate_expression(&e.this)?;
36882 self.write_keyword(" AS ");
36883 self.write_keyword("TIMESTAMP");
36884 self.write(")");
36885 self.write_keyword(" AS ");
36886 self.write_keyword("DATE");
36887 self.write(")");
36888 }
36889 Some(DialectType::ClickHouse) => {
36890 self.write_keyword("CAST");
36892 self.write("(");
36893 self.generate_expression(&e.this)?;
36894 self.write_keyword(" AS ");
36895 self.write("Nullable(DATE)");
36896 self.write(")");
36897 }
36898 _ => {
36899 self.write_keyword("CAST");
36901 self.write("(");
36902 self.generate_expression(&e.this)?;
36903 self.write_keyword(" AS ");
36904 self.write_keyword("DATE");
36905 self.write(")");
36906 }
36907 }
36908 }
36909 Ok(())
36910 }
36911
36912 fn generate_ts_or_ds_to_time(&mut self, e: &TsOrDsToTime) -> Result<()> {
36913 self.write_keyword("TS_OR_DS_TO_TIME");
36915 self.write("(");
36916 self.generate_expression(&e.this)?;
36917 if let Some(format) = &e.format {
36918 self.write(", '");
36919 self.write(format);
36920 self.write("'");
36921 }
36922 self.write(")");
36923 Ok(())
36924 }
36925
36926 fn generate_unhex(&mut self, e: &Unhex) -> Result<()> {
36927 self.write_keyword("UNHEX");
36929 self.write("(");
36930 self.generate_expression(&e.this)?;
36931 if let Some(expression) = &e.expression {
36932 self.write(", ");
36933 self.generate_expression(expression)?;
36934 }
36935 self.write(")");
36936 Ok(())
36937 }
36938
36939 fn generate_unicode_string(&mut self, e: &UnicodeString) -> Result<()> {
36940 self.write("U&");
36942 self.generate_expression(&e.this)?;
36943 if let Some(escape) = &e.escape {
36944 self.write_space();
36945 self.write_keyword("UESCAPE");
36946 self.write_space();
36947 self.generate_expression(escape)?;
36948 }
36949 Ok(())
36950 }
36951
36952 fn generate_uniform(&mut self, e: &Uniform) -> Result<()> {
36953 self.write_keyword("UNIFORM");
36955 self.write("(");
36956 self.generate_expression(&e.this)?;
36957 self.write(", ");
36958 self.generate_expression(&e.expression)?;
36959 if let Some(gen) = &e.gen {
36960 self.write(", ");
36961 self.generate_expression(gen)?;
36962 }
36963 if let Some(seed) = &e.seed {
36964 self.write(", ");
36965 self.generate_expression(seed)?;
36966 }
36967 self.write(")");
36968 Ok(())
36969 }
36970
36971 fn generate_unique_column_constraint(&mut self, e: &UniqueColumnConstraint) -> Result<()> {
36972 self.write_keyword("UNIQUE");
36974 if e.nulls.is_some() {
36976 self.write(" NULLS NOT DISTINCT");
36977 }
36978 if let Some(this) = &e.this {
36979 self.write_space();
36980 self.generate_expression(this)?;
36981 }
36982 if let Some(index_type) = &e.index_type {
36983 self.write(" USING ");
36984 self.generate_expression(index_type)?;
36985 }
36986 if let Some(on_conflict) = &e.on_conflict {
36987 self.write_space();
36988 self.generate_expression(on_conflict)?;
36989 }
36990 for opt in &e.options {
36991 self.write_space();
36992 self.generate_expression(opt)?;
36993 }
36994 Ok(())
36995 }
36996
36997 fn generate_unique_key_property(&mut self, e: &UniqueKeyProperty) -> Result<()> {
36998 self.write_keyword("UNIQUE KEY");
37000 self.write(" (");
37001 for (i, expr) in e.expressions.iter().enumerate() {
37002 if i > 0 {
37003 self.write(", ");
37004 }
37005 self.generate_expression(expr)?;
37006 }
37007 self.write(")");
37008 Ok(())
37009 }
37010
37011 fn generate_rollup_property(&mut self, e: &RollupProperty) -> Result<()> {
37012 self.write_keyword("ROLLUP");
37014 self.write(" (");
37015 for (i, index) in e.expressions.iter().enumerate() {
37016 if i > 0 {
37017 self.write(", ");
37018 }
37019 self.generate_identifier(&index.name)?;
37020 self.write("(");
37021 for (j, col) in index.expressions.iter().enumerate() {
37022 if j > 0 {
37023 self.write(", ");
37024 }
37025 self.generate_identifier(col)?;
37026 }
37027 self.write(")");
37028 }
37029 self.write(")");
37030 Ok(())
37031 }
37032
37033 fn generate_unix_to_str(&mut self, e: &UnixToStr) -> Result<()> {
37034 match self.config.dialect {
37035 Some(DialectType::DuckDB) => {
37036 self.write_keyword("STRFTIME");
37038 self.write("(");
37039 self.write_keyword("TO_TIMESTAMP");
37040 self.write("(");
37041 self.generate_expression(&e.this)?;
37042 self.write("), '");
37043 if let Some(format) = &e.format {
37044 self.write(format);
37045 }
37046 self.write("')");
37047 }
37048 Some(DialectType::Hive) => {
37049 self.write_keyword("FROM_UNIXTIME");
37051 self.write("(");
37052 self.generate_expression(&e.this)?;
37053 if let Some(format) = &e.format {
37054 if format != "yyyy-MM-dd HH:mm:ss" {
37055 self.write(", '");
37056 self.write(format);
37057 self.write("'");
37058 }
37059 }
37060 self.write(")");
37061 }
37062 Some(DialectType::Presto) | Some(DialectType::Trino) => {
37063 self.write_keyword("DATE_FORMAT");
37065 self.write("(");
37066 self.write_keyword("FROM_UNIXTIME");
37067 self.write("(");
37068 self.generate_expression(&e.this)?;
37069 self.write("), '");
37070 if let Some(format) = &e.format {
37071 self.write(format);
37072 }
37073 self.write("')");
37074 }
37075 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
37076 self.write_keyword("FROM_UNIXTIME");
37078 self.write("(");
37079 self.generate_expression(&e.this)?;
37080 if let Some(format) = &e.format {
37081 self.write(", '");
37082 self.write(format);
37083 self.write("'");
37084 }
37085 self.write(")");
37086 }
37087 _ => {
37088 self.write_keyword("UNIX_TO_STR");
37090 self.write("(");
37091 self.generate_expression(&e.this)?;
37092 if let Some(format) = &e.format {
37093 self.write(", '");
37094 self.write(format);
37095 self.write("'");
37096 }
37097 self.write(")");
37098 }
37099 }
37100 Ok(())
37101 }
37102
37103 fn generate_unix_to_time(&mut self, e: &UnixToTime) -> Result<()> {
37104 use crate::dialects::DialectType;
37105 let scale = e.scale.unwrap_or(0); match self.config.dialect {
37108 Some(DialectType::Snowflake) => {
37109 self.write_keyword("TO_TIMESTAMP");
37111 self.write("(");
37112 self.generate_expression(&e.this)?;
37113 if let Some(s) = e.scale {
37114 if s > 0 {
37115 self.write(", ");
37116 self.write(&s.to_string());
37117 }
37118 }
37119 self.write(")");
37120 }
37121 Some(DialectType::BigQuery) => {
37122 match scale {
37125 0 => {
37126 self.write_keyword("TIMESTAMP_SECONDS");
37127 self.write("(");
37128 self.generate_expression(&e.this)?;
37129 self.write(")");
37130 }
37131 3 => {
37132 self.write_keyword("TIMESTAMP_MILLIS");
37133 self.write("(");
37134 self.generate_expression(&e.this)?;
37135 self.write(")");
37136 }
37137 6 => {
37138 self.write_keyword("TIMESTAMP_MICROS");
37139 self.write("(");
37140 self.generate_expression(&e.this)?;
37141 self.write(")");
37142 }
37143 _ => {
37144 self.write_keyword("TIMESTAMP_SECONDS");
37146 self.write("(CAST(");
37147 self.generate_expression(&e.this)?;
37148 self.write(&format!(" / POWER(10, {}) AS INT64))", scale));
37149 }
37150 }
37151 }
37152 Some(DialectType::Spark) => {
37153 match scale {
37158 0 => {
37159 self.write_keyword("CAST");
37160 self.write("(");
37161 self.write_keyword("FROM_UNIXTIME");
37162 self.write("(");
37163 self.generate_expression(&e.this)?;
37164 self.write(") ");
37165 self.write_keyword("AS TIMESTAMP");
37166 self.write(")");
37167 }
37168 3 => {
37169 self.write_keyword("TIMESTAMP_MILLIS");
37170 self.write("(");
37171 self.generate_expression(&e.this)?;
37172 self.write(")");
37173 }
37174 6 => {
37175 self.write_keyword("TIMESTAMP_MICROS");
37176 self.write("(");
37177 self.generate_expression(&e.this)?;
37178 self.write(")");
37179 }
37180 _ => {
37181 self.write_keyword("TIMESTAMP_SECONDS");
37182 self.write("(");
37183 self.generate_expression(&e.this)?;
37184 self.write(&format!(" / POWER(10, {}))", scale));
37185 }
37186 }
37187 }
37188 Some(DialectType::Databricks) => {
37189 match scale {
37193 0 => {
37194 self.write_keyword("CAST");
37195 self.write("(");
37196 self.write_keyword("FROM_UNIXTIME");
37197 self.write("(");
37198 self.generate_expression(&e.this)?;
37199 self.write(") ");
37200 self.write_keyword("AS TIMESTAMP");
37201 self.write(")");
37202 }
37203 3 => {
37204 self.write_keyword("TIMESTAMP_MILLIS");
37205 self.write("(");
37206 self.generate_expression(&e.this)?;
37207 self.write(")");
37208 }
37209 6 => {
37210 self.write_keyword("TIMESTAMP_MICROS");
37211 self.write("(");
37212 self.generate_expression(&e.this)?;
37213 self.write(")");
37214 }
37215 _ => {
37216 self.write_keyword("TIMESTAMP_SECONDS");
37217 self.write("(");
37218 self.generate_expression(&e.this)?;
37219 self.write(&format!(" / POWER(10, {}))", scale));
37220 }
37221 }
37222 }
37223 Some(DialectType::Hive) => {
37224 if scale == 0 {
37226 self.write_keyword("FROM_UNIXTIME");
37227 self.write("(");
37228 self.generate_expression(&e.this)?;
37229 self.write(")");
37230 } else {
37231 self.write_keyword("FROM_UNIXTIME");
37232 self.write("(");
37233 self.generate_expression(&e.this)?;
37234 self.write(&format!(" / POWER(10, {})", scale));
37235 self.write(")");
37236 }
37237 }
37238 Some(DialectType::Presto) | Some(DialectType::Trino) => {
37239 if scale == 0 {
37242 self.write_keyword("FROM_UNIXTIME");
37243 self.write("(");
37244 self.generate_expression(&e.this)?;
37245 self.write(")");
37246 } else {
37247 self.write_keyword("FROM_UNIXTIME");
37248 self.write("(CAST(");
37249 self.generate_expression(&e.this)?;
37250 self.write(&format!(" AS DOUBLE) / POW(10, {}))", scale));
37251 }
37252 }
37253 Some(DialectType::DuckDB) => {
37254 match scale {
37258 0 => {
37259 self.write_keyword("TO_TIMESTAMP");
37260 self.write("(");
37261 self.generate_expression(&e.this)?;
37262 self.write(")");
37263 }
37264 3 => {
37265 self.write_keyword("EPOCH_MS");
37266 self.write("(");
37267 self.generate_expression(&e.this)?;
37268 self.write(")");
37269 }
37270 6 => {
37271 self.write_keyword("MAKE_TIMESTAMP");
37272 self.write("(");
37273 self.generate_expression(&e.this)?;
37274 self.write(")");
37275 }
37276 _ => {
37277 self.write_keyword("TO_TIMESTAMP");
37278 self.write("(");
37279 self.generate_expression(&e.this)?;
37280 self.write(&format!(" / POWER(10, {}))", scale));
37281 self.write_keyword(" AT TIME ZONE");
37282 self.write(" 'UTC'");
37283 }
37284 }
37285 }
37286 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
37287 self.write_keyword("FROM_UNIXTIME");
37289 self.write("(");
37290 self.generate_expression(&e.this)?;
37291 self.write(")");
37292 }
37293 Some(DialectType::Oracle) => {
37294 self.write("TO_DATE('1970-01-01', 'YYYY-MM-DD') + (");
37296 self.generate_expression(&e.this)?;
37297 self.write(" / 86400)");
37298 }
37299 Some(DialectType::Redshift) => {
37300 self.write("(TIMESTAMP 'epoch' + ");
37303 if scale == 0 {
37304 self.generate_expression(&e.this)?;
37305 } else {
37306 self.write("(");
37307 self.generate_expression(&e.this)?;
37308 self.write(&format!(" / POWER(10, {}))", scale));
37309 }
37310 self.write(" * INTERVAL '1 SECOND')");
37311 }
37312 Some(DialectType::Exasol) => {
37313 self.write_keyword("FROM_POSIX_TIME");
37315 self.write("(");
37316 self.generate_expression(&e.this)?;
37317 self.write(")");
37318 }
37319 _ => {
37320 self.write_keyword("TO_TIMESTAMP");
37322 self.write("(");
37323 self.generate_expression(&e.this)?;
37324 if let Some(s) = e.scale {
37325 self.write(", ");
37326 self.write(&s.to_string());
37327 }
37328 self.write(")");
37329 }
37330 }
37331 Ok(())
37332 }
37333
37334 fn generate_unpivot_columns(&mut self, e: &UnpivotColumns) -> Result<()> {
37335 if !matches!(&*e.this, Expression::Null(_)) {
37337 self.write_keyword("NAME");
37338 self.write_space();
37339 self.generate_expression(&e.this)?;
37340 }
37341 if !e.expressions.is_empty() {
37342 self.write_space();
37343 self.write_keyword("VALUE");
37344 self.write_space();
37345 for (i, expr) in e.expressions.iter().enumerate() {
37346 if i > 0 {
37347 self.write(", ");
37348 }
37349 self.generate_expression(expr)?;
37350 }
37351 }
37352 Ok(())
37353 }
37354
37355 fn generate_user_defined_function(&mut self, e: &UserDefinedFunction) -> Result<()> {
37356 if e.wrapped.is_some() {
37358 self.write("(");
37359 }
37360 self.generate_expression(&e.this)?;
37361 if e.wrapped.is_some() {
37362 self.write(")");
37363 }
37364 self.write("(");
37365 for (i, expr) in e.expressions.iter().enumerate() {
37366 if i > 0 {
37367 self.write(", ");
37368 }
37369 self.generate_expression(expr)?;
37370 }
37371 self.write(")");
37372 Ok(())
37373 }
37374
37375 fn generate_using_template_property(&mut self, e: &UsingTemplateProperty) -> Result<()> {
37376 self.write_keyword("USING TEMPLATE");
37378 self.write_space();
37379 self.generate_expression(&e.this)?;
37380 Ok(())
37381 }
37382
37383 fn generate_utc_time(&mut self, _e: &UtcTime) -> Result<()> {
37384 self.write_keyword("UTC_TIME");
37386 Ok(())
37387 }
37388
37389 fn generate_utc_timestamp(&mut self, _e: &UtcTimestamp) -> Result<()> {
37390 if matches!(
37391 self.config.dialect,
37392 Some(crate::dialects::DialectType::ClickHouse)
37393 ) {
37394 self.write_keyword("CURRENT_TIMESTAMP");
37395 self.write("('UTC')");
37396 } else {
37397 self.write_keyword("UTC_TIMESTAMP");
37398 }
37399 Ok(())
37400 }
37401
37402 fn generate_uuid(&mut self, e: &Uuid) -> Result<()> {
37403 use crate::dialects::DialectType;
37404 let func_name = match self.config.dialect {
37406 Some(DialectType::Snowflake) => "UUID_STRING",
37407 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
37408 Some(DialectType::BigQuery) => "GENERATE_UUID",
37409 _ => {
37410 if let Some(name) = &e.name {
37411 name.as_str()
37412 } else {
37413 "UUID"
37414 }
37415 }
37416 };
37417 self.write_keyword(func_name);
37418 self.write("(");
37419 if let Some(this) = &e.this {
37420 self.generate_expression(this)?;
37421 }
37422 self.write(")");
37423 Ok(())
37424 }
37425
37426 fn generate_var_map(&mut self, e: &VarMap) -> Result<()> {
37427 self.write_keyword("MAP");
37429 self.write("(");
37430 let mut first = true;
37431 for (k, v) in e.keys.iter().zip(e.values.iter()) {
37432 if !first {
37433 self.write(", ");
37434 }
37435 self.generate_expression(k)?;
37436 self.write(", ");
37437 self.generate_expression(v)?;
37438 first = false;
37439 }
37440 self.write(")");
37441 Ok(())
37442 }
37443
37444 fn generate_vector_search(&mut self, e: &VectorSearch) -> Result<()> {
37445 self.write_keyword("VECTOR_SEARCH");
37447 self.write("(");
37448 self.generate_expression(&e.this)?;
37449 if let Some(col) = &e.column_to_search {
37450 self.write(", ");
37451 self.generate_expression(col)?;
37452 }
37453 if let Some(query_table) = &e.query_table {
37454 self.write(", ");
37455 self.generate_expression(query_table)?;
37456 }
37457 if let Some(query_col) = &e.query_column_to_search {
37458 self.write(", ");
37459 self.generate_expression(query_col)?;
37460 }
37461 if let Some(top_k) = &e.top_k {
37462 self.write(", ");
37463 self.generate_expression(top_k)?;
37464 }
37465 if let Some(dist_type) = &e.distance_type {
37466 self.write(", ");
37467 self.generate_expression(dist_type)?;
37468 }
37469 self.write(")");
37470 Ok(())
37471 }
37472
37473 fn generate_version(&mut self, e: &Version) -> Result<()> {
37474 use crate::dialects::DialectType;
37480 let skip_for = matches!(
37481 self.config.dialect,
37482 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
37483 );
37484 if !skip_for {
37485 self.write_keyword("FOR");
37486 self.write_space();
37487 }
37488 match e.this.as_ref() {
37490 Expression::Identifier(ident) => {
37491 self.write_keyword(&ident.name);
37492 }
37493 _ => {
37494 self.generate_expression(&e.this)?;
37495 }
37496 }
37497 self.write_space();
37498 self.write_keyword(&e.kind);
37499 if let Some(expression) = &e.expression {
37500 self.write_space();
37501 self.generate_expression(expression)?;
37502 }
37503 Ok(())
37504 }
37505
37506 fn generate_view_attribute_property(&mut self, e: &ViewAttributeProperty) -> Result<()> {
37507 self.generate_expression(&e.this)?;
37509 Ok(())
37510 }
37511
37512 fn generate_volatile_property(&mut self, e: &VolatileProperty) -> Result<()> {
37513 if e.this.is_some() {
37515 self.write_keyword("NOT VOLATILE");
37516 } else {
37517 self.write_keyword("VOLATILE");
37518 }
37519 Ok(())
37520 }
37521
37522 fn generate_watermark_column_constraint(
37523 &mut self,
37524 e: &WatermarkColumnConstraint,
37525 ) -> Result<()> {
37526 self.write_keyword("WATERMARK FOR");
37528 self.write_space();
37529 self.generate_expression(&e.this)?;
37530 self.write_space();
37531 self.write_keyword("AS");
37532 self.write_space();
37533 self.generate_expression(&e.expression)?;
37534 Ok(())
37535 }
37536
37537 fn generate_week(&mut self, e: &Week) -> Result<()> {
37538 self.write_keyword("WEEK");
37540 self.write("(");
37541 self.generate_expression(&e.this)?;
37542 if let Some(mode) = &e.mode {
37543 self.write(", ");
37544 self.generate_expression(mode)?;
37545 }
37546 self.write(")");
37547 Ok(())
37548 }
37549
37550 fn generate_when(&mut self, e: &When) -> Result<()> {
37551 self.write_keyword("WHEN");
37555 self.write_space();
37556
37557 if let Some(matched) = &e.matched {
37559 match matched.as_ref() {
37561 Expression::Boolean(b) if b.value => {
37562 self.write_keyword("MATCHED");
37563 }
37564 _ => {
37565 self.write_keyword("NOT MATCHED");
37566 }
37567 }
37568 } else {
37569 self.write_keyword("NOT MATCHED");
37570 }
37571
37572 if self.config.matched_by_source {
37577 if let Some(source) = &e.source {
37578 if let Expression::Boolean(b) = source.as_ref() {
37579 if b.value {
37580 self.write_space();
37582 self.write_keyword("BY SOURCE");
37583 }
37584 } else {
37586 self.write_space();
37588 self.write_keyword("BY SOURCE");
37589 }
37590 }
37591 }
37592
37593 if let Some(condition) = &e.condition {
37595 self.write_space();
37596 self.write_keyword("AND");
37597 self.write_space();
37598 self.generate_expression(condition)?;
37599 }
37600
37601 self.write_space();
37602 self.write_keyword("THEN");
37603 self.write_space();
37604
37605 self.generate_merge_action(&e.then)?;
37608
37609 Ok(())
37610 }
37611
37612 fn generate_merge_action(&mut self, action: &Expression) -> Result<()> {
37613 match action {
37614 Expression::Tuple(tuple) => {
37615 let elements = &tuple.expressions;
37616 if elements.is_empty() {
37617 return self.generate_expression(action);
37618 }
37619 match &elements[0] {
37621 Expression::Var(v) if v.this == "INSERT" => {
37622 self.write_keyword("INSERT");
37623 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
37625 self.write(" *");
37626 if let Some(Expression::Where(w)) = elements.get(2) {
37627 self.write_space();
37628 self.generate_where(w)?;
37629 }
37630 } else {
37631 let mut values_idx = 1;
37632 if elements.len() > 1 {
37634 if let Expression::Tuple(cols) = &elements[1] {
37635 if elements.len() > 2 {
37637 self.write(" (");
37639 for (i, col) in cols.expressions.iter().enumerate() {
37640 if i > 0 {
37641 self.write(", ");
37642 }
37643 if !self.merge_strip_qualifiers.is_empty() {
37645 let stripped = self.strip_merge_qualifier(col);
37646 self.generate_expression(&stripped)?;
37647 } else {
37648 self.generate_expression(col)?;
37649 }
37650 }
37651 self.write(")");
37652 values_idx = 2;
37653 } else {
37654 values_idx = 1;
37656 }
37657 }
37658 }
37659 let mut next_idx = values_idx;
37660 if values_idx < elements.len()
37662 && !matches!(&elements[values_idx], Expression::Where(_))
37663 {
37664 let is_row = matches!(&elements[values_idx], Expression::Var(v) if v.this == "ROW");
37666 if !is_row {
37667 self.write_space();
37668 self.write_keyword("VALUES");
37669 }
37670 self.write(" ");
37671 if let Expression::Tuple(vals) = &elements[values_idx] {
37672 self.write("(");
37673 for (i, val) in vals.expressions.iter().enumerate() {
37674 if i > 0 {
37675 self.write(", ");
37676 }
37677 self.generate_expression(val)?;
37678 }
37679 self.write(")");
37680 } else {
37681 self.generate_expression(&elements[values_idx])?;
37682 }
37683 next_idx += 1;
37684 }
37685 if let Some(Expression::Where(w)) = elements.get(next_idx) {
37686 self.write_space();
37687 self.generate_where(w)?;
37688 }
37689 } }
37691 Expression::Var(v) if v.this == "UPDATE" => {
37692 self.write_keyword("UPDATE");
37693 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
37695 self.write(" *");
37696 if let Some(Expression::Where(w)) = elements.get(2) {
37697 self.write_space();
37698 self.generate_where(w)?;
37699 }
37700 } else if elements.len() > 1 {
37701 self.write_space();
37702 self.write_keyword("SET");
37703 if self.config.pretty {
37705 self.write_newline();
37706 self.indent_level += 1;
37707 self.write_indent();
37708 } else {
37709 self.write_space();
37710 }
37711 if let Expression::Tuple(assignments) = &elements[1] {
37712 for (i, assignment) in assignments.expressions.iter().enumerate() {
37713 if i > 0 {
37714 if self.config.pretty {
37715 self.write(",");
37716 self.write_newline();
37717 self.write_indent();
37718 } else {
37719 self.write(", ");
37720 }
37721 }
37722 if !self.merge_strip_qualifiers.is_empty() {
37724 self.generate_merge_set_assignment(assignment)?;
37725 } else {
37726 self.generate_expression(assignment)?;
37727 }
37728 }
37729 } else {
37730 self.generate_expression(&elements[1])?;
37731 }
37732 if self.config.pretty {
37733 self.indent_level -= 1;
37734 }
37735 if let Some(Expression::Where(w)) = elements.get(2) {
37736 self.write_space();
37737 self.generate_where(w)?;
37738 }
37739 }
37740 }
37741 Expression::Var(v) if v.this == "DELETE" => {
37742 self.write_keyword("DELETE");
37743 if let Some(Expression::Where(w)) = elements.get(1) {
37744 self.write_space();
37745 self.generate_where(w)?;
37746 }
37747 }
37748 _ => {
37749 self.generate_expression(action)?;
37751 }
37752 }
37753 }
37754 Expression::Var(v)
37755 if v.this == "INSERT"
37756 || v.this == "UPDATE"
37757 || v.this == "DELETE"
37758 || v.this == "DO NOTHING" =>
37759 {
37760 self.write_keyword(&v.this);
37761 }
37762 _ => {
37763 self.generate_expression(action)?;
37764 }
37765 }
37766 Ok(())
37767 }
37768
37769 fn generate_merge_set_assignment(&mut self, assignment: &Expression) -> Result<()> {
37771 match assignment {
37772 Expression::Eq(eq) => {
37773 let stripped_left = self.strip_merge_qualifier(&eq.left);
37775 self.generate_expression(&stripped_left)?;
37776 self.write(" = ");
37777 self.generate_expression(&eq.right)?;
37778 Ok(())
37779 }
37780 other => self.generate_expression(other),
37781 }
37782 }
37783
37784 fn strip_merge_qualifier(&self, expr: &Expression) -> Expression {
37786 match expr {
37787 Expression::Column(col) => {
37788 if let Some(ref table_ident) = col.table {
37789 if self
37790 .merge_strip_qualifiers
37791 .iter()
37792 .any(|n| n.eq_ignore_ascii_case(&table_ident.name))
37793 {
37794 let mut col = col.clone();
37796 col.table = None;
37797 return Expression::Column(col);
37798 }
37799 }
37800 expr.clone()
37801 }
37802 Expression::Dot(dot) => {
37803 if let Expression::Identifier(id) = &dot.this {
37805 if self
37806 .merge_strip_qualifiers
37807 .iter()
37808 .any(|n| n.eq_ignore_ascii_case(&id.name))
37809 {
37810 return Expression::Identifier(dot.field.clone());
37811 }
37812 }
37813 expr.clone()
37814 }
37815 _ => expr.clone(),
37816 }
37817 }
37818
37819 fn generate_whens(&mut self, e: &Whens) -> Result<()> {
37820 for (i, expr) in e.expressions.iter().enumerate() {
37822 if i > 0 {
37823 if self.config.pretty {
37825 self.write_newline();
37826 self.write_indent();
37827 } else {
37828 self.write_space();
37829 }
37830 }
37831 self.generate_expression(expr)?;
37832 }
37833 Ok(())
37834 }
37835
37836 fn generate_where(&mut self, e: &Where) -> Result<()> {
37837 self.write_keyword("WHERE");
37839 self.write_space();
37840 self.generate_expression(&e.this)?;
37841 Ok(())
37842 }
37843
37844 fn generate_width_bucket(&mut self, e: &WidthBucket) -> Result<()> {
37845 self.write_keyword("WIDTH_BUCKET");
37847 self.write("(");
37848 self.generate_expression(&e.this)?;
37849 if let Some(min_value) = &e.min_value {
37850 self.write(", ");
37851 self.generate_expression(min_value)?;
37852 }
37853 if let Some(max_value) = &e.max_value {
37854 self.write(", ");
37855 self.generate_expression(max_value)?;
37856 }
37857 if let Some(num_buckets) = &e.num_buckets {
37858 self.write(", ");
37859 self.generate_expression(num_buckets)?;
37860 }
37861 self.write(")");
37862 Ok(())
37863 }
37864
37865 fn generate_window(&mut self, e: &WindowSpec) -> Result<()> {
37866 self.generate_window_spec(e)
37868 }
37869
37870 fn generate_window_spec(&mut self, e: &WindowSpec) -> Result<()> {
37871 let mut has_content = false;
37873
37874 if !e.partition_by.is_empty() {
37876 self.write_keyword("PARTITION BY");
37877 self.write_space();
37878 for (i, expr) in e.partition_by.iter().enumerate() {
37879 if i > 0 {
37880 self.write(", ");
37881 }
37882 self.generate_expression(expr)?;
37883 }
37884 has_content = true;
37885 }
37886
37887 if !e.order_by.is_empty() {
37889 if has_content {
37890 self.write_space();
37891 }
37892 self.write_keyword("ORDER BY");
37893 self.write_space();
37894 for (i, ordered) in e.order_by.iter().enumerate() {
37895 if i > 0 {
37896 self.write(", ");
37897 }
37898 self.generate_expression(&ordered.this)?;
37899 if ordered.desc {
37900 self.write_space();
37901 self.write_keyword("DESC");
37902 } else if ordered.explicit_asc {
37903 self.write_space();
37904 self.write_keyword("ASC");
37905 }
37906 if let Some(nulls_first) = ordered.nulls_first {
37907 self.write_space();
37908 self.write_keyword("NULLS");
37909 self.write_space();
37910 if nulls_first {
37911 self.write_keyword("FIRST");
37912 } else {
37913 self.write_keyword("LAST");
37914 }
37915 }
37916 }
37917 has_content = true;
37918 }
37919
37920 if let Some(frame) = &e.frame {
37922 if has_content {
37923 self.write_space();
37924 }
37925 self.generate_window_frame(frame)?;
37926 }
37927
37928 Ok(())
37929 }
37930
37931 fn generate_with_data_property(&mut self, e: &WithDataProperty) -> Result<()> {
37932 self.write_keyword("WITH");
37934 self.write_space();
37935 if e.no.is_some() {
37936 self.write_keyword("NO");
37937 self.write_space();
37938 }
37939 self.write_keyword("DATA");
37940
37941 if let Some(statistics) = &e.statistics {
37943 self.write_space();
37944 self.write_keyword("AND");
37945 self.write_space();
37946 match statistics.as_ref() {
37948 Expression::Boolean(b) if !b.value => {
37949 self.write_keyword("NO");
37950 self.write_space();
37951 }
37952 _ => {}
37953 }
37954 self.write_keyword("STATISTICS");
37955 }
37956 Ok(())
37957 }
37958
37959 fn generate_with_fill(&mut self, e: &WithFill) -> Result<()> {
37960 self.write_keyword("WITH FILL");
37962
37963 if let Some(from_) = &e.from_ {
37964 self.write_space();
37965 self.write_keyword("FROM");
37966 self.write_space();
37967 self.generate_expression(from_)?;
37968 }
37969
37970 if let Some(to) = &e.to {
37971 self.write_space();
37972 self.write_keyword("TO");
37973 self.write_space();
37974 self.generate_expression(to)?;
37975 }
37976
37977 if let Some(step) = &e.step {
37978 self.write_space();
37979 self.write_keyword("STEP");
37980 self.write_space();
37981 self.generate_expression(step)?;
37982 }
37983
37984 if let Some(staleness) = &e.staleness {
37985 self.write_space();
37986 self.write_keyword("STALENESS");
37987 self.write_space();
37988 self.generate_expression(staleness)?;
37989 }
37990
37991 if let Some(interpolate) = &e.interpolate {
37992 self.write_space();
37993 self.write_keyword("INTERPOLATE");
37994 self.write(" (");
37995 self.generate_interpolate_item(interpolate)?;
37997 self.write(")");
37998 }
37999
38000 Ok(())
38001 }
38002
38003 fn generate_interpolate_item(&mut self, expr: &Expression) -> Result<()> {
38005 match expr {
38006 Expression::Alias(alias) => {
38007 self.generate_identifier(&alias.alias)?;
38009 self.write_space();
38010 self.write_keyword("AS");
38011 self.write_space();
38012 self.generate_expression(&alias.this)?;
38013 }
38014 Expression::Tuple(tuple) => {
38015 for (i, item) in tuple.expressions.iter().enumerate() {
38016 if i > 0 {
38017 self.write(", ");
38018 }
38019 self.generate_interpolate_item(item)?;
38020 }
38021 }
38022 other => {
38023 self.generate_expression(other)?;
38024 }
38025 }
38026 Ok(())
38027 }
38028
38029 fn generate_with_journal_table_property(&mut self, e: &WithJournalTableProperty) -> Result<()> {
38030 self.write_keyword("WITH JOURNAL TABLE");
38032 self.write("=");
38033 self.generate_expression(&e.this)?;
38034 Ok(())
38035 }
38036
38037 fn generate_with_operator(&mut self, e: &WithOperator) -> Result<()> {
38038 self.generate_expression(&e.this)?;
38040 self.write_space();
38041 self.write_keyword("WITH");
38042 self.write_space();
38043 self.write_keyword(&e.op);
38044 Ok(())
38045 }
38046
38047 fn generate_with_procedure_options(&mut self, e: &WithProcedureOptions) -> Result<()> {
38048 self.write_keyword("WITH");
38050 self.write_space();
38051 for (i, expr) in e.expressions.iter().enumerate() {
38052 if i > 0 {
38053 self.write(", ");
38054 }
38055 self.generate_expression(expr)?;
38056 }
38057 Ok(())
38058 }
38059
38060 fn generate_with_schema_binding_property(
38061 &mut self,
38062 e: &WithSchemaBindingProperty,
38063 ) -> Result<()> {
38064 self.write_keyword("WITH");
38066 self.write_space();
38067 self.generate_expression(&e.this)?;
38068 Ok(())
38069 }
38070
38071 fn generate_with_system_versioning_property(
38072 &mut self,
38073 e: &WithSystemVersioningProperty,
38074 ) -> Result<()> {
38075 let mut parts = Vec::new();
38081
38082 if let Some(this) = &e.this {
38083 let mut s = String::from("HISTORY_TABLE=");
38085 let mut gen = Generator::new();
38086 gen.generate_expression(this)?;
38087 s.push_str(&gen.output);
38088 parts.push(s);
38089 }
38090
38091 if let Some(data_consistency) = &e.data_consistency {
38092 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
38093 let mut gen = Generator::new();
38094 gen.generate_expression(data_consistency)?;
38095 s.push_str(&gen.output);
38096 parts.push(s);
38097 }
38098
38099 if let Some(retention_period) = &e.retention_period {
38100 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
38101 let mut gen = Generator::new();
38102 gen.generate_expression(retention_period)?;
38103 s.push_str(&gen.output);
38104 parts.push(s);
38105 }
38106
38107 self.write_keyword("SYSTEM_VERSIONING");
38108 self.write("=");
38109
38110 if !parts.is_empty() {
38111 self.write_keyword("ON");
38112 self.write("(");
38113 self.write(&parts.join(", "));
38114 self.write(")");
38115 } else if e.on.is_some() {
38116 self.write_keyword("ON");
38117 } else {
38118 self.write_keyword("OFF");
38119 }
38120
38121 if e.with_.is_some() {
38123 let inner = self.output.clone();
38124 self.output.clear();
38125 self.write("WITH(");
38126 self.write(&inner);
38127 self.write(")");
38128 }
38129
38130 Ok(())
38131 }
38132
38133 fn generate_with_table_hint(&mut self, e: &WithTableHint) -> Result<()> {
38134 self.write_keyword("WITH");
38136 self.write(" (");
38137 for (i, expr) in e.expressions.iter().enumerate() {
38138 if i > 0 {
38139 self.write(", ");
38140 }
38141 self.generate_expression(expr)?;
38142 }
38143 self.write(")");
38144 Ok(())
38145 }
38146
38147 fn generate_xml_element(&mut self, e: &XMLElement) -> Result<()> {
38148 self.write_keyword("XMLELEMENT");
38151 self.write("(");
38152
38153 if e.evalname.is_some() {
38154 self.write_keyword("EVALNAME");
38155 } else {
38156 self.write_keyword("NAME");
38157 }
38158 self.write_space();
38159 self.generate_expression(&e.this)?;
38160
38161 for expr in &e.expressions {
38162 self.write(", ");
38163 self.generate_expression(expr)?;
38164 }
38165 self.write(")");
38166 Ok(())
38167 }
38168
38169 fn generate_xml_get(&mut self, e: &XMLGet) -> Result<()> {
38170 self.write_keyword("XMLGET");
38172 self.write("(");
38173 self.generate_expression(&e.this)?;
38174 self.write(", ");
38175 self.generate_expression(&e.expression)?;
38176 if let Some(instance) = &e.instance {
38177 self.write(", ");
38178 self.generate_expression(instance)?;
38179 }
38180 self.write(")");
38181 Ok(())
38182 }
38183
38184 fn generate_xml_key_value_option(&mut self, e: &XMLKeyValueOption) -> Result<()> {
38185 self.generate_expression(&e.this)?;
38187 if let Some(expression) = &e.expression {
38188 self.write("(");
38189 self.generate_expression(expression)?;
38190 self.write(")");
38191 }
38192 Ok(())
38193 }
38194
38195 fn generate_xml_table(&mut self, e: &XMLTable) -> Result<()> {
38196 self.write_keyword("XMLTABLE");
38198 self.write("(");
38199
38200 if self.config.pretty {
38201 self.indent_level += 1;
38202 self.write_newline();
38203 self.write_indent();
38204 self.generate_expression(&e.this)?;
38205
38206 if let Some(passing) = &e.passing {
38207 self.write_newline();
38208 self.write_indent();
38209 self.write_keyword("PASSING");
38210 if let Expression::Tuple(tuple) = passing.as_ref() {
38211 for expr in &tuple.expressions {
38212 self.write_newline();
38213 self.indent_level += 1;
38214 self.write_indent();
38215 self.generate_expression(expr)?;
38216 self.indent_level -= 1;
38217 }
38218 } else {
38219 self.write_newline();
38220 self.indent_level += 1;
38221 self.write_indent();
38222 self.generate_expression(passing)?;
38223 self.indent_level -= 1;
38224 }
38225 }
38226
38227 if e.by_ref.is_some() {
38228 self.write_newline();
38229 self.write_indent();
38230 self.write_keyword("RETURNING SEQUENCE BY REF");
38231 }
38232
38233 if !e.columns.is_empty() {
38234 self.write_newline();
38235 self.write_indent();
38236 self.write_keyword("COLUMNS");
38237 for (i, col) in e.columns.iter().enumerate() {
38238 self.write_newline();
38239 self.indent_level += 1;
38240 self.write_indent();
38241 self.generate_expression(col)?;
38242 self.indent_level -= 1;
38243 if i < e.columns.len() - 1 {
38244 self.write(",");
38245 }
38246 }
38247 }
38248
38249 self.indent_level -= 1;
38250 self.write_newline();
38251 self.write_indent();
38252 self.write(")");
38253 return Ok(());
38254 }
38255
38256 if let Some(namespaces) = &e.namespaces {
38258 self.write_keyword("XMLNAMESPACES");
38259 self.write("(");
38260 if let Expression::Tuple(tuple) = namespaces.as_ref() {
38262 for (i, expr) in tuple.expressions.iter().enumerate() {
38263 if i > 0 {
38264 self.write(", ");
38265 }
38266 if !matches!(expr, Expression::Alias(_)) {
38269 self.write_keyword("DEFAULT");
38270 self.write_space();
38271 }
38272 self.generate_expression(expr)?;
38273 }
38274 } else {
38275 if !matches!(namespaces.as_ref(), Expression::Alias(_)) {
38277 self.write_keyword("DEFAULT");
38278 self.write_space();
38279 }
38280 self.generate_expression(namespaces)?;
38281 }
38282 self.write("), ");
38283 }
38284
38285 self.generate_expression(&e.this)?;
38287
38288 if let Some(passing) = &e.passing {
38290 self.write_space();
38291 self.write_keyword("PASSING");
38292 self.write_space();
38293 if let Expression::Tuple(tuple) = passing.as_ref() {
38295 for (i, expr) in tuple.expressions.iter().enumerate() {
38296 if i > 0 {
38297 self.write(", ");
38298 }
38299 self.generate_expression(expr)?;
38300 }
38301 } else {
38302 self.generate_expression(passing)?;
38303 }
38304 }
38305
38306 if e.by_ref.is_some() {
38308 self.write_space();
38309 self.write_keyword("RETURNING SEQUENCE BY REF");
38310 }
38311
38312 if !e.columns.is_empty() {
38314 self.write_space();
38315 self.write_keyword("COLUMNS");
38316 self.write_space();
38317 for (i, col) in e.columns.iter().enumerate() {
38318 if i > 0 {
38319 self.write(", ");
38320 }
38321 self.generate_expression(col)?;
38322 }
38323 }
38324
38325 self.write(")");
38326 Ok(())
38327 }
38328
38329 fn generate_xor(&mut self, e: &Xor) -> Result<()> {
38330 if let Some(this) = &e.this {
38333 self.generate_expression(this)?;
38334 if let Some(expression) = &e.expression {
38335 self.write_space();
38336 self.write_keyword("XOR");
38337 self.write_space();
38338 self.generate_expression(expression)?;
38339 }
38340 }
38341
38342 for (i, expr) in e.expressions.iter().enumerate() {
38344 if i > 0 || e.this.is_some() {
38345 self.write_space();
38346 self.write_keyword("XOR");
38347 self.write_space();
38348 }
38349 self.generate_expression(expr)?;
38350 }
38351 Ok(())
38352 }
38353
38354 fn generate_zipf(&mut self, e: &Zipf) -> Result<()> {
38355 self.write_keyword("ZIPF");
38357 self.write("(");
38358 self.generate_expression(&e.this)?;
38359 if let Some(elementcount) = &e.elementcount {
38360 self.write(", ");
38361 self.generate_expression(elementcount)?;
38362 }
38363 if let Some(gen) = &e.gen {
38364 self.write(", ");
38365 self.generate_expression(gen)?;
38366 }
38367 self.write(")");
38368 Ok(())
38369 }
38370}
38371
38372impl Default for Generator {
38373 fn default() -> Self {
38374 Self::new()
38375 }
38376}
38377
38378#[cfg(test)]
38379mod tests {
38380 use super::*;
38381 use crate::parser::Parser;
38382
38383 fn roundtrip(sql: &str) -> String {
38384 let ast = Parser::parse_sql(sql).unwrap();
38385 Generator::sql(&ast[0]).unwrap()
38386 }
38387
38388 #[test]
38389 fn test_simple_select() {
38390 let result = roundtrip("SELECT 1");
38391 assert_eq!(result, "SELECT 1");
38392 }
38393
38394 #[test]
38395 fn test_select_from() {
38396 let result = roundtrip("SELECT a, b FROM t");
38397 assert_eq!(result, "SELECT a, b FROM t");
38398 }
38399
38400 #[test]
38401 fn test_select_where() {
38402 let result = roundtrip("SELECT * FROM t WHERE x = 1");
38403 assert_eq!(result, "SELECT * FROM t WHERE x = 1");
38404 }
38405
38406 #[test]
38407 fn test_select_join() {
38408 let result = roundtrip("SELECT * FROM a JOIN b ON a.id = b.id");
38409 assert_eq!(result, "SELECT * FROM a JOIN b ON a.id = b.id");
38410 }
38411
38412 #[test]
38413 fn test_insert() {
38414 let result = roundtrip("INSERT INTO t (a, b) VALUES (1, 2)");
38415 assert_eq!(result, "INSERT INTO t (a, b) VALUES (1, 2)");
38416 }
38417
38418 #[test]
38419 fn test_pretty_print() {
38420 let ast = Parser::parse_sql("SELECT a, b FROM t WHERE x = 1").unwrap();
38421 let result = Generator::pretty_sql(&ast[0]).unwrap();
38422 assert!(result.contains('\n'));
38423 }
38424
38425 #[test]
38426 fn test_window_function() {
38427 let result = roundtrip("SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)");
38428 assert_eq!(
38429 result,
38430 "SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)"
38431 );
38432 }
38433
38434 #[test]
38435 fn test_window_function_with_frame() {
38436 let result = roundtrip("SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
38437 assert_eq!(result, "SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
38438 }
38439
38440 #[test]
38441 fn test_aggregate_with_filter() {
38442 let result = roundtrip("SELECT COUNT(*) FILTER (WHERE status = 1) FROM orders");
38443 assert_eq!(
38444 result,
38445 "SELECT COUNT(*) FILTER(WHERE status = 1) FROM orders"
38446 );
38447 }
38448
38449 #[test]
38450 fn test_subscript() {
38451 let result = roundtrip("SELECT arr[0]");
38452 assert_eq!(result, "SELECT arr[0]");
38453 }
38454
38455 #[test]
38457 fn test_create_table() {
38458 let result = roundtrip("CREATE TABLE users (id INT, name VARCHAR(100))");
38459 assert_eq!(result, "CREATE TABLE users (id INT, name VARCHAR(100))");
38460 }
38461
38462 #[test]
38463 fn test_create_table_with_constraints() {
38464 let result = roundtrip(
38465 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)",
38466 );
38467 assert_eq!(
38468 result,
38469 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)"
38470 );
38471 }
38472
38473 #[test]
38474 fn test_create_table_if_not_exists() {
38475 let result = roundtrip("CREATE TABLE IF NOT EXISTS t (id INT)");
38476 assert_eq!(result, "CREATE TABLE IF NOT EXISTS t (id INT)");
38477 }
38478
38479 #[test]
38480 fn test_drop_table() {
38481 let result = roundtrip("DROP TABLE users");
38482 assert_eq!(result, "DROP TABLE users");
38483 }
38484
38485 #[test]
38486 fn test_drop_table_if_exists_cascade() {
38487 let result = roundtrip("DROP TABLE IF EXISTS users CASCADE");
38488 assert_eq!(result, "DROP TABLE IF EXISTS users CASCADE");
38489 }
38490
38491 #[test]
38492 fn test_alter_table_add_column() {
38493 let result = roundtrip("ALTER TABLE users ADD COLUMN email VARCHAR(255)");
38494 assert_eq!(result, "ALTER TABLE users ADD COLUMN email VARCHAR(255)");
38495 }
38496
38497 #[test]
38498 fn test_alter_table_drop_column() {
38499 let result = roundtrip("ALTER TABLE users DROP COLUMN email");
38500 assert_eq!(result, "ALTER TABLE users DROP COLUMN email");
38501 }
38502
38503 #[test]
38504 fn test_create_index() {
38505 let result = roundtrip("CREATE INDEX idx_name ON users(name)");
38506 assert_eq!(result, "CREATE INDEX idx_name ON users(name)");
38507 }
38508
38509 #[test]
38510 fn test_create_unique_index() {
38511 let result = roundtrip("CREATE UNIQUE INDEX idx_email ON users(email)");
38512 assert_eq!(result, "CREATE UNIQUE INDEX idx_email ON users(email)");
38513 }
38514
38515 #[test]
38516 fn test_drop_index() {
38517 let result = roundtrip("DROP INDEX idx_name");
38518 assert_eq!(result, "DROP INDEX idx_name");
38519 }
38520
38521 #[test]
38522 fn test_create_view() {
38523 let result = roundtrip("CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1");
38524 assert_eq!(
38525 result,
38526 "CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1"
38527 );
38528 }
38529
38530 #[test]
38531 fn test_drop_view() {
38532 let result = roundtrip("DROP VIEW active_users");
38533 assert_eq!(result, "DROP VIEW active_users");
38534 }
38535
38536 #[test]
38537 fn test_truncate() {
38538 let result = roundtrip("TRUNCATE TABLE users");
38539 assert_eq!(result, "TRUNCATE TABLE users");
38540 }
38541
38542 #[test]
38543 fn test_string_literal_escaping_default() {
38544 let result = roundtrip("SELECT 'hello'");
38546 assert_eq!(result, "SELECT 'hello'");
38547
38548 let result = roundtrip("SELECT 'it''s a test'");
38550 assert_eq!(result, "SELECT 'it''s a test'");
38551 }
38552
38553 #[test]
38554 fn test_not_in_style_prefix_default_generic() {
38555 let result = roundtrip("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')");
38556 assert_eq!(
38557 result,
38558 "SELECT id FROM users WHERE NOT status IN ('deleted', 'banned')"
38559 );
38560 }
38561
38562 #[test]
38563 fn test_not_in_style_infix_generic_override() {
38564 let ast =
38565 Parser::parse_sql("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')")
38566 .unwrap();
38567 let config = GeneratorConfig {
38568 not_in_style: NotInStyle::Infix,
38569 ..Default::default()
38570 };
38571 let mut gen = Generator::with_config(config);
38572 let result = gen.generate(&ast[0]).unwrap();
38573 assert_eq!(
38574 result,
38575 "SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')"
38576 );
38577 }
38578
38579 #[test]
38580 fn test_string_literal_escaping_mysql() {
38581 use crate::dialects::DialectType;
38582
38583 let config = GeneratorConfig {
38584 dialect: Some(DialectType::MySQL),
38585 ..Default::default()
38586 };
38587
38588 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
38589 let mut gen = Generator::with_config(config.clone());
38590 let result = gen.generate(&ast[0]).unwrap();
38591 assert_eq!(result, "SELECT 'hello'");
38592
38593 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
38595 let mut gen = Generator::with_config(config.clone());
38596 let result = gen.generate(&ast[0]).unwrap();
38597 assert_eq!(result, "SELECT 'it''s'");
38598 }
38599
38600 #[test]
38601 fn test_string_literal_escaping_postgres() {
38602 use crate::dialects::DialectType;
38603
38604 let config = GeneratorConfig {
38605 dialect: Some(DialectType::PostgreSQL),
38606 ..Default::default()
38607 };
38608
38609 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
38610 let mut gen = Generator::with_config(config.clone());
38611 let result = gen.generate(&ast[0]).unwrap();
38612 assert_eq!(result, "SELECT 'hello'");
38613
38614 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
38616 let mut gen = Generator::with_config(config.clone());
38617 let result = gen.generate(&ast[0]).unwrap();
38618 assert_eq!(result, "SELECT 'it''s'");
38619 }
38620
38621 #[test]
38622 fn test_string_literal_escaping_bigquery() {
38623 use crate::dialects::DialectType;
38624
38625 let config = GeneratorConfig {
38626 dialect: Some(DialectType::BigQuery),
38627 ..Default::default()
38628 };
38629
38630 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
38631 let mut gen = Generator::with_config(config.clone());
38632 let result = gen.generate(&ast[0]).unwrap();
38633 assert_eq!(result, "SELECT 'hello'");
38634
38635 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
38637 let mut gen = Generator::with_config(config.clone());
38638 let result = gen.generate(&ast[0]).unwrap();
38639 assert_eq!(result, "SELECT 'it\\'s'");
38640 }
38641
38642 #[test]
38643 fn test_generate_deep_and_chain_without_stack_growth() {
38644 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
38645 Expression::column("c0"),
38646 Expression::number(0),
38647 )));
38648
38649 for i in 1..2500 {
38650 let predicate = Expression::Eq(Box::new(BinaryOp::new(
38651 Expression::column(format!("c{i}")),
38652 Expression::number(i as i64),
38653 )));
38654 expr = Expression::And(Box::new(BinaryOp::new(expr, predicate)));
38655 }
38656
38657 let sql = Generator::sql(&expr).expect("deep AND chain should generate");
38658 assert!(sql.contains("c2499 = 2499"), "{}", sql);
38659 }
38660
38661 #[test]
38662 fn test_generate_deep_or_chain_without_stack_growth() {
38663 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
38664 Expression::column("c0"),
38665 Expression::number(0),
38666 )));
38667
38668 for i in 1..2500 {
38669 let predicate = Expression::Eq(Box::new(BinaryOp::new(
38670 Expression::column(format!("c{i}")),
38671 Expression::number(i as i64),
38672 )));
38673 expr = Expression::Or(Box::new(BinaryOp::new(expr, predicate)));
38674 }
38675
38676 let sql = Generator::sql(&expr).expect("deep OR chain should generate");
38677 assert!(sql.contains("c2499 = 2499"), "{}", sql);
38678 }
38679}