1use std::borrow::Cow;
14use std::sync::Arc;
15
16use crate::error::Result;
17use crate::expressions::*;
18use crate::guard::{enforce_generate_ast, ComplexityGuardOptions};
19use crate::DialectType;
20use serde::{Deserialize, Serialize};
21
22pub struct Generator {
47 config: Arc<GeneratorConfig>,
48 output: String,
49 unsupported_messages: Vec<String>,
50 indent_level: usize,
51 athena_hive_context: bool,
54 sqlite_inline_pk_columns: std::collections::HashSet<String>,
56 merge_strip_qualifiers: Vec<String>,
58 clickhouse_nullable_depth: i32,
63}
64
65#[derive(Debug, Clone, Copy, PartialEq, Default)]
71pub enum NormalizeFunctions {
72 #[default]
74 Upper,
75 Lower,
77 None,
79}
80
81#[derive(Debug, Clone, Copy, PartialEq, Default)]
83pub enum LimitFetchStyle {
84 #[default]
86 Limit,
87 Top,
89 FetchFirst,
91}
92
93#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
95pub enum NotInStyle {
96 #[default]
98 Prefix,
99 Infix,
101}
102
103#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
105#[serde(rename_all = "lowercase")]
106pub enum UnsupportedLevel {
107 Ignore,
109 #[default]
111 Warn,
112 Raise,
114 Immediate,
116}
117
118#[derive(Debug, Clone, Copy, PartialEq, Eq)]
119enum ConnectorOperator {
120 And,
121 Or,
122}
123
124impl ConnectorOperator {
125 fn keyword(self) -> &'static str {
126 match self {
127 Self::And => "AND",
128 Self::Or => "OR",
129 }
130 }
131}
132
133#[derive(Debug, Clone, PartialEq, Eq)]
134enum TsqlDatePart {
135 Native(String),
136 Epoch,
137 IsoDayOfWeek,
138 Unsupported(String),
139}
140
141#[derive(Debug, Clone, Copy, PartialEq)]
143pub struct IdentifierQuoteStyle {
144 pub start: char,
146 pub end: char,
148}
149
150impl Default for IdentifierQuoteStyle {
151 fn default() -> Self {
152 Self {
153 start: '"',
154 end: '"',
155 }
156 }
157}
158
159impl IdentifierQuoteStyle {
160 pub const DOUBLE_QUOTE: Self = Self {
162 start: '"',
163 end: '"',
164 };
165 pub const BACKTICK: Self = Self {
167 start: '`',
168 end: '`',
169 };
170 pub const BRACKET: Self = Self {
172 start: '[',
173 end: ']',
174 };
175}
176
177#[derive(Debug, Clone)]
199pub struct GeneratorConfig {
200 pub pretty: bool,
203 pub indent: &'static str,
205 pub max_text_width: usize,
207 pub identifier_quote: char,
209 pub identifier_quote_style: IdentifierQuoteStyle,
211 pub uppercase_keywords: bool,
213 pub normalize_identifiers: bool,
215 pub dialect: Option<crate::dialects::DialectType>,
217 pub source_dialect: Option<crate::dialects::DialectType>,
219 pub unsupported_level: UnsupportedLevel,
221 pub max_unsupported: usize,
223 pub complexity_guard: ComplexityGuardOptions,
225 pub normalize_functions: NormalizeFunctions,
227 pub string_escape: char,
229 pub case_sensitive_identifiers: bool,
231 pub identifiers_can_start_with_digit: bool,
233 pub always_quote_identifiers: bool,
236 pub not_in_style: NotInStyle,
238
239 pub null_ordering_supported: bool,
243 pub ignore_nulls_in_func: bool,
246 pub nvl2_supported: bool,
248
249 pub limit_fetch_style: LimitFetchStyle,
252 pub limit_is_top: bool,
254 pub limit_only_literals: bool,
256
257 pub single_string_interval: bool,
260 pub interval_allows_plural_form: bool,
262
263 pub cte_recursive_keyword_required: bool,
266
267 pub values_as_table: bool,
270 pub wrap_derived_values: bool,
272
273 pub tablesample_seed_keyword: &'static str,
276 pub tablesample_requires_parens: bool,
278 pub tablesample_size_is_rows: bool,
280 pub tablesample_keywords: &'static str,
282 pub tablesample_with_method: bool,
284 pub alias_post_tablesample: bool,
286
287 pub aggregate_filter_supported: bool,
290 pub multi_arg_distinct: bool,
292 pub quantified_no_paren_space: bool,
294 pub supports_median: bool,
296
297 pub supports_select_into: bool,
300 pub locking_reads_supported: bool,
302
303 pub rename_table_with_db: bool,
306 pub semi_anti_join_with_side: bool,
308 pub supports_table_alias_columns: bool,
310 pub join_hints: bool,
312 pub table_hints: bool,
314 pub query_hints: bool,
316 pub query_hint_sep: &'static str,
318 pub supports_column_join_marks: bool,
320
321 pub index_using_no_space: bool,
325 pub supports_unlogged_tables: bool,
327 pub supports_create_table_like: bool,
329 pub like_property_inside_schema: bool,
331 pub alter_table_include_column_keyword: bool,
333 pub supports_table_copy: bool,
335 pub alter_set_type: &'static str,
337 pub alter_set_wrapped: bool,
339
340 pub tz_to_with_time_zone: bool,
343 pub supports_convert_timezone: bool,
345
346 pub json_type_required_for_extraction: bool,
349 pub json_path_bracketed_key_supported: bool,
351 pub json_path_single_quote_escape: bool,
353 pub quote_json_path: bool,
355 pub json_key_value_pair_sep: &'static str,
357
358 pub copy_params_are_wrapped: bool,
361 pub copy_params_eq_required: bool,
363 pub copy_has_into_keyword: bool,
365
366 pub supports_window_exclude: bool,
369 pub unnest_with_ordinality: bool,
371 pub lowercase_window_frame_keywords: bool,
374 pub normalize_window_frame_between: bool,
377
378 pub array_concat_is_var_len: bool,
381 pub array_size_dim_required: Option<bool>,
384 pub can_implement_array_any: bool,
386 pub array_size_name: &'static str,
388
389 pub supports_between_flags: bool,
392
393 pub is_bool_allowed: bool,
396 pub ensure_bools: bool,
398
399 pub extract_allows_quotes: bool,
402 pub normalize_extract_date_parts: bool,
404
405 pub try_supported: bool,
408 pub supports_uescape: bool,
410 pub supports_to_number: bool,
412 pub supports_single_arg_concat: bool,
414 pub last_day_supports_date_part: bool,
416 pub supports_exploding_projections: bool,
418 pub supports_unix_seconds: bool,
420 pub supports_like_quantifiers: bool,
422 pub supports_decode_case: bool,
424 pub set_op_modifiers: bool,
426 pub update_statement_supports_from: bool,
428
429 pub collate_is_func: bool,
432
433 pub duplicate_key_update_with_set: bool,
436 pub insert_overwrite: &'static str,
438
439 pub returning_end: bool,
442
443 pub matched_by_source: bool,
446
447 pub create_function_return_as: bool,
450 pub parameter_default_equals: bool,
452
453 pub computed_column_with_type: bool,
456
457 pub unpivot_aliases_are_identifiers: bool,
460
461 pub star_except: &'static str,
464
465 pub hex_func: &'static str,
468
469 pub with_properties_prefix: &'static str,
472
473 pub pad_fill_pattern_is_required: bool,
476
477 pub index_on: &'static str,
480
481 pub groupings_sep: &'static str,
484
485 pub struct_delimiter: (&'static str, &'static str),
488 pub struct_curly_brace_notation: bool,
490 pub array_bracket_only: bool,
492 pub struct_field_sep: &'static str,
494
495 pub except_intersect_support_all_clause: bool,
498
499 pub parameter_token: &'static str,
502 pub named_placeholder_token: &'static str,
504
505 pub data_type_specifiers_allowed: bool,
508
509 pub schema_comment_with_eq: bool,
513}
514
515impl Default for GeneratorConfig {
516 fn default() -> Self {
517 Self {
518 pretty: false,
520 indent: " ",
521 max_text_width: 80,
522 identifier_quote: '"',
523 identifier_quote_style: IdentifierQuoteStyle::DOUBLE_QUOTE,
524 uppercase_keywords: true,
525 normalize_identifiers: false,
526 dialect: None,
527 source_dialect: None,
528 unsupported_level: UnsupportedLevel::Warn,
529 max_unsupported: 3,
530 complexity_guard: ComplexityGuardOptions::default(),
531 normalize_functions: NormalizeFunctions::Upper,
532 string_escape: '\'',
533 case_sensitive_identifiers: false,
534 identifiers_can_start_with_digit: false,
535 always_quote_identifiers: false,
536 not_in_style: NotInStyle::Prefix,
537
538 null_ordering_supported: true,
540 ignore_nulls_in_func: false,
541 nvl2_supported: true,
542
543 limit_fetch_style: LimitFetchStyle::Limit,
545 limit_is_top: false,
546 limit_only_literals: false,
547
548 single_string_interval: false,
550 interval_allows_plural_form: true,
551
552 cte_recursive_keyword_required: true,
554
555 values_as_table: true,
557 wrap_derived_values: true,
558
559 tablesample_seed_keyword: "SEED",
561 tablesample_requires_parens: true,
562 tablesample_size_is_rows: true,
563 tablesample_keywords: "TABLESAMPLE",
564 tablesample_with_method: true,
565 alias_post_tablesample: false,
566
567 aggregate_filter_supported: true,
569 multi_arg_distinct: true,
570 quantified_no_paren_space: false,
571 supports_median: true,
572
573 supports_select_into: false,
575 locking_reads_supported: true,
576
577 rename_table_with_db: true,
579 semi_anti_join_with_side: true,
580 supports_table_alias_columns: true,
581 join_hints: true,
582 table_hints: true,
583 query_hints: true,
584 query_hint_sep: ", ",
585 supports_column_join_marks: false,
586
587 index_using_no_space: false,
589 supports_unlogged_tables: false,
590 supports_create_table_like: true,
591 like_property_inside_schema: false,
592 alter_table_include_column_keyword: true,
593 supports_table_copy: true,
594 alter_set_type: "SET DATA TYPE",
595 alter_set_wrapped: false,
596
597 tz_to_with_time_zone: false,
599 supports_convert_timezone: false,
600
601 json_type_required_for_extraction: false,
603 json_path_bracketed_key_supported: true,
604 json_path_single_quote_escape: false,
605 quote_json_path: true,
606 json_key_value_pair_sep: ":",
607
608 copy_params_are_wrapped: true,
610 copy_params_eq_required: false,
611 copy_has_into_keyword: true,
612
613 supports_window_exclude: false,
615 unnest_with_ordinality: true,
616 lowercase_window_frame_keywords: false,
617 normalize_window_frame_between: false,
618
619 array_concat_is_var_len: true,
621 array_size_dim_required: None,
622 can_implement_array_any: false,
623 array_size_name: "ARRAY_LENGTH",
624
625 supports_between_flags: false,
627
628 is_bool_allowed: true,
630 ensure_bools: false,
631
632 extract_allows_quotes: true,
634 normalize_extract_date_parts: false,
635
636 try_supported: true,
638 supports_uescape: true,
639 supports_to_number: true,
640 supports_single_arg_concat: true,
641 last_day_supports_date_part: true,
642 supports_exploding_projections: true,
643 supports_unix_seconds: false,
644 supports_like_quantifiers: true,
645 supports_decode_case: true,
646 set_op_modifiers: true,
647 update_statement_supports_from: true,
648
649 collate_is_func: false,
651
652 duplicate_key_update_with_set: true,
654 insert_overwrite: " OVERWRITE TABLE",
655
656 returning_end: true,
658
659 matched_by_source: true,
661
662 create_function_return_as: true,
664 parameter_default_equals: false,
665
666 computed_column_with_type: true,
668
669 unpivot_aliases_are_identifiers: true,
671
672 star_except: "EXCEPT",
674
675 hex_func: "HEX",
677
678 with_properties_prefix: "WITH",
680
681 pad_fill_pattern_is_required: false,
683
684 index_on: "ON",
686
687 groupings_sep: ",",
689
690 struct_delimiter: ("<", ">"),
692 struct_curly_brace_notation: false,
693 array_bracket_only: false,
694 struct_field_sep: " ",
695
696 except_intersect_support_all_clause: true,
698
699 parameter_token: "@",
701 named_placeholder_token: ":",
702
703 data_type_specifiers_allowed: false,
705
706 schema_comment_with_eq: true,
708 }
709 }
710}
711
712mod reserved_keywords {
715 use std::collections::HashSet;
716 use std::sync::LazyLock;
717
718 pub static SQL_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
720 [
721 "all",
722 "alter",
723 "and",
724 "any",
725 "array",
726 "as",
727 "asc",
728 "at",
729 "authorization",
730 "begin",
731 "between",
732 "both",
733 "by",
734 "case",
735 "cast",
736 "check",
737 "collate",
738 "column",
739 "commit",
740 "constraint",
741 "create",
742 "cross",
743 "cube",
744 "current",
745 "current_date",
746 "current_time",
747 "current_timestamp",
748 "current_user",
749 "default",
750 "delete",
751 "desc",
752 "distinct",
753 "drop",
754 "else",
755 "end",
756 "escape",
757 "except",
758 "execute",
759 "exists",
760 "external",
761 "false",
762 "fetch",
763 "filter",
764 "for",
765 "foreign",
766 "from",
767 "full",
768 "function",
769 "grant",
770 "group",
771 "grouping",
772 "having",
773 "if",
774 "in",
775 "index",
776 "inner",
777 "insert",
778 "intersect",
779 "interval",
780 "into",
781 "is",
782 "join",
783 "key",
784 "leading",
785 "left",
786 "like",
787 "limit",
788 "local",
789 "localtime",
790 "localtimestamp",
791 "match",
792 "merge",
793 "natural",
794 "no",
795 "not",
796 "null",
797 "of",
798 "offset",
799 "on",
800 "only",
801 "or",
802 "order",
803 "outer",
804 "over",
805 "partition",
806 "primary",
807 "procedure",
808 "range",
809 "references",
810 "right",
811 "rollback",
812 "rollup",
813 "row",
814 "rows",
815 "select",
816 "session_user",
817 "set",
818 "some",
819 "table",
820 "tablesample",
821 "then",
822 "to",
823 "trailing",
824 "true",
825 "truncate",
826 "union",
827 "unique",
828 "unknown",
829 "update",
830 "user",
831 "using",
832 "values",
833 "view",
834 "when",
835 "where",
836 "window",
837 "with",
838 ]
839 .into_iter()
840 .collect()
841 });
842
843 pub static BIGQUERY_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
846 let mut set = SQL_RESERVED.clone();
847 set.extend([
848 "assert_rows_modified",
849 "at",
850 "contains",
851 "cube",
852 "current",
853 "define",
854 "enum",
855 "escape",
856 "exclude",
857 "following",
858 "for",
859 "groups",
860 "hash",
861 "ignore",
862 "lateral",
863 "lookup",
864 "new",
865 "no",
866 "nulls",
867 "of",
868 "over",
869 "preceding",
870 "proto",
871 "qualify",
872 "recursive",
873 "respect",
874 "struct",
875 "tablesample",
876 "treat",
877 "unbounded",
878 "unnest",
879 "window",
880 "within",
881 ]);
882 set.remove("grant");
884 set.remove("key");
885 set.remove("index");
886 set.remove("offset");
887 set.remove("values");
888 set.remove("table");
889 set
890 });
891
892 pub static MYSQL_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
894 let mut set = SQL_RESERVED.clone();
895 set.extend([
896 "accessible",
897 "add",
898 "analyze",
899 "asensitive",
900 "before",
901 "bigint",
902 "binary",
903 "blob",
904 "call",
905 "cascade",
906 "change",
907 "char",
908 "character",
909 "condition",
910 "continue",
911 "convert",
912 "current_date",
913 "current_time",
914 "current_timestamp",
915 "current_user",
916 "cursor",
917 "database",
918 "databases",
919 "day_hour",
920 "day_microsecond",
921 "day_minute",
922 "day_second",
923 "dec",
924 "decimal",
925 "declare",
926 "delayed",
927 "describe",
928 "deterministic",
929 "distinctrow",
930 "div",
931 "double",
932 "dual",
933 "each",
934 "elseif",
935 "enclosed",
936 "escaped",
937 "exit",
938 "explain",
939 "float",
940 "float4",
941 "float8",
942 "force",
943 "get",
944 "high_priority",
945 "hour_microsecond",
946 "hour_minute",
947 "hour_second",
948 "ignore",
949 "infile",
950 "inout",
951 "insensitive",
952 "int",
953 "int1",
954 "int2",
955 "int3",
956 "int4",
957 "int8",
958 "integer",
959 "iterate",
960 "keys",
961 "kill",
962 "leave",
963 "linear",
964 "lines",
965 "load",
966 "lock",
967 "long",
968 "longblob",
969 "longtext",
970 "loop",
971 "low_priority",
972 "master_ssl_verify_server_cert",
973 "maxvalue",
974 "mediumblob",
975 "mediumint",
976 "mediumtext",
977 "middleint",
978 "minute_microsecond",
979 "minute_second",
980 "mod",
981 "modifies",
982 "no_write_to_binlog",
983 "numeric",
984 "optimize",
985 "option",
986 "optionally",
987 "out",
988 "outfile",
989 "precision",
990 "purge",
991 "read",
992 "reads",
993 "real",
994 "regexp",
995 "release",
996 "rename",
997 "repeat",
998 "replace",
999 "require",
1000 "resignal",
1001 "restrict",
1002 "return",
1003 "revoke",
1004 "rlike",
1005 "schema",
1006 "schemas",
1007 "second_microsecond",
1008 "sensitive",
1009 "separator",
1010 "show",
1011 "signal",
1012 "smallint",
1013 "spatial",
1014 "specific",
1015 "sql",
1016 "sql_big_result",
1017 "sql_calc_found_rows",
1018 "sql_small_result",
1019 "sqlexception",
1020 "sqlstate",
1021 "sqlwarning",
1022 "ssl",
1023 "starting",
1024 "straight_join",
1025 "terminated",
1026 "text",
1027 "tinyblob",
1028 "tinyint",
1029 "tinytext",
1030 "trigger",
1031 "undo",
1032 "unlock",
1033 "unsigned",
1034 "usage",
1035 "utc_date",
1036 "utc_time",
1037 "utc_timestamp",
1038 "varbinary",
1039 "varchar",
1040 "varcharacter",
1041 "varying",
1042 "while",
1043 "write",
1044 "xor",
1045 "year_month",
1046 "zerofill",
1047 ]);
1048 set.remove("table");
1049 set
1050 });
1051
1052 pub static DORIS_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1055 let mut set = MYSQL_RESERVED.clone();
1056 set.extend([
1057 "aggregate",
1058 "anti",
1059 "array",
1060 "backend",
1061 "backup",
1062 "begin",
1063 "bitmap",
1064 "boolean",
1065 "broker",
1066 "buckets",
1067 "cached",
1068 "cancel",
1069 "cast",
1070 "catalog",
1071 "charset",
1072 "cluster",
1073 "collation",
1074 "columns",
1075 "comment",
1076 "commit",
1077 "config",
1078 "connection",
1079 "count",
1080 "current",
1081 "data",
1082 "date",
1083 "datetime",
1084 "day",
1085 "deferred",
1086 "distributed",
1087 "dynamic",
1088 "enable",
1089 "end",
1090 "events",
1091 "export",
1092 "external",
1093 "fields",
1094 "first",
1095 "follower",
1096 "format",
1097 "free",
1098 "frontend",
1099 "full",
1100 "functions",
1101 "global",
1102 "grants",
1103 "hash",
1104 "help",
1105 "hour",
1106 "install",
1107 "intermediate",
1108 "json",
1109 "label",
1110 "last",
1111 "less",
1112 "level",
1113 "link",
1114 "local",
1115 "location",
1116 "max",
1117 "merge",
1118 "min",
1119 "minute",
1120 "modify",
1121 "month",
1122 "name",
1123 "names",
1124 "negative",
1125 "nulls",
1126 "observer",
1127 "offset",
1128 "only",
1129 "open",
1130 "overwrite",
1131 "password",
1132 "path",
1133 "plan",
1134 "plugin",
1135 "plugins",
1136 "policy",
1137 "process",
1138 "properties",
1139 "property",
1140 "query",
1141 "quota",
1142 "recover",
1143 "refresh",
1144 "repair",
1145 "replica",
1146 "repository",
1147 "resource",
1148 "restore",
1149 "resume",
1150 "role",
1151 "roles",
1152 "rollback",
1153 "rollup",
1154 "routine",
1155 "sample",
1156 "second",
1157 "semi",
1158 "session",
1159 "signed",
1160 "snapshot",
1161 "start",
1162 "stats",
1163 "status",
1164 "stop",
1165 "stream",
1166 "string",
1167 "sum",
1168 "tables",
1169 "tablet",
1170 "temporary",
1171 "text",
1172 "timestamp",
1173 "transaction",
1174 "trash",
1175 "trim",
1176 "truncate",
1177 "type",
1178 "user",
1179 "value",
1180 "variables",
1181 "verbose",
1182 "version",
1183 "view",
1184 "warnings",
1185 "week",
1186 "work",
1187 "year",
1188 ]);
1189 set
1190 });
1191
1192 pub static POSTGRES_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1194 let mut set = SQL_RESERVED.clone();
1195 set.extend([
1196 "analyse",
1197 "analyze",
1198 "asymmetric",
1199 "binary",
1200 "collation",
1201 "concurrently",
1202 "current_catalog",
1203 "current_role",
1204 "current_schema",
1205 "deferrable",
1206 "do",
1207 "freeze",
1208 "ilike",
1209 "initially",
1210 "isnull",
1211 "lateral",
1212 "notnull",
1213 "placing",
1214 "returning",
1215 "similar",
1216 "symmetric",
1217 "variadic",
1218 "verbose",
1219 ]);
1220 set.remove("default");
1222 set.remove("interval");
1223 set.remove("match");
1224 set.remove("offset");
1225 set.remove("table");
1226 set
1227 });
1228
1229 pub static REDSHIFT_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1233 [
1234 "aes128",
1235 "aes256",
1236 "all",
1237 "allowoverwrite",
1238 "analyse",
1239 "analyze",
1240 "and",
1241 "any",
1242 "array",
1243 "as",
1244 "asc",
1245 "authorization",
1246 "az64",
1247 "backup",
1248 "between",
1249 "binary",
1250 "blanksasnull",
1251 "both",
1252 "bytedict",
1253 "bzip2",
1254 "case",
1255 "cast",
1256 "check",
1257 "collate",
1258 "column",
1259 "constraint",
1260 "create",
1261 "credentials",
1262 "cross",
1263 "current_date",
1264 "current_time",
1265 "current_timestamp",
1266 "current_user",
1267 "current_user_id",
1268 "default",
1269 "deferrable",
1270 "deflate",
1271 "defrag",
1272 "delta",
1273 "delta32k",
1274 "desc",
1275 "disable",
1276 "distinct",
1277 "do",
1278 "else",
1279 "emptyasnull",
1280 "enable",
1281 "encode",
1282 "encrypt",
1283 "encryption",
1284 "end",
1285 "except",
1286 "explicit",
1287 "false",
1288 "for",
1289 "foreign",
1290 "freeze",
1291 "from",
1292 "full",
1293 "globaldict256",
1294 "globaldict64k",
1295 "grant",
1296 "group",
1297 "gzip",
1298 "having",
1299 "identity",
1300 "ignore",
1301 "ilike",
1302 "in",
1303 "initially",
1304 "inner",
1305 "intersect",
1306 "interval",
1307 "into",
1308 "is",
1309 "isnull",
1310 "join",
1311 "leading",
1312 "left",
1313 "like",
1314 "limit",
1315 "localtime",
1316 "localtimestamp",
1317 "lun",
1318 "luns",
1319 "lzo",
1320 "lzop",
1321 "minus",
1322 "mostly16",
1323 "mostly32",
1324 "mostly8",
1325 "natural",
1326 "new",
1327 "not",
1328 "notnull",
1329 "null",
1330 "nulls",
1331 "off",
1332 "offline",
1333 "offset",
1334 "oid",
1335 "old",
1336 "on",
1337 "only",
1338 "open",
1339 "or",
1340 "order",
1341 "outer",
1342 "overlaps",
1343 "parallel",
1344 "partition",
1345 "percent",
1346 "permissions",
1347 "pivot",
1348 "placing",
1349 "primary",
1350 "raw",
1351 "readratio",
1352 "recover",
1353 "references",
1354 "rejectlog",
1355 "resort",
1356 "respect",
1357 "restore",
1358 "right",
1359 "select",
1360 "session_user",
1361 "similar",
1362 "snapshot",
1363 "some",
1364 "sysdate",
1365 "system",
1366 "table",
1367 "tag",
1368 "tdes",
1369 "text255",
1370 "text32k",
1371 "then",
1372 "timestamp",
1373 "to",
1374 "top",
1375 "trailing",
1376 "true",
1377 "truncatecolumns",
1378 "type",
1379 "union",
1380 "unique",
1381 "unnest",
1382 "unpivot",
1383 "user",
1384 "using",
1385 "verbose",
1386 "wallet",
1387 "when",
1388 "where",
1389 "with",
1390 "without",
1391 ]
1392 .into_iter()
1393 .collect()
1394 });
1395
1396 pub static DUCKDB_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1398 let mut set = POSTGRES_RESERVED.clone();
1399 set.extend([
1400 "anti",
1401 "asof",
1402 "columns",
1403 "describe",
1404 "groups",
1405 "macro",
1406 "pivot",
1407 "pivot_longer",
1408 "pivot_wider",
1409 "qualify",
1410 "replace",
1411 "respect",
1412 "semi",
1413 "show",
1414 "table",
1415 "unpivot",
1416 ]);
1417 set.remove("at");
1418 set.remove("key");
1419 set.remove("range");
1420 set.remove("row");
1421 set.remove("values");
1422 set
1423 });
1424
1425 pub static PRESTO_TRINO_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1427 let mut set = SQL_RESERVED.clone();
1428 set.extend([
1429 "alter",
1430 "and",
1431 "as",
1432 "between",
1433 "by",
1434 "case",
1435 "cast",
1436 "constraint",
1437 "create",
1438 "cross",
1439 "cube",
1440 "current_catalog",
1441 "current_date",
1442 "current_path",
1443 "current_role",
1444 "current_schema",
1445 "current_time",
1446 "current_timestamp",
1447 "current_user",
1448 "deallocate",
1449 "delete",
1450 "describe",
1451 "distinct",
1452 "drop",
1453 "else",
1454 "end",
1455 "escape",
1456 "except",
1457 "execute",
1458 "exists",
1459 "extract",
1460 "false",
1461 "for",
1462 "from",
1463 "full",
1464 "group",
1465 "grouping",
1466 "having",
1467 "in",
1468 "inner",
1469 "insert",
1470 "intersect",
1471 "into",
1472 "is",
1473 "join",
1474 "json_array",
1475 "json_exists",
1476 "json_object",
1477 "json_query",
1478 "json_table",
1479 "json_value",
1480 "left",
1481 "like",
1482 "listagg",
1483 "localtime",
1484 "localtimestamp",
1485 "natural",
1486 "normalize",
1487 "not",
1488 "null",
1489 "on",
1490 "or",
1491 "order",
1492 "outer",
1493 "prepare",
1494 "recursive",
1495 "right",
1496 "rollup",
1497 "select",
1498 "skip",
1499 "table",
1500 "then",
1501 "trim",
1502 "true",
1503 "uescape",
1504 "union",
1505 "unnest",
1506 "using",
1507 "values",
1508 "when",
1509 "where",
1510 "with",
1511 ]);
1512 set.remove("key");
1514 set
1515 });
1516
1517 pub static STARROCKS_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1520 [
1521 "add",
1522 "all",
1523 "alter",
1524 "analyze",
1525 "and",
1526 "array",
1527 "as",
1528 "asc",
1529 "between",
1530 "bigint",
1531 "bitmap",
1532 "both",
1533 "by",
1534 "case",
1535 "char",
1536 "character",
1537 "check",
1538 "collate",
1539 "column",
1540 "compaction",
1541 "convert",
1542 "create",
1543 "cross",
1544 "cube",
1545 "current_date",
1546 "current_role",
1547 "current_time",
1548 "current_timestamp",
1549 "current_user",
1550 "database",
1551 "databases",
1552 "decimal",
1553 "decimalv2",
1554 "decimal32",
1555 "decimal64",
1556 "decimal128",
1557 "default",
1558 "deferred",
1559 "delete",
1560 "dense_rank",
1561 "desc",
1562 "describe",
1563 "distinct",
1564 "double",
1565 "drop",
1566 "dual",
1567 "else",
1568 "except",
1569 "exists",
1570 "explain",
1571 "false",
1572 "first_value",
1573 "float",
1574 "for",
1575 "force",
1576 "from",
1577 "full",
1578 "function",
1579 "grant",
1580 "group",
1581 "grouping",
1582 "grouping_id",
1583 "groups",
1584 "having",
1585 "hll",
1586 "host",
1587 "if",
1588 "ignore",
1589 "immediate",
1590 "in",
1591 "index",
1592 "infile",
1593 "inner",
1594 "insert",
1595 "int",
1596 "integer",
1597 "intersect",
1598 "into",
1599 "is",
1600 "join",
1601 "json",
1602 "key",
1603 "keys",
1604 "kill",
1605 "lag",
1606 "largeint",
1607 "last_value",
1608 "lateral",
1609 "lead",
1610 "left",
1611 "like",
1612 "limit",
1613 "load",
1614 "localtime",
1615 "localtimestamp",
1616 "maxvalue",
1617 "minus",
1618 "mod",
1619 "not",
1620 "ntile",
1621 "null",
1622 "on",
1623 "or",
1624 "order",
1625 "outer",
1626 "outfile",
1627 "over",
1628 "partition",
1629 "percentile",
1630 "primary",
1631 "procedure",
1632 "qualify",
1633 "range",
1634 "rank",
1635 "read",
1636 "regexp",
1637 "release",
1638 "rename",
1639 "replace",
1640 "revoke",
1641 "right",
1642 "rlike",
1643 "row",
1644 "row_number",
1645 "rows",
1646 "schema",
1647 "schemas",
1648 "select",
1649 "set",
1650 "set_var",
1651 "show",
1652 "smallint",
1653 "system",
1654 "table",
1655 "terminated",
1656 "text",
1657 "then",
1658 "tinyint",
1659 "to",
1660 "true",
1661 "union",
1662 "unique",
1663 "unsigned",
1664 "update",
1665 "use",
1666 "using",
1667 "values",
1668 "varchar",
1669 "when",
1670 "where",
1671 "with",
1672 ]
1673 .into_iter()
1674 .collect()
1675 });
1676
1677 pub static SINGLESTORE_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1680 let mut set = MYSQL_RESERVED.clone();
1681 set.extend([
1682 "abs",
1685 "account",
1686 "acos",
1687 "adddate",
1688 "addtime",
1689 "admin",
1690 "aes_decrypt",
1691 "aes_encrypt",
1692 "aggregate",
1693 "aggregates",
1694 "aggregator",
1695 "anti_join",
1696 "any_value",
1697 "approx_count_distinct",
1698 "approx_percentile",
1699 "arrange",
1700 "arrangement",
1701 "asin",
1702 "atan",
1703 "atan2",
1704 "attach",
1705 "autostats",
1706 "avro",
1707 "background",
1708 "backup",
1709 "batch",
1710 "batches",
1711 "boot_strapping",
1712 "ceil",
1713 "ceiling",
1714 "coercibility",
1715 "columnar",
1716 "columnstore",
1717 "compile",
1718 "concurrent",
1719 "connection_id",
1720 "cos",
1721 "cot",
1722 "current_security_groups",
1723 "current_security_roles",
1724 "dayname",
1725 "dayofmonth",
1726 "dayofweek",
1727 "dayofyear",
1728 "degrees",
1729 "dot_product",
1730 "dump",
1731 "durability",
1732 "earliest",
1733 "echo",
1734 "election",
1735 "euclidean_distance",
1736 "exp",
1737 "extractor",
1738 "extractors",
1739 "floor",
1740 "foreground",
1741 "found_rows",
1742 "from_base64",
1743 "from_days",
1744 "from_unixtime",
1745 "fs",
1746 "fulltext",
1747 "gc",
1748 "gcs",
1749 "geography",
1750 "geography_area",
1751 "geography_contains",
1752 "geography_distance",
1753 "geography_intersects",
1754 "geography_latitude",
1755 "geography_length",
1756 "geography_longitude",
1757 "geographypoint",
1758 "geography_point",
1759 "geography_within_distance",
1760 "geometry",
1761 "geometry_area",
1762 "geometry_contains",
1763 "geometry_distance",
1764 "geometry_filter",
1765 "geometry_intersects",
1766 "geometry_length",
1767 "geometrypoint",
1768 "geometry_point",
1769 "geometry_within_distance",
1770 "geometry_x",
1771 "geometry_y",
1772 "greatest",
1773 "groups",
1774 "group_concat",
1775 "gzip",
1776 "hdfs",
1777 "hex",
1778 "highlight",
1779 "ifnull",
1780 "ilike",
1781 "inet_aton",
1782 "inet_ntoa",
1783 "inet6_aton",
1784 "inet6_ntoa",
1785 "initcap",
1786 "instr",
1787 "interpreter_mode",
1788 "isnull",
1789 "json",
1790 "json_agg",
1791 "json_array_contains_double",
1792 "json_array_contains_json",
1793 "json_array_contains_string",
1794 "json_delete_key",
1795 "json_extract_double",
1796 "json_extract_json",
1797 "json_extract_string",
1798 "json_extract_bigint",
1799 "json_get_type",
1800 "json_length",
1801 "json_set_double",
1802 "json_set_json",
1803 "json_set_string",
1804 "kafka",
1805 "lag",
1806 "last_day",
1807 "last_insert_id",
1808 "latest",
1809 "lcase",
1810 "lead",
1811 "leaf",
1812 "least",
1813 "leaves",
1814 "length",
1815 "license",
1816 "links",
1817 "llvm",
1818 "ln",
1819 "load",
1820 "locate",
1821 "log",
1822 "log10",
1823 "log2",
1824 "lpad",
1825 "lz4",
1826 "management",
1827 "match",
1828 "mbc",
1829 "md5",
1830 "median",
1831 "memsql",
1832 "memsql_deserialize",
1833 "memsql_serialize",
1834 "metadata",
1835 "microsecond",
1836 "minute",
1837 "model",
1838 "monthname",
1839 "months_between",
1840 "mpl",
1841 "namespace",
1842 "node",
1843 "noparam",
1844 "now",
1845 "nth_value",
1846 "ntile",
1847 "nullcols",
1848 "nullif",
1849 "object",
1850 "octet_length",
1851 "offsets",
1852 "online",
1853 "optimizer",
1854 "orphan",
1855 "parquet",
1856 "partitions",
1857 "pause",
1858 "percentile_cont",
1859 "percentile_disc",
1860 "periodic",
1861 "persisted",
1862 "pi",
1863 "pipeline",
1864 "pipelines",
1865 "plancache",
1866 "plugins",
1867 "pool",
1868 "pools",
1869 "pow",
1870 "power",
1871 "process",
1872 "processlist",
1873 "profile",
1874 "profiles",
1875 "quarter",
1876 "queries",
1877 "query",
1878 "radians",
1879 "rand",
1880 "record",
1881 "reduce",
1882 "redundancy",
1883 "regexp_match",
1884 "regexp_substr",
1885 "remote",
1886 "replication",
1887 "resource",
1888 "resource_pool",
1889 "restore",
1890 "retry",
1891 "role",
1892 "roles",
1893 "round",
1894 "rpad",
1895 "rtrim",
1896 "running",
1897 "s3",
1898 "scalar",
1899 "sec_to_time",
1900 "second",
1901 "security_lists_intersect",
1902 "semi_join",
1903 "sha",
1904 "sha1",
1905 "sha2",
1906 "shard",
1907 "sharded",
1908 "sharded_id",
1909 "sigmoid",
1910 "sign",
1911 "sin",
1912 "skip",
1913 "sleep",
1914 "snapshot",
1915 "soname",
1916 "sparse",
1917 "spatial_check_index",
1918 "split",
1919 "sqrt",
1920 "standalone",
1921 "std",
1922 "stddev",
1923 "stddev_pop",
1924 "stddev_samp",
1925 "stop",
1926 "str_to_date",
1927 "subdate",
1928 "substr",
1929 "substring_index",
1930 "success",
1931 "synchronize",
1932 "table_checksum",
1933 "tan",
1934 "task",
1935 "timediff",
1936 "time_bucket",
1937 "time_format",
1938 "time_to_sec",
1939 "timestampadd",
1940 "timestampdiff",
1941 "to_base64",
1942 "to_char",
1943 "to_date",
1944 "to_days",
1945 "to_json",
1946 "to_number",
1947 "to_seconds",
1948 "to_timestamp",
1949 "tracelogs",
1950 "transform",
1951 "trim",
1952 "trunc",
1953 "truncate",
1954 "ucase",
1955 "unhex",
1956 "unix_timestamp",
1957 "utc_date",
1958 "utc_time",
1959 "utc_timestamp",
1960 "vacuum",
1961 "variance",
1962 "var_pop",
1963 "var_samp",
1964 "vector_sub",
1965 "voting",
1966 "week",
1967 "weekday",
1968 "weekofyear",
1969 "workload",
1970 "year",
1971 ]);
1972 set.remove("all");
1974 set
1975 });
1976
1977 pub static SQLITE_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1981 [
1983 "abort",
1984 "action",
1985 "add",
1986 "after",
1987 "all",
1988 "alter",
1989 "always",
1990 "analyze",
1991 "and",
1992 "as",
1993 "asc",
1994 "attach",
1995 "autoincrement",
1996 "before",
1997 "begin",
1998 "between",
1999 "by",
2000 "cascade",
2001 "case",
2002 "cast",
2003 "check",
2004 "collate",
2005 "column",
2006 "commit",
2007 "conflict",
2008 "constraint",
2009 "create",
2010 "cross",
2011 "current",
2012 "current_date",
2013 "current_time",
2014 "current_timestamp",
2015 "database",
2016 "default",
2017 "deferrable",
2018 "deferred",
2019 "delete",
2020 "desc",
2021 "detach",
2022 "distinct",
2023 "do",
2024 "drop",
2025 "each",
2026 "else",
2027 "end",
2028 "escape",
2029 "except",
2030 "exclude",
2031 "exclusive",
2032 "exists",
2033 "explain",
2034 "fail",
2035 "filter",
2036 "first",
2037 "following",
2038 "for",
2039 "foreign",
2040 "from",
2041 "full",
2042 "generated",
2043 "glob",
2044 "group",
2045 "groups",
2046 "having",
2047 "if",
2048 "ignore",
2049 "immediate",
2050 "in",
2051 "index",
2052 "indexed",
2053 "initially",
2054 "inner",
2055 "insert",
2056 "instead",
2057 "intersect",
2058 "into",
2059 "is",
2060 "isnull",
2061 "join",
2062 "key",
2063 "last",
2064 "left",
2065 "like",
2066 "limit",
2067 "natural",
2068 "no",
2069 "not",
2070 "nothing",
2071 "notnull",
2072 "null",
2073 "nulls",
2074 "of",
2075 "offset",
2076 "on",
2077 "or",
2078 "order",
2079 "others",
2080 "outer",
2081 "partition",
2082 "plan",
2083 "pragma",
2084 "preceding",
2085 "primary",
2086 "query",
2087 "raise",
2088 "range",
2089 "recursive",
2090 "references",
2091 "regexp",
2092 "reindex",
2093 "release",
2094 "rename",
2095 "replace",
2096 "restrict",
2097 "returning",
2098 "right",
2099 "rollback",
2100 "row",
2101 "rows",
2102 "savepoint",
2103 "select",
2104 "set",
2105 "table",
2106 "temp",
2107 "temporary",
2108 "then",
2109 "ties",
2110 "to",
2111 "transaction",
2112 "trigger",
2113 "unbounded",
2114 "union",
2115 "unique",
2116 "update",
2117 "using",
2118 "vacuum",
2119 "values",
2120 "view",
2121 "virtual",
2122 "when",
2123 "where",
2124 "window",
2125 "with",
2126 "without",
2127 ]
2128 .into_iter()
2129 .collect()
2130 });
2131}
2132
2133impl Generator {
2134 pub fn new() -> Self {
2140 Self::with_config(GeneratorConfig::default())
2141 }
2142
2143 pub fn with_config(config: GeneratorConfig) -> Self {
2148 Self::with_arc_config(Arc::new(config))
2149 }
2150
2151 pub(crate) fn with_arc_config(config: Arc<GeneratorConfig>) -> Self {
2156 Self {
2157 config,
2158 output: String::new(),
2159 unsupported_messages: Vec::new(),
2160 indent_level: 0,
2161 athena_hive_context: false,
2162 sqlite_inline_pk_columns: std::collections::HashSet::new(),
2163 merge_strip_qualifiers: Vec::new(),
2164 clickhouse_nullable_depth: 0,
2165 }
2166 }
2167
2168 fn add_column_aliases_to_query(expr: Expression) -> Expression {
2172 match expr {
2173 Expression::Select(mut select) => {
2174 select.expressions = select
2176 .expressions
2177 .into_iter()
2178 .map(|e| Self::add_alias_to_expression(e))
2179 .collect();
2180
2181 if let Some(ref mut from) = select.from {
2183 from.expressions = from
2184 .expressions
2185 .iter()
2186 .cloned()
2187 .map(|e| Self::add_column_aliases_to_query(e))
2188 .collect();
2189 }
2190
2191 Expression::Select(select)
2192 }
2193 Expression::Subquery(mut sq) => {
2194 sq.this = Self::add_column_aliases_to_query(sq.this);
2195 Expression::Subquery(sq)
2196 }
2197 Expression::Paren(mut p) => {
2198 p.this = Self::add_column_aliases_to_query(p.this);
2199 Expression::Paren(p)
2200 }
2201 other => other,
2203 }
2204 }
2205
2206 fn add_alias_to_expression(expr: Expression) -> Expression {
2209 use crate::expressions::Alias;
2210
2211 match &expr {
2212 Expression::Alias(_) => expr,
2214
2215 Expression::Column(col) => Expression::Alias(Box::new(Alias {
2217 this: expr.clone(),
2218 alias: col.name.clone(),
2219 column_aliases: Vec::new(),
2220 alias_explicit_as: false,
2221 alias_keyword: None,
2222 pre_alias_comments: Vec::new(),
2223 trailing_comments: Vec::new(),
2224 inferred_type: None,
2225 })),
2226
2227 Expression::Identifier(ident) => Expression::Alias(Box::new(Alias {
2229 this: expr.clone(),
2230 alias: ident.clone(),
2231 column_aliases: Vec::new(),
2232 alias_explicit_as: false,
2233 alias_keyword: None,
2234 pre_alias_comments: Vec::new(),
2235 trailing_comments: Vec::new(),
2236 inferred_type: None,
2237 })),
2238
2239 Expression::Subquery(sq) => {
2241 let processed = Self::add_column_aliases_to_query(Expression::Subquery(sq.clone()));
2242 if sq.alias.is_some() {
2244 processed
2245 } else {
2246 processed
2248 }
2249 }
2250
2251 Expression::Star(_) => expr,
2253
2254 _ => expr,
2257 }
2258 }
2259
2260 fn try_evaluate_constant(expr: &Expression) -> Option<i64> {
2264 match expr {
2265 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
2266 let Literal::Number(n) = lit.as_ref() else {
2267 unreachable!()
2268 };
2269 n.parse::<i64>().ok()
2270 }
2271 Expression::Add(op) => {
2272 let left = Self::try_evaluate_constant(&op.left)?;
2273 let right = Self::try_evaluate_constant(&op.right)?;
2274 Some(left + right)
2275 }
2276 Expression::Sub(op) => {
2277 let left = Self::try_evaluate_constant(&op.left)?;
2278 let right = Self::try_evaluate_constant(&op.right)?;
2279 Some(left - right)
2280 }
2281 Expression::Mul(op) => {
2282 let left = Self::try_evaluate_constant(&op.left)?;
2283 let right = Self::try_evaluate_constant(&op.right)?;
2284 Some(left * right)
2285 }
2286 Expression::Div(op) => {
2287 let left = Self::try_evaluate_constant(&op.left)?;
2288 let right = Self::try_evaluate_constant(&op.right)?;
2289 if right != 0 {
2290 Some(left / right)
2291 } else {
2292 None
2293 }
2294 }
2295 Expression::Paren(p) => Self::try_evaluate_constant(&p.this),
2296 _ => None,
2297 }
2298 }
2299
2300 fn is_reserved_keyword(&self, name: &str) -> bool {
2302 use crate::dialects::DialectType;
2303 let mut buf = [0u8; 128];
2304 let lower_ref: &str = if name.len() <= 128 {
2305 for (i, b) in name.bytes().enumerate() {
2306 buf[i] = b.to_ascii_lowercase();
2307 }
2308 std::str::from_utf8(&buf[..name.len()]).unwrap_or(name)
2310 } else {
2311 return false;
2312 };
2313
2314 match self.config.dialect {
2315 Some(DialectType::BigQuery) => reserved_keywords::BIGQUERY_RESERVED.contains(lower_ref),
2316 Some(DialectType::MySQL) | Some(DialectType::TiDB) => {
2317 reserved_keywords::MYSQL_RESERVED.contains(lower_ref)
2318 }
2319 Some(DialectType::Doris) => reserved_keywords::DORIS_RESERVED.contains(lower_ref),
2320 Some(DialectType::SingleStore) => {
2321 reserved_keywords::SINGLESTORE_RESERVED.contains(lower_ref)
2322 }
2323 Some(DialectType::StarRocks) => {
2324 reserved_keywords::STARROCKS_RESERVED.contains(lower_ref)
2325 }
2326 Some(DialectType::PostgreSQL)
2327 | Some(DialectType::CockroachDB)
2328 | Some(DialectType::Materialize)
2329 | Some(DialectType::RisingWave) => {
2330 reserved_keywords::POSTGRES_RESERVED.contains(lower_ref)
2331 }
2332 Some(DialectType::Redshift) => reserved_keywords::REDSHIFT_RESERVED.contains(lower_ref),
2333 Some(DialectType::Snowflake) => false,
2336 Some(DialectType::ClickHouse) => false,
2338 Some(DialectType::DuckDB) => reserved_keywords::DUCKDB_RESERVED.contains(lower_ref),
2339 Some(DialectType::Teradata) => false,
2341 Some(DialectType::TSQL)
2343 | Some(DialectType::Fabric)
2344 | Some(DialectType::Oracle)
2345 | Some(DialectType::Spark)
2346 | Some(DialectType::Databricks)
2347 | Some(DialectType::Hive)
2348 | Some(DialectType::Solr) => false,
2349 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
2350 reserved_keywords::PRESTO_TRINO_RESERVED.contains(lower_ref)
2351 }
2352 Some(DialectType::SQLite) => reserved_keywords::SQLITE_RESERVED.contains(lower_ref),
2353 Some(DialectType::Generic) | None => false,
2355 _ => reserved_keywords::SQL_RESERVED.contains(lower_ref),
2357 }
2358 }
2359
2360 fn normalize_func_name<'a>(&self, name: &'a str) -> Cow<'a, str> {
2362 match self.config.normalize_functions {
2363 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
2364 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
2365 NormalizeFunctions::None => Cow::Borrowed(name),
2366 }
2367 }
2368
2369 pub fn generate(&mut self, expr: &Expression) -> Result<String> {
2378 self.output.clear();
2379 self.unsupported_messages.clear();
2380 enforce_generate_ast(expr, &self.config.complexity_guard)?;
2381 self.generate_expression(expr)?;
2382 if self.config.unsupported_level == UnsupportedLevel::Raise
2383 && !self.unsupported_messages.is_empty()
2384 {
2385 return Err(crate::error::Error::generate(
2386 self.format_unsupported_messages(),
2387 ));
2388 }
2389 Ok(std::mem::take(&mut self.output))
2390 }
2391
2392 pub fn unsupported_messages(&self) -> &[String] {
2394 &self.unsupported_messages
2395 }
2396
2397 fn unsupported(&mut self, message: impl Into<String>) -> Result<()> {
2398 let message = message.into();
2399 if self.config.unsupported_level == UnsupportedLevel::Immediate {
2400 return Err(crate::error::Error::generate(message));
2401 }
2402 self.unsupported_messages.push(message);
2403 Ok(())
2404 }
2405
2406 fn write_unsupported_comment(&mut self, message: &str) -> Result<()> {
2407 self.unsupported(message.to_string())?;
2408 self.write("/* ");
2409 self.write(message);
2410 self.write(" */");
2411 Ok(())
2412 }
2413
2414 fn format_unsupported_messages(&self) -> String {
2415 let limit = self.config.max_unsupported.max(1);
2416 if self.unsupported_messages.len() <= limit {
2417 return self.unsupported_messages.join("; ");
2418 }
2419
2420 let mut messages = self
2421 .unsupported_messages
2422 .iter()
2423 .take(limit)
2424 .cloned()
2425 .collect::<Vec<_>>();
2426 messages.push(format!(
2427 "... and {} more",
2428 self.unsupported_messages.len() - limit
2429 ));
2430 messages.join("; ")
2431 }
2432
2433 pub fn sql(expr: &Expression) -> Result<String> {
2439 let mut gen = Generator::new();
2440 gen.generate(expr)
2441 }
2442
2443 pub fn pretty_sql(expr: &Expression) -> Result<String> {
2448 let config = GeneratorConfig {
2449 pretty: true,
2450 ..Default::default()
2451 };
2452 let mut gen = Generator::with_config(config);
2453 let mut sql = gen.generate(expr)?;
2454 if !sql.ends_with(';') {
2456 sql.push(';');
2457 }
2458 Ok(sql)
2459 }
2460
2461 fn generate_expression(&mut self, expr: &Expression) -> Result<()> {
2462 #[cfg(feature = "stacker")]
2463 {
2464 let red_zone = if cfg!(debug_assertions) {
2465 4 * 1024 * 1024
2466 } else {
2467 1024 * 1024
2468 };
2469 stacker::maybe_grow(red_zone, 8 * 1024 * 1024, || {
2470 self.generate_expression_inner(expr)
2471 })
2472 }
2473 #[cfg(not(feature = "stacker"))]
2474 {
2475 self.generate_expression_inner(expr)
2476 }
2477 }
2478
2479 fn generate_expression_inner(&mut self, expr: &Expression) -> Result<()> {
2480 match expr {
2481 Expression::Select(select) => self.generate_select(select),
2482 Expression::Union(union) => self.generate_union(union),
2483 Expression::Intersect(intersect) => self.generate_intersect(intersect),
2484 Expression::Except(except) => self.generate_except(except),
2485 Expression::Insert(insert) => self.generate_insert(insert),
2486 Expression::Update(update) => self.generate_update(update),
2487 Expression::Delete(delete) => self.generate_delete(delete),
2488 Expression::Literal(lit) => self.generate_literal(lit),
2489 Expression::Boolean(b) => self.generate_boolean(b),
2490 Expression::Null(_) => {
2491 self.write_keyword("NULL");
2492 Ok(())
2493 }
2494 Expression::Identifier(id) => self.generate_identifier(id),
2495 Expression::Column(col) => self.generate_column(col),
2496 Expression::Pseudocolumn(pc) => self.generate_pseudocolumn(pc),
2497 Expression::Connect(c) => self.generate_connect_expr(c),
2498 Expression::Prior(p) => self.generate_prior(p),
2499 Expression::ConnectByRoot(cbr) => self.generate_connect_by_root(cbr),
2500 Expression::MatchRecognize(mr) => self.generate_match_recognize(mr),
2501 Expression::Table(table) => self.generate_table(table),
2502 Expression::StageReference(sr) => self.generate_stage_reference(sr),
2503 Expression::HistoricalData(hd) => self.generate_historical_data(hd),
2504 Expression::JoinedTable(jt) => self.generate_joined_table(jt),
2505 Expression::Star(star) => self.generate_star(star),
2506 Expression::BracedWildcard(expr) => self.generate_braced_wildcard(expr),
2507 Expression::Alias(alias) => self.generate_alias(alias),
2508 Expression::Cast(cast) => self.generate_cast(cast),
2509 Expression::Collation(coll) => self.generate_collation(coll),
2510 Expression::Case(case) => self.generate_case(case),
2511 Expression::Function(func) => self.generate_function(func),
2512 Expression::FunctionEmits(fe) => self.generate_function_emits(fe),
2513 Expression::AggregateFunction(func) => self.generate_aggregate_function(func),
2514 Expression::WindowFunction(wf) => self.generate_window_function(wf),
2515 Expression::WithinGroup(wg) => self.generate_within_group(wg),
2516 Expression::Interval(interval) => self.generate_interval(interval),
2517
2518 Expression::ConcatWs(f) => self.generate_concat_ws(f),
2520 Expression::Substring(f) => self.generate_substring(f),
2521 Expression::Upper(f) => self.generate_unary_func("UPPER", f),
2522 Expression::Lower(f) => self.generate_unary_func("LOWER", f),
2523 Expression::Length(f) => {
2524 let name = match self.config.dialect {
2525 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "LEN",
2526 _ => "LENGTH",
2527 };
2528 self.generate_unary_func(name, f)
2529 }
2530 Expression::Trim(f) => self.generate_trim(f),
2531 Expression::LTrim(f) => self.generate_simple_func("LTRIM", &f.this),
2532 Expression::RTrim(f) => self.generate_simple_func("RTRIM", &f.this),
2533 Expression::Replace(f) => self.generate_replace(f),
2534 Expression::Reverse(f) => self.generate_simple_func("REVERSE", &f.this),
2535 Expression::Left(f) => self.generate_left_right("LEFT", f),
2536 Expression::Right(f) => self.generate_left_right("RIGHT", f),
2537 Expression::Repeat(f) => self.generate_repeat(f),
2538 Expression::Lpad(f) => self.generate_pad("LPAD", f),
2539 Expression::Rpad(f) => self.generate_pad("RPAD", f),
2540 Expression::Split(f) => self.generate_split(f),
2541 Expression::RegexpLike(f) => self.generate_regexp_like(f),
2542 Expression::RegexpReplace(f) => self.generate_regexp_replace(f),
2543 Expression::RegexpExtract(f) => self.generate_regexp_extract(f),
2544 Expression::Overlay(f) => self.generate_overlay(f),
2545
2546 Expression::Abs(f) => self.generate_simple_func("ABS", &f.this),
2548 Expression::Round(f) => self.generate_round(f),
2549 Expression::Floor(f) => self.generate_floor(f),
2550 Expression::Ceil(f) => self.generate_ceil(f),
2551 Expression::Power(f) => self.generate_power(f),
2552 Expression::Sqrt(f) => self.generate_sqrt_cbrt(f, "SQRT", "|/"),
2553 Expression::Cbrt(f) => self.generate_sqrt_cbrt(f, "CBRT", "||/"),
2554 Expression::Ln(f) => self.generate_simple_func("LN", &f.this),
2555 Expression::Log(f) => self.generate_log(f),
2556 Expression::Exp(f) => self.generate_simple_func("EXP", &f.this),
2557 Expression::Sign(f) => self.generate_simple_func("SIGN", &f.this),
2558 Expression::Greatest(f) => self.generate_vararg_func("GREATEST", &f.expressions),
2559 Expression::Least(f) => self.generate_vararg_func("LEAST", &f.expressions),
2560
2561 Expression::CurrentDate(_) => {
2563 self.write_keyword("CURRENT_DATE");
2564 Ok(())
2565 }
2566 Expression::CurrentTime(f) => self.generate_current_time(f),
2567 Expression::CurrentTimestamp(f) => self.generate_current_timestamp(f),
2568 Expression::AtTimeZone(f) => self.generate_at_time_zone(f),
2569 Expression::DateAdd(f) => self.generate_date_add(f, "DATE_ADD"),
2570 Expression::DateSub(f) => self.generate_date_add(f, "DATE_SUB"),
2571 Expression::DateDiff(f) => self.generate_datediff(f),
2572 Expression::DateTrunc(f) => self.generate_date_trunc(f),
2573 Expression::Extract(f) => self.generate_extract(f),
2574 Expression::ToDate(f) => self.generate_to_date(f),
2575 Expression::ToTimestamp(f) => self.generate_to_timestamp(f),
2576
2577 Expression::Coalesce(f) => {
2579 let func_name = f.original_name.as_deref().unwrap_or("COALESCE");
2581 self.generate_vararg_func(func_name, &f.expressions)
2582 }
2583 Expression::NullIf(f) => self.generate_binary_func("NULLIF", &f.this, &f.expression),
2584 Expression::IfFunc(f) => self.generate_if_func(f),
2585 Expression::IfNull(f) => self.generate_ifnull(f),
2586 Expression::Nvl(f) => self.generate_nvl(f),
2587 Expression::Nvl2(f) => self.generate_nvl2(f),
2588
2589 Expression::TryCast(cast) => self.generate_try_cast(cast),
2591 Expression::SafeCast(cast) => self.generate_safe_cast(cast),
2592
2593 Expression::Count(f) => self.generate_count(f),
2595 Expression::Sum(f) => self.generate_agg_func("SUM", f),
2596 Expression::Avg(f) => self.generate_agg_func("AVG", f),
2597 Expression::Min(f) => self.generate_agg_func("MIN", f),
2598 Expression::Max(f) => self.generate_agg_func("MAX", f),
2599 Expression::GroupConcat(f) => self.generate_group_concat(f),
2600 Expression::StringAgg(f) => self.generate_string_agg(f),
2601 Expression::ListAgg(f) => self.generate_listagg(f),
2602 Expression::ArrayAgg(f) => {
2603 let override_name = f
2606 .name
2607 .as_ref()
2608 .filter(|n| !n.eq_ignore_ascii_case("ARRAY_AGG"))
2609 .map(|n| n.to_ascii_uppercase());
2610 match override_name {
2611 Some(name) => self.generate_agg_func(&name, f),
2612 None => self.generate_agg_func("ARRAY_AGG", f),
2613 }
2614 }
2615 Expression::ArrayConcatAgg(f) => self.generate_agg_func("ARRAY_CONCAT_AGG", f),
2616 Expression::CountIf(f) => self.generate_agg_func("COUNT_IF", f),
2617 Expression::SumIf(f) => self.generate_sum_if(f),
2618 Expression::Stddev(f) => self.generate_agg_func("STDDEV", f),
2619 Expression::StddevPop(f) => self.generate_agg_func("STDDEV_POP", f),
2620 Expression::StddevSamp(f) => self.generate_stddev_samp(f),
2621 Expression::Variance(f) => self.generate_agg_func("VARIANCE", f),
2622 Expression::VarPop(f) => {
2623 let name = if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
2624 "VARIANCE_POP"
2625 } else {
2626 "VAR_POP"
2627 };
2628 self.generate_agg_func(name, f)
2629 }
2630 Expression::VarSamp(f) => self.generate_agg_func("VAR_SAMP", f),
2631 Expression::Skewness(f) => {
2632 let name = match self.config.dialect {
2633 Some(DialectType::Snowflake) => "SKEW",
2634 _ => "SKEWNESS",
2635 };
2636 self.generate_agg_func(name, f)
2637 }
2638 Expression::Median(f) => self.generate_agg_func("MEDIAN", f),
2639 Expression::Mode(f) => self.generate_agg_func("MODE", f),
2640 Expression::First(f) => self.generate_agg_func_with_ignore_nulls_bool("FIRST", f),
2641 Expression::Last(f) => self.generate_agg_func_with_ignore_nulls_bool("LAST", f),
2642 Expression::AnyValue(f) => self.generate_agg_func("ANY_VALUE", f),
2643 Expression::ApproxDistinct(f) => {
2644 match self.config.dialect {
2645 Some(DialectType::Hive)
2646 | Some(DialectType::Spark)
2647 | Some(DialectType::Databricks)
2648 | Some(DialectType::BigQuery) => {
2649 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2651 }
2652 Some(DialectType::Redshift) => {
2653 self.write_keyword("APPROXIMATE COUNT");
2655 self.write("(");
2656 self.write_keyword("DISTINCT");
2657 self.write(" ");
2658 self.generate_expression(&f.this)?;
2659 self.write(")");
2660 Ok(())
2661 }
2662 _ => self.generate_agg_func("APPROX_DISTINCT", f),
2663 }
2664 }
2665 Expression::ApproxCountDistinct(f) => {
2666 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2667 }
2668 Expression::ApproxPercentile(f) => self.generate_approx_percentile(f),
2669 Expression::Percentile(f) => self.generate_percentile("PERCENTILE", f),
2670 Expression::LogicalAnd(f) => {
2671 let name = match self.config.dialect {
2672 Some(DialectType::Snowflake) => "BOOLAND_AGG",
2673 Some(DialectType::Spark)
2674 | Some(DialectType::Databricks)
2675 | Some(DialectType::PostgreSQL)
2676 | Some(DialectType::DuckDB)
2677 | Some(DialectType::Redshift) => "BOOL_AND",
2678 Some(DialectType::Oracle)
2679 | Some(DialectType::SQLite)
2680 | Some(DialectType::MySQL) => "MIN",
2681 _ => "BOOL_AND",
2682 };
2683 self.generate_agg_func(name, f)
2684 }
2685 Expression::LogicalOr(f) => {
2686 let name = match self.config.dialect {
2687 Some(DialectType::Snowflake) => "BOOLOR_AGG",
2688 Some(DialectType::Spark)
2689 | Some(DialectType::Databricks)
2690 | Some(DialectType::PostgreSQL)
2691 | Some(DialectType::DuckDB)
2692 | Some(DialectType::Redshift) => "BOOL_OR",
2693 Some(DialectType::Oracle)
2694 | Some(DialectType::SQLite)
2695 | Some(DialectType::MySQL) => "MAX",
2696 _ => "BOOL_OR",
2697 };
2698 self.generate_agg_func(name, f)
2699 }
2700
2701 Expression::RowNumber(_) => {
2703 if self.config.dialect == Some(DialectType::ClickHouse) {
2704 self.write("row_number");
2705 } else {
2706 self.write_keyword("ROW_NUMBER");
2707 }
2708 self.write("()");
2709 Ok(())
2710 }
2711 Expression::Rank(r) => {
2712 self.write_keyword("RANK");
2713 self.write("(");
2714 if !r.args.is_empty() {
2716 for (i, arg) in r.args.iter().enumerate() {
2717 if i > 0 {
2718 self.write(", ");
2719 }
2720 self.generate_expression(arg)?;
2721 }
2722 } else if let Some(order_by) = &r.order_by {
2723 self.write_keyword(" ORDER BY ");
2725 for (i, ob) in order_by.iter().enumerate() {
2726 if i > 0 {
2727 self.write(", ");
2728 }
2729 self.generate_ordered(ob)?;
2730 }
2731 }
2732 self.write(")");
2733 Ok(())
2734 }
2735 Expression::DenseRank(dr) => {
2736 self.write_keyword("DENSE_RANK");
2737 self.write("(");
2738 for (i, arg) in dr.args.iter().enumerate() {
2740 if i > 0 {
2741 self.write(", ");
2742 }
2743 self.generate_expression(arg)?;
2744 }
2745 self.write(")");
2746 Ok(())
2747 }
2748 Expression::NTile(f) => self.generate_ntile(f),
2749 Expression::Lead(f) => self.generate_lead_lag("LEAD", f),
2750 Expression::Lag(f) => self.generate_lead_lag("LAG", f),
2751 Expression::FirstValue(f) => {
2752 self.generate_value_func_with_ignore_nulls_bool("FIRST_VALUE", f)
2753 }
2754 Expression::LastValue(f) => {
2755 self.generate_value_func_with_ignore_nulls_bool("LAST_VALUE", f)
2756 }
2757 Expression::NthValue(f) => self.generate_nth_value(f),
2758 Expression::PercentRank(pr) => {
2759 self.write_keyword("PERCENT_RANK");
2760 self.write("(");
2761 if !pr.args.is_empty() {
2763 for (i, arg) in pr.args.iter().enumerate() {
2764 if i > 0 {
2765 self.write(", ");
2766 }
2767 self.generate_expression(arg)?;
2768 }
2769 } else if let Some(order_by) = &pr.order_by {
2770 self.write_keyword(" ORDER BY ");
2772 for (i, ob) in order_by.iter().enumerate() {
2773 if i > 0 {
2774 self.write(", ");
2775 }
2776 self.generate_ordered(ob)?;
2777 }
2778 }
2779 self.write(")");
2780 Ok(())
2781 }
2782 Expression::CumeDist(cd) => {
2783 self.write_keyword("CUME_DIST");
2784 self.write("(");
2785 if !cd.args.is_empty() {
2787 for (i, arg) in cd.args.iter().enumerate() {
2788 if i > 0 {
2789 self.write(", ");
2790 }
2791 self.generate_expression(arg)?;
2792 }
2793 } else if let Some(order_by) = &cd.order_by {
2794 self.write_keyword(" ORDER BY ");
2796 for (i, ob) in order_by.iter().enumerate() {
2797 if i > 0 {
2798 self.write(", ");
2799 }
2800 self.generate_ordered(ob)?;
2801 }
2802 }
2803 self.write(")");
2804 Ok(())
2805 }
2806 Expression::PercentileCont(f) => self.generate_percentile("PERCENTILE_CONT", f),
2807 Expression::PercentileDisc(f) => self.generate_percentile("PERCENTILE_DISC", f),
2808
2809 Expression::Contains(f) => {
2811 self.generate_binary_func("CONTAINS", &f.this, &f.expression)
2812 }
2813 Expression::StartsWith(f) => {
2814 let name = match self.config.dialect {
2815 Some(DialectType::Spark) | Some(DialectType::Databricks) => "STARTSWITH",
2816 _ => "STARTS_WITH",
2817 };
2818 self.generate_binary_func(name, &f.this, &f.expression)
2819 }
2820 Expression::EndsWith(f) => {
2821 let name = match self.config.dialect {
2822 Some(DialectType::Snowflake) => "ENDSWITH",
2823 Some(DialectType::Spark) | Some(DialectType::Databricks) => "ENDSWITH",
2824 Some(DialectType::ClickHouse) => "endsWith",
2825 _ => "ENDS_WITH",
2826 };
2827 self.generate_binary_func(name, &f.this, &f.expression)
2828 }
2829 Expression::Position(f) => self.generate_position(f),
2830 Expression::Initcap(f) => match self.config.dialect {
2831 Some(DialectType::Presto)
2832 | Some(DialectType::Trino)
2833 | Some(DialectType::Athena) => {
2834 self.write_keyword("REGEXP_REPLACE");
2835 self.write("(");
2836 self.generate_expression(&f.this)?;
2837 self.write(", '(\\w)(\\w*)', x -> UPPER(x[1]) || LOWER(x[2]))");
2838 Ok(())
2839 }
2840 _ => self.generate_simple_func("INITCAP", &f.this),
2841 },
2842 Expression::Ascii(f) => self.generate_simple_func("ASCII", &f.this),
2843 Expression::Chr(f) => self.generate_simple_func("CHR", &f.this),
2844 Expression::CharFunc(f) => self.generate_char_func(f),
2845 Expression::Soundex(f) => self.generate_simple_func("SOUNDEX", &f.this),
2846 Expression::Levenshtein(f) => {
2847 self.generate_binary_func("LEVENSHTEIN", &f.this, &f.expression)
2848 }
2849
2850 Expression::ModFunc(f) => self.generate_mod_func(f),
2852 Expression::Random(_) => {
2853 self.write_keyword("RANDOM");
2854 self.write("()");
2855 Ok(())
2856 }
2857 Expression::Rand(f) => self.generate_rand(f),
2858 Expression::TruncFunc(f) => self.generate_truncate_func(f),
2859 Expression::Pi(_) => {
2860 self.write_keyword("PI");
2861 self.write("()");
2862 Ok(())
2863 }
2864 Expression::Radians(f) => self.generate_simple_func("RADIANS", &f.this),
2865 Expression::Degrees(f) => self.generate_simple_func("DEGREES", &f.this),
2866 Expression::Sin(f) => self.generate_simple_func("SIN", &f.this),
2867 Expression::Cos(f) => self.generate_simple_func("COS", &f.this),
2868 Expression::Tan(f) => self.generate_simple_func("TAN", &f.this),
2869 Expression::Asin(f) => self.generate_simple_func("ASIN", &f.this),
2870 Expression::Acos(f) => self.generate_simple_func("ACOS", &f.this),
2871 Expression::Atan(f) => self.generate_simple_func("ATAN", &f.this),
2872 Expression::Atan2(f) => {
2873 let name = f.original_name.as_deref().unwrap_or("ATAN2");
2874 self.generate_binary_func(name, &f.this, &f.expression)
2875 }
2876
2877 Expression::Decode(f) => self.generate_decode(f),
2879
2880 Expression::DateFormat(f) => self.generate_date_format("DATE_FORMAT", f),
2882 Expression::FormatDate(f) => self.generate_date_format("FORMAT_DATE", f),
2883 Expression::Year(f) => self.generate_simple_func("YEAR", &f.this),
2884 Expression::Month(f) => self.generate_simple_func("MONTH", &f.this),
2885 Expression::Day(f) => self.generate_simple_func("DAY", &f.this),
2886 Expression::Hour(f) => self.generate_simple_func("HOUR", &f.this),
2887 Expression::Minute(f) => self.generate_simple_func("MINUTE", &f.this),
2888 Expression::Second(f) => self.generate_simple_func("SECOND", &f.this),
2889 Expression::DayOfWeek(f) => {
2890 let name = match self.config.dialect {
2891 Some(DialectType::Presto)
2892 | Some(DialectType::Trino)
2893 | Some(DialectType::Athena) => "DAY_OF_WEEK",
2894 Some(DialectType::DuckDB) => "ISODOW",
2895 _ => "DAYOFWEEK",
2896 };
2897 self.generate_simple_func(name, &f.this)
2898 }
2899 Expression::DayOfMonth(f) => {
2900 let name = match self.config.dialect {
2901 Some(DialectType::Presto)
2902 | Some(DialectType::Trino)
2903 | Some(DialectType::Athena) => "DAY_OF_MONTH",
2904 _ => "DAYOFMONTH",
2905 };
2906 self.generate_simple_func(name, &f.this)
2907 }
2908 Expression::DayOfYear(f) => {
2909 let name = match self.config.dialect {
2910 Some(DialectType::Presto)
2911 | Some(DialectType::Trino)
2912 | Some(DialectType::Athena) => "DAY_OF_YEAR",
2913 _ => "DAYOFYEAR",
2914 };
2915 self.generate_simple_func(name, &f.this)
2916 }
2917 Expression::WeekOfYear(f) => {
2918 let name = match self.config.dialect {
2920 Some(DialectType::Hive)
2921 | Some(DialectType::DuckDB)
2922 | Some(DialectType::Spark)
2923 | Some(DialectType::Databricks)
2924 | Some(DialectType::MySQL) => "WEEKOFYEAR",
2925 _ => "WEEK_OF_YEAR",
2926 };
2927 self.generate_simple_func(name, &f.this)
2928 }
2929 Expression::Quarter(f) => self.generate_simple_func("QUARTER", &f.this),
2930 Expression::AddMonths(f) => {
2931 self.generate_binary_func("ADD_MONTHS", &f.this, &f.expression)
2932 }
2933 Expression::MonthsBetween(f) => {
2934 self.generate_binary_func("MONTHS_BETWEEN", &f.this, &f.expression)
2935 }
2936 Expression::LastDay(f) => self.generate_last_day(f),
2937 Expression::NextDay(f) => self.generate_binary_func("NEXT_DAY", &f.this, &f.expression),
2938 Expression::Epoch(f) => self.generate_simple_func("EPOCH", &f.this),
2939 Expression::EpochMs(f) => self.generate_simple_func("EPOCH_MS", &f.this),
2940 Expression::FromUnixtime(f) => self.generate_from_unixtime(f),
2941 Expression::UnixTimestamp(f) => self.generate_unix_timestamp(f),
2942 Expression::MakeDate(f) => self.generate_make_date(f),
2943 Expression::MakeTimestamp(f) => self.generate_make_timestamp(f),
2944 Expression::TimestampTrunc(f) => self.generate_date_trunc(f),
2945
2946 Expression::ArrayFunc(f) => self.generate_array_constructor(f),
2948 Expression::ArrayLength(f) => self.generate_simple_func("ARRAY_LENGTH", &f.this),
2949 Expression::ArraySize(f) => self.generate_simple_func("ARRAY_SIZE", &f.this),
2950 Expression::Cardinality(f) => self.generate_simple_func("CARDINALITY", &f.this),
2951 Expression::ArrayContains(f) => {
2952 self.generate_binary_func("ARRAY_CONTAINS", &f.this, &f.expression)
2953 }
2954 Expression::ArrayPosition(f) => {
2955 self.generate_binary_func("ARRAY_POSITION", &f.this, &f.expression)
2956 }
2957 Expression::ArrayAppend(f) => {
2958 self.generate_binary_func("ARRAY_APPEND", &f.this, &f.expression)
2959 }
2960 Expression::ArrayPrepend(f) => {
2961 self.generate_binary_func("ARRAY_PREPEND", &f.this, &f.expression)
2962 }
2963 Expression::ArrayConcat(f) => self.generate_vararg_func("ARRAY_CONCAT", &f.expressions),
2964 Expression::ArraySort(f) => self.generate_array_sort(f),
2965 Expression::ArrayReverse(f) => self.generate_simple_func("ARRAY_REVERSE", &f.this),
2966 Expression::ArrayDistinct(f) => self.generate_simple_func("ARRAY_DISTINCT", &f.this),
2967 Expression::ArrayJoin(f) => self.generate_array_join("ARRAY_JOIN", f),
2968 Expression::ArrayToString(f) => self.generate_array_join("ARRAY_TO_STRING", f),
2969 Expression::Unnest(f) => self.generate_unnest(f),
2970 Expression::Explode(f) => self.generate_simple_func("EXPLODE", &f.this),
2971 Expression::ExplodeOuter(f) => self.generate_simple_func("EXPLODE_OUTER", &f.this),
2972 Expression::ArrayFilter(f) => self.generate_array_filter(f),
2973 Expression::ArrayTransform(f) => self.generate_array_transform(f),
2974 Expression::ArrayFlatten(f) => self.generate_simple_func("FLATTEN", &f.this),
2975 Expression::ArrayCompact(f) => {
2976 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
2977 self.write("LIST_FILTER(");
2979 self.generate_expression(&f.this)?;
2980 self.write(", _u -> NOT _u IS NULL)");
2981 Ok(())
2982 } else {
2983 self.generate_simple_func("ARRAY_COMPACT", &f.this)
2984 }
2985 }
2986 Expression::ArrayIntersect(f) => {
2987 let func_name = f.original_name.as_deref().unwrap_or("ARRAY_INTERSECT");
2988 self.generate_vararg_func(func_name, &f.expressions)
2989 }
2990 Expression::ArrayUnion(f) => {
2991 self.generate_binary_func("ARRAY_UNION", &f.this, &f.expression)
2992 }
2993 Expression::ArrayExcept(f) => {
2994 self.generate_binary_func("ARRAY_EXCEPT", &f.this, &f.expression)
2995 }
2996 Expression::ArrayRemove(f) => {
2997 self.generate_binary_func("ARRAY_REMOVE", &f.this, &f.expression)
2998 }
2999 Expression::ArrayZip(f) => self.generate_vararg_func("ARRAYS_ZIP", &f.expressions),
3000 Expression::Sequence(f) => self.generate_sequence("SEQUENCE", f),
3001 Expression::Generate(f) => self.generate_sequence("GENERATE_SERIES", f),
3002
3003 Expression::StructFunc(f) => self.generate_struct_constructor(f),
3005 Expression::StructExtract(f) => self.generate_struct_extract(f),
3006 Expression::NamedStruct(f) => self.generate_named_struct(f),
3007
3008 Expression::MapFunc(f) => self.generate_map_constructor(f),
3010 Expression::MapFromEntries(f) => self.generate_simple_func("MAP_FROM_ENTRIES", &f.this),
3011 Expression::MapFromArrays(f) => {
3012 self.generate_binary_func("MAP_FROM_ARRAYS", &f.this, &f.expression)
3013 }
3014 Expression::MapKeys(f) => self.generate_simple_func("MAP_KEYS", &f.this),
3015 Expression::MapValues(f) => self.generate_simple_func("MAP_VALUES", &f.this),
3016 Expression::MapContainsKey(f) => {
3017 self.generate_binary_func("MAP_CONTAINS_KEY", &f.this, &f.expression)
3018 }
3019 Expression::MapConcat(f) => self.generate_vararg_func("MAP_CONCAT", &f.expressions),
3020 Expression::ElementAt(f) => {
3021 self.generate_binary_func("ELEMENT_AT", &f.this, &f.expression)
3022 }
3023 Expression::TransformKeys(f) => self.generate_transform_func("TRANSFORM_KEYS", f),
3024 Expression::TransformValues(f) => self.generate_transform_func("TRANSFORM_VALUES", f),
3025
3026 Expression::JsonExtract(f) => self.generate_json_extract("JSON_EXTRACT", f),
3028 Expression::JsonExtractScalar(f) => {
3029 self.generate_json_extract("JSON_EXTRACT_SCALAR", f)
3030 }
3031 Expression::JsonExtractPath(f) => self.generate_json_path("JSON_EXTRACT_PATH", f),
3032 Expression::JsonArray(f) => self.generate_vararg_func("JSON_ARRAY", &f.expressions),
3033 Expression::JsonObject(f) => self.generate_json_object(f),
3034 Expression::JsonQuery(f) => self.generate_json_extract("JSON_QUERY", f),
3035 Expression::JsonValue(f) => self.generate_json_extract("JSON_VALUE", f),
3036 Expression::JsonArrayLength(f) => {
3037 self.generate_simple_func("JSON_ARRAY_LENGTH", &f.this)
3038 }
3039 Expression::JsonKeys(f) => self.generate_simple_func("JSON_KEYS", &f.this),
3040 Expression::JsonType(f) => self.generate_simple_func("JSON_TYPE", &f.this),
3041 Expression::ParseJson(f) => {
3042 let name = match self.config.dialect {
3043 Some(DialectType::Presto)
3044 | Some(DialectType::Trino)
3045 | Some(DialectType::Athena) => "JSON_PARSE",
3046 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
3047 self.write_keyword("CAST");
3049 self.write("(");
3050 self.generate_expression(&f.this)?;
3051 self.write_keyword(" AS ");
3052 self.write_keyword("JSON");
3053 self.write(")");
3054 return Ok(());
3055 }
3056 Some(DialectType::Hive)
3057 | Some(DialectType::Spark)
3058 | Some(DialectType::MySQL)
3059 | Some(DialectType::SingleStore)
3060 | Some(DialectType::TiDB)
3061 | Some(DialectType::TSQL) => {
3062 self.generate_expression(&f.this)?;
3064 return Ok(());
3065 }
3066 Some(DialectType::DuckDB) => "JSON",
3067 _ => "PARSE_JSON",
3068 };
3069 self.generate_simple_func(name, &f.this)
3070 }
3071 Expression::ToJson(f) => self.generate_simple_func("TO_JSON", &f.this),
3072 Expression::JsonSet(f) => self.generate_json_modify("JSON_SET", f),
3073 Expression::JsonInsert(f) => self.generate_json_modify("JSON_INSERT", f),
3074 Expression::JsonRemove(f) => self.generate_json_path("JSON_REMOVE", f),
3075 Expression::JsonMergePatch(f) => {
3076 self.generate_binary_func("JSON_MERGE_PATCH", &f.this, &f.expression)
3077 }
3078 Expression::JsonArrayAgg(f) => self.generate_json_array_agg(f),
3079 Expression::JsonObjectAgg(f) => self.generate_json_object_agg(f),
3080
3081 Expression::Convert(f) => self.generate_convert(f),
3083 Expression::Typeof(f) => self.generate_simple_func("TYPEOF", &f.this),
3084
3085 Expression::Lambda(f) => self.generate_lambda(f),
3087 Expression::Parameter(f) => self.generate_parameter(f),
3088 Expression::Placeholder(f) => self.generate_placeholder(f),
3089 Expression::NamedArgument(f) => self.generate_named_argument(f),
3090 Expression::TableArgument(f) => self.generate_table_argument(f),
3091 Expression::SqlComment(f) => self.generate_sql_comment(f),
3092
3093 Expression::NullSafeEq(op) => self.generate_null_safe_eq(op),
3095 Expression::NullSafeNeq(op) => self.generate_null_safe_neq(op),
3096 Expression::Glob(op) => self.generate_binary_op(op, "GLOB"),
3097 Expression::SimilarTo(f) => self.generate_similar_to(f),
3098 Expression::Any(f) => self.generate_quantified("ANY", f),
3099 Expression::All(f) => self.generate_quantified("ALL", f),
3100 Expression::Overlaps(f) => self.generate_overlaps(f),
3101
3102 Expression::BitwiseLeftShift(op) => {
3104 if matches!(
3105 self.config.dialect,
3106 Some(DialectType::Presto) | Some(DialectType::Trino)
3107 ) {
3108 self.write_keyword("BITWISE_LEFT_SHIFT");
3109 self.write("(");
3110 self.generate_expression(&op.left)?;
3111 self.write(", ");
3112 self.generate_expression(&op.right)?;
3113 self.write(")");
3114 Ok(())
3115 } else if matches!(
3116 self.config.dialect,
3117 Some(DialectType::Spark) | Some(DialectType::Databricks)
3118 ) {
3119 self.write_keyword("SHIFTLEFT");
3120 self.write("(");
3121 self.generate_expression(&op.left)?;
3122 self.write(", ");
3123 self.generate_expression(&op.right)?;
3124 self.write(")");
3125 Ok(())
3126 } else {
3127 self.generate_binary_op(op, "<<")
3128 }
3129 }
3130 Expression::BitwiseRightShift(op) => {
3131 if matches!(
3132 self.config.dialect,
3133 Some(DialectType::Presto) | Some(DialectType::Trino)
3134 ) {
3135 self.write_keyword("BITWISE_RIGHT_SHIFT");
3136 self.write("(");
3137 self.generate_expression(&op.left)?;
3138 self.write(", ");
3139 self.generate_expression(&op.right)?;
3140 self.write(")");
3141 Ok(())
3142 } else if matches!(
3143 self.config.dialect,
3144 Some(DialectType::Spark) | Some(DialectType::Databricks)
3145 ) {
3146 self.write_keyword("SHIFTRIGHT");
3147 self.write("(");
3148 self.generate_expression(&op.left)?;
3149 self.write(", ");
3150 self.generate_expression(&op.right)?;
3151 self.write(")");
3152 Ok(())
3153 } else {
3154 self.generate_binary_op(op, ">>")
3155 }
3156 }
3157 Expression::BitwiseAndAgg(f) => self.generate_agg_func("BIT_AND", f),
3158 Expression::BitwiseOrAgg(f) => self.generate_agg_func("BIT_OR", f),
3159 Expression::BitwiseXorAgg(f) => self.generate_agg_func("BIT_XOR", f),
3160
3161 Expression::Subscript(s) => self.generate_subscript(s),
3163 Expression::Dot(d) => self.generate_dot_access(d),
3164 Expression::MethodCall(m) => self.generate_method_call(m),
3165 Expression::ArraySlice(s) => self.generate_array_slice(s),
3166
3167 Expression::And(op) => self.generate_connector_op(op, ConnectorOperator::And),
3168 Expression::Or(op) => self.generate_connector_op(op, ConnectorOperator::Or),
3169 Expression::Add(op) => self.generate_binary_op(op, "+"),
3170 Expression::Sub(op) => self.generate_binary_op(op, "-"),
3171 Expression::Mul(op) => self.generate_binary_op(op, "*"),
3172 Expression::Div(op) => self.generate_binary_op(op, "/"),
3173 Expression::IntDiv(f) => {
3174 use crate::dialects::DialectType;
3175 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
3176 self.generate_expression(&f.this)?;
3178 self.write(" // ");
3179 self.generate_expression(&f.expression)?;
3180 Ok(())
3181 } else if matches!(
3182 self.config.dialect,
3183 Some(DialectType::Hive | DialectType::Spark | DialectType::Databricks)
3184 ) {
3185 self.generate_expression(&f.this)?;
3187 self.write(" ");
3188 self.write_keyword("DIV");
3189 self.write(" ");
3190 self.generate_expression(&f.expression)?;
3191 Ok(())
3192 } else {
3193 self.write_keyword("DIV");
3195 self.write("(");
3196 self.generate_expression(&f.this)?;
3197 self.write(", ");
3198 self.generate_expression(&f.expression)?;
3199 self.write(")");
3200 Ok(())
3201 }
3202 }
3203 Expression::Mod(op) => {
3204 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
3205 self.generate_binary_op(op, "MOD")
3206 } else {
3207 self.generate_binary_op(op, "%")
3208 }
3209 }
3210 Expression::Eq(op) => self.generate_binary_op(op, "="),
3211 Expression::Neq(op) => self.generate_binary_op(op, "<>"),
3212 Expression::Lt(op) => self.generate_binary_op(op, "<"),
3213 Expression::Lte(op) => self.generate_binary_op(op, "<="),
3214 Expression::Gt(op) => self.generate_binary_op(op, ">"),
3215 Expression::Gte(op) => self.generate_binary_op(op, ">="),
3216 Expression::Like(op) => self.generate_like_op(op, "LIKE"),
3217 Expression::ILike(op) => self.generate_like_op(op, "ILIKE"),
3218 Expression::Match(op) => self.generate_binary_op(op, "MATCH"),
3219 Expression::Concat(op) => {
3220 if self.config.dialect == Some(DialectType::Solr) {
3222 self.generate_binary_op(op, "OR")
3223 } else if self.config.dialect == Some(DialectType::MySQL) {
3224 self.generate_mysql_concat_from_concat(op)
3225 } else {
3226 self.generate_binary_op(op, "||")
3227 }
3228 }
3229 Expression::BitwiseAnd(op) => {
3230 if matches!(
3232 self.config.dialect,
3233 Some(DialectType::Presto) | Some(DialectType::Trino)
3234 ) {
3235 self.write_keyword("BITWISE_AND");
3236 self.write("(");
3237 self.generate_expression(&op.left)?;
3238 self.write(", ");
3239 self.generate_expression(&op.right)?;
3240 self.write(")");
3241 Ok(())
3242 } else {
3243 self.generate_binary_op(op, "&")
3244 }
3245 }
3246 Expression::BitwiseOr(op) => {
3247 if matches!(
3249 self.config.dialect,
3250 Some(DialectType::Presto) | Some(DialectType::Trino)
3251 ) {
3252 self.write_keyword("BITWISE_OR");
3253 self.write("(");
3254 self.generate_expression(&op.left)?;
3255 self.write(", ");
3256 self.generate_expression(&op.right)?;
3257 self.write(")");
3258 Ok(())
3259 } else {
3260 self.generate_binary_op(op, "|")
3261 }
3262 }
3263 Expression::BitwiseXor(op) => {
3264 if matches!(
3266 self.config.dialect,
3267 Some(DialectType::Presto) | Some(DialectType::Trino)
3268 ) {
3269 self.write_keyword("BITWISE_XOR");
3270 self.write("(");
3271 self.generate_expression(&op.left)?;
3272 self.write(", ");
3273 self.generate_expression(&op.right)?;
3274 self.write(")");
3275 Ok(())
3276 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
3277 self.generate_binary_op(op, "#")
3278 } else {
3279 self.generate_binary_op(op, "^")
3280 }
3281 }
3282 Expression::Adjacent(op) => self.generate_binary_op(op, "-|-"),
3283 Expression::TsMatch(op) => self.generate_binary_op(op, "@@"),
3284 Expression::PropertyEQ(op) => self.generate_binary_op(op, ":="),
3285 Expression::ArrayContainsAll(op) => self.generate_binary_op(op, "@>"),
3286 Expression::ArrayContainedBy(op) => self.generate_binary_op(op, "<@"),
3287 Expression::ArrayOverlaps(op) => self.generate_binary_op(op, "&&"),
3288 Expression::JSONBContainsAllTopKeys(op) => self.generate_binary_op(op, "?&"),
3289 Expression::JSONBContainsAnyTopKeys(op) => self.generate_binary_op(op, "?|"),
3290 Expression::JSONBContains(f) => {
3291 self.generate_expression(&f.this)?;
3293 self.write_space();
3294 self.write(f.original_name.as_deref().unwrap_or("?"));
3295 self.write_space();
3296 self.generate_expression(&f.expression)
3297 }
3298 Expression::JSONBDeleteAtPath(op) => self.generate_binary_op(op, "#-"),
3299 Expression::ExtendsLeft(op) => self.generate_binary_op(op, "&<"),
3300 Expression::ExtendsRight(op) => self.generate_binary_op(op, "&>"),
3301 Expression::Not(op) => match &op.this {
3302 Expression::Like(like) => self.generate_like_op_negated(like, "LIKE"),
3303 Expression::ILike(like) => self.generate_like_op_negated(like, "ILIKE"),
3304 _ => self.generate_unary_op(op, "NOT"),
3305 },
3306 Expression::Neg(op) => self.generate_unary_op(op, "-"),
3307 Expression::BitwiseNot(op) => {
3308 if matches!(
3310 self.config.dialect,
3311 Some(DialectType::Presto) | Some(DialectType::Trino)
3312 ) {
3313 self.write_keyword("BITWISE_NOT");
3314 self.write("(");
3315 self.generate_expression(&op.this)?;
3316 self.write(")");
3317 Ok(())
3318 } else {
3319 self.generate_unary_op(op, "~")
3320 }
3321 }
3322 Expression::In(in_expr) => self.generate_in(in_expr),
3323 Expression::Between(between) => self.generate_between(between),
3324 Expression::IsNull(is_null) => self.generate_is_null(is_null),
3325 Expression::IsTrue(is_true) => self.generate_is_true(is_true),
3326 Expression::IsFalse(is_false) => self.generate_is_false(is_false),
3327 Expression::IsJson(is_json) => self.generate_is_json(is_json),
3328 Expression::Is(is_expr) => self.generate_is(is_expr),
3329 Expression::Exists(exists) => self.generate_exists(exists),
3330 Expression::MemberOf(member_of) => self.generate_member_of(member_of),
3331 Expression::Subquery(subquery) => self.generate_subquery(subquery),
3332 Expression::Paren(paren) => {
3333 let skip_parens = matches!(&paren.this, Expression::JoinedTable(_));
3335
3336 if !skip_parens {
3337 self.write("(");
3338 if self.config.pretty {
3339 self.write_newline();
3340 self.indent_level += 1;
3341 self.write_indent();
3342 }
3343 }
3344 self.generate_expression(&paren.this)?;
3345 if !skip_parens {
3346 if self.config.pretty {
3347 self.write_newline();
3348 self.indent_level -= 1;
3349 self.write_indent();
3350 }
3351 self.write(")");
3352 }
3353 for comment in &paren.trailing_comments {
3355 self.write(" ");
3356 self.write_formatted_comment(comment);
3357 }
3358 Ok(())
3359 }
3360 Expression::Array(arr) => self.generate_array(arr),
3361 Expression::Tuple(tuple) => self.generate_tuple(tuple),
3362 Expression::PipeOperator(pipe) => self.generate_pipe_operator(pipe),
3363 Expression::Ordered(ordered) => self.generate_ordered(ordered),
3364 Expression::DataType(dt) => self.generate_data_type(dt),
3365 Expression::Raw(raw) => {
3366 self.write(&raw.sql);
3367 Ok(())
3368 }
3369 Expression::CreateTask(task) => self.generate_create_task(task),
3370 Expression::TryCatch(try_catch) => self.generate_try_catch(try_catch),
3371 Expression::Command(cmd) => {
3372 self.write(&cmd.this);
3373 if matches!(self.config.dialect, Some(DialectType::ClickHouse))
3374 && cmd
3375 .this
3376 .trim_start()
3377 .get(..7)
3378 .is_some_and(|prefix| prefix.eq_ignore_ascii_case("EXPLAIN"))
3379 {
3380 for _ in 0..Self::missing_closing_parens_outside_quotes(&cmd.this) {
3381 self.write(")");
3382 }
3383 }
3384 Ok(())
3385 }
3386 Expression::Kill(kill) => {
3387 self.write_keyword("KILL");
3388 if let Some(kind) = &kill.kind {
3389 self.write_space();
3390 self.write_keyword(kind);
3391 }
3392 self.write_space();
3393 self.generate_expression(&kill.this)?;
3394 Ok(())
3395 }
3396 Expression::Prepare(prepare) => self.generate_prepare(prepare),
3397 Expression::Execute(exec) => {
3398 self.write_keyword("EXECUTE");
3399 self.write_space();
3400 self.generate_expression(&exec.this)?;
3401 if exec.prepared {
3402 if !exec.arguments.is_empty() {
3403 self.write("(");
3404 for (i, argument) in exec.arguments.iter().enumerate() {
3405 if i > 0 {
3406 self.write(", ");
3407 }
3408 self.generate_expression(argument)?;
3409 }
3410 self.write(")");
3411 }
3412 return Ok(());
3413 }
3414 for (i, param) in exec.parameters.iter().enumerate() {
3415 if i == 0 {
3416 self.write_space();
3417 } else {
3418 self.write(", ");
3419 }
3420 self.write(¶m.name);
3421 if !param.positional {
3423 self.write(" = ");
3424 self.generate_expression(¶m.value)?;
3425 }
3426 if param.output {
3427 self.write_space();
3428 self.write_keyword("OUTPUT");
3429 }
3430 }
3431 if let Some(ref suffix) = exec.suffix {
3432 self.write_space();
3433 self.write(suffix);
3434 }
3435 Ok(())
3436 }
3437 Expression::Annotated(annotated) => {
3438 self.generate_expression(&annotated.this)?;
3439 for comment in &annotated.trailing_comments {
3440 self.write(" ");
3441 self.write_formatted_comment(comment);
3442 }
3443 Ok(())
3444 }
3445
3446 Expression::CreateTable(ct) => self.generate_create_table(ct),
3448 Expression::DropTable(dt) => self.generate_drop_table(dt),
3449 Expression::Undrop(u) => self.generate_undrop(u),
3450 Expression::AlterTable(at) => self.generate_alter_table(at),
3451 Expression::SplitTable(st) => self.generate_split_table(st),
3452 Expression::FlashbackTable(ft) => self.generate_flashback_table(ft),
3453 Expression::CreateIndex(ci) => self.generate_create_index(ci),
3454 Expression::DropIndex(di) => self.generate_drop_index(di),
3455 Expression::CreateView(cv) => self.generate_create_view(cv),
3456 Expression::DropView(dv) => self.generate_drop_view(dv),
3457 Expression::AlterView(av) => self.generate_alter_view(av),
3458 Expression::AlterIndex(ai) => self.generate_alter_index(ai),
3459 Expression::Truncate(tr) => self.generate_truncate(tr),
3460 Expression::Use(u) => self.generate_use(u),
3461 Expression::CreateSchema(cs) => self.generate_create_schema(cs),
3463 Expression::DropSchema(ds) => self.generate_drop_schema(ds),
3464 Expression::DropNamespace(dn) => self.generate_drop_namespace(dn),
3465 Expression::CreateDatabase(cd) => self.generate_create_database(cd),
3466 Expression::DropDatabase(dd) => self.generate_drop_database(dd),
3467 Expression::CreateFunction(cf) => self.generate_create_function(cf),
3468 Expression::DropFunction(df) => self.generate_drop_function(df),
3469 Expression::CreateProcedure(cp) => self.generate_create_procedure(cp),
3470 Expression::DropProcedure(dp) => self.generate_drop_procedure(dp),
3471 Expression::CreateSequence(cs) => self.generate_create_sequence(cs),
3472 Expression::CreateSynonym(cs) => {
3473 self.write_keyword("CREATE SYNONYM");
3474 self.write_space();
3475 self.generate_table(&cs.name)?;
3476 self.write_space();
3477 self.write_keyword("FOR");
3478 self.write_space();
3479 self.generate_table(&cs.target)?;
3480 Ok(())
3481 }
3482 Expression::DropSequence(ds) => self.generate_drop_sequence(ds),
3483 Expression::AlterSequence(als) => self.generate_alter_sequence(als),
3484 Expression::CreateTrigger(ct) => self.generate_create_trigger(ct),
3485 Expression::DropTrigger(dt) => self.generate_drop_trigger(dt),
3486 Expression::CreateType(ct) => self.generate_create_type(ct),
3487 Expression::DropType(dt) => self.generate_drop_type(dt),
3488 Expression::Describe(d) => self.generate_describe(d),
3489 Expression::Show(s) => self.generate_show(s),
3490
3491 Expression::Cache(c) => self.generate_cache(c),
3493 Expression::Uncache(u) => self.generate_uncache(u),
3494 Expression::LoadData(l) => self.generate_load_data(l),
3495 Expression::Pragma(p) => self.generate_pragma(p),
3496 Expression::Grant(g) => self.generate_grant(g),
3497 Expression::Revoke(r) => self.generate_revoke(r),
3498 Expression::Comment(c) => self.generate_comment(c),
3499 Expression::SetStatement(s) => self.generate_set_statement(s),
3500
3501 Expression::Pivot(pivot) => self.generate_pivot(pivot),
3503 Expression::Unpivot(unpivot) => self.generate_unpivot(unpivot),
3504
3505 Expression::Values(values) => self.generate_values(values),
3507
3508 Expression::AIAgg(e) => self.generate_ai_agg(e),
3510 Expression::AIClassify(e) => self.generate_ai_classify(e),
3511 Expression::AddPartition(e) => self.generate_add_partition(e),
3512 Expression::AlgorithmProperty(e) => self.generate_algorithm_property(e),
3513 Expression::Aliases(e) => self.generate_aliases(e),
3514 Expression::AllowedValuesProperty(e) => self.generate_allowed_values_property(e),
3515 Expression::AlterColumn(e) => self.generate_alter_column(e),
3516 Expression::AlterSession(e) => self.generate_alter_session(e),
3517 Expression::AlterSet(e) => self.generate_alter_set(e),
3518 Expression::AlterSortKey(e) => self.generate_alter_sort_key(e),
3519 Expression::Analyze(e) => self.generate_analyze(e),
3520 Expression::AnalyzeDelete(e) => self.generate_analyze_delete(e),
3521 Expression::AnalyzeHistogram(e) => self.generate_analyze_histogram(e),
3522 Expression::AnalyzeListChainedRows(e) => self.generate_analyze_list_chained_rows(e),
3523 Expression::AnalyzeSample(e) => self.generate_analyze_sample(e),
3524 Expression::AnalyzeStatistics(e) => self.generate_analyze_statistics(e),
3525 Expression::AnalyzeValidate(e) => self.generate_analyze_validate(e),
3526 Expression::AnalyzeWith(e) => self.generate_analyze_with(e),
3527 Expression::Anonymous(e) => self.generate_anonymous(e),
3528 Expression::AnonymousAggFunc(e) => self.generate_anonymous_agg_func(e),
3529 Expression::Apply(e) => self.generate_apply(e),
3530 Expression::ApproxPercentileEstimate(e) => self.generate_approx_percentile_estimate(e),
3531 Expression::ApproxQuantile(e) => self.generate_approx_quantile(e),
3532 Expression::ApproxQuantiles(e) => self.generate_approx_quantiles(e),
3533 Expression::ApproxTopK(e) => self.generate_approx_top_k(e),
3534 Expression::ApproxTopKAccumulate(e) => self.generate_approx_top_k_accumulate(e),
3535 Expression::ApproxTopKCombine(e) => self.generate_approx_top_k_combine(e),
3536 Expression::ApproxTopKEstimate(e) => self.generate_approx_top_k_estimate(e),
3537 Expression::ApproxTopSum(e) => self.generate_approx_top_sum(e),
3538 Expression::ArgMax(e) => self.generate_arg_max(e),
3539 Expression::ArgMin(e) => self.generate_arg_min(e),
3540 Expression::ArrayAll(e) => self.generate_array_all(e),
3541 Expression::ArrayAny(e) => self.generate_array_any(e),
3542 Expression::ArrayConstructCompact(e) => self.generate_array_construct_compact(e),
3543 Expression::ArraySum(e) => self.generate_array_sum(e),
3544 Expression::AtIndex(e) => self.generate_at_index(e),
3545 Expression::Attach(e) => self.generate_attach(e),
3546 Expression::AttachOption(e) => self.generate_attach_option(e),
3547 Expression::AutoIncrementProperty(e) => self.generate_auto_increment_property(e),
3548 Expression::AutoRefreshProperty(e) => self.generate_auto_refresh_property(e),
3549 Expression::BackupProperty(e) => self.generate_backup_property(e),
3550 Expression::Base64DecodeBinary(e) => self.generate_base64_decode_binary(e),
3551 Expression::Base64DecodeString(e) => self.generate_base64_decode_string(e),
3552 Expression::Base64Encode(e) => self.generate_base64_encode(e),
3553 Expression::BlockCompressionProperty(e) => self.generate_block_compression_property(e),
3554 Expression::Booland(e) => self.generate_booland(e),
3555 Expression::Boolor(e) => self.generate_boolor(e),
3556 Expression::BuildProperty(e) => self.generate_build_property(e),
3557 Expression::ByteString(e) => self.generate_byte_string(e),
3558 Expression::CaseSpecificColumnConstraint(e) => {
3559 self.generate_case_specific_column_constraint(e)
3560 }
3561 Expression::CastToStrType(e) => self.generate_cast_to_str_type(e),
3562 Expression::Changes(e) => self.generate_changes(e),
3563 Expression::CharacterSetColumnConstraint(e) => {
3564 self.generate_character_set_column_constraint(e)
3565 }
3566 Expression::CharacterSetProperty(e) => self.generate_character_set_property(e),
3567 Expression::CheckColumnConstraint(e) => self.generate_check_column_constraint(e),
3568 Expression::AssumeColumnConstraint(e) => self.generate_assume_column_constraint(e),
3569 Expression::CheckJson(e) => self.generate_check_json(e),
3570 Expression::CheckXml(e) => self.generate_check_xml(e),
3571 Expression::ChecksumProperty(e) => self.generate_checksum_property(e),
3572 Expression::Clone(e) => self.generate_clone(e),
3573 Expression::ClusterBy(e) => self.generate_cluster_by(e),
3574 Expression::ClusterByColumnsProperty(e) => self.generate_cluster_by_columns_property(e),
3575 Expression::ClusteredByProperty(e) => self.generate_clustered_by_property(e),
3576 Expression::CollateProperty(e) => self.generate_collate_property(e),
3577 Expression::ColumnConstraint(e) => self.generate_column_constraint(e),
3578 Expression::ColumnDef(e) => self.generate_column_def_expr(e),
3579 Expression::ColumnPosition(e) => self.generate_column_position(e),
3580 Expression::ColumnPrefix(e) => self.generate_column_prefix(e),
3581 Expression::Columns(e) => self.generate_columns(e),
3582 Expression::CombinedAggFunc(e) => self.generate_combined_agg_func(e),
3583 Expression::CombinedParameterizedAgg(e) => self.generate_combined_parameterized_agg(e),
3584 Expression::Commit(e) => self.generate_commit(e),
3585 Expression::Comprehension(e) => self.generate_comprehension(e),
3586 Expression::Compress(e) => self.generate_compress(e),
3587 Expression::CompressColumnConstraint(e) => self.generate_compress_column_constraint(e),
3588 Expression::ComputedColumnConstraint(e) => self.generate_computed_column_constraint(e),
3589 Expression::ConditionalInsert(e) => self.generate_conditional_insert(e),
3590 Expression::Constraint(e) => self.generate_constraint(e),
3591 Expression::ConvertTimezone(e) => self.generate_convert_timezone(e),
3592 Expression::ConvertToCharset(e) => self.generate_convert_to_charset(e),
3593 Expression::Copy(e) => self.generate_copy(e),
3594 Expression::CopyParameter(e) => self.generate_copy_parameter(e),
3595 Expression::Corr(e) => self.generate_corr(e),
3596 Expression::CosineDistance(e) => self.generate_cosine_distance(e),
3597 Expression::CovarPop(e) => self.generate_covar_pop(e),
3598 Expression::CovarSamp(e) => self.generate_covar_samp(e),
3599 Expression::Credentials(e) => self.generate_credentials(e),
3600 Expression::CredentialsProperty(e) => self.generate_credentials_property(e),
3601 Expression::Cte(e) => self.generate_cte(e),
3602 Expression::Cube(e) => self.generate_cube(e),
3603 Expression::CurrentDatetime(e) => self.generate_current_datetime(e),
3604 Expression::CurrentSchema(e) => self.generate_current_schema(e),
3605 Expression::CurrentSchemas(e) => self.generate_current_schemas(e),
3606 Expression::CurrentUser(e) => self.generate_current_user(e),
3607 Expression::DPipe(e) => self.generate_d_pipe(e),
3608 Expression::DataBlocksizeProperty(e) => self.generate_data_blocksize_property(e),
3609 Expression::DataDeletionProperty(e) => self.generate_data_deletion_property(e),
3610 Expression::Date(e) => self.generate_date_func(e),
3611 Expression::DateBin(e) => self.generate_date_bin(e),
3612 Expression::DateFormatColumnConstraint(e) => {
3613 self.generate_date_format_column_constraint(e)
3614 }
3615 Expression::DateFromParts(e) => self.generate_date_from_parts(e),
3616 Expression::Datetime(e) => self.generate_datetime(e),
3617 Expression::DatetimeAdd(e) => self.generate_datetime_add(e),
3618 Expression::DatetimeDiff(e) => self.generate_datetime_diff(e),
3619 Expression::DatetimeSub(e) => self.generate_datetime_sub(e),
3620 Expression::DatetimeTrunc(e) => self.generate_datetime_trunc(e),
3621 Expression::Dayname(e) => self.generate_dayname(e),
3622 Expression::Declare(e) => self.generate_declare(e),
3623 Expression::DeclareItem(e) => self.generate_declare_item(e),
3624 Expression::DecodeCase(e) => self.generate_decode_case(e),
3625 Expression::DecompressBinary(e) => self.generate_decompress_binary(e),
3626 Expression::DecompressString(e) => self.generate_decompress_string(e),
3627 Expression::Decrypt(e) => self.generate_decrypt(e),
3628 Expression::DecryptRaw(e) => self.generate_decrypt_raw(e),
3629 Expression::DefaultColumnConstraint(e) => {
3630 self.write_keyword("DEFAULT");
3631 self.write_space();
3632 self.generate_expression(&e.this)?;
3633 if let Some(ref col) = e.for_column {
3634 self.write_space();
3635 self.write_keyword("FOR");
3636 self.write_space();
3637 self.generate_identifier(col)?;
3638 }
3639 Ok(())
3640 }
3641 Expression::DefinerProperty(e) => self.generate_definer_property(e),
3642 Expression::Detach(e) => self.generate_detach(e),
3643 Expression::DictProperty(e) => self.generate_dict_property(e),
3644 Expression::DictRange(e) => self.generate_dict_range(e),
3645 Expression::Directory(e) => self.generate_directory(e),
3646 Expression::DistKeyProperty(e) => self.generate_dist_key_property(e),
3647 Expression::DistStyleProperty(e) => self.generate_dist_style_property(e),
3648 Expression::DistributeBy(e) => self.generate_distribute_by(e),
3649 Expression::DistributedByProperty(e) => self.generate_distributed_by_property(e),
3650 Expression::DotProduct(e) => self.generate_dot_product(e),
3651 Expression::DropPartition(e) => self.generate_drop_partition(e),
3652 Expression::DuplicateKeyProperty(e) => self.generate_duplicate_key_property(e),
3653 Expression::Elt(e) => self.generate_elt(e),
3654 Expression::Encode(e) => self.generate_encode(e),
3655 Expression::EncodeProperty(e) => self.generate_encode_property(e),
3656 Expression::Encrypt(e) => self.generate_encrypt(e),
3657 Expression::EncryptRaw(e) => self.generate_encrypt_raw(e),
3658 Expression::EngineProperty(e) => self.generate_engine_property(e),
3659 Expression::EnviromentProperty(e) => self.generate_enviroment_property(e),
3660 Expression::EphemeralColumnConstraint(e) => {
3661 self.generate_ephemeral_column_constraint(e)
3662 }
3663 Expression::EqualNull(e) => self.generate_equal_null(e),
3664 Expression::EuclideanDistance(e) => self.generate_euclidean_distance(e),
3665 Expression::ExecuteAsProperty(e) => self.generate_execute_as_property(e),
3666 Expression::Export(e) => self.generate_export(e),
3667 Expression::ExternalProperty(e) => self.generate_external_property(e),
3668 Expression::FallbackProperty(e) => self.generate_fallback_property(e),
3669 Expression::FarmFingerprint(e) => self.generate_farm_fingerprint(e),
3670 Expression::FeaturesAtTime(e) => self.generate_features_at_time(e),
3671 Expression::Fetch(e) => self.generate_fetch(e),
3672 Expression::FileFormatProperty(e) => self.generate_file_format_property(e),
3673 Expression::Filter(e) => self.generate_filter(e),
3674 Expression::Float64(e) => self.generate_float64(e),
3675 Expression::ForIn(e) => self.generate_for_in(e),
3676 Expression::ForeignKey(e) => self.generate_foreign_key(e),
3677 Expression::Format(e) => self.generate_format(e),
3678 Expression::FormatPhrase(e) => self.generate_format_phrase(e),
3679 Expression::FreespaceProperty(e) => self.generate_freespace_property(e),
3680 Expression::From(e) => self.generate_from(e),
3681 Expression::FromBase(e) => self.generate_from_base(e),
3682 Expression::FromTimeZone(e) => self.generate_from_time_zone(e),
3683 Expression::GapFill(e) => self.generate_gap_fill(e),
3684 Expression::GenerateDateArray(e) => self.generate_generate_date_array(e),
3685 Expression::GenerateEmbedding(e) => self.generate_generate_embedding(e),
3686 Expression::GenerateSeries(e) => self.generate_generate_series(e),
3687 Expression::GenerateTimestampArray(e) => self.generate_generate_timestamp_array(e),
3688 Expression::GeneratedAsIdentityColumnConstraint(e) => {
3689 self.generate_generated_as_identity_column_constraint(e)
3690 }
3691 Expression::GeneratedAsRowColumnConstraint(e) => {
3692 self.generate_generated_as_row_column_constraint(e)
3693 }
3694 Expression::Get(e) => self.generate_get(e),
3695 Expression::GetExtract(e) => self.generate_get_extract(e),
3696 Expression::Getbit(e) => self.generate_getbit(e),
3697 Expression::GrantPrincipal(e) => self.generate_grant_principal(e),
3698 Expression::GrantPrivilege(e) => self.generate_grant_privilege(e),
3699 Expression::Group(e) => self.generate_group(e),
3700 Expression::GroupBy(e) => self.generate_group_by(e),
3701 Expression::Grouping(e) => self.generate_grouping(e),
3702 Expression::GroupingId(e) => self.generate_grouping_id(e),
3703 Expression::GroupingSets(e) => self.generate_grouping_sets(e),
3704 Expression::HashAgg(e) => self.generate_hash_agg(e),
3705 Expression::Having(e) => self.generate_having(e),
3706 Expression::HavingMax(e) => self.generate_having_max(e),
3707 Expression::Heredoc(e) => self.generate_heredoc(e),
3708 Expression::HexEncode(e) => self.generate_hex_encode(e),
3709 Expression::Hll(e) => self.generate_hll(e),
3710 Expression::InOutColumnConstraint(e) => self.generate_in_out_column_constraint(e),
3711 Expression::IncludeProperty(e) => self.generate_include_property(e),
3712 Expression::Index(e) => self.generate_index(e),
3713 Expression::IndexColumnConstraint(e) => self.generate_index_column_constraint(e),
3714 Expression::IndexConstraintOption(e) => self.generate_index_constraint_option(e),
3715 Expression::IndexParameters(e) => self.generate_index_parameters(e),
3716 Expression::IndexTableHint(e) => self.generate_index_table_hint(e),
3717 Expression::InheritsProperty(e) => self.generate_inherits_property(e),
3718 Expression::InputModelProperty(e) => self.generate_input_model_property(e),
3719 Expression::InputOutputFormat(e) => self.generate_input_output_format(e),
3720 Expression::Install(e) => self.generate_install(e),
3721 Expression::IntervalOp(e) => self.generate_interval_op(e),
3722 Expression::IntervalSpan(e) => self.generate_interval_span(e),
3723 Expression::IntoClause(e) => self.generate_into_clause(e),
3724 Expression::Introducer(e) => self.generate_introducer(e),
3725 Expression::IsolatedLoadingProperty(e) => self.generate_isolated_loading_property(e),
3726 Expression::JSON(e) => self.generate_json(e),
3727 Expression::JSONArray(e) => self.generate_json_array(e),
3728 Expression::JSONArrayAgg(e) => self.generate_json_array_agg_struct(e),
3729 Expression::JSONArrayAppend(e) => self.generate_json_array_append(e),
3730 Expression::JSONArrayContains(e) => self.generate_json_array_contains(e),
3731 Expression::JSONArrayInsert(e) => self.generate_json_array_insert(e),
3732 Expression::JSONBExists(e) => self.generate_jsonb_exists(e),
3733 Expression::JSONBExtractScalar(e) => self.generate_jsonb_extract_scalar(e),
3734 Expression::JSONBObjectAgg(e) => self.generate_jsonb_object_agg(e),
3735 Expression::JSONObjectAgg(e) => self.generate_json_object_agg_struct(e),
3736 Expression::JSONColumnDef(e) => self.generate_json_column_def(e),
3737 Expression::JSONExists(e) => self.generate_json_exists(e),
3738 Expression::JSONCast(e) => self.generate_json_cast(e),
3739 Expression::JSONExtract(e) => self.generate_json_extract_path(e),
3740 Expression::JSONExtractArray(e) => self.generate_json_extract_array(e),
3741 Expression::JSONExtractQuote(e) => self.generate_json_extract_quote(e),
3742 Expression::JSONExtractScalar(e) => self.generate_json_extract_scalar(e),
3743 Expression::JSONFormat(e) => self.generate_json_format(e),
3744 Expression::JSONKeyValue(e) => self.generate_json_key_value(e),
3745 Expression::JSONKeys(e) => self.generate_json_keys(e),
3746 Expression::JSONKeysAtDepth(e) => self.generate_json_keys_at_depth(e),
3747 Expression::JSONPath(e) => self.generate_json_path_expr(e),
3748 Expression::JSONPathFilter(e) => self.generate_json_path_filter(e),
3749 Expression::JSONPathKey(e) => self.generate_json_path_key(e),
3750 Expression::JSONPathRecursive(e) => self.generate_json_path_recursive(e),
3751 Expression::JSONPathRoot(_) => self.generate_json_path_root(),
3752 Expression::JSONPathScript(e) => self.generate_json_path_script(e),
3753 Expression::JSONPathSelector(e) => self.generate_json_path_selector(e),
3754 Expression::JSONPathSlice(e) => self.generate_json_path_slice(e),
3755 Expression::JSONPathSubscript(e) => self.generate_json_path_subscript(e),
3756 Expression::JSONPathUnion(e) => self.generate_json_path_union(e),
3757 Expression::JSONRemove(e) => self.generate_json_remove(e),
3758 Expression::JSONSchema(e) => self.generate_json_schema(e),
3759 Expression::JSONSet(e) => self.generate_json_set(e),
3760 Expression::JSONStripNulls(e) => self.generate_json_strip_nulls(e),
3761 Expression::JSONTable(e) => self.generate_json_table(e),
3762 Expression::JSONType(e) => self.generate_json_type(e),
3763 Expression::JSONValue(e) => self.generate_json_value(e),
3764 Expression::JSONValueArray(e) => self.generate_json_value_array(e),
3765 Expression::JarowinklerSimilarity(e) => self.generate_jarowinkler_similarity(e),
3766 Expression::JoinHint(e) => self.generate_join_hint(e),
3767 Expression::JournalProperty(e) => self.generate_journal_property(e),
3768 Expression::LanguageProperty(e) => self.generate_language_property(e),
3769 Expression::Lateral(e) => self.generate_lateral(e),
3770 Expression::LikeProperty(e) => self.generate_like_property(e),
3771 Expression::Limit(e) => self.generate_limit(e),
3772 Expression::LimitOptions(e) => self.generate_limit_options(e),
3773 Expression::List(e) => self.generate_list(e),
3774 Expression::ToMap(e) => self.generate_tomap(e),
3775 Expression::Localtime(e) => self.generate_localtime(e),
3776 Expression::Localtimestamp(e) => self.generate_localtimestamp(e),
3777 Expression::LocationProperty(e) => self.generate_location_property(e),
3778 Expression::Lock(e) => self.generate_lock(e),
3779 Expression::LockProperty(e) => self.generate_lock_property(e),
3780 Expression::LockingProperty(e) => self.generate_locking_property(e),
3781 Expression::LockingStatement(e) => self.generate_locking_statement(e),
3782 Expression::LogProperty(e) => self.generate_log_property(e),
3783 Expression::MD5Digest(e) => self.generate_md5_digest(e),
3784 Expression::MLForecast(e) => self.generate_ml_forecast(e),
3785 Expression::MLTranslate(e) => self.generate_ml_translate(e),
3786 Expression::MakeInterval(e) => self.generate_make_interval(e),
3787 Expression::ManhattanDistance(e) => self.generate_manhattan_distance(e),
3788 Expression::Map(e) => self.generate_map(e),
3789 Expression::MapCat(e) => self.generate_map_cat(e),
3790 Expression::MapDelete(e) => self.generate_map_delete(e),
3791 Expression::MapInsert(e) => self.generate_map_insert(e),
3792 Expression::MapPick(e) => self.generate_map_pick(e),
3793 Expression::MaskingPolicyColumnConstraint(e) => {
3794 self.generate_masking_policy_column_constraint(e)
3795 }
3796 Expression::MatchAgainst(e) => self.generate_match_against(e),
3797 Expression::MatchRecognizeMeasure(e) => self.generate_match_recognize_measure(e),
3798 Expression::MaterializedProperty(e) => self.generate_materialized_property(e),
3799 Expression::Merge(e) => self.generate_merge(e),
3800 Expression::MergeBlockRatioProperty(e) => self.generate_merge_block_ratio_property(e),
3801 Expression::MergeTreeTTL(e) => self.generate_merge_tree_ttl(e),
3802 Expression::MergeTreeTTLAction(e) => self.generate_merge_tree_ttl_action(e),
3803 Expression::Minhash(e) => self.generate_minhash(e),
3804 Expression::ModelAttribute(e) => self.generate_model_attribute(e),
3805 Expression::Monthname(e) => self.generate_monthname(e),
3806 Expression::MultitableInserts(e) => self.generate_multitable_inserts(e),
3807 Expression::NextValueFor(e) => self.generate_next_value_for(e),
3808 Expression::Normal(e) => self.generate_normal(e),
3809 Expression::Normalize(e) => self.generate_normalize(e),
3810 Expression::NotNullColumnConstraint(e) => self.generate_not_null_column_constraint(e),
3811 Expression::Nullif(e) => self.generate_nullif(e),
3812 Expression::NumberToStr(e) => self.generate_number_to_str(e),
3813 Expression::ObjectAgg(e) => self.generate_object_agg(e),
3814 Expression::ObjectIdentifier(e) => self.generate_object_identifier(e),
3815 Expression::ObjectInsert(e) => self.generate_object_insert(e),
3816 Expression::Offset(e) => self.generate_offset(e),
3817 Expression::Qualify(e) => self.generate_qualify(e),
3818 Expression::OnCluster(e) => self.generate_on_cluster(e),
3819 Expression::OnCommitProperty(e) => self.generate_on_commit_property(e),
3820 Expression::OnCondition(e) => self.generate_on_condition(e),
3821 Expression::OnConflict(e) => self.generate_on_conflict(e),
3822 Expression::OnProperty(e) => self.generate_on_property(e),
3823 Expression::Opclass(e) => self.generate_opclass(e),
3824 Expression::OpenJSON(e) => self.generate_open_json(e),
3825 Expression::OpenJSONColumnDef(e) => self.generate_open_json_column_def(e),
3826 Expression::Operator(e) => self.generate_operator(e),
3827 Expression::OrderBy(e) => self.generate_order_by(e),
3828 Expression::OutputModelProperty(e) => self.generate_output_model_property(e),
3829 Expression::OverflowTruncateBehavior(e) => self.generate_overflow_truncate_behavior(e),
3830 Expression::ParameterizedAgg(e) => self.generate_parameterized_agg(e),
3831 Expression::ParseDatetime(e) => self.generate_parse_datetime(e),
3832 Expression::ParseIp(e) => self.generate_parse_ip(e),
3833 Expression::ParseJSON(e) => self.generate_parse_json(e),
3834 Expression::ParseTime(e) => self.generate_parse_time(e),
3835 Expression::ParseUrl(e) => self.generate_parse_url(e),
3836 Expression::Partition(e) => self.generate_partition_expr(e),
3837 Expression::PartitionBoundSpec(e) => self.generate_partition_bound_spec(e),
3838 Expression::PartitionByListProperty(e) => self.generate_partition_by_list_property(e),
3839 Expression::PartitionByRangeProperty(e) => self.generate_partition_by_range_property(e),
3840 Expression::PartitionByRangePropertyDynamic(e) => {
3841 self.generate_partition_by_range_property_dynamic(e)
3842 }
3843 Expression::PartitionByTruncate(e) => self.generate_partition_by_truncate(e),
3844 Expression::PartitionList(e) => self.generate_partition_list(e),
3845 Expression::PartitionRange(e) => self.generate_partition_range(e),
3846 Expression::PartitionByProperty(e) => self.generate_partition_by_property(e),
3847 Expression::PartitionedByBucket(e) => self.generate_partitioned_by_bucket(e),
3848 Expression::PartitionedByProperty(e) => self.generate_partitioned_by_property(e),
3849 Expression::PartitionedOfProperty(e) => self.generate_partitioned_of_property(e),
3850 Expression::PeriodForSystemTimeConstraint(e) => {
3851 self.generate_period_for_system_time_constraint(e)
3852 }
3853 Expression::PivotAlias(e) => self.generate_pivot_alias(e),
3854 Expression::PivotAny(e) => self.generate_pivot_any(e),
3855 Expression::Predict(e) => self.generate_predict(e),
3856 Expression::PreviousDay(e) => self.generate_previous_day(e),
3857 Expression::PrimaryKey(e) => self.generate_primary_key(e),
3858 Expression::PrimaryKeyColumnConstraint(e) => {
3859 self.generate_primary_key_column_constraint(e)
3860 }
3861 Expression::PathColumnConstraint(e) => self.generate_path_column_constraint(e),
3862 Expression::ProjectionDef(e) => self.generate_projection_def(e),
3863 Expression::OptionsProperty(e) => self.generate_options_property(e),
3864 Expression::Properties(e) => self.generate_properties(e),
3865 Expression::Property(e) => self.generate_property(e),
3866 Expression::PseudoType(e) => self.generate_pseudo_type(e),
3867 Expression::Put(e) => self.generate_put(e),
3868 Expression::Quantile(e) => self.generate_quantile(e),
3869 Expression::QueryBand(e) => self.generate_query_band(e),
3870 Expression::QueryOption(e) => self.generate_query_option(e),
3871 Expression::QueryTransform(e) => self.generate_query_transform(e),
3872 Expression::Randn(e) => self.generate_randn(e),
3873 Expression::Randstr(e) => self.generate_randstr(e),
3874 Expression::RangeBucket(e) => self.generate_range_bucket(e),
3875 Expression::RangeN(e) => self.generate_range_n(e),
3876 Expression::ReadCSV(e) => self.generate_read_csv(e),
3877 Expression::ReadParquet(e) => self.generate_read_parquet(e),
3878 Expression::RecursiveWithSearch(e) => self.generate_recursive_with_search(e),
3879 Expression::Reduce(e) => self.generate_reduce(e),
3880 Expression::Reference(e) => self.generate_reference(e),
3881 Expression::Refresh(e) => self.generate_refresh(e),
3882 Expression::RefreshTriggerProperty(e) => self.generate_refresh_trigger_property(e),
3883 Expression::RegexpCount(e) => self.generate_regexp_count(e),
3884 Expression::RegexpExtractAll(e) => self.generate_regexp_extract_all(e),
3885 Expression::RegexpFullMatch(e) => self.generate_regexp_full_match(e),
3886 Expression::RegexpILike(e) => self.generate_regexp_i_like(e),
3887 Expression::RegexpInstr(e) => self.generate_regexp_instr(e),
3888 Expression::RegexpSplit(e) => self.generate_regexp_split(e),
3889 Expression::RegrAvgx(e) => self.generate_regr_avgx(e),
3890 Expression::RegrAvgy(e) => self.generate_regr_avgy(e),
3891 Expression::RegrCount(e) => self.generate_regr_count(e),
3892 Expression::RegrIntercept(e) => self.generate_regr_intercept(e),
3893 Expression::RegrR2(e) => self.generate_regr_r2(e),
3894 Expression::RegrSlope(e) => self.generate_regr_slope(e),
3895 Expression::RegrSxx(e) => self.generate_regr_sxx(e),
3896 Expression::RegrSxy(e) => self.generate_regr_sxy(e),
3897 Expression::RegrSyy(e) => self.generate_regr_syy(e),
3898 Expression::RegrValx(e) => self.generate_regr_valx(e),
3899 Expression::RegrValy(e) => self.generate_regr_valy(e),
3900 Expression::RemoteWithConnectionModelProperty(e) => {
3901 self.generate_remote_with_connection_model_property(e)
3902 }
3903 Expression::RenameColumn(e) => self.generate_rename_column(e),
3904 Expression::ReplacePartition(e) => self.generate_replace_partition(e),
3905 Expression::Returning(e) => self.generate_returning(e),
3906 Expression::ReturnsProperty(e) => self.generate_returns_property(e),
3907 Expression::Rollback(e) => self.generate_rollback(e),
3908 Expression::Rollup(e) => self.generate_rollup(e),
3909 Expression::RowFormatDelimitedProperty(e) => {
3910 self.generate_row_format_delimited_property(e)
3911 }
3912 Expression::RowFormatProperty(e) => self.generate_row_format_property(e),
3913 Expression::RowFormatSerdeProperty(e) => self.generate_row_format_serde_property(e),
3914 Expression::SHA2(e) => self.generate_sha2(e),
3915 Expression::SHA2Digest(e) => self.generate_sha2_digest(e),
3916 Expression::SafeAdd(e) => self.generate_safe_add(e),
3917 Expression::SafeDivide(e) => self.generate_safe_divide(e),
3918 Expression::SafeMultiply(e) => self.generate_safe_multiply(e),
3919 Expression::SafeSubtract(e) => self.generate_safe_subtract(e),
3920 Expression::SampleProperty(e) => self.generate_sample_property(e),
3921 Expression::Schema(e) => self.generate_schema(e),
3922 Expression::SchemaCommentProperty(e) => self.generate_schema_comment_property(e),
3923 Expression::ScopeResolution(e) => self.generate_scope_resolution(e),
3924 Expression::Search(e) => self.generate_search(e),
3925 Expression::SearchIp(e) => self.generate_search_ip(e),
3926 Expression::SecurityProperty(e) => self.generate_security_property(e),
3927 Expression::SemanticView(e) => self.generate_semantic_view(e),
3928 Expression::SequenceProperties(e) => self.generate_sequence_properties(e),
3929 Expression::SerdeProperties(e) => self.generate_serde_properties(e),
3930 Expression::SessionParameter(e) => self.generate_session_parameter(e),
3931 Expression::Set(e) => self.generate_set(e),
3932 Expression::SetConfigProperty(e) => self.generate_set_config_property(e),
3933 Expression::SetItem(e) => self.generate_set_item(e),
3934 Expression::SetOperation(e) => self.generate_set_operation(e),
3935 Expression::SetProperty(e) => self.generate_set_property(e),
3936 Expression::SettingsProperty(e) => self.generate_settings_property(e),
3937 Expression::SharingProperty(e) => self.generate_sharing_property(e),
3938 Expression::Slice(e) => self.generate_slice(e),
3939 Expression::SortArray(e) => self.generate_sort_array(e),
3940 Expression::SortBy(e) => self.generate_sort_by(e),
3941 Expression::SortKeyProperty(e) => self.generate_sort_key_property(e),
3942 Expression::SplitPart(e) => self.generate_split_part(e),
3943 Expression::SqlReadWriteProperty(e) => self.generate_sql_read_write_property(e),
3944 Expression::SqlSecurityProperty(e) => self.generate_sql_security_property(e),
3945 Expression::StDistance(e) => self.generate_st_distance(e),
3946 Expression::StPoint(e) => self.generate_st_point(e),
3947 Expression::StabilityProperty(e) => self.generate_stability_property(e),
3948 Expression::StandardHash(e) => self.generate_standard_hash(e),
3949 Expression::StorageHandlerProperty(e) => self.generate_storage_handler_property(e),
3950 Expression::StrPosition(e) => self.generate_str_position(e),
3951 Expression::StrToDate(e) => self.generate_str_to_date(e),
3952 Expression::DateStrToDate(f) => self.generate_simple_func("DATE_STR_TO_DATE", &f.this),
3953 Expression::DateToDateStr(f) => self.generate_simple_func("DATE_TO_DATE_STR", &f.this),
3954 Expression::StrToMap(e) => self.generate_str_to_map(e),
3955 Expression::StrToTime(e) => self.generate_str_to_time(e),
3956 Expression::StrToUnix(e) => self.generate_str_to_unix(e),
3957 Expression::StringToArray(e) => self.generate_string_to_array(e),
3958 Expression::Struct(e) => self.generate_struct(e),
3959 Expression::Stuff(e) => self.generate_stuff(e),
3960 Expression::SubstringIndex(e) => self.generate_substring_index(e),
3961 Expression::Summarize(e) => self.generate_summarize(e),
3962 Expression::Systimestamp(e) => self.generate_systimestamp(e),
3963 Expression::TableAlias(e) => self.generate_table_alias(e),
3964 Expression::TableFromRows(e) => self.generate_table_from_rows(e),
3965 Expression::RowsFrom(e) => self.generate_rows_from(e),
3966 Expression::TableSample(e) => self.generate_table_sample(e),
3967 Expression::Tag(e) => self.generate_tag(e),
3968 Expression::Tags(e) => self.generate_tags(e),
3969 Expression::TemporaryProperty(e) => self.generate_temporary_property(e),
3970 Expression::Time(e) => self.generate_time_func(e),
3971 Expression::TimeAdd(e) => self.generate_time_add(e),
3972 Expression::TimeDiff(e) => self.generate_time_diff(e),
3973 Expression::TimeFromParts(e) => self.generate_time_from_parts(e),
3974 Expression::TimeSlice(e) => self.generate_time_slice(e),
3975 Expression::TimeStrToDate(e) => self.generate_time_str_to_date(e),
3976 Expression::TimeStrToTime(e) => self.generate_time_str_to_time(e),
3977 Expression::TimeSub(e) => self.generate_time_sub(e),
3978 Expression::TimeToStr(e) => self.generate_time_to_str(e),
3979 Expression::TimeToUnix(e) => self.generate_time_to_unix(e),
3980 Expression::TimeTrunc(e) => self.generate_time_trunc(e),
3981 Expression::TimeUnit(e) => self.generate_time_unit(e),
3982 Expression::Timestamp(e) => self.generate_timestamp_func(e),
3983 Expression::TimestampAdd(e) => self.generate_timestamp_add(e),
3984 Expression::TimestampDiff(e) => self.generate_timestamp_diff(e),
3985 Expression::TimestampFromParts(e) => self.generate_timestamp_from_parts(e),
3986 Expression::TimestampSub(e) => self.generate_timestamp_sub(e),
3987 Expression::TimestampTzFromParts(e) => self.generate_timestamp_tz_from_parts(e),
3988 Expression::ToBinary(e) => self.generate_to_binary(e),
3989 Expression::ToBoolean(e) => self.generate_to_boolean(e),
3990 Expression::ToChar(e) => self.generate_to_char(e),
3991 Expression::ToDecfloat(e) => self.generate_to_decfloat(e),
3992 Expression::ToDouble(e) => self.generate_to_double(e),
3993 Expression::ToFile(e) => self.generate_to_file(e),
3994 Expression::ToNumber(e) => self.generate_to_number(e),
3995 Expression::ToTableProperty(e) => self.generate_to_table_property(e),
3996 Expression::Transaction(e) => self.generate_transaction(e),
3997 Expression::Transform(e) => self.generate_transform(e),
3998 Expression::TransformModelProperty(e) => self.generate_transform_model_property(e),
3999 Expression::TransientProperty(e) => self.generate_transient_property(e),
4000 Expression::Translate(e) => self.generate_translate(e),
4001 Expression::TranslateCharacters(e) => self.generate_translate_characters(e),
4002 Expression::TruncateTable(e) => self.generate_truncate_table(e),
4003 Expression::TryBase64DecodeBinary(e) => self.generate_try_base64_decode_binary(e),
4004 Expression::TryBase64DecodeString(e) => self.generate_try_base64_decode_string(e),
4005 Expression::TryToDecfloat(e) => self.generate_try_to_decfloat(e),
4006 Expression::TsOrDsAdd(e) => self.generate_ts_or_ds_add(e),
4007 Expression::TsOrDsDiff(e) => self.generate_ts_or_ds_diff(e),
4008 Expression::TsOrDsToDate(e) => self.generate_ts_or_ds_to_date(e),
4009 Expression::TsOrDsToTime(e) => self.generate_ts_or_ds_to_time(e),
4010 Expression::Unhex(e) => self.generate_unhex(e),
4011 Expression::UnicodeString(e) => self.generate_unicode_string(e),
4012 Expression::Uniform(e) => self.generate_uniform(e),
4013 Expression::UniqueColumnConstraint(e) => self.generate_unique_column_constraint(e),
4014 Expression::UniqueKeyProperty(e) => self.generate_unique_key_property(e),
4015 Expression::RollupProperty(e) => self.generate_rollup_property(e),
4016 Expression::UnixToStr(e) => self.generate_unix_to_str(e),
4017 Expression::UnixToTime(e) => self.generate_unix_to_time(e),
4018 Expression::UnpivotColumns(e) => self.generate_unpivot_columns(e),
4019 Expression::UserDefinedFunction(e) => self.generate_user_defined_function(e),
4020 Expression::UsingTemplateProperty(e) => self.generate_using_template_property(e),
4021 Expression::UtcTime(e) => self.generate_utc_time(e),
4022 Expression::UtcTimestamp(e) => self.generate_utc_timestamp(e),
4023 Expression::Uuid(e) => self.generate_uuid(e),
4024 Expression::Var(v) => {
4025 if matches!(self.config.dialect, Some(DialectType::MySQL))
4026 && v.this.len() > 2
4027 && (v.this.starts_with("0x") || v.this.starts_with("0X"))
4028 && !v.this[2..].chars().all(|c| c.is_ascii_hexdigit())
4029 {
4030 return self.generate_identifier(&Identifier {
4031 name: v.this.clone(),
4032 quoted: true,
4033 trailing_comments: Vec::new(),
4034 span: None,
4035 });
4036 }
4037 self.write(&v.this);
4038 Ok(())
4039 }
4040 Expression::Variadic(e) => {
4041 self.write_keyword("VARIADIC");
4042 self.write_space();
4043 self.generate_expression(&e.this)?;
4044 Ok(())
4045 }
4046 Expression::VarMap(e) => self.generate_var_map(e),
4047 Expression::VectorSearch(e) => self.generate_vector_search(e),
4048 Expression::Version(e) => self.generate_version(e),
4049 Expression::ViewAttributeProperty(e) => self.generate_view_attribute_property(e),
4050 Expression::VolatileProperty(e) => self.generate_volatile_property(e),
4051 Expression::WatermarkColumnConstraint(e) => {
4052 self.generate_watermark_column_constraint(e)
4053 }
4054 Expression::Week(e) => self.generate_week(e),
4055 Expression::When(e) => self.generate_when(e),
4056 Expression::Whens(e) => self.generate_whens(e),
4057 Expression::Where(e) => self.generate_where(e),
4058 Expression::WidthBucket(e) => self.generate_width_bucket(e),
4059 Expression::Window(e) => self.generate_window(e),
4060 Expression::WindowSpec(e) => self.generate_window_spec(e),
4061 Expression::WithDataProperty(e) => self.generate_with_data_property(e),
4062 Expression::WithFill(e) => self.generate_with_fill(e),
4063 Expression::WithJournalTableProperty(e) => self.generate_with_journal_table_property(e),
4064 Expression::WithOperator(e) => self.generate_with_operator(e),
4065 Expression::WithProcedureOptions(e) => self.generate_with_procedure_options(e),
4066 Expression::WithSchemaBindingProperty(e) => {
4067 self.generate_with_schema_binding_property(e)
4068 }
4069 Expression::WithSystemVersioningProperty(e) => {
4070 self.generate_with_system_versioning_property(e)
4071 }
4072 Expression::WithTableHint(e) => self.generate_with_table_hint(e),
4073 Expression::XMLElement(e) => self.generate_xml_element(e),
4074 Expression::XMLGet(e) => self.generate_xml_get(e),
4075 Expression::XMLKeyValueOption(e) => self.generate_xml_key_value_option(e),
4076 Expression::XMLTable(e) => self.generate_xml_table(e),
4077 Expression::Xor(e) => self.generate_xor(e),
4078 Expression::Zipf(e) => self.generate_zipf(e),
4079 _ => self.write_unsupported_comment("unsupported expression"),
4080 }
4081 }
4082
4083 fn should_handle_tsql_distinct_null_ordering(&self, select: &Select) -> bool {
4084 matches!(
4085 self.config.dialect,
4086 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4087 ) && !self.config.null_ordering_supported
4088 && select.distinct
4089 && select.order_by.as_ref().is_some_and(|order_by| {
4090 order_by
4091 .expressions
4092 .iter()
4093 .any(Self::ordered_requires_tsql_null_ordering_emulation)
4094 })
4095 }
4096
4097 fn ordered_requires_tsql_null_ordering_emulation(ordered: &Ordered) -> bool {
4098 let Some(nulls_first) = ordered.nulls_first else {
4099 return false;
4100 };
4101
4102 let random_ordering = matches!(ordered.this, Expression::Rand(_) | Expression::Random(_));
4103 let target_default_nulls_first = !ordered.desc;
4104
4105 nulls_first != target_default_nulls_first && !random_ordering
4106 }
4107
4108 fn projection_output_identifier(expression: &Expression) -> Option<Identifier> {
4109 match expression {
4110 Expression::Alias(alias) if !alias.alias.name.is_empty() => Some(alias.alias.clone()),
4111 Expression::Column(column) => Some(column.name.clone()),
4112 Expression::Identifier(identifier) => Some(identifier.clone()),
4113 _ => None,
4114 }
4115 }
4116
4117 fn identifier_names_match(left: &Identifier, right: &Identifier) -> bool {
4118 if left.quoted || right.quoted {
4119 left.name == right.name
4120 } else {
4121 left.name.eq_ignore_ascii_case(&right.name)
4122 }
4123 }
4124
4125 fn expression_matches_identifier(expression: &Expression, identifier: &Identifier) -> bool {
4126 match expression {
4127 Expression::Column(column) if column.table.is_none() => {
4128 Self::identifier_names_match(&column.name, identifier)
4129 }
4130 Expression::Identifier(other) => Self::identifier_names_match(other, identifier),
4131 _ => false,
4132 }
4133 }
4134
4135 fn column_expression(identifier: Identifier) -> Expression {
4136 Expression::Column(Box::new(Column {
4137 name: identifier,
4138 table: None,
4139 join_mark: false,
4140 trailing_comments: Vec::new(),
4141 span: None,
4142 inferred_type: None,
4143 }))
4144 }
4145
4146 fn positional_ordering_index(expression: &Expression) -> Option<usize> {
4147 match expression {
4148 Expression::Literal(lit) => match lit.as_ref() {
4149 Literal::Number(n) => {
4150 let value = n.parse::<usize>().ok()?;
4151 value.checked_sub(1)
4152 }
4153 _ => None,
4154 },
4155 _ => None,
4156 }
4157 }
4158
4159 fn projection_sort_expression(expression: &Expression) -> Option<Expression> {
4160 let expression = match expression {
4161 Expression::Alias(alias) => &alias.this,
4162 other => other,
4163 };
4164
4165 match expression {
4166 Expression::Star(_)
4167 | Expression::Literal(_)
4168 | Expression::Null(_)
4169 | Expression::Boolean(_) => None,
4170 _ => Some(expression.clone()),
4171 }
4172 }
4173
4174 fn resolve_positional_order_projection(
4175 projections: &[Expression],
4176 index: usize,
4177 ) -> Option<Expression> {
4178 Self::projection_sort_expression(projections.get(index)?)
4179 }
4180
4181 fn is_direct_grouping_expression(expression: &Expression) -> bool {
4182 match expression {
4183 Expression::Paren(paren) => Self::is_direct_grouping_expression(&paren.this),
4184 Expression::Grouping(_) | Expression::GroupingId(_) => true,
4185 Expression::Function(function) => {
4186 function.name.eq_ignore_ascii_case("GROUPING")
4187 || function.name.eq_ignore_ascii_case("GROUPING_ID")
4188 }
4189 _ => false,
4190 }
4191 }
4192
4193 fn group_by_has_multiple_grouping_levels(group_by: &GroupBy) -> bool {
4194 group_by
4195 .expressions
4196 .iter()
4197 .any(|expression| match expression {
4198 Expression::Cube(_) | Expression::Rollup(_) => true,
4199 Expression::GroupingSets(grouping_sets) => grouping_sets.expressions.len() > 1,
4200 Expression::Function(function)
4201 if function.name.eq_ignore_ascii_case("CUBE")
4202 || function.name.eq_ignore_ascii_case("ROLLUP") =>
4203 {
4204 !function.args.is_empty()
4205 }
4206 Expression::Function(function)
4207 if function.name.eq_ignore_ascii_case("GROUPING SETS") =>
4208 {
4209 function.args.len() > 1
4210 || function.args.first().is_some_and(|expression| {
4211 matches!(expression, Expression::Cube(_) | Expression::Rollup(_))
4212 || matches!(expression,
4213 Expression::Function(nested)
4214 if nested.name.eq_ignore_ascii_case("CUBE")
4215 || nested.name.eq_ignore_ascii_case("ROLLUP")
4216 )
4217 })
4218 }
4219 _ => false,
4220 })
4221 }
4222
4223 fn set_output_identifier_at(expression: &Expression, index: usize) -> Option<Identifier> {
4224 match expression {
4225 Expression::Select(select) => {
4226 Self::projection_output_identifier(select.expressions.get(index)?)
4227 }
4228 Expression::Union(union) => Self::set_output_identifier_at(&union.left, index),
4229 Expression::Intersect(intersect) => {
4230 Self::set_output_identifier_at(&intersect.left, index)
4231 }
4232 Expression::Except(except) => Self::set_output_identifier_at(&except.left, index),
4233 Expression::Subquery(subquery) => subquery
4234 .column_aliases
4235 .get(index)
4236 .cloned()
4237 .or_else(|| Self::set_output_identifier_at(&subquery.this, index)),
4238 _ => None,
4239 }
4240 }
4241
4242 fn resolve_single_subquery_star_projection(
4243 select: &Select,
4244 index: usize,
4245 ) -> Option<Expression> {
4246 if select.expressions.len() != 1
4247 || !matches!(select.expressions.first(), Some(Expression::Star(_)))
4248 {
4249 return None;
4250 }
4251
4252 let from = select.from.as_ref()?;
4253 if from.expressions.len() != 1 {
4254 return None;
4255 }
4256
4257 let Expression::Subquery(subquery) = from.expressions.first()? else {
4258 return None;
4259 };
4260
4261 subquery
4262 .column_aliases
4263 .get(index)
4264 .cloned()
4265 .or_else(|| Self::set_output_identifier_at(&subquery.this, index))
4266 .map(Self::column_expression)
4267 }
4268
4269 fn sole_tsql_ordering_source_qualifier(select: &Select) -> Option<Identifier> {
4270 if !select.joins.is_empty() {
4271 return None;
4272 }
4273
4274 let from = select.from.as_ref()?;
4275 if from.expressions.len() != 1 {
4276 return None;
4277 }
4278
4279 match from.expressions.first()? {
4280 Expression::Table(table) => {
4281 Some(table.alias.clone().unwrap_or_else(|| table.name.clone()))
4282 }
4283 Expression::Subquery(subquery) => subquery.alias.clone(),
4284 _ => None,
4285 }
4286 }
4287
4288 fn resolve_duplicate_tsql_ordering_column(
4289 select: &Select,
4290 expression: &Expression,
4291 ) -> Option<Expression> {
4292 let Expression::Column(order_column) = expression else {
4293 return None;
4294 };
4295 if order_column.table.is_some() {
4296 return None;
4297 }
4298
4299 let matching_projections: Vec<_> = select
4300 .expressions
4301 .iter()
4302 .filter(|projection| {
4303 Self::projection_output_identifier(projection).is_some_and(|identifier| {
4304 Self::identifier_names_match(&identifier, &order_column.name)
4305 })
4306 })
4307 .filter_map(Self::projection_sort_expression)
4308 .collect();
4309
4310 if matching_projections.len() < 2
4311 || matching_projections[1..]
4312 .iter()
4313 .any(|projection| projection != &matching_projections[0])
4314 {
4315 return None;
4316 }
4317
4318 let Expression::Column(projected_column) = &matching_projections[0] else {
4319 return None;
4320 };
4321 if !Self::identifier_names_match(&projected_column.name, &order_column.name) {
4322 return None;
4323 }
4324
4325 let qualifier = projected_column
4326 .table
4327 .clone()
4328 .or_else(|| Self::sole_tsql_ordering_source_qualifier(select))?;
4329 let mut resolved = order_column.as_ref().clone();
4330 resolved.table = Some(qualifier);
4331 Some(Expression::Column(Box::new(resolved)))
4332 }
4333
4334 fn resolve_tsql_null_ordering_for_select(&self, select: &Select) -> Option<Select> {
4335 if !matches!(
4336 self.config.dialect,
4337 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4338 ) || self.config.null_ordering_supported
4339 {
4340 return None;
4341 }
4342
4343 let order_by = select.order_by.as_ref()?;
4344 let grouping_order_is_constant = matches!(self.config.dialect, Some(DialectType::Fabric))
4345 && select
4346 .group_by
4347 .as_ref()
4348 .is_some_and(|group_by| !Self::group_by_has_multiple_grouping_levels(group_by));
4349 let mut resolved_expressions = Vec::with_capacity(order_by.expressions.len());
4350 let mut changed = false;
4351
4352 for mut ordered in order_by.expressions.iter().cloned() {
4353 if Self::ordered_requires_tsql_null_ordering_emulation(&ordered) {
4354 if let Some(index) = Self::positional_ordering_index(&ordered.this) {
4355 if let Some(resolved) =
4356 Self::resolve_positional_order_projection(&select.expressions, index)
4357 .or_else(|| {
4358 Self::resolve_single_subquery_star_projection(select, index)
4359 })
4360 {
4361 if resolved != ordered.this {
4362 ordered.this = resolved;
4363 changed = true;
4364 }
4365 }
4366 }
4367
4368 if let Some(resolved) =
4369 Self::resolve_duplicate_tsql_ordering_column(select, &ordered.this)
4370 {
4371 ordered.this = resolved;
4372 changed = true;
4373 }
4374 }
4375
4376 if grouping_order_is_constant && Self::is_direct_grouping_expression(&ordered.this) {
4380 changed = true;
4381 continue;
4382 }
4383
4384 resolved_expressions.push(ordered);
4385 }
4386
4387 if changed {
4388 let mut resolved_select = select.clone();
4389 resolved_select.order_by = if resolved_expressions.is_empty() {
4390 None
4391 } else {
4392 Some(OrderBy {
4393 expressions: resolved_expressions,
4394 siblings: order_by.siblings,
4395 comments: order_by.comments.clone(),
4396 })
4397 };
4398 Some(resolved_select)
4399 } else {
4400 None
4401 }
4402 }
4403
4404 fn resolve_distinct_order_projection(
4405 projections: &[Expression],
4406 order_expression: &Expression,
4407 ) -> Option<Expression> {
4408 for projection in projections {
4409 if let Expression::Alias(alias) = projection {
4410 if Self::expression_matches_identifier(order_expression, &alias.alias)
4411 || &alias.this == order_expression
4412 {
4413 return Some(alias.this.clone());
4414 }
4415 } else if projection == order_expression {
4416 return Some(projection.clone());
4417 } else if let Some(identifier) = Self::projection_output_identifier(projection) {
4418 if Self::expression_matches_identifier(order_expression, &identifier) {
4419 return Some(projection.clone());
4420 }
4421 }
4422 }
4423
4424 None
4425 }
4426
4427 fn fresh_polyglot_alias(base: &str, index: usize, used_names: &mut Vec<String>) -> String {
4428 let mut suffix = 0;
4429 loop {
4430 let candidate = if suffix == 0 {
4431 format!("{base}_{index}")
4432 } else {
4433 format!("{base}_{index}_{suffix}")
4434 };
4435
4436 if !used_names
4437 .iter()
4438 .any(|name| name.eq_ignore_ascii_case(&candidate))
4439 {
4440 used_names.push(candidate.clone());
4441 return candidate;
4442 }
4443
4444 suffix += 1;
4445 }
4446 }
4447
4448 fn tsql_null_ordering_case(expression: Expression) -> Expression {
4449 Expression::Case(Box::new(Case {
4450 operand: None,
4451 whens: vec![(
4452 Expression::IsNull(Box::new(IsNull {
4453 this: expression,
4454 not: false,
4455 postfix_form: false,
4456 })),
4457 Expression::number(1),
4458 )],
4459 else_: Some(Expression::number(0)),
4460 comments: Vec::new(),
4461 inferred_type: None,
4462 }))
4463 }
4464
4465 fn try_build_tsql_distinct_null_ordering_wrapper(&self, select: &Select) -> Option<Select> {
4466 let order_by = select.order_by.as_ref()?;
4467
4468 if order_by.siblings
4469 || select.distinct_on.is_some()
4470 || select.distribute_by.is_some()
4471 || select.cluster_by.is_some()
4472 || select.sort_by.is_some()
4473 || select.limit.is_some()
4474 || select.offset.is_some()
4475 || select.limit_by.is_some()
4476 || select.fetch.is_some()
4477 || select.top.is_some()
4478 || select.settings.is_some()
4479 || select.format.is_some()
4480 || select.kind.is_some()
4481 || select.hint.is_some()
4482 || select.into.is_some()
4483 || !select.locks.is_empty()
4484 || !select.for_xml.is_empty()
4485 || !select.for_json.is_empty()
4486 || !select.operation_modifiers.is_empty()
4487 || select.option.is_some()
4488 || select.exclude.is_some()
4489 {
4490 return None;
4491 }
4492
4493 let projection_identifiers: Vec<_> = select
4494 .expressions
4495 .iter()
4496 .map(Self::projection_output_identifier)
4497 .collect::<Option<_>>()?;
4498 let mut used_names: Vec<_> = projection_identifiers
4499 .iter()
4500 .map(|identifier| identifier.name.clone())
4501 .collect();
4502
4503 let mut inner = select.clone();
4504 inner.order_by = None;
4505
4506 let outer_with = inner.with.take();
4507 let outer_leading_comments = std::mem::take(&mut inner.leading_comments);
4508 let outer_post_select_comments = std::mem::take(&mut inner.post_select_comments);
4509
4510 let mut outer_order_expressions = Vec::with_capacity(order_by.expressions.len() * 2);
4511 for (index, ordered) in order_by.expressions.iter().enumerate() {
4512 if ordered.with_fill.is_some() {
4513 return None;
4514 }
4515
4516 let sort_expression =
4517 Self::resolve_distinct_order_projection(&select.expressions, &ordered.this)?;
4518
4519 if Self::ordered_requires_tsql_null_ordering_emulation(ordered) {
4520 let null_alias =
4521 Self::fresh_polyglot_alias("_polyglot_order_null", index, &mut used_names);
4522 inner.expressions.push(
4523 Self::tsql_null_ordering_case(sort_expression.clone())
4524 .alias(null_alias.clone()),
4525 );
4526 outer_order_expressions.push(Ordered {
4527 this: Expression::column(null_alias),
4528 desc: ordered.nulls_first == Some(true),
4529 nulls_first: None,
4530 explicit_asc: false,
4531 with_fill: None,
4532 });
4533 }
4534
4535 let key_alias =
4536 Self::fresh_polyglot_alias("_polyglot_order_key", index, &mut used_names);
4537 inner
4538 .expressions
4539 .push(sort_expression.alias(key_alias.clone()));
4540 outer_order_expressions.push(Ordered {
4541 this: Expression::column(key_alias),
4542 desc: ordered.desc,
4543 nulls_first: None,
4544 explicit_asc: ordered.explicit_asc,
4545 with_fill: None,
4546 });
4547 }
4548
4549 let subquery = Subquery {
4550 this: Expression::Select(Box::new(inner)),
4551 alias: Some(Identifier::new("_polyglot_distinct_order")),
4552 column_aliases: Vec::new(),
4553 alias_explicit_as: true,
4554 alias_keyword: None,
4555 order_by: None,
4556 limit: None,
4557 offset: None,
4558 distribute_by: None,
4559 sort_by: None,
4560 cluster_by: None,
4561 lateral: false,
4562 modifiers_inside: false,
4563 trailing_comments: Vec::new(),
4564 inferred_type: None,
4565 };
4566
4567 let mut outer = Select::new();
4568 outer.with = outer_with;
4569 outer.leading_comments = outer_leading_comments;
4570 outer.post_select_comments = outer_post_select_comments;
4571 outer.expressions = projection_identifiers
4572 .into_iter()
4573 .map(Self::column_expression)
4574 .collect();
4575 outer.from = Some(From {
4576 expressions: vec![Expression::Subquery(Box::new(subquery))],
4577 });
4578 outer.order_by = Some(OrderBy {
4579 expressions: outer_order_expressions,
4580 siblings: false,
4581 comments: order_by.comments.clone(),
4582 });
4583
4584 Some(outer)
4585 }
4586
4587 fn generate_select(&mut self, select: &Select) -> Result<()> {
4588 use crate::dialects::DialectType;
4589
4590 if let Some(resolved_select) = self.resolve_tsql_null_ordering_for_select(select) {
4591 return self.generate_select(&resolved_select);
4592 }
4593
4594 if self.should_handle_tsql_distinct_null_ordering(select) {
4595 if let Some(wrapped_select) = self.try_build_tsql_distinct_null_ordering_wrapper(select)
4596 {
4597 return self.generate_select(&wrapped_select);
4598 }
4599
4600 self.unsupported(
4601 "SELECT DISTINCT with emulated NULL ordering is not supported for TSQL/Fabric",
4602 )?;
4603 }
4604
4605 if let Some(exclude) = &select.exclude {
4609 if !exclude.is_empty() && !matches!(self.config.dialect, Some(DialectType::Redshift)) {
4610 let mut inner_select = select.clone();
4612 inner_select.exclude = None;
4613 let inner_expr = Expression::Select(Box::new(inner_select));
4614
4615 let subquery = crate::expressions::Subquery {
4617 this: inner_expr,
4618 alias: None,
4619 column_aliases: Vec::new(),
4620 alias_explicit_as: false,
4621 alias_keyword: None,
4622 order_by: None,
4623 limit: None,
4624 offset: None,
4625 distribute_by: None,
4626 sort_by: None,
4627 cluster_by: None,
4628 lateral: false,
4629 modifiers_inside: false,
4630 trailing_comments: Vec::new(),
4631 inferred_type: None,
4632 };
4633
4634 let star = Expression::Star(crate::expressions::Star {
4636 table: None,
4637 except: Some(
4638 exclude
4639 .iter()
4640 .map(|e| match e {
4641 Expression::Column(col) => col.name.clone(),
4642 Expression::Identifier(id) => id.clone(),
4643 _ => crate::expressions::Identifier::new("unknown".to_string()),
4644 })
4645 .collect(),
4646 ),
4647 replace: None,
4648 rename: None,
4649 trailing_comments: Vec::new(),
4650 span: None,
4651 });
4652
4653 let outer_select = Select {
4654 expressions: vec![star],
4655 from: Some(crate::expressions::From {
4656 expressions: vec![Expression::Subquery(Box::new(subquery))],
4657 }),
4658 ..Select::new()
4659 };
4660
4661 return self.generate_select(&outer_select);
4662 }
4663 }
4664
4665 for comment in &select.leading_comments {
4667 self.write_formatted_comment(comment);
4668 self.write(" ");
4669 }
4670
4671 if let Some(with) = &select.with {
4673 self.generate_with(with)?;
4674 if self.config.pretty {
4675 self.write_newline();
4676 self.write_indent();
4677 } else {
4678 self.write_space();
4679 }
4680 }
4681
4682 for comment in &select.post_select_comments {
4685 self.write_formatted_comment(comment);
4686 self.write(" ");
4687 }
4688
4689 self.write_keyword("SELECT");
4690
4691 if let Some(hint) = &select.hint {
4693 self.generate_hint(hint)?;
4694 }
4695
4696 let use_top_from_limit = matches!(
4700 self.config.dialect,
4701 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4702 ) && select.top.is_none()
4703 && select
4704 .limit
4705 .as_ref()
4706 .is_some_and(|limit| !Self::is_noop_limit_expr(&limit.this))
4707 && select.offset.is_none(); let is_top_dialect = matches!(
4712 self.config.dialect,
4713 Some(DialectType::TSQL) | Some(DialectType::Teradata) | Some(DialectType::Fabric)
4714 );
4715 let keep_top_verbatim = !is_top_dialect
4716 && select.limit.is_none()
4717 && select
4718 .top
4719 .as_ref()
4720 .map_or(false, |top| top.percent || top.with_ties);
4721
4722 if select.distinct && (is_top_dialect || select.top.is_some()) {
4723 self.write_space();
4724 self.write_keyword("DISTINCT");
4725 }
4726
4727 if is_top_dialect || keep_top_verbatim {
4728 if let Some(top) = &select.top {
4729 self.write_space();
4730 self.write_keyword("TOP");
4731 if top.parenthesized {
4732 if matches!(&top.this, Expression::Subquery(_) | Expression::Paren(_)) {
4733 self.write_space();
4734 self.generate_expression(&top.this)?;
4735 } else {
4736 self.write(" (");
4737 self.generate_expression(&top.this)?;
4738 self.write(")");
4739 }
4740 } else {
4741 self.write_space();
4742 self.generate_expression(&top.this)?;
4743 }
4744 if top.percent {
4745 self.write_space();
4746 self.write_keyword("PERCENT");
4747 }
4748 if top.with_ties {
4749 self.write_space();
4750 self.write_keyword("WITH TIES");
4751 }
4752 } else if use_top_from_limit {
4753 if let Some(limit) = &select.limit {
4755 self.write_space();
4756 self.write_keyword("TOP");
4757 let is_simple_literal = matches!(&limit.this, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)));
4759 if is_simple_literal {
4760 self.write_space();
4761 self.generate_expression(&limit.this)?;
4762 } else {
4763 self.write(" (");
4764 self.generate_expression(&limit.this)?;
4765 self.write(")");
4766 }
4767 }
4768 }
4769 }
4770
4771 if select.distinct && !is_top_dialect && select.top.is_none() {
4772 self.write_space();
4773 self.write_keyword("DISTINCT");
4774 }
4775
4776 if let Some(distinct_on) = &select.distinct_on {
4778 self.write_space();
4779 self.write_keyword("ON");
4780 self.write(" (");
4781 for (i, expr) in distinct_on.iter().enumerate() {
4782 if i > 0 {
4783 self.write(", ");
4784 }
4785 self.generate_expression(expr)?;
4786 }
4787 self.write(")");
4788 }
4789
4790 for modifier in &select.operation_modifiers {
4792 self.write_space();
4793 self.write_keyword(modifier);
4794 }
4795
4796 if let Some(kind) = &select.kind {
4798 self.write_space();
4799 self.write_keyword("AS");
4800 self.write_space();
4801 self.write_keyword(kind);
4802 }
4803
4804 if !select.expressions.is_empty() {
4806 if self.config.pretty {
4807 self.write_newline();
4808 self.indent_level += 1;
4809 } else {
4810 self.write_space();
4811 }
4812 }
4813
4814 for (i, expr) in select.expressions.iter().enumerate() {
4815 if i > 0 {
4816 self.write(",");
4817 if self.config.pretty {
4818 self.write_newline();
4819 } else {
4820 self.write_space();
4821 }
4822 }
4823 if self.config.pretty {
4824 self.write_indent();
4825 }
4826 self.generate_expression(expr)?;
4827 }
4828
4829 if self.config.pretty && !select.expressions.is_empty() {
4830 self.indent_level -= 1;
4831 }
4832
4833 if let Some(exclude) = &select.exclude {
4838 if !exclude.is_empty() && matches!(self.config.dialect, Some(DialectType::Redshift)) {
4839 self.write_space();
4840 self.write_keyword("EXCLUDE");
4841 self.write(" (");
4842 for (i, col) in exclude.iter().enumerate() {
4843 if i > 0 {
4844 self.write(", ");
4845 }
4846 self.generate_expression(col)?;
4847 }
4848 self.write(")");
4849 }
4850 }
4851
4852 if let Some(into) = &select.into {
4855 if self.config.pretty {
4856 self.write_newline();
4857 self.write_indent();
4858 } else {
4859 self.write_space();
4860 }
4861 if into.bulk_collect {
4862 self.write_keyword("BULK COLLECT INTO");
4863 } else {
4864 self.write_keyword("INTO");
4865 }
4866 if into.temporary {
4867 self.write_space();
4868 self.write_keyword("TEMPORARY");
4869 }
4870 if into.unlogged {
4871 self.write_space();
4872 self.write_keyword("UNLOGGED");
4873 }
4874 self.write_space();
4875 if !into.expressions.is_empty() {
4877 for (i, expr) in into.expressions.iter().enumerate() {
4878 if i > 0 {
4879 self.write(", ");
4880 }
4881 self.generate_expression(expr)?;
4882 }
4883 } else {
4884 self.generate_expression(&into.this)?;
4885 }
4886 }
4887
4888 if let Some(from) = &select.from {
4890 if self.config.pretty {
4891 self.write_newline();
4892 self.write_indent();
4893 } else {
4894 self.write_space();
4895 }
4896 self.write_keyword("FROM");
4897 self.write_space();
4898
4899 let has_tablesample = from
4904 .expressions
4905 .iter()
4906 .any(|e| matches!(e, Expression::TableSample(_)));
4907 let is_cross_join_dialect = matches!(
4908 self.config.dialect,
4909 Some(DialectType::BigQuery)
4910 | Some(DialectType::Hive)
4911 | Some(DialectType::Spark)
4912 | Some(DialectType::Databricks)
4913 | Some(DialectType::SQLite)
4914 | Some(DialectType::ClickHouse)
4915 );
4916 let source_is_same_as_target = self.config.source_dialect.is_some()
4919 && self.config.source_dialect == self.config.dialect;
4920 let source_is_cross_join_dialect = matches!(
4921 self.config.source_dialect,
4922 Some(DialectType::BigQuery)
4923 | Some(DialectType::Hive)
4924 | Some(DialectType::Spark)
4925 | Some(DialectType::Databricks)
4926 | Some(DialectType::SQLite)
4927 | Some(DialectType::ClickHouse)
4928 );
4929 let use_cross_join = !has_tablesample
4930 && is_cross_join_dialect
4931 && (source_is_same_as_target
4932 || source_is_cross_join_dialect
4933 || self.config.source_dialect.is_none());
4934
4935 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
4937
4938 for (i, expr) in from.expressions.iter().enumerate() {
4939 if i > 0 {
4940 if use_cross_join {
4941 self.write(" CROSS JOIN ");
4942 } else {
4943 self.write(", ");
4944 }
4945 }
4946 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
4947 self.write("(");
4948 self.generate_expression(expr)?;
4949 self.write(")");
4950 } else {
4951 self.generate_expression(expr)?;
4952 }
4953 let leading = Self::extract_table_leading_comments(expr);
4956 for comment in &leading {
4957 self.write_space();
4958 self.write_formatted_comment(comment);
4959 }
4960 }
4961 }
4962
4963 if self.config.pretty {
4967 self.generate_joins_with_nesting(&select.joins)?;
4968 } else {
4969 for join in &select.joins {
4970 self.generate_join(join)?;
4971 }
4972 for join in select.joins.iter().rev() {
4974 if join.deferred_condition {
4975 self.generate_join_condition(join)?;
4976 }
4977 }
4978 }
4979
4980 for (lv_idx, lateral_view) in select.lateral_views.iter().enumerate() {
4982 self.generate_lateral_view(lateral_view, lv_idx)?;
4983 }
4984
4985 if let Some(prewhere) = &select.prewhere {
4987 self.write_clause_condition("PREWHERE", prewhere)?;
4988 }
4989
4990 if let Some(where_clause) = &select.where_clause {
4992 self.write_clause_condition("WHERE", &where_clause.this)?;
4993 }
4994
4995 if let Some(connect) = &select.connect {
4997 self.generate_connect(connect)?;
4998 }
4999
5000 if let Some(group_by) = &select.group_by {
5002 if self.config.pretty {
5003 for comment in &group_by.comments {
5005 self.write_newline();
5006 self.write_indent();
5007 self.write_formatted_comment(comment);
5008 }
5009 self.write_newline();
5010 self.write_indent();
5011 } else {
5012 self.write_space();
5013 for comment in &group_by.comments {
5015 self.write_formatted_comment(comment);
5016 self.write_space();
5017 }
5018 }
5019 let clickhouse_bare_modifiers =
5020 matches!(self.config.dialect, Some(DialectType::ClickHouse))
5021 && group_by.all.is_none()
5022 && (group_by.totals || !group_by.expressions.is_empty())
5023 && group_by.expressions.iter().all(|expr| match expr {
5024 Expression::Cube(c) => c.expressions.is_empty(),
5025 Expression::Rollup(r) => r.expressions.is_empty(),
5026 _ => false,
5027 });
5028
5029 if clickhouse_bare_modifiers {
5030 let trailing_cube = group_by
5031 .expressions
5032 .iter()
5033 .any(|expr| matches!(expr, Expression::Cube(c) if c.expressions.is_empty()));
5034 let trailing_rollup = group_by
5035 .expressions
5036 .iter()
5037 .any(|expr| matches!(expr, Expression::Rollup(r) if r.expressions.is_empty()));
5038
5039 if trailing_cube {
5040 self.write_keyword("WITH CUBE");
5041 } else if trailing_rollup {
5042 self.write_keyword("WITH ROLLUP");
5043 }
5044
5045 if group_by.totals {
5046 if trailing_cube || trailing_rollup {
5047 self.write_space();
5048 }
5049 self.write_keyword("WITH TOTALS");
5050 }
5051 } else {
5052 self.write_keyword("GROUP BY");
5053 match group_by.all {
5055 Some(true) => {
5056 self.write_space();
5057 self.write_keyword("ALL");
5058 }
5059 Some(false) => {
5060 self.write_space();
5061 self.write_keyword("DISTINCT");
5062 }
5063 None => {}
5064 }
5065 if !group_by.expressions.is_empty() {
5066 let mut trailing_cube = false;
5069 let mut trailing_rollup = false;
5070 let mut plain_expressions: Vec<&Expression> = Vec::new();
5071 let mut grouping_sets_expressions: Vec<&Expression> = Vec::new();
5072 let mut cube_expressions: Vec<&Expression> = Vec::new();
5073 let mut rollup_expressions: Vec<&Expression> = Vec::new();
5074
5075 for expr in &group_by.expressions {
5076 match expr {
5077 Expression::Cube(c) if c.expressions.is_empty() => {
5078 trailing_cube = true;
5079 }
5080 Expression::Rollup(r) if r.expressions.is_empty() => {
5081 trailing_rollup = true;
5082 }
5083 Expression::Function(f) if f.name == "CUBE" => {
5084 cube_expressions.push(expr);
5085 }
5086 Expression::Function(f) if f.name == "ROLLUP" => {
5087 rollup_expressions.push(expr);
5088 }
5089 Expression::Function(f) if f.name == "GROUPING SETS" => {
5090 grouping_sets_expressions.push(expr);
5091 }
5092 _ => {
5093 plain_expressions.push(expr);
5094 }
5095 }
5096 }
5097
5098 let mut regular_expressions: Vec<&Expression> = Vec::new();
5100 regular_expressions.extend(plain_expressions);
5101 regular_expressions.extend(grouping_sets_expressions);
5102 regular_expressions.extend(cube_expressions);
5103 regular_expressions.extend(rollup_expressions);
5104
5105 if self.config.pretty {
5106 self.write_newline();
5107 self.indent_level += 1;
5108 self.write_indent();
5109 } else {
5110 self.write_space();
5111 }
5112
5113 for (i, expr) in regular_expressions.iter().enumerate() {
5114 if i > 0 {
5115 if self.config.pretty {
5116 self.write(",");
5117 self.write_newline();
5118 self.write_indent();
5119 } else {
5120 self.write(", ");
5121 }
5122 }
5123 self.generate_expression(expr)?;
5124 }
5125
5126 if self.config.pretty {
5127 self.indent_level -= 1;
5128 }
5129
5130 if trailing_cube {
5132 self.write_space();
5133 self.write_keyword("WITH CUBE");
5134 } else if trailing_rollup {
5135 self.write_space();
5136 self.write_keyword("WITH ROLLUP");
5137 }
5138 }
5139
5140 if group_by.totals {
5142 self.write_space();
5143 self.write_keyword("WITH TOTALS");
5144 }
5145 }
5146 }
5147
5148 if let Some(having) = &select.having {
5150 if self.config.pretty {
5151 for comment in &having.comments {
5153 self.write_newline();
5154 self.write_indent();
5155 self.write_formatted_comment(comment);
5156 }
5157 } else {
5158 for comment in &having.comments {
5159 self.write_space();
5160 self.write_formatted_comment(comment);
5161 }
5162 }
5163 self.write_clause_condition("HAVING", &having.this)?;
5164 }
5165
5166 if select.qualify_after_window {
5168 if let Some(windows) = &select.windows {
5170 self.write_window_clause(windows)?;
5171 }
5172 if let Some(qualify) = &select.qualify {
5173 self.write_clause_condition("QUALIFY", &qualify.this)?;
5174 }
5175 } else {
5176 if let Some(qualify) = &select.qualify {
5178 self.write_clause_condition("QUALIFY", &qualify.this)?;
5179 }
5180 if let Some(windows) = &select.windows {
5181 self.write_window_clause(windows)?;
5182 }
5183 }
5184
5185 if let Some(distribute_by) = &select.distribute_by {
5187 self.write_clause_expressions("DISTRIBUTE BY", &distribute_by.expressions)?;
5188 }
5189
5190 if let Some(cluster_by) = &select.cluster_by {
5192 self.write_order_clause("CLUSTER BY", &cluster_by.expressions)?;
5193 }
5194
5195 if let Some(sort_by) = &select.sort_by {
5197 self.write_order_clause("SORT BY", &sort_by.expressions)?;
5198 }
5199
5200 if let Some(order_by) = &select.order_by {
5202 if self.config.pretty {
5203 for comment in &order_by.comments {
5205 self.write_newline();
5206 self.write_indent();
5207 self.write_formatted_comment(comment);
5208 }
5209 } else {
5210 for comment in &order_by.comments {
5211 self.write_space();
5212 self.write_formatted_comment(comment);
5213 }
5214 }
5215 let keyword = if order_by.siblings {
5216 "ORDER SIBLINGS BY"
5217 } else {
5218 "ORDER BY"
5219 };
5220 self.write_order_clause(keyword, &order_by.expressions)?;
5221 }
5222
5223 if select.order_by.is_none()
5225 && select.fetch.is_some()
5226 && matches!(
5227 self.config.dialect,
5228 Some(DialectType::TSQL) | Some(DialectType::Fabric)
5229 )
5230 {
5231 if self.config.pretty {
5232 self.write_newline();
5233 self.write_indent();
5234 } else {
5235 self.write_space();
5236 }
5237 self.write_keyword("ORDER BY (SELECT NULL) OFFSET 0 ROWS");
5238 }
5239
5240 let is_presto_like = matches!(
5245 self.config.dialect,
5246 Some(DialectType::Presto) | Some(DialectType::Trino)
5247 );
5248
5249 if is_presto_like && select.offset.is_some() {
5250 if let Some(offset) = &select.offset {
5252 if self.config.pretty {
5253 self.write_newline();
5254 self.write_indent();
5255 } else {
5256 self.write_space();
5257 }
5258 self.write_keyword("OFFSET");
5259 self.write_space();
5260 self.write_limit_expr(&offset.this)?;
5261 if offset.rows == Some(true) {
5262 self.write_space();
5263 self.write_keyword("ROWS");
5264 }
5265 }
5266 if let Some(limit) = &select.limit {
5267 if self.config.pretty {
5268 self.write_newline();
5269 self.write_indent();
5270 } else {
5271 self.write_space();
5272 }
5273 self.write_keyword("LIMIT");
5274 self.write_space();
5275 self.write_limit_expr(&limit.this)?;
5276 if limit.percent {
5277 self.write_space();
5278 self.write_keyword("PERCENT");
5279 }
5280 for comment in &limit.comments {
5282 self.write(" ");
5283 self.write_formatted_comment(comment);
5284 }
5285 }
5286 } else {
5287 let fetch_as_limit = select.fetch.as_ref().map_or(false, |fetch| {
5289 !fetch.percent
5290 && !fetch.with_ties
5291 && fetch.count.is_some()
5292 && matches!(
5293 self.config.dialect,
5294 Some(DialectType::Spark)
5295 | Some(DialectType::Hive)
5296 | Some(DialectType::DuckDB)
5297 | Some(DialectType::SQLite)
5298 | Some(DialectType::MySQL)
5299 | Some(DialectType::BigQuery)
5300 | Some(DialectType::Databricks)
5301 | Some(DialectType::StarRocks)
5302 | Some(DialectType::Doris)
5303 | Some(DialectType::Athena)
5304 | Some(DialectType::ClickHouse)
5305 | Some(DialectType::Redshift)
5306 )
5307 });
5308
5309 if let Some(limit) = &select.limit {
5311 if !matches!(
5313 self.config.dialect,
5314 Some(DialectType::TSQL) | Some(DialectType::Fabric)
5315 ) {
5316 if self.config.pretty {
5317 self.write_newline();
5318 self.write_indent();
5319 } else {
5320 self.write_space();
5321 }
5322 self.write_keyword("LIMIT");
5323 self.write_space();
5324 self.write_limit_expr(&limit.this)?;
5325 if limit.percent {
5326 self.write_space();
5327 self.write_keyword("PERCENT");
5328 }
5329 for comment in &limit.comments {
5331 self.write(" ");
5332 self.write_formatted_comment(comment);
5333 }
5334 }
5335 }
5336
5337 if select.top.is_some() && !is_top_dialect && select.limit.is_none() {
5339 if let Some(top) = &select.top {
5340 if !top.percent && !top.with_ties {
5341 if self.config.pretty {
5342 self.write_newline();
5343 self.write_indent();
5344 } else {
5345 self.write_space();
5346 }
5347 self.write_keyword("LIMIT");
5348 self.write_space();
5349 self.generate_expression(&top.this)?;
5350 }
5351 }
5352 }
5353
5354 if fetch_as_limit && select.offset.is_some() {
5357 if let Some(fetch) = &select.fetch {
5358 if self.config.pretty {
5359 self.write_newline();
5360 self.write_indent();
5361 } else {
5362 self.write_space();
5363 }
5364 self.write_keyword("LIMIT");
5365 self.write_space();
5366 self.generate_expression(fetch.count.as_ref().unwrap())?;
5367 }
5368 }
5369
5370 if let Some(offset) = &select.offset {
5374 if self.config.pretty {
5375 self.write_newline();
5376 self.write_indent();
5377 } else {
5378 self.write_space();
5379 }
5380 if matches!(
5381 self.config.dialect,
5382 Some(DialectType::TSQL) | Some(DialectType::Fabric)
5383 ) {
5384 self.write_keyword("OFFSET");
5386 self.write_space();
5387 self.write_limit_expr(&offset.this)?;
5388 self.write_space();
5389 self.write_keyword("ROWS");
5390 if let Some(limit) = &select.limit {
5394 if !Self::is_noop_limit_expr(&limit.this) {
5395 self.write_space();
5396 self.write_keyword("FETCH NEXT");
5397 self.write_space();
5398 self.write_limit_expr(&limit.this)?;
5399 self.write_space();
5400 self.write_keyword("ROWS ONLY");
5401 }
5402 }
5403 } else {
5404 self.write_keyword("OFFSET");
5405 self.write_space();
5406 self.write_limit_expr(&offset.this)?;
5407 if offset.rows == Some(true) {
5409 self.write_space();
5410 self.write_keyword("ROWS");
5411 }
5412 }
5413 }
5414 }
5415
5416 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
5418 if let Some(limit_by) = &select.limit_by {
5419 if !limit_by.is_empty() {
5420 self.write_space();
5421 self.write_keyword("BY");
5422 self.write_space();
5423 for (i, expr) in limit_by.iter().enumerate() {
5424 if i > 0 {
5425 self.write(", ");
5426 }
5427 self.generate_expression(expr)?;
5428 }
5429 }
5430 }
5431 }
5432
5433 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
5435 if let Some(settings) = &select.settings {
5436 if self.config.pretty {
5437 self.write_newline();
5438 self.write_indent();
5439 } else {
5440 self.write_space();
5441 }
5442 self.write_keyword("SETTINGS");
5443 self.write_space();
5444 for (i, expr) in settings.iter().enumerate() {
5445 if i > 0 {
5446 self.write(", ");
5447 }
5448 self.generate_expression(expr)?;
5449 }
5450 }
5451
5452 if let Some(format_expr) = &select.format {
5453 if self.config.pretty {
5454 self.write_newline();
5455 self.write_indent();
5456 } else {
5457 self.write_space();
5458 }
5459 self.write_keyword("FORMAT");
5460 self.write_space();
5461 self.generate_expression(format_expr)?;
5462 }
5463 }
5464
5465 if let Some(fetch) = &select.fetch {
5467 let fetch_already_as_limit = select.offset.is_some()
5469 && !fetch.percent
5470 && !fetch.with_ties
5471 && fetch.count.is_some()
5472 && matches!(
5473 self.config.dialect,
5474 Some(DialectType::Spark)
5475 | Some(DialectType::Hive)
5476 | Some(DialectType::DuckDB)
5477 | Some(DialectType::SQLite)
5478 | Some(DialectType::MySQL)
5479 | Some(DialectType::BigQuery)
5480 | Some(DialectType::Databricks)
5481 | Some(DialectType::StarRocks)
5482 | Some(DialectType::Doris)
5483 | Some(DialectType::Athena)
5484 | Some(DialectType::ClickHouse)
5485 | Some(DialectType::Redshift)
5486 );
5487
5488 if fetch_already_as_limit {
5489 } else {
5491 if self.config.pretty {
5492 self.write_newline();
5493 self.write_indent();
5494 } else {
5495 self.write_space();
5496 }
5497
5498 let use_limit = !fetch.percent
5500 && !fetch.with_ties
5501 && fetch.count.is_some()
5502 && matches!(
5503 self.config.dialect,
5504 Some(DialectType::Spark)
5505 | Some(DialectType::Hive)
5506 | Some(DialectType::DuckDB)
5507 | Some(DialectType::SQLite)
5508 | Some(DialectType::MySQL)
5509 | Some(DialectType::BigQuery)
5510 | Some(DialectType::Databricks)
5511 | Some(DialectType::StarRocks)
5512 | Some(DialectType::Doris)
5513 | Some(DialectType::Athena)
5514 | Some(DialectType::ClickHouse)
5515 | Some(DialectType::Redshift)
5516 );
5517
5518 if use_limit {
5519 self.write_keyword("LIMIT");
5520 self.write_space();
5521 self.generate_expression(fetch.count.as_ref().unwrap())?;
5522 } else {
5523 self.write_keyword("FETCH");
5524 self.write_space();
5525 self.write_keyword(&fetch.direction);
5526 if let Some(ref count) = fetch.count {
5527 self.write_space();
5528 self.generate_expression(count)?;
5529 }
5530 if fetch.percent {
5531 self.write_space();
5532 self.write_keyword("PERCENT");
5533 }
5534 if fetch.rows {
5535 self.write_space();
5536 self.write_keyword("ROWS");
5537 }
5538 if fetch.with_ties {
5539 self.write_space();
5540 self.write_keyword("WITH TIES");
5541 } else {
5542 self.write_space();
5543 self.write_keyword("ONLY");
5544 }
5545 }
5546 } }
5548
5549 if let Some(sample) = &select.sample {
5551 use crate::dialects::DialectType;
5552 if self.config.pretty {
5553 self.write_newline();
5554 } else {
5555 self.write_space();
5556 }
5557
5558 if sample.is_using_sample {
5559 self.write_keyword("USING SAMPLE");
5561 self.generate_sample_body(sample)?;
5562 } else {
5563 self.write_keyword("TABLESAMPLE");
5564
5565 let snowflake_bernoulli =
5567 matches!(self.config.dialect, Some(DialectType::Snowflake))
5568 && !sample.explicit_method;
5569 if snowflake_bernoulli {
5570 self.write_space();
5571 self.write_keyword("BERNOULLI");
5572 }
5573
5574 if matches!(sample.method, SampleMethod::Bucket) {
5576 self.write_space();
5577 self.write("(");
5578 self.write_keyword("BUCKET");
5579 self.write_space();
5580 if let Some(ref num) = sample.bucket_numerator {
5581 self.generate_expression(num)?;
5582 }
5583 self.write_space();
5584 self.write_keyword("OUT OF");
5585 self.write_space();
5586 if let Some(ref denom) = sample.bucket_denominator {
5587 self.generate_expression(denom)?;
5588 }
5589 if let Some(ref field) = sample.bucket_field {
5590 self.write_space();
5591 self.write_keyword("ON");
5592 self.write_space();
5593 self.generate_expression(field)?;
5594 }
5595 self.write(")");
5596 } else if sample.unit_after_size {
5597 if sample.explicit_method && sample.method_before_size {
5599 self.write_space();
5600 match sample.method {
5601 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
5602 SampleMethod::System => self.write_keyword("SYSTEM"),
5603 SampleMethod::Block => self.write_keyword("BLOCK"),
5604 SampleMethod::Row => self.write_keyword("ROW"),
5605 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
5606 _ => {}
5607 }
5608 }
5609 self.write(" (");
5610 self.generate_expression(&sample.size)?;
5611 self.write_space();
5612 match sample.method {
5613 SampleMethod::Percent => self.write_keyword("PERCENT"),
5614 SampleMethod::Row => self.write_keyword("ROWS"),
5615 SampleMethod::Reservoir => self.write_keyword("ROWS"),
5616 _ => {
5617 self.write_keyword("PERCENT");
5618 }
5619 }
5620 self.write(")");
5621 } else {
5622 self.write_space();
5624 match sample.method {
5625 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
5626 SampleMethod::System => self.write_keyword("SYSTEM"),
5627 SampleMethod::Block => self.write_keyword("BLOCK"),
5628 SampleMethod::Row => self.write_keyword("ROW"),
5629 SampleMethod::Percent => self.write_keyword("BERNOULLI"),
5630 SampleMethod::Bucket => {}
5631 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
5632 }
5633 self.write(" (");
5634 self.generate_expression(&sample.size)?;
5635 if matches!(sample.method, SampleMethod::Percent) {
5636 self.write_space();
5637 self.write_keyword("PERCENT");
5638 }
5639 self.write(")");
5640 }
5641 }
5642
5643 if let Some(seed) = &sample.seed {
5644 self.write_space();
5645 let use_seed = sample.use_seed_keyword
5647 && !matches!(
5648 self.config.dialect,
5649 Some(crate::dialects::DialectType::Databricks)
5650 | Some(crate::dialects::DialectType::Spark)
5651 );
5652 if use_seed {
5653 self.write_keyword("SEED");
5654 } else {
5655 self.write_keyword("REPEATABLE");
5656 }
5657 self.write(" (");
5658 self.generate_expression(seed)?;
5659 self.write(")");
5660 }
5661 }
5662
5663 if self.config.locking_reads_supported {
5666 for lock in &select.locks {
5667 if self.config.pretty {
5668 self.write_newline();
5669 self.write_indent();
5670 } else {
5671 self.write_space();
5672 }
5673 self.generate_lock(lock)?;
5674 }
5675 }
5676
5677 if !select.for_xml.is_empty() {
5679 if self.config.pretty {
5680 self.write_newline();
5681 self.write_indent();
5682 } else {
5683 self.write_space();
5684 }
5685 self.write_keyword("FOR XML");
5686 for (i, opt) in select.for_xml.iter().enumerate() {
5687 if self.config.pretty {
5688 if i > 0 {
5689 self.write(",");
5690 }
5691 self.write_newline();
5692 self.write_indent();
5693 self.write(" "); } else {
5695 if i > 0 {
5696 self.write(",");
5697 }
5698 self.write_space();
5699 }
5700 self.generate_for_xml_option(opt)?;
5701 }
5702 }
5703
5704 if !select.for_json.is_empty()
5706 && matches!(
5707 self.config.dialect,
5708 None | Some(DialectType::TSQL) | Some(DialectType::Fabric)
5709 )
5710 {
5711 if self.config.pretty {
5712 self.write_newline();
5713 self.write_indent();
5714 } else {
5715 self.write_space();
5716 }
5717 self.write_keyword("FOR JSON");
5718 for (i, opt) in select.for_json.iter().enumerate() {
5719 if self.config.pretty {
5720 if i > 0 {
5721 self.write(",");
5722 }
5723 self.write_newline();
5724 self.write_indent();
5725 self.write(" "); } else {
5727 if i > 0 {
5728 self.write(",");
5729 }
5730 self.write_space();
5731 }
5732 self.generate_for_xml_option(opt)?;
5733 }
5734 }
5735
5736 if let Some(ref option) = select.option {
5738 if matches!(
5739 self.config.dialect,
5740 Some(crate::dialects::DialectType::TSQL)
5741 | Some(crate::dialects::DialectType::Fabric)
5742 ) {
5743 self.write_space();
5744 self.write(option);
5745 }
5746 }
5747
5748 Ok(())
5749 }
5750
5751 fn generate_for_xml_option(&mut self, opt: &Expression) -> Result<()> {
5753 match opt {
5754 Expression::QueryOption(qo) => {
5755 if let Expression::Var(var) = &*qo.this {
5757 self.write(&var.this);
5758 } else {
5759 self.generate_expression(&qo.this)?;
5760 }
5761 if let Some(expr) = &qo.expression {
5763 self.write("(");
5764 self.generate_expression(expr)?;
5765 self.write(")");
5766 }
5767 }
5768 _ => {
5769 self.generate_expression(opt)?;
5770 }
5771 }
5772 Ok(())
5773 }
5774
5775 fn generate_with(&mut self, with: &With) -> Result<()> {
5776 use crate::dialects::DialectType;
5777
5778 for comment in &with.leading_comments {
5780 self.write_formatted_comment(comment);
5781 self.write(" ");
5782 }
5783 self.write_keyword("WITH");
5784 if with.recursive && self.config.cte_recursive_keyword_required {
5785 self.write_space();
5786 self.write_keyword("RECURSIVE");
5787 }
5788 self.write_space();
5789
5790 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
5792
5793 for (i, cte) in with.ctes.iter().enumerate() {
5794 if i > 0 {
5795 self.write(",");
5796 if self.config.pretty {
5797 self.write_space();
5798 } else {
5799 self.write(" ");
5800 }
5801 }
5802 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !cte.alias_first {
5803 self.generate_expression(&cte.this)?;
5804 self.write_space();
5805 self.write_keyword("AS");
5806 self.write_space();
5807 self.generate_identifier(&cte.alias)?;
5808 continue;
5809 }
5810 self.generate_identifier(&cte.alias)?;
5811 for comment in &cte.comments {
5813 self.write_space();
5814 self.write_formatted_comment(comment);
5815 }
5816 if !cte.columns.is_empty() && !skip_cte_columns {
5817 self.write("(");
5818 for (j, col) in cte.columns.iter().enumerate() {
5819 if j > 0 {
5820 self.write(", ");
5821 }
5822 self.generate_identifier(col)?;
5823 }
5824 self.write(")");
5825 }
5826 if !cte.key_expressions.is_empty() {
5828 self.write_space();
5829 self.write_keyword("USING KEY");
5830 self.write(" (");
5831 for (i, key) in cte.key_expressions.iter().enumerate() {
5832 if i > 0 {
5833 self.write(", ");
5834 }
5835 self.generate_identifier(key)?;
5836 }
5837 self.write(")");
5838 }
5839 self.write_space();
5840 self.write_keyword("AS");
5841 if let Some(materialized) = cte.materialized {
5843 self.write_space();
5844 if materialized {
5845 self.write_keyword("MATERIALIZED");
5846 } else {
5847 self.write_keyword("NOT MATERIALIZED");
5848 }
5849 }
5850 self.write(" (");
5851 if self.config.pretty {
5852 self.write_newline();
5853 self.indent_level += 1;
5854 self.write_indent();
5855 }
5856 let wrap_values_in_select = matches!(
5859 self.config.dialect,
5860 Some(DialectType::Spark) | Some(DialectType::Databricks)
5861 ) && matches!(&cte.this, Expression::Values(_));
5862
5863 if wrap_values_in_select {
5864 self.write_keyword("SELECT");
5865 self.write(" * ");
5866 self.write_keyword("FROM");
5867 self.write_space();
5868 }
5869 self.generate_expression(&cte.this)?;
5870 if self.config.pretty {
5871 self.write_newline();
5872 self.indent_level -= 1;
5873 self.write_indent();
5874 }
5875 self.write(")");
5876 }
5877
5878 if let Some(search) = &with.search {
5880 self.write_space();
5881 self.generate_expression(search)?;
5882 }
5883
5884 Ok(())
5885 }
5886
5887 fn generate_joins_with_nesting(&mut self, joins: &[Join]) -> Result<()> {
5891 let mut i = 0;
5892 while i < joins.len() {
5893 if joins[i].deferred_condition {
5894 let parent_group = joins[i].nesting_group;
5895
5896 self.generate_join_without_condition(&joins[i])?;
5899
5900 let child_start = i + 1;
5902 let mut child_end = child_start;
5903 while child_end < joins.len()
5904 && !joins[child_end].deferred_condition
5905 && joins[child_end].nesting_group == parent_group
5906 {
5907 child_end += 1;
5908 }
5909
5910 if child_start < child_end {
5912 self.indent_level += 1;
5913 for j in child_start..child_end {
5914 self.generate_join(&joins[j])?;
5915 }
5916 self.indent_level -= 1;
5917 }
5918
5919 self.generate_join_condition(&joins[i])?;
5921
5922 i = child_end;
5923 } else {
5924 self.generate_join(&joins[i])?;
5926 i += 1;
5927 }
5928 }
5929 Ok(())
5930 }
5931
5932 fn generate_join_without_condition(&mut self, join: &Join) -> Result<()> {
5935 let mut join_copy = join.clone();
5938 join_copy.on = None;
5939 join_copy.using = Vec::new();
5940 join_copy.deferred_condition = false;
5941 self.generate_join(&join_copy)
5942 }
5943
5944 fn generate_join(&mut self, join: &Join) -> Result<()> {
5945 if join.kind == JoinKind::Implicit {
5947 self.write(",");
5948 if self.config.pretty {
5949 self.write_newline();
5950 self.write_indent();
5951 } else {
5952 self.write_space();
5953 }
5954 self.generate_expression(&join.this)?;
5955 return Ok(());
5956 }
5957
5958 if self.config.pretty {
5959 self.write_newline();
5960 self.write_indent();
5961 } else {
5962 self.write_space();
5963 }
5964
5965 let hint_str = if self.config.join_hints {
5968 join.join_hint
5969 .as_ref()
5970 .map(|h| format!(" {}", h))
5971 .unwrap_or_default()
5972 } else {
5973 String::new()
5974 };
5975
5976 let clickhouse_join_keyword =
5977 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
5978 if let Some(hint) = &join.join_hint {
5979 let mut global = false;
5980 let mut strictness: Option<&'static str> = None;
5981 for part in hint.split_whitespace() {
5982 if part.eq_ignore_ascii_case("GLOBAL") {
5983 global = true;
5984 } else if part.eq_ignore_ascii_case("ALL") {
5985 strictness = Some("ALL");
5986 } else if part.eq_ignore_ascii_case("ANY") {
5987 strictness = Some("ANY");
5988 } else if part.eq_ignore_ascii_case("ASOF") {
5989 strictness = Some("ASOF");
5990 } else if part.eq_ignore_ascii_case("SEMI") {
5991 strictness = Some("SEMI");
5992 } else if part.eq_ignore_ascii_case("ANTI") {
5993 strictness = Some("ANTI");
5994 }
5995 }
5996
5997 if global || strictness.is_some() {
5998 let join_type = match join.kind {
5999 JoinKind::Left => {
6000 if join.use_outer_keyword {
6001 "LEFT OUTER"
6002 } else if join.use_inner_keyword {
6003 "LEFT INNER"
6004 } else {
6005 "LEFT"
6006 }
6007 }
6008 JoinKind::Right => {
6009 if join.use_outer_keyword {
6010 "RIGHT OUTER"
6011 } else if join.use_inner_keyword {
6012 "RIGHT INNER"
6013 } else {
6014 "RIGHT"
6015 }
6016 }
6017 JoinKind::Full => {
6018 if join.use_outer_keyword {
6019 "FULL OUTER"
6020 } else {
6021 "FULL"
6022 }
6023 }
6024 JoinKind::Inner => {
6025 if join.use_inner_keyword {
6026 "INNER"
6027 } else {
6028 ""
6029 }
6030 }
6031 _ => "",
6032 };
6033
6034 let mut parts = Vec::new();
6035 if global {
6036 parts.push("GLOBAL");
6037 }
6038 if !join_type.is_empty() {
6039 parts.push(join_type);
6040 }
6041 if let Some(strict) = strictness {
6042 parts.push(strict);
6043 }
6044 parts.push("JOIN");
6045 Some(parts.join(" "))
6046 } else {
6047 None
6048 }
6049 } else {
6050 None
6051 }
6052 } else {
6053 None
6054 };
6055
6056 if !join.comments.is_empty() {
6060 if self.config.pretty {
6061 let trimmed = self.output.trim_end().len();
6066 self.output.truncate(trimmed);
6067 for comment in &join.comments {
6068 self.write_newline();
6069 self.write_indent();
6070 self.write_formatted_comment(comment);
6071 }
6072 self.write_newline();
6073 self.write_indent();
6074 } else {
6075 for comment in &join.comments {
6076 self.write_formatted_comment(comment);
6077 self.write_space();
6078 }
6079 }
6080 }
6081
6082 let directed_str = if join.directed { " DIRECTED" } else { "" };
6083
6084 if let Some(keyword) = clickhouse_join_keyword {
6085 self.write_keyword(&keyword);
6086 } else {
6087 match join.kind {
6088 JoinKind::Inner => {
6089 if join.use_inner_keyword {
6090 if hint_str.is_empty() && directed_str.is_empty() {
6091 self.write_keyword("INNER JOIN");
6092 } else {
6093 self.write_keyword("INNER");
6094 if !hint_str.is_empty() {
6095 self.write_keyword(&hint_str);
6096 }
6097 if !directed_str.is_empty() {
6098 self.write_keyword(directed_str);
6099 }
6100 self.write_keyword(" JOIN");
6101 }
6102 } else {
6103 if !hint_str.is_empty() {
6104 self.write_keyword(hint_str.trim());
6105 self.write_keyword(" ");
6106 }
6107 if !directed_str.is_empty() {
6108 self.write_keyword("DIRECTED ");
6109 }
6110 self.write_keyword("JOIN");
6111 }
6112 }
6113 JoinKind::Left => {
6114 if join.use_outer_keyword {
6115 if hint_str.is_empty() && directed_str.is_empty() {
6116 self.write_keyword("LEFT OUTER JOIN");
6117 } else {
6118 self.write_keyword("LEFT OUTER");
6119 if !hint_str.is_empty() {
6120 self.write_keyword(&hint_str);
6121 }
6122 if !directed_str.is_empty() {
6123 self.write_keyword(directed_str);
6124 }
6125 self.write_keyword(" JOIN");
6126 }
6127 } else if join.use_inner_keyword {
6128 if hint_str.is_empty() && directed_str.is_empty() {
6129 self.write_keyword("LEFT INNER JOIN");
6130 } else {
6131 self.write_keyword("LEFT INNER");
6132 if !hint_str.is_empty() {
6133 self.write_keyword(&hint_str);
6134 }
6135 if !directed_str.is_empty() {
6136 self.write_keyword(directed_str);
6137 }
6138 self.write_keyword(" JOIN");
6139 }
6140 } else {
6141 if hint_str.is_empty() && directed_str.is_empty() {
6142 self.write_keyword("LEFT JOIN");
6143 } else {
6144 self.write_keyword("LEFT");
6145 if !hint_str.is_empty() {
6146 self.write_keyword(&hint_str);
6147 }
6148 if !directed_str.is_empty() {
6149 self.write_keyword(directed_str);
6150 }
6151 self.write_keyword(" JOIN");
6152 }
6153 }
6154 }
6155 JoinKind::Right => {
6156 if join.use_outer_keyword {
6157 if hint_str.is_empty() && directed_str.is_empty() {
6158 self.write_keyword("RIGHT OUTER JOIN");
6159 } else {
6160 self.write_keyword("RIGHT OUTER");
6161 if !hint_str.is_empty() {
6162 self.write_keyword(&hint_str);
6163 }
6164 if !directed_str.is_empty() {
6165 self.write_keyword(directed_str);
6166 }
6167 self.write_keyword(" JOIN");
6168 }
6169 } else if join.use_inner_keyword {
6170 if hint_str.is_empty() && directed_str.is_empty() {
6171 self.write_keyword("RIGHT INNER JOIN");
6172 } else {
6173 self.write_keyword("RIGHT INNER");
6174 if !hint_str.is_empty() {
6175 self.write_keyword(&hint_str);
6176 }
6177 if !directed_str.is_empty() {
6178 self.write_keyword(directed_str);
6179 }
6180 self.write_keyword(" JOIN");
6181 }
6182 } else {
6183 if hint_str.is_empty() && directed_str.is_empty() {
6184 self.write_keyword("RIGHT JOIN");
6185 } else {
6186 self.write_keyword("RIGHT");
6187 if !hint_str.is_empty() {
6188 self.write_keyword(&hint_str);
6189 }
6190 if !directed_str.is_empty() {
6191 self.write_keyword(directed_str);
6192 }
6193 self.write_keyword(" JOIN");
6194 }
6195 }
6196 }
6197 JoinKind::Full => {
6198 if join.use_outer_keyword {
6199 if hint_str.is_empty() && directed_str.is_empty() {
6200 self.write_keyword("FULL OUTER JOIN");
6201 } else {
6202 self.write_keyword("FULL OUTER");
6203 if !hint_str.is_empty() {
6204 self.write_keyword(&hint_str);
6205 }
6206 if !directed_str.is_empty() {
6207 self.write_keyword(directed_str);
6208 }
6209 self.write_keyword(" JOIN");
6210 }
6211 } else {
6212 if hint_str.is_empty() && directed_str.is_empty() {
6213 self.write_keyword("FULL JOIN");
6214 } else {
6215 self.write_keyword("FULL");
6216 if !hint_str.is_empty() {
6217 self.write_keyword(&hint_str);
6218 }
6219 if !directed_str.is_empty() {
6220 self.write_keyword(directed_str);
6221 }
6222 self.write_keyword(" JOIN");
6223 }
6224 }
6225 }
6226 JoinKind::Outer => {
6227 if directed_str.is_empty() {
6228 self.write_keyword("OUTER JOIN");
6229 } else {
6230 self.write_keyword("OUTER");
6231 self.write_keyword(directed_str);
6232 self.write_keyword(" JOIN");
6233 }
6234 }
6235 JoinKind::Cross => {
6236 if directed_str.is_empty() {
6237 self.write_keyword("CROSS JOIN");
6238 } else {
6239 self.write_keyword("CROSS");
6240 self.write_keyword(directed_str);
6241 self.write_keyword(" JOIN");
6242 }
6243 }
6244 JoinKind::Natural => {
6245 if join.use_inner_keyword {
6246 if directed_str.is_empty() {
6247 self.write_keyword("NATURAL INNER JOIN");
6248 } else {
6249 self.write_keyword("NATURAL INNER");
6250 self.write_keyword(directed_str);
6251 self.write_keyword(" JOIN");
6252 }
6253 } else {
6254 if directed_str.is_empty() {
6255 self.write_keyword("NATURAL JOIN");
6256 } else {
6257 self.write_keyword("NATURAL");
6258 self.write_keyword(directed_str);
6259 self.write_keyword(" JOIN");
6260 }
6261 }
6262 }
6263 JoinKind::NaturalLeft => {
6264 if join.use_outer_keyword {
6265 if directed_str.is_empty() {
6266 self.write_keyword("NATURAL LEFT OUTER JOIN");
6267 } else {
6268 self.write_keyword("NATURAL LEFT OUTER");
6269 self.write_keyword(directed_str);
6270 self.write_keyword(" JOIN");
6271 }
6272 } else {
6273 if directed_str.is_empty() {
6274 self.write_keyword("NATURAL LEFT JOIN");
6275 } else {
6276 self.write_keyword("NATURAL LEFT");
6277 self.write_keyword(directed_str);
6278 self.write_keyword(" JOIN");
6279 }
6280 }
6281 }
6282 JoinKind::NaturalRight => {
6283 if join.use_outer_keyword {
6284 if directed_str.is_empty() {
6285 self.write_keyword("NATURAL RIGHT OUTER JOIN");
6286 } else {
6287 self.write_keyword("NATURAL RIGHT OUTER");
6288 self.write_keyword(directed_str);
6289 self.write_keyword(" JOIN");
6290 }
6291 } else {
6292 if directed_str.is_empty() {
6293 self.write_keyword("NATURAL RIGHT JOIN");
6294 } else {
6295 self.write_keyword("NATURAL RIGHT");
6296 self.write_keyword(directed_str);
6297 self.write_keyword(" JOIN");
6298 }
6299 }
6300 }
6301 JoinKind::NaturalFull => {
6302 if join.use_outer_keyword {
6303 if directed_str.is_empty() {
6304 self.write_keyword("NATURAL FULL OUTER JOIN");
6305 } else {
6306 self.write_keyword("NATURAL FULL OUTER");
6307 self.write_keyword(directed_str);
6308 self.write_keyword(" JOIN");
6309 }
6310 } else {
6311 if directed_str.is_empty() {
6312 self.write_keyword("NATURAL FULL JOIN");
6313 } else {
6314 self.write_keyword("NATURAL FULL");
6315 self.write_keyword(directed_str);
6316 self.write_keyword(" JOIN");
6317 }
6318 }
6319 }
6320 JoinKind::Semi => self.write_keyword("SEMI JOIN"),
6321 JoinKind::Anti => self.write_keyword("ANTI JOIN"),
6322 JoinKind::LeftSemi => self.write_keyword("LEFT SEMI JOIN"),
6323 JoinKind::LeftAnti => self.write_keyword("LEFT ANTI JOIN"),
6324 JoinKind::RightSemi => self.write_keyword("RIGHT SEMI JOIN"),
6325 JoinKind::RightAnti => self.write_keyword("RIGHT ANTI JOIN"),
6326 JoinKind::CrossApply => {
6327 if matches!(
6329 self.config.dialect,
6330 Some(DialectType::TSQL) | Some(DialectType::Fabric) | None
6331 ) {
6332 self.write_keyword("CROSS APPLY");
6333 } else {
6334 self.write_keyword("INNER JOIN LATERAL");
6335 }
6336 }
6337 JoinKind::OuterApply => {
6338 if matches!(
6340 self.config.dialect,
6341 Some(DialectType::TSQL) | Some(DialectType::Fabric) | None
6342 ) {
6343 self.write_keyword("OUTER APPLY");
6344 } else {
6345 self.write_keyword("LEFT JOIN LATERAL");
6346 }
6347 }
6348 JoinKind::AsOf => self.write_keyword("ASOF JOIN"),
6349 JoinKind::AsOfLeft => {
6350 if join.use_outer_keyword {
6351 self.write_keyword("ASOF LEFT OUTER JOIN");
6352 } else {
6353 self.write_keyword("ASOF LEFT JOIN");
6354 }
6355 }
6356 JoinKind::AsOfRight => {
6357 if join.use_outer_keyword {
6358 self.write_keyword("ASOF RIGHT OUTER JOIN");
6359 } else {
6360 self.write_keyword("ASOF RIGHT JOIN");
6361 }
6362 }
6363 JoinKind::Lateral => self.write_keyword("LATERAL JOIN"),
6364 JoinKind::LeftLateral => {
6365 if join.use_outer_keyword {
6366 self.write_keyword("LEFT OUTER LATERAL JOIN");
6367 } else {
6368 self.write_keyword("LEFT LATERAL JOIN");
6369 }
6370 }
6371 JoinKind::Straight => self.write_keyword("STRAIGHT_JOIN"),
6372 JoinKind::Implicit => {
6373 use crate::dialects::DialectType;
6377 let is_cj_dialect = matches!(
6378 self.config.dialect,
6379 Some(DialectType::BigQuery)
6380 | Some(DialectType::Hive)
6381 | Some(DialectType::Spark)
6382 | Some(DialectType::Databricks)
6383 );
6384 let source_is_same = self.config.source_dialect.is_some()
6385 && self.config.source_dialect == self.config.dialect;
6386 let source_is_cj = matches!(
6387 self.config.source_dialect,
6388 Some(DialectType::BigQuery)
6389 | Some(DialectType::Hive)
6390 | Some(DialectType::Spark)
6391 | Some(DialectType::Databricks)
6392 );
6393 if is_cj_dialect
6394 && (source_is_same || source_is_cj || self.config.source_dialect.is_none())
6395 {
6396 self.write_keyword("CROSS JOIN");
6397 } else {
6398 self.output.truncate(self.output.trim_end().len());
6402 self.write(",");
6403 }
6404 }
6405 JoinKind::Array => self.write_keyword("ARRAY JOIN"),
6406 JoinKind::LeftArray => self.write_keyword("LEFT ARRAY JOIN"),
6407 JoinKind::Paste => self.write_keyword("PASTE JOIN"),
6408 JoinKind::Positional => self.write_keyword("POSITIONAL JOIN"),
6409 }
6410 }
6411
6412 if matches!(join.kind, JoinKind::Array | JoinKind::LeftArray) {
6414 match &join.this {
6415 Expression::Tuple(t) if t.expressions.is_empty() => {}
6416 Expression::Tuple(t) => {
6417 self.write_space();
6418 for (i, item) in t.expressions.iter().enumerate() {
6419 if i > 0 {
6420 self.write(", ");
6421 }
6422 self.generate_expression(item)?;
6423 }
6424 }
6425 other => {
6426 self.write_space();
6427 self.generate_expression(other)?;
6428 }
6429 }
6430 } else {
6431 self.write_space();
6432 self.generate_expression(&join.this)?;
6433 }
6434
6435 if !join.deferred_condition {
6437 if let Some(match_cond) = &join.match_condition {
6439 self.write_space();
6440 self.write_keyword("MATCH_CONDITION");
6441 self.write(" (");
6442 self.generate_expression(match_cond)?;
6443 self.write(")");
6444 }
6445
6446 if let Some(on) = &join.on {
6447 if self.config.pretty {
6448 self.write_newline();
6449 self.indent_level += 1;
6450 self.write_indent();
6451 self.write_keyword("ON");
6452 self.write_space();
6453 self.generate_join_on_condition(on)?;
6454 self.indent_level -= 1;
6455 } else {
6456 self.write_space();
6457 self.write_keyword("ON");
6458 self.write_space();
6459 self.generate_expression(on)?;
6460 }
6461 }
6462
6463 if !join.using.is_empty() {
6464 if self.config.pretty {
6465 self.write_newline();
6466 self.indent_level += 1;
6467 self.write_indent();
6468 self.write_keyword("USING");
6469 self.write(" (");
6470 for (i, col) in join.using.iter().enumerate() {
6471 if i > 0 {
6472 self.write(", ");
6473 }
6474 self.generate_identifier(col)?;
6475 }
6476 self.write(")");
6477 self.indent_level -= 1;
6478 } else {
6479 self.write_space();
6480 self.write_keyword("USING");
6481 self.write(" (");
6482 for (i, col) in join.using.iter().enumerate() {
6483 if i > 0 {
6484 self.write(", ");
6485 }
6486 self.generate_identifier(col)?;
6487 }
6488 self.write(")");
6489 }
6490 }
6491 }
6492
6493 for pivot in &join.pivots {
6495 self.write_space();
6496 self.generate_expression(pivot)?;
6497 }
6498
6499 Ok(())
6500 }
6501
6502 fn generate_join_condition(&mut self, join: &Join) -> Result<()> {
6504 if let Some(match_cond) = &join.match_condition {
6506 self.write_space();
6507 self.write_keyword("MATCH_CONDITION");
6508 self.write(" (");
6509 self.generate_expression(match_cond)?;
6510 self.write(")");
6511 }
6512
6513 if let Some(on) = &join.on {
6514 if self.config.pretty {
6515 self.write_newline();
6516 self.indent_level += 1;
6517 self.write_indent();
6518 self.write_keyword("ON");
6519 self.write_space();
6520 self.generate_join_on_condition(on)?;
6522 self.indent_level -= 1;
6523 } else {
6524 self.write_space();
6525 self.write_keyword("ON");
6526 self.write_space();
6527 self.generate_expression(on)?;
6528 }
6529 }
6530
6531 if !join.using.is_empty() {
6532 if self.config.pretty {
6533 self.write_newline();
6534 self.indent_level += 1;
6535 self.write_indent();
6536 self.write_keyword("USING");
6537 self.write(" (");
6538 for (i, col) in join.using.iter().enumerate() {
6539 if i > 0 {
6540 self.write(", ");
6541 }
6542 self.generate_identifier(col)?;
6543 }
6544 self.write(")");
6545 self.indent_level -= 1;
6546 } else {
6547 self.write_space();
6548 self.write_keyword("USING");
6549 self.write(" (");
6550 for (i, col) in join.using.iter().enumerate() {
6551 if i > 0 {
6552 self.write(", ");
6553 }
6554 self.generate_identifier(col)?;
6555 }
6556 self.write(")");
6557 }
6558 }
6559
6560 for pivot in &join.pivots {
6562 self.write_space();
6563 self.generate_expression(pivot)?;
6564 }
6565
6566 Ok(())
6567 }
6568
6569 fn generate_join_on_condition(&mut self, expr: &Expression) -> Result<()> {
6571 if let Expression::And(and_op) = expr {
6572 if let Some(conditions) = self.flatten_connector_terms(and_op, ConnectorOperator::And) {
6573 self.generate_expression(conditions[0])?;
6574 for condition in conditions.iter().skip(1) {
6575 self.write_newline();
6576 self.write_indent();
6577 self.write_keyword("AND");
6578 self.write_space();
6579 self.generate_expression(condition)?;
6580 }
6581 return Ok(());
6582 }
6583 }
6584
6585 self.generate_expression(expr)
6586 }
6587
6588 fn generate_joined_table(&mut self, jt: &JoinedTable) -> Result<()> {
6589 self.write("(");
6591 self.generate_expression(&jt.left)?;
6592
6593 for join in &jt.joins {
6595 self.generate_join(join)?;
6596 }
6597
6598 for (lv_idx, lv) in jt.lateral_views.iter().enumerate() {
6600 self.generate_lateral_view(lv, lv_idx)?;
6601 }
6602
6603 self.write(")");
6604
6605 if let Some(alias) = &jt.alias {
6607 self.write_space();
6608 self.write_keyword("AS");
6609 self.write_space();
6610 self.generate_identifier(alias)?;
6611 }
6612
6613 Ok(())
6614 }
6615
6616 fn generate_lateral_view(&mut self, lv: &LateralView, lv_index: usize) -> Result<()> {
6617 use crate::dialects::DialectType;
6618
6619 if self.config.pretty {
6620 self.write_newline();
6621 self.write_indent();
6622 } else {
6623 self.write_space();
6624 }
6625
6626 let use_lateral_join = matches!(
6629 self.config.dialect,
6630 Some(DialectType::PostgreSQL)
6631 | Some(DialectType::DuckDB)
6632 | Some(DialectType::Snowflake)
6633 | Some(DialectType::TSQL)
6634 | Some(DialectType::Presto)
6635 | Some(DialectType::Trino)
6636 | Some(DialectType::Athena)
6637 );
6638
6639 let use_unnest = matches!(
6641 self.config.dialect,
6642 Some(DialectType::DuckDB)
6643 | Some(DialectType::Presto)
6644 | Some(DialectType::Trino)
6645 | Some(DialectType::Athena)
6646 );
6647
6648 let (is_posexplode, is_inline, func_args) = match &lv.this {
6650 Expression::Explode(uf) => {
6651 (false, false, vec![uf.this.clone()])
6653 }
6654 Expression::Unnest(uf) => {
6655 let mut args = vec![uf.this.clone()];
6656 args.extend(uf.expressions.clone());
6657 (false, false, args)
6658 }
6659 Expression::Function(func) => {
6660 if func.name.eq_ignore_ascii_case("POSEXPLODE")
6661 || func.name.eq_ignore_ascii_case("POSEXPLODE_OUTER")
6662 {
6663 (true, false, func.args.clone())
6664 } else if func.name.eq_ignore_ascii_case("INLINE") {
6665 (false, true, func.args.clone())
6666 } else if func.name.eq_ignore_ascii_case("EXPLODE")
6667 || func.name.eq_ignore_ascii_case("EXPLODE_OUTER")
6668 {
6669 (false, false, func.args.clone())
6670 } else {
6671 (false, false, vec![])
6672 }
6673 }
6674 _ => (false, false, vec![]),
6675 };
6676
6677 if use_lateral_join {
6678 if lv.outer {
6680 self.write_keyword("LEFT JOIN LATERAL");
6681 } else {
6682 self.write_keyword("CROSS JOIN");
6683 }
6684 self.write_space();
6685
6686 if use_unnest && !func_args.is_empty() {
6687 let unnest_args = if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
6690 func_args
6692 .iter()
6693 .map(|a| {
6694 if let Expression::Function(ref f) = a {
6695 if f.name.eq_ignore_ascii_case("ARRAY") && f.args.len() == 1 {
6696 return Expression::ArrayFunc(Box::new(
6697 crate::expressions::ArrayConstructor {
6698 expressions: f.args.clone(),
6699 bracket_notation: true,
6700 use_list_keyword: false,
6701 },
6702 ));
6703 }
6704 }
6705 a.clone()
6706 })
6707 .collect::<Vec<_>>()
6708 } else if matches!(
6709 self.config.dialect,
6710 Some(DialectType::Presto)
6711 | Some(DialectType::Trino)
6712 | Some(DialectType::Athena)
6713 ) {
6714 func_args
6716 .iter()
6717 .map(|a| {
6718 if let Expression::Function(ref f) = a {
6719 if f.name.eq_ignore_ascii_case("ARRAY") && f.args.len() >= 1 {
6720 return Expression::ArrayFunc(Box::new(
6721 crate::expressions::ArrayConstructor {
6722 expressions: f.args.clone(),
6723 bracket_notation: true,
6724 use_list_keyword: false,
6725 },
6726 ));
6727 }
6728 }
6729 a.clone()
6730 })
6731 .collect::<Vec<_>>()
6732 } else {
6733 func_args
6734 };
6735
6736 if is_posexplode {
6738 self.write_keyword("LATERAL");
6739 self.write(" (");
6740 self.write_keyword("SELECT");
6741 self.write_space();
6742
6743 let pos_alias = if !lv.column_aliases.is_empty() {
6746 lv.column_aliases[0].clone()
6747 } else {
6748 Identifier::new("pos")
6749 };
6750 let data_aliases: Vec<Identifier> = if lv.column_aliases.len() > 1 {
6751 lv.column_aliases[1..].to_vec()
6752 } else {
6753 vec![Identifier::new("col")]
6754 };
6755
6756 self.generate_identifier(&pos_alias)?;
6758 self.write(" - 1");
6759 self.write_space();
6760 self.write_keyword("AS");
6761 self.write_space();
6762 self.generate_identifier(&pos_alias)?;
6763
6764 for data_col in &data_aliases {
6766 self.write(", ");
6767 self.generate_identifier(data_col)?;
6768 }
6769
6770 self.write_space();
6771 self.write_keyword("FROM");
6772 self.write_space();
6773 self.write_keyword("UNNEST");
6774 self.write("(");
6775 for (i, arg) in unnest_args.iter().enumerate() {
6776 if i > 0 {
6777 self.write(", ");
6778 }
6779 self.generate_expression(arg)?;
6780 }
6781 self.write(")");
6782 self.write_space();
6783 self.write_keyword("WITH ORDINALITY");
6784 self.write_space();
6785 self.write_keyword("AS");
6786 self.write_space();
6787
6788 let table_alias_ident = lv
6790 .table_alias
6791 .clone()
6792 .unwrap_or_else(|| Identifier::new("t"));
6793 self.generate_identifier(&table_alias_ident)?;
6794 self.write("(");
6795 for (i, data_col) in data_aliases.iter().enumerate() {
6796 if i > 0 {
6797 self.write(", ");
6798 }
6799 self.generate_identifier(data_col)?;
6800 }
6801 self.write(", ");
6802 self.generate_identifier(&pos_alias)?;
6803 self.write("))");
6804 } else if is_inline && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
6805 self.write_keyword("LATERAL");
6807 self.write(" (");
6808 self.write_keyword("SELECT");
6809 self.write_space();
6810 self.write_keyword("UNNEST");
6811 self.write("(");
6812 for (i, arg) in unnest_args.iter().enumerate() {
6813 if i > 0 {
6814 self.write(", ");
6815 }
6816 self.generate_expression(arg)?;
6817 }
6818 self.write(", ");
6819 self.write_keyword("max_depth");
6820 self.write(" => 2))");
6821
6822 if let Some(alias) = &lv.table_alias {
6824 self.write_space();
6825 self.write_keyword("AS");
6826 self.write_space();
6827 self.generate_identifier(alias)?;
6828 if !lv.column_aliases.is_empty() {
6829 self.write("(");
6830 for (i, col) in lv.column_aliases.iter().enumerate() {
6831 if i > 0 {
6832 self.write(", ");
6833 }
6834 self.generate_identifier(col)?;
6835 }
6836 self.write(")");
6837 }
6838 } else if !lv.column_aliases.is_empty() {
6839 self.write_space();
6841 self.write_keyword("AS");
6842 self.write_space();
6843 self.write(&format!("_u_{}", lv_index));
6844 self.write("(");
6845 for (i, col) in lv.column_aliases.iter().enumerate() {
6846 if i > 0 {
6847 self.write(", ");
6848 }
6849 self.generate_identifier(col)?;
6850 }
6851 self.write(")");
6852 }
6853 } else {
6854 self.write_keyword("UNNEST");
6855 self.write("(");
6856 for (i, arg) in unnest_args.iter().enumerate() {
6857 if i > 0 {
6858 self.write(", ");
6859 }
6860 self.generate_expression(arg)?;
6861 }
6862 self.write(")");
6863
6864 if let Some(alias) = &lv.table_alias {
6866 self.write_space();
6867 self.write_keyword("AS");
6868 self.write_space();
6869 self.generate_identifier(alias)?;
6870 if !lv.column_aliases.is_empty() {
6871 self.write("(");
6872 for (i, col) in lv.column_aliases.iter().enumerate() {
6873 if i > 0 {
6874 self.write(", ");
6875 }
6876 self.generate_identifier(col)?;
6877 }
6878 self.write(")");
6879 }
6880 } else if !lv.column_aliases.is_empty() {
6881 self.write_space();
6882 self.write_keyword("AS");
6883 self.write(" t(");
6884 for (i, col) in lv.column_aliases.iter().enumerate() {
6885 if i > 0 {
6886 self.write(", ");
6887 }
6888 self.generate_identifier(col)?;
6889 }
6890 self.write(")");
6891 }
6892 }
6893 } else {
6894 if !lv.outer {
6896 self.write_keyword("LATERAL");
6897 self.write_space();
6898 }
6899 self.generate_expression(&lv.this)?;
6900
6901 if let Some(alias) = &lv.table_alias {
6903 self.write_space();
6904 self.write_keyword("AS");
6905 self.write_space();
6906 self.generate_identifier(alias)?;
6907 if !lv.column_aliases.is_empty() {
6908 self.write("(");
6909 for (i, col) in lv.column_aliases.iter().enumerate() {
6910 if i > 0 {
6911 self.write(", ");
6912 }
6913 self.generate_identifier(col)?;
6914 }
6915 self.write(")");
6916 }
6917 } else if !lv.column_aliases.is_empty() {
6918 self.write_space();
6919 self.write_keyword("AS");
6920 self.write(" t(");
6921 for (i, col) in lv.column_aliases.iter().enumerate() {
6922 if i > 0 {
6923 self.write(", ");
6924 }
6925 self.generate_identifier(col)?;
6926 }
6927 self.write(")");
6928 }
6929 }
6930
6931 if lv.outer {
6933 self.write_space();
6934 self.write_keyword("ON TRUE");
6935 }
6936 } else {
6937 self.write_keyword("LATERAL VIEW");
6939 if lv.outer {
6940 self.write_space();
6941 self.write_keyword("OUTER");
6942 }
6943 if self.config.pretty {
6944 self.write_newline();
6945 self.write_indent();
6946 } else {
6947 self.write_space();
6948 }
6949 self.generate_expression(&lv.this)?;
6950
6951 if let Some(alias) = &lv.table_alias {
6953 self.write_space();
6954 self.generate_identifier(alias)?;
6955 }
6956
6957 if !lv.column_aliases.is_empty() {
6959 self.write_space();
6960 self.write_keyword("AS");
6961 self.write_space();
6962 for (i, col) in lv.column_aliases.iter().enumerate() {
6963 if i > 0 {
6964 self.write(", ");
6965 }
6966 self.generate_identifier(col)?;
6967 }
6968 }
6969 }
6970
6971 Ok(())
6972 }
6973
6974 fn should_wrap_set_operation_modifiers(
6975 &self,
6976 order_by: &Option<OrderBy>,
6977 limit: &Option<Box<Expression>>,
6978 offset: &Option<Box<Expression>>,
6979 ) -> bool {
6980 let has_row_limit = limit.is_some() || offset.is_some();
6981 let has_emulated_null_ordering = order_by.as_ref().map_or(false, |order_by| {
6982 order_by
6983 .expressions
6984 .iter()
6985 .any(|ordered| ordered.nulls_first.is_some())
6986 });
6987
6988 (has_row_limit || has_emulated_null_ordering)
6989 && matches!(
6990 self.config.dialect,
6991 Some(DialectType::TSQL) | Some(DialectType::Fabric)
6992 )
6993 }
6994
6995 fn generate_tsql_wrapped_set_operation(
6996 &mut self,
6997 inner: Expression,
6998 with: Option<With>,
6999 order_by: Option<OrderBy>,
7000 limit: Option<Box<Expression>>,
7001 offset: Option<Box<Expression>>,
7002 ) -> Result<()> {
7003 let subquery = Subquery {
7004 this: inner,
7005 alias: Some(Identifier::new("_l_0".to_string())),
7006 column_aliases: Vec::new(),
7007 alias_explicit_as: true,
7008 alias_keyword: None,
7009 order_by: None,
7010 limit: None,
7011 offset: None,
7012 lateral: false,
7013 modifiers_inside: false,
7014 trailing_comments: Vec::new(),
7015 distribute_by: None,
7016 sort_by: None,
7017 cluster_by: None,
7018 inferred_type: None,
7019 };
7020
7021 let mut outer_select = Select {
7022 expressions: vec![Expression::Star(Star {
7023 table: None,
7024 except: None,
7025 replace: None,
7026 rename: None,
7027 trailing_comments: Vec::new(),
7028 span: None,
7029 })],
7030 from: Some(From {
7031 expressions: vec![Expression::Subquery(Box::new(subquery))],
7032 }),
7033 with,
7034 order_by,
7035 limit: limit.map(|limit| Limit {
7036 this: *limit,
7037 percent: false,
7038 comments: Vec::new(),
7039 }),
7040 offset: offset.map(|offset| Offset {
7041 this: *offset,
7042 rows: Some(true),
7043 }),
7044 ..Select::new()
7045 };
7046
7047 if outer_select.offset.is_some() && outer_select.order_by.is_none() {
7048 outer_select.order_by = Some(Self::dummy_tsql_order_by());
7049 }
7050
7051 self.generate_select(&outer_select)
7052 }
7053
7054 pub(crate) fn dummy_tsql_order_by() -> OrderBy {
7055 let null_select = Expression::Select(Box::new(Select {
7056 expressions: vec![Expression::Null(Null)],
7057 ..Select::new()
7058 }));
7059
7060 OrderBy {
7061 expressions: vec![Ordered {
7062 this: Expression::Subquery(Box::new(Subquery {
7063 this: null_select,
7064 alias: None,
7065 column_aliases: Vec::new(),
7066 alias_explicit_as: false,
7067 alias_keyword: None,
7068 order_by: None,
7069 limit: None,
7070 offset: None,
7071 lateral: false,
7072 modifiers_inside: false,
7073 trailing_comments: Vec::new(),
7074 distribute_by: None,
7075 sort_by: None,
7076 cluster_by: None,
7077 inferred_type: None,
7078 })),
7079 desc: false,
7080 nulls_first: None,
7081 explicit_asc: false,
7082 with_fill: None,
7083 }],
7084 siblings: false,
7085 comments: Vec::new(),
7086 }
7087 }
7088
7089 fn generate_union(&mut self, outermost: &Union) -> Result<()> {
7090 if self.should_wrap_set_operation_modifiers(
7091 &outermost.order_by,
7092 &outermost.limit,
7093 &outermost.offset,
7094 ) {
7095 let mut inner = outermost.clone();
7096 let with = inner.with.take();
7097 let order_by = inner.order_by.take();
7098 let limit = inner.limit.take();
7099 let offset = inner.offset.take();
7100
7101 return self.generate_tsql_wrapped_set_operation(
7102 Expression::Union(Box::new(inner)),
7103 with,
7104 order_by,
7105 limit,
7106 offset,
7107 );
7108 }
7109
7110 let mut chain: Vec<&Union> = vec![outermost];
7115 let mut leftmost: &Expression = &outermost.left;
7116 while let Expression::Union(inner) = leftmost {
7117 chain.push(inner);
7118 leftmost = &inner.left;
7119 }
7120 if let Some(with) = &outermost.with {
7125 self.generate_with(with)?;
7126 self.write_space();
7127 }
7128
7129 self.generate_expression(leftmost)?;
7131
7132 for union in chain.iter().rev() {
7134 self.generate_union_step(union)?;
7135 }
7136 Ok(())
7137 }
7138
7139 fn generate_union_step(&mut self, union: &Union) -> Result<()> {
7141 if self.config.pretty {
7142 self.write_newline();
7143 self.write_indent();
7144 } else {
7145 self.write_space();
7146 }
7147
7148 if let Some(side) = &union.side {
7150 self.write_keyword(side);
7151 self.write_space();
7152 }
7153 if let Some(kind) = &union.kind {
7154 self.write_keyword(kind);
7155 self.write_space();
7156 }
7157
7158 self.write_keyword("UNION");
7159 if union.all {
7160 self.write_space();
7161 self.write_keyword("ALL");
7162 } else if union.distinct {
7163 self.write_space();
7164 self.write_keyword("DISTINCT");
7165 }
7166
7167 if union.corresponding || union.by_name {
7170 self.write_space();
7171 self.write_keyword("BY NAME");
7172 }
7173 if !union.on_columns.is_empty() {
7174 self.write_space();
7175 self.write_keyword("ON");
7176 self.write(" (");
7177 for (i, col) in union.on_columns.iter().enumerate() {
7178 if i > 0 {
7179 self.write(", ");
7180 }
7181 self.generate_expression(col)?;
7182 }
7183 self.write(")");
7184 }
7185
7186 if self.config.pretty {
7187 self.write_newline();
7188 self.write_indent();
7189 } else {
7190 self.write_space();
7191 }
7192 self.generate_expression(&union.right)?;
7193 if let Some(order_by) = &union.order_by {
7195 if self.config.pretty {
7196 self.write_newline();
7197 } else {
7198 self.write_space();
7199 }
7200 self.write_keyword("ORDER BY");
7201 self.write_space();
7202 for (i, ordered) in order_by.expressions.iter().enumerate() {
7203 if i > 0 {
7204 self.write(", ");
7205 }
7206 self.generate_ordered(ordered)?;
7207 }
7208 }
7209 if let Some(limit) = &union.limit {
7210 if self.config.pretty {
7211 self.write_newline();
7212 } else {
7213 self.write_space();
7214 }
7215 self.write_keyword("LIMIT");
7216 self.write_space();
7217 self.generate_expression(limit)?;
7218 }
7219 if let Some(offset) = &union.offset {
7220 if self.config.pretty {
7221 self.write_newline();
7222 } else {
7223 self.write_space();
7224 }
7225 self.write_keyword("OFFSET");
7226 self.write_space();
7227 self.generate_expression(offset)?;
7228 }
7229 if let Some(distribute_by) = &union.distribute_by {
7231 self.write_space();
7232 self.write_keyword("DISTRIBUTE BY");
7233 self.write_space();
7234 for (i, expr) in distribute_by.expressions.iter().enumerate() {
7235 if i > 0 {
7236 self.write(", ");
7237 }
7238 self.generate_expression(expr)?;
7239 }
7240 }
7241 if let Some(sort_by) = &union.sort_by {
7243 self.write_space();
7244 self.write_keyword("SORT BY");
7245 self.write_space();
7246 for (i, ord) in sort_by.expressions.iter().enumerate() {
7247 if i > 0 {
7248 self.write(", ");
7249 }
7250 self.generate_ordered(ord)?;
7251 }
7252 }
7253 if let Some(cluster_by) = &union.cluster_by {
7255 self.write_space();
7256 self.write_keyword("CLUSTER BY");
7257 self.write_space();
7258 for (i, ord) in cluster_by.expressions.iter().enumerate() {
7259 if i > 0 {
7260 self.write(", ");
7261 }
7262 self.generate_ordered(ord)?;
7263 }
7264 }
7265 Ok(())
7266 }
7267
7268 fn generate_intersect(&mut self, outermost: &Intersect) -> Result<()> {
7269 if self.should_wrap_set_operation_modifiers(
7270 &outermost.order_by,
7271 &outermost.limit,
7272 &outermost.offset,
7273 ) {
7274 let mut inner = outermost.clone();
7275 let with = inner.with.take();
7276 let order_by = inner.order_by.take();
7277 let limit = inner.limit.take();
7278 let offset = inner.offset.take();
7279
7280 return self.generate_tsql_wrapped_set_operation(
7281 Expression::Intersect(Box::new(inner)),
7282 with,
7283 order_by,
7284 limit,
7285 offset,
7286 );
7287 }
7288
7289 let mut chain: Vec<&Intersect> = vec![outermost];
7291 let mut leftmost: &Expression = &outermost.left;
7292 while let Expression::Intersect(inner) = leftmost {
7293 chain.push(inner);
7294 leftmost = &inner.left;
7295 }
7296
7297 if let Some(with) = &outermost.with {
7298 self.generate_with(with)?;
7299 self.write_space();
7300 }
7301
7302 self.generate_expression(leftmost)?;
7303
7304 for intersect in chain.iter().rev() {
7305 self.generate_intersect_step(intersect)?;
7306 }
7307 Ok(())
7308 }
7309
7310 fn generate_intersect_step(&mut self, intersect: &Intersect) -> Result<()> {
7312 if self.config.pretty {
7313 self.write_newline();
7314 self.write_indent();
7315 } else {
7316 self.write_space();
7317 }
7318
7319 if let Some(side) = &intersect.side {
7321 self.write_keyword(side);
7322 self.write_space();
7323 }
7324 if let Some(kind) = &intersect.kind {
7325 self.write_keyword(kind);
7326 self.write_space();
7327 }
7328
7329 self.write_keyword("INTERSECT");
7330 if intersect.all {
7331 if !self.config.except_intersect_support_all_clause {
7332 self.unsupported("INTERSECT ALL is not supported")?;
7333 }
7334 self.write_space();
7335 self.write_keyword("ALL");
7336 } else if intersect.distinct {
7337 self.write_space();
7338 self.write_keyword("DISTINCT");
7339 }
7340
7341 if intersect.corresponding || intersect.by_name {
7344 self.write_space();
7345 self.write_keyword("BY NAME");
7346 }
7347 if !intersect.on_columns.is_empty() {
7348 self.write_space();
7349 self.write_keyword("ON");
7350 self.write(" (");
7351 for (i, col) in intersect.on_columns.iter().enumerate() {
7352 if i > 0 {
7353 self.write(", ");
7354 }
7355 self.generate_expression(col)?;
7356 }
7357 self.write(")");
7358 }
7359
7360 if self.config.pretty {
7361 self.write_newline();
7362 self.write_indent();
7363 } else {
7364 self.write_space();
7365 }
7366 self.generate_expression(&intersect.right)?;
7367 if let Some(order_by) = &intersect.order_by {
7369 if self.config.pretty {
7370 self.write_newline();
7371 } else {
7372 self.write_space();
7373 }
7374 self.write_keyword("ORDER BY");
7375 self.write_space();
7376 for (i, ordered) in order_by.expressions.iter().enumerate() {
7377 if i > 0 {
7378 self.write(", ");
7379 }
7380 self.generate_ordered(ordered)?;
7381 }
7382 }
7383 if let Some(limit) = &intersect.limit {
7384 if self.config.pretty {
7385 self.write_newline();
7386 } else {
7387 self.write_space();
7388 }
7389 self.write_keyword("LIMIT");
7390 self.write_space();
7391 self.generate_expression(limit)?;
7392 }
7393 if let Some(offset) = &intersect.offset {
7394 if self.config.pretty {
7395 self.write_newline();
7396 } else {
7397 self.write_space();
7398 }
7399 self.write_keyword("OFFSET");
7400 self.write_space();
7401 self.generate_expression(offset)?;
7402 }
7403 if let Some(distribute_by) = &intersect.distribute_by {
7405 self.write_space();
7406 self.write_keyword("DISTRIBUTE BY");
7407 self.write_space();
7408 for (i, expr) in distribute_by.expressions.iter().enumerate() {
7409 if i > 0 {
7410 self.write(", ");
7411 }
7412 self.generate_expression(expr)?;
7413 }
7414 }
7415 if let Some(sort_by) = &intersect.sort_by {
7417 self.write_space();
7418 self.write_keyword("SORT BY");
7419 self.write_space();
7420 for (i, ord) in sort_by.expressions.iter().enumerate() {
7421 if i > 0 {
7422 self.write(", ");
7423 }
7424 self.generate_ordered(ord)?;
7425 }
7426 }
7427 if let Some(cluster_by) = &intersect.cluster_by {
7429 self.write_space();
7430 self.write_keyword("CLUSTER BY");
7431 self.write_space();
7432 for (i, ord) in cluster_by.expressions.iter().enumerate() {
7433 if i > 0 {
7434 self.write(", ");
7435 }
7436 self.generate_ordered(ord)?;
7437 }
7438 }
7439 Ok(())
7440 }
7441
7442 fn generate_except(&mut self, outermost: &Except) -> Result<()> {
7443 if self.should_wrap_set_operation_modifiers(
7444 &outermost.order_by,
7445 &outermost.limit,
7446 &outermost.offset,
7447 ) {
7448 let mut inner = outermost.clone();
7449 let with = inner.with.take();
7450 let order_by = inner.order_by.take();
7451 let limit = inner.limit.take();
7452 let offset = inner.offset.take();
7453
7454 return self.generate_tsql_wrapped_set_operation(
7455 Expression::Except(Box::new(inner)),
7456 with,
7457 order_by,
7458 limit,
7459 offset,
7460 );
7461 }
7462
7463 let mut chain: Vec<&Except> = vec![outermost];
7465 let mut leftmost: &Expression = &outermost.left;
7466 while let Expression::Except(inner) = leftmost {
7467 chain.push(inner);
7468 leftmost = &inner.left;
7469 }
7470
7471 if let Some(with) = &outermost.with {
7472 self.generate_with(with)?;
7473 self.write_space();
7474 }
7475
7476 self.generate_expression(leftmost)?;
7477
7478 for except in chain.iter().rev() {
7479 self.generate_except_step(except)?;
7480 }
7481 Ok(())
7482 }
7483
7484 fn generate_except_step(&mut self, except: &Except) -> Result<()> {
7486 use crate::dialects::DialectType;
7487
7488 if self.config.pretty {
7489 self.write_newline();
7490 self.write_indent();
7491 } else {
7492 self.write_space();
7493 }
7494
7495 if let Some(side) = &except.side {
7497 self.write_keyword(side);
7498 self.write_space();
7499 }
7500 if let Some(kind) = &except.kind {
7501 self.write_keyword(kind);
7502 self.write_space();
7503 }
7504
7505 match self.config.dialect {
7507 Some(DialectType::Oracle) if !except.all => {
7508 self.write_keyword("MINUS");
7509 }
7510 Some(DialectType::ClickHouse) => {
7511 self.write_keyword("EXCEPT");
7512 let preserve_all = self.config.source_dialect.is_none()
7513 || matches!(self.config.source_dialect, Some(DialectType::ClickHouse));
7514 if except.all && preserve_all {
7515 self.write_space();
7516 self.write_keyword("ALL");
7517 }
7518 if except.distinct {
7519 self.write_space();
7520 self.write_keyword("DISTINCT");
7521 }
7522 }
7523 Some(DialectType::BigQuery) => {
7524 self.write_keyword("EXCEPT");
7526 if except.all {
7527 self.write_space();
7528 self.write_keyword("ALL");
7529 } else {
7530 self.write_space();
7531 self.write_keyword("DISTINCT");
7532 }
7533 }
7534 _ => {
7535 self.write_keyword("EXCEPT");
7536 if except.all {
7537 if !self.config.except_intersect_support_all_clause {
7538 self.unsupported("EXCEPT ALL is not supported")?;
7539 }
7540 self.write_space();
7541 self.write_keyword("ALL");
7542 } else if except.distinct {
7543 self.write_space();
7544 self.write_keyword("DISTINCT");
7545 }
7546 }
7547 }
7548
7549 if except.corresponding || except.by_name {
7552 self.write_space();
7553 self.write_keyword("BY NAME");
7554 }
7555 if !except.on_columns.is_empty() {
7556 self.write_space();
7557 self.write_keyword("ON");
7558 self.write(" (");
7559 for (i, col) in except.on_columns.iter().enumerate() {
7560 if i > 0 {
7561 self.write(", ");
7562 }
7563 self.generate_expression(col)?;
7564 }
7565 self.write(")");
7566 }
7567
7568 if self.config.pretty {
7569 self.write_newline();
7570 self.write_indent();
7571 } else {
7572 self.write_space();
7573 }
7574 self.generate_expression(&except.right)?;
7575 if let Some(order_by) = &except.order_by {
7577 if self.config.pretty {
7578 self.write_newline();
7579 } else {
7580 self.write_space();
7581 }
7582 self.write_keyword("ORDER BY");
7583 self.write_space();
7584 for (i, ordered) in order_by.expressions.iter().enumerate() {
7585 if i > 0 {
7586 self.write(", ");
7587 }
7588 self.generate_ordered(ordered)?;
7589 }
7590 }
7591 if let Some(limit) = &except.limit {
7592 if self.config.pretty {
7593 self.write_newline();
7594 } else {
7595 self.write_space();
7596 }
7597 self.write_keyword("LIMIT");
7598 self.write_space();
7599 self.generate_expression(limit)?;
7600 }
7601 if let Some(offset) = &except.offset {
7602 if self.config.pretty {
7603 self.write_newline();
7604 } else {
7605 self.write_space();
7606 }
7607 self.write_keyword("OFFSET");
7608 self.write_space();
7609 self.generate_expression(offset)?;
7610 }
7611 if let Some(distribute_by) = &except.distribute_by {
7613 self.write_space();
7614 self.write_keyword("DISTRIBUTE BY");
7615 self.write_space();
7616 for (i, expr) in distribute_by.expressions.iter().enumerate() {
7617 if i > 0 {
7618 self.write(", ");
7619 }
7620 self.generate_expression(expr)?;
7621 }
7622 }
7623 if let Some(sort_by) = &except.sort_by {
7625 self.write_space();
7626 self.write_keyword("SORT BY");
7627 self.write_space();
7628 for (i, ord) in sort_by.expressions.iter().enumerate() {
7629 if i > 0 {
7630 self.write(", ");
7631 }
7632 self.generate_ordered(ord)?;
7633 }
7634 }
7635 if let Some(cluster_by) = &except.cluster_by {
7637 self.write_space();
7638 self.write_keyword("CLUSTER BY");
7639 self.write_space();
7640 for (i, ord) in cluster_by.expressions.iter().enumerate() {
7641 if i > 0 {
7642 self.write(", ");
7643 }
7644 self.generate_ordered(ord)?;
7645 }
7646 }
7647 Ok(())
7648 }
7649
7650 fn generate_insert(&mut self, insert: &Insert) -> Result<()> {
7651 let prepend_query_cte = if insert.with.is_none() {
7653 use crate::dialects::DialectType;
7654 let should_prepend = matches!(
7655 self.config.dialect,
7656 Some(DialectType::TSQL)
7657 | Some(DialectType::Fabric)
7658 | Some(DialectType::Spark)
7659 | Some(DialectType::Databricks)
7660 | Some(DialectType::Hive)
7661 );
7662 if should_prepend {
7663 if let Some(Expression::Select(select)) = &insert.query {
7664 select.with.clone()
7665 } else {
7666 None
7667 }
7668 } else {
7669 None
7670 }
7671 } else {
7672 None
7673 };
7674
7675 if let Some(with) = &insert.with {
7677 self.generate_with(with)?;
7678 self.write_space();
7679 } else if let Some(with) = &prepend_query_cte {
7680 self.generate_with(with)?;
7681 self.write_space();
7682 }
7683
7684 for comment in &insert.leading_comments {
7686 self.write_formatted_comment(comment);
7687 self.write(" ");
7688 }
7689
7690 if let Some(dir) = &insert.directory {
7692 self.write_keyword("INSERT OVERWRITE");
7693 if dir.local {
7694 self.write_space();
7695 self.write_keyword("LOCAL");
7696 }
7697 self.write_space();
7698 self.write_keyword("DIRECTORY");
7699 self.write_space();
7700 self.write("'");
7701 self.write(&dir.path);
7702 self.write("'");
7703
7704 if let Some(row_format) = &dir.row_format {
7706 self.write_space();
7707 self.write_keyword("ROW FORMAT");
7708 if row_format.delimited {
7709 self.write_space();
7710 self.write_keyword("DELIMITED");
7711 }
7712 if let Some(val) = &row_format.fields_terminated_by {
7713 self.write_space();
7714 self.write_keyword("FIELDS TERMINATED BY");
7715 self.write_space();
7716 self.generate_string_literal(val)?;
7717 }
7718 if let Some(val) = &row_format.collection_items_terminated_by {
7719 self.write_space();
7720 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
7721 self.write_space();
7722 self.write("'");
7723 self.write(val);
7724 self.write("'");
7725 }
7726 if let Some(val) = &row_format.map_keys_terminated_by {
7727 self.write_space();
7728 self.write_keyword("MAP KEYS TERMINATED BY");
7729 self.write_space();
7730 self.write("'");
7731 self.write(val);
7732 self.write("'");
7733 }
7734 if let Some(val) = &row_format.lines_terminated_by {
7735 self.write_space();
7736 self.write_keyword("LINES TERMINATED BY");
7737 self.write_space();
7738 self.write("'");
7739 self.write(val);
7740 self.write("'");
7741 }
7742 if let Some(val) = &row_format.null_defined_as {
7743 self.write_space();
7744 self.write_keyword("NULL DEFINED AS");
7745 self.write_space();
7746 self.write("'");
7747 self.write(val);
7748 self.write("'");
7749 }
7750 }
7751
7752 if let Some(format) = &dir.stored_as {
7754 self.write_space();
7755 self.write_keyword("STORED AS");
7756 self.write_space();
7757 self.write_keyword(format);
7758 }
7759
7760 if let Some(query) = &insert.query {
7762 self.write_space();
7763 self.generate_expression(query)?;
7764 }
7765
7766 return Ok(());
7767 }
7768
7769 if insert.is_replace {
7770 self.write_keyword("REPLACE INTO");
7772 } else if insert.overwrite {
7773 self.write_keyword("INSERT");
7775 if let Some(ref hint) = insert.hint {
7777 self.generate_hint(hint)?;
7778 }
7779 self.write(&self.config.insert_overwrite.to_ascii_uppercase());
7780 } else if let Some(ref action) = insert.conflict_action {
7781 self.write_keyword("INSERT OR");
7783 self.write_space();
7784 self.write_keyword(action);
7785 self.write_space();
7786 self.write_keyword("INTO");
7787 } else if insert.ignore {
7788 self.write_keyword("INSERT IGNORE INTO");
7790 } else {
7791 self.write_keyword("INSERT");
7792 if let Some(ref hint) = insert.hint {
7794 self.generate_hint(hint)?;
7795 }
7796 self.write_space();
7797 self.write_keyword("INTO");
7798 }
7799 if let Some(ref func) = insert.function_target {
7801 self.write_space();
7802 self.write_keyword("FUNCTION");
7803 self.write_space();
7804 self.generate_expression(func)?;
7805 } else {
7806 self.write_space();
7807 self.generate_table(&insert.table)?;
7808 }
7809
7810 if let Some(ref alias) = insert.alias {
7812 self.write_space();
7813 if insert.alias_explicit_as {
7814 self.write_keyword("AS");
7815 self.write_space();
7816 }
7817 self.generate_identifier(alias)?;
7818 }
7819
7820 if insert.if_exists {
7822 self.write_space();
7823 self.write_keyword("IF EXISTS");
7824 }
7825
7826 if let Some(ref replace_where) = insert.replace_where {
7828 if self.config.pretty {
7829 self.write_newline();
7830 self.write_indent();
7831 } else {
7832 self.write_space();
7833 }
7834 self.write_keyword("REPLACE WHERE");
7835 self.write_space();
7836 self.generate_expression(replace_where)?;
7837 }
7838
7839 if !insert.partition.is_empty() {
7841 self.write_space();
7842 self.write_keyword("PARTITION");
7843 self.write("(");
7844 for (i, (col, val)) in insert.partition.iter().enumerate() {
7845 if i > 0 {
7846 self.write(", ");
7847 }
7848 self.generate_identifier(col)?;
7849 if let Some(v) = val {
7850 self.write(" = ");
7851 self.generate_expression(v)?;
7852 }
7853 }
7854 self.write(")");
7855 }
7856
7857 if let Some(ref partition_by) = insert.partition_by {
7859 self.write_space();
7860 self.write_keyword("PARTITION BY");
7861 self.write_space();
7862 self.generate_expression(partition_by)?;
7863 }
7864
7865 if !insert.settings.is_empty() {
7867 self.write_space();
7868 self.write_keyword("SETTINGS");
7869 self.write_space();
7870 for (i, setting) in insert.settings.iter().enumerate() {
7871 if i > 0 {
7872 self.write(", ");
7873 }
7874 self.generate_expression(setting)?;
7875 }
7876 }
7877
7878 if !insert.columns.is_empty() {
7879 if insert.alias.is_some() && insert.alias_explicit_as {
7880 self.write("(");
7882 } else {
7883 self.write(" (");
7885 }
7886 for (i, col) in insert.columns.iter().enumerate() {
7887 if i > 0 {
7888 self.write(", ");
7889 }
7890 self.generate_identifier(col)?;
7891 }
7892 self.write(")");
7893 }
7894
7895 if let Some(ref output) = insert.output {
7897 self.generate_output_clause(output)?;
7898 }
7899
7900 if insert.by_name {
7902 self.write_space();
7903 self.write_keyword("BY NAME");
7904 }
7905
7906 if insert.default_values {
7907 self.write_space();
7908 self.write_keyword("DEFAULT VALUES");
7909 } else if let Some(query) = &insert.query {
7910 if self.config.pretty {
7911 self.write_newline();
7912 } else {
7913 self.write_space();
7914 }
7915 if prepend_query_cte.is_some() {
7917 if let Expression::Select(select) = query {
7918 let mut select_no_with = select.clone();
7919 select_no_with.with = None;
7920 self.generate_select(&select_no_with)?;
7921 } else {
7922 self.generate_expression(query)?;
7923 }
7924 } else {
7925 self.generate_expression(query)?;
7926 }
7927 } else if !insert.values.is_empty() {
7928 if self.config.pretty {
7929 self.write_newline();
7931 self.write_keyword("VALUES");
7932 self.write_newline();
7933 self.indent_level += 1;
7934 for (i, row) in insert.values.iter().enumerate() {
7935 if i > 0 {
7936 self.write(",");
7937 self.write_newline();
7938 }
7939 self.write_indent();
7940 self.write("(");
7941 for (j, val) in row.iter().enumerate() {
7942 if j > 0 {
7943 self.write(", ");
7944 }
7945 self.generate_expression(val)?;
7946 }
7947 self.write(")");
7948 }
7949 self.indent_level -= 1;
7950 } else {
7951 self.write_space();
7953 self.write_keyword("VALUES");
7954 for (i, row) in insert.values.iter().enumerate() {
7955 if i > 0 {
7956 self.write(",");
7957 }
7958 self.write(" (");
7959 for (j, val) in row.iter().enumerate() {
7960 if j > 0 {
7961 self.write(", ");
7962 }
7963 self.generate_expression(val)?;
7964 }
7965 self.write(")");
7966 }
7967 }
7968 }
7969
7970 if let Some(ref source) = insert.source {
7972 self.write_space();
7973 self.write_keyword("TABLE");
7974 self.write_space();
7975 self.generate_expression(source)?;
7976 }
7977
7978 if let Some(alias) = &insert.source_alias {
7980 self.write_space();
7981 self.write_keyword("AS");
7982 self.write_space();
7983 self.generate_identifier(alias)?;
7984 }
7985
7986 if let Some(on_conflict) = &insert.on_conflict {
7988 if !matches!(self.config.dialect, Some(DialectType::Materialize)) {
7989 self.write_space();
7990 self.generate_expression(on_conflict)?;
7991 }
7992 }
7993
7994 if !insert.returning.is_empty() {
7996 self.write_space();
7997 self.write_keyword("RETURNING");
7998 self.write_space();
7999 for (i, expr) in insert.returning.iter().enumerate() {
8000 if i > 0 {
8001 self.write(", ");
8002 }
8003 self.generate_expression(expr)?;
8004 }
8005 }
8006
8007 Ok(())
8008 }
8009
8010 fn generate_update(&mut self, update: &Update) -> Result<()> {
8011 for comment in &update.leading_comments {
8013 self.write_formatted_comment(comment);
8014 self.write(" ");
8015 }
8016
8017 if let Some(ref with) = update.with {
8019 self.generate_with(with)?;
8020 self.write_space();
8021 }
8022
8023 self.write_keyword("UPDATE");
8024 if let Some(hint) = &update.hint {
8025 self.generate_hint(hint)?;
8026 }
8027 self.write_space();
8028 self.generate_table(&update.table)?;
8029
8030 let mysql_like_update_from = matches!(
8031 self.config.dialect,
8032 Some(DialectType::MySQL) | Some(DialectType::SingleStore)
8033 ) && update.from_clause.is_some();
8034
8035 let mut set_pairs = update.set.clone();
8036
8037 let mut pre_set_joins = update.table_joins.clone();
8039 if mysql_like_update_from {
8040 let target_name = update
8041 .table
8042 .alias
8043 .as_ref()
8044 .map(|a| a.name.clone())
8045 .unwrap_or_else(|| update.table.name.name.clone());
8046
8047 for (col, _) in &mut set_pairs {
8048 if !col.name.contains('.') {
8049 col.name = format!("{}.{}", target_name, col.name);
8050 }
8051 }
8052
8053 if let Some(from_clause) = &update.from_clause {
8054 for table_expr in &from_clause.expressions {
8055 pre_set_joins.push(crate::expressions::Join {
8056 this: table_expr.clone(),
8057 on: Some(Expression::Boolean(crate::expressions::BooleanLiteral {
8058 value: true,
8059 })),
8060 using: Vec::new(),
8061 kind: crate::expressions::JoinKind::Inner,
8062 use_inner_keyword: false,
8063 use_outer_keyword: false,
8064 deferred_condition: false,
8065 join_hint: None,
8066 match_condition: None,
8067 pivots: Vec::new(),
8068 comments: Vec::new(),
8069 nesting_group: 0,
8070 directed: false,
8071 });
8072 }
8073 }
8074 for join in &update.from_joins {
8075 let mut join = join.clone();
8076 if join.on.is_none() && join.using.is_empty() {
8077 join.on = Some(Expression::Boolean(crate::expressions::BooleanLiteral {
8078 value: true,
8079 }));
8080 }
8081 pre_set_joins.push(join);
8082 }
8083 }
8084
8085 for extra_table in &update.extra_tables {
8087 self.write(", ");
8088 self.generate_table(extra_table)?;
8089 }
8090
8091 for join in &pre_set_joins {
8093 self.generate_join(join)?;
8095 }
8096
8097 let teradata_from_before_set = matches!(self.config.dialect, Some(DialectType::Teradata));
8099 if teradata_from_before_set && !mysql_like_update_from {
8100 if let Some(ref from_clause) = update.from_clause {
8101 self.write_space();
8102 self.write_keyword("FROM");
8103 self.write_space();
8104 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
8105 if i > 0 {
8106 self.write(", ");
8107 }
8108 self.generate_expression(table_expr)?;
8109 }
8110 }
8111 for join in &update.from_joins {
8112 self.generate_join(join)?;
8113 }
8114 }
8115
8116 self.write_space();
8117 self.write_keyword("SET");
8118 self.write_space();
8119
8120 for (i, (col, val)) in set_pairs.iter().enumerate() {
8121 if i > 0 {
8122 self.write(", ");
8123 }
8124 self.generate_identifier(col)?;
8125 self.write(" = ");
8126 self.generate_expression(val)?;
8127 }
8128
8129 if let Some(ref output) = update.output {
8131 self.generate_output_clause(output)?;
8132 }
8133
8134 if !mysql_like_update_from && !teradata_from_before_set {
8136 if let Some(ref from_clause) = update.from_clause {
8137 self.write_space();
8138 self.write_keyword("FROM");
8139 self.write_space();
8140 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
8142 if i > 0 {
8143 self.write(", ");
8144 }
8145 self.generate_expression(table_expr)?;
8146 }
8147 }
8148 }
8149
8150 if !mysql_like_update_from && !teradata_from_before_set {
8151 for join in &update.from_joins {
8153 self.generate_join(join)?;
8154 }
8155 }
8156
8157 if let Some(where_clause) = &update.where_clause {
8158 self.write_space();
8159 self.write_keyword("WHERE");
8160 self.write_space();
8161 self.generate_expression(&where_clause.this)?;
8162 }
8163
8164 if !update.returning.is_empty() {
8166 self.write_space();
8167 self.write_keyword("RETURNING");
8168 self.write_space();
8169 for (i, expr) in update.returning.iter().enumerate() {
8170 if i > 0 {
8171 self.write(", ");
8172 }
8173 self.generate_expression(expr)?;
8174 }
8175 }
8176
8177 if let Some(ref order_by) = update.order_by {
8179 self.write_space();
8180 self.generate_order_by(order_by)?;
8181 }
8182
8183 if let Some(ref limit) = update.limit {
8185 self.write_space();
8186 self.write_keyword("LIMIT");
8187 self.write_space();
8188 self.generate_expression(limit)?;
8189 }
8190
8191 Ok(())
8192 }
8193
8194 fn generate_delete(&mut self, delete: &Delete) -> Result<()> {
8195 if let Some(with) = &delete.with {
8197 self.generate_with(with)?;
8198 self.write_space();
8199 }
8200
8201 for comment in &delete.leading_comments {
8203 self.write_formatted_comment(comment);
8204 self.write(" ");
8205 }
8206
8207 if !delete.tables.is_empty() && !delete.tables_from_using {
8209 self.write_keyword("DELETE");
8211 if let Some(hint) = &delete.hint {
8212 self.generate_hint(hint)?;
8213 }
8214 self.write_space();
8215 for (i, tbl) in delete.tables.iter().enumerate() {
8216 if i > 0 {
8217 self.write(", ");
8218 }
8219 self.generate_table(tbl)?;
8220 }
8221 if let Some(ref output) = delete.output {
8223 self.generate_output_clause(output)?;
8224 }
8225 self.write_space();
8226 self.write_keyword("FROM");
8227 self.write_space();
8228 self.generate_table(&delete.table)?;
8229 } else if !delete.tables.is_empty() && delete.tables_from_using {
8230 self.write_keyword("DELETE");
8232 if let Some(hint) = &delete.hint {
8233 self.generate_hint(hint)?;
8234 }
8235 self.write_space();
8236 self.write_keyword("FROM");
8237 self.write_space();
8238 for (i, tbl) in delete.tables.iter().enumerate() {
8239 if i > 0 {
8240 self.write(", ");
8241 }
8242 self.generate_table(tbl)?;
8243 }
8244 } else if delete.no_from && matches!(self.config.dialect, Some(DialectType::BigQuery)) {
8245 self.write_keyword("DELETE");
8247 if let Some(hint) = &delete.hint {
8248 self.generate_hint(hint)?;
8249 }
8250 self.write_space();
8251 self.generate_table(&delete.table)?;
8252 } else {
8253 self.write_keyword("DELETE");
8254 if let Some(hint) = &delete.hint {
8255 self.generate_hint(hint)?;
8256 }
8257 self.write_space();
8258 self.write_keyword("FROM");
8259 self.write_space();
8260 self.generate_table(&delete.table)?;
8261 }
8262
8263 if let Some(ref on_cluster) = delete.on_cluster {
8265 self.write_space();
8266 self.generate_on_cluster(on_cluster)?;
8267 }
8268
8269 if let Some(ref idx) = delete.force_index {
8271 self.write_space();
8272 self.write_keyword("FORCE INDEX");
8273 self.write(" (");
8274 self.write(idx);
8275 self.write(")");
8276 }
8277
8278 if let Some(ref alias) = delete.alias {
8280 self.write_space();
8281 if delete.alias_explicit_as
8282 || matches!(self.config.dialect, Some(DialectType::BigQuery))
8283 {
8284 self.write_keyword("AS");
8285 self.write_space();
8286 }
8287 self.generate_identifier(alias)?;
8288 }
8289
8290 if !delete.tables_from_using {
8292 for join in &delete.joins {
8293 self.generate_join(join)?;
8294 }
8295 }
8296
8297 if !delete.using.is_empty() {
8299 self.write_space();
8300 self.write_keyword("USING");
8301 for (i, table) in delete.using.iter().enumerate() {
8302 if i > 0 {
8303 self.write(",");
8304 }
8305 self.write_space();
8306 if !table.hints.is_empty() && table.name.is_empty() {
8308 self.generate_expression(&table.hints[0])?;
8310 if let Some(ref alias) = table.alias {
8311 self.write_space();
8312 if table.alias_explicit_as {
8313 self.write_keyword("AS");
8314 self.write_space();
8315 }
8316 self.generate_identifier(alias)?;
8317 if !table.column_aliases.is_empty() {
8318 self.write("(");
8319 for (j, col_alias) in table.column_aliases.iter().enumerate() {
8320 if j > 0 {
8321 self.write(", ");
8322 }
8323 self.generate_identifier(col_alias)?;
8324 }
8325 self.write(")");
8326 }
8327 }
8328 } else {
8329 self.generate_table(table)?;
8330 }
8331 }
8332 }
8333
8334 if delete.tables_from_using {
8336 for join in &delete.joins {
8337 self.generate_join(join)?;
8338 }
8339 }
8340
8341 let output_already_emitted =
8343 !delete.tables.is_empty() && !delete.tables_from_using && delete.output.is_some();
8344 if !output_already_emitted {
8345 if let Some(ref output) = delete.output {
8346 self.generate_output_clause(output)?;
8347 }
8348 }
8349
8350 if let Some(where_clause) = &delete.where_clause {
8351 self.write_space();
8352 self.write_keyword("WHERE");
8353 self.write_space();
8354 self.generate_expression(&where_clause.this)?;
8355 }
8356
8357 if let Some(ref order_by) = delete.order_by {
8359 self.write_space();
8360 self.generate_order_by(order_by)?;
8361 }
8362
8363 if let Some(ref limit) = delete.limit {
8365 self.write_space();
8366 self.write_keyword("LIMIT");
8367 self.write_space();
8368 self.generate_expression(limit)?;
8369 }
8370
8371 if !delete.returning.is_empty() {
8373 self.write_space();
8374 self.write_keyword("RETURNING");
8375 self.write_space();
8376 for (i, expr) in delete.returning.iter().enumerate() {
8377 if i > 0 {
8378 self.write(", ");
8379 }
8380 self.generate_expression(expr)?;
8381 }
8382 }
8383
8384 Ok(())
8385 }
8386
8387 fn generate_create_table(&mut self, ct: &CreateTable) -> Result<()> {
8390 let saved_athena_hive_context = self.athena_hive_context;
8394 let is_clickhouse = matches!(self.config.dialect, Some(DialectType::ClickHouse));
8395 if matches!(
8396 self.config.dialect,
8397 Some(crate::dialects::DialectType::Athena)
8398 ) {
8399 let is_external = ct
8403 .table_modifier
8404 .as_ref()
8405 .map(|m| m.eq_ignore_ascii_case("EXTERNAL"))
8406 .unwrap_or(false);
8407 let has_as_select = ct.as_select.is_some();
8408 self.athena_hive_context = is_external || !has_as_select;
8409 }
8410
8411 if matches!(
8413 self.config.dialect,
8414 Some(crate::dialects::DialectType::TSQL)
8415 ) {
8416 if let Some(ref query) = ct.as_select {
8417 if let Some(with_cte) = &ct.with_cte {
8419 self.generate_with(with_cte)?;
8420 self.write_space();
8421 }
8422
8423 self.write_keyword("SELECT");
8425 self.write(" * ");
8426 self.write_keyword("INTO");
8427 self.write_space();
8428
8429 if ct.temporary {
8431 self.write("#");
8432 }
8433 self.generate_table(&ct.name)?;
8434
8435 self.write_space();
8436 self.write_keyword("FROM");
8437 self.write(" (");
8438 let aliased_query = Self::add_column_aliases_to_query(query.clone());
8440 self.generate_expression(&aliased_query)?;
8441 self.write(") ");
8442 self.write_keyword("AS");
8443 self.write(" temp");
8444 return Ok(());
8445 }
8446 }
8447
8448 if let Some(with_cte) = &ct.with_cte {
8450 self.generate_with(with_cte)?;
8451 self.write_space();
8452 }
8453
8454 for comment in &ct.leading_comments {
8456 self.write_formatted_comment(comment);
8457 self.write(" ");
8458 }
8459 self.write_keyword("CREATE");
8460
8461 if ct.or_replace {
8462 self.write_space();
8463 self.write_keyword("OR REPLACE");
8464 }
8465
8466 if ct.temporary {
8467 self.write_space();
8468 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
8470 self.write_keyword("GLOBAL TEMPORARY");
8471 } else {
8472 self.write_keyword("TEMPORARY");
8473 }
8474 }
8475
8476 let is_dictionary = ct
8478 .table_modifier
8479 .as_ref()
8480 .map(|m| m.eq_ignore_ascii_case("DICTIONARY"))
8481 .unwrap_or(false);
8482 if let Some(ref modifier) = ct.table_modifier {
8483 let skip_transient = modifier.eq_ignore_ascii_case("TRANSIENT")
8485 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None);
8486 let is_teradata_modifier = modifier.eq_ignore_ascii_case("VOLATILE")
8488 || modifier.eq_ignore_ascii_case("SET")
8489 || modifier.eq_ignore_ascii_case("MULTISET")
8490 || modifier.to_ascii_uppercase().contains("VOLATILE")
8491 || modifier.to_ascii_uppercase().starts_with("SET ")
8492 || modifier.to_ascii_uppercase().starts_with("MULTISET ");
8493 let skip_teradata =
8494 is_teradata_modifier && !matches!(self.config.dialect, Some(DialectType::Teradata));
8495 if !skip_transient && !skip_teradata {
8496 self.write_space();
8497 self.write_keyword(modifier);
8498 }
8499 }
8500
8501 if !is_dictionary {
8502 self.write_space();
8503 self.write_keyword("TABLE");
8504 }
8505
8506 if ct.if_not_exists {
8507 self.write_space();
8508 self.write_keyword("IF NOT EXISTS");
8509 }
8510
8511 self.write_space();
8512 self.generate_table(&ct.name)?;
8513
8514 if let Some(ref uuid) = ct.uuid {
8516 self.write_space();
8517 self.write_keyword("UUID");
8518 self.write(" '");
8519 self.write(uuid);
8520 self.write("'");
8521 }
8522
8523 if let Some(ref on_cluster) = ct.on_cluster {
8525 self.write_space();
8526 self.generate_on_cluster(on_cluster)?;
8527 }
8528
8529 if matches!(
8531 self.config.dialect,
8532 Some(crate::dialects::DialectType::Teradata)
8533 ) && !ct.teradata_post_name_options.is_empty()
8534 {
8535 for opt in &ct.teradata_post_name_options {
8536 self.write(", ");
8537 self.write(opt);
8538 }
8539 }
8540
8541 if ct.copy_grants {
8543 self.write_space();
8544 self.write_keyword("COPY GRANTS");
8545 }
8546
8547 if let Some(ref using_template) = ct.using_template {
8549 self.write_space();
8550 self.write_keyword("USING TEMPLATE");
8551 self.write_space();
8552 self.generate_expression(using_template)?;
8553 return Ok(());
8554 }
8555
8556 if is_clickhouse {
8560 if let Some(ref clone_source) = ct.clone_source {
8561 if ct.columns.is_empty() && ct.constraints.is_empty() {
8562 self.write_space();
8563 self.write_keyword("AS");
8564 self.write_space();
8565 self.generate_table(clone_source)?;
8566 }
8567 }
8568 }
8569
8570 if !is_clickhouse {
8572 if let Some(ref clone_source) = ct.clone_source {
8573 self.write_space();
8574 if ct.is_copy && self.config.supports_table_copy {
8575 self.write_keyword("COPY");
8577 } else if ct.shallow_clone {
8578 self.write_keyword("SHALLOW CLONE");
8579 } else if ct.deep_clone {
8580 self.write_keyword("DEEP CLONE");
8581 } else {
8582 self.write_keyword("CLONE");
8583 }
8584 self.write_space();
8585 self.generate_table(clone_source)?;
8586 if let Some(ref at_clause) = ct.clone_at_clause {
8588 self.write_space();
8589 self.generate_expression(at_clause)?;
8590 }
8591 return Ok(());
8592 }
8593 }
8594
8595 if let Some(ref partition_of) = ct.partition_of {
8599 self.write_space();
8600
8601 if let Expression::PartitionedOfProperty(ref pop) = partition_of {
8603 self.write_keyword("PARTITION OF");
8605 self.write_space();
8606 self.generate_expression(&pop.this)?;
8607
8608 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
8610 self.write(" (");
8611 let mut first = true;
8612 for col in &ct.columns {
8613 if !first {
8614 self.write(", ");
8615 }
8616 first = false;
8617 self.generate_column_def(col)?;
8618 }
8619 for constraint in &ct.constraints {
8620 if !first {
8621 self.write(", ");
8622 }
8623 first = false;
8624 self.generate_table_constraint(constraint)?;
8625 }
8626 self.write(")");
8627 }
8628
8629 if let Expression::PartitionBoundSpec(_) = pop.expression.as_ref() {
8631 self.write_space();
8632 self.write_keyword("FOR VALUES");
8633 self.write_space();
8634 self.generate_expression(&pop.expression)?;
8635 } else {
8636 self.write_space();
8637 self.write_keyword("DEFAULT");
8638 }
8639 } else {
8640 self.generate_expression(partition_of)?;
8642
8643 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
8645 self.write(" (");
8646 let mut first = true;
8647 for col in &ct.columns {
8648 if !first {
8649 self.write(", ");
8650 }
8651 first = false;
8652 self.generate_column_def(col)?;
8653 }
8654 for constraint in &ct.constraints {
8655 if !first {
8656 self.write(", ");
8657 }
8658 first = false;
8659 self.generate_table_constraint(constraint)?;
8660 }
8661 self.write(")");
8662 }
8663 }
8664
8665 for prop in &ct.properties {
8667 self.write_space();
8668 self.generate_expression(prop)?;
8669 }
8670
8671 return Ok(());
8672 }
8673
8674 self.sqlite_inline_pk_columns.clear();
8677 if matches!(
8678 self.config.dialect,
8679 Some(crate::dialects::DialectType::SQLite)
8680 ) {
8681 for constraint in &ct.constraints {
8682 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
8683 if columns.len() == 1 && name.is_none() {
8685 let pk_col_name = columns[0].name.to_ascii_lowercase();
8686 if ct
8688 .columns
8689 .iter()
8690 .any(|c| c.name.name.to_ascii_lowercase() == pk_col_name)
8691 {
8692 self.sqlite_inline_pk_columns.insert(pk_col_name);
8693 }
8694 }
8695 }
8696 }
8697 }
8698
8699 if !ct.columns.is_empty() {
8701 if self.config.pretty {
8702 self.write(" (");
8704 self.write_newline();
8705 self.indent_level += 1;
8706 for (i, col) in ct.columns.iter().enumerate() {
8707 if i > 0 {
8708 self.write(",");
8709 self.write_newline();
8710 }
8711 self.write_indent();
8712 self.generate_column_def(col)?;
8713 }
8714 for constraint in &ct.constraints {
8716 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
8718 if columns.len() == 1
8719 && name.is_none()
8720 && self
8721 .sqlite_inline_pk_columns
8722 .contains(&columns[0].name.to_ascii_lowercase())
8723 {
8724 continue;
8725 }
8726 }
8727 self.write(",");
8728 self.write_newline();
8729 self.write_indent();
8730 self.generate_table_constraint(constraint)?;
8731 }
8732 self.indent_level -= 1;
8733 self.write_newline();
8734 self.write(")");
8735 } else {
8736 self.write(" (");
8737 for (i, col) in ct.columns.iter().enumerate() {
8738 if i > 0 {
8739 self.write(", ");
8740 }
8741 self.generate_column_def(col)?;
8742 }
8743 let mut first_constraint = true;
8745 for constraint in &ct.constraints {
8746 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
8748 if columns.len() == 1
8749 && name.is_none()
8750 && self
8751 .sqlite_inline_pk_columns
8752 .contains(&columns[0].name.to_ascii_lowercase())
8753 {
8754 continue;
8755 }
8756 }
8757 if first_constraint {
8758 self.write(", ");
8759 first_constraint = false;
8760 } else {
8761 self.write(", ");
8762 }
8763 self.generate_table_constraint(constraint)?;
8764 }
8765 self.write(")");
8766 }
8767 } else if !ct.constraints.is_empty() {
8768 let has_like_only = ct
8770 .constraints
8771 .iter()
8772 .all(|c| matches!(c, TableConstraint::Like { .. }));
8773 let has_tags_only = ct
8774 .constraints
8775 .iter()
8776 .all(|c| matches!(c, TableConstraint::Tags(_)));
8777 let is_pg_like = matches!(
8781 self.config.dialect,
8782 Some(crate::dialects::DialectType::PostgreSQL)
8783 | Some(crate::dialects::DialectType::CockroachDB)
8784 | Some(crate::dialects::DialectType::Materialize)
8785 | Some(crate::dialects::DialectType::RisingWave)
8786 | Some(crate::dialects::DialectType::Redshift)
8787 | Some(crate::dialects::DialectType::Presto)
8788 | Some(crate::dialects::DialectType::Trino)
8789 | Some(crate::dialects::DialectType::Athena)
8790 );
8791 let use_parens = if has_like_only {
8792 is_pg_like
8793 } else {
8794 !has_tags_only
8795 };
8796 if self.config.pretty && use_parens {
8797 self.write(" (");
8798 self.write_newline();
8799 self.indent_level += 1;
8800 for (i, constraint) in ct.constraints.iter().enumerate() {
8801 if i > 0 {
8802 self.write(",");
8803 self.write_newline();
8804 }
8805 self.write_indent();
8806 self.generate_table_constraint(constraint)?;
8807 }
8808 self.indent_level -= 1;
8809 self.write_newline();
8810 self.write(")");
8811 } else {
8812 if use_parens {
8813 self.write(" (");
8814 } else {
8815 self.write_space();
8816 }
8817 for (i, constraint) in ct.constraints.iter().enumerate() {
8818 if i > 0 {
8819 self.write(", ");
8820 }
8821 self.generate_table_constraint(constraint)?;
8822 }
8823 if use_parens {
8824 self.write(")");
8825 }
8826 }
8827 }
8828
8829 if is_clickhouse && (!ct.columns.is_empty() || !ct.constraints.is_empty()) {
8830 if let Some(ref clone_source) = ct.clone_source {
8831 self.write_space();
8832 self.write_keyword("AS");
8833 self.write_space();
8834 self.generate_table(clone_source)?;
8835 }
8836 }
8837
8838 if let Some(ref on_prop) = ct.on_property {
8840 self.write(" ");
8841 self.write_keyword("ON");
8842 self.write(" ");
8843 self.generate_expression(&on_prop.this)?;
8844 }
8845
8846 if !ct.with_partition_columns.is_empty() {
8848 if self.config.pretty {
8849 self.write_newline();
8850 } else {
8851 self.write_space();
8852 }
8853 self.write_keyword("WITH PARTITION COLUMNS");
8854 self.write(" (");
8855 if self.config.pretty {
8856 self.write_newline();
8857 self.indent_level += 1;
8858 for (i, col) in ct.with_partition_columns.iter().enumerate() {
8859 if i > 0 {
8860 self.write(",");
8861 self.write_newline();
8862 }
8863 self.write_indent();
8864 self.generate_column_def(col)?;
8865 }
8866 self.indent_level -= 1;
8867 self.write_newline();
8868 } else {
8869 for (i, col) in ct.with_partition_columns.iter().enumerate() {
8870 if i > 0 {
8871 self.write(", ");
8872 }
8873 self.generate_column_def(col)?;
8874 }
8875 }
8876 self.write(")");
8877 }
8878
8879 if let Some(ref conn) = ct.with_connection {
8881 if self.config.pretty {
8882 self.write_newline();
8883 } else {
8884 self.write_space();
8885 }
8886 self.write_keyword("WITH CONNECTION");
8887 self.write_space();
8888 self.generate_table(conn)?;
8889 }
8890
8891 if !is_clickhouse {
8894 for prop in &ct.properties {
8895 if let Expression::SchemaCommentProperty(_) = prop {
8896 if self.config.pretty {
8897 self.write_newline();
8898 } else {
8899 self.write_space();
8900 }
8901 self.generate_expression(prop)?;
8902 }
8903 }
8904 }
8905
8906 if !ct.with_properties.is_empty() {
8908 let is_snowflake_special_table = matches!(
8910 self.config.dialect,
8911 Some(crate::dialects::DialectType::Snowflake)
8912 ) && (ct.table_modifier.as_deref() == Some("ICEBERG")
8913 || ct.table_modifier.as_deref() == Some("DYNAMIC"));
8914 if is_snowflake_special_table {
8915 for (key, value) in &ct.with_properties {
8916 self.write_space();
8917 self.write(key);
8918 self.write("=");
8919 self.write(value);
8920 }
8921 } else if self.config.pretty {
8922 self.write_newline();
8923 self.write_keyword("WITH");
8924 self.write(" (");
8925 self.write_newline();
8926 self.indent_level += 1;
8927 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
8928 if i > 0 {
8929 self.write(",");
8930 self.write_newline();
8931 }
8932 self.write_indent();
8933 self.write(key);
8934 self.write("=");
8935 self.write(value);
8936 }
8937 self.indent_level -= 1;
8938 self.write_newline();
8939 self.write(")");
8940 } else {
8941 self.write_space();
8942 self.write_keyword("WITH");
8943 self.write(" (");
8944 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
8945 if i > 0 {
8946 self.write(", ");
8947 }
8948 self.write(key);
8949 self.write("=");
8950 self.write(value);
8951 }
8952 self.write(")");
8953 }
8954 }
8955
8956 let (pre_as_properties, post_as_properties): (Vec<&Expression>, Vec<&Expression>) =
8957 if is_clickhouse && ct.as_select.is_some() {
8958 let mut pre = Vec::new();
8959 let mut post = Vec::new();
8960 for prop in &ct.properties {
8961 if matches!(prop, Expression::SchemaCommentProperty(_)) {
8962 post.push(prop);
8963 } else {
8964 pre.push(prop);
8965 }
8966 }
8967 (pre, post)
8968 } else {
8969 (ct.properties.iter().collect(), Vec::new())
8970 };
8971
8972 for prop in pre_as_properties {
8974 if !is_clickhouse && matches!(prop, Expression::SchemaCommentProperty(_)) {
8976 continue;
8977 }
8978 if self.config.pretty {
8979 self.write_newline();
8980 } else {
8981 self.write_space();
8982 }
8983 if let Expression::Properties(props) = prop {
8987 let is_hive_dialect = matches!(
8988 self.config.dialect,
8989 Some(crate::dialects::DialectType::Hive)
8990 | Some(crate::dialects::DialectType::Spark)
8991 | Some(crate::dialects::DialectType::Databricks)
8992 | Some(crate::dialects::DialectType::Athena)
8993 );
8994 let is_doris_starrocks = matches!(
8995 self.config.dialect,
8996 Some(crate::dialects::DialectType::Doris)
8997 | Some(crate::dialects::DialectType::StarRocks)
8998 );
8999 if is_hive_dialect {
9000 self.generate_tblproperties_clause(&props.expressions)?;
9001 } else if is_doris_starrocks {
9002 self.generate_properties_clause(&props.expressions)?;
9003 } else {
9004 self.generate_options_clause(&props.expressions)?;
9005 }
9006 } else {
9007 self.generate_expression(prop)?;
9008 }
9009 }
9010
9011 for prop in &ct.post_table_properties {
9013 if let Expression::WithSystemVersioningProperty(ref svp) = prop {
9014 self.write(" WITH(");
9015 self.generate_system_versioning_content(svp)?;
9016 self.write(")");
9017 } else if let Expression::Properties(props) = prop {
9018 let is_doris_starrocks = matches!(
9020 self.config.dialect,
9021 Some(crate::dialects::DialectType::Doris)
9022 | Some(crate::dialects::DialectType::StarRocks)
9023 );
9024 self.write_space();
9025 if is_doris_starrocks {
9026 self.generate_properties_clause(&props.expressions)?;
9027 } else {
9028 self.generate_options_clause(&props.expressions)?;
9029 }
9030 } else {
9031 self.write_space();
9032 self.generate_expression(prop)?;
9033 }
9034 }
9035
9036 if let Some(ref rollup) = ct.rollup {
9039 if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
9040 self.write_space();
9041 self.generate_rollup_property(rollup)?;
9042 }
9043 }
9044
9045 let is_mysql_compatible = matches!(
9049 self.config.dialect,
9050 Some(DialectType::MySQL)
9051 | Some(DialectType::TiDB)
9052 | Some(DialectType::SingleStore)
9053 | Some(DialectType::Doris)
9054 | Some(DialectType::StarRocks)
9055 | None
9056 );
9057 let is_hive_compatible = matches!(
9058 self.config.dialect,
9059 Some(DialectType::Hive)
9060 | Some(DialectType::Spark)
9061 | Some(DialectType::Databricks)
9062 | Some(DialectType::Athena)
9063 );
9064 let mysql_pretty_options =
9065 self.config.pretty && matches!(self.config.dialect, Some(DialectType::MySQL));
9066 for (key, value) in &ct.mysql_table_options {
9067 let should_output = if is_mysql_compatible {
9069 true
9070 } else if is_hive_compatible && key == "COMMENT" {
9071 true } else {
9073 false
9074 };
9075 if should_output {
9076 if mysql_pretty_options {
9077 self.write_newline();
9078 self.write_indent();
9079 } else {
9080 self.write_space();
9081 }
9082 self.write_keyword(key);
9083 if key == "COMMENT" && !self.config.schema_comment_with_eq {
9085 self.write_space();
9086 } else {
9087 self.write("=");
9088 }
9089 self.write(value);
9090 }
9091 }
9092
9093 for option in &ct.tidb_table_options {
9094 if self.config.pretty {
9095 self.write_newline();
9096 self.write_indent();
9097 } else {
9098 self.write_space();
9099 }
9100 self.generate_tidb_table_option(option, false)?;
9101 }
9102
9103 if ct.temporary
9105 && matches!(
9106 self.config.dialect,
9107 Some(DialectType::Spark) | Some(DialectType::Databricks)
9108 )
9109 && ct.as_select.is_none()
9110 {
9111 self.write_space();
9112 self.write_keyword("USING PARQUET");
9113 }
9114
9115 if !ct.inherits.is_empty() {
9117 self.write_space();
9118 self.write_keyword("INHERITS");
9119 self.write(" (");
9120 for (i, parent) in ct.inherits.iter().enumerate() {
9121 if i > 0 {
9122 self.write(", ");
9123 }
9124 self.generate_table(parent)?;
9125 }
9126 self.write(")");
9127 }
9128
9129 if let Some(ref query) = ct.as_select {
9131 self.write_space();
9132 self.write_keyword("AS");
9133 self.write_space();
9134 let source_is_clickhouse =
9135 matches!(self.config.source_dialect, Some(DialectType::ClickHouse));
9136 let wrap_as_select =
9137 ct.as_select_parenthesized && !(is_clickhouse && source_is_clickhouse);
9138 if wrap_as_select {
9139 self.write("(");
9140 }
9141 self.generate_expression(query)?;
9142 if wrap_as_select {
9143 self.write(")");
9144 }
9145
9146 if let Some(with_data) = ct.with_data {
9148 self.write_space();
9149 self.write_keyword("WITH");
9150 if !with_data {
9151 self.write_space();
9152 self.write_keyword("NO");
9153 }
9154 self.write_space();
9155 self.write_keyword("DATA");
9156 }
9157
9158 if let Some(with_statistics) = ct.with_statistics {
9160 self.write_space();
9161 self.write_keyword("AND");
9162 if !with_statistics {
9163 self.write_space();
9164 self.write_keyword("NO");
9165 }
9166 self.write_space();
9167 self.write_keyword("STATISTICS");
9168 }
9169
9170 for index in &ct.teradata_indexes {
9172 self.write_space();
9173 match index.kind {
9174 TeradataIndexKind::NoPrimary => {
9175 self.write_keyword("NO PRIMARY INDEX");
9176 }
9177 TeradataIndexKind::Primary => {
9178 self.write_keyword("PRIMARY INDEX");
9179 }
9180 TeradataIndexKind::PrimaryAmp => {
9181 self.write_keyword("PRIMARY AMP INDEX");
9182 }
9183 TeradataIndexKind::Unique => {
9184 self.write_keyword("UNIQUE INDEX");
9185 }
9186 TeradataIndexKind::UniquePrimary => {
9187 self.write_keyword("UNIQUE PRIMARY INDEX");
9188 }
9189 TeradataIndexKind::Secondary => {
9190 self.write_keyword("INDEX");
9191 }
9192 }
9193 if let Some(ref name) = index.name {
9195 self.write_space();
9196 self.write(name);
9197 }
9198 if !index.columns.is_empty() {
9200 self.write(" (");
9201 for (i, col) in index.columns.iter().enumerate() {
9202 if i > 0 {
9203 self.write(", ");
9204 }
9205 self.write(col);
9206 }
9207 self.write(")");
9208 }
9209 }
9210
9211 if let Some(ref on_commit) = ct.on_commit {
9213 self.write_space();
9214 self.write_keyword("ON COMMIT");
9215 self.write_space();
9216 match on_commit {
9217 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
9218 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
9219 }
9220 }
9221
9222 if !post_as_properties.is_empty() {
9223 for prop in post_as_properties {
9224 self.write_space();
9225 self.generate_expression(prop)?;
9226 }
9227 }
9228
9229 self.athena_hive_context = saved_athena_hive_context;
9231 return Ok(());
9232 }
9233
9234 if let Some(ref on_commit) = ct.on_commit {
9236 self.write_space();
9237 self.write_keyword("ON COMMIT");
9238 self.write_space();
9239 match on_commit {
9240 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
9241 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
9242 }
9243 }
9244
9245 self.athena_hive_context = saved_athena_hive_context;
9247
9248 Ok(())
9249 }
9250
9251 fn generate_column_def_expr(&mut self, col: &ColumnDef) -> Result<()> {
9254 self.generate_identifier(&col.name)?;
9256 if !matches!(col.data_type, DataType::Unknown) {
9258 self.write_space();
9259 self.generate_data_type(&col.data_type)?;
9260 }
9261 for constraint in &col.constraints {
9263 if let ColumnConstraint::Path(path_expr) = constraint {
9264 self.write_space();
9265 self.write_keyword("PATH");
9266 self.write_space();
9267 self.generate_expression(path_expr)?;
9268 }
9269 }
9270 Ok(())
9271 }
9272
9273 fn generate_column_def(&mut self, col: &ColumnDef) -> Result<()> {
9274 let has_computed_no_type = matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
9276 && col
9277 .constraints
9278 .iter()
9279 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
9280 let omit_computed_type = !self.config.computed_column_with_type
9282 && col
9283 .constraints
9284 .iter()
9285 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
9286
9287 let is_partition_column_spec = matches!(col.data_type, DataType::Unknown);
9290
9291 let has_no_type = col.no_type
9294 || (matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
9295 && col.constraints.is_empty());
9296
9297 self.generate_identifier(&col.name)?;
9298
9299 let serial_expansion = if matches!(
9301 self.config.dialect,
9302 Some(DialectType::Materialize) | Some(DialectType::PostgreSQL)
9303 ) {
9304 if let DataType::Custom { ref name } = col.data_type {
9305 if name.eq_ignore_ascii_case("SERIAL") {
9306 Some("INT")
9307 } else if name.eq_ignore_ascii_case("BIGSERIAL") {
9308 Some("BIGINT")
9309 } else if name.eq_ignore_ascii_case("SMALLSERIAL") {
9310 Some("SMALLINT")
9311 } else {
9312 None
9313 }
9314 } else {
9315 None
9316 }
9317 } else {
9318 None
9319 };
9320
9321 if !has_computed_no_type && !omit_computed_type && !is_partition_column_spec && !has_no_type
9322 {
9323 self.write_space();
9324 let saved_nullable_depth = self.clickhouse_nullable_depth;
9327 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
9328 self.clickhouse_nullable_depth = -1;
9329 }
9330 if let Some(int_type) = serial_expansion {
9331 self.write_keyword(int_type);
9333 } else if col.unsigned && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
9334 let unsigned_type = match &col.data_type {
9336 DataType::Int { .. } => Some("UINTEGER"),
9337 DataType::BigInt { .. } => Some("UBIGINT"),
9338 DataType::SmallInt { .. } => Some("USMALLINT"),
9339 DataType::TinyInt { .. } => Some("UTINYINT"),
9340 _ => None,
9341 };
9342 if let Some(utype) = unsigned_type {
9343 self.write_keyword(utype);
9344 } else {
9345 self.generate_data_type(&col.data_type)?;
9346 }
9347 } else {
9348 self.generate_data_type(&col.data_type)?;
9349 }
9350 self.clickhouse_nullable_depth = saved_nullable_depth;
9351 }
9352
9353 if col.unsigned && !matches!(self.config.dialect, Some(DialectType::DuckDB)) {
9356 self.write_space();
9357 self.write_keyword("UNSIGNED");
9358 }
9359 if col.zerofill {
9360 self.write_space();
9361 self.write_keyword("ZEROFILL");
9362 }
9363
9364 if let Some(ref charset) = col.character_set {
9368 self.write_space();
9369 self.write_keyword("CHARACTER SET");
9370 self.write_space();
9371 self.write(charset);
9372 }
9373
9374 if col.uppercase {
9375 self.write_space();
9376 self.write_keyword("UPPERCASE");
9377 }
9378
9379 if let Some(casespecific) = col.casespecific {
9380 self.write_space();
9381 if casespecific {
9382 self.write_keyword("CASESPECIFIC");
9383 } else {
9384 self.write_keyword("NOT CASESPECIFIC");
9385 }
9386 }
9387
9388 if let Some(ref format) = col.format {
9389 self.write_space();
9390 self.write_keyword("FORMAT");
9391 self.write(" '");
9392 self.write(format);
9393 self.write("'");
9394 }
9395
9396 if let Some(ref title) = col.title {
9397 self.write_space();
9398 self.write_keyword("TITLE");
9399 self.write(" '");
9400 self.write(title);
9401 self.write("'");
9402 }
9403
9404 if let Some(length) = col.inline_length {
9405 self.write_space();
9406 self.write_keyword("INLINE LENGTH");
9407 self.write(" ");
9408 self.write(&length.to_string());
9409 }
9410
9411 if let Some(ref compress) = col.compress {
9412 self.write_space();
9413 self.write_keyword("COMPRESS");
9414 if !compress.is_empty() {
9415 if compress.len() == 1 {
9417 if let Expression::Literal(lit) = &compress[0] {
9418 if let Literal::String(_) = lit.as_ref() {
9419 self.write_space();
9420 self.generate_expression(&compress[0])?;
9421 }
9422 } else {
9423 self.write(" (");
9424 self.generate_expression(&compress[0])?;
9425 self.write(")");
9426 }
9427 } else {
9428 self.write(" (");
9429 for (i, val) in compress.iter().enumerate() {
9430 if i > 0 {
9431 self.write(", ");
9432 }
9433 self.generate_expression(val)?;
9434 }
9435 self.write(")");
9436 }
9437 }
9438 }
9439
9440 if !col.constraint_order.is_empty() {
9443 let mut references_idx = 0;
9446 let mut check_idx = 0;
9447 let mut generated_idx = 0;
9448 let mut collate_idx = 0;
9449 let mut comment_idx = 0;
9450 let defer_not_null_after_identity = false;
9453 let mut pending_not_null_after_identity = false;
9454
9455 for constraint_type in &col.constraint_order {
9456 match constraint_type {
9457 ConstraintType::PrimaryKey => {
9458 if col.primary_key
9460 && !matches!(self.config.dialect, Some(DialectType::Materialize))
9461 {
9462 if let Some(ref cname) = col.primary_key_constraint_name {
9463 self.write_space();
9464 self.write_keyword("CONSTRAINT");
9465 self.write_space();
9466 self.write(cname);
9467 }
9468 self.write_space();
9469 self.write_keyword("PRIMARY KEY");
9470 if let Some(ref order) = col.primary_key_order {
9471 self.write_space();
9472 match order {
9473 SortOrder::Asc => self.write_keyword("ASC"),
9474 SortOrder::Desc => self.write_keyword("DESC"),
9475 }
9476 }
9477 }
9478 }
9479 ConstraintType::Unique => {
9480 if col.unique {
9481 if let Some(ref cname) = col.unique_constraint_name {
9482 self.write_space();
9483 self.write_keyword("CONSTRAINT");
9484 self.write_space();
9485 self.write(cname);
9486 }
9487 self.write_space();
9488 self.write_keyword("UNIQUE");
9489 if col.unique_nulls_not_distinct {
9491 self.write(" NULLS NOT DISTINCT");
9492 }
9493 }
9494 }
9495 ConstraintType::NotNull => {
9496 if col.nullable == Some(false) {
9497 if defer_not_null_after_identity {
9498 pending_not_null_after_identity = true;
9499 continue;
9500 }
9501 if let Some(ref cname) = col.not_null_constraint_name {
9502 self.write_space();
9503 self.write_keyword("CONSTRAINT");
9504 self.write_space();
9505 self.write(cname);
9506 }
9507 self.write_space();
9508 self.write_keyword("NOT NULL");
9509 }
9510 }
9511 ConstraintType::Null => {
9512 if col.nullable == Some(true) {
9513 self.write_space();
9514 self.write_keyword("NULL");
9515 }
9516 }
9517 ConstraintType::Default => {
9518 if let Some(ref default) = col.default {
9519 self.write_space();
9520 self.write_keyword("DEFAULT");
9521 self.write_space();
9522 self.generate_expression(default)?;
9523 }
9524 }
9525 ConstraintType::AutoIncrement => {
9526 if col.auto_increment {
9527 if matches!(
9529 self.config.dialect,
9530 Some(crate::dialects::DialectType::DuckDB)
9531 ) {
9532 } else if matches!(
9534 self.config.dialect,
9535 Some(crate::dialects::DialectType::Materialize)
9536 ) {
9537 if !matches!(col.nullable, Some(false)) {
9539 self.write_space();
9540 self.write_keyword("NOT NULL");
9541 }
9542 } else if matches!(
9543 self.config.dialect,
9544 Some(crate::dialects::DialectType::PostgreSQL)
9545 ) {
9546 self.write_space();
9548 self.generate_auto_increment_keyword(col)?;
9549 } else if matches!(
9550 self.config.dialect,
9551 Some(crate::dialects::DialectType::SQLite)
9552 ) && !col.primary_key
9553 && self
9554 .sqlite_inline_pk_columns
9555 .contains(&col.name.name.to_ascii_lowercase())
9556 {
9557 } else {
9560 self.write_space();
9561 self.generate_auto_increment_keyword(col)?;
9562 if pending_not_null_after_identity {
9563 self.write_space();
9564 self.write_keyword("NOT NULL");
9565 pending_not_null_after_identity = false;
9566 }
9567 }
9568 } }
9570 ConstraintType::AutoRandom => {
9571 if let Some(ref auto_random) = col.auto_random {
9572 self.write_space();
9573 self.generate_tidb_auto_random(auto_random)?;
9574 }
9575 }
9576 ConstraintType::References => {
9577 while references_idx < col.constraints.len() {
9579 if let ColumnConstraint::References(fk_ref) =
9580 &col.constraints[references_idx]
9581 {
9582 if let Some(ref name) = fk_ref.constraint_name {
9584 self.write_space();
9585 self.write_keyword("CONSTRAINT");
9586 self.write_space();
9587 self.write(name);
9588 }
9589 self.write_space();
9590 if fk_ref.has_foreign_key_keywords {
9591 self.write_keyword("FOREIGN KEY");
9592 self.write_space();
9593 }
9594 self.write_keyword("REFERENCES");
9595 self.write_space();
9596 self.generate_table(&fk_ref.table)?;
9597 if !fk_ref.columns.is_empty() {
9598 self.write(" (");
9599 for (i, c) in fk_ref.columns.iter().enumerate() {
9600 if i > 0 {
9601 self.write(", ");
9602 }
9603 self.generate_identifier(c)?;
9604 }
9605 self.write(")");
9606 }
9607 self.generate_referential_actions(fk_ref)?;
9608 references_idx += 1;
9609 break;
9610 }
9611 references_idx += 1;
9612 }
9613 }
9614 ConstraintType::Check => {
9615 while check_idx < col.constraints.len() {
9617 if let ColumnConstraint::Check(expr) = &col.constraints[check_idx] {
9618 if check_idx == 0 {
9620 if let Some(ref cname) = col.check_constraint_name {
9621 self.write_space();
9622 self.write_keyword("CONSTRAINT");
9623 self.write_space();
9624 self.write(cname);
9625 }
9626 }
9627 self.write_space();
9628 self.write_keyword("CHECK");
9629 self.write(" (");
9630 self.generate_expression(expr)?;
9631 self.write(")");
9632 check_idx += 1;
9633 break;
9634 }
9635 check_idx += 1;
9636 }
9637 }
9638 ConstraintType::GeneratedAsIdentity => {
9639 while generated_idx < col.constraints.len() {
9641 if let ColumnConstraint::GeneratedAsIdentity(gen) =
9642 &col.constraints[generated_idx]
9643 {
9644 self.write_space();
9645 if matches!(
9647 self.config.dialect,
9648 Some(crate::dialects::DialectType::Redshift)
9649 ) {
9650 self.write_keyword("IDENTITY");
9651 self.write("(");
9652 if let Some(ref start) = gen.start {
9653 self.generate_expression(start)?;
9654 } else {
9655 self.write("0");
9656 }
9657 self.write(", ");
9658 if let Some(ref incr) = gen.increment {
9659 self.generate_expression(incr)?;
9660 } else {
9661 self.write("1");
9662 }
9663 self.write(")");
9664 } else {
9665 self.write_keyword("GENERATED");
9666 if gen.always {
9667 self.write_space();
9668 self.write_keyword("ALWAYS");
9669 } else {
9670 self.write_space();
9671 self.write_keyword("BY DEFAULT");
9672 if gen.on_null {
9673 self.write_space();
9674 self.write_keyword("ON NULL");
9675 }
9676 }
9677 self.write_space();
9678 self.write_keyword("AS IDENTITY");
9679
9680 let has_options = gen.start.is_some()
9681 || gen.increment.is_some()
9682 || gen.minvalue.is_some()
9683 || gen.maxvalue.is_some()
9684 || gen.cycle.is_some();
9685 if has_options {
9686 self.write(" (");
9687 let mut first = true;
9688 if let Some(ref start) = gen.start {
9689 if !first {
9690 self.write(" ");
9691 }
9692 first = false;
9693 self.write_keyword("START WITH");
9694 self.write_space();
9695 self.generate_expression(start)?;
9696 }
9697 if let Some(ref incr) = gen.increment {
9698 if !first {
9699 self.write(" ");
9700 }
9701 first = false;
9702 self.write_keyword("INCREMENT BY");
9703 self.write_space();
9704 self.generate_expression(incr)?;
9705 }
9706 if let Some(ref minv) = gen.minvalue {
9707 if !first {
9708 self.write(" ");
9709 }
9710 first = false;
9711 self.write_keyword("MINVALUE");
9712 self.write_space();
9713 self.generate_expression(minv)?;
9714 }
9715 if let Some(ref maxv) = gen.maxvalue {
9716 if !first {
9717 self.write(" ");
9718 }
9719 first = false;
9720 self.write_keyword("MAXVALUE");
9721 self.write_space();
9722 self.generate_expression(maxv)?;
9723 }
9724 if let Some(cycle) = gen.cycle {
9725 if !first {
9726 self.write(" ");
9727 }
9728 if cycle {
9729 self.write_keyword("CYCLE");
9730 } else {
9731 self.write_keyword("NO CYCLE");
9732 }
9733 }
9734 self.write(")");
9735 }
9736 }
9737 generated_idx += 1;
9738 break;
9739 }
9740 generated_idx += 1;
9741 }
9742 }
9743 ConstraintType::Collate => {
9744 while collate_idx < col.constraints.len() {
9746 if let ColumnConstraint::Collate(collation) =
9747 &col.constraints[collate_idx]
9748 {
9749 self.write_space();
9750 self.write_keyword("COLLATE");
9751 self.write_space();
9752 self.generate_identifier(collation)?;
9753 collate_idx += 1;
9754 break;
9755 }
9756 collate_idx += 1;
9757 }
9758 }
9759 ConstraintType::Comment => {
9760 while comment_idx < col.constraints.len() {
9762 if let ColumnConstraint::Comment(comment) =
9763 &col.constraints[comment_idx]
9764 {
9765 self.write_space();
9766 self.write_keyword("COMMENT");
9767 self.write_space();
9768 self.generate_string_literal(comment)?;
9769 comment_idx += 1;
9770 break;
9771 }
9772 comment_idx += 1;
9773 }
9774 }
9775 ConstraintType::Tags => {
9776 for constraint in &col.constraints {
9778 if let ColumnConstraint::Tags(tags) = constraint {
9779 self.write_space();
9780 self.write_keyword("TAG");
9781 self.write(" (");
9782 for (i, expr) in tags.expressions.iter().enumerate() {
9783 if i > 0 {
9784 self.write(", ");
9785 }
9786 self.generate_expression(expr)?;
9787 }
9788 self.write(")");
9789 break;
9790 }
9791 }
9792 }
9793 ConstraintType::ComputedColumn => {
9794 for constraint in &col.constraints {
9796 if let ColumnConstraint::ComputedColumn(cc) = constraint {
9797 self.write_space();
9798 self.generate_computed_column_inline(cc)?;
9799 break;
9800 }
9801 }
9802 }
9803 ConstraintType::GeneratedAsRow => {
9804 for constraint in &col.constraints {
9806 if let ColumnConstraint::GeneratedAsRow(gar) = constraint {
9807 self.write_space();
9808 self.generate_generated_as_row_inline(gar)?;
9809 break;
9810 }
9811 }
9812 }
9813 ConstraintType::OnUpdate => {
9814 if let Some(ref expr) = col.on_update {
9815 self.write_space();
9816 self.write_keyword("ON UPDATE");
9817 self.write_space();
9818 self.generate_expression(expr)?;
9819 }
9820 }
9821 ConstraintType::Encode => {
9822 if let Some(ref encoding) = col.encoding {
9823 self.write_space();
9824 self.write_keyword("ENCODE");
9825 self.write_space();
9826 self.write(encoding);
9827 }
9828 }
9829 ConstraintType::Path => {
9830 for constraint in &col.constraints {
9832 if let ColumnConstraint::Path(path_expr) = constraint {
9833 self.write_space();
9834 self.write_keyword("PATH");
9835 self.write_space();
9836 self.generate_expression(path_expr)?;
9837 break;
9838 }
9839 }
9840 }
9841 }
9842 }
9843 if pending_not_null_after_identity {
9844 self.write_space();
9845 self.write_keyword("NOT NULL");
9846 }
9847 } else {
9848 if col.primary_key {
9850 self.write_space();
9851 self.write_keyword("PRIMARY KEY");
9852 if let Some(ref order) = col.primary_key_order {
9853 self.write_space();
9854 match order {
9855 SortOrder::Asc => self.write_keyword("ASC"),
9856 SortOrder::Desc => self.write_keyword("DESC"),
9857 }
9858 }
9859 }
9860
9861 if col.unique {
9862 self.write_space();
9863 self.write_keyword("UNIQUE");
9864 if col.unique_nulls_not_distinct {
9866 self.write(" NULLS NOT DISTINCT");
9867 }
9868 }
9869
9870 match col.nullable {
9871 Some(false) => {
9872 self.write_space();
9873 self.write_keyword("NOT NULL");
9874 }
9875 Some(true) => {
9876 self.write_space();
9877 self.write_keyword("NULL");
9878 }
9879 None => {}
9880 }
9881
9882 if let Some(ref default) = col.default {
9883 self.write_space();
9884 self.write_keyword("DEFAULT");
9885 self.write_space();
9886 self.generate_expression(default)?;
9887 }
9888
9889 if col.auto_increment {
9890 self.write_space();
9891 self.generate_auto_increment_keyword(col)?;
9892 }
9893
9894 if let Some(ref auto_random) = col.auto_random {
9895 self.write_space();
9896 self.generate_tidb_auto_random(auto_random)?;
9897 }
9898
9899 for constraint in &col.constraints {
9901 match constraint {
9902 ColumnConstraint::References(fk_ref) => {
9903 self.write_space();
9904 if fk_ref.has_foreign_key_keywords {
9905 self.write_keyword("FOREIGN KEY");
9906 self.write_space();
9907 }
9908 self.write_keyword("REFERENCES");
9909 self.write_space();
9910 self.generate_table(&fk_ref.table)?;
9911 if !fk_ref.columns.is_empty() {
9912 self.write(" (");
9913 for (i, c) in fk_ref.columns.iter().enumerate() {
9914 if i > 0 {
9915 self.write(", ");
9916 }
9917 self.generate_identifier(c)?;
9918 }
9919 self.write(")");
9920 }
9921 self.generate_referential_actions(fk_ref)?;
9922 }
9923 ColumnConstraint::Check(expr) => {
9924 self.write_space();
9925 self.write_keyword("CHECK");
9926 self.write(" (");
9927 self.generate_expression(expr)?;
9928 self.write(")");
9929 }
9930 ColumnConstraint::GeneratedAsIdentity(gen) => {
9931 self.write_space();
9932 if matches!(
9934 self.config.dialect,
9935 Some(crate::dialects::DialectType::Redshift)
9936 ) {
9937 self.write_keyword("IDENTITY");
9938 self.write("(");
9939 if let Some(ref start) = gen.start {
9940 self.generate_expression(start)?;
9941 } else {
9942 self.write("0");
9943 }
9944 self.write(", ");
9945 if let Some(ref incr) = gen.increment {
9946 self.generate_expression(incr)?;
9947 } else {
9948 self.write("1");
9949 }
9950 self.write(")");
9951 } else {
9952 self.write_keyword("GENERATED");
9953 if gen.always {
9954 self.write_space();
9955 self.write_keyword("ALWAYS");
9956 } else {
9957 self.write_space();
9958 self.write_keyword("BY DEFAULT");
9959 if gen.on_null {
9960 self.write_space();
9961 self.write_keyword("ON NULL");
9962 }
9963 }
9964 self.write_space();
9965 self.write_keyword("AS IDENTITY");
9966
9967 let has_options = gen.start.is_some()
9968 || gen.increment.is_some()
9969 || gen.minvalue.is_some()
9970 || gen.maxvalue.is_some()
9971 || gen.cycle.is_some();
9972 if has_options {
9973 self.write(" (");
9974 let mut first = true;
9975 if let Some(ref start) = gen.start {
9976 if !first {
9977 self.write(" ");
9978 }
9979 first = false;
9980 self.write_keyword("START WITH");
9981 self.write_space();
9982 self.generate_expression(start)?;
9983 }
9984 if let Some(ref incr) = gen.increment {
9985 if !first {
9986 self.write(" ");
9987 }
9988 first = false;
9989 self.write_keyword("INCREMENT BY");
9990 self.write_space();
9991 self.generate_expression(incr)?;
9992 }
9993 if let Some(ref minv) = gen.minvalue {
9994 if !first {
9995 self.write(" ");
9996 }
9997 first = false;
9998 self.write_keyword("MINVALUE");
9999 self.write_space();
10000 self.generate_expression(minv)?;
10001 }
10002 if let Some(ref maxv) = gen.maxvalue {
10003 if !first {
10004 self.write(" ");
10005 }
10006 first = false;
10007 self.write_keyword("MAXVALUE");
10008 self.write_space();
10009 self.generate_expression(maxv)?;
10010 }
10011 if let Some(cycle) = gen.cycle {
10012 if !first {
10013 self.write(" ");
10014 }
10015 if cycle {
10016 self.write_keyword("CYCLE");
10017 } else {
10018 self.write_keyword("NO CYCLE");
10019 }
10020 }
10021 self.write(")");
10022 }
10023 }
10024 }
10025 ColumnConstraint::Collate(collation) => {
10026 self.write_space();
10027 self.write_keyword("COLLATE");
10028 self.write_space();
10029 self.generate_identifier(collation)?;
10030 }
10031 ColumnConstraint::Comment(comment) => {
10032 self.write_space();
10033 self.write_keyword("COMMENT");
10034 self.write_space();
10035 self.generate_string_literal(comment)?;
10036 }
10037 ColumnConstraint::Path(path_expr) => {
10038 self.write_space();
10039 self.write_keyword("PATH");
10040 self.write_space();
10041 self.generate_expression(path_expr)?;
10042 }
10043 _ => {} }
10045 }
10046
10047 if let Some(ref encoding) = col.encoding {
10049 self.write_space();
10050 self.write_keyword("ENCODE");
10051 self.write_space();
10052 self.write(encoding);
10053 }
10054 }
10055
10056 if let Some(ref codec) = col.codec {
10058 self.write_space();
10059 self.write_keyword("CODEC");
10060 self.write("(");
10061 self.write(codec);
10062 self.write(")");
10063 }
10064
10065 if let Some(visible) = col.visible {
10066 self.write_space();
10067 if visible {
10068 self.write_keyword("VISIBLE");
10069 } else {
10070 self.write_keyword("INVISIBLE");
10071 }
10072 }
10073
10074 if let Some(ref ephemeral) = col.ephemeral {
10076 self.write_space();
10077 self.write_keyword("EPHEMERAL");
10078 if let Some(ref expr) = ephemeral {
10079 self.write_space();
10080 self.generate_expression(expr)?;
10081 }
10082 }
10083
10084 if let Some(ref mat_expr) = col.materialized_expr {
10086 self.write_space();
10087 self.write_keyword("MATERIALIZED");
10088 self.write_space();
10089 self.generate_expression(mat_expr)?;
10090 }
10091
10092 if let Some(ref alias_expr) = col.alias_expr {
10094 self.write_space();
10095 self.write_keyword("ALIAS");
10096 self.write_space();
10097 self.generate_expression(alias_expr)?;
10098 }
10099
10100 if let Some(ref ttl_expr) = col.ttl_expr {
10102 self.write_space();
10103 self.write_keyword("TTL");
10104 self.write_space();
10105 self.generate_expression(ttl_expr)?;
10106 }
10107
10108 if col.not_for_replication
10110 && matches!(
10111 self.config.dialect,
10112 Some(crate::dialects::DialectType::TSQL)
10113 | Some(crate::dialects::DialectType::Fabric)
10114 )
10115 {
10116 self.write_space();
10117 self.write_keyword("NOT FOR REPLICATION");
10118 }
10119
10120 if !col.options.is_empty() {
10122 self.write_space();
10123 self.generate_options_clause(&col.options)?;
10124 }
10125
10126 if !col.primary_key
10129 && self
10130 .sqlite_inline_pk_columns
10131 .contains(&col.name.name.to_ascii_lowercase())
10132 {
10133 self.write_space();
10134 self.write_keyword("PRIMARY KEY");
10135 if matches!(self.config.dialect, Some(DialectType::SQLite)) && col.auto_increment {
10136 self.write_space();
10137 self.generate_auto_increment_keyword(col)?;
10138 }
10139 }
10140
10141 if serial_expansion.is_some() {
10144 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
10145 self.write_space();
10146 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY NOT NULL");
10147 } else if matches!(self.config.dialect, Some(DialectType::Materialize)) {
10148 self.write_space();
10149 self.write_keyword("NOT NULL");
10150 }
10151 }
10152
10153 Ok(())
10154 }
10155
10156 fn generate_table_constraint(&mut self, constraint: &TableConstraint) -> Result<()> {
10157 match constraint {
10158 TableConstraint::PrimaryKey {
10159 name,
10160 columns,
10161 include_columns,
10162 modifiers,
10163 has_constraint_keyword,
10164 } => {
10165 if let Some(ref n) = name {
10166 if *has_constraint_keyword {
10167 self.write_keyword("CONSTRAINT");
10168 self.write_space();
10169 self.generate_identifier(n)?;
10170 self.write_space();
10171 }
10172 }
10173 self.write_keyword("PRIMARY KEY");
10174 if let Some(ref clustered) = modifiers.clustered {
10176 self.write_space();
10177 self.write_keyword(clustered);
10178 }
10179 if let Some(ref n) = name {
10181 if !*has_constraint_keyword {
10182 self.write_space();
10183 self.generate_identifier(n)?;
10184 }
10185 }
10186 self.write(" (");
10187 for (i, col) in columns.iter().enumerate() {
10188 if i > 0 {
10189 self.write(", ");
10190 }
10191 self.generate_identifier(col)?;
10192 }
10193 self.write(")");
10194 if !include_columns.is_empty() {
10195 self.write_space();
10196 self.write_keyword("INCLUDE");
10197 self.write(" (");
10198 for (i, col) in include_columns.iter().enumerate() {
10199 if i > 0 {
10200 self.write(", ");
10201 }
10202 self.generate_identifier(col)?;
10203 }
10204 self.write(")");
10205 }
10206 self.generate_constraint_modifiers(modifiers);
10207 }
10208 TableConstraint::Unique {
10209 name,
10210 columns,
10211 columns_parenthesized,
10212 modifiers,
10213 has_constraint_keyword,
10214 nulls_not_distinct,
10215 } => {
10216 if let Some(ref n) = name {
10217 if *has_constraint_keyword {
10218 self.write_keyword("CONSTRAINT");
10219 self.write_space();
10220 self.generate_identifier(n)?;
10221 self.write_space();
10222 }
10223 }
10224 self.write_keyword("UNIQUE");
10225 if let Some(ref clustered) = modifiers.clustered {
10227 self.write_space();
10228 self.write_keyword(clustered);
10229 }
10230 if *nulls_not_distinct {
10232 self.write(" NULLS NOT DISTINCT");
10233 }
10234 if let Some(ref n) = name {
10236 if !*has_constraint_keyword {
10237 self.write_space();
10238 self.generate_identifier(n)?;
10239 }
10240 }
10241 if *columns_parenthesized {
10242 self.write(" (");
10243 for (i, col) in columns.iter().enumerate() {
10244 if i > 0 {
10245 self.write(", ");
10246 }
10247 self.generate_identifier(col)?;
10248 }
10249 self.write(")");
10250 } else {
10251 for col in columns.iter() {
10253 self.write_space();
10254 self.generate_identifier(col)?;
10255 }
10256 }
10257 self.generate_constraint_modifiers(modifiers);
10258 }
10259 TableConstraint::ForeignKey {
10260 name,
10261 columns,
10262 references,
10263 on_delete,
10264 on_update,
10265 modifiers,
10266 } => {
10267 if let Some(ref n) = name {
10268 self.write_keyword("CONSTRAINT");
10269 self.write_space();
10270 self.generate_identifier(n)?;
10271 self.write_space();
10272 }
10273 self.write_keyword("FOREIGN KEY");
10274 self.write(" (");
10275 for (i, col) in columns.iter().enumerate() {
10276 if i > 0 {
10277 self.write(", ");
10278 }
10279 self.generate_identifier(col)?;
10280 }
10281 self.write(")");
10282 if let Some(ref refs) = references {
10283 self.write(" ");
10284 self.write_keyword("REFERENCES");
10285 self.write_space();
10286 self.generate_table(&refs.table)?;
10287 if !refs.columns.is_empty() {
10288 if self.config.pretty {
10289 self.write(" (");
10290 self.write_newline();
10291 self.indent_level += 1;
10292 for (i, col) in refs.columns.iter().enumerate() {
10293 if i > 0 {
10294 self.write(",");
10295 self.write_newline();
10296 }
10297 self.write_indent();
10298 self.generate_identifier(col)?;
10299 }
10300 self.indent_level -= 1;
10301 self.write_newline();
10302 self.write_indent();
10303 self.write(")");
10304 } else {
10305 self.write(" (");
10306 for (i, col) in refs.columns.iter().enumerate() {
10307 if i > 0 {
10308 self.write(", ");
10309 }
10310 self.generate_identifier(col)?;
10311 }
10312 self.write(")");
10313 }
10314 }
10315 self.generate_referential_actions(refs)?;
10316 } else {
10317 if let Some(ref action) = on_delete {
10319 self.write_space();
10320 self.write_keyword("ON DELETE");
10321 self.write_space();
10322 self.generate_referential_action(action);
10323 }
10324 if let Some(ref action) = on_update {
10325 self.write_space();
10326 self.write_keyword("ON UPDATE");
10327 self.write_space();
10328 self.generate_referential_action(action);
10329 }
10330 }
10331 self.generate_constraint_modifiers(modifiers);
10332 }
10333 TableConstraint::Check {
10334 name,
10335 expression,
10336 modifiers,
10337 } => {
10338 if let Some(ref n) = name {
10339 self.write_keyword("CONSTRAINT");
10340 self.write_space();
10341 self.generate_identifier(n)?;
10342 self.write_space();
10343 }
10344 self.write_keyword("CHECK");
10345 self.write(" (");
10346 self.generate_expression(expression)?;
10347 self.write(")");
10348 self.generate_constraint_modifiers(modifiers);
10349 }
10350 TableConstraint::Assume { name, expression } => {
10351 if let Some(ref n) = name {
10352 self.write_keyword("CONSTRAINT");
10353 self.write_space();
10354 self.generate_identifier(n)?;
10355 self.write_space();
10356 }
10357 self.write_keyword("ASSUME");
10358 self.write(" (");
10359 self.generate_expression(expression)?;
10360 self.write(")");
10361 }
10362 TableConstraint::Default {
10363 name,
10364 expression,
10365 column,
10366 } => {
10367 if let Some(ref n) = name {
10368 self.write_keyword("CONSTRAINT");
10369 self.write_space();
10370 self.generate_identifier(n)?;
10371 self.write_space();
10372 }
10373 self.write_keyword("DEFAULT");
10374 self.write_space();
10375 self.generate_expression(expression)?;
10376 self.write_space();
10377 self.write_keyword("FOR");
10378 self.write_space();
10379 self.generate_identifier(column)?;
10380 }
10381 TableConstraint::Index {
10382 name,
10383 columns,
10384 key_parts,
10385 kind,
10386 modifiers,
10387 use_key_keyword,
10388 expression,
10389 index_type,
10390 granularity,
10391 } => {
10392 if expression.is_some() {
10394 self.write_keyword("INDEX");
10395 if let Some(ref n) = name {
10396 self.write_space();
10397 self.generate_identifier(n)?;
10398 }
10399 if let Some(ref expr) = expression {
10400 self.write_space();
10401 self.generate_expression(expr)?;
10402 }
10403 if let Some(ref idx_type) = index_type {
10404 self.write_space();
10405 self.write_keyword("TYPE");
10406 self.write_space();
10407 self.generate_expression(idx_type)?;
10408 }
10409 if let Some(ref gran) = granularity {
10410 self.write_space();
10411 self.write_keyword("GRANULARITY");
10412 self.write_space();
10413 self.generate_expression(gran)?;
10414 }
10415 } else {
10416 use crate::dialects::DialectType;
10420 let index_keyword = if *use_key_keyword
10421 && !matches!(self.config.dialect, Some(DialectType::MySQL))
10422 {
10423 "KEY"
10424 } else {
10425 "INDEX"
10426 };
10427
10428 if let Some(ref k) = kind {
10430 self.write_keyword(k);
10431 if k != "UNIQUE" {
10433 self.write_space();
10434 self.write_keyword(index_keyword);
10435 }
10436 } else {
10437 self.write_keyword(index_keyword);
10438 }
10439
10440 if modifiers.using_before_columns && name.is_none() {
10442 if let Some(ref using) = modifiers.using {
10443 self.write_space();
10444 self.write_keyword("USING");
10445 self.write_space();
10446 self.write_keyword(using);
10447 }
10448 }
10449
10450 if let Some(ref n) = name {
10452 self.write_space();
10453 self.generate_identifier(n)?;
10454 }
10455
10456 if modifiers.using_before_columns && name.is_some() {
10458 if let Some(ref using) = modifiers.using {
10459 self.write_space();
10460 self.write_keyword("USING");
10461 self.write_space();
10462 self.write_keyword(using);
10463 }
10464 }
10465
10466 self.write(" (");
10468 if key_parts.is_empty() {
10469 for (i, col) in columns.iter().enumerate() {
10470 if i > 0 {
10471 self.write(", ");
10472 }
10473 self.generate_identifier(col)?;
10474 }
10475 } else {
10476 self.generate_index_key_parts(key_parts)?;
10477 }
10478 self.write(")");
10479
10480 if !modifiers.using_before_columns {
10482 if let Some(ref using) = modifiers.using {
10483 self.write_space();
10484 self.write_keyword("USING");
10485 self.write_space();
10486 self.write_keyword(using);
10487 }
10488 }
10489
10490 self.generate_constraint_modifiers_without_using(modifiers);
10492 }
10493 }
10494 TableConstraint::Projection { name, expression } => {
10495 self.write_keyword("PROJECTION");
10497 self.write_space();
10498 self.generate_identifier(name)?;
10499 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
10500 if let Expression::Raw(raw) = expression {
10501 if raw
10502 .sql
10503 .trim_start()
10504 .to_ascii_uppercase()
10505 .starts_with("INDEX ")
10506 {
10507 self.write_space();
10508 self.write(raw.sql.trim());
10509 return Ok(());
10510 }
10511 }
10512 }
10513 self.write(" (");
10514 self.generate_expression(expression)?;
10515 self.write(")");
10516 }
10517 TableConstraint::Like { source, options } => {
10518 self.write_keyword("LIKE");
10519 self.write_space();
10520 self.generate_table(source)?;
10521 for (action, prop) in options {
10522 self.write_space();
10523 match action {
10524 LikeOptionAction::Including => self.write_keyword("INCLUDING"),
10525 LikeOptionAction::Excluding => self.write_keyword("EXCLUDING"),
10526 }
10527 self.write_space();
10528 self.write_keyword(prop);
10529 }
10530 }
10531 TableConstraint::PeriodForSystemTime { start_col, end_col } => {
10532 self.write_keyword("PERIOD FOR SYSTEM_TIME");
10533 self.write(" (");
10534 self.generate_identifier(start_col)?;
10535 self.write(", ");
10536 self.generate_identifier(end_col)?;
10537 self.write(")");
10538 }
10539 TableConstraint::Exclude {
10540 name,
10541 using,
10542 elements,
10543 include_columns,
10544 where_clause,
10545 with_params,
10546 using_index_tablespace,
10547 modifiers: _,
10548 } => {
10549 if let Some(ref n) = name {
10550 self.write_keyword("CONSTRAINT");
10551 self.write_space();
10552 self.generate_identifier(n)?;
10553 self.write_space();
10554 }
10555 self.write_keyword("EXCLUDE");
10556 if let Some(ref method) = using {
10557 self.write_space();
10558 self.write_keyword("USING");
10559 self.write_space();
10560 self.write(method);
10561 self.write("(");
10562 } else {
10563 self.write(" (");
10564 }
10565 for (i, elem) in elements.iter().enumerate() {
10566 if i > 0 {
10567 self.write(", ");
10568 }
10569 self.write(&elem.expression);
10570 self.write_space();
10571 self.write_keyword("WITH");
10572 self.write_space();
10573 self.write(&elem.operator);
10574 }
10575 self.write(")");
10576 if !include_columns.is_empty() {
10577 self.write_space();
10578 self.write_keyword("INCLUDE");
10579 self.write(" (");
10580 for (i, col) in include_columns.iter().enumerate() {
10581 if i > 0 {
10582 self.write(", ");
10583 }
10584 self.generate_identifier(col)?;
10585 }
10586 self.write(")");
10587 }
10588 if !with_params.is_empty() {
10589 self.write_space();
10590 self.write_keyword("WITH");
10591 self.write(" (");
10592 for (i, (key, val)) in with_params.iter().enumerate() {
10593 if i > 0 {
10594 self.write(", ");
10595 }
10596 self.write(key);
10597 self.write("=");
10598 self.write(val);
10599 }
10600 self.write(")");
10601 }
10602 if let Some(ref tablespace) = using_index_tablespace {
10603 self.write_space();
10604 self.write_keyword("USING INDEX TABLESPACE");
10605 self.write_space();
10606 self.write(tablespace);
10607 }
10608 if let Some(ref where_expr) = where_clause {
10609 self.write_space();
10610 self.write_keyword("WHERE");
10611 self.write(" (");
10612 self.generate_expression(where_expr)?;
10613 self.write(")");
10614 }
10615 }
10616 TableConstraint::Tags(tags) => {
10617 self.write_keyword("TAG");
10618 self.write(" (");
10619 for (i, expr) in tags.expressions.iter().enumerate() {
10620 if i > 0 {
10621 self.write(", ");
10622 }
10623 self.generate_expression(expr)?;
10624 }
10625 self.write(")");
10626 }
10627 TableConstraint::InitiallyDeferred { deferred } => {
10628 self.write_keyword("INITIALLY");
10629 self.write_space();
10630 if *deferred {
10631 self.write_keyword("DEFERRED");
10632 } else {
10633 self.write_keyword("IMMEDIATE");
10634 }
10635 }
10636 }
10637 Ok(())
10638 }
10639
10640 fn generate_constraint_modifiers(&mut self, modifiers: &ConstraintModifiers) {
10641 if let Some(using) = &modifiers.using {
10643 self.write_space();
10644 self.write_keyword("USING");
10645 self.write_space();
10646 self.write_keyword(using);
10647 }
10648 if let Some(enforced) = modifiers.enforced {
10650 self.write_space();
10651 if enforced {
10652 self.write_keyword("ENFORCED");
10653 } else {
10654 self.write_keyword("NOT ENFORCED");
10655 }
10656 }
10657 if let Some(deferrable) = modifiers.deferrable {
10659 self.write_space();
10660 if deferrable {
10661 self.write_keyword("DEFERRABLE");
10662 } else {
10663 self.write_keyword("NOT DEFERRABLE");
10664 }
10665 }
10666 if let Some(initially_deferred) = modifiers.initially_deferred {
10668 self.write_space();
10669 if initially_deferred {
10670 self.write_keyword("INITIALLY DEFERRED");
10671 } else {
10672 self.write_keyword("INITIALLY IMMEDIATE");
10673 }
10674 }
10675 if modifiers.norely {
10677 self.write_space();
10678 self.write_keyword("NORELY");
10679 }
10680 if modifiers.rely {
10682 self.write_space();
10683 self.write_keyword("RELY");
10684 }
10685 if modifiers.not_valid {
10687 self.write_space();
10688 self.write_keyword("NOT VALID");
10689 }
10690 if let Some(on_conflict) = &modifiers.on_conflict {
10692 self.write_space();
10693 self.write_keyword("ON CONFLICT");
10694 self.write_space();
10695 self.write_keyword(on_conflict);
10696 }
10697 if !modifiers.with_options.is_empty() {
10699 self.write_space();
10700 self.write_keyword("WITH");
10701 self.write(" (");
10702 for (i, (key, value)) in modifiers.with_options.iter().enumerate() {
10703 if i > 0 {
10704 self.write(", ");
10705 }
10706 self.write(key);
10707 self.write("=");
10708 self.write(value);
10709 }
10710 self.write(")");
10711 }
10712 if let Some(ref fg) = modifiers.on_filegroup {
10714 self.write_space();
10715 self.write_keyword("ON");
10716 self.write_space();
10717 let _ = self.generate_identifier(fg);
10718 }
10719 }
10720
10721 fn generate_constraint_modifiers_without_using(&mut self, modifiers: &ConstraintModifiers) {
10723 if let Some(enforced) = modifiers.enforced {
10725 self.write_space();
10726 if enforced {
10727 self.write_keyword("ENFORCED");
10728 } else {
10729 self.write_keyword("NOT ENFORCED");
10730 }
10731 }
10732 if let Some(deferrable) = modifiers.deferrable {
10734 self.write_space();
10735 if deferrable {
10736 self.write_keyword("DEFERRABLE");
10737 } else {
10738 self.write_keyword("NOT DEFERRABLE");
10739 }
10740 }
10741 if let Some(initially_deferred) = modifiers.initially_deferred {
10743 self.write_space();
10744 if initially_deferred {
10745 self.write_keyword("INITIALLY DEFERRED");
10746 } else {
10747 self.write_keyword("INITIALLY IMMEDIATE");
10748 }
10749 }
10750 if modifiers.norely {
10752 self.write_space();
10753 self.write_keyword("NORELY");
10754 }
10755 if modifiers.rely {
10757 self.write_space();
10758 self.write_keyword("RELY");
10759 }
10760 if modifiers.not_valid {
10762 self.write_space();
10763 self.write_keyword("NOT VALID");
10764 }
10765 if let Some(on_conflict) = &modifiers.on_conflict {
10767 self.write_space();
10768 self.write_keyword("ON CONFLICT");
10769 self.write_space();
10770 self.write_keyword(on_conflict);
10771 }
10772 self.generate_index_specific_modifiers(modifiers);
10774 }
10775
10776 fn generate_index_specific_modifiers(&mut self, modifiers: &ConstraintModifiers) {
10778 if let Some(ref comment) = modifiers.comment {
10779 self.write_space();
10780 self.write_keyword("COMMENT");
10781 self.write(" '");
10782 self.write(comment);
10783 self.write("'");
10784 }
10785 if let Some(visible) = modifiers.visible {
10786 self.write_space();
10787 if visible {
10788 self.write_keyword("VISIBLE");
10789 } else {
10790 self.write_keyword("INVISIBLE");
10791 }
10792 }
10793 if let Some(ref attr) = modifiers.engine_attribute {
10794 self.write_space();
10795 self.write_keyword("ENGINE_ATTRIBUTE");
10796 self.write(" = '");
10797 self.write(attr);
10798 self.write("'");
10799 }
10800 if let Some(ref parser) = modifiers.with_parser {
10801 self.write_space();
10802 self.write_keyword("WITH PARSER");
10803 self.write_space();
10804 self.write(parser);
10805 }
10806 }
10807
10808 fn generate_referential_actions(&mut self, fk_ref: &ForeignKeyRef) -> Result<()> {
10809 if !fk_ref.match_after_actions {
10811 if let Some(ref match_type) = fk_ref.match_type {
10812 self.write_space();
10813 self.write_keyword("MATCH");
10814 self.write_space();
10815 match match_type {
10816 MatchType::Full => self.write_keyword("FULL"),
10817 MatchType::Partial => self.write_keyword("PARTIAL"),
10818 MatchType::Simple => self.write_keyword("SIMPLE"),
10819 }
10820 }
10821 }
10822
10823 if fk_ref.on_update_first {
10825 if let Some(ref action) = fk_ref.on_update {
10826 self.write_space();
10827 self.write_keyword("ON UPDATE");
10828 self.write_space();
10829 self.generate_referential_action(action);
10830 }
10831 if let Some(ref action) = fk_ref.on_delete {
10832 self.write_space();
10833 self.write_keyword("ON DELETE");
10834 self.write_space();
10835 self.generate_referential_action(action);
10836 }
10837 } else {
10838 if let Some(ref action) = fk_ref.on_delete {
10839 self.write_space();
10840 self.write_keyword("ON DELETE");
10841 self.write_space();
10842 self.generate_referential_action(action);
10843 }
10844 if let Some(ref action) = fk_ref.on_update {
10845 self.write_space();
10846 self.write_keyword("ON UPDATE");
10847 self.write_space();
10848 self.generate_referential_action(action);
10849 }
10850 }
10851
10852 if fk_ref.match_after_actions {
10854 if let Some(ref match_type) = fk_ref.match_type {
10855 self.write_space();
10856 self.write_keyword("MATCH");
10857 self.write_space();
10858 match match_type {
10859 MatchType::Full => self.write_keyword("FULL"),
10860 MatchType::Partial => self.write_keyword("PARTIAL"),
10861 MatchType::Simple => self.write_keyword("SIMPLE"),
10862 }
10863 }
10864 }
10865
10866 if let Some(deferrable) = fk_ref.deferrable {
10868 self.write_space();
10869 if deferrable {
10870 self.write_keyword("DEFERRABLE");
10871 } else {
10872 self.write_keyword("NOT DEFERRABLE");
10873 }
10874 }
10875
10876 Ok(())
10877 }
10878
10879 fn generate_referential_action(&mut self, action: &ReferentialAction) {
10880 match action {
10881 ReferentialAction::Cascade => self.write_keyword("CASCADE"),
10882 ReferentialAction::SetNull => self.write_keyword("SET NULL"),
10883 ReferentialAction::SetDefault => self.write_keyword("SET DEFAULT"),
10884 ReferentialAction::Restrict => self.write_keyword("RESTRICT"),
10885 ReferentialAction::NoAction => self.write_keyword("NO ACTION"),
10886 }
10887 }
10888
10889 fn generate_drop_table(&mut self, dt: &DropTable) -> Result<()> {
10890 if let Some(ref object_id_args) = dt.object_id_args {
10892 if matches!(
10893 self.config.dialect,
10894 Some(crate::dialects::DialectType::TSQL)
10895 | Some(crate::dialects::DialectType::Fabric)
10896 ) {
10897 self.write_keyword("IF NOT OBJECT_ID");
10898 self.write("(");
10899 self.write(object_id_args);
10900 self.write(")");
10901 self.write_space();
10902 self.write_keyword("IS NULL BEGIN DROP TABLE");
10903 self.write_space();
10904 for (i, table) in dt.names.iter().enumerate() {
10905 if i > 0 {
10906 self.write(", ");
10907 }
10908 self.generate_table(table)?;
10909 }
10910 self.write("; ");
10911 self.write_keyword("END");
10912 return Ok(());
10913 }
10914 }
10915
10916 let saved_athena_hive_context = self.athena_hive_context;
10918 if matches!(
10919 self.config.dialect,
10920 Some(crate::dialects::DialectType::Athena)
10921 ) {
10922 self.athena_hive_context = true;
10923 }
10924
10925 for comment in &dt.leading_comments {
10927 self.write_formatted_comment(comment);
10928 self.write_space();
10929 }
10930 if dt.iceberg {
10931 self.write_keyword("DROP ICEBERG TABLE");
10932 } else {
10933 self.write_keyword("DROP TABLE");
10934 }
10935
10936 if dt.if_exists {
10937 self.write_space();
10938 self.write_keyword("IF EXISTS");
10939 }
10940
10941 self.write_space();
10942 for (i, table) in dt.names.iter().enumerate() {
10943 if i > 0 {
10944 self.write(", ");
10945 }
10946 self.generate_table(table)?;
10947 }
10948
10949 if dt.cascade_constraints {
10950 self.write_space();
10951 self.write_keyword("CASCADE CONSTRAINTS");
10952 } else if dt.cascade {
10953 self.write_space();
10954 self.write_keyword("CASCADE");
10955 }
10956
10957 if dt.restrict {
10958 self.write_space();
10959 self.write_keyword("RESTRICT");
10960 }
10961
10962 if dt.purge {
10963 self.write_space();
10964 self.write_keyword("PURGE");
10965 }
10966
10967 if dt.sync {
10968 self.write_space();
10969 self.write_keyword("SYNC");
10970 }
10971
10972 self.athena_hive_context = saved_athena_hive_context;
10974
10975 Ok(())
10976 }
10977
10978 fn generate_undrop(&mut self, u: &Undrop) -> Result<()> {
10979 self.write_keyword("UNDROP");
10980 self.write_space();
10981 self.write_keyword(&u.kind);
10982 if u.if_exists {
10983 self.write_space();
10984 self.write_keyword("IF EXISTS");
10985 }
10986 self.write_space();
10987 self.generate_table(&u.name)?;
10988 if let Some(rename_to) = &u.rename_to {
10989 self.write_space();
10990 self.write_keyword("RENAME TO");
10991 self.write_space();
10992 self.generate_table(rename_to)?;
10993 }
10994 Ok(())
10995 }
10996
10997 fn generate_split_table(&mut self, split: &SplitTable) -> Result<()> {
10998 if !matches!(self.config.dialect, Some(DialectType::TiDB)) {
10999 return self
11000 .write_unsupported_comment("SPLIT TABLE is only supported by the TiDB dialect");
11001 }
11002
11003 match &split.partition_scope {
11004 SplitTablePartitionScope::Table => self.write_keyword("SPLIT TABLE"),
11005 SplitTablePartitionScope::AllPartitions
11006 | SplitTablePartitionScope::Partitions { .. } => {
11007 self.write_keyword("SPLIT PARTITION TABLE")
11008 }
11009 }
11010 self.write_space();
11011 self.generate_table(&split.table)?;
11012 if let SplitTablePartitionScope::Partitions { names } = &split.partition_scope {
11013 self.write_space();
11014 self.write_keyword("PARTITION");
11015 self.write(" (");
11016 for (index, name) in names.iter().enumerate() {
11017 if index > 0 {
11018 self.write(", ");
11019 }
11020 self.generate_identifier(name)?;
11021 }
11022 self.write(")");
11023 }
11024 if let Some(index) = &split.index {
11025 self.write_space();
11026 self.write_keyword("INDEX");
11027 self.write_space();
11028 self.generate_identifier(index)?;
11029 }
11030 match &split.mode {
11031 SplitTableMode::Between {
11032 lower,
11033 upper,
11034 regions,
11035 } => {
11036 self.write_space();
11037 self.write_keyword("BETWEEN");
11038 self.write_space();
11039 self.generate_tidb_split_values(lower)?;
11040 self.write_space();
11041 self.write_keyword("AND");
11042 self.write_space();
11043 self.generate_tidb_split_values(upper)?;
11044 self.write_space();
11045 self.write_keyword("REGIONS");
11046 self.write_space();
11047 self.write(®ions.to_string());
11048 }
11049 SplitTableMode::By { points } => {
11050 self.write_space();
11051 self.write_keyword("BY");
11052 self.write_space();
11053 for (index, point) in points.iter().enumerate() {
11054 if index > 0 {
11055 self.write(", ");
11056 }
11057 self.generate_tidb_split_values(point)?;
11058 }
11059 }
11060 }
11061 Ok(())
11062 }
11063
11064 fn generate_tidb_split_values(&mut self, values: &[Expression]) -> Result<()> {
11065 self.write("(");
11066 for (index, value) in values.iter().enumerate() {
11067 if index > 0 {
11068 self.write(", ");
11069 }
11070 self.generate_expression(value)?;
11071 }
11072 self.write(")");
11073 Ok(())
11074 }
11075
11076 fn generate_flashback_table(&mut self, flashback: &FlashbackTable) -> Result<()> {
11077 if !matches!(self.config.dialect, Some(DialectType::TiDB)) {
11078 return self.write_unsupported_comment(
11079 "FLASHBACK TABLE is only supported by the TiDB dialect",
11080 );
11081 }
11082 self.write_keyword("FLASHBACK TABLE");
11083 self.write_space();
11084 self.generate_table(&flashback.table)?;
11085 if let Some(rename_to) = &flashback.rename_to {
11086 self.write_space();
11087 self.write_keyword("TO");
11088 self.write_space();
11089 self.generate_identifier(rename_to)?;
11090 }
11091 Ok(())
11092 }
11093
11094 fn generate_alter_table(&mut self, at: &AlterTable) -> Result<()> {
11095 let saved_athena_hive_context = self.athena_hive_context;
11097 if matches!(
11098 self.config.dialect,
11099 Some(crate::dialects::DialectType::Athena)
11100 ) {
11101 self.athena_hive_context = true;
11102 }
11103
11104 self.write_keyword("ALTER");
11105 if let Some(ref modifier) = at.table_modifier {
11107 if !matches!(
11108 self.config.dialect,
11109 Some(crate::dialects::DialectType::DuckDB)
11110 ) {
11111 self.write_space();
11112 self.write_keyword(modifier);
11113 }
11114 }
11115 self.write(" ");
11116 self.write_keyword("TABLE");
11117 if at.if_exists {
11118 self.write_space();
11119 self.write_keyword("IF EXISTS");
11120 }
11121 self.write_space();
11122 self.generate_table(&at.name)?;
11123
11124 if let Some(ref on_cluster) = at.on_cluster {
11126 self.write_space();
11127 self.generate_on_cluster(on_cluster)?;
11128 }
11129
11130 if let Some(ref partition) = at.partition {
11132 self.write_space();
11133 self.write_keyword("PARTITION");
11134 self.write("(");
11135 for (i, (key, value)) in partition.iter().enumerate() {
11136 if i > 0 {
11137 self.write(", ");
11138 }
11139 self.generate_identifier(key)?;
11140 self.write(" = ");
11141 self.generate_expression(value)?;
11142 }
11143 self.write(")");
11144 }
11145
11146 if let Some(ref with_check) = at.with_check {
11148 self.write_space();
11149 self.write_keyword(with_check);
11150 }
11151
11152 if self.config.pretty {
11153 self.write_newline();
11155 self.indent_level += 1;
11156 for (i, action) in at.actions.iter().enumerate() {
11157 let is_continuation = i > 0
11159 && matches!(
11160 (&at.actions[i - 1], action),
11161 (
11162 AlterTableAction::AddColumn { .. },
11163 AlterTableAction::AddColumn { .. }
11164 ) | (
11165 AlterTableAction::AddConstraint(_),
11166 AlterTableAction::AddConstraint(_)
11167 )
11168 );
11169 if i > 0 {
11170 self.write(",");
11171 self.write_newline();
11172 }
11173 self.write_indent();
11174 self.generate_alter_action_with_continuation(action, is_continuation)?;
11175 }
11176 self.indent_level -= 1;
11177 } else {
11178 for (i, action) in at.actions.iter().enumerate() {
11179 let is_continuation = i > 0
11181 && matches!(
11182 (&at.actions[i - 1], action),
11183 (
11184 AlterTableAction::AddColumn { .. },
11185 AlterTableAction::AddColumn { .. }
11186 ) | (
11187 AlterTableAction::AddConstraint(_),
11188 AlterTableAction::AddConstraint(_)
11189 )
11190 );
11191 if i > 0 {
11192 self.write(",");
11193 }
11194 self.write_space();
11195 self.generate_alter_action_with_continuation(action, is_continuation)?;
11196 }
11197 }
11198
11199 if let Some(ref algorithm) = at.algorithm {
11201 self.write(", ");
11202 self.write_keyword("ALGORITHM");
11203 self.write("=");
11204 self.write_keyword(algorithm);
11205 }
11206 if let Some(ref lock) = at.lock {
11207 self.write(", ");
11208 self.write_keyword("LOCK");
11209 self.write("=");
11210 self.write_keyword(lock);
11211 }
11212
11213 self.athena_hive_context = saved_athena_hive_context;
11215
11216 Ok(())
11217 }
11218
11219 fn generate_alter_action_with_continuation(
11220 &mut self,
11221 action: &AlterTableAction,
11222 is_continuation: bool,
11223 ) -> Result<()> {
11224 match action {
11225 AlterTableAction::AddColumn {
11226 column,
11227 if_not_exists,
11228 position,
11229 } => {
11230 use crate::dialects::DialectType;
11231 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
11235 let is_tsql_like = matches!(
11236 self.config.dialect,
11237 Some(DialectType::TSQL) | Some(DialectType::Fabric)
11238 );
11239 let is_athena = matches!(self.config.dialect, Some(DialectType::Athena));
11241
11242 if is_continuation && (is_snowflake || is_tsql_like) {
11243 } else if is_snowflake {
11245 self.write_keyword("ADD");
11246 self.write_space();
11247 } else if is_athena {
11248 self.write_keyword("ADD COLUMNS");
11250 self.write(" (");
11251 } else if self.config.alter_table_include_column_keyword {
11252 self.write_keyword("ADD COLUMN");
11253 self.write_space();
11254 } else {
11255 self.write_keyword("ADD");
11257 self.write_space();
11258 }
11259
11260 if *if_not_exists {
11261 self.write_keyword("IF NOT EXISTS");
11262 self.write_space();
11263 }
11264 self.generate_column_def(column)?;
11265
11266 if is_athena {
11268 self.write(")");
11269 }
11270
11271 if let Some(pos) = position {
11273 self.write_space();
11274 match pos {
11275 ColumnPosition::First => self.write_keyword("FIRST"),
11276 ColumnPosition::After(col_name) => {
11277 self.write_keyword("AFTER");
11278 self.write_space();
11279 self.generate_identifier(col_name)?;
11280 }
11281 }
11282 }
11283 }
11284 AlterTableAction::DropColumn {
11285 name,
11286 if_exists,
11287 cascade,
11288 } => {
11289 self.write_keyword("DROP COLUMN");
11290 if *if_exists {
11291 self.write_space();
11292 self.write_keyword("IF EXISTS");
11293 }
11294 self.write_space();
11295 self.generate_identifier(name)?;
11296 if *cascade {
11297 self.write_space();
11298 self.write_keyword("CASCADE");
11299 }
11300 }
11301 AlterTableAction::DropColumns { names } => {
11302 self.write_keyword("DROP COLUMNS");
11303 self.write(" (");
11304 for (i, name) in names.iter().enumerate() {
11305 if i > 0 {
11306 self.write(", ");
11307 }
11308 self.generate_identifier(name)?;
11309 }
11310 self.write(")");
11311 }
11312 AlterTableAction::RenameColumn {
11313 old_name,
11314 new_name,
11315 if_exists,
11316 } => {
11317 self.write_keyword("RENAME COLUMN");
11318 if *if_exists {
11319 self.write_space();
11320 self.write_keyword("IF EXISTS");
11321 }
11322 self.write_space();
11323 self.generate_identifier(old_name)?;
11324 self.write_space();
11325 self.write_keyword("TO");
11326 self.write_space();
11327 self.generate_identifier(new_name)?;
11328 }
11329 AlterTableAction::AlterColumn {
11330 name,
11331 action,
11332 use_modify_keyword,
11333 } => {
11334 use crate::dialects::DialectType;
11335 let use_modify = *use_modify_keyword
11338 || (matches!(self.config.dialect, Some(DialectType::MySQL))
11339 && matches!(action, AlterColumnAction::SetDataType { .. }));
11340 if use_modify {
11341 self.write_keyword("MODIFY COLUMN");
11342 self.write_space();
11343 self.generate_identifier(name)?;
11344 if let AlterColumnAction::SetDataType {
11346 data_type,
11347 using: _,
11348 collate,
11349 } = action
11350 {
11351 self.write_space();
11352 self.generate_data_type(data_type)?;
11353 if let Some(collate_name) = collate {
11355 self.write_space();
11356 self.write_keyword("COLLATE");
11357 self.write_space();
11358 self.write(&format!("'{}'", collate_name));
11360 }
11361 } else {
11362 self.write_space();
11363 self.generate_alter_column_action(action)?;
11364 }
11365 } else if matches!(self.config.dialect, Some(DialectType::Hive))
11366 && matches!(action, AlterColumnAction::SetDataType { .. })
11367 {
11368 self.write_keyword("CHANGE COLUMN");
11370 self.write_space();
11371 self.generate_identifier(name)?;
11372 self.write_space();
11373 self.generate_identifier(name)?;
11374 if let AlterColumnAction::SetDataType { data_type, .. } = action {
11375 self.write_space();
11376 self.generate_data_type(data_type)?;
11377 }
11378 } else {
11379 self.write_keyword("ALTER COLUMN");
11380 self.write_space();
11381 self.generate_identifier(name)?;
11382 self.write_space();
11383 self.generate_alter_column_action(action)?;
11384 }
11385 }
11386 AlterTableAction::ModifyColumn {
11387 column,
11388 if_exists,
11389 position,
11390 } => {
11391 if !matches!(
11392 self.config.dialect,
11393 Some(DialectType::TiDB) | Some(DialectType::MySQL)
11394 ) {
11395 return self.write_unsupported_comment(
11396 "MODIFY COLUMN is only supported by MySQL-compatible dialects",
11397 );
11398 }
11399 self.write_keyword("MODIFY COLUMN");
11400 self.write_space();
11401 if *if_exists {
11402 self.write_keyword("IF EXISTS");
11403 self.write_space();
11404 }
11405 self.generate_column_def(column)?;
11406 if let Some(position) = position {
11407 self.write_space();
11408 match position {
11409 ColumnPosition::First => self.write_keyword("FIRST"),
11410 ColumnPosition::After(name) => {
11411 self.write_keyword("AFTER");
11412 self.write_space();
11413 self.generate_identifier(name)?;
11414 }
11415 }
11416 }
11417 }
11418 AlterTableAction::RenameTable(new_name) => {
11419 let mysql_like = matches!(
11421 self.config.dialect,
11422 Some(DialectType::MySQL)
11423 | Some(DialectType::Doris)
11424 | Some(DialectType::StarRocks)
11425 | Some(DialectType::SingleStore)
11426 );
11427 if mysql_like {
11428 self.write_keyword("RENAME");
11429 } else {
11430 self.write_keyword("RENAME TO");
11431 }
11432 self.write_space();
11433 let rename_table_with_db = !matches!(
11435 self.config.dialect,
11436 Some(DialectType::Doris)
11437 | Some(DialectType::DuckDB)
11438 | Some(DialectType::BigQuery)
11439 | Some(DialectType::PostgreSQL)
11440 );
11441 if !rename_table_with_db {
11442 let mut stripped = new_name.clone();
11443 stripped.schema = None;
11444 stripped.catalog = None;
11445 self.generate_table(&stripped)?;
11446 } else {
11447 self.generate_table(new_name)?;
11448 }
11449 }
11450 AlterTableAction::AddConstraint(constraint) => {
11451 if !is_continuation {
11454 self.write_keyword("ADD");
11455 self.write_space();
11456 }
11457 self.generate_table_constraint(constraint)?;
11458 }
11459 AlterTableAction::DropConstraint { name, if_exists } => {
11460 self.write_keyword("DROP CONSTRAINT");
11461 if *if_exists {
11462 self.write_space();
11463 self.write_keyword("IF EXISTS");
11464 }
11465 self.write_space();
11466 self.generate_identifier(name)?;
11467 }
11468 AlterTableAction::DropForeignKey { name } => {
11469 self.write_keyword("DROP FOREIGN KEY");
11470 self.write_space();
11471 self.generate_identifier(name)?;
11472 }
11473 AlterTableAction::DropPartition {
11474 partitions,
11475 if_exists,
11476 } => {
11477 self.write_keyword("DROP");
11478 if *if_exists {
11479 self.write_space();
11480 self.write_keyword("IF EXISTS");
11481 }
11482 for (i, partition) in partitions.iter().enumerate() {
11483 if i > 0 {
11484 self.write(",");
11485 }
11486 self.write_space();
11487 self.write_keyword("PARTITION");
11488 if partition.len() == 1 && partition[0].0.name == "__expr__" {
11490 self.write_space();
11492 self.generate_expression(&partition[0].1)?;
11493 } else if partition.len() == 1 && partition[0].0.name == "ALL" {
11494 self.write_space();
11496 self.write_keyword("ALL");
11497 } else if partition.len() == 1 && partition[0].0.name == "ID" {
11498 self.write_space();
11500 self.write_keyword("ID");
11501 self.write_space();
11502 self.generate_expression(&partition[0].1)?;
11503 } else {
11504 self.write("(");
11506 for (j, (key, value)) in partition.iter().enumerate() {
11507 if j > 0 {
11508 self.write(", ");
11509 }
11510 self.generate_identifier(key)?;
11511 self.write(" = ");
11512 self.generate_expression(value)?;
11513 }
11514 self.write(")");
11515 }
11516 }
11517 }
11518 AlterTableAction::Delete { where_clause } => {
11519 self.write_keyword("DELETE");
11520 self.write_space();
11521 self.write_keyword("WHERE");
11522 self.write_space();
11523 self.generate_expression(where_clause)?;
11524 }
11525 AlterTableAction::SwapWith(target) => {
11526 self.write_keyword("SWAP WITH");
11527 self.write_space();
11528 self.generate_table(target)?;
11529 }
11530 AlterTableAction::SetProperty { properties } => {
11531 use crate::dialects::DialectType;
11532 self.write_keyword("SET");
11533 let is_trino_presto = matches!(
11535 self.config.dialect,
11536 Some(DialectType::Trino) | Some(DialectType::Presto)
11537 );
11538 if is_trino_presto {
11539 self.write_space();
11540 self.write_keyword("PROPERTIES");
11541 }
11542 let eq = if is_trino_presto { " = " } else { "=" };
11543 for (i, (key, value)) in properties.iter().enumerate() {
11544 if i > 0 {
11545 self.write(",");
11546 }
11547 self.write_space();
11548 if key.contains(' ') {
11550 self.generate_string_literal(key)?;
11551 } else {
11552 self.write(key);
11553 }
11554 self.write(eq);
11555 self.generate_expression(value)?;
11556 }
11557 }
11558 AlterTableAction::UnsetProperty { properties } => {
11559 self.write_keyword("UNSET");
11560 for (i, name) in properties.iter().enumerate() {
11561 if i > 0 {
11562 self.write(",");
11563 }
11564 self.write_space();
11565 self.write(name);
11566 }
11567 }
11568 AlterTableAction::ClusterBy { expressions } => {
11569 self.write_keyword("CLUSTER BY");
11570 self.write(" (");
11571 for (i, expr) in expressions.iter().enumerate() {
11572 if i > 0 {
11573 self.write(", ");
11574 }
11575 self.generate_expression(expr)?;
11576 }
11577 self.write(")");
11578 }
11579 AlterTableAction::SetTag { expressions } => {
11580 self.write_keyword("SET TAG");
11581 for (i, (key, value)) in expressions.iter().enumerate() {
11582 if i > 0 {
11583 self.write(",");
11584 }
11585 self.write_space();
11586 self.write(key);
11587 self.write(" = ");
11588 self.generate_expression(value)?;
11589 }
11590 }
11591 AlterTableAction::UnsetTag { names } => {
11592 self.write_keyword("UNSET TAG");
11593 for (i, name) in names.iter().enumerate() {
11594 if i > 0 {
11595 self.write(",");
11596 }
11597 self.write_space();
11598 self.write(name);
11599 }
11600 }
11601 AlterTableAction::SetOptions { expressions } => {
11602 self.write_keyword("SET");
11603 self.write(" (");
11604 for (i, expr) in expressions.iter().enumerate() {
11605 if i > 0 {
11606 self.write(", ");
11607 }
11608 self.generate_expression(expr)?;
11609 }
11610 self.write(")");
11611 }
11612 AlterTableAction::AlterIndex { name, visible } => {
11613 self.write_keyword("ALTER INDEX");
11614 self.write_space();
11615 self.generate_identifier(name)?;
11616 self.write_space();
11617 if *visible {
11618 self.write_keyword("VISIBLE");
11619 } else {
11620 self.write_keyword("INVISIBLE");
11621 }
11622 }
11623 AlterTableAction::SetAttribute { attribute } => {
11624 self.write_keyword("SET");
11625 self.write_space();
11626 self.write_keyword(attribute);
11627 }
11628 AlterTableAction::SetStageFileFormat { options } => {
11629 self.write_keyword("SET");
11630 self.write_space();
11631 self.write_keyword("STAGE_FILE_FORMAT");
11632 self.write(" = (");
11633 if let Some(opts) = options {
11634 self.generate_space_separated_properties(opts)?;
11635 }
11636 self.write(")");
11637 }
11638 AlterTableAction::SetStageCopyOptions { options } => {
11639 self.write_keyword("SET");
11640 self.write_space();
11641 self.write_keyword("STAGE_COPY_OPTIONS");
11642 self.write(" = (");
11643 if let Some(opts) = options {
11644 self.generate_space_separated_properties(opts)?;
11645 }
11646 self.write(")");
11647 }
11648 AlterTableAction::AddColumns { columns, cascade } => {
11649 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
11652 if is_oracle {
11653 self.write_keyword("ADD");
11654 } else {
11655 self.write_keyword("ADD COLUMNS");
11656 }
11657 self.write(" (");
11658 for (i, col) in columns.iter().enumerate() {
11659 if i > 0 {
11660 self.write(", ");
11661 }
11662 self.generate_column_def(col)?;
11663 }
11664 self.write(")");
11665 if *cascade {
11666 self.write_space();
11667 self.write_keyword("CASCADE");
11668 }
11669 }
11670 AlterTableAction::ChangeColumn {
11671 old_name,
11672 new_name,
11673 data_type,
11674 comment,
11675 cascade,
11676 } => {
11677 use crate::dialects::DialectType;
11678 let is_spark = matches!(
11679 self.config.dialect,
11680 Some(DialectType::Spark) | Some(DialectType::Databricks)
11681 );
11682 let is_rename = old_name.name != new_name.name;
11683
11684 if is_spark {
11685 if is_rename {
11686 self.write_keyword("RENAME COLUMN");
11688 self.write_space();
11689 self.generate_identifier(old_name)?;
11690 self.write_space();
11691 self.write_keyword("TO");
11692 self.write_space();
11693 self.generate_identifier(new_name)?;
11694 } else if comment.is_some() {
11695 self.write_keyword("ALTER COLUMN");
11697 self.write_space();
11698 self.generate_identifier(old_name)?;
11699 self.write_space();
11700 self.write_keyword("COMMENT");
11701 self.write_space();
11702 self.write("'");
11703 self.write(comment.as_ref().unwrap());
11704 self.write("'");
11705 } else if data_type.is_some() {
11706 self.write_keyword("ALTER COLUMN");
11708 self.write_space();
11709 self.generate_identifier(old_name)?;
11710 self.write_space();
11711 self.write_keyword("TYPE");
11712 self.write_space();
11713 self.generate_data_type(data_type.as_ref().unwrap())?;
11714 } else {
11715 self.write_keyword("CHANGE COLUMN");
11717 self.write_space();
11718 self.generate_identifier(old_name)?;
11719 self.write_space();
11720 self.generate_identifier(new_name)?;
11721 }
11722 } else {
11723 if data_type.is_some() {
11725 self.write_keyword("CHANGE COLUMN");
11726 } else {
11727 self.write_keyword("CHANGE");
11728 }
11729 self.write_space();
11730 self.generate_identifier(old_name)?;
11731 self.write_space();
11732 self.generate_identifier(new_name)?;
11733 if let Some(ref dt) = data_type {
11734 self.write_space();
11735 self.generate_data_type(dt)?;
11736 }
11737 if let Some(ref c) = comment {
11738 self.write_space();
11739 self.write_keyword("COMMENT");
11740 self.write_space();
11741 self.write("'");
11742 self.write(c);
11743 self.write("'");
11744 }
11745 if *cascade {
11746 self.write_space();
11747 self.write_keyword("CASCADE");
11748 }
11749 }
11750 }
11751 AlterTableAction::AddPartition {
11752 partition,
11753 if_not_exists,
11754 location,
11755 } => {
11756 self.write_keyword("ADD");
11757 self.write_space();
11758 if *if_not_exists {
11759 self.write_keyword("IF NOT EXISTS");
11760 self.write_space();
11761 }
11762 self.generate_expression(partition)?;
11763 if let Some(ref loc) = location {
11764 self.write_space();
11765 self.write_keyword("LOCATION");
11766 self.write_space();
11767 self.generate_expression(loc)?;
11768 }
11769 }
11770 AlterTableAction::AlterSortKey {
11771 this,
11772 expressions,
11773 compound,
11774 } => {
11775 self.write_keyword("ALTER");
11777 if *compound {
11778 self.write_space();
11779 self.write_keyword("COMPOUND");
11780 }
11781 self.write_space();
11782 self.write_keyword("SORTKEY");
11783 self.write_space();
11784 if let Some(style) = this {
11785 self.write_keyword(style);
11786 } else if !expressions.is_empty() {
11787 self.write("(");
11788 for (i, expr) in expressions.iter().enumerate() {
11789 if i > 0 {
11790 self.write(", ");
11791 }
11792 self.generate_expression(expr)?;
11793 }
11794 self.write(")");
11795 }
11796 }
11797 AlterTableAction::AlterDistStyle { style, distkey } => {
11798 self.write_keyword("ALTER");
11800 self.write_space();
11801 self.write_keyword("DISTSTYLE");
11802 self.write_space();
11803 self.write_keyword(style);
11804 if let Some(col) = distkey {
11805 self.write_space();
11806 self.write_keyword("DISTKEY");
11807 self.write_space();
11808 self.generate_identifier(col)?;
11809 }
11810 }
11811 AlterTableAction::SetTableProperties { properties } => {
11812 self.write_keyword("SET TABLE PROPERTIES");
11814 self.write(" (");
11815 for (i, (key, value)) in properties.iter().enumerate() {
11816 if i > 0 {
11817 self.write(", ");
11818 }
11819 self.generate_expression(key)?;
11820 self.write(" = ");
11821 self.generate_expression(value)?;
11822 }
11823 self.write(")");
11824 }
11825 AlterTableAction::SetLocation { location } => {
11826 self.write_keyword("SET LOCATION");
11828 self.write_space();
11829 self.write("'");
11830 self.write(location);
11831 self.write("'");
11832 }
11833 AlterTableAction::SetFileFormat { format } => {
11834 self.write_keyword("SET FILE FORMAT");
11836 self.write_space();
11837 self.write_keyword(format);
11838 }
11839 AlterTableAction::ReplacePartition { partition, source } => {
11840 self.write_keyword("REPLACE PARTITION");
11842 self.write_space();
11843 self.generate_expression(partition)?;
11844 if let Some(src) = source {
11845 self.write_space();
11846 self.write_keyword("FROM");
11847 self.write_space();
11848 self.generate_expression(src)?;
11849 }
11850 }
11851 AlterTableAction::SetTiDBTableOption { option, force } => {
11852 self.generate_tidb_table_option(option, *force)?;
11853 }
11854 AlterTableAction::RemoveTiDBTtl { executable_comment } => {
11855 if !matches!(self.config.dialect, Some(DialectType::TiDB)) {
11856 return self.write_unsupported_comment(
11857 "REMOVE TTL is only supported by the TiDB dialect",
11858 );
11859 }
11860 if *executable_comment {
11861 self.write("/*T![ttl] REMOVE TTL */");
11862 } else {
11863 self.write_keyword("REMOVE TTL");
11864 }
11865 }
11866 AlterTableAction::Raw { sql } => {
11867 self.write(sql);
11868 }
11869 }
11870 Ok(())
11871 }
11872
11873 fn generate_alter_column_action(&mut self, action: &AlterColumnAction) -> Result<()> {
11874 match action {
11875 AlterColumnAction::SetDataType {
11876 data_type,
11877 using,
11878 collate,
11879 } => {
11880 use crate::dialects::DialectType;
11881 let is_no_prefix = matches!(
11886 self.config.dialect,
11887 Some(DialectType::TSQL) | Some(DialectType::Fabric) | Some(DialectType::Hive)
11888 );
11889 let is_type_only = matches!(
11890 self.config.dialect,
11891 Some(DialectType::Redshift)
11892 | Some(DialectType::Spark)
11893 | Some(DialectType::Databricks)
11894 );
11895 if is_type_only {
11896 self.write_keyword("TYPE");
11897 self.write_space();
11898 } else if !is_no_prefix {
11899 self.write_keyword("SET DATA TYPE");
11900 self.write_space();
11901 }
11902 self.generate_data_type(data_type)?;
11903 if let Some(ref collation) = collate {
11904 self.write_space();
11905 self.write_keyword("COLLATE");
11906 self.write_space();
11907 self.write(collation);
11908 }
11909 if let Some(ref using_expr) = using {
11910 self.write_space();
11911 self.write_keyword("USING");
11912 self.write_space();
11913 self.generate_expression(using_expr)?;
11914 }
11915 }
11916 AlterColumnAction::SetDefault(expr) => {
11917 self.write_keyword("SET DEFAULT");
11918 self.write_space();
11919 self.generate_expression(expr)?;
11920 }
11921 AlterColumnAction::DropDefault => {
11922 self.write_keyword("DROP DEFAULT");
11923 }
11924 AlterColumnAction::SetNotNull => {
11925 self.write_keyword("SET NOT NULL");
11926 }
11927 AlterColumnAction::DropNotNull => {
11928 self.write_keyword("DROP NOT NULL");
11929 }
11930 AlterColumnAction::Comment(comment) => {
11931 self.write_keyword("COMMENT");
11932 self.write_space();
11933 self.generate_string_literal(comment)?;
11934 }
11935 AlterColumnAction::SetVisible => {
11936 self.write_keyword("SET VISIBLE");
11937 }
11938 AlterColumnAction::SetInvisible => {
11939 self.write_keyword("SET INVISIBLE");
11940 }
11941 }
11942 Ok(())
11943 }
11944
11945 fn generate_create_index(&mut self, ci: &CreateIndex) -> Result<()> {
11946 self.write_keyword("CREATE");
11947
11948 if ci.unique {
11949 self.write_space();
11950 self.write_keyword("UNIQUE");
11951 }
11952
11953 if let Some(ref clustered) = ci.clustered {
11955 self.write_space();
11956 self.write_keyword(clustered);
11957 }
11958
11959 self.write_space();
11960 self.write_keyword("INDEX");
11961
11962 if ci.concurrently {
11964 self.write_space();
11965 self.write_keyword("CONCURRENTLY");
11966 }
11967
11968 if ci.if_not_exists {
11969 self.write_space();
11970 self.write_keyword("IF NOT EXISTS");
11971 }
11972
11973 if !ci.name.name.is_empty() {
11975 self.write_space();
11976 self.generate_identifier(&ci.name)?;
11977 }
11978 self.write_space();
11979 self.write_keyword("ON");
11980 if matches!(self.config.dialect, Some(DialectType::Hive)) {
11982 self.write_space();
11983 self.write_keyword("TABLE");
11984 }
11985 self.write_space();
11986 self.generate_table(&ci.table)?;
11987
11988 if !ci.columns.is_empty() || !ci.key_parts.is_empty() || ci.using.is_some() {
11991 let space_before_paren = false;
11992
11993 if let Some(ref using) = ci.using {
11994 self.write_space();
11995 self.write_keyword("USING");
11996 self.write_space();
11997 self.write(using);
11998 if space_before_paren {
11999 self.write(" (");
12000 } else {
12001 self.write("(");
12002 }
12003 } else {
12004 if space_before_paren {
12005 self.write(" (");
12006 } else {
12007 self.write("(");
12008 }
12009 }
12010 if ci.key_parts.is_empty() {
12011 for (i, col) in ci.columns.iter().enumerate() {
12012 if i > 0 {
12013 self.write(", ");
12014 }
12015 self.generate_identifier(&col.column)?;
12016 if let Some(ref opclass) = col.opclass {
12017 self.write_space();
12018 self.write(opclass);
12019 }
12020 if col.desc {
12021 self.write_space();
12022 self.write_keyword("DESC");
12023 } else if col.asc {
12024 self.write_space();
12025 self.write_keyword("ASC");
12026 }
12027 if let Some(nulls_first) = col.nulls_first {
12028 self.write_space();
12029 self.write_keyword("NULLS");
12030 self.write_space();
12031 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
12032 }
12033 }
12034 } else {
12035 self.generate_index_key_parts(&ci.key_parts)?;
12036 }
12037 self.write(")");
12038 }
12039
12040 if !ci.include_columns.is_empty() {
12042 self.write_space();
12043 self.write_keyword("INCLUDE");
12044 self.write(" (");
12045 for (i, col) in ci.include_columns.iter().enumerate() {
12046 if i > 0 {
12047 self.write(", ");
12048 }
12049 self.generate_identifier(col)?;
12050 }
12051 self.write(")");
12052 }
12053
12054 if !ci.with_options.is_empty() {
12056 self.write_space();
12057 self.write_keyword("WITH");
12058 self.write(" (");
12059 for (i, (key, value)) in ci.with_options.iter().enumerate() {
12060 if i > 0 {
12061 self.write(", ");
12062 }
12063 self.write(key);
12064 self.write("=");
12065 self.write(value);
12066 }
12067 self.write(")");
12068 }
12069
12070 if let Some(ref where_clause) = ci.where_clause {
12072 self.write_space();
12073 self.write_keyword("WHERE");
12074 self.write_space();
12075 self.generate_expression(where_clause)?;
12076 }
12077
12078 if let Some(ref on_fg) = ci.on_filegroup {
12080 self.write_space();
12081 self.write_keyword("ON");
12082 self.write_space();
12083 self.write(on_fg);
12084 }
12085
12086 Ok(())
12087 }
12088
12089 fn generate_index_key_parts(&mut self, key_parts: &[IndexKeyPart]) -> Result<()> {
12090 for (i, part) in key_parts.iter().enumerate() {
12091 if i > 0 {
12092 self.write(", ");
12093 }
12094 self.generate_expression(&part.expression)?;
12095 if let Some(ref prefix_length) = part.prefix_length {
12096 self.write("(");
12097 self.write(prefix_length);
12098 self.write(")");
12099 }
12100 if let Some(ref opclass) = part.opclass {
12101 self.write_space();
12102 self.write(opclass);
12103 }
12104 if part.desc {
12105 self.write_space();
12106 self.write_keyword("DESC");
12107 } else if part.asc {
12108 self.write_space();
12109 self.write_keyword("ASC");
12110 }
12111 if let Some(nulls_first) = part.nulls_first {
12112 self.write_space();
12113 self.write_keyword("NULLS");
12114 self.write_space();
12115 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
12116 }
12117 }
12118 Ok(())
12119 }
12120
12121 fn generate_drop_index(&mut self, di: &DropIndex) -> Result<()> {
12122 self.write_keyword("DROP INDEX");
12123
12124 if di.concurrently {
12125 self.write_space();
12126 self.write_keyword("CONCURRENTLY");
12127 }
12128
12129 if di.if_exists {
12130 self.write_space();
12131 self.write_keyword("IF EXISTS");
12132 }
12133
12134 self.write_space();
12135 self.generate_table(&di.name)?;
12136
12137 if let Some(ref table) = di.table {
12138 self.write_space();
12139 self.write_keyword("ON");
12140 self.write_space();
12141 self.generate_table(table)?;
12142 }
12143
12144 Ok(())
12145 }
12146
12147 fn generate_create_view(&mut self, cv: &CreateView) -> Result<()> {
12148 self.write_keyword("CREATE");
12149
12150 if let Some(ref algorithm) = cv.algorithm {
12152 self.write_space();
12153 self.write_keyword("ALGORITHM");
12154 self.write("=");
12155 self.write_keyword(algorithm);
12156 }
12157
12158 if let Some(ref definer) = cv.definer {
12160 self.write_space();
12161 self.write_keyword("DEFINER");
12162 self.write("=");
12163 self.write(definer);
12164 }
12165
12166 if cv.security_sql_style && !cv.security_after_name {
12168 if let Some(ref security) = cv.security {
12169 self.write_space();
12170 self.write_keyword("SQL SECURITY");
12171 self.write_space();
12172 match security {
12173 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
12174 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
12175 FunctionSecurity::None => self.write_keyword("NONE"),
12176 }
12177 }
12178 }
12179
12180 if cv.or_alter {
12181 self.write_space();
12182 self.write_keyword("OR ALTER");
12183 } else if cv.or_replace {
12184 self.write_space();
12185 self.write_keyword("OR REPLACE");
12186 }
12187
12188 if cv.temporary {
12189 self.write_space();
12190 self.write_keyword("TEMPORARY");
12191 }
12192
12193 if cv.materialized {
12194 self.write_space();
12195 self.write_keyword("MATERIALIZED");
12196 }
12197
12198 if cv.secure {
12200 self.write_space();
12201 self.write_keyword("SECURE");
12202 }
12203
12204 self.write_space();
12205 self.write_keyword("VIEW");
12206
12207 if cv.if_not_exists {
12208 self.write_space();
12209 self.write_keyword("IF NOT EXISTS");
12210 }
12211
12212 self.write_space();
12213 self.generate_table(&cv.name)?;
12214
12215 if let Some(ref on_cluster) = cv.on_cluster {
12217 self.write_space();
12218 self.generate_on_cluster(on_cluster)?;
12219 }
12220
12221 if let Some(ref to_table) = cv.to_table {
12223 self.write_space();
12224 self.write_keyword("TO");
12225 self.write_space();
12226 self.generate_table(to_table)?;
12227 }
12228
12229 if !cv.materialized {
12232 if let Some(ref schema) = cv.schema {
12234 self.write(" (");
12235 for (i, expr) in schema.expressions.iter().enumerate() {
12236 if i > 0 {
12237 self.write(", ");
12238 }
12239 self.generate_expression(expr)?;
12240 }
12241 self.write(")");
12242 } else if !cv.columns.is_empty() {
12243 self.write(" (");
12244 for (i, col) in cv.columns.iter().enumerate() {
12245 if i > 0 {
12246 self.write(", ");
12247 }
12248 self.generate_identifier(&col.name)?;
12249 if !col.options.is_empty() {
12251 self.write_space();
12252 self.generate_options_clause(&col.options)?;
12253 }
12254 if let Some(ref comment) = col.comment {
12255 self.write_space();
12256 self.write_keyword("COMMENT");
12257 self.write_space();
12258 self.generate_string_literal(comment)?;
12259 }
12260 }
12261 self.write(")");
12262 }
12263
12264 if !cv.security_sql_style || cv.security_after_name {
12267 if let Some(ref security) = cv.security {
12268 self.write_space();
12269 if cv.security_sql_style {
12270 self.write_keyword("SQL SECURITY");
12271 } else {
12272 self.write_keyword("SECURITY");
12273 }
12274 self.write_space();
12275 match security {
12276 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
12277 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
12278 FunctionSecurity::None => self.write_keyword("NONE"),
12279 }
12280 }
12281 }
12282
12283 if cv.copy_grants {
12285 self.write_space();
12286 self.write_keyword("COPY GRANTS");
12287 }
12288 } else {
12289 if cv.copy_grants {
12291 self.write_space();
12292 self.write_keyword("COPY GRANTS");
12293 }
12294
12295 if let Some(ref schema) = cv.schema {
12297 self.write(" (");
12298 for (i, expr) in schema.expressions.iter().enumerate() {
12299 if i > 0 {
12300 self.write(", ");
12301 }
12302 self.generate_expression(expr)?;
12303 }
12304 self.write(")");
12305 } else if !cv.columns.is_empty() {
12306 self.write(" (");
12308 for (i, col) in cv.columns.iter().enumerate() {
12309 if i > 0 {
12310 self.write(", ");
12311 }
12312 self.generate_identifier(&col.name)?;
12313 if !col.options.is_empty() {
12315 self.write_space();
12316 self.generate_options_clause(&col.options)?;
12317 }
12318 if let Some(ref comment) = col.comment {
12319 self.write_space();
12320 self.write_keyword("COMMENT");
12321 self.write_space();
12322 self.generate_string_literal(comment)?;
12323 }
12324 }
12325 self.write(")");
12326 }
12327
12328 if let Some(ref unique_key) = cv.unique_key {
12330 self.write_space();
12331 self.write_keyword("KEY");
12332 self.write(" (");
12333 for (i, expr) in unique_key.expressions.iter().enumerate() {
12334 if i > 0 {
12335 self.write(", ");
12336 }
12337 self.generate_expression(expr)?;
12338 }
12339 self.write(")");
12340 }
12341 }
12342
12343 if let Some(ref row_access_policy) = cv.row_access_policy {
12344 self.write_space();
12345 self.write_keyword("WITH");
12346 self.write_space();
12347 self.write(row_access_policy);
12348 }
12349
12350 if let Some(ref comment) = cv.comment {
12352 self.write_space();
12353 self.write_keyword("COMMENT");
12354 self.write("=");
12355 self.generate_string_literal(comment)?;
12356 }
12357
12358 if !cv.tags.is_empty() {
12360 self.write_space();
12361 self.write_keyword("TAG");
12362 self.write(" (");
12363 for (i, (name, value)) in cv.tags.iter().enumerate() {
12364 if i > 0 {
12365 self.write(", ");
12366 }
12367 self.write(name);
12368 self.write("='");
12369 self.write(value);
12370 self.write("'");
12371 }
12372 self.write(")");
12373 }
12374
12375 if !cv.options.is_empty() {
12377 self.write_space();
12378 self.generate_options_clause(&cv.options)?;
12379 }
12380
12381 if let Some(ref build) = cv.build {
12383 self.write_space();
12384 self.write_keyword("BUILD");
12385 self.write_space();
12386 self.write_keyword(build);
12387 }
12388
12389 if let Some(ref refresh) = cv.refresh {
12391 self.write_space();
12392 self.generate_refresh_trigger_property(refresh)?;
12393 }
12394
12395 if let Some(auto_refresh) = cv.auto_refresh {
12397 self.write_space();
12398 self.write_keyword("AUTO REFRESH");
12399 self.write_space();
12400 if auto_refresh {
12401 self.write_keyword("YES");
12402 } else {
12403 self.write_keyword("NO");
12404 }
12405 }
12406
12407 for prop in &cv.table_properties {
12409 self.write_space();
12410 self.generate_expression(prop)?;
12411 }
12412
12413 if let Some(ref population) = cv.clickhouse_population {
12415 self.write_space();
12416 self.write_keyword(population);
12417 }
12418
12419 if !matches!(&cv.query, Expression::Null(_)) {
12421 self.write_space();
12422 self.write_keyword("AS");
12423 self.write_space();
12424
12425 if let Some(ref mode) = cv.locking_mode {
12427 self.write_keyword("LOCKING");
12428 self.write_space();
12429 self.write_keyword(mode);
12430 if let Some(ref access) = cv.locking_access {
12431 self.write_space();
12432 self.write_keyword("FOR");
12433 self.write_space();
12434 self.write_keyword(access);
12435 }
12436 self.write_space();
12437 }
12438
12439 if cv.query_parenthesized {
12440 self.write("(");
12441 }
12442 self.generate_expression(&cv.query)?;
12443 if cv.query_parenthesized {
12444 self.write(")");
12445 }
12446 }
12447
12448 if cv.no_schema_binding {
12450 self.write_space();
12451 self.write_keyword("WITH NO SCHEMA BINDING");
12452 }
12453
12454 Ok(())
12455 }
12456
12457 fn generate_drop_view(&mut self, dv: &DropView) -> Result<()> {
12458 self.write_keyword("DROP");
12459
12460 if dv.materialized {
12461 self.write_space();
12462 self.write_keyword("MATERIALIZED");
12463 }
12464
12465 self.write_space();
12466 self.write_keyword("VIEW");
12467
12468 if dv.if_exists {
12469 self.write_space();
12470 self.write_keyword("IF EXISTS");
12471 }
12472
12473 self.write_space();
12474 self.generate_table(&dv.name)?;
12475
12476 Ok(())
12477 }
12478
12479 fn generate_truncate(&mut self, tr: &Truncate) -> Result<()> {
12480 match tr.target {
12481 TruncateTarget::Database => self.write_keyword("TRUNCATE DATABASE"),
12482 TruncateTarget::Table => self.write_keyword("TRUNCATE TABLE"),
12483 }
12484 if tr.if_exists {
12485 self.write_space();
12486 self.write_keyword("IF EXISTS");
12487 }
12488 self.write_space();
12489 self.generate_table(&tr.table)?;
12490
12491 if let Some(ref on_cluster) = tr.on_cluster {
12493 self.write_space();
12494 self.generate_on_cluster(on_cluster)?;
12495 }
12496
12497 if !tr.extra_tables.is_empty() {
12499 let skip_first = if let Some(first) = tr.extra_tables.first() {
12501 first.table.name == tr.table.name && first.star
12502 } else {
12503 false
12504 };
12505
12506 let strip_star = matches!(
12508 self.config.dialect,
12509 Some(crate::dialects::DialectType::PostgreSQL)
12510 | Some(crate::dialects::DialectType::Redshift)
12511 );
12512 if skip_first && !strip_star {
12513 self.write("*");
12514 }
12515
12516 for (i, entry) in tr.extra_tables.iter().enumerate() {
12518 if i == 0 && skip_first {
12519 continue; }
12521 self.write(", ");
12522 self.generate_table(&entry.table)?;
12523 if entry.star && !strip_star {
12524 self.write("*");
12525 }
12526 }
12527 }
12528
12529 if let Some(identity) = &tr.identity {
12531 self.write_space();
12532 match identity {
12533 TruncateIdentity::Restart => self.write_keyword("RESTART IDENTITY"),
12534 TruncateIdentity::Continue => self.write_keyword("CONTINUE IDENTITY"),
12535 }
12536 }
12537
12538 if tr.cascade {
12539 self.write_space();
12540 self.write_keyword("CASCADE");
12541 }
12542
12543 if tr.restrict {
12544 self.write_space();
12545 self.write_keyword("RESTRICT");
12546 }
12547
12548 if let Some(ref partition) = tr.partition {
12550 self.write_space();
12551 self.generate_expression(partition)?;
12552 }
12553
12554 Ok(())
12555 }
12556
12557 fn generate_use(&mut self, u: &Use) -> Result<()> {
12558 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
12560 self.write_keyword("DATABASE");
12561 self.write_space();
12562 self.generate_identifier(&u.this)?;
12563 return Ok(());
12564 }
12565
12566 self.write_keyword("USE");
12567
12568 if let Some(kind) = &u.kind {
12569 self.write_space();
12570 match kind {
12571 UseKind::Database => self.write_keyword("DATABASE"),
12572 UseKind::Schema => self.write_keyword("SCHEMA"),
12573 UseKind::Role => self.write_keyword("ROLE"),
12574 UseKind::Warehouse => self.write_keyword("WAREHOUSE"),
12575 UseKind::Catalog => self.write_keyword("CATALOG"),
12576 UseKind::SecondaryRoles => self.write_keyword("SECONDARY ROLES"),
12577 }
12578 }
12579
12580 self.write_space();
12581 if matches!(&u.kind, Some(UseKind::SecondaryRoles)) {
12584 self.write(&u.this.name);
12585 } else {
12586 self.generate_identifier(&u.this)?;
12587 }
12588 Ok(())
12589 }
12590
12591 fn generate_cache(&mut self, c: &Cache) -> Result<()> {
12592 self.write_keyword("CACHE");
12593 if c.lazy {
12594 self.write_space();
12595 self.write_keyword("LAZY");
12596 }
12597 self.write_space();
12598 self.write_keyword("TABLE");
12599 self.write_space();
12600 self.generate_identifier(&c.table)?;
12601
12602 if !c.options.is_empty() {
12604 self.write_space();
12605 self.write_keyword("OPTIONS");
12606 self.write("(");
12607 for (i, (key, value)) in c.options.iter().enumerate() {
12608 if i > 0 {
12609 self.write(", ");
12610 }
12611 self.generate_expression(key)?;
12612 self.write(" = ");
12613 self.generate_expression(value)?;
12614 }
12615 self.write(")");
12616 }
12617
12618 if let Some(query) = &c.query {
12620 self.write_space();
12621 self.write_keyword("AS");
12622 self.write_space();
12623 self.generate_expression(query)?;
12624 }
12625
12626 Ok(())
12627 }
12628
12629 fn generate_uncache(&mut self, u: &Uncache) -> Result<()> {
12630 self.write_keyword("UNCACHE TABLE");
12631 if u.if_exists {
12632 self.write_space();
12633 self.write_keyword("IF EXISTS");
12634 }
12635 self.write_space();
12636 self.generate_identifier(&u.table)?;
12637 Ok(())
12638 }
12639
12640 fn generate_load_data(&mut self, l: &LoadData) -> Result<()> {
12641 self.write_keyword("LOAD DATA");
12642 if l.local {
12643 self.write_space();
12644 self.write_keyword("LOCAL");
12645 }
12646 self.write_space();
12647 self.write_keyword("INPATH");
12648 self.write_space();
12649 self.write("'");
12650 self.write(&l.inpath);
12651 self.write("'");
12652
12653 if l.overwrite {
12654 self.write_space();
12655 self.write_keyword("OVERWRITE");
12656 }
12657
12658 self.write_space();
12659 self.write_keyword("INTO TABLE");
12660 self.write_space();
12661 self.generate_expression(&l.table)?;
12662
12663 if !l.partition.is_empty() {
12665 self.write_space();
12666 self.write_keyword("PARTITION");
12667 self.write("(");
12668 for (i, (col, val)) in l.partition.iter().enumerate() {
12669 if i > 0 {
12670 self.write(", ");
12671 }
12672 self.generate_identifier(col)?;
12673 self.write(" = ");
12674 self.generate_expression(val)?;
12675 }
12676 self.write(")");
12677 }
12678
12679 if let Some(fmt) = &l.input_format {
12681 self.write_space();
12682 self.write_keyword("INPUTFORMAT");
12683 self.write_space();
12684 self.write("'");
12685 self.write(fmt);
12686 self.write("'");
12687 }
12688
12689 if let Some(serde) = &l.serde {
12691 self.write_space();
12692 self.write_keyword("SERDE");
12693 self.write_space();
12694 self.write("'");
12695 self.write(serde);
12696 self.write("'");
12697 }
12698
12699 Ok(())
12700 }
12701
12702 fn generate_pragma(&mut self, p: &Pragma) -> Result<()> {
12703 self.write_keyword("PRAGMA");
12704 self.write_space();
12705
12706 if let Some(schema) = &p.schema {
12708 self.generate_identifier(schema)?;
12709 self.write(".");
12710 }
12711
12712 self.generate_identifier(&p.name)?;
12714
12715 if p.use_assignment_syntax {
12717 self.write(" = ");
12718 if let Some(value) = &p.value {
12719 self.generate_expression(value)?;
12720 } else if let Some(arg) = p.args.first() {
12721 self.generate_expression(arg)?;
12722 }
12723 } else if !p.args.is_empty() {
12724 self.write("(");
12725 for (i, arg) in p.args.iter().enumerate() {
12726 if i > 0 {
12727 self.write(", ");
12728 }
12729 self.generate_expression(arg)?;
12730 }
12731 self.write(")");
12732 }
12733
12734 Ok(())
12735 }
12736
12737 fn generate_grant(&mut self, g: &Grant) -> Result<()> {
12738 self.write_keyword("GRANT");
12739 self.write_space();
12740
12741 for (i, privilege) in g.privileges.iter().enumerate() {
12743 if i > 0 {
12744 self.write(", ");
12745 }
12746 self.write_keyword(&privilege.name);
12747 if !privilege.columns.is_empty() {
12749 self.write("(");
12750 for (j, col) in privilege.columns.iter().enumerate() {
12751 if j > 0 {
12752 self.write(", ");
12753 }
12754 self.write(col);
12755 }
12756 self.write(")");
12757 }
12758 }
12759
12760 self.write_space();
12761 self.write_keyword("ON");
12762 self.write_space();
12763
12764 if let Some(kind) = &g.kind {
12766 self.write_keyword(kind);
12767 self.write_space();
12768 }
12769
12770 {
12772 use crate::dialects::DialectType;
12773 let should_upper = matches!(
12774 self.config.dialect,
12775 Some(DialectType::PostgreSQL)
12776 | Some(DialectType::CockroachDB)
12777 | Some(DialectType::Materialize)
12778 | Some(DialectType::RisingWave)
12779 ) && (g.kind.as_deref() == Some("FUNCTION")
12780 || g.kind.as_deref() == Some("PROCEDURE"));
12781 if should_upper {
12782 use crate::expressions::Identifier;
12783 let upper_id = Identifier {
12784 name: g.securable.name.to_ascii_uppercase(),
12785 quoted: g.securable.quoted,
12786 ..g.securable.clone()
12787 };
12788 self.generate_identifier(&upper_id)?;
12789 } else {
12790 self.generate_identifier(&g.securable)?;
12791 }
12792 }
12793
12794 if !g.function_params.is_empty() {
12796 self.write("(");
12797 for (i, param) in g.function_params.iter().enumerate() {
12798 if i > 0 {
12799 self.write(", ");
12800 }
12801 self.write(param);
12802 }
12803 self.write(")");
12804 }
12805
12806 self.write_space();
12807 self.write_keyword("TO");
12808 self.write_space();
12809
12810 for (i, principal) in g.principals.iter().enumerate() {
12812 if i > 0 {
12813 self.write(", ");
12814 }
12815 if principal.is_role {
12816 self.write_keyword("ROLE");
12817 self.write_space();
12818 } else if principal.is_group {
12819 self.write_keyword("GROUP");
12820 self.write_space();
12821 } else if principal.is_share {
12822 self.write_keyword("SHARE");
12823 self.write_space();
12824 }
12825 self.generate_identifier(&principal.name)?;
12826 }
12827
12828 if g.grant_option {
12830 self.write_space();
12831 self.write_keyword("WITH GRANT OPTION");
12832 }
12833
12834 if let Some(ref principal) = g.as_principal {
12836 self.write_space();
12837 self.write_keyword("AS");
12838 self.write_space();
12839 self.generate_identifier(principal)?;
12840 }
12841
12842 Ok(())
12843 }
12844
12845 fn generate_revoke(&mut self, r: &Revoke) -> Result<()> {
12846 self.write_keyword("REVOKE");
12847 self.write_space();
12848
12849 if r.grant_option {
12851 self.write_keyword("GRANT OPTION FOR");
12852 self.write_space();
12853 }
12854
12855 for (i, privilege) in r.privileges.iter().enumerate() {
12857 if i > 0 {
12858 self.write(", ");
12859 }
12860 self.write_keyword(&privilege.name);
12861 if !privilege.columns.is_empty() {
12863 self.write("(");
12864 for (j, col) in privilege.columns.iter().enumerate() {
12865 if j > 0 {
12866 self.write(", ");
12867 }
12868 self.write(col);
12869 }
12870 self.write(")");
12871 }
12872 }
12873
12874 self.write_space();
12875 self.write_keyword("ON");
12876 self.write_space();
12877
12878 if let Some(kind) = &r.kind {
12880 self.write_keyword(kind);
12881 self.write_space();
12882 }
12883
12884 {
12886 use crate::dialects::DialectType;
12887 let should_upper = matches!(
12888 self.config.dialect,
12889 Some(DialectType::PostgreSQL)
12890 | Some(DialectType::CockroachDB)
12891 | Some(DialectType::Materialize)
12892 | Some(DialectType::RisingWave)
12893 ) && (r.kind.as_deref() == Some("FUNCTION")
12894 || r.kind.as_deref() == Some("PROCEDURE"));
12895 if should_upper {
12896 use crate::expressions::Identifier;
12897 let upper_id = Identifier {
12898 name: r.securable.name.to_ascii_uppercase(),
12899 quoted: r.securable.quoted,
12900 ..r.securable.clone()
12901 };
12902 self.generate_identifier(&upper_id)?;
12903 } else {
12904 self.generate_identifier(&r.securable)?;
12905 }
12906 }
12907
12908 if !r.function_params.is_empty() {
12910 self.write("(");
12911 for (i, param) in r.function_params.iter().enumerate() {
12912 if i > 0 {
12913 self.write(", ");
12914 }
12915 self.write(param);
12916 }
12917 self.write(")");
12918 }
12919
12920 self.write_space();
12921 self.write_keyword("FROM");
12922 self.write_space();
12923
12924 for (i, principal) in r.principals.iter().enumerate() {
12926 if i > 0 {
12927 self.write(", ");
12928 }
12929 if principal.is_role {
12930 self.write_keyword("ROLE");
12931 self.write_space();
12932 } else if principal.is_group {
12933 self.write_keyword("GROUP");
12934 self.write_space();
12935 } else if principal.is_share {
12936 self.write_keyword("SHARE");
12937 self.write_space();
12938 }
12939 self.generate_identifier(&principal.name)?;
12940 }
12941
12942 if r.cascade {
12944 self.write_space();
12945 self.write_keyword("CASCADE");
12946 } else if r.restrict {
12947 self.write_space();
12948 self.write_keyword("RESTRICT");
12949 }
12950
12951 Ok(())
12952 }
12953
12954 fn generate_comment(&mut self, c: &Comment) -> Result<()> {
12955 self.write_keyword("COMMENT");
12956
12957 if c.exists {
12959 self.write_space();
12960 self.write_keyword("IF EXISTS");
12961 }
12962
12963 self.write_space();
12964 self.write_keyword("ON");
12965
12966 if c.materialized {
12968 self.write_space();
12969 self.write_keyword("MATERIALIZED");
12970 }
12971
12972 self.write_space();
12973 self.write_keyword(&c.kind);
12974 self.write_space();
12975
12976 self.generate_expression(&c.this)?;
12978
12979 self.write_space();
12980 self.write_keyword("IS");
12981 self.write_space();
12982
12983 self.generate_expression(&c.expression)?;
12985
12986 Ok(())
12987 }
12988
12989 fn generate_set_statement(&mut self, s: &SetStatement) -> Result<()> {
12990 self.write_keyword("SET");
12991
12992 for (i, item) in s.items.iter().enumerate() {
12993 if i > 0 {
12994 self.write(",");
12995 }
12996 self.write_space();
12997
12998 let has_variable_kind = item.kind.as_deref() == Some("VARIABLE");
13000 if let Some(ref kind) = item.kind {
13001 if has_variable_kind {
13005 if matches!(
13006 self.config.dialect,
13007 Some(DialectType::Spark | DialectType::Databricks | DialectType::DuckDB)
13008 ) {
13009 self.write_keyword("VARIABLE");
13010 self.write_space();
13011 }
13012 } else {
13013 self.write_keyword(kind);
13014 self.write_space();
13015 }
13016 }
13017
13018 let name_str = match &item.name {
13020 Expression::Identifier(id) => Some(id.name.as_str()),
13021 _ => None,
13022 };
13023
13024 let is_transaction = name_str == Some("TRANSACTION");
13025 let is_session_authorization = name_str == Some("SESSION AUTHORIZATION");
13026 let is_character_set = name_str == Some("CHARACTER SET");
13027 let is_names = name_str == Some("NAMES");
13028 let is_collate = name_str == Some("COLLATE");
13029 let is_identity_insert = name_str == Some("IDENTITY_INSERT");
13030 let is_value_only =
13031 matches!(&item.value, Expression::Identifier(id) if id.name.is_empty());
13032
13033 if is_session_authorization {
13034 self.write_keyword("SESSION AUTHORIZATION");
13037 self.write_space();
13038 self.generate_set_value(&item.value)?;
13039 } else if is_transaction {
13040 self.write_keyword("TRANSACTION");
13042 if let Expression::Identifier(id) = &item.value {
13043 if !id.name.is_empty() {
13044 self.write_space();
13045 self.write(&id.name);
13046 }
13047 }
13048 } else if is_character_set {
13049 self.write_keyword("CHARACTER SET");
13051 self.write_space();
13052 self.generate_set_value(&item.value)?;
13053 } else if is_names {
13054 self.write_keyword("NAMES");
13056 self.write_space();
13057 self.generate_set_value(&item.value)?;
13058 } else if is_collate {
13059 self.write_keyword("COLLATE");
13061 self.write_space();
13062 self.generate_set_value(&item.value)?;
13063 } else if is_identity_insert {
13064 self.write_keyword("IDENTITY_INSERT");
13066 self.write_space();
13067 self.generate_identity_insert_value(&item.value)?;
13068 } else if has_variable_kind {
13069 if let Some(ns) = name_str {
13072 self.write(ns);
13073 } else {
13074 self.generate_expression(&item.name)?;
13075 }
13076 self.write(" = ");
13077 self.generate_set_value(&item.value)?;
13078 } else if is_value_only {
13079 self.generate_expression(&item.name)?;
13081 } else if item.no_equals && matches!(self.config.dialect, Some(DialectType::TSQL)) {
13082 self.generate_expression(&item.name)?;
13084 self.write_space();
13085 self.generate_set_value(&item.value)?;
13086 } else {
13087 match &item.name {
13090 Expression::Identifier(id) => {
13091 self.write(&id.name);
13092 }
13093 _ => {
13094 self.generate_expression(&item.name)?;
13095 }
13096 }
13097 self.write(" = ");
13098 self.generate_set_value(&item.value)?;
13099 }
13100 }
13101
13102 Ok(())
13103 }
13104
13105 fn generate_identity_insert_value(&mut self, value: &Expression) -> Result<()> {
13106 if let Expression::Tuple(tuple) = value {
13107 if tuple.expressions.len() == 2 {
13108 self.generate_expression(&tuple.expressions[0])?;
13109 self.write_space();
13110 self.generate_set_value(&tuple.expressions[1])?;
13111 return Ok(());
13112 }
13113 }
13114
13115 self.generate_set_value(value)
13116 }
13117
13118 fn generate_set_value(&mut self, value: &Expression) -> Result<()> {
13121 if let Expression::Identifier(id) = value {
13122 match id.name.as_str() {
13123 "DEFAULT" | "ON" | "OFF" => {
13124 self.write_keyword(&id.name);
13125 return Ok(());
13126 }
13127 _ => {}
13128 }
13129 }
13130 self.generate_expression(value)
13131 }
13132
13133 fn generate_alter_view(&mut self, av: &AlterView) -> Result<()> {
13136 self.write_keyword("ALTER");
13137 if let Some(ref algorithm) = av.algorithm {
13139 self.write_space();
13140 self.write_keyword("ALGORITHM");
13141 self.write(" = ");
13142 self.write_keyword(algorithm);
13143 }
13144 if let Some(ref definer) = av.definer {
13145 self.write_space();
13146 self.write_keyword("DEFINER");
13147 self.write(" = ");
13148 self.write(definer);
13149 }
13150 if let Some(ref sql_security) = av.sql_security {
13151 self.write_space();
13152 self.write_keyword("SQL SECURITY");
13153 self.write(" = ");
13154 self.write_keyword(sql_security);
13155 }
13156 self.write_space();
13157 self.write_keyword("VIEW");
13158 self.write_space();
13159 self.generate_table(&av.name)?;
13160
13161 if !av.columns.is_empty() {
13163 self.write(" (");
13164 for (i, col) in av.columns.iter().enumerate() {
13165 if i > 0 {
13166 self.write(", ");
13167 }
13168 self.generate_identifier(&col.name)?;
13169 if let Some(ref comment) = col.comment {
13170 self.write_space();
13171 self.write_keyword("COMMENT");
13172 self.write(" ");
13173 self.generate_string_literal(comment)?;
13174 }
13175 }
13176 self.write(")");
13177 }
13178
13179 if let Some(ref opt) = av.with_option {
13181 self.write_space();
13182 self.write_keyword("WITH");
13183 self.write_space();
13184 self.write_keyword(opt);
13185 }
13186
13187 for action in &av.actions {
13188 self.write_space();
13189 match action {
13190 AlterViewAction::Rename(new_name) => {
13191 self.write_keyword("RENAME TO");
13192 self.write_space();
13193 self.generate_table(new_name)?;
13194 }
13195 AlterViewAction::OwnerTo(owner) => {
13196 self.write_keyword("OWNER TO");
13197 self.write_space();
13198 self.generate_identifier(owner)?;
13199 }
13200 AlterViewAction::SetSchema(schema) => {
13201 self.write_keyword("SET SCHEMA");
13202 self.write_space();
13203 self.generate_identifier(schema)?;
13204 }
13205 AlterViewAction::SetAuthorization(auth) => {
13206 self.write_keyword("SET AUTHORIZATION");
13207 self.write_space();
13208 self.write(auth);
13209 }
13210 AlterViewAction::AlterColumn { name, action } => {
13211 self.write_keyword("ALTER COLUMN");
13212 self.write_space();
13213 self.generate_identifier(name)?;
13214 self.write_space();
13215 self.generate_alter_column_action(action)?;
13216 }
13217 AlterViewAction::AsSelect(query) => {
13218 self.write_keyword("AS");
13219 self.write_space();
13220 self.generate_expression(query)?;
13221 }
13222 AlterViewAction::SetTblproperties(props) => {
13223 self.write_keyword("SET TBLPROPERTIES");
13224 self.write(" (");
13225 for (i, (key, value)) in props.iter().enumerate() {
13226 if i > 0 {
13227 self.write(", ");
13228 }
13229 self.generate_string_literal(key)?;
13230 self.write("=");
13231 self.generate_string_literal(value)?;
13232 }
13233 self.write(")");
13234 }
13235 AlterViewAction::UnsetTblproperties(keys) => {
13236 self.write_keyword("UNSET TBLPROPERTIES");
13237 self.write(" (");
13238 for (i, key) in keys.iter().enumerate() {
13239 if i > 0 {
13240 self.write(", ");
13241 }
13242 self.generate_string_literal(key)?;
13243 }
13244 self.write(")");
13245 }
13246 }
13247 }
13248
13249 Ok(())
13250 }
13251
13252 fn generate_alter_index(&mut self, ai: &AlterIndex) -> Result<()> {
13253 self.write_keyword("ALTER INDEX");
13254 self.write_space();
13255 self.generate_identifier(&ai.name)?;
13256
13257 if let Some(table) = &ai.table {
13258 self.write_space();
13259 self.write_keyword("ON");
13260 self.write_space();
13261 self.generate_table(table)?;
13262 }
13263
13264 for action in &ai.actions {
13265 self.write_space();
13266 match action {
13267 AlterIndexAction::Rename(new_name) => {
13268 self.write_keyword("RENAME TO");
13269 self.write_space();
13270 self.generate_identifier(new_name)?;
13271 }
13272 AlterIndexAction::SetTablespace(tablespace) => {
13273 self.write_keyword("SET TABLESPACE");
13274 self.write_space();
13275 self.generate_identifier(tablespace)?;
13276 }
13277 AlterIndexAction::Visible(visible) => {
13278 if *visible {
13279 self.write_keyword("VISIBLE");
13280 } else {
13281 self.write_keyword("INVISIBLE");
13282 }
13283 }
13284 }
13285 }
13286
13287 Ok(())
13288 }
13289
13290 fn generate_create_schema(&mut self, cs: &CreateSchema) -> Result<()> {
13291 for comment in &cs.leading_comments {
13293 self.write_formatted_comment(comment);
13294 self.write_space();
13295 }
13296
13297 let saved_athena_hive_context = self.athena_hive_context;
13299 if matches!(
13300 self.config.dialect,
13301 Some(crate::dialects::DialectType::Athena)
13302 ) {
13303 self.athena_hive_context = true;
13304 }
13305
13306 self.write_keyword("CREATE SCHEMA");
13307
13308 if cs.if_not_exists {
13309 self.write_space();
13310 self.write_keyword("IF NOT EXISTS");
13311 }
13312
13313 self.write_space();
13314 for (i, part) in cs.name.iter().enumerate() {
13315 if i > 0 {
13316 self.write(".");
13317 }
13318 self.generate_identifier(part)?;
13319 }
13320
13321 if let Some(ref clone_parts) = cs.clone_from {
13322 self.write_keyword(" CLONE ");
13323 for (i, part) in clone_parts.iter().enumerate() {
13324 if i > 0 {
13325 self.write(".");
13326 }
13327 self.generate_identifier(part)?;
13328 }
13329 }
13330
13331 if let Some(ref at_clause) = cs.at_clause {
13332 self.write_space();
13333 self.generate_expression(at_clause)?;
13334 }
13335
13336 if let Some(auth) = &cs.authorization {
13337 self.write_space();
13338 self.write_keyword("AUTHORIZATION");
13339 self.write_space();
13340 self.generate_identifier(auth)?;
13341 }
13342
13343 let with_properties: Vec<_> = cs
13346 .properties
13347 .iter()
13348 .filter(|p| matches!(p, Expression::Property(_)))
13349 .collect();
13350 let other_properties: Vec<_> = cs
13351 .properties
13352 .iter()
13353 .filter(|p| !matches!(p, Expression::Property(_)))
13354 .collect();
13355
13356 if !with_properties.is_empty() {
13358 self.write_space();
13359 self.write_keyword("WITH");
13360 self.write(" (");
13361 for (i, prop) in with_properties.iter().enumerate() {
13362 if i > 0 {
13363 self.write(", ");
13364 }
13365 self.generate_expression(prop)?;
13366 }
13367 self.write(")");
13368 }
13369
13370 for prop in other_properties {
13372 self.write_space();
13373 self.generate_expression(prop)?;
13374 }
13375
13376 self.athena_hive_context = saved_athena_hive_context;
13378
13379 Ok(())
13380 }
13381
13382 fn generate_drop_schema(&mut self, ds: &DropSchema) -> Result<()> {
13383 self.write_keyword("DROP SCHEMA");
13384
13385 if ds.if_exists {
13386 self.write_space();
13387 self.write_keyword("IF EXISTS");
13388 }
13389
13390 self.write_space();
13391 self.generate_identifier(&ds.name)?;
13392
13393 if ds.cascade {
13394 self.write_space();
13395 self.write_keyword("CASCADE");
13396 }
13397
13398 Ok(())
13399 }
13400
13401 fn generate_drop_namespace(&mut self, dn: &DropNamespace) -> Result<()> {
13402 self.write_keyword("DROP NAMESPACE");
13403
13404 if dn.if_exists {
13405 self.write_space();
13406 self.write_keyword("IF EXISTS");
13407 }
13408
13409 self.write_space();
13410 self.generate_identifier(&dn.name)?;
13411
13412 if dn.cascade {
13413 self.write_space();
13414 self.write_keyword("CASCADE");
13415 }
13416
13417 Ok(())
13418 }
13419
13420 fn generate_create_database(&mut self, cd: &CreateDatabase) -> Result<()> {
13421 self.write_keyword("CREATE DATABASE");
13422
13423 if cd.if_not_exists {
13424 self.write_space();
13425 self.write_keyword("IF NOT EXISTS");
13426 }
13427
13428 self.write_space();
13429 self.generate_identifier(&cd.name)?;
13430
13431 if let Some(ref clone_src) = cd.clone_from {
13432 self.write_keyword(" CLONE ");
13433 self.generate_identifier(clone_src)?;
13434 }
13435
13436 if let Some(ref at_clause) = cd.at_clause {
13438 self.write_space();
13439 self.generate_expression(at_clause)?;
13440 }
13441
13442 for option in &cd.options {
13443 self.write_space();
13444 match option {
13445 DatabaseOption::CharacterSet(charset) => {
13446 self.write_keyword("CHARACTER SET");
13447 self.write(" = ");
13448 self.write(&format!("'{}'", charset));
13449 }
13450 DatabaseOption::Collate(collate) => {
13451 self.write_keyword("COLLATE");
13452 self.write(" = ");
13453 self.write(&format!("'{}'", collate));
13454 }
13455 DatabaseOption::Owner(owner) => {
13456 self.write_keyword("OWNER");
13457 self.write(" = ");
13458 self.generate_identifier(owner)?;
13459 }
13460 DatabaseOption::Template(template) => {
13461 self.write_keyword("TEMPLATE");
13462 self.write(" = ");
13463 self.generate_identifier(template)?;
13464 }
13465 DatabaseOption::Encoding(encoding) => {
13466 self.write_keyword("ENCODING");
13467 self.write(" = ");
13468 self.write(&format!("'{}'", encoding));
13469 }
13470 DatabaseOption::Location(location) => {
13471 self.write_keyword("LOCATION");
13472 self.write(" = ");
13473 self.write(&format!("'{}'", location));
13474 }
13475 }
13476 }
13477
13478 Ok(())
13479 }
13480
13481 fn generate_drop_database(&mut self, dd: &DropDatabase) -> Result<()> {
13482 self.write_keyword("DROP DATABASE");
13483
13484 if dd.if_exists {
13485 self.write_space();
13486 self.write_keyword("IF EXISTS");
13487 }
13488
13489 self.write_space();
13490 self.generate_identifier(&dd.name)?;
13491
13492 if dd.sync {
13493 self.write_space();
13494 self.write_keyword("SYNC");
13495 }
13496
13497 Ok(())
13498 }
13499
13500 fn generate_create_function(&mut self, cf: &CreateFunction) -> Result<()> {
13501 self.write_keyword("CREATE");
13502
13503 if cf.or_alter {
13504 self.write_space();
13505 self.write_keyword("OR ALTER");
13506 } else if cf.or_replace {
13507 self.write_space();
13508 self.write_keyword("OR REPLACE");
13509 }
13510
13511 if cf.temporary {
13512 self.write_space();
13513 self.write_keyword("TEMPORARY");
13514 }
13515
13516 self.write_space();
13517 if cf.is_table_function {
13518 self.write_keyword("TABLE FUNCTION");
13519 } else {
13520 self.write_keyword("FUNCTION");
13521 }
13522
13523 if cf.if_not_exists {
13524 self.write_space();
13525 self.write_keyword("IF NOT EXISTS");
13526 }
13527
13528 self.write_space();
13529 self.generate_table(&cf.name)?;
13530 if cf.has_parens {
13531 let func_multiline = self.config.pretty
13532 && matches!(
13533 self.config.dialect,
13534 Some(crate::dialects::DialectType::TSQL)
13535 | Some(crate::dialects::DialectType::Fabric)
13536 )
13537 && !cf.parameters.is_empty();
13538 if func_multiline {
13539 self.write("(\n");
13540 self.indent_level += 2;
13541 self.write_indent();
13542 self.generate_function_parameters(&cf.parameters)?;
13543 self.write("\n");
13544 self.indent_level -= 2;
13545 self.write(")");
13546 } else {
13547 self.write("(");
13548 self.generate_function_parameters(&cf.parameters)?;
13549 self.write(")");
13550 }
13551 }
13552
13553 let use_multiline = self.config.pretty
13556 && matches!(
13557 self.config.dialect,
13558 Some(crate::dialects::DialectType::BigQuery)
13559 | Some(crate::dialects::DialectType::TSQL)
13560 | Some(crate::dialects::DialectType::Fabric)
13561 );
13562
13563 if cf.language_first {
13564 if let Some(lang) = &cf.language {
13566 if use_multiline {
13567 self.write_newline();
13568 } else {
13569 self.write_space();
13570 }
13571 self.write_keyword("LANGUAGE");
13572 self.write_space();
13573 self.write(lang);
13574 }
13575
13576 if let Some(sql_data) = &cf.sql_data_access {
13578 self.write_space();
13579 match sql_data {
13580 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
13581 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
13582 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
13583 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
13584 }
13585 }
13586
13587 if let Some(ref rtb) = cf.returns_table_body {
13588 if use_multiline {
13589 self.write_newline();
13590 } else {
13591 self.write_space();
13592 }
13593 self.write_keyword("RETURNS");
13594 self.write_space();
13595 self.write(rtb);
13596 } else if let Some(return_type) = &cf.return_type {
13597 if use_multiline {
13598 self.write_newline();
13599 } else {
13600 self.write_space();
13601 }
13602 self.write_keyword("RETURNS");
13603 self.write_space();
13604 self.generate_function_return_type(return_type)?;
13605 }
13606 } else {
13607 let is_duckdb = matches!(
13610 self.config.dialect,
13611 Some(crate::dialects::DialectType::DuckDB)
13612 );
13613 if let Some(ref rtb) = cf.returns_table_body {
13614 if !(is_duckdb && rtb.is_empty()) {
13615 if use_multiline {
13616 self.write_newline();
13617 } else {
13618 self.write_space();
13619 }
13620 self.write_keyword("RETURNS");
13621 self.write_space();
13622 self.write(rtb);
13623 }
13624 } else if let Some(return_type) = &cf.return_type {
13625 if !is_duckdb {
13627 let is_table_return = matches!(return_type, crate::expressions::DataType::Custom { ref name } if name.eq_ignore_ascii_case("TABLE"));
13628 if use_multiline {
13629 self.write_newline();
13630 } else {
13631 self.write_space();
13632 }
13633 self.write_keyword("RETURNS");
13634 self.write_space();
13635 if is_table_return {
13636 self.write_keyword("TABLE");
13637 } else {
13638 self.generate_function_return_type(return_type)?;
13639 }
13640 }
13641 }
13642 }
13643
13644 if !cf.property_order.is_empty() {
13646 let is_bigquery = matches!(
13648 self.config.dialect,
13649 Some(crate::dialects::DialectType::BigQuery)
13650 );
13651 let is_postgres = matches!(
13652 self.config.dialect,
13653 Some(crate::dialects::DialectType::PostgreSQL)
13654 );
13655 let property_order = if is_bigquery {
13656 let mut reordered = Vec::new();
13658 let mut has_as = false;
13659 let mut has_options = false;
13660 for prop in &cf.property_order {
13661 match prop {
13662 FunctionPropertyKind::As => has_as = true,
13663 FunctionPropertyKind::Options => has_options = true,
13664 _ => {}
13665 }
13666 }
13667 if has_as && has_options {
13668 for prop in &cf.property_order {
13670 if *prop != FunctionPropertyKind::As
13671 && *prop != FunctionPropertyKind::Options
13672 {
13673 reordered.push(*prop);
13674 }
13675 }
13676 reordered.push(FunctionPropertyKind::Options);
13677 reordered.push(FunctionPropertyKind::As);
13678 reordered
13679 } else {
13680 cf.property_order.clone()
13681 }
13682 } else if is_postgres
13683 && cf.property_order.contains(&FunctionPropertyKind::As)
13684 && cf.property_order.contains(&FunctionPropertyKind::NullInput)
13685 {
13686 let mut reordered: Vec<_> = cf
13687 .property_order
13688 .iter()
13689 .copied()
13690 .filter(|prop| *prop != FunctionPropertyKind::As)
13691 .collect();
13692 reordered.push(FunctionPropertyKind::As);
13693 reordered
13694 } else {
13695 cf.property_order.clone()
13696 };
13697
13698 for prop in &property_order {
13699 match prop {
13700 FunctionPropertyKind::Set => {
13701 self.generate_function_set_options(cf)?;
13702 }
13703 FunctionPropertyKind::As => {
13704 self.generate_function_body(cf)?;
13705 }
13706 FunctionPropertyKind::Using => {
13707 self.generate_function_using_resources(cf)?;
13708 }
13709 FunctionPropertyKind::Language => {
13710 if !cf.language_first {
13711 if let Some(lang) = &cf.language {
13713 let use_multiline = self.config.pretty
13715 && matches!(
13716 self.config.dialect,
13717 Some(crate::dialects::DialectType::BigQuery)
13718 );
13719 if use_multiline {
13720 self.write_newline();
13721 } else {
13722 self.write_space();
13723 }
13724 self.write_keyword("LANGUAGE");
13725 self.write_space();
13726 self.write(lang);
13727 }
13728 }
13729 }
13730 FunctionPropertyKind::Determinism => {
13731 self.generate_function_determinism(cf)?;
13732 }
13733 FunctionPropertyKind::NullInput => {
13734 self.generate_function_null_input(cf)?;
13735 }
13736 FunctionPropertyKind::Security => {
13737 self.generate_function_security(cf)?;
13738 }
13739 FunctionPropertyKind::SqlDataAccess => {
13740 if !cf.language_first {
13741 self.generate_function_sql_data_access(cf)?;
13743 }
13744 }
13745 FunctionPropertyKind::Options => {
13746 if !cf.options.is_empty() {
13747 self.write_space();
13748 self.generate_options_clause(&cf.options)?;
13749 }
13750 }
13751 FunctionPropertyKind::Environment => {
13752 if !cf.environment.is_empty() {
13753 self.write_space();
13754 self.generate_environment_clause(&cf.environment)?;
13755 }
13756 }
13757 FunctionPropertyKind::Handler => {
13758 if let Some(ref h) = cf.handler {
13759 self.write_space();
13760 self.write_keyword("HANDLER");
13761 if cf.handler_uses_eq {
13762 self.write(" = ");
13763 } else {
13764 self.write_space();
13765 }
13766 self.write("'");
13767 self.write(h);
13768 self.write("'");
13769 }
13770 }
13771 FunctionPropertyKind::RuntimeVersion => {
13772 if let Some(ref runtime_version) = cf.runtime_version {
13773 self.write_space();
13774 self.write_keyword("RUNTIME_VERSION");
13775 self.write("='");
13776 self.write(runtime_version);
13777 self.write("'");
13778 }
13779 }
13780 FunctionPropertyKind::Packages => {
13781 if let Some(ref packages) = cf.packages {
13782 self.write_space();
13783 self.write_keyword("PACKAGES");
13784 self.write("=(");
13785 for (i, package) in packages.iter().enumerate() {
13786 if i > 0 {
13787 self.write(", ");
13788 }
13789 self.write("'");
13790 self.write(package);
13791 self.write("'");
13792 }
13793 self.write(")");
13794 }
13795 }
13796 FunctionPropertyKind::ParameterStyle => {
13797 if let Some(ref ps) = cf.parameter_style {
13798 self.write_space();
13799 self.write_keyword("PARAMETER STYLE");
13800 self.write_space();
13801 self.write_keyword(ps);
13802 }
13803 }
13804 }
13805 }
13806
13807 if !cf.options.is_empty() && !cf.property_order.contains(&FunctionPropertyKind::Options)
13809 {
13810 self.write_space();
13811 self.generate_options_clause(&cf.options)?;
13812 }
13813
13814 if !cf.environment.is_empty()
13816 && !cf
13817 .property_order
13818 .contains(&FunctionPropertyKind::Environment)
13819 {
13820 self.write_space();
13821 self.generate_environment_clause(&cf.environment)?;
13822 }
13823 } else {
13824 if matches!(
13827 self.config.dialect,
13828 Some(crate::dialects::DialectType::BigQuery)
13829 ) {
13830 self.generate_function_determinism(cf)?;
13831 }
13832
13833 let use_multiline = self.config.pretty
13835 && matches!(
13836 self.config.dialect,
13837 Some(crate::dialects::DialectType::BigQuery)
13838 );
13839
13840 if !cf.language_first {
13841 if let Some(lang) = &cf.language {
13842 if use_multiline {
13843 self.write_newline();
13844 } else {
13845 self.write_space();
13846 }
13847 self.write_keyword("LANGUAGE");
13848 self.write_space();
13849 self.write(lang);
13850 }
13851
13852 self.generate_function_sql_data_access(cf)?;
13854 }
13855
13856 if !matches!(
13858 self.config.dialect,
13859 Some(crate::dialects::DialectType::BigQuery)
13860 ) {
13861 self.generate_function_determinism(cf)?;
13862 }
13863
13864 self.generate_function_null_input(cf)?;
13865 self.generate_function_security(cf)?;
13866 self.generate_function_set_options(cf)?;
13867
13868 if !cf.options.is_empty() {
13870 self.write_space();
13871 self.generate_options_clause(&cf.options)?;
13872 }
13873
13874 if !cf.environment.is_empty() {
13876 self.write_space();
13877 self.generate_environment_clause(&cf.environment)?;
13878 }
13879
13880 if let Some(ref h) = cf.handler {
13881 self.write_space();
13882 self.write_keyword("HANDLER");
13883 if cf.handler_uses_eq {
13884 self.write(" = ");
13885 } else {
13886 self.write_space();
13887 }
13888 self.write("'");
13889 self.write(h);
13890 self.write("'");
13891 }
13892
13893 if let Some(ref runtime_version) = cf.runtime_version {
13894 self.write_space();
13895 self.write_keyword("RUNTIME_VERSION");
13896 self.write("='");
13897 self.write(runtime_version);
13898 self.write("'");
13899 }
13900
13901 if let Some(ref packages) = cf.packages {
13902 self.write_space();
13903 self.write_keyword("PACKAGES");
13904 self.write("=(");
13905 for (i, package) in packages.iter().enumerate() {
13906 if i > 0 {
13907 self.write(", ");
13908 }
13909 self.write("'");
13910 self.write(package);
13911 self.write("'");
13912 }
13913 self.write(")");
13914 }
13915
13916 self.generate_function_body(cf)?;
13917 self.generate_function_using_resources(cf)?;
13918 }
13919
13920 Ok(())
13921 }
13922
13923 fn generate_function_return_type(&mut self, return_type: &DataType) -> Result<()> {
13924 if matches!(
13925 self.config.dialect,
13926 Some(crate::dialects::DialectType::PostgreSQL)
13927 ) {
13928 if let DataType::Custom { name } = return_type {
13929 if name.eq_ignore_ascii_case("integer") {
13930 self.write_keyword("INT");
13931 return Ok(());
13932 }
13933 }
13934 }
13935
13936 self.generate_data_type(return_type)
13937 }
13938
13939 fn generate_function_set_options(&mut self, cf: &CreateFunction) -> Result<()> {
13941 for opt in &cf.set_options {
13942 self.write_space();
13943 self.write_keyword("SET");
13944 self.write_space();
13945 self.write(&opt.name);
13946 match &opt.value {
13947 FunctionSetValue::Value { value, use_to } => {
13948 if *use_to {
13949 self.write(" TO ");
13950 } else {
13951 self.write(" = ");
13952 }
13953 self.write(value);
13954 }
13955 FunctionSetValue::FromCurrent => {
13956 self.write_space();
13957 self.write_keyword("FROM CURRENT");
13958 }
13959 }
13960 }
13961 Ok(())
13962 }
13963
13964 fn generate_function_using_resources(&mut self, cf: &CreateFunction) -> Result<()> {
13965 if cf.using_resources.is_empty() {
13966 return Ok(());
13967 }
13968
13969 self.write_space();
13970 self.write_keyword("USING");
13971 for resource in &cf.using_resources {
13972 self.write_space();
13973 self.write_keyword(&resource.kind);
13974 self.write_space();
13975 self.generate_string_literal(&resource.uri)?;
13976 }
13977 Ok(())
13978 }
13979
13980 fn generate_function_body(&mut self, cf: &CreateFunction) -> Result<()> {
13982 if let Some(body) = &cf.body {
13983 self.write_space();
13985 let use_multiline = self.config.pretty
13987 && matches!(
13988 self.config.dialect,
13989 Some(crate::dialects::DialectType::BigQuery)
13990 );
13991 match body {
13992 FunctionBody::Block(block) => {
13993 self.write_keyword("AS");
13994 if matches!(
13995 self.config.dialect,
13996 Some(crate::dialects::DialectType::TSQL)
13997 ) {
13998 self.write(" BEGIN ");
13999 self.write(block);
14000 self.write(" END");
14001 } else if matches!(
14002 self.config.dialect,
14003 Some(crate::dialects::DialectType::PostgreSQL)
14004 ) {
14005 self.write(" $$");
14006 self.write(block);
14007 self.write("$$");
14008 } else {
14009 let escaped = self.escape_block_for_single_quote(block);
14011 if use_multiline {
14013 self.write_newline();
14014 } else {
14015 self.write(" ");
14016 }
14017 self.write("'");
14018 self.write(&escaped);
14019 self.write("'");
14020 }
14021 }
14022 FunctionBody::StringLiteral(s) => {
14023 self.write_keyword("AS");
14024 if use_multiline {
14026 self.write_newline();
14027 } else {
14028 self.write(" ");
14029 }
14030 self.generate_string_literal(s)?;
14031 }
14032 FunctionBody::Expression(expr) => {
14033 self.write_keyword("AS");
14034 self.write_space();
14035 self.generate_expression(expr)?;
14036 }
14037 FunctionBody::External(name) => {
14038 self.write_keyword("EXTERNAL NAME");
14039 self.write(" '");
14040 self.write(name);
14041 self.write("'");
14042 }
14043 FunctionBody::Return(expr) => {
14044 if matches!(
14045 self.config.dialect,
14046 Some(crate::dialects::DialectType::DuckDB)
14047 ) {
14048 self.write_keyword("AS");
14050 self.write_space();
14051 let is_table_return = cf.returns_table_body.is_some()
14053 || matches!(&cf.return_type, Some(crate::expressions::DataType::Custom { ref name }) if name.eq_ignore_ascii_case("TABLE"));
14054 if is_table_return {
14055 self.write_keyword("TABLE");
14056 self.write_space();
14057 }
14058 self.generate_expression(expr)?;
14059 } else {
14060 if self.config.create_function_return_as {
14061 self.write_keyword("AS");
14062 if self.config.pretty
14064 && matches!(
14065 self.config.dialect,
14066 Some(crate::dialects::DialectType::TSQL)
14067 | Some(crate::dialects::DialectType::Fabric)
14068 )
14069 {
14070 self.write_newline();
14071 } else {
14072 self.write_space();
14073 }
14074 }
14075 self.write_keyword("RETURN");
14076 self.write_space();
14077 self.generate_expression(expr)?;
14078 }
14079 }
14080 FunctionBody::Statements(stmts) => {
14081 self.write_keyword("AS");
14082 self.write(" BEGIN ");
14083 for (i, stmt) in stmts.iter().enumerate() {
14084 if i > 0 {
14085 self.write(" ");
14086 }
14087 self.generate_expression(stmt)?;
14088 self.write(";");
14089 }
14090 self.write(" END");
14091 }
14092 FunctionBody::RawBlock(text) => {
14093 self.write_newline();
14094 self.write(text);
14095 }
14096 FunctionBody::DollarQuoted { content, tag } => {
14097 self.write_keyword("AS");
14098 self.write(" ");
14099 let supports_dollar_quoting = matches!(
14101 self.config.dialect,
14102 Some(crate::dialects::DialectType::PostgreSQL)
14103 | Some(crate::dialects::DialectType::Databricks)
14104 | Some(crate::dialects::DialectType::Redshift)
14105 | Some(crate::dialects::DialectType::DuckDB)
14106 );
14107 if supports_dollar_quoting {
14108 self.write("$");
14110 if let Some(t) = tag {
14111 self.write(t);
14112 }
14113 self.write("$");
14114 self.write(content);
14115 self.write("$");
14116 if let Some(t) = tag {
14117 self.write(t);
14118 }
14119 self.write("$");
14120 } else {
14121 let escaped = self.escape_block_for_single_quote(content);
14123 self.write("'");
14124 self.write(&escaped);
14125 self.write("'");
14126 }
14127 }
14128 }
14129 }
14130 Ok(())
14131 }
14132
14133 fn generate_function_determinism(&mut self, cf: &CreateFunction) -> Result<()> {
14135 if let Some(det) = cf.deterministic {
14136 self.write_space();
14137 if matches!(
14138 self.config.dialect,
14139 Some(crate::dialects::DialectType::BigQuery)
14140 ) {
14141 if det {
14143 self.write_keyword("DETERMINISTIC");
14144 } else {
14145 self.write_keyword("NOT DETERMINISTIC");
14146 }
14147 } else {
14148 if det {
14150 self.write_keyword("IMMUTABLE");
14151 } else {
14152 self.write_keyword("VOLATILE");
14153 }
14154 }
14155 }
14156 Ok(())
14157 }
14158
14159 fn generate_function_null_input(&mut self, cf: &CreateFunction) -> Result<()> {
14161 if let Some(returns_null) = cf.returns_null_on_null_input {
14162 self.write_space();
14163 if returns_null {
14164 if cf.strict {
14165 self.write_keyword("STRICT");
14166 } else {
14167 self.write_keyword("RETURNS NULL ON NULL INPUT");
14168 }
14169 } else {
14170 self.write_keyword("CALLED ON NULL INPUT");
14171 }
14172 }
14173 Ok(())
14174 }
14175
14176 fn generate_function_security(&mut self, cf: &CreateFunction) -> Result<()> {
14178 if let Some(security) = &cf.security {
14179 self.write_space();
14180 if matches!(
14182 self.config.dialect,
14183 Some(crate::dialects::DialectType::MySQL)
14184 ) {
14185 self.write_keyword("SQL SECURITY");
14186 } else {
14187 self.write_keyword("SECURITY");
14188 }
14189 self.write_space();
14190 match security {
14191 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
14192 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
14193 FunctionSecurity::None => self.write_keyword("NONE"),
14194 }
14195 }
14196 Ok(())
14197 }
14198
14199 fn generate_function_sql_data_access(&mut self, cf: &CreateFunction) -> Result<()> {
14201 if let Some(sql_data) = &cf.sql_data_access {
14202 self.write_space();
14203 match sql_data {
14204 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
14205 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
14206 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
14207 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
14208 }
14209 }
14210 Ok(())
14211 }
14212
14213 fn generate_function_parameters(&mut self, params: &[FunctionParameter]) -> Result<()> {
14214 for (i, param) in params.iter().enumerate() {
14215 if i > 0 {
14216 self.write(", ");
14217 }
14218
14219 if let Some(mode) = ¶m.mode {
14220 if let Some(text) = ¶m.mode_text {
14221 self.write(text);
14222 } else {
14223 match mode {
14224 ParameterMode::In => self.write_keyword("IN"),
14225 ParameterMode::Out => self.write_keyword("OUT"),
14226 ParameterMode::InOut => self.write_keyword("INOUT"),
14227 ParameterMode::Variadic => self.write_keyword("VARIADIC"),
14228 }
14229 }
14230 self.write_space();
14231 }
14232
14233 if let Some(name) = ¶m.name {
14234 self.generate_identifier(name)?;
14235 let skip_type =
14237 matches!(¶m.data_type, DataType::Custom { name } if name.is_empty());
14238 if !skip_type {
14239 self.write_space();
14240 self.generate_data_type(¶m.data_type)?;
14241 }
14242 } else {
14243 self.generate_data_type(¶m.data_type)?;
14244 }
14245
14246 if let Some(default) = ¶m.default {
14247 if self.config.parameter_default_equals {
14248 self.write(" = ");
14249 } else {
14250 self.write(" DEFAULT ");
14251 }
14252 self.generate_expression(default)?;
14253 }
14254 }
14255
14256 Ok(())
14257 }
14258
14259 fn generate_drop_function(&mut self, df: &DropFunction) -> Result<()> {
14260 self.write_keyword("DROP FUNCTION");
14261
14262 if df.if_exists {
14263 self.write_space();
14264 self.write_keyword("IF EXISTS");
14265 }
14266
14267 self.write_space();
14268 self.generate_table(&df.name)?;
14269
14270 if let Some(params) = &df.parameters {
14271 self.write(" (");
14272 for (i, dt) in params.iter().enumerate() {
14273 if i > 0 {
14274 self.write(", ");
14275 }
14276 self.generate_data_type(dt)?;
14277 }
14278 self.write(")");
14279 }
14280
14281 if df.cascade {
14282 self.write_space();
14283 self.write_keyword("CASCADE");
14284 }
14285
14286 Ok(())
14287 }
14288
14289 fn generate_create_procedure(&mut self, cp: &CreateProcedure) -> Result<()> {
14290 self.write_keyword("CREATE");
14291
14292 if cp.or_alter {
14293 self.write_space();
14294 self.write_keyword("OR ALTER");
14295 } else if cp.or_replace {
14296 self.write_space();
14297 self.write_keyword("OR REPLACE");
14298 }
14299
14300 self.write_space();
14301 if cp.use_proc_keyword {
14302 self.write_keyword("PROC");
14303 } else {
14304 self.write_keyword("PROCEDURE");
14305 }
14306
14307 if cp.if_not_exists {
14308 self.write_space();
14309 self.write_keyword("IF NOT EXISTS");
14310 }
14311
14312 self.write_space();
14313 self.generate_table(&cp.name)?;
14314 if cp.has_parens {
14315 self.write("(");
14316 self.generate_function_parameters(&cp.parameters)?;
14317 self.write(")");
14318 } else if !cp.parameters.is_empty() {
14319 self.write_space();
14321 self.generate_function_parameters(&cp.parameters)?;
14322 }
14323
14324 if let Some(return_type) = &cp.return_type {
14326 self.write_space();
14327 self.write_keyword("RETURNS");
14328 self.write_space();
14329 self.generate_data_type(return_type)?;
14330 }
14331
14332 if let Some(execute_as) = &cp.execute_as {
14334 self.write_space();
14335 self.write_keyword("EXECUTE AS");
14336 self.write_space();
14337 self.write_keyword(execute_as);
14338 }
14339
14340 if let Some(lang) = &cp.language {
14341 self.write_space();
14342 self.write_keyword("LANGUAGE");
14343 self.write_space();
14344 self.write(lang);
14345 }
14346
14347 if let Some(security) = &cp.security {
14348 self.write_space();
14349 self.write_keyword("SECURITY");
14350 self.write_space();
14351 match security {
14352 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
14353 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
14354 FunctionSecurity::None => self.write_keyword("NONE"),
14355 }
14356 }
14357
14358 if !cp.with_options.is_empty() {
14360 self.write_space();
14361 self.write_keyword("WITH");
14362 self.write_space();
14363 for (i, opt) in cp.with_options.iter().enumerate() {
14364 if i > 0 {
14365 self.write(", ");
14366 }
14367 self.write(opt);
14368 }
14369 }
14370
14371 if let Some(body) = &cp.body {
14372 self.write_space();
14373 match body {
14374 FunctionBody::Block(block) => {
14375 self.write_keyword("AS");
14376 if matches!(
14377 self.config.dialect,
14378 Some(crate::dialects::DialectType::TSQL)
14379 ) {
14380 self.write(" BEGIN ");
14381 self.write(block);
14382 self.write(" END");
14383 } else if matches!(
14384 self.config.dialect,
14385 Some(crate::dialects::DialectType::PostgreSQL)
14386 ) {
14387 self.write(" $$");
14388 self.write(block);
14389 self.write("$$");
14390 } else {
14391 let escaped = self.escape_block_for_single_quote(block);
14393 self.write(" '");
14394 self.write(&escaped);
14395 self.write("'");
14396 }
14397 }
14398 FunctionBody::StringLiteral(s) => {
14399 self.write_keyword("AS");
14400 self.write_space();
14401 self.generate_string_literal(s)?;
14402 }
14403 FunctionBody::Expression(expr) => {
14404 self.write_keyword("AS");
14405 self.write_space();
14406 self.generate_expression(expr)?;
14407 }
14408 FunctionBody::External(name) => {
14409 self.write_keyword("EXTERNAL NAME");
14410 self.write(" '");
14411 self.write(name);
14412 self.write("'");
14413 }
14414 FunctionBody::Return(expr) => {
14415 self.write_keyword("RETURN");
14416 self.write_space();
14417 self.generate_expression(expr)?;
14418 }
14419 FunctionBody::Statements(stmts) => {
14420 self.write_keyword("AS");
14421 self.write(" BEGIN ");
14422 for (i, stmt) in stmts.iter().enumerate() {
14423 if i > 0 {
14424 self.write(" ");
14425 }
14426 self.generate_expression(stmt)?;
14427 self.write(";");
14428 }
14429 self.write(" END");
14430 }
14431 FunctionBody::RawBlock(text) => {
14432 self.write_newline();
14433 self.write(text);
14434 }
14435 FunctionBody::DollarQuoted { content, tag } => {
14436 self.write_keyword("AS");
14437 self.write(" ");
14438 let supports_dollar_quoting = matches!(
14440 self.config.dialect,
14441 Some(crate::dialects::DialectType::PostgreSQL)
14442 | Some(crate::dialects::DialectType::Databricks)
14443 | Some(crate::dialects::DialectType::Redshift)
14444 | Some(crate::dialects::DialectType::DuckDB)
14445 );
14446 if supports_dollar_quoting {
14447 self.write("$");
14449 if let Some(t) = tag {
14450 self.write(t);
14451 }
14452 self.write("$");
14453 self.write(content);
14454 self.write("$");
14455 if let Some(t) = tag {
14456 self.write(t);
14457 }
14458 self.write("$");
14459 } else {
14460 let escaped = self.escape_block_for_single_quote(content);
14462 self.write("'");
14463 self.write(&escaped);
14464 self.write("'");
14465 }
14466 }
14467 }
14468 }
14469
14470 Ok(())
14471 }
14472
14473 fn generate_drop_procedure(&mut self, dp: &DropProcedure) -> Result<()> {
14474 self.write_keyword("DROP PROCEDURE");
14475
14476 if dp.if_exists {
14477 self.write_space();
14478 self.write_keyword("IF EXISTS");
14479 }
14480
14481 self.write_space();
14482 self.generate_table(&dp.name)?;
14483
14484 if let Some(params) = &dp.parameters {
14485 self.write(" (");
14486 for (i, dt) in params.iter().enumerate() {
14487 if i > 0 {
14488 self.write(", ");
14489 }
14490 self.generate_data_type(dt)?;
14491 }
14492 self.write(")");
14493 }
14494
14495 if dp.cascade {
14496 self.write_space();
14497 self.write_keyword("CASCADE");
14498 }
14499
14500 Ok(())
14501 }
14502
14503 fn generate_create_sequence(&mut self, cs: &CreateSequence) -> Result<()> {
14504 self.write_keyword("CREATE");
14505
14506 if cs.or_replace {
14507 self.write_space();
14508 self.write_keyword("OR REPLACE");
14509 }
14510
14511 if cs.temporary {
14512 self.write_space();
14513 self.write_keyword("TEMPORARY");
14514 }
14515
14516 self.write_space();
14517 self.write_keyword("SEQUENCE");
14518
14519 if cs.if_not_exists {
14520 self.write_space();
14521 self.write_keyword("IF NOT EXISTS");
14522 }
14523
14524 self.write_space();
14525 self.generate_table(&cs.name)?;
14526
14527 if let Some(as_type) = &cs.as_type {
14529 self.write_space();
14530 self.write_keyword("AS");
14531 self.write_space();
14532 self.generate_data_type(as_type)?;
14533 }
14534
14535 if let Some(comment) = &cs.comment {
14537 self.write_space();
14538 self.write_keyword("COMMENT");
14539 self.write("=");
14540 self.generate_string_literal(comment)?;
14541 }
14542
14543 if !cs.property_order.is_empty() {
14545 for prop in &cs.property_order {
14546 match prop {
14547 SeqPropKind::Start => {
14548 if let Some(start) = cs.start {
14549 self.write_space();
14550 self.write_keyword("START WITH");
14551 self.write(&format!(" {}", start));
14552 }
14553 }
14554 SeqPropKind::Increment => {
14555 if let Some(inc) = cs.increment {
14556 self.write_space();
14557 self.write_keyword("INCREMENT BY");
14558 self.write(&format!(" {}", inc));
14559 }
14560 }
14561 SeqPropKind::Minvalue => {
14562 if let Some(min) = &cs.minvalue {
14563 self.write_space();
14564 match min {
14565 SequenceBound::Value(v) => {
14566 self.write_keyword("MINVALUE");
14567 self.write(&format!(" {}", v));
14568 }
14569 SequenceBound::None => {
14570 self.write_keyword("NO MINVALUE");
14571 }
14572 }
14573 }
14574 }
14575 SeqPropKind::Maxvalue => {
14576 if let Some(max) = &cs.maxvalue {
14577 self.write_space();
14578 match max {
14579 SequenceBound::Value(v) => {
14580 self.write_keyword("MAXVALUE");
14581 self.write(&format!(" {}", v));
14582 }
14583 SequenceBound::None => {
14584 self.write_keyword("NO MAXVALUE");
14585 }
14586 }
14587 }
14588 }
14589 SeqPropKind::Cache => {
14590 if let Some(cache) = cs.cache {
14591 self.write_space();
14592 self.write_keyword("CACHE");
14593 self.write(&format!(" {}", cache));
14594 }
14595 }
14596 SeqPropKind::NoCache => {
14597 self.write_space();
14598 self.write_keyword("NO CACHE");
14599 }
14600 SeqPropKind::NoCacheWord => {
14601 self.write_space();
14602 self.write_keyword("NOCACHE");
14603 }
14604 SeqPropKind::Cycle => {
14605 self.write_space();
14606 self.write_keyword("CYCLE");
14607 }
14608 SeqPropKind::NoCycle => {
14609 self.write_space();
14610 self.write_keyword("NO CYCLE");
14611 }
14612 SeqPropKind::NoCycleWord => {
14613 self.write_space();
14614 self.write_keyword("NOCYCLE");
14615 }
14616 SeqPropKind::OwnedBy => {
14617 if !cs.owned_by_none {
14619 if let Some(owned) = &cs.owned_by {
14620 self.write_space();
14621 self.write_keyword("OWNED BY");
14622 self.write_space();
14623 self.generate_table(owned)?;
14624 }
14625 }
14626 }
14627 SeqPropKind::Order => {
14628 self.write_space();
14629 self.write_keyword("ORDER");
14630 }
14631 SeqPropKind::NoOrder => {
14632 self.write_space();
14633 self.write_keyword("NOORDER");
14634 }
14635 SeqPropKind::Comment => {
14636 }
14638 SeqPropKind::Sharing => {
14639 if let Some(val) = &cs.sharing {
14640 self.write_space();
14641 self.write(&format!("SHARING={}", val));
14642 }
14643 }
14644 SeqPropKind::Keep => {
14645 self.write_space();
14646 self.write_keyword("KEEP");
14647 }
14648 SeqPropKind::NoKeep => {
14649 self.write_space();
14650 self.write_keyword("NOKEEP");
14651 }
14652 SeqPropKind::Scale => {
14653 self.write_space();
14654 self.write_keyword("SCALE");
14655 if let Some(modifier) = &cs.scale_modifier {
14656 if !modifier.is_empty() {
14657 self.write_space();
14658 self.write_keyword(modifier);
14659 }
14660 }
14661 }
14662 SeqPropKind::NoScale => {
14663 self.write_space();
14664 self.write_keyword("NOSCALE");
14665 }
14666 SeqPropKind::Shard => {
14667 self.write_space();
14668 self.write_keyword("SHARD");
14669 if let Some(modifier) = &cs.shard_modifier {
14670 if !modifier.is_empty() {
14671 self.write_space();
14672 self.write_keyword(modifier);
14673 }
14674 }
14675 }
14676 SeqPropKind::NoShard => {
14677 self.write_space();
14678 self.write_keyword("NOSHARD");
14679 }
14680 SeqPropKind::Session => {
14681 self.write_space();
14682 self.write_keyword("SESSION");
14683 }
14684 SeqPropKind::Global => {
14685 self.write_space();
14686 self.write_keyword("GLOBAL");
14687 }
14688 SeqPropKind::NoMinvalueWord => {
14689 self.write_space();
14690 self.write_keyword("NOMINVALUE");
14691 }
14692 SeqPropKind::NoMaxvalueWord => {
14693 self.write_space();
14694 self.write_keyword("NOMAXVALUE");
14695 }
14696 }
14697 }
14698 } else {
14699 if let Some(inc) = cs.increment {
14701 self.write_space();
14702 self.write_keyword("INCREMENT BY");
14703 self.write(&format!(" {}", inc));
14704 }
14705
14706 if let Some(min) = &cs.minvalue {
14707 self.write_space();
14708 match min {
14709 SequenceBound::Value(v) => {
14710 self.write_keyword("MINVALUE");
14711 self.write(&format!(" {}", v));
14712 }
14713 SequenceBound::None => {
14714 self.write_keyword("NO MINVALUE");
14715 }
14716 }
14717 }
14718
14719 if let Some(max) = &cs.maxvalue {
14720 self.write_space();
14721 match max {
14722 SequenceBound::Value(v) => {
14723 self.write_keyword("MAXVALUE");
14724 self.write(&format!(" {}", v));
14725 }
14726 SequenceBound::None => {
14727 self.write_keyword("NO MAXVALUE");
14728 }
14729 }
14730 }
14731
14732 if let Some(start) = cs.start {
14733 self.write_space();
14734 self.write_keyword("START WITH");
14735 self.write(&format!(" {}", start));
14736 }
14737
14738 if let Some(cache) = cs.cache {
14739 self.write_space();
14740 self.write_keyword("CACHE");
14741 self.write(&format!(" {}", cache));
14742 }
14743
14744 if cs.cycle {
14745 self.write_space();
14746 self.write_keyword("CYCLE");
14747 }
14748
14749 if let Some(owned) = &cs.owned_by {
14750 self.write_space();
14751 self.write_keyword("OWNED BY");
14752 self.write_space();
14753 self.generate_table(owned)?;
14754 }
14755 }
14756
14757 Ok(())
14758 }
14759
14760 fn generate_drop_sequence(&mut self, ds: &DropSequence) -> Result<()> {
14761 self.write_keyword("DROP SEQUENCE");
14762
14763 if ds.if_exists {
14764 self.write_space();
14765 self.write_keyword("IF EXISTS");
14766 }
14767
14768 self.write_space();
14769 self.generate_table(&ds.name)?;
14770
14771 if ds.cascade {
14772 self.write_space();
14773 self.write_keyword("CASCADE");
14774 }
14775
14776 Ok(())
14777 }
14778
14779 fn generate_alter_sequence(&mut self, als: &AlterSequence) -> Result<()> {
14780 self.write_keyword("ALTER SEQUENCE");
14781
14782 if als.if_exists {
14783 self.write_space();
14784 self.write_keyword("IF EXISTS");
14785 }
14786
14787 self.write_space();
14788 self.generate_table(&als.name)?;
14789
14790 if let Some(inc) = als.increment {
14791 self.write_space();
14792 self.write_keyword("INCREMENT BY");
14793 self.write(&format!(" {}", inc));
14794 }
14795
14796 if let Some(min) = &als.minvalue {
14797 self.write_space();
14798 match min {
14799 SequenceBound::Value(v) => {
14800 self.write_keyword("MINVALUE");
14801 self.write(&format!(" {}", v));
14802 }
14803 SequenceBound::None => {
14804 self.write_keyword("NO MINVALUE");
14805 }
14806 }
14807 }
14808
14809 if let Some(max) = &als.maxvalue {
14810 self.write_space();
14811 match max {
14812 SequenceBound::Value(v) => {
14813 self.write_keyword("MAXVALUE");
14814 self.write(&format!(" {}", v));
14815 }
14816 SequenceBound::None => {
14817 self.write_keyword("NO MAXVALUE");
14818 }
14819 }
14820 }
14821
14822 if let Some(start) = als.start {
14823 self.write_space();
14824 self.write_keyword("START WITH");
14825 self.write(&format!(" {}", start));
14826 }
14827
14828 if let Some(restart) = &als.restart {
14829 self.write_space();
14830 self.write_keyword("RESTART");
14831 if let Some(val) = restart {
14832 self.write_keyword(" WITH");
14833 self.write(&format!(" {}", val));
14834 }
14835 }
14836
14837 if let Some(cache) = als.cache {
14838 self.write_space();
14839 self.write_keyword("CACHE");
14840 self.write(&format!(" {}", cache));
14841 }
14842
14843 if let Some(cycle) = als.cycle {
14844 self.write_space();
14845 if cycle {
14846 self.write_keyword("CYCLE");
14847 } else {
14848 self.write_keyword("NO CYCLE");
14849 }
14850 }
14851
14852 if let Some(owned) = &als.owned_by {
14853 self.write_space();
14854 self.write_keyword("OWNED BY");
14855 self.write_space();
14856 if let Some(table) = owned {
14857 self.generate_table(table)?;
14858 } else {
14859 self.write_keyword("NONE");
14860 }
14861 }
14862
14863 Ok(())
14864 }
14865
14866 fn generate_create_trigger(&mut self, ct: &CreateTrigger) -> Result<()> {
14867 self.write_keyword("CREATE");
14868
14869 if ct.or_alter {
14870 self.write_space();
14871 self.write_keyword("OR ALTER");
14872 } else if ct.or_replace {
14873 self.write_space();
14874 self.write_keyword("OR REPLACE");
14875 }
14876
14877 if ct.constraint {
14878 self.write_space();
14879 self.write_keyword("CONSTRAINT");
14880 }
14881
14882 self.write_space();
14883 self.write_keyword("TRIGGER");
14884 self.write_space();
14885 self.generate_identifier(&ct.name)?;
14886
14887 self.write_space();
14888 match ct.timing {
14889 TriggerTiming::Before => self.write_keyword("BEFORE"),
14890 TriggerTiming::After => self.write_keyword("AFTER"),
14891 TriggerTiming::InsteadOf => self.write_keyword("INSTEAD OF"),
14892 }
14893
14894 for (i, event) in ct.events.iter().enumerate() {
14896 if i > 0 {
14897 self.write_keyword(" OR");
14898 }
14899 self.write_space();
14900 match event {
14901 TriggerEvent::Insert => self.write_keyword("INSERT"),
14902 TriggerEvent::Update(cols) => {
14903 self.write_keyword("UPDATE");
14904 if let Some(cols) = cols {
14905 self.write_space();
14906 self.write_keyword("OF");
14907 for (j, col) in cols.iter().enumerate() {
14908 if j > 0 {
14909 self.write(",");
14910 }
14911 self.write_space();
14912 self.generate_identifier(col)?;
14913 }
14914 }
14915 }
14916 TriggerEvent::Delete => self.write_keyword("DELETE"),
14917 TriggerEvent::Truncate => self.write_keyword("TRUNCATE"),
14918 }
14919 }
14920
14921 self.write_space();
14922 self.write_keyword("ON");
14923 self.write_space();
14924 self.generate_table(&ct.table)?;
14925
14926 if let Some(ref_clause) = &ct.referencing {
14928 self.write_space();
14929 self.write_keyword("REFERENCING");
14930 if let Some(old_table) = &ref_clause.old_table {
14931 self.write_space();
14932 self.write_keyword("OLD TABLE AS");
14933 self.write_space();
14934 self.generate_identifier(old_table)?;
14935 }
14936 if let Some(new_table) = &ref_clause.new_table {
14937 self.write_space();
14938 self.write_keyword("NEW TABLE AS");
14939 self.write_space();
14940 self.generate_identifier(new_table)?;
14941 }
14942 if let Some(old_row) = &ref_clause.old_row {
14943 self.write_space();
14944 self.write_keyword("OLD ROW AS");
14945 self.write_space();
14946 self.generate_identifier(old_row)?;
14947 }
14948 if let Some(new_row) = &ref_clause.new_row {
14949 self.write_space();
14950 self.write_keyword("NEW ROW AS");
14951 self.write_space();
14952 self.generate_identifier(new_row)?;
14953 }
14954 }
14955
14956 if let Some(deferrable) = ct.deferrable {
14958 self.write_space();
14959 if deferrable {
14960 self.write_keyword("DEFERRABLE");
14961 } else {
14962 self.write_keyword("NOT DEFERRABLE");
14963 }
14964 }
14965
14966 if let Some(initially) = ct.initially_deferred {
14967 self.write_space();
14968 self.write_keyword("INITIALLY");
14969 self.write_space();
14970 if initially {
14971 self.write_keyword("DEFERRED");
14972 } else {
14973 self.write_keyword("IMMEDIATE");
14974 }
14975 }
14976
14977 if let Some(for_each) = ct.for_each {
14978 self.write_space();
14979 self.write_keyword("FOR EACH");
14980 self.write_space();
14981 match for_each {
14982 TriggerForEach::Row => self.write_keyword("ROW"),
14983 TriggerForEach::Statement => self.write_keyword("STATEMENT"),
14984 }
14985 }
14986
14987 if let Some(when) = &ct.when {
14989 self.write_space();
14990 self.write_keyword("WHEN");
14991 if ct.when_paren {
14992 self.write(" (");
14993 self.generate_expression(when)?;
14994 self.write(")");
14995 } else {
14996 self.write_space();
14997 self.generate_expression(when)?;
14998 }
14999 }
15000
15001 self.write_space();
15003 match &ct.body {
15004 TriggerBody::Execute { function, args } => {
15005 self.write_keyword("EXECUTE FUNCTION");
15006 self.write_space();
15007 self.generate_table(function)?;
15008 self.write("(");
15009 for (i, arg) in args.iter().enumerate() {
15010 if i > 0 {
15011 self.write(", ");
15012 }
15013 self.generate_expression(arg)?;
15014 }
15015 self.write(")");
15016 }
15017 TriggerBody::Block(block) => {
15018 self.write_keyword("BEGIN");
15019 self.write_space();
15020 self.write(block);
15021 self.write_space();
15022 self.write_keyword("END");
15023 }
15024 }
15025
15026 Ok(())
15027 }
15028
15029 fn generate_drop_trigger(&mut self, dt: &DropTrigger) -> Result<()> {
15030 self.write_keyword("DROP TRIGGER");
15031
15032 if dt.if_exists {
15033 self.write_space();
15034 self.write_keyword("IF EXISTS");
15035 }
15036
15037 self.write_space();
15038 self.generate_identifier(&dt.name)?;
15039
15040 if let Some(table) = &dt.table {
15041 self.write_space();
15042 self.write_keyword("ON");
15043 self.write_space();
15044 self.generate_table(table)?;
15045 }
15046
15047 if dt.cascade {
15048 self.write_space();
15049 self.write_keyword("CASCADE");
15050 }
15051
15052 Ok(())
15053 }
15054
15055 fn generate_create_type(&mut self, ct: &CreateType) -> Result<()> {
15056 self.write_keyword("CREATE TYPE");
15057
15058 if ct.if_not_exists {
15059 self.write_space();
15060 self.write_keyword("IF NOT EXISTS");
15061 }
15062
15063 self.write_space();
15064 self.generate_table(&ct.name)?;
15065
15066 if let TypeDefinition::Base {
15067 input,
15068 output,
15069 internallength,
15070 } = &ct.definition
15071 {
15072 if input.is_empty() && output.is_empty() && internallength.is_none() {
15073 return Ok(());
15074 }
15075 }
15076
15077 self.write_space();
15078 self.write_keyword("AS");
15079 self.write_space();
15080
15081 match &ct.definition {
15082 TypeDefinition::Enum(values) => {
15083 self.write_keyword("ENUM");
15084 self.write(" (");
15085 for (i, val) in values.iter().enumerate() {
15086 if i > 0 {
15087 self.write(", ");
15088 }
15089 self.write(&format!("'{}'", val));
15090 }
15091 self.write(")");
15092 }
15093 TypeDefinition::Composite(attrs) => {
15094 self.write("(");
15095 for (i, attr) in attrs.iter().enumerate() {
15096 if i > 0 {
15097 self.write(", ");
15098 }
15099 self.generate_identifier(&attr.name)?;
15100 self.write_space();
15101 self.generate_data_type(&attr.data_type)?;
15102 if let Some(collate) = &attr.collate {
15103 self.write_space();
15104 self.write_keyword("COLLATE");
15105 self.write_space();
15106 self.generate_identifier(collate)?;
15107 }
15108 }
15109 self.write(")");
15110 }
15111 TypeDefinition::Range {
15112 subtype,
15113 subtype_diff,
15114 canonical,
15115 } => {
15116 self.write_keyword("RANGE");
15117 self.write(" (");
15118 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
15119 self.write("subtype");
15120 } else {
15121 self.write_keyword("SUBTYPE");
15122 }
15123 self.write(" = ");
15124 self.generate_data_type(subtype)?;
15125 if let Some(diff) = subtype_diff {
15126 self.write(", ");
15127 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
15128 self.write("subtype_diff");
15129 } else {
15130 self.write_keyword("SUBTYPE_DIFF");
15131 }
15132 self.write(" = ");
15133 self.write(diff);
15134 }
15135 if let Some(canon) = canonical {
15136 self.write(", ");
15137 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
15138 self.write("canonical");
15139 } else {
15140 self.write_keyword("CANONICAL");
15141 }
15142 self.write(" = ");
15143 self.write(canon);
15144 }
15145 self.write(")");
15146 }
15147 TypeDefinition::Base {
15148 input,
15149 output,
15150 internallength,
15151 } => {
15152 self.write("(");
15153 self.write_keyword("INPUT");
15154 self.write(" = ");
15155 self.write(input);
15156 self.write(", ");
15157 self.write_keyword("OUTPUT");
15158 self.write(" = ");
15159 self.write(output);
15160 if let Some(len) = internallength {
15161 self.write(", ");
15162 self.write_keyword("INTERNALLENGTH");
15163 self.write(" = ");
15164 self.write(&len.to_string());
15165 }
15166 self.write(")");
15167 }
15168 TypeDefinition::Domain {
15169 base_type,
15170 default,
15171 constraints,
15172 } => {
15173 self.generate_data_type(base_type)?;
15174 if let Some(def) = default {
15175 self.write_space();
15176 self.write_keyword("DEFAULT");
15177 self.write_space();
15178 self.generate_expression(def)?;
15179 }
15180 for constr in constraints {
15181 self.write_space();
15182 if let Some(name) = &constr.name {
15183 self.write_keyword("CONSTRAINT");
15184 self.write_space();
15185 self.generate_identifier(name)?;
15186 self.write_space();
15187 }
15188 self.write_keyword("CHECK");
15189 self.write(" (");
15190 self.generate_expression(&constr.check)?;
15191 self.write(")");
15192 }
15193 }
15194 }
15195
15196 Ok(())
15197 }
15198
15199 fn generate_create_task(&mut self, task: &crate::expressions::CreateTask) -> Result<()> {
15200 self.write_keyword("CREATE");
15201 if task.or_replace {
15202 self.write_space();
15203 self.write_keyword("OR REPLACE");
15204 }
15205 self.write_space();
15206 self.write_keyword("TASK");
15207 if task.if_not_exists {
15208 self.write_space();
15209 self.write_keyword("IF NOT EXISTS");
15210 }
15211 self.write_space();
15212 self.write(&task.name);
15213 if !task.properties.is_empty() {
15214 if !task.properties.starts_with('\n') && !task.properties.starts_with(' ') {
15216 self.write_space();
15217 }
15218 self.write(&task.properties);
15219 }
15220 self.write_space();
15221 self.write_keyword("AS");
15222 self.write_space();
15223 self.generate_expression(&task.body)?;
15224 Ok(())
15225 }
15226
15227 fn generate_try_catch(&mut self, try_catch: &TryCatch) -> Result<()> {
15228 self.write_keyword("BEGIN TRY");
15229 self.generate_tsql_block_statements(&try_catch.try_body)?;
15230 self.write_keyword("END TRY");
15231
15232 if let Some(catch_body) = &try_catch.catch_body {
15233 if self.config.pretty {
15234 self.write_newline();
15235 self.write_indent();
15236 } else {
15237 self.write_space();
15238 }
15239 self.write_keyword("BEGIN CATCH");
15240 self.generate_tsql_block_statements(catch_body)?;
15241 self.write_keyword("END CATCH");
15242 }
15243
15244 Ok(())
15245 }
15246
15247 fn generate_tsql_block_statements(&mut self, statements: &[Expression]) -> Result<()> {
15248 if statements.is_empty() {
15249 self.write_space();
15250 return Ok(());
15251 }
15252
15253 if self.config.pretty {
15254 self.indent_level += 1;
15255 for stmt in statements {
15256 self.write_newline();
15257 self.write_indent();
15258 self.generate_expression(stmt)?;
15259 self.write(";");
15260 }
15261 self.indent_level -= 1;
15262 self.write_newline();
15263 self.write_indent();
15264 } else {
15265 self.write_space();
15266 for (i, stmt) in statements.iter().enumerate() {
15267 if i > 0 {
15268 self.write_space();
15269 }
15270 self.generate_expression(stmt)?;
15271 self.write(";");
15272 }
15273 self.write_space();
15274 }
15275
15276 Ok(())
15277 }
15278
15279 fn generate_drop_type(&mut self, dt: &DropType) -> Result<()> {
15280 self.write_keyword("DROP TYPE");
15281
15282 if dt.if_exists {
15283 self.write_space();
15284 self.write_keyword("IF EXISTS");
15285 }
15286
15287 self.write_space();
15288 self.generate_table(&dt.name)?;
15289
15290 if dt.cascade {
15291 self.write_space();
15292 self.write_keyword("CASCADE");
15293 }
15294
15295 Ok(())
15296 }
15297
15298 fn generate_describe(&mut self, d: &Describe) -> Result<()> {
15299 let saved_athena_hive_context = self.athena_hive_context;
15301 if matches!(
15302 self.config.dialect,
15303 Some(crate::dialects::DialectType::Athena)
15304 ) {
15305 self.athena_hive_context = true;
15306 }
15307
15308 for comment in &d.leading_comments {
15310 self.write_formatted_comment(comment);
15311 self.write(" ");
15312 }
15313
15314 self.write_keyword("DESCRIBE");
15315
15316 if d.extended {
15317 self.write_space();
15318 self.write_keyword("EXTENDED");
15319 } else if d.formatted {
15320 self.write_space();
15321 self.write_keyword("FORMATTED");
15322 }
15323
15324 if let Some(ref style) = d.style {
15326 self.write_space();
15327 self.write_keyword(style);
15328 }
15329
15330 let should_output_kind = match self.config.dialect {
15332 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
15334 false
15335 }
15336 Some(DialectType::Snowflake) => true,
15338 _ => d.kind.is_some(),
15339 };
15340 if should_output_kind {
15341 if let Some(ref kind) = d.kind {
15342 self.write_space();
15343 self.write_keyword(kind);
15344 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
15345 self.write_space();
15346 self.write_keyword("TABLE");
15347 }
15348 }
15349
15350 self.write_space();
15351 self.generate_expression(&d.target)?;
15352
15353 if !d.params.is_empty() {
15355 self.write("(");
15356 for (i, param) in d.params.iter().enumerate() {
15357 if i > 0 {
15358 self.write(", ");
15359 }
15360 self.write(param);
15361 }
15362 self.write(")");
15363 }
15364
15365 if let Some(ref partition) = d.partition {
15367 self.write_space();
15368 self.generate_expression(partition)?;
15369 }
15370
15371 if d.as_json {
15373 self.write_space();
15374 self.write_keyword("AS JSON");
15375 }
15376
15377 for (name, value) in &d.properties {
15379 self.write_space();
15380 self.write(name);
15381 self.write("=");
15382 self.write(value);
15383 }
15384
15385 self.athena_hive_context = saved_athena_hive_context;
15387
15388 Ok(())
15389 }
15390
15391 fn generate_show(&mut self, s: &Show) -> Result<()> {
15394 self.write_keyword("SHOW");
15395 self.write_space();
15396
15397 let show_terse = s.terse
15400 && !matches!(
15401 s.this.as_str(),
15402 "PRIMARY KEYS" | "UNIQUE KEYS" | "IMPORTED KEYS"
15403 );
15404 if show_terse {
15405 self.write_keyword("TERSE");
15406 self.write_space();
15407 }
15408
15409 self.write_keyword(&s.this);
15411
15412 if let Some(ref target_expr) = s.target {
15414 self.write_space();
15415 self.generate_expression(target_expr)?;
15416 }
15417
15418 if s.history {
15420 self.write_space();
15421 self.write_keyword("HISTORY");
15422 }
15423
15424 if let Some(ref for_target) = s.for_target {
15426 self.write_space();
15427 self.write_keyword("FOR");
15428 self.write_space();
15429 self.generate_expression(for_target)?;
15430 }
15431
15432 use crate::dialects::DialectType;
15436 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
15437 let is_mysql = matches!(self.config.dialect, Some(DialectType::MySQL));
15438 let mysql_tables_scope_as_from = is_mysql
15439 && matches!(s.this.as_str(), "TABLES" | "FULL TABLES")
15440 && s.scope_kind.as_deref() == Some("SCHEMA")
15441 && s.scope.is_some()
15442 && s.from.is_none();
15443
15444 if !is_snowflake && s.from.is_some() {
15445 if let Some(ref scope_kind) = s.scope_kind {
15449 self.write_space();
15450 self.write_keyword("IN");
15451 self.write_space();
15452 self.write_keyword(scope_kind);
15453 if let Some(ref scope) = s.scope {
15454 self.write_space();
15455 self.generate_expression(scope)?;
15456 }
15457 } else if let Some(ref scope) = s.scope {
15458 self.write_space();
15459 self.write_keyword("IN");
15460 self.write_space();
15461 self.generate_expression(scope)?;
15462 }
15463
15464 if let Some(ref from) = s.from {
15466 self.write_space();
15467 self.write_keyword("FROM");
15468 self.write_space();
15469 self.generate_expression(from)?;
15470 }
15471
15472 if let Some(ref db) = s.db {
15474 self.write_space();
15475 self.write_keyword("FROM");
15476 self.write_space();
15477 self.generate_expression(db)?;
15478 }
15479
15480 if let Some(ref like) = s.like {
15482 self.write_space();
15483 self.write_keyword("LIKE");
15484 self.write_space();
15485 self.generate_expression(like)?;
15486 }
15487 } else {
15488 if let Some(ref like) = s.like {
15492 self.write_space();
15493 self.write_keyword("LIKE");
15494 self.write_space();
15495 self.generate_expression(like)?;
15496 }
15497
15498 if mysql_tables_scope_as_from {
15500 self.write_space();
15501 self.write_keyword("FROM");
15502 self.write_space();
15503 self.generate_expression(s.scope.as_ref().unwrap())?;
15504 } else if let Some(ref scope_kind) = s.scope_kind {
15505 self.write_space();
15506 self.write_keyword("IN");
15507 self.write_space();
15508 self.write_keyword(scope_kind);
15509 if let Some(ref scope) = s.scope {
15510 self.write_space();
15511 self.generate_expression(scope)?;
15512 }
15513 } else if let Some(ref scope) = s.scope {
15514 self.write_space();
15515 self.write_keyword("IN");
15516 self.write_space();
15517 self.generate_expression(scope)?;
15518 }
15519 }
15520
15521 if let Some(ref starts_with) = s.starts_with {
15523 self.write_space();
15524 self.write_keyword("STARTS WITH");
15525 self.write_space();
15526 self.generate_expression(starts_with)?;
15527 }
15528
15529 if let Some(ref limit) = s.limit {
15531 self.write_space();
15532 self.generate_limit(limit)?;
15533 }
15534
15535 if is_snowflake {
15537 if let Some(ref from) = s.from {
15538 self.write_space();
15539 self.write_keyword("FROM");
15540 self.write_space();
15541 self.generate_expression(from)?;
15542 }
15543 }
15544
15545 if let Some(ref where_clause) = s.where_clause {
15547 self.write_space();
15548 self.write_keyword("WHERE");
15549 self.write_space();
15550 self.generate_expression(where_clause)?;
15551 }
15552
15553 if let Some(is_mutex) = s.mutex {
15555 self.write_space();
15556 if is_mutex {
15557 self.write_keyword("MUTEX");
15558 } else {
15559 self.write_keyword("STATUS");
15560 }
15561 }
15562
15563 if !s.privileges.is_empty() {
15565 self.write_space();
15566 self.write_keyword("WITH PRIVILEGES");
15567 self.write_space();
15568 for (i, priv_name) in s.privileges.iter().enumerate() {
15569 if i > 0 {
15570 self.write(", ");
15571 }
15572 self.write_keyword(priv_name);
15573 }
15574 }
15575
15576 Ok(())
15577 }
15578
15579 fn generate_literal(&mut self, lit: &Literal) -> Result<()> {
15582 use crate::dialects::DialectType;
15583 match lit {
15584 Literal::String(s) => {
15585 self.generate_string_literal(s)?;
15586 }
15587 Literal::Number(n) => {
15588 if matches!(self.config.dialect, Some(DialectType::MySQL))
15589 && n.len() > 2
15590 && (n.starts_with("0x") || n.starts_with("0X"))
15591 && !n[2..].chars().all(|c| c.is_ascii_hexdigit())
15592 {
15593 return self.generate_identifier(&Identifier {
15594 name: n.clone(),
15595 quoted: true,
15596 trailing_comments: Vec::new(),
15597 span: None,
15598 });
15599 }
15600 let n = if n.contains('_')
15604 && !matches!(
15605 self.config.dialect,
15606 Some(DialectType::ClickHouse)
15607 | Some(DialectType::DuckDB)
15608 | Some(DialectType::PostgreSQL)
15609 | Some(DialectType::Hive)
15610 | Some(DialectType::Spark)
15611 | Some(DialectType::Databricks)
15612 ) {
15613 std::borrow::Cow::Owned(n.replace('_', ""))
15614 } else {
15615 std::borrow::Cow::Borrowed(n.as_str())
15616 };
15617 if n.starts_with('.') {
15620 self.write("0");
15621 self.write(&n);
15622 } else if n.starts_with("-.") {
15623 self.write("-0");
15625 self.write(&n[1..]);
15626 } else {
15627 self.write(&n);
15628 }
15629 }
15630 Literal::HexString(h) => {
15631 match self.config.dialect {
15633 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
15634 self.write("0x");
15635 self.write(h);
15636 return Ok(());
15637 }
15638 Some(DialectType::Spark)
15639 | Some(DialectType::Databricks)
15640 | Some(DialectType::Teradata) => self.write("X'"),
15641 _ => self.write("x'"),
15642 }
15643 self.write(h);
15644 self.write("'");
15645 }
15646 Literal::HexNumber(h) => {
15647 match self.config.dialect {
15651 Some(DialectType::BigQuery)
15652 | Some(DialectType::ClickHouse)
15653 | Some(DialectType::TSQL)
15654 | Some(DialectType::Fabric) => {
15655 self.write("0x");
15656 self.write(h);
15657 }
15658 _ => {
15659 if let Ok(val) = u64::from_str_radix(h, 16) {
15661 self.write(&val.to_string());
15662 } else {
15663 self.write("0x");
15665 self.write(h);
15666 }
15667 }
15668 }
15669 }
15670 Literal::BitString(b) => {
15671 self.write("B'");
15673 self.write(b);
15674 self.write("'");
15675 }
15676 Literal::ByteString(b) => {
15677 self.write("b'");
15679 self.write_escaped_byte_string(b);
15681 self.write("'");
15682 }
15683 Literal::NationalString(s) => {
15684 let keep_n_prefix = matches!(
15687 self.config.dialect,
15688 Some(DialectType::TSQL)
15689 | Some(DialectType::Oracle)
15690 | Some(DialectType::MySQL)
15691 | None
15692 );
15693 if keep_n_prefix {
15694 self.write("N'");
15695 } else {
15696 self.write("'");
15697 }
15698 self.write(s);
15699 self.write("'");
15700 }
15701 Literal::Date(d) => {
15702 self.generate_date_literal(d)?;
15703 }
15704 Literal::Time(t) => {
15705 self.generate_time_literal(t)?;
15706 }
15707 Literal::Timestamp(ts) => {
15708 self.generate_timestamp_literal(ts)?;
15709 }
15710 Literal::Datetime(dt) => {
15711 self.generate_datetime_literal(dt)?;
15712 }
15713 Literal::TripleQuotedString(s, _quote_char) => {
15714 if matches!(
15716 self.config.dialect,
15717 Some(crate::dialects::DialectType::BigQuery)
15718 | Some(crate::dialects::DialectType::DuckDB)
15719 | Some(crate::dialects::DialectType::Snowflake)
15720 | Some(crate::dialects::DialectType::Spark)
15721 | Some(crate::dialects::DialectType::Hive)
15722 | Some(crate::dialects::DialectType::Presto)
15723 | Some(crate::dialects::DialectType::Trino)
15724 | Some(crate::dialects::DialectType::PostgreSQL)
15725 | Some(crate::dialects::DialectType::MySQL)
15726 | Some(crate::dialects::DialectType::Redshift)
15727 | Some(crate::dialects::DialectType::TSQL)
15728 | Some(crate::dialects::DialectType::Oracle)
15729 | Some(crate::dialects::DialectType::ClickHouse)
15730 | Some(crate::dialects::DialectType::Databricks)
15731 | Some(crate::dialects::DialectType::SQLite)
15732 ) {
15733 self.generate_string_literal(s)?;
15734 } else {
15735 let quotes = format!("{0}{0}{0}", _quote_char);
15737 self.write("es);
15738 self.write(s);
15739 self.write("es);
15740 }
15741 }
15742 Literal::EscapeString(s) => {
15743 use crate::dialects::DialectType;
15747 let content = if let Some(c) = s.strip_prefix("e:") {
15748 c
15749 } else if let Some(c) = s.strip_prefix("E:") {
15750 c
15751 } else {
15752 s.as_str()
15753 };
15754
15755 if matches!(
15757 self.config.dialect,
15758 Some(DialectType::MySQL) | Some(DialectType::TiDB)
15759 ) {
15760 self.write("'");
15761 self.write(&content.replace('\'', "''"));
15762 self.write("'");
15763 } else {
15764 let prefix = if matches!(
15766 self.config.dialect,
15767 Some(DialectType::SingleStore)
15768 | Some(DialectType::DuckDB)
15769 | Some(DialectType::PostgreSQL)
15770 | Some(DialectType::CockroachDB)
15771 | Some(DialectType::Materialize)
15772 | Some(DialectType::RisingWave)
15773 ) {
15774 "e'"
15775 } else {
15776 "E'"
15777 };
15778
15779 let normalized = content.replace("\\'", "''");
15781 self.write(prefix);
15782 self.write(&normalized);
15783 self.write("'");
15784 }
15785 }
15786 Literal::DollarString(s) => {
15787 use crate::dialects::DialectType;
15790 let (_tag, content) = crate::tokens::parse_dollar_string_token(s);
15792 let escape_backslash = matches!(
15794 self.config.dialect,
15795 Some(DialectType::ClickHouse) | Some(DialectType::Snowflake)
15796 );
15797 let use_backslash_quote =
15801 matches!(self.config.dialect, Some(DialectType::Snowflake));
15802
15803 let mut escaped = String::with_capacity(content.len() + 4);
15804 for ch in content.chars() {
15805 if escape_backslash && ch == '\\' {
15806 escaped.push('\\');
15808 escaped.push('\\');
15809 } else if ch == '\'' {
15810 if use_backslash_quote {
15811 escaped.push('\\');
15812 escaped.push('\'');
15813 } else {
15814 escaped.push('\'');
15815 escaped.push('\'');
15816 }
15817 } else {
15818 escaped.push(ch);
15819 }
15820 }
15821 self.write("'");
15822 self.write(&escaped);
15823 self.write("'");
15824 }
15825 Literal::RawString(s) => {
15826 use crate::dialects::DialectType;
15832
15833 let escape_backslash = matches!(
15835 self.config.dialect,
15836 Some(DialectType::BigQuery)
15837 | Some(DialectType::MySQL)
15838 | Some(DialectType::SingleStore)
15839 | Some(DialectType::TiDB)
15840 | Some(DialectType::Hive)
15841 | Some(DialectType::Spark)
15842 | Some(DialectType::Databricks)
15843 | Some(DialectType::Drill)
15844 | Some(DialectType::Snowflake)
15845 | Some(DialectType::Redshift)
15846 | Some(DialectType::ClickHouse)
15847 );
15848
15849 let backslash_escapes_quote = matches!(
15852 self.config.dialect,
15853 Some(DialectType::BigQuery)
15854 | Some(DialectType::Hive)
15855 | Some(DialectType::Spark)
15856 | Some(DialectType::Databricks)
15857 | Some(DialectType::Drill)
15858 | Some(DialectType::Snowflake)
15859 | Some(DialectType::Redshift)
15860 );
15861
15862 let supports_escape_sequences = escape_backslash;
15865
15866 let mut escaped = String::with_capacity(s.len() + 4);
15867 for ch in s.chars() {
15868 if escape_backslash && ch == '\\' {
15869 escaped.push('\\');
15871 escaped.push('\\');
15872 } else if ch == '\'' {
15873 if backslash_escapes_quote {
15874 escaped.push('\\');
15876 escaped.push('\'');
15877 } else {
15878 escaped.push('\'');
15880 escaped.push('\'');
15881 }
15882 } else if supports_escape_sequences {
15883 match ch {
15886 '\n' => {
15887 escaped.push('\\');
15888 escaped.push('n');
15889 }
15890 '\r' => {
15891 escaped.push('\\');
15892 escaped.push('r');
15893 }
15894 '\t' => {
15895 escaped.push('\\');
15896 escaped.push('t');
15897 }
15898 '\x07' => {
15899 escaped.push('\\');
15900 escaped.push('a');
15901 }
15902 '\x08' => {
15903 escaped.push('\\');
15904 escaped.push('b');
15905 }
15906 '\x0C' => {
15907 escaped.push('\\');
15908 escaped.push('f');
15909 }
15910 '\x0B' => {
15911 escaped.push('\\');
15912 escaped.push('v');
15913 }
15914 _ => escaped.push(ch),
15915 }
15916 } else {
15917 escaped.push(ch);
15918 }
15919 }
15920 self.write("'");
15921 self.write(&escaped);
15922 self.write("'");
15923 }
15924 }
15925 Ok(())
15926 }
15927
15928 fn generate_date_literal(&mut self, d: &str) -> Result<()> {
15930 use crate::dialects::DialectType;
15931
15932 match self.config.dialect {
15933 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
15935 self.write("CAST('");
15936 self.write(d);
15937 self.write("' AS DATE)");
15938 }
15939 Some(DialectType::BigQuery) => {
15942 self.write("CAST('");
15943 self.write(d);
15944 self.write("' AS DATE)");
15945 }
15946 Some(DialectType::Exasol) => {
15949 self.write("CAST('");
15950 self.write(d);
15951 self.write("' AS DATE)");
15952 }
15953 Some(DialectType::Snowflake) => {
15956 self.write("CAST('");
15957 self.write(d);
15958 self.write("' AS DATE)");
15959 }
15960 Some(DialectType::PostgreSQL)
15962 | Some(DialectType::MySQL)
15963 | Some(DialectType::SingleStore)
15964 | Some(DialectType::TiDB)
15965 | Some(DialectType::Redshift) => {
15966 self.write("CAST('");
15967 self.write(d);
15968 self.write("' AS DATE)");
15969 }
15970 Some(DialectType::DuckDB)
15972 | Some(DialectType::Presto)
15973 | Some(DialectType::Trino)
15974 | Some(DialectType::Athena)
15975 | Some(DialectType::Spark)
15976 | Some(DialectType::Databricks)
15977 | Some(DialectType::Hive) => {
15978 self.write("CAST('");
15979 self.write(d);
15980 self.write("' AS DATE)");
15981 }
15982 Some(DialectType::Oracle) => {
15984 self.write("TO_DATE('");
15985 self.write(d);
15986 self.write("', 'YYYY-MM-DD')");
15987 }
15988 _ => {
15990 self.write_keyword("DATE");
15991 self.write(" '");
15992 self.write(d);
15993 self.write("'");
15994 }
15995 }
15996 Ok(())
15997 }
15998
15999 fn generate_time_literal(&mut self, t: &str) -> Result<()> {
16001 use crate::dialects::DialectType;
16002
16003 match self.config.dialect {
16004 Some(DialectType::TSQL) => {
16006 self.write("CAST('");
16007 self.write(t);
16008 self.write("' AS TIME)");
16009 }
16010 Some(DialectType::Fabric) => {
16011 self.write("CAST('");
16012 self.write(t);
16013 self.write("' AS TIME(6))");
16014 }
16015 _ => {
16017 self.write_keyword("TIME");
16018 self.write(" '");
16019 self.write(t);
16020 self.write("'");
16021 }
16022 }
16023 Ok(())
16024 }
16025
16026 fn generate_dremio_date_expression(&mut self, expr: &Expression) -> Result<()> {
16028 use crate::expressions::Literal;
16029
16030 match expr {
16031 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Date(_)) => {
16032 let Literal::Date(d) = lit.as_ref() else {
16033 unreachable!()
16034 };
16035 self.write("CAST('");
16037 self.write(d);
16038 self.write("' AS DATE)");
16039 }
16040 _ => {
16041 self.generate_expression(expr)?;
16043 }
16044 }
16045 Ok(())
16046 }
16047
16048 fn generate_timestamp_literal(&mut self, ts: &str) -> Result<()> {
16050 use crate::dialects::DialectType;
16051
16052 match self.config.dialect {
16053 Some(DialectType::TSQL) => {
16055 self.write("CAST('");
16056 self.write(ts);
16057 self.write("' AS DATETIME2)");
16058 }
16059 Some(DialectType::BigQuery) => {
16062 self.write("CAST('");
16063 self.write(ts);
16064 self.write("' AS TIMESTAMP)");
16065 }
16066 Some(DialectType::Snowflake) => {
16069 self.write("CAST('");
16070 self.write(ts);
16071 self.write("' AS TIMESTAMP)");
16072 }
16073 Some(DialectType::Dremio) => {
16076 self.write("CAST('");
16077 self.write(ts);
16078 self.write("' AS TIMESTAMP)");
16079 }
16080 Some(DialectType::Exasol) => {
16083 self.write("CAST('");
16084 self.write(ts);
16085 self.write("' AS TIMESTAMP)");
16086 }
16087 Some(DialectType::Oracle) => {
16090 self.write("TO_TIMESTAMP('");
16091 self.write(ts);
16092 self.write("', 'YYYY-MM-DD HH24:MI:SS.FF6')");
16093 }
16094 Some(DialectType::Presto) | Some(DialectType::Trino) => {
16096 if Self::timestamp_has_timezone(ts) {
16097 self.write("CAST('");
16098 self.write(ts);
16099 self.write("' AS TIMESTAMP WITH TIME ZONE)");
16100 } else {
16101 self.write("CAST('");
16102 self.write(ts);
16103 self.write("' AS TIMESTAMP)");
16104 }
16105 }
16106 Some(DialectType::ClickHouse) => {
16108 self.write("CAST('");
16109 self.write(ts);
16110 self.write("' AS Nullable(DateTime))");
16111 }
16112 Some(DialectType::Spark) => {
16114 self.write("CAST('");
16115 self.write(ts);
16116 self.write("' AS TIMESTAMP)");
16117 }
16118 Some(DialectType::Redshift) => {
16121 if ts == "epoch" {
16122 self.write_keyword("TIMESTAMP");
16123 self.write(" '");
16124 self.write(ts);
16125 self.write("'");
16126 } else {
16127 self.write("CAST('");
16128 self.write(ts);
16129 self.write("' AS TIMESTAMP)");
16130 }
16131 }
16132 Some(DialectType::PostgreSQL)
16134 | Some(DialectType::Hive)
16135 | Some(DialectType::SQLite)
16136 | Some(DialectType::DuckDB)
16137 | Some(DialectType::Athena)
16138 | Some(DialectType::Drill)
16139 | Some(DialectType::Teradata) => {
16140 self.write("CAST('");
16141 self.write(ts);
16142 self.write("' AS TIMESTAMP)");
16143 }
16144 Some(DialectType::MySQL) | Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
16146 self.write("CAST('");
16147 self.write(ts);
16148 self.write("' AS DATETIME)");
16149 }
16150 Some(DialectType::Databricks) => {
16152 self.write("CAST('");
16153 self.write(ts);
16154 self.write("' AS TIMESTAMP_NTZ)");
16155 }
16156 _ => {
16158 self.write_keyword("TIMESTAMP");
16159 self.write(" '");
16160 self.write(ts);
16161 self.write("'");
16162 }
16163 }
16164 Ok(())
16165 }
16166
16167 fn timestamp_has_timezone(ts: &str) -> bool {
16170 let ts_lower = ts.to_ascii_lowercase();
16174
16175 let continent_prefixes = [
16177 "africa/",
16178 "america/",
16179 "antarctica/",
16180 "arctic/",
16181 "asia/",
16182 "atlantic/",
16183 "australia/",
16184 "europe/",
16185 "indian/",
16186 "pacific/",
16187 "etc/",
16188 "brazil/",
16189 "canada/",
16190 "chile/",
16191 "mexico/",
16192 "us/",
16193 ];
16194
16195 for prefix in &continent_prefixes {
16196 if ts_lower.contains(prefix) {
16197 return true;
16198 }
16199 }
16200
16201 let tz_abbrevs = [
16204 " utc", " gmt", " cet", " cest", " eet", " eest", " wet", " west", " est", " edt",
16205 " cst", " cdt", " mst", " mdt", " pst", " pdt", " ist", " bst", " jst", " kst", " hkt",
16206 " sgt", " aest", " aedt", " acst", " acdt", " awst",
16207 ];
16208
16209 for abbrev in &tz_abbrevs {
16210 if ts_lower.ends_with(abbrev) {
16211 return true;
16212 }
16213 }
16214
16215 let trimmed = ts.trim();
16219 if let Some(last_space) = trimmed.rfind(' ') {
16220 let suffix = &trimmed[last_space + 1..];
16221 if (suffix.starts_with('+') || suffix.starts_with('-')) && suffix.len() > 1 {
16222 let rest = &suffix[1..];
16224 if rest.chars().all(|c| c.is_ascii_digit() || c == ':') {
16225 return true;
16226 }
16227 }
16228 }
16229
16230 false
16231 }
16232
16233 fn generate_datetime_literal(&mut self, dt: &str) -> Result<()> {
16235 use crate::dialects::DialectType;
16236
16237 match self.config.dialect {
16238 Some(DialectType::BigQuery) => {
16241 self.write("CAST('");
16242 self.write(dt);
16243 self.write("' AS DATETIME)");
16244 }
16245 Some(DialectType::DuckDB) => {
16247 self.write("CAST('");
16248 self.write(dt);
16249 self.write("' AS TIMESTAMP)");
16250 }
16251 _ => {
16254 self.write_keyword("DATETIME");
16255 self.write(" '");
16256 self.write(dt);
16257 self.write("'");
16258 }
16259 }
16260 Ok(())
16261 }
16262
16263 fn generate_string_literal(&mut self, s: &str) -> Result<()> {
16265 use crate::dialects::DialectType;
16266
16267 match self.config.dialect {
16268 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
16272 self.write("'");
16274 for c in s.chars() {
16275 match c {
16276 '\'' => self.write("\\'"),
16277 '\\' => self.write("\\\\"),
16278 '\n' => self.write("\\n"),
16279 '\r' => self.write("\\r"),
16280 '\t' => self.write("\\t"),
16281 '\0' => self.write("\\0"),
16282 _ => self.output.push(c),
16283 }
16284 }
16285 self.write("'");
16286 }
16287 Some(DialectType::Drill) => {
16288 self.write("'");
16291 for c in s.chars() {
16292 match c {
16293 '\'' => self.write("''"),
16294 '\\' => self.write("\\\\"),
16295 '\n' => self.write("\\n"),
16296 '\r' => self.write("\\r"),
16297 '\t' => self.write("\\t"),
16298 '\0' => self.write("\\0"),
16299 _ => self.output.push(c),
16300 }
16301 }
16302 self.write("'");
16303 }
16304 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB) => {
16305 self.write("'");
16306 for c in s.chars() {
16307 match c {
16308 '\'' => self.write("''"),
16310 '\\' => self.write("\\\\"),
16311 '\n' => self.write("\\n"),
16312 '\r' => self.write("\\r"),
16313 '\t' => self.write("\\t"),
16314 '\0' => self.output.push('\0'),
16316 _ => self.output.push(c),
16317 }
16318 }
16319 self.write("'");
16320 }
16321 Some(DialectType::BigQuery) => {
16323 self.write("'");
16324 for c in s.chars() {
16325 match c {
16326 '\'' => self.write("\\'"),
16327 '\\' => self.write("\\\\"),
16328 '\n' => self.write("\\n"),
16329 '\r' => self.write("\\r"),
16330 '\t' => self.write("\\t"),
16331 '\0' => self.write("\\0"),
16332 '\x07' => self.write("\\a"),
16333 '\x08' => self.write("\\b"),
16334 '\x0C' => self.write("\\f"),
16335 '\x0B' => self.write("\\v"),
16336 _ => self.output.push(c),
16337 }
16338 }
16339 self.write("'");
16340 }
16341 Some(DialectType::Athena) => {
16345 if self.athena_hive_context {
16346 self.write("'");
16348 for c in s.chars() {
16349 match c {
16350 '\'' => self.write("\\'"),
16351 '\\' => self.write("\\\\"),
16352 '\n' => self.write("\\n"),
16353 '\r' => self.write("\\r"),
16354 '\t' => self.write("\\t"),
16355 '\0' => self.write("\\0"),
16356 _ => self.output.push(c),
16357 }
16358 }
16359 self.write("'");
16360 } else {
16361 self.write("'");
16363 for c in s.chars() {
16364 match c {
16365 '\'' => self.write("''"),
16366 _ => self.output.push(c),
16368 }
16369 }
16370 self.write("'");
16371 }
16372 }
16373 Some(DialectType::Snowflake) => {
16375 self.write("'");
16376 for c in s.chars() {
16377 match c {
16378 '\'' => self.write("\\'"),
16379 '\\' => self.write("\\\\"),
16380 '\0' => self.write("\\x00"),
16381 '\x08' => self.write("\\b"),
16382 '\x0C' => self.write("\\f"),
16383 '\n' => self.write("\\n"),
16384 '\r' => self.write("\\r"),
16385 '\t' => self.write("\\t"),
16386 _ => self.output.push(c),
16387 }
16388 }
16389 self.write("'");
16390 }
16391 Some(DialectType::PostgreSQL) => {
16393 self.write("'");
16394 for c in s.chars() {
16395 match c {
16396 '\'' => self.write("''"),
16397 _ => self.output.push(c),
16398 }
16399 }
16400 self.write("'");
16401 }
16402 Some(DialectType::Redshift) => {
16404 self.write("'");
16405 for c in s.chars() {
16406 match c {
16407 '\'' => self.write("\\'"),
16408 _ => self.output.push(c),
16409 }
16410 }
16411 self.write("'");
16412 }
16413 Some(DialectType::Oracle) => {
16415 self.write("'");
16416 for ch in s.chars() {
16417 if ch == '\'' {
16418 self.output.push_str("''");
16419 } else {
16420 self.output.push(ch);
16421 }
16422 }
16423 self.write("'");
16424 }
16425 Some(DialectType::ClickHouse) => {
16428 self.write("'");
16429 for c in s.chars() {
16430 match c {
16431 '\'' => self.write("''"),
16432 '\\' => self.write("\\\\"),
16433 '\n' => self.write("\\n"),
16434 '\r' => self.write("\\r"),
16435 '\t' => self.write("\\t"),
16436 '\0' => self.write("\\0"),
16437 '\x07' => self.write("\\a"),
16438 '\x08' => self.write("\\b"),
16439 '\x0C' => self.write("\\f"),
16440 '\x0B' => self.write("\\v"),
16441 c if c.is_control() || (c as u32) < 0x20 => {
16443 let byte = c as u32;
16444 if byte < 256 {
16445 self.write(&format!("\\x{:02X}", byte));
16446 } else {
16447 self.output.push(c);
16448 }
16449 }
16450 _ => self.output.push(c),
16451 }
16452 }
16453 self.write("'");
16454 }
16455 _ => {
16458 self.write("'");
16459 for ch in s.chars() {
16460 if ch == '\'' {
16461 self.output.push_str("''");
16462 } else {
16463 self.output.push(ch);
16464 }
16465 }
16466 self.write("'");
16467 }
16468 }
16469 Ok(())
16470 }
16471
16472 fn write_escaped_byte_string(&mut self, s: &str) {
16475 for c in s.chars() {
16476 match c {
16477 '\'' => self.write("\\'"),
16479 '\\' => self.write("\\\\"),
16481 _ if !c.is_control() => self.output.push(c),
16483 _ => {
16485 let byte = c as u32;
16486 if byte < 256 {
16487 self.write(&format!("\\x{:02x}", byte));
16488 } else {
16489 for b in c.to_string().as_bytes() {
16491 self.write(&format!("\\x{:02x}", b));
16492 }
16493 }
16494 }
16495 }
16496 }
16497 }
16498
16499 fn generate_boolean(&mut self, b: &BooleanLiteral) -> Result<()> {
16500 use crate::dialects::DialectType;
16501
16502 match self.config.dialect {
16504 Some(DialectType::TSQL) => {
16507 self.write(if b.value { "1" } else { "0" });
16508 }
16509 Some(DialectType::Oracle) => {
16511 self.write(if b.value { "1" } else { "0" });
16512 }
16513 Some(DialectType::MySQL) => {
16515 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
16516 }
16517 _ => {
16519 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
16520 }
16521 }
16522 Ok(())
16523 }
16524
16525 fn generate_alias_identifier(&mut self, id: &Identifier) -> Result<()> {
16528 let name = &id.name;
16529 let quote_style = &self.config.identifier_quote_style;
16530
16531 let needs_quoting = id.quoted || self.is_reserved_keyword(name);
16535
16536 let output_name = if self.config.normalize_identifiers && !id.quoted {
16538 name.to_ascii_lowercase()
16539 } else {
16540 name.to_string()
16541 };
16542
16543 if needs_quoting {
16544 let quote_style = if matches!(self.config.dialect, Some(DialectType::ClickHouse))
16545 && matches!(self.config.source_dialect, Some(DialectType::ClickHouse))
16546 && quote_style.start == '"'
16547 && output_name.contains('"')
16548 {
16549 &IdentifierQuoteStyle::BACKTICK
16550 } else {
16551 quote_style
16552 };
16553 let escaped_name = if quote_style.start == quote_style.end {
16555 output_name.replace(
16556 quote_style.end,
16557 &format!("{}{}", quote_style.end, quote_style.end),
16558 )
16559 } else {
16560 output_name.replace(
16561 quote_style.end,
16562 &format!("{}{}", quote_style.end, quote_style.end),
16563 )
16564 };
16565 self.write(&format!(
16566 "{}{}{}",
16567 quote_style.start, escaped_name, quote_style.end
16568 ));
16569 } else {
16570 self.write(&output_name);
16571 }
16572
16573 for comment in &id.trailing_comments {
16575 self.write(" ");
16576 self.write_formatted_comment(comment);
16577 }
16578 Ok(())
16579 }
16580
16581 fn generate_identifier(&mut self, id: &Identifier) -> Result<()> {
16582 use crate::dialects::DialectType;
16583
16584 let name = &id.name;
16585
16586 let quote_style = if matches!(self.config.dialect, Some(DialectType::Athena))
16588 && self.athena_hive_context
16589 {
16590 &IdentifierQuoteStyle::BACKTICK
16591 } else {
16592 &self.config.identifier_quote_style
16593 };
16594
16595 let starts_with_digit = name.chars().next().map_or(false, |c| c.is_ascii_digit());
16602 let needs_digit_quoting = starts_with_digit
16603 && !self.config.identifiers_can_start_with_digit
16604 && self.config.dialect.is_some();
16605 let mysql_invalid_hex_identifier = matches!(self.config.dialect, Some(DialectType::MySQL))
16606 && name.len() > 2
16607 && (name.starts_with("0x") || name.starts_with("0X"))
16608 && !name[2..].chars().all(|c| c.is_ascii_hexdigit());
16609 let clickhouse_unsafe_identifier =
16610 matches!(self.config.dialect, Some(DialectType::ClickHouse))
16611 && matches!(self.config.source_dialect, Some(DialectType::ClickHouse))
16612 && !name.starts_with('{')
16613 && !name.contains('(')
16614 && !name.contains(')')
16615 && name != "?"
16616 && name
16617 .chars()
16618 .any(|c| !(c.is_ascii_alphanumeric() || c == '_'));
16619 let needs_quoting = id.quoted
16620 || self.is_reserved_keyword(name)
16621 || self.config.always_quote_identifiers
16622 || needs_digit_quoting
16623 || mysql_invalid_hex_identifier
16624 || clickhouse_unsafe_identifier;
16625
16626 let (base_name, suffix) = if needs_quoting {
16629 if let Some(paren_pos) = name.find('(') {
16631 let base = &name[..paren_pos];
16632 let rest = &name[paren_pos..];
16633 if rest.starts_with('(')
16635 && (rest.ends_with(')') || rest.ends_with(") ASC") || rest.ends_with(") DESC"))
16636 {
16637 let close_paren = rest.find(')').unwrap_or(rest.len());
16639 let inside = &rest[1..close_paren];
16640 if inside.chars().all(|c| c.is_ascii_digit()) {
16641 (base.to_string(), rest.to_string())
16642 } else {
16643 (name.to_string(), String::new())
16644 }
16645 } else {
16646 (name.to_string(), String::new())
16647 }
16648 } else if name.ends_with(" ASC") {
16649 let base = &name[..name.len() - 4];
16650 (base.to_string(), " ASC".to_string())
16651 } else if name.ends_with(" DESC") {
16652 let base = &name[..name.len() - 5];
16653 (base.to_string(), " DESC".to_string())
16654 } else {
16655 (name.to_string(), String::new())
16656 }
16657 } else {
16658 (name.to_string(), String::new())
16659 };
16660
16661 let output_name = if self.config.normalize_identifiers && !id.quoted {
16665 base_name.to_ascii_lowercase()
16666 } else if matches!(self.config.dialect, Some(DialectType::Exasol))
16667 && !id.quoted
16668 && self.is_reserved_keyword(name)
16669 {
16670 base_name.to_ascii_uppercase()
16673 } else {
16674 base_name
16675 };
16676
16677 if needs_quoting {
16678 let escaped_name = if quote_style.start == quote_style.end {
16680 output_name.replace(
16682 quote_style.end,
16683 &format!("{}{}", quote_style.end, quote_style.end),
16684 )
16685 } else {
16686 output_name.replace(
16688 quote_style.end,
16689 &format!("{}{}", quote_style.end, quote_style.end),
16690 )
16691 };
16692 self.write(&format!(
16693 "{}{}{}{}",
16694 quote_style.start, escaped_name, quote_style.end, suffix
16695 ));
16696 } else {
16697 self.write(&output_name);
16698 }
16699
16700 for comment in &id.trailing_comments {
16702 self.write(" ");
16703 self.write_formatted_comment(comment);
16704 }
16705 Ok(())
16706 }
16707
16708 fn generate_column(&mut self, col: &Column) -> Result<()> {
16709 use crate::dialects::DialectType;
16710
16711 if let Some(table) = &col.table {
16712 let is_exasol_local_prefix = matches!(self.config.dialect, Some(DialectType::Exasol))
16716 && !table.quoted
16717 && table.name.eq_ignore_ascii_case("LOCAL");
16718
16719 if is_exasol_local_prefix {
16720 self.write("LOCAL");
16722 } else {
16723 self.generate_identifier(table)?;
16724 }
16725 self.write(".");
16726 }
16727 self.generate_identifier(&col.name)?;
16728 if col.join_mark && self.config.supports_column_join_marks {
16731 self.write(" (+)");
16732 }
16733 for comment in &col.trailing_comments {
16735 self.write_space();
16736 self.write_formatted_comment(comment);
16737 }
16738 Ok(())
16739 }
16740
16741 fn generate_prepare(&mut self, prepare: &PrepareStatement) -> Result<()> {
16742 self.write_keyword("PREPARE");
16743 self.write_space();
16744 self.generate_identifier(&prepare.name)?;
16745
16746 if !prepare.parameter_types.is_empty() {
16747 self.write(" (");
16748 for (i, data_type) in prepare.parameter_types.iter().enumerate() {
16749 if i > 0 {
16750 self.write(", ");
16751 }
16752 self.generate_data_type(data_type)?;
16753 }
16754 self.write(")");
16755 }
16756
16757 self.write_space();
16758 self.write_keyword("AS");
16759 self.write_space();
16760 self.generate_expression(&prepare.statement)
16761 }
16762
16763 fn generate_pseudocolumn(&mut self, pc: &Pseudocolumn) -> Result<()> {
16766 use crate::dialects::DialectType;
16767 use crate::expressions::PseudocolumnType;
16768
16769 if pc.kind == PseudocolumnType::Sysdate
16771 && !matches!(
16772 self.config.dialect,
16773 Some(DialectType::Oracle) | Some(DialectType::Redshift) | None
16774 )
16775 {
16776 self.write_keyword("CURRENT_TIMESTAMP");
16777 if matches!(
16779 self.config.dialect,
16780 Some(DialectType::MySQL)
16781 | Some(DialectType::ClickHouse)
16782 | Some(DialectType::Spark)
16783 | Some(DialectType::Databricks)
16784 | Some(DialectType::Hive)
16785 ) {
16786 self.write("()");
16787 }
16788 } else {
16789 self.write(pc.kind.as_str());
16790 }
16791 Ok(())
16792 }
16793
16794 fn generate_connect(&mut self, connect: &Connect) -> Result<()> {
16796 use crate::dialects::DialectType;
16797
16798 let supports_connect_by = matches!(
16801 self.config.dialect,
16802 Some(DialectType::Oracle) | Some(DialectType::Snowflake)
16803 );
16804
16805 if !supports_connect_by && self.config.dialect.is_some() {
16806 if self.config.pretty {
16808 self.write_newline();
16809 } else {
16810 self.write_space();
16811 }
16812 self.write_unsupported_comment(
16813 "CONNECT BY requires manual conversion to recursive CTE",
16814 )?;
16815 }
16816
16817 if let Some(start) = &connect.start {
16819 if self.config.pretty {
16820 self.write_newline();
16821 } else {
16822 self.write_space();
16823 }
16824 self.write_keyword("START WITH");
16825 self.write_space();
16826 self.generate_expression(start)?;
16827 }
16828
16829 if self.config.pretty {
16831 self.write_newline();
16832 } else {
16833 self.write_space();
16834 }
16835 self.write_keyword("CONNECT BY");
16836 if connect.nocycle {
16837 self.write_space();
16838 self.write_keyword("NOCYCLE");
16839 }
16840 self.write_space();
16841 self.generate_expression(&connect.connect)?;
16842
16843 Ok(())
16844 }
16845
16846 fn generate_connect_expr(&mut self, connect: &Connect) -> Result<()> {
16848 self.generate_connect(connect)
16849 }
16850
16851 fn generate_prior(&mut self, prior: &Prior) -> Result<()> {
16853 self.write_keyword("PRIOR");
16854 self.write_space();
16855 self.generate_expression(&prior.this)?;
16856 Ok(())
16857 }
16858
16859 fn generate_connect_by_root(&mut self, cbr: &ConnectByRoot) -> Result<()> {
16862 self.write_keyword("CONNECT_BY_ROOT");
16863 self.write_space();
16864 self.generate_expression(&cbr.this)?;
16865 Ok(())
16866 }
16867
16868 fn generate_match_recognize(&mut self, mr: &MatchRecognize) -> Result<()> {
16870 use crate::dialects::DialectType;
16871
16872 let supports_match_recognize = matches!(
16874 self.config.dialect,
16875 Some(DialectType::Oracle)
16876 | Some(DialectType::Snowflake)
16877 | Some(DialectType::Presto)
16878 | Some(DialectType::Trino)
16879 );
16880
16881 if let Some(source) = &mr.this {
16883 self.generate_expression(source)?;
16884 }
16885
16886 if !supports_match_recognize {
16887 self.write_unsupported_comment("MATCH_RECOGNIZE not supported in this dialect")?;
16888 return Ok(());
16889 }
16890
16891 if self.config.pretty {
16893 self.write_newline();
16894 } else {
16895 self.write_space();
16896 }
16897
16898 self.write_keyword("MATCH_RECOGNIZE");
16899 self.write(" (");
16900
16901 if self.config.pretty {
16902 self.indent_level += 1;
16903 }
16904
16905 let mut needs_separator = false;
16906
16907 if let Some(partition_by) = &mr.partition_by {
16909 if !partition_by.is_empty() {
16910 if self.config.pretty {
16911 self.write_newline();
16912 self.write_indent();
16913 }
16914 self.write_keyword("PARTITION BY");
16915 self.write_space();
16916 for (i, expr) in partition_by.iter().enumerate() {
16917 if i > 0 {
16918 self.write(", ");
16919 }
16920 self.generate_expression(expr)?;
16921 }
16922 needs_separator = true;
16923 }
16924 }
16925
16926 if let Some(order_by) = &mr.order_by {
16928 if !order_by.is_empty() {
16929 if needs_separator {
16930 if self.config.pretty {
16931 self.write_newline();
16932 self.write_indent();
16933 } else {
16934 self.write_space();
16935 }
16936 } else if self.config.pretty {
16937 self.write_newline();
16938 self.write_indent();
16939 }
16940 self.write_keyword("ORDER BY");
16941 if self.config.pretty {
16943 self.indent_level += 1;
16944 for (i, ordered) in order_by.iter().enumerate() {
16945 if i > 0 {
16946 self.write(",");
16947 }
16948 self.write_newline();
16949 self.write_indent();
16950 self.generate_ordered(ordered)?;
16951 }
16952 self.indent_level -= 1;
16953 } else {
16954 self.write_space();
16955 for (i, ordered) in order_by.iter().enumerate() {
16956 if i > 0 {
16957 self.write(", ");
16958 }
16959 self.generate_ordered(ordered)?;
16960 }
16961 }
16962 needs_separator = true;
16963 }
16964 }
16965
16966 if let Some(measures) = &mr.measures {
16968 if !measures.is_empty() {
16969 if needs_separator {
16970 if self.config.pretty {
16971 self.write_newline();
16972 self.write_indent();
16973 } else {
16974 self.write_space();
16975 }
16976 } else if self.config.pretty {
16977 self.write_newline();
16978 self.write_indent();
16979 }
16980 self.write_keyword("MEASURES");
16981 if self.config.pretty {
16983 self.indent_level += 1;
16984 for (i, measure) in measures.iter().enumerate() {
16985 if i > 0 {
16986 self.write(",");
16987 }
16988 self.write_newline();
16989 self.write_indent();
16990 if let Some(semantics) = &measure.window_frame {
16992 match semantics {
16993 MatchRecognizeSemantics::Running => {
16994 self.write_keyword("RUNNING");
16995 self.write_space();
16996 }
16997 MatchRecognizeSemantics::Final => {
16998 self.write_keyword("FINAL");
16999 self.write_space();
17000 }
17001 }
17002 }
17003 self.generate_expression(&measure.this)?;
17004 }
17005 self.indent_level -= 1;
17006 } else {
17007 self.write_space();
17008 for (i, measure) in measures.iter().enumerate() {
17009 if i > 0 {
17010 self.write(", ");
17011 }
17012 if let Some(semantics) = &measure.window_frame {
17014 match semantics {
17015 MatchRecognizeSemantics::Running => {
17016 self.write_keyword("RUNNING");
17017 self.write_space();
17018 }
17019 MatchRecognizeSemantics::Final => {
17020 self.write_keyword("FINAL");
17021 self.write_space();
17022 }
17023 }
17024 }
17025 self.generate_expression(&measure.this)?;
17026 }
17027 }
17028 needs_separator = true;
17029 }
17030 }
17031
17032 if let Some(rows) = &mr.rows {
17034 if needs_separator {
17035 if self.config.pretty {
17036 self.write_newline();
17037 self.write_indent();
17038 } else {
17039 self.write_space();
17040 }
17041 } else if self.config.pretty {
17042 self.write_newline();
17043 self.write_indent();
17044 }
17045 match rows {
17046 MatchRecognizeRows::OneRowPerMatch => {
17047 self.write_keyword("ONE ROW PER MATCH");
17048 }
17049 MatchRecognizeRows::AllRowsPerMatch => {
17050 self.write_keyword("ALL ROWS PER MATCH");
17051 }
17052 MatchRecognizeRows::AllRowsPerMatchShowEmptyMatches => {
17053 self.write_keyword("ALL ROWS PER MATCH SHOW EMPTY MATCHES");
17054 }
17055 MatchRecognizeRows::AllRowsPerMatchOmitEmptyMatches => {
17056 self.write_keyword("ALL ROWS PER MATCH OMIT EMPTY MATCHES");
17057 }
17058 MatchRecognizeRows::AllRowsPerMatchWithUnmatchedRows => {
17059 self.write_keyword("ALL ROWS PER MATCH WITH UNMATCHED ROWS");
17060 }
17061 }
17062 needs_separator = true;
17063 }
17064
17065 if let Some(after) = &mr.after {
17067 if needs_separator {
17068 if self.config.pretty {
17069 self.write_newline();
17070 self.write_indent();
17071 } else {
17072 self.write_space();
17073 }
17074 } else if self.config.pretty {
17075 self.write_newline();
17076 self.write_indent();
17077 }
17078 match after {
17079 MatchRecognizeAfter::PastLastRow => {
17080 self.write_keyword("AFTER MATCH SKIP PAST LAST ROW");
17081 }
17082 MatchRecognizeAfter::ToNextRow => {
17083 self.write_keyword("AFTER MATCH SKIP TO NEXT ROW");
17084 }
17085 MatchRecognizeAfter::ToFirst(ident) => {
17086 self.write_keyword("AFTER MATCH SKIP TO FIRST");
17087 self.write_space();
17088 self.generate_identifier(ident)?;
17089 }
17090 MatchRecognizeAfter::ToLast(ident) => {
17091 self.write_keyword("AFTER MATCH SKIP TO LAST");
17092 self.write_space();
17093 self.generate_identifier(ident)?;
17094 }
17095 }
17096 needs_separator = true;
17097 }
17098
17099 if let Some(pattern) = &mr.pattern {
17101 if needs_separator {
17102 if self.config.pretty {
17103 self.write_newline();
17104 self.write_indent();
17105 } else {
17106 self.write_space();
17107 }
17108 } else if self.config.pretty {
17109 self.write_newline();
17110 self.write_indent();
17111 }
17112 self.write_keyword("PATTERN");
17113 self.write_space();
17114 self.write("(");
17115 self.write(pattern);
17116 self.write(")");
17117 needs_separator = true;
17118 }
17119
17120 if let Some(define) = &mr.define {
17122 if !define.is_empty() {
17123 if needs_separator {
17124 if self.config.pretty {
17125 self.write_newline();
17126 self.write_indent();
17127 } else {
17128 self.write_space();
17129 }
17130 } else if self.config.pretty {
17131 self.write_newline();
17132 self.write_indent();
17133 }
17134 self.write_keyword("DEFINE");
17135 if self.config.pretty {
17137 self.indent_level += 1;
17138 for (i, (name, expr)) in define.iter().enumerate() {
17139 if i > 0 {
17140 self.write(",");
17141 }
17142 self.write_newline();
17143 self.write_indent();
17144 self.generate_identifier(name)?;
17145 self.write(" AS ");
17146 self.generate_expression(expr)?;
17147 }
17148 self.indent_level -= 1;
17149 } else {
17150 self.write_space();
17151 for (i, (name, expr)) in define.iter().enumerate() {
17152 if i > 0 {
17153 self.write(", ");
17154 }
17155 self.generate_identifier(name)?;
17156 self.write(" AS ");
17157 self.generate_expression(expr)?;
17158 }
17159 }
17160 }
17161 }
17162
17163 if self.config.pretty {
17164 self.indent_level -= 1;
17165 self.write_newline();
17166 }
17167 self.write(")");
17168
17169 if let Some(alias) = &mr.alias {
17171 self.write(" ");
17172 if mr.alias_explicit_as {
17173 self.write_keyword("AS");
17174 self.write(" ");
17175 }
17176 self.generate_identifier(alias)?;
17177 }
17178
17179 Ok(())
17180 }
17181
17182 fn generate_hint(&mut self, hint: &Hint) -> Result<()> {
17184 use crate::dialects::DialectType;
17185
17186 let supports_hints = matches!(
17188 self.config.dialect,
17189 None | Some(DialectType::Oracle) | Some(DialectType::MySQL) |
17191 Some(DialectType::Spark) | Some(DialectType::Hive) |
17192 Some(DialectType::Databricks) | Some(DialectType::PostgreSQL)
17193 );
17194
17195 if !supports_hints || hint.expressions.is_empty() {
17196 return Ok(());
17197 }
17198
17199 let mut hint_strings: Vec<String> = Vec::new();
17202 for expr in &hint.expressions {
17203 match expr {
17204 HintExpression::Raw(text) => {
17205 let parsed = self.parse_raw_hint_text(text);
17207 hint_strings.extend(parsed);
17208 }
17209 _ => {
17210 hint_strings.push(self.hint_expression_to_string(expr)?);
17211 }
17212 }
17213 }
17214
17215 let use_multiline = self.config.pretty && hint_strings.len() > 1;
17219
17220 if use_multiline {
17221 self.write(" /*+ ");
17223 for (i, hint_str) in hint_strings.iter().enumerate() {
17224 if i > 0 {
17225 self.write_newline();
17226 self.write(" "); }
17228 self.write(hint_str);
17229 }
17230 self.write(" */");
17231 } else {
17232 self.write(" /*+ ");
17234 let sep = match self.config.dialect {
17235 Some(DialectType::Spark) | Some(DialectType::Databricks) => ", ",
17236 _ => " ",
17237 };
17238 for (i, hint_str) in hint_strings.iter().enumerate() {
17239 if i > 0 {
17240 self.write(sep);
17241 }
17242 self.write(hint_str);
17243 }
17244 self.write(" */");
17245 }
17246
17247 Ok(())
17248 }
17249
17250 fn parse_raw_hint_text(&self, text: &str) -> Vec<String> {
17254 let mut results = Vec::new();
17255 let mut chars = text.chars().peekable();
17256 let mut current = String::new();
17257 let mut paren_depth = 0;
17258 let mut has_unparseable_content = false;
17259 let mut position_after_last_function = 0;
17260 let mut char_position = 0;
17261
17262 while let Some(c) = chars.next() {
17263 char_position += c.len_utf8();
17264 match c {
17265 '(' => {
17266 paren_depth += 1;
17267 current.push(c);
17268 }
17269 ')' => {
17270 paren_depth -= 1;
17271 current.push(c);
17272 if paren_depth == 0 {
17274 let trimmed = current.trim().to_string();
17275 if !trimmed.is_empty() {
17276 let formatted = self.format_hint_function(&trimmed);
17278 results.push(formatted);
17279 }
17280 current.clear();
17281 position_after_last_function = char_position;
17282 }
17283 }
17284 ' ' | '\t' | '\n' | ',' if paren_depth == 0 => {
17285 }
17287 _ if paren_depth == 0 => {
17288 current.push(c);
17290 }
17291 _ => {
17292 current.push(c);
17293 }
17294 }
17295 }
17296
17297 let remaining_text = text[position_after_last_function..].trim();
17299 if !remaining_text.is_empty() {
17300 let words: Vec<&str> = remaining_text.split_whitespace().collect();
17304 let looks_like_hint_functions = words.iter().all(|word| {
17305 word.contains('(') || (word.chars().all(|c| c.is_ascii_uppercase() || c == '_'))
17307 });
17308
17309 if !looks_like_hint_functions && words.len() > 1 {
17310 has_unparseable_content = true;
17311 }
17312 }
17313
17314 if has_unparseable_content {
17316 return vec![text.trim().to_string()];
17317 }
17318
17319 if results.is_empty() {
17321 results.push(text.trim().to_string());
17322 }
17323
17324 results
17325 }
17326
17327 fn format_hint_function(&self, hint: &str) -> String {
17330 if !self.config.pretty {
17331 return hint.to_string();
17332 }
17333
17334 if let Some(paren_pos) = hint.find('(') {
17336 if hint.ends_with(')') {
17337 let name = &hint[..paren_pos];
17338 let args_str = &hint[paren_pos + 1..hint.len() - 1];
17339
17340 let args: Vec<&str> = args_str.split_whitespace().collect();
17342
17343 let total_args_width: usize =
17345 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() {
17349 let mut result = format!("{}(\n", name);
17350 for arg in &args {
17351 result.push_str(" "); result.push_str(arg);
17353 result.push('\n');
17354 }
17355 result.push_str(" )"); return result;
17357 }
17358 }
17359 }
17360
17361 hint.to_string()
17362 }
17363
17364 fn hint_expression_to_string(&mut self, expr: &HintExpression) -> Result<String> {
17366 match expr {
17367 HintExpression::Function { name, args } => {
17368 let arg_strings: Vec<String> = args
17370 .iter()
17371 .map(|arg| {
17372 let mut gen = Generator::with_arc_config(self.config.clone());
17373 gen.generate_expression(arg)?;
17374 Ok(gen.output)
17375 })
17376 .collect::<Result<Vec<_>>>()?;
17377
17378 let total_args_width: usize = arg_strings.iter().map(|s| s.len()).sum::<usize>()
17380 + arg_strings.len().saturating_sub(1); let args_multiline =
17385 self.config.pretty && total_args_width > self.config.max_text_width;
17386
17387 if args_multiline && !arg_strings.is_empty() {
17388 let mut result = format!("{}(\n", name);
17390 for arg_str in &arg_strings {
17391 result.push_str(" "); result.push_str(arg_str);
17393 result.push('\n');
17394 }
17395 result.push_str(" )"); Ok(result)
17397 } else {
17398 let args_str = arg_strings.join(" ");
17400 Ok(format!("{}({})", name, args_str))
17401 }
17402 }
17403 HintExpression::Identifier(name) => Ok(name.clone()),
17404 HintExpression::Raw(text) => {
17405 if self.config.pretty {
17407 Ok(self.format_hint_function(text))
17408 } else {
17409 Ok(text.clone())
17410 }
17411 }
17412 }
17413 }
17414
17415 fn generate_table(&mut self, table: &TableRef) -> Result<()> {
17416 if table.only {
17418 self.write_keyword("ONLY");
17419 self.write_space();
17420 }
17421
17422 if let Some(ref identifier_func) = table.identifier_func {
17424 self.generate_expression(identifier_func)?;
17425 if !table.name.name.is_empty() {
17427 if let Some(catalog) = &table.catalog {
17428 self.write(".");
17429 self.generate_identifier(catalog)?;
17430 }
17431 if let Some(schema) = &table.schema {
17432 self.write(".");
17433 self.generate_identifier(schema)?;
17434 }
17435 self.write(".");
17436 self.generate_identifier(&table.name)?;
17437 }
17438 } else {
17439 if let Some(catalog) = &table.catalog {
17440 self.generate_identifier(catalog)?;
17441 self.write(".");
17442 }
17443 if let Some(schema) = &table.schema {
17444 self.generate_identifier(schema)?;
17445 self.write(".");
17446 }
17447 self.generate_identifier(&table.name)?;
17448 }
17449
17450 if let Some(changes) = &table.changes {
17452 self.write(" ");
17453 self.generate_changes(changes)?;
17454 }
17455
17456 if !table.partitions.is_empty() {
17458 self.write_space();
17459 self.write_keyword("PARTITION");
17460 self.write("(");
17461 for (i, partition) in table.partitions.iter().enumerate() {
17462 if i > 0 {
17463 self.write(", ");
17464 }
17465 self.generate_identifier(partition)?;
17466 }
17467 self.write(")");
17468 }
17469
17470 if table.changes.is_none() {
17473 if let Some(when) = &table.when {
17474 self.write_space();
17475 self.generate_historical_data(when)?;
17476 }
17477 }
17478
17479 let system_time_post_alias = matches!(self.config.dialect, Some(DialectType::BigQuery));
17481 if !system_time_post_alias {
17482 if let Some(ref system_time) = table.system_time {
17483 self.write_space();
17484 self.write(system_time);
17485 }
17486 }
17487
17488 if let Some(ref version) = table.version {
17490 self.write_space();
17491 self.generate_version(version)?;
17492 }
17493
17494 let alias_post_tablesample = self.config.alias_post_tablesample;
17498
17499 if alias_post_tablesample {
17500 self.generate_table_sample_clause(table)?;
17502 }
17503
17504 let is_sqlite_hint = matches!(self.config.dialect, Some(DialectType::SQLite))
17507 && table.hints.iter().any(|h| {
17508 if let Expression::Identifier(id) = h {
17509 id.name.starts_with("INDEXED BY") || id.name == "NOT INDEXED"
17510 } else {
17511 false
17512 }
17513 });
17514 if !table.hints.is_empty() && !is_sqlite_hint {
17515 for hint in &table.hints {
17516 self.write_space();
17517 self.generate_expression(hint)?;
17518 }
17519 }
17520
17521 if let Some(alias) = &table.alias {
17522 self.write_space();
17523 let always_use_as = self.config.dialect.is_none()
17526 || matches!(
17527 self.config.dialect,
17528 Some(DialectType::Generic)
17529 | Some(DialectType::PostgreSQL)
17530 | Some(DialectType::Redshift)
17531 | Some(DialectType::Snowflake)
17532 | Some(DialectType::BigQuery)
17533 | Some(DialectType::DuckDB)
17534 | Some(DialectType::Presto)
17535 | Some(DialectType::Trino)
17536 | Some(DialectType::TSQL)
17537 | Some(DialectType::Fabric)
17538 | Some(DialectType::MySQL)
17539 | Some(DialectType::Spark)
17540 | Some(DialectType::Hive)
17541 | Some(DialectType::SQLite)
17542 | Some(DialectType::Drill)
17543 );
17544 let is_stage_ref = table.name.name.starts_with('@');
17545 let suppress_as = matches!(self.config.dialect, Some(DialectType::Oracle));
17547 if !suppress_as && (table.alias_explicit_as || always_use_as || is_stage_ref) {
17548 self.write_keyword("AS");
17549 self.write_space();
17550 }
17551 self.generate_identifier(alias)?;
17552
17553 if !table.column_aliases.is_empty() && self.config.supports_table_alias_columns {
17556 self.write("(");
17557 for (i, col_alias) in table.column_aliases.iter().enumerate() {
17558 if i > 0 {
17559 self.write(", ");
17560 }
17561 self.generate_identifier(col_alias)?;
17562 }
17563 self.write(")");
17564 }
17565 }
17566
17567 if system_time_post_alias {
17569 if let Some(ref system_time) = table.system_time {
17570 self.write_space();
17571 self.write(system_time);
17572 }
17573 }
17574
17575 if !alias_post_tablesample {
17577 self.generate_table_sample_clause(table)?;
17578 }
17579
17580 if is_sqlite_hint {
17582 for hint in &table.hints {
17583 self.write_space();
17584 self.generate_expression(hint)?;
17585 }
17586 }
17587
17588 if table.final_ && matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
17590 self.write_space();
17591 self.write_keyword("FINAL");
17592 }
17593
17594 for comment in &table.trailing_comments {
17596 self.write_space();
17597 self.write_formatted_comment(comment);
17598 }
17599 Ok(())
17603 }
17604
17605 fn generate_table_sample_clause(&mut self, table: &TableRef) -> Result<()> {
17607 if let Some(ref ts) = table.table_sample {
17608 self.write_space();
17609 if ts.is_using_sample {
17610 self.write_keyword("USING SAMPLE");
17611 } else {
17612 self.write_keyword(self.config.tablesample_keywords);
17614 }
17615 self.generate_sample_body(ts)?;
17616 if let Some(ref seed) = ts.seed {
17618 self.write_space();
17619 self.write_keyword(self.config.tablesample_seed_keyword);
17620 self.write(" (");
17621 self.generate_expression(seed)?;
17622 self.write(")");
17623 }
17624 }
17625 Ok(())
17626 }
17627
17628 fn generate_stage_reference(&mut self, sr: &StageReference) -> Result<()> {
17629 if sr.quoted {
17633 self.write("'");
17634 }
17635
17636 self.write(&sr.name);
17637 if let Some(path) = &sr.path {
17638 self.write(path);
17639 }
17640
17641 if sr.quoted {
17642 self.write("'");
17643 }
17644
17645 let has_options = sr.file_format.is_some() || sr.pattern.is_some();
17647 if has_options {
17648 self.write(" (");
17649 let mut first = true;
17650
17651 if let Some(file_format) = &sr.file_format {
17652 if !first {
17653 self.write(", ");
17654 }
17655 self.write_keyword("FILE_FORMAT");
17656 self.write(" => ");
17657 self.generate_expression(file_format)?;
17658 first = false;
17659 }
17660
17661 if let Some(pattern) = &sr.pattern {
17662 if !first {
17663 self.write(", ");
17664 }
17665 self.write_keyword("PATTERN");
17666 self.write(" => '");
17667 self.write(pattern);
17668 self.write("'");
17669 }
17670
17671 self.write(")");
17672 }
17673 Ok(())
17674 }
17675
17676 fn generate_star(&mut self, star: &Star) -> Result<()> {
17677 use crate::dialects::DialectType;
17678
17679 if let Some(table) = &star.table {
17680 self.generate_identifier(table)?;
17681 self.write(".");
17682 }
17683 self.write("*");
17684
17685 if let Some(except) = &star.except {
17687 if !except.is_empty() {
17688 self.write_space();
17689 match self.config.dialect {
17691 Some(DialectType::BigQuery) => self.write_keyword("EXCEPT"),
17692 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => {
17693 self.write_keyword("EXCLUDE")
17694 }
17695 _ => self.write_keyword("EXCEPT"), }
17697 self.write(" (");
17698 for (i, col) in except.iter().enumerate() {
17699 if i > 0 {
17700 self.write(", ");
17701 }
17702 self.generate_identifier(col)?;
17703 }
17704 self.write(")");
17705 }
17706 }
17707
17708 if let Some(replace) = &star.replace {
17710 if !replace.is_empty() {
17711 self.write_space();
17712 self.write_keyword("REPLACE");
17713 self.write(" (");
17714 for (i, alias) in replace.iter().enumerate() {
17715 if i > 0 {
17716 self.write(", ");
17717 }
17718 self.generate_expression(&alias.this)?;
17719 self.write_space();
17720 self.write_keyword("AS");
17721 self.write_space();
17722 self.generate_identifier(&alias.alias)?;
17723 }
17724 self.write(")");
17725 }
17726 }
17727
17728 if let Some(rename) = &star.rename {
17730 if !rename.is_empty() {
17731 self.write_space();
17732 self.write_keyword("RENAME");
17733 self.write(" (");
17734 for (i, (old_name, new_name)) in rename.iter().enumerate() {
17735 if i > 0 {
17736 self.write(", ");
17737 }
17738 self.generate_identifier(old_name)?;
17739 self.write_space();
17740 self.write_keyword("AS");
17741 self.write_space();
17742 self.generate_identifier(new_name)?;
17743 }
17744 self.write(")");
17745 }
17746 }
17747
17748 for comment in &star.trailing_comments {
17750 self.write_space();
17751 self.write_formatted_comment(comment);
17752 }
17753
17754 Ok(())
17755 }
17756
17757 fn generate_braced_wildcard(&mut self, expr: &Expression) -> Result<()> {
17759 self.write("{");
17760 match expr {
17761 Expression::Star(star) => {
17762 self.generate_star(star)?;
17764 }
17765 Expression::ILike(ilike) => {
17766 self.generate_expression(&ilike.left)?;
17768 self.write_space();
17769 self.write_keyword("ILIKE");
17770 self.write_space();
17771 self.generate_expression(&ilike.right)?;
17772 }
17773 _ => {
17774 self.generate_expression(expr)?;
17775 }
17776 }
17777 self.write("}");
17778 Ok(())
17779 }
17780
17781 fn generate_alias(&mut self, alias: &Alias) -> Result<()> {
17782 match &alias.this {
17786 Expression::Column(col) => {
17787 if let Some(table) = &col.table {
17789 self.generate_identifier(table)?;
17790 self.write(".");
17791 }
17792 self.generate_identifier(&col.name)?;
17793 }
17794 _ => {
17795 self.generate_expression(&alias.this)?;
17796 }
17797 }
17798
17799 if !alias.pre_alias_comments.is_empty() && !alias.trailing_comments.is_empty() {
17803 for comment in &alias.pre_alias_comments {
17804 self.write_space();
17805 self.write_formatted_comment(comment);
17806 }
17807 }
17808
17809 use crate::dialects::DialectType;
17810
17811 let is_table_source = matches!(
17817 &alias.this,
17818 Expression::JSONTable(_)
17819 | Expression::XMLTable(_)
17820 | Expression::TableFromRows(_)
17821 | Expression::Unnest(_)
17822 | Expression::MatchRecognize(_)
17823 | Expression::Select(_)
17824 | Expression::Subquery(_)
17825 | Expression::Paren(_)
17826 | Expression::JoinedTable(_)
17827 );
17828 let dialect_skips_table_alias_as = matches!(self.config.dialect, Some(DialectType::Oracle));
17829 let skip_as = is_table_source && dialect_skips_table_alias_as;
17830
17831 self.write_space();
17832 if !skip_as {
17833 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
17834 if let Some(ref alias_keyword) = alias.alias_keyword {
17835 self.write(alias_keyword);
17836 } else {
17837 self.write_keyword("AS");
17838 }
17839 } else {
17840 self.write_keyword("AS");
17841 }
17842 self.write_space();
17843 }
17844
17845 let skip_column_aliases = matches!(self.config.dialect, Some(DialectType::BigQuery));
17847
17848 if alias.alias.is_empty() && !alias.column_aliases.is_empty() && !skip_column_aliases {
17850 self.write("(");
17852 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
17853 if i > 0 {
17854 self.write(", ");
17855 }
17856 self.generate_alias_identifier(col_alias)?;
17857 }
17858 self.write(")");
17859 } else if !alias.column_aliases.is_empty() && !skip_column_aliases {
17860 self.generate_alias_identifier(&alias.alias)?;
17862 self.write("(");
17863 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
17864 if i > 0 {
17865 self.write(", ");
17866 }
17867 self.generate_alias_identifier(col_alias)?;
17868 }
17869 self.write(")");
17870 } else {
17871 self.generate_alias_identifier(&alias.alias)?;
17873 }
17874
17875 for comment in &alias.trailing_comments {
17877 self.write_space();
17878 self.write_formatted_comment(comment);
17879 }
17880
17881 if alias.trailing_comments.is_empty() {
17886 for comment in &alias.pre_alias_comments {
17887 self.write_space();
17888 self.write_formatted_comment(comment);
17889 }
17890 }
17891
17892 Ok(())
17893 }
17894
17895 fn generate_cast(&mut self, cast: &Cast) -> Result<()> {
17896 use crate::dialects::DialectType;
17897
17898 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
17900 self.generate_expression(&cast.this)?;
17901 self.write(" :> ");
17902 self.generate_data_type(&cast.to)?;
17903 return Ok(());
17904 }
17905
17906 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
17908 let is_unknown_type = matches!(cast.to, DataType::Unknown)
17909 || matches!(cast.to, DataType::Custom { ref name } if name.is_empty());
17910 if is_unknown_type {
17911 if let Some(format) = &cast.format {
17912 self.write_keyword("CAST");
17913 self.write("(");
17914 self.generate_expression(&cast.this)?;
17915 self.write_space();
17916 self.write_keyword("AS");
17917 self.write_space();
17918 self.write_keyword("FORMAT");
17919 self.write_space();
17920 self.generate_expression(format)?;
17921 self.write(")");
17922 return Ok(());
17923 }
17924 }
17925 }
17926
17927 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
17930 if let Some(format) = &cast.format {
17931 let is_date = matches!(
17933 cast.to,
17934 DataType::Date
17935 | DataType::Oracle {
17936 oracle_type: OracleDataType::Date
17937 }
17938 );
17939 let is_timestamp = matches!(
17940 cast.to,
17941 DataType::Timestamp { .. }
17942 | DataType::Oracle {
17943 oracle_type: OracleDataType::Timestamp { .. }
17944 }
17945 );
17946
17947 if is_date || is_timestamp {
17948 let func_name = if is_date { "TO_DATE" } else { "TO_TIMESTAMP" };
17949 self.write_keyword(func_name);
17950 self.write("(");
17951 self.generate_expression(&cast.this)?;
17952 self.write(", ");
17953
17954 if let Expression::Literal(lit) = format.as_ref() {
17957 if let Literal::String(fmt_str) = lit.as_ref() {
17958 let normalized = self.normalize_oracle_format(fmt_str);
17959 self.write("'");
17960 self.write(&normalized);
17961 self.write("'");
17962 }
17963 } else {
17964 self.generate_expression(format)?;
17965 }
17966
17967 self.write(")");
17968 return Ok(());
17969 }
17970 }
17971 }
17972
17973 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
17976 if let Expression::Array(arr) = &cast.this {
17977 self.generate_data_type(&cast.to)?;
17978 self.write("[");
17980 for (i, expr) in arr.expressions.iter().enumerate() {
17981 if i > 0 {
17982 self.write(", ");
17983 }
17984 self.generate_expression(expr)?;
17985 }
17986 self.write("]");
17987 return Ok(());
17988 }
17989 if matches!(&cast.this, Expression::ArrayFunc(_)) {
17990 self.generate_data_type(&cast.to)?;
17991 self.generate_expression(&cast.this)?;
17992 return Ok(());
17993 }
17994 }
17995
17996 if matches!(
17999 self.config.dialect,
18000 Some(DialectType::DuckDB) | Some(DialectType::Presto) | Some(DialectType::Trino)
18001 ) {
18002 if let Expression::Struct(ref s) = cast.this {
18003 let all_unnamed = s.fields.iter().all(|(name, _)| name.is_none());
18004 if all_unnamed && matches!(cast.to, DataType::Struct { .. }) {
18005 self.write_keyword("CAST");
18006 self.write("(");
18007 self.generate_struct_as_row(s)?;
18008 self.write_space();
18009 self.write_keyword("AS");
18010 self.write_space();
18011 self.generate_data_type(&cast.to)?;
18012 self.write(")");
18013 return Ok(());
18014 }
18015 }
18016 }
18017
18018 let use_double_colon = cast.double_colon_syntax && self.dialect_prefers_double_colon();
18021
18022 if use_double_colon {
18023 self.generate_expression(&cast.this)?;
18025 self.write("::");
18026 self.generate_data_type(&cast.to)?;
18027 } else {
18028 self.write_keyword("CAST");
18030 self.write("(");
18031 self.generate_expression(&cast.this)?;
18032 self.write_space();
18033 self.write_keyword("AS");
18034 self.write_space();
18035 if matches!(
18038 self.config.dialect,
18039 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB)
18040 ) {
18041 match &cast.to {
18042 DataType::Custom { ref name } => {
18043 if name.eq_ignore_ascii_case("LONGTEXT")
18044 || name.eq_ignore_ascii_case("MEDIUMTEXT")
18045 || name.eq_ignore_ascii_case("TINYTEXT")
18046 || name.eq_ignore_ascii_case("LONGBLOB")
18047 || name.eq_ignore_ascii_case("MEDIUMBLOB")
18048 || name.eq_ignore_ascii_case("TINYBLOB")
18049 {
18050 self.write_keyword("CHAR");
18051 } else {
18052 self.generate_data_type(&cast.to)?;
18053 }
18054 }
18055 DataType::VarChar { length, .. } => {
18056 self.write_keyword("CHAR");
18058 if let Some(n) = length {
18059 self.write(&format!("({})", n));
18060 }
18061 }
18062 DataType::Text => {
18063 self.write_keyword("CHAR");
18065 }
18066 DataType::Timestamp {
18067 precision,
18068 timezone: false,
18069 } => {
18070 self.write_keyword("DATETIME");
18072 if let Some(p) = precision {
18073 self.write(&format!("({})", p));
18074 }
18075 }
18076 _ => {
18077 self.generate_data_type(&cast.to)?;
18078 }
18079 }
18080 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
18081 match &cast.to {
18083 DataType::String { length } => {
18084 self.write_keyword("VARCHAR");
18085 if let Some(n) = length {
18086 self.write(&format!("({})", n));
18087 }
18088 }
18089 _ => {
18090 self.generate_data_type(&cast.to)?;
18091 }
18092 }
18093 } else if matches!(self.config.dialect, Some(DialectType::Oracle)) {
18094 match &cast.to {
18097 DataType::Oracle {
18098 oracle_type: OracleDataType::BinaryFloat,
18099 } => self.write_keyword("FLOAT"),
18100 DataType::Oracle {
18101 oracle_type: OracleDataType::BinaryDouble,
18102 } => self.write_keyword("DOUBLE PRECISION"),
18103 _ => self.generate_data_type(&cast.to)?,
18104 }
18105 } else {
18106 self.generate_data_type(&cast.to)?;
18107 }
18108
18109 if let Some(default) = &cast.default {
18111 self.write_space();
18112 self.write_keyword("DEFAULT");
18113 self.write_space();
18114 self.generate_expression(default)?;
18115 self.write_space();
18116 self.write_keyword("ON");
18117 self.write_space();
18118 self.write_keyword("CONVERSION");
18119 self.write_space();
18120 self.write_keyword("ERROR");
18121 }
18122
18123 if let Some(format) = &cast.format {
18126 if matches!(
18128 self.config.dialect,
18129 Some(crate::dialects::DialectType::Oracle)
18130 ) {
18131 self.write(", ");
18132 } else {
18133 self.write_space();
18134 self.write_keyword("FORMAT");
18135 self.write_space();
18136 }
18137 self.generate_expression(format)?;
18138 }
18139
18140 self.write(")");
18141 for comment in &cast.trailing_comments {
18143 self.write_space();
18144 self.write_formatted_comment(comment);
18145 }
18146 }
18147 Ok(())
18148 }
18149
18150 fn generate_struct_as_row(&mut self, s: &crate::expressions::Struct) -> Result<()> {
18153 self.write_keyword("ROW");
18154 self.write("(");
18155 for (i, (_, expr)) in s.fields.iter().enumerate() {
18156 if i > 0 {
18157 self.write(", ");
18158 }
18159 if let Expression::Struct(ref inner_s) = expr {
18161 self.generate_struct_as_row(inner_s)?;
18162 } else {
18163 self.generate_expression(expr)?;
18164 }
18165 }
18166 self.write(")");
18167 Ok(())
18168 }
18169
18170 fn normalize_oracle_format(&self, format: &str) -> String {
18173 let mut result = String::new();
18176 let chars: Vec<char> = format.chars().collect();
18177 let mut i = 0;
18178
18179 while i < chars.len() {
18180 if i + 1 < chars.len() && chars[i] == 'H' && chars[i + 1] == 'H' {
18181 if i + 2 < chars.len() {
18183 let next = chars[i + 2];
18184 if next == '1' || next == '2' {
18185 result.push('H');
18187 result.push('H');
18188 i += 2;
18189 continue;
18190 }
18191 }
18192 result.push_str("HH12");
18194 i += 2;
18195 } else {
18196 result.push(chars[i]);
18197 i += 1;
18198 }
18199 }
18200
18201 result
18202 }
18203
18204 fn dialect_prefers_double_colon(&self) -> bool {
18207 matches!(self.config.dialect, Some(DialectType::ClickHouse))
18208 }
18209
18210 fn generate_mod_func(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
18212 use crate::dialects::DialectType;
18213
18214 let use_percent_operator = matches!(
18216 self.config.dialect,
18217 Some(DialectType::Snowflake)
18218 | Some(DialectType::MySQL)
18219 | Some(DialectType::Presto)
18220 | Some(DialectType::Trino)
18221 | Some(DialectType::PostgreSQL)
18222 | Some(DialectType::DuckDB)
18223 | Some(DialectType::Hive)
18224 | Some(DialectType::Spark)
18225 | Some(DialectType::Databricks)
18226 | Some(DialectType::Athena)
18227 | Some(DialectType::TSQL)
18228 | Some(DialectType::Fabric)
18229 );
18230
18231 if use_percent_operator {
18232 let needs_paren = |e: &Expression| {
18235 matches!(
18236 e,
18237 Expression::Add(_)
18238 | Expression::Sub(_)
18239 | Expression::Mul(_)
18240 | Expression::Div(_)
18241 | Expression::Mod(_)
18242 | Expression::ModFunc(_)
18243 )
18244 };
18245 if needs_paren(&f.this) {
18246 self.write("(");
18247 self.generate_expression(&f.this)?;
18248 self.write(")");
18249 } else {
18250 self.generate_expression(&f.this)?;
18251 }
18252 self.write(" % ");
18253 if needs_paren(&f.expression) {
18254 self.write("(");
18255 self.generate_expression(&f.expression)?;
18256 self.write(")");
18257 } else {
18258 self.generate_expression(&f.expression)?;
18259 }
18260 Ok(())
18261 } else {
18262 self.generate_binary_func("MOD", &f.this, &f.expression)
18263 }
18264 }
18265
18266 fn generate_ifnull(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
18268 use crate::dialects::DialectType;
18269
18270 let func_name = match self.config.dialect {
18272 Some(DialectType::Snowflake) => "COALESCE",
18273 _ => "IFNULL",
18274 };
18275
18276 self.generate_binary_func(func_name, &f.this, &f.expression)
18277 }
18278
18279 fn generate_nvl(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
18281 if let Some(ref original_name) = f.original_name {
18283 return self.generate_binary_func(original_name, &f.this, &f.expression);
18284 }
18285
18286 use crate::dialects::DialectType;
18288 let func_name = match self.config.dialect {
18289 Some(DialectType::Snowflake)
18290 | Some(DialectType::ClickHouse)
18291 | Some(DialectType::PostgreSQL)
18292 | Some(DialectType::Presto)
18293 | Some(DialectType::Trino)
18294 | Some(DialectType::Athena)
18295 | Some(DialectType::DuckDB)
18296 | Some(DialectType::BigQuery)
18297 | Some(DialectType::Spark)
18298 | Some(DialectType::Databricks)
18299 | Some(DialectType::Hive) => "COALESCE",
18300 Some(DialectType::MySQL)
18301 | Some(DialectType::Doris)
18302 | Some(DialectType::StarRocks)
18303 | Some(DialectType::SingleStore)
18304 | Some(DialectType::TiDB) => "IFNULL",
18305 _ => "NVL",
18306 };
18307
18308 self.generate_binary_func(func_name, &f.this, &f.expression)
18309 }
18310
18311 fn generate_stddev_samp(&mut self, f: &crate::expressions::AggFunc) -> Result<()> {
18313 use crate::dialects::DialectType;
18314
18315 let func_name = match self.config.dialect {
18317 Some(DialectType::Snowflake) => "STDDEV",
18318 _ => "STDDEV_SAMP",
18319 };
18320
18321 self.generate_agg_func(func_name, f)
18322 }
18323
18324 fn generate_collation(&mut self, coll: &CollationExpr) -> Result<()> {
18325 self.generate_expression(&coll.this)?;
18326 self.write_space();
18327 self.write_keyword("COLLATE");
18328 self.write_space();
18329 if coll.quoted {
18330 self.write("'");
18332 self.write(&coll.collation);
18333 self.write("'");
18334 } else if coll.double_quoted {
18335 self.write("\"");
18337 self.write(&coll.collation);
18338 self.write("\"");
18339 } else {
18340 self.write(&coll.collation);
18342 }
18343 Ok(())
18344 }
18345
18346 fn generate_case(&mut self, case: &Case) -> Result<()> {
18347 let multiline_case = if self.config.pretty {
18349 let mut statements: Vec<String> = Vec::new();
18351 let operand_str = if let Some(operand) = &case.operand {
18352 let s = self.generate_to_string(operand)?;
18353 statements.push(format!("CASE {}", s));
18354 s
18355 } else {
18356 statements.push("CASE".to_string());
18357 String::new()
18358 };
18359 let _ = operand_str;
18360 for (condition, result) in &case.whens {
18361 statements.push(format!("WHEN {}", self.generate_to_string(condition)?));
18362 statements.push(format!("THEN {}", self.generate_to_string(result)?));
18363 }
18364 if let Some(else_) = &case.else_ {
18365 statements.push(format!("ELSE {}", self.generate_to_string(else_)?));
18366 }
18367 statements.push("END".to_string());
18368 self.too_wide(&statements)
18369 } else {
18370 false
18371 };
18372
18373 self.write_keyword("CASE");
18374 if let Some(operand) = &case.operand {
18375 self.write_space();
18376 self.generate_expression(operand)?;
18377 }
18378 if multiline_case {
18379 self.indent_level += 1;
18380 }
18381 for (condition, result) in &case.whens {
18382 if multiline_case {
18383 self.write_newline();
18384 self.write_indent();
18385 } else {
18386 self.write_space();
18387 }
18388 self.write_keyword("WHEN");
18389 self.write_space();
18390 self.generate_expression(condition)?;
18391 if multiline_case {
18392 self.write_newline();
18393 self.write_indent();
18394 } else {
18395 self.write_space();
18396 }
18397 self.write_keyword("THEN");
18398 self.write_space();
18399 self.generate_expression(result)?;
18400 }
18401 if let Some(else_) = &case.else_ {
18402 if multiline_case {
18403 self.write_newline();
18404 self.write_indent();
18405 } else {
18406 self.write_space();
18407 }
18408 self.write_keyword("ELSE");
18409 self.write_space();
18410 self.generate_expression(else_)?;
18411 }
18412 if multiline_case {
18413 self.indent_level -= 1;
18414 self.write_newline();
18415 self.write_indent();
18416 } else {
18417 self.write_space();
18418 }
18419 self.write_keyword("END");
18420 for comment in &case.comments {
18422 self.write(" ");
18423 self.write_formatted_comment(comment);
18424 }
18425 Ok(())
18426 }
18427
18428 fn generate_function(&mut self, func: &Function) -> Result<()> {
18429 let normalized_name = if func.name.eq_ignore_ascii_case("GROUPING")
18431 && func.args.len() > 1
18432 && matches!(
18433 self.config.dialect,
18434 Some(DialectType::TSQL | DialectType::Fabric)
18435 ) {
18436 Cow::Borrowed("GROUPING_ID")
18437 } else if matches!(self.config.dialect, Some(DialectType::Snowflake))
18438 && func.name.to_ascii_uppercase().starts_with("IDENTIFIER(")
18439 {
18440 Cow::Borrowed(func.name.as_str())
18441 } else {
18442 self.normalize_func_name(&func.name)
18443 };
18444
18445 if matches!(self.config.dialect, Some(DialectType::DuckDB))
18447 && func.name.eq_ignore_ascii_case("ARRAY_CONSTRUCT_COMPACT")
18448 {
18449 self.write("LIST_FILTER(");
18450 self.write("[");
18451 for (i, arg) in func.args.iter().enumerate() {
18452 if i > 0 {
18453 self.write(", ");
18454 }
18455 self.generate_expression(arg)?;
18456 }
18457 self.write("], _u -> NOT _u IS NULL)");
18458 return Ok(());
18459 }
18460
18461 if matches!(self.config.dialect, Some(DialectType::Snowflake))
18464 && func.name.eq_ignore_ascii_case("TO_VARIANT")
18465 && func.args.len() == 1
18466 {
18467 let array_expressions = match &func.args[0] {
18468 Expression::ArrayFunc(arr) => Some(&arr.expressions),
18469 Expression::Array(arr) => Some(&arr.expressions),
18470 _ => None,
18471 };
18472 if let Some(expressions) = array_expressions {
18473 self.write_keyword("TO_VARIANT");
18474 self.write("(");
18475 self.write_keyword("ARRAY_CONSTRUCT");
18476 self.write("(");
18477 for (i, arg) in expressions.iter().enumerate() {
18478 if i > 0 {
18479 self.write(", ");
18480 }
18481 self.generate_expression(arg)?;
18482 }
18483 self.write(")");
18484 self.write(")");
18485 return Ok(());
18486 }
18487 }
18488
18489 if func.name.eq_ignore_ascii_case("STRUCT")
18491 && !matches!(
18492 self.config.dialect,
18493 Some(DialectType::BigQuery)
18494 | Some(DialectType::Spark)
18495 | Some(DialectType::Databricks)
18496 | Some(DialectType::Hive)
18497 | None
18498 )
18499 {
18500 return self.generate_struct_function_cross_dialect(func);
18501 }
18502
18503 if func.name.eq_ignore_ascii_case("__SS_JSON_PATH_QMARK__") && func.args.len() == 2 {
18506 self.generate_expression(&func.args[0])?;
18507 self.write("::?");
18508 if let Expression::Literal(lit) = &func.args[1] {
18510 if let crate::expressions::Literal::String(key) = lit.as_ref() {
18511 self.write(key);
18512 }
18513 } else {
18514 self.generate_expression(&func.args[1])?;
18515 }
18516 return Ok(());
18517 }
18518
18519 if func.name.eq_ignore_ascii_case("__PG_BITWISE_XOR__") && func.args.len() == 2 {
18521 self.generate_expression(&func.args[0])?;
18522 self.write(" # ");
18523 self.generate_expression(&func.args[1])?;
18524 return Ok(());
18525 }
18526
18527 if matches!(
18529 self.config.dialect,
18530 Some(DialectType::Spark | DialectType::Databricks | DialectType::Hive)
18531 ) && func.name.eq_ignore_ascii_case("TRY")
18532 && func.args.len() == 1
18533 {
18534 self.generate_expression(&func.args[0])?;
18535 return Ok(());
18536 }
18537
18538 if self.config.dialect == Some(DialectType::ClickHouse)
18540 && func.name.eq_ignore_ascii_case("TOSTARTOFDAY")
18541 && func.args.len() == 1
18542 {
18543 self.write("dateTrunc('DAY', ");
18544 self.generate_expression(&func.args[0])?;
18545 self.write(")");
18546 return Ok(());
18547 }
18548
18549 if self.config.dialect == Some(DialectType::ClickHouse)
18551 && func.name.eq_ignore_ascii_case("DATE_TRUNC")
18552 && func.args.len() == 2
18553 {
18554 self.write("dateTrunc(");
18555 self.generate_expression(&func.args[0])?;
18556 self.write(", ");
18557 self.generate_expression(&func.args[1])?;
18558 self.write(")");
18559 return Ok(());
18560 }
18561
18562 if matches!(
18564 self.config.dialect,
18565 Some(DialectType::Presto | DialectType::Trino | DialectType::Athena)
18566 ) && func.name.eq_ignore_ascii_case("SUBSTRING")
18567 {
18568 self.write_keyword("SUBSTR");
18569 self.write("(");
18570 for (i, arg) in func.args.iter().enumerate() {
18571 if i > 0 {
18572 self.write(", ");
18573 }
18574 self.generate_expression(arg)?;
18575 }
18576 self.write(")");
18577 return Ok(());
18578 }
18579
18580 if self.config.dialect == Some(DialectType::Snowflake)
18581 && func.name.eq_ignore_ascii_case("LIST_DISTINCT")
18582 && func.args.len() == 1
18583 {
18584 self.write_keyword("ARRAY_DISTINCT");
18585 self.write("(");
18586 self.write_keyword("ARRAY_COMPACT");
18587 self.write("(");
18588 self.generate_expression(&func.args[0])?;
18589 self.write("))");
18590 return Ok(());
18591 }
18592
18593 if self.config.dialect == Some(DialectType::Snowflake)
18594 && func.name.eq_ignore_ascii_case("LIST")
18595 && func.args.len() == 1
18596 && !matches!(func.args.first(), Some(Expression::Select(_)))
18597 {
18598 self.write_keyword("ARRAY_AGG");
18599 self.write("(");
18600 self.generate_expression(&func.args[0])?;
18601 self.write(")");
18602 return Ok(());
18603 }
18604
18605 if self.config.dialect == Some(DialectType::Redshift)
18607 && func.name.eq_ignore_ascii_case("CONCAT")
18608 && func.args.len() >= 2
18609 {
18610 for (i, arg) in func.args.iter().enumerate() {
18611 if i > 0 {
18612 self.write(" || ");
18613 }
18614 self.generate_expression(arg)?;
18615 }
18616 return Ok(());
18617 }
18618
18619 if self.config.dialect == Some(DialectType::Redshift)
18621 && func.name.eq_ignore_ascii_case("CONCAT_WS")
18622 && func.args.len() >= 2
18623 {
18624 let sep = &func.args[0];
18625 for (i, arg) in func.args.iter().skip(1).enumerate() {
18626 if i > 0 {
18627 self.write(" || ");
18628 self.generate_expression(sep)?;
18629 self.write(" || ");
18630 }
18631 self.generate_expression(arg)?;
18632 }
18633 return Ok(());
18634 }
18635
18636 if self.config.dialect == Some(DialectType::Redshift)
18639 && (func.name.eq_ignore_ascii_case("DATEDIFF")
18640 || func.name.eq_ignore_ascii_case("DATE_DIFF"))
18641 && func.args.len() == 3
18642 {
18643 self.write_keyword("DATEDIFF");
18644 self.write("(");
18645 self.write_redshift_date_part(&func.args[0]);
18647 self.write(", ");
18648 self.generate_expression(&func.args[1])?;
18649 self.write(", ");
18650 self.generate_expression(&func.args[2])?;
18651 self.write(")");
18652 return Ok(());
18653 }
18654
18655 if self.config.dialect == Some(DialectType::Redshift)
18658 && (func.name.eq_ignore_ascii_case("DATEADD")
18659 || func.name.eq_ignore_ascii_case("DATE_ADD"))
18660 && func.args.len() == 3
18661 {
18662 self.write_keyword("DATEADD");
18663 self.write("(");
18664 self.write_redshift_date_part(&func.args[0]);
18666 self.write(", ");
18667 self.generate_expression(&func.args[1])?;
18668 self.write(", ");
18669 self.generate_expression(&func.args[2])?;
18670 self.write(")");
18671 return Ok(());
18672 }
18673
18674 if func.name.eq_ignore_ascii_case("UUID_STRING")
18676 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None)
18677 {
18678 if matches!(
18679 self.config.dialect,
18680 Some(DialectType::Hive | DialectType::Spark | DialectType::Databricks)
18681 ) {
18682 self.write_keyword("CAST");
18683 self.write("(");
18684 self.write_keyword("UUID");
18685 self.write("() ");
18686 self.write_keyword("AS");
18687 self.write(" ");
18688 self.write_keyword("STRING");
18689 self.write(")");
18690 return Ok(());
18691 }
18692
18693 if matches!(
18694 self.config.dialect,
18695 Some(DialectType::Presto | DialectType::Trino)
18696 ) {
18697 self.write_keyword("CAST");
18698 self.write("(");
18699 self.write_keyword("UUID");
18700 self.write("() ");
18701 self.write_keyword("AS");
18702 self.write(" ");
18703 self.write_keyword("VARCHAR");
18704 self.write(")");
18705 return Ok(());
18706 }
18707
18708 if self.config.dialect == Some(DialectType::DuckDB) && func.args.len() == 2 {
18709 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(");
18710 self.generate_expression(&func.args[0])?;
18711 self.write(", '-', '')) || ENCODE(");
18712 self.generate_expression(&func.args[1])?;
18713 self.write(")), 1, 32) AS h))");
18714 return Ok(());
18715 }
18716
18717 let func_name = match self.config.dialect {
18718 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
18719 Some(DialectType::BigQuery) => "GENERATE_UUID",
18720 _ => "UUID",
18721 };
18722 self.write_keyword(func_name);
18723 self.write("()");
18724 return Ok(());
18725 }
18726
18727 if matches!(self.config.dialect, Some(DialectType::Snowflake))
18731 && func.name.eq_ignore_ascii_case("GENERATOR")
18732 {
18733 let has_positional_args =
18734 !func.args.is_empty() && !matches!(&func.args[0], Expression::NamedArgument(_));
18735 if has_positional_args {
18736 let param_names = ["ROWCOUNT", "TIMELIMIT"];
18737 self.write_keyword("GENERATOR");
18738 self.write("(");
18739 for (i, arg) in func.args.iter().enumerate() {
18740 if i > 0 {
18741 self.write(", ");
18742 }
18743 if i < param_names.len() {
18744 self.write_keyword(param_names[i]);
18745 self.write(" => ");
18746 self.generate_expression(arg)?;
18747 } else {
18748 self.generate_expression(arg)?;
18749 }
18750 }
18751 self.write(")");
18752 return Ok(());
18753 }
18754 }
18755
18756 if self.config.dialect == Some(DialectType::Redshift)
18759 && func.name.eq_ignore_ascii_case("DATE_TRUNC")
18760 && func.args.len() == 2
18761 {
18762 self.write_keyword("DATE_TRUNC");
18763 self.write("(");
18764 self.write_redshift_date_part_quoted(&func.args[0]);
18766 self.write(", ");
18767 self.generate_expression(&func.args[1])?;
18768 self.write(")");
18769 return Ok(());
18770 }
18771
18772 if matches!(
18774 self.config.dialect,
18775 Some(DialectType::TSQL) | Some(DialectType::Fabric)
18776 ) && (func.name.eq_ignore_ascii_case("DATE_PART")
18777 || func.name.eq_ignore_ascii_case("DATEPART"))
18778 && func.args.len() == 2
18779 {
18780 if let Some(part) = self.extract_date_part_string(&func.args[0]) {
18781 let date_part = self.classify_tsql_date_part_name(&part);
18782 self.generate_tsql_date_part(date_part, &func.args[1])?;
18783 } else {
18784 self.write_keyword("DATEPART");
18785 self.write("(");
18786 self.generate_expression(&func.args[0])?;
18787 self.write(", ");
18788 self.generate_expression(&func.args[1])?;
18789 self.write(")");
18790 }
18791 return Ok(());
18792 }
18793
18794 if matches!(
18796 self.config.dialect,
18797 Some(DialectType::TSQL) | Some(DialectType::Fabric)
18798 ) && (func.name.eq_ignore_ascii_case("DATETRUNC")
18799 || func.name.eq_ignore_ascii_case("DATE_TRUNC"))
18800 && func.args.len() == 2
18801 {
18802 if let Some(part) = self.extract_date_part_string(&func.args[0]) {
18803 let date_part = self.classify_tsql_date_trunc_name(&part);
18804 self.generate_tsql_date_trunc(date_part, &func.args[1])?;
18805 } else {
18806 self.write_keyword("DATETRUNC");
18807 self.write("(");
18808 self.generate_expression(&func.args[0])?;
18809 self.write(", ");
18810 self.generate_expression(&func.args[1])?;
18811 self.write(")");
18812 }
18813 return Ok(());
18814 }
18815
18816 if matches!(
18818 self.config.dialect,
18819 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
18820 ) && (func.name.eq_ignore_ascii_case("DATE_PART")
18821 || func.name.eq_ignore_ascii_case("DATEPART"))
18822 && func.args.len() == 2
18823 {
18824 self.write_keyword("EXTRACT");
18825 self.write("(");
18826 match &func.args[0] {
18828 Expression::Literal(lit)
18829 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
18830 {
18831 let crate::expressions::Literal::String(s) = lit.as_ref() else {
18832 unreachable!()
18833 };
18834 self.write(&s.to_ascii_lowercase());
18835 }
18836 _ => self.generate_expression(&func.args[0])?,
18837 }
18838 self.write_space();
18839 self.write_keyword("FROM");
18840 self.write_space();
18841 self.generate_expression(&func.args[1])?;
18842 self.write(")");
18843 return Ok(());
18844 }
18845
18846 if self.config.dialect == Some(DialectType::PostgreSQL)
18848 && matches!(
18849 func.name.to_ascii_uppercase().as_str(),
18850 "DATE_ADD" | "DATE_SUB"
18851 )
18852 && func.args.len() == 2
18853 && matches!(func.args[1], Expression::Interval(_))
18854 {
18855 self.generate_expression(&func.args[0])?;
18856 self.write_space();
18857 if func.name.eq_ignore_ascii_case("DATE_SUB") {
18858 self.write("-");
18859 } else {
18860 self.write("+");
18861 }
18862 self.write_space();
18863 self.generate_expression(&func.args[1])?;
18864 return Ok(());
18865 }
18866
18867 if self.config.dialect == Some(DialectType::Dremio)
18870 && (func.name.eq_ignore_ascii_case("DATE_PART")
18871 || func.name.eq_ignore_ascii_case("DATEPART"))
18872 && func.args.len() == 2
18873 {
18874 self.write_keyword("EXTRACT");
18875 self.write("(");
18876 self.generate_expression(&func.args[0])?;
18877 self.write_space();
18878 self.write_keyword("FROM");
18879 self.write_space();
18880 self.generate_dremio_date_expression(&func.args[1])?;
18882 self.write(")");
18883 return Ok(());
18884 }
18885
18886 if self.config.dialect == Some(DialectType::Dremio)
18888 && func.name.eq_ignore_ascii_case("CURRENT_DATE_UTC")
18889 && func.args.is_empty()
18890 {
18891 self.write_keyword("CURRENT_DATE_UTC");
18892 return Ok(());
18893 }
18894
18895 if self.config.dialect == Some(DialectType::Dremio)
18899 && func.name.eq_ignore_ascii_case("DATETYPE")
18900 && func.args.len() == 3
18901 {
18902 fn get_int_literal(expr: &Expression) -> Option<i64> {
18904 if let Expression::Literal(lit) = expr {
18905 if let crate::expressions::Literal::Number(s) = lit.as_ref() {
18906 s.parse::<i64>().ok()
18907 } else {
18908 None
18909 }
18910 } else {
18911 None
18912 }
18913 }
18914
18915 if let (Some(year), Some(month), Some(day)) = (
18917 get_int_literal(&func.args[0]),
18918 get_int_literal(&func.args[1]),
18919 get_int_literal(&func.args[2]),
18920 ) {
18921 self.write_keyword("DATE");
18923 self.write(&format!("('{:04}-{:02}-{:02}')", year, month, day));
18924 return Ok(());
18925 }
18926
18927 self.write_keyword("CAST");
18929 self.write("(");
18930 self.write_keyword("CONCAT");
18931 self.write("(");
18932 self.generate_expression(&func.args[0])?;
18933 self.write(", '-', ");
18934 self.generate_expression(&func.args[1])?;
18935 self.write(", '-', ");
18936 self.generate_expression(&func.args[2])?;
18937 self.write(")");
18938 self.write_space();
18939 self.write_keyword("AS");
18940 self.write_space();
18941 self.write_keyword("DATE");
18942 self.write(")");
18943 return Ok(());
18944 }
18945
18946 let is_presto_like = matches!(
18949 self.config.dialect,
18950 Some(DialectType::Presto) | Some(DialectType::Trino)
18951 );
18952 if is_presto_like && func.name.eq_ignore_ascii_case("DATE_ADD") && func.args.len() == 3 {
18953 self.write_keyword("DATE_ADD");
18954 self.write("(");
18955 self.generate_expression(&func.args[0])?;
18957 self.write(", ");
18958 let interval = &func.args[1];
18960 let needs_cast = !self.returns_integer_type(interval);
18961 if needs_cast {
18962 self.write_keyword("CAST");
18963 self.write("(");
18964 }
18965 self.generate_expression(interval)?;
18966 if needs_cast {
18967 self.write_space();
18968 self.write_keyword("AS");
18969 self.write_space();
18970 self.write_keyword("BIGINT");
18971 self.write(")");
18972 }
18973 self.write(", ");
18974 self.generate_expression(&func.args[2])?;
18976 self.write(")");
18977 return Ok(());
18978 }
18979
18980 let use_brackets = func.use_bracket_syntax;
18982
18983 let has_ordinality = func.name.len() >= 16
18988 && func.name[func.name.len() - 16..].eq_ignore_ascii_case(" WITH ORDINALITY");
18989 let output_name = if has_ordinality {
18990 let base_name = &func.name[..func.name.len() - " WITH ORDINALITY".len()];
18991 self.normalize_func_name(base_name)
18992 } else {
18993 normalized_name.clone()
18994 };
18995
18996 let quote_source_clickhouse_function =
18999 matches!(self.config.dialect, Some(DialectType::ClickHouse))
19000 && matches!(self.config.source_dialect, Some(DialectType::ClickHouse))
19001 && func.quoted;
19002
19003 if quote_source_clickhouse_function {
19004 self.generate_identifier(&Identifier {
19005 name: func.name.clone(),
19006 quoted: true,
19007 trailing_comments: Vec::new(),
19008 span: None,
19009 })?;
19010 } else if func.name.contains('.') && !has_ordinality {
19011 if func.quoted {
19014 self.write("`");
19015 self.write(&func.name);
19016 self.write("`");
19017 } else {
19018 self.write(&func.name);
19019 }
19020 } else {
19021 self.write(&output_name);
19022 }
19023
19024 let force_parens = func.no_parens && func.args.is_empty() && !func.distinct && {
19027 let needs_parens = if func.name.eq_ignore_ascii_case("CURRENT_USER")
19028 || func.name.eq_ignore_ascii_case("SESSION_USER")
19029 || func.name.eq_ignore_ascii_case("SYSTEM_USER")
19030 {
19031 matches!(
19032 self.config.dialect,
19033 Some(DialectType::Snowflake)
19034 | Some(DialectType::Spark)
19035 | Some(DialectType::Databricks)
19036 | Some(DialectType::Hive)
19037 )
19038 } else {
19039 false
19040 };
19041 !needs_parens
19042 };
19043 if force_parens {
19044 for comment in &func.trailing_comments {
19046 self.write_space();
19047 self.write_formatted_comment(comment);
19048 }
19049 return Ok(());
19050 }
19051
19052 if func.name.eq_ignore_ascii_case("CUBE")
19054 || func.name.eq_ignore_ascii_case("ROLLUP")
19055 || func.name.eq_ignore_ascii_case("GROUPING SETS")
19056 {
19057 self.write(" (");
19058 } else if use_brackets {
19059 self.write("[");
19060 } else {
19061 self.write("(");
19062 }
19063 if func.distinct {
19064 self.write_keyword("DISTINCT");
19065 self.write_space();
19066 }
19067
19068 let compact_pretty_func = matches!(self.config.dialect, Some(DialectType::Snowflake))
19070 && (func.name.eq_ignore_ascii_case("TABLE")
19071 || func.name.eq_ignore_ascii_case("FLATTEN"));
19072 let is_grouping_func = func.name.eq_ignore_ascii_case("GROUPING SETS")
19074 || func.name.eq_ignore_ascii_case("CUBE")
19075 || func.name.eq_ignore_ascii_case("ROLLUP");
19076 let should_split = if self.config.pretty && !func.args.is_empty() && !compact_pretty_func {
19077 if is_grouping_func {
19078 true
19079 } else {
19080 let mut expr_strings: Vec<String> = Vec::with_capacity(func.args.len());
19082 for arg in &func.args {
19083 let mut temp_gen = Generator::with_arc_config(self.config.clone());
19084 Arc::make_mut(&mut temp_gen.config).pretty = false; temp_gen.generate_expression(arg)?;
19086 expr_strings.push(temp_gen.output);
19087 }
19088 self.too_wide(&expr_strings)
19089 }
19090 } else {
19091 false
19092 };
19093
19094 if should_split {
19095 self.write_newline();
19097 self.indent_level += 1;
19098 for (i, arg) in func.args.iter().enumerate() {
19099 self.write_indent();
19100 self.generate_expression(arg)?;
19101 if i + 1 < func.args.len() {
19102 self.write(",");
19103 }
19104 self.write_newline();
19105 }
19106 self.indent_level -= 1;
19107 self.write_indent();
19108 } else {
19109 for (i, arg) in func.args.iter().enumerate() {
19111 if i > 0 {
19112 self.write(", ");
19113 }
19114 self.generate_expression(arg)?;
19115 }
19116 }
19117
19118 if use_brackets {
19119 self.write("]");
19120 } else {
19121 self.write(")");
19122 }
19123 if has_ordinality {
19125 self.write_space();
19126 self.write_keyword("WITH ORDINALITY");
19127 }
19128 for comment in &func.trailing_comments {
19130 self.write_space();
19131 self.write_formatted_comment(comment);
19132 }
19133 Ok(())
19134 }
19135
19136 fn generate_function_emits(&mut self, fe: &FunctionEmits) -> Result<()> {
19137 self.generate_expression(&fe.this)?;
19138 self.write_keyword(" EMITS ");
19139 self.generate_expression(&fe.emits)?;
19140 Ok(())
19141 }
19142
19143 fn generate_aggregate_function(&mut self, func: &AggregateFunction) -> Result<()> {
19144 let mut normalized_name = self.normalize_func_name(&func.name);
19146
19147 if func.name.eq_ignore_ascii_case("MAX_BY") || func.name.eq_ignore_ascii_case("MIN_BY") {
19149 let is_max = func.name.eq_ignore_ascii_case("MAX_BY");
19150 match self.config.dialect {
19151 Some(DialectType::ClickHouse) => {
19152 normalized_name = if is_max {
19153 Cow::Borrowed("argMax")
19154 } else {
19155 Cow::Borrowed("argMin")
19156 };
19157 }
19158 Some(DialectType::DuckDB) => {
19159 normalized_name = if is_max {
19160 Cow::Borrowed("ARG_MAX")
19161 } else {
19162 Cow::Borrowed("ARG_MIN")
19163 };
19164 }
19165 _ => {}
19166 }
19167 }
19168 self.write(normalized_name.as_ref());
19169 self.write("(");
19170 if func.distinct {
19171 self.write_keyword("DISTINCT");
19172 self.write_space();
19173 }
19174
19175 let is_count = normalized_name.eq_ignore_ascii_case("COUNT");
19179 let needs_multi_arg_transform =
19180 func.distinct && is_count && func.args.len() > 1 && !self.config.multi_arg_distinct;
19181
19182 if needs_multi_arg_transform {
19183 self.write_keyword("CASE");
19185 for arg in &func.args {
19186 self.write_space();
19187 self.write_keyword("WHEN");
19188 self.write_space();
19189 self.generate_expression(arg)?;
19190 self.write_space();
19191 self.write_keyword("IS NULL THEN NULL");
19192 }
19193 self.write_space();
19194 self.write_keyword("ELSE");
19195 self.write(" (");
19196 for (i, arg) in func.args.iter().enumerate() {
19197 if i > 0 {
19198 self.write(", ");
19199 }
19200 self.generate_expression(arg)?;
19201 }
19202 self.write(")");
19203 self.write_space();
19204 self.write_keyword("END");
19205 } else {
19206 for (i, arg) in func.args.iter().enumerate() {
19207 if i > 0 {
19208 self.write(", ");
19209 }
19210 self.generate_expression(arg)?;
19211 }
19212 }
19213
19214 let clickhouse_ignore_nulls_outside =
19216 matches!(self.config.dialect, Some(DialectType::ClickHouse));
19217 if self.config.ignore_nulls_in_func
19218 && !matches!(
19219 self.config.dialect,
19220 Some(DialectType::DuckDB) | Some(DialectType::ClickHouse)
19221 )
19222 {
19223 if let Some(ignore) = func.ignore_nulls {
19224 self.write_space();
19225 if ignore {
19226 self.write_keyword("IGNORE NULLS");
19227 } else {
19228 self.write_keyword("RESPECT NULLS");
19229 }
19230 }
19231 }
19232
19233 if !func.order_by.is_empty() {
19235 self.write_space();
19236 self.write_keyword("ORDER BY");
19237 self.write_space();
19238 for (i, ord) in func.order_by.iter().enumerate() {
19239 if i > 0 {
19240 self.write(", ");
19241 }
19242 self.generate_ordered(ord)?;
19243 }
19244 }
19245
19246 if let Some(limit) = &func.limit {
19248 self.write_space();
19249 self.write_keyword("LIMIT");
19250 self.write_space();
19251 if let Expression::Tuple(t) = limit.as_ref() {
19253 if t.expressions.len() == 2 {
19254 self.generate_expression(&t.expressions[0])?;
19255 self.write(", ");
19256 self.generate_expression(&t.expressions[1])?;
19257 } else {
19258 self.generate_expression(limit)?;
19259 }
19260 } else {
19261 self.generate_expression(limit)?;
19262 }
19263 }
19264
19265 self.write(")");
19266
19267 if (!self.config.ignore_nulls_in_func || clickhouse_ignore_nulls_outside)
19269 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
19270 {
19271 if let Some(ignore) = func.ignore_nulls {
19272 self.write_space();
19273 if ignore {
19274 self.write_keyword("IGNORE NULLS");
19275 } else {
19276 self.write_keyword("RESPECT NULLS");
19277 }
19278 }
19279 }
19280
19281 if let Some(filter) = &func.filter {
19282 self.write_space();
19283 self.write_keyword("FILTER");
19284 self.write("(");
19285 self.write_keyword("WHERE");
19286 self.write_space();
19287 self.generate_expression(filter)?;
19288 self.write(")");
19289 }
19290
19291 Ok(())
19292 }
19293
19294 fn generate_window_function(&mut self, wf: &WindowFunction) -> Result<()> {
19295 self.generate_expression(&wf.this)?;
19296
19297 if let Some(keep) = &wf.keep {
19299 self.write_space();
19300 self.write_keyword("KEEP");
19301 self.write(" (");
19302 self.write_keyword("DENSE_RANK");
19303 self.write_space();
19304 if keep.first {
19305 self.write_keyword("FIRST");
19306 } else {
19307 self.write_keyword("LAST");
19308 }
19309 self.write_space();
19310 self.write_keyword("ORDER BY");
19311 self.write_space();
19312 for (i, ord) in keep.order_by.iter().enumerate() {
19313 if i > 0 {
19314 self.write(", ");
19315 }
19316 self.generate_ordered(ord)?;
19317 }
19318 self.write(")");
19319 }
19320
19321 let has_over = !wf.over.partition_by.is_empty()
19323 || !wf.over.order_by.is_empty()
19324 || wf.over.frame.is_some()
19325 || wf.over.window_name.is_some();
19326
19327 if has_over {
19329 self.write_space();
19330 self.write_keyword("OVER");
19331
19332 let has_specs = !wf.over.partition_by.is_empty()
19334 || !wf.over.order_by.is_empty()
19335 || wf.over.frame.is_some();
19336
19337 if wf.over.window_name.is_some() && !has_specs {
19338 self.write_space();
19340 self.write(&wf.over.window_name.as_ref().unwrap().name);
19341 } else {
19342 self.write(" (");
19344 self.generate_over(&wf.over)?;
19345 self.write(")");
19346 }
19347 } else if wf.keep.is_none() {
19348 self.write_space();
19350 self.write_keyword("OVER");
19351 self.write(" ()");
19352 }
19353
19354 Ok(())
19355 }
19356
19357 fn generate_within_group(&mut self, wg: &WithinGroup) -> Result<()> {
19359 self.generate_expression(&wg.this)?;
19360 self.write_space();
19361 self.write_keyword("WITHIN GROUP");
19362 self.write(" (");
19363 self.write_keyword("ORDER BY");
19364 self.write_space();
19365 for (i, ord) in wg.order_by.iter().enumerate() {
19366 if i > 0 {
19367 self.write(", ");
19368 }
19369 self.generate_ordered(ord)?;
19370 }
19371 self.write(")");
19372 Ok(())
19373 }
19374
19375 fn generate_over(&mut self, over: &Over) -> Result<()> {
19377 let mut has_content = false;
19378
19379 if let Some(name) = &over.window_name {
19381 self.write(&name.name);
19382 has_content = true;
19383 }
19384
19385 if !over.partition_by.is_empty() {
19387 if has_content {
19388 self.write_space();
19389 }
19390 self.write_keyword("PARTITION BY");
19391 self.write_space();
19392 for (i, expr) in over.partition_by.iter().enumerate() {
19393 if i > 0 {
19394 self.write(", ");
19395 }
19396 self.generate_expression(expr)?;
19397 }
19398 has_content = true;
19399 }
19400
19401 if !over.order_by.is_empty() {
19403 if has_content {
19404 self.write_space();
19405 }
19406 self.write_keyword("ORDER BY");
19407 self.write_space();
19408 for (i, ordered) in over.order_by.iter().enumerate() {
19409 if i > 0 {
19410 self.write(", ");
19411 }
19412 self.generate_ordered(ordered)?;
19413 }
19414 has_content = true;
19415 }
19416
19417 if let Some(frame) = &over.frame {
19419 if has_content {
19420 self.write_space();
19421 }
19422 self.generate_window_frame(frame)?;
19423 }
19424
19425 Ok(())
19426 }
19427
19428 fn generate_window_frame(&mut self, frame: &WindowFrame) -> Result<()> {
19429 let lowercase_frame = self.config.lowercase_window_frame_keywords;
19431
19432 if !lowercase_frame {
19434 if let Some(kind_text) = &frame.kind_text {
19435 self.write(kind_text);
19436 } else {
19437 match frame.kind {
19438 WindowFrameKind::Rows => self.write_keyword("ROWS"),
19439 WindowFrameKind::Range => self.write_keyword("RANGE"),
19440 WindowFrameKind::Groups => self.write_keyword("GROUPS"),
19441 }
19442 }
19443 } else {
19444 match frame.kind {
19445 WindowFrameKind::Rows => self.write("rows"),
19446 WindowFrameKind::Range => self.write("range"),
19447 WindowFrameKind::Groups => self.write("groups"),
19448 }
19449 }
19450
19451 self.write_space();
19454 let should_normalize = self.config.normalize_window_frame_between
19455 && frame.end.is_none()
19456 && matches!(
19457 frame.start,
19458 WindowFrameBound::Preceding(_)
19459 | WindowFrameBound::Following(_)
19460 | WindowFrameBound::UnboundedPreceding
19461 | WindowFrameBound::UnboundedFollowing
19462 );
19463
19464 if let Some(end) = &frame.end {
19465 self.write_keyword("BETWEEN");
19467 self.write_space();
19468 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
19469 self.write_space();
19470 self.write_keyword("AND");
19471 self.write_space();
19472 self.generate_window_frame_bound(end, frame.end_side_text.as_deref())?;
19473 } else if should_normalize {
19474 self.write_keyword("BETWEEN");
19476 self.write_space();
19477 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
19478 self.write_space();
19479 self.write_keyword("AND");
19480 self.write_space();
19481 self.write_keyword("CURRENT ROW");
19482 } else {
19483 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
19485 }
19486
19487 if let Some(exclude) = &frame.exclude {
19489 self.write_space();
19490 self.write_keyword("EXCLUDE");
19491 self.write_space();
19492 match exclude {
19493 WindowFrameExclude::CurrentRow => self.write_keyword("CURRENT ROW"),
19494 WindowFrameExclude::Group => self.write_keyword("GROUP"),
19495 WindowFrameExclude::Ties => self.write_keyword("TIES"),
19496 WindowFrameExclude::NoOthers => self.write_keyword("NO OTHERS"),
19497 }
19498 }
19499
19500 Ok(())
19501 }
19502
19503 fn generate_window_frame_bound(
19504 &mut self,
19505 bound: &WindowFrameBound,
19506 side_text: Option<&str>,
19507 ) -> Result<()> {
19508 let lowercase_frame = self.config.lowercase_window_frame_keywords;
19510
19511 match bound {
19512 WindowFrameBound::CurrentRow => {
19513 self.write_keyword("CURRENT ROW");
19514 }
19515 WindowFrameBound::UnboundedPreceding => {
19516 self.write_keyword("UNBOUNDED");
19517 self.write_space();
19518 if lowercase_frame {
19519 self.write("preceding");
19520 } else if let Some(text) = side_text {
19521 self.write(text);
19522 } else {
19523 self.write_keyword("PRECEDING");
19524 }
19525 }
19526 WindowFrameBound::UnboundedFollowing => {
19527 self.write_keyword("UNBOUNDED");
19528 self.write_space();
19529 if lowercase_frame {
19530 self.write("following");
19531 } else if let Some(text) = side_text {
19532 self.write(text);
19533 } else {
19534 self.write_keyword("FOLLOWING");
19535 }
19536 }
19537 WindowFrameBound::Preceding(expr) => {
19538 self.generate_expression(expr)?;
19539 self.write_space();
19540 if lowercase_frame {
19541 self.write("preceding");
19542 } else if let Some(text) = side_text {
19543 self.write(text);
19544 } else {
19545 self.write_keyword("PRECEDING");
19546 }
19547 }
19548 WindowFrameBound::Following(expr) => {
19549 self.generate_expression(expr)?;
19550 self.write_space();
19551 if lowercase_frame {
19552 self.write("following");
19553 } else if let Some(text) = side_text {
19554 self.write(text);
19555 } else {
19556 self.write_keyword("FOLLOWING");
19557 }
19558 }
19559 WindowFrameBound::BarePreceding => {
19560 if lowercase_frame {
19561 self.write("preceding");
19562 } else if let Some(text) = side_text {
19563 self.write(text);
19564 } else {
19565 self.write_keyword("PRECEDING");
19566 }
19567 }
19568 WindowFrameBound::BareFollowing => {
19569 if lowercase_frame {
19570 self.write("following");
19571 } else if let Some(text) = side_text {
19572 self.write(text);
19573 } else {
19574 self.write_keyword("FOLLOWING");
19575 }
19576 }
19577 WindowFrameBound::Value(expr) => {
19578 self.generate_expression(expr)?;
19580 }
19581 }
19582 Ok(())
19583 }
19584
19585 fn generate_interval(&mut self, interval: &Interval) -> Result<()> {
19586 let skip_interval_keyword = matches!(self.config.dialect, Some(DialectType::Oracle))
19589 && matches!(&interval.unit, Some(IntervalUnitSpec::ExprSpan(_)))
19590 && !matches!(&interval.this, Some(Expression::Literal(_)));
19591
19592 if self.config.single_string_interval {
19595 if let (
19596 Some(Expression::Literal(lit)),
19597 Some(IntervalUnitSpec::Simple {
19598 ref unit,
19599 ref use_plural,
19600 }),
19601 ) = (&interval.this, &interval.unit)
19602 {
19603 if let Literal::String(ref val) = lit.as_ref() {
19604 self.write_keyword("INTERVAL");
19605 self.write_space();
19606 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
19607 let unit_str = self.interval_unit_str(unit, effective_plural);
19608 self.write("'");
19609 self.write(val);
19610 self.write(" ");
19611 self.write(&unit_str);
19612 self.write("'");
19613 return Ok(());
19614 }
19615 }
19616 }
19617
19618 if !skip_interval_keyword {
19619 self.write_keyword("INTERVAL");
19620 }
19621
19622 if let Some(ref value) = interval.this {
19624 if !skip_interval_keyword {
19625 self.write_space();
19626 }
19627 let needs_parens = interval.unit.is_some()
19631 && matches!(
19632 value,
19633 Expression::Add(_)
19634 | Expression::Sub(_)
19635 | Expression::Mul(_)
19636 | Expression::Div(_)
19637 | Expression::Mod(_)
19638 | Expression::BitwiseAnd(_)
19639 | Expression::BitwiseOr(_)
19640 | Expression::BitwiseXor(_)
19641 );
19642 if needs_parens {
19643 self.write("(");
19644 }
19645 self.generate_expression(value)?;
19646 if needs_parens {
19647 self.write(")");
19648 }
19649 }
19650
19651 if let Some(ref unit_spec) = interval.unit {
19653 self.write_space();
19654 self.write_interval_unit_spec(unit_spec)?;
19655 }
19656
19657 Ok(())
19658 }
19659
19660 fn interval_unit_str(&self, unit: &IntervalUnit, use_plural: bool) -> &'static str {
19662 match (unit, use_plural) {
19663 (IntervalUnit::Year, false) => "YEAR",
19664 (IntervalUnit::Year, true) => "YEARS",
19665 (IntervalUnit::Quarter, false) => "QUARTER",
19666 (IntervalUnit::Quarter, true) => "QUARTERS",
19667 (IntervalUnit::Month, false) => "MONTH",
19668 (IntervalUnit::Month, true) => "MONTHS",
19669 (IntervalUnit::Week, false) => "WEEK",
19670 (IntervalUnit::Week, true) => "WEEKS",
19671 (IntervalUnit::Day, false) => "DAY",
19672 (IntervalUnit::Day, true) => "DAYS",
19673 (IntervalUnit::Hour, false) => "HOUR",
19674 (IntervalUnit::Hour, true) => "HOURS",
19675 (IntervalUnit::Minute, false) => "MINUTE",
19676 (IntervalUnit::Minute, true) => "MINUTES",
19677 (IntervalUnit::Second, false) => "SECOND",
19678 (IntervalUnit::Second, true) => "SECONDS",
19679 (IntervalUnit::Millisecond, false) => "MILLISECOND",
19680 (IntervalUnit::Millisecond, true) => "MILLISECONDS",
19681 (IntervalUnit::Microsecond, false) => "MICROSECOND",
19682 (IntervalUnit::Microsecond, true) => "MICROSECONDS",
19683 (IntervalUnit::Nanosecond, false) => "NANOSECOND",
19684 (IntervalUnit::Nanosecond, true) => "NANOSECONDS",
19685 }
19686 }
19687
19688 fn write_interval_unit_spec(&mut self, unit_spec: &IntervalUnitSpec) -> Result<()> {
19689 match unit_spec {
19690 IntervalUnitSpec::Simple { unit, use_plural } => {
19691 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
19693 self.write_simple_interval_unit(unit, effective_plural);
19694 }
19695 IntervalUnitSpec::Span(span) => {
19696 self.write_simple_interval_unit(&span.this, false);
19697 self.write_space();
19698 self.write_keyword("TO");
19699 self.write_space();
19700 self.write_simple_interval_unit(&span.expression, false);
19701 }
19702 IntervalUnitSpec::ExprSpan(span) => {
19703 self.generate_expression(&span.this)?;
19705 self.write_space();
19706 self.write_keyword("TO");
19707 self.write_space();
19708 self.generate_expression(&span.expression)?;
19709 }
19710 IntervalUnitSpec::Expr(expr) => {
19711 self.generate_expression(expr)?;
19712 }
19713 }
19714 Ok(())
19715 }
19716
19717 fn write_simple_interval_unit(&mut self, unit: &IntervalUnit, use_plural: bool) {
19718 match (unit, use_plural) {
19720 (IntervalUnit::Year, false) => self.write_keyword("YEAR"),
19721 (IntervalUnit::Year, true) => self.write_keyword("YEARS"),
19722 (IntervalUnit::Quarter, false) => self.write_keyword("QUARTER"),
19723 (IntervalUnit::Quarter, true) => self.write_keyword("QUARTERS"),
19724 (IntervalUnit::Month, false) => self.write_keyword("MONTH"),
19725 (IntervalUnit::Month, true) => self.write_keyword("MONTHS"),
19726 (IntervalUnit::Week, false) => self.write_keyword("WEEK"),
19727 (IntervalUnit::Week, true) => self.write_keyword("WEEKS"),
19728 (IntervalUnit::Day, false) => self.write_keyword("DAY"),
19729 (IntervalUnit::Day, true) => self.write_keyword("DAYS"),
19730 (IntervalUnit::Hour, false) => self.write_keyword("HOUR"),
19731 (IntervalUnit::Hour, true) => self.write_keyword("HOURS"),
19732 (IntervalUnit::Minute, false) => self.write_keyword("MINUTE"),
19733 (IntervalUnit::Minute, true) => self.write_keyword("MINUTES"),
19734 (IntervalUnit::Second, false) => self.write_keyword("SECOND"),
19735 (IntervalUnit::Second, true) => self.write_keyword("SECONDS"),
19736 (IntervalUnit::Millisecond, false) => self.write_keyword("MILLISECOND"),
19737 (IntervalUnit::Millisecond, true) => self.write_keyword("MILLISECONDS"),
19738 (IntervalUnit::Microsecond, false) => self.write_keyword("MICROSECOND"),
19739 (IntervalUnit::Microsecond, true) => self.write_keyword("MICROSECONDS"),
19740 (IntervalUnit::Nanosecond, false) => self.write_keyword("NANOSECOND"),
19741 (IntervalUnit::Nanosecond, true) => self.write_keyword("NANOSECONDS"),
19742 }
19743 }
19744
19745 fn write_redshift_date_part(&mut self, expr: &Expression) {
19748 let part_str = self.extract_date_part_string(expr);
19749 if let Some(part) = part_str {
19750 let normalized = self.normalize_date_part(&part);
19751 self.write_keyword(&normalized);
19752 } else {
19753 let _ = self.generate_expression(expr);
19755 }
19756 }
19757
19758 fn write_redshift_date_part_quoted(&mut self, expr: &Expression) {
19761 let part_str = self.extract_date_part_string(expr);
19762 if let Some(part) = part_str {
19763 let normalized = self.normalize_date_part(&part);
19764 self.write("'");
19765 self.write(&normalized);
19766 self.write("'");
19767 } else {
19768 let _ = self.generate_expression(expr);
19770 }
19771 }
19772
19773 fn extract_date_part_string(&self, expr: &Expression) -> Option<String> {
19775 match expr {
19776 Expression::Literal(lit)
19777 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
19778 {
19779 let crate::expressions::Literal::String(s) = lit.as_ref() else {
19780 unreachable!()
19781 };
19782 Some(s.clone())
19783 }
19784 Expression::Identifier(id) => Some(id.name.clone()),
19785 Expression::Var(v) => Some(v.this.clone()),
19786 Expression::Column(col) if col.table.is_none() => {
19787 Some(col.name.name.clone())
19789 }
19790 Expression::Cast(cast)
19791 if cast.format.is_none()
19792 && cast.default.is_none()
19793 && Self::is_string_data_type(&cast.to)
19794 && matches!(
19795 &cast.this,
19796 Expression::Literal(lit)
19797 if matches!(lit.as_ref(), crate::expressions::Literal::String(_))
19798 ) =>
19799 {
19800 self.extract_date_part_string(&cast.this)
19801 }
19802 _ => None,
19803 }
19804 }
19805
19806 fn classify_tsql_datetime_field(&self, field: &DateTimeField) -> TsqlDatePart {
19807 match field {
19808 DateTimeField::Year => TsqlDatePart::Native("YEAR".to_string()),
19809 DateTimeField::Month => TsqlDatePart::Native("MONTH".to_string()),
19810 DateTimeField::Day => TsqlDatePart::Native("DAY".to_string()),
19811 DateTimeField::Hour => TsqlDatePart::Native("HOUR".to_string()),
19812 DateTimeField::Minute => TsqlDatePart::Native("MINUTE".to_string()),
19813 DateTimeField::Second => TsqlDatePart::Native("SECOND".to_string()),
19814 DateTimeField::Millisecond => TsqlDatePart::Native("MILLISECOND".to_string()),
19815 DateTimeField::Microsecond => TsqlDatePart::Native("MICROSECOND".to_string()),
19816 DateTimeField::DayOfWeek => TsqlDatePart::Native("WEEKDAY".to_string()),
19817 DateTimeField::DayOfYear => TsqlDatePart::Native("DAYOFYEAR".to_string()),
19818 DateTimeField::Week => TsqlDatePart::Native("WEEK".to_string()),
19819 DateTimeField::WeekWithModifier(modifier) => {
19820 TsqlDatePart::Unsupported(format!("WEEK({modifier})"))
19821 }
19822 DateTimeField::Quarter => TsqlDatePart::Native("QUARTER".to_string()),
19823 DateTimeField::Epoch => TsqlDatePart::Epoch,
19824 DateTimeField::TimezoneMinute => TsqlDatePart::Native("TZOFFSET".to_string()),
19825 DateTimeField::Timezone => TsqlDatePart::Unsupported("TIMEZONE".to_string()),
19826 DateTimeField::TimezoneHour => TsqlDatePart::Unsupported("TIMEZONE_HOUR".to_string()),
19827 DateTimeField::Date => TsqlDatePart::Unsupported("DATE".to_string()),
19828 DateTimeField::Time => TsqlDatePart::Unsupported("TIME".to_string()),
19829 DateTimeField::Custom(name) => self.classify_tsql_date_part_name(name),
19830 }
19831 }
19832
19833 fn classify_tsql_date_part_name(&self, part: &str) -> TsqlDatePart {
19834 let trimmed = part.trim();
19835 let upper = trimmed.to_ascii_uppercase();
19836 match upper.as_str() {
19837 "YEAR" => TsqlDatePart::Native(trimmed.to_string()),
19838 "YY" | "YYY" | "YYYY" | "YR" | "YEARS" | "YRS" => {
19839 TsqlDatePart::Native("YEAR".to_string())
19840 }
19841 "QUARTER" => TsqlDatePart::Native(trimmed.to_string()),
19842 "Q" | "QQ" | "QTR" | "QTRS" | "QUARTERS" => TsqlDatePart::Native("QUARTER".to_string()),
19843 "MONTH" => TsqlDatePart::Native(trimmed.to_string()),
19844 "MM" | "M" | "MON" | "MONS" | "MONTHS" => TsqlDatePart::Native("MONTH".to_string()),
19845 "DAYOFYEAR" => TsqlDatePart::Native(trimmed.to_string()),
19846 "DOY" | "DY" | "Y" => TsqlDatePart::Native("DAYOFYEAR".to_string()),
19847 "DAY" => TsqlDatePart::Native(trimmed.to_string()),
19848 "D" | "DD" | "DAYS" | "DAYOFMONTH" => TsqlDatePart::Native("DAY".to_string()),
19849 "WEEK" | "W" | "WK" | "WW" | "WEEKOFYEAR" | "WOY" | "WY" | "WEEKS" => {
19850 if upper == "WEEK" {
19851 TsqlDatePart::Native(trimmed.to_string())
19852 } else {
19853 TsqlDatePart::Native("WEEK".to_string())
19854 }
19855 }
19856 "WEEKDAY" => TsqlDatePart::Native(trimmed.to_string()),
19857 "DAYOFWEEK" | "DOW" | "DW" => TsqlDatePart::Native("WEEKDAY".to_string()),
19858 "ISODOW" | "ISO_DOW" | "DOW_ISO" | "DW_ISO" | "ISO_DAYOFWEEK" | "ISO_WEEKDAY"
19859 | "DAYOFWEEKISO" | "DAYOFWEEK_ISO" | "WEEKDAY_ISO" => TsqlDatePart::IsoDayOfWeek,
19860 "HOUR" => TsqlDatePart::Native(trimmed.to_string()),
19861 "H" | "HH" | "HR" | "HOURS" | "HRS" => TsqlDatePart::Native("HOUR".to_string()),
19862 "MINUTE" => TsqlDatePart::Native(trimmed.to_string()),
19863 "MI" | "MIN" | "MINUTES" | "MINS" | "N" => TsqlDatePart::Native("MINUTE".to_string()),
19864 "SECOND" => TsqlDatePart::Native(trimmed.to_string()),
19865 "S" | "SEC" | "SECONDS" | "SECS" | "SS" => TsqlDatePart::Native("SECOND".to_string()),
19866 "MILLISECOND" | "MS" | "MSEC" | "MSECS" | "MSECOND" | "MSECONDS" | "MILLISEC"
19867 | "MILLISECS" | "MILLISECON" | "MILLISECONDS" => {
19868 if upper == "MILLISECOND" {
19869 TsqlDatePart::Native(trimmed.to_string())
19870 } else {
19871 TsqlDatePart::Native("MILLISECOND".to_string())
19872 }
19873 }
19874 "MICROSECOND" | "US" | "USEC" | "USECS" | "MICROSEC" | "MICROSECS" | "USECOND"
19875 | "USECONDS" | "MICROSECONDS" | "MCS" => {
19876 if upper == "MICROSECOND" {
19877 TsqlDatePart::Native(trimmed.to_string())
19878 } else {
19879 TsqlDatePart::Native("MICROSECOND".to_string())
19880 }
19881 }
19882 "NANOSECOND" | "NS" | "NSEC" | "NANOSEC" | "NSECOND" | "NSECONDS" | "NANOSECS" => {
19883 if upper == "NANOSECOND" {
19884 TsqlDatePart::Native(trimmed.to_string())
19885 } else {
19886 TsqlDatePart::Native("NANOSECOND".to_string())
19887 }
19888 }
19889 "TZOFFSET" => TsqlDatePart::Native(trimmed.to_string()),
19890 "TZ" | "TZM" | "TIMEZONE_MINUTE" => TsqlDatePart::Native("TZOFFSET".to_string()),
19891 "ISO_WEEK" | "ISOWEEK" | "ISOWK" | "ISOWW" | "WEEKISO" | "WEEKOFYEARISO"
19892 | "WEEKOFYEAR_ISO" | "WEEK_ISO" => {
19893 if upper == "ISO_WEEK" {
19894 TsqlDatePart::Native(trimmed.to_string())
19895 } else {
19896 TsqlDatePart::Native("ISO_WEEK".to_string())
19897 }
19898 }
19899 "EPOCH" | "EPOCH_SECOND" | "EPOCH_SECONDS" => TsqlDatePart::Epoch,
19900 "DECADE" | "DECADES" | "DEC" | "DECS" | "CENTURY" | "CENTURIES" | "CENT" | "CENTS"
19901 | "MILLENNIUM" | "MILLENIA" | "MIL" | "MILS" | "TIMEZONE" | "TIMEZONE_HOUR" | "TZH"
19902 | "DATE" | "TIME" => TsqlDatePart::Unsupported(upper),
19903 _ => TsqlDatePart::Unsupported(upper),
19904 }
19905 }
19906
19907 fn classify_tsql_date_trunc_field(&self, field: &DateTimeField) -> TsqlDatePart {
19908 match field {
19909 DateTimeField::Year => TsqlDatePart::Native("YEAR".to_string()),
19910 DateTimeField::Month => TsqlDatePart::Native("MONTH".to_string()),
19911 DateTimeField::Day => TsqlDatePart::Native("DAY".to_string()),
19912 DateTimeField::Hour => TsqlDatePart::Native("HOUR".to_string()),
19913 DateTimeField::Minute => TsqlDatePart::Native("MINUTE".to_string()),
19914 DateTimeField::Second => TsqlDatePart::Native("SECOND".to_string()),
19915 DateTimeField::Millisecond => TsqlDatePart::Native("MILLISECOND".to_string()),
19916 DateTimeField::Microsecond => TsqlDatePart::Native("MICROSECOND".to_string()),
19917 DateTimeField::DayOfYear => TsqlDatePart::Native("DAYOFYEAR".to_string()),
19918 DateTimeField::Week => TsqlDatePart::Native("WEEK".to_string()),
19919 DateTimeField::WeekWithModifier(modifier) => {
19920 match modifier.to_ascii_uppercase().as_str() {
19921 "MONDAY" | "ISO" | "ISO_WEEK" => TsqlDatePart::Native("ISO_WEEK".to_string()),
19922 "SUNDAY" => TsqlDatePart::Native("WEEK".to_string()),
19923 _ => TsqlDatePart::Unsupported(format!("WEEK({modifier})")),
19924 }
19925 }
19926 DateTimeField::Quarter => TsqlDatePart::Native("QUARTER".to_string()),
19927 DateTimeField::DayOfWeek => TsqlDatePart::Unsupported("WEEKDAY".to_string()),
19928 DateTimeField::Epoch => TsqlDatePart::Unsupported("EPOCH".to_string()),
19929 DateTimeField::Timezone => TsqlDatePart::Unsupported("TIMEZONE".to_string()),
19930 DateTimeField::TimezoneHour => TsqlDatePart::Unsupported("TIMEZONE_HOUR".to_string()),
19931 DateTimeField::TimezoneMinute => {
19932 TsqlDatePart::Unsupported("TIMEZONE_MINUTE".to_string())
19933 }
19934 DateTimeField::Date => TsqlDatePart::Unsupported("DATE".to_string()),
19935 DateTimeField::Time => TsqlDatePart::Unsupported("TIME".to_string()),
19936 DateTimeField::Custom(name) => self.classify_tsql_date_trunc_name(name),
19937 }
19938 }
19939
19940 fn classify_tsql_date_trunc_name(&self, part: &str) -> TsqlDatePart {
19941 let upper = part.trim().to_ascii_uppercase();
19942 match upper.as_str() {
19943 "YEAR" | "YY" | "YYY" | "YYYY" | "YR" | "YEARS" | "YRS" => {
19944 TsqlDatePart::Native("YEAR".to_string())
19945 }
19946 "QUARTER" | "Q" | "QQ" | "QTR" | "QTRS" | "QUARTERS" => {
19947 TsqlDatePart::Native("QUARTER".to_string())
19948 }
19949 "MONTH" | "MM" | "M" | "MON" | "MONS" | "MONTHS" => {
19950 TsqlDatePart::Native("MONTH".to_string())
19951 }
19952 "DAYOFYEAR" | "DOY" | "DY" | "Y" => TsqlDatePart::Native("DAYOFYEAR".to_string()),
19953 "DAY" | "D" | "DD" | "DAYS" | "DAYOFMONTH" => TsqlDatePart::Native("DAY".to_string()),
19954 "WEEK" | "W" | "WK" | "WW" | "WEEKS" | "WEEKOFYEAR" | "WOY" | "WY" => {
19955 TsqlDatePart::Native("WEEK".to_string())
19956 }
19957 "ISO_WEEK" | "ISOWEEK" | "ISOWK" | "ISOWW" | "WEEKISO" | "WEEKOFYEARISO"
19958 | "WEEKOFYEAR_ISO" | "WEEK_ISO" => TsqlDatePart::Native("ISO_WEEK".to_string()),
19959 "HOUR" | "H" | "HH" | "HR" | "HOURS" | "HRS" => {
19960 TsqlDatePart::Native("HOUR".to_string())
19961 }
19962 "MINUTE" | "MI" | "MIN" | "MINUTES" | "MINS" | "N" => {
19963 TsqlDatePart::Native("MINUTE".to_string())
19964 }
19965 "SECOND" | "S" | "SEC" | "SECONDS" | "SECS" | "SS" => {
19966 TsqlDatePart::Native("SECOND".to_string())
19967 }
19968 "MILLISECOND" | "MS" | "MSEC" | "MSECS" | "MSECOND" | "MSECONDS" | "MILLISEC"
19969 | "MILLISECS" | "MILLISECON" | "MILLISECONDS" => {
19970 TsqlDatePart::Native("MILLISECOND".to_string())
19971 }
19972 "MICROSECOND" | "US" | "USEC" | "USECS" | "MICROSEC" | "MICROSECS" | "USECOND"
19973 | "USECONDS" | "MICROSECONDS" | "MCS" => {
19974 TsqlDatePart::Native("MICROSECOND".to_string())
19975 }
19976 "WEEKDAY" | "DAYOFWEEK" | "DOW" | "DW" | "ISODOW" | "ISO_DOW" | "DOW_ISO"
19977 | "DW_ISO" | "ISO_DAYOFWEEK" | "ISO_WEEKDAY" | "DAYOFWEEKISO" | "DAYOFWEEK_ISO"
19978 | "WEEKDAY_ISO" | "NANOSECOND" | "NS" | "NSEC" | "NANOSEC" | "NSECOND" | "NSECONDS"
19979 | "NANOSECS" | "TZOFFSET" | "TZ" | "TZM" | "TIMEZONE" | "TIMEZONE_HOUR"
19980 | "TIMEZONE_MINUTE" | "TZH" | "EPOCH" | "EPOCH_SECOND" | "EPOCH_SECONDS" | "DECADE"
19981 | "DECADES" | "DEC" | "DECS" | "CENTURY" | "CENTURIES" | "CENT" | "CENTS"
19982 | "MILLENNIUM" | "MILLENIA" | "MIL" | "MILS" | "DATE" | "TIME" => {
19983 TsqlDatePart::Unsupported(upper)
19984 }
19985 _ => TsqlDatePart::Unsupported(upper),
19986 }
19987 }
19988
19989 fn generate_tsql_date_part(&mut self, part: TsqlDatePart, expr: &Expression) -> Result<()> {
19990 match part {
19991 TsqlDatePart::Native(name) => self.generate_tsql_native_datepart(&name, expr),
19992 TsqlDatePart::Epoch => self.generate_tsql_epoch_seconds(expr),
19993 TsqlDatePart::IsoDayOfWeek => self.generate_tsql_iso_day_of_week(expr),
19994 TsqlDatePart::Unsupported(name) => {
19995 self.unsupported(format!("DATEPART {name} is not supported by T-SQL/Fabric"))?;
19996 self.write_keyword("DATEPART");
19997 self.write("(");
19998 self.write_keyword(&name);
19999 self.write(", ");
20000 self.generate_expression(expr)?;
20001 self.write(")");
20002 Ok(())
20003 }
20004 }
20005 }
20006
20007 fn generate_tsql_native_datepart(&mut self, name: &str, expr: &Expression) -> Result<()> {
20008 self.write_keyword("DATEPART");
20009 self.write("(");
20010 self.write_keyword(name);
20011 self.write(", ");
20012 self.generate_expression(expr)?;
20013 self.write(")");
20014 Ok(())
20015 }
20016
20017 fn generate_tsql_epoch_seconds(&mut self, expr: &Expression) -> Result<()> {
20018 self.write_keyword("DATEDIFF");
20019 self.write("(SECOND, ");
20020 self.write_keyword("CAST");
20021 self.write("('1970-01-01' AS ");
20022 self.write_keyword("DATETIME2");
20023 self.write("), ");
20024 self.generate_expression(expr)?;
20025 self.write(")");
20026 Ok(())
20027 }
20028
20029 fn generate_tsql_iso_day_of_week(&mut self, expr: &Expression) -> Result<()> {
20030 self.write("(((DATEPART(WEEKDAY, ");
20031 self.generate_expression(expr)?;
20032 self.write(") + @@DATEFIRST - 2) % 7) + 1)");
20033 Ok(())
20034 }
20035
20036 fn generate_tsql_date_trunc(&mut self, part: TsqlDatePart, expr: &Expression) -> Result<()> {
20037 match part {
20038 TsqlDatePart::Native(name) => {
20039 self.write_keyword("DATETRUNC");
20040 self.write("(");
20041 self.write_keyword(&name);
20042 self.write(", ");
20043 self.generate_expression(expr)?;
20044 self.write(")");
20045 Ok(())
20046 }
20047 TsqlDatePart::Epoch => {
20048 self.generate_tsql_unsupported_date_trunc("EPOCH".to_string(), expr)
20049 }
20050 TsqlDatePart::IsoDayOfWeek => {
20051 self.generate_tsql_unsupported_date_trunc("ISODOW".to_string(), expr)
20052 }
20053 TsqlDatePart::Unsupported(name) => {
20054 self.generate_tsql_unsupported_date_trunc(name, expr)
20055 }
20056 }
20057 }
20058
20059 fn generate_tsql_unsupported_date_trunc(
20060 &mut self,
20061 name: String,
20062 expr: &Expression,
20063 ) -> Result<()> {
20064 self.unsupported(format!("DATETRUNC {name} is not supported by T-SQL/Fabric"))?;
20065 self.write_keyword("DATETRUNC");
20066 self.write("(");
20067 self.write_keyword(&name);
20068 self.write(", ");
20069 self.generate_expression(expr)?;
20070 self.write(")");
20071 Ok(())
20072 }
20073
20074 fn normalize_date_part(&self, part: &str) -> String {
20077 let mut buf = [0u8; 64];
20078 let lower: &str = if part.len() <= 64 {
20079 for (i, b) in part.bytes().enumerate() {
20080 buf[i] = b.to_ascii_lowercase();
20081 }
20082 std::str::from_utf8(&buf[..part.len()]).unwrap_or(part)
20083 } else {
20084 return part.to_ascii_uppercase();
20085 };
20086 match lower {
20087 "day" | "days" | "d" => "DAY".to_string(),
20088 "month" | "months" | "mon" | "mons" | "mm" => "MONTH".to_string(),
20089 "year" | "years" | "y" | "yy" | "yyyy" => "YEAR".to_string(),
20090 "week" | "weeks" | "w" | "wk" => "WEEK".to_string(),
20091 "hour" | "hours" | "h" | "hh" => "HOUR".to_string(),
20092 "minute" | "minutes" | "m" | "mi" | "n" => "MINUTE".to_string(),
20093 "second" | "seconds" | "s" | "ss" => "SECOND".to_string(),
20094 "millisecond" | "milliseconds" | "ms" => "MILLISECOND".to_string(),
20095 "microsecond" | "microseconds" | "us" => "MICROSECOND".to_string(),
20096 "quarter" | "quarters" | "q" | "qq" => "QUARTER".to_string(),
20097 _ => part.to_ascii_uppercase(),
20098 }
20099 }
20100
20101 fn write_datetime_field(&mut self, field: &DateTimeField) {
20102 match field {
20103 DateTimeField::Year => self.write_keyword("YEAR"),
20104 DateTimeField::Month => self.write_keyword("MONTH"),
20105 DateTimeField::Day => self.write_keyword("DAY"),
20106 DateTimeField::Hour => self.write_keyword("HOUR"),
20107 DateTimeField::Minute => self.write_keyword("MINUTE"),
20108 DateTimeField::Second => self.write_keyword("SECOND"),
20109 DateTimeField::Millisecond => self.write_keyword("MILLISECOND"),
20110 DateTimeField::Microsecond => self.write_keyword("MICROSECOND"),
20111 DateTimeField::DayOfWeek => {
20112 let name = match self.config.dialect {
20113 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFWEEK",
20114 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "WEEKDAY",
20115 _ => "DOW",
20116 };
20117 self.write_keyword(name);
20118 }
20119 DateTimeField::DayOfYear => {
20120 let name = match self.config.dialect {
20121 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFYEAR",
20122 _ => "DOY",
20123 };
20124 self.write_keyword(name);
20125 }
20126 DateTimeField::Week => self.write_keyword("WEEK"),
20127 DateTimeField::WeekWithModifier(modifier) => {
20128 self.write_keyword("WEEK");
20129 self.write("(");
20130 self.write(modifier);
20131 self.write(")");
20132 }
20133 DateTimeField::Quarter => self.write_keyword("QUARTER"),
20134 DateTimeField::Epoch => self.write_keyword("EPOCH"),
20135 DateTimeField::Timezone => self.write_keyword("TIMEZONE"),
20136 DateTimeField::TimezoneHour => self.write_keyword("TIMEZONE_HOUR"),
20137 DateTimeField::TimezoneMinute => self.write_keyword("TIMEZONE_MINUTE"),
20138 DateTimeField::Date => self.write_keyword("DATE"),
20139 DateTimeField::Time => self.write_keyword("TIME"),
20140 DateTimeField::Custom(name) => self.write(name),
20141 }
20142 }
20143
20144 fn write_datetime_field_lower(&mut self, field: &DateTimeField) {
20146 match field {
20147 DateTimeField::Year => self.write("year"),
20148 DateTimeField::Month => self.write("month"),
20149 DateTimeField::Day => self.write("day"),
20150 DateTimeField::Hour => self.write("hour"),
20151 DateTimeField::Minute => self.write("minute"),
20152 DateTimeField::Second => self.write("second"),
20153 DateTimeField::Millisecond => self.write("millisecond"),
20154 DateTimeField::Microsecond => self.write("microsecond"),
20155 DateTimeField::DayOfWeek => self.write("dow"),
20156 DateTimeField::DayOfYear => self.write("doy"),
20157 DateTimeField::Week => self.write("week"),
20158 DateTimeField::WeekWithModifier(modifier) => {
20159 self.write("week(");
20160 self.write(modifier);
20161 self.write(")");
20162 }
20163 DateTimeField::Quarter => self.write("quarter"),
20164 DateTimeField::Epoch => self.write("epoch"),
20165 DateTimeField::Timezone => self.write("timezone"),
20166 DateTimeField::TimezoneHour => self.write("timezone_hour"),
20167 DateTimeField::TimezoneMinute => self.write("timezone_minute"),
20168 DateTimeField::Date => self.write("date"),
20169 DateTimeField::Time => self.write("time"),
20170 DateTimeField::Custom(name) => self.write(name),
20171 }
20172 }
20173
20174 fn generate_simple_func(&mut self, name: &str, arg: &Expression) -> Result<()> {
20177 self.write_keyword(name);
20178 self.write("(");
20179 self.generate_expression(arg)?;
20180 self.write(")");
20181 Ok(())
20182 }
20183
20184 fn generate_unary_func(
20186 &mut self,
20187 default_name: &str,
20188 f: &crate::expressions::UnaryFunc,
20189 ) -> Result<()> {
20190 let name = f.original_name.as_deref().unwrap_or(default_name);
20191 self.write_keyword(name);
20192 self.write("(");
20193 self.generate_expression(&f.this)?;
20194 self.write(")");
20195 Ok(())
20196 }
20197
20198 fn generate_sqrt_cbrt(
20200 &mut self,
20201 f: &crate::expressions::UnaryFunc,
20202 func_name: &str,
20203 _op: &str,
20204 ) -> Result<()> {
20205 self.write_keyword(func_name);
20208 self.write("(");
20209 self.generate_expression(&f.this)?;
20210 self.write(")");
20211 Ok(())
20212 }
20213
20214 fn generate_binary_func(
20215 &mut self,
20216 name: &str,
20217 arg1: &Expression,
20218 arg2: &Expression,
20219 ) -> Result<()> {
20220 self.write_keyword(name);
20221 self.write("(");
20222 self.generate_expression(arg1)?;
20223 self.write(", ");
20224 self.generate_expression(arg2)?;
20225 self.write(")");
20226 Ok(())
20227 }
20228
20229 fn generate_char_func(&mut self, f: &crate::expressions::CharFunc) -> Result<()> {
20233 let func_name = f.name.as_deref().unwrap_or("CHAR");
20235 self.write_keyword(func_name);
20236 self.write("(");
20237 for (i, arg) in f.args.iter().enumerate() {
20238 if i > 0 {
20239 self.write(", ");
20240 }
20241 self.generate_expression(arg)?;
20242 }
20243 if let Some(ref charset) = f.charset {
20244 self.write(" ");
20245 self.write_keyword("USING");
20246 self.write(" ");
20247 self.write(charset);
20248 }
20249 self.write(")");
20250 Ok(())
20251 }
20252
20253 fn generate_power(&mut self, f: &BinaryFunc) -> Result<()> {
20254 use crate::dialects::DialectType;
20255
20256 match self.config.dialect {
20257 Some(DialectType::Teradata) => {
20258 self.generate_expression(&f.this)?;
20260 self.write(" ** ");
20261 self.generate_expression(&f.expression)?;
20262 Ok(())
20263 }
20264 _ => {
20265 self.generate_binary_func("POWER", &f.this, &f.expression)
20267 }
20268 }
20269 }
20270
20271 fn generate_vararg_func(&mut self, name: &str, args: &[Expression]) -> Result<()> {
20272 self.write_func_name(name);
20273 self.write("(");
20274 for (i, arg) in args.iter().enumerate() {
20275 if i > 0 {
20276 self.write(", ");
20277 }
20278 self.generate_expression(arg)?;
20279 }
20280 self.write(")");
20281 Ok(())
20282 }
20283
20284 fn generate_concat_ws(&mut self, f: &ConcatWs) -> Result<()> {
20287 self.write_keyword("CONCAT_WS");
20288 self.write("(");
20289 self.generate_expression(&f.separator)?;
20290 for expr in &f.expressions {
20291 self.write(", ");
20292 self.generate_expression(expr)?;
20293 }
20294 self.write(")");
20295 Ok(())
20296 }
20297
20298 fn collect_concat_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
20299 if let Expression::Concat(op) = expr {
20300 Self::collect_concat_operands(&op.left, out);
20301 Self::collect_concat_operands(&op.right, out);
20302 } else {
20303 out.push(expr);
20304 }
20305 }
20306
20307 fn generate_mysql_concat_from_concat(&mut self, op: &BinaryOp) -> Result<()> {
20308 let mut operands = Vec::new();
20309 Self::collect_concat_operands(&op.left, &mut operands);
20310 Self::collect_concat_operands(&op.right, &mut operands);
20311
20312 self.write_keyword("CONCAT");
20313 self.write("(");
20314 for (i, operand) in operands.iter().enumerate() {
20315 if i > 0 {
20316 self.write(", ");
20317 }
20318 self.generate_expression(operand)?;
20319 }
20320 self.write(")");
20321 Ok(())
20322 }
20323
20324 fn collect_dpipe_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
20325 if let Expression::DPipe(dpipe) = expr {
20326 Self::collect_dpipe_operands(&dpipe.this, out);
20327 Self::collect_dpipe_operands(&dpipe.expression, out);
20328 } else {
20329 out.push(expr);
20330 }
20331 }
20332
20333 fn generate_mysql_concat_from_dpipe(&mut self, e: &DPipe) -> Result<()> {
20334 let mut operands = Vec::new();
20335 Self::collect_dpipe_operands(&e.this, &mut operands);
20336 Self::collect_dpipe_operands(&e.expression, &mut operands);
20337
20338 self.write_keyword("CONCAT");
20339 self.write("(");
20340 for (i, operand) in operands.iter().enumerate() {
20341 if i > 0 {
20342 self.write(", ");
20343 }
20344 self.generate_expression(operand)?;
20345 }
20346 self.write(")");
20347 Ok(())
20348 }
20349
20350 fn generate_substring(&mut self, f: &SubstringFunc) -> Result<()> {
20351 let use_substr = matches!(
20353 self.config.dialect,
20354 Some(
20355 DialectType::Oracle
20356 | DialectType::Presto
20357 | DialectType::Trino
20358 | DialectType::Athena
20359 )
20360 );
20361 if use_substr {
20362 self.write_keyword("SUBSTR");
20363 } else {
20364 self.write_keyword("SUBSTRING");
20365 }
20366 self.write("(");
20367 self.generate_expression(&f.this)?;
20368 let force_from_for = matches!(self.config.dialect, Some(DialectType::PostgreSQL));
20370 let use_comma_syntax = matches!(
20372 self.config.dialect,
20373 Some(DialectType::Spark)
20374 | Some(DialectType::Hive)
20375 | Some(DialectType::Databricks)
20376 | Some(DialectType::TSQL)
20377 | Some(DialectType::Fabric)
20378 );
20379 if (f.from_for_syntax || force_from_for) && !use_comma_syntax {
20380 self.write_space();
20382 self.write_keyword("FROM");
20383 self.write_space();
20384 self.generate_expression(&f.start)?;
20385 if let Some(length) = &f.length {
20386 self.write_space();
20387 self.write_keyword("FOR");
20388 self.write_space();
20389 self.generate_expression(length)?;
20390 }
20391 } else {
20392 self.write(", ");
20394 self.generate_expression(&f.start)?;
20395 if let Some(length) = &f.length {
20396 self.write(", ");
20397 self.generate_expression(length)?;
20398 }
20399 }
20400 self.write(")");
20401 Ok(())
20402 }
20403
20404 fn generate_overlay(&mut self, f: &OverlayFunc) -> Result<()> {
20405 self.write_keyword("OVERLAY");
20406 self.write("(");
20407 self.generate_expression(&f.this)?;
20408 self.write_space();
20409 self.write_keyword("PLACING");
20410 self.write_space();
20411 self.generate_expression(&f.replacement)?;
20412 self.write_space();
20413 self.write_keyword("FROM");
20414 self.write_space();
20415 self.generate_expression(&f.from)?;
20416 if let Some(length) = &f.length {
20417 self.write_space();
20418 self.write_keyword("FOR");
20419 self.write_space();
20420 self.generate_expression(length)?;
20421 }
20422 self.write(")");
20423 Ok(())
20424 }
20425
20426 fn generate_trim(&mut self, f: &TrimFunc) -> Result<()> {
20427 if f.position_explicit && f.characters.is_none() {
20430 match f.position {
20431 TrimPosition::Leading => {
20432 self.write_keyword("LTRIM");
20433 self.write("(");
20434 self.generate_expression(&f.this)?;
20435 self.write(")");
20436 return Ok(());
20437 }
20438 TrimPosition::Trailing => {
20439 self.write_keyword("RTRIM");
20440 self.write("(");
20441 self.generate_expression(&f.this)?;
20442 self.write(")");
20443 return Ok(());
20444 }
20445 TrimPosition::Both => {
20446 }
20449 }
20450 }
20451
20452 self.write_keyword("TRIM");
20453 self.write("(");
20454 let force_standard = f.characters.is_some()
20457 && !f.sql_standard_syntax
20458 && matches!(
20459 self.config.dialect,
20460 Some(DialectType::Hive)
20461 | Some(DialectType::Spark)
20462 | Some(DialectType::Databricks)
20463 | Some(DialectType::ClickHouse)
20464 );
20465 let use_standard = (f.sql_standard_syntax || force_standard)
20466 && !(f.position_explicit
20467 && f.characters.is_none()
20468 && matches!(f.position, TrimPosition::Both));
20469 if use_standard {
20470 if f.position_explicit {
20473 match f.position {
20474 TrimPosition::Both => self.write_keyword("BOTH"),
20475 TrimPosition::Leading => self.write_keyword("LEADING"),
20476 TrimPosition::Trailing => self.write_keyword("TRAILING"),
20477 }
20478 self.write_space();
20479 }
20480 if let Some(chars) = &f.characters {
20481 self.generate_expression(chars)?;
20482 self.write_space();
20483 }
20484 self.write_keyword("FROM");
20485 self.write_space();
20486 self.generate_expression(&f.this)?;
20487 } else {
20488 self.generate_expression(&f.this)?;
20490 if let Some(chars) = &f.characters {
20491 self.write(", ");
20492 self.generate_expression(chars)?;
20493 }
20494 }
20495 self.write(")");
20496 Ok(())
20497 }
20498
20499 fn generate_replace(&mut self, f: &ReplaceFunc) -> Result<()> {
20500 self.write_keyword("REPLACE");
20501 self.write("(");
20502 self.generate_expression(&f.this)?;
20503 self.write(", ");
20504 self.generate_expression(&f.old)?;
20505 self.write(", ");
20506 self.generate_expression(&f.new)?;
20507 self.write(")");
20508 Ok(())
20509 }
20510
20511 fn generate_left_right(&mut self, name: &str, f: &LeftRightFunc) -> Result<()> {
20512 self.write_keyword(name);
20513 self.write("(");
20514 self.generate_expression(&f.this)?;
20515 self.write(", ");
20516 self.generate_expression(&f.length)?;
20517 self.write(")");
20518 Ok(())
20519 }
20520
20521 fn generate_repeat(&mut self, f: &RepeatFunc) -> Result<()> {
20522 self.write_keyword("REPEAT");
20523 self.write("(");
20524 self.generate_expression(&f.this)?;
20525 self.write(", ");
20526 self.generate_expression(&f.times)?;
20527 self.write(")");
20528 Ok(())
20529 }
20530
20531 fn generate_pad(&mut self, name: &str, f: &PadFunc) -> Result<()> {
20532 self.write_keyword(name);
20533 self.write("(");
20534 self.generate_expression(&f.this)?;
20535 self.write(", ");
20536 self.generate_expression(&f.length)?;
20537 if let Some(fill) = &f.fill {
20538 self.write(", ");
20539 self.generate_expression(fill)?;
20540 }
20541 self.write(")");
20542 Ok(())
20543 }
20544
20545 fn generate_split(&mut self, f: &SplitFunc) -> Result<()> {
20546 self.write_keyword("SPLIT");
20547 self.write("(");
20548 self.generate_expression(&f.this)?;
20549 self.write(", ");
20550 self.generate_expression(&f.delimiter)?;
20551 self.write(")");
20552 Ok(())
20553 }
20554
20555 fn generate_regexp_like(&mut self, f: &RegexpFunc) -> Result<()> {
20556 use crate::dialects::DialectType;
20557 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) && f.flags.is_none() {
20559 self.generate_expression(&f.this)?;
20560 self.write(" ~ ");
20561 self.generate_expression(&f.pattern)?;
20562 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && f.flags.is_none()
20563 {
20564 self.write("match(");
20566 self.generate_expression(&f.this)?;
20567 self.write(", ");
20568 self.generate_expression(&f.pattern)?;
20569 self.write(")");
20570 } else if matches!(self.config.dialect, Some(DialectType::Exasol)) && f.flags.is_none() {
20571 self.generate_expression(&f.this)?;
20573 self.write_keyword(" REGEXP_LIKE ");
20574 self.generate_expression(&f.pattern)?;
20575 } else if matches!(
20576 self.config.dialect,
20577 Some(DialectType::SingleStore)
20578 | Some(DialectType::Spark)
20579 | Some(DialectType::Hive)
20580 | Some(DialectType::Databricks)
20581 ) && f.flags.is_none()
20582 {
20583 self.generate_expression(&f.this)?;
20585 self.write_keyword(" RLIKE ");
20586 self.generate_expression(&f.pattern)?;
20587 } else if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
20588 self.write_keyword("REGEXP");
20590 self.write("(");
20591 self.generate_expression(&f.this)?;
20592 self.write(", ");
20593 self.generate_expression(&f.pattern)?;
20594 if let Some(flags) = &f.flags {
20595 self.write(", ");
20596 self.generate_expression(flags)?;
20597 }
20598 self.write(")");
20599 } else {
20600 self.write_keyword("REGEXP_LIKE");
20601 self.write("(");
20602 self.generate_expression(&f.this)?;
20603 self.write(", ");
20604 self.generate_expression(&f.pattern)?;
20605 if let Some(flags) = &f.flags {
20606 self.write(", ");
20607 self.generate_expression(flags)?;
20608 }
20609 self.write(")");
20610 }
20611 Ok(())
20612 }
20613
20614 fn generate_regexp_replace(&mut self, f: &RegexpReplaceFunc) -> Result<()> {
20615 self.write_keyword("REGEXP_REPLACE");
20616 self.write("(");
20617 self.generate_expression(&f.this)?;
20618 self.write(", ");
20619 self.generate_expression(&f.pattern)?;
20620 self.write(", ");
20621 self.generate_expression(&f.replacement)?;
20622 if let Some(flags) = &f.flags {
20623 self.write(", ");
20624 self.generate_expression(flags)?;
20625 }
20626 self.write(")");
20627 Ok(())
20628 }
20629
20630 fn generate_regexp_extract(&mut self, f: &RegexpExtractFunc) -> Result<()> {
20631 self.write_keyword("REGEXP_EXTRACT");
20632 self.write("(");
20633 self.generate_expression(&f.this)?;
20634 self.write(", ");
20635 self.generate_expression(&f.pattern)?;
20636 if let Some(group) = &f.group {
20637 self.write(", ");
20638 self.generate_expression(group)?;
20639 }
20640 self.write(")");
20641 Ok(())
20642 }
20643
20644 fn generate_round(&mut self, f: &RoundFunc) -> Result<()> {
20647 self.write_keyword("ROUND");
20648 self.write("(");
20649 self.generate_expression(&f.this)?;
20650 if let Some(decimals) = &f.decimals {
20651 self.write(", ");
20652 self.generate_expression(decimals)?;
20653 }
20654 self.write(")");
20655 Ok(())
20656 }
20657
20658 fn generate_floor(&mut self, f: &FloorFunc) -> Result<()> {
20659 self.write_keyword("FLOOR");
20660 self.write("(");
20661 self.generate_expression(&f.this)?;
20662 if let Some(to) = &f.to {
20664 self.write(" ");
20665 self.write_keyword("TO");
20666 self.write(" ");
20667 self.generate_expression(to)?;
20668 } else if let Some(scale) = &f.scale {
20669 self.write(", ");
20670 self.generate_expression(scale)?;
20671 }
20672 self.write(")");
20673 Ok(())
20674 }
20675
20676 fn generate_ceil(&mut self, f: &CeilFunc) -> Result<()> {
20677 self.write_keyword("CEIL");
20678 self.write("(");
20679 self.generate_expression(&f.this)?;
20680 if let Some(to) = &f.to {
20682 self.write(" ");
20683 self.write_keyword("TO");
20684 self.write(" ");
20685 self.generate_expression(to)?;
20686 } else if let Some(decimals) = &f.decimals {
20687 self.write(", ");
20688 self.generate_expression(decimals)?;
20689 }
20690 self.write(")");
20691 Ok(())
20692 }
20693
20694 fn generate_log(&mut self, f: &LogFunc) -> Result<()> {
20695 use crate::expressions::Literal;
20696
20697 if let Some(base) = &f.base {
20698 if self.is_log_base_none() {
20701 if matches!(base, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(s) if s == "2"))
20702 {
20703 self.write_func_name("LOG2");
20704 self.write("(");
20705 self.generate_expression(&f.this)?;
20706 self.write(")");
20707 return Ok(());
20708 } else if matches!(base, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(s) if s == "10"))
20709 {
20710 self.write_func_name("LOG10");
20711 self.write("(");
20712 self.generate_expression(&f.this)?;
20713 self.write(")");
20714 return Ok(());
20715 }
20716 }
20718
20719 self.write_func_name("LOG");
20720 self.write("(");
20721 if self.is_log_value_first() {
20722 self.generate_expression(&f.this)?;
20724 self.write(", ");
20725 self.generate_expression(base)?;
20726 } else {
20727 self.generate_expression(base)?;
20729 self.write(", ");
20730 self.generate_expression(&f.this)?;
20731 }
20732 self.write(")");
20733 } else {
20734 self.write_func_name("LOG");
20736 self.write("(");
20737 self.generate_expression(&f.this)?;
20738 self.write(")");
20739 }
20740 Ok(())
20741 }
20742
20743 fn is_log_value_first(&self) -> bool {
20746 use crate::dialects::DialectType;
20747 matches!(
20748 self.config.dialect,
20749 Some(DialectType::BigQuery)
20750 | Some(DialectType::TSQL)
20751 | Some(DialectType::Tableau)
20752 | Some(DialectType::Fabric)
20753 )
20754 }
20755
20756 fn is_log_base_none(&self) -> bool {
20759 use crate::dialects::DialectType;
20760 matches!(
20761 self.config.dialect,
20762 Some(DialectType::Presto)
20763 | Some(DialectType::Trino)
20764 | Some(DialectType::ClickHouse)
20765 | Some(DialectType::Athena)
20766 )
20767 }
20768
20769 fn generate_current_time(&mut self, f: &CurrentTime) -> Result<()> {
20772 self.write_keyword("CURRENT_TIME");
20773 if let Some(precision) = f.precision {
20774 self.write(&format!("({})", precision));
20775 } else if matches!(
20776 self.config.dialect,
20777 Some(crate::dialects::DialectType::MySQL)
20778 | Some(crate::dialects::DialectType::SingleStore)
20779 | Some(crate::dialects::DialectType::TiDB)
20780 ) {
20781 self.write("()");
20782 }
20783 Ok(())
20784 }
20785
20786 fn generate_current_timestamp(&mut self, f: &CurrentTimestamp) -> Result<()> {
20787 use crate::dialects::DialectType;
20788
20789 if f.sysdate {
20791 match self.config.dialect {
20792 Some(DialectType::Oracle) | Some(DialectType::Redshift) => {
20793 self.write_keyword("SYSDATE");
20794 return Ok(());
20795 }
20796 Some(DialectType::Snowflake) => {
20797 self.write_keyword("SYSDATE");
20799 self.write("()");
20800 return Ok(());
20801 }
20802 _ => {
20803 }
20805 }
20806 }
20807
20808 self.write_keyword("CURRENT_TIMESTAMP");
20809 if let Some(precision) = f.precision {
20811 self.write(&format!("({})", precision));
20812 } else if matches!(
20813 self.config.dialect,
20814 Some(crate::dialects::DialectType::MySQL)
20815 | Some(crate::dialects::DialectType::SingleStore)
20816 | Some(crate::dialects::DialectType::TiDB)
20817 | Some(crate::dialects::DialectType::Spark)
20818 | Some(crate::dialects::DialectType::Hive)
20819 | Some(crate::dialects::DialectType::Databricks)
20820 | Some(crate::dialects::DialectType::ClickHouse)
20821 | Some(crate::dialects::DialectType::BigQuery)
20822 | Some(crate::dialects::DialectType::Snowflake)
20823 | Some(crate::dialects::DialectType::Exasol)
20824 ) {
20825 self.write("()");
20826 }
20827 Ok(())
20828 }
20829
20830 fn generate_at_time_zone(&mut self, f: &AtTimeZone) -> Result<()> {
20831 if self.config.dialect == Some(DialectType::Exasol) {
20833 self.write_keyword("CONVERT_TZ");
20834 self.write("(");
20835 self.generate_expression(&f.this)?;
20836 self.write(", 'UTC', ");
20837 self.generate_expression(&f.zone)?;
20838 self.write(")");
20839 return Ok(());
20840 }
20841
20842 self.generate_expression(&f.this)?;
20843 self.write_space();
20844 self.write_keyword("AT TIME ZONE");
20845 self.write_space();
20846 self.generate_expression(&f.zone)?;
20847 Ok(())
20848 }
20849
20850 fn generate_date_add(&mut self, f: &DateAddFunc, name: &str) -> Result<()> {
20851 use crate::dialects::DialectType;
20852
20853 let is_presto_like = matches!(
20856 self.config.dialect,
20857 Some(DialectType::Presto) | Some(DialectType::Trino)
20858 );
20859
20860 if is_presto_like {
20861 self.write_keyword(name);
20862 self.write("(");
20863 self.write("'");
20865 self.write_simple_interval_unit(&f.unit, false);
20866 self.write("'");
20867 self.write(", ");
20868 let needs_cast = !self.returns_integer_type(&f.interval);
20870 if needs_cast {
20871 self.write_keyword("CAST");
20872 self.write("(");
20873 }
20874 self.generate_expression(&f.interval)?;
20875 if needs_cast {
20876 self.write_space();
20877 self.write_keyword("AS");
20878 self.write_space();
20879 self.write_keyword("BIGINT");
20880 self.write(")");
20881 }
20882 self.write(", ");
20883 self.generate_expression(&f.this)?;
20884 self.write(")");
20885 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
20886 self.generate_expression(&f.this)?;
20887 self.write_space();
20888 if name.eq_ignore_ascii_case("DATE_SUB") {
20889 self.write("-");
20890 } else {
20891 self.write("+");
20892 }
20893 self.write_space();
20894 self.write_keyword("INTERVAL");
20895 self.write_space();
20896 self.write("'");
20897 let mut interval_gen = Generator::with_arc_config(self.config.clone());
20898 let interval_sql = interval_gen.generate(&f.interval)?;
20899 self.write(&interval_sql);
20900 self.write(" ");
20901 self.write_simple_interval_unit(&f.unit, false);
20902 self.write("'");
20903 } else {
20904 self.write_keyword(name);
20905 self.write("(");
20906 self.generate_expression(&f.this)?;
20907 self.write(", ");
20908 self.write_keyword("INTERVAL");
20909 self.write_space();
20910 self.generate_expression(&f.interval)?;
20911 self.write_space();
20912 self.write_simple_interval_unit(&f.unit, false); self.write(")");
20914 }
20915 Ok(())
20916 }
20917
20918 fn returns_integer_type(&self, expr: &Expression) -> bool {
20921 use crate::expressions::{DataType, Literal};
20922 match expr {
20923 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
20925 let Literal::Number(n) = lit.as_ref() else {
20926 unreachable!()
20927 };
20928 !n.contains('.')
20929 }
20930
20931 Expression::Floor(f) => self.returns_integer_type(&f.this),
20933
20934 Expression::Round(f) => {
20936 f.decimals.is_none() && self.returns_integer_type(&f.this)
20938 }
20939
20940 Expression::Sign(f) => self.returns_integer_type(&f.this),
20942
20943 Expression::Abs(f) => self.returns_integer_type(&f.this),
20945
20946 Expression::Mul(op) => {
20948 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
20949 }
20950 Expression::Add(op) => {
20951 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
20952 }
20953 Expression::Sub(op) => {
20954 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
20955 }
20956 Expression::Mod(op) => self.returns_integer_type(&op.left),
20957
20958 Expression::Cast(c) => matches!(
20960 &c.to,
20961 DataType::BigInt { .. }
20962 | DataType::Int { .. }
20963 | DataType::SmallInt { .. }
20964 | DataType::TinyInt { .. }
20965 ),
20966
20967 Expression::Neg(op) => self.returns_integer_type(&op.this),
20969
20970 Expression::Paren(p) => self.returns_integer_type(&p.this),
20972
20973 _ => false,
20976 }
20977 }
20978
20979 fn generate_datediff(&mut self, f: &DateDiffFunc) -> Result<()> {
20980 self.write_keyword("DATEDIFF");
20981 self.write("(");
20982 if let Some(unit) = &f.unit {
20983 self.write_simple_interval_unit(unit, false); self.write(", ");
20985 }
20986 if self.config.dialect == Some(DialectType::Snowflake) {
20987 self.generate_expression(&f.expression)?;
20988 self.write(", ");
20989 self.generate_expression(&f.this)?;
20990 } else {
20991 self.generate_expression(&f.this)?;
20992 self.write(", ");
20993 self.generate_expression(&f.expression)?;
20994 }
20995 self.write(")");
20996 Ok(())
20997 }
20998
20999 fn generate_date_trunc(&mut self, f: &DateTruncFunc) -> Result<()> {
21000 if matches!(
21001 self.config.dialect,
21002 Some(DialectType::TSQL) | Some(DialectType::Fabric)
21003 ) {
21004 let date_part = self.classify_tsql_date_trunc_field(&f.unit);
21005 self.generate_tsql_date_trunc(date_part, &f.this)?;
21006 return Ok(());
21007 }
21008 if self.config.dialect == Some(DialectType::ClickHouse) {
21009 self.write("dateTrunc");
21010 } else {
21011 self.write_keyword("DATE_TRUNC");
21012 }
21013 self.write("('");
21014 self.write_datetime_field(&f.unit);
21015 self.write("', ");
21016 self.generate_expression(&f.this)?;
21017 self.write(")");
21018 Ok(())
21019 }
21020
21021 fn generate_last_day(&mut self, f: &LastDayFunc) -> Result<()> {
21022 use crate::dialects::DialectType;
21023 use crate::expressions::DateTimeField;
21024
21025 self.write_keyword("LAST_DAY");
21026 self.write("(");
21027 self.generate_expression(&f.this)?;
21028 if let Some(unit) = &f.unit {
21029 self.write(", ");
21030 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
21033 if let DateTimeField::WeekWithModifier(_) = unit {
21034 self.write_keyword("WEEK");
21035 } else {
21036 self.write_datetime_field(unit);
21037 }
21038 } else {
21039 self.write_datetime_field(unit);
21040 }
21041 }
21042 self.write(")");
21043 Ok(())
21044 }
21045
21046 fn generate_extract(&mut self, f: &ExtractFunc) -> Result<()> {
21047 if matches!(
21049 self.config.dialect,
21050 Some(DialectType::TSQL) | Some(DialectType::Fabric)
21051 ) {
21052 let date_part = self.classify_tsql_datetime_field(&f.field);
21053 self.generate_tsql_date_part(date_part, &f.this)?;
21054 return Ok(());
21055 }
21056 self.write_keyword("EXTRACT");
21057 self.write("(");
21058 if matches!(
21060 self.config.dialect,
21061 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
21062 ) {
21063 self.write_datetime_field_lower(&f.field);
21064 } else {
21065 self.write_datetime_field(&f.field);
21066 }
21067 self.write_space();
21068 self.write_keyword("FROM");
21069 self.write_space();
21070 self.generate_expression(&f.this)?;
21071 self.write(")");
21072 Ok(())
21073 }
21074
21075 fn generate_to_date(&mut self, f: &ToDateFunc) -> Result<()> {
21076 self.write_keyword("TO_DATE");
21077 self.write("(");
21078 self.generate_expression(&f.this)?;
21079 if let Some(format) = &f.format {
21080 self.write(", ");
21081 self.generate_expression(format)?;
21082 }
21083 self.write(")");
21084 Ok(())
21085 }
21086
21087 fn generate_to_timestamp(&mut self, f: &ToTimestampFunc) -> Result<()> {
21088 self.write_keyword("TO_TIMESTAMP");
21089 self.write("(");
21090 self.generate_expression(&f.this)?;
21091 if let Some(format) = &f.format {
21092 self.write(", ");
21093 self.generate_expression(format)?;
21094 }
21095 self.write(")");
21096 Ok(())
21097 }
21098
21099 fn generate_if_func(&mut self, f: &IfFunc) -> Result<()> {
21102 use crate::dialects::DialectType;
21103
21104 if self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic) {
21106 self.write_keyword("CASE WHEN");
21107 self.write_space();
21108 self.generate_expression(&f.condition)?;
21109 self.write_space();
21110 self.write_keyword("THEN");
21111 self.write_space();
21112 self.generate_expression(&f.true_value)?;
21113 if let Some(false_val) = &f.false_value {
21114 self.write_space();
21115 self.write_keyword("ELSE");
21116 self.write_space();
21117 self.generate_expression(false_val)?;
21118 }
21119 self.write_space();
21120 self.write_keyword("END");
21121 return Ok(());
21122 }
21123
21124 if self.config.dialect == Some(DialectType::Exasol) {
21126 self.write_keyword("IF");
21127 self.write_space();
21128 self.generate_expression(&f.condition)?;
21129 self.write_space();
21130 self.write_keyword("THEN");
21131 self.write_space();
21132 self.generate_expression(&f.true_value)?;
21133 if let Some(false_val) = &f.false_value {
21134 self.write_space();
21135 self.write_keyword("ELSE");
21136 self.write_space();
21137 self.generate_expression(false_val)?;
21138 }
21139 self.write_space();
21140 self.write_keyword("ENDIF");
21141 return Ok(());
21142 }
21143
21144 let func_name = match self.config.dialect {
21146 Some(DialectType::ClickHouse) => f.original_name.as_deref().unwrap_or("IF"),
21147 Some(DialectType::Snowflake) => "IFF",
21148 Some(DialectType::SQLite) | Some(DialectType::TSQL) => "IIF",
21149 Some(DialectType::Drill) => "`IF`",
21150 _ => "IF",
21151 };
21152 self.write(func_name);
21153 self.write("(");
21154 self.generate_expression(&f.condition)?;
21155 self.write(", ");
21156 self.generate_expression(&f.true_value)?;
21157 if let Some(false_val) = &f.false_value {
21158 self.write(", ");
21159 self.generate_expression(false_val)?;
21160 }
21161 self.write(")");
21162 Ok(())
21163 }
21164
21165 fn generate_nvl2(&mut self, f: &Nvl2Func) -> Result<()> {
21166 self.write_keyword("NVL2");
21167 self.write("(");
21168 self.generate_expression(&f.this)?;
21169 self.write(", ");
21170 self.generate_expression(&f.true_value)?;
21171 self.write(", ");
21172 self.generate_expression(&f.false_value)?;
21173 self.write(")");
21174 Ok(())
21175 }
21176
21177 fn generate_count(&mut self, f: &CountFunc) -> Result<()> {
21180 let count_name = match self.config.normalize_functions {
21182 NormalizeFunctions::Upper => "COUNT".to_string(),
21183 NormalizeFunctions::Lower => "count".to_string(),
21184 NormalizeFunctions::None => f
21185 .original_name
21186 .clone()
21187 .unwrap_or_else(|| "COUNT".to_string()),
21188 };
21189 self.write(&count_name);
21190 self.write("(");
21191 if f.distinct {
21192 self.write_keyword("DISTINCT");
21193 self.write_space();
21194 }
21195 if f.star {
21196 self.write("*");
21197 } else if let Some(ref expr) = f.this {
21198 if let Expression::Tuple(tuple) = expr {
21200 let needs_transform =
21204 f.distinct && tuple.expressions.len() > 1 && !self.config.multi_arg_distinct;
21205
21206 if needs_transform {
21207 self.write_keyword("CASE");
21209 for e in &tuple.expressions {
21210 self.write_space();
21211 self.write_keyword("WHEN");
21212 self.write_space();
21213 self.generate_expression(e)?;
21214 self.write_space();
21215 self.write_keyword("IS NULL THEN NULL");
21216 }
21217 self.write_space();
21218 self.write_keyword("ELSE");
21219 self.write(" (");
21220 for (i, e) in tuple.expressions.iter().enumerate() {
21221 if i > 0 {
21222 self.write(", ");
21223 }
21224 self.generate_expression(e)?;
21225 }
21226 self.write(")");
21227 self.write_space();
21228 self.write_keyword("END");
21229 } else {
21230 for (i, e) in tuple.expressions.iter().enumerate() {
21231 if i > 0 {
21232 self.write(", ");
21233 }
21234 self.generate_expression(e)?;
21235 }
21236 }
21237 } else {
21238 self.generate_expression(expr)?;
21239 }
21240 }
21241 let clickhouse_ignore_nulls_outside =
21242 matches!(self.config.dialect, Some(DialectType::ClickHouse));
21243 if let Some(ignore) = f.ignore_nulls.filter(|_| !clickhouse_ignore_nulls_outside) {
21244 self.write_space();
21245 if ignore {
21246 self.write_keyword("IGNORE NULLS");
21247 } else {
21248 self.write_keyword("RESPECT NULLS");
21249 }
21250 }
21251 self.write(")");
21252 if let Some(ignore) = f.ignore_nulls.filter(|_| clickhouse_ignore_nulls_outside) {
21253 self.write_space();
21254 if ignore {
21255 self.write_keyword("IGNORE NULLS");
21256 } else {
21257 self.write_keyword("RESPECT NULLS");
21258 }
21259 }
21260 if let Some(ref filter) = f.filter {
21261 self.write_space();
21262 self.write_keyword("FILTER");
21263 self.write("(");
21264 self.write_keyword("WHERE");
21265 self.write_space();
21266 self.generate_expression(filter)?;
21267 self.write(")");
21268 }
21269 Ok(())
21270 }
21271
21272 fn generate_agg_func(&mut self, name: &str, f: &AggFunc) -> Result<()> {
21273 let func_name: Cow<'_, str> = match self.config.normalize_functions {
21275 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
21276 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
21277 NormalizeFunctions::None => {
21278 if let Some(ref original) = f.name {
21281 Cow::Owned(original.clone())
21282 } else {
21283 Cow::Owned(name.to_ascii_lowercase())
21284 }
21285 }
21286 };
21287 self.write(func_name.as_ref());
21288 self.write("(");
21289 if f.distinct {
21290 self.write_keyword("DISTINCT");
21291 self.write_space();
21292 }
21293 let is_zero_arg_mode =
21296 name.eq_ignore_ascii_case("MODE") && matches!(f.this, Expression::Null(_));
21297 if !is_zero_arg_mode {
21298 self.generate_expression(&f.this)?;
21299 }
21300 if self.config.ignore_nulls_in_func
21303 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
21304 {
21305 match f.ignore_nulls {
21306 Some(true) => {
21307 self.write_space();
21308 self.write_keyword("IGNORE NULLS");
21309 }
21310 Some(false) => {
21311 self.write_space();
21312 self.write_keyword("RESPECT NULLS");
21313 }
21314 None => {}
21315 }
21316 }
21317 if let Some((ref expr, is_max)) = f.having_max {
21320 self.write_space();
21321 self.write_keyword("HAVING");
21322 self.write_space();
21323 if is_max {
21324 self.write_keyword("MAX");
21325 } else {
21326 self.write_keyword("MIN");
21327 }
21328 self.write_space();
21329 self.generate_expression(expr)?;
21330 }
21331 if !f.order_by.is_empty() {
21333 self.write_space();
21334 self.write_keyword("ORDER BY");
21335 self.write_space();
21336 for (i, ord) in f.order_by.iter().enumerate() {
21337 if i > 0 {
21338 self.write(", ");
21339 }
21340 self.generate_ordered(ord)?;
21341 }
21342 }
21343 if let Some(ref limit) = f.limit {
21345 self.write_space();
21346 self.write_keyword("LIMIT");
21347 self.write_space();
21348 if let Expression::Tuple(t) = limit.as_ref() {
21350 if t.expressions.len() == 2 {
21351 self.generate_expression(&t.expressions[0])?;
21352 self.write(", ");
21353 self.generate_expression(&t.expressions[1])?;
21354 } else {
21355 self.generate_expression(limit)?;
21356 }
21357 } else {
21358 self.generate_expression(limit)?;
21359 }
21360 }
21361 self.write(")");
21362 if !self.config.ignore_nulls_in_func
21365 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
21366 {
21367 match f.ignore_nulls {
21368 Some(true) => {
21369 self.write_space();
21370 self.write_keyword("IGNORE NULLS");
21371 }
21372 Some(false) => {
21373 self.write_space();
21374 self.write_keyword("RESPECT NULLS");
21375 }
21376 None => {}
21377 }
21378 }
21379 if let Some(ref filter) = f.filter {
21380 self.write_space();
21381 self.write_keyword("FILTER");
21382 self.write("(");
21383 self.write_keyword("WHERE");
21384 self.write_space();
21385 self.generate_expression(filter)?;
21386 self.write(")");
21387 }
21388 Ok(())
21389 }
21390
21391 fn generate_agg_func_with_ignore_nulls_bool(&mut self, name: &str, f: &AggFunc) -> Result<()> {
21394 if matches!(self.config.dialect, Some(DialectType::Hive)) && f.ignore_nulls == Some(true) {
21396 let func_name: Cow<'_, str> = match self.config.normalize_functions {
21398 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
21399 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
21400 NormalizeFunctions::None => {
21401 if let Some(ref original) = f.name {
21402 Cow::Owned(original.clone())
21403 } else {
21404 Cow::Owned(name.to_ascii_lowercase())
21405 }
21406 }
21407 };
21408 self.write(func_name.as_ref());
21409 self.write("(");
21410 if f.distinct {
21411 self.write_keyword("DISTINCT");
21412 self.write_space();
21413 }
21414 if !matches!(f.this, Expression::Null(_)) {
21415 self.generate_expression(&f.this)?;
21416 }
21417 self.write(", ");
21418 self.write_keyword("TRUE");
21419 self.write(")");
21420 return Ok(());
21421 }
21422 self.generate_agg_func(name, f)
21423 }
21424
21425 fn generate_group_concat(&mut self, f: &GroupConcatFunc) -> Result<()> {
21426 self.write_keyword("GROUP_CONCAT");
21427 self.write("(");
21428 if f.distinct {
21429 self.write_keyword("DISTINCT");
21430 self.write_space();
21431 }
21432 self.generate_expression(&f.this)?;
21433 if let Some(ref order_by) = f.order_by {
21434 self.write_space();
21435 self.write_keyword("ORDER BY");
21436 self.write_space();
21437 for (i, ord) in order_by.iter().enumerate() {
21438 if i > 0 {
21439 self.write(", ");
21440 }
21441 self.generate_ordered(ord)?;
21442 }
21443 }
21444 if let Some(ref sep) = f.separator {
21445 if matches!(
21448 self.config.dialect,
21449 Some(crate::dialects::DialectType::SQLite)
21450 ) {
21451 self.write(", ");
21452 self.generate_expression(sep)?;
21453 } else {
21454 self.write_space();
21455 self.write_keyword("SEPARATOR");
21456 self.write_space();
21457 self.generate_expression(sep)?;
21458 }
21459 }
21460 if let Some(ref limit) = f.limit {
21461 self.write_space();
21462 self.write_keyword("LIMIT");
21463 self.write_space();
21464 self.generate_expression(limit)?;
21465 }
21466 self.write(")");
21467 if let Some(ref filter) = f.filter {
21468 self.write_space();
21469 self.write_keyword("FILTER");
21470 self.write("(");
21471 self.write_keyword("WHERE");
21472 self.write_space();
21473 self.generate_expression(filter)?;
21474 self.write(")");
21475 }
21476 Ok(())
21477 }
21478
21479 fn generate_string_agg(&mut self, f: &StringAggFunc) -> Result<()> {
21480 let uses_within_group_order = matches!(
21481 self.config.dialect,
21482 Some(crate::dialects::DialectType::TSQL | crate::dialects::DialectType::Fabric)
21483 );
21484 self.write_keyword("STRING_AGG");
21485 self.write("(");
21486 if f.distinct {
21487 self.write_keyword("DISTINCT");
21488 self.write_space();
21489 }
21490 self.generate_expression(&f.this)?;
21491 if let Some(ref separator) = f.separator {
21492 self.write(", ");
21493 self.generate_string_agg_separator(separator)?;
21494 }
21495 if !uses_within_group_order {
21497 if let Some(ref order_by) = f.order_by {
21498 self.write_space();
21499 self.write_keyword("ORDER BY");
21500 self.write_space();
21501 for (i, ord) in order_by.iter().enumerate() {
21502 if i > 0 {
21503 self.write(", ");
21504 }
21505 self.generate_ordered(ord)?;
21506 }
21507 }
21508 }
21509 if let Some(ref limit) = f.limit {
21510 self.write_space();
21511 self.write_keyword("LIMIT");
21512 self.write_space();
21513 self.generate_expression(limit)?;
21514 }
21515 self.write(")");
21516 if uses_within_group_order {
21517 if let Some(ref order_by) = f.order_by {
21518 self.write_space();
21519 self.write_keyword("WITHIN GROUP");
21520 self.write(" (");
21521 self.write_keyword("ORDER BY");
21522 self.write_space();
21523 for (i, ord) in order_by.iter().enumerate() {
21524 if i > 0 {
21525 self.write(", ");
21526 }
21527 self.generate_ordered(ord)?;
21528 }
21529 self.write(")");
21530 }
21531 }
21532 if let Some(ref filter) = f.filter {
21533 self.write_space();
21534 self.write_keyword("FILTER");
21535 self.write("(");
21536 self.write_keyword("WHERE");
21537 self.write_space();
21538 self.generate_expression(filter)?;
21539 self.write(")");
21540 }
21541 Ok(())
21542 }
21543
21544 fn generate_string_agg_separator(&mut self, separator: &Expression) -> Result<()> {
21545 if matches!(
21546 self.config.dialect,
21547 Some(crate::dialects::DialectType::TSQL | crate::dialects::DialectType::Fabric)
21548 ) {
21549 if let Some(inner) = Self::tsql_string_agg_literal_separator_cast_inner(separator) {
21550 return self.generate_expression(inner);
21551 }
21552 }
21553
21554 self.generate_expression(separator)
21555 }
21556
21557 fn tsql_string_agg_literal_separator_cast_inner(separator: &Expression) -> Option<&Expression> {
21558 let Expression::Cast(cast) = separator else {
21559 return None;
21560 };
21561
21562 if cast.format.is_some() || cast.default.is_some() {
21563 return None;
21564 }
21565
21566 if !Self::is_string_data_type(&cast.to) {
21567 return None;
21568 }
21569
21570 match &cast.this {
21571 Expression::Literal(literal) if literal.is_string() => Some(&cast.this),
21572 _ => None,
21573 }
21574 }
21575
21576 fn is_string_data_type(data_type: &DataType) -> bool {
21577 matches!(
21578 data_type,
21579 DataType::Char { .. }
21580 | DataType::VarChar { .. }
21581 | DataType::String { .. }
21582 | DataType::Text
21583 | DataType::TextWithLength { .. }
21584 ) || matches!(
21585 data_type,
21586 DataType::Custom { name, .. }
21587 if name.eq_ignore_ascii_case("VARCHAR")
21588 || name.eq_ignore_ascii_case("NVARCHAR")
21589 || name.eq_ignore_ascii_case("VARCHAR(MAX)")
21590 || name.eq_ignore_ascii_case("NVARCHAR(MAX)")
21591 )
21592 }
21593
21594 fn generate_listagg(&mut self, f: &ListAggFunc) -> Result<()> {
21595 use crate::dialects::DialectType;
21596 let order_inside_args = matches!(self.config.dialect, Some(DialectType::DuckDB));
21597 self.write_keyword("LISTAGG");
21598 self.write("(");
21599 if f.distinct {
21600 self.write_keyword("DISTINCT");
21601 self.write_space();
21602 }
21603 self.generate_expression(&f.this)?;
21604 if let Some(ref sep) = f.separator {
21605 self.write(", ");
21606 self.generate_expression(sep)?;
21607 } else if matches!(
21608 self.config.dialect,
21609 Some(DialectType::Trino) | Some(DialectType::Presto)
21610 ) {
21611 self.write(", ','");
21613 }
21614 if let Some(ref overflow) = f.on_overflow {
21615 self.write_space();
21616 self.write_keyword("ON OVERFLOW");
21617 self.write_space();
21618 match overflow {
21619 ListAggOverflow::Error => self.write_keyword("ERROR"),
21620 ListAggOverflow::Truncate { filler, with_count } => {
21621 self.write_keyword("TRUNCATE");
21622 if let Some(ref fill) = filler {
21623 self.write_space();
21624 self.generate_expression(fill)?;
21625 }
21626 if *with_count {
21627 self.write_space();
21628 self.write_keyword("WITH COUNT");
21629 } else {
21630 self.write_space();
21631 self.write_keyword("WITHOUT COUNT");
21632 }
21633 }
21634 }
21635 }
21636 if order_inside_args {
21637 if let Some(ref order_by) = f.order_by {
21638 self.write_space();
21639 self.write_keyword("ORDER BY");
21640 self.write_space();
21641 for (i, ord) in order_by.iter().enumerate() {
21642 if i > 0 {
21643 self.write(", ");
21644 }
21645 self.generate_ordered(ord)?;
21646 }
21647 }
21648 }
21649 self.write(")");
21650 if !order_inside_args {
21651 if let Some(ref order_by) = f.order_by {
21652 self.write_space();
21653 self.write_keyword("WITHIN GROUP");
21654 self.write(" (");
21655 self.write_keyword("ORDER BY");
21656 self.write_space();
21657 for (i, ord) in order_by.iter().enumerate() {
21658 if i > 0 {
21659 self.write(", ");
21660 }
21661 self.generate_ordered(ord)?;
21662 }
21663 self.write(")");
21664 }
21665 }
21666 if let Some(ref filter) = f.filter {
21667 self.write_space();
21668 self.write_keyword("FILTER");
21669 self.write("(");
21670 self.write_keyword("WHERE");
21671 self.write_space();
21672 self.generate_expression(filter)?;
21673 self.write(")");
21674 }
21675 Ok(())
21676 }
21677
21678 fn generate_sum_if(&mut self, f: &SumIfFunc) -> Result<()> {
21679 self.write_keyword("SUM_IF");
21680 self.write("(");
21681 self.generate_expression(&f.this)?;
21682 self.write(", ");
21683 self.generate_expression(&f.condition)?;
21684 self.write(")");
21685 if let Some(ref filter) = f.filter {
21686 self.write_space();
21687 self.write_keyword("FILTER");
21688 self.write("(");
21689 self.write_keyword("WHERE");
21690 self.write_space();
21691 self.generate_expression(filter)?;
21692 self.write(")");
21693 }
21694 Ok(())
21695 }
21696
21697 fn generate_approx_percentile(&mut self, f: &ApproxPercentileFunc) -> Result<()> {
21698 self.write_keyword("APPROX_PERCENTILE");
21699 self.write("(");
21700 self.generate_expression(&f.this)?;
21701 self.write(", ");
21702 self.generate_expression(&f.percentile)?;
21703 if let Some(ref acc) = f.accuracy {
21704 self.write(", ");
21705 self.generate_expression(acc)?;
21706 }
21707 self.write(")");
21708 if let Some(ref filter) = f.filter {
21709 self.write_space();
21710 self.write_keyword("FILTER");
21711 self.write("(");
21712 self.write_keyword("WHERE");
21713 self.write_space();
21714 self.generate_expression(filter)?;
21715 self.write(")");
21716 }
21717 Ok(())
21718 }
21719
21720 fn generate_percentile(&mut self, name: &str, f: &PercentileFunc) -> Result<()> {
21721 self.write_keyword(name);
21722 self.write("(");
21723 self.generate_expression(&f.percentile)?;
21724 self.write(")");
21725 if let Some(ref order_by) = f.order_by {
21726 self.write_space();
21727 self.write_keyword("WITHIN GROUP");
21728 self.write(" (");
21729 self.write_keyword("ORDER BY");
21730 self.write_space();
21731 self.generate_expression(&f.this)?;
21732 for ord in order_by.iter() {
21733 if ord.desc {
21734 self.write_space();
21735 self.write_keyword("DESC");
21736 }
21737 }
21738 self.write(")");
21739 }
21740 if let Some(ref filter) = f.filter {
21741 self.write_space();
21742 self.write_keyword("FILTER");
21743 self.write("(");
21744 self.write_keyword("WHERE");
21745 self.write_space();
21746 self.generate_expression(filter)?;
21747 self.write(")");
21748 }
21749 Ok(())
21750 }
21751
21752 fn generate_ntile(&mut self, f: &NTileFunc) -> Result<()> {
21755 self.write_keyword("NTILE");
21756 self.write("(");
21757 if let Some(num_buckets) = &f.num_buckets {
21758 self.generate_expression(num_buckets)?;
21759 }
21760 if let Some(order_by) = &f.order_by {
21761 self.write_keyword(" ORDER BY ");
21762 for (i, ob) in order_by.iter().enumerate() {
21763 if i > 0 {
21764 self.write(", ");
21765 }
21766 self.generate_ordered(ob)?;
21767 }
21768 }
21769 self.write(")");
21770 Ok(())
21771 }
21772
21773 fn generate_lead_lag(&mut self, name: &str, f: &LeadLagFunc) -> Result<()> {
21774 self.write_keyword(name);
21775 self.write("(");
21776 self.generate_expression(&f.this)?;
21777 if let Some(ref offset) = f.offset {
21778 self.write(", ");
21779 self.generate_expression(offset)?;
21780 if let Some(ref default) = f.default {
21781 self.write(", ");
21782 self.generate_expression(default)?;
21783 }
21784 }
21785 if self.config.ignore_nulls_in_func {
21787 match f.ignore_nulls {
21788 Some(true) => {
21789 self.write_space();
21790 self.write_keyword("IGNORE NULLS");
21791 }
21792 Some(false) => {
21793 self.write_space();
21794 self.write_keyword("RESPECT NULLS");
21795 }
21796 None => {}
21797 }
21798 }
21799 self.write(")");
21800 if !self.config.ignore_nulls_in_func {
21802 match f.ignore_nulls {
21803 Some(true) => {
21804 self.write_space();
21805 self.write_keyword("IGNORE NULLS");
21806 }
21807 Some(false) => {
21808 self.write_space();
21809 self.write_keyword("RESPECT NULLS");
21810 }
21811 None => {}
21812 }
21813 }
21814 Ok(())
21815 }
21816
21817 fn generate_value_func(&mut self, name: &str, f: &ValueFunc) -> Result<()> {
21818 self.write_keyword(name);
21819 self.write("(");
21820 self.generate_expression(&f.this)?;
21821 if !f.order_by.is_empty() {
21823 self.write_space();
21824 self.write_keyword("ORDER BY");
21825 self.write_space();
21826 for (i, ordered) in f.order_by.iter().enumerate() {
21827 if i > 0 {
21828 self.write(", ");
21829 }
21830 self.generate_ordered(ordered)?;
21831 }
21832 }
21833 if self.config.ignore_nulls_in_func {
21835 match f.ignore_nulls {
21836 Some(true) => {
21837 self.write_space();
21838 self.write_keyword("IGNORE NULLS");
21839 }
21840 Some(false) => {
21841 self.write_space();
21842 self.write_keyword("RESPECT NULLS");
21843 }
21844 None => {}
21845 }
21846 }
21847 self.write(")");
21848 if !self.config.ignore_nulls_in_func {
21850 match f.ignore_nulls {
21851 Some(true) => {
21852 self.write_space();
21853 self.write_keyword("IGNORE NULLS");
21854 }
21855 Some(false) => {
21856 self.write_space();
21857 self.write_keyword("RESPECT NULLS");
21858 }
21859 None => {}
21860 }
21861 }
21862 Ok(())
21863 }
21864
21865 fn generate_value_func_with_ignore_nulls_bool(
21868 &mut self,
21869 name: &str,
21870 f: &ValueFunc,
21871 ) -> Result<()> {
21872 if matches!(self.config.dialect, Some(DialectType::Hive)) && f.ignore_nulls == Some(true) {
21873 self.write_keyword(name);
21874 self.write("(");
21875 self.generate_expression(&f.this)?;
21876 self.write(", ");
21877 self.write_keyword("TRUE");
21878 self.write(")");
21879 return Ok(());
21880 }
21881 self.generate_value_func(name, f)
21882 }
21883
21884 fn generate_nth_value(&mut self, f: &NthValueFunc) -> Result<()> {
21885 self.write_keyword("NTH_VALUE");
21886 self.write("(");
21887 self.generate_expression(&f.this)?;
21888 self.write(", ");
21889 self.generate_expression(&f.offset)?;
21890 if self.config.ignore_nulls_in_func {
21892 match f.ignore_nulls {
21893 Some(true) => {
21894 self.write_space();
21895 self.write_keyword("IGNORE NULLS");
21896 }
21897 Some(false) => {
21898 self.write_space();
21899 self.write_keyword("RESPECT NULLS");
21900 }
21901 None => {}
21902 }
21903 }
21904 self.write(")");
21905 if matches!(
21907 self.config.dialect,
21908 Some(crate::dialects::DialectType::Snowflake)
21909 ) {
21910 match f.from_first {
21911 Some(true) => {
21912 self.write_space();
21913 self.write_keyword("FROM FIRST");
21914 }
21915 Some(false) => {
21916 self.write_space();
21917 self.write_keyword("FROM LAST");
21918 }
21919 None => {}
21920 }
21921 }
21922 if !self.config.ignore_nulls_in_func {
21924 match f.ignore_nulls {
21925 Some(true) => {
21926 self.write_space();
21927 self.write_keyword("IGNORE NULLS");
21928 }
21929 Some(false) => {
21930 self.write_space();
21931 self.write_keyword("RESPECT NULLS");
21932 }
21933 None => {}
21934 }
21935 }
21936 Ok(())
21937 }
21938
21939 fn generate_position(&mut self, f: &PositionFunc) -> Result<()> {
21942 if matches!(
21945 self.config.dialect,
21946 Some(crate::dialects::DialectType::ClickHouse)
21947 ) {
21948 self.write_keyword("POSITION");
21949 self.write("(");
21950 self.generate_expression(&f.string)?;
21951 self.write(", ");
21952 self.generate_expression(&f.substring)?;
21953 if let Some(ref start) = f.start {
21954 self.write(", ");
21955 self.generate_expression(start)?;
21956 }
21957 self.write(")");
21958 return Ok(());
21959 }
21960
21961 self.write_keyword("POSITION");
21962 self.write("(");
21963 self.generate_expression(&f.substring)?;
21964 self.write_space();
21965 self.write_keyword("IN");
21966 self.write_space();
21967 self.generate_expression(&f.string)?;
21968 if let Some(ref start) = f.start {
21969 self.write(", ");
21970 self.generate_expression(start)?;
21971 }
21972 self.write(")");
21973 Ok(())
21974 }
21975
21976 fn generate_rand(&mut self, f: &Rand) -> Result<()> {
21979 if f.lower.is_some() || f.upper.is_some() {
21981 self.write_keyword("RANDOM");
21982 self.write("(");
21983 if let Some(ref lower) = f.lower {
21984 self.generate_expression(lower)?;
21985 }
21986 if let Some(ref upper) = f.upper {
21987 self.write(", ");
21988 self.generate_expression(upper)?;
21989 }
21990 self.write(")");
21991 return Ok(());
21992 }
21993 let func_name = match self.config.dialect {
21995 Some(crate::dialects::DialectType::Snowflake)
21996 | Some(crate::dialects::DialectType::DuckDB) => "RANDOM",
21997 _ => "RAND",
21998 };
21999 self.write_keyword(func_name);
22000 self.write("(");
22001 if !matches!(
22003 self.config.dialect,
22004 Some(crate::dialects::DialectType::DuckDB)
22005 ) {
22006 if let Some(ref seed) = f.seed {
22007 self.generate_expression(seed)?;
22008 }
22009 }
22010 self.write(")");
22011 Ok(())
22012 }
22013
22014 fn generate_truncate_func(&mut self, f: &TruncateFunc) -> Result<()> {
22015 self.write_keyword("TRUNCATE");
22016 self.write("(");
22017 self.generate_expression(&f.this)?;
22018 if let Some(ref decimals) = f.decimals {
22019 self.write(", ");
22020 self.generate_expression(decimals)?;
22021 }
22022 self.write(")");
22023 Ok(())
22024 }
22025
22026 fn generate_decode(&mut self, f: &DecodeFunc) -> Result<()> {
22029 self.write_keyword("DECODE");
22030 self.write("(");
22031 self.generate_expression(&f.this)?;
22032 for (search, result) in &f.search_results {
22033 self.write(", ");
22034 self.generate_expression(search)?;
22035 self.write(", ");
22036 self.generate_expression(result)?;
22037 }
22038 if let Some(ref default) = f.default {
22039 self.write(", ");
22040 self.generate_expression(default)?;
22041 }
22042 self.write(")");
22043 Ok(())
22044 }
22045
22046 fn generate_date_format(&mut self, name: &str, f: &DateFormatFunc) -> Result<()> {
22049 self.write_keyword(name);
22050 self.write("(");
22051 self.generate_expression(&f.this)?;
22052 self.write(", ");
22053 self.generate_expression(&f.format)?;
22054 self.write(")");
22055 Ok(())
22056 }
22057
22058 fn generate_from_unixtime(&mut self, f: &FromUnixtimeFunc) -> Result<()> {
22059 self.write_keyword("FROM_UNIXTIME");
22060 self.write("(");
22061 self.generate_expression(&f.this)?;
22062 if let Some(ref format) = f.format {
22063 self.write(", ");
22064 self.generate_expression(format)?;
22065 }
22066 self.write(")");
22067 Ok(())
22068 }
22069
22070 fn generate_unix_timestamp(&mut self, f: &UnixTimestampFunc) -> Result<()> {
22071 self.write_keyword("UNIX_TIMESTAMP");
22072 self.write("(");
22073 if let Some(ref expr) = f.this {
22074 self.generate_expression(expr)?;
22075 if let Some(ref format) = f.format {
22076 self.write(", ");
22077 self.generate_expression(format)?;
22078 }
22079 } else if matches!(
22080 self.config.dialect,
22081 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
22082 ) {
22083 self.write_keyword("CURRENT_TIMESTAMP");
22085 self.write("()");
22086 }
22087 self.write(")");
22088 Ok(())
22089 }
22090
22091 fn generate_make_date(&mut self, f: &MakeDateFunc) -> Result<()> {
22092 self.write_keyword("MAKE_DATE");
22093 self.write("(");
22094 self.generate_expression(&f.year)?;
22095 self.write(", ");
22096 self.generate_expression(&f.month)?;
22097 self.write(", ");
22098 self.generate_expression(&f.day)?;
22099 self.write(")");
22100 Ok(())
22101 }
22102
22103 fn generate_make_timestamp(&mut self, f: &MakeTimestampFunc) -> Result<()> {
22104 self.write_keyword("MAKE_TIMESTAMP");
22105 self.write("(");
22106 self.generate_expression(&f.year)?;
22107 self.write(", ");
22108 self.generate_expression(&f.month)?;
22109 self.write(", ");
22110 self.generate_expression(&f.day)?;
22111 self.write(", ");
22112 self.generate_expression(&f.hour)?;
22113 self.write(", ");
22114 self.generate_expression(&f.minute)?;
22115 self.write(", ");
22116 self.generate_expression(&f.second)?;
22117 if let Some(ref tz) = f.timezone {
22118 self.write(", ");
22119 self.generate_expression(tz)?;
22120 }
22121 self.write(")");
22122 Ok(())
22123 }
22124
22125 fn extract_struct_field_names(expr: &Expression) -> Option<Vec<String>> {
22127 match expr {
22128 Expression::Struct(s) => {
22129 if s.fields.iter().all(|(name, _)| name.is_some()) {
22130 Some(
22131 s.fields
22132 .iter()
22133 .map(|(name, _)| name.as_deref().unwrap_or("").to_string())
22134 .collect(),
22135 )
22136 } else {
22137 None
22138 }
22139 }
22140 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
22141 if f.args.iter().all(|a| matches!(a, Expression::Alias(_))) {
22143 Some(
22144 f.args
22145 .iter()
22146 .filter_map(|a| {
22147 if let Expression::Alias(alias) = a {
22148 Some(alias.alias.name.clone())
22149 } else {
22150 None
22151 }
22152 })
22153 .collect(),
22154 )
22155 } else {
22156 None
22157 }
22158 }
22159 _ => None,
22160 }
22161 }
22162
22163 fn struct_has_unnamed_fields(expr: &Expression) -> bool {
22165 match expr {
22166 Expression::Struct(s) => s.fields.iter().any(|(name, _)| name.is_none()),
22167 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
22168 f.args.iter().any(|a| !matches!(a, Expression::Alias(_)))
22169 }
22170 _ => false,
22171 }
22172 }
22173
22174 fn struct_field_count(expr: &Expression) -> usize {
22176 match expr {
22177 Expression::Struct(s) => s.fields.len(),
22178 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => f.args.len(),
22179 _ => 0,
22180 }
22181 }
22182
22183 fn apply_struct_field_names(expr: &Expression, field_names: &[String]) -> Expression {
22185 match expr {
22186 Expression::Struct(s) => {
22187 let mut new_fields = Vec::with_capacity(s.fields.len());
22188 for (i, (name, value)) in s.fields.iter().enumerate() {
22189 if name.is_none() && i < field_names.len() {
22190 new_fields.push((Some(field_names[i].clone()), value.clone()));
22191 } else {
22192 new_fields.push((name.clone(), value.clone()));
22193 }
22194 }
22195 Expression::Struct(Box::new(crate::expressions::Struct { fields: new_fields }))
22196 }
22197 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
22198 let mut new_args = Vec::with_capacity(f.args.len());
22199 for (i, arg) in f.args.iter().enumerate() {
22200 if !matches!(arg, Expression::Alias(_)) && i < field_names.len() {
22201 new_args.push(Expression::Alias(Box::new(crate::expressions::Alias {
22203 this: arg.clone(),
22204 alias: crate::expressions::Identifier::new(field_names[i].clone()),
22205 column_aliases: Vec::new(),
22206 alias_explicit_as: false,
22207 alias_keyword: None,
22208 pre_alias_comments: Vec::new(),
22209 trailing_comments: Vec::new(),
22210 inferred_type: None,
22211 })));
22212 } else {
22213 new_args.push(arg.clone());
22214 }
22215 }
22216 Expression::Function(Box::new(crate::expressions::Function {
22217 name: f.name.clone(),
22218 args: new_args,
22219 distinct: f.distinct,
22220 trailing_comments: f.trailing_comments.clone(),
22221 use_bracket_syntax: f.use_bracket_syntax,
22222 no_parens: f.no_parens,
22223 quoted: f.quoted,
22224 span: None,
22225 inferred_type: None,
22226 }))
22227 }
22228 _ => expr.clone(),
22229 }
22230 }
22231
22232 fn inherit_struct_field_names(expressions: &[Expression]) -> Vec<Expression> {
22236 let first = match expressions.first() {
22237 Some(e) => e,
22238 None => return expressions.to_vec(),
22239 };
22240
22241 let field_names = match Self::extract_struct_field_names(first) {
22242 Some(names) if !names.is_empty() => names,
22243 _ => return expressions.to_vec(),
22244 };
22245
22246 let mut result = Vec::with_capacity(expressions.len());
22247 for (idx, expr) in expressions.iter().enumerate() {
22248 if idx == 0 {
22249 result.push(expr.clone());
22250 continue;
22251 }
22252 if Self::struct_field_count(expr) == field_names.len()
22254 && Self::struct_has_unnamed_fields(expr)
22255 {
22256 result.push(Self::apply_struct_field_names(expr, &field_names));
22257 } else {
22258 result.push(expr.clone());
22259 }
22260 }
22261 result
22262 }
22263
22264 fn generate_array_constructor(&mut self, f: &ArrayConstructor) -> Result<()> {
22267 let needs_inheritance = matches!(
22270 self.config.dialect,
22271 Some(DialectType::DuckDB)
22272 | Some(DialectType::Spark)
22273 | Some(DialectType::Databricks)
22274 | Some(DialectType::Hive)
22275 | Some(DialectType::Snowflake)
22276 | Some(DialectType::Presto)
22277 | Some(DialectType::Trino)
22278 );
22279 let propagated: Vec<Expression>;
22280 let expressions = if needs_inheritance && f.expressions.len() > 1 {
22281 propagated = Self::inherit_struct_field_names(&f.expressions);
22282 &propagated
22283 } else {
22284 &f.expressions
22285 };
22286
22287 let should_split = if self.config.pretty && !expressions.is_empty() {
22289 let mut expr_strings: Vec<String> = Vec::with_capacity(expressions.len());
22290 for expr in expressions {
22291 let mut temp_gen = Generator::with_arc_config(self.config.clone());
22292 Arc::make_mut(&mut temp_gen.config).pretty = false;
22293 temp_gen.generate_expression(expr)?;
22294 expr_strings.push(temp_gen.output);
22295 }
22296 self.too_wide(&expr_strings)
22297 } else {
22298 false
22299 };
22300
22301 if f.bracket_notation {
22302 let (open, close) = match self.config.dialect {
22306 None
22307 | Some(DialectType::Generic)
22308 | Some(DialectType::Spark)
22309 | Some(DialectType::Databricks)
22310 | Some(DialectType::Hive) => {
22311 self.write_keyword("ARRAY");
22312 ("(", ")")
22313 }
22314 Some(DialectType::Presto)
22315 | Some(DialectType::Trino)
22316 | Some(DialectType::PostgreSQL)
22317 | Some(DialectType::Redshift)
22318 | Some(DialectType::Materialize)
22319 | Some(DialectType::RisingWave)
22320 | Some(DialectType::CockroachDB) => {
22321 self.write_keyword("ARRAY");
22322 ("[", "]")
22323 }
22324 _ => ("[", "]"),
22325 };
22326 self.write(open);
22327 if should_split {
22328 self.write_newline();
22329 self.indent_level += 1;
22330 for (i, expr) in expressions.iter().enumerate() {
22331 self.write_indent();
22332 self.generate_expression(expr)?;
22333 if i + 1 < expressions.len() {
22334 self.write(",");
22335 }
22336 self.write_newline();
22337 }
22338 self.indent_level -= 1;
22339 self.write_indent();
22340 } else {
22341 for (i, expr) in expressions.iter().enumerate() {
22342 if i > 0 {
22343 self.write(", ");
22344 }
22345 self.generate_expression(expr)?;
22346 }
22347 }
22348 self.write(close);
22349 } else {
22350 if f.use_list_keyword {
22352 self.write_keyword("LIST");
22353 } else {
22354 self.write_keyword("ARRAY");
22355 }
22356 let has_subquery = expressions
22359 .iter()
22360 .any(|e| matches!(e, Expression::Select(_)));
22361 let (open, close) = if matches!(
22362 self.config.dialect,
22363 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive)
22364 ) || (matches!(self.config.dialect, Some(DialectType::BigQuery))
22365 && has_subquery)
22366 {
22367 ("(", ")")
22368 } else {
22369 ("[", "]")
22370 };
22371 self.write(open);
22372 if should_split {
22373 self.write_newline();
22374 self.indent_level += 1;
22375 for (i, expr) in expressions.iter().enumerate() {
22376 self.write_indent();
22377 self.generate_expression(expr)?;
22378 if i + 1 < expressions.len() {
22379 self.write(",");
22380 }
22381 self.write_newline();
22382 }
22383 self.indent_level -= 1;
22384 self.write_indent();
22385 } else {
22386 for (i, expr) in expressions.iter().enumerate() {
22387 if i > 0 {
22388 self.write(", ");
22389 }
22390 self.generate_expression(expr)?;
22391 }
22392 }
22393 self.write(close);
22394 }
22395 Ok(())
22396 }
22397
22398 fn generate_array_sort(&mut self, f: &ArraySortFunc) -> Result<()> {
22399 self.write_keyword("ARRAY_SORT");
22400 self.write("(");
22401 self.generate_expression(&f.this)?;
22402 if let Some(ref comp) = f.comparator {
22403 self.write(", ");
22404 self.generate_expression(comp)?;
22405 }
22406 self.write(")");
22407 Ok(())
22408 }
22409
22410 fn generate_array_join(&mut self, name: &str, f: &ArrayJoinFunc) -> Result<()> {
22411 self.write_keyword(name);
22412 self.write("(");
22413 self.generate_expression(&f.this)?;
22414 self.write(", ");
22415 self.generate_expression(&f.separator)?;
22416 if let Some(ref null_rep) = f.null_replacement {
22417 self.write(", ");
22418 self.generate_expression(null_rep)?;
22419 }
22420 self.write(")");
22421 Ok(())
22422 }
22423
22424 fn generate_unnest(&mut self, f: &UnnestFunc) -> Result<()> {
22425 self.write_keyword("UNNEST");
22426 self.write("(");
22427 self.generate_expression(&f.this)?;
22428 for extra in &f.expressions {
22429 self.write(", ");
22430 self.generate_expression(extra)?;
22431 }
22432 self.write(")");
22433 if f.with_ordinality {
22434 self.write_space();
22435 if self.config.unnest_with_ordinality {
22436 self.write_keyword("WITH ORDINALITY");
22438 } else if f.offset_alias.is_some() {
22439 if let Some(ref alias) = f.alias {
22442 self.write_keyword("AS");
22443 self.write_space();
22444 self.generate_identifier(alias)?;
22445 self.write_space();
22446 }
22447 self.write_keyword("WITH OFFSET");
22448 if let Some(ref offset_alias) = f.offset_alias {
22449 self.write_space();
22450 self.write_keyword("AS");
22451 self.write_space();
22452 self.generate_identifier(offset_alias)?;
22453 }
22454 } else {
22455 self.write_keyword("WITH OFFSET");
22457 if f.alias.is_none() {
22458 self.write(" AS offset");
22459 }
22460 }
22461 }
22462 if let Some(ref alias) = f.alias {
22463 let should_add_alias = if !f.with_ordinality {
22465 true
22466 } else if self.config.unnest_with_ordinality {
22467 true
22469 } else if f.offset_alias.is_some() {
22470 false
22472 } else {
22473 true
22475 };
22476 if should_add_alias {
22477 self.write_space();
22478 self.write_keyword("AS");
22479 self.write_space();
22480 self.generate_identifier(alias)?;
22481 }
22482 }
22483 Ok(())
22484 }
22485
22486 fn generate_array_filter(&mut self, f: &ArrayFilterFunc) -> Result<()> {
22487 self.write_keyword("FILTER");
22488 self.write("(");
22489 self.generate_expression(&f.this)?;
22490 self.write(", ");
22491 self.generate_expression(&f.filter)?;
22492 self.write(")");
22493 Ok(())
22494 }
22495
22496 fn generate_array_transform(&mut self, f: &ArrayTransformFunc) -> Result<()> {
22497 self.write_keyword("TRANSFORM");
22498 self.write("(");
22499 self.generate_expression(&f.this)?;
22500 self.write(", ");
22501 self.generate_expression(&f.transform)?;
22502 self.write(")");
22503 Ok(())
22504 }
22505
22506 fn generate_sequence(&mut self, name: &str, f: &SequenceFunc) -> Result<()> {
22507 self.write_keyword(name);
22508 self.write("(");
22509 self.generate_expression(&f.start)?;
22510 self.write(", ");
22511 self.generate_expression(&f.stop)?;
22512 if let Some(ref step) = f.step {
22513 self.write(", ");
22514 self.generate_expression(step)?;
22515 }
22516 self.write(")");
22517 Ok(())
22518 }
22519
22520 fn generate_struct_constructor(&mut self, f: &StructConstructor) -> Result<()> {
22523 self.write_keyword("STRUCT");
22524 self.write("(");
22525 for (i, (name, expr)) in f.fields.iter().enumerate() {
22526 if i > 0 {
22527 self.write(", ");
22528 }
22529 if let Some(ref id) = name {
22530 self.generate_identifier(id)?;
22531 self.write(" ");
22532 self.write_keyword("AS");
22533 self.write(" ");
22534 }
22535 self.generate_expression(expr)?;
22536 }
22537 self.write(")");
22538 Ok(())
22539 }
22540
22541 fn generate_struct_function_cross_dialect(&mut self, func: &Function) -> Result<()> {
22543 let mut names: Vec<Option<String>> = Vec::new();
22546 let mut values: Vec<&Expression> = Vec::new();
22547 let mut all_named = true;
22548
22549 for arg in &func.args {
22550 match arg {
22551 Expression::Alias(a) => {
22552 names.push(Some(a.alias.name.clone()));
22553 values.push(&a.this);
22554 }
22555 _ => {
22556 names.push(None);
22557 values.push(arg);
22558 all_named = false;
22559 }
22560 }
22561 }
22562
22563 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
22564 self.write("{");
22566 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
22567 if i > 0 {
22568 self.write(", ");
22569 }
22570 if let Some(n) = name {
22571 self.write("'");
22572 self.write(n);
22573 self.write("'");
22574 } else {
22575 self.write("'_");
22576 self.write(&i.to_string());
22577 self.write("'");
22578 }
22579 self.write(": ");
22580 self.generate_expression(value)?;
22581 }
22582 self.write("}");
22583 return Ok(());
22584 }
22585
22586 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
22587 self.write_keyword("OBJECT_CONSTRUCT");
22589 self.write("(");
22590 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
22591 if i > 0 {
22592 self.write(", ");
22593 }
22594 if let Some(n) = name {
22595 self.write("'");
22596 self.write(n);
22597 self.write("'");
22598 } else {
22599 self.write("'_");
22600 self.write(&i.to_string());
22601 self.write("'");
22602 }
22603 self.write(", ");
22604 self.generate_expression(value)?;
22605 }
22606 self.write(")");
22607 return Ok(());
22608 }
22609
22610 if matches!(
22611 self.config.dialect,
22612 Some(DialectType::Presto) | Some(DialectType::Trino)
22613 ) {
22614 if all_named && !names.is_empty() {
22615 self.write_keyword("CAST");
22618 self.write("(");
22619 self.write_keyword("ROW");
22620 self.write("(");
22621 for (i, value) in values.iter().enumerate() {
22622 if i > 0 {
22623 self.write(", ");
22624 }
22625 self.generate_expression(value)?;
22626 }
22627 self.write(")");
22628 self.write(" ");
22629 self.write_keyword("AS");
22630 self.write(" ");
22631 self.write_keyword("ROW");
22632 self.write("(");
22633 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
22634 if i > 0 {
22635 self.write(", ");
22636 }
22637 if let Some(n) = name {
22638 self.write(n);
22639 }
22640 self.write(" ");
22641 let type_str = Self::infer_sql_type_for_presto(value);
22642 self.write_keyword(&type_str);
22643 }
22644 self.write(")");
22645 self.write(")");
22646 } else {
22647 self.write_keyword("ROW");
22649 self.write("(");
22650 for (i, value) in values.iter().enumerate() {
22651 if i > 0 {
22652 self.write(", ");
22653 }
22654 self.generate_expression(value)?;
22655 }
22656 self.write(")");
22657 }
22658 return Ok(());
22659 }
22660
22661 self.write_keyword("ROW");
22663 self.write("(");
22664 for (i, value) in values.iter().enumerate() {
22665 if i > 0 {
22666 self.write(", ");
22667 }
22668 self.generate_expression(value)?;
22669 }
22670 self.write(")");
22671 Ok(())
22672 }
22673
22674 fn infer_sql_type_for_presto(expr: &Expression) -> String {
22676 match expr {
22677 Expression::Literal(lit)
22678 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
22679 {
22680 "VARCHAR".to_string()
22681 }
22682 Expression::Literal(lit)
22683 if matches!(lit.as_ref(), crate::expressions::Literal::Number(_)) =>
22684 {
22685 let crate::expressions::Literal::Number(n) = lit.as_ref() else {
22686 unreachable!()
22687 };
22688 if n.contains('.') {
22689 "DOUBLE".to_string()
22690 } else {
22691 "INTEGER".to_string()
22692 }
22693 }
22694 Expression::Boolean(_) => "BOOLEAN".to_string(),
22695 Expression::Literal(lit)
22696 if matches!(lit.as_ref(), crate::expressions::Literal::Date(_)) =>
22697 {
22698 "DATE".to_string()
22699 }
22700 Expression::Literal(lit)
22701 if matches!(lit.as_ref(), crate::expressions::Literal::Timestamp(_)) =>
22702 {
22703 "TIMESTAMP".to_string()
22704 }
22705 Expression::Literal(lit)
22706 if matches!(lit.as_ref(), crate::expressions::Literal::Datetime(_)) =>
22707 {
22708 "TIMESTAMP".to_string()
22709 }
22710 Expression::Array(_) | Expression::ArrayFunc(_) => {
22711 "ARRAY(VARCHAR)".to_string()
22713 }
22714 Expression::Struct(_) | Expression::StructFunc(_) => "ROW".to_string(),
22716 Expression::Function(f) => {
22717 if f.name.eq_ignore_ascii_case("STRUCT") {
22718 "ROW".to_string()
22719 } else if f.name.eq_ignore_ascii_case("CURRENT_DATE") {
22720 "DATE".to_string()
22721 } else if f.name.eq_ignore_ascii_case("CURRENT_TIMESTAMP")
22722 || f.name.eq_ignore_ascii_case("NOW")
22723 {
22724 "TIMESTAMP".to_string()
22725 } else {
22726 "VARCHAR".to_string()
22727 }
22728 }
22729 _ => "VARCHAR".to_string(),
22730 }
22731 }
22732
22733 fn generate_struct_extract(&mut self, f: &StructExtractFunc) -> Result<()> {
22734 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
22736 self.write_keyword("STRUCT_EXTRACT");
22737 self.write("(");
22738 self.generate_expression(&f.this)?;
22739 self.write(", ");
22740 self.write("'");
22742 self.write(&f.field.name);
22743 self.write("'");
22744 self.write(")");
22745 return Ok(());
22746 }
22747 self.generate_expression(&f.this)?;
22748 self.write(".");
22749 self.generate_identifier(&f.field)
22750 }
22751
22752 fn generate_named_struct(&mut self, f: &NamedStructFunc) -> Result<()> {
22753 if matches!(
22754 self.config.dialect,
22755 Some(DialectType::Spark | DialectType::Databricks)
22756 ) {
22757 self.write_keyword("STRUCT");
22758 self.write("(");
22759 for (i, (name, value)) in f.pairs.iter().enumerate() {
22760 if i > 0 {
22761 self.write(", ");
22762 }
22763 self.generate_expression(value)?;
22764 self.write(" ");
22765 self.write_keyword("AS");
22766 self.write(" ");
22767 if let Expression::Literal(lit) = name {
22768 if let Literal::String(field_name) = lit.as_ref() {
22769 self.generate_identifier(&Identifier::new(field_name))?;
22770 } else {
22771 self.generate_expression(name)?;
22772 }
22773 } else {
22774 self.generate_expression(name)?;
22775 }
22776 }
22777 self.write(")");
22778 return Ok(());
22779 }
22780
22781 self.write_keyword("NAMED_STRUCT");
22782 self.write("(");
22783 for (i, (name, value)) in f.pairs.iter().enumerate() {
22784 if i > 0 {
22785 self.write(", ");
22786 }
22787 self.generate_expression(name)?;
22788 self.write(", ");
22789 self.generate_expression(value)?;
22790 }
22791 self.write(")");
22792 Ok(())
22793 }
22794
22795 fn generate_map_constructor(&mut self, f: &MapConstructor) -> Result<()> {
22798 if f.curly_brace_syntax {
22799 if f.with_map_keyword {
22801 self.write_keyword("MAP");
22802 self.write(" ");
22803 }
22804 self.write("{");
22805 for (i, (key, val)) in f.keys.iter().zip(f.values.iter()).enumerate() {
22806 if i > 0 {
22807 self.write(", ");
22808 }
22809 self.generate_expression(key)?;
22810 self.write(": ");
22811 self.generate_expression(val)?;
22812 }
22813 self.write("}");
22814 } else {
22815 self.write_keyword("MAP");
22817 self.write("(");
22818 self.write_keyword("ARRAY");
22819 self.write("[");
22820 for (i, key) in f.keys.iter().enumerate() {
22821 if i > 0 {
22822 self.write(", ");
22823 }
22824 self.generate_expression(key)?;
22825 }
22826 self.write("], ");
22827 self.write_keyword("ARRAY");
22828 self.write("[");
22829 for (i, val) in f.values.iter().enumerate() {
22830 if i > 0 {
22831 self.write(", ");
22832 }
22833 self.generate_expression(val)?;
22834 }
22835 self.write("])");
22836 }
22837 Ok(())
22838 }
22839
22840 fn generate_transform_func(&mut self, name: &str, f: &TransformFunc) -> Result<()> {
22841 self.write_keyword(name);
22842 self.write("(");
22843 self.generate_expression(&f.this)?;
22844 self.write(", ");
22845 self.generate_expression(&f.transform)?;
22846 self.write(")");
22847 Ok(())
22848 }
22849
22850 fn generate_json_extract(&mut self, name: &str, f: &JsonExtractFunc) -> Result<()> {
22853 use crate::dialects::DialectType;
22854
22855 let use_arrow = f.arrow_syntax && self.dialect_supports_json_arrow();
22857
22858 if use_arrow {
22859 self.generate_expression(&f.this)?;
22861 if name == "JSON_EXTRACT_SCALAR" || name == "JSON_EXTRACT_PATH_TEXT" {
22862 self.write(" ->> ");
22863 } else {
22864 self.write(" -> ");
22865 }
22866 self.generate_expression(&f.path)?;
22867 return Ok(());
22868 }
22869
22870 if f.hash_arrow_syntax
22872 && matches!(
22873 self.config.dialect,
22874 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
22875 )
22876 {
22877 self.generate_expression(&f.this)?;
22878 self.write(" #>> ");
22879 self.generate_expression(&f.path)?;
22880 return Ok(());
22881 }
22882
22883 let func_name = if matches!(self.config.dialect, Some(DialectType::Redshift)) {
22886 match name {
22887 "JSON_EXTRACT_SCALAR"
22888 | "JSON_EXTRACT_PATH_TEXT"
22889 | "JSON_EXTRACT"
22890 | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH_TEXT",
22891 _ => name,
22892 }
22893 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
22894 match name {
22895 "JSON_EXTRACT_SCALAR" | "JSON_EXTRACT_PATH_TEXT" => "JSON_EXTRACT_PATH_TEXT",
22896 "JSON_EXTRACT" | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH",
22897 _ => name,
22898 }
22899 } else {
22900 name
22901 };
22902
22903 self.write_keyword(func_name);
22904 self.write("(");
22905 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
22907 if let Expression::Cast(ref cast) = f.this {
22908 if matches!(cast.to, crate::expressions::DataType::Json) {
22909 self.generate_expression(&cast.this)?;
22910 } else {
22911 self.generate_expression(&f.this)?;
22912 }
22913 } else {
22914 self.generate_expression(&f.this)?;
22915 }
22916 } else {
22917 self.generate_expression(&f.this)?;
22918 }
22919 if matches!(
22922 self.config.dialect,
22923 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
22924 ) && (func_name == "JSON_EXTRACT_PATH" || func_name == "JSON_EXTRACT_PATH_TEXT")
22925 {
22926 if let Expression::Literal(ref lit) = f.path {
22927 if let Literal::String(ref s) = lit.as_ref() {
22928 let parts = Self::decompose_json_path(s);
22929 for part in &parts {
22930 self.write(", '");
22931 self.write(part);
22932 self.write("'");
22933 }
22934 }
22935 } else {
22936 self.write(", ");
22937 self.generate_expression(&f.path)?;
22938 }
22939 } else {
22940 self.write(", ");
22941 self.generate_expression(&f.path)?;
22942 }
22943
22944 if let Some(ref wrapper) = f.wrapper_option {
22947 self.write_space();
22948 self.write_keyword(wrapper);
22949 }
22950 if let Some(ref quotes) = f.quotes_option {
22951 self.write_space();
22952 self.write_keyword(quotes);
22953 if f.on_scalar_string {
22954 self.write_space();
22955 self.write_keyword("ON SCALAR STRING");
22956 }
22957 }
22958 if let Some(ref on_err) = f.on_error {
22959 self.write_space();
22960 self.write_keyword(on_err);
22961 }
22962 if let Some(ref ret_type) = f.returning {
22963 self.write_space();
22964 self.write_keyword("RETURNING");
22965 self.write_space();
22966 self.generate_data_type(ret_type)?;
22967 }
22968
22969 self.write(")");
22970 Ok(())
22971 }
22972
22973 fn dialect_supports_json_arrow(&self) -> bool {
22975 use crate::dialects::DialectType;
22976 match self.config.dialect {
22977 Some(DialectType::PostgreSQL) => true,
22979 Some(DialectType::MySQL) => true,
22980 Some(DialectType::DuckDB) => true,
22981 Some(DialectType::CockroachDB) => true,
22982 Some(DialectType::StarRocks) => true,
22983 Some(DialectType::SQLite) => true,
22984 _ => false,
22986 }
22987 }
22988
22989 fn generate_json_path(&mut self, name: &str, f: &JsonPathFunc) -> Result<()> {
22990 use crate::dialects::DialectType;
22991
22992 if matches!(
22994 self.config.dialect,
22995 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
22996 ) && name == "JSON_EXTRACT_PATH"
22997 {
22998 self.generate_expression(&f.this)?;
22999 self.write(" #> ");
23000 if f.paths.len() == 1 {
23001 self.generate_expression(&f.paths[0])?;
23002 } else {
23003 self.write_keyword("ARRAY");
23005 self.write("[");
23006 for (i, path) in f.paths.iter().enumerate() {
23007 if i > 0 {
23008 self.write(", ");
23009 }
23010 self.generate_expression(path)?;
23011 }
23012 self.write("]");
23013 }
23014 return Ok(());
23015 }
23016
23017 self.write_keyword(name);
23018 self.write("(");
23019 self.generate_expression(&f.this)?;
23020 for path in &f.paths {
23021 self.write(", ");
23022 self.generate_expression(path)?;
23023 }
23024 self.write(")");
23025 Ok(())
23026 }
23027
23028 fn generate_json_object(&mut self, f: &JsonObjectFunc) -> Result<()> {
23029 use crate::dialects::DialectType;
23030
23031 self.write_keyword("JSON_OBJECT");
23032 self.write("(");
23033 if f.star {
23034 self.write("*");
23035 } else {
23036 let use_comma_syntax = self.config.json_key_value_pair_sep == ","
23040 || matches!(
23041 self.config.dialect,
23042 Some(DialectType::BigQuery)
23043 | Some(DialectType::MySQL)
23044 | Some(DialectType::SQLite)
23045 );
23046
23047 for (i, (key, value)) in f.pairs.iter().enumerate() {
23048 if i > 0 {
23049 self.write(", ");
23050 }
23051 self.generate_expression(key)?;
23052 if use_comma_syntax {
23053 self.write(", ");
23054 } else {
23055 self.write(": ");
23056 }
23057 self.generate_expression(value)?;
23058 }
23059 }
23060 if let Some(null_handling) = f.null_handling {
23061 self.write_space();
23062 match null_handling {
23063 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
23064 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
23065 }
23066 }
23067 if f.with_unique_keys {
23068 self.write_space();
23069 self.write_keyword("WITH UNIQUE KEYS");
23070 }
23071 if let Some(ref ret_type) = f.returning_type {
23072 self.write_space();
23073 self.write_keyword("RETURNING");
23074 self.write_space();
23075 self.generate_data_type(ret_type)?;
23076 if f.format_json {
23077 self.write_space();
23078 self.write_keyword("FORMAT JSON");
23079 }
23080 if let Some(ref enc) = f.encoding {
23081 self.write_space();
23082 self.write_keyword("ENCODING");
23083 self.write_space();
23084 self.write(enc);
23085 }
23086 }
23087 self.write(")");
23088 Ok(())
23089 }
23090
23091 fn generate_json_modify(&mut self, name: &str, f: &JsonModifyFunc) -> Result<()> {
23092 self.write_keyword(name);
23093 self.write("(");
23094 self.generate_expression(&f.this)?;
23095 for (path, value) in &f.path_values {
23096 self.write(", ");
23097 self.generate_expression(path)?;
23098 self.write(", ");
23099 self.generate_expression(value)?;
23100 }
23101 self.write(")");
23102 Ok(())
23103 }
23104
23105 fn generate_json_array_agg(&mut self, f: &JsonArrayAggFunc) -> Result<()> {
23106 self.write_keyword("JSON_ARRAYAGG");
23107 self.write("(");
23108 self.generate_expression(&f.this)?;
23109 if let Some(ref order_by) = f.order_by {
23110 self.write_space();
23111 self.write_keyword("ORDER BY");
23112 self.write_space();
23113 for (i, ord) in order_by.iter().enumerate() {
23114 if i > 0 {
23115 self.write(", ");
23116 }
23117 self.generate_ordered(ord)?;
23118 }
23119 }
23120 if let Some(null_handling) = f.null_handling {
23121 self.write_space();
23122 match null_handling {
23123 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
23124 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
23125 }
23126 }
23127 self.write(")");
23128 if let Some(ref filter) = f.filter {
23129 self.write_space();
23130 self.write_keyword("FILTER");
23131 self.write("(");
23132 self.write_keyword("WHERE");
23133 self.write_space();
23134 self.generate_expression(filter)?;
23135 self.write(")");
23136 }
23137 Ok(())
23138 }
23139
23140 fn generate_json_object_agg(&mut self, f: &JsonObjectAggFunc) -> Result<()> {
23141 self.write_keyword("JSON_OBJECTAGG");
23142 self.write("(");
23143 self.generate_expression(&f.key)?;
23144 self.write(": ");
23145 self.generate_expression(&f.value)?;
23146 if let Some(null_handling) = f.null_handling {
23147 self.write_space();
23148 match null_handling {
23149 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
23150 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
23151 }
23152 }
23153 self.write(")");
23154 if let Some(ref filter) = f.filter {
23155 self.write_space();
23156 self.write_keyword("FILTER");
23157 self.write("(");
23158 self.write_keyword("WHERE");
23159 self.write_space();
23160 self.generate_expression(filter)?;
23161 self.write(")");
23162 }
23163 Ok(())
23164 }
23165
23166 fn generate_convert(&mut self, f: &ConvertFunc) -> Result<()> {
23169 use crate::dialects::DialectType;
23170
23171 if self.config.dialect == Some(DialectType::Redshift) {
23173 self.write_keyword("CAST");
23174 self.write("(");
23175 self.generate_expression(&f.this)?;
23176 self.write_space();
23177 self.write_keyword("AS");
23178 self.write_space();
23179 self.generate_data_type(&f.to)?;
23180 self.write(")");
23181 return Ok(());
23182 }
23183
23184 self.write_keyword("CONVERT");
23185 self.write("(");
23186 self.generate_data_type(&f.to)?;
23187 self.write(", ");
23188 self.generate_expression(&f.this)?;
23189 if let Some(ref style) = f.style {
23190 self.write(", ");
23191 self.generate_expression(style)?;
23192 }
23193 self.write(")");
23194 Ok(())
23195 }
23196
23197 fn generate_lambda(&mut self, f: &LambdaExpr) -> Result<()> {
23200 if f.colon {
23201 self.write_keyword("LAMBDA");
23203 self.write_space();
23204 for (i, param) in f.parameters.iter().enumerate() {
23205 if i > 0 {
23206 self.write(", ");
23207 }
23208 self.generate_identifier(param)?;
23209 }
23210 self.write(" : ");
23211 } else {
23212 if f.parameters.len() == 1 {
23214 self.generate_identifier(&f.parameters[0])?;
23215 } else {
23216 self.write("(");
23217 for (i, param) in f.parameters.iter().enumerate() {
23218 if i > 0 {
23219 self.write(", ");
23220 }
23221 self.generate_identifier(param)?;
23222 }
23223 self.write(")");
23224 }
23225 self.write(" -> ");
23226 }
23227 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23228 if let Expression::Lambda(inner) = &f.body {
23229 self.generate_lambda_with_parenthesized_single_param(inner)?;
23230 return Ok(());
23231 }
23232 }
23233
23234 self.generate_expression(&f.body)
23235 }
23236
23237 fn generate_lambda_with_parenthesized_single_param(&mut self, f: &LambdaExpr) -> Result<()> {
23238 if f.colon {
23239 return self.generate_lambda(f);
23240 }
23241
23242 self.write("(");
23243 for (i, param) in f.parameters.iter().enumerate() {
23244 if i > 0 {
23245 self.write(", ");
23246 }
23247 self.generate_identifier(param)?;
23248 }
23249 self.write(") -> ");
23250 self.generate_expression(&f.body)
23251 }
23252
23253 fn generate_named_argument(&mut self, f: &NamedArgument) -> Result<()> {
23254 self.generate_identifier(&f.name)?;
23255 match f.separator {
23256 NamedArgSeparator::DArrow => self.write(" => "),
23257 NamedArgSeparator::ColonEq => self.write(" := "),
23258 NamedArgSeparator::Eq => self.write(" = "),
23259 }
23260 self.generate_expression(&f.value)
23261 }
23262
23263 fn generate_table_argument(&mut self, f: &TableArgument) -> Result<()> {
23264 self.write_keyword(&f.prefix);
23265 self.write(" ");
23266 self.generate_expression(&f.this)
23267 }
23268
23269 fn generate_parameter(&mut self, f: &Parameter) -> Result<()> {
23270 match f.style {
23271 ParameterStyle::Question => self.write("?"),
23272 ParameterStyle::Dollar => {
23273 if let Some(idx) = f.index {
23274 if matches!(
23275 self.config.dialect,
23276 Some(DialectType::TSQL) | Some(DialectType::Fabric)
23277 ) {
23278 self.write("@P");
23279 self.write(&idx.to_string());
23280 } else {
23281 self.write("$");
23282 self.write(&idx.to_string());
23283 }
23284 } else {
23285 self.write("$");
23286 if let Some(ref name) = f.name {
23287 self.write(name);
23289 }
23290 }
23291 }
23292 ParameterStyle::DollarBrace => {
23293 self.write("${");
23295 if let Some(ref name) = f.name {
23296 self.write(name);
23297 }
23298 if let Some(ref expr) = f.expression {
23299 self.write(":");
23300 self.write(expr);
23301 }
23302 self.write("}");
23303 }
23304 ParameterStyle::Colon => {
23305 self.write(":");
23306 if let Some(idx) = f.index {
23307 self.write(&idx.to_string());
23308 } else if let Some(ref name) = f.name {
23309 self.write(name);
23310 }
23311 }
23312 ParameterStyle::At => {
23313 self.write("@");
23314 if let Some(ref name) = f.name {
23315 if f.string_quoted {
23316 self.write("'");
23317 self.write(name);
23318 self.write("'");
23319 } else if f.quoted {
23320 self.write("\"");
23321 self.write(name);
23322 self.write("\"");
23323 } else {
23324 self.write(name);
23325 }
23326 }
23327 }
23328 ParameterStyle::DoubleAt => {
23329 self.write("@@");
23330 if let Some(ref name) = f.name {
23331 self.write(name);
23332 }
23333 }
23334 ParameterStyle::DoubleDollar => {
23335 self.write("$$");
23336 if let Some(ref name) = f.name {
23337 self.write(name);
23338 }
23339 }
23340 ParameterStyle::Percent => {
23341 if let Some(ref name) = f.name {
23342 self.write("%(");
23344 self.write(name);
23345 self.write(")s");
23346 } else {
23347 self.write("%s");
23349 }
23350 }
23351 ParameterStyle::Brace => {
23352 self.write("{");
23355 if let Some(ref name) = f.name {
23356 self.write(name);
23357 }
23358 if let Some(ref expr) = f.expression {
23359 self.write(": ");
23360 self.write(expr);
23361 }
23362 self.write("}");
23363 }
23364 }
23365 Ok(())
23366 }
23367
23368 fn generate_placeholder(&mut self, f: &Placeholder) -> Result<()> {
23369 self.write("?");
23370 if let Some(idx) = f.index {
23371 self.write(&idx.to_string());
23372 }
23373 Ok(())
23374 }
23375
23376 fn generate_sql_comment(&mut self, f: &SqlComment) -> Result<()> {
23377 if f.is_block {
23378 self.write("/*");
23379 self.write(&f.text);
23380 self.write("*/");
23381 } else {
23382 self.write("--");
23383 self.write(&f.text);
23384 }
23385 Ok(())
23386 }
23387
23388 fn generate_similar_to(&mut self, f: &SimilarToExpr) -> Result<()> {
23391 self.generate_expression(&f.this)?;
23392 if f.not {
23393 self.write_space();
23394 self.write_keyword("NOT");
23395 }
23396 self.write_space();
23397 self.write_keyword("SIMILAR TO");
23398 self.write_space();
23399 self.generate_expression(&f.pattern)?;
23400 if let Some(ref escape) = f.escape {
23401 self.write_space();
23402 self.write_keyword("ESCAPE");
23403 self.write_space();
23404 self.generate_expression(escape)?;
23405 }
23406 Ok(())
23407 }
23408
23409 fn generate_quantified(&mut self, name: &str, f: &QuantifiedExpr) -> Result<()> {
23410 self.generate_expression(&f.this)?;
23411 self.write_space();
23412 if let Some(op) = &f.op {
23414 match op {
23415 QuantifiedOp::Eq => self.write("="),
23416 QuantifiedOp::Neq => self.write("<>"),
23417 QuantifiedOp::Lt => self.write("<"),
23418 QuantifiedOp::Lte => self.write("<="),
23419 QuantifiedOp::Gt => self.write(">"),
23420 QuantifiedOp::Gte => self.write(">="),
23421 }
23422 self.write_space();
23423 }
23424 self.write_keyword(name);
23425
23426 if matches!(&f.subquery, Expression::Subquery(_)) {
23428 self.write_space();
23429 self.generate_expression(&f.subquery)?;
23430 } else {
23431 let is_statement = matches!(
23432 &f.subquery,
23433 Expression::Select(_)
23434 | Expression::Union(_)
23435 | Expression::Intersect(_)
23436 | Expression::Except(_)
23437 );
23438 if is_statement
23439 && !self.config.quantified_no_paren_space
23440 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
23441 {
23442 self.write_space();
23443 }
23444 self.write("(");
23445
23446 if self.config.pretty && is_statement {
23447 self.write_newline();
23448 self.indent_level += 1;
23449 self.write_indent();
23450 }
23451 self.generate_expression(&f.subquery)?;
23452 if self.config.pretty && is_statement {
23453 self.write_newline();
23454 self.indent_level -= 1;
23455 self.write_indent();
23456 }
23457 self.write(")");
23458 }
23459 Ok(())
23460 }
23461
23462 fn generate_overlaps(&mut self, f: &OverlapsExpr) -> Result<()> {
23463 if let (Some(this), Some(expr)) = (&f.this, &f.expression) {
23465 self.generate_expression(this)?;
23466 self.write_space();
23467 self.write_keyword("OVERLAPS");
23468 self.write_space();
23469 self.generate_expression(expr)?;
23470 } else if let (Some(ls), Some(le), Some(rs), Some(re)) =
23471 (&f.left_start, &f.left_end, &f.right_start, &f.right_end)
23472 {
23473 self.write("(");
23475 self.generate_expression(ls)?;
23476 self.write(", ");
23477 self.generate_expression(le)?;
23478 self.write(")");
23479 self.write_space();
23480 self.write_keyword("OVERLAPS");
23481 self.write_space();
23482 self.write("(");
23483 self.generate_expression(rs)?;
23484 self.write(", ");
23485 self.generate_expression(re)?;
23486 self.write(")");
23487 }
23488 Ok(())
23489 }
23490
23491 fn generate_try_cast(&mut self, cast: &Cast) -> Result<()> {
23494 use crate::dialects::DialectType;
23495
23496 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
23498 self.generate_expression(&cast.this)?;
23499 self.write(" !:> ");
23500 self.generate_data_type(&cast.to)?;
23501 return Ok(());
23502 }
23503
23504 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
23506 self.write_keyword("TRYCAST");
23507 self.write("(");
23508 self.generate_expression(&cast.this)?;
23509 self.write_space();
23510 self.write_keyword("AS");
23511 self.write_space();
23512 self.generate_data_type(&cast.to)?;
23513 self.write(")");
23514 return Ok(());
23515 }
23516
23517 let keyword = if matches!(
23519 self.config.dialect,
23520 Some(DialectType::Hive)
23521 | Some(DialectType::MySQL)
23522 | Some(DialectType::SQLite)
23523 | Some(DialectType::Oracle)
23524 | Some(DialectType::ClickHouse)
23525 | Some(DialectType::Redshift)
23526 | Some(DialectType::PostgreSQL)
23527 | Some(DialectType::StarRocks)
23528 | Some(DialectType::Doris)
23529 ) {
23530 "CAST"
23531 } else {
23532 "TRY_CAST"
23533 };
23534
23535 self.write_keyword(keyword);
23536 self.write("(");
23537 self.generate_expression(&cast.this)?;
23538 self.write_space();
23539 self.write_keyword("AS");
23540 self.write_space();
23541 self.generate_data_type(&cast.to)?;
23542
23543 if let Some(format) = &cast.format {
23545 self.write_space();
23546 self.write_keyword("FORMAT");
23547 self.write_space();
23548 self.generate_expression(format)?;
23549 }
23550
23551 self.write(")");
23552 Ok(())
23553 }
23554
23555 fn generate_safe_cast(&mut self, cast: &Cast) -> Result<()> {
23556 self.write_keyword("SAFE_CAST");
23557 self.write("(");
23558 self.generate_expression(&cast.this)?;
23559 self.write_space();
23560 self.write_keyword("AS");
23561 self.write_space();
23562 self.generate_data_type(&cast.to)?;
23563
23564 if let Some(format) = &cast.format {
23566 self.write_space();
23567 self.write_keyword("FORMAT");
23568 self.write_space();
23569 self.generate_expression(format)?;
23570 }
23571
23572 self.write(")");
23573 Ok(())
23574 }
23575
23576 fn generate_subscript(&mut self, s: &Subscript) -> Result<()> {
23579 let needs_parens = matches!(&s.this, Expression::JsonExtract(ref f) if f.arrow_syntax);
23583 if needs_parens {
23584 self.write("(");
23585 }
23586 self.generate_expression(&s.this)?;
23587 if needs_parens {
23588 self.write(")");
23589 }
23590 self.write("[");
23591 self.generate_expression(&s.index)?;
23592 self.write("]");
23593 Ok(())
23594 }
23595
23596 fn generate_dot_access(&mut self, d: &DotAccess) -> Result<()> {
23597 self.generate_expression(&d.this)?;
23598 let use_colon = matches!(self.config.dialect, Some(DialectType::Snowflake))
23601 && matches!(
23602 &d.this,
23603 Expression::Cast(_) | Expression::SafeCast(_) | Expression::TryCast(_)
23604 );
23605 if use_colon {
23606 self.write(":");
23607 } else {
23608 self.write(".");
23609 }
23610 self.generate_identifier(&d.field)
23611 }
23612
23613 fn generate_method_call(&mut self, m: &MethodCall) -> Result<()> {
23614 self.generate_expression(&m.this)?;
23615 self.write(".");
23616 if m.method.quoted {
23619 let q = self.config.identifier_quote;
23620 self.write(&format!("{}{}{}", q, m.method.name, q));
23621 } else {
23622 self.write(&m.method.name);
23623 }
23624 self.write("(");
23625 for (i, arg) in m.args.iter().enumerate() {
23626 if i > 0 {
23627 self.write(", ");
23628 }
23629 self.generate_expression(arg)?;
23630 }
23631 self.write(")");
23632 Ok(())
23633 }
23634
23635 fn generate_array_slice(&mut self, s: &ArraySlice) -> Result<()> {
23636 let needs_parens = matches!(
23639 &s.this,
23640 Expression::JsonExtract(f) if f.arrow_syntax
23641 ) || matches!(
23642 &s.this,
23643 Expression::JsonExtractScalar(f) if f.arrow_syntax
23644 );
23645
23646 if needs_parens {
23647 self.write("(");
23648 }
23649 self.generate_expression(&s.this)?;
23650 if needs_parens {
23651 self.write(")");
23652 }
23653 self.write("[");
23654 if let Some(start) = &s.start {
23655 self.generate_expression(start)?;
23656 }
23657 self.write(":");
23658 if let Some(end) = &s.end {
23659 self.generate_expression(end)?;
23660 }
23661 self.write("]");
23662 Ok(())
23663 }
23664
23665 fn generate_binary_op(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
23666 match &op.left {
23670 Expression::Column(col) => {
23671 if let Some(table) = &col.table {
23674 self.generate_identifier(table)?;
23675 self.write(".");
23676 }
23677 self.generate_identifier(&col.name)?;
23678 if col.join_mark && self.config.supports_column_join_marks {
23680 self.write(" (+)");
23681 }
23682 if op.left_comments.is_empty() {
23684 for comment in &col.trailing_comments {
23685 self.write_space();
23686 self.write_formatted_comment(comment);
23687 }
23688 }
23689 }
23690 Expression::Add(inner_op)
23691 | Expression::Sub(inner_op)
23692 | Expression::Mul(inner_op)
23693 | Expression::Div(inner_op)
23694 | Expression::Concat(inner_op) => {
23695 self.generate_binary_op_no_trailing(inner_op, match &op.left {
23697 Expression::Add(_) => "+",
23698 Expression::Sub(_) => "-",
23699 Expression::Mul(_) => "*",
23700 Expression::Div(_) => "/",
23701 Expression::Concat(_) => "||",
23702 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
23703 })?;
23704 }
23705 _ => {
23706 self.generate_expression(&op.left)?;
23707 }
23708 }
23709 for comment in &op.left_comments {
23711 self.write_space();
23712 self.write_formatted_comment(comment);
23713 }
23714 if self.config.pretty
23715 && matches!(self.config.dialect, Some(DialectType::Snowflake))
23716 && (operator == "AND" || operator == "OR")
23717 {
23718 self.write_newline();
23719 self.write_indent();
23720 self.write_keyword(operator);
23721 } else {
23722 self.write_space();
23723 if operator.chars().all(|c| c.is_alphabetic()) {
23724 self.write_keyword(operator);
23725 } else {
23726 self.write(operator);
23727 }
23728 }
23729 for comment in &op.operator_comments {
23731 self.write_space();
23732 self.write_formatted_comment(comment);
23733 }
23734 self.write_space();
23735 self.generate_expression(&op.right)?;
23736 for comment in &op.trailing_comments {
23738 self.write_space();
23739 self.write_formatted_comment(comment);
23740 }
23741 Ok(())
23742 }
23743
23744 fn generate_connector_op(&mut self, op: &BinaryOp, connector: ConnectorOperator) -> Result<()> {
23745 let keyword = connector.keyword();
23746 let Some(terms) = self.flatten_connector_terms(op, connector) else {
23747 return self.generate_binary_op(op, keyword);
23748 };
23749
23750 let wrap_clickhouse_or_term = |generator: &mut Self, term: &Expression| -> Result<()> {
23751 let should_wrap = matches!(connector, ConnectorOperator::Or)
23752 && matches!(generator.config.dialect, Some(DialectType::ClickHouse))
23753 && matches!(
23754 generator.config.source_dialect,
23755 Some(DialectType::ClickHouse)
23756 )
23757 && matches!(term, Expression::And(_));
23758 if should_wrap {
23759 generator.write("(");
23760 generator.generate_expression(term)?;
23761 generator.write(")");
23762 } else {
23763 generator.generate_expression(term)?;
23764 }
23765 Ok(())
23766 };
23767
23768 wrap_clickhouse_or_term(self, terms[0])?;
23769 for term in terms.iter().skip(1) {
23770 if self.config.pretty && matches!(self.config.dialect, Some(DialectType::Snowflake)) {
23771 self.write_newline();
23772 self.write_indent();
23773 self.write_keyword(keyword);
23774 } else {
23775 self.write_space();
23776 self.write_keyword(keyword);
23777 }
23778 self.write_space();
23779 wrap_clickhouse_or_term(self, term)?;
23780 }
23781
23782 Ok(())
23783 }
23784
23785 fn flatten_connector_terms<'a>(
23786 &self,
23787 root: &'a BinaryOp,
23788 connector: ConnectorOperator,
23789 ) -> Option<Vec<&'a Expression>> {
23790 if !root.left_comments.is_empty()
23791 || !root.operator_comments.is_empty()
23792 || !root.trailing_comments.is_empty()
23793 {
23794 return None;
23795 }
23796
23797 let mut terms = Vec::new();
23798 let mut stack: Vec<&Expression> = vec![&root.right, &root.left];
23799
23800 while let Some(expr) = stack.pop() {
23801 match (connector, expr) {
23802 (ConnectorOperator::And, Expression::And(inner))
23803 if inner.left_comments.is_empty()
23804 && inner.operator_comments.is_empty()
23805 && inner.trailing_comments.is_empty() =>
23806 {
23807 stack.push(&inner.right);
23808 stack.push(&inner.left);
23809 }
23810 (ConnectorOperator::Or, Expression::Or(inner))
23811 if inner.left_comments.is_empty()
23812 && inner.operator_comments.is_empty()
23813 && inner.trailing_comments.is_empty() =>
23814 {
23815 stack.push(&inner.right);
23816 stack.push(&inner.left);
23817 }
23818 _ => terms.push(expr),
23819 }
23820 }
23821
23822 if terms.len() > 1 {
23823 Some(terms)
23824 } else {
23825 None
23826 }
23827 }
23828
23829 fn missing_closing_parens_outside_quotes(sql: &str) -> usize {
23830 let mut depth = 0usize;
23831 let mut quote: Option<char> = None;
23832 let mut chars = sql.chars().peekable();
23833
23834 while let Some(ch) = chars.next() {
23835 if let Some(quote_char) = quote {
23836 if ch == '\\' {
23837 chars.next();
23838 } else if ch == quote_char {
23839 if quote_char == '\'' && chars.peek() == Some(&'\'') {
23840 chars.next();
23841 } else {
23842 quote = None;
23843 }
23844 }
23845 continue;
23846 }
23847
23848 match ch {
23849 '\'' | '"' | '`' => quote = Some(ch),
23850 '(' => depth += 1,
23851 ')' => depth = depth.saturating_sub(1),
23852 _ => {}
23853 }
23854 }
23855
23856 depth
23857 }
23858
23859 fn generate_like_op(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
23861 self.generate_like_op_inner(op, operator, false)
23862 }
23863
23864 fn generate_like_op_negated(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
23865 self.generate_like_op_inner(op, operator, true)
23866 }
23867
23868 fn generate_like_op_inner(&mut self, op: &LikeOp, operator: &str, negated: bool) -> Result<()> {
23869 if negated
23870 && matches!(
23871 self.config.dialect,
23872 Some(DialectType::ClickHouse)
23873 | Some(DialectType::DataFusion)
23874 | Some(DialectType::TSQL)
23875 | Some(DialectType::Fabric)
23876 )
23877 {
23878 self.write_keyword("NOT");
23879 self.write_space();
23880 return self.generate_like_op_inner(op, operator, false);
23881 }
23882
23883 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23884 if let Expression::Star(star) = &op.left {
23885 if star
23886 .except
23887 .as_ref()
23888 .is_some_and(|except| !except.is_empty())
23889 {
23890 if let Some(table) = &star.table {
23891 self.generate_identifier(table)?;
23892 self.write(".");
23893 }
23894 self.write("*");
23895 self.write_space();
23896 self.write_keyword(operator);
23897 if let Some(quantifier) = &op.quantifier {
23898 self.write_space();
23899 self.write_keyword(quantifier);
23900 self.write_space();
23901 } else {
23902 self.write_space();
23903 }
23904 self.generate_expression(&op.right)?;
23905 if let Some(escape) = &op.escape {
23906 self.write_space();
23907 self.write_keyword("ESCAPE");
23908 self.write_space();
23909 self.generate_expression(escape)?;
23910 }
23911 if let Some(except) = &star.except {
23912 self.write_space();
23913 self.write_keyword("EXCEPT");
23914 self.write(" (");
23915 for (i, col) in except.iter().enumerate() {
23916 if i > 0 {
23917 self.write(", ");
23918 }
23919 self.generate_identifier(col)?;
23920 }
23921 self.write(")");
23922 }
23923 return Ok(());
23924 }
23925 }
23926 }
23927
23928 self.generate_expression(&op.left)?;
23929 self.write_space();
23930 if negated {
23931 self.write_keyword("NOT");
23932 self.write_space();
23933 }
23934 if operator == "ILIKE" && matches!(self.config.dialect, Some(DialectType::Drill)) {
23936 self.write("`ILIKE`");
23937 } else {
23938 self.write_keyword(operator);
23939 }
23940 if let Some(quantifier) = &op.quantifier {
23941 self.write_space();
23942 self.write_keyword(quantifier);
23943 let is_any =
23948 quantifier.eq_ignore_ascii_case("ANY") || quantifier.eq_ignore_ascii_case("SOME");
23949 if !(is_any && matches!(&op.right, Expression::Paren(_))) {
23950 self.write_space();
23951 }
23952 } else {
23953 self.write_space();
23954 }
23955 self.generate_expression(&op.right)?;
23956 if let Some(escape) = &op.escape {
23957 self.write_space();
23958 self.write_keyword("ESCAPE");
23959 self.write_space();
23960 self.generate_expression(escape)?;
23961 }
23962 Ok(())
23963 }
23964
23965 fn generate_null_safe_eq(&mut self, op: &BinaryOp) -> Result<()> {
23968 use crate::dialects::DialectType;
23969 self.generate_expression(&op.left)?;
23970 self.write_space();
23971 if matches!(self.config.dialect, Some(DialectType::MySQL)) {
23972 self.write("<=>");
23973 } else {
23974 self.write_keyword("IS NOT DISTINCT FROM");
23975 }
23976 self.write_space();
23977 self.generate_expression(&op.right)?;
23978 Ok(())
23979 }
23980
23981 fn generate_null_safe_neq(&mut self, op: &BinaryOp) -> Result<()> {
23983 self.generate_expression(&op.left)?;
23984 self.write_space();
23985 self.write_keyword("IS DISTINCT FROM");
23986 self.write_space();
23987 self.generate_expression(&op.right)?;
23988 Ok(())
23989 }
23990
23991 fn generate_binary_op_no_trailing(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
23993 match &op.left {
23995 Expression::Column(col) => {
23996 if let Some(table) = &col.table {
23997 self.generate_identifier(table)?;
23998 self.write(".");
23999 }
24000 self.generate_identifier(&col.name)?;
24001 if col.join_mark && self.config.supports_column_join_marks {
24003 self.write(" (+)");
24004 }
24005 }
24006 Expression::Add(inner_op)
24007 | Expression::Sub(inner_op)
24008 | Expression::Mul(inner_op)
24009 | Expression::Div(inner_op)
24010 | Expression::Concat(inner_op) => {
24011 self.generate_binary_op_no_trailing(inner_op, match &op.left {
24012 Expression::Add(_) => "+",
24013 Expression::Sub(_) => "-",
24014 Expression::Mul(_) => "*",
24015 Expression::Div(_) => "/",
24016 Expression::Concat(_) => "||",
24017 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
24018 })?;
24019 }
24020 _ => {
24021 self.generate_expression(&op.left)?;
24022 }
24023 }
24024 for comment in &op.left_comments {
24026 self.write_space();
24027 self.write_formatted_comment(comment);
24028 }
24029 self.write_space();
24030 if operator.chars().all(|c| c.is_alphabetic()) {
24031 self.write_keyword(operator);
24032 } else {
24033 self.write(operator);
24034 }
24035 for comment in &op.operator_comments {
24037 self.write_space();
24038 self.write_formatted_comment(comment);
24039 }
24040 self.write_space();
24041 match &op.right {
24044 Expression::Column(col) => {
24045 if let Some(table) = &col.table {
24046 self.generate_identifier(table)?;
24047 self.write(".");
24048 }
24049 self.generate_identifier(&col.name)?;
24050 if col.join_mark && self.config.supports_column_join_marks {
24052 self.write(" (+)");
24053 }
24054 }
24055 _ => {
24056 self.generate_expression(&op.right)?;
24057 }
24058 }
24059 Ok(())
24061 }
24062
24063 fn generate_unary_op(&mut self, op: &UnaryOp, operator: &str) -> Result<()> {
24064 if operator.chars().all(|c| c.is_alphabetic()) {
24065 self.write_keyword(operator);
24066 self.write_space();
24067 } else {
24068 self.write(operator);
24069 if matches!(&op.this, Expression::Neg(_) | Expression::BitwiseNot(_)) {
24071 self.write_space();
24072 }
24073 }
24074 self.generate_expression(&op.this)
24075 }
24076
24077 fn generate_in(&mut self, in_expr: &In) -> Result<()> {
24078 let is_generic =
24082 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
24083 let use_prefix_not =
24084 in_expr.not && is_generic && self.config.not_in_style == NotInStyle::Prefix;
24085 if use_prefix_not {
24086 self.write_keyword("NOT");
24087 self.write_space();
24088 }
24089 self.generate_expression(&in_expr.this)?;
24090 if in_expr.global {
24091 self.write_space();
24092 self.write_keyword("GLOBAL");
24093 }
24094 if in_expr.not && !use_prefix_not {
24095 self.write_space();
24096 self.write_keyword("NOT");
24097 }
24098 self.write_space();
24099 self.write_keyword("IN");
24100
24101 if let Some(unnest_expr) = &in_expr.unnest {
24103 self.write_space();
24104 self.write_keyword("UNNEST");
24105 self.write("(");
24106 self.generate_expression(unnest_expr)?;
24107 self.write(")");
24108 return Ok(());
24109 }
24110
24111 if let Some(query) = &in_expr.query {
24112 let is_bare = in_expr.expressions.is_empty()
24115 && !matches!(
24116 query,
24117 Expression::Select(_)
24118 | Expression::Union(_)
24119 | Expression::Intersect(_)
24120 | Expression::Except(_)
24121 | Expression::Subquery(_)
24122 );
24123 if is_bare {
24124 self.write_space();
24126 self.generate_expression(query)?;
24127 } else {
24128 self.write(" (");
24130 let is_statement = matches!(
24131 query,
24132 Expression::Select(_)
24133 | Expression::Union(_)
24134 | Expression::Intersect(_)
24135 | Expression::Except(_)
24136 | Expression::Subquery(_)
24137 );
24138 if self.config.pretty && is_statement {
24139 self.write_newline();
24140 self.indent_level += 1;
24141 self.write_indent();
24142 }
24143 self.generate_expression(query)?;
24144 if self.config.pretty && is_statement {
24145 self.write_newline();
24146 self.indent_level -= 1;
24147 self.write_indent();
24148 }
24149 self.write(")");
24150 }
24151 } else {
24152 let is_duckdb = matches!(
24156 self.config.dialect,
24157 Some(crate::dialects::DialectType::DuckDB)
24158 );
24159 let is_clickhouse = matches!(
24160 self.config.dialect,
24161 Some(crate::dialects::DialectType::ClickHouse)
24162 );
24163 let single_expr = in_expr.expressions.len() == 1;
24164 if is_clickhouse && single_expr {
24165 if let Expression::Array(arr) = &in_expr.expressions[0] {
24166 self.write(" (");
24168 for (i, expr) in arr.expressions.iter().enumerate() {
24169 if i > 0 {
24170 self.write(", ");
24171 }
24172 self.generate_expression(expr)?;
24173 }
24174 self.write(")");
24175 } else if in_expr.is_field {
24176 self.write_space();
24177 self.generate_expression(&in_expr.expressions[0])?;
24178 } else {
24179 self.write(" (");
24180 self.generate_expression(&in_expr.expressions[0])?;
24181 self.write(")");
24182 }
24183 } else {
24184 let is_bare_ref = single_expr
24185 && matches!(
24186 &in_expr.expressions[0],
24187 Expression::Column(_) | Expression::Identifier(_) | Expression::Dot(_)
24188 );
24189 if (is_duckdb && is_bare_ref) || (in_expr.is_field && single_expr) {
24190 self.write_space();
24193 self.generate_expression(&in_expr.expressions[0])?;
24194 } else {
24195 self.write(" (");
24197 for (i, expr) in in_expr.expressions.iter().enumerate() {
24198 if i > 0 {
24199 self.write(", ");
24200 }
24201 self.generate_expression(expr)?;
24202 }
24203 self.write(")");
24204 }
24205 }
24206 }
24207
24208 Ok(())
24209 }
24210
24211 fn generate_between(&mut self, between: &Between) -> Result<()> {
24212 let use_prefix_not = between.not
24214 && (self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic));
24215 if use_prefix_not {
24216 self.write_keyword("NOT");
24217 self.write_space();
24218 }
24219 self.generate_expression(&between.this)?;
24220 if between.not && !use_prefix_not {
24221 self.write_space();
24222 self.write_keyword("NOT");
24223 }
24224 self.write_space();
24225 self.write_keyword("BETWEEN");
24226 if let Some(sym) = between.symmetric {
24228 if sym {
24229 self.write(" SYMMETRIC");
24230 } else {
24231 self.write(" ASYMMETRIC");
24232 }
24233 }
24234 self.write_space();
24235 self.generate_expression(&between.low)?;
24236 self.write_space();
24237 self.write_keyword("AND");
24238 self.write_space();
24239 self.generate_expression(&between.high)
24240 }
24241
24242 fn generate_is_null(&mut self, is_null: &IsNull) -> Result<()> {
24243 let use_prefix_not = is_null.not
24245 && (self.config.dialect.is_none()
24246 || self.config.dialect == Some(DialectType::Generic)
24247 || is_null.postfix_form);
24248 if use_prefix_not {
24249 self.write_keyword("NOT");
24251 self.write_space();
24252 self.generate_expression(&is_null.this)?;
24253 self.write_space();
24254 self.write_keyword("IS");
24255 self.write_space();
24256 self.write_keyword("NULL");
24257 } else {
24258 self.generate_expression(&is_null.this)?;
24259 self.write_space();
24260 self.write_keyword("IS");
24261 if is_null.not {
24262 self.write_space();
24263 self.write_keyword("NOT");
24264 }
24265 self.write_space();
24266 self.write_keyword("NULL");
24267 }
24268 Ok(())
24269 }
24270
24271 fn generate_is_true(&mut self, is_true: &IsTrueFalse) -> Result<()> {
24272 self.generate_expression(&is_true.this)?;
24273 self.write_space();
24274 self.write_keyword("IS");
24275 if is_true.not {
24276 self.write_space();
24277 self.write_keyword("NOT");
24278 }
24279 self.write_space();
24280 self.write_keyword("TRUE");
24281 Ok(())
24282 }
24283
24284 fn generate_is_false(&mut self, is_false: &IsTrueFalse) -> Result<()> {
24285 self.generate_expression(&is_false.this)?;
24286 self.write_space();
24287 self.write_keyword("IS");
24288 if is_false.not {
24289 self.write_space();
24290 self.write_keyword("NOT");
24291 }
24292 self.write_space();
24293 self.write_keyword("FALSE");
24294 Ok(())
24295 }
24296
24297 fn generate_is_json(&mut self, is_json: &IsJson) -> Result<()> {
24298 self.generate_expression(&is_json.this)?;
24299 self.write_space();
24300 self.write_keyword("IS");
24301 if is_json.negated {
24302 self.write_space();
24303 self.write_keyword("NOT");
24304 }
24305 self.write_space();
24306 self.write_keyword("JSON");
24307
24308 if let Some(ref json_type) = is_json.json_type {
24310 self.write_space();
24311 self.write_keyword(json_type);
24312 }
24313
24314 match &is_json.unique_keys {
24316 Some(JsonUniqueKeys::With) => {
24317 self.write_space();
24318 self.write_keyword("WITH UNIQUE KEYS");
24319 }
24320 Some(JsonUniqueKeys::Without) => {
24321 self.write_space();
24322 self.write_keyword("WITHOUT UNIQUE KEYS");
24323 }
24324 Some(JsonUniqueKeys::Shorthand) => {
24325 self.write_space();
24326 self.write_keyword("UNIQUE KEYS");
24327 }
24328 None => {}
24329 }
24330
24331 Ok(())
24332 }
24333
24334 fn generate_is(&mut self, is_expr: &BinaryOp) -> Result<()> {
24335 self.generate_expression(&is_expr.left)?;
24336 self.write_space();
24337 self.write_keyword("IS");
24338 self.write_space();
24339 self.generate_expression(&is_expr.right)
24340 }
24341
24342 fn generate_exists(&mut self, exists: &Exists) -> Result<()> {
24343 if exists.not {
24344 self.write_keyword("NOT");
24345 self.write_space();
24346 }
24347 self.write_keyword("EXISTS");
24348 self.write("(");
24349 let is_statement = matches!(
24350 &exists.this,
24351 Expression::Select(_)
24352 | Expression::Union(_)
24353 | Expression::Intersect(_)
24354 | Expression::Except(_)
24355 );
24356 if self.config.pretty && is_statement {
24357 self.write_newline();
24358 self.indent_level += 1;
24359 self.write_indent();
24360 self.generate_expression(&exists.this)?;
24361 self.write_newline();
24362 self.indent_level -= 1;
24363 self.write_indent();
24364 self.write(")");
24365 } else {
24366 self.generate_expression(&exists.this)?;
24367 self.write(")");
24368 }
24369 Ok(())
24370 }
24371
24372 fn generate_member_of(&mut self, op: &BinaryOp) -> Result<()> {
24373 self.generate_expression(&op.left)?;
24374 self.write_space();
24375 self.write_keyword("MEMBER OF");
24376 self.write("(");
24377 self.generate_expression(&op.right)?;
24378 self.write(")");
24379 Ok(())
24380 }
24381
24382 fn generate_subquery(&mut self, subquery: &Subquery) -> Result<()> {
24383 if subquery.lateral {
24384 self.write_keyword("LATERAL");
24385 self.write_space();
24386 }
24387
24388 let skip_outer_parens = if let Expression::Paren(ref p) = &subquery.this {
24392 matches!(
24393 &p.this,
24394 Expression::Select(_)
24395 | Expression::Union(_)
24396 | Expression::Intersect(_)
24397 | Expression::Except(_)
24398 | Expression::Subquery(_)
24399 )
24400 } else {
24401 false
24402 };
24403
24404 let is_statement = matches!(
24406 &subquery.this,
24407 Expression::Select(_)
24408 | Expression::Union(_)
24409 | Expression::Intersect(_)
24410 | Expression::Except(_)
24411 | Expression::Merge(_)
24412 );
24413
24414 if !skip_outer_parens {
24415 self.write("(");
24416 if self.config.pretty && is_statement {
24417 self.write_newline();
24418 self.indent_level += 1;
24419 self.write_indent();
24420 }
24421 }
24422 self.generate_expression(&subquery.this)?;
24423
24424 if subquery.modifiers_inside {
24426 if let Some(order_by) = &subquery.order_by {
24428 self.write_space();
24429 self.write_keyword("ORDER BY");
24430 self.write_space();
24431 for (i, ord) in order_by.expressions.iter().enumerate() {
24432 if i > 0 {
24433 self.write(", ");
24434 }
24435 self.generate_ordered(ord)?;
24436 }
24437 }
24438
24439 if let Some(limit) = &subquery.limit {
24440 self.write_space();
24441 self.write_keyword("LIMIT");
24442 self.write_space();
24443 self.generate_expression(&limit.this)?;
24444 if limit.percent {
24445 self.write_space();
24446 self.write_keyword("PERCENT");
24447 }
24448 }
24449
24450 if let Some(offset) = &subquery.offset {
24451 self.write_space();
24452 self.write_keyword("OFFSET");
24453 self.write_space();
24454 self.generate_expression(&offset.this)?;
24455 }
24456 }
24457
24458 if !skip_outer_parens {
24459 if self.config.pretty && is_statement {
24460 self.write_newline();
24461 self.indent_level -= 1;
24462 self.write_indent();
24463 }
24464 self.write(")");
24465 }
24466
24467 if !subquery.modifiers_inside {
24469 if let Some(order_by) = &subquery.order_by {
24470 self.write_space();
24471 self.write_keyword("ORDER BY");
24472 self.write_space();
24473 for (i, ord) in order_by.expressions.iter().enumerate() {
24474 if i > 0 {
24475 self.write(", ");
24476 }
24477 self.generate_ordered(ord)?;
24478 }
24479 }
24480
24481 if let Some(limit) = &subquery.limit {
24482 self.write_space();
24483 self.write_keyword("LIMIT");
24484 self.write_space();
24485 self.generate_expression(&limit.this)?;
24486 if limit.percent {
24487 self.write_space();
24488 self.write_keyword("PERCENT");
24489 }
24490 }
24491
24492 if let Some(offset) = &subquery.offset {
24493 self.write_space();
24494 self.write_keyword("OFFSET");
24495 self.write_space();
24496 self.generate_expression(&offset.this)?;
24497 }
24498
24499 if let Some(distribute_by) = &subquery.distribute_by {
24501 self.write_space();
24502 self.write_keyword("DISTRIBUTE BY");
24503 self.write_space();
24504 for (i, expr) in distribute_by.expressions.iter().enumerate() {
24505 if i > 0 {
24506 self.write(", ");
24507 }
24508 self.generate_expression(expr)?;
24509 }
24510 }
24511
24512 if let Some(sort_by) = &subquery.sort_by {
24514 self.write_space();
24515 self.write_keyword("SORT BY");
24516 self.write_space();
24517 for (i, ord) in sort_by.expressions.iter().enumerate() {
24518 if i > 0 {
24519 self.write(", ");
24520 }
24521 self.generate_ordered(ord)?;
24522 }
24523 }
24524
24525 if let Some(cluster_by) = &subquery.cluster_by {
24527 self.write_space();
24528 self.write_keyword("CLUSTER BY");
24529 self.write_space();
24530 for (i, ord) in cluster_by.expressions.iter().enumerate() {
24531 if i > 0 {
24532 self.write(", ");
24533 }
24534 self.generate_ordered(ord)?;
24535 }
24536 }
24537 }
24538
24539 if let Some(alias) = &subquery.alias {
24540 self.write_space();
24541 let skip_as = matches!(self.config.dialect, Some(DialectType::Oracle))
24542 || (matches!(self.config.dialect, Some(DialectType::ClickHouse))
24543 && !subquery.alias_explicit_as);
24544 if !skip_as {
24545 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
24546 self.write(subquery.alias_keyword.as_deref().unwrap_or("AS"));
24547 } else {
24548 self.write_keyword("AS");
24549 }
24550 self.write_space();
24551 }
24552 self.generate_identifier(alias)?;
24553 if !subquery.column_aliases.is_empty() {
24554 self.write("(");
24555 for (i, col) in subquery.column_aliases.iter().enumerate() {
24556 if i > 0 {
24557 self.write(", ");
24558 }
24559 self.generate_identifier(col)?;
24560 }
24561 self.write(")");
24562 }
24563 }
24564 for comment in &subquery.trailing_comments {
24566 self.write(" ");
24567 self.write_formatted_comment(comment);
24568 }
24569 Ok(())
24570 }
24571
24572 fn generate_pivot(&mut self, pivot: &Pivot) -> Result<()> {
24573 if let Some(ref with) = pivot.with {
24575 self.generate_with(with)?;
24576 self.write_space();
24577 }
24578
24579 let direction = if pivot.unpivot { "UNPIVOT" } else { "PIVOT" };
24580
24581 let is_redshift_unpivot = pivot.unpivot
24585 && pivot.expressions.is_empty()
24586 && pivot.fields.is_empty()
24587 && pivot.using.is_empty()
24588 && pivot.into.is_none()
24589 && !matches!(&pivot.this, Expression::Null(_));
24590
24591 if is_redshift_unpivot {
24592 self.write_keyword("UNPIVOT");
24594 self.write_space();
24595 self.generate_expression(&pivot.this)?;
24596 if let Some(alias) = &pivot.alias {
24598 self.write_space();
24599 self.write_keyword("AS");
24600 self.write_space();
24601 self.write(&alias.name);
24603 }
24604 return Ok(());
24605 }
24606
24607 let is_simplified = !pivot.using.is_empty()
24609 || pivot.into.is_some()
24610 || (pivot.fields.is_empty()
24611 && !pivot.expressions.is_empty()
24612 && !matches!(&pivot.this, Expression::Null(_)));
24613
24614 if is_simplified {
24615 self.write_keyword(direction);
24619 self.write_space();
24620 self.generate_expression(&pivot.this)?;
24621
24622 if !pivot.expressions.is_empty() {
24623 self.write_space();
24624 self.write_keyword("ON");
24625 self.write_space();
24626 for (i, expr) in pivot.expressions.iter().enumerate() {
24627 if i > 0 {
24628 self.write(", ");
24629 }
24630 self.generate_expression(expr)?;
24631 }
24632 }
24633
24634 if let Some(into) = &pivot.into {
24636 self.write_space();
24637 self.write_keyword("INTO");
24638 self.write_space();
24639 self.generate_expression(into)?;
24640 }
24641
24642 if !pivot.using.is_empty() {
24644 self.write_space();
24645 self.write_keyword("USING");
24646 self.write_space();
24647 for (i, expr) in pivot.using.iter().enumerate() {
24648 if i > 0 {
24649 self.write(", ");
24650 }
24651 self.generate_expression(expr)?;
24652 }
24653 }
24654
24655 if let Some(group) = &pivot.group {
24657 self.write_space();
24658 self.generate_expression(group)?;
24659 }
24660 } else {
24661 if !matches!(&pivot.this, Expression::Null(_)) {
24666 self.generate_expression(&pivot.this)?;
24667 self.write_space();
24668 }
24669 self.write_keyword(direction);
24670 self.write("(");
24671
24672 for (i, expr) in pivot.expressions.iter().enumerate() {
24674 if i > 0 {
24675 self.write(", ");
24676 }
24677 self.generate_expression(expr)?;
24678 }
24679
24680 if !pivot.fields.is_empty() {
24682 if !pivot.expressions.is_empty() {
24683 self.write_space();
24684 }
24685 self.write_keyword("FOR");
24686 self.write_space();
24687 for (i, field) in pivot.fields.iter().enumerate() {
24688 if i > 0 {
24689 self.write_space();
24690 }
24691 self.generate_expression(field)?;
24693 }
24694 }
24695
24696 if let Some(default_val) = &pivot.default_on_null {
24698 self.write_space();
24699 self.write_keyword("DEFAULT ON NULL");
24700 self.write(" (");
24701 self.generate_expression(default_val)?;
24702 self.write(")");
24703 }
24704
24705 if let Some(group) = &pivot.group {
24707 self.write_space();
24708 self.generate_expression(group)?;
24709 }
24710
24711 self.write(")");
24712 }
24713
24714 if let Some(alias) = &pivot.alias {
24716 self.write_space();
24717 self.write_keyword("AS");
24718 self.write_space();
24719 self.generate_identifier(alias)?;
24720 self.generate_alias_column_list(&pivot.alias_columns)?;
24721 }
24722
24723 Ok(())
24724 }
24725
24726 fn generate_unpivot(&mut self, unpivot: &Unpivot) -> Result<()> {
24727 self.generate_expression(&unpivot.this)?;
24728 self.write_space();
24729 self.write_keyword("UNPIVOT");
24730 if let Some(include) = unpivot.include_nulls {
24732 self.write_space();
24733 if include {
24734 self.write_keyword("INCLUDE NULLS");
24735 } else {
24736 self.write_keyword("EXCLUDE NULLS");
24737 }
24738 self.write_space();
24739 }
24740 self.write("(");
24741 if unpivot.value_column_parenthesized {
24742 self.write("(");
24743 }
24744 self.generate_identifier(&unpivot.value_column)?;
24745 for extra_col in &unpivot.extra_value_columns {
24747 self.write(", ");
24748 self.generate_identifier(extra_col)?;
24749 }
24750 if unpivot.value_column_parenthesized {
24751 self.write(")");
24752 }
24753 self.write_space();
24754 self.write_keyword("FOR");
24755 self.write_space();
24756 self.generate_identifier(&unpivot.name_column)?;
24757 self.write_space();
24758 self.write_keyword("IN");
24759 self.write(" (");
24760 for (i, col) in unpivot.columns.iter().enumerate() {
24761 if i > 0 {
24762 self.write(", ");
24763 }
24764 self.generate_expression(col)?;
24765 }
24766 self.write("))");
24767 if let Some(alias) = &unpivot.alias {
24768 self.write_space();
24769 self.write_keyword("AS");
24770 self.write_space();
24771 self.generate_identifier(alias)?;
24772 self.generate_alias_column_list(&unpivot.alias_columns)?;
24773 }
24774 Ok(())
24775 }
24776
24777 fn generate_alias_column_list(&mut self, columns: &[Identifier]) -> Result<()> {
24778 if columns.is_empty() {
24779 return Ok(());
24780 }
24781
24782 self.write("(");
24783 for (i, column) in columns.iter().enumerate() {
24784 if i > 0 {
24785 self.write(", ");
24786 }
24787 self.generate_identifier(column)?;
24788 }
24789 self.write(")");
24790 Ok(())
24791 }
24792
24793 fn generate_values(&mut self, values: &Values) -> Result<()> {
24794 self.write_keyword("VALUES");
24795 for (i, row) in values.expressions.iter().enumerate() {
24796 if i > 0 {
24797 self.write(",");
24798 }
24799 self.write(" (");
24800 for (j, expr) in row.expressions.iter().enumerate() {
24801 if j > 0 {
24802 self.write(", ");
24803 }
24804 self.generate_expression(expr)?;
24805 }
24806 self.write(")");
24807 }
24808 if let Some(alias) = &values.alias {
24809 self.write_space();
24810 self.write_keyword("AS");
24811 self.write_space();
24812 self.generate_identifier(alias)?;
24813 if !values.column_aliases.is_empty() {
24814 self.write("(");
24815 for (i, col) in values.column_aliases.iter().enumerate() {
24816 if i > 0 {
24817 self.write(", ");
24818 }
24819 self.generate_identifier(col)?;
24820 }
24821 self.write(")");
24822 }
24823 }
24824 Ok(())
24825 }
24826
24827 fn generate_array(&mut self, arr: &Array) -> Result<()> {
24828 let needs_inheritance = matches!(
24830 self.config.dialect,
24831 Some(DialectType::DuckDB)
24832 | Some(DialectType::Spark)
24833 | Some(DialectType::Databricks)
24834 | Some(DialectType::Hive)
24835 | Some(DialectType::Snowflake)
24836 | Some(DialectType::Presto)
24837 | Some(DialectType::Trino)
24838 );
24839 let propagated: Vec<Expression>;
24840 let expressions = if needs_inheritance && arr.expressions.len() > 1 {
24841 propagated = Self::inherit_struct_field_names(&arr.expressions);
24842 &propagated
24843 } else {
24844 &arr.expressions
24845 };
24846
24847 let use_parens =
24850 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
24851 if !self.config.array_bracket_only {
24852 self.write_keyword("ARRAY");
24853 }
24854 if use_parens {
24855 self.write("(");
24856 } else {
24857 self.write("[");
24858 }
24859 for (i, expr) in expressions.iter().enumerate() {
24860 if i > 0 {
24861 self.write(", ");
24862 }
24863 self.generate_expression(expr)?;
24864 }
24865 if use_parens {
24866 self.write(")");
24867 } else {
24868 self.write("]");
24869 }
24870 Ok(())
24871 }
24872
24873 fn generate_tuple(&mut self, tuple: &Tuple) -> Result<()> {
24874 if tuple.expressions.len() == 2 {
24877 if let Expression::TableAlias(_) = &tuple.expressions[1] {
24878 self.generate_expression(&tuple.expressions[0])?;
24880 self.write_space();
24881 self.write_keyword("AS");
24882 self.write_space();
24883 self.generate_expression(&tuple.expressions[1])?;
24884 return Ok(());
24885 }
24886 }
24887
24888 let expand_tuple = if self.config.pretty && tuple.expressions.len() > 1 {
24891 let mut expr_strings: Vec<String> = Vec::with_capacity(tuple.expressions.len());
24892 for expr in &tuple.expressions {
24893 expr_strings.push(self.generate_to_string(expr)?);
24894 }
24895 self.too_wide(&expr_strings)
24896 } else {
24897 false
24898 };
24899
24900 if expand_tuple {
24901 self.write("(");
24902 self.write_newline();
24903 self.indent_level += 1;
24904 for (i, expr) in tuple.expressions.iter().enumerate() {
24905 if i > 0 {
24906 self.write(",");
24907 self.write_newline();
24908 }
24909 self.write_indent();
24910 self.generate_expression(expr)?;
24911 }
24912 self.indent_level -= 1;
24913 self.write_newline();
24914 self.write_indent();
24915 self.write(")");
24916 } else {
24917 self.write("(");
24918 for (i, expr) in tuple.expressions.iter().enumerate() {
24919 if i > 0 {
24920 self.write(", ");
24921 }
24922 self.generate_expression(expr)?;
24923 }
24924 self.write(")");
24925 }
24926 Ok(())
24927 }
24928
24929 fn generate_pipe_operator(&mut self, pipe: &PipeOperator) -> Result<()> {
24930 self.generate_expression(&pipe.this)?;
24931 self.write(" |> ");
24932 self.generate_expression(&pipe.expression)?;
24933 Ok(())
24934 }
24935
24936 fn generate_ordered(&mut self, ordered: &Ordered) -> Result<()> {
24937 let unsupported_tsql_null_ordering = ordered.nulls_first.is_some()
24938 && !self.config.null_ordering_supported
24939 && matches!(
24940 self.config.dialect,
24941 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24942 );
24943 let random_ordering = matches!(ordered.this, Expression::Rand(_) | Expression::Random(_));
24944 let emulate_tsql_null_ordering = if let Some(nulls_first) = ordered.nulls_first {
24945 let target_default_nulls_first = !ordered.desc;
24946
24947 unsupported_tsql_null_ordering
24948 && nulls_first != target_default_nulls_first
24949 && !random_ordering
24950 } else {
24951 false
24952 };
24953
24954 if emulate_tsql_null_ordering {
24955 if Self::is_integer_ordering_literal(&ordered.this) {
24956 let nulls_order = if ordered.nulls_first == Some(true) {
24957 "NULLS FIRST"
24958 } else {
24959 "NULLS LAST"
24960 };
24961 self.unsupported(format!(
24962 "'{nulls_order}' translation not supported with positional ordering"
24963 ))?;
24964 } else {
24965 self.write_keyword("CASE WHEN");
24966 self.write_space();
24967 self.generate_expression(&ordered.this)?;
24968 self.write_space();
24969 self.write_keyword("IS NULL THEN 1 ELSE 0 END");
24970 if ordered.nulls_first == Some(true) {
24971 self.write_space();
24972 self.write_keyword("DESC");
24973 }
24974 self.write(", ");
24975 }
24976 }
24977
24978 self.generate_expression(&ordered.this)?;
24979 if ordered.desc {
24980 self.write_space();
24981 self.write_keyword("DESC");
24982 } else if ordered.explicit_asc {
24983 self.write_space();
24984 self.write_keyword("ASC");
24985 }
24986 if let Some(nulls_first) = ordered.nulls_first {
24987 if !unsupported_tsql_null_ordering
24988 && (self.config.null_ordering_supported
24989 || !matches!(self.config.dialect, Some(DialectType::Fabric)))
24990 {
24991 let is_asc = !ordered.desc;
25005 let is_nulls_are_large = matches!(
25006 self.config.dialect,
25007 Some(DialectType::Oracle)
25008 | Some(DialectType::PostgreSQL)
25009 | Some(DialectType::Redshift)
25010 | Some(DialectType::Snowflake)
25011 );
25012 let is_nulls_are_last = matches!(
25013 self.config.dialect,
25014 Some(DialectType::Dremio)
25015 | Some(DialectType::DuckDB)
25016 | Some(DialectType::Presto)
25017 | Some(DialectType::Trino)
25018 | Some(DialectType::Athena)
25019 | Some(DialectType::ClickHouse)
25020 | Some(DialectType::Drill)
25021 | Some(DialectType::Exasol)
25022 );
25023
25024 let is_default_nulls = if is_nulls_are_large {
25026 (is_asc && !nulls_first) || (!is_asc && nulls_first)
25028 } else if is_nulls_are_last {
25029 !nulls_first
25031 } else {
25032 false
25033 };
25034
25035 if !is_default_nulls {
25036 self.write_space();
25037 self.write_keyword("NULLS");
25038 self.write_space();
25039 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
25040 }
25041 }
25042 }
25043 if let Some(ref with_fill) = ordered.with_fill {
25045 self.write_space();
25046 self.generate_with_fill(with_fill)?;
25047 }
25048 Ok(())
25049 }
25050
25051 fn is_integer_ordering_literal(expr: &Expression) -> bool {
25052 matches!(
25053 expr,
25054 Expression::Literal(lit)
25055 if matches!(lit.as_ref(), Literal::Number(n) if n.parse::<u64>().is_ok())
25056 )
25057 }
25058
25059 fn write_clickhouse_type(&mut self, type_str: &str) {
25061 if self.clickhouse_nullable_depth < 0 {
25062 self.write(type_str);
25064 } else {
25065 self.write(&format!("Nullable({})", type_str));
25066 }
25067 }
25068
25069 fn write_type_with_length(&mut self, name: &str, length: Option<u32>) {
25070 self.write_keyword(name);
25071 if let Some(length) = length {
25072 self.write(&format!("({length})"));
25073 }
25074 }
25075
25076 fn write_oracle_number(&mut self, precision: Option<u32>, scale: Option<i32>) -> Result<()> {
25077 use crate::dialects::DialectType;
25078
25079 if matches!(self.config.dialect, Some(DialectType::Oracle) | None) {
25080 self.write_keyword("NUMBER");
25081 if precision.is_some() || scale.is_some() {
25082 self.write("(");
25083 if let Some(precision) = precision {
25084 self.write(&precision.to_string());
25085 } else {
25086 self.write("*");
25087 }
25088 if let Some(scale) = scale {
25089 self.write(&format!(", {scale}"));
25090 }
25091 self.write(")");
25092 }
25093 return Ok(());
25094 }
25095
25096 let target = self.config.dialect;
25097 match (precision, scale) {
25098 (None, None) => match target {
25099 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
25100 self.write_keyword("NUMERIC");
25101 }
25102 Some(DialectType::MySQL)
25103 | Some(DialectType::SingleStore)
25104 | Some(DialectType::TiDB) => {
25105 self.unsupported(
25106 "Oracle NUMBER without precision or scale has no exact MySQL mapping",
25107 )?;
25108 self.write_keyword("DECIMAL(65, 30)");
25109 }
25110 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
25111 self.unsupported(
25112 "Oracle NUMBER without precision or scale has no exact T-SQL mapping",
25113 )?;
25114 self.write_keyword("DECIMAL(38, 10)");
25115 }
25116 _ => self.write_keyword("DECIMAL"),
25117 },
25118 (Some(precision), None) | (Some(precision), Some(0)) => {
25119 if precision <= 9 {
25120 self.write_keyword("INT");
25121 } else if precision <= 18 {
25122 self.write_keyword("BIGINT");
25123 } else {
25124 self.write(&format!("DECIMAL({precision}, 0)"));
25125 }
25126 }
25127 (Some(precision), Some(scale)) if scale < 0 => match target {
25128 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
25129 self.write(&format!("NUMERIC({precision}, {scale})"));
25130 }
25131 Some(DialectType::MySQL)
25132 | Some(DialectType::SingleStore)
25133 | Some(DialectType::TiDB) => {
25134 self.unsupported(format!(
25135 "Oracle NUMBER({precision}, {scale}) negative-scale rounding cannot be enforced by MySQL"
25136 ))?;
25137 let width = precision.saturating_add(scale.unsigned_abs()).min(65);
25138 self.write(&format!("DECIMAL({width}, 0)"));
25139 }
25140 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
25141 self.unsupported(format!(
25142 "Oracle NUMBER({precision}, {scale}) negative-scale rounding cannot be enforced by T-SQL"
25143 ))?;
25144 let width = precision.saturating_add(scale.unsigned_abs()).min(38);
25145 self.write(&format!("DECIMAL({width}, 0)"));
25146 }
25147 _ => {
25148 self.unsupported(format!(
25149 "Oracle NUMBER({precision}, {scale}) negative-scale rounding may not be supported"
25150 ))?;
25151 let width = precision.saturating_add(scale.unsigned_abs());
25152 self.write(&format!("DECIMAL({width}, 0)"));
25153 }
25154 },
25155 (Some(precision), Some(scale)) => {
25156 let mut target_precision = precision;
25157 let mut target_scale = u32::try_from(scale).unwrap_or_default();
25158 let limits = match target {
25159 Some(DialectType::MySQL)
25160 | Some(DialectType::SingleStore)
25161 | Some(DialectType::TiDB) => Some((65, 30, "MySQL")),
25162 Some(DialectType::TSQL) | Some(DialectType::Fabric) => Some((38, 38, "T-SQL")),
25163 _ => None,
25164 };
25165 if let Some((max_precision, max_scale, dialect_name)) = limits {
25166 let requested_precision = target_precision;
25167 let requested_scale = target_scale;
25168 target_scale = target_scale.min(max_scale);
25169 target_precision = target_precision.max(target_scale).min(max_precision);
25170 if target_precision != requested_precision || target_scale != requested_scale {
25171 self.unsupported(format!(
25172 "Oracle NUMBER({precision}, {scale}) exceeds {dialect_name} DECIMAL limits"
25173 ))?;
25174 }
25175 }
25176 self.write(&format!("DECIMAL({target_precision}, {target_scale})"));
25177 }
25178 (None, Some(scale)) => {
25179 self.unsupported(format!(
25180 "Oracle NUMBER(*, {scale}) has no exact target mapping"
25181 ))?;
25182 self.write_keyword("DECIMAL");
25183 }
25184 }
25185 Ok(())
25186 }
25187
25188 fn write_oracle_character(
25189 &mut self,
25190 kind: OracleCharacterKind,
25191 length: Option<u32>,
25192 semantics: Option<OracleCharacterLengthSemantics>,
25193 ) -> Result<()> {
25194 use crate::dialects::DialectType;
25195
25196 if matches!(self.config.dialect, Some(DialectType::Oracle) | None) {
25197 let name = match kind {
25198 OracleCharacterKind::Char => "CHAR",
25199 OracleCharacterKind::VarChar => "VARCHAR2",
25200 OracleCharacterKind::NChar => "NCHAR",
25201 OracleCharacterKind::NVarChar => "NVARCHAR2",
25202 };
25203 self.write_keyword(name);
25204 if let Some(length) = length {
25205 self.write(&format!("({length}"));
25206 if let Some(semantics) = semantics {
25207 self.write(match semantics {
25208 OracleCharacterLengthSemantics::Byte => " BYTE",
25209 OracleCharacterLengthSemantics::Char => " CHAR",
25210 });
25211 }
25212 self.write(")");
25213 }
25214 return Ok(());
25215 }
25216
25217 let mut target_kind = kind;
25218 match self.config.dialect {
25219 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25220 if semantics == Some(OracleCharacterLengthSemantics::Char)
25221 && matches!(
25222 kind,
25223 OracleCharacterKind::Char | OracleCharacterKind::VarChar
25224 ) =>
25225 {
25226 self.unsupported(
25227 "Oracle CHAR length semantics require a national-character approximation in T-SQL",
25228 )?;
25229 target_kind = match kind {
25230 OracleCharacterKind::Char => OracleCharacterKind::NChar,
25231 OracleCharacterKind::VarChar => OracleCharacterKind::NVarChar,
25232 _ => kind,
25233 };
25234 }
25235 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize)
25236 if matches!(
25237 kind,
25238 OracleCharacterKind::NChar | OracleCharacterKind::NVarChar
25239 ) =>
25240 {
25241 target_kind = match kind {
25242 OracleCharacterKind::NChar => OracleCharacterKind::Char,
25243 OracleCharacterKind::NVarChar => OracleCharacterKind::VarChar,
25244 _ => kind,
25245 };
25246 }
25247 _ => {}
25248 }
25249
25250 if semantics == Some(OracleCharacterLengthSemantics::Byte)
25251 && matches!(
25252 self.config.dialect,
25253 Some(DialectType::MySQL)
25254 | Some(DialectType::SingleStore)
25255 | Some(DialectType::TiDB)
25256 | Some(DialectType::PostgreSQL)
25257 | Some(DialectType::Materialize)
25258 )
25259 {
25260 self.unsupported(
25261 "Oracle BYTE character length semantics cannot be enforced by the target type",
25262 )?;
25263 }
25264
25265 let name = match target_kind {
25266 OracleCharacterKind::Char => "CHAR",
25267 OracleCharacterKind::VarChar => "VARCHAR",
25268 OracleCharacterKind::NChar => "NCHAR",
25269 OracleCharacterKind::NVarChar => "NVARCHAR",
25270 };
25271 let length = if matches!(
25272 target_kind,
25273 OracleCharacterKind::Char | OracleCharacterKind::NChar
25274 ) {
25275 Some(length.unwrap_or(1))
25276 } else {
25277 length
25278 };
25279 self.write_type_with_length(name, length);
25280 Ok(())
25281 }
25282
25283 fn oracle_timestamp_precision(&mut self, precision: Option<u32>, maximum: u32) -> Result<u32> {
25284 let requested = precision.unwrap_or(6);
25285 if requested > maximum {
25286 self.unsupported(format!(
25287 "Oracle timestamp precision {requested} exceeds the target maximum of {maximum}"
25288 ))?;
25289 }
25290 Ok(requested.min(maximum))
25291 }
25292
25293 fn write_oracle_data_type(&mut self, data_type: &OracleDataType) -> Result<()> {
25294 use crate::dialects::DialectType;
25295
25296 match data_type {
25297 OracleDataType::Number { precision, scale } => {
25298 self.write_oracle_number(*precision, *scale)?;
25299 }
25300 OracleDataType::BinaryFloat => match self.config.dialect {
25301 Some(DialectType::Oracle) | None => self.write_keyword("BINARY_FLOAT"),
25302 Some(DialectType::TSQL)
25303 | Some(DialectType::Fabric)
25304 | Some(DialectType::PostgreSQL)
25305 | Some(DialectType::Materialize) => self.write_keyword("REAL"),
25306 _ => self.write_keyword("FLOAT"),
25307 },
25308 OracleDataType::BinaryDouble => match self.config.dialect {
25309 Some(DialectType::Oracle) | None => self.write_keyword("BINARY_DOUBLE"),
25310 Some(DialectType::TSQL) | Some(DialectType::Fabric) => self.write_keyword("FLOAT"),
25311 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
25312 self.write_keyword("DOUBLE PRECISION")
25313 }
25314 _ => self.write_keyword("DOUBLE"),
25315 },
25316 OracleDataType::Float { precision } => {
25317 if matches!(self.config.dialect, Some(DialectType::Oracle) | None) {
25318 self.write_keyword("FLOAT");
25319 if let Some(precision) = precision {
25320 self.write(&format!("({precision})"));
25321 }
25322 } else {
25323 let precision = precision.unwrap_or(126);
25324 match self.config.dialect {
25325 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
25326 if precision > 53 {
25327 self.unsupported(format!(
25328 "Oracle FLOAT({precision}) exceeds T-SQL FLOAT precision"
25329 ))?;
25330 }
25331 self.write(&format!("FLOAT({})", precision.min(53)));
25332 }
25333 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
25334 self.write_keyword(if precision <= 24 {
25335 "REAL"
25336 } else {
25337 "DOUBLE PRECISION"
25338 });
25339 }
25340 Some(DialectType::MySQL)
25341 | Some(DialectType::SingleStore)
25342 | Some(DialectType::TiDB) => {
25343 self.write_keyword(if precision <= 24 { "FLOAT" } else { "DOUBLE" });
25344 }
25345 _ => self.write_keyword("DOUBLE PRECISION"),
25346 }
25347 }
25348 }
25349 OracleDataType::Character {
25350 kind,
25351 length,
25352 semantics,
25353 } => self.write_oracle_character(*kind, *length, *semantics)?,
25354 OracleDataType::Date => match self.config.dialect {
25355 Some(DialectType::Oracle) | None => self.write_keyword("DATE"),
25356 Some(DialectType::MySQL)
25357 | Some(DialectType::SingleStore)
25358 | Some(DialectType::TiDB) => self.write_keyword("DATETIME"),
25359 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
25360 self.write_keyword("DATETIME2(0)")
25361 }
25362 _ => self.write_keyword("TIMESTAMP(0)"),
25363 },
25364 OracleDataType::Timestamp {
25365 precision,
25366 timezone,
25367 } => {
25368 if matches!(self.config.dialect, Some(DialectType::Oracle) | None) {
25369 self.write_keyword("TIMESTAMP");
25370 if let Some(precision) = precision {
25371 self.write(&format!("({precision})"));
25372 }
25373 match timezone {
25374 OracleTimestampTimeZone::None => {}
25375 OracleTimestampTimeZone::WithTimeZone => {
25376 self.write_keyword(" WITH TIME ZONE")
25377 }
25378 OracleTimestampTimeZone::WithLocalTimeZone => {
25379 self.write_keyword(" WITH LOCAL TIME ZONE")
25380 }
25381 }
25382 } else {
25383 match self.config.dialect {
25384 Some(DialectType::MySQL)
25385 | Some(DialectType::SingleStore)
25386 | Some(DialectType::TiDB) => {
25387 let precision = self.oracle_timestamp_precision(*precision, 6)?;
25388 match timezone {
25389 OracleTimestampTimeZone::None => {
25390 self.write(&format!("DATETIME({precision})"));
25391 }
25392 OracleTimestampTimeZone::WithTimeZone => {
25393 self.unsupported(
25394 "Oracle TIMESTAMP WITH TIME ZONE loses its time zone in MySQL",
25395 )?;
25396 self.write(&format!("DATETIME({precision})"));
25397 }
25398 OracleTimestampTimeZone::WithLocalTimeZone => {
25399 self.unsupported(
25400 "Oracle TIMESTAMP WITH LOCAL TIME ZONE has only an approximate MySQL mapping",
25401 )?;
25402 self.write(&format!("TIMESTAMP({precision})"));
25403 }
25404 }
25405 }
25406 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
25407 let precision = self.oracle_timestamp_precision(*precision, 7)?;
25408 match timezone {
25409 OracleTimestampTimeZone::None => {
25410 self.write(&format!("DATETIME2({precision})"));
25411 }
25412 OracleTimestampTimeZone::WithTimeZone => {
25413 self.write(&format!("DATETIMEOFFSET({precision})"));
25414 }
25415 OracleTimestampTimeZone::WithLocalTimeZone => {
25416 self.unsupported(
25417 "Oracle TIMESTAMP WITH LOCAL TIME ZONE loses session time-zone semantics in T-SQL",
25418 )?;
25419 self.write(&format!("DATETIME2({precision})"));
25420 }
25421 }
25422 }
25423 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
25424 let precision = self.oracle_timestamp_precision(*precision, 6)?;
25425 match timezone {
25426 OracleTimestampTimeZone::None => {
25427 self.write(&format!("TIMESTAMP({precision})"));
25428 }
25429 OracleTimestampTimeZone::WithTimeZone => {
25430 self.write(&format!("TIMESTAMPTZ({precision})"));
25431 }
25432 OracleTimestampTimeZone::WithLocalTimeZone => {
25433 self.unsupported(
25434 "Oracle TIMESTAMP WITH LOCAL TIME ZONE has only an approximate PostgreSQL mapping",
25435 )?;
25436 self.write(&format!("TIMESTAMPTZ({precision})"));
25437 }
25438 }
25439 }
25440 _ => {
25441 let precision = precision.unwrap_or(6);
25442 let name = if matches!(timezone, OracleTimestampTimeZone::None) {
25443 "TIMESTAMP"
25444 } else {
25445 "TIMESTAMPTZ"
25446 };
25447 self.write(&format!("{name}({precision})"));
25448 }
25449 }
25450 }
25451 }
25452 OracleDataType::IntervalYearToMonth { year_precision } => {
25453 if matches!(self.config.dialect, Some(DialectType::Oracle) | None) {
25454 self.write_keyword("INTERVAL YEAR");
25455 if let Some(precision) = year_precision {
25456 self.write(&format!("({precision})"));
25457 }
25458 self.write_keyword(" TO MONTH");
25459 } else if matches!(
25460 self.config.dialect,
25461 Some(DialectType::MySQL)
25462 | Some(DialectType::SingleStore)
25463 | Some(DialectType::TiDB)
25464 | Some(DialectType::TSQL)
25465 | Some(DialectType::Fabric)
25466 ) {
25467 self.unsupported(
25468 "Oracle INTERVAL YEAR TO MONTH has no native target column type",
25469 )?;
25470 self.write_keyword("VARCHAR(30)");
25471 } else {
25472 if year_precision.is_some() {
25473 self.unsupported(
25474 "Oracle INTERVAL YEAR leading precision cannot be preserved",
25475 )?;
25476 }
25477 self.write_keyword("INTERVAL YEAR TO MONTH");
25478 }
25479 }
25480 OracleDataType::IntervalDayToSecond {
25481 day_precision,
25482 fractional_seconds_precision,
25483 } => {
25484 if matches!(self.config.dialect, Some(DialectType::Oracle) | None) {
25485 self.write_keyword("INTERVAL DAY");
25486 if let Some(precision) = day_precision {
25487 self.write(&format!("({precision})"));
25488 }
25489 self.write_keyword(" TO SECOND");
25490 if let Some(precision) = fractional_seconds_precision {
25491 self.write(&format!("({precision})"));
25492 }
25493 } else if matches!(
25494 self.config.dialect,
25495 Some(DialectType::MySQL)
25496 | Some(DialectType::SingleStore)
25497 | Some(DialectType::TiDB)
25498 | Some(DialectType::TSQL)
25499 | Some(DialectType::Fabric)
25500 ) {
25501 self.unsupported(
25502 "Oracle INTERVAL DAY TO SECOND has no native target column type",
25503 )?;
25504 self.write_keyword("VARCHAR(30)");
25505 } else {
25506 if day_precision.is_some() {
25507 self.unsupported(
25508 "Oracle INTERVAL DAY leading precision cannot be preserved",
25509 )?;
25510 }
25511 self.write_keyword("INTERVAL");
25512 if let Some(precision) = fractional_seconds_precision {
25513 self.write(&format!("({precision})"));
25514 }
25515 self.write_keyword(" DAY TO SECOND");
25516 }
25517 }
25518 OracleDataType::Clob { national } => match self.config.dialect {
25519 Some(DialectType::Oracle) | None => {
25520 self.write_keyword(if *national { "NCLOB" } else { "CLOB" })
25521 }
25522 Some(DialectType::MySQL)
25523 | Some(DialectType::SingleStore)
25524 | Some(DialectType::TiDB) => self.write_keyword("LONGTEXT"),
25525 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
25526 self.write_keyword(if *national {
25527 "NVARCHAR(MAX)"
25528 } else {
25529 "VARCHAR(MAX)"
25530 });
25531 }
25532 _ => self.write_keyword("TEXT"),
25533 },
25534 OracleDataType::Blob => match self.config.dialect {
25535 Some(DialectType::Oracle) | None => self.write_keyword("BLOB"),
25536 Some(DialectType::MySQL)
25537 | Some(DialectType::SingleStore)
25538 | Some(DialectType::TiDB) => self.write_keyword("LONGBLOB"),
25539 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
25540 self.write_keyword("VARBINARY(MAX)")
25541 }
25542 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
25543 self.write_keyword("BYTEA")
25544 }
25545 _ => self.write_keyword("BLOB"),
25546 },
25547 OracleDataType::Raw { length } => match self.config.dialect {
25548 Some(DialectType::Oracle) | None => self.write_type_with_length("RAW", *length),
25549 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
25550 if length.is_some() {
25551 self.unsupported("Oracle RAW length constraint is lost in PostgreSQL")?;
25552 }
25553 self.write_keyword("BYTEA");
25554 }
25555 _ => self.write_type_with_length("VARBINARY", *length),
25556 },
25557 OracleDataType::Long { raw } => {
25558 if matches!(self.config.dialect, Some(DialectType::Oracle) | None) {
25559 self.write_keyword(if *raw { "LONG RAW" } else { "LONG" });
25560 } else if *raw {
25561 match self.config.dialect {
25562 Some(DialectType::MySQL)
25563 | Some(DialectType::SingleStore)
25564 | Some(DialectType::TiDB) => self.write_keyword("LONGBLOB"),
25565 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
25566 self.write_keyword("VARBINARY(MAX)")
25567 }
25568 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
25569 self.write_keyword("BYTEA")
25570 }
25571 _ => self.write_keyword("BLOB"),
25572 }
25573 } else {
25574 match self.config.dialect {
25575 Some(DialectType::MySQL)
25576 | Some(DialectType::SingleStore)
25577 | Some(DialectType::TiDB) => self.write_keyword("LONGTEXT"),
25578 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
25579 self.write_keyword("VARCHAR(MAX)")
25580 }
25581 _ => self.write_keyword("TEXT"),
25582 }
25583 }
25584 }
25585 OracleDataType::RowId => {
25586 if matches!(self.config.dialect, Some(DialectType::Oracle) | None) {
25587 self.write_keyword("ROWID");
25588 } else {
25589 self.unsupported(
25590 "Oracle ROWID physical row identity is reduced to its text representation",
25591 )?;
25592 self.write_keyword("CHAR(18)");
25593 }
25594 }
25595 }
25596 Ok(())
25597 }
25598
25599 fn generate_data_type(&mut self, dt: &DataType) -> Result<()> {
25600 use crate::dialects::DialectType;
25601
25602 match dt {
25603 DataType::Boolean => {
25604 match self.config.dialect {
25606 Some(DialectType::TSQL) => self.write_keyword("BIT"),
25607 Some(DialectType::MySQL) => self.write_keyword("BOOLEAN"), Some(DialectType::Oracle) => {
25609 self.write_keyword("NUMBER(1)")
25611 }
25612 Some(DialectType::ClickHouse) => self.write("Bool"), _ => self.write_keyword("BOOLEAN"),
25614 }
25615 }
25616 DataType::TinyInt { length } => {
25617 match self.config.dialect {
25621 Some(DialectType::PostgreSQL)
25622 | Some(DialectType::Redshift)
25623 | Some(DialectType::Oracle)
25624 | Some(DialectType::Exasol) => {
25625 self.write_keyword("SMALLINT");
25626 }
25627 Some(DialectType::Teradata) => {
25628 self.write_keyword("BYTEINT");
25630 }
25631 Some(DialectType::Dremio) => {
25632 self.write_keyword("INT");
25634 }
25635 Some(DialectType::ClickHouse) => {
25636 self.write_clickhouse_type("Int8");
25637 }
25638 _ => {
25639 self.write_keyword("TINYINT");
25640 }
25641 }
25642 if let Some(n) = length {
25643 if !matches!(
25644 self.config.dialect,
25645 Some(DialectType::Dremio) | Some(DialectType::ClickHouse)
25646 ) {
25647 self.write(&format!("({})", n));
25648 }
25649 }
25650 }
25651 DataType::SmallInt { length } => {
25652 match self.config.dialect {
25654 Some(DialectType::Dremio) => {
25655 self.write_keyword("INT");
25656 }
25657 Some(DialectType::SQLite) | Some(DialectType::Drill) => {
25658 self.write_keyword("INTEGER");
25659 }
25660 Some(DialectType::BigQuery) => {
25661 self.write_keyword("INT64");
25662 }
25663 Some(DialectType::ClickHouse) => {
25664 self.write_clickhouse_type("Int16");
25665 }
25666 _ => {
25667 self.write_keyword("SMALLINT");
25668 if let Some(n) = length {
25669 self.write(&format!("({})", n));
25670 }
25671 }
25672 }
25673 }
25674 DataType::Int {
25675 length,
25676 integer_spelling: _,
25677 } => {
25678 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
25680 self.write_keyword("INT64");
25681 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
25682 self.write_clickhouse_type("Int32");
25683 } else {
25684 let use_integer = match self.config.dialect {
25686 Some(DialectType::TSQL)
25687 | Some(DialectType::Fabric)
25688 | Some(DialectType::Presto)
25689 | Some(DialectType::Trino)
25690 | Some(DialectType::SQLite)
25691 | Some(DialectType::Redshift) => true,
25692 _ => false,
25693 };
25694 if use_integer {
25695 self.write_keyword("INTEGER");
25696 } else {
25697 self.write_keyword("INT");
25698 }
25699 if let Some(n) = length {
25700 self.write(&format!("({})", n));
25701 }
25702 }
25703 }
25704 DataType::BigInt { length } => {
25705 match self.config.dialect {
25707 Some(DialectType::Oracle) => {
25708 self.write_keyword("INT");
25710 }
25711 Some(DialectType::ClickHouse) => {
25712 self.write_clickhouse_type("Int64");
25713 }
25714 _ => {
25715 self.write_keyword("BIGINT");
25716 if let Some(n) = length {
25717 self.write(&format!("({})", n));
25718 }
25719 }
25720 }
25721 }
25722 DataType::Float {
25723 precision,
25724 scale,
25725 real_spelling,
25726 } => {
25727 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
25731 self.write_clickhouse_type("Float32");
25732 } else if *real_spelling
25733 && !matches!(
25734 self.config.dialect,
25735 Some(DialectType::Spark)
25736 | Some(DialectType::Databricks)
25737 | Some(DialectType::Hive)
25738 | Some(DialectType::Snowflake)
25739 | Some(DialectType::MySQL)
25740 | Some(DialectType::BigQuery)
25741 )
25742 {
25743 self.write_keyword("REAL")
25744 } else {
25745 match self.config.dialect {
25746 Some(DialectType::PostgreSQL) => self.write_keyword("REAL"),
25747 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
25748 _ => self.write_keyword("FLOAT"),
25749 }
25750 }
25751 if !matches!(
25754 self.config.dialect,
25755 Some(DialectType::Spark)
25756 | Some(DialectType::Databricks)
25757 | Some(DialectType::Hive)
25758 | Some(DialectType::Presto)
25759 | Some(DialectType::Trino)
25760 ) {
25761 if let Some(p) = precision {
25762 self.write(&format!("({}", p));
25763 if let Some(s) = scale {
25764 self.write(&format!(", {})", s));
25765 } else {
25766 self.write(")");
25767 }
25768 }
25769 }
25770 }
25771 DataType::Double { precision, scale } => {
25772 match self.config.dialect {
25774 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
25775 self.write_keyword("FLOAT")
25776 } Some(DialectType::Oracle) => self.write_keyword("DOUBLE PRECISION"),
25778 Some(DialectType::ClickHouse) => self.write_clickhouse_type("Float64"),
25779 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
25780 Some(DialectType::SQLite) => self.write_keyword("REAL"),
25781 Some(DialectType::PostgreSQL)
25782 | Some(DialectType::Redshift)
25783 | Some(DialectType::Teradata)
25784 | Some(DialectType::Materialize) => self.write_keyword("DOUBLE PRECISION"),
25785 _ => self.write_keyword("DOUBLE"),
25786 }
25787 if let Some(p) = precision {
25789 self.write(&format!("({}", p));
25790 if let Some(s) = scale {
25791 self.write(&format!(", {})", s));
25792 } else {
25793 self.write(")");
25794 }
25795 }
25796 }
25797 DataType::Decimal { precision, scale } => {
25798 match self.config.dialect {
25800 Some(DialectType::ClickHouse) => {
25801 self.write("Decimal");
25802 if let Some(p) = precision {
25803 self.write(&format!("({}", p));
25804 if let Some(s) = scale {
25805 self.write(&format!(", {}", s));
25806 }
25807 self.write(")");
25808 }
25809 }
25810 Some(DialectType::Oracle) => {
25811 self.write_keyword("NUMBER");
25813 if let Some(p) = precision {
25814 self.write(&format!("({}", p));
25815 if let Some(s) = scale {
25816 self.write(&format!(", {}", s));
25817 }
25818 self.write(")");
25819 }
25820 }
25821 Some(DialectType::BigQuery) => {
25822 self.write_keyword("NUMERIC");
25824 if let Some(p) = precision {
25825 self.write(&format!("({}", p));
25826 if let Some(s) = scale {
25827 self.write(&format!(", {}", s));
25828 }
25829 self.write(")");
25830 }
25831 }
25832 _ => {
25833 self.write_keyword("DECIMAL");
25834 if let Some(p) = precision {
25835 self.write(&format!("({}", p));
25836 if let Some(s) = scale {
25837 self.write(&format!(", {}", s));
25838 }
25839 self.write(")");
25840 }
25841 }
25842 }
25843 }
25844 DataType::Oracle { oracle_type } => {
25845 self.write_oracle_data_type(oracle_type)?;
25846 }
25847 DataType::Char { length } => {
25848 match self.config.dialect {
25850 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
25851 self.write_keyword("TEXT");
25853 }
25854 Some(DialectType::Hive)
25855 | Some(DialectType::Spark)
25856 | Some(DialectType::Databricks) => {
25857 if length.is_some()
25860 && !matches!(self.config.dialect, Some(DialectType::Hive))
25861 {
25862 self.write_keyword("CHAR");
25863 if let Some(n) = length {
25864 self.write(&format!("({})", n));
25865 }
25866 } else {
25867 self.write_keyword("STRING");
25868 }
25869 }
25870 Some(DialectType::Dremio) => {
25871 self.write_keyword("VARCHAR");
25873 if let Some(n) = length {
25874 self.write(&format!("({})", n));
25875 }
25876 }
25877 _ => {
25878 self.write_keyword("CHAR");
25879 if let Some(n) = length {
25880 self.write(&format!("({})", n));
25881 }
25882 }
25883 }
25884 }
25885 DataType::VarChar {
25886 length,
25887 parenthesized_length,
25888 } => {
25889 match self.config.dialect {
25891 Some(DialectType::Oracle) => {
25892 self.write_keyword("VARCHAR2");
25893 if let Some(n) = length {
25894 self.write(&format!("({})", n));
25895 }
25896 }
25897 Some(DialectType::DuckDB) => {
25898 self.write_keyword("TEXT");
25900 if let Some(n) = length {
25901 self.write(&format!("({})", n));
25902 }
25903 }
25904 Some(DialectType::SQLite) => {
25905 self.write_keyword("TEXT");
25907 if let Some(n) = length {
25908 self.write(&format!("({})", n));
25909 }
25910 }
25911 Some(DialectType::MySQL) if length.is_none() => {
25912 self.write_keyword("TEXT");
25914 }
25915 Some(DialectType::Hive)
25916 | Some(DialectType::Spark)
25917 | Some(DialectType::Databricks)
25918 if length.is_none() =>
25919 {
25920 self.write_keyword("STRING");
25922 }
25923 _ => {
25924 self.write_keyword("VARCHAR");
25925 if let Some(n) = length {
25926 if *parenthesized_length {
25928 self.write(&format!("(({}))", n));
25929 } else {
25930 self.write(&format!("({})", n));
25931 }
25932 }
25933 }
25934 }
25935 }
25936 DataType::Text => {
25937 match self.config.dialect {
25939 Some(DialectType::Oracle) => self.write_keyword("CLOB"),
25940 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
25941 self.write_keyword("VARCHAR(MAX)")
25942 }
25943 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
25944 Some(DialectType::Snowflake)
25945 | Some(DialectType::Dremio)
25946 | Some(DialectType::Drill) => self.write_keyword("VARCHAR"),
25947 Some(DialectType::Exasol) => self.write_keyword("LONG VARCHAR"),
25948 Some(DialectType::Presto)
25949 | Some(DialectType::Trino)
25950 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
25951 Some(DialectType::Spark)
25952 | Some(DialectType::Databricks)
25953 | Some(DialectType::Hive) => self.write_keyword("STRING"),
25954 Some(DialectType::Redshift) => self.write_keyword("VARCHAR(MAX)"),
25955 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
25956 self.write_keyword("STRING")
25957 }
25958 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
25959 _ => self.write_keyword("TEXT"),
25960 }
25961 }
25962 DataType::TextWithLength { length } => {
25963 match self.config.dialect {
25965 Some(DialectType::Oracle) => self.write(&format!("CLOB({})", length)),
25966 Some(DialectType::Hive)
25967 | Some(DialectType::Spark)
25968 | Some(DialectType::Databricks) => {
25969 self.write(&format!("VARCHAR({})", length));
25970 }
25971 Some(DialectType::Redshift) => self.write(&format!("VARCHAR({})", length)),
25972 Some(DialectType::BigQuery) => self.write(&format!("STRING({})", length)),
25973 Some(DialectType::Snowflake)
25974 | Some(DialectType::Presto)
25975 | Some(DialectType::Trino)
25976 | Some(DialectType::Athena)
25977 | Some(DialectType::Drill)
25978 | Some(DialectType::Dremio) => {
25979 self.write(&format!("VARCHAR({})", length));
25980 }
25981 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
25982 self.write(&format!("VARCHAR({})", length))
25983 }
25984 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
25985 self.write(&format!("STRING({})", length))
25986 }
25987 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
25988 _ => self.write(&format!("TEXT({})", length)),
25989 }
25990 }
25991 DataType::String { length } => {
25992 match self.config.dialect {
25994 Some(DialectType::ClickHouse) => {
25995 self.write("String");
25997 if let Some(n) = length {
25998 self.write(&format!("({})", n));
25999 }
26000 }
26001 Some(DialectType::BigQuery)
26002 | Some(DialectType::Hive)
26003 | Some(DialectType::Spark)
26004 | Some(DialectType::Databricks)
26005 | Some(DialectType::StarRocks)
26006 | Some(DialectType::Doris) => {
26007 self.write_keyword("STRING");
26008 if let Some(n) = length {
26009 self.write(&format!("({})", n));
26010 }
26011 }
26012 Some(DialectType::PostgreSQL) => {
26013 if let Some(n) = length {
26015 self.write_keyword("VARCHAR");
26016 self.write(&format!("({})", n));
26017 } else {
26018 self.write_keyword("TEXT");
26019 }
26020 }
26021 Some(DialectType::Redshift) => {
26022 if let Some(n) = length {
26024 self.write_keyword("VARCHAR");
26025 self.write(&format!("({})", n));
26026 } else {
26027 self.write_keyword("VARCHAR(MAX)");
26028 }
26029 }
26030 Some(DialectType::MySQL) => {
26031 if let Some(n) = length {
26033 self.write_keyword("VARCHAR");
26034 self.write(&format!("({})", n));
26035 } else {
26036 self.write_keyword("TEXT");
26037 }
26038 }
26039 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
26040 if let Some(n) = length {
26042 self.write_keyword("VARCHAR");
26043 self.write(&format!("({})", n));
26044 } else {
26045 self.write_keyword("VARCHAR(MAX)");
26046 }
26047 }
26048 Some(DialectType::Oracle) => {
26049 self.write_keyword("CLOB");
26051 }
26052 Some(DialectType::DuckDB) | Some(DialectType::Materialize) => {
26053 self.write_keyword("TEXT");
26055 if let Some(n) = length {
26056 self.write(&format!("({})", n));
26057 }
26058 }
26059 Some(DialectType::Presto)
26060 | Some(DialectType::Trino)
26061 | Some(DialectType::Drill)
26062 | Some(DialectType::Dremio) => {
26063 self.write_keyword("VARCHAR");
26065 if let Some(n) = length {
26066 self.write(&format!("({})", n));
26067 }
26068 }
26069 Some(DialectType::Snowflake) => {
26070 self.write_keyword("STRING");
26073 if let Some(n) = length {
26074 self.write(&format!("({})", n));
26075 }
26076 }
26077 _ => {
26078 self.write_keyword("STRING");
26080 if let Some(n) = length {
26081 self.write(&format!("({})", n));
26082 }
26083 }
26084 }
26085 }
26086 DataType::Binary { length } => {
26087 match self.config.dialect {
26089 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
26090 self.write_keyword("BYTEA");
26091 if let Some(n) = length {
26092 self.write(&format!("({})", n));
26093 }
26094 }
26095 Some(DialectType::Redshift) => {
26096 self.write_keyword("VARBYTE");
26097 if let Some(n) = length {
26098 self.write(&format!("({})", n));
26099 }
26100 }
26101 Some(DialectType::DuckDB)
26102 | Some(DialectType::SQLite)
26103 | Some(DialectType::Oracle) => {
26104 self.write_keyword("BLOB");
26106 if let Some(n) = length {
26107 self.write(&format!("({})", n));
26108 }
26109 }
26110 Some(DialectType::Presto)
26111 | Some(DialectType::Trino)
26112 | Some(DialectType::Athena)
26113 | Some(DialectType::Drill)
26114 | Some(DialectType::Dremio) => {
26115 self.write_keyword("VARBINARY");
26117 if let Some(n) = length {
26118 self.write(&format!("({})", n));
26119 }
26120 }
26121 Some(DialectType::ClickHouse) => {
26122 if self.clickhouse_nullable_depth < 0 {
26124 self.write("BINARY");
26125 } else {
26126 self.write("Nullable(BINARY");
26127 }
26128 if let Some(n) = length {
26129 self.write(&format!("({})", n));
26130 }
26131 if self.clickhouse_nullable_depth >= 0 {
26132 self.write(")");
26133 }
26134 }
26135 _ => {
26136 self.write_keyword("BINARY");
26137 if let Some(n) = length {
26138 self.write(&format!("({})", n));
26139 }
26140 }
26141 }
26142 }
26143 DataType::VarBinary { length } => {
26144 match self.config.dialect {
26146 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
26147 self.write_keyword("BYTEA");
26148 if let Some(n) = length {
26149 self.write(&format!("({})", n));
26150 }
26151 }
26152 Some(DialectType::Redshift) => {
26153 self.write_keyword("VARBYTE");
26154 if let Some(n) = length {
26155 self.write(&format!("({})", n));
26156 }
26157 }
26158 Some(DialectType::DuckDB)
26159 | Some(DialectType::SQLite)
26160 | Some(DialectType::Oracle) => {
26161 self.write_keyword("BLOB");
26163 if let Some(n) = length {
26164 self.write(&format!("({})", n));
26165 }
26166 }
26167 Some(DialectType::Exasol) => {
26168 self.write_keyword("VARCHAR");
26170 }
26171 Some(DialectType::Spark)
26172 | Some(DialectType::Hive)
26173 | Some(DialectType::Databricks) => {
26174 self.write_keyword("BINARY");
26176 if let Some(n) = length {
26177 self.write(&format!("({})", n));
26178 }
26179 }
26180 Some(DialectType::ClickHouse) => {
26181 self.write_clickhouse_type("String");
26183 }
26184 _ => {
26185 self.write_keyword("VARBINARY");
26186 if let Some(n) = length {
26187 self.write(&format!("({})", n));
26188 }
26189 }
26190 }
26191 }
26192 DataType::Blob => {
26193 match self.config.dialect {
26195 Some(DialectType::PostgreSQL) => self.write_keyword("BYTEA"),
26196 Some(DialectType::Redshift) => self.write_keyword("VARBYTE"),
26197 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
26198 self.write_keyword("VARBINARY")
26199 }
26200 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
26201 Some(DialectType::Exasol) => self.write_keyword("VARCHAR"),
26202 Some(DialectType::Presto)
26203 | Some(DialectType::Trino)
26204 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
26205 Some(DialectType::DuckDB) => {
26206 self.write_keyword("VARBINARY");
26209 }
26210 Some(DialectType::Spark)
26211 | Some(DialectType::Databricks)
26212 | Some(DialectType::Hive) => self.write_keyword("BINARY"),
26213 Some(DialectType::ClickHouse) => {
26214 self.write("Nullable(String)");
26218 }
26219 _ => self.write_keyword("BLOB"),
26220 }
26221 }
26222 DataType::Bit { length } => {
26223 match self.config.dialect {
26225 Some(DialectType::Dremio)
26226 | Some(DialectType::Spark)
26227 | Some(DialectType::Databricks)
26228 | Some(DialectType::Hive)
26229 | Some(DialectType::Snowflake)
26230 | Some(DialectType::BigQuery)
26231 | Some(DialectType::Presto)
26232 | Some(DialectType::Trino)
26233 | Some(DialectType::ClickHouse)
26234 | Some(DialectType::Redshift) => {
26235 self.write_keyword("BOOLEAN");
26237 }
26238 _ => {
26239 self.write_keyword("BIT");
26240 if let Some(n) = length {
26241 self.write(&format!("({})", n));
26242 }
26243 }
26244 }
26245 }
26246 DataType::VarBit { length } => {
26247 self.write_keyword("VARBIT");
26248 if let Some(n) = length {
26249 self.write(&format!("({})", n));
26250 }
26251 }
26252 DataType::Date => self.write_keyword("DATE"),
26253 DataType::Time {
26254 precision,
26255 timezone,
26256 } => {
26257 if *timezone {
26258 match self.config.dialect {
26260 Some(DialectType::DuckDB) => {
26261 self.write_keyword("TIMETZ");
26263 }
26264 Some(DialectType::PostgreSQL) => {
26265 self.write_keyword("TIMETZ");
26267 if let Some(p) = precision {
26268 self.write(&format!("({})", p));
26269 }
26270 }
26271 _ => {
26272 self.write_keyword("TIME");
26274 if let Some(p) = precision {
26275 self.write(&format!("({})", p));
26276 }
26277 self.write_keyword(" WITH TIME ZONE");
26278 }
26279 }
26280 } else {
26281 if matches!(
26283 self.config.dialect,
26284 Some(DialectType::Spark)
26285 | Some(DialectType::Databricks)
26286 | Some(DialectType::Hive)
26287 ) {
26288 self.write_keyword("TIMESTAMP");
26289 } else {
26290 self.write_keyword("TIME");
26291 if let Some(p) = precision {
26292 self.write(&format!("({})", p));
26293 }
26294 }
26295 }
26296 }
26297 DataType::Timestamp {
26298 precision,
26299 timezone,
26300 } => {
26301 match self.config.dialect {
26303 Some(DialectType::Snowflake) if *timezone => {
26304 self.write_keyword("TIMESTAMPTZ");
26305 if let Some(p) = precision {
26306 self.write(&format!("({})", p));
26307 }
26308 }
26309 Some(DialectType::ClickHouse) => {
26310 self.write("DateTime");
26311 if let Some(p) = precision {
26312 self.write(&format!("({})", p));
26313 }
26314 }
26315 Some(DialectType::TSQL) => {
26316 if *timezone {
26317 self.write_keyword("DATETIMEOFFSET");
26318 } else {
26319 self.write_keyword("DATETIME2");
26320 }
26321 if let Some(p) = precision {
26322 self.write(&format!("({})", p));
26323 }
26324 }
26325 Some(DialectType::MySQL) => {
26326 self.write_keyword("TIMESTAMP");
26328 if let Some(p) = precision {
26329 self.write(&format!("({})", p));
26330 }
26331 }
26332 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
26333 self.write_keyword("DATETIME");
26335 if let Some(p) = precision {
26336 self.write(&format!("({})", p));
26337 }
26338 }
26339 Some(DialectType::BigQuery) => {
26340 if *timezone {
26342 self.write_keyword("TIMESTAMP");
26343 } else {
26344 self.write_keyword("DATETIME");
26345 }
26346 }
26347 Some(DialectType::DuckDB) => {
26348 if *timezone {
26350 self.write_keyword("TIMESTAMPTZ");
26351 } else {
26352 self.write_keyword("TIMESTAMP");
26353 if let Some(p) = precision {
26354 self.write(&format!("({})", p));
26355 }
26356 }
26357 }
26358 _ => {
26359 if *timezone && !self.config.tz_to_with_time_zone {
26360 self.write_keyword("TIMESTAMPTZ");
26362 if let Some(p) = precision {
26363 self.write(&format!("({})", p));
26364 }
26365 } else {
26366 self.write_keyword("TIMESTAMP");
26367 if let Some(p) = precision {
26368 self.write(&format!("({})", p));
26369 }
26370 if *timezone {
26371 self.write_space();
26372 self.write_keyword("WITH TIME ZONE");
26373 }
26374 }
26375 }
26376 }
26377 }
26378 DataType::Interval { unit, to } => {
26379 self.write_keyword("INTERVAL");
26380 if let Some(u) = unit {
26381 self.write_space();
26382 self.write_keyword(u);
26383 }
26384 if let Some(t) = to {
26386 self.write_space();
26387 self.write_keyword("TO");
26388 self.write_space();
26389 self.write_keyword(t);
26390 }
26391 }
26392 DataType::Json => {
26393 match self.config.dialect {
26395 Some(DialectType::Oracle) => self.write_keyword("JSON"), Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"), Some(DialectType::MySQL) => self.write_keyword("JSON"),
26398 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
26399 _ => self.write_keyword("JSON"),
26400 }
26401 }
26402 DataType::JsonB => {
26403 match self.config.dialect {
26405 Some(DialectType::PostgreSQL) => self.write_keyword("JSONB"),
26406 Some(DialectType::Doris) => self.write_keyword("JSONB"),
26407 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
26408 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
26409 Some(DialectType::DuckDB) => self.write_keyword("JSON"), _ => self.write_keyword("JSON"), }
26412 }
26413 DataType::Uuid => {
26414 match self.config.dialect {
26416 Some(DialectType::TSQL) => self.write_keyword("UNIQUEIDENTIFIER"),
26417 Some(DialectType::MySQL) => self.write_keyword("CHAR(36)"),
26418 Some(DialectType::Oracle) => self.write_keyword("RAW(16)"),
26419 Some(DialectType::BigQuery)
26420 | Some(DialectType::Spark)
26421 | Some(DialectType::Databricks) => self.write_keyword("STRING"),
26422 _ => self.write_keyword("UUID"),
26423 }
26424 }
26425 DataType::Array {
26426 element_type,
26427 dimension,
26428 } => {
26429 match self.config.dialect {
26431 Some(DialectType::PostgreSQL)
26432 | Some(DialectType::Redshift)
26433 | Some(DialectType::DuckDB) => {
26434 self.generate_data_type(element_type)?;
26436 if let Some(dim) = dimension {
26437 self.write(&format!("[{}]", dim));
26438 } else {
26439 self.write("[]");
26440 }
26441 }
26442 Some(DialectType::BigQuery) => {
26443 self.write_keyword("ARRAY<");
26444 self.generate_data_type(element_type)?;
26445 self.write(">");
26446 }
26447 Some(DialectType::Snowflake)
26448 | Some(DialectType::Presto)
26449 | Some(DialectType::Trino)
26450 | Some(DialectType::ClickHouse) => {
26451 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
26453 self.write("Array(");
26454 } else {
26455 self.write_keyword("ARRAY(");
26456 }
26457 self.generate_data_type(element_type)?;
26458 self.write(")");
26459 }
26460 Some(DialectType::TSQL)
26461 | Some(DialectType::MySQL)
26462 | Some(DialectType::Oracle) => {
26463 match self.config.dialect {
26466 Some(DialectType::MySQL) => self.write_keyword("JSON"),
26467 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
26468 _ => self.write_keyword("JSON"),
26469 }
26470 }
26471 _ => {
26472 self.write_keyword("ARRAY<");
26474 self.generate_data_type(element_type)?;
26475 self.write(">");
26476 }
26477 }
26478 }
26479 DataType::List { element_type } => {
26480 self.generate_data_type(element_type)?;
26482 self.write_keyword(" LIST");
26483 }
26484 DataType::Map {
26485 key_type,
26486 value_type,
26487 } => {
26488 match self.config.dialect {
26490 Some(DialectType::Materialize) => {
26491 self.write_keyword("MAP[");
26493 self.generate_data_type(key_type)?;
26494 self.write(" => ");
26495 self.generate_data_type(value_type)?;
26496 self.write("]");
26497 }
26498 Some(DialectType::Snowflake)
26499 | Some(DialectType::RisingWave)
26500 | Some(DialectType::DuckDB)
26501 | Some(DialectType::Presto)
26502 | Some(DialectType::Trino)
26503 | Some(DialectType::Athena) => {
26504 self.write_keyword("MAP(");
26505 self.generate_data_type(key_type)?;
26506 self.write(", ");
26507 self.generate_data_type(value_type)?;
26508 self.write(")");
26509 }
26510 Some(DialectType::ClickHouse) => {
26511 self.write("Map(");
26514 self.clickhouse_nullable_depth = -1; self.generate_data_type(key_type)?;
26516 self.clickhouse_nullable_depth = 0;
26517 self.write(", ");
26518 self.generate_data_type(value_type)?;
26519 self.write(")");
26520 }
26521 _ => {
26522 self.write_keyword("MAP<");
26523 self.generate_data_type(key_type)?;
26524 self.write(", ");
26525 self.generate_data_type(value_type)?;
26526 self.write(">");
26527 }
26528 }
26529 }
26530 DataType::Vector {
26531 element_type,
26532 dimension,
26533 } => {
26534 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
26535 self.write_keyword("VECTOR(");
26537 if let Some(dim) = dimension {
26538 self.write(&dim.to_string());
26539 }
26540 let type_alias = element_type.as_ref().and_then(|et| match et.as_ref() {
26542 DataType::TinyInt { .. } => Some("I8"),
26543 DataType::SmallInt { .. } => Some("I16"),
26544 DataType::Int { .. } => Some("I32"),
26545 DataType::BigInt { .. } => Some("I64"),
26546 DataType::Float { .. } => Some("F32"),
26547 DataType::Double { .. } => Some("F64"),
26548 _ => None,
26549 });
26550 if let Some(alias) = type_alias {
26551 if dimension.is_some() {
26552 self.write(", ");
26553 }
26554 self.write(alias);
26555 }
26556 self.write(")");
26557 } else {
26558 self.write_keyword("VECTOR(");
26560 if let Some(ref et) = element_type {
26561 self.generate_data_type(et)?;
26562 if dimension.is_some() {
26563 self.write(", ");
26564 }
26565 }
26566 if let Some(dim) = dimension {
26567 self.write(&dim.to_string());
26568 }
26569 self.write(")");
26570 }
26571 }
26572 DataType::Object { fields, modifier } => {
26573 self.write_keyword("OBJECT(");
26574 for (i, (name, dt, not_null)) in fields.iter().enumerate() {
26575 if i > 0 {
26576 self.write(", ");
26577 }
26578 self.write(name);
26579 self.write(" ");
26580 self.generate_data_type(dt)?;
26581 if *not_null {
26582 self.write_keyword(" NOT NULL");
26583 }
26584 }
26585 self.write(")");
26586 if let Some(mod_str) = modifier {
26587 self.write(" ");
26588 self.write_keyword(mod_str);
26589 }
26590 }
26591 DataType::Struct { fields, nested } => {
26592 match self.config.dialect {
26594 Some(DialectType::Snowflake) => {
26595 self.write_keyword("OBJECT(");
26597 for (i, field) in fields.iter().enumerate() {
26598 if i > 0 {
26599 self.write(", ");
26600 }
26601 if !field.name.is_empty() {
26602 self.write(&field.name);
26603 self.write(" ");
26604 }
26605 self.generate_data_type(&field.data_type)?;
26606 }
26607 self.write(")");
26608 }
26609 Some(DialectType::Presto) | Some(DialectType::Trino) => {
26610 self.write_keyword("ROW(");
26612 for (i, field) in fields.iter().enumerate() {
26613 if i > 0 {
26614 self.write(", ");
26615 }
26616 if !field.name.is_empty() {
26617 self.write(&field.name);
26618 self.write(" ");
26619 }
26620 self.generate_data_type(&field.data_type)?;
26621 }
26622 self.write(")");
26623 }
26624 Some(DialectType::DuckDB) => {
26625 self.write_keyword("STRUCT(");
26627 for (i, field) in fields.iter().enumerate() {
26628 if i > 0 {
26629 self.write(", ");
26630 }
26631 if !field.name.is_empty() {
26632 self.write(&field.name);
26633 self.write(" ");
26634 }
26635 self.generate_data_type(&field.data_type)?;
26636 }
26637 self.write(")");
26638 }
26639 Some(DialectType::ClickHouse) => {
26640 self.write("Tuple(");
26642 for (i, field) in fields.iter().enumerate() {
26643 if i > 0 {
26644 self.write(", ");
26645 }
26646 if !field.name.is_empty() {
26647 self.write(&field.name);
26648 self.write(" ");
26649 }
26650 self.generate_data_type(&field.data_type)?;
26651 }
26652 self.write(")");
26653 }
26654 Some(DialectType::SingleStore) => {
26655 self.write_keyword("RECORD(");
26657 for (i, field) in fields.iter().enumerate() {
26658 if i > 0 {
26659 self.write(", ");
26660 }
26661 if !field.name.is_empty() {
26662 self.write(&field.name);
26663 self.write(" ");
26664 }
26665 self.generate_data_type(&field.data_type)?;
26666 }
26667 self.write(")");
26668 }
26669 _ => {
26670 let force_angle_brackets = matches!(
26672 self.config.dialect,
26673 Some(DialectType::Hive)
26674 | Some(DialectType::Spark)
26675 | Some(DialectType::Databricks)
26676 );
26677 if *nested && !force_angle_brackets {
26678 self.write_keyword("STRUCT(");
26679 for (i, field) in fields.iter().enumerate() {
26680 if i > 0 {
26681 self.write(", ");
26682 }
26683 if !field.name.is_empty() {
26684 self.write(&field.name);
26685 self.write(" ");
26686 }
26687 self.generate_data_type(&field.data_type)?;
26688 }
26689 self.write(")");
26690 } else {
26691 self.write_keyword("STRUCT<");
26692 for (i, field) in fields.iter().enumerate() {
26693 if i > 0 {
26694 self.write(", ");
26695 }
26696 if !field.name.is_empty() {
26697 self.write(&field.name);
26699 self.write(self.config.struct_field_sep);
26700 }
26701 self.generate_data_type(&field.data_type)?;
26703 if let Some(comment) = &field.comment {
26705 self.write(" COMMENT '");
26706 self.write(comment);
26707 self.write("'");
26708 }
26709 if !field.options.is_empty() {
26711 self.write(" ");
26712 self.generate_options_clause(&field.options)?;
26713 }
26714 }
26715 self.write(">");
26716 }
26717 }
26718 }
26719 }
26720 DataType::Enum {
26721 values,
26722 assignments,
26723 } => {
26724 if self.config.dialect == Some(DialectType::ClickHouse) {
26727 self.write("Enum(");
26728 } else {
26729 self.write_keyword("ENUM(");
26730 }
26731 for (i, val) in values.iter().enumerate() {
26732 if i > 0 {
26733 self.write(", ");
26734 }
26735 self.write("'");
26736 self.write(val);
26737 self.write("'");
26738 if let Some(Some(assignment)) = assignments.get(i) {
26739 self.write(" = ");
26740 self.write(assignment);
26741 }
26742 }
26743 self.write(")");
26744 }
26745 DataType::Set { values } => {
26746 self.write_keyword("SET(");
26748 for (i, val) in values.iter().enumerate() {
26749 if i > 0 {
26750 self.write(", ");
26751 }
26752 self.write("'");
26753 self.write(val);
26754 self.write("'");
26755 }
26756 self.write(")");
26757 }
26758 DataType::Union { fields } => {
26759 self.write_keyword("UNION(");
26761 for (i, (name, dt)) in fields.iter().enumerate() {
26762 if i > 0 {
26763 self.write(", ");
26764 }
26765 if !name.is_empty() {
26766 self.write(name);
26767 self.write(" ");
26768 }
26769 self.generate_data_type(dt)?;
26770 }
26771 self.write(")");
26772 }
26773 DataType::Nullable { inner } => {
26774 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
26776 self.write("Nullable(");
26777 let saved_depth = self.clickhouse_nullable_depth;
26779 self.clickhouse_nullable_depth = -1;
26780 self.generate_data_type(inner)?;
26781 self.clickhouse_nullable_depth = saved_depth;
26782 self.write(")");
26783 } else {
26784 match inner.as_ref() {
26786 DataType::Custom { name } if name.eq_ignore_ascii_case("DATETIME") => {
26787 self.generate_data_type(&DataType::Timestamp {
26788 precision: None,
26789 timezone: false,
26790 })?;
26791 }
26792 _ => {
26793 self.generate_data_type(inner)?;
26794 }
26795 }
26796 }
26797 }
26798 DataType::Custom { name } => {
26799 let name_upper = name.to_ascii_uppercase();
26801 match self.config.dialect {
26802 Some(DialectType::ClickHouse) => {
26803 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
26804 (name_upper[..idx].to_string(), &name[idx..])
26805 } else {
26806 (name_upper.clone(), "")
26807 };
26808 let mapped = match base_upper.as_str() {
26809 "DATETIME" | "TIMESTAMPTZ" | "TIMESTAMP" | "TIMESTAMPNTZ"
26810 | "SMALLDATETIME" | "DATETIME2" => "DateTime",
26811 "DATETIME64" => "DateTime64",
26812 "DATE32" => "Date32",
26813 "INT" => "Int32",
26814 "MEDIUMINT" => "Int32",
26815 "INT8" => "Int8",
26816 "INT16" => "Int16",
26817 "INT32" => "Int32",
26818 "INT64" => "Int64",
26819 "INT128" => "Int128",
26820 "INT256" => "Int256",
26821 "UINT8" => "UInt8",
26822 "UINT16" => "UInt16",
26823 "UINT32" => "UInt32",
26824 "UINT64" => "UInt64",
26825 "UINT128" => "UInt128",
26826 "UINT256" => "UInt256",
26827 "FLOAT32" => "Float32",
26828 "FLOAT64" => "Float64",
26829 "DECIMAL32" => "Decimal32",
26830 "DECIMAL64" => "Decimal64",
26831 "DECIMAL128" => "Decimal128",
26832 "DECIMAL256" => "Decimal256",
26833 "ENUM" => "Enum",
26834 "ENUM8" => "Enum8",
26835 "ENUM16" => "Enum16",
26836 "FIXEDSTRING" => "FixedString",
26837 "NESTED" => "Nested",
26838 "LOWCARDINALITY" => "LowCardinality",
26839 "NULLABLE" => "Nullable",
26840 "IPV4" => "IPv4",
26841 "IPV6" => "IPv6",
26842 "POINT" => "Point",
26843 "RING" => "Ring",
26844 "LINESTRING" => "LineString",
26845 "MULTILINESTRING" => "MultiLineString",
26846 "POLYGON" => "Polygon",
26847 "MULTIPOLYGON" => "MultiPolygon",
26848 "AGGREGATEFUNCTION" => "AggregateFunction",
26849 "SIMPLEAGGREGATEFUNCTION" => "SimpleAggregateFunction",
26850 "DYNAMIC" => "Dynamic",
26851 _ => "",
26852 };
26853 if mapped.is_empty() {
26854 self.write(name);
26855 } else {
26856 self.write(mapped);
26857 if matches!(base_upper.as_str(), "ENUM8" | "ENUM16")
26858 && !suffix.is_empty()
26859 {
26860 let escaped_suffix = suffix
26861 .replace('\\', "\\\\")
26862 .replace('\t', "\\t")
26863 .replace('\n', "\\n")
26864 .replace('\r', "\\r");
26865 self.write(&escaped_suffix);
26866 } else {
26867 self.write(suffix);
26868 }
26869 }
26870 }
26871 Some(DialectType::MySQL)
26872 if name_upper == "TIMESTAMPTZ" || name_upper == "TIMESTAMPLTZ" =>
26873 {
26874 self.write_keyword("TIMESTAMP");
26876 }
26877 Some(DialectType::Snowflake) => {
26878 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
26879 (name_upper[..idx].to_string(), &name[idx..])
26880 } else {
26881 (name_upper.clone(), "")
26882 };
26883
26884 match base_upper.as_str() {
26885 "TIMESTAMPNTZ" | "TIMESTAMP_NTZ" => {
26886 self.write_keyword("TIMESTAMPNTZ");
26887 self.write(suffix);
26888 }
26889 "TIMESTAMPLTZ" | "TIMESTAMP_LTZ" => {
26890 self.write_keyword("TIMESTAMPLTZ");
26891 self.write(suffix);
26892 }
26893 "TIMESTAMPTZ" | "TIMESTAMP_TZ" => {
26894 self.write_keyword("TIMESTAMPTZ");
26895 self.write(suffix);
26896 }
26897 _ => self.write(name),
26898 }
26899 }
26900 Some(DialectType::Fabric) => {
26901 let (base_upper, args_str) = if let Some(idx) = name.find('(') {
26902 (name_upper[..idx].to_string(), Some(&name[idx..]))
26903 } else {
26904 (name_upper.clone(), None)
26905 };
26906
26907 match base_upper.as_str() {
26908 "NVARCHAR" => {
26909 self.write_keyword("VARCHAR");
26910 if let Some(args) = args_str {
26911 self.write(args);
26912 }
26913 }
26914 "NCHAR" => {
26915 self.write_keyword("CHAR");
26916 if let Some(args) = args_str {
26917 self.write(args);
26918 }
26919 }
26920 _ => self.write(name),
26921 }
26922 }
26923 Some(DialectType::TSQL) if name_upper == "VARIANT" => {
26924 self.write_keyword("SQL_VARIANT");
26925 }
26926 Some(DialectType::DuckDB) if name_upper == "DECFLOAT" => {
26927 self.write_keyword("DECIMAL(38, 5)");
26928 }
26929 Some(DialectType::Exasol) => {
26930 match name_upper.as_str() {
26932 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => self.write_keyword("VARCHAR"),
26934 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => self.write_keyword("VARCHAR"),
26936 "MEDIUMINT" => self.write_keyword("INT"),
26938 "DECIMAL32" | "DECIMAL64" | "DECIMAL128" | "DECIMAL256" => {
26940 self.write_keyword("DECIMAL")
26941 }
26942 "DATETIME" => self.write_keyword("TIMESTAMP"),
26944 "TIMESTAMPLTZ" => self.write_keyword("TIMESTAMP WITH LOCAL TIME ZONE"),
26945 _ => self.write(name),
26946 }
26947 }
26948 Some(DialectType::Dremio) => {
26949 match name_upper.as_str() {
26951 "TIMESTAMPNTZ" | "DATETIME" => self.write_keyword("TIMESTAMP"),
26952 "ARRAY" => self.write_keyword("LIST"),
26953 "NCHAR" => self.write_keyword("VARCHAR"),
26954 _ => self.write(name),
26955 }
26956 }
26957 _ => {
26959 let (base_upper, _args_str) = if let Some(idx) = name_upper.find('(') {
26961 (name_upper[..idx].to_string(), Some(&name[idx..]))
26962 } else {
26963 (name_upper.clone(), None)
26964 };
26965
26966 match base_upper.as_str() {
26967 "INT64"
26968 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
26969 {
26970 self.write_keyword("BIGINT");
26971 }
26972 "FLOAT64"
26973 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
26974 {
26975 self.write_keyword("DOUBLE");
26976 }
26977 "BOOL"
26978 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
26979 {
26980 self.write_keyword("BOOLEAN");
26981 }
26982 "BYTES"
26983 if matches!(
26984 self.config.dialect,
26985 Some(DialectType::Spark)
26986 | Some(DialectType::Hive)
26987 | Some(DialectType::Databricks)
26988 ) =>
26989 {
26990 self.write_keyword("BINARY");
26991 }
26992 "BYTES"
26993 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
26994 {
26995 self.write_keyword("VARBINARY");
26996 }
26997 "DATETIME2" | "SMALLDATETIME"
26999 if !matches!(
27000 self.config.dialect,
27001 Some(DialectType::TSQL) | Some(DialectType::Fabric)
27002 ) =>
27003 {
27004 if matches!(
27006 self.config.dialect,
27007 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
27008 ) {
27009 self.write_keyword("TIMESTAMP");
27010 if let Some(args) = _args_str {
27011 self.write(args);
27012 }
27013 } else {
27014 self.write_keyword("TIMESTAMP");
27015 }
27016 }
27017 "DATETIMEOFFSET"
27019 if !matches!(
27020 self.config.dialect,
27021 Some(DialectType::TSQL) | Some(DialectType::Fabric)
27022 ) =>
27023 {
27024 if matches!(
27025 self.config.dialect,
27026 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
27027 ) {
27028 self.write_keyword("TIMESTAMPTZ");
27029 if let Some(args) = _args_str {
27030 self.write(args);
27031 }
27032 } else {
27033 self.write_keyword("TIMESTAMPTZ");
27034 }
27035 }
27036 "UNIQUEIDENTIFIER"
27038 if !matches!(
27039 self.config.dialect,
27040 Some(DialectType::TSQL) | Some(DialectType::Fabric)
27041 ) =>
27042 {
27043 match self.config.dialect {
27044 Some(DialectType::Spark)
27045 | Some(DialectType::Databricks)
27046 | Some(DialectType::Hive) => self.write_keyword("STRING"),
27047 _ => self.write_keyword("UUID"),
27048 }
27049 }
27050 "BIT"
27052 if !matches!(
27053 self.config.dialect,
27054 Some(DialectType::TSQL)
27055 | Some(DialectType::Fabric)
27056 | Some(DialectType::PostgreSQL)
27057 | Some(DialectType::MySQL)
27058 | Some(DialectType::DuckDB)
27059 ) =>
27060 {
27061 self.write_keyword("BOOLEAN");
27062 }
27063 "NVARCHAR"
27065 if !matches!(
27066 self.config.dialect,
27067 Some(DialectType::TSQL) | Some(DialectType::Fabric)
27068 ) =>
27069 {
27070 match self.config.dialect {
27071 Some(DialectType::Oracle) => {
27072 self.write_keyword("NVARCHAR2");
27074 if let Some(args) = _args_str {
27075 self.write(args);
27076 }
27077 }
27078 Some(DialectType::BigQuery) => {
27079 self.write_keyword("STRING");
27081 }
27082 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
27083 self.write_keyword("TEXT");
27084 if let Some(args) = _args_str {
27085 self.write(args);
27086 }
27087 }
27088 Some(DialectType::Hive) => {
27089 self.write_keyword("STRING");
27091 }
27092 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
27093 if _args_str.is_some() {
27094 self.write_keyword("VARCHAR");
27095 self.write(_args_str.unwrap());
27096 } else {
27097 self.write_keyword("STRING");
27098 }
27099 }
27100 _ => {
27101 self.write_keyword("VARCHAR");
27102 if let Some(args) = _args_str {
27103 self.write(args);
27104 }
27105 }
27106 }
27107 }
27108 "NCHAR"
27110 if !matches!(
27111 self.config.dialect,
27112 Some(DialectType::TSQL) | Some(DialectType::Fabric)
27113 ) =>
27114 {
27115 match self.config.dialect {
27116 Some(DialectType::Oracle) => {
27117 self.write_keyword("NCHAR");
27119 if let Some(args) = _args_str {
27120 self.write(args);
27121 }
27122 }
27123 Some(DialectType::BigQuery) => {
27124 self.write_keyword("STRING");
27126 }
27127 Some(DialectType::Hive) => {
27128 self.write_keyword("STRING");
27130 }
27131 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
27132 self.write_keyword("TEXT");
27133 if let Some(args) = _args_str {
27134 self.write(args);
27135 }
27136 }
27137 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
27138 if _args_str.is_some() {
27139 self.write_keyword("CHAR");
27140 self.write(_args_str.unwrap());
27141 } else {
27142 self.write_keyword("STRING");
27143 }
27144 }
27145 _ => {
27146 self.write_keyword("CHAR");
27147 if let Some(args) = _args_str {
27148 self.write(args);
27149 }
27150 }
27151 }
27152 }
27153 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => match self.config.dialect {
27156 Some(DialectType::MySQL)
27157 | Some(DialectType::SingleStore)
27158 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
27159 Some(DialectType::Spark)
27160 | Some(DialectType::Databricks)
27161 | Some(DialectType::Hive) => self.write_keyword("TEXT"),
27162 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
27163 Some(DialectType::Presto)
27164 | Some(DialectType::Trino)
27165 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
27166 Some(DialectType::Snowflake)
27167 | Some(DialectType::Redshift)
27168 | Some(DialectType::Dremio) => self.write_keyword("VARCHAR"),
27169 _ => self.write_keyword("TEXT"),
27170 },
27171 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => match self.config.dialect {
27174 Some(DialectType::MySQL)
27175 | Some(DialectType::SingleStore)
27176 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
27177 Some(DialectType::Spark)
27178 | Some(DialectType::Databricks)
27179 | Some(DialectType::Hive) => self.write_keyword("BLOB"),
27180 Some(DialectType::DuckDB) => self.write_keyword("VARBINARY"),
27181 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
27182 Some(DialectType::Presto)
27183 | Some(DialectType::Trino)
27184 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
27185 Some(DialectType::Snowflake)
27186 | Some(DialectType::Redshift)
27187 | Some(DialectType::Dremio) => self.write_keyword("VARBINARY"),
27188 _ => self.write_keyword("BLOB"),
27189 },
27190 "LONGVARCHAR" => match self.config.dialect {
27192 Some(DialectType::SQLite) => self.write_keyword("TEXT"),
27193 _ => self.write_keyword("VARCHAR"),
27194 },
27195 "DATETIME" => {
27197 match self.config.dialect {
27198 Some(DialectType::MySQL)
27199 | Some(DialectType::Doris)
27200 | Some(DialectType::StarRocks)
27201 | Some(DialectType::TSQL)
27202 | Some(DialectType::Fabric)
27203 | Some(DialectType::BigQuery)
27204 | Some(DialectType::SQLite)
27205 | Some(DialectType::Snowflake) => {
27206 self.write_keyword("DATETIME");
27207 if let Some(args) = _args_str {
27208 self.write(args);
27209 }
27210 }
27211 Some(_) => {
27212 self.write_keyword("TIMESTAMP");
27214 if let Some(args) = _args_str {
27215 self.write(args);
27216 }
27217 }
27218 None => {
27219 self.write(name);
27221 }
27222 }
27223 }
27224 "VARCHAR2"
27226 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
27227 {
27228 match self.config.dialect {
27229 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
27230 self.write_keyword("TEXT");
27231 }
27232 Some(DialectType::Hive)
27233 | Some(DialectType::Spark)
27234 | Some(DialectType::Databricks)
27235 | Some(DialectType::BigQuery)
27236 | Some(DialectType::ClickHouse)
27237 | Some(DialectType::StarRocks)
27238 | Some(DialectType::Doris) => {
27239 self.write_keyword("STRING");
27240 }
27241 _ => {
27242 self.write_keyword("VARCHAR");
27243 if let Some(args) = _args_str {
27244 self.write(args);
27245 }
27246 }
27247 }
27248 }
27249 "NVARCHAR2"
27250 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
27251 {
27252 match self.config.dialect {
27253 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
27254 self.write_keyword("TEXT");
27255 }
27256 Some(DialectType::Hive)
27257 | Some(DialectType::Spark)
27258 | Some(DialectType::Databricks)
27259 | Some(DialectType::BigQuery)
27260 | Some(DialectType::ClickHouse)
27261 | Some(DialectType::StarRocks)
27262 | Some(DialectType::Doris) => {
27263 self.write_keyword("STRING");
27264 }
27265 _ => {
27266 self.write_keyword("VARCHAR");
27267 if let Some(args) = _args_str {
27268 self.write(args);
27269 }
27270 }
27271 }
27272 }
27273 _ => self.write(name),
27274 }
27275 }
27276 }
27277 }
27278 DataType::Geometry { subtype, srid } => {
27279 match self.config.dialect {
27281 Some(DialectType::MySQL) => {
27282 if let Some(sub) = subtype {
27284 self.write_keyword(sub);
27285 if let Some(s) = srid {
27286 self.write(" SRID ");
27287 self.write(&s.to_string());
27288 }
27289 } else {
27290 self.write_keyword("GEOMETRY");
27291 }
27292 }
27293 Some(DialectType::BigQuery) => {
27294 self.write_keyword("GEOGRAPHY");
27296 }
27297 Some(DialectType::Teradata) => {
27298 self.write_keyword("ST_GEOMETRY");
27300 if subtype.is_some() || srid.is_some() {
27301 self.write("(");
27302 if let Some(sub) = subtype {
27303 self.write_keyword(sub);
27304 }
27305 if let Some(s) = srid {
27306 if subtype.is_some() {
27307 self.write(", ");
27308 }
27309 self.write(&s.to_string());
27310 }
27311 self.write(")");
27312 }
27313 }
27314 _ => {
27315 self.write_keyword("GEOMETRY");
27317 if subtype.is_some() || srid.is_some() {
27318 self.write("(");
27319 if let Some(sub) = subtype {
27320 self.write_keyword(sub);
27321 }
27322 if let Some(s) = srid {
27323 if subtype.is_some() {
27324 self.write(", ");
27325 }
27326 self.write(&s.to_string());
27327 }
27328 self.write(")");
27329 }
27330 }
27331 }
27332 }
27333 DataType::Geography { subtype, srid } => {
27334 match self.config.dialect {
27336 Some(DialectType::MySQL) => {
27337 if let Some(sub) = subtype {
27339 self.write_keyword(sub);
27340 } else {
27341 self.write_keyword("GEOMETRY");
27342 }
27343 let effective_srid = srid.unwrap_or(4326);
27345 self.write(" SRID ");
27346 self.write(&effective_srid.to_string());
27347 }
27348 Some(DialectType::BigQuery) => {
27349 self.write_keyword("GEOGRAPHY");
27351 }
27352 Some(DialectType::Snowflake) => {
27353 self.write_keyword("GEOGRAPHY");
27355 }
27356 _ => {
27357 self.write_keyword("GEOGRAPHY");
27359 if subtype.is_some() || srid.is_some() {
27360 self.write("(");
27361 if let Some(sub) = subtype {
27362 self.write_keyword(sub);
27363 }
27364 if let Some(s) = srid {
27365 if subtype.is_some() {
27366 self.write(", ");
27367 }
27368 self.write(&s.to_string());
27369 }
27370 self.write(")");
27371 }
27372 }
27373 }
27374 }
27375 DataType::CharacterSet { name } => {
27376 self.write_keyword("CHAR CHARACTER SET ");
27378 self.write(name);
27379 }
27380 _ => self.write("UNKNOWN"),
27381 }
27382 Ok(())
27383 }
27384
27385 #[inline]
27388 fn write(&mut self, s: &str) {
27389 self.output.push_str(s);
27390 }
27391
27392 #[inline]
27393 fn write_space(&mut self) {
27394 self.output.push(' ');
27395 }
27396
27397 #[inline]
27398 fn write_keyword(&mut self, keyword: &str) {
27399 if self.config.uppercase_keywords {
27400 self.output.push_str(keyword);
27401 } else {
27402 for b in keyword.bytes() {
27403 self.output.push(b.to_ascii_lowercase() as char);
27404 }
27405 }
27406 }
27407
27408 fn write_func_name(&mut self, name: &str) {
27410 let normalized = self.normalize_func_name(name);
27411 self.output.push_str(normalized.as_ref());
27412 }
27413
27414 fn convert_strptime_to_exasol_format(format: &str) -> String {
27418 let mut result = String::new();
27419 let chars: Vec<char> = format.chars().collect();
27420 let mut i = 0;
27421 while i < chars.len() {
27422 if chars[i] == '%' && i + 1 < chars.len() {
27423 let spec = chars[i + 1];
27424 let exasol_spec = match spec {
27425 'Y' => "YYYY",
27426 'y' => "YY",
27427 'm' => "MM",
27428 'd' => "DD",
27429 'H' => "HH",
27430 'M' => "MI",
27431 'S' => "SS",
27432 'a' => "DY", 'A' => "DAY", 'b' => "MON", 'B' => "MONTH", 'I' => "H12", 'u' => "ID", 'V' => "IW", 'G' => "IYYY", 'W' => "UW", 'U' => "UW", 'z' => "Z", _ => {
27444 result.push('%');
27446 result.push(spec);
27447 i += 2;
27448 continue;
27449 }
27450 };
27451 result.push_str(exasol_spec);
27452 i += 2;
27453 } else {
27454 result.push(chars[i]);
27455 i += 1;
27456 }
27457 }
27458 result
27459 }
27460
27461 fn convert_strptime_to_postgres_format(format: &str) -> String {
27465 let mut result = String::new();
27466 let chars: Vec<char> = format.chars().collect();
27467 let mut i = 0;
27468 while i < chars.len() {
27469 if chars[i] == '%' && i + 1 < chars.len() {
27470 if chars[i + 1] == '-' && i + 2 < chars.len() {
27472 let spec = chars[i + 2];
27473 let pg_spec = match spec {
27474 'd' => "FMDD",
27475 'm' => "FMMM",
27476 'H' => "FMHH24",
27477 'M' => "FMMI",
27478 'S' => "FMSS",
27479 _ => {
27480 result.push('%');
27481 result.push('-');
27482 result.push(spec);
27483 i += 3;
27484 continue;
27485 }
27486 };
27487 result.push_str(pg_spec);
27488 i += 3;
27489 continue;
27490 }
27491 let spec = chars[i + 1];
27492 let pg_spec = match spec {
27493 'Y' => "YYYY",
27494 'y' => "YY",
27495 'm' => "MM",
27496 'd' => "DD",
27497 'H' => "HH24",
27498 'I' => "HH12",
27499 'M' => "MI",
27500 'S' => "SS",
27501 'f' => "US", 'u' => "D", 'j' => "DDD", 'z' => "OF", 'Z' => "TZ", 'A' => "TMDay", 'a' => "TMDy", 'b' => "TMMon", 'B' => "TMMonth", 'U' => "WW", _ => {
27512 result.push('%');
27514 result.push(spec);
27515 i += 2;
27516 continue;
27517 }
27518 };
27519 result.push_str(pg_spec);
27520 i += 2;
27521 } else {
27522 result.push(chars[i]);
27523 i += 1;
27524 }
27525 }
27526 result
27527 }
27528
27529 fn write_limit_expr(&mut self, expr: &Expression) -> Result<()> {
27531 if self.config.limit_only_literals {
27532 if let Some(value) = Self::try_evaluate_constant(expr) {
27533 self.write(&value.to_string());
27534 return Ok(());
27535 }
27536 }
27537 self.generate_expression(expr)
27538 }
27539
27540 fn is_noop_limit_expr(expr: &Expression) -> bool {
27541 match expr {
27542 Expression::Null(_) => true,
27543 Expression::Identifier(identifier) => identifier.name.eq_ignore_ascii_case("ALL"),
27544 Expression::Column(column) => {
27545 column.table.is_none() && column.name.name.eq_ignore_ascii_case("ALL")
27546 }
27547 Expression::Var(var) => var.this.eq_ignore_ascii_case("ALL"),
27548 Expression::Paren(paren) => Self::is_noop_limit_expr(&paren.this),
27549 _ => false,
27550 }
27551 }
27552
27553 fn write_formatted_comment(&mut self, comment: &str) {
27557 let content = if comment.starts_with("/*") && comment.ends_with("*/") {
27560 &comment[2..comment.len() - 2]
27563 } else if comment.starts_with("--") {
27564 &comment[2..]
27567 } else {
27568 comment
27570 };
27571 if content.trim().is_empty() {
27573 return;
27574 }
27575 let sanitized = content.replace("*/", "* /").replace("/*", "/ *");
27578 let content = &sanitized;
27579 self.output.push_str("/*");
27581 if !content.starts_with(' ') {
27582 self.output.push(' ');
27583 }
27584 self.output.push_str(content);
27585 if !content.ends_with(' ') {
27586 self.output.push(' ');
27587 }
27588 self.output.push_str("*/");
27589 }
27590
27591 fn escape_block_for_single_quote(&self, block: &str) -> String {
27594 let escape_backslash = matches!(
27595 self.config.dialect,
27596 Some(crate::dialects::DialectType::Snowflake)
27597 );
27598 let mut escaped = String::with_capacity(block.len() + 4);
27599 for ch in block.chars() {
27600 if ch == '\'' {
27601 escaped.push('\\');
27602 escaped.push('\'');
27603 } else if escape_backslash && ch == '\\' {
27604 escaped.push('\\');
27605 escaped.push('\\');
27606 } else {
27607 escaped.push(ch);
27608 }
27609 }
27610 escaped
27611 }
27612
27613 fn write_newline(&mut self) {
27614 self.output.push('\n');
27615 }
27616
27617 fn write_indent(&mut self) {
27618 for _ in 0..self.indent_level {
27619 self.output.push_str(self.config.indent);
27620 }
27621 }
27622
27623 fn too_wide(&self, args: &[String]) -> bool {
27629 args.iter().map(|s| s.len()).sum::<usize>() > self.config.max_text_width
27630 }
27631
27632 fn generate_to_string(&self, expr: &Expression) -> Result<String> {
27635 let config = GeneratorConfig {
27636 pretty: false,
27637 dialect: self.config.dialect,
27638 ..Default::default()
27639 };
27640 let mut gen = Generator::with_config(config);
27641 gen.generate_expression(expr)?;
27642 Ok(gen.output)
27643 }
27644
27645 fn write_clause_condition(&mut self, keyword: &str, condition: &Expression) -> Result<()> {
27648 if self.config.pretty {
27649 self.write_newline();
27650 self.write_indent();
27651 self.write_keyword(keyword);
27652 self.write_newline();
27653 self.indent_level += 1;
27654 self.write_indent();
27655 self.generate_expression(condition)?;
27656 self.indent_level -= 1;
27657 } else {
27658 self.write_space();
27659 self.write_keyword(keyword);
27660 self.write_space();
27661 self.generate_expression(condition)?;
27662 }
27663 Ok(())
27664 }
27665
27666 fn write_clause_expressions(&mut self, keyword: &str, exprs: &[Expression]) -> Result<()> {
27669 if exprs.is_empty() {
27670 return Ok(());
27671 }
27672
27673 if self.config.pretty {
27674 self.write_newline();
27675 self.write_indent();
27676 self.write_keyword(keyword);
27677 self.write_newline();
27678 self.indent_level += 1;
27679 for (i, expr) in exprs.iter().enumerate() {
27680 if i > 0 {
27681 self.write(",");
27682 self.write_newline();
27683 }
27684 self.write_indent();
27685 self.generate_expression(expr)?;
27686 }
27687 self.indent_level -= 1;
27688 } else {
27689 self.write_space();
27690 self.write_keyword(keyword);
27691 self.write_space();
27692 for (i, expr) in exprs.iter().enumerate() {
27693 if i > 0 {
27694 self.write(", ");
27695 }
27696 self.generate_expression(expr)?;
27697 }
27698 }
27699 Ok(())
27700 }
27701
27702 fn write_order_clause(&mut self, keyword: &str, orderings: &[Ordered]) -> Result<()> {
27704 if orderings.is_empty() {
27705 return Ok(());
27706 }
27707
27708 if self.config.pretty {
27709 self.write_newline();
27710 self.write_indent();
27711 self.write_keyword(keyword);
27712 self.write_newline();
27713 self.indent_level += 1;
27714 for (i, ordered) in orderings.iter().enumerate() {
27715 if i > 0 {
27716 self.write(",");
27717 self.write_newline();
27718 }
27719 self.write_indent();
27720 self.generate_ordered(ordered)?;
27721 }
27722 self.indent_level -= 1;
27723 } else {
27724 self.write_space();
27725 self.write_keyword(keyword);
27726 self.write_space();
27727 for (i, ordered) in orderings.iter().enumerate() {
27728 if i > 0 {
27729 self.write(", ");
27730 }
27731 self.generate_ordered(ordered)?;
27732 }
27733 }
27734 Ok(())
27735 }
27736
27737 fn write_window_clause(&mut self, windows: &[NamedWindow]) -> Result<()> {
27739 if windows.is_empty() {
27740 return Ok(());
27741 }
27742
27743 if self.config.pretty {
27744 self.write_newline();
27745 self.write_indent();
27746 self.write_keyword("WINDOW");
27747 self.write_newline();
27748 self.indent_level += 1;
27749 for (i, named_window) in windows.iter().enumerate() {
27750 if i > 0 {
27751 self.write(",");
27752 self.write_newline();
27753 }
27754 self.write_indent();
27755 self.generate_identifier(&named_window.name)?;
27756 self.write_space();
27757 self.write_keyword("AS");
27758 self.write(" (");
27759 self.generate_over(&named_window.spec)?;
27760 self.write(")");
27761 }
27762 self.indent_level -= 1;
27763 } else {
27764 self.write_space();
27765 self.write_keyword("WINDOW");
27766 self.write_space();
27767 for (i, named_window) in windows.iter().enumerate() {
27768 if i > 0 {
27769 self.write(", ");
27770 }
27771 self.generate_identifier(&named_window.name)?;
27772 self.write_space();
27773 self.write_keyword("AS");
27774 self.write(" (");
27775 self.generate_over(&named_window.spec)?;
27776 self.write(")");
27777 }
27778 }
27779 Ok(())
27780 }
27781
27782 fn generate_ai_agg(&mut self, e: &AIAgg) -> Result<()> {
27784 self.write_keyword("AI_AGG");
27786 self.write("(");
27787 self.generate_expression(&e.this)?;
27788 self.write(", ");
27789 self.generate_expression(&e.expression)?;
27790 self.write(")");
27791 Ok(())
27792 }
27793
27794 fn generate_ai_classify(&mut self, e: &AIClassify) -> Result<()> {
27795 self.write_keyword("AI_CLASSIFY");
27797 self.write("(");
27798 self.generate_expression(&e.this)?;
27799 if let Some(categories) = &e.categories {
27800 self.write(", ");
27801 self.generate_expression(categories)?;
27802 }
27803 if let Some(config) = &e.config {
27804 self.write(", ");
27805 self.generate_expression(config)?;
27806 }
27807 self.write(")");
27808 Ok(())
27809 }
27810
27811 fn generate_add_partition(&mut self, e: &AddPartition) -> Result<()> {
27812 self.write_keyword("ADD");
27814 self.write_space();
27815 if e.exists {
27816 self.write_keyword("IF NOT EXISTS");
27817 self.write_space();
27818 }
27819 self.generate_expression(&e.this)?;
27820 if let Some(location) = &e.location {
27821 self.write_space();
27822 self.generate_expression(location)?;
27823 }
27824 Ok(())
27825 }
27826
27827 fn generate_algorithm_property(&mut self, e: &AlgorithmProperty) -> Result<()> {
27828 self.write_keyword("ALGORITHM");
27830 self.write("=");
27831 self.generate_expression(&e.this)?;
27832 Ok(())
27833 }
27834
27835 fn generate_aliases(&mut self, e: &Aliases) -> Result<()> {
27836 self.generate_expression(&e.this)?;
27838 self.write_space();
27839 self.write_keyword("AS");
27840 self.write(" (");
27841 for (i, expr) in e.expressions.iter().enumerate() {
27842 if i > 0 {
27843 self.write(", ");
27844 }
27845 self.generate_expression(expr)?;
27846 }
27847 self.write(")");
27848 Ok(())
27849 }
27850
27851 fn generate_allowed_values_property(&mut self, e: &AllowedValuesProperty) -> Result<()> {
27852 self.write_keyword("ALLOWED_VALUES");
27854 self.write_space();
27855 for (i, expr) in e.expressions.iter().enumerate() {
27856 if i > 0 {
27857 self.write(", ");
27858 }
27859 self.generate_expression(expr)?;
27860 }
27861 Ok(())
27862 }
27863
27864 fn generate_alter_column(&mut self, e: &AlterColumn) -> Result<()> {
27865 self.write_keyword("ALTER COLUMN");
27867 self.write_space();
27868 self.generate_expression(&e.this)?;
27869
27870 if let Some(dtype) = &e.dtype {
27871 self.write_space();
27872 self.write_keyword("SET DATA TYPE");
27873 self.write_space();
27874 self.generate_expression(dtype)?;
27875 if let Some(collate) = &e.collate {
27876 self.write_space();
27877 self.write_keyword("COLLATE");
27878 self.write_space();
27879 self.generate_expression(collate)?;
27880 }
27881 if let Some(using) = &e.using {
27882 self.write_space();
27883 self.write_keyword("USING");
27884 self.write_space();
27885 self.generate_expression(using)?;
27886 }
27887 } else if let Some(default) = &e.default {
27888 self.write_space();
27889 self.write_keyword("SET DEFAULT");
27890 self.write_space();
27891 self.generate_expression(default)?;
27892 } else if let Some(comment) = &e.comment {
27893 self.write_space();
27894 self.write_keyword("COMMENT");
27895 self.write_space();
27896 self.generate_expression(comment)?;
27897 } else if let Some(drop) = &e.drop {
27898 self.write_space();
27899 self.write_keyword("DROP");
27900 self.write_space();
27901 self.generate_expression(drop)?;
27902 } else if let Some(visible) = &e.visible {
27903 self.write_space();
27904 self.generate_expression(visible)?;
27905 } else if let Some(rename_to) = &e.rename_to {
27906 self.write_space();
27907 self.write_keyword("RENAME TO");
27908 self.write_space();
27909 self.generate_expression(rename_to)?;
27910 } else if let Some(allow_null) = &e.allow_null {
27911 self.write_space();
27912 self.generate_expression(allow_null)?;
27913 }
27914 Ok(())
27915 }
27916
27917 fn generate_alter_session(&mut self, e: &AlterSession) -> Result<()> {
27918 self.write_keyword("ALTER SESSION");
27920 self.write_space();
27921 if e.unset.is_some() {
27922 self.write_keyword("UNSET");
27923 } else {
27924 self.write_keyword("SET");
27925 }
27926 self.write_space();
27927 for (i, expr) in e.expressions.iter().enumerate() {
27928 if i > 0 {
27929 self.write(", ");
27930 }
27931 self.generate_expression(expr)?;
27932 }
27933 Ok(())
27934 }
27935
27936 fn generate_alter_set(&mut self, e: &AlterSet) -> Result<()> {
27937 self.write_keyword("SET");
27939
27940 if let Some(opt) = &e.option {
27942 self.write_space();
27943 self.generate_expression(opt)?;
27944 }
27945
27946 if !e.expressions.is_empty() {
27949 let is_properties = e
27951 .expressions
27952 .iter()
27953 .any(|expr| matches!(expr, Expression::Eq(_)));
27954 if is_properties && e.option.is_none() {
27955 self.write_space();
27956 self.write_keyword("PROPERTIES");
27957 }
27958 self.write_space();
27959 for (i, expr) in e.expressions.iter().enumerate() {
27960 if i > 0 {
27961 self.write(", ");
27962 }
27963 self.generate_expression(expr)?;
27964 }
27965 }
27966
27967 if let Some(file_format) = &e.file_format {
27969 self.write(" ");
27970 self.write_keyword("STAGE_FILE_FORMAT");
27971 self.write(" = (");
27972 self.generate_space_separated_properties(file_format)?;
27973 self.write(")");
27974 }
27975
27976 if let Some(copy_options) = &e.copy_options {
27978 self.write(" ");
27979 self.write_keyword("STAGE_COPY_OPTIONS");
27980 self.write(" = (");
27981 self.generate_space_separated_properties(copy_options)?;
27982 self.write(")");
27983 }
27984
27985 if let Some(tag) = &e.tag {
27987 self.write(" ");
27988 self.write_keyword("TAG");
27989 self.write(" ");
27990 self.generate_expression(tag)?;
27991 }
27992
27993 Ok(())
27994 }
27995
27996 fn generate_space_separated_properties(&mut self, expr: &Expression) -> Result<()> {
27998 match expr {
27999 Expression::Tuple(t) => {
28000 for (i, prop) in t.expressions.iter().enumerate() {
28001 if i > 0 {
28002 self.write(" ");
28003 }
28004 self.generate_expression(prop)?;
28005 }
28006 }
28007 _ => {
28008 self.generate_expression(expr)?;
28009 }
28010 }
28011 Ok(())
28012 }
28013
28014 fn generate_alter_sort_key(&mut self, e: &AlterSortKey) -> Result<()> {
28015 self.write_keyword("ALTER");
28017 if e.compound.is_some() {
28018 self.write_space();
28019 self.write_keyword("COMPOUND");
28020 }
28021 self.write_space();
28022 self.write_keyword("SORTKEY");
28023 self.write_space();
28024 if let Some(this) = &e.this {
28025 self.generate_expression(this)?;
28026 } else if !e.expressions.is_empty() {
28027 self.write("(");
28028 for (i, expr) in e.expressions.iter().enumerate() {
28029 if i > 0 {
28030 self.write(", ");
28031 }
28032 self.generate_expression(expr)?;
28033 }
28034 self.write(")");
28035 }
28036 Ok(())
28037 }
28038
28039 fn generate_analyze(&mut self, e: &Analyze) -> Result<()> {
28040 self.write_keyword("ANALYZE");
28042 if !e.options.is_empty() {
28043 self.write_space();
28044 for (i, opt) in e.options.iter().enumerate() {
28045 if i > 0 {
28046 self.write_space();
28047 }
28048 if let Expression::Identifier(id) = opt {
28050 self.write_keyword(&id.name);
28051 } else {
28052 self.generate_expression(opt)?;
28053 }
28054 }
28055 }
28056 if let Some(kind) = &e.kind {
28057 self.write_space();
28058 self.write_keyword(kind);
28059 }
28060 if let Some(this) = &e.this {
28061 self.write_space();
28062 self.generate_expression(this)?;
28063 }
28064 if !e.columns.is_empty() {
28066 self.write("(");
28067 for (i, col) in e.columns.iter().enumerate() {
28068 if i > 0 {
28069 self.write(", ");
28070 }
28071 self.write(col);
28072 }
28073 self.write(")");
28074 }
28075 if let Some(partition) = &e.partition {
28076 self.write_space();
28077 self.generate_expression(partition)?;
28078 }
28079 if let Some(mode) = &e.mode {
28080 self.write_space();
28081 self.generate_expression(mode)?;
28082 }
28083 if let Some(expression) = &e.expression {
28084 self.write_space();
28085 self.generate_expression(expression)?;
28086 }
28087 if !e.properties.is_empty() {
28088 self.write_space();
28089 self.write_keyword(self.config.with_properties_prefix);
28090 self.write(" (");
28091 for (i, prop) in e.properties.iter().enumerate() {
28092 if i > 0 {
28093 self.write(", ");
28094 }
28095 self.generate_expression(prop)?;
28096 }
28097 self.write(")");
28098 }
28099 Ok(())
28100 }
28101
28102 fn generate_analyze_delete(&mut self, e: &AnalyzeDelete) -> Result<()> {
28103 self.write_keyword("DELETE");
28105 if let Some(kind) = &e.kind {
28106 self.write_space();
28107 self.write_keyword(kind);
28108 }
28109 self.write_space();
28110 self.write_keyword("STATISTICS");
28111 Ok(())
28112 }
28113
28114 fn generate_analyze_histogram(&mut self, e: &AnalyzeHistogram) -> Result<()> {
28115 if let Expression::Identifier(id) = e.this.as_ref() {
28118 self.write_keyword(&id.name);
28119 } else {
28120 self.generate_expression(&e.this)?;
28121 }
28122 self.write_space();
28123 self.write_keyword("HISTOGRAM ON");
28124 self.write_space();
28125 for (i, expr) in e.expressions.iter().enumerate() {
28126 if i > 0 {
28127 self.write(", ");
28128 }
28129 self.generate_expression(expr)?;
28130 }
28131 if let Some(expression) = &e.expression {
28132 self.write_space();
28133 self.generate_expression(expression)?;
28134 }
28135 if let Some(update_options) = &e.update_options {
28136 self.write_space();
28137 self.generate_expression(update_options)?;
28138 self.write_space();
28139 self.write_keyword("UPDATE");
28140 }
28141 Ok(())
28142 }
28143
28144 fn generate_analyze_list_chained_rows(&mut self, e: &AnalyzeListChainedRows) -> Result<()> {
28145 self.write_keyword("LIST CHAINED ROWS");
28147 if let Some(expression) = &e.expression {
28148 self.write_space();
28149 self.write_keyword("INTO");
28150 self.write_space();
28151 self.generate_expression(expression)?;
28152 }
28153 Ok(())
28154 }
28155
28156 fn generate_analyze_sample(&mut self, e: &AnalyzeSample) -> Result<()> {
28157 self.write_keyword("SAMPLE");
28159 self.write_space();
28160 if let Some(sample) = &e.sample {
28161 self.generate_expression(sample)?;
28162 self.write_space();
28163 }
28164 self.write_keyword(&e.kind);
28165 Ok(())
28166 }
28167
28168 fn generate_analyze_statistics(&mut self, e: &AnalyzeStatistics) -> Result<()> {
28169 self.write_keyword(&e.kind);
28171 if let Some(option) = &e.option {
28172 self.write_space();
28173 self.generate_expression(option)?;
28174 }
28175 self.write_space();
28176 self.write_keyword("STATISTICS");
28177 if let Some(this) = &e.this {
28178 self.write_space();
28179 self.generate_expression(this)?;
28180 }
28181 if !e.expressions.is_empty() {
28182 self.write_space();
28183 for (i, expr) in e.expressions.iter().enumerate() {
28184 if i > 0 {
28185 self.write(", ");
28186 }
28187 self.generate_expression(expr)?;
28188 }
28189 }
28190 Ok(())
28191 }
28192
28193 fn generate_analyze_validate(&mut self, e: &AnalyzeValidate) -> Result<()> {
28194 self.write_keyword("VALIDATE");
28196 self.write_space();
28197 self.write_keyword(&e.kind);
28198 if let Some(this) = &e.this {
28199 self.write_space();
28200 if let Expression::Identifier(id) = this.as_ref() {
28202 self.write_keyword(&id.name);
28203 } else {
28204 self.generate_expression(this)?;
28205 }
28206 }
28207 if let Some(expression) = &e.expression {
28208 self.write_space();
28209 self.write_keyword("INTO");
28210 self.write_space();
28211 self.generate_expression(expression)?;
28212 }
28213 Ok(())
28214 }
28215
28216 fn generate_analyze_with(&mut self, e: &AnalyzeWith) -> Result<()> {
28217 self.write_keyword("WITH");
28219 self.write_space();
28220 for (i, expr) in e.expressions.iter().enumerate() {
28221 if i > 0 {
28222 self.write(", ");
28223 }
28224 self.generate_expression(expr)?;
28225 }
28226 Ok(())
28227 }
28228
28229 fn generate_anonymous(&mut self, e: &Anonymous) -> Result<()> {
28230 self.generate_expression(&e.this)?;
28233 self.write("(");
28234 for (i, arg) in e.expressions.iter().enumerate() {
28235 if i > 0 {
28236 self.write(", ");
28237 }
28238 self.generate_expression(arg)?;
28239 }
28240 self.write(")");
28241 Ok(())
28242 }
28243
28244 fn generate_anonymous_agg_func(&mut self, e: &AnonymousAggFunc) -> Result<()> {
28245 self.generate_expression(&e.this)?;
28247 self.write("(");
28248 for (i, arg) in e.expressions.iter().enumerate() {
28249 if i > 0 {
28250 self.write(", ");
28251 }
28252 self.generate_expression(arg)?;
28253 }
28254 self.write(")");
28255 Ok(())
28256 }
28257
28258 fn generate_apply(&mut self, e: &Apply) -> Result<()> {
28259 self.generate_expression(&e.this)?;
28261 self.write_space();
28262 self.write_keyword("APPLY");
28263 self.write("(");
28264 self.generate_expression(&e.expression)?;
28265 self.write(")");
28266 Ok(())
28267 }
28268
28269 fn generate_approx_percentile_estimate(&mut self, e: &ApproxPercentileEstimate) -> Result<()> {
28270 self.write_keyword("APPROX_PERCENTILE_ESTIMATE");
28272 self.write("(");
28273 self.generate_expression(&e.this)?;
28274 if let Some(percentile) = &e.percentile {
28275 self.write(", ");
28276 self.generate_expression(percentile)?;
28277 }
28278 self.write(")");
28279 Ok(())
28280 }
28281
28282 fn generate_approx_quantile(&mut self, e: &ApproxQuantile) -> Result<()> {
28283 self.write_keyword("APPROX_QUANTILE");
28285 self.write("(");
28286 self.generate_expression(&e.this)?;
28287 if let Some(quantile) = &e.quantile {
28288 self.write(", ");
28289 self.generate_expression(quantile)?;
28290 }
28291 if let Some(accuracy) = &e.accuracy {
28292 self.write(", ");
28293 self.generate_expression(accuracy)?;
28294 }
28295 if let Some(weight) = &e.weight {
28296 self.write(", ");
28297 self.generate_expression(weight)?;
28298 }
28299 self.write(")");
28300 Ok(())
28301 }
28302
28303 fn generate_approx_quantiles(&mut self, e: &ApproxQuantiles) -> Result<()> {
28304 self.write_keyword("APPROX_QUANTILES");
28306 self.write("(");
28307 self.generate_expression(&e.this)?;
28308 if let Some(expression) = &e.expression {
28309 self.write(", ");
28310 self.generate_expression(expression)?;
28311 }
28312 self.write(")");
28313 Ok(())
28314 }
28315
28316 fn generate_approx_top_k(&mut self, e: &ApproxTopK) -> Result<()> {
28317 self.write_keyword("APPROX_TOP_K");
28319 self.write("(");
28320 self.generate_expression(&e.this)?;
28321 if let Some(expression) = &e.expression {
28322 self.write(", ");
28323 self.generate_expression(expression)?;
28324 }
28325 if let Some(counters) = &e.counters {
28326 self.write(", ");
28327 self.generate_expression(counters)?;
28328 }
28329 self.write(")");
28330 Ok(())
28331 }
28332
28333 fn generate_approx_top_k_accumulate(&mut self, e: &ApproxTopKAccumulate) -> Result<()> {
28334 self.write_keyword("APPROX_TOP_K_ACCUMULATE");
28336 self.write("(");
28337 self.generate_expression(&e.this)?;
28338 if let Some(expression) = &e.expression {
28339 self.write(", ");
28340 self.generate_expression(expression)?;
28341 }
28342 self.write(")");
28343 Ok(())
28344 }
28345
28346 fn generate_approx_top_k_combine(&mut self, e: &ApproxTopKCombine) -> Result<()> {
28347 self.write_keyword("APPROX_TOP_K_COMBINE");
28349 self.write("(");
28350 self.generate_expression(&e.this)?;
28351 if let Some(expression) = &e.expression {
28352 self.write(", ");
28353 self.generate_expression(expression)?;
28354 }
28355 self.write(")");
28356 Ok(())
28357 }
28358
28359 fn generate_approx_top_k_estimate(&mut self, e: &ApproxTopKEstimate) -> Result<()> {
28360 self.write_keyword("APPROX_TOP_K_ESTIMATE");
28362 self.write("(");
28363 self.generate_expression(&e.this)?;
28364 if let Some(expression) = &e.expression {
28365 self.write(", ");
28366 self.generate_expression(expression)?;
28367 }
28368 self.write(")");
28369 Ok(())
28370 }
28371
28372 fn generate_approx_top_sum(&mut self, e: &ApproxTopSum) -> Result<()> {
28373 self.write_keyword("APPROX_TOP_SUM");
28375 self.write("(");
28376 self.generate_expression(&e.this)?;
28377 self.write(", ");
28378 self.generate_expression(&e.expression)?;
28379 if let Some(count) = &e.count {
28380 self.write(", ");
28381 self.generate_expression(count)?;
28382 }
28383 self.write(")");
28384 Ok(())
28385 }
28386
28387 fn generate_arg_max(&mut self, e: &ArgMax) -> Result<()> {
28388 self.write_keyword("ARG_MAX");
28390 self.write("(");
28391 self.generate_expression(&e.this)?;
28392 self.write(", ");
28393 self.generate_expression(&e.expression)?;
28394 if let Some(count) = &e.count {
28395 self.write(", ");
28396 self.generate_expression(count)?;
28397 }
28398 self.write(")");
28399 Ok(())
28400 }
28401
28402 fn generate_arg_min(&mut self, e: &ArgMin) -> Result<()> {
28403 self.write_keyword("ARG_MIN");
28405 self.write("(");
28406 self.generate_expression(&e.this)?;
28407 self.write(", ");
28408 self.generate_expression(&e.expression)?;
28409 if let Some(count) = &e.count {
28410 self.write(", ");
28411 self.generate_expression(count)?;
28412 }
28413 self.write(")");
28414 Ok(())
28415 }
28416
28417 fn generate_array_all(&mut self, e: &ArrayAll) -> Result<()> {
28418 self.write_keyword("ARRAY_ALL");
28420 self.write("(");
28421 self.generate_expression(&e.this)?;
28422 self.write(", ");
28423 self.generate_expression(&e.expression)?;
28424 self.write(")");
28425 Ok(())
28426 }
28427
28428 fn generate_array_any(&mut self, e: &ArrayAny) -> Result<()> {
28429 self.write_keyword("ARRAY_ANY");
28431 self.write("(");
28432 self.generate_expression(&e.this)?;
28433 self.write(", ");
28434 self.generate_expression(&e.expression)?;
28435 self.write(")");
28436 Ok(())
28437 }
28438
28439 fn generate_array_construct_compact(&mut self, e: &ArrayConstructCompact) -> Result<()> {
28440 self.write_keyword("ARRAY_CONSTRUCT_COMPACT");
28442 self.write("(");
28443 for (i, expr) in e.expressions.iter().enumerate() {
28444 if i > 0 {
28445 self.write(", ");
28446 }
28447 self.generate_expression(expr)?;
28448 }
28449 self.write(")");
28450 Ok(())
28451 }
28452
28453 fn generate_array_sum(&mut self, e: &ArraySum) -> Result<()> {
28454 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
28456 self.write("arraySum");
28457 } else {
28458 self.write_keyword("ARRAY_SUM");
28459 }
28460 self.write("(");
28461 self.generate_expression(&e.this)?;
28462 if let Some(expression) = &e.expression {
28463 self.write(", ");
28464 self.generate_expression(expression)?;
28465 }
28466 self.write(")");
28467 Ok(())
28468 }
28469
28470 fn generate_at_index(&mut self, e: &AtIndex) -> Result<()> {
28471 self.generate_expression(&e.this)?;
28473 self.write_space();
28474 self.write_keyword("AT");
28475 self.write_space();
28476 self.generate_expression(&e.expression)?;
28477 Ok(())
28478 }
28479
28480 fn generate_attach(&mut self, e: &Attach) -> Result<()> {
28481 self.write_keyword("ATTACH");
28483 if e.exists {
28484 self.write_space();
28485 self.write_keyword("IF NOT EXISTS");
28486 }
28487 self.write_space();
28488 self.generate_expression(&e.this)?;
28489 if !e.expressions.is_empty() {
28490 self.write(" (");
28491 for (i, expr) in e.expressions.iter().enumerate() {
28492 if i > 0 {
28493 self.write(", ");
28494 }
28495 self.generate_expression(expr)?;
28496 }
28497 self.write(")");
28498 }
28499 Ok(())
28500 }
28501
28502 fn generate_attach_option(&mut self, e: &AttachOption) -> Result<()> {
28503 self.generate_expression(&e.this)?;
28506 if let Some(expression) = &e.expression {
28507 self.write_space();
28508 self.generate_expression(expression)?;
28509 }
28510 Ok(())
28511 }
28512
28513 fn generate_auto_increment_keyword(
28517 &mut self,
28518 col: &crate::expressions::ColumnDef,
28519 ) -> Result<()> {
28520 use crate::dialects::DialectType;
28521 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
28522 self.write_keyword("IDENTITY");
28523 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
28524 self.write("(");
28525 if let Some(ref start) = col.auto_increment_start {
28526 self.generate_expression(start)?;
28527 } else {
28528 self.write("0");
28529 }
28530 self.write(", ");
28531 if let Some(ref inc) = col.auto_increment_increment {
28532 self.generate_expression(inc)?;
28533 } else {
28534 self.write("1");
28535 }
28536 self.write(")");
28537 }
28538 } else if matches!(
28539 self.config.dialect,
28540 Some(DialectType::Snowflake) | Some(DialectType::SQLite)
28541 ) {
28542 self.write_keyword("AUTOINCREMENT");
28543 if let Some(ref start) = col.auto_increment_start {
28544 self.write_space();
28545 self.write_keyword("START");
28546 self.write_space();
28547 self.generate_expression(start)?;
28548 }
28549 if let Some(ref inc) = col.auto_increment_increment {
28550 self.write_space();
28551 self.write_keyword("INCREMENT");
28552 self.write_space();
28553 self.generate_expression(inc)?;
28554 }
28555 if let Some(order) = col.auto_increment_order {
28556 self.write_space();
28557 if order {
28558 self.write_keyword("ORDER");
28559 } else {
28560 self.write_keyword("NOORDER");
28561 }
28562 }
28563 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
28564 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
28565 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
28566 self.write(" (");
28567 let mut first = true;
28568 if let Some(ref start) = col.auto_increment_start {
28569 self.write_keyword("START WITH");
28570 self.write_space();
28571 self.generate_expression(start)?;
28572 first = false;
28573 }
28574 if let Some(ref inc) = col.auto_increment_increment {
28575 if !first {
28576 self.write_space();
28577 }
28578 self.write_keyword("INCREMENT BY");
28579 self.write_space();
28580 self.generate_expression(inc)?;
28581 }
28582 self.write(")");
28583 }
28584 } else if matches!(self.config.dialect, Some(DialectType::Databricks)) {
28585 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
28588 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
28589 } else {
28590 self.write_keyword("GENERATED ALWAYS AS IDENTITY");
28591 }
28592 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
28593 self.write(" (");
28594 let mut first = true;
28595 if let Some(ref start) = col.auto_increment_start {
28596 self.write_keyword("START WITH");
28597 self.write_space();
28598 self.generate_expression(start)?;
28599 first = false;
28600 }
28601 if let Some(ref inc) = col.auto_increment_increment {
28602 if !first {
28603 self.write_space();
28604 }
28605 self.write_keyword("INCREMENT BY");
28606 self.write_space();
28607 self.generate_expression(inc)?;
28608 }
28609 self.write(")");
28610 }
28611 } else if matches!(
28612 self.config.dialect,
28613 Some(DialectType::TSQL) | Some(DialectType::Fabric)
28614 ) {
28615 self.write_keyword("IDENTITY");
28616 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
28617 self.write("(");
28618 if let Some(ref start) = col.auto_increment_start {
28619 self.generate_expression(start)?;
28620 } else {
28621 self.write("0");
28622 }
28623 self.write(", ");
28624 if let Some(ref inc) = col.auto_increment_increment {
28625 self.generate_expression(inc)?;
28626 } else {
28627 self.write("1");
28628 }
28629 self.write(")");
28630 }
28631 } else {
28632 self.write_keyword("AUTO_INCREMENT");
28633 if let Some(ref start) = col.auto_increment_start {
28634 self.write_space();
28635 self.write_keyword("START");
28636 self.write_space();
28637 self.generate_expression(start)?;
28638 }
28639 if let Some(ref inc) = col.auto_increment_increment {
28640 self.write_space();
28641 self.write_keyword("INCREMENT");
28642 self.write_space();
28643 self.generate_expression(inc)?;
28644 }
28645 if let Some(order) = col.auto_increment_order {
28646 self.write_space();
28647 if order {
28648 self.write_keyword("ORDER");
28649 } else {
28650 self.write_keyword("NOORDER");
28651 }
28652 }
28653 }
28654 Ok(())
28655 }
28656
28657 fn generate_tidb_auto_random(&mut self, auto_random: &TiDBAutoRandom) -> Result<()> {
28658 let is_tidb = matches!(self.config.dialect, Some(DialectType::TiDB));
28659 let is_mysql = matches!(self.config.dialect, Some(DialectType::MySQL));
28660
28661 if !is_tidb && !is_mysql {
28662 return self
28663 .write_unsupported_comment("AUTO_RANDOM is only supported by the TiDB dialect");
28664 }
28665 if is_mysql {
28666 self.unsupported("MySQL ignores TiDB AUTO_RANDOM executable comments")?;
28667 }
28668
28669 let use_comment = auto_random.executable_comment || is_mysql;
28670 if use_comment {
28671 self.write("/*T![auto_rand] ");
28672 }
28673 self.write_keyword("AUTO_RANDOM");
28674 if let Some(shard_bits) = auto_random.shard_bits {
28675 self.write("(");
28676 self.write(&shard_bits.to_string());
28677 if let Some(range_bits) = auto_random.range_bits {
28678 self.write(", ");
28679 self.write(&range_bits.to_string());
28680 }
28681 self.write(")");
28682 }
28683 if use_comment {
28684 self.write(" */");
28685 }
28686 Ok(())
28687 }
28688
28689 fn generate_tidb_table_option(&mut self, option: &TiDBTableOption, force: bool) -> Result<()> {
28690 let is_tidb = matches!(self.config.dialect, Some(DialectType::TiDB));
28691 let is_mysql = matches!(self.config.dialect, Some(DialectType::MySQL));
28692 if !is_tidb && !is_mysql {
28693 return self.write_unsupported_comment(
28694 "TiDB table options are not supported by the target dialect",
28695 );
28696 }
28697 if is_mysql {
28698 self.unsupported("MySQL ignores TiDB table-option executable comments")?;
28699 }
28700
28701 let use_comment = option.executable_comment || is_mysql;
28702 if use_comment {
28703 match option.kind {
28704 TiDBTableOptionKind::Ttl { .. }
28705 | TiDBTableOptionKind::TtlEnable { .. }
28706 | TiDBTableOptionKind::TtlJobInterval { .. } => self.write("/*T![ttl] "),
28707 TiDBTableOptionKind::PlacementPolicy { .. } => self.write("/*T![placement] "),
28708 _ => self.write("/*T! "),
28709 }
28710 }
28711 if force {
28712 self.write_keyword("FORCE");
28713 self.write_space();
28714 }
28715 match &option.kind {
28716 TiDBTableOptionKind::ShardRowIdBits { bits } => {
28717 self.write_keyword("SHARD_ROW_ID_BITS");
28718 self.write("=");
28719 self.write(&bits.to_string());
28720 }
28721 TiDBTableOptionKind::PreSplitRegions { regions } => {
28722 self.write_keyword("PRE_SPLIT_REGIONS");
28723 self.write("=");
28724 self.write(®ions.to_string());
28725 }
28726 TiDBTableOptionKind::AutoRandomBase { value } => {
28727 self.write_keyword("AUTO_RANDOM_BASE");
28728 self.write("=");
28729 self.write(&value.to_string());
28730 }
28731 TiDBTableOptionKind::PlacementPolicy { policy } => {
28732 self.write_keyword("PLACEMENT POLICY");
28733 self.write("=");
28734 if let Some(policy) = policy {
28735 self.generate_identifier(policy)?;
28736 } else {
28737 self.write_keyword("DEFAULT");
28738 }
28739 }
28740 TiDBTableOptionKind::Ttl {
28741 column,
28742 interval,
28743 enabled,
28744 } => {
28745 self.write_keyword("TTL");
28746 self.write("=");
28747 self.generate_identifier(column)?;
28748 self.write(" + ");
28749 self.generate_tidb_ttl_interval(interval)?;
28750 if let Some(enabled) = enabled {
28751 self.write_space();
28752 self.write_keyword("TTL_ENABLE");
28753 self.write("='");
28754 self.write(if *enabled { "ON" } else { "OFF" });
28755 self.write("'");
28756 }
28757 }
28758 TiDBTableOptionKind::TtlEnable { enabled } => {
28759 self.write_keyword("TTL_ENABLE");
28760 self.write("='");
28761 self.write(if *enabled { "ON" } else { "OFF" });
28762 self.write("'");
28763 }
28764 TiDBTableOptionKind::TtlJobInterval { interval } => {
28765 self.write_keyword("TTL_JOB_INTERVAL");
28766 self.write("=");
28767 self.generate_string_literal(interval)?;
28768 }
28769 }
28770 if use_comment {
28771 self.write(" */");
28772 }
28773 Ok(())
28774 }
28775
28776 fn generate_tidb_ttl_interval(&mut self, interval: &Interval) -> Result<()> {
28777 self.write_keyword("INTERVAL");
28778 if let Some(value) = &interval.this {
28779 self.write_space();
28780 if let Expression::Literal(literal) = value {
28781 if let Literal::String(value) = literal.as_ref() {
28782 if value.parse::<f64>().is_ok() {
28783 self.write(value);
28784 } else {
28785 self.generate_string_literal(value)?;
28786 }
28787 } else {
28788 self.generate_expression(value)?;
28789 }
28790 } else {
28791 self.generate_expression(value)?;
28792 }
28793 }
28794 if let Some(unit) = &interval.unit {
28795 self.write_space();
28796 self.write_interval_unit_spec(unit)?;
28797 }
28798 Ok(())
28799 }
28800
28801 fn generate_auto_increment_property(&mut self, e: &AutoIncrementProperty) -> Result<()> {
28802 self.write_keyword("AUTO_INCREMENT");
28804 self.write("=");
28805 self.generate_expression(&e.this)?;
28806 Ok(())
28807 }
28808
28809 fn generate_auto_refresh_property(&mut self, e: &AutoRefreshProperty) -> Result<()> {
28810 self.write_keyword("AUTO_REFRESH");
28812 self.write("=");
28813 self.generate_expression(&e.this)?;
28814 Ok(())
28815 }
28816
28817 fn generate_backup_property(&mut self, e: &BackupProperty) -> Result<()> {
28818 self.write_keyword("BACKUP");
28820 self.write_space();
28821 self.generate_expression(&e.this)?;
28822 Ok(())
28823 }
28824
28825 fn generate_base64_decode_binary(&mut self, e: &Base64DecodeBinary) -> Result<()> {
28826 self.write_keyword("BASE64_DECODE_BINARY");
28828 self.write("(");
28829 self.generate_expression(&e.this)?;
28830 if let Some(alphabet) = &e.alphabet {
28831 self.write(", ");
28832 self.generate_expression(alphabet)?;
28833 }
28834 self.write(")");
28835 Ok(())
28836 }
28837
28838 fn generate_base64_decode_string(&mut self, e: &Base64DecodeString) -> Result<()> {
28839 self.write_keyword("BASE64_DECODE_STRING");
28841 self.write("(");
28842 self.generate_expression(&e.this)?;
28843 if let Some(alphabet) = &e.alphabet {
28844 self.write(", ");
28845 self.generate_expression(alphabet)?;
28846 }
28847 self.write(")");
28848 Ok(())
28849 }
28850
28851 fn generate_base64_encode(&mut self, e: &Base64Encode) -> Result<()> {
28852 self.write_keyword("BASE64_ENCODE");
28854 self.write("(");
28855 self.generate_expression(&e.this)?;
28856 if let Some(max_line_length) = &e.max_line_length {
28857 self.write(", ");
28858 self.generate_expression(max_line_length)?;
28859 }
28860 if let Some(alphabet) = &e.alphabet {
28861 self.write(", ");
28862 self.generate_expression(alphabet)?;
28863 }
28864 self.write(")");
28865 Ok(())
28866 }
28867
28868 fn generate_block_compression_property(&mut self, e: &BlockCompressionProperty) -> Result<()> {
28869 self.write_keyword("BLOCKCOMPRESSION");
28871 self.write("=");
28872 if let Some(autotemp) = &e.autotemp {
28873 self.write_keyword("AUTOTEMP");
28874 self.write("(");
28875 self.generate_expression(autotemp)?;
28876 self.write(")");
28877 }
28878 if let Some(always) = &e.always {
28879 self.generate_expression(always)?;
28880 }
28881 if let Some(default) = &e.default {
28882 self.generate_expression(default)?;
28883 }
28884 if let Some(manual) = &e.manual {
28885 self.generate_expression(manual)?;
28886 }
28887 if let Some(never) = &e.never {
28888 self.generate_expression(never)?;
28889 }
28890 Ok(())
28891 }
28892
28893 fn generate_booland(&mut self, e: &Booland) -> Result<()> {
28894 self.write("((");
28896 self.generate_expression(&e.this)?;
28897 self.write(") ");
28898 self.write_keyword("AND");
28899 self.write(" (");
28900 self.generate_expression(&e.expression)?;
28901 self.write("))");
28902 Ok(())
28903 }
28904
28905 fn generate_boolor(&mut self, e: &Boolor) -> Result<()> {
28906 self.write("((");
28908 self.generate_expression(&e.this)?;
28909 self.write(") ");
28910 self.write_keyword("OR");
28911 self.write(" (");
28912 self.generate_expression(&e.expression)?;
28913 self.write("))");
28914 Ok(())
28915 }
28916
28917 fn generate_build_property(&mut self, e: &BuildProperty) -> Result<()> {
28918 self.write_keyword("BUILD");
28920 self.write_space();
28921 self.generate_expression(&e.this)?;
28922 Ok(())
28923 }
28924
28925 fn generate_byte_string(&mut self, e: &ByteString) -> Result<()> {
28926 self.generate_expression(&e.this)?;
28928 Ok(())
28929 }
28930
28931 fn generate_case_specific_column_constraint(
28932 &mut self,
28933 e: &CaseSpecificColumnConstraint,
28934 ) -> Result<()> {
28935 if e.not_.is_some() {
28937 self.write_keyword("NOT");
28938 self.write_space();
28939 }
28940 self.write_keyword("CASESPECIFIC");
28941 Ok(())
28942 }
28943
28944 fn generate_cast_to_str_type(&mut self, e: &CastToStrType) -> Result<()> {
28945 self.write_keyword("CAST");
28947 self.write("(");
28948 self.generate_expression(&e.this)?;
28949 if self.config.dialect == Some(DialectType::ClickHouse) {
28950 self.write(", ");
28952 } else {
28953 self.write_space();
28954 self.write_keyword("AS");
28955 self.write_space();
28956 }
28957 if let Some(to) = &e.to {
28958 self.generate_expression(to)?;
28959 }
28960 self.write(")");
28961 Ok(())
28962 }
28963
28964 fn generate_changes(&mut self, e: &Changes) -> Result<()> {
28965 self.write_keyword("CHANGES");
28968 self.write(" (");
28969 if let Some(information) = &e.information {
28970 self.write_keyword("INFORMATION");
28971 self.write(" => ");
28972 self.generate_expression(information)?;
28973 }
28974 self.write(")");
28975 if let Some(at_before) = &e.at_before {
28977 self.write(" ");
28978 self.generate_expression(at_before)?;
28979 }
28980 if let Some(end) = &e.end {
28981 self.write(" ");
28982 self.generate_expression(end)?;
28983 }
28984 Ok(())
28985 }
28986
28987 fn generate_character_set_column_constraint(
28988 &mut self,
28989 e: &CharacterSetColumnConstraint,
28990 ) -> Result<()> {
28991 self.write_keyword("CHARACTER SET");
28993 self.write_space();
28994 self.generate_expression(&e.this)?;
28995 Ok(())
28996 }
28997
28998 fn generate_character_set_property(&mut self, e: &CharacterSetProperty) -> Result<()> {
28999 if e.default.is_some() {
29001 self.write_keyword("DEFAULT");
29002 self.write_space();
29003 }
29004 self.write_keyword("CHARACTER SET");
29005 self.write("=");
29006 self.generate_expression(&e.this)?;
29007 Ok(())
29008 }
29009
29010 fn generate_check_column_constraint(&mut self, e: &CheckColumnConstraint) -> Result<()> {
29011 self.write_keyword("CHECK");
29013 self.write(" (");
29014 self.generate_expression(&e.this)?;
29015 self.write(")");
29016 if e.enforced.is_some() {
29017 self.write_space();
29018 self.write_keyword("ENFORCED");
29019 }
29020 Ok(())
29021 }
29022
29023 fn generate_assume_column_constraint(&mut self, e: &AssumeColumnConstraint) -> Result<()> {
29024 self.write_keyword("ASSUME");
29026 self.write(" (");
29027 self.generate_expression(&e.this)?;
29028 self.write(")");
29029 Ok(())
29030 }
29031
29032 fn generate_check_json(&mut self, e: &CheckJson) -> Result<()> {
29033 self.write_keyword("CHECK_JSON");
29035 self.write("(");
29036 self.generate_expression(&e.this)?;
29037 self.write(")");
29038 Ok(())
29039 }
29040
29041 fn generate_check_xml(&mut self, e: &CheckXml) -> Result<()> {
29042 self.write_keyword("CHECK_XML");
29044 self.write("(");
29045 self.generate_expression(&e.this)?;
29046 self.write(")");
29047 Ok(())
29048 }
29049
29050 fn generate_checksum_property(&mut self, e: &ChecksumProperty) -> Result<()> {
29051 self.write_keyword("CHECKSUM");
29053 self.write("=");
29054 if e.on.is_some() {
29055 self.write_keyword("ON");
29056 } else if e.default.is_some() {
29057 self.write_keyword("DEFAULT");
29058 } else {
29059 self.write_keyword("OFF");
29060 }
29061 Ok(())
29062 }
29063
29064 fn generate_clone(&mut self, e: &Clone) -> Result<()> {
29065 if e.shallow.is_some() {
29067 self.write_keyword("SHALLOW");
29068 self.write_space();
29069 }
29070 if e.copy.is_some() {
29071 self.write_keyword("COPY");
29072 } else {
29073 self.write_keyword("CLONE");
29074 }
29075 self.write_space();
29076 self.generate_expression(&e.this)?;
29077 Ok(())
29078 }
29079
29080 fn generate_cluster_by(&mut self, e: &ClusterBy) -> Result<()> {
29081 self.write_keyword("CLUSTER BY");
29083 self.write(" (");
29084 for (i, ord) in e.expressions.iter().enumerate() {
29085 if i > 0 {
29086 self.write(", ");
29087 }
29088 self.generate_ordered(ord)?;
29089 }
29090 self.write(")");
29091 Ok(())
29092 }
29093
29094 fn generate_cluster_by_columns_property(&mut self, e: &ClusterByColumnsProperty) -> Result<()> {
29095 self.write_keyword("CLUSTER BY");
29097 self.write_space();
29098 for (i, col) in e.columns.iter().enumerate() {
29099 if i > 0 {
29100 self.write(", ");
29101 }
29102 self.generate_identifier(col)?;
29103 }
29104 Ok(())
29105 }
29106
29107 fn generate_clustered_by_property(&mut self, e: &ClusteredByProperty) -> Result<()> {
29108 self.write_keyword("CLUSTERED BY");
29110 self.write(" (");
29111 for (i, expr) in e.expressions.iter().enumerate() {
29112 if i > 0 {
29113 self.write(", ");
29114 }
29115 self.generate_expression(expr)?;
29116 }
29117 self.write(")");
29118 if let Some(sorted_by) = &e.sorted_by {
29119 self.write_space();
29120 self.write_keyword("SORTED BY");
29121 self.write(" (");
29122 if let Expression::Tuple(t) = sorted_by.as_ref() {
29124 for (i, expr) in t.expressions.iter().enumerate() {
29125 if i > 0 {
29126 self.write(", ");
29127 }
29128 self.generate_expression(expr)?;
29129 }
29130 } else {
29131 self.generate_expression(sorted_by)?;
29132 }
29133 self.write(")");
29134 }
29135 if let Some(buckets) = &e.buckets {
29136 self.write_space();
29137 self.write_keyword("INTO");
29138 self.write_space();
29139 self.generate_expression(buckets)?;
29140 self.write_space();
29141 self.write_keyword("BUCKETS");
29142 }
29143 Ok(())
29144 }
29145
29146 fn generate_collate_property(&mut self, e: &CollateProperty) -> Result<()> {
29147 if e.default.is_some() {
29151 self.write_keyword("DEFAULT");
29152 self.write_space();
29153 }
29154 self.write_keyword("COLLATE");
29155 match self.config.dialect {
29157 Some(DialectType::BigQuery) => self.write_space(),
29158 _ => self.write("="),
29159 }
29160 self.generate_expression(&e.this)?;
29161 Ok(())
29162 }
29163
29164 fn generate_column_constraint(&mut self, e: &ColumnConstraint) -> Result<()> {
29165 match e {
29167 ColumnConstraint::NotNull => {
29168 self.write_keyword("NOT NULL");
29169 }
29170 ColumnConstraint::Null => {
29171 self.write_keyword("NULL");
29172 }
29173 ColumnConstraint::Unique => {
29174 self.write_keyword("UNIQUE");
29175 }
29176 ColumnConstraint::PrimaryKey => {
29177 self.write_keyword("PRIMARY KEY");
29178 }
29179 ColumnConstraint::Default(expr) => {
29180 self.write_keyword("DEFAULT");
29181 self.write_space();
29182 self.generate_expression(expr)?;
29183 }
29184 ColumnConstraint::Check(expr) => {
29185 self.write_keyword("CHECK");
29186 self.write(" (");
29187 self.generate_expression(expr)?;
29188 self.write(")");
29189 }
29190 ColumnConstraint::References(fk_ref) => {
29191 if fk_ref.has_foreign_key_keywords {
29192 self.write_keyword("FOREIGN KEY");
29193 self.write_space();
29194 }
29195 self.write_keyword("REFERENCES");
29196 self.write_space();
29197 self.generate_table(&fk_ref.table)?;
29198 if !fk_ref.columns.is_empty() {
29199 self.write(" (");
29200 for (i, col) in fk_ref.columns.iter().enumerate() {
29201 if i > 0 {
29202 self.write(", ");
29203 }
29204 self.generate_identifier(col)?;
29205 }
29206 self.write(")");
29207 }
29208 }
29209 ColumnConstraint::GeneratedAsIdentity(gen) => {
29210 self.write_keyword("GENERATED");
29211 self.write_space();
29212 if gen.always {
29213 self.write_keyword("ALWAYS");
29214 } else {
29215 self.write_keyword("BY DEFAULT");
29216 if gen.on_null {
29217 self.write_space();
29218 self.write_keyword("ON NULL");
29219 }
29220 }
29221 self.write_space();
29222 self.write_keyword("AS IDENTITY");
29223 }
29224 ColumnConstraint::Collate(collation) => {
29225 self.write_keyword("COLLATE");
29226 self.write_space();
29227 self.generate_identifier(collation)?;
29228 }
29229 ColumnConstraint::Comment(comment) => {
29230 self.write_keyword("COMMENT");
29231 self.write(" '");
29232 self.write(comment);
29233 self.write("'");
29234 }
29235 ColumnConstraint::ComputedColumn(cc) => {
29236 self.generate_computed_column_inline(cc)?;
29237 }
29238 ColumnConstraint::GeneratedAsRow(gar) => {
29239 self.generate_generated_as_row_inline(gar)?;
29240 }
29241 ColumnConstraint::Tags(tags) => {
29242 self.write_keyword("TAG");
29243 self.write(" (");
29244 for (i, expr) in tags.expressions.iter().enumerate() {
29245 if i > 0 {
29246 self.write(", ");
29247 }
29248 self.generate_expression(expr)?;
29249 }
29250 self.write(")");
29251 }
29252 ColumnConstraint::Path(path_expr) => {
29253 self.write_keyword("PATH");
29254 self.write_space();
29255 self.generate_expression(path_expr)?;
29256 }
29257 }
29258 Ok(())
29259 }
29260
29261 fn generate_column_position(&mut self, e: &ColumnPosition) -> Result<()> {
29262 match e {
29264 ColumnPosition::First => {
29265 self.write_keyword("FIRST");
29266 }
29267 ColumnPosition::After(ident) => {
29268 self.write_keyword("AFTER");
29269 self.write_space();
29270 self.generate_identifier(ident)?;
29271 }
29272 }
29273 Ok(())
29274 }
29275
29276 fn generate_column_prefix(&mut self, e: &ColumnPrefix) -> Result<()> {
29277 self.generate_expression(&e.this)?;
29279 self.write("(");
29280 self.generate_expression(&e.expression)?;
29281 self.write(")");
29282 Ok(())
29283 }
29284
29285 fn generate_columns(&mut self, e: &Columns) -> Result<()> {
29286 if let Some(ref unpack) = e.unpack {
29289 if let Expression::Boolean(b) = unpack.as_ref() {
29290 if b.value {
29291 self.write("*");
29292 }
29293 }
29294 }
29295 self.write_keyword("COLUMNS");
29296 self.write("(");
29297 self.generate_expression(&e.this)?;
29298 self.write(")");
29299 Ok(())
29300 }
29301
29302 fn generate_combined_agg_func(&mut self, e: &CombinedAggFunc) -> Result<()> {
29303 self.generate_expression(&e.this)?;
29305 self.write("(");
29306 for (i, expr) in e.expressions.iter().enumerate() {
29307 if i > 0 {
29308 self.write(", ");
29309 }
29310 self.generate_expression(expr)?;
29311 }
29312 self.write(")");
29313 Ok(())
29314 }
29315
29316 fn generate_combined_parameterized_agg(&mut self, e: &CombinedParameterizedAgg) -> Result<()> {
29317 self.generate_expression(&e.this)?;
29319 self.write("(");
29320 for (i, param) in e.params.iter().enumerate() {
29321 if i > 0 {
29322 self.write(", ");
29323 }
29324 self.generate_expression(param)?;
29325 }
29326 self.write(")(");
29327 for (i, expr) in e.expressions.iter().enumerate() {
29328 if i > 0 {
29329 self.write(", ");
29330 }
29331 self.generate_expression(expr)?;
29332 }
29333 self.write(")");
29334 Ok(())
29335 }
29336
29337 fn generate_commit(&mut self, e: &Commit) -> Result<()> {
29338 self.write_keyword("COMMIT");
29340
29341 if e.this.is_none()
29343 && matches!(
29344 self.config.dialect,
29345 Some(DialectType::TSQL) | Some(DialectType::Fabric)
29346 )
29347 {
29348 self.write_space();
29349 self.write_keyword("TRANSACTION");
29350 }
29351
29352 if let Some(this) = &e.this {
29354 let is_transaction_marker = matches!(
29356 this.as_ref(),
29357 Expression::Identifier(id) if id.name == "TRANSACTION"
29358 );
29359
29360 self.write_space();
29361 self.write_keyword("TRANSACTION");
29362
29363 if !is_transaction_marker {
29365 self.write_space();
29366 self.generate_expression(this)?;
29367 }
29368 }
29369
29370 if let Some(durability) = &e.durability {
29372 self.write_space();
29373 self.write_keyword("WITH");
29374 self.write(" (");
29375 self.write_keyword("DELAYED_DURABILITY");
29376 self.write(" = ");
29377 if let Expression::Boolean(BooleanLiteral { value: true }) = durability.as_ref() {
29378 self.write_keyword("ON");
29379 } else {
29380 self.write_keyword("OFF");
29381 }
29382 self.write(")");
29383 }
29384
29385 if let Some(chain) = &e.chain {
29387 self.write_space();
29388 if let Expression::Boolean(BooleanLiteral { value: false }) = chain.as_ref() {
29389 self.write_keyword("AND NO CHAIN");
29390 } else {
29391 self.write_keyword("AND CHAIN");
29392 }
29393 }
29394 Ok(())
29395 }
29396
29397 fn generate_comprehension(&mut self, e: &Comprehension) -> Result<()> {
29398 self.write("[");
29400 self.generate_expression(&e.this)?;
29401 self.write_space();
29402 self.write_keyword("FOR");
29403 self.write_space();
29404 self.generate_expression(&e.expression)?;
29405 if let Some(pos) = &e.position {
29407 self.write(", ");
29408 self.generate_expression(pos)?;
29409 }
29410 if let Some(iterator) = &e.iterator {
29411 self.write_space();
29412 self.write_keyword("IN");
29413 self.write_space();
29414 self.generate_expression(iterator)?;
29415 }
29416 if let Some(condition) = &e.condition {
29417 self.write_space();
29418 self.write_keyword("IF");
29419 self.write_space();
29420 self.generate_expression(condition)?;
29421 }
29422 self.write("]");
29423 Ok(())
29424 }
29425
29426 fn generate_compress(&mut self, e: &Compress) -> Result<()> {
29427 self.write_keyword("COMPRESS");
29429 self.write("(");
29430 self.generate_expression(&e.this)?;
29431 if let Some(method) = &e.method {
29432 self.write(", '");
29433 self.write(method);
29434 self.write("'");
29435 }
29436 self.write(")");
29437 Ok(())
29438 }
29439
29440 fn generate_compress_column_constraint(&mut self, e: &CompressColumnConstraint) -> Result<()> {
29441 self.write_keyword("COMPRESS");
29443 if let Some(this) = &e.this {
29444 self.write_space();
29445 self.generate_expression(this)?;
29446 }
29447 Ok(())
29448 }
29449
29450 fn generate_computed_column_constraint(&mut self, e: &ComputedColumnConstraint) -> Result<()> {
29451 self.write_keyword("AS");
29453 self.write_space();
29454 self.generate_expression(&e.this)?;
29455 if e.not_null.is_some() {
29456 self.write_space();
29457 self.write_keyword("PERSISTED NOT NULL");
29458 } else if e.persisted.is_some() {
29459 self.write_space();
29460 self.write_keyword("PERSISTED");
29461 }
29462 Ok(())
29463 }
29464
29465 fn generate_computed_column_inline(&mut self, cc: &ComputedColumn) -> Result<()> {
29469 let computed_expr = if matches!(
29470 self.config.dialect,
29471 Some(DialectType::TSQL) | Some(DialectType::Fabric)
29472 ) {
29473 match &*cc.expression {
29474 Expression::Year(y) if !matches!(&y.this, Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
29475 {
29476 let wrapped = Expression::Cast(Box::new(Cast {
29477 this: y.this.clone(),
29478 to: DataType::Date,
29479 trailing_comments: Vec::new(),
29480 double_colon_syntax: false,
29481 format: None,
29482 default: None,
29483 inferred_type: None,
29484 }));
29485 Expression::Year(Box::new(UnaryFunc::new(wrapped)))
29486 }
29487 Expression::Function(f)
29488 if f.name.eq_ignore_ascii_case("YEAR")
29489 && f.args.len() == 1
29490 && !matches!(&f.args[0], Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
29491 {
29492 let wrapped = Expression::Cast(Box::new(Cast {
29493 this: f.args[0].clone(),
29494 to: DataType::Date,
29495 trailing_comments: Vec::new(),
29496 double_colon_syntax: false,
29497 format: None,
29498 default: None,
29499 inferred_type: None,
29500 }));
29501 Expression::Function(Box::new(Function::new("YEAR".to_string(), vec![wrapped])))
29502 }
29503 _ => *cc.expression.clone(),
29504 }
29505 } else {
29506 *cc.expression.clone()
29507 };
29508
29509 match cc.persistence_kind.as_deref() {
29510 Some("STORED") | Some("VIRTUAL") => {
29511 self.write_keyword("GENERATED ALWAYS AS");
29513 self.write(" (");
29514 self.generate_expression(&computed_expr)?;
29515 self.write(")");
29516 self.write_space();
29517 if cc.persisted {
29518 self.write_keyword("STORED");
29519 } else {
29520 self.write_keyword("VIRTUAL");
29521 }
29522 }
29523 Some("PERSISTED") => {
29524 self.write_keyword("AS");
29526 self.write(" (");
29527 self.generate_expression(&computed_expr)?;
29528 self.write(")");
29529 self.write_space();
29530 self.write_keyword("PERSISTED");
29531 if let Some(ref dt) = cc.data_type {
29533 self.write_space();
29534 self.generate_data_type(dt)?;
29535 }
29536 if cc.not_null {
29537 self.write_space();
29538 self.write_keyword("NOT NULL");
29539 }
29540 }
29541 _ => {
29542 if matches!(
29545 self.config.dialect,
29546 Some(DialectType::Spark)
29547 | Some(DialectType::Databricks)
29548 | Some(DialectType::Hive)
29549 ) {
29550 self.write_keyword("GENERATED ALWAYS AS");
29551 self.write(" (");
29552 self.generate_expression(&computed_expr)?;
29553 self.write(")");
29554 } else if matches!(
29555 self.config.dialect,
29556 Some(DialectType::TSQL) | Some(DialectType::Fabric)
29557 ) {
29558 self.write_keyword("AS");
29559 let omit_parens = matches!(computed_expr, Expression::Year(_))
29560 || matches!(&computed_expr, Expression::Function(f) if f.name.eq_ignore_ascii_case("YEAR"));
29561 if omit_parens {
29562 self.write_space();
29563 self.generate_expression(&computed_expr)?;
29564 } else {
29565 self.write(" (");
29566 self.generate_expression(&computed_expr)?;
29567 self.write(")");
29568 }
29569 } else {
29570 self.write_keyword("AS");
29571 self.write(" (");
29572 self.generate_expression(&computed_expr)?;
29573 self.write(")");
29574 }
29575 }
29576 }
29577 Ok(())
29578 }
29579
29580 fn generate_generated_as_row_inline(&mut self, gar: &GeneratedAsRow) -> Result<()> {
29583 self.write_keyword("GENERATED ALWAYS AS ROW ");
29584 if gar.start {
29585 self.write_keyword("START");
29586 } else {
29587 self.write_keyword("END");
29588 }
29589 if gar.hidden {
29590 self.write_space();
29591 self.write_keyword("HIDDEN");
29592 }
29593 Ok(())
29594 }
29595
29596 fn generate_system_versioning_content(
29598 &mut self,
29599 e: &WithSystemVersioningProperty,
29600 ) -> Result<()> {
29601 let mut parts = Vec::new();
29602
29603 if let Some(this) = &e.this {
29604 let mut s = String::from("HISTORY_TABLE=");
29605 let mut gen = Generator::with_arc_config(self.config.clone());
29606 gen.generate_expression(this)?;
29607 s.push_str(&gen.output);
29608 parts.push(s);
29609 }
29610
29611 if let Some(data_consistency) = &e.data_consistency {
29612 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
29613 let mut gen = Generator::with_arc_config(self.config.clone());
29614 gen.generate_expression(data_consistency)?;
29615 s.push_str(&gen.output);
29616 parts.push(s);
29617 }
29618
29619 if let Some(retention_period) = &e.retention_period {
29620 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
29621 let mut gen = Generator::with_arc_config(self.config.clone());
29622 gen.generate_expression(retention_period)?;
29623 s.push_str(&gen.output);
29624 parts.push(s);
29625 }
29626
29627 self.write_keyword("SYSTEM_VERSIONING");
29628 self.write("=");
29629
29630 if !parts.is_empty() {
29631 self.write_keyword("ON");
29632 self.write("(");
29633 self.write(&parts.join(", "));
29634 self.write(")");
29635 } else if e.on.is_some() {
29636 self.write_keyword("ON");
29637 } else {
29638 self.write_keyword("OFF");
29639 }
29640
29641 Ok(())
29642 }
29643
29644 fn generate_conditional_insert(&mut self, e: &ConditionalInsert) -> Result<()> {
29645 if e.else_.is_some() {
29648 self.write_keyword("ELSE");
29649 self.write_space();
29650 } else if let Some(expression) = &e.expression {
29651 self.write_keyword("WHEN");
29652 self.write_space();
29653 self.generate_expression(expression)?;
29654 self.write_space();
29655 self.write_keyword("THEN");
29656 self.write_space();
29657 }
29658
29659 if let Expression::Insert(insert) = e.this.as_ref() {
29662 self.write_keyword("INTO");
29663 self.write_space();
29664 self.generate_table(&insert.table)?;
29665
29666 if !insert.columns.is_empty() {
29668 self.write(" (");
29669 for (i, col) in insert.columns.iter().enumerate() {
29670 if i > 0 {
29671 self.write(", ");
29672 }
29673 self.generate_identifier(col)?;
29674 }
29675 self.write(")");
29676 }
29677
29678 if !insert.values.is_empty() {
29680 self.write_space();
29681 self.write_keyword("VALUES");
29682 for (row_idx, row) in insert.values.iter().enumerate() {
29683 if row_idx > 0 {
29684 self.write(", ");
29685 }
29686 self.write(" (");
29687 for (i, val) in row.iter().enumerate() {
29688 if i > 0 {
29689 self.write(", ");
29690 }
29691 self.generate_expression(val)?;
29692 }
29693 self.write(")");
29694 }
29695 }
29696 } else {
29697 self.generate_expression(&e.this)?;
29699 }
29700 Ok(())
29701 }
29702
29703 fn generate_constraint(&mut self, e: &Constraint) -> Result<()> {
29704 self.write_keyword("CONSTRAINT");
29706 self.write_space();
29707 self.generate_expression(&e.this)?;
29708 if !e.expressions.is_empty() {
29709 self.write_space();
29710 for (i, expr) in e.expressions.iter().enumerate() {
29711 if i > 0 {
29712 self.write_space();
29713 }
29714 self.generate_expression(expr)?;
29715 }
29716 }
29717 Ok(())
29718 }
29719
29720 fn generate_convert_timezone(&mut self, e: &ConvertTimezone) -> Result<()> {
29721 self.write_keyword("CONVERT_TIMEZONE");
29723 self.write("(");
29724 let mut first = true;
29725 if let Some(source_tz) = &e.source_tz {
29726 self.generate_expression(source_tz)?;
29727 first = false;
29728 }
29729 if let Some(target_tz) = &e.target_tz {
29730 if !first {
29731 self.write(", ");
29732 }
29733 self.generate_expression(target_tz)?;
29734 first = false;
29735 }
29736 if let Some(timestamp) = &e.timestamp {
29737 if !first {
29738 self.write(", ");
29739 }
29740 self.generate_expression(timestamp)?;
29741 }
29742 self.write(")");
29743 Ok(())
29744 }
29745
29746 fn generate_convert_to_charset(&mut self, e: &ConvertToCharset) -> Result<()> {
29747 self.write_keyword("CONVERT");
29749 self.write("(");
29750 self.generate_expression(&e.this)?;
29751 if let Some(dest) = &e.dest {
29752 self.write_space();
29753 self.write_keyword("USING");
29754 self.write_space();
29755 self.generate_expression(dest)?;
29756 }
29757 self.write(")");
29758 Ok(())
29759 }
29760
29761 fn generate_copy(&mut self, e: &CopyStmt) -> Result<()> {
29762 self.write_keyword("COPY");
29763 if e.is_into {
29764 self.write_space();
29765 self.write_keyword("INTO");
29766 }
29767 self.write_space();
29768
29769 if let Expression::Literal(lit) = &e.this {
29771 if let Literal::String(s) = lit.as_ref() {
29772 if s.starts_with('@') {
29773 self.write(s);
29774 } else {
29775 self.generate_expression(&e.this)?;
29776 }
29777 }
29778 } else {
29779 self.generate_expression(&e.this)?;
29780 }
29781
29782 if e.kind {
29784 if self.config.pretty {
29786 self.write_newline();
29787 } else {
29788 self.write_space();
29789 }
29790 self.write_keyword("FROM");
29791 self.write_space();
29792 } else if !e.files.is_empty() {
29793 if self.config.pretty {
29795 self.write_newline();
29796 } else {
29797 self.write_space();
29798 }
29799 self.write_keyword("TO");
29800 self.write_space();
29801 }
29802
29803 for (i, file) in e.files.iter().enumerate() {
29805 if i > 0 {
29806 self.write_space();
29807 }
29808 if let Expression::Literal(lit) = file {
29810 if let Literal::String(s) = lit.as_ref() {
29811 if s.starts_with('@') {
29812 self.write(s);
29813 } else {
29814 self.generate_expression(file)?;
29815 }
29816 }
29817 } else if let Expression::Identifier(id) = file {
29818 if id.quoted {
29820 self.write("`");
29821 self.write(&id.name);
29822 self.write("`");
29823 } else {
29824 self.generate_expression(file)?;
29825 }
29826 } else {
29827 self.generate_expression(file)?;
29828 }
29829 }
29830
29831 if !e.with_wrapped {
29833 if let Some(ref creds) = e.credentials {
29834 if let Some(ref storage) = creds.storage {
29835 if self.config.pretty {
29836 self.write_newline();
29837 } else {
29838 self.write_space();
29839 }
29840 self.write_keyword("STORAGE_INTEGRATION");
29841 self.write(" = ");
29842 self.write(storage);
29843 }
29844 if creds.credentials.is_empty() {
29845 if self.config.pretty {
29847 self.write_newline();
29848 } else {
29849 self.write_space();
29850 }
29851 self.write_keyword("CREDENTIALS");
29852 self.write(" = ()");
29853 } else {
29854 if self.config.pretty {
29855 self.write_newline();
29856 } else {
29857 self.write_space();
29858 }
29859 self.write_keyword("CREDENTIALS");
29860 if creds.credentials.len() == 1 && creds.credentials[0].0.is_empty() {
29863 self.write(" '");
29865 self.write(&creds.credentials[0].1);
29866 self.write("'");
29867 } else {
29868 self.write(" = (");
29870 for (i, (k, v)) in creds.credentials.iter().enumerate() {
29871 if i > 0 {
29872 self.write_space();
29873 }
29874 self.write(k);
29875 self.write("='");
29876 self.write(v);
29877 self.write("'");
29878 }
29879 self.write(")");
29880 }
29881 }
29882 if let Some(ref encryption) = creds.encryption {
29883 self.write_space();
29884 self.write_keyword("ENCRYPTION");
29885 self.write(" = ");
29886 self.write(encryption);
29887 }
29888 }
29889 }
29890
29891 if !e.params.is_empty() {
29893 if e.with_wrapped {
29894 self.write_space();
29896 self.write_keyword("WITH");
29897 self.write(" (");
29898 for (i, param) in e.params.iter().enumerate() {
29899 if i > 0 {
29900 self.write(", ");
29901 }
29902 self.generate_copy_param_with_format(param)?;
29903 }
29904 self.write(")");
29905 } else {
29906 for param in &e.params {
29910 if self.config.pretty {
29911 self.write_newline();
29912 } else {
29913 self.write_space();
29914 }
29915 self.write(¶m.name);
29917 if let Some(ref value) = param.value {
29918 if param.eq {
29920 self.write(" = ");
29921 } else {
29922 self.write(" ");
29923 }
29924 if !param.values.is_empty() {
29925 self.write("(");
29926 for (i, v) in param.values.iter().enumerate() {
29927 if i > 0 {
29928 self.write_space();
29929 }
29930 self.generate_copy_nested_param(v)?;
29931 }
29932 self.write(")");
29933 } else {
29934 self.generate_copy_param_value(value)?;
29936 }
29937 } else if !param.values.is_empty() {
29938 if param.eq {
29940 self.write(" = (");
29941 } else {
29942 self.write(" (");
29943 }
29944 let is_key_value_pairs = param
29949 .values
29950 .first()
29951 .map_or(false, |v| matches!(v, Expression::Eq(_)));
29952 let sep = if is_key_value_pairs && param.eq {
29953 " "
29954 } else {
29955 ", "
29956 };
29957 for (i, v) in param.values.iter().enumerate() {
29958 if i > 0 {
29959 self.write(sep);
29960 }
29961 self.generate_copy_nested_param(v)?;
29962 }
29963 self.write(")");
29964 }
29965 }
29966 }
29967 }
29968
29969 Ok(())
29970 }
29971
29972 fn generate_copy_param_with_format(&mut self, param: &CopyParameter) -> Result<()> {
29975 self.write_keyword(¶m.name);
29976 if !param.values.is_empty() {
29977 self.write(" = (");
29979 for (i, v) in param.values.iter().enumerate() {
29980 if i > 0 {
29981 self.write(", ");
29982 }
29983 self.generate_copy_nested_param(v)?;
29984 }
29985 self.write(")");
29986 } else if let Some(ref value) = param.value {
29987 if param.eq {
29988 self.write(" = ");
29989 } else {
29990 self.write(" ");
29991 }
29992 self.generate_expression(value)?;
29993 }
29994 Ok(())
29995 }
29996
29997 fn generate_copy_nested_param(&mut self, expr: &Expression) -> Result<()> {
29999 match expr {
30000 Expression::Eq(eq) => {
30001 match &eq.left {
30003 Expression::Column(c) => self.write(&c.name.name),
30004 _ => self.generate_expression(&eq.left)?,
30005 }
30006 self.write("=");
30007 match &eq.right {
30009 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
30010 let Literal::String(s) = lit.as_ref() else {
30011 unreachable!()
30012 };
30013 self.write("'");
30014 self.write(s);
30015 self.write("'");
30016 }
30017 Expression::Tuple(t) => {
30018 self.write("(");
30020 if self.config.pretty {
30021 self.write_newline();
30022 self.indent_level += 1;
30023 for (i, item) in t.expressions.iter().enumerate() {
30024 if i > 0 {
30025 self.write(", ");
30026 }
30027 self.write_indent();
30028 self.generate_expression(item)?;
30029 }
30030 self.write_newline();
30031 self.indent_level -= 1;
30032 } else {
30033 for (i, item) in t.expressions.iter().enumerate() {
30034 if i > 0 {
30035 self.write(", ");
30036 }
30037 self.generate_expression(item)?;
30038 }
30039 }
30040 self.write(")");
30041 }
30042 _ => self.generate_expression(&eq.right)?,
30043 }
30044 Ok(())
30045 }
30046 Expression::Column(c) => {
30047 self.write(&c.name.name);
30049 Ok(())
30050 }
30051 _ => self.generate_expression(expr),
30052 }
30053 }
30054
30055 fn generate_copy_param_value(&mut self, expr: &Expression) -> Result<()> {
30058 match expr {
30059 Expression::Column(c) => {
30060 if c.name.quoted {
30062 self.write("\"");
30063 self.write(&c.name.name);
30064 self.write("\"");
30065 } else {
30066 self.write(&c.name.name);
30067 }
30068 Ok(())
30069 }
30070 Expression::Identifier(id) => {
30071 if id.quoted {
30073 self.write("\"");
30074 self.write(&id.name);
30075 self.write("\"");
30076 } else {
30077 self.write(&id.name);
30078 }
30079 Ok(())
30080 }
30081 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
30082 let Literal::String(s) = lit.as_ref() else {
30083 unreachable!()
30084 };
30085 self.write("'");
30087 self.write(s);
30088 self.write("'");
30089 Ok(())
30090 }
30091 _ => self.generate_expression(expr),
30092 }
30093 }
30094
30095 fn generate_copy_parameter(&mut self, e: &CopyParameter) -> Result<()> {
30096 self.write_keyword(&e.name);
30097 if let Some(ref value) = e.value {
30098 if e.eq {
30099 self.write(" = ");
30100 } else {
30101 self.write(" ");
30102 }
30103 self.generate_expression(value)?;
30104 }
30105 if !e.values.is_empty() {
30106 if e.eq {
30107 self.write(" = ");
30108 } else {
30109 self.write(" ");
30110 }
30111 self.write("(");
30112 for (i, v) in e.values.iter().enumerate() {
30113 if i > 0 {
30114 self.write(", ");
30115 }
30116 self.generate_expression(v)?;
30117 }
30118 self.write(")");
30119 }
30120 Ok(())
30121 }
30122
30123 fn generate_corr(&mut self, e: &Corr) -> Result<()> {
30124 self.write_keyword("CORR");
30126 self.write("(");
30127 self.generate_expression(&e.this)?;
30128 self.write(", ");
30129 self.generate_expression(&e.expression)?;
30130 self.write(")");
30131 Ok(())
30132 }
30133
30134 fn generate_cosine_distance(&mut self, e: &CosineDistance) -> Result<()> {
30135 self.write_keyword("COSINE_DISTANCE");
30137 self.write("(");
30138 self.generate_expression(&e.this)?;
30139 self.write(", ");
30140 self.generate_expression(&e.expression)?;
30141 self.write(")");
30142 Ok(())
30143 }
30144
30145 fn generate_covar_pop(&mut self, e: &CovarPop) -> Result<()> {
30146 self.write_keyword("COVAR_POP");
30148 self.write("(");
30149 self.generate_expression(&e.this)?;
30150 self.write(", ");
30151 self.generate_expression(&e.expression)?;
30152 self.write(")");
30153 Ok(())
30154 }
30155
30156 fn generate_covar_samp(&mut self, e: &CovarSamp) -> Result<()> {
30157 self.write_keyword("COVAR_SAMP");
30159 self.write("(");
30160 self.generate_expression(&e.this)?;
30161 self.write(", ");
30162 self.generate_expression(&e.expression)?;
30163 self.write(")");
30164 Ok(())
30165 }
30166
30167 fn generate_credentials(&mut self, e: &Credentials) -> Result<()> {
30168 self.write_keyword("CREDENTIALS");
30170 self.write(" (");
30171 for (i, (key, value)) in e.credentials.iter().enumerate() {
30172 if i > 0 {
30173 self.write(", ");
30174 }
30175 self.write(key);
30176 self.write("='");
30177 self.write(value);
30178 self.write("'");
30179 }
30180 self.write(")");
30181 Ok(())
30182 }
30183
30184 fn generate_credentials_property(&mut self, e: &CredentialsProperty) -> Result<()> {
30185 self.write_keyword("CREDENTIALS");
30187 self.write("=(");
30188 for (i, expr) in e.expressions.iter().enumerate() {
30189 if i > 0 {
30190 self.write(", ");
30191 }
30192 self.generate_expression(expr)?;
30193 }
30194 self.write(")");
30195 Ok(())
30196 }
30197
30198 fn generate_cte(&mut self, e: &Cte) -> Result<()> {
30199 use crate::dialects::DialectType;
30200
30201 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !e.alias_first {
30204 self.generate_expression(&e.this)?;
30205 self.write_space();
30206 self.write_keyword("AS");
30207 self.write_space();
30208 self.generate_identifier(&e.alias)?;
30209 return Ok(());
30210 }
30211 self.write(&e.alias.name);
30212
30213 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
30215
30216 if !e.columns.is_empty() && !skip_cte_columns {
30217 self.write("(");
30218 for (i, col) in e.columns.iter().enumerate() {
30219 if i > 0 {
30220 self.write(", ");
30221 }
30222 self.write(&col.name);
30223 }
30224 self.write(")");
30225 }
30226 if !e.key_expressions.is_empty() {
30228 self.write_space();
30229 self.write_keyword("USING KEY");
30230 self.write(" (");
30231 for (i, key) in e.key_expressions.iter().enumerate() {
30232 if i > 0 {
30233 self.write(", ");
30234 }
30235 self.write(&key.name);
30236 }
30237 self.write(")");
30238 }
30239 self.write_space();
30240 self.write_keyword("AS");
30241 self.write_space();
30242 if let Some(materialized) = e.materialized {
30243 if materialized {
30244 self.write_keyword("MATERIALIZED");
30245 } else {
30246 self.write_keyword("NOT MATERIALIZED");
30247 }
30248 self.write_space();
30249 }
30250 self.write("(");
30251 self.generate_expression(&e.this)?;
30252 self.write(")");
30253 Ok(())
30254 }
30255
30256 fn generate_cube(&mut self, e: &Cube) -> Result<()> {
30257 if e.expressions.is_empty() {
30259 self.write_keyword("WITH CUBE");
30260 } else {
30261 self.write_keyword("CUBE");
30262 self.write("(");
30263 for (i, expr) in e.expressions.iter().enumerate() {
30264 if i > 0 {
30265 self.write(", ");
30266 }
30267 self.generate_expression(expr)?;
30268 }
30269 self.write(")");
30270 }
30271 Ok(())
30272 }
30273
30274 fn generate_current_datetime(&mut self, e: &CurrentDatetime) -> Result<()> {
30275 self.write_keyword("CURRENT_DATETIME");
30277 if let Some(this) = &e.this {
30278 self.write("(");
30279 self.generate_expression(this)?;
30280 self.write(")");
30281 }
30282 Ok(())
30283 }
30284
30285 fn generate_current_schema(&mut self, _e: &CurrentSchema) -> Result<()> {
30286 self.write_keyword("CURRENT_SCHEMA");
30288 Ok(())
30289 }
30290
30291 fn generate_current_schemas(&mut self, e: &CurrentSchemas) -> Result<()> {
30292 self.write_keyword("CURRENT_SCHEMAS");
30294 self.write("(");
30295 if !matches!(
30297 self.config.dialect,
30298 Some(crate::dialects::DialectType::Snowflake)
30299 ) {
30300 if let Some(this) = &e.this {
30301 self.generate_expression(this)?;
30302 }
30303 }
30304 self.write(")");
30305 Ok(())
30306 }
30307
30308 fn generate_current_user(&mut self, e: &CurrentUser) -> Result<()> {
30309 self.write_keyword("CURRENT_USER");
30311 let needs_parens = e.this.is_some()
30313 || matches!(
30314 self.config.dialect,
30315 Some(DialectType::Snowflake)
30316 | Some(DialectType::Spark)
30317 | Some(DialectType::Hive)
30318 | Some(DialectType::DuckDB)
30319 | Some(DialectType::BigQuery)
30320 | Some(DialectType::MySQL)
30321 | Some(DialectType::Databricks)
30322 );
30323 if needs_parens {
30324 self.write("()");
30325 }
30326 Ok(())
30327 }
30328
30329 fn generate_d_pipe(&mut self, e: &DPipe) -> Result<()> {
30330 if self.config.dialect == Some(DialectType::Solr) {
30332 self.generate_expression(&e.this)?;
30333 self.write(" ");
30334 self.write_keyword("OR");
30335 self.write(" ");
30336 self.generate_expression(&e.expression)?;
30337 } else if self.config.dialect == Some(DialectType::MySQL) {
30338 self.generate_mysql_concat_from_dpipe(e)?;
30339 } else {
30340 self.generate_expression(&e.this)?;
30342 self.write(" || ");
30343 self.generate_expression(&e.expression)?;
30344 }
30345 Ok(())
30346 }
30347
30348 fn generate_data_blocksize_property(&mut self, e: &DataBlocksizeProperty) -> Result<()> {
30349 self.write_keyword("DATABLOCKSIZE");
30351 self.write("=");
30352 if let Some(size) = e.size {
30353 self.write(&size.to_string());
30354 if let Some(units) = &e.units {
30355 self.write_space();
30356 self.generate_expression(units)?;
30357 }
30358 } else if e.minimum.is_some() {
30359 self.write_keyword("MINIMUM");
30360 } else if e.maximum.is_some() {
30361 self.write_keyword("MAXIMUM");
30362 } else if e.default.is_some() {
30363 self.write_keyword("DEFAULT");
30364 }
30365 Ok(())
30366 }
30367
30368 fn generate_data_deletion_property(&mut self, e: &DataDeletionProperty) -> Result<()> {
30369 self.write_keyword("DATA_DELETION");
30371 self.write("=");
30372
30373 let is_on = matches!(&*e.on, Expression::Boolean(BooleanLiteral { value: true }));
30374 let has_options = e.filter_column.is_some() || e.retention_period.is_some();
30375
30376 if is_on {
30377 self.write_keyword("ON");
30378 if has_options {
30379 self.write("(");
30380 let mut first = true;
30381 if let Some(filter_column) = &e.filter_column {
30382 self.write_keyword("FILTER_COLUMN");
30383 self.write("=");
30384 self.generate_expression(filter_column)?;
30385 first = false;
30386 }
30387 if let Some(retention_period) = &e.retention_period {
30388 if !first {
30389 self.write(", ");
30390 }
30391 self.write_keyword("RETENTION_PERIOD");
30392 self.write("=");
30393 self.generate_expression(retention_period)?;
30394 }
30395 self.write(")");
30396 }
30397 } else {
30398 self.write_keyword("OFF");
30399 }
30400 Ok(())
30401 }
30402
30403 fn generate_date_func(&mut self, e: &UnaryFunc) -> Result<()> {
30407 use crate::dialects::DialectType;
30408 use crate::expressions::Literal;
30409
30410 match self.config.dialect {
30411 Some(DialectType::Exasol) => {
30413 self.write_keyword("TO_DATE");
30414 self.write("(");
30415 match &e.this {
30417 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
30418 let Literal::String(s) = lit.as_ref() else {
30419 unreachable!()
30420 };
30421 self.write("'");
30422 self.write(s);
30423 self.write("'");
30424 }
30425 _ => {
30426 self.generate_expression(&e.this)?;
30427 }
30428 }
30429 self.write(")");
30430 }
30431 _ => {
30433 self.write_keyword("DATE");
30434 self.write("(");
30435 self.generate_expression(&e.this)?;
30436 self.write(")");
30437 }
30438 }
30439 Ok(())
30440 }
30441
30442 fn generate_date_bin(&mut self, e: &DateBin) -> Result<()> {
30443 self.write_keyword("DATE_BIN");
30445 self.write("(");
30446 self.generate_expression(&e.this)?;
30447 self.write(", ");
30448 self.generate_expression(&e.expression)?;
30449 if let Some(origin) = &e.origin {
30450 self.write(", ");
30451 self.generate_expression(origin)?;
30452 }
30453 self.write(")");
30454 Ok(())
30455 }
30456
30457 fn generate_date_format_column_constraint(
30458 &mut self,
30459 e: &DateFormatColumnConstraint,
30460 ) -> Result<()> {
30461 self.write_keyword("FORMAT");
30463 self.write_space();
30464 self.generate_expression(&e.this)?;
30465 Ok(())
30466 }
30467
30468 fn generate_date_from_parts(&mut self, e: &DateFromParts) -> Result<()> {
30469 self.write_keyword("DATE_FROM_PARTS");
30471 self.write("(");
30472 let mut first = true;
30473 if let Some(year) = &e.year {
30474 self.generate_expression(year)?;
30475 first = false;
30476 }
30477 if let Some(month) = &e.month {
30478 if !first {
30479 self.write(", ");
30480 }
30481 self.generate_expression(month)?;
30482 first = false;
30483 }
30484 if let Some(day) = &e.day {
30485 if !first {
30486 self.write(", ");
30487 }
30488 self.generate_expression(day)?;
30489 }
30490 self.write(")");
30491 Ok(())
30492 }
30493
30494 fn generate_datetime(&mut self, e: &Datetime) -> Result<()> {
30495 self.write_keyword("DATETIME");
30497 self.write("(");
30498 self.generate_expression(&e.this)?;
30499 if let Some(expr) = &e.expression {
30500 self.write(", ");
30501 self.generate_expression(expr)?;
30502 }
30503 self.write(")");
30504 Ok(())
30505 }
30506
30507 fn generate_datetime_add(&mut self, e: &DatetimeAdd) -> Result<()> {
30508 self.write_keyword("DATETIME_ADD");
30510 self.write("(");
30511 self.generate_expression(&e.this)?;
30512 self.write(", ");
30513 self.generate_expression(&e.expression)?;
30514 if let Some(unit) = &e.unit {
30515 self.write(", ");
30516 self.write_keyword(unit);
30517 }
30518 self.write(")");
30519 Ok(())
30520 }
30521
30522 fn generate_datetime_diff(&mut self, e: &DatetimeDiff) -> Result<()> {
30523 self.write_keyword("DATETIME_DIFF");
30525 self.write("(");
30526 self.generate_expression(&e.this)?;
30527 self.write(", ");
30528 self.generate_expression(&e.expression)?;
30529 if let Some(unit) = &e.unit {
30530 self.write(", ");
30531 self.write_keyword(unit);
30532 }
30533 self.write(")");
30534 Ok(())
30535 }
30536
30537 fn generate_datetime_sub(&mut self, e: &DatetimeSub) -> Result<()> {
30538 self.write_keyword("DATETIME_SUB");
30540 self.write("(");
30541 self.generate_expression(&e.this)?;
30542 self.write(", ");
30543 self.generate_expression(&e.expression)?;
30544 if let Some(unit) = &e.unit {
30545 self.write(", ");
30546 self.write_keyword(unit);
30547 }
30548 self.write(")");
30549 Ok(())
30550 }
30551
30552 fn generate_datetime_trunc(&mut self, e: &DatetimeTrunc) -> Result<()> {
30553 self.write_keyword("DATETIME_TRUNC");
30555 self.write("(");
30556 self.generate_expression(&e.this)?;
30557 self.write(", ");
30558 self.write_keyword(&e.unit);
30559 if let Some(zone) = &e.zone {
30560 self.write(", ");
30561 self.generate_expression(zone)?;
30562 }
30563 self.write(")");
30564 Ok(())
30565 }
30566
30567 fn generate_dayname(&mut self, e: &Dayname) -> Result<()> {
30568 self.write_keyword("DAYNAME");
30570 self.write("(");
30571 self.generate_expression(&e.this)?;
30572 self.write(")");
30573 Ok(())
30574 }
30575
30576 fn generate_declare(&mut self, e: &Declare) -> Result<()> {
30577 self.write_keyword("DECLARE");
30579 self.write_space();
30580 if e.replace {
30581 self.write_keyword("OR");
30582 self.write_space();
30583 self.write_keyword("REPLACE");
30584 self.write_space();
30585 }
30586 for (i, expr) in e.expressions.iter().enumerate() {
30587 if i > 0 {
30588 self.write(", ");
30589 }
30590 self.generate_expression(expr)?;
30591 }
30592 Ok(())
30593 }
30594
30595 fn generate_declare_item(&mut self, e: &DeclareItem) -> Result<()> {
30596 use crate::dialects::DialectType;
30597
30598 self.generate_expression(&e.this)?;
30600 for name in &e.additional_names {
30602 self.write(", ");
30603 self.generate_expression(name)?;
30604 }
30605 if let Some(kind) = &e.kind {
30606 self.write_space();
30607 match self.config.dialect {
30611 Some(DialectType::BigQuery) => {
30612 self.write(kind);
30613 }
30614 Some(DialectType::TSQL) => {
30615 let is_complex_table = kind.starts_with("TABLE")
30619 && (kind.contains("CLUSTERED") || kind.contains("INDEX"));
30620 if is_complex_table {
30621 self.write(kind);
30622 } else if kind == "INT" {
30623 self.write("INTEGER");
30624 } else if kind.starts_with("TABLE") {
30625 let normalized = kind
30627 .replace(" INT ", " INTEGER ")
30628 .replace(" INT,", " INTEGER,")
30629 .replace(" INT)", " INTEGER)")
30630 .replace("(INT ", "(INTEGER ");
30631 self.write(&normalized);
30632 } else {
30633 self.write(kind);
30634 }
30635 }
30636 _ => {
30637 if e.has_as {
30638 self.write_keyword("AS");
30639 self.write_space();
30640 }
30641 self.write(kind);
30642 }
30643 }
30644 }
30645 if let Some(default) = &e.default {
30646 match self.config.dialect {
30648 Some(DialectType::BigQuery) => {
30649 self.write_space();
30650 self.write_keyword("DEFAULT");
30651 self.write_space();
30652 }
30653 _ => {
30654 self.write(" = ");
30655 }
30656 }
30657 self.generate_expression(default)?;
30658 }
30659 Ok(())
30660 }
30661
30662 fn generate_decode_case(&mut self, e: &DecodeCase) -> Result<()> {
30663 self.write_keyword("DECODE");
30665 self.write("(");
30666 for (i, expr) in e.expressions.iter().enumerate() {
30667 if i > 0 {
30668 self.write(", ");
30669 }
30670 self.generate_expression(expr)?;
30671 }
30672 self.write(")");
30673 Ok(())
30674 }
30675
30676 fn generate_decompress_binary(&mut self, e: &DecompressBinary) -> Result<()> {
30677 self.write_keyword("DECOMPRESS");
30679 self.write("(");
30680 self.generate_expression(&e.this)?;
30681 self.write(", '");
30682 self.write(&e.method);
30683 self.write("')");
30684 Ok(())
30685 }
30686
30687 fn generate_decompress_string(&mut self, e: &DecompressString) -> Result<()> {
30688 self.write_keyword("DECOMPRESS");
30690 self.write("(");
30691 self.generate_expression(&e.this)?;
30692 self.write(", '");
30693 self.write(&e.method);
30694 self.write("')");
30695 Ok(())
30696 }
30697
30698 fn generate_decrypt(&mut self, e: &Decrypt) -> Result<()> {
30699 self.write_keyword("DECRYPT");
30701 self.write("(");
30702 self.generate_expression(&e.this)?;
30703 if let Some(passphrase) = &e.passphrase {
30704 self.write(", ");
30705 self.generate_expression(passphrase)?;
30706 }
30707 if let Some(aad) = &e.aad {
30708 self.write(", ");
30709 self.generate_expression(aad)?;
30710 }
30711 if let Some(method) = &e.encryption_method {
30712 self.write(", ");
30713 self.generate_expression(method)?;
30714 }
30715 self.write(")");
30716 Ok(())
30717 }
30718
30719 fn generate_decrypt_raw(&mut self, e: &DecryptRaw) -> Result<()> {
30720 self.write_keyword("DECRYPT_RAW");
30722 self.write("(");
30723 self.generate_expression(&e.this)?;
30724 if let Some(key) = &e.key {
30725 self.write(", ");
30726 self.generate_expression(key)?;
30727 }
30728 if let Some(iv) = &e.iv {
30729 self.write(", ");
30730 self.generate_expression(iv)?;
30731 }
30732 if let Some(aad) = &e.aad {
30733 self.write(", ");
30734 self.generate_expression(aad)?;
30735 }
30736 if let Some(method) = &e.encryption_method {
30737 self.write(", ");
30738 self.generate_expression(method)?;
30739 }
30740 self.write(")");
30741 Ok(())
30742 }
30743
30744 fn generate_definer_property(&mut self, e: &DefinerProperty) -> Result<()> {
30745 self.write_keyword("DEFINER");
30747 self.write(" = ");
30748 self.generate_expression(&e.this)?;
30749 Ok(())
30750 }
30751
30752 fn generate_detach(&mut self, e: &Detach) -> Result<()> {
30753 self.write_keyword("DETACH");
30755 if e.exists {
30756 self.write_keyword(" DATABASE IF EXISTS");
30757 }
30758 self.write_space();
30759 self.generate_expression(&e.this)?;
30760 Ok(())
30761 }
30762
30763 fn generate_dict_property(&mut self, e: &DictProperty) -> Result<()> {
30764 let property_name = match e.this.as_ref() {
30765 Expression::Identifier(id) => id.name.as_str(),
30766 Expression::Var(v) => v.this.as_str(),
30767 _ => "DICTIONARY",
30768 };
30769 self.write_keyword(property_name);
30770 self.write("(");
30771 self.write(&e.kind);
30772 if let Some(settings) = &e.settings {
30773 self.write("(");
30774 if let Expression::Tuple(t) = settings.as_ref() {
30775 if self.config.pretty && !t.expressions.is_empty() {
30776 self.write_newline();
30777 self.indent_level += 1;
30778 for (i, pair) in t.expressions.iter().enumerate() {
30779 if i > 0 {
30780 self.write(",");
30781 self.write_newline();
30782 }
30783 self.write_indent();
30784 if let Expression::Tuple(pair_tuple) = pair {
30785 if let Some(k) = pair_tuple.expressions.first() {
30786 self.generate_expression(k)?;
30787 }
30788 if let Some(v) = pair_tuple.expressions.get(1) {
30789 self.write(" ");
30790 self.generate_expression(v)?;
30791 }
30792 } else {
30793 self.generate_expression(pair)?;
30794 }
30795 }
30796 self.indent_level -= 1;
30797 self.write_newline();
30798 self.write_indent();
30799 } else {
30800 for (i, pair) in t.expressions.iter().enumerate() {
30801 if i > 0 {
30802 self.write(" ");
30804 }
30805 if let Expression::Tuple(pair_tuple) = pair {
30806 if let Some(k) = pair_tuple.expressions.first() {
30807 self.generate_expression(k)?;
30808 }
30809 if let Some(v) = pair_tuple.expressions.get(1) {
30810 self.write(" ");
30811 self.generate_expression(v)?;
30812 }
30813 } else {
30814 self.generate_expression(pair)?;
30815 }
30816 }
30817 }
30818 } else {
30819 self.generate_expression(settings)?;
30820 }
30821 self.write(")");
30822 } else {
30823 self.write("()");
30825 }
30826 self.write(")");
30827 Ok(())
30828 }
30829
30830 fn generate_dict_range(&mut self, e: &DictRange) -> Result<()> {
30831 let property_name = match e.this.as_ref() {
30832 Expression::Identifier(id) => id.name.as_str(),
30833 Expression::Var(v) => v.this.as_str(),
30834 _ => "RANGE",
30835 };
30836 self.write_keyword(property_name);
30837 self.write("(");
30838 if let Some(min) = &e.min {
30839 self.write_keyword("MIN");
30840 self.write_space();
30841 self.generate_expression(min)?;
30842 }
30843 if let Some(max) = &e.max {
30844 self.write_space();
30845 self.write_keyword("MAX");
30846 self.write_space();
30847 self.generate_expression(max)?;
30848 }
30849 self.write(")");
30850 Ok(())
30851 }
30852
30853 fn generate_directory(&mut self, e: &Directory) -> Result<()> {
30854 if e.local.is_some() {
30856 self.write_keyword("LOCAL ");
30857 }
30858 self.write_keyword("DIRECTORY");
30859 self.write_space();
30860 self.generate_expression(&e.this)?;
30861 if let Some(row_format) = &e.row_format {
30862 self.write_space();
30863 self.generate_expression(row_format)?;
30864 }
30865 Ok(())
30866 }
30867
30868 fn generate_dist_key_property(&mut self, e: &DistKeyProperty) -> Result<()> {
30869 self.write_keyword("DISTKEY");
30871 self.write("(");
30872 self.generate_expression(&e.this)?;
30873 self.write(")");
30874 Ok(())
30875 }
30876
30877 fn generate_dist_style_property(&mut self, e: &DistStyleProperty) -> Result<()> {
30878 self.write_keyword("DISTSTYLE");
30880 self.write_space();
30881 self.generate_expression(&e.this)?;
30882 Ok(())
30883 }
30884
30885 fn generate_distribute_by(&mut self, e: &DistributeBy) -> Result<()> {
30886 self.write_keyword("DISTRIBUTE BY");
30888 self.write_space();
30889 for (i, expr) in e.expressions.iter().enumerate() {
30890 if i > 0 {
30891 self.write(", ");
30892 }
30893 self.generate_expression(expr)?;
30894 }
30895 Ok(())
30896 }
30897
30898 fn generate_distributed_by_property(&mut self, e: &DistributedByProperty) -> Result<()> {
30899 self.write_keyword("DISTRIBUTED BY");
30901 self.write_space();
30902 self.write(&e.kind);
30903 if !e.expressions.is_empty() {
30904 self.write(" (");
30905 for (i, expr) in e.expressions.iter().enumerate() {
30906 if i > 0 {
30907 self.write(", ");
30908 }
30909 self.generate_expression(expr)?;
30910 }
30911 self.write(")");
30912 }
30913 if let Some(buckets) = &e.buckets {
30914 self.write_space();
30915 self.write_keyword("BUCKETS");
30916 self.write_space();
30917 self.generate_expression(buckets)?;
30918 }
30919 if let Some(order) = &e.order {
30920 self.write_space();
30921 self.generate_expression(order)?;
30922 }
30923 Ok(())
30924 }
30925
30926 fn generate_dot_product(&mut self, e: &DotProduct) -> Result<()> {
30927 self.write_keyword("DOT_PRODUCT");
30929 self.write("(");
30930 self.generate_expression(&e.this)?;
30931 self.write(", ");
30932 self.generate_expression(&e.expression)?;
30933 self.write(")");
30934 Ok(())
30935 }
30936
30937 fn generate_drop_partition(&mut self, e: &DropPartition) -> Result<()> {
30938 self.write_keyword("DROP");
30940 if e.exists {
30941 self.write_keyword(" IF EXISTS ");
30942 } else {
30943 self.write_space();
30944 }
30945 for (i, expr) in e.expressions.iter().enumerate() {
30946 if i > 0 {
30947 self.write(", ");
30948 }
30949 self.generate_expression(expr)?;
30950 }
30951 Ok(())
30952 }
30953
30954 fn generate_duplicate_key_property(&mut self, e: &DuplicateKeyProperty) -> Result<()> {
30955 self.write_keyword("DUPLICATE KEY");
30957 self.write(" (");
30958 for (i, expr) in e.expressions.iter().enumerate() {
30959 if i > 0 {
30960 self.write(", ");
30961 }
30962 self.generate_expression(expr)?;
30963 }
30964 self.write(")");
30965 Ok(())
30966 }
30967
30968 fn generate_elt(&mut self, e: &Elt) -> Result<()> {
30969 self.write_keyword("ELT");
30971 self.write("(");
30972 self.generate_expression(&e.this)?;
30973 for expr in &e.expressions {
30974 self.write(", ");
30975 self.generate_expression(expr)?;
30976 }
30977 self.write(")");
30978 Ok(())
30979 }
30980
30981 fn generate_encode(&mut self, e: &Encode) -> Result<()> {
30982 self.write_keyword("ENCODE");
30984 self.write("(");
30985 self.generate_expression(&e.this)?;
30986 if let Some(charset) = &e.charset {
30987 self.write(", ");
30988 self.generate_expression(charset)?;
30989 }
30990 self.write(")");
30991 Ok(())
30992 }
30993
30994 fn generate_encode_property(&mut self, e: &EncodeProperty) -> Result<()> {
30995 if e.key.is_some() {
30997 self.write_keyword("KEY ");
30998 }
30999 self.write_keyword("ENCODE");
31000 self.write_space();
31001 self.generate_expression(&e.this)?;
31002 if !e.properties.is_empty() {
31003 self.write(" (");
31004 for (i, prop) in e.properties.iter().enumerate() {
31005 if i > 0 {
31006 self.write(", ");
31007 }
31008 self.generate_expression(prop)?;
31009 }
31010 self.write(")");
31011 }
31012 Ok(())
31013 }
31014
31015 fn generate_encrypt(&mut self, e: &Encrypt) -> Result<()> {
31016 self.write_keyword("ENCRYPT");
31018 self.write("(");
31019 self.generate_expression(&e.this)?;
31020 if let Some(passphrase) = &e.passphrase {
31021 self.write(", ");
31022 self.generate_expression(passphrase)?;
31023 }
31024 if let Some(aad) = &e.aad {
31025 self.write(", ");
31026 self.generate_expression(aad)?;
31027 }
31028 if let Some(method) = &e.encryption_method {
31029 self.write(", ");
31030 self.generate_expression(method)?;
31031 }
31032 self.write(")");
31033 Ok(())
31034 }
31035
31036 fn generate_encrypt_raw(&mut self, e: &EncryptRaw) -> Result<()> {
31037 self.write_keyword("ENCRYPT_RAW");
31039 self.write("(");
31040 self.generate_expression(&e.this)?;
31041 if let Some(key) = &e.key {
31042 self.write(", ");
31043 self.generate_expression(key)?;
31044 }
31045 if let Some(iv) = &e.iv {
31046 self.write(", ");
31047 self.generate_expression(iv)?;
31048 }
31049 if let Some(aad) = &e.aad {
31050 self.write(", ");
31051 self.generate_expression(aad)?;
31052 }
31053 if let Some(method) = &e.encryption_method {
31054 self.write(", ");
31055 self.generate_expression(method)?;
31056 }
31057 self.write(")");
31058 Ok(())
31059 }
31060
31061 fn generate_engine_property(&mut self, e: &EngineProperty) -> Result<()> {
31062 self.write_keyword("ENGINE");
31064 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
31065 self.write("=");
31066 } else {
31067 self.write(" = ");
31068 }
31069 self.generate_expression(&e.this)?;
31070 Ok(())
31071 }
31072
31073 fn generate_enviroment_property(&mut self, e: &EnviromentProperty) -> Result<()> {
31074 self.write_keyword("ENVIRONMENT");
31076 self.write(" (");
31077 for (i, expr) in e.expressions.iter().enumerate() {
31078 if i > 0 {
31079 self.write(", ");
31080 }
31081 self.generate_expression(expr)?;
31082 }
31083 self.write(")");
31084 Ok(())
31085 }
31086
31087 fn generate_ephemeral_column_constraint(
31088 &mut self,
31089 e: &EphemeralColumnConstraint,
31090 ) -> Result<()> {
31091 self.write_keyword("EPHEMERAL");
31093 if let Some(this) = &e.this {
31094 self.write_space();
31095 self.generate_expression(this)?;
31096 }
31097 Ok(())
31098 }
31099
31100 fn generate_equal_null(&mut self, e: &EqualNull) -> Result<()> {
31101 self.write_keyword("EQUAL_NULL");
31103 self.write("(");
31104 self.generate_expression(&e.this)?;
31105 self.write(", ");
31106 self.generate_expression(&e.expression)?;
31107 self.write(")");
31108 Ok(())
31109 }
31110
31111 fn generate_euclidean_distance(&mut self, e: &EuclideanDistance) -> Result<()> {
31112 use crate::dialects::DialectType;
31113
31114 match self.config.dialect {
31116 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
31117 self.generate_expression(&e.this)?;
31118 self.write(" <-> ");
31119 self.generate_expression(&e.expression)?;
31120 }
31121 _ => {
31122 self.write_keyword("EUCLIDEAN_DISTANCE");
31124 self.write("(");
31125 self.generate_expression(&e.this)?;
31126 self.write(", ");
31127 self.generate_expression(&e.expression)?;
31128 self.write(")");
31129 }
31130 }
31131 Ok(())
31132 }
31133
31134 fn generate_execute_as_property(&mut self, e: &ExecuteAsProperty) -> Result<()> {
31135 self.write_keyword("EXECUTE AS");
31137 self.write_space();
31138 self.generate_expression(&e.this)?;
31139 Ok(())
31140 }
31141
31142 fn generate_export(&mut self, e: &Export) -> Result<()> {
31143 self.write_keyword("EXPORT DATA");
31145 if let Some(connection) = &e.connection {
31146 self.write_space();
31147 self.write_keyword("WITH CONNECTION");
31148 self.write_space();
31149 self.generate_expression(connection)?;
31150 }
31151 if !e.options.is_empty() {
31152 self.write_space();
31153 self.generate_options_clause(&e.options)?;
31154 }
31155 self.write_space();
31156 self.write_keyword("AS");
31157 self.write_space();
31158 self.generate_expression(&e.this)?;
31159 Ok(())
31160 }
31161
31162 fn generate_external_property(&mut self, e: &ExternalProperty) -> Result<()> {
31163 self.write_keyword("EXTERNAL");
31165 if let Some(this) = &e.this {
31166 self.write_space();
31167 self.generate_expression(this)?;
31168 }
31169 Ok(())
31170 }
31171
31172 fn generate_fallback_property(&mut self, e: &FallbackProperty) -> Result<()> {
31173 if e.no.is_some() {
31175 self.write_keyword("NO ");
31176 }
31177 self.write_keyword("FALLBACK");
31178 if e.protection.is_some() {
31179 self.write_keyword(" PROTECTION");
31180 }
31181 Ok(())
31182 }
31183
31184 fn generate_farm_fingerprint(&mut self, e: &FarmFingerprint) -> Result<()> {
31185 self.write_keyword("FARM_FINGERPRINT");
31187 self.write("(");
31188 for (i, expr) in e.expressions.iter().enumerate() {
31189 if i > 0 {
31190 self.write(", ");
31191 }
31192 self.generate_expression(expr)?;
31193 }
31194 self.write(")");
31195 Ok(())
31196 }
31197
31198 fn generate_features_at_time(&mut self, e: &FeaturesAtTime) -> Result<()> {
31199 self.write_keyword("FEATURES_AT_TIME");
31201 self.write("(");
31202 self.generate_expression(&e.this)?;
31203 if let Some(time) = &e.time {
31204 self.write(", ");
31205 self.generate_expression(time)?;
31206 }
31207 if let Some(num_rows) = &e.num_rows {
31208 self.write(", ");
31209 self.generate_expression(num_rows)?;
31210 }
31211 if let Some(ignore_nulls) = &e.ignore_feature_nulls {
31212 self.write(", ");
31213 self.generate_expression(ignore_nulls)?;
31214 }
31215 self.write(")");
31216 Ok(())
31217 }
31218
31219 fn generate_fetch(&mut self, e: &Fetch) -> Result<()> {
31220 let use_limit = !e.percent
31222 && !e.with_ties
31223 && e.count.is_some()
31224 && matches!(
31225 self.config.dialect,
31226 Some(DialectType::Spark)
31227 | Some(DialectType::Hive)
31228 | Some(DialectType::DuckDB)
31229 | Some(DialectType::SQLite)
31230 | Some(DialectType::MySQL)
31231 | Some(DialectType::BigQuery)
31232 | Some(DialectType::Databricks)
31233 | Some(DialectType::StarRocks)
31234 | Some(DialectType::Doris)
31235 | Some(DialectType::Athena)
31236 | Some(DialectType::ClickHouse)
31237 );
31238
31239 if use_limit {
31240 self.write_keyword("LIMIT");
31241 self.write_space();
31242 self.generate_expression(e.count.as_ref().unwrap())?;
31243 return Ok(());
31244 }
31245
31246 self.write_keyword("FETCH");
31248 if !e.direction.is_empty() {
31249 self.write_space();
31250 self.write_keyword(&e.direction);
31251 }
31252 if let Some(count) = &e.count {
31253 self.write_space();
31254 self.generate_expression(count)?;
31255 }
31256 if e.percent {
31258 self.write_keyword(" PERCENT");
31259 }
31260 if e.rows {
31261 self.write_keyword(" ROWS");
31262 }
31263 if e.with_ties {
31264 self.write_keyword(" WITH TIES");
31265 } else if e.rows {
31266 self.write_keyword(" ONLY");
31267 } else {
31268 self.write_keyword(" ROWS ONLY");
31269 }
31270 Ok(())
31271 }
31272
31273 fn generate_file_format_property(&mut self, e: &FileFormatProperty) -> Result<()> {
31274 if e.hive_format.is_some() {
31278 self.write_keyword("STORED AS");
31280 self.write_space();
31281 if let Some(this) = &e.this {
31282 if let Expression::Identifier(id) = this.as_ref() {
31284 self.write_keyword(&id.name.to_ascii_uppercase());
31285 } else {
31286 self.generate_expression(this)?;
31287 }
31288 }
31289 } else if matches!(self.config.dialect, Some(DialectType::Hive)) {
31290 self.write_keyword("STORED AS");
31292 self.write_space();
31293 if let Some(this) = &e.this {
31294 if let Expression::Identifier(id) = this.as_ref() {
31295 self.write_keyword(&id.name.to_ascii_uppercase());
31296 } else {
31297 self.generate_expression(this)?;
31298 }
31299 }
31300 } else if matches!(
31301 self.config.dialect,
31302 Some(DialectType::Spark) | Some(DialectType::Databricks)
31303 ) {
31304 self.write_keyword("USING");
31306 self.write_space();
31307 if let Some(this) = &e.this {
31308 self.generate_expression(this)?;
31309 }
31310 } else {
31311 self.write_keyword("FILE_FORMAT");
31313 self.write(" = ");
31314 if let Some(this) = &e.this {
31315 self.generate_expression(this)?;
31316 } else if !e.expressions.is_empty() {
31317 self.write("(");
31318 for (i, expr) in e.expressions.iter().enumerate() {
31319 if i > 0 {
31320 self.write(", ");
31321 }
31322 self.generate_expression(expr)?;
31323 }
31324 self.write(")");
31325 }
31326 }
31327 Ok(())
31328 }
31329
31330 fn generate_filter(&mut self, e: &Filter) -> Result<()> {
31331 self.generate_expression(&e.this)?;
31333 self.write_space();
31334 self.write_keyword("FILTER");
31335 self.write("(");
31336 self.write_keyword("WHERE");
31337 self.write_space();
31338 self.generate_expression(&e.expression)?;
31339 self.write(")");
31340 Ok(())
31341 }
31342
31343 fn generate_float64(&mut self, e: &Float64) -> Result<()> {
31344 self.write_keyword("FLOAT64");
31346 self.write("(");
31347 self.generate_expression(&e.this)?;
31348 if let Some(expr) = &e.expression {
31349 self.write(", ");
31350 self.generate_expression(expr)?;
31351 }
31352 self.write(")");
31353 Ok(())
31354 }
31355
31356 fn generate_for_in(&mut self, e: &ForIn) -> Result<()> {
31357 self.write_keyword("FOR");
31359 self.write_space();
31360 self.generate_expression(&e.this)?;
31361 self.write_space();
31362 self.write_keyword("DO");
31363 self.write_space();
31364 self.generate_expression(&e.expression)?;
31365 Ok(())
31366 }
31367
31368 fn generate_foreign_key(&mut self, e: &ForeignKey) -> Result<()> {
31369 self.write_keyword("FOREIGN KEY");
31371 if !e.expressions.is_empty() {
31372 self.write(" (");
31373 for (i, expr) in e.expressions.iter().enumerate() {
31374 if i > 0 {
31375 self.write(", ");
31376 }
31377 self.generate_expression(expr)?;
31378 }
31379 self.write(")");
31380 }
31381 if let Some(reference) = &e.reference {
31382 self.write_space();
31383 self.generate_expression(reference)?;
31384 }
31385 if let Some(delete) = &e.delete {
31386 self.write_space();
31387 self.write_keyword("ON DELETE");
31388 self.write_space();
31389 self.generate_expression(delete)?;
31390 }
31391 if let Some(update) = &e.update {
31392 self.write_space();
31393 self.write_keyword("ON UPDATE");
31394 self.write_space();
31395 self.generate_expression(update)?;
31396 }
31397 if !e.options.is_empty() {
31398 self.write_space();
31399 for (i, opt) in e.options.iter().enumerate() {
31400 if i > 0 {
31401 self.write_space();
31402 }
31403 self.generate_expression(opt)?;
31404 }
31405 }
31406 Ok(())
31407 }
31408
31409 fn generate_format(&mut self, e: &Format) -> Result<()> {
31410 self.write_keyword("FORMAT");
31412 self.write("(");
31413 self.generate_expression(&e.this)?;
31414 for expr in &e.expressions {
31415 self.write(", ");
31416 self.generate_expression(expr)?;
31417 }
31418 self.write(")");
31419 Ok(())
31420 }
31421
31422 fn generate_format_phrase(&mut self, e: &FormatPhrase) -> Result<()> {
31423 self.generate_expression(&e.this)?;
31425 self.write(" (");
31426 self.write_keyword("FORMAT");
31427 self.write(" '");
31428 self.write(&e.format);
31429 self.write("')");
31430 Ok(())
31431 }
31432
31433 fn generate_freespace_property(&mut self, e: &FreespaceProperty) -> Result<()> {
31434 self.write_keyword("FREESPACE");
31436 self.write("=");
31437 self.generate_expression(&e.this)?;
31438 if e.percent.is_some() {
31439 self.write_keyword(" PERCENT");
31440 }
31441 Ok(())
31442 }
31443
31444 fn generate_from(&mut self, e: &From) -> Result<()> {
31445 self.write_keyword("FROM");
31447 self.write_space();
31448
31449 use crate::dialects::DialectType;
31453 let has_tablesample = e
31454 .expressions
31455 .iter()
31456 .any(|expr| matches!(expr, Expression::TableSample(_)));
31457 let is_cross_join_dialect = matches!(
31458 self.config.dialect,
31459 Some(DialectType::BigQuery)
31460 | Some(DialectType::Hive)
31461 | Some(DialectType::Spark)
31462 | Some(DialectType::Databricks)
31463 | Some(DialectType::SQLite)
31464 | Some(DialectType::ClickHouse)
31465 );
31466 let source_is_same_as_target2 = self.config.source_dialect.is_some()
31467 && self.config.source_dialect == self.config.dialect;
31468 let source_is_cross_join_dialect2 = matches!(
31469 self.config.source_dialect,
31470 Some(DialectType::BigQuery)
31471 | Some(DialectType::Hive)
31472 | Some(DialectType::Spark)
31473 | Some(DialectType::Databricks)
31474 | Some(DialectType::SQLite)
31475 | Some(DialectType::ClickHouse)
31476 );
31477 let use_cross_join = !has_tablesample
31478 && is_cross_join_dialect
31479 && (source_is_same_as_target2
31480 || source_is_cross_join_dialect2
31481 || self.config.source_dialect.is_none());
31482
31483 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
31485
31486 for (i, expr) in e.expressions.iter().enumerate() {
31487 if i > 0 {
31488 if use_cross_join {
31489 self.write(" CROSS JOIN ");
31490 } else {
31491 self.write(", ");
31492 }
31493 }
31494 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
31495 self.write("(");
31496 self.generate_expression(expr)?;
31497 self.write(")");
31498 } else {
31499 self.generate_expression(expr)?;
31500 }
31501 let leading = Self::extract_table_leading_comments(expr);
31504 for comment in &leading {
31505 self.write_space();
31506 self.write_formatted_comment(comment);
31507 }
31508 }
31509 Ok(())
31510 }
31511
31512 fn extract_table_leading_comments(expr: &Expression) -> Vec<String> {
31514 match expr {
31515 Expression::Table(t) => t.leading_comments.clone(),
31516 Expression::Pivot(p) => {
31517 if let Expression::Table(t) = &p.this {
31518 t.leading_comments.clone()
31519 } else {
31520 Vec::new()
31521 }
31522 }
31523 _ => Vec::new(),
31524 }
31525 }
31526
31527 fn generate_from_base(&mut self, e: &FromBase) -> Result<()> {
31528 self.write_keyword("FROM_BASE");
31530 self.write("(");
31531 self.generate_expression(&e.this)?;
31532 self.write(", ");
31533 self.generate_expression(&e.expression)?;
31534 self.write(")");
31535 Ok(())
31536 }
31537
31538 fn generate_from_time_zone(&mut self, e: &FromTimeZone) -> Result<()> {
31539 self.generate_expression(&e.this)?;
31541 if let Some(zone) = &e.zone {
31542 self.write_space();
31543 self.write_keyword("AT TIME ZONE");
31544 self.write_space();
31545 self.generate_expression(zone)?;
31546 self.write_space();
31547 self.write_keyword("AT TIME ZONE");
31548 self.write(" 'UTC'");
31549 }
31550 Ok(())
31551 }
31552
31553 fn generate_gap_fill(&mut self, e: &GapFill) -> Result<()> {
31554 self.write_keyword("GAP_FILL");
31556 self.write("(");
31557 self.generate_expression(&e.this)?;
31558 if let Some(ts_column) = &e.ts_column {
31559 self.write(", ");
31560 self.generate_expression(ts_column)?;
31561 }
31562 if let Some(bucket_width) = &e.bucket_width {
31563 self.write(", ");
31564 self.generate_expression(bucket_width)?;
31565 }
31566 if let Some(partitioning_columns) = &e.partitioning_columns {
31567 self.write(", ");
31568 self.generate_expression(partitioning_columns)?;
31569 }
31570 if let Some(value_columns) = &e.value_columns {
31571 self.write(", ");
31572 self.generate_expression(value_columns)?;
31573 }
31574 self.write(")");
31575 Ok(())
31576 }
31577
31578 fn generate_generate_date_array(&mut self, e: &GenerateDateArray) -> Result<()> {
31579 self.write_keyword("GENERATE_DATE_ARRAY");
31581 self.write("(");
31582 let mut first = true;
31583 if let Some(start) = &e.start {
31584 self.generate_expression(start)?;
31585 first = false;
31586 }
31587 if let Some(end) = &e.end {
31588 if !first {
31589 self.write(", ");
31590 }
31591 self.generate_expression(end)?;
31592 first = false;
31593 }
31594 if let Some(step) = &e.step {
31595 if !first {
31596 self.write(", ");
31597 }
31598 self.generate_expression(step)?;
31599 }
31600 self.write(")");
31601 Ok(())
31602 }
31603
31604 fn generate_generate_embedding(&mut self, e: &GenerateEmbedding) -> Result<()> {
31605 self.write_keyword("ML.GENERATE_EMBEDDING");
31607 self.write("(");
31608 self.generate_expression(&e.this)?;
31609 self.write(", ");
31610 self.generate_expression(&e.expression)?;
31611 if let Some(params) = &e.params_struct {
31612 self.write(", ");
31613 self.generate_expression(params)?;
31614 }
31615 self.write(")");
31616 Ok(())
31617 }
31618
31619 fn generate_generate_series(&mut self, e: &GenerateSeries) -> Result<()> {
31620 let fn_name = match self.config.dialect {
31622 Some(DialectType::Presto)
31623 | Some(DialectType::Trino)
31624 | Some(DialectType::Athena)
31625 | Some(DialectType::Spark)
31626 | Some(DialectType::Databricks)
31627 | Some(DialectType::Hive) => "SEQUENCE",
31628 _ => "GENERATE_SERIES",
31629 };
31630 self.write_keyword(fn_name);
31631 self.write("(");
31632 let mut first = true;
31633 if let Some(start) = &e.start {
31634 self.generate_expression(start)?;
31635 first = false;
31636 }
31637 if let Some(end) = &e.end {
31638 if !first {
31639 self.write(", ");
31640 }
31641 self.generate_expression(end)?;
31642 first = false;
31643 }
31644 if let Some(step) = &e.step {
31645 if !first {
31646 self.write(", ");
31647 }
31648 if matches!(
31651 self.config.dialect,
31652 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
31653 ) {
31654 if let Some(converted) = self.convert_week_interval_to_day(step) {
31655 self.generate_expression(&converted)?;
31656 } else {
31657 self.generate_expression(step)?;
31658 }
31659 } else {
31660 self.generate_expression(step)?;
31661 }
31662 }
31663 self.write(")");
31664 Ok(())
31665 }
31666
31667 fn convert_week_interval_to_day(&self, expr: &Expression) -> Option<Expression> {
31670 use crate::expressions::*;
31671 if let Expression::Interval(ref iv) = expr {
31672 let (is_week, count_str) = if let Some(IntervalUnitSpec::Simple {
31674 unit: IntervalUnit::Week,
31675 ..
31676 }) = &iv.unit
31677 {
31678 let count = match &iv.this {
31680 Some(Expression::Literal(lit)) => match lit.as_ref() {
31681 Literal::String(s) | Literal::Number(s) => s.clone(),
31682 _ => return None,
31683 },
31684 _ => return None,
31685 };
31686 (true, count)
31687 } else if iv.unit.is_none() {
31688 if let Some(Expression::Literal(lit)) = &iv.this {
31690 if let Literal::String(s) = lit.as_ref() {
31691 let parts: Vec<&str> = s.trim().splitn(2, char::is_whitespace).collect();
31692 if parts.len() == 2 && parts[1].eq_ignore_ascii_case("WEEK") {
31693 (true, parts[0].to_string())
31694 } else {
31695 (false, String::new())
31696 }
31697 } else {
31698 (false, String::new())
31699 }
31700 } else {
31701 (false, String::new())
31702 }
31703 } else {
31704 (false, String::new())
31705 };
31706
31707 if is_week {
31708 let count_expr = Expression::Literal(Box::new(Literal::Number(count_str)));
31710 let day_interval = Expression::Interval(Box::new(Interval {
31711 this: Some(Expression::Literal(Box::new(Literal::String(
31712 "7".to_string(),
31713 )))),
31714 unit: Some(IntervalUnitSpec::Simple {
31715 unit: IntervalUnit::Day,
31716 use_plural: false,
31717 }),
31718 }));
31719 let mul = Expression::Mul(Box::new(BinaryOp {
31720 left: count_expr,
31721 right: day_interval,
31722 left_comments: vec![],
31723 operator_comments: vec![],
31724 trailing_comments: vec![],
31725 inferred_type: None,
31726 }));
31727 return Some(Expression::Paren(Box::new(Paren {
31728 this: mul,
31729 trailing_comments: vec![],
31730 })));
31731 }
31732 }
31733 None
31734 }
31735
31736 fn generate_generate_timestamp_array(&mut self, e: &GenerateTimestampArray) -> Result<()> {
31737 self.write_keyword("GENERATE_TIMESTAMP_ARRAY");
31739 self.write("(");
31740 let mut first = true;
31741 if let Some(start) = &e.start {
31742 self.generate_expression(start)?;
31743 first = false;
31744 }
31745 if let Some(end) = &e.end {
31746 if !first {
31747 self.write(", ");
31748 }
31749 self.generate_expression(end)?;
31750 first = false;
31751 }
31752 if let Some(step) = &e.step {
31753 if !first {
31754 self.write(", ");
31755 }
31756 self.generate_expression(step)?;
31757 }
31758 self.write(")");
31759 Ok(())
31760 }
31761
31762 fn generate_generated_as_identity_column_constraint(
31763 &mut self,
31764 e: &GeneratedAsIdentityColumnConstraint,
31765 ) -> Result<()> {
31766 use crate::dialects::DialectType;
31767
31768 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
31770 self.write_keyword("AUTOINCREMENT");
31771 if let Some(start) = &e.start {
31772 self.write_keyword(" START ");
31773 self.generate_expression(start)?;
31774 }
31775 if let Some(increment) = &e.increment {
31776 self.write_keyword(" INCREMENT ");
31777 self.generate_expression(increment)?;
31778 }
31779 return Ok(());
31780 }
31781
31782 self.write_keyword("GENERATED");
31784 if let Some(this) = &e.this {
31785 if let Expression::Boolean(b) = this.as_ref() {
31787 if b.value {
31788 self.write_keyword(" ALWAYS");
31789 } else {
31790 self.write_keyword(" BY DEFAULT");
31791 if e.on_null.is_some() {
31792 self.write_keyword(" ON NULL");
31793 }
31794 }
31795 } else {
31796 self.write_keyword(" ALWAYS");
31797 }
31798 }
31799 self.write_keyword(" AS IDENTITY");
31800 let has_options = e.start.is_some()
31802 || e.increment.is_some()
31803 || e.minvalue.is_some()
31804 || e.maxvalue.is_some();
31805 if has_options {
31806 self.write(" (");
31807 let mut first = true;
31808 if let Some(start) = &e.start {
31809 self.write_keyword("START WITH ");
31810 self.generate_expression(start)?;
31811 first = false;
31812 }
31813 if let Some(increment) = &e.increment {
31814 if !first {
31815 self.write(" ");
31816 }
31817 self.write_keyword("INCREMENT BY ");
31818 self.generate_expression(increment)?;
31819 first = false;
31820 }
31821 if let Some(minvalue) = &e.minvalue {
31822 if !first {
31823 self.write(" ");
31824 }
31825 self.write_keyword("MINVALUE ");
31826 self.generate_expression(minvalue)?;
31827 first = false;
31828 }
31829 if let Some(maxvalue) = &e.maxvalue {
31830 if !first {
31831 self.write(" ");
31832 }
31833 self.write_keyword("MAXVALUE ");
31834 self.generate_expression(maxvalue)?;
31835 }
31836 self.write(")");
31837 }
31838 Ok(())
31839 }
31840
31841 fn generate_generated_as_row_column_constraint(
31842 &mut self,
31843 e: &GeneratedAsRowColumnConstraint,
31844 ) -> Result<()> {
31845 self.write_keyword("GENERATED ALWAYS AS ROW ");
31847 if e.start.is_some() {
31848 self.write_keyword("START");
31849 } else {
31850 self.write_keyword("END");
31851 }
31852 if e.hidden.is_some() {
31853 self.write_keyword(" HIDDEN");
31854 }
31855 Ok(())
31856 }
31857
31858 fn generate_get(&mut self, e: &Get) -> Result<()> {
31859 self.write_keyword("GET");
31861 self.write_space();
31862 self.generate_expression(&e.this)?;
31863 if let Some(target) = &e.target {
31864 self.write_space();
31865 self.generate_expression(target)?;
31866 }
31867 for prop in &e.properties {
31868 self.write_space();
31869 self.generate_expression(prop)?;
31870 }
31871 Ok(())
31872 }
31873
31874 fn generate_get_extract(&mut self, e: &GetExtract) -> Result<()> {
31875 self.generate_expression(&e.this)?;
31877 self.write("[");
31878 self.generate_expression(&e.expression)?;
31879 self.write("]");
31880 Ok(())
31881 }
31882
31883 fn generate_getbit(&mut self, e: &Getbit) -> Result<()> {
31884 self.write_keyword("GETBIT");
31886 self.write("(");
31887 self.generate_expression(&e.this)?;
31888 self.write(", ");
31889 self.generate_expression(&e.expression)?;
31890 self.write(")");
31891 Ok(())
31892 }
31893
31894 fn generate_grant_principal(&mut self, e: &GrantPrincipal) -> Result<()> {
31895 if e.is_role {
31897 self.write_keyword("ROLE");
31898 self.write_space();
31899 } else if e.is_group {
31900 self.write_keyword("GROUP");
31901 self.write_space();
31902 } else if e.is_share {
31903 self.write_keyword("SHARE");
31904 self.write_space();
31905 }
31906 self.write(&e.name.name);
31907 Ok(())
31908 }
31909
31910 fn generate_grant_privilege(&mut self, e: &GrantPrivilege) -> Result<()> {
31911 self.generate_expression(&e.this)?;
31913 if !e.expressions.is_empty() {
31914 self.write("(");
31915 for (i, expr) in e.expressions.iter().enumerate() {
31916 if i > 0 {
31917 self.write(", ");
31918 }
31919 self.generate_expression(expr)?;
31920 }
31921 self.write(")");
31922 }
31923 Ok(())
31924 }
31925
31926 fn generate_group(&mut self, e: &Group) -> Result<()> {
31927 self.write_keyword("GROUP BY");
31929 match e.all {
31931 Some(true) => {
31932 self.write_space();
31933 self.write_keyword("ALL");
31934 }
31935 Some(false) => {
31936 self.write_space();
31937 self.write_keyword("DISTINCT");
31938 }
31939 None => {}
31940 }
31941 if !e.expressions.is_empty() {
31942 self.write_space();
31943 for (i, expr) in e.expressions.iter().enumerate() {
31944 if i > 0 {
31945 self.write(", ");
31946 }
31947 self.generate_expression(expr)?;
31948 }
31949 }
31950 if let Some(cube) = &e.cube {
31952 if !e.expressions.is_empty() {
31953 self.write(", ");
31954 } else {
31955 self.write_space();
31956 }
31957 self.generate_expression(cube)?;
31958 }
31959 if let Some(rollup) = &e.rollup {
31960 if !e.expressions.is_empty() || e.cube.is_some() {
31961 self.write(", ");
31962 } else {
31963 self.write_space();
31964 }
31965 self.generate_expression(rollup)?;
31966 }
31967 if let Some(grouping_sets) = &e.grouping_sets {
31968 if !e.expressions.is_empty() || e.cube.is_some() || e.rollup.is_some() {
31969 self.write(", ");
31970 } else {
31971 self.write_space();
31972 }
31973 self.generate_expression(grouping_sets)?;
31974 }
31975 if let Some(totals) = &e.totals {
31976 self.write_space();
31977 self.write_keyword("WITH TOTALS");
31978 self.generate_expression(totals)?;
31979 }
31980 Ok(())
31981 }
31982
31983 fn generate_group_by(&mut self, e: &GroupBy) -> Result<()> {
31984 self.write_keyword("GROUP BY");
31986 match e.all {
31988 Some(true) => {
31989 self.write_space();
31990 self.write_keyword("ALL");
31991 }
31992 Some(false) => {
31993 self.write_space();
31994 self.write_keyword("DISTINCT");
31995 }
31996 None => {}
31997 }
31998
31999 let mut trailing_cube = false;
32002 let mut trailing_rollup = false;
32003 let mut regular_expressions: Vec<&Expression> = Vec::new();
32004
32005 for expr in &e.expressions {
32006 match expr {
32007 Expression::Cube(c) if c.expressions.is_empty() => {
32008 trailing_cube = true;
32009 }
32010 Expression::Rollup(r) if r.expressions.is_empty() => {
32011 trailing_rollup = true;
32012 }
32013 _ => {
32014 regular_expressions.push(expr);
32015 }
32016 }
32017 }
32018
32019 if self.config.pretty {
32021 self.write_newline();
32022 self.indent_level += 1;
32023 for (i, expr) in regular_expressions.iter().enumerate() {
32024 if i > 0 {
32025 self.write(",");
32026 self.write_newline();
32027 }
32028 self.write_indent();
32029 self.generate_expression(expr)?;
32030 }
32031 self.indent_level -= 1;
32032 } else {
32033 self.write_space();
32034 for (i, expr) in regular_expressions.iter().enumerate() {
32035 if i > 0 {
32036 self.write(", ");
32037 }
32038 self.generate_expression(expr)?;
32039 }
32040 }
32041
32042 if trailing_cube {
32044 self.write_space();
32045 self.write_keyword("WITH CUBE");
32046 } else if trailing_rollup {
32047 self.write_space();
32048 self.write_keyword("WITH ROLLUP");
32049 }
32050
32051 if e.totals {
32053 self.write_space();
32054 self.write_keyword("WITH TOTALS");
32055 }
32056
32057 Ok(())
32058 }
32059
32060 fn generate_grouping(&mut self, e: &Grouping) -> Result<()> {
32061 let function_name = if e.expressions.len() > 1
32062 && matches!(
32063 self.config.dialect,
32064 Some(DialectType::TSQL | DialectType::Fabric)
32065 ) {
32066 "GROUPING_ID"
32067 } else {
32068 "GROUPING"
32069 };
32070 self.write_keyword(function_name);
32071 self.write("(");
32072 for (i, expr) in e.expressions.iter().enumerate() {
32073 if i > 0 {
32074 self.write(", ");
32075 }
32076 self.generate_expression(expr)?;
32077 }
32078 self.write(")");
32079 Ok(())
32080 }
32081
32082 fn generate_grouping_id(&mut self, e: &GroupingId) -> Result<()> {
32083 self.write_keyword("GROUPING_ID");
32085 self.write("(");
32086 for (i, expr) in e.expressions.iter().enumerate() {
32087 if i > 0 {
32088 self.write(", ");
32089 }
32090 self.generate_expression(expr)?;
32091 }
32092 self.write(")");
32093 Ok(())
32094 }
32095
32096 fn generate_grouping_sets(&mut self, e: &GroupingSets) -> Result<()> {
32097 self.write_keyword("GROUPING SETS");
32099 self.write(" (");
32100 for (i, expr) in e.expressions.iter().enumerate() {
32101 if i > 0 {
32102 self.write(", ");
32103 }
32104 self.generate_expression(expr)?;
32105 }
32106 self.write(")");
32107 Ok(())
32108 }
32109
32110 fn generate_hash_agg(&mut self, e: &HashAgg) -> Result<()> {
32111 self.write_keyword("HASH_AGG");
32113 self.write("(");
32114 self.generate_expression(&e.this)?;
32115 for expr in &e.expressions {
32116 self.write(", ");
32117 self.generate_expression(expr)?;
32118 }
32119 self.write(")");
32120 Ok(())
32121 }
32122
32123 fn generate_having(&mut self, e: &Having) -> Result<()> {
32124 self.write_keyword("HAVING");
32126 self.write_space();
32127 self.generate_expression(&e.this)?;
32128 Ok(())
32129 }
32130
32131 fn generate_having_max(&mut self, e: &HavingMax) -> Result<()> {
32132 self.generate_expression(&e.this)?;
32134 self.write_space();
32135 self.write_keyword("HAVING");
32136 self.write_space();
32137 if e.max.is_some() {
32138 self.write_keyword("MAX");
32139 } else {
32140 self.write_keyword("MIN");
32141 }
32142 self.write_space();
32143 self.generate_expression(&e.expression)?;
32144 Ok(())
32145 }
32146
32147 fn generate_heredoc(&mut self, e: &Heredoc) -> Result<()> {
32148 use crate::dialects::DialectType;
32149 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
32151 if let Expression::Literal(ref lit) = *e.this {
32153 if let Literal::String(ref s) = lit.as_ref() {
32154 return self.generate_string_literal(s);
32155 }
32156 }
32157 }
32158 if matches!(
32160 self.config.dialect,
32161 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
32162 ) {
32163 self.write("$");
32164 if let Some(tag) = &e.tag {
32165 self.generate_expression(tag)?;
32166 }
32167 self.write("$");
32168 self.generate_expression(&e.this)?;
32169 self.write("$");
32170 if let Some(tag) = &e.tag {
32171 self.generate_expression(tag)?;
32172 }
32173 self.write("$");
32174 return Ok(());
32175 }
32176 self.write("$");
32178 if let Some(tag) = &e.tag {
32179 self.generate_expression(tag)?;
32180 }
32181 self.write("$");
32182 self.generate_expression(&e.this)?;
32183 self.write("$");
32184 if let Some(tag) = &e.tag {
32185 self.generate_expression(tag)?;
32186 }
32187 self.write("$");
32188 Ok(())
32189 }
32190
32191 fn generate_hex_encode(&mut self, e: &HexEncode) -> Result<()> {
32192 self.write_keyword("HEX_ENCODE");
32194 self.write("(");
32195 self.generate_expression(&e.this)?;
32196 self.write(")");
32197 Ok(())
32198 }
32199
32200 fn generate_historical_data(&mut self, e: &HistoricalData) -> Result<()> {
32201 match e.this.as_ref() {
32204 Expression::Identifier(id) => self.write(&id.name),
32205 other => self.generate_expression(other)?,
32206 }
32207 self.write(" (");
32208 self.write(&e.kind);
32209 self.write(" => ");
32210 self.generate_expression(&e.expression)?;
32211 self.write(")");
32212 Ok(())
32213 }
32214
32215 fn generate_hll(&mut self, e: &Hll) -> Result<()> {
32216 self.write_keyword("HLL");
32218 self.write("(");
32219 self.generate_expression(&e.this)?;
32220 for expr in &e.expressions {
32221 self.write(", ");
32222 self.generate_expression(expr)?;
32223 }
32224 self.write(")");
32225 Ok(())
32226 }
32227
32228 fn generate_in_out_column_constraint(&mut self, e: &InOutColumnConstraint) -> Result<()> {
32229 if e.input_.is_some() && e.output.is_some() {
32231 self.write_keyword("IN OUT");
32232 } else if e.input_.is_some() {
32233 self.write_keyword("IN");
32234 } else if e.output.is_some() {
32235 self.write_keyword("OUT");
32236 }
32237 Ok(())
32238 }
32239
32240 fn generate_include_property(&mut self, e: &IncludeProperty) -> Result<()> {
32241 self.write_keyword("INCLUDE");
32243 self.write_space();
32244 self.generate_expression(&e.this)?;
32245 if let Some(column_def) = &e.column_def {
32246 self.write_space();
32247 self.generate_expression(column_def)?;
32248 }
32249 if let Some(alias) = &e.alias {
32250 self.write_space();
32251 self.write_keyword("AS");
32252 self.write_space();
32253 self.write(alias);
32254 }
32255 Ok(())
32256 }
32257
32258 fn generate_index(&mut self, e: &Index) -> Result<()> {
32259 if e.unique {
32261 self.write_keyword("UNIQUE");
32262 self.write_space();
32263 }
32264 if e.primary.is_some() {
32265 self.write_keyword("PRIMARY");
32266 self.write_space();
32267 }
32268 if e.amp.is_some() {
32269 self.write_keyword("AMP");
32270 self.write_space();
32271 }
32272 if e.table.is_none() {
32273 self.write_keyword("INDEX");
32274 self.write_space();
32275 }
32276 if let Some(name) = &e.this {
32277 self.generate_expression(name)?;
32278 self.write_space();
32279 }
32280 if let Some(table) = &e.table {
32281 self.write_keyword("ON");
32282 self.write_space();
32283 self.generate_expression(table)?;
32284 }
32285 if !e.params.is_empty() {
32286 self.write("(");
32287 for (i, param) in e.params.iter().enumerate() {
32288 if i > 0 {
32289 self.write(", ");
32290 }
32291 self.generate_expression(param)?;
32292 }
32293 self.write(")");
32294 }
32295 Ok(())
32296 }
32297
32298 fn generate_index_column_constraint(&mut self, e: &IndexColumnConstraint) -> Result<()> {
32299 if let Some(kind) = &e.kind {
32301 self.write(kind);
32302 self.write_space();
32303 }
32304 self.write_keyword("INDEX");
32305 if let Some(this) = &e.this {
32306 self.write_space();
32307 self.generate_expression(this)?;
32308 }
32309 if let Some(index_type) = &e.index_type {
32310 self.write_space();
32311 self.write_keyword("USING");
32312 self.write_space();
32313 self.generate_expression(index_type)?;
32314 }
32315 if !e.expressions.is_empty() {
32316 self.write(" (");
32317 for (i, expr) in e.expressions.iter().enumerate() {
32318 if i > 0 {
32319 self.write(", ");
32320 }
32321 self.generate_expression(expr)?;
32322 }
32323 self.write(")");
32324 }
32325 for opt in &e.options {
32326 self.write_space();
32327 self.generate_expression(opt)?;
32328 }
32329 Ok(())
32330 }
32331
32332 fn generate_index_constraint_option(&mut self, e: &IndexConstraintOption) -> Result<()> {
32333 if let Some(key_block_size) = &e.key_block_size {
32335 self.write_keyword("KEY_BLOCK_SIZE");
32336 self.write(" = ");
32337 self.generate_expression(key_block_size)?;
32338 } else if let Some(using) = &e.using {
32339 self.write_keyword("USING");
32340 self.write_space();
32341 self.generate_expression(using)?;
32342 } else if let Some(parser) = &e.parser {
32343 self.write_keyword("WITH PARSER");
32344 self.write_space();
32345 self.generate_expression(parser)?;
32346 } else if let Some(comment) = &e.comment {
32347 self.write_keyword("COMMENT");
32348 self.write_space();
32349 self.generate_expression(comment)?;
32350 } else if let Some(visible) = &e.visible {
32351 self.generate_expression(visible)?;
32352 } else if let Some(engine_attr) = &e.engine_attr {
32353 self.write_keyword("ENGINE_ATTRIBUTE");
32354 self.write(" = ");
32355 self.generate_expression(engine_attr)?;
32356 } else if let Some(secondary_engine_attr) = &e.secondary_engine_attr {
32357 self.write_keyword("SECONDARY_ENGINE_ATTRIBUTE");
32358 self.write(" = ");
32359 self.generate_expression(secondary_engine_attr)?;
32360 }
32361 Ok(())
32362 }
32363
32364 fn generate_index_parameters(&mut self, e: &IndexParameters) -> Result<()> {
32365 if let Some(using) = &e.using {
32367 self.write_keyword("USING");
32368 self.write_space();
32369 self.generate_expression(using)?;
32370 }
32371 if !e.columns.is_empty() {
32372 self.write("(");
32373 for (i, col) in e.columns.iter().enumerate() {
32374 if i > 0 {
32375 self.write(", ");
32376 }
32377 self.generate_expression(col)?;
32378 }
32379 self.write(")");
32380 }
32381 if let Some(partition_by) = &e.partition_by {
32382 self.write_space();
32383 self.write_keyword("PARTITION BY");
32384 self.write_space();
32385 self.generate_expression(partition_by)?;
32386 }
32387 if let Some(where_) = &e.where_ {
32388 self.write_space();
32389 self.generate_expression(where_)?;
32390 }
32391 if let Some(include) = &e.include {
32392 self.write_space();
32393 self.write_keyword("INCLUDE");
32394 self.write(" (");
32395 self.generate_expression(include)?;
32396 self.write(")");
32397 }
32398 if let Some(with_storage) = &e.with_storage {
32399 self.write_space();
32400 self.write_keyword("WITH");
32401 self.write(" (");
32402 self.generate_expression(with_storage)?;
32403 self.write(")");
32404 }
32405 if let Some(tablespace) = &e.tablespace {
32406 self.write_space();
32407 self.write_keyword("USING INDEX TABLESPACE");
32408 self.write_space();
32409 self.generate_expression(tablespace)?;
32410 }
32411 Ok(())
32412 }
32413
32414 fn generate_index_table_hint(&mut self, e: &IndexTableHint) -> Result<()> {
32415 if let Expression::Identifier(id) = &*e.this {
32419 self.write_keyword(&id.name);
32420 } else {
32421 self.generate_expression(&e.this)?;
32422 }
32423 self.write_space();
32424 self.write_keyword("INDEX");
32425 if let Some(target) = &e.target {
32426 self.write_space();
32427 self.write_keyword("FOR");
32428 self.write_space();
32429 if let Expression::Identifier(id) = &**target {
32430 self.write_keyword(&id.name);
32431 } else {
32432 self.generate_expression(target)?;
32433 }
32434 }
32435 self.write(" (");
32437 for (i, expr) in e.expressions.iter().enumerate() {
32438 if i > 0 {
32439 self.write(", ");
32440 }
32441 self.generate_expression(expr)?;
32442 }
32443 self.write(")");
32444 Ok(())
32445 }
32446
32447 fn generate_inherits_property(&mut self, e: &InheritsProperty) -> Result<()> {
32448 self.write_keyword("INHERITS");
32450 self.write(" (");
32451 for (i, expr) in e.expressions.iter().enumerate() {
32452 if i > 0 {
32453 self.write(", ");
32454 }
32455 self.generate_expression(expr)?;
32456 }
32457 self.write(")");
32458 Ok(())
32459 }
32460
32461 fn generate_input_model_property(&mut self, e: &InputModelProperty) -> Result<()> {
32462 self.write_keyword("INPUT");
32464 self.write("(");
32465 self.generate_expression(&e.this)?;
32466 self.write(")");
32467 Ok(())
32468 }
32469
32470 fn generate_input_output_format(&mut self, e: &InputOutputFormat) -> Result<()> {
32471 if let Some(input_format) = &e.input_format {
32473 self.write_keyword("INPUTFORMAT");
32474 self.write_space();
32475 self.generate_expression(input_format)?;
32476 }
32477 if let Some(output_format) = &e.output_format {
32478 if e.input_format.is_some() {
32479 self.write(" ");
32480 }
32481 self.write_keyword("OUTPUTFORMAT");
32482 self.write_space();
32483 self.generate_expression(output_format)?;
32484 }
32485 Ok(())
32486 }
32487
32488 fn generate_install(&mut self, e: &Install) -> Result<()> {
32489 if e.force.is_some() {
32491 self.write_keyword("FORCE");
32492 self.write_space();
32493 }
32494 self.write_keyword("INSTALL");
32495 self.write_space();
32496 self.generate_expression(&e.this)?;
32497 if let Some(from) = &e.from_ {
32498 self.write_space();
32499 self.write_keyword("FROM");
32500 self.write_space();
32501 self.generate_expression(from)?;
32502 }
32503 Ok(())
32504 }
32505
32506 fn generate_interval_op(&mut self, e: &IntervalOp) -> Result<()> {
32507 self.write_keyword("INTERVAL");
32509 self.write_space();
32510 self.generate_expression(&e.expression)?;
32512 if let Some(unit) = &e.unit {
32513 self.write_space();
32514 self.write(unit);
32515 }
32516 Ok(())
32517 }
32518
32519 fn generate_interval_span(&mut self, e: &IntervalSpan) -> Result<()> {
32520 self.write(&format!("{:?}", e.this).to_ascii_uppercase());
32522 self.write_space();
32523 self.write_keyword("TO");
32524 self.write_space();
32525 self.write(&format!("{:?}", e.expression).to_ascii_uppercase());
32526 Ok(())
32527 }
32528
32529 fn generate_into_clause(&mut self, e: &IntoClause) -> Result<()> {
32530 self.write_keyword("INTO");
32532 if e.temporary {
32533 self.write_keyword(" TEMPORARY");
32534 }
32535 if e.unlogged.is_some() {
32536 self.write_keyword(" UNLOGGED");
32537 }
32538 if let Some(this) = &e.this {
32539 self.write_space();
32540 self.generate_expression(this)?;
32541 }
32542 if !e.expressions.is_empty() {
32543 self.write(" (");
32544 for (i, expr) in e.expressions.iter().enumerate() {
32545 if i > 0 {
32546 self.write(", ");
32547 }
32548 self.generate_expression(expr)?;
32549 }
32550 self.write(")");
32551 }
32552 Ok(())
32553 }
32554
32555 fn generate_introducer(&mut self, e: &Introducer) -> Result<()> {
32556 self.generate_expression(&e.this)?;
32558 self.write_space();
32559 self.generate_expression(&e.expression)?;
32560 Ok(())
32561 }
32562
32563 fn generate_isolated_loading_property(&mut self, e: &IsolatedLoadingProperty) -> Result<()> {
32564 self.write_keyword("WITH");
32566 if e.no.is_some() {
32567 self.write_keyword(" NO");
32568 }
32569 if e.concurrent.is_some() {
32570 self.write_keyword(" CONCURRENT");
32571 }
32572 self.write_keyword(" ISOLATED LOADING");
32573 if let Some(target) = &e.target {
32574 self.write_space();
32575 self.generate_expression(target)?;
32576 }
32577 Ok(())
32578 }
32579
32580 fn generate_json(&mut self, e: &JSON) -> Result<()> {
32581 self.write_keyword("JSON");
32583 if let Some(this) = &e.this {
32584 self.write_space();
32585 self.generate_expression(this)?;
32586 }
32587 if let Some(with_) = &e.with_ {
32588 if let Expression::Boolean(b) = with_.as_ref() {
32590 if b.value {
32591 self.write_keyword(" WITH");
32592 } else {
32593 self.write_keyword(" WITHOUT");
32594 }
32595 }
32596 }
32597 if e.unique {
32598 self.write_keyword(" UNIQUE KEYS");
32599 }
32600 Ok(())
32601 }
32602
32603 fn generate_json_array(&mut self, e: &JSONArray) -> Result<()> {
32604 self.write_keyword("JSON_ARRAY");
32606 self.write("(");
32607 for (i, expr) in e.expressions.iter().enumerate() {
32608 if i > 0 {
32609 self.write(", ");
32610 }
32611 self.generate_expression(expr)?;
32612 }
32613 if let Some(null_handling) = &e.null_handling {
32614 self.write_space();
32615 self.generate_expression(null_handling)?;
32616 }
32617 if let Some(return_type) = &e.return_type {
32618 self.write_space();
32619 self.write_keyword("RETURNING");
32620 self.write_space();
32621 self.generate_expression(return_type)?;
32622 }
32623 if e.strict.is_some() {
32624 self.write_space();
32625 self.write_keyword("STRICT");
32626 }
32627 self.write(")");
32628 Ok(())
32629 }
32630
32631 fn generate_json_array_agg_struct(&mut self, e: &JSONArrayAgg) -> Result<()> {
32632 self.write_keyword("JSON_ARRAYAGG");
32634 self.write("(");
32635 self.generate_expression(&e.this)?;
32636 if let Some(order) = &e.order {
32637 self.write_space();
32638 if let Expression::OrderBy(ob) = order.as_ref() {
32640 self.write_keyword("ORDER BY");
32641 self.write_space();
32642 for (i, ord) in ob.expressions.iter().enumerate() {
32643 if i > 0 {
32644 self.write(", ");
32645 }
32646 self.generate_ordered(ord)?;
32647 }
32648 } else {
32649 self.generate_expression(order)?;
32651 }
32652 }
32653 if let Some(null_handling) = &e.null_handling {
32654 self.write_space();
32655 self.generate_expression(null_handling)?;
32656 }
32657 if let Some(return_type) = &e.return_type {
32658 self.write_space();
32659 self.write_keyword("RETURNING");
32660 self.write_space();
32661 self.generate_expression(return_type)?;
32662 }
32663 if e.strict.is_some() {
32664 self.write_space();
32665 self.write_keyword("STRICT");
32666 }
32667 self.write(")");
32668 Ok(())
32669 }
32670
32671 fn generate_json_object_agg_struct(&mut self, e: &JSONObjectAgg) -> Result<()> {
32672 self.write_keyword("JSON_OBJECTAGG");
32674 self.write("(");
32675 for (i, expr) in e.expressions.iter().enumerate() {
32676 if i > 0 {
32677 self.write(", ");
32678 }
32679 self.generate_expression(expr)?;
32680 }
32681 if let Some(null_handling) = &e.null_handling {
32682 self.write_space();
32683 self.generate_expression(null_handling)?;
32684 }
32685 if let Some(unique_keys) = &e.unique_keys {
32686 self.write_space();
32687 if let Expression::Boolean(b) = unique_keys.as_ref() {
32688 if b.value {
32689 self.write_keyword("WITH UNIQUE KEYS");
32690 } else {
32691 self.write_keyword("WITHOUT UNIQUE KEYS");
32692 }
32693 }
32694 }
32695 if let Some(return_type) = &e.return_type {
32696 self.write_space();
32697 self.write_keyword("RETURNING");
32698 self.write_space();
32699 self.generate_expression(return_type)?;
32700 }
32701 self.write(")");
32702 Ok(())
32703 }
32704
32705 fn generate_json_array_append(&mut self, e: &JSONArrayAppend) -> Result<()> {
32706 self.write_keyword("JSON_ARRAY_APPEND");
32708 self.write("(");
32709 self.generate_expression(&e.this)?;
32710 for expr in &e.expressions {
32711 self.write(", ");
32712 self.generate_expression(expr)?;
32713 }
32714 self.write(")");
32715 Ok(())
32716 }
32717
32718 fn generate_json_array_contains(&mut self, e: &JSONArrayContains) -> Result<()> {
32719 self.write_keyword("JSON_ARRAY_CONTAINS");
32721 self.write("(");
32722 self.generate_expression(&e.this)?;
32723 self.write(", ");
32724 self.generate_expression(&e.expression)?;
32725 self.write(")");
32726 Ok(())
32727 }
32728
32729 fn generate_json_array_insert(&mut self, e: &JSONArrayInsert) -> Result<()> {
32730 self.write_keyword("JSON_ARRAY_INSERT");
32732 self.write("(");
32733 self.generate_expression(&e.this)?;
32734 for expr in &e.expressions {
32735 self.write(", ");
32736 self.generate_expression(expr)?;
32737 }
32738 self.write(")");
32739 Ok(())
32740 }
32741
32742 fn generate_jsonb_exists(&mut self, e: &JSONBExists) -> Result<()> {
32743 self.write_keyword("JSONB_EXISTS");
32745 self.write("(");
32746 self.generate_expression(&e.this)?;
32747 if let Some(path) = &e.path {
32748 self.write(", ");
32749 self.generate_expression(path)?;
32750 }
32751 self.write(")");
32752 Ok(())
32753 }
32754
32755 fn generate_jsonb_extract_scalar(&mut self, e: &JSONBExtractScalar) -> Result<()> {
32756 self.write_keyword("JSONB_EXTRACT_SCALAR");
32758 self.write("(");
32759 self.generate_expression(&e.this)?;
32760 self.write(", ");
32761 self.generate_expression(&e.expression)?;
32762 self.write(")");
32763 Ok(())
32764 }
32765
32766 fn generate_jsonb_object_agg(&mut self, e: &JSONBObjectAgg) -> Result<()> {
32767 self.write_keyword("JSONB_OBJECT_AGG");
32769 self.write("(");
32770 self.generate_expression(&e.this)?;
32771 self.write(", ");
32772 self.generate_expression(&e.expression)?;
32773 self.write(")");
32774 Ok(())
32775 }
32776
32777 fn generate_json_column_def(&mut self, e: &JSONColumnDef) -> Result<()> {
32778 if let Some(nested_schema) = &e.nested_schema {
32780 self.write_keyword("NESTED");
32781 if let Some(path) = &e.path {
32782 self.write_space();
32783 self.write_keyword("PATH");
32784 self.write_space();
32785 self.generate_expression(path)?;
32786 }
32787 self.write_space();
32788 self.generate_expression(nested_schema)?;
32789 } else {
32790 if let Some(this) = &e.this {
32791 self.generate_expression(this)?;
32792 }
32793 if let Some(kind) = &e.kind {
32794 self.write_space();
32795 self.write(kind);
32796 }
32797 if e.format_json {
32798 self.write_space();
32799 self.write_keyword("FORMAT JSON");
32800 }
32801 if let Some(path) = &e.path {
32802 self.write_space();
32803 self.write_keyword("PATH");
32804 self.write_space();
32805 self.generate_expression(path)?;
32806 }
32807 if e.ordinality.is_some() {
32808 self.write_keyword(" FOR ORDINALITY");
32809 }
32810 }
32811 Ok(())
32812 }
32813
32814 fn generate_json_exists(&mut self, e: &JSONExists) -> Result<()> {
32815 self.write_keyword("JSON_EXISTS");
32817 self.write("(");
32818 self.generate_expression(&e.this)?;
32819 if let Some(path) = &e.path {
32820 self.write(", ");
32821 self.generate_expression(path)?;
32822 }
32823 if let Some(passing) = &e.passing {
32824 self.write_space();
32825 self.write_keyword("PASSING");
32826 self.write_space();
32827 self.generate_expression(passing)?;
32828 }
32829 if let Some(on_condition) = &e.on_condition {
32830 self.write_space();
32831 self.generate_expression(on_condition)?;
32832 }
32833 self.write(")");
32834 Ok(())
32835 }
32836
32837 fn generate_json_cast(&mut self, e: &JSONCast) -> Result<()> {
32838 self.generate_expression(&e.this)?;
32839 self.write(".:");
32840 if Self::data_type_has_nested_expressions(&e.to) {
32844 let saved = std::mem::take(&mut self.output);
32846 self.generate_data_type(&e.to)?;
32847 let type_sql = std::mem::replace(&mut self.output, saved);
32848 self.write("\"");
32849 self.write(&type_sql);
32850 self.write("\"");
32851 } else {
32852 self.generate_data_type(&e.to)?;
32853 }
32854 Ok(())
32855 }
32856
32857 fn data_type_has_nested_expressions(dt: &DataType) -> bool {
32860 matches!(
32861 dt,
32862 DataType::Array { .. } | DataType::Map { .. } | DataType::Struct { .. }
32863 )
32864 }
32865
32866 fn generate_json_extract_array(&mut self, e: &JSONExtractArray) -> Result<()> {
32867 self.write_keyword("JSON_EXTRACT_ARRAY");
32869 self.write("(");
32870 self.generate_expression(&e.this)?;
32871 if let Some(expr) = &e.expression {
32872 self.write(", ");
32873 self.generate_expression(expr)?;
32874 }
32875 self.write(")");
32876 Ok(())
32877 }
32878
32879 fn generate_json_extract_quote(&mut self, e: &JSONExtractQuote) -> Result<()> {
32880 if let Some(option) = &e.option {
32882 self.generate_expression(option)?;
32883 self.write_space();
32884 }
32885 self.write_keyword("QUOTES");
32886 if e.scalar.is_some() {
32887 self.write_keyword(" SCALAR_ONLY");
32888 }
32889 Ok(())
32890 }
32891
32892 fn generate_json_extract_scalar(&mut self, e: &JSONExtractScalar) -> Result<()> {
32893 self.write_keyword("JSON_EXTRACT_SCALAR");
32895 self.write("(");
32896 self.generate_expression(&e.this)?;
32897 self.write(", ");
32898 self.generate_expression(&e.expression)?;
32899 self.write(")");
32900 Ok(())
32901 }
32902
32903 fn generate_json_extract_path(&mut self, e: &JSONExtract) -> Result<()> {
32904 if e.variant_extract.is_some() {
32908 use crate::dialects::DialectType;
32909 if matches!(self.config.dialect, Some(DialectType::Databricks)) {
32910 self.generate_expression(&e.this)?;
32914 self.write(":");
32915 match e.expression.as_ref() {
32916 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
32917 let Literal::String(s) = lit.as_ref() else {
32918 unreachable!()
32919 };
32920 self.write_databricks_json_path(s);
32921 }
32922 _ => {
32923 self.generate_expression(&e.expression)?;
32925 }
32926 }
32927 } else {
32928 self.write_keyword("GET_PATH");
32930 self.write("(");
32931 self.generate_expression(&e.this)?;
32932 self.write(", ");
32933 self.generate_expression(&e.expression)?;
32934 self.write(")");
32935 }
32936 } else {
32937 self.write_keyword("JSON_EXTRACT");
32938 self.write("(");
32939 self.generate_expression(&e.this)?;
32940 self.write(", ");
32941 self.generate_expression(&e.expression)?;
32942 for expr in &e.expressions {
32943 self.write(", ");
32944 self.generate_expression(expr)?;
32945 }
32946 self.write(")");
32947 }
32948 Ok(())
32949 }
32950
32951 fn write_databricks_json_path(&mut self, path: &str) {
32955 if path.starts_with("[\"") || path.starts_with("['") {
32958 self.write(path);
32959 return;
32960 }
32961 let mut first = true;
32965 for segment in path.split('.') {
32966 if !first {
32967 self.write(".");
32968 }
32969 first = false;
32970 if let Some(bracket_pos) = segment.find('[') {
32972 let key = &segment[..bracket_pos];
32973 let subscript = &segment[bracket_pos..];
32974 if key.is_empty() {
32975 self.write(segment);
32977 } else if Self::is_safe_json_path_key(key) {
32978 self.write(key);
32979 self.write(subscript);
32980 } else {
32981 self.write("[\"");
32982 self.write(key);
32983 self.write("\"]");
32984 self.write(subscript);
32985 }
32986 } else if Self::is_safe_json_path_key(segment) {
32987 self.write(segment);
32988 } else {
32989 self.write("[\"");
32990 self.write(segment);
32991 self.write("\"]");
32992 }
32993 }
32994 }
32995
32996 fn is_safe_json_path_key(key: &str) -> bool {
32999 if key.is_empty() {
33000 return false;
33001 }
33002 let mut chars = key.chars();
33003 let first = chars.next().unwrap();
33004 if first != '_' && !first.is_ascii_alphabetic() {
33005 return false;
33006 }
33007 chars.all(|c| c == '_' || c.is_ascii_alphanumeric())
33008 }
33009
33010 fn generate_json_format(&mut self, e: &JSONFormat) -> Result<()> {
33011 if let Some(this) = &e.this {
33014 self.generate_expression(this)?;
33015 self.write_space();
33016 }
33017 self.write_keyword("FORMAT JSON");
33018 Ok(())
33019 }
33020
33021 fn generate_json_key_value(&mut self, e: &JSONKeyValue) -> Result<()> {
33022 self.generate_expression(&e.this)?;
33024 self.write(": ");
33025 self.generate_expression(&e.expression)?;
33026 Ok(())
33027 }
33028
33029 fn generate_json_keys(&mut self, e: &JSONKeys) -> Result<()> {
33030 self.write_keyword("JSON_KEYS");
33032 self.write("(");
33033 self.generate_expression(&e.this)?;
33034 if let Some(expr) = &e.expression {
33035 self.write(", ");
33036 self.generate_expression(expr)?;
33037 }
33038 for expr in &e.expressions {
33039 self.write(", ");
33040 self.generate_expression(expr)?;
33041 }
33042 self.write(")");
33043 Ok(())
33044 }
33045
33046 fn generate_json_keys_at_depth(&mut self, e: &JSONKeysAtDepth) -> Result<()> {
33047 self.write_keyword("JSON_KEYS");
33049 self.write("(");
33050 self.generate_expression(&e.this)?;
33051 if let Some(expr) = &e.expression {
33052 self.write(", ");
33053 self.generate_expression(expr)?;
33054 }
33055 self.write(")");
33056 Ok(())
33057 }
33058
33059 fn generate_json_path_expr(&mut self, e: &JSONPath) -> Result<()> {
33060 let mut path_str = String::new();
33063 for expr in &e.expressions {
33064 match expr {
33065 Expression::JSONPathRoot(_) => {
33066 path_str.push('$');
33067 }
33068 Expression::JSONPathKey(k) => {
33069 if let Expression::Literal(lit) = k.this.as_ref() {
33071 if let crate::expressions::Literal::String(s) = lit.as_ref() {
33072 path_str.push('.');
33073 let needs_quoting = s.chars().any(|c| !c.is_alphanumeric() && c != '_');
33075 if needs_quoting {
33076 path_str.push('"');
33077 path_str.push_str(s);
33078 path_str.push('"');
33079 } else {
33080 path_str.push_str(s);
33081 }
33082 }
33083 }
33084 }
33085 Expression::JSONPathSubscript(s) => {
33086 if let Expression::Literal(lit) = s.this.as_ref() {
33088 if let crate::expressions::Literal::Number(n) = lit.as_ref() {
33089 path_str.push('[');
33090 path_str.push_str(n);
33091 path_str.push(']');
33092 }
33093 }
33094 }
33095 _ => {
33096 let mut temp_gen = Self::with_arc_config(self.config.clone());
33098 temp_gen.generate_expression(expr)?;
33099 path_str.push_str(&temp_gen.output);
33100 }
33101 }
33102 }
33103 self.write("'");
33105 self.write(&path_str);
33106 self.write("'");
33107 Ok(())
33108 }
33109
33110 fn generate_json_path_filter(&mut self, e: &JSONPathFilter) -> Result<()> {
33111 self.write("?(");
33113 self.generate_expression(&e.this)?;
33114 self.write(")");
33115 Ok(())
33116 }
33117
33118 fn generate_json_path_key(&mut self, e: &JSONPathKey) -> Result<()> {
33119 self.write(".");
33121 self.generate_expression(&e.this)?;
33122 Ok(())
33123 }
33124
33125 fn generate_json_path_recursive(&mut self, e: &JSONPathRecursive) -> Result<()> {
33126 self.write("..");
33128 if let Some(this) = &e.this {
33129 self.generate_expression(this)?;
33130 }
33131 Ok(())
33132 }
33133
33134 fn generate_json_path_root(&mut self) -> Result<()> {
33135 self.write("$");
33137 Ok(())
33138 }
33139
33140 fn generate_json_path_script(&mut self, e: &JSONPathScript) -> Result<()> {
33141 self.write("(");
33143 self.generate_expression(&e.this)?;
33144 self.write(")");
33145 Ok(())
33146 }
33147
33148 fn generate_json_path_selector(&mut self, e: &JSONPathSelector) -> Result<()> {
33149 self.generate_expression(&e.this)?;
33151 Ok(())
33152 }
33153
33154 fn generate_json_path_slice(&mut self, e: &JSONPathSlice) -> Result<()> {
33155 self.write("[");
33157 if let Some(start) = &e.start {
33158 self.generate_expression(start)?;
33159 }
33160 self.write(":");
33161 if let Some(end) = &e.end {
33162 self.generate_expression(end)?;
33163 }
33164 if let Some(step) = &e.step {
33165 self.write(":");
33166 self.generate_expression(step)?;
33167 }
33168 self.write("]");
33169 Ok(())
33170 }
33171
33172 fn generate_json_path_subscript(&mut self, e: &JSONPathSubscript) -> Result<()> {
33173 self.write("[");
33175 self.generate_expression(&e.this)?;
33176 self.write("]");
33177 Ok(())
33178 }
33179
33180 fn generate_json_path_union(&mut self, e: &JSONPathUnion) -> Result<()> {
33181 self.write("[");
33183 for (i, expr) in e.expressions.iter().enumerate() {
33184 if i > 0 {
33185 self.write(", ");
33186 }
33187 self.generate_expression(expr)?;
33188 }
33189 self.write("]");
33190 Ok(())
33191 }
33192
33193 fn generate_json_remove(&mut self, e: &JSONRemove) -> Result<()> {
33194 self.write_keyword("JSON_REMOVE");
33196 self.write("(");
33197 self.generate_expression(&e.this)?;
33198 for expr in &e.expressions {
33199 self.write(", ");
33200 self.generate_expression(expr)?;
33201 }
33202 self.write(")");
33203 Ok(())
33204 }
33205
33206 fn generate_json_schema(&mut self, e: &JSONSchema) -> Result<()> {
33207 self.write_keyword("COLUMNS");
33210 self.write("(");
33211
33212 if self.config.pretty && !e.expressions.is_empty() {
33213 let mut expr_strings: Vec<String> = Vec::with_capacity(e.expressions.len());
33215 for expr in &e.expressions {
33216 let mut temp_gen = Generator::with_arc_config(self.config.clone());
33217 temp_gen.generate_expression(expr)?;
33218 expr_strings.push(temp_gen.output);
33219 }
33220
33221 if self.too_wide(&expr_strings) {
33223 self.write_newline();
33225 self.indent_level += 1;
33226 for (i, expr_str) in expr_strings.iter().enumerate() {
33227 if i > 0 {
33228 self.write(",");
33229 self.write_newline();
33230 }
33231 self.write_indent();
33232 self.write(expr_str);
33233 }
33234 self.write_newline();
33235 self.indent_level -= 1;
33236 self.write_indent();
33237 } else {
33238 for (i, expr_str) in expr_strings.iter().enumerate() {
33240 if i > 0 {
33241 self.write(", ");
33242 }
33243 self.write(expr_str);
33244 }
33245 }
33246 } else {
33247 for (i, expr) in e.expressions.iter().enumerate() {
33249 if i > 0 {
33250 self.write(", ");
33251 }
33252 self.generate_expression(expr)?;
33253 }
33254 }
33255 self.write(")");
33256 Ok(())
33257 }
33258
33259 fn generate_json_set(&mut self, e: &JSONSet) -> Result<()> {
33260 self.write_keyword("JSON_SET");
33262 self.write("(");
33263 self.generate_expression(&e.this)?;
33264 for expr in &e.expressions {
33265 self.write(", ");
33266 self.generate_expression(expr)?;
33267 }
33268 self.write(")");
33269 Ok(())
33270 }
33271
33272 fn generate_json_strip_nulls(&mut self, e: &JSONStripNulls) -> Result<()> {
33273 self.write_keyword("JSON_STRIP_NULLS");
33275 self.write("(");
33276 self.generate_expression(&e.this)?;
33277 if let Some(expr) = &e.expression {
33278 self.write(", ");
33279 self.generate_expression(expr)?;
33280 }
33281 self.write(")");
33282 Ok(())
33283 }
33284
33285 fn generate_json_table(&mut self, e: &JSONTable) -> Result<()> {
33286 self.write_keyword("JSON_TABLE");
33288 self.write("(");
33289 self.generate_expression(&e.this)?;
33290 if let Some(path) = &e.path {
33291 self.write(", ");
33292 self.generate_expression(path)?;
33293 }
33294 if let Some(error_handling) = &e.error_handling {
33295 self.write_space();
33296 self.generate_expression(error_handling)?;
33297 }
33298 if let Some(empty_handling) = &e.empty_handling {
33299 self.write_space();
33300 self.generate_expression(empty_handling)?;
33301 }
33302 if let Some(schema) = &e.schema {
33303 self.write_space();
33304 self.generate_expression(schema)?;
33305 }
33306 self.write(")");
33307 Ok(())
33308 }
33309
33310 fn generate_json_type(&mut self, e: &JSONType) -> Result<()> {
33311 self.write_keyword("JSON_TYPE");
33313 self.write("(");
33314 self.generate_expression(&e.this)?;
33315 self.write(")");
33316 Ok(())
33317 }
33318
33319 fn generate_json_value(&mut self, e: &JSONValue) -> Result<()> {
33320 self.write_keyword("JSON_VALUE");
33322 self.write("(");
33323 self.generate_expression(&e.this)?;
33324 if let Some(path) = &e.path {
33325 self.write(", ");
33326 self.generate_expression(path)?;
33327 }
33328 if let Some(returning) = &e.returning {
33329 self.write_space();
33330 self.write_keyword("RETURNING");
33331 self.write_space();
33332 self.generate_expression(returning)?;
33333 }
33334 if let Some(on_condition) = &e.on_condition {
33335 self.write_space();
33336 self.generate_expression(on_condition)?;
33337 }
33338 self.write(")");
33339 Ok(())
33340 }
33341
33342 fn generate_json_value_array(&mut self, e: &JSONValueArray) -> Result<()> {
33343 self.write_keyword("JSON_VALUE_ARRAY");
33345 self.write("(");
33346 self.generate_expression(&e.this)?;
33347 self.write(")");
33348 Ok(())
33349 }
33350
33351 fn generate_jarowinkler_similarity(&mut self, e: &JarowinklerSimilarity) -> Result<()> {
33352 self.write_keyword("JAROWINKLER_SIMILARITY");
33354 self.write("(");
33355 self.generate_expression(&e.this)?;
33356 self.write(", ");
33357 self.generate_expression(&e.expression)?;
33358 self.write(")");
33359 Ok(())
33360 }
33361
33362 fn generate_join_hint(&mut self, e: &JoinHint) -> Result<()> {
33363 self.generate_expression(&e.this)?;
33365 self.write("(");
33366 for (i, expr) in e.expressions.iter().enumerate() {
33367 if i > 0 {
33368 self.write(", ");
33369 }
33370 self.generate_expression(expr)?;
33371 }
33372 self.write(")");
33373 Ok(())
33374 }
33375
33376 fn generate_journal_property(&mut self, e: &JournalProperty) -> Result<()> {
33377 if e.no.is_some() {
33379 self.write_keyword("NO ");
33380 }
33381 if let Some(local) = &e.local {
33382 self.generate_expression(local)?;
33383 self.write_space();
33384 }
33385 if e.dual.is_some() {
33386 self.write_keyword("DUAL ");
33387 }
33388 if e.before.is_some() {
33389 self.write_keyword("BEFORE ");
33390 }
33391 if e.after.is_some() {
33392 self.write_keyword("AFTER ");
33393 }
33394 self.write_keyword("JOURNAL");
33395 Ok(())
33396 }
33397
33398 fn generate_language_property(&mut self, e: &LanguageProperty) -> Result<()> {
33399 self.write_keyword("LANGUAGE");
33401 self.write_space();
33402 self.generate_expression(&e.this)?;
33403 Ok(())
33404 }
33405
33406 fn generate_lateral(&mut self, e: &Lateral) -> Result<()> {
33407 if e.view.is_some() {
33409 self.write_keyword("LATERAL VIEW");
33411 if e.outer.is_some() {
33412 self.write_space();
33413 self.write_keyword("OUTER");
33414 }
33415 self.write_space();
33416 self.generate_expression(&e.this)?;
33417 if let Some(alias) = &e.alias {
33418 self.write_space();
33419 self.write(alias);
33420 }
33421 } else {
33422 self.write_keyword("LATERAL");
33424 self.write_space();
33425 self.generate_expression(&e.this)?;
33426 if e.ordinality.is_some() {
33427 self.write_space();
33428 self.write_keyword("WITH ORDINALITY");
33429 }
33430 if let Some(alias) = &e.alias {
33431 self.write_space();
33432 self.write_keyword("AS");
33433 self.write_space();
33434 self.write(alias);
33435 if !e.column_aliases.is_empty() {
33436 self.write("(");
33437 for (i, col) in e.column_aliases.iter().enumerate() {
33438 if i > 0 {
33439 self.write(", ");
33440 }
33441 self.write(col);
33442 }
33443 self.write(")");
33444 }
33445 }
33446 }
33447 Ok(())
33448 }
33449
33450 fn generate_like_property(&mut self, e: &LikeProperty) -> Result<()> {
33451 self.write_keyword("LIKE");
33453 self.write_space();
33454 self.generate_expression(&e.this)?;
33455 for expr in &e.expressions {
33456 self.write_space();
33457 self.generate_expression(expr)?;
33458 }
33459 Ok(())
33460 }
33461
33462 fn generate_limit(&mut self, e: &Limit) -> Result<()> {
33463 self.write_keyword("LIMIT");
33464 self.write_space();
33465 self.write_limit_expr(&e.this)?;
33466 if e.percent {
33467 self.write_space();
33468 self.write_keyword("PERCENT");
33469 }
33470 for comment in &e.comments {
33472 self.write(" ");
33473 self.write_formatted_comment(comment);
33474 }
33475 Ok(())
33476 }
33477
33478 fn generate_limit_options(&mut self, e: &LimitOptions) -> Result<()> {
33479 if e.percent.is_some() {
33481 self.write_keyword(" PERCENT");
33482 }
33483 if e.rows.is_some() {
33484 self.write_keyword(" ROWS");
33485 }
33486 if e.with_ties.is_some() {
33487 self.write_keyword(" WITH TIES");
33488 } else if e.rows.is_some() {
33489 self.write_keyword(" ONLY");
33490 }
33491 Ok(())
33492 }
33493
33494 fn generate_list(&mut self, e: &List) -> Result<()> {
33495 use crate::dialects::DialectType;
33496 let is_materialize = matches!(self.config.dialect, Some(DialectType::Materialize));
33497
33498 if e.expressions.len() == 1 {
33500 if let Expression::Select(_) = &e.expressions[0] {
33501 self.write_keyword("LIST");
33502 self.write("(");
33503 self.generate_expression(&e.expressions[0])?;
33504 self.write(")");
33505 return Ok(());
33506 }
33507 }
33508
33509 if is_materialize {
33511 self.write_keyword("LIST");
33512 self.write("[");
33513 for (i, expr) in e.expressions.iter().enumerate() {
33514 if i > 0 {
33515 self.write(", ");
33516 }
33517 self.generate_expression(expr)?;
33518 }
33519 self.write("]");
33520 } else {
33521 self.write_keyword("LIST");
33523 self.write("(");
33524 for (i, expr) in e.expressions.iter().enumerate() {
33525 if i > 0 {
33526 self.write(", ");
33527 }
33528 self.generate_expression(expr)?;
33529 }
33530 self.write(")");
33531 }
33532 Ok(())
33533 }
33534
33535 fn generate_tomap(&mut self, e: &ToMap) -> Result<()> {
33536 if let Expression::Select(_) = &*e.this {
33538 self.write_keyword("MAP");
33539 self.write("(");
33540 self.generate_expression(&e.this)?;
33541 self.write(")");
33542 return Ok(());
33543 }
33544
33545 let is_duckdb = matches!(self.config.dialect, Some(DialectType::DuckDB));
33546
33547 self.write_keyword("MAP");
33549 if is_duckdb {
33550 self.write(" {");
33551 } else {
33552 self.write("[");
33553 }
33554 if let Expression::Struct(s) = &*e.this {
33555 for (i, (_, expr)) in s.fields.iter().enumerate() {
33556 if i > 0 {
33557 self.write(", ");
33558 }
33559 if let Expression::PropertyEQ(op) = expr {
33560 self.generate_expression(&op.left)?;
33561 if is_duckdb {
33562 self.write(": ");
33563 } else {
33564 self.write(" => ");
33565 }
33566 self.generate_expression(&op.right)?;
33567 } else {
33568 self.generate_expression(expr)?;
33569 }
33570 }
33571 }
33572 if is_duckdb {
33573 self.write("}");
33574 } else {
33575 self.write("]");
33576 }
33577 Ok(())
33578 }
33579
33580 fn generate_localtime(&mut self, e: &Localtime) -> Result<()> {
33581 self.write_keyword("LOCALTIME");
33583 if let Some(precision) = &e.this {
33584 self.write("(");
33585 self.generate_expression(precision)?;
33586 self.write(")");
33587 }
33588 Ok(())
33589 }
33590
33591 fn generate_localtimestamp(&mut self, e: &Localtimestamp) -> Result<()> {
33592 self.write_keyword("LOCALTIMESTAMP");
33594 if let Some(precision) = &e.this {
33595 self.write("(");
33596 self.generate_expression(precision)?;
33597 self.write(")");
33598 }
33599 Ok(())
33600 }
33601
33602 fn generate_location_property(&mut self, e: &LocationProperty) -> Result<()> {
33603 self.write_keyword("LOCATION");
33605 self.write_space();
33606 self.generate_expression(&e.this)?;
33607 Ok(())
33608 }
33609
33610 fn generate_lock(&mut self, e: &Lock) -> Result<()> {
33611 if e.update.is_some() {
33613 if e.key.is_some() {
33614 self.write_keyword("FOR NO KEY UPDATE");
33615 } else {
33616 self.write_keyword("FOR UPDATE");
33617 }
33618 } else {
33619 if e.key.is_some() {
33620 self.write_keyword("FOR KEY SHARE");
33621 } else {
33622 self.write_keyword("FOR SHARE");
33623 }
33624 }
33625 if !e.expressions.is_empty() {
33626 self.write_keyword(" OF ");
33627 for (i, expr) in e.expressions.iter().enumerate() {
33628 if i > 0 {
33629 self.write(", ");
33630 }
33631 self.generate_expression(expr)?;
33632 }
33633 }
33634 if let Some(wait) = &e.wait {
33639 match wait.as_ref() {
33640 Expression::Boolean(b) => {
33641 if b.value {
33642 self.write_keyword(" NOWAIT");
33643 } else {
33644 self.write_keyword(" SKIP LOCKED");
33645 }
33646 }
33647 _ => {
33648 self.write_keyword(" WAIT ");
33650 self.generate_expression(wait)?;
33651 }
33652 }
33653 }
33654 Ok(())
33655 }
33656
33657 fn generate_lock_property(&mut self, e: &LockProperty) -> Result<()> {
33658 self.write_keyword("LOCK");
33660 self.write_space();
33661 self.generate_expression(&e.this)?;
33662 Ok(())
33663 }
33664
33665 fn generate_locking_property(&mut self, e: &LockingProperty) -> Result<()> {
33666 self.write_keyword("LOCKING");
33668 self.write_space();
33669 self.write(&e.kind);
33670 if let Some(this) = &e.this {
33671 self.write_space();
33672 self.generate_expression(this)?;
33673 }
33674 if let Some(for_or_in) = &e.for_or_in {
33675 self.write_space();
33676 self.generate_expression(for_or_in)?;
33677 }
33678 if let Some(lock_type) = &e.lock_type {
33679 self.write_space();
33680 self.generate_expression(lock_type)?;
33681 }
33682 if e.override_.is_some() {
33683 self.write_keyword(" OVERRIDE");
33684 }
33685 Ok(())
33686 }
33687
33688 fn generate_locking_statement(&mut self, e: &LockingStatement) -> Result<()> {
33689 self.generate_expression(&e.this)?;
33691 self.write_space();
33692 self.generate_expression(&e.expression)?;
33693 Ok(())
33694 }
33695
33696 fn generate_log_property(&mut self, e: &LogProperty) -> Result<()> {
33697 if e.no.is_some() {
33699 self.write_keyword("NO ");
33700 }
33701 self.write_keyword("LOG");
33702 Ok(())
33703 }
33704
33705 fn generate_md5_digest(&mut self, e: &MD5Digest) -> Result<()> {
33706 self.write_keyword("MD5");
33708 self.write("(");
33709 self.generate_expression(&e.this)?;
33710 for expr in &e.expressions {
33711 self.write(", ");
33712 self.generate_expression(expr)?;
33713 }
33714 self.write(")");
33715 Ok(())
33716 }
33717
33718 fn generate_ml_forecast(&mut self, e: &MLForecast) -> Result<()> {
33719 self.write_keyword("ML.FORECAST");
33721 self.write("(");
33722 self.generate_expression(&e.this)?;
33723 if let Some(expression) = &e.expression {
33724 self.write(", ");
33725 self.generate_expression(expression)?;
33726 }
33727 if let Some(params) = &e.params_struct {
33728 self.write(", ");
33729 self.generate_expression(params)?;
33730 }
33731 self.write(")");
33732 Ok(())
33733 }
33734
33735 fn generate_ml_translate(&mut self, e: &MLTranslate) -> Result<()> {
33736 self.write_keyword("ML.TRANSLATE");
33738 self.write("(");
33739 self.generate_expression(&e.this)?;
33740 self.write(", ");
33741 self.generate_expression(&e.expression)?;
33742 if let Some(params) = &e.params_struct {
33743 self.write(", ");
33744 self.generate_expression(params)?;
33745 }
33746 self.write(")");
33747 Ok(())
33748 }
33749
33750 fn generate_make_interval(&mut self, e: &MakeInterval) -> Result<()> {
33751 self.write_keyword("MAKE_INTERVAL");
33753 self.write("(");
33754 let mut first = true;
33755 if let Some(year) = &e.year {
33756 self.write("years => ");
33757 self.generate_expression(year)?;
33758 first = false;
33759 }
33760 if let Some(month) = &e.month {
33761 if !first {
33762 self.write(", ");
33763 }
33764 self.write("months => ");
33765 self.generate_expression(month)?;
33766 first = false;
33767 }
33768 if let Some(week) = &e.week {
33769 if !first {
33770 self.write(", ");
33771 }
33772 self.write("weeks => ");
33773 self.generate_expression(week)?;
33774 first = false;
33775 }
33776 if let Some(day) = &e.day {
33777 if !first {
33778 self.write(", ");
33779 }
33780 self.write("days => ");
33781 self.generate_expression(day)?;
33782 first = false;
33783 }
33784 if let Some(hour) = &e.hour {
33785 if !first {
33786 self.write(", ");
33787 }
33788 self.write("hours => ");
33789 self.generate_expression(hour)?;
33790 first = false;
33791 }
33792 if let Some(minute) = &e.minute {
33793 if !first {
33794 self.write(", ");
33795 }
33796 self.write("mins => ");
33797 self.generate_expression(minute)?;
33798 first = false;
33799 }
33800 if let Some(second) = &e.second {
33801 if !first {
33802 self.write(", ");
33803 }
33804 self.write("secs => ");
33805 self.generate_expression(second)?;
33806 }
33807 self.write(")");
33808 Ok(())
33809 }
33810
33811 fn generate_manhattan_distance(&mut self, e: &ManhattanDistance) -> Result<()> {
33812 self.write_keyword("MANHATTAN_DISTANCE");
33814 self.write("(");
33815 self.generate_expression(&e.this)?;
33816 self.write(", ");
33817 self.generate_expression(&e.expression)?;
33818 self.write(")");
33819 Ok(())
33820 }
33821
33822 fn generate_map(&mut self, e: &Map) -> Result<()> {
33823 self.write_keyword("MAP");
33825 self.write("(");
33826 for (i, (key, value)) in e.keys.iter().zip(e.values.iter()).enumerate() {
33827 if i > 0 {
33828 self.write(", ");
33829 }
33830 self.generate_expression(key)?;
33831 self.write(", ");
33832 self.generate_expression(value)?;
33833 }
33834 self.write(")");
33835 Ok(())
33836 }
33837
33838 fn generate_map_cat(&mut self, e: &MapCat) -> Result<()> {
33839 self.write_keyword("MAP_CAT");
33841 self.write("(");
33842 self.generate_expression(&e.this)?;
33843 self.write(", ");
33844 self.generate_expression(&e.expression)?;
33845 self.write(")");
33846 Ok(())
33847 }
33848
33849 fn generate_map_delete(&mut self, e: &MapDelete) -> Result<()> {
33850 self.write_keyword("MAP_DELETE");
33852 self.write("(");
33853 self.generate_expression(&e.this)?;
33854 for expr in &e.expressions {
33855 self.write(", ");
33856 self.generate_expression(expr)?;
33857 }
33858 self.write(")");
33859 Ok(())
33860 }
33861
33862 fn generate_map_insert(&mut self, e: &MapInsert) -> Result<()> {
33863 self.write_keyword("MAP_INSERT");
33865 self.write("(");
33866 self.generate_expression(&e.this)?;
33867 if let Some(key) = &e.key {
33868 self.write(", ");
33869 self.generate_expression(key)?;
33870 }
33871 if let Some(value) = &e.value {
33872 self.write(", ");
33873 self.generate_expression(value)?;
33874 }
33875 if let Some(update_flag) = &e.update_flag {
33876 self.write(", ");
33877 self.generate_expression(update_flag)?;
33878 }
33879 self.write(")");
33880 Ok(())
33881 }
33882
33883 fn generate_map_pick(&mut self, e: &MapPick) -> Result<()> {
33884 self.write_keyword("MAP_PICK");
33886 self.write("(");
33887 self.generate_expression(&e.this)?;
33888 for expr in &e.expressions {
33889 self.write(", ");
33890 self.generate_expression(expr)?;
33891 }
33892 self.write(")");
33893 Ok(())
33894 }
33895
33896 fn generate_masking_policy_column_constraint(
33897 &mut self,
33898 e: &MaskingPolicyColumnConstraint,
33899 ) -> Result<()> {
33900 self.write_keyword("MASKING POLICY");
33902 self.write_space();
33903 self.generate_expression(&e.this)?;
33904 if !e.expressions.is_empty() {
33905 self.write_keyword(" USING");
33906 self.write(" (");
33907 for (i, expr) in e.expressions.iter().enumerate() {
33908 if i > 0 {
33909 self.write(", ");
33910 }
33911 self.generate_expression(expr)?;
33912 }
33913 self.write(")");
33914 }
33915 Ok(())
33916 }
33917
33918 fn generate_match_against(&mut self, e: &MatchAgainst) -> Result<()> {
33919 if matches!(
33920 self.config.dialect,
33921 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
33922 ) {
33923 if e.expressions.len() > 1 {
33924 self.write("(");
33925 }
33926 for (i, expr) in e.expressions.iter().enumerate() {
33927 if i > 0 {
33928 self.write_keyword(" OR ");
33929 }
33930 self.generate_expression(expr)?;
33931 self.write_space();
33932 self.write("@@");
33933 self.write_space();
33934 self.generate_expression(&e.this)?;
33935 }
33936 if e.expressions.len() > 1 {
33937 self.write(")");
33938 }
33939 return Ok(());
33940 }
33941
33942 self.write_keyword("MATCH");
33944 self.write("(");
33945 for (i, expr) in e.expressions.iter().enumerate() {
33946 if i > 0 {
33947 self.write(", ");
33948 }
33949 self.generate_expression(expr)?;
33950 }
33951 self.write(")");
33952 self.write_keyword(" AGAINST");
33953 self.write("(");
33954 self.generate_expression(&e.this)?;
33955 if let Some(modifier) = &e.modifier {
33956 self.write_space();
33957 self.generate_expression(modifier)?;
33958 }
33959 self.write(")");
33960 Ok(())
33961 }
33962
33963 fn generate_match_recognize_measure(&mut self, e: &MatchRecognizeMeasure) -> Result<()> {
33964 if let Some(window_frame) = &e.window_frame {
33966 self.write(&format!("{:?}", window_frame).to_ascii_uppercase());
33967 self.write_space();
33968 }
33969 self.generate_expression(&e.this)?;
33970 Ok(())
33971 }
33972
33973 fn generate_materialized_property(&mut self, e: &MaterializedProperty) -> Result<()> {
33974 self.write_keyword("MATERIALIZED");
33976 if let Some(this) = &e.this {
33977 self.write_space();
33978 self.generate_expression(this)?;
33979 }
33980 Ok(())
33981 }
33982
33983 fn generate_merge(&mut self, e: &Merge) -> Result<()> {
33984 if let Some(with_) = &e.with_ {
33987 if let Expression::With(with_clause) = with_.as_ref() {
33988 self.generate_with(with_clause)?;
33989 self.write_space();
33990 } else {
33991 self.generate_expression(with_)?;
33992 self.write_space();
33993 }
33994 }
33995 self.write_keyword("MERGE INTO");
33996 self.write_space();
33997 if matches!(self.config.dialect, Some(crate::DialectType::Oracle)) {
33998 if let Expression::Alias(alias) = e.this.as_ref() {
33999 self.generate_expression(&alias.this)?;
34000 self.write_space();
34001 self.generate_identifier(&alias.alias)?;
34002 } else {
34003 self.generate_expression(&e.this)?;
34004 }
34005 } else {
34006 self.generate_expression(&e.this)?;
34007 }
34008
34009 if self.config.pretty {
34011 self.write_newline();
34012 self.write_indent();
34013 } else {
34014 self.write_space();
34015 }
34016 self.write_keyword("USING");
34017 self.write_space();
34018 self.generate_expression(&e.using)?;
34019
34020 if let Some(on) = &e.on {
34022 if self.config.pretty {
34023 self.write_newline();
34024 self.write_indent();
34025 } else {
34026 self.write_space();
34027 }
34028 self.write_keyword("ON");
34029 self.write_space();
34030 self.generate_expression(on)?;
34031 }
34032 if let Some(using_cond) = &e.using_cond {
34034 self.write_space();
34035 self.write_keyword("USING");
34036 self.write_space();
34037 self.write("(");
34038 if let Expression::Tuple(tuple) = using_cond.as_ref() {
34040 for (i, col) in tuple.expressions.iter().enumerate() {
34041 if i > 0 {
34042 self.write(", ");
34043 }
34044 self.generate_expression(col)?;
34045 }
34046 } else {
34047 self.generate_expression(using_cond)?;
34048 }
34049 self.write(")");
34050 }
34051 let saved_merge_strip = std::mem::take(&mut self.merge_strip_qualifiers);
34053 if matches!(
34054 self.config.dialect,
34055 Some(crate::DialectType::PostgreSQL)
34056 | Some(crate::DialectType::Redshift)
34057 | Some(crate::DialectType::Trino)
34058 | Some(crate::DialectType::Presto)
34059 | Some(crate::DialectType::Athena)
34060 ) {
34061 let mut names = Vec::new();
34062 match e.this.as_ref() {
34063 Expression::Alias(a) => {
34064 if let Expression::Table(t) = &a.this {
34066 names.push(t.name.name.clone());
34067 } else if let Expression::Identifier(id) = &a.this {
34068 names.push(id.name.clone());
34069 }
34070 names.push(a.alias.name.clone());
34071 }
34072 Expression::Table(t) => {
34073 names.push(t.name.name.clone());
34074 }
34075 Expression::Identifier(id) => {
34076 names.push(id.name.clone());
34077 }
34078 _ => {}
34079 }
34080 self.merge_strip_qualifiers = names;
34081 }
34082
34083 if let Some(whens) = &e.whens {
34085 if self.config.pretty {
34086 self.write_newline();
34087 self.write_indent();
34088 } else {
34089 self.write_space();
34090 }
34091 self.generate_expression(whens)?;
34092 }
34093
34094 self.merge_strip_qualifiers = saved_merge_strip;
34096
34097 if let Some(returning) = &e.returning {
34099 if self.config.pretty {
34100 self.write_newline();
34101 self.write_indent();
34102 } else {
34103 self.write_space();
34104 }
34105 self.generate_expression(returning)?;
34106 }
34107 Ok(())
34108 }
34109
34110 fn generate_merge_block_ratio_property(&mut self, e: &MergeBlockRatioProperty) -> Result<()> {
34111 if e.no.is_some() {
34113 self.write_keyword("NO MERGEBLOCKRATIO");
34114 } else if e.default.is_some() {
34115 self.write_keyword("DEFAULT MERGEBLOCKRATIO");
34116 } else {
34117 self.write_keyword("MERGEBLOCKRATIO");
34118 self.write("=");
34119 if let Some(this) = &e.this {
34120 self.generate_expression(this)?;
34121 }
34122 if e.percent.is_some() {
34123 self.write_keyword(" PERCENT");
34124 }
34125 }
34126 Ok(())
34127 }
34128
34129 fn generate_merge_tree_ttl(&mut self, e: &MergeTreeTTL) -> Result<()> {
34130 self.write_keyword("TTL");
34132 let pretty_clickhouse = self.config.pretty
34133 && matches!(
34134 self.config.dialect,
34135 Some(crate::dialects::DialectType::ClickHouse)
34136 );
34137
34138 if pretty_clickhouse {
34139 self.write_newline();
34140 self.indent_level += 1;
34141 for (i, expr) in e.expressions.iter().enumerate() {
34142 if i > 0 {
34143 self.write(",");
34144 self.write_newline();
34145 }
34146 self.write_indent();
34147 self.generate_expression(expr)?;
34148 }
34149 self.indent_level -= 1;
34150 } else {
34151 self.write_space();
34152 for (i, expr) in e.expressions.iter().enumerate() {
34153 if i > 0 {
34154 self.write(", ");
34155 }
34156 self.generate_expression(expr)?;
34157 }
34158 }
34159
34160 if let Some(where_) = &e.where_ {
34161 if pretty_clickhouse {
34162 self.write_newline();
34163 if let Expression::Where(w) = where_.as_ref() {
34164 self.write_indent();
34165 self.write_keyword("WHERE");
34166 self.write_newline();
34167 self.indent_level += 1;
34168 self.write_indent();
34169 self.generate_expression(&w.this)?;
34170 self.indent_level -= 1;
34171 } else {
34172 self.write_indent();
34173 self.generate_expression(where_)?;
34174 }
34175 } else {
34176 self.write_space();
34177 self.generate_expression(where_)?;
34178 }
34179 }
34180 if let Some(group) = &e.group {
34181 if pretty_clickhouse {
34182 self.write_newline();
34183 if let Expression::Group(g) = group.as_ref() {
34184 self.write_indent();
34185 self.write_keyword("GROUP BY");
34186 self.write_newline();
34187 self.indent_level += 1;
34188 for (i, expr) in g.expressions.iter().enumerate() {
34189 if i > 0 {
34190 self.write(",");
34191 self.write_newline();
34192 }
34193 self.write_indent();
34194 self.generate_expression(expr)?;
34195 }
34196 self.indent_level -= 1;
34197 } else {
34198 self.write_indent();
34199 self.generate_expression(group)?;
34200 }
34201 } else {
34202 self.write_space();
34203 self.generate_expression(group)?;
34204 }
34205 }
34206 if let Some(aggregates) = &e.aggregates {
34207 if pretty_clickhouse {
34208 self.write_newline();
34209 self.write_indent();
34210 self.write_keyword("SET");
34211 self.write_newline();
34212 self.indent_level += 1;
34213 if let Expression::Tuple(t) = aggregates.as_ref() {
34214 for (i, agg) in t.expressions.iter().enumerate() {
34215 if i > 0 {
34216 self.write(",");
34217 self.write_newline();
34218 }
34219 self.write_indent();
34220 self.generate_expression(agg)?;
34221 }
34222 } else {
34223 self.write_indent();
34224 self.generate_expression(aggregates)?;
34225 }
34226 self.indent_level -= 1;
34227 } else {
34228 self.write_space();
34229 self.write_keyword("SET");
34230 self.write_space();
34231 if let Expression::Tuple(t) = aggregates.as_ref() {
34232 for (i, agg) in t.expressions.iter().enumerate() {
34233 if i > 0 {
34234 self.write(", ");
34235 }
34236 self.generate_expression(agg)?;
34237 }
34238 } else {
34239 self.generate_expression(aggregates)?;
34240 }
34241 }
34242 }
34243 Ok(())
34244 }
34245
34246 fn generate_merge_tree_ttl_action(&mut self, e: &MergeTreeTTLAction) -> Result<()> {
34247 self.generate_expression(&e.this)?;
34249 if e.delete.is_some() {
34250 self.write_keyword(" DELETE");
34251 }
34252 if let Some(recompress) = &e.recompress {
34253 self.write_keyword(" RECOMPRESS ");
34254 self.generate_expression(recompress)?;
34255 }
34256 if let Some(to_disk) = &e.to_disk {
34257 self.write_keyword(" TO DISK ");
34258 self.generate_expression(to_disk)?;
34259 }
34260 if let Some(to_volume) = &e.to_volume {
34261 self.write_keyword(" TO VOLUME ");
34262 self.generate_expression(to_volume)?;
34263 }
34264 Ok(())
34265 }
34266
34267 fn generate_minhash(&mut self, e: &Minhash) -> Result<()> {
34268 self.write_keyword("MINHASH");
34270 self.write("(");
34271 self.generate_expression(&e.this)?;
34272 for expr in &e.expressions {
34273 self.write(", ");
34274 self.generate_expression(expr)?;
34275 }
34276 self.write(")");
34277 Ok(())
34278 }
34279
34280 fn generate_model_attribute(&mut self, e: &ModelAttribute) -> Result<()> {
34281 self.generate_expression(&e.this)?;
34283 self.write("!");
34284 self.generate_expression(&e.expression)?;
34285 Ok(())
34286 }
34287
34288 fn generate_monthname(&mut self, e: &Monthname) -> Result<()> {
34289 self.write_keyword("MONTHNAME");
34291 self.write("(");
34292 self.generate_expression(&e.this)?;
34293 self.write(")");
34294 Ok(())
34295 }
34296
34297 fn generate_multitable_inserts(&mut self, e: &MultitableInserts) -> Result<()> {
34298 for comment in &e.leading_comments {
34300 self.write_formatted_comment(comment);
34301 if self.config.pretty {
34302 self.write_newline();
34303 self.write_indent();
34304 } else {
34305 self.write_space();
34306 }
34307 }
34308 self.write_keyword("INSERT");
34310 if e.overwrite {
34311 self.write_space();
34312 self.write_keyword("OVERWRITE");
34313 }
34314 self.write_space();
34315 self.write(&e.kind);
34316 if self.config.pretty {
34317 self.indent_level += 1;
34318 for expr in &e.expressions {
34319 self.write_newline();
34320 self.write_indent();
34321 self.generate_expression(expr)?;
34322 }
34323 self.indent_level -= 1;
34324 } else {
34325 for expr in &e.expressions {
34326 self.write_space();
34327 self.generate_expression(expr)?;
34328 }
34329 }
34330 if let Some(source) = &e.source {
34331 if self.config.pretty {
34332 self.write_newline();
34333 self.write_indent();
34334 } else {
34335 self.write_space();
34336 }
34337 self.generate_expression(source)?;
34338 }
34339 Ok(())
34340 }
34341
34342 fn generate_next_value_for(&mut self, e: &NextValueFor) -> Result<()> {
34343 self.write_keyword("NEXT VALUE FOR");
34345 self.write_space();
34346 self.generate_expression(&e.this)?;
34347 if let Some(order) = &e.order {
34348 self.write_space();
34349 self.write_keyword("OVER");
34350 self.write(" (");
34351 self.generate_expression(order)?;
34352 self.write(")");
34353 }
34354 Ok(())
34355 }
34356
34357 fn generate_normal(&mut self, e: &Normal) -> Result<()> {
34358 self.write_keyword("NORMAL");
34360 self.write("(");
34361 self.generate_expression(&e.this)?;
34362 if let Some(stddev) = &e.stddev {
34363 self.write(", ");
34364 self.generate_expression(stddev)?;
34365 }
34366 if let Some(gen) = &e.gen {
34367 self.write(", ");
34368 self.generate_expression(gen)?;
34369 }
34370 self.write(")");
34371 Ok(())
34372 }
34373
34374 fn generate_normalize(&mut self, e: &Normalize) -> Result<()> {
34375 if e.is_casefold.is_some() {
34377 self.write_keyword("NORMALIZE_AND_CASEFOLD");
34378 } else {
34379 self.write_keyword("NORMALIZE");
34380 }
34381 self.write("(");
34382 self.generate_expression(&e.this)?;
34383 if let Some(form) = &e.form {
34384 self.write(", ");
34385 self.generate_expression(form)?;
34386 }
34387 self.write(")");
34388 Ok(())
34389 }
34390
34391 fn generate_not_null_column_constraint(&mut self, e: &NotNullColumnConstraint) -> Result<()> {
34392 if e.allow_null.is_none() {
34394 self.write_keyword("NOT ");
34395 }
34396 self.write_keyword("NULL");
34397 Ok(())
34398 }
34399
34400 fn generate_nullif(&mut self, e: &Nullif) -> Result<()> {
34401 self.write_keyword("NULLIF");
34403 self.write("(");
34404 self.generate_expression(&e.this)?;
34405 self.write(", ");
34406 self.generate_expression(&e.expression)?;
34407 self.write(")");
34408 Ok(())
34409 }
34410
34411 fn generate_number_to_str(&mut self, e: &NumberToStr) -> Result<()> {
34412 self.write_keyword("FORMAT");
34414 self.write("(");
34415 self.generate_expression(&e.this)?;
34416 self.write(", '");
34417 self.write(&e.format);
34418 self.write("'");
34419 if let Some(culture) = &e.culture {
34420 self.write(", ");
34421 self.generate_expression(culture)?;
34422 }
34423 self.write(")");
34424 Ok(())
34425 }
34426
34427 fn generate_object_agg(&mut self, e: &ObjectAgg) -> Result<()> {
34428 self.write_keyword("OBJECT_AGG");
34430 self.write("(");
34431 self.generate_expression(&e.this)?;
34432 self.write(", ");
34433 self.generate_expression(&e.expression)?;
34434 self.write(")");
34435 Ok(())
34436 }
34437
34438 fn generate_object_identifier(&mut self, e: &ObjectIdentifier) -> Result<()> {
34439 self.generate_expression(&e.this)?;
34441 Ok(())
34442 }
34443
34444 fn generate_object_insert(&mut self, e: &ObjectInsert) -> Result<()> {
34445 self.write_keyword("OBJECT_INSERT");
34447 self.write("(");
34448 self.generate_expression(&e.this)?;
34449 if let Some(key) = &e.key {
34450 self.write(", ");
34451 self.generate_expression(key)?;
34452 }
34453 if let Some(value) = &e.value {
34454 self.write(", ");
34455 self.generate_expression(value)?;
34456 }
34457 if let Some(update_flag) = &e.update_flag {
34458 self.write(", ");
34459 self.generate_expression(update_flag)?;
34460 }
34461 self.write(")");
34462 Ok(())
34463 }
34464
34465 fn generate_offset(&mut self, e: &Offset) -> Result<()> {
34466 self.write_keyword("OFFSET");
34468 self.write_space();
34469 self.generate_expression(&e.this)?;
34470 if e.rows == Some(true)
34472 && matches!(
34473 self.config.dialect,
34474 Some(crate::dialects::DialectType::TSQL)
34475 | Some(crate::dialects::DialectType::Oracle)
34476 )
34477 {
34478 self.write_space();
34479 self.write_keyword("ROWS");
34480 }
34481 Ok(())
34482 }
34483
34484 fn generate_qualify(&mut self, e: &Qualify) -> Result<()> {
34485 self.write_keyword("QUALIFY");
34487 self.write_space();
34488 self.generate_expression(&e.this)?;
34489 Ok(())
34490 }
34491
34492 fn generate_on_cluster(&mut self, e: &OnCluster) -> Result<()> {
34493 self.write_keyword("ON CLUSTER");
34495 self.write_space();
34496 self.generate_expression(&e.this)?;
34497 Ok(())
34498 }
34499
34500 fn generate_on_commit_property(&mut self, e: &OnCommitProperty) -> Result<()> {
34501 self.write_keyword("ON COMMIT");
34503 if e.delete.is_some() {
34504 self.write_keyword(" DELETE ROWS");
34505 } else {
34506 self.write_keyword(" PRESERVE ROWS");
34507 }
34508 Ok(())
34509 }
34510
34511 fn generate_on_condition(&mut self, e: &OnCondition) -> Result<()> {
34512 if let Some(empty) = &e.empty {
34514 self.generate_expression(empty)?;
34515 self.write_keyword(" ON EMPTY");
34516 }
34517 if let Some(error) = &e.error {
34518 if e.empty.is_some() {
34519 self.write_space();
34520 }
34521 self.generate_expression(error)?;
34522 self.write_keyword(" ON ERROR");
34523 }
34524 if let Some(null) = &e.null {
34525 if e.empty.is_some() || e.error.is_some() {
34526 self.write_space();
34527 }
34528 self.generate_expression(null)?;
34529 self.write_keyword(" ON NULL");
34530 }
34531 Ok(())
34532 }
34533
34534 fn generate_on_conflict(&mut self, e: &OnConflict) -> Result<()> {
34535 if matches!(self.config.dialect, Some(DialectType::Materialize)) {
34537 return Ok(());
34538 }
34539 if e.duplicate.is_some() {
34541 self.write_keyword("ON DUPLICATE KEY UPDATE");
34543 for (i, expr) in e.expressions.iter().enumerate() {
34544 if i > 0 {
34545 self.write(",");
34546 }
34547 self.write_space();
34548 self.generate_expression(expr)?;
34549 }
34550 return Ok(());
34551 } else {
34552 self.write_keyword("ON CONFLICT");
34553 }
34554 if let Some(constraint) = &e.constraint {
34555 self.write_keyword(" ON CONSTRAINT ");
34556 self.generate_expression(constraint)?;
34557 }
34558 if let Some(conflict_keys) = &e.conflict_keys {
34559 if let Expression::Tuple(t) = conflict_keys.as_ref() {
34561 self.write("(");
34562 for (i, expr) in t.expressions.iter().enumerate() {
34563 if i > 0 {
34564 self.write(", ");
34565 }
34566 self.generate_expression(expr)?;
34567 }
34568 self.write(")");
34569 } else {
34570 self.write("(");
34571 self.generate_expression(conflict_keys)?;
34572 self.write(")");
34573 }
34574 }
34575 if let Some(index_predicate) = &e.index_predicate {
34576 self.write_keyword(" WHERE ");
34577 self.generate_expression(index_predicate)?;
34578 }
34579 if let Some(action) = &e.action {
34580 if let Expression::Identifier(id) = action.as_ref() {
34582 if id.name.eq_ignore_ascii_case("NOTHING") {
34583 self.write_keyword(" DO NOTHING");
34584 } else {
34585 self.write_keyword(" DO ");
34586 self.generate_expression(action)?;
34587 }
34588 } else if let Expression::Tuple(t) = action.as_ref() {
34589 self.write_keyword(" DO UPDATE SET ");
34591 for (i, expr) in t.expressions.iter().enumerate() {
34592 if i > 0 {
34593 self.write(", ");
34594 }
34595 self.generate_expression(expr)?;
34596 }
34597 } else {
34598 self.write_keyword(" DO ");
34599 self.generate_expression(action)?;
34600 }
34601 }
34602 if let Some(where_) = &e.where_ {
34604 self.write_keyword(" WHERE ");
34605 self.generate_expression(where_)?;
34606 }
34607 Ok(())
34608 }
34609
34610 fn generate_on_property(&mut self, e: &OnProperty) -> Result<()> {
34611 self.write_keyword("ON");
34613 self.write_space();
34614 self.generate_expression(&e.this)?;
34615 Ok(())
34616 }
34617
34618 fn generate_opclass(&mut self, e: &Opclass) -> Result<()> {
34619 self.generate_expression(&e.this)?;
34621 self.write_space();
34622 self.generate_expression(&e.expression)?;
34623 Ok(())
34624 }
34625
34626 fn generate_open_json(&mut self, e: &OpenJSON) -> Result<()> {
34627 self.write_keyword("OPENJSON");
34629 self.write("(");
34630 self.generate_expression(&e.this)?;
34631 if let Some(path) = &e.path {
34632 self.write(", ");
34633 self.generate_expression(path)?;
34634 }
34635 self.write(")");
34636 if !e.expressions.is_empty() {
34637 self.write_keyword(" WITH");
34638 if self.config.pretty {
34639 self.write(" (\n");
34640 self.indent_level += 2;
34641 for (i, expr) in e.expressions.iter().enumerate() {
34642 if i > 0 {
34643 self.write(",\n");
34644 }
34645 self.write_indent();
34646 self.generate_expression(expr)?;
34647 }
34648 self.write("\n");
34649 self.indent_level -= 2;
34650 self.write(")");
34651 } else {
34652 self.write(" (");
34653 for (i, expr) in e.expressions.iter().enumerate() {
34654 if i > 0 {
34655 self.write(", ");
34656 }
34657 self.generate_expression(expr)?;
34658 }
34659 self.write(")");
34660 }
34661 }
34662 Ok(())
34663 }
34664
34665 fn generate_open_json_column_def(&mut self, e: &OpenJSONColumnDef) -> Result<()> {
34666 self.generate_expression(&e.this)?;
34668 self.write_space();
34669 if let Some(ref dt) = e.data_type {
34671 self.generate_data_type(dt)?;
34672 } else if !e.kind.is_empty() {
34673 self.write(&e.kind);
34674 }
34675 if let Some(path) = &e.path {
34676 self.write_space();
34677 self.generate_expression(path)?;
34678 }
34679 if e.as_json.is_some() {
34680 self.write_keyword(" AS JSON");
34681 }
34682 Ok(())
34683 }
34684
34685 fn generate_operator(&mut self, e: &Operator) -> Result<()> {
34686 self.generate_expression(&e.this)?;
34688 self.write_space();
34689 if let Some(op) = &e.operator {
34690 self.write_keyword("OPERATOR");
34691 self.write("(");
34692 self.generate_expression(op)?;
34693 self.write(")");
34694 }
34695 for comment in &e.comments {
34697 self.write_space();
34698 self.write_formatted_comment(comment);
34699 }
34700 self.write_space();
34701 self.generate_expression(&e.expression)?;
34702 Ok(())
34703 }
34704
34705 fn generate_order_by(&mut self, e: &OrderBy) -> Result<()> {
34706 self.write_keyword("ORDER BY");
34708 let pretty_clickhouse_single_paren = self.config.pretty
34709 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
34710 && e.expressions.len() == 1
34711 && matches!(e.expressions[0].this, Expression::Paren(ref p) if !matches!(p.this, Expression::Tuple(_)));
34712 let clickhouse_single_tuple = matches!(self.config.dialect, Some(DialectType::ClickHouse))
34713 && e.expressions.len() == 1
34714 && matches!(e.expressions[0].this, Expression::Tuple(_))
34715 && !e.expressions[0].desc
34716 && e.expressions[0].nulls_first.is_none();
34717
34718 if pretty_clickhouse_single_paren {
34719 self.write_space();
34720 if let Expression::Paren(p) = &e.expressions[0].this {
34721 self.write("(");
34722 self.write_newline();
34723 self.indent_level += 1;
34724 self.write_indent();
34725 self.generate_expression(&p.this)?;
34726 self.indent_level -= 1;
34727 self.write_newline();
34728 self.write(")");
34729 }
34730 return Ok(());
34731 }
34732
34733 if clickhouse_single_tuple {
34734 self.write_space();
34735 if let Expression::Tuple(t) = &e.expressions[0].this {
34736 self.write("(");
34737 for (i, expr) in t.expressions.iter().enumerate() {
34738 if i > 0 {
34739 self.write(", ");
34740 }
34741 self.generate_expression(expr)?;
34742 }
34743 self.write(")");
34744 }
34745 return Ok(());
34746 }
34747
34748 self.write_space();
34749 for (i, ordered) in e.expressions.iter().enumerate() {
34750 if i > 0 {
34751 self.write(", ");
34752 }
34753 self.generate_expression(&ordered.this)?;
34754 if ordered.desc {
34755 self.write_space();
34756 self.write_keyword("DESC");
34757 } else if ordered.explicit_asc {
34758 self.write_space();
34759 self.write_keyword("ASC");
34760 }
34761 if let Some(nulls_first) = ordered.nulls_first {
34762 let skip_nulls_last =
34764 !nulls_first && matches!(self.config.dialect, Some(DialectType::Dremio));
34765 if !skip_nulls_last {
34766 self.write_space();
34767 self.write_keyword("NULLS");
34768 self.write_space();
34769 if nulls_first {
34770 self.write_keyword("FIRST");
34771 } else {
34772 self.write_keyword("LAST");
34773 }
34774 }
34775 }
34776 }
34777 Ok(())
34778 }
34779
34780 fn generate_output_model_property(&mut self, e: &OutputModelProperty) -> Result<()> {
34781 self.write_keyword("OUTPUT");
34783 self.write("(");
34784 if self.config.pretty {
34785 self.indent_level += 1;
34786 self.write_newline();
34787 self.write_indent();
34788 self.generate_expression(&e.this)?;
34789 self.indent_level -= 1;
34790 self.write_newline();
34791 } else {
34792 self.generate_expression(&e.this)?;
34793 }
34794 self.write(")");
34795 Ok(())
34796 }
34797
34798 fn generate_overflow_truncate_behavior(&mut self, e: &OverflowTruncateBehavior) -> Result<()> {
34799 self.write_keyword("TRUNCATE");
34801 if let Some(this) = &e.this {
34802 self.write_space();
34803 self.generate_expression(this)?;
34804 }
34805 if e.with_count.is_some() {
34806 self.write_keyword(" WITH COUNT");
34807 } else {
34808 self.write_keyword(" WITHOUT COUNT");
34809 }
34810 Ok(())
34811 }
34812
34813 fn generate_parameterized_agg(&mut self, e: &ParameterizedAgg) -> Result<()> {
34814 self.generate_expression(&e.this)?;
34816 self.write("(");
34817 for (i, expr) in e.expressions.iter().enumerate() {
34818 if i > 0 {
34819 self.write(", ");
34820 }
34821 self.generate_expression(expr)?;
34822 }
34823 self.write(")(");
34824 for (i, param) in e.params.iter().enumerate() {
34825 if i > 0 {
34826 self.write(", ");
34827 }
34828 self.generate_expression(param)?;
34829 }
34830 self.write(")");
34831 Ok(())
34832 }
34833
34834 fn generate_parse_datetime(&mut self, e: &ParseDatetime) -> Result<()> {
34835 self.write_keyword("PARSE_DATETIME");
34837 self.write("(");
34838 if let Some(format) = &e.format {
34839 self.write("'");
34840 self.write(format);
34841 self.write("', ");
34842 }
34843 self.generate_expression(&e.this)?;
34844 if let Some(zone) = &e.zone {
34845 self.write(", ");
34846 self.generate_expression(zone)?;
34847 }
34848 self.write(")");
34849 Ok(())
34850 }
34851
34852 fn generate_parse_ip(&mut self, e: &ParseIp) -> Result<()> {
34853 self.write_keyword("PARSE_IP");
34855 self.write("(");
34856 self.generate_expression(&e.this)?;
34857 if let Some(type_) = &e.type_ {
34858 self.write(", ");
34859 self.generate_expression(type_)?;
34860 }
34861 if let Some(permissive) = &e.permissive {
34862 self.write(", ");
34863 self.generate_expression(permissive)?;
34864 }
34865 self.write(")");
34866 Ok(())
34867 }
34868
34869 fn generate_parse_json(&mut self, e: &ParseJSON) -> Result<()> {
34870 self.write_keyword("PARSE_JSON");
34872 self.write("(");
34873 self.generate_expression(&e.this)?;
34874 if let Some(expression) = &e.expression {
34875 self.write(", ");
34876 self.generate_expression(expression)?;
34877 }
34878 self.write(")");
34879 Ok(())
34880 }
34881
34882 fn generate_parse_time(&mut self, e: &ParseTime) -> Result<()> {
34883 self.write_keyword("PARSE_TIME");
34885 self.write("(");
34886 self.write(&format!("'{}'", e.format));
34887 self.write(", ");
34888 self.generate_expression(&e.this)?;
34889 self.write(")");
34890 Ok(())
34891 }
34892
34893 fn generate_parse_url(&mut self, e: &ParseUrl) -> Result<()> {
34894 self.write_keyword("PARSE_URL");
34896 self.write("(");
34897 self.generate_expression(&e.this)?;
34898 if let Some(part) = &e.part_to_extract {
34899 self.write(", ");
34900 self.generate_expression(part)?;
34901 }
34902 if let Some(key) = &e.key {
34903 self.write(", ");
34904 self.generate_expression(key)?;
34905 }
34906 if let Some(permissive) = &e.permissive {
34907 self.write(", ");
34908 self.generate_expression(permissive)?;
34909 }
34910 self.write(")");
34911 Ok(())
34912 }
34913
34914 fn generate_partition_expr(&mut self, e: &Partition) -> Result<()> {
34915 if e.subpartition {
34917 self.write_keyword("SUBPARTITION");
34918 } else {
34919 self.write_keyword("PARTITION");
34920 }
34921 self.write("(");
34922 for (i, expr) in e.expressions.iter().enumerate() {
34923 if i > 0 {
34924 self.write(", ");
34925 }
34926 self.generate_expression(expr)?;
34927 }
34928 self.write(")");
34929 Ok(())
34930 }
34931
34932 fn generate_partition_bound_spec(&mut self, e: &PartitionBoundSpec) -> Result<()> {
34933 if let Some(this) = &e.this {
34935 if let Some(expression) = &e.expression {
34936 self.write_keyword("WITH");
34938 self.write(" (");
34939 self.write_keyword("MODULUS");
34940 self.write_space();
34941 self.generate_expression(this)?;
34942 self.write(", ");
34943 self.write_keyword("REMAINDER");
34944 self.write_space();
34945 self.generate_expression(expression)?;
34946 self.write(")");
34947 } else {
34948 self.write_keyword("IN");
34950 self.write(" (");
34951 self.generate_partition_bound_values(this)?;
34952 self.write(")");
34953 }
34954 } else if let (Some(from), Some(to)) = (&e.from_expressions, &e.to_expressions) {
34955 self.write_keyword("FROM");
34957 self.write(" (");
34958 self.generate_partition_bound_values(from)?;
34959 self.write(") ");
34960 self.write_keyword("TO");
34961 self.write(" (");
34962 self.generate_partition_bound_values(to)?;
34963 self.write(")");
34964 }
34965 Ok(())
34966 }
34967
34968 fn generate_partition_bound_values(&mut self, expr: &Expression) -> Result<()> {
34971 if let Expression::Tuple(t) = expr {
34972 for (i, e) in t.expressions.iter().enumerate() {
34973 if i > 0 {
34974 self.write(", ");
34975 }
34976 self.generate_expression(e)?;
34977 }
34978 Ok(())
34979 } else {
34980 self.generate_expression(expr)
34981 }
34982 }
34983
34984 fn generate_partition_by_list_property(&mut self, e: &PartitionByListProperty) -> Result<()> {
34985 self.write_keyword("PARTITION BY LIST");
34987 if let Some(partition_exprs) = &e.partition_expressions {
34988 self.write(" (");
34989 self.generate_doris_partition_expressions(partition_exprs)?;
34991 self.write(")");
34992 }
34993 if let Some(create_exprs) = &e.create_expressions {
34994 self.write(" (");
34995 self.generate_doris_partition_definitions(create_exprs)?;
34997 self.write(")");
34998 }
34999 Ok(())
35000 }
35001
35002 fn generate_partition_by_range_property(&mut self, e: &PartitionByRangeProperty) -> Result<()> {
35003 self.write_keyword("PARTITION BY RANGE");
35005 if let Some(partition_exprs) = &e.partition_expressions {
35006 self.write(" (");
35007 self.generate_doris_partition_expressions(partition_exprs)?;
35009 self.write(")");
35010 }
35011 if let Some(create_exprs) = &e.create_expressions {
35012 self.write(" (");
35013 self.generate_doris_partition_definitions(create_exprs)?;
35015 self.write(")");
35016 }
35017 Ok(())
35018 }
35019
35020 fn generate_doris_partition_expressions(&mut self, expr: &Expression) -> Result<()> {
35022 if let Expression::Tuple(t) = expr {
35023 for (i, e) in t.expressions.iter().enumerate() {
35024 if i > 0 {
35025 self.write(", ");
35026 }
35027 self.generate_expression(e)?;
35028 }
35029 } else {
35030 self.generate_expression(expr)?;
35031 }
35032 Ok(())
35033 }
35034
35035 fn generate_doris_partition_definitions(&mut self, expr: &Expression) -> Result<()> {
35037 match expr {
35038 Expression::Tuple(t) => {
35039 for (i, part) in t.expressions.iter().enumerate() {
35041 if i > 0 {
35042 self.write(", ");
35043 }
35044 if let Expression::Partition(p) = part {
35046 for (j, inner) in p.expressions.iter().enumerate() {
35047 if j > 0 {
35048 self.write(", ");
35049 }
35050 self.generate_expression(inner)?;
35051 }
35052 } else {
35053 self.generate_expression(part)?;
35054 }
35055 }
35056 }
35057 Expression::PartitionByRangePropertyDynamic(_) => {
35058 self.generate_expression(expr)?;
35060 }
35061 _ => {
35062 self.generate_expression(expr)?;
35063 }
35064 }
35065 Ok(())
35066 }
35067
35068 fn generate_partition_by_range_property_dynamic(
35069 &mut self,
35070 e: &PartitionByRangePropertyDynamic,
35071 ) -> Result<()> {
35072 if e.use_start_end {
35073 if let Some(start) = &e.start {
35075 self.write_keyword("START");
35076 self.write(" (");
35077 self.generate_expression(start)?;
35078 self.write(")");
35079 }
35080 if let Some(end) = &e.end {
35081 self.write_space();
35082 self.write_keyword("END");
35083 self.write(" (");
35084 self.generate_expression(end)?;
35085 self.write(")");
35086 }
35087 if let Some(every) = &e.every {
35088 self.write_space();
35089 self.write_keyword("EVERY");
35090 self.write(" (");
35091 self.generate_doris_interval(every)?;
35093 self.write(")");
35094 }
35095 } else {
35096 if let Some(start) = &e.start {
35098 self.write_keyword("FROM");
35099 self.write(" (");
35100 self.generate_expression(start)?;
35101 self.write(")");
35102 }
35103 if let Some(end) = &e.end {
35104 self.write_space();
35105 self.write_keyword("TO");
35106 self.write(" (");
35107 self.generate_expression(end)?;
35108 self.write(")");
35109 }
35110 if let Some(every) = &e.every {
35111 self.write_space();
35112 self.generate_doris_interval(every)?;
35114 }
35115 }
35116 Ok(())
35117 }
35118
35119 fn generate_doris_interval(&mut self, expr: &Expression) -> Result<()> {
35121 if let Expression::Interval(interval) = expr {
35122 self.write_keyword("INTERVAL");
35123 if let Some(ref value) = interval.this {
35124 self.write_space();
35125 match value {
35129 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()) => {
35130 if let Literal::String(s) = lit.as_ref() {
35131 self.write(s);
35132 }
35133 }
35134 _ => {
35135 self.generate_expression(value)?;
35136 }
35137 }
35138 }
35139 if let Some(ref unit_spec) = interval.unit {
35140 self.write_space();
35141 self.write_interval_unit_spec(unit_spec)?;
35142 }
35143 Ok(())
35144 } else {
35145 self.generate_expression(expr)
35146 }
35147 }
35148
35149 fn generate_partition_by_truncate(&mut self, e: &PartitionByTruncate) -> Result<()> {
35150 self.write_keyword("TRUNCATE");
35152 self.write("(");
35153 self.generate_expression(&e.expression)?;
35154 self.write(", ");
35155 self.generate_expression(&e.this)?;
35156 self.write(")");
35157 Ok(())
35158 }
35159
35160 fn generate_partition_list(&mut self, e: &PartitionList) -> Result<()> {
35161 self.write_keyword("PARTITION");
35163 self.write_space();
35164 self.generate_expression(&e.this)?;
35165 self.write_space();
35166 self.write_keyword("VALUES IN");
35167 self.write(" (");
35168 for (i, expr) in e.expressions.iter().enumerate() {
35169 if i > 0 {
35170 self.write(", ");
35171 }
35172 self.generate_expression(expr)?;
35173 }
35174 self.write(")");
35175 Ok(())
35176 }
35177
35178 fn generate_partition_range(&mut self, e: &PartitionRange) -> Result<()> {
35179 if e.expressions.is_empty() && e.expression.is_some() {
35182 self.generate_expression(&e.this)?;
35184 self.write_space();
35185 self.write_keyword("TO");
35186 self.write_space();
35187 self.generate_expression(e.expression.as_ref().unwrap())?;
35188 return Ok(());
35189 }
35190
35191 self.write_keyword("PARTITION");
35193 self.write_space();
35194 self.generate_expression(&e.this)?;
35195 self.write_space();
35196
35197 if e.expressions.len() == 1 {
35199 self.write_keyword("VALUES LESS THAN");
35201 self.write(" (");
35202 self.generate_expression(&e.expressions[0])?;
35203 self.write(")");
35204 } else if !e.expressions.is_empty() {
35205 self.write_keyword("VALUES");
35207 self.write(" [");
35208 for (i, expr) in e.expressions.iter().enumerate() {
35209 if i > 0 {
35210 self.write(", ");
35211 }
35212 if let Expression::Tuple(t) = expr {
35214 self.write("(");
35215 for (j, inner) in t.expressions.iter().enumerate() {
35216 if j > 0 {
35217 self.write(", ");
35218 }
35219 self.generate_expression(inner)?;
35220 }
35221 self.write(")");
35222 } else {
35223 self.write("(");
35224 self.generate_expression(expr)?;
35225 self.write(")");
35226 }
35227 }
35228 self.write(")");
35229 }
35230 Ok(())
35231 }
35232
35233 fn generate_partitioned_by_bucket(&mut self, e: &PartitionedByBucket) -> Result<()> {
35234 self.write_keyword("BUCKET");
35236 self.write("(");
35237 self.generate_expression(&e.this)?;
35238 self.write(", ");
35239 self.generate_expression(&e.expression)?;
35240 self.write(")");
35241 Ok(())
35242 }
35243
35244 fn generate_partition_by_property(&mut self, e: &PartitionByProperty) -> Result<()> {
35245 self.write_keyword("PARTITION BY");
35247 self.write_space();
35248 for (i, expr) in e.expressions.iter().enumerate() {
35249 if i > 0 {
35250 self.write(", ");
35251 }
35252 self.generate_expression(expr)?;
35253 }
35254 Ok(())
35255 }
35256
35257 fn generate_partitioned_by_property(&mut self, e: &PartitionedByProperty) -> Result<()> {
35258 if matches!(
35260 self.config.dialect,
35261 Some(crate::dialects::DialectType::Teradata)
35262 | Some(crate::dialects::DialectType::ClickHouse)
35263 ) {
35264 self.write_keyword("PARTITION BY");
35265 } else {
35266 self.write_keyword("PARTITIONED BY");
35267 }
35268 self.write_space();
35269 if self.config.pretty {
35271 if let Expression::Tuple(ref tuple) = *e.this {
35272 self.write("(");
35273 self.write_newline();
35274 self.indent_level += 1;
35275 for (i, expr) in tuple.expressions.iter().enumerate() {
35276 if i > 0 {
35277 self.write(",");
35278 self.write_newline();
35279 }
35280 self.write_indent();
35281 self.generate_expression(expr)?;
35282 }
35283 self.indent_level -= 1;
35284 self.write_newline();
35285 self.write(")");
35286 } else {
35287 self.generate_expression(&e.this)?;
35288 }
35289 } else {
35290 self.generate_expression(&e.this)?;
35291 }
35292 Ok(())
35293 }
35294
35295 fn generate_partitioned_of_property(&mut self, e: &PartitionedOfProperty) -> Result<()> {
35296 self.write_keyword("PARTITION OF");
35298 self.write_space();
35299 self.generate_expression(&e.this)?;
35300 if let Expression::PartitionBoundSpec(_) = e.expression.as_ref() {
35302 self.write_space();
35303 self.write_keyword("FOR VALUES");
35304 self.write_space();
35305 self.generate_expression(&e.expression)?;
35306 } else {
35307 self.write_space();
35308 self.write_keyword("DEFAULT");
35309 }
35310 Ok(())
35311 }
35312
35313 fn generate_period_for_system_time_constraint(
35314 &mut self,
35315 e: &PeriodForSystemTimeConstraint,
35316 ) -> Result<()> {
35317 self.write_keyword("PERIOD FOR SYSTEM_TIME");
35319 self.write(" (");
35320 self.generate_expression(&e.this)?;
35321 self.write(", ");
35322 self.generate_expression(&e.expression)?;
35323 self.write(")");
35324 Ok(())
35325 }
35326
35327 fn generate_pivot_alias(&mut self, e: &PivotAlias) -> Result<()> {
35328 self.generate_expression(&e.this)?;
35331 self.write_space();
35332 self.write_keyword("AS");
35333 self.write_space();
35334 if self.config.unpivot_aliases_are_identifiers {
35336 match &e.alias {
35337 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
35338 let Literal::String(s) = lit.as_ref() else {
35339 unreachable!()
35340 };
35341 self.generate_identifier(&Identifier::new(s.clone()))?;
35343 }
35344 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
35345 let Literal::Number(n) = lit.as_ref() else {
35346 unreachable!()
35347 };
35348 let mut id = Identifier::new(n.clone());
35350 id.quoted = true;
35351 self.generate_identifier(&id)?;
35352 }
35353 other => {
35354 self.generate_expression(other)?;
35355 }
35356 }
35357 } else {
35358 self.generate_expression(&e.alias)?;
35359 }
35360 Ok(())
35361 }
35362
35363 fn generate_pivot_any(&mut self, e: &PivotAny) -> Result<()> {
35364 self.write_keyword("ANY");
35366 if let Some(this) = &e.this {
35367 self.write_space();
35368 self.generate_expression(this)?;
35369 }
35370 Ok(())
35371 }
35372
35373 fn generate_predict(&mut self, e: &Predict) -> Result<()> {
35374 self.write_keyword("ML.PREDICT");
35376 self.write("(");
35377 self.write_keyword("MODEL");
35378 self.write_space();
35379 self.generate_expression(&e.this)?;
35380 self.write(", ");
35381 self.generate_expression(&e.expression)?;
35382 if let Some(params) = &e.params_struct {
35383 self.write(", ");
35384 self.generate_expression(params)?;
35385 }
35386 self.write(")");
35387 Ok(())
35388 }
35389
35390 fn generate_previous_day(&mut self, e: &PreviousDay) -> Result<()> {
35391 self.write_keyword("PREVIOUS_DAY");
35393 self.write("(");
35394 self.generate_expression(&e.this)?;
35395 self.write(", ");
35396 self.generate_expression(&e.expression)?;
35397 self.write(")");
35398 Ok(())
35399 }
35400
35401 fn generate_primary_key(&mut self, e: &PrimaryKey) -> Result<()> {
35402 self.write_keyword("PRIMARY KEY");
35404 if let Some(name) = &e.this {
35405 self.write_space();
35406 self.generate_expression(name)?;
35407 }
35408 if !e.expressions.is_empty() {
35409 self.write(" (");
35410 for (i, expr) in e.expressions.iter().enumerate() {
35411 if i > 0 {
35412 self.write(", ");
35413 }
35414 self.generate_expression(expr)?;
35415 }
35416 self.write(")");
35417 }
35418 if let Some(include) = &e.include {
35419 self.write_space();
35420 self.generate_expression(include)?;
35421 }
35422 if !e.options.is_empty() {
35423 self.write_space();
35424 for (i, opt) in e.options.iter().enumerate() {
35425 if i > 0 {
35426 self.write_space();
35427 }
35428 self.generate_expression(opt)?;
35429 }
35430 }
35431 Ok(())
35432 }
35433
35434 fn generate_primary_key_column_constraint(
35435 &mut self,
35436 _e: &PrimaryKeyColumnConstraint,
35437 ) -> Result<()> {
35438 self.write_keyword("PRIMARY KEY");
35440 Ok(())
35441 }
35442
35443 fn generate_path_column_constraint(&mut self, e: &PathColumnConstraint) -> Result<()> {
35444 self.write_keyword("PATH");
35446 self.write_space();
35447 self.generate_expression(&e.this)?;
35448 Ok(())
35449 }
35450
35451 fn generate_projection_def(&mut self, e: &ProjectionDef) -> Result<()> {
35452 self.write_keyword("PROJECTION");
35454 self.write_space();
35455 self.generate_expression(&e.this)?;
35456 self.write(" (");
35457 self.generate_expression(&e.expression)?;
35458 self.write(")");
35459 Ok(())
35460 }
35461
35462 fn generate_properties(&mut self, e: &Properties) -> Result<()> {
35463 for (i, prop) in e.expressions.iter().enumerate() {
35465 if i > 0 {
35466 self.write(", ");
35467 }
35468 self.generate_expression(prop)?;
35469 }
35470 Ok(())
35471 }
35472
35473 fn generate_property(&mut self, e: &Property) -> Result<()> {
35474 self.generate_expression(&e.this)?;
35476 if let Some(value) = &e.value {
35477 self.write("=");
35478 self.generate_expression(value)?;
35479 }
35480 Ok(())
35481 }
35482
35483 fn generate_options_property(&mut self, e: &OptionsProperty) -> Result<()> {
35484 self.write_keyword("OPTIONS");
35485 if e.entries.is_empty() {
35486 self.write(" ()");
35487 return Ok(());
35488 }
35489
35490 if self.config.pretty {
35491 self.write(" (");
35492 self.write_newline();
35493 self.indent_level += 1;
35494 for (i, entry) in e.entries.iter().enumerate() {
35495 if i > 0 {
35496 self.write(",");
35497 self.write_newline();
35498 }
35499 self.write_indent();
35500 self.generate_identifier(&entry.key)?;
35501 self.write("=");
35502 self.generate_expression(&entry.value)?;
35503 }
35504 self.indent_level -= 1;
35505 self.write_newline();
35506 self.write(")");
35507 } else {
35508 self.write(" (");
35509 for (i, entry) in e.entries.iter().enumerate() {
35510 if i > 0 {
35511 self.write(", ");
35512 }
35513 self.generate_identifier(&entry.key)?;
35514 self.write("=");
35515 self.generate_expression(&entry.value)?;
35516 }
35517 self.write(")");
35518 }
35519 Ok(())
35520 }
35521
35522 fn generate_options_clause(&mut self, options: &[Expression]) -> Result<()> {
35524 self.write_keyword("OPTIONS");
35525 self.write(" (");
35526 for (i, opt) in options.iter().enumerate() {
35527 if i > 0 {
35528 self.write(", ");
35529 }
35530 self.generate_option_expression(opt)?;
35531 }
35532 self.write(")");
35533 Ok(())
35534 }
35535
35536 fn generate_properties_clause(&mut self, properties: &[Expression]) -> Result<()> {
35538 self.write_keyword("PROPERTIES");
35539 self.write(" (");
35540 for (i, prop) in properties.iter().enumerate() {
35541 if i > 0 {
35542 self.write(", ");
35543 }
35544 self.generate_option_expression(prop)?;
35545 }
35546 self.write(")");
35547 Ok(())
35548 }
35549
35550 fn generate_environment_clause(&mut self, environment: &[Expression]) -> Result<()> {
35552 self.write_keyword("ENVIRONMENT");
35553 self.write(" (");
35554 for (i, env_item) in environment.iter().enumerate() {
35555 if i > 0 {
35556 self.write(", ");
35557 }
35558 self.generate_environment_expression(env_item)?;
35559 }
35560 self.write(")");
35561 Ok(())
35562 }
35563
35564 fn generate_environment_expression(&mut self, expr: &Expression) -> Result<()> {
35566 match expr {
35567 Expression::Eq(eq) => {
35568 self.generate_expression(&eq.left)?;
35570 self.write(" = ");
35571 self.generate_expression(&eq.right)?;
35572 Ok(())
35573 }
35574 _ => self.generate_expression(expr),
35575 }
35576 }
35577
35578 fn generate_tblproperties_clause(&mut self, options: &[Expression]) -> Result<()> {
35580 self.write_keyword("TBLPROPERTIES");
35581 if self.config.pretty {
35582 self.write(" (");
35583 self.write_newline();
35584 self.indent_level += 1;
35585 for (i, opt) in options.iter().enumerate() {
35586 if i > 0 {
35587 self.write(",");
35588 self.write_newline();
35589 }
35590 self.write_indent();
35591 self.generate_option_expression(opt)?;
35592 }
35593 self.indent_level -= 1;
35594 self.write_newline();
35595 self.write(")");
35596 } else {
35597 self.write(" (");
35598 for (i, opt) in options.iter().enumerate() {
35599 if i > 0 {
35600 self.write(", ");
35601 }
35602 self.generate_option_expression(opt)?;
35603 }
35604 self.write(")");
35605 }
35606 Ok(())
35607 }
35608
35609 fn generate_option_expression(&mut self, expr: &Expression) -> Result<()> {
35611 match expr {
35612 Expression::Eq(eq) => {
35613 self.generate_expression(&eq.left)?;
35615 self.write("=");
35616 self.generate_expression(&eq.right)?;
35617 Ok(())
35618 }
35619 _ => self.generate_expression(expr),
35620 }
35621 }
35622
35623 fn generate_pseudo_type(&mut self, e: &PseudoType) -> Result<()> {
35624 self.generate_expression(&e.this)?;
35626 Ok(())
35627 }
35628
35629 fn generate_put(&mut self, e: &PutStmt) -> Result<()> {
35630 self.write_keyword("PUT");
35632 self.write_space();
35633
35634 if e.source_quoted {
35636 self.write("'");
35637 self.write(&e.source);
35638 self.write("'");
35639 } else {
35640 self.write(&e.source);
35641 }
35642
35643 self.write_space();
35644
35645 if let Expression::Literal(lit) = &e.target {
35647 if let Literal::String(s) = lit.as_ref() {
35648 self.write(s);
35649 }
35650 } else {
35651 self.generate_expression(&e.target)?;
35652 }
35653
35654 for param in &e.params {
35656 self.write_space();
35657 self.write(¶m.name);
35658 if let Some(ref value) = param.value {
35659 self.write("=");
35660 self.generate_expression(value)?;
35661 }
35662 }
35663
35664 Ok(())
35665 }
35666
35667 fn generate_quantile(&mut self, e: &Quantile) -> Result<()> {
35668 self.write_keyword("QUANTILE");
35670 self.write("(");
35671 self.generate_expression(&e.this)?;
35672 if let Some(quantile) = &e.quantile {
35673 self.write(", ");
35674 self.generate_expression(quantile)?;
35675 }
35676 self.write(")");
35677 Ok(())
35678 }
35679
35680 fn generate_query_band(&mut self, e: &QueryBand) -> Result<()> {
35681 if matches!(
35683 self.config.dialect,
35684 Some(crate::dialects::DialectType::Teradata)
35685 ) {
35686 self.write_keyword("SET");
35687 self.write_space();
35688 }
35689 self.write_keyword("QUERY_BAND");
35690 self.write(" = ");
35691 self.generate_expression(&e.this)?;
35692 if e.update.is_some() {
35693 self.write_space();
35694 self.write_keyword("UPDATE");
35695 }
35696 if let Some(scope) = &e.scope {
35697 self.write_space();
35698 self.write_keyword("FOR");
35699 self.write_space();
35700 self.generate_expression(scope)?;
35701 }
35702 Ok(())
35703 }
35704
35705 fn generate_query_option(&mut self, e: &QueryOption) -> Result<()> {
35706 self.generate_expression(&e.this)?;
35708 if let Some(expression) = &e.expression {
35709 self.write(" = ");
35710 self.generate_expression(expression)?;
35711 }
35712 Ok(())
35713 }
35714
35715 fn generate_query_transform(&mut self, e: &QueryTransform) -> Result<()> {
35716 self.write_keyword("TRANSFORM");
35718 self.write("(");
35719 for (i, expr) in e.expressions.iter().enumerate() {
35720 if i > 0 {
35721 self.write(", ");
35722 }
35723 self.generate_expression(expr)?;
35724 }
35725 self.write(")");
35726 if let Some(row_format_before) = &e.row_format_before {
35727 self.write_space();
35728 self.generate_expression(row_format_before)?;
35729 }
35730 if let Some(record_writer) = &e.record_writer {
35731 self.write_space();
35732 self.write_keyword("RECORDWRITER");
35733 self.write_space();
35734 self.generate_expression(record_writer)?;
35735 }
35736 if let Some(command_script) = &e.command_script {
35737 self.write_space();
35738 self.write_keyword("USING");
35739 self.write_space();
35740 self.generate_expression(command_script)?;
35741 }
35742 if let Some(schema) = &e.schema {
35743 self.write_space();
35744 self.write_keyword("AS");
35745 self.write_space();
35746 self.generate_expression(schema)?;
35747 }
35748 if let Some(row_format_after) = &e.row_format_after {
35749 self.write_space();
35750 self.generate_expression(row_format_after)?;
35751 }
35752 if let Some(record_reader) = &e.record_reader {
35753 self.write_space();
35754 self.write_keyword("RECORDREADER");
35755 self.write_space();
35756 self.generate_expression(record_reader)?;
35757 }
35758 Ok(())
35759 }
35760
35761 fn generate_randn(&mut self, e: &Randn) -> Result<()> {
35762 self.write_keyword("RANDN");
35764 self.write("(");
35765 if let Some(this) = &e.this {
35766 self.generate_expression(this)?;
35767 }
35768 self.write(")");
35769 Ok(())
35770 }
35771
35772 fn generate_randstr(&mut self, e: &Randstr) -> Result<()> {
35773 self.write_keyword("RANDSTR");
35775 self.write("(");
35776 self.generate_expression(&e.this)?;
35777 if let Some(generator) = &e.generator {
35778 self.write(", ");
35779 self.generate_expression(generator)?;
35780 }
35781 self.write(")");
35782 Ok(())
35783 }
35784
35785 fn generate_range_bucket(&mut self, e: &RangeBucket) -> Result<()> {
35786 self.write_keyword("RANGE_BUCKET");
35788 self.write("(");
35789 self.generate_expression(&e.this)?;
35790 self.write(", ");
35791 self.generate_expression(&e.expression)?;
35792 self.write(")");
35793 Ok(())
35794 }
35795
35796 fn generate_range_n(&mut self, e: &RangeN) -> Result<()> {
35797 self.write_keyword("RANGE_N");
35799 self.write("(");
35800 self.generate_expression(&e.this)?;
35801 self.write_space();
35802 self.write_keyword("BETWEEN");
35803 self.write_space();
35804 for (i, expr) in e.expressions.iter().enumerate() {
35805 if i > 0 {
35806 self.write(", ");
35807 }
35808 self.generate_expression(expr)?;
35809 }
35810 if let Some(each) = &e.each {
35811 self.write_space();
35812 self.write_keyword("EACH");
35813 self.write_space();
35814 self.generate_expression(each)?;
35815 }
35816 self.write(")");
35817 Ok(())
35818 }
35819
35820 fn generate_read_csv(&mut self, e: &ReadCSV) -> Result<()> {
35821 self.write_keyword("READ_CSV");
35823 self.write("(");
35824 self.generate_expression(&e.this)?;
35825 for expr in &e.expressions {
35826 self.write(", ");
35827 self.generate_expression(expr)?;
35828 }
35829 self.write(")");
35830 Ok(())
35831 }
35832
35833 fn generate_read_parquet(&mut self, e: &ReadParquet) -> Result<()> {
35834 self.write_keyword("READ_PARQUET");
35836 self.write("(");
35837 for (i, expr) in e.expressions.iter().enumerate() {
35838 if i > 0 {
35839 self.write(", ");
35840 }
35841 self.generate_expression(expr)?;
35842 }
35843 self.write(")");
35844 Ok(())
35845 }
35846
35847 fn generate_recursive_with_search(&mut self, e: &RecursiveWithSearch) -> Result<()> {
35848 if e.kind == "CYCLE" {
35851 self.write_keyword("CYCLE");
35852 } else {
35853 self.write_keyword("SEARCH");
35854 self.write_space();
35855 self.write(&e.kind);
35856 self.write_space();
35857 self.write_keyword("FIRST BY");
35858 }
35859 self.write_space();
35860 self.generate_expression(&e.this)?;
35861 self.write_space();
35862 self.write_keyword("SET");
35863 self.write_space();
35864 self.generate_expression(&e.expression)?;
35865 if let Some(using) = &e.using {
35866 self.write_space();
35867 self.write_keyword("USING");
35868 self.write_space();
35869 self.generate_expression(using)?;
35870 }
35871 Ok(())
35872 }
35873
35874 fn generate_reduce(&mut self, e: &Reduce) -> Result<()> {
35875 self.write_keyword("REDUCE");
35877 self.write("(");
35878 self.generate_expression(&e.this)?;
35879 if let Some(initial) = &e.initial {
35880 self.write(", ");
35881 self.generate_expression(initial)?;
35882 }
35883 if let Some(merge) = &e.merge {
35884 self.write(", ");
35885 self.generate_expression(merge)?;
35886 }
35887 if let Some(finish) = &e.finish {
35888 self.write(", ");
35889 self.generate_expression(finish)?;
35890 }
35891 self.write(")");
35892 Ok(())
35893 }
35894
35895 fn generate_reference(&mut self, e: &Reference) -> Result<()> {
35896 self.write_keyword("REFERENCES");
35898 self.write_space();
35899 self.generate_expression(&e.this)?;
35900 if !e.expressions.is_empty() {
35901 self.write(" (");
35902 for (i, expr) in e.expressions.iter().enumerate() {
35903 if i > 0 {
35904 self.write(", ");
35905 }
35906 self.generate_expression(expr)?;
35907 }
35908 self.write(")");
35909 }
35910 for opt in &e.options {
35911 self.write_space();
35912 self.generate_expression(opt)?;
35913 }
35914 Ok(())
35915 }
35916
35917 fn generate_refresh(&mut self, e: &Refresh) -> Result<()> {
35918 self.write_keyword("REFRESH");
35920 if !e.kind.is_empty() {
35921 self.write_space();
35922 self.write_keyword(&e.kind);
35923 }
35924 self.write_space();
35925 self.generate_expression(&e.this)?;
35926 Ok(())
35927 }
35928
35929 fn generate_refresh_trigger_property(&mut self, e: &RefreshTriggerProperty) -> Result<()> {
35930 self.write_keyword("REFRESH");
35932 self.write_space();
35933 self.write_keyword(&e.method);
35934
35935 if let Some(ref kind) = e.kind {
35936 self.write_space();
35937 self.write_keyword("ON");
35938 self.write_space();
35939 self.write_keyword(kind);
35940
35941 if let Some(ref every) = e.every {
35943 self.write_space();
35944 self.write_keyword("EVERY");
35945 self.write_space();
35946 self.generate_expression(every)?;
35947 if let Some(ref unit) = e.unit {
35948 self.write_space();
35949 self.write_keyword(unit);
35950 }
35951 }
35952
35953 if let Some(ref starts) = e.starts {
35955 self.write_space();
35956 self.write_keyword("STARTS");
35957 self.write_space();
35958 self.generate_expression(starts)?;
35959 }
35960 }
35961 Ok(())
35962 }
35963
35964 fn generate_regexp_count(&mut self, e: &RegexpCount) -> Result<()> {
35965 self.write_keyword("REGEXP_COUNT");
35967 self.write("(");
35968 self.generate_expression(&e.this)?;
35969 self.write(", ");
35970 self.generate_expression(&e.expression)?;
35971 if let Some(position) = &e.position {
35972 self.write(", ");
35973 self.generate_expression(position)?;
35974 }
35975 if let Some(parameters) = &e.parameters {
35976 self.write(", ");
35977 self.generate_expression(parameters)?;
35978 }
35979 self.write(")");
35980 Ok(())
35981 }
35982
35983 fn generate_regexp_extract_all(&mut self, e: &RegexpExtractAll) -> Result<()> {
35984 self.write_keyword("REGEXP_EXTRACT_ALL");
35986 self.write("(");
35987 self.generate_expression(&e.this)?;
35988 self.write(", ");
35989 self.generate_expression(&e.expression)?;
35990 if let Some(group) = &e.group {
35991 self.write(", ");
35992 self.generate_expression(group)?;
35993 }
35994 self.write(")");
35995 Ok(())
35996 }
35997
35998 fn generate_regexp_full_match(&mut self, e: &RegexpFullMatch) -> Result<()> {
35999 self.write_keyword("REGEXP_FULL_MATCH");
36001 self.write("(");
36002 self.generate_expression(&e.this)?;
36003 self.write(", ");
36004 self.generate_expression(&e.expression)?;
36005 self.write(")");
36006 Ok(())
36007 }
36008
36009 fn generate_regexp_i_like(&mut self, e: &RegexpILike) -> Result<()> {
36010 use crate::dialects::DialectType;
36011 if matches!(
36013 self.config.dialect,
36014 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
36015 ) && e.flag.is_none()
36016 {
36017 self.generate_expression(&e.this)?;
36018 self.write(" ~* ");
36019 self.generate_expression(&e.expression)?;
36020 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && e.flag.is_none() {
36021 self.write("match(");
36025 self.generate_expression(&e.this)?;
36026 self.write(", ");
36027 if let Expression::Literal(lit) = e.expression.as_ref() {
36028 if let Literal::String(s) = lit.as_ref() {
36029 let insensitive =
36030 Expression::Literal(Box::new(Literal::String(format!("(?i){s}"))));
36031 self.generate_expression(&insensitive)?;
36032 self.write(")");
36033 return Ok(());
36034 }
36035 }
36036 self.write("concat('(?i)', ");
36037 self.generate_expression(&e.expression)?;
36038 self.write("))");
36039 return Ok(());
36040 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
36041 self.write_keyword("REGEXP_LIKE");
36043 self.write("(");
36044 self.generate_expression(&e.this)?;
36045 self.write(", ");
36046 self.generate_expression(&e.expression)?;
36047 self.write(", ");
36048 if let Some(flag) = &e.flag {
36049 self.generate_expression(flag)?;
36050 } else {
36051 self.write("'i'");
36052 }
36053 self.write(")");
36054 } else {
36055 self.generate_expression(&e.this)?;
36057 self.write_space();
36058 self.write_keyword("REGEXP_ILIKE");
36059 self.write_space();
36060 self.generate_expression(&e.expression)?;
36061 if let Some(flag) = &e.flag {
36062 self.write(", ");
36063 self.generate_expression(flag)?;
36064 }
36065 }
36066 Ok(())
36067 }
36068
36069 fn generate_regexp_instr(&mut self, e: &RegexpInstr) -> Result<()> {
36070 self.write_keyword("REGEXP_INSTR");
36072 self.write("(");
36073 self.generate_expression(&e.this)?;
36074 self.write(", ");
36075 self.generate_expression(&e.expression)?;
36076 if let Some(position) = &e.position {
36077 self.write(", ");
36078 self.generate_expression(position)?;
36079 }
36080 if let Some(occurrence) = &e.occurrence {
36081 self.write(", ");
36082 self.generate_expression(occurrence)?;
36083 }
36084 if let Some(option) = &e.option {
36085 self.write(", ");
36086 self.generate_expression(option)?;
36087 }
36088 if let Some(parameters) = &e.parameters {
36089 self.write(", ");
36090 self.generate_expression(parameters)?;
36091 }
36092 if let Some(group) = &e.group {
36093 self.write(", ");
36094 self.generate_expression(group)?;
36095 }
36096 self.write(")");
36097 Ok(())
36098 }
36099
36100 fn generate_regexp_split(&mut self, e: &RegexpSplit) -> Result<()> {
36101 self.write_keyword("REGEXP_SPLIT");
36103 self.write("(");
36104 self.generate_expression(&e.this)?;
36105 self.write(", ");
36106 self.generate_expression(&e.expression)?;
36107 if let Some(limit) = &e.limit {
36108 self.write(", ");
36109 self.generate_expression(limit)?;
36110 }
36111 self.write(")");
36112 Ok(())
36113 }
36114
36115 fn generate_regr_avgx(&mut self, e: &RegrAvgx) -> Result<()> {
36116 self.write_keyword("REGR_AVGX");
36118 self.write("(");
36119 self.generate_expression(&e.this)?;
36120 self.write(", ");
36121 self.generate_expression(&e.expression)?;
36122 self.write(")");
36123 Ok(())
36124 }
36125
36126 fn generate_regr_avgy(&mut self, e: &RegrAvgy) -> Result<()> {
36127 self.write_keyword("REGR_AVGY");
36129 self.write("(");
36130 self.generate_expression(&e.this)?;
36131 self.write(", ");
36132 self.generate_expression(&e.expression)?;
36133 self.write(")");
36134 Ok(())
36135 }
36136
36137 fn generate_regr_count(&mut self, e: &RegrCount) -> Result<()> {
36138 self.write_keyword("REGR_COUNT");
36140 self.write("(");
36141 self.generate_expression(&e.this)?;
36142 self.write(", ");
36143 self.generate_expression(&e.expression)?;
36144 self.write(")");
36145 Ok(())
36146 }
36147
36148 fn generate_regr_intercept(&mut self, e: &RegrIntercept) -> Result<()> {
36149 self.write_keyword("REGR_INTERCEPT");
36151 self.write("(");
36152 self.generate_expression(&e.this)?;
36153 self.write(", ");
36154 self.generate_expression(&e.expression)?;
36155 self.write(")");
36156 Ok(())
36157 }
36158
36159 fn generate_regr_r2(&mut self, e: &RegrR2) -> Result<()> {
36160 self.write_keyword("REGR_R2");
36162 self.write("(");
36163 self.generate_expression(&e.this)?;
36164 self.write(", ");
36165 self.generate_expression(&e.expression)?;
36166 self.write(")");
36167 Ok(())
36168 }
36169
36170 fn generate_regr_slope(&mut self, e: &RegrSlope) -> Result<()> {
36171 self.write_keyword("REGR_SLOPE");
36173 self.write("(");
36174 self.generate_expression(&e.this)?;
36175 self.write(", ");
36176 self.generate_expression(&e.expression)?;
36177 self.write(")");
36178 Ok(())
36179 }
36180
36181 fn generate_regr_sxx(&mut self, e: &RegrSxx) -> Result<()> {
36182 self.write_keyword("REGR_SXX");
36184 self.write("(");
36185 self.generate_expression(&e.this)?;
36186 self.write(", ");
36187 self.generate_expression(&e.expression)?;
36188 self.write(")");
36189 Ok(())
36190 }
36191
36192 fn generate_regr_sxy(&mut self, e: &RegrSxy) -> Result<()> {
36193 self.write_keyword("REGR_SXY");
36195 self.write("(");
36196 self.generate_expression(&e.this)?;
36197 self.write(", ");
36198 self.generate_expression(&e.expression)?;
36199 self.write(")");
36200 Ok(())
36201 }
36202
36203 fn generate_regr_syy(&mut self, e: &RegrSyy) -> Result<()> {
36204 self.write_keyword("REGR_SYY");
36206 self.write("(");
36207 self.generate_expression(&e.this)?;
36208 self.write(", ");
36209 self.generate_expression(&e.expression)?;
36210 self.write(")");
36211 Ok(())
36212 }
36213
36214 fn generate_regr_valx(&mut self, e: &RegrValx) -> Result<()> {
36215 self.write_keyword("REGR_VALX");
36217 self.write("(");
36218 self.generate_expression(&e.this)?;
36219 self.write(", ");
36220 self.generate_expression(&e.expression)?;
36221 self.write(")");
36222 Ok(())
36223 }
36224
36225 fn generate_regr_valy(&mut self, e: &RegrValy) -> Result<()> {
36226 self.write_keyword("REGR_VALY");
36228 self.write("(");
36229 self.generate_expression(&e.this)?;
36230 self.write(", ");
36231 self.generate_expression(&e.expression)?;
36232 self.write(")");
36233 Ok(())
36234 }
36235
36236 fn generate_remote_with_connection_model_property(
36237 &mut self,
36238 e: &RemoteWithConnectionModelProperty,
36239 ) -> Result<()> {
36240 self.write_keyword("REMOTE WITH CONNECTION");
36242 self.write_space();
36243 self.generate_expression(&e.this)?;
36244 Ok(())
36245 }
36246
36247 fn generate_rename_column(&mut self, e: &RenameColumn) -> Result<()> {
36248 self.write_keyword("RENAME COLUMN");
36250 if e.exists {
36251 self.write_space();
36252 self.write_keyword("IF EXISTS");
36253 }
36254 self.write_space();
36255 self.generate_expression(&e.this)?;
36256 if let Some(to) = &e.to {
36257 self.write_space();
36258 self.write_keyword("TO");
36259 self.write_space();
36260 self.generate_expression(to)?;
36261 }
36262 Ok(())
36263 }
36264
36265 fn generate_replace_partition(&mut self, e: &ReplacePartition) -> Result<()> {
36266 self.write_keyword("REPLACE PARTITION");
36268 self.write_space();
36269 self.generate_expression(&e.expression)?;
36270 if let Some(source) = &e.source {
36271 self.write_space();
36272 self.write_keyword("FROM");
36273 self.write_space();
36274 self.generate_expression(source)?;
36275 }
36276 Ok(())
36277 }
36278
36279 fn generate_returning(&mut self, e: &Returning) -> Result<()> {
36280 let keyword = match self.config.dialect {
36283 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "OUTPUT",
36284 _ => "RETURNING",
36285 };
36286 self.write_keyword(keyword);
36287 self.write_space();
36288 for (i, expr) in e.expressions.iter().enumerate() {
36289 if i > 0 {
36290 self.write(", ");
36291 }
36292 self.generate_expression(expr)?;
36293 }
36294 if let Some(into) = &e.into {
36295 self.write_space();
36296 self.write_keyword("INTO");
36297 self.write_space();
36298 self.generate_expression(into)?;
36299 }
36300 Ok(())
36301 }
36302
36303 fn generate_output_clause(&mut self, output: &OutputClause) -> Result<()> {
36304 self.write_space();
36306 self.write_keyword("OUTPUT");
36307 self.write_space();
36308 for (i, expr) in output.columns.iter().enumerate() {
36309 if i > 0 {
36310 self.write(", ");
36311 }
36312 self.generate_expression(expr)?;
36313 }
36314 if let Some(into_table) = &output.into_table {
36315 self.write_space();
36316 self.write_keyword("INTO");
36317 self.write_space();
36318 self.generate_expression(into_table)?;
36319 }
36320 Ok(())
36321 }
36322
36323 fn generate_returns_property(&mut self, e: &ReturnsProperty) -> Result<()> {
36324 self.write_keyword("RETURNS");
36326 if e.is_table.is_some() {
36327 self.write_space();
36328 self.write_keyword("TABLE");
36329 }
36330 if let Some(table) = &e.table {
36331 self.write_space();
36332 self.generate_expression(table)?;
36333 } else if let Some(this) = &e.this {
36334 self.write_space();
36335 self.generate_expression(this)?;
36336 }
36337 if e.null.is_some() {
36338 self.write_space();
36339 self.write_keyword("NULL ON NULL INPUT");
36340 }
36341 Ok(())
36342 }
36343
36344 fn generate_rollback(&mut self, e: &Rollback) -> Result<()> {
36345 self.write_keyword("ROLLBACK");
36347
36348 if e.this.is_none()
36350 && matches!(
36351 self.config.dialect,
36352 Some(DialectType::TSQL) | Some(DialectType::Fabric)
36353 )
36354 {
36355 self.write_space();
36356 self.write_keyword("TRANSACTION");
36357 }
36358
36359 if let Some(this) = &e.this {
36361 let is_transaction_marker = matches!(
36363 this.as_ref(),
36364 Expression::Identifier(id) if id.name == "TRANSACTION"
36365 );
36366
36367 self.write_space();
36368 self.write_keyword("TRANSACTION");
36369
36370 if !is_transaction_marker {
36372 self.write_space();
36373 self.generate_expression(this)?;
36374 }
36375 }
36376
36377 if let Some(savepoint) = &e.savepoint {
36379 self.write_space();
36380 self.write_keyword("TO");
36381 self.write_space();
36382 self.generate_expression(savepoint)?;
36383 }
36384 Ok(())
36385 }
36386
36387 fn generate_rollup(&mut self, e: &Rollup) -> Result<()> {
36388 if e.expressions.is_empty() {
36390 self.write_keyword("WITH ROLLUP");
36391 } else {
36392 self.write_keyword("ROLLUP");
36393 self.write("(");
36394 for (i, expr) in e.expressions.iter().enumerate() {
36395 if i > 0 {
36396 self.write(", ");
36397 }
36398 self.generate_expression(expr)?;
36399 }
36400 self.write(")");
36401 }
36402 Ok(())
36403 }
36404
36405 fn generate_row_format_delimited_property(
36406 &mut self,
36407 e: &RowFormatDelimitedProperty,
36408 ) -> Result<()> {
36409 self.write_keyword("ROW FORMAT DELIMITED");
36411 if let Some(fields) = &e.fields {
36412 self.write_space();
36413 self.write_keyword("FIELDS TERMINATED BY");
36414 self.write_space();
36415 self.generate_expression(fields)?;
36416 }
36417 if let Some(escaped) = &e.escaped {
36418 self.write_space();
36419 self.write_keyword("ESCAPED BY");
36420 self.write_space();
36421 self.generate_expression(escaped)?;
36422 }
36423 if let Some(items) = &e.collection_items {
36424 self.write_space();
36425 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
36426 self.write_space();
36427 self.generate_expression(items)?;
36428 }
36429 if let Some(keys) = &e.map_keys {
36430 self.write_space();
36431 self.write_keyword("MAP KEYS TERMINATED BY");
36432 self.write_space();
36433 self.generate_expression(keys)?;
36434 }
36435 if let Some(lines) = &e.lines {
36436 self.write_space();
36437 self.write_keyword("LINES TERMINATED BY");
36438 self.write_space();
36439 self.generate_expression(lines)?;
36440 }
36441 if let Some(null) = &e.null {
36442 self.write_space();
36443 self.write_keyword("NULL DEFINED AS");
36444 self.write_space();
36445 self.generate_expression(null)?;
36446 }
36447 if let Some(serde) = &e.serde {
36448 self.write_space();
36449 self.generate_expression(serde)?;
36450 }
36451 Ok(())
36452 }
36453
36454 fn generate_row_format_property(&mut self, e: &RowFormatProperty) -> Result<()> {
36455 self.write_keyword("ROW FORMAT");
36457 self.write_space();
36458 self.generate_expression(&e.this)?;
36459 Ok(())
36460 }
36461
36462 fn generate_row_format_serde_property(&mut self, e: &RowFormatSerdeProperty) -> Result<()> {
36463 self.write_keyword("ROW FORMAT SERDE");
36465 self.write_space();
36466 self.generate_expression(&e.this)?;
36467 if let Some(props) = &e.serde_properties {
36468 self.write_space();
36469 self.generate_expression(props)?;
36471 }
36472 Ok(())
36473 }
36474
36475 fn generate_sha2(&mut self, e: &SHA2) -> Result<()> {
36476 self.write_keyword("SHA2");
36478 self.write("(");
36479 self.generate_expression(&e.this)?;
36480 if let Some(length) = e.length {
36481 self.write(", ");
36482 self.write(&length.to_string());
36483 }
36484 self.write(")");
36485 Ok(())
36486 }
36487
36488 fn generate_sha2_digest(&mut self, e: &SHA2Digest) -> Result<()> {
36489 self.write_keyword("SHA2_DIGEST");
36491 self.write("(");
36492 self.generate_expression(&e.this)?;
36493 if let Some(length) = e.length {
36494 self.write(", ");
36495 self.write(&length.to_string());
36496 }
36497 self.write(")");
36498 Ok(())
36499 }
36500
36501 fn generate_safe_add(&mut self, e: &SafeAdd) -> Result<()> {
36502 let name = if matches!(
36503 self.config.dialect,
36504 Some(crate::dialects::DialectType::Spark)
36505 | Some(crate::dialects::DialectType::Databricks)
36506 ) {
36507 "TRY_ADD"
36508 } else {
36509 "SAFE_ADD"
36510 };
36511 self.write_keyword(name);
36512 self.write("(");
36513 self.generate_expression(&e.this)?;
36514 self.write(", ");
36515 self.generate_expression(&e.expression)?;
36516 self.write(")");
36517 Ok(())
36518 }
36519
36520 fn generate_safe_divide(&mut self, e: &SafeDivide) -> Result<()> {
36521 self.write_keyword("SAFE_DIVIDE");
36523 self.write("(");
36524 self.generate_expression(&e.this)?;
36525 self.write(", ");
36526 self.generate_expression(&e.expression)?;
36527 self.write(")");
36528 Ok(())
36529 }
36530
36531 fn generate_safe_multiply(&mut self, e: &SafeMultiply) -> Result<()> {
36532 let name = if matches!(
36533 self.config.dialect,
36534 Some(crate::dialects::DialectType::Spark)
36535 | Some(crate::dialects::DialectType::Databricks)
36536 ) {
36537 "TRY_MULTIPLY"
36538 } else {
36539 "SAFE_MULTIPLY"
36540 };
36541 self.write_keyword(name);
36542 self.write("(");
36543 self.generate_expression(&e.this)?;
36544 self.write(", ");
36545 self.generate_expression(&e.expression)?;
36546 self.write(")");
36547 Ok(())
36548 }
36549
36550 fn generate_safe_subtract(&mut self, e: &SafeSubtract) -> Result<()> {
36551 let name = if matches!(
36552 self.config.dialect,
36553 Some(crate::dialects::DialectType::Spark)
36554 | Some(crate::dialects::DialectType::Databricks)
36555 ) {
36556 "TRY_SUBTRACT"
36557 } else {
36558 "SAFE_SUBTRACT"
36559 };
36560 self.write_keyword(name);
36561 self.write("(");
36562 self.generate_expression(&e.this)?;
36563 self.write(", ");
36564 self.generate_expression(&e.expression)?;
36565 self.write(")");
36566 Ok(())
36567 }
36568
36569 fn generate_sample_body(&mut self, sample: &Sample) -> Result<()> {
36572 if matches!(sample.method, SampleMethod::Bucket) {
36574 self.write(" (");
36575 self.write_keyword("BUCKET");
36576 self.write_space();
36577 if let Some(ref num) = sample.bucket_numerator {
36578 self.generate_expression(num)?;
36579 }
36580 self.write_space();
36581 self.write_keyword("OUT OF");
36582 self.write_space();
36583 if let Some(ref denom) = sample.bucket_denominator {
36584 self.generate_expression(denom)?;
36585 }
36586 if let Some(ref field) = sample.bucket_field {
36587 self.write_space();
36588 self.write_keyword("ON");
36589 self.write_space();
36590 self.generate_expression(field)?;
36591 }
36592 self.write(")");
36593 return Ok(());
36594 }
36595
36596 let is_snowflake = matches!(
36598 self.config.dialect,
36599 Some(crate::dialects::DialectType::Snowflake)
36600 );
36601 let is_postgres = matches!(
36602 self.config.dialect,
36603 Some(crate::dialects::DialectType::PostgreSQL)
36604 | Some(crate::dialects::DialectType::Redshift)
36605 );
36606 let is_databricks = matches!(
36608 self.config.dialect,
36609 Some(crate::dialects::DialectType::Databricks)
36610 );
36611 let is_spark = matches!(
36612 self.config.dialect,
36613 Some(crate::dialects::DialectType::Spark)
36614 );
36615 let suppress_method = is_databricks || is_spark || sample.suppress_method_output;
36616 let force_method = is_postgres && matches!(sample.method, SampleMethod::Bernoulli);
36618 if !suppress_method && (sample.explicit_method || is_snowflake || force_method) {
36619 self.write_space();
36620 if !sample.explicit_method && (is_snowflake || force_method) {
36621 self.write_keyword("BERNOULLI");
36623 } else {
36624 match sample.method {
36625 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
36626 SampleMethod::System => self.write_keyword("SYSTEM"),
36627 SampleMethod::Block => self.write_keyword("BLOCK"),
36628 SampleMethod::Row => self.write_keyword("ROW"),
36629 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
36630 SampleMethod::Percent => self.write_keyword("SYSTEM"),
36631 SampleMethod::Bucket => {} }
36633 }
36634 }
36635
36636 let emit_size_no_parens = !self.config.tablesample_requires_parens;
36638 if emit_size_no_parens {
36639 self.write_space();
36640 match &sample.size {
36641 Expression::Tuple(tuple) => {
36642 for (i, expr) in tuple.expressions.iter().enumerate() {
36643 if i > 0 {
36644 self.write(", ");
36645 }
36646 self.generate_expression(expr)?;
36647 }
36648 }
36649 expr => self.generate_expression(expr)?,
36650 }
36651 } else {
36652 self.write(" (");
36653 self.generate_expression(&sample.size)?;
36654 }
36655
36656 let is_rows_method = matches!(
36658 sample.method,
36659 SampleMethod::Reservoir | SampleMethod::Row | SampleMethod::Bucket
36660 );
36661 let is_percent = matches!(
36662 sample.method,
36663 SampleMethod::Percent
36664 | SampleMethod::System
36665 | SampleMethod::Bernoulli
36666 | SampleMethod::Block
36667 );
36668
36669 let is_presto = matches!(
36673 self.config.dialect,
36674 Some(crate::dialects::DialectType::Presto)
36675 | Some(crate::dialects::DialectType::Trino)
36676 | Some(crate::dialects::DialectType::Athena)
36677 );
36678 let should_output_unit = if is_databricks || is_spark {
36679 is_percent || is_rows_method || sample.unit_after_size
36681 } else if is_snowflake || is_postgres || is_presto {
36682 sample.unit_after_size
36683 } else {
36684 sample.unit_after_size || (sample.explicit_method && (is_rows_method || is_percent))
36685 };
36686
36687 if should_output_unit {
36688 self.write_space();
36689 if sample.is_percent {
36690 self.write_keyword("PERCENT");
36691 } else if is_rows_method && !sample.unit_after_size {
36692 self.write_keyword("ROWS");
36693 } else if sample.unit_after_size {
36694 match sample.method {
36695 SampleMethod::Percent
36696 | SampleMethod::System
36697 | SampleMethod::Bernoulli
36698 | SampleMethod::Block => {
36699 self.write_keyword("PERCENT");
36700 }
36701 SampleMethod::Row | SampleMethod::Reservoir => {
36702 self.write_keyword("ROWS");
36703 }
36704 _ => self.write_keyword("ROWS"),
36705 }
36706 } else {
36707 self.write_keyword("PERCENT");
36708 }
36709 }
36710
36711 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
36712 if let Some(ref offset) = sample.offset {
36713 self.write_space();
36714 self.write_keyword("OFFSET");
36715 self.write_space();
36716 self.generate_expression(offset)?;
36717 }
36718 }
36719 if !emit_size_no_parens {
36720 self.write(")");
36721 }
36722
36723 Ok(())
36724 }
36725
36726 fn generate_sample_property(&mut self, e: &SampleProperty) -> Result<()> {
36727 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
36729 self.write_keyword("SAMPLE BY");
36730 } else {
36731 self.write_keyword("SAMPLE");
36732 }
36733 self.write_space();
36734 self.generate_expression(&e.this)?;
36735 Ok(())
36736 }
36737
36738 fn generate_schema(&mut self, e: &Schema) -> Result<()> {
36739 if let Some(this) = &e.this {
36741 self.generate_expression(this)?;
36742 }
36743 if !e.expressions.is_empty() {
36744 if e.this.is_some() {
36746 self.write_space();
36747 }
36748 self.write("(");
36749 for (i, expr) in e.expressions.iter().enumerate() {
36750 if i > 0 {
36751 self.write(", ");
36752 }
36753 self.generate_expression(expr)?;
36754 }
36755 self.write(")");
36756 }
36757 Ok(())
36758 }
36759
36760 fn generate_schema_comment_property(&mut self, e: &SchemaCommentProperty) -> Result<()> {
36761 self.write_keyword("COMMENT");
36763 self.write_space();
36764 self.generate_expression(&e.this)?;
36765 Ok(())
36766 }
36767
36768 fn generate_scope_resolution(&mut self, e: &ScopeResolution) -> Result<()> {
36769 if let Some(this) = &e.this {
36771 self.generate_expression(this)?;
36772 self.write("::");
36773 }
36774 self.generate_expression(&e.expression)?;
36775 Ok(())
36776 }
36777
36778 fn generate_search(&mut self, e: &Search) -> Result<()> {
36779 self.write_keyword("SEARCH");
36781 self.write("(");
36782 self.generate_expression(&e.this)?;
36783 self.write(", ");
36784 self.generate_expression(&e.expression)?;
36785 if let Some(json_scope) = &e.json_scope {
36786 self.write(", ");
36787 self.generate_expression(json_scope)?;
36788 }
36789 if let Some(analyzer) = &e.analyzer {
36790 self.write(", ");
36791 self.generate_expression(analyzer)?;
36792 }
36793 if let Some(analyzer_options) = &e.analyzer_options {
36794 self.write(", ");
36795 self.generate_expression(analyzer_options)?;
36796 }
36797 if let Some(search_mode) = &e.search_mode {
36798 self.write(", ");
36799 self.generate_expression(search_mode)?;
36800 }
36801 self.write(")");
36802 Ok(())
36803 }
36804
36805 fn generate_search_ip(&mut self, e: &SearchIp) -> Result<()> {
36806 self.write_keyword("SEARCH_IP");
36808 self.write("(");
36809 self.generate_expression(&e.this)?;
36810 self.write(", ");
36811 self.generate_expression(&e.expression)?;
36812 self.write(")");
36813 Ok(())
36814 }
36815
36816 fn generate_security_property(&mut self, e: &SecurityProperty) -> Result<()> {
36817 self.write_keyword("SECURITY");
36819 self.write_space();
36820 self.generate_expression(&e.this)?;
36821 Ok(())
36822 }
36823
36824 fn generate_semantic_view(&mut self, e: &SemanticView) -> Result<()> {
36825 self.write("SEMANTIC_VIEW(");
36827
36828 if self.config.pretty {
36829 self.write_newline();
36831 self.indent_level += 1;
36832 self.write_indent();
36833 self.generate_expression(&e.this)?;
36834
36835 if let Some(metrics) = &e.metrics {
36836 self.write_newline();
36837 self.write_indent();
36838 self.write_keyword("METRICS");
36839 self.write_space();
36840 self.generate_semantic_view_tuple(metrics)?;
36841 }
36842 if let Some(dimensions) = &e.dimensions {
36843 self.write_newline();
36844 self.write_indent();
36845 self.write_keyword("DIMENSIONS");
36846 self.write_space();
36847 self.generate_semantic_view_tuple(dimensions)?;
36848 }
36849 if let Some(facts) = &e.facts {
36850 self.write_newline();
36851 self.write_indent();
36852 self.write_keyword("FACTS");
36853 self.write_space();
36854 self.generate_semantic_view_tuple(facts)?;
36855 }
36856 if let Some(where_) = &e.where_ {
36857 self.write_newline();
36858 self.write_indent();
36859 self.write_keyword("WHERE");
36860 self.write_space();
36861 self.generate_expression(where_)?;
36862 }
36863 self.write_newline();
36864 self.indent_level -= 1;
36865 self.write_indent();
36866 } else {
36867 self.generate_expression(&e.this)?;
36869 if let Some(metrics) = &e.metrics {
36870 self.write_space();
36871 self.write_keyword("METRICS");
36872 self.write_space();
36873 self.generate_semantic_view_tuple(metrics)?;
36874 }
36875 if let Some(dimensions) = &e.dimensions {
36876 self.write_space();
36877 self.write_keyword("DIMENSIONS");
36878 self.write_space();
36879 self.generate_semantic_view_tuple(dimensions)?;
36880 }
36881 if let Some(facts) = &e.facts {
36882 self.write_space();
36883 self.write_keyword("FACTS");
36884 self.write_space();
36885 self.generate_semantic_view_tuple(facts)?;
36886 }
36887 if let Some(where_) = &e.where_ {
36888 self.write_space();
36889 self.write_keyword("WHERE");
36890 self.write_space();
36891 self.generate_expression(where_)?;
36892 }
36893 }
36894 self.write(")");
36895 Ok(())
36896 }
36897
36898 fn generate_semantic_view_tuple(&mut self, expr: &Expression) -> Result<()> {
36900 if let Expression::Tuple(t) = expr {
36901 for (i, e) in t.expressions.iter().enumerate() {
36902 if i > 0 {
36903 self.write(", ");
36904 }
36905 self.generate_expression(e)?;
36906 }
36907 } else {
36908 self.generate_expression(expr)?;
36909 }
36910 Ok(())
36911 }
36912
36913 fn generate_sequence_properties(&mut self, e: &SequenceProperties) -> Result<()> {
36914 if let Some(start) = &e.start {
36916 self.write_keyword("START WITH");
36917 self.write_space();
36918 self.generate_expression(start)?;
36919 }
36920 if let Some(increment) = &e.increment {
36921 self.write_space();
36922 self.write_keyword("INCREMENT BY");
36923 self.write_space();
36924 self.generate_expression(increment)?;
36925 }
36926 if let Some(minvalue) = &e.minvalue {
36927 self.write_space();
36928 self.write_keyword("MINVALUE");
36929 self.write_space();
36930 self.generate_expression(minvalue)?;
36931 }
36932 if let Some(maxvalue) = &e.maxvalue {
36933 self.write_space();
36934 self.write_keyword("MAXVALUE");
36935 self.write_space();
36936 self.generate_expression(maxvalue)?;
36937 }
36938 if let Some(cache) = &e.cache {
36939 self.write_space();
36940 self.write_keyword("CACHE");
36941 self.write_space();
36942 self.generate_expression(cache)?;
36943 }
36944 if let Some(owned) = &e.owned {
36945 self.write_space();
36946 self.write_keyword("OWNED BY");
36947 self.write_space();
36948 self.generate_expression(owned)?;
36949 }
36950 for opt in &e.options {
36951 self.write_space();
36952 self.generate_expression(opt)?;
36953 }
36954 Ok(())
36955 }
36956
36957 fn generate_serde_properties(&mut self, e: &SerdeProperties) -> Result<()> {
36958 if e.with_.is_some() {
36960 self.write_keyword("WITH");
36961 self.write_space();
36962 }
36963 self.write_keyword("SERDEPROPERTIES");
36964 self.write(" (");
36965 for (i, expr) in e.expressions.iter().enumerate() {
36966 if i > 0 {
36967 self.write(", ");
36968 }
36969 match expr {
36971 Expression::Eq(eq) => {
36972 self.generate_expression(&eq.left)?;
36973 self.write("=");
36974 self.generate_expression(&eq.right)?;
36975 }
36976 _ => self.generate_expression(expr)?,
36977 }
36978 }
36979 self.write(")");
36980 Ok(())
36981 }
36982
36983 fn generate_session_parameter(&mut self, e: &SessionParameter) -> Result<()> {
36984 self.write("@@");
36986 if let Some(kind) = &e.kind {
36987 self.write(kind);
36988 self.write(".");
36989 }
36990 self.generate_expression(&e.this)?;
36991 Ok(())
36992 }
36993
36994 fn generate_set(&mut self, e: &Set) -> Result<()> {
36995 if e.unset.is_some() {
36997 self.write_keyword("UNSET");
36998 } else {
36999 self.write_keyword("SET");
37000 }
37001 if e.tag.is_some() {
37002 self.write_space();
37003 self.write_keyword("TAG");
37004 }
37005 if !e.expressions.is_empty() {
37006 self.write_space();
37007 for (i, expr) in e.expressions.iter().enumerate() {
37008 if i > 0 {
37009 self.write(", ");
37010 }
37011 self.generate_expression(expr)?;
37012 }
37013 }
37014 Ok(())
37015 }
37016
37017 fn generate_set_config_property(&mut self, e: &SetConfigProperty) -> Result<()> {
37018 self.write_keyword("SET");
37020 self.write_space();
37021 self.generate_expression(&e.this)?;
37022 Ok(())
37023 }
37024
37025 fn generate_set_item(&mut self, e: &SetItem) -> Result<()> {
37026 if let Some(kind) = &e.kind {
37028 self.write_keyword(kind);
37029 self.write_space();
37030 }
37031 self.generate_expression(&e.name)?;
37032 self.write(" = ");
37033 self.generate_expression(&e.value)?;
37034 Ok(())
37035 }
37036
37037 fn generate_set_operation(&mut self, e: &SetOperation) -> Result<()> {
37038 if let Some(with_) = &e.with_ {
37040 self.generate_expression(with_)?;
37041 self.write_space();
37042 }
37043 self.generate_expression(&e.this)?;
37044 self.write_space();
37045 if let Some(kind) = &e.kind {
37047 self.write_keyword(kind);
37048 }
37049 if e.distinct {
37050 self.write_space();
37051 self.write_keyword("DISTINCT");
37052 } else {
37053 self.write_space();
37054 self.write_keyword("ALL");
37055 }
37056 if e.by_name.is_some() {
37057 self.write_space();
37058 self.write_keyword("BY NAME");
37059 }
37060 self.write_space();
37061 self.generate_expression(&e.expression)?;
37062 Ok(())
37063 }
37064
37065 fn generate_set_property(&mut self, e: &SetProperty) -> Result<()> {
37066 if e.multi.is_some() {
37068 self.write_keyword("MULTISET");
37069 } else {
37070 self.write_keyword("SET");
37071 }
37072 Ok(())
37073 }
37074
37075 fn generate_settings_property(&mut self, e: &SettingsProperty) -> Result<()> {
37076 self.write_keyword("SETTINGS");
37078 if self.config.pretty && e.expressions.len() > 1 {
37079 self.indent_level += 1;
37081 for (i, expr) in e.expressions.iter().enumerate() {
37082 if i > 0 {
37083 self.write(",");
37084 }
37085 self.write_newline();
37086 self.write_indent();
37087 self.generate_expression(expr)?;
37088 }
37089 self.indent_level -= 1;
37090 } else {
37091 self.write_space();
37092 for (i, expr) in e.expressions.iter().enumerate() {
37093 if i > 0 {
37094 self.write(", ");
37095 }
37096 self.generate_expression(expr)?;
37097 }
37098 }
37099 Ok(())
37100 }
37101
37102 fn generate_sharing_property(&mut self, e: &SharingProperty) -> Result<()> {
37103 self.write_keyword("SHARING");
37105 if let Some(this) = &e.this {
37106 self.write(" = ");
37107 self.generate_expression(this)?;
37108 }
37109 Ok(())
37110 }
37111
37112 fn generate_slice(&mut self, e: &Slice) -> Result<()> {
37113 if let Some(begin) = &e.this {
37115 self.generate_expression(begin)?;
37116 }
37117 self.write(":");
37118 if let Some(end) = &e.expression {
37119 self.generate_expression(end)?;
37120 }
37121 if let Some(step) = &e.step {
37122 self.write(":");
37123 self.generate_expression(step)?;
37124 }
37125 Ok(())
37126 }
37127
37128 fn generate_sort_array(&mut self, e: &SortArray) -> Result<()> {
37129 self.write_keyword("SORT_ARRAY");
37131 self.write("(");
37132 self.generate_expression(&e.this)?;
37133 if let Some(asc) = &e.asc {
37134 self.write(", ");
37135 self.generate_expression(asc)?;
37136 }
37137 self.write(")");
37138 Ok(())
37139 }
37140
37141 fn generate_sort_by(&mut self, e: &SortBy) -> Result<()> {
37142 self.write_keyword("SORT BY");
37144 self.write_space();
37145 for (i, expr) in e.expressions.iter().enumerate() {
37146 if i > 0 {
37147 self.write(", ");
37148 }
37149 self.generate_ordered(expr)?;
37150 }
37151 Ok(())
37152 }
37153
37154 fn generate_sort_key_property(&mut self, e: &SortKeyProperty) -> Result<()> {
37155 if e.compound.is_some() {
37157 self.write_keyword("COMPOUND");
37158 self.write_space();
37159 }
37160 self.write_keyword("SORTKEY");
37161 self.write("(");
37162 if let Expression::Tuple(t) = e.this.as_ref() {
37164 for (i, expr) in t.expressions.iter().enumerate() {
37165 if i > 0 {
37166 self.write(", ");
37167 }
37168 self.generate_expression(expr)?;
37169 }
37170 } else {
37171 self.generate_expression(&e.this)?;
37172 }
37173 self.write(")");
37174 Ok(())
37175 }
37176
37177 fn generate_split_part(&mut self, e: &SplitPart) -> Result<()> {
37178 self.write_keyword("SPLIT_PART");
37180 self.write("(");
37181 self.generate_expression(&e.this)?;
37182 if let Some(delimiter) = &e.delimiter {
37183 self.write(", ");
37184 self.generate_expression(delimiter)?;
37185 }
37186 if let Some(part_index) = &e.part_index {
37187 self.write(", ");
37188 self.generate_expression(part_index)?;
37189 }
37190 self.write(")");
37191 Ok(())
37192 }
37193
37194 fn generate_sql_read_write_property(&mut self, e: &SqlReadWriteProperty) -> Result<()> {
37195 self.generate_expression(&e.this)?;
37197 Ok(())
37198 }
37199
37200 fn generate_sql_security_property(&mut self, e: &SqlSecurityProperty) -> Result<()> {
37201 self.write_keyword("SQL SECURITY");
37203 self.write_space();
37204 self.generate_expression(&e.this)?;
37205 Ok(())
37206 }
37207
37208 fn generate_st_distance(&mut self, e: &StDistance) -> Result<()> {
37209 self.write_keyword("ST_DISTANCE");
37211 self.write("(");
37212 self.generate_expression(&e.this)?;
37213 self.write(", ");
37214 self.generate_expression(&e.expression)?;
37215 if let Some(use_spheroid) = &e.use_spheroid {
37216 self.write(", ");
37217 self.generate_expression(use_spheroid)?;
37218 }
37219 self.write(")");
37220 Ok(())
37221 }
37222
37223 fn generate_st_point(&mut self, e: &StPoint) -> Result<()> {
37224 self.write_keyword("ST_POINT");
37226 self.write("(");
37227 self.generate_expression(&e.this)?;
37228 self.write(", ");
37229 self.generate_expression(&e.expression)?;
37230 self.write(")");
37231 Ok(())
37232 }
37233
37234 fn generate_stability_property(&mut self, e: &StabilityProperty) -> Result<()> {
37235 self.generate_expression(&e.this)?;
37237 Ok(())
37238 }
37239
37240 fn generate_standard_hash(&mut self, e: &StandardHash) -> Result<()> {
37241 self.write_keyword("STANDARD_HASH");
37243 self.write("(");
37244 self.generate_expression(&e.this)?;
37245 if let Some(expression) = &e.expression {
37246 self.write(", ");
37247 self.generate_expression(expression)?;
37248 }
37249 self.write(")");
37250 Ok(())
37251 }
37252
37253 fn generate_storage_handler_property(&mut self, e: &StorageHandlerProperty) -> Result<()> {
37254 self.write_keyword("STORED BY");
37256 self.write_space();
37257 self.generate_expression(&e.this)?;
37258 Ok(())
37259 }
37260
37261 fn generate_str_position(&mut self, e: &StrPosition) -> Result<()> {
37262 use crate::dialects::DialectType;
37265 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
37266 self.write_keyword("CHARINDEX");
37268 self.write("(");
37269 if let Some(substr) = &e.substr {
37270 self.generate_expression(substr)?;
37271 self.write(", ");
37272 }
37273 self.generate_expression(&e.this)?;
37274 if let Some(position) = &e.position {
37275 self.write(", ");
37276 self.generate_expression(position)?;
37277 }
37278 self.write(")");
37279 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
37280 self.write_keyword("POSITION");
37281 self.write("(");
37282 self.generate_expression(&e.this)?;
37283 if let Some(substr) = &e.substr {
37284 self.write(", ");
37285 self.generate_expression(substr)?;
37286 }
37287 if let Some(position) = &e.position {
37288 self.write(", ");
37289 self.generate_expression(position)?;
37290 }
37291 if let Some(occurrence) = &e.occurrence {
37292 self.write(", ");
37293 self.generate_expression(occurrence)?;
37294 }
37295 self.write(")");
37296 } else if matches!(
37297 self.config.dialect,
37298 Some(DialectType::SQLite)
37299 | Some(DialectType::Oracle)
37300 | Some(DialectType::BigQuery)
37301 | Some(DialectType::Teradata)
37302 ) {
37303 self.write_keyword("INSTR");
37304 self.write("(");
37305 self.generate_expression(&e.this)?;
37306 if let Some(substr) = &e.substr {
37307 self.write(", ");
37308 self.generate_expression(substr)?;
37309 }
37310 if let Some(position) = &e.position {
37311 self.write(", ");
37312 self.generate_expression(position)?;
37313 } else if e.occurrence.is_some() {
37314 self.write(", 1");
37317 }
37318 if let Some(occurrence) = &e.occurrence {
37319 self.write(", ");
37320 self.generate_expression(occurrence)?;
37321 }
37322 self.write(")");
37323 } else if matches!(
37324 self.config.dialect,
37325 Some(DialectType::MySQL)
37326 | Some(DialectType::SingleStore)
37327 | Some(DialectType::Doris)
37328 | Some(DialectType::StarRocks)
37329 | Some(DialectType::Hive)
37330 | Some(DialectType::Spark)
37331 | Some(DialectType::Databricks)
37332 ) {
37333 self.write_keyword("LOCATE");
37335 self.write("(");
37336 if let Some(substr) = &e.substr {
37337 self.generate_expression(substr)?;
37338 self.write(", ");
37339 }
37340 self.generate_expression(&e.this)?;
37341 if let Some(position) = &e.position {
37342 self.write(", ");
37343 self.generate_expression(position)?;
37344 }
37345 self.write(")");
37346 } else if matches!(
37347 self.config.dialect,
37348 Some(DialectType::TSQL) | Some(DialectType::Fabric)
37349 ) {
37350 self.write_keyword("CHARINDEX");
37352 self.write("(");
37353 if let Some(substr) = &e.substr {
37354 self.generate_expression(substr)?;
37355 self.write(", ");
37356 }
37357 self.generate_expression(&e.this)?;
37358 if let Some(position) = &e.position {
37359 self.write(", ");
37360 self.generate_expression(position)?;
37361 }
37362 self.write(")");
37363 } else if matches!(
37364 self.config.dialect,
37365 Some(DialectType::PostgreSQL)
37366 | Some(DialectType::Materialize)
37367 | Some(DialectType::RisingWave)
37368 | Some(DialectType::Redshift)
37369 ) {
37370 self.write_keyword("POSITION");
37372 self.write("(");
37373 if let Some(substr) = &e.substr {
37374 self.generate_expression(substr)?;
37375 self.write(" IN ");
37376 }
37377 self.generate_expression(&e.this)?;
37378 self.write(")");
37379 } else {
37380 self.write_keyword("STRPOS");
37381 self.write("(");
37382 self.generate_expression(&e.this)?;
37383 if let Some(substr) = &e.substr {
37384 self.write(", ");
37385 self.generate_expression(substr)?;
37386 }
37387 if let Some(position) = &e.position {
37388 self.write(", ");
37389 self.generate_expression(position)?;
37390 }
37391 if let Some(occurrence) = &e.occurrence {
37392 self.write(", ");
37393 self.generate_expression(occurrence)?;
37394 }
37395 self.write(")");
37396 }
37397 Ok(())
37398 }
37399
37400 fn generate_str_to_date(&mut self, e: &StrToDate) -> Result<()> {
37401 match self.config.dialect {
37402 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
37403 self.generate_tsql_str_to_temporal(&e.this, e.format.as_deref(), "DATE")?;
37404 }
37405 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
37406 self.write_keyword("TO_DATE");
37408 self.write("(");
37409 self.generate_expression(&e.this)?;
37410 if let Some(format) = &e.format {
37411 self.write(", '");
37412 self.write(&Self::strftime_to_java_format(format));
37413 self.write("'");
37414 }
37415 self.write(")");
37416 }
37417 Some(DialectType::DuckDB) => {
37418 self.write_keyword("CAST");
37420 self.write("(");
37421 self.write_keyword("STRPTIME");
37422 self.write("(");
37423 self.generate_expression(&e.this)?;
37424 if let Some(format) = &e.format {
37425 self.write(", '");
37426 self.write(format);
37427 self.write("'");
37428 }
37429 self.write(")");
37430 self.write_keyword(" AS ");
37431 self.write_keyword("DATE");
37432 self.write(")");
37433 }
37434 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
37435 self.write_keyword("TO_DATE");
37437 self.write("(");
37438 self.generate_expression(&e.this)?;
37439 if let Some(format) = &e.format {
37440 self.write(", '");
37441 self.write(&Self::strftime_to_postgres_format(format));
37442 self.write("'");
37443 }
37444 self.write(")");
37445 }
37446 Some(DialectType::BigQuery) => {
37447 self.write_keyword("PARSE_DATE");
37449 self.write("(");
37450 if let Some(format) = &e.format {
37451 self.write("'");
37452 self.write(format);
37453 self.write("'");
37454 self.write(", ");
37455 }
37456 self.generate_expression(&e.this)?;
37457 self.write(")");
37458 }
37459 Some(DialectType::Teradata) => {
37460 self.write_keyword("CAST");
37462 self.write("(");
37463 self.generate_expression(&e.this)?;
37464 self.write_keyword(" AS ");
37465 self.write_keyword("DATE");
37466 if let Some(format) = &e.format {
37467 self.write_keyword(" FORMAT ");
37468 self.write("'");
37469 self.write(&Self::strftime_to_teradata_format(format));
37470 self.write("'");
37471 }
37472 self.write(")");
37473 }
37474 _ => {
37475 self.write_keyword("STR_TO_DATE");
37477 self.write("(");
37478 self.generate_expression(&e.this)?;
37479 if let Some(format) = &e.format {
37480 self.write(", '");
37481 self.write(format);
37482 self.write("'");
37483 }
37484 self.write(")");
37485 }
37486 }
37487 Ok(())
37488 }
37489
37490 fn strftime_to_teradata_format(fmt: &str) -> String {
37492 let mut result = String::with_capacity(fmt.len() * 2);
37493 let bytes = fmt.as_bytes();
37494 let len = bytes.len();
37495 let mut i = 0;
37496 while i < len {
37497 if bytes[i] == b'%' && i + 1 < len {
37498 let replacement = match bytes[i + 1] {
37499 b'Y' => "YYYY",
37500 b'y' => "YY",
37501 b'm' => "MM",
37502 b'B' => "MMMM",
37503 b'b' => "MMM",
37504 b'd' => "DD",
37505 b'j' => "DDD",
37506 b'H' => "HH",
37507 b'M' => "MI",
37508 b'S' => "SS",
37509 b'f' => "SSSSSS",
37510 b'A' => "EEEE",
37511 b'a' => "EEE",
37512 _ => {
37513 result.push('%');
37514 i += 1;
37515 continue;
37516 }
37517 };
37518 result.push_str(replacement);
37519 i += 2;
37520 } else {
37521 result.push(bytes[i] as char);
37522 i += 1;
37523 }
37524 }
37525 result
37526 }
37527
37528 pub fn strftime_to_java_format_static(fmt: &str) -> String {
37531 Self::strftime_to_java_format(fmt)
37532 }
37533
37534 fn strftime_to_java_format(fmt: &str) -> String {
37536 let mut result = String::with_capacity(fmt.len() * 2);
37537 let bytes = fmt.as_bytes();
37538 let len = bytes.len();
37539 let mut i = 0;
37540 while i < len {
37541 if bytes[i] == b'%' && i + 1 < len {
37542 if bytes[i + 1] == b'-' && i + 2 < len {
37544 let replacement = match bytes[i + 2] {
37545 b'd' => "d",
37546 b'm' => "M",
37547 b'H' => "H",
37548 b'M' => "m",
37549 b'S' => "s",
37550 _ => {
37551 result.push('%');
37552 i += 1;
37553 continue;
37554 }
37555 };
37556 result.push_str(replacement);
37557 i += 3;
37558 } else {
37559 let replacement = match bytes[i + 1] {
37560 b'Y' => "yyyy",
37561 b'y' => "yy",
37562 b'm' => "MM",
37563 b'B' => "MMMM",
37564 b'b' => "MMM",
37565 b'd' => "dd",
37566 b'j' => "DDD",
37567 b'H' => "HH",
37568 b'M' => "mm",
37569 b'S' => "ss",
37570 b'f' => "SSSSSS",
37571 b'A' => "EEEE",
37572 b'a' => "EEE",
37573 _ => {
37574 result.push('%');
37575 i += 1;
37576 continue;
37577 }
37578 };
37579 result.push_str(replacement);
37580 i += 2;
37581 }
37582 } else {
37583 result.push(bytes[i] as char);
37584 i += 1;
37585 }
37586 }
37587 result
37588 }
37589
37590 fn strftime_to_tsql_format(fmt: &str) -> String {
37593 let mut result = String::with_capacity(fmt.len() * 2);
37594 let bytes = fmt.as_bytes();
37595 let len = bytes.len();
37596 let mut i = 0;
37597 while i < len {
37598 if bytes[i] == b'%' && i + 1 < len {
37599 if bytes[i + 1] == b'-' && i + 2 < len {
37601 let replacement = match bytes[i + 2] {
37602 b'd' => "d",
37603 b'm' => "M",
37604 b'H' => "H",
37605 b'M' => "m",
37606 b'S' => "s",
37607 _ => {
37608 result.push('%');
37609 i += 1;
37610 continue;
37611 }
37612 };
37613 result.push_str(replacement);
37614 i += 3;
37615 } else {
37616 let replacement = match bytes[i + 1] {
37617 b'Y' => "yyyy",
37618 b'y' => "yy",
37619 b'm' => "MM",
37620 b'B' => "MMMM",
37621 b'b' => "MMM",
37622 b'd' => "dd",
37623 b'j' => "DDD",
37624 b'H' => "HH",
37625 b'M' => "mm",
37626 b'S' => "ss",
37627 b'f' => "ffffff",
37628 b'A' => "dddd",
37629 b'a' => "ddd",
37630 _ => {
37631 result.push('%');
37632 i += 1;
37633 continue;
37634 }
37635 };
37636 result.push_str(replacement);
37637 i += 2;
37638 }
37639 } else {
37640 result.push(bytes[i] as char);
37641 i += 1;
37642 }
37643 }
37644 result
37645 }
37646
37647 fn tsql_convert_style_for_strftime(fmt: &str) -> Option<u16> {
37648 match fmt.trim() {
37649 "%b %d %Y %-I:%M%p" => Some(100),
37650 "%m/%d/%y" => Some(1),
37651 "%y.%m.%d" => Some(2),
37652 "%d/%m/%y" => Some(3),
37653 "%d.%m.%y" => Some(4),
37654 "%d-%m-%y" => Some(5),
37655 "%d %b %y" => Some(6),
37656 "%b %d, %y" => Some(7),
37657 "%H:%M:%S" => Some(108),
37658 "%b %d %Y %-I:%M:%S:%f%p" => Some(109),
37659 "%m-%d-%y" => Some(10),
37660 "%y/%m/%d" => Some(11),
37661 "%y%m%d" => Some(12),
37662 "%d %b %Y %H:%M:%S:%f" => Some(113),
37663 "%H:%M:%S:%f" => Some(114),
37664 "%m/%d/%Y" => Some(101),
37665 "%Y.%m.%d" => Some(102),
37666 "%d/%m/%Y" => Some(103),
37667 "%d.%m.%Y" => Some(104),
37668 "%d-%m-%Y" => Some(105),
37669 "%d %b %Y" => Some(106),
37670 "%b %d, %Y" => Some(107),
37671 "%m-%d-%Y" => Some(110),
37672 "%Y/%m/%d" => Some(111),
37673 "%Y%m%d" => Some(112),
37674 "%Y-%m-%d %H:%M:%S" => Some(120),
37675 "%Y-%m-%d %H:%M:%S.%f" => Some(121),
37676 "%Y-%m-%dT%H:%M:%S" | "%Y-%m-%dT%H:%M:%S.%f" => Some(126),
37677 "%Y-%m-%d" => Some(23),
37678 _ => None,
37679 }
37680 }
37681
37682 fn generate_tsql_str_to_temporal(
37683 &mut self,
37684 this: &Expression,
37685 format: Option<&str>,
37686 target_type: &str,
37687 ) -> Result<()> {
37688 if let Some(format) = format {
37689 if let Some(style) = Self::tsql_convert_style_for_strftime(format) {
37690 self.write_keyword("CONVERT");
37691 self.write("(");
37692 self.write_keyword(target_type);
37693 self.write(", ");
37694 self.generate_expression(this)?;
37695 self.write(", ");
37696 self.write(&style.to_string());
37697 self.write(")");
37698 return Ok(());
37699 }
37700
37701 self.unsupported(format!(
37702 "T-SQL/Fabric {target_type} parsing format '{format}' has no CONVERT style mapping"
37703 ))?;
37704 }
37705
37706 self.write_keyword("CAST");
37707 self.write("(");
37708 self.generate_expression(this)?;
37709 self.write(" AS ");
37710 self.write_keyword(target_type);
37711 self.write(")");
37712 Ok(())
37713 }
37714
37715 fn decompose_json_path(path: &str) -> Vec<String> {
37718 let mut parts = Vec::new();
37719 let path = if path.starts_with("$.") {
37721 &path[2..]
37722 } else if path.starts_with('$') {
37723 &path[1..]
37724 } else {
37725 path
37726 };
37727 if path.is_empty() {
37728 return parts;
37729 }
37730 let mut current = String::new();
37731 let chars: Vec<char> = path.chars().collect();
37732 let mut i = 0;
37733 while i < chars.len() {
37734 match chars[i] {
37735 '.' => {
37736 if !current.is_empty() {
37737 parts.push(current.clone());
37738 current.clear();
37739 }
37740 i += 1;
37741 }
37742 '[' => {
37743 if !current.is_empty() {
37744 parts.push(current.clone());
37745 current.clear();
37746 }
37747 i += 1;
37748 let mut bracket_content = String::new();
37750 while i < chars.len() && chars[i] != ']' {
37751 if chars[i] == '"' || chars[i] == '\'' {
37753 let quote = chars[i];
37754 i += 1;
37755 while i < chars.len() && chars[i] != quote {
37756 bracket_content.push(chars[i]);
37757 i += 1;
37758 }
37759 if i < chars.len() {
37760 i += 1;
37761 } } else {
37763 bracket_content.push(chars[i]);
37764 i += 1;
37765 }
37766 }
37767 if i < chars.len() {
37768 i += 1;
37769 } if bracket_content != "*" {
37772 parts.push(bracket_content);
37773 }
37774 }
37775 _ => {
37776 current.push(chars[i]);
37777 i += 1;
37778 }
37779 }
37780 }
37781 if !current.is_empty() {
37782 parts.push(current);
37783 }
37784 parts
37785 }
37786
37787 fn strftime_to_postgres_format(fmt: &str) -> String {
37789 let mut result = String::with_capacity(fmt.len() * 2);
37790 let bytes = fmt.as_bytes();
37791 let len = bytes.len();
37792 let mut i = 0;
37793 while i < len {
37794 if bytes[i] == b'%' && i + 1 < len {
37795 if bytes[i + 1] == b'-' && i + 2 < len {
37797 let replacement = match bytes[i + 2] {
37798 b'd' => "FMDD",
37799 b'm' => "FMMM",
37800 b'H' => "FMHH24",
37801 b'M' => "FMMI",
37802 b'S' => "FMSS",
37803 _ => {
37804 result.push('%');
37805 i += 1;
37806 continue;
37807 }
37808 };
37809 result.push_str(replacement);
37810 i += 3;
37811 } else {
37812 let replacement = match bytes[i + 1] {
37813 b'Y' => "YYYY",
37814 b'y' => "YY",
37815 b'm' => "MM",
37816 b'B' => "Month",
37817 b'b' => "Mon",
37818 b'd' => "DD",
37819 b'j' => "DDD",
37820 b'H' => "HH24",
37821 b'M' => "MI",
37822 b'S' => "SS",
37823 b'f' => "US",
37824 b'A' => "Day",
37825 b'a' => "Dy",
37826 _ => {
37827 result.push('%');
37828 i += 1;
37829 continue;
37830 }
37831 };
37832 result.push_str(replacement);
37833 i += 2;
37834 }
37835 } else {
37836 result.push(bytes[i] as char);
37837 i += 1;
37838 }
37839 }
37840 result
37841 }
37842
37843 fn strftime_to_snowflake_format(fmt: &str) -> String {
37845 let mut result = String::with_capacity(fmt.len() * 2);
37846 let bytes = fmt.as_bytes();
37847 let len = bytes.len();
37848 let mut i = 0;
37849 while i < len {
37850 if bytes[i] == b'%' && i + 1 < len {
37851 if bytes[i + 1] == b'-' && i + 2 < len {
37853 let replacement = match bytes[i + 2] {
37854 b'd' => "dd",
37855 b'm' => "mm",
37856 _ => {
37857 result.push('%');
37858 i += 1;
37859 continue;
37860 }
37861 };
37862 result.push_str(replacement);
37863 i += 3;
37864 } else {
37865 let replacement = match bytes[i + 1] {
37866 b'Y' => "yyyy",
37867 b'y' => "yy",
37868 b'm' => "mm",
37869 b'd' => "DD",
37870 b'H' => "hh24",
37871 b'M' => "mi",
37872 b'S' => "ss",
37873 b'f' => "ff",
37874 _ => {
37875 result.push('%');
37876 i += 1;
37877 continue;
37878 }
37879 };
37880 result.push_str(replacement);
37881 i += 2;
37882 }
37883 } else {
37884 result.push(bytes[i] as char);
37885 i += 1;
37886 }
37887 }
37888 result
37889 }
37890
37891 fn generate_str_to_map(&mut self, e: &StrToMap) -> Result<()> {
37892 self.write_keyword("STR_TO_MAP");
37894 self.write("(");
37895 self.generate_expression(&e.this)?;
37896 let needs_defaults = matches!(
37898 self.config.dialect,
37899 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
37900 );
37901 if let Some(pair_delim) = &e.pair_delim {
37902 self.write(", ");
37903 self.generate_expression(pair_delim)?;
37904 } else if needs_defaults {
37905 self.write(", ','");
37906 }
37907 if let Some(key_value_delim) = &e.key_value_delim {
37908 self.write(", ");
37909 self.generate_expression(key_value_delim)?;
37910 } else if needs_defaults {
37911 self.write(", ':'");
37912 }
37913 self.write(")");
37914 Ok(())
37915 }
37916
37917 fn generate_str_to_time(&mut self, e: &StrToTime) -> Result<()> {
37918 let is_strftime = e.format.contains('%');
37920 let to_strftime = |f: &str| -> String {
37922 if is_strftime {
37923 f.to_string()
37924 } else {
37925 Self::snowflake_format_to_strftime(f)
37926 }
37927 };
37928 let to_java = |f: &str| -> String {
37930 if is_strftime {
37931 Self::strftime_to_java_format(f)
37932 } else {
37933 Self::snowflake_format_to_spark(f)
37934 }
37935 };
37936 let to_pg = |f: &str| -> String {
37938 if is_strftime {
37939 Self::strftime_to_postgres_format(f)
37940 } else {
37941 Self::convert_strptime_to_postgres_format(f)
37942 }
37943 };
37944
37945 match self.config.dialect {
37946 Some(DialectType::Exasol) => {
37947 self.write_keyword("TO_DATE");
37948 self.write("(");
37949 self.generate_expression(&e.this)?;
37950 self.write(", '");
37951 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
37952 self.write("'");
37953 self.write(")");
37954 }
37955 Some(DialectType::BigQuery) => {
37956 let fmt = to_strftime(&e.format);
37958 let fmt = fmt.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
37960 self.write_keyword("PARSE_TIMESTAMP");
37961 self.write("('");
37962 self.write(&fmt);
37963 self.write("', ");
37964 self.generate_expression(&e.this)?;
37965 self.write(")");
37966 }
37967 Some(DialectType::Hive) => {
37968 let java_fmt = to_java(&e.format);
37971 if java_fmt == "yyyy-MM-dd HH:mm:ss"
37972 || java_fmt == "yyyy-MM-dd"
37973 || e.format == "yyyy-MM-dd HH:mm:ss"
37974 || e.format == "yyyy-MM-dd"
37975 {
37976 self.write_keyword("CAST");
37977 self.write("(");
37978 self.generate_expression(&e.this)?;
37979 self.write(" ");
37980 self.write_keyword("AS TIMESTAMP");
37981 self.write(")");
37982 } else {
37983 self.write_keyword("CAST");
37985 self.write("(");
37986 self.write_keyword("FROM_UNIXTIME");
37987 self.write("(");
37988 self.write_keyword("UNIX_TIMESTAMP");
37989 self.write("(");
37990 self.generate_expression(&e.this)?;
37991 self.write(", '");
37992 self.write(&java_fmt);
37993 self.write("')");
37994 self.write(") ");
37995 self.write_keyword("AS TIMESTAMP");
37996 self.write(")");
37997 }
37998 }
37999 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
38000 let java_fmt = to_java(&e.format);
38002 self.write_keyword("TO_TIMESTAMP");
38003 self.write("(");
38004 self.generate_expression(&e.this)?;
38005 self.write(", '");
38006 self.write(&java_fmt);
38007 self.write("')");
38008 }
38009 Some(DialectType::MySQL) => {
38010 let mut fmt = to_strftime(&e.format);
38012 fmt = fmt.replace("%-d", "%e");
38014 fmt = fmt.replace("%-m", "%c");
38015 fmt = fmt.replace("%H:%M:%S", "%T");
38016 self.write_keyword("STR_TO_DATE");
38017 self.write("(");
38018 self.generate_expression(&e.this)?;
38019 self.write(", '");
38020 self.write(&fmt);
38021 self.write("')");
38022 }
38023 Some(DialectType::Drill) => {
38024 let java_fmt = to_java(&e.format);
38026 let java_fmt = java_fmt.replace('T', "''T''");
38028 self.write_keyword("TO_TIMESTAMP");
38029 self.write("(");
38030 self.generate_expression(&e.this)?;
38031 self.write(", '");
38032 self.write(&java_fmt);
38033 self.write("')");
38034 }
38035 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
38036 let mut fmt = to_strftime(&e.format);
38038 fmt = fmt.replace("%-d", "%e");
38040 fmt = fmt.replace("%-m", "%c");
38041 fmt = fmt.replace("%H:%M:%S", "%T");
38042 self.write_keyword("DATE_PARSE");
38043 self.write("(");
38044 self.generate_expression(&e.this)?;
38045 self.write(", '");
38046 self.write(&fmt);
38047 self.write("')");
38048 }
38049 Some(DialectType::DuckDB) => {
38050 let fmt = to_strftime(&e.format);
38052 self.write_keyword("STRPTIME");
38053 self.write("(");
38054 self.generate_expression(&e.this)?;
38055 self.write(", '");
38056 self.write(&fmt);
38057 self.write("')");
38058 }
38059 Some(DialectType::PostgreSQL)
38060 | Some(DialectType::Redshift)
38061 | Some(DialectType::Materialize) => {
38062 let pg_fmt = to_pg(&e.format);
38064 self.write_keyword("TO_TIMESTAMP");
38065 self.write("(");
38066 self.generate_expression(&e.this)?;
38067 self.write(", '");
38068 self.write(&pg_fmt);
38069 self.write("')");
38070 }
38071 Some(DialectType::Oracle) => {
38072 let pg_fmt = to_pg(&e.format);
38074 self.write_keyword("TO_TIMESTAMP");
38075 self.write("(");
38076 self.generate_expression(&e.this)?;
38077 self.write(", '");
38078 self.write(&pg_fmt);
38079 self.write("')");
38080 }
38081 Some(DialectType::Snowflake) => {
38082 self.write_keyword("TO_TIMESTAMP");
38084 self.write("(");
38085 self.generate_expression(&e.this)?;
38086 self.write(", '");
38087 self.write(&e.format);
38088 self.write("')");
38089 }
38090 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
38091 self.generate_tsql_str_to_temporal(&e.this, Some(&e.format), "DATETIME2")?;
38092 }
38093 _ => {
38094 self.write_keyword("STR_TO_TIME");
38096 self.write("(");
38097 self.generate_expression(&e.this)?;
38098 self.write(", '");
38099 self.write(&e.format);
38100 self.write("'");
38101 self.write(")");
38102 }
38103 }
38104 Ok(())
38105 }
38106
38107 fn snowflake_format_to_strftime(format: &str) -> String {
38109 let mut result = String::new();
38110 let chars: Vec<char> = format.chars().collect();
38111 let mut i = 0;
38112 while i < chars.len() {
38113 let remaining = &format[i..];
38114 if remaining.starts_with("yyyy") {
38115 result.push_str("%Y");
38116 i += 4;
38117 } else if remaining.starts_with("yy") {
38118 result.push_str("%y");
38119 i += 2;
38120 } else if remaining.starts_with("mmmm") {
38121 result.push_str("%B"); i += 4;
38123 } else if remaining.starts_with("mon") {
38124 result.push_str("%b"); i += 3;
38126 } else if remaining.starts_with("mm") {
38127 result.push_str("%m");
38128 i += 2;
38129 } else if remaining.starts_with("DD") {
38130 result.push_str("%d");
38131 i += 2;
38132 } else if remaining.starts_with("dy") {
38133 result.push_str("%a"); i += 2;
38135 } else if remaining.starts_with("hh24") {
38136 result.push_str("%H");
38137 i += 4;
38138 } else if remaining.starts_with("hh12") {
38139 result.push_str("%I");
38140 i += 4;
38141 } else if remaining.starts_with("hh") {
38142 result.push_str("%H");
38143 i += 2;
38144 } else if remaining.starts_with("mi") {
38145 result.push_str("%M");
38146 i += 2;
38147 } else if remaining.starts_with("ss") {
38148 result.push_str("%S");
38149 i += 2;
38150 } else if remaining.starts_with("ff") {
38151 result.push_str("%f");
38153 i += 2;
38154 while i < chars.len() && chars[i].is_ascii_digit() {
38156 i += 1;
38157 }
38158 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
38159 result.push_str("%p");
38160 i += 2;
38161 } else if remaining.starts_with("tz") {
38162 result.push_str("%Z");
38163 i += 2;
38164 } else {
38165 result.push(chars[i]);
38166 i += 1;
38167 }
38168 }
38169 result
38170 }
38171
38172 fn snowflake_format_to_spark(format: &str) -> String {
38174 let mut result = String::new();
38175 let chars: Vec<char> = format.chars().collect();
38176 let mut i = 0;
38177 while i < chars.len() {
38178 let remaining = &format[i..];
38179 if remaining.starts_with("yyyy") {
38180 result.push_str("yyyy");
38181 i += 4;
38182 } else if remaining.starts_with("yy") {
38183 result.push_str("yy");
38184 i += 2;
38185 } else if remaining.starts_with("mmmm") {
38186 result.push_str("MMMM"); i += 4;
38188 } else if remaining.starts_with("mon") {
38189 result.push_str("MMM"); i += 3;
38191 } else if remaining.starts_with("mm") {
38192 result.push_str("MM");
38193 i += 2;
38194 } else if remaining.starts_with("DD") {
38195 result.push_str("dd");
38196 i += 2;
38197 } else if remaining.starts_with("dy") {
38198 result.push_str("EEE"); i += 2;
38200 } else if remaining.starts_with("hh24") {
38201 result.push_str("HH");
38202 i += 4;
38203 } else if remaining.starts_with("hh12") {
38204 result.push_str("hh");
38205 i += 4;
38206 } else if remaining.starts_with("hh") {
38207 result.push_str("HH");
38208 i += 2;
38209 } else if remaining.starts_with("mi") {
38210 result.push_str("mm");
38211 i += 2;
38212 } else if remaining.starts_with("ss") {
38213 result.push_str("ss");
38214 i += 2;
38215 } else if remaining.starts_with("ff") {
38216 result.push_str("SSS"); i += 2;
38218 while i < chars.len() && chars[i].is_ascii_digit() {
38220 i += 1;
38221 }
38222 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
38223 result.push_str("a");
38224 i += 2;
38225 } else if remaining.starts_with("tz") {
38226 result.push_str("z");
38227 i += 2;
38228 } else {
38229 result.push(chars[i]);
38230 i += 1;
38231 }
38232 }
38233 result
38234 }
38235
38236 fn generate_str_to_unix(&mut self, e: &StrToUnix) -> Result<()> {
38237 match self.config.dialect {
38238 Some(DialectType::DuckDB) => {
38239 self.write_keyword("EPOCH");
38241 self.write("(");
38242 self.write_keyword("STRPTIME");
38243 self.write("(");
38244 if let Some(this) = &e.this {
38245 self.generate_expression(this)?;
38246 }
38247 if let Some(format) = &e.format {
38248 self.write(", '");
38249 self.write(format);
38250 self.write("'");
38251 }
38252 self.write("))");
38253 }
38254 Some(DialectType::Hive) => {
38255 self.write_keyword("UNIX_TIMESTAMP");
38257 self.write("(");
38258 if let Some(this) = &e.this {
38259 self.generate_expression(this)?;
38260 }
38261 if let Some(format) = &e.format {
38262 let java_fmt = Self::strftime_to_java_format(format);
38263 if java_fmt != "yyyy-MM-dd HH:mm:ss" {
38264 self.write(", '");
38265 self.write(&java_fmt);
38266 self.write("'");
38267 }
38268 }
38269 self.write(")");
38270 }
38271 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
38272 self.write_keyword("UNIX_TIMESTAMP");
38274 self.write("(");
38275 if let Some(this) = &e.this {
38276 self.generate_expression(this)?;
38277 }
38278 if let Some(format) = &e.format {
38279 self.write(", '");
38280 self.write(format);
38281 self.write("'");
38282 }
38283 self.write(")");
38284 }
38285 Some(DialectType::Presto) | Some(DialectType::Trino) => {
38286 let c_fmt = e.format.as_deref().unwrap_or("%Y-%m-%d %T");
38289 let java_fmt = Self::strftime_to_java_format(c_fmt);
38290 self.write_keyword("TO_UNIXTIME");
38291 self.write("(");
38292 self.write_keyword("COALESCE");
38293 self.write("(");
38294 self.write_keyword("TRY");
38295 self.write("(");
38296 self.write_keyword("DATE_PARSE");
38297 self.write("(");
38298 self.write_keyword("CAST");
38299 self.write("(");
38300 if let Some(this) = &e.this {
38301 self.generate_expression(this)?;
38302 }
38303 self.write(" ");
38304 self.write_keyword("AS VARCHAR");
38305 self.write("), '");
38306 self.write(c_fmt);
38307 self.write("')), ");
38308 self.write_keyword("PARSE_DATETIME");
38309 self.write("(");
38310 self.write_keyword("DATE_FORMAT");
38311 self.write("(");
38312 self.write_keyword("CAST");
38313 self.write("(");
38314 if let Some(this) = &e.this {
38315 self.generate_expression(this)?;
38316 }
38317 self.write(" ");
38318 self.write_keyword("AS TIMESTAMP");
38319 self.write("), '");
38320 self.write(c_fmt);
38321 self.write("'), '");
38322 self.write(&java_fmt);
38323 self.write("')))");
38324 }
38325 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
38326 self.write_keyword("UNIX_TIMESTAMP");
38328 self.write("(");
38329 if let Some(this) = &e.this {
38330 self.generate_expression(this)?;
38331 }
38332 if let Some(format) = &e.format {
38333 let java_fmt = Self::strftime_to_java_format(format);
38334 self.write(", '");
38335 self.write(&java_fmt);
38336 self.write("'");
38337 }
38338 self.write(")");
38339 }
38340 _ => {
38341 self.write_keyword("STR_TO_UNIX");
38343 self.write("(");
38344 if let Some(this) = &e.this {
38345 self.generate_expression(this)?;
38346 }
38347 if let Some(format) = &e.format {
38348 self.write(", '");
38349 self.write(format);
38350 self.write("'");
38351 }
38352 self.write(")");
38353 }
38354 }
38355 Ok(())
38356 }
38357
38358 fn generate_string_to_array(&mut self, e: &StringToArray) -> Result<()> {
38359 self.write_keyword("STRING_TO_ARRAY");
38361 self.write("(");
38362 self.generate_expression(&e.this)?;
38363 if let Some(expression) = &e.expression {
38364 self.write(", ");
38365 self.generate_expression(expression)?;
38366 }
38367 if let Some(null_val) = &e.null {
38368 self.write(", ");
38369 self.generate_expression(null_val)?;
38370 }
38371 self.write(")");
38372 Ok(())
38373 }
38374
38375 fn generate_struct(&mut self, e: &Struct) -> Result<()> {
38376 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
38377 self.write_keyword("OBJECT_CONSTRUCT");
38379 self.write("(");
38380 for (i, (name, expr)) in e.fields.iter().enumerate() {
38381 if i > 0 {
38382 self.write(", ");
38383 }
38384 if let Some(name) = name {
38385 self.write("'");
38386 self.write(name);
38387 self.write("'");
38388 self.write(", ");
38389 } else {
38390 self.write("'_");
38391 self.write(&i.to_string());
38392 self.write("'");
38393 self.write(", ");
38394 }
38395 self.generate_expression(expr)?;
38396 }
38397 self.write(")");
38398 } else if self.config.struct_curly_brace_notation {
38399 self.write("{");
38401 for (i, (name, expr)) in e.fields.iter().enumerate() {
38402 if i > 0 {
38403 self.write(", ");
38404 }
38405 if let Some(name) = name {
38406 self.write("'");
38408 self.write(name);
38409 self.write("'");
38410 self.write(": ");
38411 } else {
38412 self.write("'_");
38414 self.write(&i.to_string());
38415 self.write("'");
38416 self.write(": ");
38417 }
38418 self.generate_expression(expr)?;
38419 }
38420 self.write("}");
38421 } else {
38422 let value_as_name = matches!(
38426 self.config.dialect,
38427 Some(DialectType::BigQuery)
38428 | Some(DialectType::Spark)
38429 | Some(DialectType::Databricks)
38430 | Some(DialectType::Hive)
38431 );
38432 self.write_keyword("STRUCT");
38433 self.write("(");
38434 for (i, (name, expr)) in e.fields.iter().enumerate() {
38435 if i > 0 {
38436 self.write(", ");
38437 }
38438 if let Some(name) = name {
38439 if value_as_name {
38440 self.generate_expression(expr)?;
38442 self.write_space();
38443 self.write_keyword("AS");
38444 self.write_space();
38445 let needs_quoting = name.contains(' ') || name.contains('-');
38447 if needs_quoting {
38448 if matches!(
38449 self.config.dialect,
38450 Some(DialectType::Spark)
38451 | Some(DialectType::Databricks)
38452 | Some(DialectType::Hive)
38453 ) {
38454 self.write("`");
38455 self.write(name);
38456 self.write("`");
38457 } else {
38458 self.write(name);
38459 }
38460 } else {
38461 self.write(name);
38462 }
38463 } else {
38464 self.write(name);
38466 self.write_space();
38467 self.write_keyword("AS");
38468 self.write_space();
38469 self.generate_expression(expr)?;
38470 }
38471 } else {
38472 self.generate_expression(expr)?;
38473 }
38474 }
38475 self.write(")");
38476 }
38477 Ok(())
38478 }
38479
38480 fn generate_stuff(&mut self, e: &Stuff) -> Result<()> {
38481 self.write_keyword("STUFF");
38483 self.write("(");
38484 self.generate_expression(&e.this)?;
38485 if let Some(start) = &e.start {
38486 self.write(", ");
38487 self.generate_expression(start)?;
38488 }
38489 if let Some(length) = e.length {
38490 self.write(", ");
38491 self.write(&length.to_string());
38492 }
38493 self.write(", ");
38494 self.generate_expression(&e.expression)?;
38495 self.write(")");
38496 Ok(())
38497 }
38498
38499 fn generate_substring_index(&mut self, e: &SubstringIndex) -> Result<()> {
38500 self.write_keyword("SUBSTRING_INDEX");
38502 self.write("(");
38503 self.generate_expression(&e.this)?;
38504 if let Some(delimiter) = &e.delimiter {
38505 self.write(", ");
38506 self.generate_expression(delimiter)?;
38507 }
38508 if let Some(count) = &e.count {
38509 self.write(", ");
38510 self.generate_expression(count)?;
38511 }
38512 self.write(")");
38513 Ok(())
38514 }
38515
38516 fn generate_summarize(&mut self, e: &Summarize) -> Result<()> {
38517 self.write_keyword("SUMMARIZE");
38519 if e.table.is_some() {
38520 self.write_space();
38521 self.write_keyword("TABLE");
38522 }
38523 self.write_space();
38524 self.generate_expression(&e.this)?;
38525 Ok(())
38526 }
38527
38528 fn generate_systimestamp(&mut self, _e: &Systimestamp) -> Result<()> {
38529 self.write_keyword("SYSTIMESTAMP");
38531 Ok(())
38532 }
38533
38534 fn generate_table_alias(&mut self, e: &TableAlias) -> Result<()> {
38535 if let Some(this) = &e.this {
38537 self.generate_expression(this)?;
38538 }
38539 if !e.columns.is_empty() {
38540 self.write("(");
38541 for (i, col) in e.columns.iter().enumerate() {
38542 if i > 0 {
38543 self.write(", ");
38544 }
38545 self.generate_expression(col)?;
38546 }
38547 self.write(")");
38548 }
38549 Ok(())
38550 }
38551
38552 fn generate_table_from_rows(&mut self, e: &TableFromRows) -> Result<()> {
38553 self.write_keyword("TABLE");
38555 self.write("(");
38556 self.generate_expression(&e.this)?;
38557 self.write(")");
38558 if let Some(alias) = &e.alias {
38559 self.write_space();
38560 self.write_keyword("AS");
38561 self.write_space();
38562 self.write(alias);
38563 }
38564 Ok(())
38565 }
38566
38567 fn generate_rows_from(&mut self, e: &RowsFrom) -> Result<()> {
38568 self.write_keyword("ROWS FROM");
38570 self.write(" (");
38571 for (i, expr) in e.expressions.iter().enumerate() {
38572 if i > 0 {
38573 self.write(", ");
38574 }
38575 match expr {
38579 Expression::Tuple(tuple) if tuple.expressions.len() == 2 => {
38580 self.generate_expression(&tuple.expressions[0])?;
38582 self.write_space();
38583 self.write_keyword("AS");
38584 self.write_space();
38585 self.generate_expression(&tuple.expressions[1])?;
38586 }
38587 _ => {
38588 self.generate_expression(expr)?;
38589 }
38590 }
38591 }
38592 self.write(")");
38593 if e.ordinality {
38594 self.write_space();
38595 self.write_keyword("WITH ORDINALITY");
38596 }
38597 if let Some(alias) = &e.alias {
38598 self.write_space();
38599 self.write_keyword("AS");
38600 self.write_space();
38601 self.generate_expression(alias)?;
38602 }
38603 Ok(())
38604 }
38605
38606 fn generate_table_sample(&mut self, e: &TableSample) -> Result<()> {
38607 use crate::dialects::DialectType;
38608
38609 if let (Some(this), Some(sample)) = (&e.this, &e.sample) {
38611 if self.config.alias_post_tablesample {
38613 if let Expression::Subquery(ref s) = **this {
38615 if let Some(ref alias) = s.alias {
38616 let mut subquery_no_alias = (**s).clone();
38618 subquery_no_alias.alias = None;
38619 subquery_no_alias.column_aliases = Vec::new();
38620 self.generate_expression(&Expression::Subquery(Box::new(
38621 subquery_no_alias,
38622 )))?;
38623 self.write_space();
38624 self.write_keyword(self.config.tablesample_keywords);
38625 self.generate_sample_body(sample)?;
38626 if let Some(ref seed) = sample.seed {
38627 self.write_space();
38628 let use_seed = sample.use_seed_keyword
38629 && !matches!(
38630 self.config.dialect,
38631 Some(crate::dialects::DialectType::Databricks)
38632 | Some(crate::dialects::DialectType::Spark)
38633 );
38634 if use_seed {
38635 self.write_keyword("SEED");
38636 } else {
38637 self.write_keyword("REPEATABLE");
38638 }
38639 self.write(" (");
38640 self.generate_expression(seed)?;
38641 self.write(")");
38642 }
38643 self.write_space();
38644 self.write_keyword("AS");
38645 self.write_space();
38646 self.generate_identifier(alias)?;
38647 return Ok(());
38648 }
38649 } else if let Expression::Alias(ref a) = **this {
38650 self.generate_expression(&a.this)?;
38652 self.write_space();
38653 self.write_keyword(self.config.tablesample_keywords);
38654 self.generate_sample_body(sample)?;
38655 if let Some(ref seed) = sample.seed {
38656 self.write_space();
38657 let use_seed = sample.use_seed_keyword
38658 && !matches!(
38659 self.config.dialect,
38660 Some(crate::dialects::DialectType::Databricks)
38661 | Some(crate::dialects::DialectType::Spark)
38662 );
38663 if use_seed {
38664 self.write_keyword("SEED");
38665 } else {
38666 self.write_keyword("REPEATABLE");
38667 }
38668 self.write(" (");
38669 self.generate_expression(seed)?;
38670 self.write(")");
38671 }
38672 self.write_space();
38674 self.write_keyword("AS");
38675 self.write_space();
38676 self.generate_identifier(&a.alias)?;
38677 return Ok(());
38678 }
38679 }
38680 self.generate_expression(this)?;
38682 self.write_space();
38683 self.write_keyword(self.config.tablesample_keywords);
38684 self.generate_sample_body(sample)?;
38685 if let Some(ref seed) = sample.seed {
38687 self.write_space();
38688 let use_seed = sample.use_seed_keyword
38690 && !matches!(
38691 self.config.dialect,
38692 Some(crate::dialects::DialectType::Databricks)
38693 | Some(crate::dialects::DialectType::Spark)
38694 );
38695 if use_seed {
38696 self.write_keyword("SEED");
38697 } else {
38698 self.write_keyword("REPEATABLE");
38699 }
38700 self.write(" (");
38701 self.generate_expression(seed)?;
38702 self.write(")");
38703 }
38704 return Ok(());
38705 }
38706
38707 self.write_keyword(self.config.tablesample_keywords);
38709 if let Some(method) = &e.method {
38710 self.write_space();
38711 self.write_keyword(method);
38712 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
38713 self.write_space();
38715 self.write_keyword("BERNOULLI");
38716 }
38717 if let (Some(numerator), Some(denominator)) = (&e.bucket_numerator, &e.bucket_denominator) {
38718 self.write_space();
38719 self.write_keyword("BUCKET");
38720 self.write_space();
38721 self.generate_expression(numerator)?;
38722 self.write_space();
38723 self.write_keyword("OUT OF");
38724 self.write_space();
38725 self.generate_expression(denominator)?;
38726 if let Some(field) = &e.bucket_field {
38727 self.write_space();
38728 self.write_keyword("ON");
38729 self.write_space();
38730 self.generate_expression(field)?;
38731 }
38732 } else if !e.expressions.is_empty() {
38733 self.write(" (");
38734 for (i, expr) in e.expressions.iter().enumerate() {
38735 if i > 0 {
38736 self.write(", ");
38737 }
38738 self.generate_expression(expr)?;
38739 }
38740 self.write(")");
38741 } else if let Some(percent) = &e.percent {
38742 self.write(" (");
38743 self.generate_expression(percent)?;
38744 self.write_space();
38745 self.write_keyword("PERCENT");
38746 self.write(")");
38747 }
38748 Ok(())
38749 }
38750
38751 fn generate_tag(&mut self, e: &Tag) -> Result<()> {
38752 if let Some(prefix) = &e.prefix {
38754 self.generate_expression(prefix)?;
38755 }
38756 if let Some(this) = &e.this {
38757 self.generate_expression(this)?;
38758 }
38759 if let Some(postfix) = &e.postfix {
38760 self.generate_expression(postfix)?;
38761 }
38762 Ok(())
38763 }
38764
38765 fn generate_tags(&mut self, e: &Tags) -> Result<()> {
38766 self.write_keyword("TAG");
38768 self.write(" (");
38769 for (i, expr) in e.expressions.iter().enumerate() {
38770 if i > 0 {
38771 self.write(", ");
38772 }
38773 self.generate_expression(expr)?;
38774 }
38775 self.write(")");
38776 Ok(())
38777 }
38778
38779 fn generate_temporary_property(&mut self, e: &TemporaryProperty) -> Result<()> {
38780 if let Some(this) = &e.this {
38782 self.generate_expression(this)?;
38783 self.write_space();
38784 }
38785 self.write_keyword("TEMPORARY");
38786 Ok(())
38787 }
38788
38789 fn generate_time_func(&mut self, e: &UnaryFunc) -> Result<()> {
38792 self.write_keyword("TIME");
38794 self.write("(");
38795 self.generate_expression(&e.this)?;
38796 self.write(")");
38797 Ok(())
38798 }
38799
38800 fn generate_time_add(&mut self, e: &TimeAdd) -> Result<()> {
38801 self.write_keyword("TIME_ADD");
38803 self.write("(");
38804 self.generate_expression(&e.this)?;
38805 self.write(", ");
38806 self.generate_expression(&e.expression)?;
38807 if let Some(unit) = &e.unit {
38808 self.write(", ");
38809 self.write_keyword(unit);
38810 }
38811 self.write(")");
38812 Ok(())
38813 }
38814
38815 fn generate_time_diff(&mut self, e: &TimeDiff) -> Result<()> {
38816 self.write_keyword("TIME_DIFF");
38818 self.write("(");
38819 self.generate_expression(&e.this)?;
38820 self.write(", ");
38821 self.generate_expression(&e.expression)?;
38822 if let Some(unit) = &e.unit {
38823 self.write(", ");
38824 self.write_keyword(unit);
38825 }
38826 self.write(")");
38827 Ok(())
38828 }
38829
38830 fn generate_time_from_parts(&mut self, e: &TimeFromParts) -> Result<()> {
38831 self.write_keyword("TIME_FROM_PARTS");
38833 self.write("(");
38834 let mut first = true;
38835 if let Some(hour) = &e.hour {
38836 self.generate_expression(hour)?;
38837 first = false;
38838 }
38839 if let Some(minute) = &e.min {
38840 if !first {
38841 self.write(", ");
38842 }
38843 self.generate_expression(minute)?;
38844 first = false;
38845 }
38846 if let Some(second) = &e.sec {
38847 if !first {
38848 self.write(", ");
38849 }
38850 self.generate_expression(second)?;
38851 first = false;
38852 }
38853 if let Some(ns) = &e.nano {
38854 if !first {
38855 self.write(", ");
38856 }
38857 self.generate_expression(ns)?;
38858 }
38859 self.write(")");
38860 Ok(())
38861 }
38862
38863 fn generate_time_slice(&mut self, e: &TimeSlice) -> Result<()> {
38864 self.write_keyword("TIME_SLICE");
38866 self.write("(");
38867 self.generate_expression(&e.this)?;
38868 self.write(", ");
38869 self.generate_expression(&e.expression)?;
38870 self.write(", ");
38871 self.write_keyword(&e.unit);
38872 self.write(")");
38873 Ok(())
38874 }
38875
38876 fn generate_time_str_to_time(&mut self, e: &TimeStrToTime) -> Result<()> {
38877 self.write_keyword("TIME_STR_TO_TIME");
38879 self.write("(");
38880 self.generate_expression(&e.this)?;
38881 self.write(")");
38882 Ok(())
38883 }
38884
38885 fn generate_time_sub(&mut self, e: &TimeSub) -> Result<()> {
38886 self.write_keyword("TIME_SUB");
38888 self.write("(");
38889 self.generate_expression(&e.this)?;
38890 self.write(", ");
38891 self.generate_expression(&e.expression)?;
38892 if let Some(unit) = &e.unit {
38893 self.write(", ");
38894 self.write_keyword(unit);
38895 }
38896 self.write(")");
38897 Ok(())
38898 }
38899
38900 fn generate_time_to_str(&mut self, e: &TimeToStr) -> Result<()> {
38901 match self.config.dialect {
38902 Some(DialectType::Exasol) => {
38903 self.write_keyword("TO_CHAR");
38905 self.write("(");
38906 self.generate_expression(&e.this)?;
38907 self.write(", '");
38908 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
38909 self.write("'");
38910 self.write(")");
38911 }
38912 Some(DialectType::PostgreSQL)
38913 | Some(DialectType::Redshift)
38914 | Some(DialectType::Materialize) => {
38915 self.write_keyword("TO_CHAR");
38917 self.write("(");
38918 self.generate_expression(&e.this)?;
38919 self.write(", '");
38920 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
38921 self.write("'");
38922 self.write(")");
38923 }
38924 Some(DialectType::Oracle) => {
38925 self.write_keyword("TO_CHAR");
38927 self.write("(");
38928 self.generate_expression(&e.this)?;
38929 self.write(", '");
38930 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
38931 self.write("'");
38932 self.write(")");
38933 }
38934 Some(DialectType::Drill) => {
38935 self.write_keyword("TO_CHAR");
38937 self.write("(");
38938 self.generate_expression(&e.this)?;
38939 self.write(", '");
38940 self.write(&Self::strftime_to_java_format(&e.format));
38941 self.write("'");
38942 self.write(")");
38943 }
38944 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
38945 self.write_keyword("FORMAT");
38947 self.write("(");
38948 self.generate_expression(&e.this)?;
38949 self.write(", '");
38950 self.write(&Self::strftime_to_tsql_format(&e.format));
38951 self.write("'");
38952 self.write(")");
38953 }
38954 Some(DialectType::DuckDB) => {
38955 self.write_keyword("STRFTIME");
38957 self.write("(");
38958 self.generate_expression(&e.this)?;
38959 self.write(", '");
38960 self.write(&e.format);
38961 self.write("'");
38962 self.write(")");
38963 }
38964 Some(DialectType::BigQuery) => {
38965 let fmt = e.format.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
38968 self.write_keyword("FORMAT_DATE");
38969 self.write("('");
38970 self.write(&fmt);
38971 self.write("', ");
38972 self.generate_expression(&e.this)?;
38973 self.write(")");
38974 }
38975 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
38976 self.write_keyword("DATE_FORMAT");
38978 self.write("(");
38979 self.generate_expression(&e.this)?;
38980 self.write(", '");
38981 self.write(&Self::strftime_to_java_format(&e.format));
38982 self.write("'");
38983 self.write(")");
38984 }
38985 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
38986 self.write_keyword("DATE_FORMAT");
38988 self.write("(");
38989 self.generate_expression(&e.this)?;
38990 self.write(", '");
38991 self.write(&e.format);
38992 self.write("'");
38993 self.write(")");
38994 }
38995 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
38996 self.write_keyword("DATE_FORMAT");
38998 self.write("(");
38999 self.generate_expression(&e.this)?;
39000 self.write(", '");
39001 self.write(&e.format);
39002 self.write("'");
39003 self.write(")");
39004 }
39005 _ => {
39006 self.write_keyword("TIME_TO_STR");
39008 self.write("(");
39009 self.generate_expression(&e.this)?;
39010 self.write(", '");
39011 self.write(&e.format);
39012 self.write("'");
39013 self.write(")");
39014 }
39015 }
39016 Ok(())
39017 }
39018
39019 fn generate_time_to_unix(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
39020 match self.config.dialect {
39021 Some(DialectType::DuckDB) => {
39022 self.write_keyword("EPOCH");
39024 self.write("(");
39025 self.generate_expression(&e.this)?;
39026 self.write(")");
39027 }
39028 Some(DialectType::Hive)
39029 | Some(DialectType::Spark)
39030 | Some(DialectType::Databricks)
39031 | Some(DialectType::Doris)
39032 | Some(DialectType::StarRocks)
39033 | Some(DialectType::Drill) => {
39034 self.write_keyword("UNIX_TIMESTAMP");
39036 self.write("(");
39037 self.generate_expression(&e.this)?;
39038 self.write(")");
39039 }
39040 Some(DialectType::Presto) | Some(DialectType::Trino) => {
39041 self.write_keyword("TO_UNIXTIME");
39043 self.write("(");
39044 self.generate_expression(&e.this)?;
39045 self.write(")");
39046 }
39047 _ => {
39048 self.write_keyword("TIME_TO_UNIX");
39050 self.write("(");
39051 self.generate_expression(&e.this)?;
39052 self.write(")");
39053 }
39054 }
39055 Ok(())
39056 }
39057
39058 fn generate_time_str_to_date(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
39059 match self.config.dialect {
39060 Some(DialectType::Hive) => {
39061 self.write_keyword("TO_DATE");
39063 self.write("(");
39064 self.generate_expression(&e.this)?;
39065 self.write(")");
39066 }
39067 _ => {
39068 self.write_keyword("TIME_STR_TO_DATE");
39070 self.write("(");
39071 self.generate_expression(&e.this)?;
39072 self.write(")");
39073 }
39074 }
39075 Ok(())
39076 }
39077
39078 fn generate_time_trunc(&mut self, e: &TimeTrunc) -> Result<()> {
39079 self.write_keyword("TIME_TRUNC");
39081 self.write("(");
39082 self.generate_expression(&e.this)?;
39083 self.write(", ");
39084 self.write_keyword(&e.unit);
39085 self.write(")");
39086 Ok(())
39087 }
39088
39089 fn generate_time_unit(&mut self, e: &TimeUnit) -> Result<()> {
39090 if let Some(unit) = &e.unit {
39092 self.write_keyword(unit);
39093 }
39094 Ok(())
39095 }
39096
39097 fn generate_timestamp_func(&mut self, e: &TimestampFunc) -> Result<()> {
39101 use crate::dialects::DialectType;
39102 use crate::expressions::Literal;
39103
39104 match self.config.dialect {
39105 Some(DialectType::Exasol) => {
39107 self.write_keyword("TO_TIMESTAMP");
39108 self.write("(");
39109 if let Some(this) = &e.this {
39111 match this.as_ref() {
39112 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
39113 let Literal::String(s) = lit.as_ref() else {
39114 unreachable!()
39115 };
39116 self.write("'");
39117 self.write(s);
39118 self.write("'");
39119 }
39120 _ => {
39121 self.generate_expression(this)?;
39122 }
39123 }
39124 }
39125 self.write(")");
39126 }
39127 _ => {
39129 self.write_keyword("TIMESTAMP");
39130 self.write("(");
39131 if let Some(this) = &e.this {
39132 self.generate_expression(this)?;
39133 }
39134 if let Some(zone) = &e.zone {
39135 self.write(", ");
39136 self.generate_expression(zone)?;
39137 }
39138 self.write(")");
39139 }
39140 }
39141 Ok(())
39142 }
39143
39144 fn generate_timestamp_add(&mut self, e: &TimestampAdd) -> Result<()> {
39145 self.write_keyword("TIMESTAMP_ADD");
39147 self.write("(");
39148 self.generate_expression(&e.this)?;
39149 self.write(", ");
39150 self.generate_expression(&e.expression)?;
39151 if let Some(unit) = &e.unit {
39152 self.write(", ");
39153 self.write_keyword(unit);
39154 }
39155 self.write(")");
39156 Ok(())
39157 }
39158
39159 fn generate_timestamp_diff(&mut self, e: &TimestampDiff) -> Result<()> {
39160 self.write_keyword("TIMESTAMP_DIFF");
39162 self.write("(");
39163 self.generate_expression(&e.this)?;
39164 self.write(", ");
39165 self.generate_expression(&e.expression)?;
39166 if let Some(unit) = &e.unit {
39167 self.write(", ");
39168 self.write_keyword(unit);
39169 }
39170 self.write(")");
39171 Ok(())
39172 }
39173
39174 fn generate_timestamp_from_parts(&mut self, e: &TimestampFromParts) -> Result<()> {
39175 self.write_keyword("TIMESTAMP_FROM_PARTS");
39177 self.write("(");
39178 if let Some(this) = &e.this {
39179 self.generate_expression(this)?;
39180 }
39181 if let Some(expression) = &e.expression {
39182 self.write(", ");
39183 self.generate_expression(expression)?;
39184 }
39185 if let Some(zone) = &e.zone {
39186 self.write(", ");
39187 self.generate_expression(zone)?;
39188 }
39189 if let Some(milli) = &e.milli {
39190 self.write(", ");
39191 self.generate_expression(milli)?;
39192 }
39193 self.write(")");
39194 Ok(())
39195 }
39196
39197 fn generate_timestamp_sub(&mut self, e: &TimestampSub) -> Result<()> {
39198 self.write_keyword("TIMESTAMP_SUB");
39200 self.write("(");
39201 self.generate_expression(&e.this)?;
39202 self.write(", ");
39203 self.write_keyword("INTERVAL");
39204 self.write_space();
39205 self.generate_expression(&e.expression)?;
39206 if let Some(unit) = &e.unit {
39207 self.write_space();
39208 self.write_keyword(unit);
39209 }
39210 self.write(")");
39211 Ok(())
39212 }
39213
39214 fn generate_timestamp_tz_from_parts(&mut self, e: &TimestampTzFromParts) -> Result<()> {
39215 self.write_keyword("TIMESTAMP_TZ_FROM_PARTS");
39217 self.write("(");
39218 if let Some(zone) = &e.zone {
39219 self.generate_expression(zone)?;
39220 }
39221 self.write(")");
39222 Ok(())
39223 }
39224
39225 fn generate_to_binary(&mut self, e: &ToBinary) -> Result<()> {
39226 self.write_keyword("TO_BINARY");
39228 self.write("(");
39229 self.generate_expression(&e.this)?;
39230 if let Some(format) = &e.format {
39231 self.write(", '");
39232 self.write(format);
39233 self.write("'");
39234 }
39235 self.write(")");
39236 Ok(())
39237 }
39238
39239 fn generate_to_boolean(&mut self, e: &ToBoolean) -> Result<()> {
39240 self.write_keyword("TO_BOOLEAN");
39242 self.write("(");
39243 self.generate_expression(&e.this)?;
39244 self.write(")");
39245 Ok(())
39246 }
39247
39248 fn generate_to_char(&mut self, e: &ToChar) -> Result<()> {
39249 self.write_keyword("TO_CHAR");
39251 self.write("(");
39252 self.generate_expression(&e.this)?;
39253 if let Some(format) = &e.format {
39254 self.write(", '");
39255 self.write(format);
39256 self.write("'");
39257 }
39258 if let Some(nlsparam) = &e.nlsparam {
39259 self.write(", ");
39260 self.generate_expression(nlsparam)?;
39261 }
39262 self.write(")");
39263 Ok(())
39264 }
39265
39266 fn generate_to_decfloat(&mut self, e: &ToDecfloat) -> Result<()> {
39267 self.write_keyword("TO_DECFLOAT");
39269 self.write("(");
39270 self.generate_expression(&e.this)?;
39271 if let Some(format) = &e.format {
39272 self.write(", '");
39273 self.write(format);
39274 self.write("'");
39275 }
39276 self.write(")");
39277 Ok(())
39278 }
39279
39280 fn generate_to_double(&mut self, e: &ToDouble) -> Result<()> {
39281 self.write_keyword("TO_DOUBLE");
39283 self.write("(");
39284 self.generate_expression(&e.this)?;
39285 if let Some(format) = &e.format {
39286 self.write(", '");
39287 self.write(format);
39288 self.write("'");
39289 }
39290 self.write(")");
39291 Ok(())
39292 }
39293
39294 fn generate_to_file(&mut self, e: &ToFile) -> Result<()> {
39295 self.write_keyword("TO_FILE");
39297 self.write("(");
39298 self.generate_expression(&e.this)?;
39299 if let Some(path) = &e.path {
39300 self.write(", ");
39301 self.generate_expression(path)?;
39302 }
39303 self.write(")");
39304 Ok(())
39305 }
39306
39307 fn generate_to_number(&mut self, e: &ToNumber) -> Result<()> {
39308 let is_safe = e.safe.is_some();
39311 if is_safe {
39312 self.write_keyword("TRY_TO_NUMBER");
39313 } else {
39314 self.write_keyword("TO_NUMBER");
39315 }
39316 self.write("(");
39317 self.generate_expression(&e.this)?;
39318 let precision_is_snowflake_default = e.precision.is_none()
39319 || matches!(
39320 e.precision.as_deref(),
39321 Some(Expression::Literal(lit))
39322 if matches!(lit.as_ref(), Literal::Number(n) if n == "0")
39323 );
39324 let is_snowflake_default_precision =
39325 matches!(self.config.dialect, Some(DialectType::Snowflake))
39326 && e.nlsparam.is_none()
39327 && e.scale.is_none()
39328 && matches!(
39329 e.format.as_deref(),
39330 Some(Expression::Literal(lit))
39331 if matches!(lit.as_ref(), Literal::Number(n) if n == "38")
39332 )
39333 && precision_is_snowflake_default;
39334
39335 if !is_snowflake_default_precision {
39336 if let Some(format) = &e.format {
39337 self.write(", ");
39338 self.generate_expression(format)?;
39339 }
39340 if let Some(nlsparam) = &e.nlsparam {
39341 self.write(", ");
39342 self.generate_expression(nlsparam)?;
39343 }
39344 if let Some(precision) = &e.precision {
39345 self.write(", ");
39346 self.generate_expression(precision)?;
39347 }
39348 if let Some(scale) = &e.scale {
39349 self.write(", ");
39350 self.generate_expression(scale)?;
39351 }
39352 }
39353 self.write(")");
39354 Ok(())
39355 }
39356
39357 fn generate_to_table_property(&mut self, e: &ToTableProperty) -> Result<()> {
39358 self.write_keyword("TO_TABLE");
39360 self.write_space();
39361 self.generate_expression(&e.this)?;
39362 Ok(())
39363 }
39364
39365 fn generate_transaction(&mut self, e: &Transaction) -> Result<()> {
39366 let mark_text = e.mark.as_ref().map(|m| match m.as_ref() {
39368 Expression::Identifier(id) => id.name.clone(),
39369 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
39370 let Literal::String(s) = lit.as_ref() else {
39371 unreachable!()
39372 };
39373 s.clone()
39374 }
39375 _ => String::new(),
39376 });
39377
39378 let is_start = mark_text.as_ref().map_or(false, |s| s == "START");
39379 let has_transaction_keyword = mark_text.as_ref().map_or(false, |s| s == "TRANSACTION");
39380 let has_with_mark = e.mark.as_ref().map_or(false, |m| {
39381 matches!(m.as_ref(), Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)))
39382 });
39383
39384 let use_start_transaction = matches!(
39386 self.config.dialect,
39387 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
39388 );
39389 let strip_transaction = matches!(
39391 self.config.dialect,
39392 Some(DialectType::Snowflake)
39393 | Some(DialectType::PostgreSQL)
39394 | Some(DialectType::Redshift)
39395 | Some(DialectType::MySQL)
39396 | Some(DialectType::Hive)
39397 | Some(DialectType::Spark)
39398 | Some(DialectType::Databricks)
39399 | Some(DialectType::DuckDB)
39400 | Some(DialectType::Oracle)
39401 | Some(DialectType::Doris)
39402 | Some(DialectType::StarRocks)
39403 | Some(DialectType::Materialize)
39404 | Some(DialectType::ClickHouse)
39405 );
39406
39407 if is_start || use_start_transaction {
39408 self.write_keyword("START TRANSACTION");
39410 if let Some(modes) = &e.modes {
39411 self.write_space();
39412 self.generate_expression(modes)?;
39413 }
39414 } else {
39415 self.write_keyword("BEGIN");
39417
39418 let is_kind = e.this.as_ref().map_or(false, |t| {
39420 if let Expression::Identifier(id) = t.as_ref() {
39421 id.name.eq_ignore_ascii_case("DEFERRED")
39422 || id.name.eq_ignore_ascii_case("IMMEDIATE")
39423 || id.name.eq_ignore_ascii_case("EXCLUSIVE")
39424 } else {
39425 false
39426 }
39427 });
39428
39429 if is_kind {
39431 if let Some(this) = &e.this {
39432 self.write_space();
39433 if let Expression::Identifier(id) = this.as_ref() {
39434 self.write_keyword(&id.name);
39435 }
39436 }
39437 }
39438
39439 if (has_transaction_keyword || has_with_mark) && !strip_transaction {
39441 self.write_space();
39442 self.write_keyword("TRANSACTION");
39443 }
39444
39445 if !is_kind {
39447 if let Some(this) = &e.this {
39448 self.write_space();
39449 self.generate_expression(this)?;
39450 }
39451 }
39452
39453 if has_with_mark {
39455 self.write_space();
39456 self.write_keyword("WITH MARK");
39457 if let Some(Expression::Literal(lit)) = e.mark.as_deref() {
39458 if let Literal::String(desc) = lit.as_ref() {
39459 if !desc.is_empty() {
39460 self.write_space();
39461 self.write(&format!("'{}'", desc));
39462 }
39463 }
39464 }
39465 }
39466
39467 if let Some(modes) = &e.modes {
39469 self.write_space();
39470 self.generate_expression(modes)?;
39471 }
39472 }
39473 Ok(())
39474 }
39475
39476 fn generate_transform(&mut self, e: &Transform) -> Result<()> {
39477 self.write_keyword("TRANSFORM");
39479 self.write("(");
39480 self.generate_expression(&e.this)?;
39481 self.write(", ");
39482 self.generate_expression(&e.expression)?;
39483 self.write(")");
39484 Ok(())
39485 }
39486
39487 fn generate_transform_model_property(&mut self, e: &TransformModelProperty) -> Result<()> {
39488 self.write_keyword("TRANSFORM");
39490 self.write("(");
39491 if self.config.pretty && !e.expressions.is_empty() {
39492 self.indent_level += 1;
39493 for (i, expr) in e.expressions.iter().enumerate() {
39494 if i > 0 {
39495 self.write(",");
39496 }
39497 self.write_newline();
39498 self.write_indent();
39499 self.generate_expression(expr)?;
39500 }
39501 self.indent_level -= 1;
39502 self.write_newline();
39503 self.write(")");
39504 } else {
39505 for (i, expr) in e.expressions.iter().enumerate() {
39506 if i > 0 {
39507 self.write(", ");
39508 }
39509 self.generate_expression(expr)?;
39510 }
39511 self.write(")");
39512 }
39513 Ok(())
39514 }
39515
39516 fn generate_transient_property(&mut self, e: &TransientProperty) -> Result<()> {
39517 use crate::dialects::DialectType;
39518 if let Some(this) = &e.this {
39520 self.generate_expression(this)?;
39521 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
39522 self.write_space();
39523 }
39524 }
39525 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
39526 self.write_keyword("TRANSIENT");
39527 }
39528 Ok(())
39529 }
39530
39531 fn generate_translate(&mut self, e: &Translate) -> Result<()> {
39532 self.write_keyword("TRANSLATE");
39534 self.write("(");
39535 self.generate_expression(&e.this)?;
39536 if let Some(from) = &e.from_ {
39537 self.write(", ");
39538 self.generate_expression(from)?;
39539 }
39540 if let Some(to) = &e.to {
39541 self.write(", ");
39542 self.generate_expression(to)?;
39543 }
39544 self.write(")");
39545 Ok(())
39546 }
39547
39548 fn generate_translate_characters(&mut self, e: &TranslateCharacters) -> Result<()> {
39549 self.write_keyword("TRANSLATE");
39551 self.write("(");
39552 self.generate_expression(&e.this)?;
39553 self.write_space();
39554 self.write_keyword("USING");
39555 self.write_space();
39556 self.generate_expression(&e.expression)?;
39557 if e.with_error.is_some() {
39558 self.write_space();
39559 self.write_keyword("WITH ERROR");
39560 }
39561 self.write(")");
39562 Ok(())
39563 }
39564
39565 fn generate_truncate_table(&mut self, e: &TruncateTable) -> Result<()> {
39566 self.write_keyword("TRUNCATE TABLE");
39568 self.write_space();
39569 for (i, expr) in e.expressions.iter().enumerate() {
39570 if i > 0 {
39571 self.write(", ");
39572 }
39573 self.generate_expression(expr)?;
39574 }
39575 Ok(())
39576 }
39577
39578 fn generate_try_base64_decode_binary(&mut self, e: &TryBase64DecodeBinary) -> Result<()> {
39579 self.write_keyword("TRY_BASE64_DECODE_BINARY");
39581 self.write("(");
39582 self.generate_expression(&e.this)?;
39583 if let Some(alphabet) = &e.alphabet {
39584 self.write(", ");
39585 self.generate_expression(alphabet)?;
39586 }
39587 self.write(")");
39588 Ok(())
39589 }
39590
39591 fn generate_try_base64_decode_string(&mut self, e: &TryBase64DecodeString) -> Result<()> {
39592 self.write_keyword("TRY_BASE64_DECODE_STRING");
39594 self.write("(");
39595 self.generate_expression(&e.this)?;
39596 if let Some(alphabet) = &e.alphabet {
39597 self.write(", ");
39598 self.generate_expression(alphabet)?;
39599 }
39600 self.write(")");
39601 Ok(())
39602 }
39603
39604 fn generate_try_to_decfloat(&mut self, e: &TryToDecfloat) -> Result<()> {
39605 self.write_keyword("TRY_TO_DECFLOAT");
39607 self.write("(");
39608 self.generate_expression(&e.this)?;
39609 if let Some(format) = &e.format {
39610 self.write(", '");
39611 self.write(format);
39612 self.write("'");
39613 }
39614 self.write(")");
39615 Ok(())
39616 }
39617
39618 fn generate_ts_or_ds_add(&mut self, e: &TsOrDsAdd) -> Result<()> {
39619 self.write_keyword("TS_OR_DS_ADD");
39621 self.write("(");
39622 self.generate_expression(&e.this)?;
39623 self.write(", ");
39624 self.generate_expression(&e.expression)?;
39625 if let Some(unit) = &e.unit {
39626 self.write(", ");
39627 self.write_keyword(unit);
39628 }
39629 if let Some(return_type) = &e.return_type {
39630 self.write(", ");
39631 self.generate_expression(return_type)?;
39632 }
39633 self.write(")");
39634 Ok(())
39635 }
39636
39637 fn generate_ts_or_ds_diff(&mut self, e: &TsOrDsDiff) -> Result<()> {
39638 self.write_keyword("TS_OR_DS_DIFF");
39640 self.write("(");
39641 self.generate_expression(&e.this)?;
39642 self.write(", ");
39643 self.generate_expression(&e.expression)?;
39644 if let Some(unit) = &e.unit {
39645 self.write(", ");
39646 self.write_keyword(unit);
39647 }
39648 self.write(")");
39649 Ok(())
39650 }
39651
39652 fn generate_ts_or_ds_to_date(&mut self, e: &TsOrDsToDate) -> Result<()> {
39653 let default_time_format = "%Y-%m-%d %H:%M:%S";
39654 let default_date_format = "%Y-%m-%d";
39655 let has_non_default_format = e.format.as_ref().map_or(false, |f| {
39656 f != default_time_format && f != default_date_format
39657 });
39658
39659 if has_non_default_format {
39660 let fmt = e.format.as_ref().unwrap();
39662 match self.config.dialect {
39663 Some(DialectType::MySQL) | Some(DialectType::StarRocks) => {
39664 let str_to_time = crate::expressions::StrToTime {
39667 this: Box::new((*e.this).clone()),
39668 format: fmt.clone(),
39669 zone: None,
39670 safe: None,
39671 target_type: None,
39672 };
39673 self.generate_str_to_time(&str_to_time)?;
39674 }
39675 Some(DialectType::Hive)
39676 | Some(DialectType::Spark)
39677 | Some(DialectType::Databricks) => {
39678 self.write_keyword("TO_DATE");
39680 self.write("(");
39681 self.generate_expression(&e.this)?;
39682 self.write(", '");
39683 self.write(&Self::strftime_to_java_format(fmt));
39684 self.write("')");
39685 }
39686 Some(DialectType::Snowflake) => {
39687 self.write_keyword("TO_DATE");
39689 self.write("(");
39690 self.generate_expression(&e.this)?;
39691 self.write(", '");
39692 self.write(&Self::strftime_to_snowflake_format(fmt));
39693 self.write("')");
39694 }
39695 Some(DialectType::Doris) => {
39696 self.write_keyword("TO_DATE");
39698 self.write("(");
39699 self.generate_expression(&e.this)?;
39700 self.write(")");
39701 }
39702 _ => {
39703 self.write_keyword("CAST");
39705 self.write("(");
39706 let str_to_time = crate::expressions::StrToTime {
39707 this: Box::new((*e.this).clone()),
39708 format: fmt.clone(),
39709 zone: None,
39710 safe: None,
39711 target_type: None,
39712 };
39713 self.generate_str_to_time(&str_to_time)?;
39714 self.write_keyword(" AS ");
39715 self.write_keyword("DATE");
39716 self.write(")");
39717 }
39718 }
39719 } else {
39720 match self.config.dialect {
39722 Some(DialectType::MySQL)
39723 | Some(DialectType::SQLite)
39724 | Some(DialectType::StarRocks) => {
39725 self.write_keyword("DATE");
39727 self.write("(");
39728 self.generate_expression(&e.this)?;
39729 self.write(")");
39730 }
39731 Some(DialectType::Hive)
39732 | Some(DialectType::Spark)
39733 | Some(DialectType::Databricks)
39734 | Some(DialectType::Snowflake)
39735 | Some(DialectType::Doris) => {
39736 self.write_keyword("TO_DATE");
39738 self.write("(");
39739 self.generate_expression(&e.this)?;
39740 self.write(")");
39741 }
39742 Some(DialectType::Presto)
39743 | Some(DialectType::Trino)
39744 | Some(DialectType::Athena) => {
39745 self.write_keyword("CAST");
39747 self.write("(");
39748 self.write_keyword("CAST");
39749 self.write("(");
39750 self.generate_expression(&e.this)?;
39751 self.write_keyword(" AS ");
39752 self.write_keyword("TIMESTAMP");
39753 self.write(")");
39754 self.write_keyword(" AS ");
39755 self.write_keyword("DATE");
39756 self.write(")");
39757 }
39758 Some(DialectType::ClickHouse) => {
39759 self.write_keyword("CAST");
39761 self.write("(");
39762 self.generate_expression(&e.this)?;
39763 self.write_keyword(" AS ");
39764 self.write("Nullable(DATE)");
39765 self.write(")");
39766 }
39767 _ => {
39768 self.write_keyword("CAST");
39770 self.write("(");
39771 self.generate_expression(&e.this)?;
39772 self.write_keyword(" AS ");
39773 self.write_keyword("DATE");
39774 self.write(")");
39775 }
39776 }
39777 }
39778 Ok(())
39779 }
39780
39781 fn generate_ts_or_ds_to_time(&mut self, e: &TsOrDsToTime) -> Result<()> {
39782 self.write_keyword("TS_OR_DS_TO_TIME");
39784 self.write("(");
39785 self.generate_expression(&e.this)?;
39786 if let Some(format) = &e.format {
39787 self.write(", '");
39788 self.write(format);
39789 self.write("'");
39790 }
39791 self.write(")");
39792 Ok(())
39793 }
39794
39795 fn generate_unhex(&mut self, e: &Unhex) -> Result<()> {
39796 self.write_keyword("UNHEX");
39798 self.write("(");
39799 self.generate_expression(&e.this)?;
39800 if let Some(expression) = &e.expression {
39801 self.write(", ");
39802 self.generate_expression(expression)?;
39803 }
39804 self.write(")");
39805 Ok(())
39806 }
39807
39808 fn generate_unicode_string(&mut self, e: &UnicodeString) -> Result<()> {
39809 self.write("U&");
39811 self.generate_expression(&e.this)?;
39812 if let Some(escape) = &e.escape {
39813 self.write_space();
39814 self.write_keyword("UESCAPE");
39815 self.write_space();
39816 self.generate_expression(escape)?;
39817 }
39818 Ok(())
39819 }
39820
39821 fn generate_uniform(&mut self, e: &Uniform) -> Result<()> {
39822 self.write_keyword("UNIFORM");
39824 self.write("(");
39825 self.generate_expression(&e.this)?;
39826 self.write(", ");
39827 self.generate_expression(&e.expression)?;
39828 if let Some(gen) = &e.gen {
39829 self.write(", ");
39830 self.generate_expression(gen)?;
39831 }
39832 if let Some(seed) = &e.seed {
39833 self.write(", ");
39834 self.generate_expression(seed)?;
39835 }
39836 self.write(")");
39837 Ok(())
39838 }
39839
39840 fn generate_unique_column_constraint(&mut self, e: &UniqueColumnConstraint) -> Result<()> {
39841 self.write_keyword("UNIQUE");
39843 if e.nulls.is_some() {
39845 self.write(" NULLS NOT DISTINCT");
39846 }
39847 if let Some(this) = &e.this {
39848 self.write_space();
39849 self.generate_expression(this)?;
39850 }
39851 if let Some(index_type) = &e.index_type {
39852 self.write(" USING ");
39853 self.generate_expression(index_type)?;
39854 }
39855 if let Some(on_conflict) = &e.on_conflict {
39856 self.write_space();
39857 self.generate_expression(on_conflict)?;
39858 }
39859 for opt in &e.options {
39860 self.write_space();
39861 self.generate_expression(opt)?;
39862 }
39863 Ok(())
39864 }
39865
39866 fn generate_unique_key_property(&mut self, e: &UniqueKeyProperty) -> Result<()> {
39867 self.write_keyword("UNIQUE KEY");
39869 self.write(" (");
39870 for (i, expr) in e.expressions.iter().enumerate() {
39871 if i > 0 {
39872 self.write(", ");
39873 }
39874 self.generate_expression(expr)?;
39875 }
39876 self.write(")");
39877 Ok(())
39878 }
39879
39880 fn generate_rollup_property(&mut self, e: &RollupProperty) -> Result<()> {
39881 self.write_keyword("ROLLUP");
39883 self.write(" (");
39884 for (i, index) in e.expressions.iter().enumerate() {
39885 if i > 0 {
39886 self.write(", ");
39887 }
39888 self.generate_identifier(&index.name)?;
39889 self.write("(");
39890 for (j, col) in index.expressions.iter().enumerate() {
39891 if j > 0 {
39892 self.write(", ");
39893 }
39894 self.generate_identifier(col)?;
39895 }
39896 self.write(")");
39897 }
39898 self.write(")");
39899 Ok(())
39900 }
39901
39902 fn generate_unix_to_str(&mut self, e: &UnixToStr) -> Result<()> {
39903 match self.config.dialect {
39904 Some(DialectType::DuckDB) => {
39905 self.write_keyword("STRFTIME");
39907 self.write("(");
39908 self.write_keyword("TO_TIMESTAMP");
39909 self.write("(");
39910 self.generate_expression(&e.this)?;
39911 self.write("), '");
39912 if let Some(format) = &e.format {
39913 self.write(format);
39914 }
39915 self.write("')");
39916 }
39917 Some(DialectType::Hive) => {
39918 self.write_keyword("FROM_UNIXTIME");
39920 self.write("(");
39921 self.generate_expression(&e.this)?;
39922 if let Some(format) = &e.format {
39923 if format != "yyyy-MM-dd HH:mm:ss" {
39924 self.write(", '");
39925 self.write(format);
39926 self.write("'");
39927 }
39928 }
39929 self.write(")");
39930 }
39931 Some(DialectType::Presto) | Some(DialectType::Trino) => {
39932 self.write_keyword("DATE_FORMAT");
39934 self.write("(");
39935 self.write_keyword("FROM_UNIXTIME");
39936 self.write("(");
39937 self.generate_expression(&e.this)?;
39938 self.write("), '");
39939 if let Some(format) = &e.format {
39940 self.write(format);
39941 }
39942 self.write("')");
39943 }
39944 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
39945 self.write_keyword("FROM_UNIXTIME");
39947 self.write("(");
39948 self.generate_expression(&e.this)?;
39949 if let Some(format) = &e.format {
39950 self.write(", '");
39951 self.write(format);
39952 self.write("'");
39953 }
39954 self.write(")");
39955 }
39956 _ => {
39957 self.write_keyword("UNIX_TO_STR");
39959 self.write("(");
39960 self.generate_expression(&e.this)?;
39961 if let Some(format) = &e.format {
39962 self.write(", '");
39963 self.write(format);
39964 self.write("'");
39965 }
39966 self.write(")");
39967 }
39968 }
39969 Ok(())
39970 }
39971
39972 fn generate_unix_to_time(&mut self, e: &UnixToTime) -> Result<()> {
39973 use crate::dialects::DialectType;
39974 let scale = e.scale.unwrap_or(0); match self.config.dialect {
39977 Some(DialectType::Snowflake) => {
39978 self.write_keyword("TO_TIMESTAMP");
39980 self.write("(");
39981 self.generate_expression(&e.this)?;
39982 if let Some(s) = e.scale {
39983 if s > 0 {
39984 self.write(", ");
39985 self.write(&s.to_string());
39986 }
39987 }
39988 self.write(")");
39989 }
39990 Some(DialectType::BigQuery) => {
39991 match scale {
39994 0 => {
39995 self.write_keyword("TIMESTAMP_SECONDS");
39996 self.write("(");
39997 self.generate_expression(&e.this)?;
39998 self.write(")");
39999 }
40000 3 => {
40001 self.write_keyword("TIMESTAMP_MILLIS");
40002 self.write("(");
40003 self.generate_expression(&e.this)?;
40004 self.write(")");
40005 }
40006 6 => {
40007 self.write_keyword("TIMESTAMP_MICROS");
40008 self.write("(");
40009 self.generate_expression(&e.this)?;
40010 self.write(")");
40011 }
40012 _ => {
40013 self.write_keyword("TIMESTAMP_SECONDS");
40015 self.write("(CAST(");
40016 self.generate_expression(&e.this)?;
40017 self.write(&format!(" / POWER(10, {}) AS INT64))", scale));
40018 }
40019 }
40020 }
40021 Some(DialectType::Spark) => {
40022 match scale {
40027 0 => {
40028 self.write_keyword("CAST");
40029 self.write("(");
40030 self.write_keyword("FROM_UNIXTIME");
40031 self.write("(");
40032 self.generate_expression(&e.this)?;
40033 self.write(") ");
40034 self.write_keyword("AS TIMESTAMP");
40035 self.write(")");
40036 }
40037 3 => {
40038 self.write_keyword("TIMESTAMP_MILLIS");
40039 self.write("(");
40040 self.generate_expression(&e.this)?;
40041 self.write(")");
40042 }
40043 6 => {
40044 self.write_keyword("TIMESTAMP_MICROS");
40045 self.write("(");
40046 self.generate_expression(&e.this)?;
40047 self.write(")");
40048 }
40049 _ => {
40050 self.write_keyword("TIMESTAMP_SECONDS");
40051 self.write("(");
40052 self.generate_expression(&e.this)?;
40053 self.write(&format!(" / POWER(10, {}))", scale));
40054 }
40055 }
40056 }
40057 Some(DialectType::Databricks) => {
40058 match scale {
40062 0 => {
40063 self.write_keyword("CAST");
40064 self.write("(");
40065 self.write_keyword("FROM_UNIXTIME");
40066 self.write("(");
40067 self.generate_expression(&e.this)?;
40068 self.write(") ");
40069 self.write_keyword("AS TIMESTAMP");
40070 self.write(")");
40071 }
40072 3 => {
40073 self.write_keyword("TIMESTAMP_MILLIS");
40074 self.write("(");
40075 self.generate_expression(&e.this)?;
40076 self.write(")");
40077 }
40078 6 => {
40079 self.write_keyword("TIMESTAMP_MICROS");
40080 self.write("(");
40081 self.generate_expression(&e.this)?;
40082 self.write(")");
40083 }
40084 _ => {
40085 self.write_keyword("TIMESTAMP_SECONDS");
40086 self.write("(");
40087 self.generate_expression(&e.this)?;
40088 self.write(&format!(" / POWER(10, {}))", scale));
40089 }
40090 }
40091 }
40092 Some(DialectType::Hive) => {
40093 if scale == 0 {
40095 self.write_keyword("FROM_UNIXTIME");
40096 self.write("(");
40097 self.generate_expression(&e.this)?;
40098 self.write(")");
40099 } else {
40100 self.write_keyword("FROM_UNIXTIME");
40101 self.write("(");
40102 self.generate_expression(&e.this)?;
40103 self.write(&format!(" / POWER(10, {})", scale));
40104 self.write(")");
40105 }
40106 }
40107 Some(DialectType::Presto) | Some(DialectType::Trino) => {
40108 if scale == 0 {
40111 self.write_keyword("FROM_UNIXTIME");
40112 self.write("(");
40113 self.generate_expression(&e.this)?;
40114 self.write(")");
40115 } else {
40116 self.write_keyword("FROM_UNIXTIME");
40117 self.write("(CAST(");
40118 self.generate_expression(&e.this)?;
40119 self.write(&format!(" AS DOUBLE) / POW(10, {}))", scale));
40120 }
40121 }
40122 Some(DialectType::DuckDB) => {
40123 match scale {
40127 0 => {
40128 self.write_keyword("TO_TIMESTAMP");
40129 self.write("(");
40130 self.generate_expression(&e.this)?;
40131 self.write(")");
40132 }
40133 3 => {
40134 self.write_keyword("EPOCH_MS");
40135 self.write("(");
40136 self.generate_expression(&e.this)?;
40137 self.write(")");
40138 }
40139 6 => {
40140 self.write_keyword("MAKE_TIMESTAMP");
40141 self.write("(");
40142 self.generate_expression(&e.this)?;
40143 self.write(")");
40144 }
40145 _ => {
40146 self.write_keyword("TO_TIMESTAMP");
40147 self.write("(");
40148 self.generate_expression(&e.this)?;
40149 self.write(&format!(" / POWER(10, {}))", scale));
40150 self.write_keyword(" AT TIME ZONE");
40151 self.write(" 'UTC'");
40152 }
40153 }
40154 }
40155 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
40156 self.write_keyword("FROM_UNIXTIME");
40158 self.write("(");
40159 self.generate_expression(&e.this)?;
40160 self.write(")");
40161 }
40162 Some(DialectType::Oracle) => {
40163 self.write("TO_DATE('1970-01-01', 'YYYY-MM-DD') + (");
40165 self.generate_expression(&e.this)?;
40166 self.write(" / 86400)");
40167 }
40168 Some(DialectType::Redshift) => {
40169 self.write("(TIMESTAMP 'epoch' + ");
40172 if scale == 0 {
40173 self.generate_expression(&e.this)?;
40174 } else {
40175 self.write("(");
40176 self.generate_expression(&e.this)?;
40177 self.write(&format!(" / POWER(10, {}))", scale));
40178 }
40179 self.write(" * INTERVAL '1 SECOND')");
40180 }
40181 Some(DialectType::Exasol) => {
40182 self.write_keyword("FROM_POSIX_TIME");
40184 self.write("(");
40185 self.generate_expression(&e.this)?;
40186 self.write(")");
40187 }
40188 _ => {
40189 self.write_keyword("TO_TIMESTAMP");
40191 self.write("(");
40192 self.generate_expression(&e.this)?;
40193 if let Some(s) = e.scale {
40194 self.write(", ");
40195 self.write(&s.to_string());
40196 }
40197 self.write(")");
40198 }
40199 }
40200 Ok(())
40201 }
40202
40203 fn generate_unpivot_columns(&mut self, e: &UnpivotColumns) -> Result<()> {
40204 if !matches!(&*e.this, Expression::Null(_)) {
40206 self.write_keyword("NAME");
40207 self.write_space();
40208 self.generate_expression(&e.this)?;
40209 }
40210 if !e.expressions.is_empty() {
40211 self.write_space();
40212 self.write_keyword("VALUE");
40213 self.write_space();
40214 for (i, expr) in e.expressions.iter().enumerate() {
40215 if i > 0 {
40216 self.write(", ");
40217 }
40218 self.generate_expression(expr)?;
40219 }
40220 }
40221 Ok(())
40222 }
40223
40224 fn generate_user_defined_function(&mut self, e: &UserDefinedFunction) -> Result<()> {
40225 if e.wrapped.is_some() {
40227 self.write("(");
40228 }
40229 self.generate_expression(&e.this)?;
40230 if e.wrapped.is_some() {
40231 self.write(")");
40232 }
40233 self.write("(");
40234 for (i, expr) in e.expressions.iter().enumerate() {
40235 if i > 0 {
40236 self.write(", ");
40237 }
40238 self.generate_expression(expr)?;
40239 }
40240 self.write(")");
40241 Ok(())
40242 }
40243
40244 fn generate_using_template_property(&mut self, e: &UsingTemplateProperty) -> Result<()> {
40245 self.write_keyword("USING TEMPLATE");
40247 self.write_space();
40248 self.generate_expression(&e.this)?;
40249 Ok(())
40250 }
40251
40252 fn generate_utc_time(&mut self, _e: &UtcTime) -> Result<()> {
40253 self.write_keyword("UTC_TIME");
40255 Ok(())
40256 }
40257
40258 fn generate_utc_timestamp(&mut self, _e: &UtcTimestamp) -> Result<()> {
40259 if matches!(
40260 self.config.dialect,
40261 Some(crate::dialects::DialectType::ClickHouse)
40262 ) {
40263 self.write_keyword("CURRENT_TIMESTAMP");
40264 self.write("('UTC')");
40265 } else {
40266 self.write_keyword("UTC_TIMESTAMP");
40267 }
40268 Ok(())
40269 }
40270
40271 fn generate_uuid(&mut self, e: &Uuid) -> Result<()> {
40272 use crate::dialects::DialectType;
40273 let func_name = match self.config.dialect {
40275 Some(DialectType::Snowflake) => "UUID_STRING",
40276 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
40277 Some(DialectType::BigQuery) => "GENERATE_UUID",
40278 _ => {
40279 if let Some(name) = &e.name {
40280 name.as_str()
40281 } else {
40282 "UUID"
40283 }
40284 }
40285 };
40286 self.write_keyword(func_name);
40287 self.write("(");
40288 if let Some(this) = &e.this {
40289 self.generate_expression(this)?;
40290 }
40291 self.write(")");
40292 Ok(())
40293 }
40294
40295 fn generate_var_map(&mut self, e: &VarMap) -> Result<()> {
40296 self.write_keyword("MAP");
40298 self.write("(");
40299 let mut first = true;
40300 for (k, v) in e.keys.iter().zip(e.values.iter()) {
40301 if !first {
40302 self.write(", ");
40303 }
40304 self.generate_expression(k)?;
40305 self.write(", ");
40306 self.generate_expression(v)?;
40307 first = false;
40308 }
40309 self.write(")");
40310 Ok(())
40311 }
40312
40313 fn generate_vector_search(&mut self, e: &VectorSearch) -> Result<()> {
40314 self.write_keyword("VECTOR_SEARCH");
40316 self.write("(");
40317 self.generate_expression(&e.this)?;
40318 if let Some(col) = &e.column_to_search {
40319 self.write(", ");
40320 self.generate_expression(col)?;
40321 }
40322 if let Some(query_table) = &e.query_table {
40323 self.write(", ");
40324 self.generate_expression(query_table)?;
40325 }
40326 if let Some(query_col) = &e.query_column_to_search {
40327 self.write(", ");
40328 self.generate_expression(query_col)?;
40329 }
40330 if let Some(top_k) = &e.top_k {
40331 self.write(", ");
40332 self.generate_expression(top_k)?;
40333 }
40334 if let Some(dist_type) = &e.distance_type {
40335 self.write(", ");
40336 self.generate_expression(dist_type)?;
40337 }
40338 self.write(")");
40339 Ok(())
40340 }
40341
40342 fn generate_version(&mut self, e: &Version) -> Result<()> {
40343 use crate::dialects::DialectType;
40349 let skip_for = matches!(
40350 self.config.dialect,
40351 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
40352 );
40353 if !skip_for {
40354 self.write_keyword("FOR");
40355 self.write_space();
40356 }
40357 match e.this.as_ref() {
40359 Expression::Identifier(ident) => {
40360 self.write_keyword(&ident.name);
40361 }
40362 _ => {
40363 self.generate_expression(&e.this)?;
40364 }
40365 }
40366 self.write_space();
40367 self.write_keyword(&e.kind);
40368 if let Some(expression) = &e.expression {
40369 self.write_space();
40370 self.generate_expression(expression)?;
40371 }
40372 Ok(())
40373 }
40374
40375 fn generate_view_attribute_property(&mut self, e: &ViewAttributeProperty) -> Result<()> {
40376 self.generate_expression(&e.this)?;
40378 Ok(())
40379 }
40380
40381 fn generate_volatile_property(&mut self, e: &VolatileProperty) -> Result<()> {
40382 if e.this.is_some() {
40384 self.write_keyword("NOT VOLATILE");
40385 } else {
40386 self.write_keyword("VOLATILE");
40387 }
40388 Ok(())
40389 }
40390
40391 fn generate_watermark_column_constraint(
40392 &mut self,
40393 e: &WatermarkColumnConstraint,
40394 ) -> Result<()> {
40395 self.write_keyword("WATERMARK FOR");
40397 self.write_space();
40398 self.generate_expression(&e.this)?;
40399 self.write_space();
40400 self.write_keyword("AS");
40401 self.write_space();
40402 self.generate_expression(&e.expression)?;
40403 Ok(())
40404 }
40405
40406 fn generate_week(&mut self, e: &Week) -> Result<()> {
40407 self.write_keyword("WEEK");
40409 self.write("(");
40410 self.generate_expression(&e.this)?;
40411 if let Some(mode) = &e.mode {
40412 self.write(", ");
40413 self.generate_expression(mode)?;
40414 }
40415 self.write(")");
40416 Ok(())
40417 }
40418
40419 fn generate_when(&mut self, e: &When) -> Result<()> {
40420 self.write_keyword("WHEN");
40424 self.write_space();
40425
40426 if let Some(matched) = &e.matched {
40428 match matched.as_ref() {
40430 Expression::Boolean(b) if b.value => {
40431 self.write_keyword("MATCHED");
40432 }
40433 _ => {
40434 self.write_keyword("NOT MATCHED");
40435 }
40436 }
40437 } else {
40438 self.write_keyword("NOT MATCHED");
40439 }
40440
40441 if self.config.matched_by_source {
40446 if let Some(source) = &e.source {
40447 if let Expression::Boolean(b) = source.as_ref() {
40448 if b.value {
40449 self.write_space();
40451 self.write_keyword("BY SOURCE");
40452 }
40453 } else {
40455 self.write_space();
40457 self.write_keyword("BY SOURCE");
40458 }
40459 }
40460 }
40461
40462 if let Some(condition) = &e.condition {
40464 self.write_space();
40465 self.write_keyword("AND");
40466 self.write_space();
40467 self.generate_expression(condition)?;
40468 }
40469
40470 self.write_space();
40471 self.write_keyword("THEN");
40472 self.write_space();
40473
40474 self.generate_merge_action(&e.then)?;
40477
40478 Ok(())
40479 }
40480
40481 fn generate_merge_action(&mut self, action: &Expression) -> Result<()> {
40482 match action {
40483 Expression::Tuple(tuple) => {
40484 let elements = &tuple.expressions;
40485 if elements.is_empty() {
40486 return self.generate_expression(action);
40487 }
40488 match &elements[0] {
40490 Expression::Var(v) if v.this == "INSERT" => {
40491 self.write_keyword("INSERT");
40492 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
40494 self.write(" *");
40495 if let Some(Expression::Where(w)) = elements.get(2) {
40496 self.write_space();
40497 self.generate_where(w)?;
40498 }
40499 } else {
40500 let mut values_idx = 1;
40501 if elements.len() > 1 {
40503 if let Expression::Tuple(cols) = &elements[1] {
40504 if elements.len() > 2 {
40506 self.write(" (");
40508 for (i, col) in cols.expressions.iter().enumerate() {
40509 if i > 0 {
40510 self.write(", ");
40511 }
40512 if !self.merge_strip_qualifiers.is_empty() {
40514 let stripped = self.strip_merge_qualifier(col);
40515 self.generate_expression(&stripped)?;
40516 } else {
40517 self.generate_expression(col)?;
40518 }
40519 }
40520 self.write(")");
40521 values_idx = 2;
40522 } else {
40523 values_idx = 1;
40525 }
40526 }
40527 }
40528 let mut next_idx = values_idx;
40529 if values_idx < elements.len()
40531 && !matches!(&elements[values_idx], Expression::Where(_))
40532 {
40533 let is_row = matches!(&elements[values_idx], Expression::Var(v) if v.this == "ROW");
40535 if !is_row {
40536 self.write_space();
40537 self.write_keyword("VALUES");
40538 }
40539 self.write(" ");
40540 if let Expression::Tuple(vals) = &elements[values_idx] {
40541 self.write("(");
40542 for (i, val) in vals.expressions.iter().enumerate() {
40543 if i > 0 {
40544 self.write(", ");
40545 }
40546 self.generate_expression(val)?;
40547 }
40548 self.write(")");
40549 } else {
40550 self.generate_expression(&elements[values_idx])?;
40551 }
40552 next_idx += 1;
40553 }
40554 if let Some(Expression::Where(w)) = elements.get(next_idx) {
40555 self.write_space();
40556 self.generate_where(w)?;
40557 }
40558 } }
40560 Expression::Var(v) if v.this == "UPDATE" => {
40561 self.write_keyword("UPDATE");
40562 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
40564 self.write(" *");
40565 if let Some(Expression::Where(w)) = elements.get(2) {
40566 self.write_space();
40567 self.generate_where(w)?;
40568 }
40569 } else if elements.len() > 1 {
40570 self.write_space();
40571 self.write_keyword("SET");
40572 if self.config.pretty {
40574 self.write_newline();
40575 self.indent_level += 1;
40576 self.write_indent();
40577 } else {
40578 self.write_space();
40579 }
40580 if let Expression::Tuple(assignments) = &elements[1] {
40581 for (i, assignment) in assignments.expressions.iter().enumerate() {
40582 if i > 0 {
40583 if self.config.pretty {
40584 self.write(",");
40585 self.write_newline();
40586 self.write_indent();
40587 } else {
40588 self.write(", ");
40589 }
40590 }
40591 if !self.merge_strip_qualifiers.is_empty() {
40593 self.generate_merge_set_assignment(assignment)?;
40594 } else {
40595 self.generate_expression(assignment)?;
40596 }
40597 }
40598 } else {
40599 self.generate_expression(&elements[1])?;
40600 }
40601 if self.config.pretty {
40602 self.indent_level -= 1;
40603 }
40604 if let Some(Expression::Where(w)) = elements.get(2) {
40605 self.write_space();
40606 self.generate_where(w)?;
40607 }
40608 }
40609 }
40610 Expression::Var(v) if v.this == "DELETE" => {
40611 self.write_keyword("DELETE");
40612 if let Some(Expression::Where(w)) = elements.get(1) {
40613 self.write_space();
40614 self.generate_where(w)?;
40615 }
40616 }
40617 _ => {
40618 self.generate_expression(action)?;
40620 }
40621 }
40622 }
40623 Expression::Var(v)
40624 if v.this == "INSERT"
40625 || v.this == "UPDATE"
40626 || v.this == "DELETE"
40627 || v.this == "DO NOTHING" =>
40628 {
40629 self.write_keyword(&v.this);
40630 }
40631 _ => {
40632 self.generate_expression(action)?;
40633 }
40634 }
40635 Ok(())
40636 }
40637
40638 fn generate_merge_set_assignment(&mut self, assignment: &Expression) -> Result<()> {
40640 match assignment {
40641 Expression::Eq(eq) => {
40642 let stripped_left = self.strip_merge_qualifier(&eq.left);
40644 self.generate_expression(&stripped_left)?;
40645 self.write(" = ");
40646 self.generate_expression(&eq.right)?;
40647 Ok(())
40648 }
40649 other => self.generate_expression(other),
40650 }
40651 }
40652
40653 fn strip_merge_qualifier(&self, expr: &Expression) -> Expression {
40655 match expr {
40656 Expression::Column(col) => {
40657 if let Some(ref table_ident) = col.table {
40658 if self
40659 .merge_strip_qualifiers
40660 .iter()
40661 .any(|n| n.eq_ignore_ascii_case(&table_ident.name))
40662 {
40663 let mut col = col.clone();
40665 col.table = None;
40666 return Expression::Column(col);
40667 }
40668 }
40669 expr.clone()
40670 }
40671 Expression::Dot(dot) => {
40672 if let Expression::Identifier(id) = &dot.this {
40674 if self
40675 .merge_strip_qualifiers
40676 .iter()
40677 .any(|n| n.eq_ignore_ascii_case(&id.name))
40678 {
40679 return Expression::Identifier(dot.field.clone());
40680 }
40681 }
40682 expr.clone()
40683 }
40684 _ => expr.clone(),
40685 }
40686 }
40687
40688 fn generate_whens(&mut self, e: &Whens) -> Result<()> {
40689 for (i, expr) in e.expressions.iter().enumerate() {
40691 if i > 0 {
40692 if self.config.pretty {
40694 self.write_newline();
40695 self.write_indent();
40696 } else {
40697 self.write_space();
40698 }
40699 }
40700 self.generate_expression(expr)?;
40701 }
40702 Ok(())
40703 }
40704
40705 fn generate_where(&mut self, e: &Where) -> Result<()> {
40706 self.write_keyword("WHERE");
40708 self.write_space();
40709 self.generate_expression(&e.this)?;
40710 Ok(())
40711 }
40712
40713 fn generate_width_bucket(&mut self, e: &WidthBucket) -> Result<()> {
40714 self.write_keyword("WIDTH_BUCKET");
40716 self.write("(");
40717 self.generate_expression(&e.this)?;
40718 if let Some(min_value) = &e.min_value {
40719 self.write(", ");
40720 self.generate_expression(min_value)?;
40721 }
40722 if let Some(max_value) = &e.max_value {
40723 self.write(", ");
40724 self.generate_expression(max_value)?;
40725 }
40726 if let Some(num_buckets) = &e.num_buckets {
40727 self.write(", ");
40728 self.generate_expression(num_buckets)?;
40729 }
40730 self.write(")");
40731 Ok(())
40732 }
40733
40734 fn generate_window(&mut self, e: &WindowSpec) -> Result<()> {
40735 self.generate_window_spec(e)
40737 }
40738
40739 fn generate_window_spec(&mut self, e: &WindowSpec) -> Result<()> {
40740 let mut has_content = false;
40742
40743 if !e.partition_by.is_empty() {
40745 self.write_keyword("PARTITION BY");
40746 self.write_space();
40747 for (i, expr) in e.partition_by.iter().enumerate() {
40748 if i > 0 {
40749 self.write(", ");
40750 }
40751 self.generate_expression(expr)?;
40752 }
40753 has_content = true;
40754 }
40755
40756 if !e.order_by.is_empty() {
40758 if has_content {
40759 self.write_space();
40760 }
40761 self.write_keyword("ORDER BY");
40762 self.write_space();
40763 for (i, ordered) in e.order_by.iter().enumerate() {
40764 if i > 0 {
40765 self.write(", ");
40766 }
40767 self.generate_expression(&ordered.this)?;
40768 if ordered.desc {
40769 self.write_space();
40770 self.write_keyword("DESC");
40771 } else if ordered.explicit_asc {
40772 self.write_space();
40773 self.write_keyword("ASC");
40774 }
40775 if let Some(nulls_first) = ordered.nulls_first {
40776 self.write_space();
40777 self.write_keyword("NULLS");
40778 self.write_space();
40779 if nulls_first {
40780 self.write_keyword("FIRST");
40781 } else {
40782 self.write_keyword("LAST");
40783 }
40784 }
40785 }
40786 has_content = true;
40787 }
40788
40789 if let Some(frame) = &e.frame {
40791 if has_content {
40792 self.write_space();
40793 }
40794 self.generate_window_frame(frame)?;
40795 }
40796
40797 Ok(())
40798 }
40799
40800 fn generate_with_data_property(&mut self, e: &WithDataProperty) -> Result<()> {
40801 self.write_keyword("WITH");
40803 self.write_space();
40804 if e.no.is_some() {
40805 self.write_keyword("NO");
40806 self.write_space();
40807 }
40808 self.write_keyword("DATA");
40809
40810 if let Some(statistics) = &e.statistics {
40812 self.write_space();
40813 self.write_keyword("AND");
40814 self.write_space();
40815 match statistics.as_ref() {
40817 Expression::Boolean(b) if !b.value => {
40818 self.write_keyword("NO");
40819 self.write_space();
40820 }
40821 _ => {}
40822 }
40823 self.write_keyword("STATISTICS");
40824 }
40825 Ok(())
40826 }
40827
40828 fn generate_with_fill(&mut self, e: &WithFill) -> Result<()> {
40829 self.write_keyword("WITH FILL");
40831
40832 if let Some(from_) = &e.from_ {
40833 self.write_space();
40834 self.write_keyword("FROM");
40835 self.write_space();
40836 self.generate_expression(from_)?;
40837 }
40838
40839 if let Some(to) = &e.to {
40840 self.write_space();
40841 self.write_keyword("TO");
40842 self.write_space();
40843 self.generate_expression(to)?;
40844 }
40845
40846 if let Some(step) = &e.step {
40847 self.write_space();
40848 self.write_keyword("STEP");
40849 self.write_space();
40850 self.generate_expression(step)?;
40851 }
40852
40853 if let Some(staleness) = &e.staleness {
40854 self.write_space();
40855 self.write_keyword("STALENESS");
40856 self.write_space();
40857 self.generate_expression(staleness)?;
40858 }
40859
40860 if let Some(interpolate) = &e.interpolate {
40861 self.write_space();
40862 self.write_keyword("INTERPOLATE");
40863 self.write(" (");
40864 self.generate_interpolate_item(interpolate)?;
40866 self.write(")");
40867 }
40868
40869 Ok(())
40870 }
40871
40872 fn generate_interpolate_item(&mut self, expr: &Expression) -> Result<()> {
40874 match expr {
40875 Expression::Alias(alias) => {
40876 self.generate_identifier(&alias.alias)?;
40878 self.write_space();
40879 self.write_keyword("AS");
40880 self.write_space();
40881 self.generate_expression(&alias.this)?;
40882 }
40883 Expression::Tuple(tuple) => {
40884 for (i, item) in tuple.expressions.iter().enumerate() {
40885 if i > 0 {
40886 self.write(", ");
40887 }
40888 self.generate_interpolate_item(item)?;
40889 }
40890 }
40891 other => {
40892 self.generate_expression(other)?;
40893 }
40894 }
40895 Ok(())
40896 }
40897
40898 fn generate_with_journal_table_property(&mut self, e: &WithJournalTableProperty) -> Result<()> {
40899 self.write_keyword("WITH JOURNAL TABLE");
40901 self.write("=");
40902 self.generate_expression(&e.this)?;
40903 Ok(())
40904 }
40905
40906 fn generate_with_operator(&mut self, e: &WithOperator) -> Result<()> {
40907 self.generate_expression(&e.this)?;
40909 self.write_space();
40910 self.write_keyword("WITH");
40911 self.write_space();
40912 self.write_keyword(&e.op);
40913 Ok(())
40914 }
40915
40916 fn generate_with_procedure_options(&mut self, e: &WithProcedureOptions) -> Result<()> {
40917 self.write_keyword("WITH");
40919 self.write_space();
40920 for (i, expr) in e.expressions.iter().enumerate() {
40921 if i > 0 {
40922 self.write(", ");
40923 }
40924 self.generate_expression(expr)?;
40925 }
40926 Ok(())
40927 }
40928
40929 fn generate_with_schema_binding_property(
40930 &mut self,
40931 e: &WithSchemaBindingProperty,
40932 ) -> Result<()> {
40933 self.write_keyword("WITH");
40935 self.write_space();
40936 self.generate_expression(&e.this)?;
40937 Ok(())
40938 }
40939
40940 fn generate_with_system_versioning_property(
40941 &mut self,
40942 e: &WithSystemVersioningProperty,
40943 ) -> Result<()> {
40944 let mut parts = Vec::new();
40950
40951 if let Some(this) = &e.this {
40952 let mut s = String::from("HISTORY_TABLE=");
40954 let mut gen = Generator::new();
40955 gen.generate_expression(this)?;
40956 s.push_str(&gen.output);
40957 parts.push(s);
40958 }
40959
40960 if let Some(data_consistency) = &e.data_consistency {
40961 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
40962 let mut gen = Generator::new();
40963 gen.generate_expression(data_consistency)?;
40964 s.push_str(&gen.output);
40965 parts.push(s);
40966 }
40967
40968 if let Some(retention_period) = &e.retention_period {
40969 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
40970 let mut gen = Generator::new();
40971 gen.generate_expression(retention_period)?;
40972 s.push_str(&gen.output);
40973 parts.push(s);
40974 }
40975
40976 self.write_keyword("SYSTEM_VERSIONING");
40977 self.write("=");
40978
40979 if !parts.is_empty() {
40980 self.write_keyword("ON");
40981 self.write("(");
40982 self.write(&parts.join(", "));
40983 self.write(")");
40984 } else if e.on.is_some() {
40985 self.write_keyword("ON");
40986 } else {
40987 self.write_keyword("OFF");
40988 }
40989
40990 if e.with_.is_some() {
40992 let inner = self.output.clone();
40993 self.output.clear();
40994 self.write("WITH(");
40995 self.write(&inner);
40996 self.write(")");
40997 }
40998
40999 Ok(())
41000 }
41001
41002 fn generate_with_table_hint(&mut self, e: &WithTableHint) -> Result<()> {
41003 self.write_keyword("WITH");
41005 self.write(" (");
41006 for (i, expr) in e.expressions.iter().enumerate() {
41007 if i > 0 {
41008 self.write(", ");
41009 }
41010 self.generate_expression(expr)?;
41011 }
41012 self.write(")");
41013 Ok(())
41014 }
41015
41016 fn generate_xml_element(&mut self, e: &XMLElement) -> Result<()> {
41017 self.write_keyword("XMLELEMENT");
41020 self.write("(");
41021
41022 if e.evalname.is_some() {
41023 self.write_keyword("EVALNAME");
41024 } else {
41025 self.write_keyword("NAME");
41026 }
41027 self.write_space();
41028 self.generate_expression(&e.this)?;
41029
41030 for expr in &e.expressions {
41031 self.write(", ");
41032 self.generate_expression(expr)?;
41033 }
41034 self.write(")");
41035 Ok(())
41036 }
41037
41038 fn generate_xml_get(&mut self, e: &XMLGet) -> Result<()> {
41039 self.write_keyword("XMLGET");
41041 self.write("(");
41042 self.generate_expression(&e.this)?;
41043 self.write(", ");
41044 self.generate_expression(&e.expression)?;
41045 if let Some(instance) = &e.instance {
41046 self.write(", ");
41047 self.generate_expression(instance)?;
41048 }
41049 self.write(")");
41050 Ok(())
41051 }
41052
41053 fn generate_xml_key_value_option(&mut self, e: &XMLKeyValueOption) -> Result<()> {
41054 self.generate_expression(&e.this)?;
41056 if let Some(expression) = &e.expression {
41057 self.write("(");
41058 self.generate_expression(expression)?;
41059 self.write(")");
41060 }
41061 Ok(())
41062 }
41063
41064 fn generate_xml_table(&mut self, e: &XMLTable) -> Result<()> {
41065 self.write_keyword("XMLTABLE");
41067 self.write("(");
41068
41069 if self.config.pretty {
41070 self.indent_level += 1;
41071 self.write_newline();
41072 self.write_indent();
41073 self.generate_expression(&e.this)?;
41074
41075 if let Some(passing) = &e.passing {
41076 self.write_newline();
41077 self.write_indent();
41078 self.write_keyword("PASSING");
41079 if let Expression::Tuple(tuple) = passing.as_ref() {
41080 for expr in &tuple.expressions {
41081 self.write_newline();
41082 self.indent_level += 1;
41083 self.write_indent();
41084 self.generate_expression(expr)?;
41085 self.indent_level -= 1;
41086 }
41087 } else {
41088 self.write_newline();
41089 self.indent_level += 1;
41090 self.write_indent();
41091 self.generate_expression(passing)?;
41092 self.indent_level -= 1;
41093 }
41094 }
41095
41096 if e.by_ref.is_some() {
41097 self.write_newline();
41098 self.write_indent();
41099 self.write_keyword("RETURNING SEQUENCE BY REF");
41100 }
41101
41102 if !e.columns.is_empty() {
41103 self.write_newline();
41104 self.write_indent();
41105 self.write_keyword("COLUMNS");
41106 for (i, col) in e.columns.iter().enumerate() {
41107 self.write_newline();
41108 self.indent_level += 1;
41109 self.write_indent();
41110 self.generate_expression(col)?;
41111 self.indent_level -= 1;
41112 if i < e.columns.len() - 1 {
41113 self.write(",");
41114 }
41115 }
41116 }
41117
41118 self.indent_level -= 1;
41119 self.write_newline();
41120 self.write_indent();
41121 self.write(")");
41122 return Ok(());
41123 }
41124
41125 if let Some(namespaces) = &e.namespaces {
41127 self.write_keyword("XMLNAMESPACES");
41128 self.write("(");
41129 if let Expression::Tuple(tuple) = namespaces.as_ref() {
41131 for (i, expr) in tuple.expressions.iter().enumerate() {
41132 if i > 0 {
41133 self.write(", ");
41134 }
41135 if !matches!(expr, Expression::Alias(_)) {
41138 self.write_keyword("DEFAULT");
41139 self.write_space();
41140 }
41141 self.generate_expression(expr)?;
41142 }
41143 } else {
41144 if !matches!(namespaces.as_ref(), Expression::Alias(_)) {
41146 self.write_keyword("DEFAULT");
41147 self.write_space();
41148 }
41149 self.generate_expression(namespaces)?;
41150 }
41151 self.write("), ");
41152 }
41153
41154 self.generate_expression(&e.this)?;
41156
41157 if let Some(passing) = &e.passing {
41159 self.write_space();
41160 self.write_keyword("PASSING");
41161 self.write_space();
41162 if let Expression::Tuple(tuple) = passing.as_ref() {
41164 for (i, expr) in tuple.expressions.iter().enumerate() {
41165 if i > 0 {
41166 self.write(", ");
41167 }
41168 self.generate_expression(expr)?;
41169 }
41170 } else {
41171 self.generate_expression(passing)?;
41172 }
41173 }
41174
41175 if e.by_ref.is_some() {
41177 self.write_space();
41178 self.write_keyword("RETURNING SEQUENCE BY REF");
41179 }
41180
41181 if !e.columns.is_empty() {
41183 self.write_space();
41184 self.write_keyword("COLUMNS");
41185 self.write_space();
41186 for (i, col) in e.columns.iter().enumerate() {
41187 if i > 0 {
41188 self.write(", ");
41189 }
41190 self.generate_expression(col)?;
41191 }
41192 }
41193
41194 self.write(")");
41195 Ok(())
41196 }
41197
41198 fn generate_xor(&mut self, e: &Xor) -> Result<()> {
41199 if let Some(this) = &e.this {
41202 self.generate_expression(this)?;
41203 if let Some(expression) = &e.expression {
41204 self.write_space();
41205 self.write_keyword("XOR");
41206 self.write_space();
41207 self.generate_expression(expression)?;
41208 }
41209 }
41210
41211 for (i, expr) in e.expressions.iter().enumerate() {
41213 if i > 0 || e.this.is_some() {
41214 self.write_space();
41215 self.write_keyword("XOR");
41216 self.write_space();
41217 }
41218 self.generate_expression(expr)?;
41219 }
41220 Ok(())
41221 }
41222
41223 fn generate_zipf(&mut self, e: &Zipf) -> Result<()> {
41224 self.write_keyword("ZIPF");
41226 self.write("(");
41227 self.generate_expression(&e.this)?;
41228 if let Some(elementcount) = &e.elementcount {
41229 self.write(", ");
41230 self.generate_expression(elementcount)?;
41231 }
41232 if let Some(gen) = &e.gen {
41233 self.write(", ");
41234 self.generate_expression(gen)?;
41235 }
41236 self.write(")");
41237 Ok(())
41238 }
41239}
41240
41241impl Default for Generator {
41242 fn default() -> Self {
41243 Self::new()
41244 }
41245}
41246
41247#[cfg(test)]
41248mod tests {
41249 use super::*;
41250 use crate::parser::Parser;
41251
41252 fn roundtrip(sql: &str) -> String {
41253 let ast = Parser::parse_sql(sql).unwrap();
41254 Generator::sql(&ast[0]).unwrap()
41255 }
41256
41257 #[test]
41258 fn test_simple_select() {
41259 let result = roundtrip("SELECT 1");
41260 assert_eq!(result, "SELECT 1");
41261 }
41262
41263 #[test]
41264 fn test_select_from() {
41265 let result = roundtrip("SELECT a, b FROM t");
41266 assert_eq!(result, "SELECT a, b FROM t");
41267 }
41268
41269 #[test]
41270 fn test_select_where() {
41271 let result = roundtrip("SELECT * FROM t WHERE x = 1");
41272 assert_eq!(result, "SELECT * FROM t WHERE x = 1");
41273 }
41274
41275 #[test]
41276 fn test_select_join() {
41277 let result = roundtrip("SELECT * FROM a JOIN b ON a.id = b.id");
41278 assert_eq!(result, "SELECT * FROM a JOIN b ON a.id = b.id");
41279 }
41280
41281 #[test]
41282 fn test_insert() {
41283 let result = roundtrip("INSERT INTO t (a, b) VALUES (1, 2)");
41284 assert_eq!(result, "INSERT INTO t (a, b) VALUES (1, 2)");
41285 }
41286
41287 #[test]
41288 fn test_pretty_print() {
41289 let ast = Parser::parse_sql("SELECT a, b FROM t WHERE x = 1").unwrap();
41290 let result = Generator::pretty_sql(&ast[0]).unwrap();
41291 assert!(result.contains('\n'));
41292 }
41293
41294 #[test]
41295 fn test_window_function() {
41296 let result = roundtrip("SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)");
41297 assert_eq!(
41298 result,
41299 "SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)"
41300 );
41301 }
41302
41303 #[test]
41304 fn test_window_function_with_frame() {
41305 let result = roundtrip("SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
41306 assert_eq!(result, "SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
41307 }
41308
41309 #[test]
41310 fn test_aggregate_with_filter() {
41311 let result = roundtrip("SELECT COUNT(*) FILTER (WHERE status = 1) FROM orders");
41312 assert_eq!(
41313 result,
41314 "SELECT COUNT(*) FILTER(WHERE status = 1) FROM orders"
41315 );
41316 }
41317
41318 #[test]
41319 fn test_subscript() {
41320 let result = roundtrip("SELECT arr[0]");
41321 assert_eq!(result, "SELECT arr[0]");
41322 }
41323
41324 #[test]
41326 fn test_create_table() {
41327 let result = roundtrip("CREATE TABLE users (id INT, name VARCHAR(100))");
41328 assert_eq!(result, "CREATE TABLE users (id INT, name VARCHAR(100))");
41329 }
41330
41331 #[test]
41332 fn test_create_table_with_constraints() {
41333 let result = roundtrip(
41334 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)",
41335 );
41336 assert_eq!(
41337 result,
41338 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)"
41339 );
41340 }
41341
41342 #[test]
41343 fn test_create_table_if_not_exists() {
41344 let result = roundtrip("CREATE TABLE IF NOT EXISTS t (id INT)");
41345 assert_eq!(result, "CREATE TABLE IF NOT EXISTS t (id INT)");
41346 }
41347
41348 #[test]
41349 fn test_drop_table() {
41350 let result = roundtrip("DROP TABLE users");
41351 assert_eq!(result, "DROP TABLE users");
41352 }
41353
41354 #[test]
41355 fn test_drop_table_if_exists_cascade() {
41356 let result = roundtrip("DROP TABLE IF EXISTS users CASCADE");
41357 assert_eq!(result, "DROP TABLE IF EXISTS users CASCADE");
41358 }
41359
41360 #[test]
41361 fn test_alter_table_add_column() {
41362 let result = roundtrip("ALTER TABLE users ADD COLUMN email VARCHAR(255)");
41363 assert_eq!(result, "ALTER TABLE users ADD COLUMN email VARCHAR(255)");
41364 }
41365
41366 #[test]
41367 fn test_alter_table_drop_column() {
41368 let result = roundtrip("ALTER TABLE users DROP COLUMN email");
41369 assert_eq!(result, "ALTER TABLE users DROP COLUMN email");
41370 }
41371
41372 #[test]
41373 fn test_create_index() {
41374 let result = roundtrip("CREATE INDEX idx_name ON users(name)");
41375 assert_eq!(result, "CREATE INDEX idx_name ON users(name)");
41376 }
41377
41378 #[test]
41379 fn test_create_unique_index() {
41380 let result = roundtrip("CREATE UNIQUE INDEX idx_email ON users(email)");
41381 assert_eq!(result, "CREATE UNIQUE INDEX idx_email ON users(email)");
41382 }
41383
41384 #[test]
41385 fn test_drop_index() {
41386 let result = roundtrip("DROP INDEX idx_name");
41387 assert_eq!(result, "DROP INDEX idx_name");
41388
41389 let result = roundtrip(r#"DROP INDEX IF EXISTS "idx_tokenKey__pb_users_auth_""#);
41390 assert_eq!(
41391 result,
41392 r#"DROP INDEX IF EXISTS "idx_tokenKey__pb_users_auth_""#
41393 );
41394
41395 let result = roundtrip(r#"DROP INDEX "public"."IdxMixed""#);
41396 assert_eq!(result, r#"DROP INDEX "public"."IdxMixed""#);
41397 }
41398
41399 #[test]
41400 fn test_create_view() {
41401 let result = roundtrip("CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1");
41402 assert_eq!(
41403 result,
41404 "CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1"
41405 );
41406 }
41407
41408 #[test]
41409 fn test_drop_view() {
41410 let result = roundtrip("DROP VIEW active_users");
41411 assert_eq!(result, "DROP VIEW active_users");
41412 }
41413
41414 #[test]
41415 fn test_truncate() {
41416 let result = roundtrip("TRUNCATE TABLE users");
41417 assert_eq!(result, "TRUNCATE TABLE users");
41418 }
41419
41420 #[test]
41421 fn test_string_literal_escaping_default() {
41422 let result = roundtrip("SELECT 'hello'");
41424 assert_eq!(result, "SELECT 'hello'");
41425
41426 let result = roundtrip("SELECT 'it''s a test'");
41428 assert_eq!(result, "SELECT 'it''s a test'");
41429 }
41430
41431 #[test]
41432 fn test_not_in_style_prefix_default_generic() {
41433 let result = roundtrip("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')");
41434 assert_eq!(
41435 result,
41436 "SELECT id FROM users WHERE NOT status IN ('deleted', 'banned')"
41437 );
41438 }
41439
41440 #[test]
41441 fn test_not_in_style_infix_generic_override() {
41442 let ast =
41443 Parser::parse_sql("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')")
41444 .unwrap();
41445 let config = GeneratorConfig {
41446 not_in_style: NotInStyle::Infix,
41447 ..Default::default()
41448 };
41449 let mut gen = Generator::with_config(config);
41450 let result = gen.generate(&ast[0]).unwrap();
41451 assert_eq!(
41452 result,
41453 "SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')"
41454 );
41455 }
41456
41457 #[test]
41458 fn test_string_literal_escaping_mysql() {
41459 use crate::dialects::DialectType;
41460
41461 let config = GeneratorConfig {
41462 dialect: Some(DialectType::MySQL),
41463 ..Default::default()
41464 };
41465
41466 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
41467 let mut gen = Generator::with_config(config.clone());
41468 let result = gen.generate(&ast[0]).unwrap();
41469 assert_eq!(result, "SELECT 'hello'");
41470
41471 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
41473 let mut gen = Generator::with_config(config.clone());
41474 let result = gen.generate(&ast[0]).unwrap();
41475 assert_eq!(result, "SELECT 'it''s'");
41476 }
41477
41478 #[test]
41479 fn test_string_literal_escaping_postgres() {
41480 use crate::dialects::DialectType;
41481
41482 let config = GeneratorConfig {
41483 dialect: Some(DialectType::PostgreSQL),
41484 ..Default::default()
41485 };
41486
41487 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
41488 let mut gen = Generator::with_config(config.clone());
41489 let result = gen.generate(&ast[0]).unwrap();
41490 assert_eq!(result, "SELECT 'hello'");
41491
41492 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
41494 let mut gen = Generator::with_config(config.clone());
41495 let result = gen.generate(&ast[0]).unwrap();
41496 assert_eq!(result, "SELECT 'it''s'");
41497 }
41498
41499 #[test]
41500 fn test_string_literal_escaping_bigquery() {
41501 use crate::dialects::DialectType;
41502
41503 let config = GeneratorConfig {
41504 dialect: Some(DialectType::BigQuery),
41505 ..Default::default()
41506 };
41507
41508 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
41509 let mut gen = Generator::with_config(config.clone());
41510 let result = gen.generate(&ast[0]).unwrap();
41511 assert_eq!(result, "SELECT 'hello'");
41512
41513 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
41515 let mut gen = Generator::with_config(config.clone());
41516 let result = gen.generate(&ast[0]).unwrap();
41517 assert_eq!(result, "SELECT 'it\\'s'");
41518 }
41519
41520 #[test]
41521 fn test_generate_deep_and_chain_without_stack_growth() {
41522 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
41523 Expression::column("c0"),
41524 Expression::number(0),
41525 )));
41526
41527 for i in 1..2500 {
41528 let predicate = Expression::Eq(Box::new(BinaryOp::new(
41529 Expression::column(format!("c{i}")),
41530 Expression::number(i as i64),
41531 )));
41532 expr = Expression::And(Box::new(BinaryOp::new(expr, predicate)));
41533 }
41534
41535 let sql = Generator::sql(&expr).expect("deep AND chain should generate");
41536 assert!(sql.contains("c2499 = 2499"), "{}", sql);
41537 }
41538
41539 #[test]
41540 fn test_generate_deep_or_chain_without_stack_growth() {
41541 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
41542 Expression::column("c0"),
41543 Expression::number(0),
41544 )));
41545
41546 for i in 1..2500 {
41547 let predicate = Expression::Eq(Box::new(BinaryOp::new(
41548 Expression::column(format!("c{i}")),
41549 Expression::number(i as i64),
41550 )));
41551 expr = Expression::Or(Box::new(BinaryOp::new(expr, predicate)));
41552 }
41553
41554 let sql = Generator::sql(&expr).expect("deep OR chain should generate");
41555 assert!(sql.contains("c2499 = 2499"), "{}", sql);
41556 }
41557}